djcev.com

//

Git Repos / fte_dogmode / commit 656b401

Commit: 656b40151f36e26fc4f715957e75cc0af7a0ec7c
Parent: 6d390b97ae7cfb400f697f93b7b83be01a2420a3
Author: Cameron Vanderzanden, 2023-10-13 16:13
Committer: Cameron Vanderzanden, 2023-10-13 16:13

Commit Message

New movement code based on SV_RunClientCommand

Alright so here's the first import of the new movement code from
my untracked working files. The relevant pieces are in qc/pmove.qc
and qc/sv_runclient.qc . Some other movement-related changes have
been made in qc/client.qc and qc/triggers.qc .

This "new movement" relies on and will not work without the
SV_RunClientCommand engine extension. (Currently available in FTE
and I think Darkplaces).

It's very important to note that the client side (client prediction)
has *not* been written yet, so running this code requires "cl_nopred 1"
in FTE.

I've also touched most files to change their format to unix text
(plus more changes I'm sure I'm forgetting).

There's some cleanup that needs to be done here, I think.  Both with
the progs_dump code and my own additions.

Change List

?File Add Del
M .gitignore +1
M build.sh +2 -2
M qc/buttons.qc +205 -205
M qc/client.qc +1390 -1447
M qc/combat.qc +366 -366
A qc/defs_constants.qc +6
M qc/doe_elbutton.qc +157 -157
M qc/doe_plats.qc +630 -630
M qc/doors.qc +945 -945
M qc/dtmisc.qc +1176 -1176
M qc/dtquake.qc +103 -103
M qc/fight.qc +509 -509
M qc/fteqcc.ini +240 -240
M qc/items.qc +2441 -2441
M qc/math.qc +209 -209
M qc/misc.qc +1871 -1871
M qc/misc_model.qc +170 -170
M qc/monsters.qc +518 -518
M qc/monsters/boss.qc +415 -415
M qc/monsters/demon.qc +502 -502
M qc/monsters/dog.qc +503 -503
M qc/monsters/enforcer.qc +1044 -1044
M qc/monsters/fish.qc +306 -306
M qc/monsters/hknight.qc +755 -755
M qc/monsters/knight.qc +418 -418
M qc/monsters/ogre.qc +1571 -1571
M qc/monsters/oldone.qc +296 -296
M qc/monsters/shalrath.qc +433 -433
M qc/monsters/shambler.qc +727 -727
M qc/monsters/soldier.qc +709 -709
M qc/monsters/wizard.qc +580 -580
M qc/monsters/zombie.qc +865 -865
M qc/plats.qc +786 -786
M qc/player.qc +762 -762
A qc/pmove.qc +1180
M qc/progs.src +79 -76
M qc/rubicon2.qc +1010 -1010
M qc/subs.qc +1 -1
A qc/sv_runclient.qc +7
M qc/triggers.qc +54 -16
M qc/weapons.qc +1807 -1807
M qc/world.qc +621 -621

Diff .gitignore

diff --git a/.gitignore b/.gitignore
index ff180ef..4ab1c40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
*.dat
*.lno
*.swp
+qc/fteextensions.qc

Return to the top of this page or return to the overview of this repo.

Diff build.sh

diff --git a/build.sh b/build.sh
index e27afe6..9f27b6f 100755
--- a/build.sh
+++ b/build.sh
@@ -2,8 +2,8 @@

FTEQCC=/z/games/Quake/engines/fteqcc/fteqcc64
SRCDIR=/z/work/cvanderz/fte_dogmode
-CLIENTQCDIR=$SRCDIR/qc-server/csqc
-SERVERQCDIR=$SRCDIR/qc-server
+CLIENTQCDIR=$SRCDIR/qc/csqc
+SERVERQCDIR=$SRCDIR/qc

cd $CLIENTQCDIR
$FTEQCC csqc_progs.src

Return to the top of this page or return to the overview of this repo.

Diff qc/buttons.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/client.qc

diff --git a/qc/client.qc b/qc/client.qc
index cb97b95..448eb2b 100644
--- a/qc/client.qc
+++ b/qc/client.qc
@@ -1,1447 +1,1390 @@
-
-// prototypes
-void () W_WeaponFrame;
-void() W_SetCurrentAmmo;
-void(entity attacker, float damage) player_pain;
-void() player_stand1;
-//void (vector org) spawn_tfog; //moved to items.qc -- dumptruck_ds
-void (vector org, entity death_owner) spawn_tdeath;
-
-
-float modelindex_eyes, modelindex_player;
-void() SUB_CheckWaiting; // in triggers.qc
-
-
-
-
-
-void() SetChangeParms =
-{
- if (self.health <= 0)
- {
- SetNewParms ();
- return;
- }
-
-// remove items
- self.items = self.items - (self.items &
- (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
-
-// cap super health
- if (self.health > 100)
- self.health = 100;
- if (self.health < 50)
- self.health = 50;
- parm1 = self.items;
- parm2 = self.health;
- parm3 = self.armorvalue;
- if (self.ammo_shells < 25)
- parm4 = 25;
- else
- parm4 = self.ammo_shells;
- parm5 = self.ammo_nails;
- parm6 = self.ammo_rockets;
- parm7 = self.ammo_cells;
- parm8 = self.weapon;
- parm9 = self.armortype * 100;
-};
-
-void() SetNewParms =
-{
- parm2 = 100; // self.health
- parm3 = 0; // self.armorvalue
- parm5 = 0; // self.ammo_nails
- parm6 = 0; // self.ammo_rockets
- parm7 = 0; // self.ammo_cells
- parm9 = 0; // self.armortype * 100
-
-// "reset_items 2" makes the player start with only the axe -- iw
- if (world.reset_items == 2)
- {
- parm1 = IT_AXE; // self.items
- parm4 = 0; // self.ammo_shells
- parm8 = IT_AXE; // self.weapon
- }
- else
- {
- parm1 = IT_AXE | IT_SHOTGUN; // self.items
- parm4 = 25; // self.ammo_shells
- parm8 = IT_SHOTGUN; // self.weapon
- }
-};
-
-void() DecodeLevelParms =
-{
-// Reset the player's inventory if they returned to the start map with
-// a rune, or if the mapper set the "reset_items" field of worldspawn to
-// a non-zero value. (The old "reset_items" check, which this replaces,
-// had a comment from dumptruck_ds thanking Spike.) -- iw
-//
- if ((serverflags != 0 && world.model == "maps/start.bsp") ||
- world.reset_items != 0)
- {
- SetNewParms ();
- }
-
- self.items = parm1;
- self.health = parm2;
- self.armorvalue = parm3;
- self.ammo_shells = parm4;
- self.ammo_nails = parm5;
- self.ammo_rockets = parm6;
- self.ammo_cells = parm7;
- self.weapon = parm8;
- self.armortype = parm9 * 0.01;
-};
-
-void(entity client, string savename) autosave =
-{
- //autosavename = savename;
- stuffcmd(client, "echo Autosaving...; wait; save ");
- stuffcmd(client, savename);
- stuffcmd(client, "\n");
-}
-
-/*
-=============================================================================
-
- PLAYER GAME EDGE FUNCTIONS
-
-=============================================================================
-*/
-
-void() set_suicide_frame;
-
-// called by ClientKill and DeadThink
-void() respawn =
-{
- if (coop)
- {
- // make a copy of the dead body for appearances sake
- CopyToBodyQue (self);
- // get the spawn parms as they were at level start
- setspawnparms (self);
- // respawn
- PutClientInServer ();
- }
- else if (deathmatch)
- {
- // make a copy of the dead body for appearances sake
- CopyToBodyQue (self);
- // set default spawn parms
- SetNewParms ();
- // respawn
- PutClientInServer ();
- }
- else
- { // restart the entire server
- localcmd ("restart\n");
- }
-};
-
-
-/*
-============
-ClientKill
-
-Player entered the suicide command
-============
-*/
-void() ClientKill =
-
-{
- // 1998-07-27 Suicide during intermission fix by Zhenga start
- if ((intermission_running)&&((coop)||(deathmatch))) // not allowed during intermission
- return;
-// 1998-07-27 Suicide during intermission fix by Zhenga end
- bprint (self.netname);
- bprint (" suicides\n");
- set_suicide_frame ();
- self.modelindex = modelindex_player;
- self.frags = self.frags - 2; // extra penalty
- respawn ();
-};
-
-float(vector v) CheckSpawnPoint =
-{
- return FALSE;
-};
-
-/*
-============
-SelectSpawnPoint
-
-Returns the entity to spawn at
-============
-*/
-entity() SelectSpawnPoint =
-{
- local entity spot;
- local entity thing;
- local float pcount;
-
-// testinfo_player_start is only found in regioned levels
- spot = find (world, classname, "testplayerstart");
- if (spot)
- return spot;
-
-// choose a info_player_deathmatch point
- if (coop)
- {
- lastspawn = find(lastspawn, classname, "info_player_coop");
- if (lastspawn == world)
- lastspawn = find (lastspawn, classname, "info_player_start");
- if (lastspawn != world)
- return lastspawn;
- }
- else if (deathmatch)
- {
- 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, 32);
- while(thing)
- {
- if (thing.classname == "player")
- pcount = pcount + 1;
- thing = thing.chain;
- }
- if (pcount == 0)
- {
- lastspawn = spot;
- return spot;
- }
- }
- }
- }
-
- if (serverflags)
- { // return with a rune to start
- spot = find (world, classname, "info_player_start2");
- if (spot)
- return spot;
- }
-
- spot = find (world, classname, "info_player_start");
- if (!spot)
- error ("PutClientInServer: no info_player_start on level");
-
- return spot;
-};
-
-/*
-===========
-PutClientInServer
-
-called each time a player is spawned
-============
-*/
-void() DecodeLevelParms;
-void() PlayerDie;
-void() monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
-void() PutClientInServer =
-{
- local entity spot;
-
- spot = SelectSpawnPoint ();
-
- self.classname = "player";
- self.health = 100;
- self.takedamage = DAMAGE_AIM;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_WALK;
- self.show_hostile = 0;
- self.max_health = 100;
- self.flags = FL_CLIENT;
- self.air_finished = time + 12;
- self.dmg = 2; // initial water damage
- self.super_damage_finished = 0;
- self.radsuit_finished = 0;
- self.invisible_finished = 0;
- self.invincible_finished = 0;
- self.effects = 0;
- self.invincible_time = 0;
- self.deathtype = "";
- self.gravity = 0;
- self.wantedgravity = 0;
- self.onladder = 0;
- self.customkeys = 0; // support for item_key_custom -- iw
-
- // Setup cutscene stuff. Legacy code from Zerstorer. --dumptruck_ds
- self.script_count = 2;
- self.script_delay = 1;
- self.script_time = 0;
-
-
- DecodeLevelParms ();
-
- W_SetCurrentAmmo ();
-
- self.attack_finished = time;
- self.th_pain = player_pain;
- self.th_die = PlayerDie;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.deadflag = DEAD_NO;
-// paustime is set by teleporters to keep the player from moving a while
- self.pausetime = 0;
-
-// spot = SelectSpawnPoint ();
-
- self.origin = spot.origin + '0 0 1';
- self.angles = spot.angles;
- self.fixangle = TRUE; // turn this way immediately
-
- // fog control.
- // Looks if there's any fog values set at the current spawn point. If not, looks for those in worldspawn instead
- if (spot.fog_density)
- fog_save(self, spot.fog_density, spot.fog_color);
- else if (world.fog_density)
- fog_save(self, world.fog_density, world.fog_color);
-
- if (spot.skyfog_density)
- skyfog_save(self, spot.skyfog_density);
- else if (world.skyfog_density)
- skyfog_save(self, world.skyfog_density);
-
- cleanUpClientStuff = 2; // decreased on subsequent frames, used to startup some fog-related stuff
-
-// oh, this is a hack!
- setmodel (self, "progs/eyes.mdl");
- modelindex_eyes = self.modelindex;
-
- setmodel (self, "progs/s_null.spr"); // Drake -- dumptruck_ds
- // setmodel (self, "progs/null_256.spr"); // Drake -- dumptruck_ds
- mindex_inviso = self.modelindex;
-
- setmodel (self, "progs/player.mdl");
- modelindex_player = self.modelindex;
-
- setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
-
- 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'; // 1998-07-21 Player moves after respawn fix by Xian
-
- player_stand1 ();
-
- if (deathmatch || coop)
- {
- makevectors(self.angles);
- spawn_tfog (self.origin + v_forward*20);
- }
-
- spawn_tdeath (self.origin, self);
-};
-
-
-/*
-=============================================================================
-
- QUAKED FUNCTIONS
-
-=============================================================================
-*/
-
-
-/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-The normal starting point for a level.
-*/
-void() info_player_start =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-Only used on start map for the return point from an episode.
-*/
-void() info_player_start2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-/*
-saved out by quaked in region mode
-*/
-void() testplayerstart =
-{
-};
-
-/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-potential spawning position for deathmatch games
-*/
-void() info_player_deathmatch =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/player.mdl");
-}
-potential spawning position for coop games
-*/
-void() info_player_coop =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*QUAKED info_monster_spawnpoint (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/teleport.mdl");
-}
- spawning position for func_monster_spawner
-*/
-void() info_monster_spawnpoint =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-/*
-===============================================================================
-
-RULES
-
-===============================================================================
-*/
-
-/*
-go to the next level for deathmatch
-only called if a time or frag limit has expired
-*/
-void() NextLevel =
-{
- local entity o;
-
- if (mapname == "start")
- {
- if (!cvar("registered"))
- {
- mapname = "e1m1";
- }
- else if (!(serverflags & 1))
- {
- mapname = "e1m1";
- serverflags = serverflags | 1;
- }
- else if (!(serverflags & 2))
- {
- mapname = "e2m1";
- serverflags = serverflags | 2;
- }
- else if (!(serverflags & 4))
- {
- mapname = "e3m1";
- serverflags = serverflags | 4;
- }
- else if (!(serverflags & 8))
- {
- mapname = "e4m1";
- serverflags = serverflags - 7;
- }
-
- o = spawn();
- o.map = mapname;
- }
- else
- {
- // find a trigger changelevel
- o = find(world, classname, "trigger_changelevel");
-
- // go back to start if no trigger_changelevel
- if (!o)
- {
- mapname = "start";
- o = spawn();
- o.map = mapname;
- }
- }
-
- nextmap = o.map;
- gameover = TRUE;
-
- if (o.nextthink < time)
- {
- o.think = execute_changelevel;
- o.nextthink = time + 0.1;
- }
-};
-
-/*
-============
-CheckRules
-
-Exit deathmatch games upon conditions
-============
-*/
-void() CheckRules =
-{
- local float timelimit;
- local float fraglimit;
-
- if (gameover) // someone else quit the game already
- return;
-
- timelimit = cvar("timelimit") * 60;
- fraglimit = cvar("fraglimit");
-
-if (deathmatch && timelimit && time >= timelimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
- {
- NextLevel ();
- return;
- }
-
-if (deathmatch && fraglimit && self.frags >= fraglimit) // 1998-07-27 Timelimit/Fraglimit fix by Maddes
- {
- NextLevel ();
- return;
- }
-};
-
-//============================================================================
-
-void() PlayerDeathThink =
-{
- local float forward;
-
- if ((self.flags & FL_ONGROUND))
- {
- forward = vlen (self.velocity);
- forward = forward - 20;
- if (forward <= 0)
- self.velocity = '0 0 0';
- else
- self.velocity = forward * normalize(self.velocity);
- }
-
-// wait for all buttons released
- if (self.deadflag == DEAD_DEAD)
- {
- if (self.button2 || self.button1 || self.button0)
- return;
- self.deadflag = DEAD_RESPAWNABLE;
- return;
- }
-
-// wait for any button down
- if (!self.button2 && !self.button1 && !self.button0)
- return;
-
- self.button0 = 0;
- self.button1 = 0;
- self.button2 = 0;
- respawn();
-};
-
-/*
-===========
-PlayerClimb
-============
-*/
-void() PlayerClimb = //johnfitz
-{
- self.velocity = '0 0 160';
-}
-
-
-void() PlayerJump =
-{
-
- if (self.flags & FL_WATERJUMP)
- return;
-
- if (self.waterlevel >= 2)
- {
- if (self.watertype == CONTENT_WATER)
- self.velocity_z = 100;
- else if (self.watertype == CONTENT_SLIME)
- self.velocity_z = 80;
- else
- self.velocity_z = 50;
-
-// play swiming sound
- if (self.swim_flag < time)
- {
- self.swim_flag = time + 1;
- if (random() < 0.5)
- sound (self, CHAN_BODY, "misc/water1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_BODY, "misc/water2.wav", 1, ATTN_NORM);
- }
-
- return;
- }
-
- // refactoring from Copper -- dumptruck_ds
- if (self.movetype != MOVETYPE_NOCLIP)
- {
- if (!(self.flags & FL_ONGROUND)) return;
- if ( !(self.flags & FL_JUMPRELEASED) ) return; // don't pogo stick
- // player jumping sound
- sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM); // h00rt
- }
-
- // if (!(self.flags & FL_ONGROUND))
- // return;
- //
- // if ( !(self.flags & FL_JUMPRELEASED) )
- // return; // don't pogo stick
- // refactoring from Copper -- dumptruck_ds
- // self.flags = not(self.flags, FL_JUMPRELEASED | FL_ONGROUND); // don't stairwalk
-
- self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
-
- self.flags = self.flags - FL_ONGROUND; // don't stairwalk
-
- self.button2 = 0;
- // sound (self, CHAN_AUTO, "player/plyrjmp8.wav", 1, ATTN_NORM);
- self.velocity_z = self.velocity_z + 270;
-};
-
-
-/*
-===========
-WaterMove
-
-============
-*/
-.float dmgtime;
-
-void() WaterMove =
-{
-//dprint (ftos(self.waterlevel));
- // if (self.movetype == MOVETYPE_NOCLIP)
- // return;
- //from Copper -- dumptruck_ds
- if (self.movetype == MOVETYPE_NOCLIP)
- {
- self.air_finished = time + 120;
- return;
- }
-
- if (self.health < 0)
- return;
-
- if (self.waterlevel != 3)
- {
- if (self.air_finished < time)
- sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
- else if (self.air_finished < time + 9)
- sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
- self.air_finished = time + 12;
- self.dmg = 2;
- }
- else if (self.air_finished < time)
- { // drown!
- if (self.pain_finished < time)
- {
- self.dmg = self.dmg + 2;
- if (self.dmg > 15)
- self.dmg = 10;
- self.deathtype = "drowning";
- T_Damage (self, world, world, self.dmg);
- self.deathtype = "";
- self.pain_finished = time + 1;
- }
- }
-
- if (!self.waterlevel)
- {
- if (self.flags & FL_INWATER)
- {
- // play leave water sound
- sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
- self.flags = self.flags - FL_INWATER;
- }
- return;
- }
-
- if (self.watertype == CONTENT_LAVA)
- { // do damage
- if (self.dmgtime < time)
- {
- if (self.radsuit_finished > time)
- self.dmgtime = time + 1;
- else
- self.dmgtime = time + 0.2;
-
- self.deathtype = "lava";
- T_Damage (self, world, world, 10*self.waterlevel);
- self.deathtype = "";
- }
- }
- else if (self.watertype == CONTENT_SLIME)
- { // do damage
- if (self.dmgtime < time && self.radsuit_finished < time)
- {
- self.dmgtime = time + 1;
- self.deathtype = "slime";
- T_Damage (self, world, world, 4*self.waterlevel);
- self.deathtype = "";
- }
- }
-
- if ( !(self.flags & FL_INWATER) )
- {
-
-// player enter water sound
-
- if (self.watertype == CONTENT_LAVA)
- sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
- if (self.watertype == CONTENT_WATER)
- sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
- if (self.watertype == CONTENT_SLIME)
- sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
-
- self.flags = self.flags + FL_INWATER;
- self.dmgtime = 0;
- }
-
- if (! (self.flags & FL_WATERJUMP) )
- self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity;
-};
-
-void() CheckWaterJump =
-{
- if (self.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return;
-
- local vector start, end;
-
-// check for a jump-out-of-water
- makevectors (self.angles);
- start = self.origin;
- start_z = start_z + 8;
- v_forward_z = 0;
- normalize(v_forward);
- end = start + v_forward*24;
- traceline (start, end, TRUE, self);
- if (trace_fraction < 1)
- { // solid at waist
- start_z = start_z + self.maxs_z - 8;
- end = start + v_forward*24;
- self.movedir = trace_plane_normal * -50;
- traceline (start, end, TRUE, self);
- if (trace_fraction == 1)
- { // open at eye level
- self.flags = self.flags | FL_WATERJUMP;
- self.velocity_z = 225;
- self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
- self.teleport_time = time + 2; // safety net
- return;
- }
- }
-};
-
-
-/*
-================
-PlayerPreThink
-
-Called every frame before physics are run
-================
-*/
-void() PlayerPreThink =
-{
- local float do_ladder_physics;
-
- if (intermission_running)
- {
- IntermissionThink (); // otherwise a button could be missed between
- return; // the think tics
- }
-
- if (self.view_ofs == '0 0 0')
- {
- Cutscene_Think (); // Check for cutscene stuff.
- return; // intermission or finale
- }
-
- // note that this code block is here, before the tests which check
- // whether the player is dead, so that the player's gravity will be
- // correctly updated even if they e.g. fell off a ladder because
- // they died -- iw
- if (self.onladder)
- {
- do_ladder_physics = TRUE;
- self.gravity = 0.0000001; // not zero, because zero means "default"
- self.onladder = 0;
- }
- else
- {
- do_ladder_physics = FALSE;
- self.gravity = self.wantedgravity;
- }
-
- // If just spawned in, try to recover previous fog values from own client entity, if any
- if (cleanUpClientStuff)
- fog_setFromEnt(self, self);
-
- makevectors (self.v_angle); // is this still used
-
- CheckRules ();
- WaterMove ();
-
- if (self.waterlevel == 2)
- CheckWaterJump ();
-
- if (self.deadflag >= DEAD_DEAD)
- {
- PlayerDeathThink ();
- return;
- }
-
- if (self.deadflag == DEAD_DYING)
- return; // dying, so do nothing
-
-//johnfitz ladder conditions //added from Rubicon2 client.qc -- dumptruck_ds
-if (do_ladder_physics)
-{
- if (self.button2)
- {
- PlayerClimb ();
-
- /* no ladder footsteps for now
- if (time > self.ladder_step_finished) {
- r = random();
- if (r > 0.66)
- sound (self, CHAN_BODY, "ladder/metal1.wav", 0.5, ATTN_NORM);
- else if (r > 0.33)
- sound (self, CHAN_BODY, "ladder/metal2.wav", 0.5, ATTN_NORM);
- else
- sound (self, CHAN_BODY, "ladder/metal3.wav", 0.5, ATTN_NORM);
- self.ladder_step_finished = time + 0.3;
- }
- */
- }
- else
- {
- self.flags = self.flags | FL_JUMPRELEASED;
- self.velocity = 0.9 * self.velocity;
- self.velocity_z = 0;
- }
-}
-else
-{
- if (self.button2)
- PlayerJump ();
- else
- self.flags = self.flags | FL_JUMPRELEASED;
-} //johnfitz
-
-// teleporters can force a non-moving pause time
- if (time < self.pausetime)
- self.velocity = '0 0 0';
-
- if(time > self.attack_finished && self.currentammo == 0 && self.weapon != IT_AXE)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- }
- // from copper -- dumptruck_ds
- if (self.movetype == MOVETYPE_NOCLIP)
- {
- self.flags = self.flags | FL_FLY;
- }
-};
-
-/*
-================
-CheckPowerups
-
-Check for turning off powerups
-================
-*/
-void() CheckPowerups =
-{
- if (self.health <= 0)
- return;
-
-// invisibility
- if (self.invisible_finished)
- {
-// sound and screen flash when items starts to run out
- if (self.invisible_sound < time)
- {
- sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE);
- self.invisible_sound = time + ((random() * 3) + 1);
- }
-
-
- if (self.invisible_finished < time + 3)
- {
- if (self.invisible_time == 1)
- {
- sprint (self, "Ring of Shadows magic is fading\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM);
- self.invisible_time = time + 1;
- }
-
- if (self.invisible_time < time)
- {
- self.invisible_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.invisible_finished < time)
- { // just stopped
- self.items = self.items - IT_INVISIBILITY;
- self.invisible_finished = 0;
- self.invisible_time = 0;
- }
-
- // use the eyes
- self.frame = 0;
- self.modelindex = modelindex_eyes;
- }
- else
- self.modelindex = modelindex_player; // don't use eyes
-
-// invincibility
- if (self.invincible_finished)
- {
-// sound and screen flash when items starts to run out
- if (self.invincible_finished < time + 3)
- {
- if (self.invincible_time == 1)
- {
- sprint (self, "Protection is almost burned out\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM);
- self.invincible_time = time + 1;
- }
-
- if (self.invincible_time < time)
- {
- self.invincible_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.invincible_finished < time)
- { // just stopped
- self.items = self.items - IT_INVULNERABILITY;
- self.invincible_time = 0;
- self.invincible_finished = 0;
- }
- if (self.invincible_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- }
-
-// super damage
- if (self.super_damage_finished)
- {
-
-// sound and screen flash when items starts to run out
-
- if (self.super_damage_finished < time + 3)
- {
- if (self.super_time == 1)
- {
- sprint (self, "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;
- }
-
- if (self.super_time < time)
- {
- self.super_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.super_damage_finished < time)
- { // just stopped
- self.items = self.items - IT_QUAD;
- self.super_damage_finished = 0;
- self.super_time = 0;
- }
- if (self.super_damage_finished > time)
- self.effects = self.effects | EF_DIMLIGHT;
- else
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- }
-
-// suit
- if (self.radsuit_finished)
- {
- self.air_finished = time + 12; // don't drown
-
-// sound and screen flash when items starts to run out
- if (self.radsuit_finished < time + 3)
- {
- if (self.rad_time == 1)
- {
- sprint (self, "Air supply in Biosuit expiring\n");
- stuffcmd (self, "bf\n");
- sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
- self.rad_time = time + 1;
- }
-
- if (self.rad_time < time)
- {
- self.rad_time = time + 1;
- stuffcmd (self, "bf\n");
- }
- }
-
- if (self.radsuit_finished < time)
- { // just stopped
- self.items = self.items - IT_SUIT;
- self.rad_time = 0;
- self.radsuit_finished = 0;
- }
- }
-};
-
-/*
-================
-PlayerPostThink
-
-Called every frame after physics are run
-================
-*/
-void() PlayerPostThink =
-{
-
- if (self.view_ofs == '0 0 0')
- return; // intermission or finale
- if (self.deadflag)
- return;
-
-// do weapon stuff
-
- W_WeaponFrame ();
-
-// check to see if player landed and play landing sound
- if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) && (self.health > 0))
- {
- if (self.watertype == CONTENT_WATER)
- 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);
- self.deathtype = "";
- sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
- }
- else
- sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
-
- self.jump_flag = 0;
- }
-
- if (!(self.flags & FL_ONGROUND))
- self.jump_flag = self.velocity_z;
-
- if (self.health > self.max_health) //dumptruck_ds -- this replaces item_megahealth_rot in items.qc
-
- {
- if (self.megahealth_rottime < time)
- {
- self.megahealth_rottime = time + 1;
- self.health = self.health - 1;
- }
-
- else if (self.health <= 100) //thanks ydrol!!!
- self.items = self.items - (self.items & IT_SUPERHEALTH);
-}
-
-CheckPowerups ();
-// from Copper -- dumptruck_ds
-if (self.movetype != MOVETYPE_NOCLIP)
-{
- self.flags = not(self.flags, FL_FLY);
-}
-
-};
-
-
-/*
-===========
-ClientConnect
-
-called when a player connects to a server
-============
-*/
-void() ClientConnect =
-{
- bprint (self.netname);
- bprint (" entered the game\n");
-
-// a client connecting during an intermission can cause problems
- if (intermission_running)
- ExitIntermission ();
-};
-
-
-/*
-===========
-ClientDisconnect
-
-called when a player disconnects from a server
-============
-*/
-void() ClientDisconnect =
-{
- if (gameover)
- return;
- // if the level end trigger has been activated, just return
- // since they aren't *really* leaving
-
- // let everyone else know
- bprint (self.netname);
- bprint (" left the game with ");
- bprint (ftos(self.frags));
- bprint (" frags\n");
- sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
- set_suicide_frame ();
-};
-
-/*
-===========
-ClientObituary
-
-called when a player dies
-============
-*/
-void(entity targ, entity inflictor, entity attacker) ClientObituary =
-{
- local float rnum;
- local string deathstring, deathstring2;
- rnum = random();
-
- if (targ.classname == "player")
- {
- if (attacker.classname == "teledeath")
- {
- bprint (targ.netname);
- bprint (" was telefragged by ");
- bprint (attacker.owner.netname);
- bprint ("\n");
-
- attacker.owner.frags = attacker.owner.frags + 1;
- return;
- }
-
- if (attacker.classname == "teledeath2")
- {
- bprint ("Satan's power deflects ");
- bprint (targ.netname);
- bprint ("'s telefrag\n");
-
- targ.frags = targ.frags - 1;
- return;
- }
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- // double 666 telefrag
- // (can happen often in deathmatch 4 and levels with more than one pentagram)
- if (attacker.classname == "teledeath3")
- {
- bprint (targ.netname);
- bprint (" was telefragged by ");
- bprint (attacker.owner.netname);
- bprint ("'s Satan's power\n");
-// 1998-07-26 only telefrag player on spot by Maddes start
-// targ.frags = targ.frags - 1;
- attacker.owner.frags = attacker.owner.frags + 1;
-// 1998-07-26 only telefrag player on spot by Maddes end
- return;
- }
-// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
- if (attacker.classname == "player")
- {
- if (targ == attacker)
- {
- // killed self
- attacker.frags = attacker.frags - 1;
- bprint (targ.netname);
-
- if (targ.weapon == 64 && targ.waterlevel > 1)
- {
- bprint (" discharges into the water.\n");
- return;
- }
- if (targ.weapon == IT_GRENADE_LAUNCHER)
- bprint (" tries to put the pin back in\n");
- else
- bprint (" becomes bored with life\n");
- return;
- }
- else if ( (teamplay == 2) && (targ.team > 0)&&(targ.team == attacker.team) )
- {
- if (rnum < 0.25)
- deathstring = " mows down a teammate\n";
- else if (rnum < 0.50)
- deathstring = " checks his glasses\n";
- else if (rnum < 0.75)
- deathstring = " gets a frag for the other team\n";
- else
- deathstring = " loses another friend\n";
- bprint (attacker.netname);
- bprint (deathstring);
- attacker.frags = attacker.frags - 1;
- return;
- }
- else
- {
- 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)
- {
- deathstring = " was nailed by ";
- deathstring2 = "\n";
- }
- if (rnum == IT_SUPER_NAILGUN)
- {
- deathstring = " was punctured by ";
- deathstring2 = "\n";
- }
- if (rnum == IT_GRENADE_LAUNCHER)
- {
- deathstring = " eats ";
- deathstring2 = "'s pineapple\n";
- if (targ.health < -40)
- {
- deathstring = " was gibbed by ";
- deathstring2 = "'s grenade\n";
- }
- }
- if (rnum == IT_ROCKET_LAUNCHER)
- {
- deathstring = " rides ";
- deathstring2 = "'s rocket\n";
- if (targ.health < -40)
- {
- deathstring = " was gibbed by ";
- deathstring2 = "'s rocket\n" ;
- }
- }
- if (rnum == IT_LIGHTNING)
- {
- deathstring = " accepts ";
- if (attacker.waterlevel > 1)
- deathstring2 = "'s discharge\n";
- else
- deathstring2 = "'s shaft\n";
- }
- bprint (targ.netname);
- bprint (deathstring);
- bprint (attacker.netname);
- bprint (deathstring2);
- }
- return;
- }
- else
- {
- targ.frags = targ.frags - 1;
- bprint (targ.netname);
-
- // custom obituary messages
- if (inflictor.deathtype != "")
- {
- bprint (" ");
- bprint (inflictor.deathtype);
- bprint ("\n");
- return;
- }
- if (attacker.deathtype != "")
- {
- bprint (" ");
- bprint (attacker.deathtype);
- bprint ("\n");
- return;
- }
-
- // killed by a montser?
- // if (attacker.flags & FL_MONSTER)
- if ((attacker.flags & FL_MONSTER) && (attacker.obit_name == ""))
- {
- if (attacker.classname == "monster_army")
- bprint (" was shot by a Grunt\n");
- if (attacker.classname == "monster_demon1")
- bprint (" was eviscerated by a Fiend\n");
- if (attacker.classname == "monster_dog")
- bprint (" was mauled by a Rottweiler\n");
- if (attacker.classname == "monster_dragon")
- bprint (" was fried by a Dragon\n");
- if (attacker.classname == "monster_enforcer")
- bprint (" was blasted by an Enforcer\n");
- if (attacker.classname == "monster_fish")
- bprint (" was fed to the Rotfish\n");
- if (attacker.classname == "monster_hell_knight")
- bprint (" was slain by a Death Knight\n");
- if (attacker.classname == "monster_knight")
- bprint (" was slashed by a Knight\n");
- if (attacker.classname == "monster_ogre")
- bprint (" was destroyed by an Ogre\n");
- if (attacker.classname == "monster_ogre_marksman")
- bprint (" was felled by a Marksman\n"); // dumptruck_ds
- if (attacker.classname == "monster_oldone")
- bprint (" became one with Shub-Niggurath\n");
- if (attacker.classname == "monster_oldone2")// dumptruck_ds
- bprint (" became one with Shub-Niggurath\n");
- if (attacker.classname == "monster_boss2")// dumptruck_ds
- bprint (" was exploded by Chthon\n");
- if (attacker.classname == "monster_boss")// dumptruck_ds
- bprint (" was exploded by Chthon\n");
- if (attacker.classname == "monster_shalrath")
- bprint (" was exploded by a Vore\n");
- if (attacker.classname == "monster_shambler")
- bprint (" was smashed by a Shambler\n");
- if (attacker.classname == "monster_vomit")
- bprint (" was vomited on by a Vomitus\n");
- if (attacker.classname == "monster_wizard")
- bprint (" was scragged by a Scrag\n");
- if (attacker.classname == "monster_zombie")
- bprint (" joins the Zombies\n");
-
- return;
- }
- // obits for custom monsters -- progs_dump -- dumptruck_ds
- if (attacker.obit_name != "")
- {
- bprint (" was ");
- if !(attacker.obit_method)
- bprint ("killed");
- else
- bprint (attacker.obit_method); // e.g. ripped apart
- bprint (" by ");
- bprint (attacker.obit_name); // a bad monster
- bprint ("\n");
- return;
- }
-
- // tricks and traps
- if (attacker.classname == "explo_box" ||
- attacker.classname == "play_explosion")
- {
- bprint (" blew up\n");
- return;
- }
- if (attacker.classname == "func_laser")
- {
- bprint (" discovered that lasers are hot\n");
- return;
- }
- if ((attacker.solid == SOLID_BSP &&
- attacker != world &&
- attacker.classname != "togglewall") ||
- (inflictor.classname == "func_movewall" &&
- !(inflictor.spawnflags & MOVEWALL_TOUCH)))
- {
- bprint (" was squished\n");
- return;
- }
- if (attacker.classname == "trap_shooter" ||
- attacker.classname == "trap_spikeshooter" ||
- attacker.classname == "trap_switched_shooter")
- {
- // bprint (" was spiked\n");
- bprint (" was unlucky\n"); //changed for custom shooters --dumptruck_ds
- return;
- }
- if (attacker.classname == "ltrail_start" ||
- attacker.classname == "ltrail_relay")
- {
- bprint (" had an electrifying experience\n");
- return;
- }
- if (attacker.classname == "fireball")
- {
- bprint (" ate a lavaball\n");
- return;
- }
- if (attacker.classname == "trigger_changelevel")
- {
- bprint (" tried to leave\n");
- return;
- }
-
- // in-liquid deaths
- if (targ.deathtype == "drowning")
- {
- if (random() < 0.5)
- bprint (" sleeps with the fishes\n");
- else
- bprint (" sucks it down\n");
- return;
- }
- if (targ.deathtype == "slime")
- {
- if (random() < 0.5)
- bprint (" gulped a load of slime\n");
- else
- bprint (" can't exist on slime alone\n");
- return;
- }
- if (targ.deathtype == "lava")
- {
- if (targ.health < -15)
- {
- bprint (" burst into flames\n");
- return;
- }
- if (random() < 0.5)
- bprint (" turned into hot slag\n");
- else
- bprint (" visits the Volcano God\n");
- return;
- }
-
- // fell to their death?
- if (targ.deathtype == "falling")
- {
- bprint (" fell to his death\n");
- return;
- }
-
- // hell if I know; he's just dead!!!
- bprint (" died\n");
- }
- }
-};
+/*==============================================================================
+ CLIENT.QC
+==============================================================================*/
+
+// prototypes
+void () W_WeaponFrame;
+void() W_SetCurrentAmmo;
+void(entity attacker, float damage) player_pain;
+void() player_stand1;
+//void (vector org) spawn_tfog; //moved to items.qc -- dumptruck_ds
+void (vector org, entity death_owner) spawn_tdeath;
+
+float modelindex_eyes, modelindex_player;
+void() SUB_CheckWaiting; // in triggers.qc
+
+void() SetChangeParms =
+{
+ if (self.health <= 0)
+ {
+ SetNewParms ();
+ return;
+ }
+
+ // remove items
+ self.items = self.items - (self.items &
+ (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY
+ | IT_SUIT | IT_QUAD)
+ );
+
+ // cap super health
+ if (self.health > 100)
+ self.health = 100;
+ if (self.health < 50)
+ self.health = 50;
+ parm1 = self.items;
+ parm2 = self.health;
+ parm3 = self.armorvalue;
+ if (self.ammo_shells < 25)
+ parm4 = 25;
+ else
+ parm4 = self.ammo_shells;
+ parm5 = self.ammo_nails;
+ parm6 = self.ammo_rockets;
+ parm7 = self.ammo_cells;
+ parm8 = self.weapon;
+ parm9 = self.armortype * 100;
+};
+
+void() SetNewParms =
+{
+ parm2 = 100; // self.health
+ parm3 = 0; // self.armorvalue
+ parm5 = 0; // self.ammo_nails
+ parm6 = 0; // self.ammo_rockets
+ parm7 = 0; // self.ammo_cells
+ parm9 = 0; // self.armortype * 100
+
+ // "reset_items 2" makes the player start with only the axe -- iw
+ if (world.reset_items == 2)
+ {
+ parm1 = IT_AXE; // self.items
+ parm4 = 0; // self.ammo_shells
+ parm8 = IT_AXE; // self.weapon
+ }
+ else
+ {
+ parm1 = IT_AXE | IT_SHOTGUN; // self.items
+ parm4 = 25; // self.ammo_shells
+ parm8 = IT_SHOTGUN; // self.weapon
+ }
+};
+
+void() DecodeLevelParms =
+{
+ // Reset the player's inventory if they returned to the start map
+ // with a rune, or if the mapper set the "reset_items" field of
+ // worldspawn to a non-zero value. (The old "reset_items" check,
+ // which this replaces, had a comment from dumptruck_ds thanking
+ // Spike.) -- iw
+ if ((serverflags != 0 && world.model == "maps/start.bsp") ||
+ world.reset_items != 0)
+ {
+ SetNewParms ();
+ }
+
+ self.items = parm1;
+ self.health = parm2;
+ self.armorvalue = parm3;
+ self.ammo_shells = parm4;
+ self.ammo_nails = parm5;
+ self.ammo_rockets = parm6;
+ self.ammo_cells = parm7;
+ self.weapon = parm8;
+ self.armortype = parm9 * 0.01;
+};
+
+void(entity client, string savename) autosave =
+{
+ //autosavename = savename;
+ stuffcmd(client, "echo Autosaving...; wait; save ");
+ stuffcmd(client, savename);
+ stuffcmd(client, "\n");
+}
+
+/*==============================================================================
+ PLAYER GAME EDGE FUNCTIONS
+==============================================================================*/
+
+void() set_suicide_frame;
+
+// called by ClientKill and DeadThink
+void() respawn =
+{
+ if (coop)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // get the spawn parms as they were at level start
+ setspawnparms (self);
+ // respawn
+ PutClientInServer ();
+ }
+ else if (deathmatch)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // set default spawn parms
+ SetNewParms ();
+ // respawn
+ PutClientInServer ();
+ }
+ else
+ { // restart the entire server
+ localcmd ("restart\n");
+ }
+};
+
+//======================================================================
+// ClientKill
+// Player entered the suicide command
+//======================================================================
+void() ClientKill =
+{
+ // 1998-07-27 Suicide during intermission fix by Zhenga start
+ // not allowed during intermission
+ if ((intermission_running) && ((coop) || (deathmatch)))
+ return;
+ // 1998-07-27 Suicide during intermission fix by Zhenga end
+ bprint (self.netname);
+ bprint (" suicides\n");
+ set_suicide_frame ();
+ self.modelindex = modelindex_player;
+ // extra penalty
+ self.frags = self.frags - 2;
+ respawn ();
+};
+
+float(vector v) CheckSpawnPoint =
+{
+ return FALSE;
+};
+
+//======================================================================
+// SelectSpawnPoint
+// Returns the entity to spawn at
+//======================================================================
+entity() SelectSpawnPoint =
+{
+ local entity spot;
+ local entity thing;
+ local float pcount;
+
+ // testinfo_player_start is only found in regioned levels
+ spot = find (world, classname, "testplayerstart");
+ if (spot) return spot;
+
+ // choose a info_player_deathmatch point
+ if (coop)
+ {
+ lastspawn = find (lastspawn, classname, "info_player_coop");
+ if (lastspawn == world)
+ lastspawn = find (lastspawn, classname,
+ "info_player_start");
+ if (lastspawn != world) return lastspawn;
+ }
+ else if (deathmatch)
+ {
+ 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, 32);
+ while (thing)
+ {
+ if (thing.classname == "player")
+ pcount = pcount + 1;
+ thing = thing.chain;
+ }
+ if (pcount == 0)
+ {
+ lastspawn = spot;
+ return spot;
+ }
+ }
+ }
+ }
+
+ if (serverflags)
+ {
+ // return with a rune to start
+ spot = find (world, classname, "info_player_start2");
+ if (spot) return spot;
+ }
+
+ spot = find (world, classname, "info_player_start");
+ if (!spot)
+ error ("PutClientInServer: no info_player_start on level");
+
+ return spot;
+};
+
+//======================================================================
+// PutClientInServer
+// called each time a player is spawned
+//======================================================================
+void() DecodeLevelParms;
+void() PlayerDie;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+void() monster_touch;
+
+void() PutClientInServer =
+{
+ local entity spot;
+
+ spot = SelectSpawnPoint ();
+
+ self.classname = "player";
+ self.health = 100;
+ self.takedamage = DAMAGE_AIM;
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_WALK;
+ self.show_hostile = 0;
+ self.max_health = 100;
+ self.flags = FL_CLIENT;
+ self.air_finished = time + 12;
+ self.dmg = 2; // initial water damage
+ self.super_damage_finished = 0;
+ self.radsuit_finished = 0;
+ self.invisible_finished = 0;
+ self.invincible_finished = 0;
+ self.effects = 0;
+ self.invincible_time = 0;
+ self.deathtype = "";
+ self.gravity = 0;
+ self.wantedgravity = 0;
+ self.onladder = 0;
+ self.customkeys = 0; // support for item_key_custom -- iw
+
+ // Setup cutscene stuff. Legacy code from Zerstorer. -- dumptruck_ds
+ self.script_count = 2;
+ self.script_delay = 1;
+ self.script_time = 0;
+
+ DecodeLevelParms ();
+
+ W_SetCurrentAmmo ();
+
+ self.attack_finished = time;
+ self.th_pain = player_pain;
+ self.th_die = PlayerDie;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix
+ // by Maddes/Kryten
+ self.touch = monster_touch;
+ self.deadflag = DEAD_NO;
+ // pausetime is set by teleporters to keep the player from moving
+ // for a while
+ self.pausetime = 0;
+
+ // spot = SelectSpawnPoint ();
+
+ self.origin = spot.origin + '0 0 1';
+ self.angles = spot.angles;
+ self.fixangle = TRUE; // turn this way immediately
+
+ // fog control.
+ // Looks if there's any fog values set at the current spawn point.
+ // If not, looks for those in worldspawn instead
+ if (spot.fog_density)
+ fog_save (self, spot.fog_density, spot.fog_color);
+ else if (world.fog_density)
+ fog_save (self, world.fog_density, world.fog_color);
+
+ if (spot.skyfog_density)
+ skyfog_save (self, spot.skyfog_density);
+ else if (world.skyfog_density)
+ skyfog_save (self, world.skyfog_density);
+
+ // decreased on subsequent frames, used to start some fog-related stuff
+ cleanUpClientStuff = 2;
+
+ // oh, this is a hack!
+ setmodel (self, "progs/eyes.mdl");
+ modelindex_eyes = self.modelindex;
+
+ // Drake -- dumptruck_ds
+ setmodel (self, "progs/s_null.spr");
+ // Drake -- dumptruck_ds
+ // setmodel (self, "progs/null_256.spr");
+ mindex_inviso = self.modelindex;
+
+ setmodel (self, "progs/player.mdl");
+ modelindex_player = self.modelindex;
+
+ setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
+
+ 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';
+ // 1998-07-21 Player moves after respawn fix by Xian
+
+ player_stand1 ();
+
+ if (deathmatch || coop)
+ {
+ makevectors (self.angles);
+ spawn_tfog (self.origin + v_forward*20);
+ }
+
+ spawn_tdeath (self.origin, self);
+};
+
+
+/*==============================================================================
+ QUAKED FUNCTIONS
+==============================================================================*/
+
+/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+The normal starting point for a level.
+*/
+void() info_player_start =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+};
+
+
+/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+Only used on start map for the return point from an episode.
+*/
+void() info_player_start2 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+};
+
+
+/*
+saved out by quaked in region mode
+*/
+void() testplayerstart =
+{
+};
+
+/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for deathmatch games
+*/
+void() info_player_deathmatch =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+};
+
+/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for coop games
+*/
+void() info_player_coop =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+};
+
+/*QUAKED info_monster_spawnpoint (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/teleport.mdl");
+}
+ spawning position for func_monster_spawner
+*/
+void() info_monster_spawnpoint =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+};
+
+/*==============================================================================
+ RULES
+==============================================================================*/
+
+// go to the next level for deathmatch
+// only called if a time or frag limit has expired
+void() NextLevel =
+{
+ local entity o;
+
+ if (mapname == "start")
+ {
+ if (!cvar ("registered"))
+ {
+ mapname = "e1m1";
+ }
+ else if (!(serverflags & 1))
+ {
+ mapname = "e1m1";
+ serverflags = serverflags | 1;
+ }
+ else if (!(serverflags & 2))
+ {
+ mapname = "e2m1";
+ serverflags = serverflags | 2;
+ }
+ else if (!(serverflags & 4))
+ {
+ mapname = "e3m1";
+ serverflags = serverflags | 4;
+ }
+ else if (!(serverflags & 8))
+ {
+ mapname = "e4m1";
+ serverflags = serverflags - 7;
+ }
+
+ o = spawn ();
+ o.map = mapname;
+ }
+ else
+ {
+ // find a trigger changelevel
+ o = find (world, classname, "trigger_changelevel");
+
+ // go back to start if no trigger_changelevel
+ if (!o)
+ {
+ mapname = "start";
+ o = spawn ();
+ o.map = mapname;
+ }
+ }
+
+ nextmap = o.map;
+ gameover = TRUE;
+
+ if (o.nextthink < time)
+ {
+ o.think = execute_changelevel;
+ o.nextthink = time + 0.1;
+ }
+};
+
+//======================================================================
+// CheckRules
+// Exit deathmatch games upon conditions
+//======================================================================
+void() CheckRules =
+{
+ local float timelimit;
+ local float fraglimit;
+
+ // someone else quit the game already
+ if (gameover) return;
+
+ timelimit = cvar ("timelimit") * 60;
+ fraglimit = cvar ("fraglimit");
+
+ // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ if (deathmatch && timelimit && time >= timelimit)
+ {
+ NextLevel ();
+ return;
+ }
+
+ // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ if (deathmatch && fraglimit && self.frags >= fraglimit)
+ {
+ NextLevel ();
+ return;
+ }
+};
+
+//======================================================================
+void() PlayerDeathThink =
+{
+ local float forward;
+
+ if ((self.flags & FL_ONGROUND))
+ {
+ forward = vlen (self.velocity);
+ forward = forward - 20;
+ if (forward <= 0)
+ self.velocity = '0 0 0';
+ else
+ self.velocity = forward * normalize (self.velocity);
+ }
+
+ // wait for all buttons released
+ if (self.deadflag == DEAD_DEAD)
+ {
+ if (self.button2 || self.button1 || self.button0)
+ return;
+ self.deadflag = DEAD_RESPAWNABLE;
+ return;
+ }
+
+ // wait for any button down
+ if (!self.button2 && !self.button1 && !self.button0)
+ return;
+
+ self.button0 = 0;
+ self.button1 = 0;
+ self.button2 = 0;
+ respawn ();
+};
+
+//======================================================================
+// PlayerClimb
+// johnfitz
+//======================================================================
+void() PlayerClimb =
+{
+ self.velocity = '0 0 160';
+}
+
+//======================================================================
+// WaterMove
+//======================================================================
+.float dmgtime;
+
+void() WaterMove =
+{
+ // dprint (ftos(self.waterlevel));
+ // if (self.movetype == MOVETYPE_NOCLIP)
+ // return;
+ // from Copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.air_finished = time + 120;
+ return;
+ }
+
+ if (self.health < 0)
+ return;
+
+ if (self.waterlevel != 3)
+ {
+ if (self.air_finished < time)
+ sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM);
+ else if (self.air_finished < time + 9)
+ sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM);
+ self.air_finished = time + 12;
+ self.dmg = 2;
+ }
+ else if (self.air_finished < time)
+ {
+ // drown!
+ if (self.pain_finished < time)
+ {
+ self.dmg = self.dmg + 2;
+ if (self.dmg > 15) self.dmg = 10;
+ self.deathtype = "drowning";
+ T_Damage (self, world, world, self.dmg);
+ self.deathtype = "";
+ self.pain_finished = time + 1;
+ }
+ }
+
+ if (!self.waterlevel)
+ {
+ if (self.flags & FL_INWATER)
+ {
+ // play leave water sound
+ sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM);
+ self.flags = self.flags - FL_INWATER;
+ }
+ return;
+ }
+
+ if (self.watertype == CONTENT_LAVA)
+ {
+ // do damage
+ if (self.dmgtime < time)
+ {
+ if (self.radsuit_finished > time)
+ self.dmgtime = time + 1;
+ else
+ self.dmgtime = time + 0.2;
+
+ self.deathtype = "lava";
+ T_Damage (self, world, world, 10 * self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+ else if (self.watertype == CONTENT_SLIME)
+ {
+ // do damage
+ if (self.dmgtime < time && self.radsuit_finished < time)
+ {
+ self.dmgtime = time + 1;
+ self.deathtype = "slime";
+ T_Damage (self, world, world, 4 * self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+
+ if ( !(self.flags & FL_INWATER) )
+ {
+
+ // player enter water sound
+ if (self.watertype == CONTENT_LAVA)
+ sound (self, CHAN_BODY, "player/inlava.wav", 1, ATTN_NORM);
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/inh2o.wav", 1, ATTN_NORM);
+ if (self.watertype == CONTENT_SLIME)
+ sound (self, CHAN_BODY, "player/slimbrn2.wav", 1, ATTN_NORM);
+
+ self.flags = self.flags + FL_INWATER;
+ self.dmgtime = 0;
+ }
+
+ if (! (self.flags & FL_WATERJUMP) )
+ self.velocity -= 0.8 * self.waterlevel * frametime *
+ self.velocity;
+};
+
+//======================================================================
+// CheckWaterJump
+//======================================================================
+void() CheckWaterJump =
+{
+ // from Copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP) return;
+
+ local vector start, end;
+
+ // check for a jump-out-of-water
+ makevectors (self.angles);
+ start = self.origin;
+ start_z = start_z + 8;
+ v_forward_z = 0;
+ normalize (v_forward);
+ end = start + v_forward * 24;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction < 1)
+ {
+ // solid at waist
+ start_z = start_z + self.maxs_z - 8;
+ end = start + v_forward*24;
+ self.movedir = trace_plane_normal * -50;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction == 1)
+ {
+ // open at eye level
+ self.flags |= FL_WATERJUMP;
+ self.velocity_z = 225;
+ // self.flags -= self.flags & FL_JUMPRELEASED;
+ self.flags &~= FL_JUMPRELEASED;
+ self.teleport_time = time + 2; // safety net
+ return;
+ }
+ }
+};
+
+//======================================================================
+// PlayerPreThink
+// Called every frame before physics are run
+//======================================================================
+void() PlayerPreThink =
+{
+ local float do_ladder_physics;
+
+ if (intermission_running)
+ {
+ // otherwise a button could be missed between the think tics
+ IntermissionThink ();
+ return;
+ }
+
+ if (self.view_ofs == '0 0 0')
+ {
+ // Check for cutscene stuff.
+ Cutscene_Think ();
+ // intermission or finale
+ return;
+ }
+
+ // note that this code block is here, before the tests which check
+ // whether the player is dead, so that the player's gravity will be
+ // correctly updated even if they e.g. fell off a ladder because
+ // they died -- iw
+ if (self.onladder)
+ {
+ do_ladder_physics = TRUE;
+ // not zero because zero means "default"
+ self.gravity = 0.0000001;
+ self.onladder = 0;
+ }
+ else
+ {
+ do_ladder_physics = FALSE;
+ self.gravity = self.wantedgravity;
+ }
+
+ // If just spawned in, try to recover previous fog values from
+ // own client entity, if any
+ if (cleanUpClientStuff) fog_setFromEnt(self, self);
+
+ // is this still used?
+ makevectors (self.v_angle);
+
+ CheckRules ();
+ WaterMove ();
+
+ if (self.waterlevel == 2) CheckWaterJump ();
+
+ if (self.deadflag >= DEAD_DEAD)
+ {
+ PlayerDeathThink ();
+ return;
+ }
+
+ if (self.deadflag == DEAD_DYING)
+ // dying, so do nothing
+ return;
+
+ // save velocity + speed here before running engine-side physics -- CEV
+ self.primal_velocity = self.velocity;
+ self.primal_velocity_z = 0;
+ self.primal_speed = vlen (self.primal_velocity);
+
+ // johnfitz ladder conditions, added from Rubicon2 -- dumptruck_ds
+ if (do_ladder_physics)
+ {
+ if (self.button2)
+ {
+ PlayerClimb ();
+
+ /* no ladder footsteps for now
+ if (time > self.ladder_step_finished)
+ {
+ r = random();
+ if (r > 0.66)
+ sound (self, CHAN_BODY, "ladder/metal1.wav", 0.5, ATTN_NORM);
+ else if (r > 0.33)
+ sound (self, CHAN_BODY, "ladder/metal2.wav", 0.5, ATTN_NORM);
+ else
+ sound (self, CHAN_BODY, "ladder/metal3.wav", 0.5, ATTN_NORM);
+ self.ladder_step_finished = time + 0.3;
+ }
+ */
+ }
+ else
+ {
+ self.flags = self.flags | FL_JUMPRELEASED;
+ self.velocity = 0.9 * self.velocity;
+ self.velocity_z = 0;
+ }
+ }
+
+ // teleporters can force a non-moving pause time
+ if (time < self.pausetime)
+ self.velocity = '0 0 0';
+
+ // save Z velocity here for later -- CEV
+ self.primal_velocity_z = self.velocity_z;
+
+ if (time > self.attack_finished
+ && self.currentammo == 0
+ && self.weapon != IT_AXE)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ }
+
+ // from copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.flags = self.flags | FL_FLY;
+ }
+
+ if (!self.boost_time && (self.teleport_time > time - 0.1))
+ self.boost_time = time;
+};
+
+//======================================================================
+// CheckPowerups
+// Check for turning off powerups
+//======================================================================
+void() CheckPowerups =
+{
+ if (self.health <= 0) return;
+
+ // invisibility
+ if (self.invisible_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.invisible_sound < time)
+ {
+ sound (self, CHAN_AUTO, "items/inv3.wav", 0.5, ATTN_IDLE);
+ self.invisible_sound = time + ((random() * 3) + 1);
+ }
+
+ if (self.invisible_finished < time + 3)
+ {
+ if (self.invisible_time == 1)
+ {
+ sprint (self, "Ring of Shadows magic is fading\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/inv2.wav", 1, ATTN_NORM);
+ self.invisible_time = time + 1;
+ }
+
+ if (self.invisible_time < time)
+ {
+ self.invisible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invisible_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_INVISIBILITY;
+ self.invisible_finished = 0;
+ self.invisible_time = 0;
+ }
+
+ // use the eyes
+ self.frame = 0;
+ self.modelindex = modelindex_eyes;
+ }
+ else
+ {
+ // don't use the eyes
+ self.modelindex = modelindex_player;
+ }
+
+ // invincibility
+ if (self.invincible_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.invincible_finished < time + 3)
+ {
+ if (self.invincible_time == 1)
+ {
+ sprint (self, "Protection is almost burned out\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/protect2.wav", 1, ATTN_NORM);
+ self.invincible_time = time + 1;
+ }
+
+ if (self.invincible_time < time)
+ {
+ self.invincible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invincible_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_INVULNERABILITY;
+ self.invincible_time = 0;
+ self.invincible_finished = 0;
+ }
+ if (self.invincible_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects -= self.effects & EF_DIMLIGHT;
+ }
+
+ // super damage
+ if (self.super_damage_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.super_damage_finished < time + 3)
+ {
+ if (self.super_time == 1)
+ {
+ sprint (self, "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;
+ }
+
+ if (self.super_time < time)
+ {
+ self.super_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.super_damage_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_QUAD;
+ self.super_damage_finished = 0;
+ self.super_time = 0;
+ }
+ if (self.super_damage_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects -= self.effects & EF_DIMLIGHT;
+ }
+
+ // suit
+ if (self.radsuit_finished)
+ {
+ // don't drown
+ self.air_finished = time + 12;
+
+ // sound and screen flash when items starts to run out
+ if (self.radsuit_finished < time + 3)
+ {
+ if (self.rad_time == 1)
+ {
+ sprint (self, "Air supply in Biosuit expiring\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/suit2.wav", 1, ATTN_NORM);
+ self.rad_time = time + 1;
+ }
+
+ if (self.rad_time < time)
+ {
+ self.rad_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.radsuit_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_SUIT;
+ self.rad_time = 0;
+ self.radsuit_finished = 0;
+ }
+ }
+};
+
+//======================================================================
+// PlayerPostThink
+// Called every frame after physics are run
+//======================================================================
+void() PlayerPostThink =
+{
+ if (self.view_ofs == '0 0 0')
+ // intermission or finale
+ return;
+ if (self.deadflag)
+ return;
+
+ // do weapon stuff
+ W_WeaponFrame ();
+
+ // check to see if player landed and play landing sound
+ if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) &&
+ (self.health > 0))
+ {
+ if (self.watertype == CONTENT_WATER)
+ 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);
+ self.deathtype = "";
+ sound (self, CHAN_VOICE, "player/land2.wav", 1, ATTN_NORM);
+ }
+ else
+ sound (self, CHAN_VOICE, "player/land.wav", 1, ATTN_NORM);
+
+ self.jump_flag = 0;
+ }
+
+ if (!(self.flags & FL_ONGROUND))
+ self.jump_flag = self.velocity_z;
+
+ // dumptruck_ds -- this replaces item_megahealth_rot in items.qc
+ if (self.health > self.max_health)
+ {
+ if (self.megahealth_rottime < time)
+ {
+ self.megahealth_rottime = time + 1;
+ self.health = self.health - 1;
+ }
+ else if (self.health <= 100)
+ {
+ // thanks ydrol!!!
+ self.items = self.items - (self.items & IT_SUPERHEALTH);
+ }
+ }
+
+ CheckPowerups ();
+
+ // from Copper -- dumptruck_ds
+ if (self.movetype != MOVETYPE_NOCLIP)
+ {
+ self.flags = not(self.flags, FL_FLY);
+ }
+};
+
+//======================================================================
+// ClientConnect
+// called when a player connects to a server
+//======================================================================
+void() ClientConnect =
+{
+ bprint (self.netname);
+ bprint (" entered the game\n");
+
+ // a client connecting during an intermission can cause problems
+ if (intermission_running)
+ ExitIntermission ();
+};
+
+//======================================================================
+// ClientDisconnect
+// called when a player disconnects from a server
+//======================================================================
+void() ClientDisconnect =
+{
+ if (gameover)
+ return;
+ // if the level end trigger has been activated, just return
+ // since they aren't *really* leaving
+
+ // let everyone else know
+ bprint (self.netname);
+ bprint (" left the game with ");
+ bprint (ftos(self.frags));
+ bprint (" frags\n");
+ sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
+ set_suicide_frame ();
+};
+
+//======================================================================
+// ClientObituary
+// called when a player dies
+//======================================================================
+void(entity targ, entity inflictor, entity attacker) ClientObituary =
+{
+ local float rnum;
+ local string deathstring, deathstring2;
+ rnum = random();
+
+ // refactored to remove one level of indentation -- CEV
+ if (targ.classname != "player") return;
+
+ if (attacker.classname == "teledeath")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("\n");
+
+ attacker.owner.frags = attacker.owner.frags + 1;
+ return;
+ }
+
+ if (attacker.classname == "teledeath2")
+ {
+ bprint ("Satan's power deflects ");
+ bprint (targ.netname);
+ bprint ("'s telefrag\n");
+
+ targ.frags = targ.frags - 1;
+ return;
+ }
+
+ // 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ // double 666 telefrag
+ // (can happen often in deathmatch 4 and levels with more
+ // than one pentagram)
+ if (attacker.classname == "teledeath3")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("'s Satan's power\n");
+ // 1998-07-26 only tfrag player on spot by Maddes start
+ // targ.frags = targ.frags - 1;
+ attacker.owner.frags = attacker.owner.frags + 1;
+ // 1998-07-26 only tfrag player on spot by Maddes end
+ return;
+ }
+
+ // 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+ if (attacker.classname == "player")
+ {
+ if (targ == attacker)
+ {
+ // killed self
+ attacker.frags = attacker.frags - 1;
+ bprint (targ.netname);
+
+ if (targ.weapon == 64 && targ.waterlevel > 1)
+ {
+ bprint (" discharges into the water.\n");
+ return;
+ }
+ if (targ.weapon == IT_GRENADE_LAUNCHER)
+ bprint (" tries to put the pin back in\n");
+ else
+ bprint (" becomes bored with life\n");
+ return;
+ }
+ else if ((teamplay == 2) && (targ.team > 0) &&
+ (targ.team == attacker.team))
+ {
+ if (rnum < 0.25)
+ deathstring = " mows down a teammate\n";
+ else if (rnum < 0.50)
+ deathstring = " checks his glasses\n";
+ else if (rnum < 0.75)
+ deathstring = " gets a frag for the other team\n";
+ else
+ deathstring = " loses another friend\n";
+ bprint (attacker.netname);
+ bprint (deathstring);
+ attacker.frags = attacker.frags - 1;
+ return;
+ }
+ else
+ {
+ 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)
+ {
+ deathstring = " was nailed by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_SUPER_NAILGUN)
+ {
+ deathstring = " was punctured by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_GRENADE_LAUNCHER)
+ {
+ deathstring = " eats ";
+ deathstring2 = "'s pineapple\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s grenade\n";
+ }
+ }
+ if (rnum == IT_ROCKET_LAUNCHER)
+ {
+ deathstring = " rides ";
+ deathstring2 = "'s rocket\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s rocket\n" ;
+ }
+ }
+ if (rnum == IT_LIGHTNING)
+ {
+ deathstring = " accepts ";
+ if (attacker.waterlevel > 1)
+ deathstring2 = "'s discharge\n";
+ else
+ deathstring2 = "'s shaft\n";
+ }
+ bprint (targ.netname);
+ bprint (deathstring);
+ bprint (attacker.netname);
+ bprint (deathstring2);
+ }
+ return;
+ }
+ else
+ {
+ targ.frags = targ.frags - 1;
+ bprint (targ.netname);
+
+ // custom obituary messages
+ if (inflictor.deathtype != "")
+ {
+ bprint (" ");
+ bprint (inflictor.deathtype);
+ bprint ("\n");
+ return;
+ }
+ if (attacker.deathtype != "")
+ {
+ bprint (" ");
+ bprint (attacker.deathtype);
+ bprint ("\n");
+ return;
+ }
+
+ // killed by a monster?
+ // if (attacker.flags & FL_MONSTER)
+ if ((attacker.flags & FL_MONSTER) && (attacker.obit_name == ""))
+ {
+ if (attacker.classname == "monster_army")
+ bprint (" was shot by a Grunt\n");
+ if (attacker.classname == "monster_demon1")
+ bprint (" was eviscerated by a Fiend\n");
+ if (attacker.classname == "monster_dog")
+ bprint (" was mauled by a Rottweiler\n");
+ if (attacker.classname == "monster_dragon")
+ bprint (" was fried by a Dragon\n");
+ if (attacker.classname == "monster_enforcer")
+ bprint (" was blasted by an Enforcer\n");
+ if (attacker.classname == "monster_fish")
+ bprint (" was fed to the Rotfish\n");
+ if (attacker.classname == "monster_hell_knight")
+ bprint (" was slain by a Death Knight\n");
+ if (attacker.classname == "monster_knight")
+ bprint (" was slashed by a Knight\n");
+ if (attacker.classname == "monster_ogre")
+ bprint (" was destroyed by an Ogre\n");
+ if (attacker.classname == "monster_ogre_marksman")
+ // dumptruck_ds
+ bprint (" was felled by a Marksman\n");
+ if (attacker.classname == "monster_oldone")
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_oldone2")
+ // dumptruck_ds
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_boss2")
+ // dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_boss")
+ // dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_shalrath")
+ bprint (" was exploded by a Vore\n");
+ if (attacker.classname == "monster_shambler")
+ bprint (" was smashed by a Shambler\n");
+ if (attacker.classname == "monster_vomit")
+ bprint (" was vomited on by a Vomitus\n");
+ if (attacker.classname == "monster_wizard")
+ bprint (" was scragged by a Scrag\n");
+ if (attacker.classname == "monster_zombie")
+ bprint (" joins the Zombies\n");
+
+ return;
+ }
+
+ // obits for custom monsters -- progs_dump -- dumptruck_ds
+ if (attacker.obit_name != "")
+ {
+ bprint (" was ");
+ if !(attacker.obit_method)
+ bprint ("killed");
+ else
+ // e.g. ripped apart
+ bprint (attacker.obit_method);
+ bprint (" by ");
+ // a bad monster
+ bprint (attacker.obit_name);
+ bprint ("\n");
+ return;
+ }
+
+ // tricks and traps
+ if (attacker.classname == "explo_box" ||
+ attacker.classname == "play_explosion")
+ {
+ bprint (" blew up\n");
+ return;
+ }
+ if (attacker.classname == "func_laser")
+ {
+ bprint (" discovered that lasers are hot\n");
+ return;
+ }
+ if ((attacker.solid == SOLID_BSP &&
+ attacker != world &&
+ attacker.classname != "togglewall") ||
+ (inflictor.classname == "func_movewall" &&
+ !(inflictor.spawnflags & MOVEWALL_TOUCH)))
+ {
+ bprint (" was squished\n");
+ return;
+ }
+ if (attacker.classname == "trap_shooter" ||
+ attacker.classname == "trap_spikeshooter" ||
+ attacker.classname == "trap_switched_shooter")
+ {
+ // bprint (" was spiked\n");
+ // changed for custom shooters -- dumptruck_ds
+ bprint (" was unlucky\n");
+ return;
+ }
+ if (attacker.classname == "ltrail_start" ||
+ attacker.classname == "ltrail_relay")
+ {
+ bprint (" had an electrifying experience\n");
+ return;
+ }
+ if (attacker.classname == "fireball")
+ {
+ bprint (" ate a lavaball\n");
+ return;
+ }
+ if (attacker.classname == "trigger_changelevel")
+ {
+ bprint (" tried to leave\n");
+ return;
+ }
+
+ // in-liquid deaths
+ if (targ.deathtype == "drowning")
+ {
+ if (random() < 0.5)
+ bprint (" sleeps with the fishes\n");
+ else
+ bprint (" sucks it down\n");
+ return;
+ }
+ if (targ.deathtype == "slime")
+ {
+ if (random() < 0.5)
+ bprint (" gulped a load of slime\n");
+ else
+ bprint (" can't exist on slime alone\n");
+ return;
+ }
+ if (targ.deathtype == "lava")
+ {
+ if (targ.health < -15)
+ {
+ bprint (" burst into flames\n");
+ return;
+ }
+ if (random() < 0.5)
+ bprint (" turned into hot slag\n");
+ else
+ bprint (" visits the Volcano God\n");
+ return;
+ }
+
+ // fell to their death?
+ if (targ.deathtype == "falling")
+ {
+ bprint (" fell to his death\n");
+ return;
+ }
+
+ // hell if I know; he's just dead!!!
+ bprint (" died\n");
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/combat.qc

diff --git a/qc/combat.qc b/qc/combat.qc
index 83ca79a..ad32c61 100644
--- a/qc/combat.qc
+++ b/qc/combat.qc
@@ -1,366 +1,366 @@
-
-void() T_MissileTouch;
-void() info_player_start;
-void(entity targ, entity inflictor, entity attacker) ClientObituary;
-
-void() monster_death_use;
-
-//============================================================================
-
-/*
-============
-CanDamage
-
-Returns true if the inflictor can directly damage the target. Used for
-explosions and melee attacks.
-============
-*/
-float(entity targ, entity inflictor) CanDamage =
-{
-// bmodels need special checking because their origin is 0,0,0
- if (targ.movetype == MOVETYPE_PUSH)
- {
- traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- if (trace_ent == targ)
- return TRUE;
- return FALSE;
- }
-
- traceline(inflictor.origin, targ.origin, TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
- traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
- if (trace_fraction == 1)
- return TRUE;
-
- return FALSE;
-};
-
-
-/*
-============
-Killed
-============
-*/
-void(entity targ, entity inflictor, entity attacker) Killed =
-{
- local entity oself;
-
- oself = self;
- self = targ;
-
- if (self.health < -99)
- self.health = -99; // don't let sbar look bad if a player
-
- if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
- { // doors, triggers, etc
- self.th_die ();
- self = oself;
- return;
- }
-
- self.enemy = attacker;
-
-// bump the monster counter
- if (self.flags & FL_MONSTER)
- {
- killed_monsters = killed_monsters + 1;
- WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
- }
-
- ClientObituary (self, inflictor, attacker);
-
- self.takedamage = DAMAGE_NO;
- self.touch = SUB_Null;
-
- monster_death_use();
- self.th_die ();
-
- self = oself;
-};
-
-
-/*
-============
-T_Damage
-
-The damage is coming from inflictor, but get mad at attacker
-This should be the only function that ever reduces health.
-============
-*/
-void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
-{
- local vector dir;
- local entity oldself;
- local float save;
- local float take;
- local float ignore_armor; //johnfitz
- local string death_type; //johnfitz
-
- // don't try to damage the world. Not healthy - bmFbr
- if (!targ)
- return;
-
- //johnfitz -- make sure targ.deathtype doesn't keep stale info after this function is done
- death_type = targ.deathtype;
- targ.deathtype = "";
- //johnfitz
-
- if (!targ.takedamage)
- return;
-
- //johnfitz -- some func_breakables ignore monster damage //added from Rubicon2 combat.qc dumptruck_ds
- if (targ.classname == "func_breakable")
- {
- if (targ.spawnflags & BREAKABLE_NO_MONSTERS && attacker.flags & FL_MONSTER)
- return;
- }
- //johnfitz
-
-// used by buttons and triggers to set activator for target firing
- damage_attacker = attacker;
-
-// check for quad damage powerup on the attacker
- if (attacker.super_damage_finished > time)
- damage = damage * 4;
-
- // damage mod for monsters -- dumptruck_ds
- if (attacker.damage_mod)
- damage = damage * attacker.damage_mod;
-
- //don't deplete armor if drowning/burning, or protected by biosuit/pentagram/godmode (note: in ID1 pentagram/godmode doesn't actually protect your armor)
- if (death_type == "burning" || death_type == "drowning" || targ.invincible_finished >= time || targ.flags & FL_GODMODE)
- ignore_armor = TRUE;
- else
- ignore_armor = FALSE;
-//johnfitz
-// save damage based on the target's armor level
- if (ignore_armor) //johnfitz -- some damage doesn't deplete armor
- {
- save = 0;
- }
- else
- {
- save = ceil(targ.armortype*damage);
- 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));
- }
-}
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
-// }
-// else
-// save = 0;
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
- targ.armorvalue = targ.armorvalue - save;
- take = ceil(damage-save);
-
-// add to the damage total for clients, which will be sent as a single
-// message at the end of the frame
-// FIXME: remove after combining shotgun blasts?
- if (targ.flags & FL_CLIENT)
- {
- targ.dmg_take = targ.dmg_take + take;
- targ.dmg_save = targ.dmg_save + save;
- targ.dmg_inflictor = inflictor;
- }
-
-// figure momentum add
- if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
- {
- dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
- dir = normalize(dir);
- targ.velocity = targ.velocity + dir*damage*8;
- }
-
-// check for godmode or invincibility
- if (targ.flags & FL_GODMODE)
- return;
- if (targ.invincible_finished >= time)
- {
- if (self.invincible_sound < time)
- {
- sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
- self.invincible_sound = time + 2;
- }
- return;
- }
-
-// team play damage avoidance
-// 1998-07-29 Teamplay 1 fix by Maddes start
- if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team)
- && (targ != attacker)
- && (attacker.classname == "player")
- && (inflictor.classname != "door") ) // because squishing a teammate is still possible
-// 1998-07-29 Teamplay 1 fix by Maddes end
- return;
-
-// do the damage
- targ.health = targ.health - take;
-
-// fire pain_target if appropriate
- if ((targ.flags & FL_MONSTER) &&
- targ.pain_target != "" &&
- targ.health <= targ.pain_threshold)
- {
- oldself = self;
- self = targ;
- monster_pain_use ();
- self = oldself;
- }
-
- if (targ.health <= 0)
- {
- Killed (targ, inflictor, attacker);
- return;
- }
-
-// react to the damage
- oldself = self;
- self = targ;
-
- if ( (self.flags & FL_MONSTER) && attacker != world)
- {
- // get mad unless of the same class (except for soldiers)
- if (self != attacker && attacker != self.enemy)
- {
- local float mode;
- mode = 0;
- // take highest mode so infighting happens consistently
- if (self.infight_mode == -1 || self.infight_mode > mode)
- {
- mode = self.infight_mode;
- }
- if (mode != -1 && attacker.infight_mode > mode)
- {
- mode = attacker.infight_mode;
- }
- //soldiers of the same style will infight -- dumptruck_ds - thanks for c0burn and Shamblernaut for your help!
- if (mode == -1)
- {
- if (attacker.classname == "player")
- {
- if (self.enemy.classname == "player")
- self.oldenemy = self.enemy;
- self.enemy = attacker;
- FoundTarget ();
- }
- }
- else if (
- (self.classname != attacker.classname) ||
- ((self.classname == "monster_army") && (self.style == attacker.style)) ||
- (mode > 0 && self.mdl_body != attacker.mdl_body) || // infight if different models
- (mode > 1 && self.skin != attacker.skin) || // infight if different skin
- (mode > 2) // always infight
- )
- {
- if (self.enemy.classname == "player")
- self.oldenemy = self.enemy;
- self.enemy = attacker;
- FoundTarget ();
- }
- }
- }
-
- if (self.th_pain)
- {
- self.th_pain (attacker, take);
- // nightmare mode monsters don't go into pain frames often
- if (skill == 3)
- self.pain_finished = time + 5;
- }
-
- self = oldself;
-};
-
-/*
-============
-T_RadiusDamage
-============
-*/
-void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
-{
- local float points;
- local entity head;
- local vector org;
-
- head = findradius(inflictor.origin, damage+40);
-
- while (head)
- {
- if (head != ignore)
- {
- if (head.takedamage)
- {
- org = head.origin + (head.mins + head.maxs)*0.5;
- points = 0.5*vlen (inflictor.origin - org);
- if (points < 0)
- points = 0;
- points = damage - points;
- if (head == attacker)
- points = points * 0.5;
- if (points > 0)
- {
- if (CanDamage (head, inflictor))
- { // shambler takes half damage from all explosions
- if (head.classname == "monster_shambler")
- T_Damage (head, inflictor, attacker, points*0.5);
- else
- T_Damage (head, inflictor, attacker, points);
- }
- }
- }
- }
- head = head.chain;
- }
-};
-
-/*
-============
-T_BeamDamage
-============
-*/
-void(entity attacker, float damage) T_BeamDamage =
-{
- local float points;
- local entity head;
-
- head = findradius(attacker.origin, damage+40);
-
- while (head)
- {
- if (head.takedamage)
- {
- points = 0.5*vlen (attacker.origin - head.origin);
- if (points < 0)
- points = 0;
- points = damage - points;
- if (head == attacker)
- points = points * 0.5;
- if (points > 0)
- {
- if (CanDamage (head, attacker))
- {
- if (head.classname == "monster_shambler")
- T_Damage (head, attacker, attacker, points*0.5);
- else
- T_Damage (head, attacker, attacker, points);
- }
- }
- }
- head = head.chain;
- }
-};
+
+void() T_MissileTouch;
+void() info_player_start;
+void(entity targ, entity inflictor, entity attacker) ClientObituary;
+
+void() monster_death_use;
+
+//============================================================================
+
+/*
+============
+CanDamage
+
+Returns true if the inflictor can directly damage the target. Used for
+explosions and melee attacks.
+============
+*/
+float(entity targ, entity inflictor) CanDamage =
+{
+// bmodels need special checking because their origin is 0,0,0
+ if (targ.movetype == MOVETYPE_PUSH)
+ {
+ traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ if (trace_ent == targ)
+ return TRUE;
+ return FALSE;
+ }
+
+ traceline(inflictor.origin, targ.origin, TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+ traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
+ if (trace_fraction == 1)
+ return TRUE;
+
+ return FALSE;
+};
+
+
+/*
+============
+Killed
+============
+*/
+void(entity targ, entity inflictor, entity attacker) Killed =
+{
+ local entity oself;
+
+ oself = self;
+ self = targ;
+
+ if (self.health < -99)
+ self.health = -99; // don't let sbar look bad if a player
+
+ if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
+ { // doors, triggers, etc
+ self.th_die ();
+ self = oself;
+ return;
+ }
+
+ self.enemy = attacker;
+
+// bump the monster counter
+ if (self.flags & FL_MONSTER)
+ {
+ killed_monsters = killed_monsters + 1;
+ WriteByte (MSG_ALL, SVC_KILLEDMONSTER);
+ }
+
+ ClientObituary (self, inflictor, attacker);
+
+ self.takedamage = DAMAGE_NO;
+ self.touch = SUB_Null;
+
+ monster_death_use();
+ self.th_die ();
+
+ self = oself;
+};
+
+
+/*
+============
+T_Damage
+
+The damage is coming from inflictor, but get mad at attacker
+This should be the only function that ever reduces health.
+============
+*/
+void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
+{
+ local vector dir;
+ local entity oldself;
+ local float save;
+ local float take;
+ local float ignore_armor; //johnfitz
+ local string death_type; //johnfitz
+
+ // don't try to damage the world. Not healthy - bmFbr
+ if (!targ)
+ return;
+
+ //johnfitz -- make sure targ.deathtype doesn't keep stale info after this function is done
+ death_type = targ.deathtype;
+ targ.deathtype = "";
+ //johnfitz
+
+ if (!targ.takedamage)
+ return;
+
+ //johnfitz -- some func_breakables ignore monster damage //added from Rubicon2 combat.qc dumptruck_ds
+ if (targ.classname == "func_breakable")
+ {
+ if (targ.spawnflags & BREAKABLE_NO_MONSTERS && attacker.flags & FL_MONSTER)
+ return;
+ }
+ //johnfitz
+
+// used by buttons and triggers to set activator for target firing
+ damage_attacker = attacker;
+
+// check for quad damage powerup on the attacker
+ if (attacker.super_damage_finished > time)
+ damage = damage * 4;
+
+ // damage mod for monsters -- dumptruck_ds
+ if (attacker.damage_mod)
+ damage = damage * attacker.damage_mod;
+
+ //don't deplete armor if drowning/burning, or protected by biosuit/pentagram/godmode (note: in ID1 pentagram/godmode doesn't actually protect your armor)
+ if (death_type == "burning" || death_type == "drowning" || targ.invincible_finished >= time || targ.flags & FL_GODMODE)
+ ignore_armor = TRUE;
+ else
+ ignore_armor = FALSE;
+//johnfitz
+// save damage based on the target's armor level
+ if (ignore_armor) //johnfitz -- some damage doesn't deplete armor
+ {
+ save = 0;
+ }
+ else
+ {
+ save = ceil(targ.armortype*damage);
+ 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));
+ }
+}
+// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
+// }
+// else
+// save = 0;
+// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
+ targ.armorvalue = targ.armorvalue - save;
+ take = ceil(damage-save);
+
+// add to the damage total for clients, which will be sent as a single
+// message at the end of the frame
+// FIXME: remove after combining shotgun blasts?
+ if (targ.flags & FL_CLIENT)
+ {
+ targ.dmg_take = targ.dmg_take + take;
+ targ.dmg_save = targ.dmg_save + save;
+ targ.dmg_inflictor = inflictor;
+ }
+
+// figure momentum add
+ if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
+ {
+ dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
+ dir = normalize(dir);
+ targ.velocity = targ.velocity + dir*damage*8;
+ }
+
+// check for godmode or invincibility
+ if (targ.flags & FL_GODMODE)
+ return;
+ if (targ.invincible_finished >= time)
+ {
+ if (self.invincible_sound < time)
+ {
+ sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
+ self.invincible_sound = time + 2;
+ }
+ return;
+ }
+
+// team play damage avoidance
+// 1998-07-29 Teamplay 1 fix by Maddes start
+ if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team)
+ && (targ != attacker)
+ && (attacker.classname == "player")
+ && (inflictor.classname != "door") ) // because squishing a teammate is still possible
+// 1998-07-29 Teamplay 1 fix by Maddes end
+ return;
+
+// do the damage
+ targ.health = targ.health - take;
+
+// fire pain_target if appropriate
+ if ((targ.flags & FL_MONSTER) &&
+ targ.pain_target != "" &&
+ targ.health <= targ.pain_threshold)
+ {
+ oldself = self;
+ self = targ;
+ monster_pain_use ();
+ self = oldself;
+ }
+
+ if (targ.health <= 0)
+ {
+ Killed (targ, inflictor, attacker);
+ return;
+ }
+
+// react to the damage
+ oldself = self;
+ self = targ;
+
+ if ( (self.flags & FL_MONSTER) && attacker != world)
+ {
+ // get mad unless of the same class (except for soldiers)
+ if (self != attacker && attacker != self.enemy)
+ {
+ local float mode;
+ mode = 0;
+ // take highest mode so infighting happens consistently
+ if (self.infight_mode == -1 || self.infight_mode > mode)
+ {
+ mode = self.infight_mode;
+ }
+ if (mode != -1 && attacker.infight_mode > mode)
+ {
+ mode = attacker.infight_mode;
+ }
+ //soldiers of the same style will infight -- dumptruck_ds - thanks for c0burn and Shamblernaut for your help!
+ if (mode == -1)
+ {
+ if (attacker.classname == "player")
+ {
+ if (self.enemy.classname == "player")
+ self.oldenemy = self.enemy;
+ self.enemy = attacker;
+ FoundTarget ();
+ }
+ }
+ else if (
+ (self.classname != attacker.classname) ||
+ ((self.classname == "monster_army") && (self.style == attacker.style)) ||
+ (mode > 0 && self.mdl_body != attacker.mdl_body) || // infight if different models
+ (mode > 1 && self.skin != attacker.skin) || // infight if different skin
+ (mode > 2) // always infight
+ )
+ {
+ if (self.enemy.classname == "player")
+ self.oldenemy = self.enemy;
+ self.enemy = attacker;
+ FoundTarget ();
+ }
+ }
+ }
+
+ if (self.th_pain)
+ {
+ self.th_pain (attacker, take);
+ // nightmare mode monsters don't go into pain frames often
+ if (skill == 3)
+ self.pain_finished = time + 5;
+ }
+
+ self = oldself;
+};
+
+/*
+============
+T_RadiusDamage
+============
+*/
+void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
+{
+ local float points;
+ local entity head;
+ local vector org;
+
+ head = findradius(inflictor.origin, damage+40);
+
+ while (head)
+ {
+ if (head != ignore)
+ {
+ if (head.takedamage)
+ {
+ org = head.origin + (head.mins + head.maxs)*0.5;
+ points = 0.5*vlen (inflictor.origin - org);
+ if (points < 0)
+ points = 0;
+ points = damage - points;
+ if (head == attacker)
+ points = points * 0.5;
+ if (points > 0)
+ {
+ if (CanDamage (head, inflictor))
+ { // shambler takes half damage from all explosions
+ if (head.classname == "monster_shambler")
+ T_Damage (head, inflictor, attacker, points*0.5);
+ else
+ T_Damage (head, inflictor, attacker, points);
+ }
+ }
+ }
+ }
+ head = head.chain;
+ }
+};
+
+/*
+============
+T_BeamDamage
+============
+*/
+void(entity attacker, float damage) T_BeamDamage =
+{
+ local float points;
+ local entity head;
+
+ head = findradius(attacker.origin, damage+40);
+
+ while (head)
+ {
+ if (head.takedamage)
+ {
+ points = 0.5*vlen (attacker.origin - head.origin);
+ if (points < 0)
+ points = 0;
+ points = damage - points;
+ if (head == attacker)
+ points = points * 0.5;
+ if (points > 0)
+ {
+ if (CanDamage (head, attacker))
+ {
+ if (head.classname == "monster_shambler")
+ T_Damage (head, attacker, attacker, points*0.5);
+ else
+ T_Damage (head, attacker, attacker, points);
+ }
+ }
+ }
+ head = head.chain;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/defs_constants.qc

diff --git a/qc/defs_constants.qc b/qc/defs_constants.qc
new file mode 100644
index 0000000..7f920bb
--- /dev/null
+++ b/qc/defs_constants.qc
@@ -0,0 +1,6 @@
+/*==============================================================================
+ CONSTANT VALS COLLECTED HERE
+==============================================================================*/
+
+#define PM_TELEDROP '0 0 -64' // drop tele to floor if within Z val
+

Return to the top of this page or return to the overview of this repo.

Diff qc/doe_elbutton.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/doe_plats.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/doors.qc

diff --git a/qc/doors.qc b/qc/doors.qc
index b04f606..419ed89 100644
--- a/qc/doors.qc
+++ b/qc/doors.qc
@@ -1,945 +1,945 @@
-
-float DOOR_START_OPEN = 1;
-float DOOR_DONT_LINK = 4;
-float DOOR_GOLD_KEY = 8;
-float DOOR_SILVER_KEY = 16;
-float DOOR_TOGGLE = 32;
-float DOOR_DOOM_STYLE_UNLOCK = 64;
-/*
-
-Doors are similar to buttons, but can spawn a fat trigger field around them
-to open without a touch, and they link together to form simultanious
-double/quad doors.
-
-Door.owner is the master door. If there is only one door, it points to itself.
-If multiple doors, all will point to a single one.
-
-Door.enemy chains from the master door through all doors linked in the chain.
-
-*/
-
-/*
-=============================================================================
-
-THINK FUNCTIONS
-
-=============================================================================
-*/
-
-void() door_go_down;
-void() door_go_up;
-
-void() door_blocked =
-{
- T_Damage (other, self, self, self.dmg);
-
-// if a door has a negative wait, it would never come back if blocked,
-// so let it just squash the object to death real fast
- if (self.wait >= 0)
- {
- if (self.state == STATE_DOWN)
- door_go_up ();
- else
- door_go_down ();
- }
-};
-
-
-void() door_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- if (self.spawnflags & DOOR_TOGGLE)
- return; // don't come down automatically
- self.think = door_go_down;
- self.nextthink = self.ltime + self.wait;
-};
-
-void() door_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
-
-void() door_go_down =
-{
- entity shadow;
- entity oldself;
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- if (self.max_health)
- {
- self.takedamage = DAMAGE_YES;
- self.health = self.max_health;
- }
-
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
-
- if(self.switchshadstyle) {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if(oldself.spawnflags & DOOR_START_OPEN) {
- shadow_fade_out();
- shadow.shadowoff = 1;
- } else {
- shadow_fade_in();
- shadow.shadowoff = 0;
- }
-
- self = oldself;
-
- }
-};
-
-void() door_go_up =
-{
- entity shadow;
- entity oldself;
-
- if (self.state == STATE_UP)
- return; // allready going up
-
- if (self.state == STATE_TOP)
- { // reset top wait time
- self.nextthink = self.ltime + self.wait;
- return;
- }
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, door_hit_top);
-
- SUB_UseTargets();
-
- if(self.switchshadstyle) {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if(oldself.spawnflags & DOOR_START_OPEN) {
- shadow_fade_in();
- shadow.shadowoff = 0;
- } else {
- shadow_fade_out();
- shadow.shadowoff = 1;
- }
-
- self = oldself;
- }
-};
-
-
-void() door_group_go_down = {
- local entity oself, starte;
-
- oself = self;
- starte = self;
-
- do
- {
- door_go_down ();
- self = self.enemy;
- } while ( (self != starte) && (self != world) );
- self = oself;
-
-};
-
-void() door_group_go_up = {
- local entity oself, starte;
-
- oself = self;
- starte = self;
-
- do
- {
- door_go_up ();
- self = self.enemy;
- } while ( (self != starte) && (self != world) );
-
- self = oself;
-};
-
-/*
-=============================================================================
-
-ACTIVATION FUNCTIONS
-
-=============================================================================
-*/
-
-void() door_fire =
-{
-
- if (self.owner != self)
- objerror ("door_fire: self.owner != self");
-
- if (self.estate != STATE_ACTIVE)
- return;
-// self.noise4 is now played in keylock_try_to_unlock -- iw
-
- self.message = string_null; // no more message
-
-
- if (self.spawnflags & DOOR_TOGGLE)
- {
- if (self.state == STATE_UP || self.state == STATE_TOP)
- {
- door_group_go_down();
- return;
- }
- }
-
- // trigger all paired doors
- door_group_go_up();
-};
-
-
-void() door_use =
-{
- local entity oself;
-
- self.message = ""; // door message are for touch only
- self.owner.message = "";
- self.enemy.message = "";
- oself = self;
- self = self.owner;
- door_fire ();
- self = oself;
-};
-
-
-void() door_trigger_touch =
-{
- if (other.health <= 0)
- return;
-
- if (other.movetype == MOVETYPE_NOCLIP) // from copper -- dumptruck_ds
- return;
-
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 1;
-
- activator = other;
-
- self = self.owner;
- door_use ();
-};
-
-
-void() door_killed =
-{
- local entity oself;
-
- oself = self;
- self = self.owner;
- self.health = self.max_health;
- self.takedamage = DAMAGE_NO; // wil be reset upon return
- door_use ();
- self = oself;
-};
-
-
-/*
-================
-door_unlock
-
-Perform the actions which should be performed when self is successfully
-unlocked with a key.
-
-This function exists so that it can be passed as an argument to the new
-keylock_try_to_unlock function. This code was previously part of the
-door_touch function. -- iw
-================
-*/
-void() door_unlock =
-{
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
- {
- self.touch = SUB_Null;
- if (self.enemy)
- self.enemy.touch = SUB_Null; // get paired door
- }
- door_use ();
-};
-
-
-/*
-================
-door_touch
-
-Prints messages and opens key doors
-================
-*/
-void() door_touch =
-{
- // if (other.classname != "player")
- // return;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.owner.attack_finished > time)
- return;
-
- self.owner.attack_finished = time + 2;
-
- if (self.owner.message != "")
- {
- centerprint (other, self.owner.message);
- sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
- }
-
-// key door stuff
- if (!keylock_has_key_set ())
- return;
-
- keylock_try_to_unlock (other, "", door_unlock);
-};
-
-
-
-/*
-=============================================================================
-ENTITY STATE FUNCTIONS
-=============================================================================
-*/
-
-void(entity e, float closealldoors) door_estate_lock = {
- local entity oself, next;
-
- if (e.owner.estate == STATE_INACTIVE) return;
-
- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
-
- oself = self;
- self = e.owner;
-
- self.estate = STATE_INACTIVE;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
-
- self.prevstate = self.state;
-
- if (self.state == STATE_UP || self.state == STATE_TOP) {
- if (
- // don't close wait -1 nor toggleable doors...
- !(self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
- // ...unless the trigger_setstate has a "Close all doors" spawnflag on
- || closealldoors
- )
- door_group_go_down();
-
- }
-
- if (self.max_health) {
- next = self;
- do {
- //e.health = 0;
- next.takedamage = DAMAGE_NO;
- next = next.enemy;
- } while ( (next != self) && (next != world) );
- }
-
- self = oself;
-
-}
-
-void(entity e, float openalldoors) door_estate_unlock = {
- local entity oself, next;
-
- if (e.owner.estate == STATE_ACTIVE) return;
-
- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
-
- oself = self;
- self = e.owner;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
-
- if (self.prevstate == STATE_UP || self.prevstate == STATE_TOP) {
- if (
- (self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
- && openalldoors
- ) door_group_go_up();
- }
-
- if (self.max_health) {
- next = self;
- do {
- next.health = next.max_health;
- next.takedamage = DAMAGE_YES;
- next = next.enemy;
- } while ( (next != self) && (next != world) );
- }
-
- self.estate = STATE_ACTIVE;
- self = oself;
-}
-
-
-/*
-=============================================================================
-
-SPAWNING FUNCTIONS
-
-=============================================================================
-*/
-
-
-entity(vector fmins, vector fmaxs) spawn_field =
-{
- local entity trigger;
- local vector t1, t2;
-
- trigger = spawn();
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.owner = self;
- trigger.touch = door_trigger_touch;
-
- t1 = fmins;
- t2 = fmaxs;
- setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
- return (trigger);
-};
-
-
-float (entity e1, entity e2) EntitiesTouching =
-{
- if (e1.mins_x > e2.maxs_x)
- return FALSE;
- if (e1.mins_y > e2.maxs_y)
- return FALSE;
- if (e1.mins_z > e2.maxs_z)
- return FALSE;
- if (e1.maxs_x < e2.mins_x)
- return FALSE;
- if (e1.maxs_y < e2.mins_y)
- return FALSE;
- if (e1.maxs_z < e2.mins_z)
- return FALSE;
- return TRUE;
-};
-
-
-/*
-=============
-LinkDoors
-
-
-=============
-*/
-void() LinkDoors =
-{
- local entity t, starte;
- local vector cmins, cmaxs;
-
- if (self.enemy)
- return; // already linked by another door
- if (self.spawnflags & 4)
- {
- self.owner = self.enemy = self;
- return; // don't want to link this door
- }
-
- cmins = self.mins;
- cmaxs = self.maxs;
-
- starte = self;
- t = self;
-
- do
- {
- self.owner = starte; // master door
-
- if (self.health)
- starte.health = self.health;
- if (self.targetname != "")
- starte.targetname = self.targetname;
- if (self.message != "")
- starte.message = self.message;
-
- t = find (t, classname, self.classname);
- if (!t)
- {
- self.enemy = starte; // make the chain a loop
-
- // shootable, fired, or key doors just needed the owner/enemy links,
- // they don't spawn a field
-
- self = self.owner;
-
- if (self.health)
- return;
- if (self.targetname != "")
- return;
- if (keylock_has_key_set ())
- return;
-
- self.owner.trigger_field = spawn_field(cmins, cmaxs);
-
- return;
- }
-
- if (EntitiesTouching(self,t))
- {
- if (t.enemy)
- objerror ("cross connected doors");
-
- self.enemy = t;
- self = t;
-
- if (t.mins_x < cmins_x)
- cmins_x = t.mins_x;
- if (t.mins_y < cmins_y)
- cmins_y = t.mins_y;
- if (t.mins_z < cmins_z)
- cmins_z = t.mins_z;
- if (t.maxs_x > cmaxs_x)
- cmaxs_x = t.maxs_x;
- if (t.maxs_y > cmaxs_y)
- cmaxs_y = t.maxs_y;
- if (t.maxs_z > cmaxs_z)
- cmaxs_z = t.maxs_z;
- }
- } while (1 );
-
-};
-
-
-/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-if two doors touch, they are assumed to be connected and operate as a unit.
-
-TOGGLE causes the door to wait in both the start and end states for a trigger event.
-
-START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
-
-Key doors are always wait -1.
-
-"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
-"angle" determines the opening direction
-"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
-"health" if set, door must be shot open
-"speed" movement speed (100 default)
-"wait" wait before returning (3 default, -1 = never return)
-"lip" lip remaining at end of move (8 default)
-"dmg" damage to inflict when blocked (2 default)
-"cnt" if 1, leave a used key in the player's inventory (0 default)
-"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
-"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
-"noise2" sound file for the "move" sound (if set, overrides "sounds")
-"noise3" sound file for the "key required" sound (default is per worldtype)
-"noise4" sound file for the "key used" sound (default is per worldtype)
-"sounds"
-0) no sound
-1) stone
-2) base
-3) stone chain
-4) screechy metal
-*/
-
-void() func_door =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local string default_noise1;
- local string default_noise2;
- entity shadow;
- entity oldself;
-
-// self.noise3 and self.noise4 can now be overridden by the mapper, but
-// will be set to default values in keylock_init if necessary -- iw
- keylock_init ();
-
-// self.noise1 and self.noise2 can now be overridden by the mapper -- iw
- default_noise1 = "misc/null.wav";
- default_noise2 = "misc/null.wav";
- if (self.sounds == 1)
- {
- default_noise1 = "doors/drclos4.wav";
- default_noise2 = "doors/doormv1.wav";
- }
- if (self.sounds == 2)
- {
- default_noise1 = "doors/hydro2.wav";
- default_noise2 = "doors/hydro1.wav";
- }
- if (self.sounds == 3)
- {
- default_noise1 = "doors/stndr2.wav";
- default_noise2 = "doors/stndr1.wav";
- }
- if (self.sounds == 4)
- {
- default_noise1 = "doors/ddoor2.wav";
- default_noise2 = "doors/ddoor1.wav";
- }
-
- if (self.noise1 == "")
- self.noise1 = default_noise1;
- if (self.noise2 == "")
- self.noise2 = default_noise2;
-
- precache_sound (self.noise1);
- precache_sound (self.noise2);
-
- SetMovedir ();
-
- self.max_health = self.health;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- //self.classname = "door";
-
- self.blocked = door_blocked;
- self.use = door_use;
-
- if (self.spawnflags & DOOR_SILVER_KEY){
- keylock_set_silver_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
- if (self.spawnflags & DOOR_GOLD_KEY){
- keylock_set_gold_key ();
-
- if (self.keyname != "") {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
-
-// support for item_key_custom -- iw
- if (self.keyname != "")
- {
- keylock_set_custom_key (self.keyname);
- self.keyname = ""; // this should not be referenced again
- }
-
- if (!self.speed)
- self.speed = 100;
- if (!self.wait)
- self.wait = 3;
- if (!self.lip)
- self.lip = 8;
- if (!self.dmg)
- self.dmg = 2;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
-
-// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
-// but spawn in the open position
- if (self.spawnflags & DOOR_START_OPEN)
- {
- setorigin (self, self.pos2);
- self.pos2 = self.pos1;
- self.pos1 = self.origin;
- }
-
- self.state = STATE_BOTTOM;
-
- if (self.health)
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = door_killed;
- }
-
- if (self.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
- self.cnt = 1;
-
- if (keylock_has_key_set ())
- {
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
- {
- self.wait = -1;
- }
- }
- self.touch = door_touch;
-
-// LinkDoors can't be done until all of the doors have been spawned, so
-// the sizes can be detected properly.
- self.think = LinkDoors;
- self.nextthink = self.ltime + 0.1;
-
- // creates a shadow controller entity for the door if it has switchable shadows
- if(self.switchshadstyle) {
-
- shadow = spawn();
-
- self.shadowcontroller = shadow;
-
- shadow.classname = "misc_shadowcontroller";
- shadow.switchshadstyle = self.switchshadstyle;
- shadow.speed = vlen(self.pos2 - self.pos1) / self.speed;
-
- if(self.spawnflags & DOOR_START_OPEN) shadow.spawnflags = 1;
- else shadow.spawnflags = 0;
-
-
- oldself = self;
-
- self = shadow;
- misc_shadowcontroller();
-
- self = oldself;
- }
-};
-
-/*
-=============================================================================
-
-SECRET DOORS
-
-=============================================================================
-*/
-
-void() fd_secret_move1;
-void() fd_secret_move2;
-void() fd_secret_move3;
-void() fd_secret_move4;
-void() fd_secret_move5;
-void() fd_secret_move6;
-void() fd_secret_done;
-
-float SECRET_OPEN_ONCE = 1; // stays open
-float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
-float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
-float SECRET_NO_SHOOT = 8; // only opened by trigger
-float SECRET_YES_SHOOT = 16; // shootable even if targeted
-
-
-void () fd_secret_use =
-{
- local float temp;
-
- self.health = 10000;
-
- // exit if still moving around...
- if (self.origin != self.oldorigin)
- return;
-
- self.message = string_null; // no more message
-
- SUB_UseTargets(); // fire all targets / killtargets
-
- if (!(self.spawnflags & SECRET_NO_SHOOT))
- {
- self.th_pain = SUB_NullPain;
- self.takedamage = DAMAGE_NO;
- }
- self.velocity = '0 0 0';
-
- // Make a sound, wait a little...
-
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.nextthink = self.ltime + 0.1;
-
- temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
- makevectors(self.mangle);
-
- if (!self.t_width)
- {
- if (self.spawnflags & SECRET_1ST_DOWN)
- self. t_width = fabs(v_up * self.size);
- else
- self. t_width = fabs(v_right * self.size);
- }
-
- if (!self.t_length)
- self. t_length = fabs(v_forward * self.size);
-
- if (self.spawnflags & SECRET_1ST_DOWN)
- self.dest1 = self.origin - v_up * self.t_width;
- else
- self.dest1 = self.origin + v_right * (self.t_width * temp);
-
- self.dest2 = self.dest1 + v_forward * self.t_length;
- SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-};
-
-void(entity attacker, float damage) fd_secret_pain = { fd_secret_use(); };
-
-// Wait after first movement...
-void () fd_secret_move1 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move2;
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-// Start moving sideways w/sound...
-void () fd_secret_move2 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
-};
-
-// Wait here until time to go back...
-void () fd_secret_move3 =
-{
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- if (!(self.spawnflags & SECRET_OPEN_ONCE))
- {
- self.nextthink = self.ltime + self.wait;
- self.think = fd_secret_move4;
- }
-};
-
-// Move backward...
-void () fd_secret_move4 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
-};
-
-// Wait 1 second...
-void () fd_secret_move5 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move6;
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-void () fd_secret_move6 =
-{
- sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
-};
-
-void () fd_secret_done =
-{
- if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
- {
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- }
- sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-void () secret_blocked =
-{
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
-
-/*
-================
-ouch
-
-Prints messages
-================
-*/
-void() secret_touch =
-{
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.attack_finished > time)
- return;
-
- self.attack_finished = time + 2;
-
- if (self.message != "")
- {
- centerprint (other, self.message);
- sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
- }
-};
-
-
-/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Basic secret door. Slides back, then to the side. Angle determines direction.
-wait = # of seconds before coming back
-1st_left = 1st move is left of arrow
-1st_down = 1st move is down from arrow
-always_shoot = even if targeted, keep shootable
-t_width = override WIDTH to move back (or height if going down)
-t_length = override LENGTH to move sideways
-"dmg" damage to inflict when blocked (2 default)
-
-If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
-"sounds"
-1) medieval
-2) metal
-3) base
-*/
-
-void () func_door_secret =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.sounds == 0)
- self.sounds = 3;
- if (self.sounds == 1)
- {
- precache_sound ("doors/latch2.wav");
- precache_sound ("doors/winch2.wav");
- precache_sound ("doors/drclos4.wav");
- self.noise1 = "doors/latch2.wav";
- self.noise2 = "doors/winch2.wav";
- self.noise3 = "doors/drclos4.wav";
- }
- if (self.sounds == 2)
- {
- precache_sound ("doors/airdoor1.wav");
- precache_sound ("doors/airdoor2.wav");
- self.noise2 = "doors/airdoor1.wav";
- self.noise1 = "doors/airdoor2.wav";
- self.noise3 = "doors/airdoor2.wav";
- }
- if (self.sounds == 3)
- {
- precache_sound ("doors/basesec1.wav");
- precache_sound ("doors/basesec2.wav");
- self.noise2 = "doors/basesec1.wav";
- self.noise1 = "doors/basesec2.wav";
- self.noise3 = "doors/basesec2.wav";
- }
-
- if (!self.dmg)
- self.dmg = 2;
-
- // Magic formula...
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- //self.classname = "door";
- setmodel (self, self.model);
- setorigin (self, self.origin);
-
- self.touch = secret_touch;
- self.blocked = secret_blocked;
- self.speed = 50;
- self.use = fd_secret_use;
- if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
- {
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- self.th_die = fd_secret_use;
- }
- self.oldorigin = self.origin;
- if (!self.wait)
- self.wait = 5; // 5 seconds before closing
-};
+
+float DOOR_START_OPEN = 1;
+float DOOR_DONT_LINK = 4;
+float DOOR_GOLD_KEY = 8;
+float DOOR_SILVER_KEY = 16;
+float DOOR_TOGGLE = 32;
+float DOOR_DOOM_STYLE_UNLOCK = 64;
+/*
+
+Doors are similar to buttons, but can spawn a fat trigger field around them
+to open without a touch, and they link together to form simultanious
+double/quad doors.
+
+Door.owner is the master door. If there is only one door, it points to itself.
+If multiple doors, all will point to a single one.
+
+Door.enemy chains from the master door through all doors linked in the chain.
+
+*/
+
+/*
+=============================================================================
+
+THINK FUNCTIONS
+
+=============================================================================
+*/
+
+void() door_go_down;
+void() door_go_up;
+
+void() door_blocked =
+{
+ T_Damage (other, self, self, self.dmg);
+
+// if a door has a negative wait, it would never come back if blocked,
+// so let it just squash the object to death real fast
+ if (self.wait >= 0)
+ {
+ if (self.state == STATE_DOWN)
+ door_go_up ();
+ else
+ door_go_down ();
+ }
+};
+
+
+void() door_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+ if (self.spawnflags & DOOR_TOGGLE)
+ return; // don't come down automatically
+ self.think = door_go_down;
+ self.nextthink = self.ltime + self.wait;
+};
+
+void() door_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+};
+
+void() door_go_down =
+{
+ entity shadow;
+ entity oldself;
+
+ sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ if (self.max_health)
+ {
+ self.takedamage = DAMAGE_YES;
+ self.health = self.max_health;
+ }
+
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
+
+ if(self.switchshadstyle) {
+ shadow = self.shadowcontroller;
+ oldself = self;
+ self = shadow;
+
+ if(oldself.spawnflags & DOOR_START_OPEN) {
+ shadow_fade_out();
+ shadow.shadowoff = 1;
+ } else {
+ shadow_fade_in();
+ shadow.shadowoff = 0;
+ }
+
+ self = oldself;
+
+ }
+};
+
+void() door_go_up =
+{
+ entity shadow;
+ entity oldself;
+
+ if (self.state == STATE_UP)
+ return; // allready going up
+
+ if (self.state == STATE_TOP)
+ { // reset top wait time
+ self.nextthink = self.ltime + self.wait;
+ return;
+ }
+
+ sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos2, self.speed, door_hit_top);
+
+ SUB_UseTargets();
+
+ if(self.switchshadstyle) {
+ shadow = self.shadowcontroller;
+ oldself = self;
+ self = shadow;
+
+ if(oldself.spawnflags & DOOR_START_OPEN) {
+ shadow_fade_in();
+ shadow.shadowoff = 0;
+ } else {
+ shadow_fade_out();
+ shadow.shadowoff = 1;
+ }
+
+ self = oldself;
+ }
+};
+
+
+void() door_group_go_down = {
+ local entity oself, starte;
+
+ oself = self;
+ starte = self;
+
+ do
+ {
+ door_go_down ();
+ self = self.enemy;
+ } while ( (self != starte) && (self != world) );
+ self = oself;
+
+};
+
+void() door_group_go_up = {
+ local entity oself, starte;
+
+ oself = self;
+ starte = self;
+
+ do
+ {
+ door_go_up ();
+ self = self.enemy;
+ } while ( (self != starte) && (self != world) );
+
+ self = oself;
+};
+
+/*
+=============================================================================
+
+ACTIVATION FUNCTIONS
+
+=============================================================================
+*/
+
+void() door_fire =
+{
+
+ if (self.owner != self)
+ objerror ("door_fire: self.owner != self");
+
+ if (self.estate != STATE_ACTIVE)
+ return;
+// self.noise4 is now played in keylock_try_to_unlock -- iw
+
+ self.message = string_null; // no more message
+
+
+ if (self.spawnflags & DOOR_TOGGLE)
+ {
+ if (self.state == STATE_UP || self.state == STATE_TOP)
+ {
+ door_group_go_down();
+ return;
+ }
+ }
+
+ // trigger all paired doors
+ door_group_go_up();
+};
+
+
+void() door_use =
+{
+ local entity oself;
+
+ self.message = ""; // door message are for touch only
+ self.owner.message = "";
+ self.enemy.message = "";
+ oself = self;
+ self = self.owner;
+ door_fire ();
+ self = oself;
+};
+
+
+void() door_trigger_touch =
+{
+ if (other.health <= 0)
+ return;
+
+ if (other.movetype == MOVETYPE_NOCLIP) // from copper -- dumptruck_ds
+ return;
+
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 1;
+
+ activator = other;
+
+ self = self.owner;
+ door_use ();
+};
+
+
+void() door_killed =
+{
+ local entity oself;
+
+ oself = self;
+ self = self.owner;
+ self.health = self.max_health;
+ self.takedamage = DAMAGE_NO; // wil be reset upon return
+ door_use ();
+ self = oself;
+};
+
+
+/*
+================
+door_unlock
+
+Perform the actions which should be performed when self is successfully
+unlocked with a key.
+
+This function exists so that it can be passed as an argument to the new
+keylock_try_to_unlock function. This code was previously part of the
+door_touch function. -- iw
+================
+*/
+void() door_unlock =
+{
+ if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ {
+ self.touch = SUB_Null;
+ if (self.enemy)
+ self.enemy.touch = SUB_Null; // get paired door
+ }
+ door_use ();
+};
+
+
+/*
+================
+door_touch
+
+Prints messages and opens key doors
+================
+*/
+void() door_touch =
+{
+ // if (other.classname != "player")
+ // return;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.owner.attack_finished > time)
+ return;
+
+ self.owner.attack_finished = time + 2;
+
+ if (self.owner.message != "")
+ {
+ centerprint (other, self.owner.message);
+ sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
+ }
+
+// key door stuff
+ if (!keylock_has_key_set ())
+ return;
+
+ keylock_try_to_unlock (other, "", door_unlock);
+};
+
+
+
+/*
+=============================================================================
+ENTITY STATE FUNCTIONS
+=============================================================================
+*/
+
+void(entity e, float closealldoors) door_estate_lock = {
+ local entity oself, next;
+
+ if (e.owner.estate == STATE_INACTIVE) return;
+
+ // blocks linked doors from updating the same owner repeatedly
+ if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
+
+ oself = self;
+ self = e.owner;
+
+ self.estate = STATE_INACTIVE;
+
+ self.last_setstate = oself;
+ self.last_setstate_frame = framecount;
+
+ self.prevstate = self.state;
+
+ if (self.state == STATE_UP || self.state == STATE_TOP) {
+ if (
+ // don't close wait -1 nor toggleable doors...
+ !(self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
+ // ...unless the trigger_setstate has a "Close all doors" spawnflag on
+ || closealldoors
+ )
+ door_group_go_down();
+
+ }
+
+ if (self.max_health) {
+ next = self;
+ do {
+ //e.health = 0;
+ next.takedamage = DAMAGE_NO;
+ next = next.enemy;
+ } while ( (next != self) && (next != world) );
+ }
+
+ self = oself;
+
+}
+
+void(entity e, float openalldoors) door_estate_unlock = {
+ local entity oself, next;
+
+ if (e.owner.estate == STATE_ACTIVE) return;
+
+ // blocks linked doors from updating the same owner repeatedly
+ if (e.owner.last_setstate == self && e.owner.last_setstate_frame == framecount) return;
+
+ oself = self;
+ self = e.owner;
+
+ self.last_setstate = oself;
+ self.last_setstate_frame = framecount;
+
+ if (self.prevstate == STATE_UP || self.prevstate == STATE_TOP) {
+ if (
+ (self.wait == -1 || (self.spawnflags & DOOR_TOGGLE))
+ && openalldoors
+ ) door_group_go_up();
+ }
+
+ if (self.max_health) {
+ next = self;
+ do {
+ next.health = next.max_health;
+ next.takedamage = DAMAGE_YES;
+ next = next.enemy;
+ } while ( (next != self) && (next != world) );
+ }
+
+ self.estate = STATE_ACTIVE;
+ self = oself;
+}
+
+
+/*
+=============================================================================
+
+SPAWNING FUNCTIONS
+
+=============================================================================
+*/
+
+
+entity(vector fmins, vector fmaxs) spawn_field =
+{
+ local entity trigger;
+ local vector t1, t2;
+
+ trigger = spawn();
+ trigger.movetype = MOVETYPE_NONE;
+ trigger.solid = SOLID_TRIGGER;
+ trigger.owner = self;
+ trigger.touch = door_trigger_touch;
+
+ t1 = fmins;
+ t2 = fmaxs;
+ setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
+ return (trigger);
+};
+
+
+float (entity e1, entity e2) EntitiesTouching =
+{
+ if (e1.mins_x > e2.maxs_x)
+ return FALSE;
+ if (e1.mins_y > e2.maxs_y)
+ return FALSE;
+ if (e1.mins_z > e2.maxs_z)
+ return FALSE;
+ if (e1.maxs_x < e2.mins_x)
+ return FALSE;
+ if (e1.maxs_y < e2.mins_y)
+ return FALSE;
+ if (e1.maxs_z < e2.mins_z)
+ return FALSE;
+ return TRUE;
+};
+
+
+/*
+=============
+LinkDoors
+
+
+=============
+*/
+void() LinkDoors =
+{
+ local entity t, starte;
+ local vector cmins, cmaxs;
+
+ if (self.enemy)
+ return; // already linked by another door
+ if (self.spawnflags & 4)
+ {
+ self.owner = self.enemy = self;
+ return; // don't want to link this door
+ }
+
+ cmins = self.mins;
+ cmaxs = self.maxs;
+
+ starte = self;
+ t = self;
+
+ do
+ {
+ self.owner = starte; // master door
+
+ if (self.health)
+ starte.health = self.health;
+ if (self.targetname != "")
+ starte.targetname = self.targetname;
+ if (self.message != "")
+ starte.message = self.message;
+
+ t = find (t, classname, self.classname);
+ if (!t)
+ {
+ self.enemy = starte; // make the chain a loop
+
+ // shootable, fired, or key doors just needed the owner/enemy links,
+ // they don't spawn a field
+
+ self = self.owner;
+
+ if (self.health)
+ return;
+ if (self.targetname != "")
+ return;
+ if (keylock_has_key_set ())
+ return;
+
+ self.owner.trigger_field = spawn_field(cmins, cmaxs);
+
+ return;
+ }
+
+ if (EntitiesTouching(self,t))
+ {
+ if (t.enemy)
+ objerror ("cross connected doors");
+
+ self.enemy = t;
+ self = t;
+
+ if (t.mins_x < cmins_x)
+ cmins_x = t.mins_x;
+ if (t.mins_y < cmins_y)
+ cmins_y = t.mins_y;
+ if (t.mins_z < cmins_z)
+ cmins_z = t.mins_z;
+ if (t.maxs_x > cmaxs_x)
+ cmaxs_x = t.maxs_x;
+ if (t.maxs_y > cmaxs_y)
+ cmaxs_y = t.maxs_y;
+ if (t.maxs_z > cmaxs_z)
+ cmaxs_z = t.maxs_z;
+ }
+ } while (1 );
+
+};
+
+
+/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+if two doors touch, they are assumed to be connected and operate as a unit.
+
+TOGGLE causes the door to wait in both the start and end states for a trigger event.
+
+START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
+
+Key doors are always wait -1.
+
+"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
+"angle" determines the opening direction
+"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
+"health" if set, door must be shot open
+"speed" movement speed (100 default)
+"wait" wait before returning (3 default, -1 = never return)
+"lip" lip remaining at end of move (8 default)
+"dmg" damage to inflict when blocked (2 default)
+"cnt" if 1, leave a used key in the player's inventory (0 default)
+"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
+"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
+"noise2" sound file for the "move" sound (if set, overrides "sounds")
+"noise3" sound file for the "key required" sound (default is per worldtype)
+"noise4" sound file for the "key used" sound (default is per worldtype)
+"sounds"
+0) no sound
+1) stone
+2) base
+3) stone chain
+4) screechy metal
+*/
+
+void() func_door =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local string default_noise1;
+ local string default_noise2;
+ entity shadow;
+ entity oldself;
+
+// self.noise3 and self.noise4 can now be overridden by the mapper, but
+// will be set to default values in keylock_init if necessary -- iw
+ keylock_init ();
+
+// self.noise1 and self.noise2 can now be overridden by the mapper -- iw
+ default_noise1 = "misc/null.wav";
+ default_noise2 = "misc/null.wav";
+ if (self.sounds == 1)
+ {
+ default_noise1 = "doors/drclos4.wav";
+ default_noise2 = "doors/doormv1.wav";
+ }
+ if (self.sounds == 2)
+ {
+ default_noise1 = "doors/hydro2.wav";
+ default_noise2 = "doors/hydro1.wav";
+ }
+ if (self.sounds == 3)
+ {
+ default_noise1 = "doors/stndr2.wav";
+ default_noise2 = "doors/stndr1.wav";
+ }
+ if (self.sounds == 4)
+ {
+ default_noise1 = "doors/ddoor2.wav";
+ default_noise2 = "doors/ddoor1.wav";
+ }
+
+ if (self.noise1 == "")
+ self.noise1 = default_noise1;
+ if (self.noise2 == "")
+ self.noise2 = default_noise2;
+
+ precache_sound (self.noise1);
+ precache_sound (self.noise2);
+
+ SetMovedir ();
+
+ self.max_health = self.health;
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setorigin (self, self.origin);
+ setmodel (self, self.model);
+ //self.classname = "door";
+
+ self.blocked = door_blocked;
+ self.use = door_use;
+
+ if (self.spawnflags & DOOR_SILVER_KEY){
+ keylock_set_silver_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+ if (self.spawnflags & DOOR_GOLD_KEY){
+ keylock_set_gold_key ();
+
+ if (self.keyname != "") {
+ self.netname = self.keyname;
+ self.keyname = "";
+ }
+ }
+
+// support for item_key_custom -- iw
+ if (self.keyname != "")
+ {
+ keylock_set_custom_key (self.keyname);
+ self.keyname = ""; // this should not be referenced again
+ }
+
+ if (!self.speed)
+ self.speed = 100;
+ if (!self.wait)
+ self.wait = 3;
+ if (!self.lip)
+ self.lip = 8;
+ if (!self.dmg)
+ self.dmg = 2;
+
+ self.pos1 = self.origin;
+ self.pos2 = self.pos1 + self.movedir*(fabs(self.movedir*self.size) - self.lip);
+
+// DOOR_START_OPEN is to allow an entity to be lighted in the closed position
+// but spawn in the open position
+ if (self.spawnflags & DOOR_START_OPEN)
+ {
+ setorigin (self, self.pos2);
+ self.pos2 = self.pos1;
+ self.pos1 = self.origin;
+ }
+
+ self.state = STATE_BOTTOM;
+
+ if (self.health)
+ {
+ self.takedamage = DAMAGE_YES;
+ self.th_die = door_killed;
+ }
+
+ if (self.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
+ self.cnt = 1;
+
+ if (keylock_has_key_set ())
+ {
+ if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ {
+ self.wait = -1;
+ }
+ }
+ self.touch = door_touch;
+
+// LinkDoors can't be done until all of the doors have been spawned, so
+// the sizes can be detected properly.
+ self.think = LinkDoors;
+ self.nextthink = self.ltime + 0.1;
+
+ // creates a shadow controller entity for the door if it has switchable shadows
+ if(self.switchshadstyle) {
+
+ shadow = spawn();
+
+ self.shadowcontroller = shadow;
+
+ shadow.classname = "misc_shadowcontroller";
+ shadow.switchshadstyle = self.switchshadstyle;
+ shadow.speed = vlen(self.pos2 - self.pos1) / self.speed;
+
+ if(self.spawnflags & DOOR_START_OPEN) shadow.spawnflags = 1;
+ else shadow.spawnflags = 0;
+
+
+ oldself = self;
+
+ self = shadow;
+ misc_shadowcontroller();
+
+ self = oldself;
+ }
+};
+
+/*
+=============================================================================
+
+SECRET DOORS
+
+=============================================================================
+*/
+
+void() fd_secret_move1;
+void() fd_secret_move2;
+void() fd_secret_move3;
+void() fd_secret_move4;
+void() fd_secret_move5;
+void() fd_secret_move6;
+void() fd_secret_done;
+
+float SECRET_OPEN_ONCE = 1; // stays open
+float SECRET_1ST_LEFT = 2; // 1st move is left of arrow
+float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
+float SECRET_NO_SHOOT = 8; // only opened by trigger
+float SECRET_YES_SHOOT = 16; // shootable even if targeted
+
+
+void () fd_secret_use =
+{
+ local float temp;
+
+ self.health = 10000;
+
+ // exit if still moving around...
+ if (self.origin != self.oldorigin)
+ return;
+
+ self.message = string_null; // no more message
+
+ SUB_UseTargets(); // fire all targets / killtargets
+
+ if (!(self.spawnflags & SECRET_NO_SHOOT))
+ {
+ self.th_pain = SUB_NullPain;
+ self.takedamage = DAMAGE_NO;
+ }
+ self.velocity = '0 0 0';
+
+ // Make a sound, wait a little...
+
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.nextthink = self.ltime + 0.1;
+
+ temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
+ makevectors(self.mangle);
+
+ if (!self.t_width)
+ {
+ if (self.spawnflags & SECRET_1ST_DOWN)
+ self. t_width = fabs(v_up * self.size);
+ else
+ self. t_width = fabs(v_right * self.size);
+ }
+
+ if (!self.t_length)
+ self. t_length = fabs(v_forward * self.size);
+
+ if (self.spawnflags & SECRET_1ST_DOWN)
+ self.dest1 = self.origin - v_up * self.t_width;
+ else
+ self.dest1 = self.origin + v_right * (self.t_width * temp);
+
+ self.dest2 = self.dest1 + v_forward * self.t_length;
+ SUB_CalcMove(self.dest1, self.speed, fd_secret_move1);
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+};
+
+void(entity attacker, float damage) fd_secret_pain = { fd_secret_use(); };
+
+// Wait after first movement...
+void () fd_secret_move1 =
+{
+ self.nextthink = self.ltime + 1.0;
+ self.think = fd_secret_move2;
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+// Start moving sideways w/sound...
+void () fd_secret_move2 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.dest2, self.speed, fd_secret_move3);
+};
+
+// Wait here until time to go back...
+void () fd_secret_move3 =
+{
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+ if (!(self.spawnflags & SECRET_OPEN_ONCE))
+ {
+ self.nextthink = self.ltime + self.wait;
+ self.think = fd_secret_move4;
+ }
+};
+
+// Move backward...
+void () fd_secret_move4 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.dest1, self.speed, fd_secret_move5);
+};
+
+// Wait 1 second...
+void () fd_secret_move5 =
+{
+ self.nextthink = self.ltime + 1.0;
+ self.think = fd_secret_move6;
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+void () fd_secret_move6 =
+{
+ sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
+ SUB_CalcMove(self.oldorigin, self.speed, fd_secret_done);
+};
+
+void () fd_secret_done =
+{
+ if (!self.targetname || self.spawnflags&SECRET_YES_SHOOT)
+ {
+ self.health = 10000;
+ self.takedamage = DAMAGE_YES;
+ self.th_pain = fd_secret_pain;
+ }
+ sound(self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
+};
+
+void () secret_blocked =
+{
+ if (time < self.attack_finished)
+ return;
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+};
+
+/*
+================
+ouch
+
+Prints messages
+================
+*/
+void() secret_touch =
+{
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.attack_finished > time)
+ return;
+
+ self.attack_finished = time + 2;
+
+ if (self.message != "")
+ {
+ centerprint (other, self.message);
+ sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
+ }
+};
+
+
+/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Basic secret door. Slides back, then to the side. Angle determines direction.
+wait = # of seconds before coming back
+1st_left = 1st move is left of arrow
+1st_down = 1st move is down from arrow
+always_shoot = even if targeted, keep shootable
+t_width = override WIDTH to move back (or height if going down)
+t_length = override LENGTH to move sideways
+"dmg" damage to inflict when blocked (2 default)
+
+If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
+"sounds"
+1) medieval
+2) metal
+3) base
+*/
+
+void () func_door_secret =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.sounds == 0)
+ self.sounds = 3;
+ if (self.sounds == 1)
+ {
+ precache_sound ("doors/latch2.wav");
+ precache_sound ("doors/winch2.wav");
+ precache_sound ("doors/drclos4.wav");
+ self.noise1 = "doors/latch2.wav";
+ self.noise2 = "doors/winch2.wav";
+ self.noise3 = "doors/drclos4.wav";
+ }
+ if (self.sounds == 2)
+ {
+ precache_sound ("doors/airdoor1.wav");
+ precache_sound ("doors/airdoor2.wav");
+ self.noise2 = "doors/airdoor1.wav";
+ self.noise1 = "doors/airdoor2.wav";
+ self.noise3 = "doors/airdoor2.wav";
+ }
+ if (self.sounds == 3)
+ {
+ precache_sound ("doors/basesec1.wav");
+ precache_sound ("doors/basesec2.wav");
+ self.noise2 = "doors/basesec1.wav";
+ self.noise1 = "doors/basesec2.wav";
+ self.noise3 = "doors/basesec2.wav";
+ }
+
+ if (!self.dmg)
+ self.dmg = 2;
+
+ // Magic formula...
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ //self.classname = "door";
+ setmodel (self, self.model);
+ setorigin (self, self.origin);
+
+ self.touch = secret_touch;
+ self.blocked = secret_blocked;
+ self.speed = 50;
+ self.use = fd_secret_use;
+ if ( !self.targetname || self.spawnflags&SECRET_YES_SHOOT)
+ {
+ self.health = 10000;
+ self.takedamage = DAMAGE_YES;
+ self.th_pain = fd_secret_pain;
+ self.th_die = fd_secret_use;
+ }
+ self.oldorigin = self.origin;
+ if (!self.wait)
+ self.wait = 5; // 5 seconds before closing
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/dtmisc.qc

diff --git a/qc/dtmisc.qc b/qc/dtmisc.qc
index c850f83..8519097 100644
--- a/qc/dtmisc.qc
+++ b/qc/dtmisc.qc
@@ -1,1176 +1,1176 @@
-//a collection of various pieces of mods and some new code -- dumptruck_ds
-
-/* Miscelanneous QuickC program
- Copyright (c)1996 Hipnotic Interactive, Inc.
- All rights reserved.
- Distributed (unsupported) on 3.12.97
-*/
-
-void() play_sound_use =
- {
- if (self.spawnflags & 1)
- {
- if (self.state == 0)
- {
- self.state = 1;
- sound (self, self.impulse, self.noise, self.volume, self.speed);
- }
- else
- {
- self.state = 0;
- sound (self, self.impulse, "misc/null.wav", self.volume, self.speed);
- }
- }
- else
- {
- sound (self, self.impulse, self.noise, self.volume, self.speed);
- }
- };
-
-void() PlaySoundThink =
- {
- local float t;
- t = self.wait * random();
- if (t < self.delay)
- t = self.delay;
- self.nextthink = time + t;
- play_sound_use();
- };
-
-/*QUAKED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) toggle
-play a sound when it is used
-"toggle" determines whether sound should be stopped when triggered again
-"volume" how loud (1 default full volume)
-"noise" sound to play
-"impulse" channel on which to play sound (0-7) (0 automatic is default)
-"speed" attenuation factor
- -1 - no attenuation
- 1 - normal
- 2 - idle
- 3 - static
-*/
-void() play_sound_triggered =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
- precache_sound (self.noise);
- precache_sound ("misc/null.wav");
- if (self.volume == 0)
- self.volume = 1;
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
- if (self.spawnflags & 1)
- if (self.impulse == 0)
- self.impulse = 7;
- self.use = play_sound_use;
- };
-
-/*QUAKED play_sound (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
-play a sound on a periodic basis
-"volume" how loud (1 default full volume)
-"noise" sound to play
-"wait" random time between sounds (default 20)
-"delay" minimum delay between sounds (default 2)
-"impulse" channel on which to play sound (0-7) (0 automatic is default)
-"speed" attenuation factor
- -1 - no attenuation
- 1 - normal
- 2 - idle
- 3 - static
-*/
-void() play_sound =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float t;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
-
- play_sound_triggered();
- if (self.wait == 0)
- self.wait = 20;
- if (self.delay == 0)
- self.delay = 2;
- self.think = PlaySoundThink;
- t = self.wait * random();
- if (t < self.delay)
- t = self.delay;
- self.nextthink = time + t;
- };
-
-
- //johnfitz -- ambient_general (this is from Rubicon Rumble dev kit)
-
-/*QUAKED ambient_general (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Plays any looped sound
-
-Keys:
-
-"noise" is the wav file to play
-
-"volume" default 1
-
-"speed" attenuation, default 3
-*/
-void () ambient_general =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.noise) //dumptruck_ds
- {
- objerror ("no soundfile set in noise!\n");
- remove(self);
- return;
- }
-
- precache_sound (self.noise);
- if (!self.speed)
- {
- self.speed = ATTN_NORM;
- }
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
- if (!self.volume)
- {
- self.volume = 0.5;
- }
- ambientsound (self.origin, self.noise, self.volume, self.speed);
- remove(self);
-};
-//johnfitz
-
-/*QUAKED tele_fog (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, tele_fog shows the teleport particle effects and sounds.
-
-Use this when killtageting an entity if the player can see.
-
-*/
-
-void () play_tfog = //thanks Khreathor -- dumptruck_ds
-
-{
- spawn_tfog(self.origin);
-}
-
-void() tele_fog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_tfog;
-};
-
-/*QUAKED play_tele (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, tele_fog shows the teleport particle effects and sounds.
-Same os tele_fog.
-
-Use this when killtageting an entity if the player can see.
-
-*/
-void() play_tele = //same as tele_fog, added for "play_xxxx" consistancy
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_tfog;
-};
-
-/*QUAKED play_explosion (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, creates a explosion at it's origin. Causes damage.
-
-*/
-
-void () play_explosion_fx = //thanks Khreathor -- dumptruck_ds
-
-{
- self.owner = self; // GrenadeExplode uses self.owner as the attacker -- iw
- GrenadeExplode();
-}
-
-void() play_explosion =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_explosion_fx;
-};
-
-/*QUAKED play_lavasplash (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays the lavasplash effect from E1M7.
-
-Use noise key for a custom sound.
-
-*/
-
-void () play_lavasplash_fx = //thanks Khreathor -- dumptruck_ds
-{
- if (self.noise != "")
- {
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
- }
-WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
-WriteCoord (MSG_BROADCAST, self.origin_x);
-WriteCoord (MSG_BROADCAST, self.origin_y);
-WriteCoord (MSG_BROADCAST, self.origin_z);
-};
-
-void () play_lavasplash =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.noise != "") precache_sound (self.noise);
- precache_sound("boss1/out1.wav");
- self.use = play_lavasplash_fx;
-};
-
-/*QUAKED meat_shower (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays a gib effect.
-
-Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
-
-*/
-
-void () play_meatspray = //-- dumptruck_ds -- thanks to Spike for helping with errors
-{
- if (self.style == 1)
- {
- ThrowGib ("progs/gib1.mdl", random()*-80);
- ThrowGib ("progs/gib2.mdl", random()*-80);
- ThrowGib ("progs/gib3.mdl", random()*-80);
- ThrowGib ("progs/gib1.mdl", random()*-75);
- ThrowGib ("progs/gib2.mdl", random()*-75);
- ThrowGib ("progs/gib3.mdl", random()*-75);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", random()*-65);
- ThrowGib ("progs/gib2.mdl", random()*-65);
- ThrowGib ("progs/gib3.mdl", random()*-65);
- }
- {
- if (self.fly_sound != 1)
- return;
- }
- {
- if (random() < 0.5)
- sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-}
-};
-
-void() meat_shower =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_meatspray;
-}
-
-/*QUAKED play_gibs (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-
-When triggered, plays a gib effect. Same as meat_shower.
-
-Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
-
-*/
-void() play_gibs = //same as meat_shower, added for "play_xxxx" consistancy
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = play_meatspray;
-}
-
-void() mflash_use =
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-};
-
-/*QUAKED play_mflash (0 .5 .8) (-8 -8 -8) (8 8 8)
-triggable muzzle flash effect entity
-*/
-
-void() play_mflash =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- self.use = mflash_use;
-};
-
-//
-// play_bfield triggerable effect
-//
-
-void() bfield_toggle =
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTFIELD;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTFIELD);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_bfield (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable, spherical field of yellow particles
-state 1 = start on
-*/
-
-void() play_bfield =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin( self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTFIELD;
- self.use = bfield_toggle;
-};
-
-//
-// play_brlight triggerable effect
-//
-
-void() brlight_toggle = //dumptruck_ds -- thanks to c0burn
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_brlight (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable bright lighting effect
-state 1 = start on
-*/
-
-void() play_brlight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTLIGHT;
- self.use = brlight_toggle;
-};
-//
-// play_dimlight triggerable effect
-//
-void() dim_toggle =
-{
- if (!self.state)
- {
- self.state = 1;
- self.effects = self.effects | EF_DIMLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
-};
-
-/*QUAKED play_dimlight (0 .5 .8) (-8 -8 -8) (8 8 8)
-a triggerable lighting effect
-state 1 = start on
-*/
-
-void() play_dimlight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "") precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- // setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_DIMLIGHT;
- setorigin (self, self.origin);
- self.use = dim_toggle;
-};
-
-/* misc gore */
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-/*
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-deadstuff version 1.0 - tony collen - manero@canweb.net - EfNet IRC #QuakeEd or #Trinity
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-*/
-
-/*QUAKED gib_head_demon (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_demon.mdl");
-}
-*/
-void() gib_head_demon =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_demon.mdl");
- setmodel(self, "progs/h_demon.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-13.64 -16.77 -0.11','17.44 16.22 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_dog (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_dog.mdl");
-}
-*/
-void() gib_head_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_dog.mdl");
- setmodel(self, "progs/h_dog.mdl");
- self.frame = 0; //was 1 -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_army (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_guard.mdl");
-}
-*/
-void() gib_head_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_guard.mdl");
- setmodel(self, "progs/h_guard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_hell_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_hellkn.mdl");
-}*/
-void() gib_head_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_hellkn.mdl");
- setmodel(self, "progs/h_hellkn.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_knight.mdl");
-}*/
-void() gib_head_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_knight.mdl");
- setmodel(self, "progs/h_knight.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-8.17 -7.47 -0.13','8.36 6.5 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_enforcer (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_mega.mdl");
-}
-*/
-void() gib_head_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_mega.mdl");
- setmodel(self, "progs/h_mega.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-10.63 -10.23 -0.05','9.27 8.25 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_ogre (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_ogre.mdl");
-}*/
-void() gib_head_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_ogre.mdl");
- setmodel(self, "progs/h_ogre.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-12.35 -15.7 -0.17','10.67 13.88 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_player.mdl");
-}*/
-void() gib_head_player =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_player.mdl");
- setmodel(self, "progs/h_player.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-9.67 -12.38 -2.1','11.49 50.7 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_shal.mdl");
-}*/
-void() gib_head_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_shal.mdl");
- setmodel(self, "progs/h_shal.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-19.85 -19.09 -1.44','13.72 16.8 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_shambler (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_shams.mdl");
-}*/
-void() gib_head_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_shams.mdl");
- setmodel(self, "progs/h_shams.mdl");
- self.frame = 0; //was 1, caused an error -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-15.15 -20.638 -0.45','21.44 21.76 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_head_wizard (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/h_wizard.mdl");
-}*/
-void() gib_head_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/h_wizard.mdl");
- setmodel(self, "progs/h_wizard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-10.41 -8.66 -0.54','6.52 10.82 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib1.mdl");
-}*/
-void() gib_misc_1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib1.mdl");
- setmodel(self, "progs/gib1.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-3.57 -8.06 -3.34','3.69 8.31 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib2.mdl");
-}*/
-void() gib_misc_2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib2.mdl");
- setmodel(self, "progs/gib2.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-12.68 -14.83 -6.19','13.53 14.57 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-
-/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/gib3.mdl");
-}*/
-void() gib_misc_3 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/gib3.mdl");
- setmodel(self, "progs/gib3.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-18.95 -15.92 -3.13','13.17 15.66 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
-/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-// /*==============================================================================
-// func_fall from RennyC
-//
-// A brush that drops and fades away when touched or triggered.
-//
-// dumptruck_ds
-// noise = sound to play when triggered
-// wait = wait this long before falling
-// ==============================================================================*/
-float DONT_FADE = 1;
-float SILENT = 2;
-
-void() func_fall_think =
-{
- if (self.cnt == TRUE && self.attack_finished < time)
- {
- self.solid = SOLID_BBOX;
- // self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_TOSS;
-
- if (!(self.spawnflags & DONT_FADE))
- {
-
- if (self.alpha > 0.1)
- self.alpha = self.alpha - 0.03;
- else
- {
- remove(self);
- return;
- }
- }
- }
- self.nextthink = time + 0.1;
-};
-
-void() fall_touch =
-{
- if (other.classname == "player")
- {
- if (!(other.flags & FL_ONGROUND))
- other.flags = other.flags | FL_ONGROUND;
- }
-
- else if (other.flags & FL_MONSTER)
- T_Damage (other, self, other, 50000);
-
- else
- return;
-
- if (self.cnt == TRUE)
- return;
-
- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
-
- if (!(self.spawnflags & SILENT))
- {
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
- }
-};
-
-void() fall_use = // thanks again RennyC for help on revisions --dumptruck_ds
- {
- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
- };
-
-/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A brush that drops and fades away when touched and/or triggered.
-Add some spice to your jumping puzzles or other scripted sequences!
-Monsters will not trigger func_fall but will be gibbed if one falls on them.
-NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
-noise = sound to play when triggered, the default is a switch sound.
-wait = wait this long before falling.
-Use the DONT_FADE spawnflag if desired.
-
-Falling brush upon touch
-*/
-
-void() func_fall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound("buttons/switch21.wav");
- if (self.noise != "") precache_sound (self.noise);
-
-
- self.alpha = 1;
- self.cnt = FALSE;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.think = func_fall_think;
- self.nextthink = time;
- self.touch = fall_touch;
- self.use = fall_use;
- setmodel (self, self.model);
-};
-
-//=START PARTICLE-STREAM==================================================
-// from Zerstrorer mod -- dumptruck_ds
-
-void(vector start, vector end, float color1, float color2, float pdensity) Particle_Beam =
-{
-local vector spray, next;
-local float dist, loop, clr;
-
- clr = color1;
- spray = start - end;
- dist = vlen(spray);
- loop = dist / 24;
- spray = normalize(spray);
- next = spray * 24;
- while(loop > 0)
- {
- particle (end, spray, clr, pdensity);
- end = end + next;
- loop = loop - 1;
- if (clr == color1)
- clr = color2;
- else
- clr = color1;
- }
-};
-
-
-void() particle_use =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- Particle_Beam(self.origin, self.enemy.origin, self.dmg, self.cnt, 15); // was 40 - too many particles for my taste --dumptruck_ds
-};
-
-void() particle_stream_start =
-{
-local entity pspot;
-
- pspot = find(world, targetname, self.target);
- if(!pspot)
- {
- dprint("Particle stream can't find target!");
- return;
- }
-
- self.enemy = pspot;
-};
-
-/*QUAKED misc_particle_stream (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A particle stream! It appears when triggered. This entity is
-one end of the stream, target another entity as the other end-point.
-I used the info_notnull, but you should be able to target anything
-(like monsters).
-
-"target" This entities origin is the end-point of the stream
-"dmg" 1st Color - Use if you want a single color stream
-"cnt" 2nd Color - Mixes particles of both colors
-"noise" Sound to play when triggered
-*/
-void() misc_particle_stream =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if(!self.target)
- objerror("misc_particle_stream with not target!");
-
- if(!self.dmg)
- self.dmg = 73;
- if(!self.cnt)
- self.cnt = self.dmg;
- if(!self.noise)
- self.noise = "misc/null.wav";
-
- precache_sound(self.noise);
-
- self.use = particle_use;
- self.think = particle_stream_start;
- self.nextthink = time + 0.2;
-};
-// from custents, modified by dumptruck_ds
-//##########################################
-//#### HEAL TRIGGER ####
-//##########################################
-// Original entity submitted by Jan Martin Mathiassen, aka. TGR
-
-void() heal_think =
-{
- if (self.cnt == self.count)
- {
- dprint("trigger_heal think: full\n");
- self.think = SUB_Null;
- return;
- }
- local float recharge_amount = self.speed;
- if (self.count < (self.cnt + self.speed))
- {
- recharge_amount = self.count - self.cnt;
- }
- dprint("trigger_heal think: [max: ");
- dprint(ftos(self.count));
- dprint(", current: ");
- dprint(ftos(self.cnt));
- dprint(", recharging: ");
- dprint(ftos(recharge_amount));
- dprint("]\n");
-
- self.cnt = self.cnt + recharge_amount;
- self.nextthink = time + self.delay;
-};
-
-void() heal_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
- if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
- return FALSE;
- if(self.spawnflags & HEAL_PLAYER_ONLY && other.classname != "player")
- return;
- if(self.spawnflags & HEAL_MONSTER_ONLY && !(other.flags & FL_MONSTER))
- return;
- if(other.classname != "player" && !(other.flags & FL_MONSTER))
- return;
-
- if(other.heal_timer > time)
- return;
-
- if(self.count && self.cnt <= 0)
- {
- if(self.message2)
- centerprint(other, self.message2);
- return;
- }
-
- if ((other.takedamage) && (other.health < self.health_max))
- {
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "items/r_item1.wav", 1, ATTN_NORM);
- local float calculated_healing;
- if ((other.health + self.heal_amount) > self.health_max)
- {
- calculated_healing = self.health_max - other.health;
- }
- else
- {
- calculated_healing = self.heal_amount;
- }
-
- if (self.count)
- {
-
- if (calculated_healing > self.cnt)
- {
- calculated_healing = self.cnt;
- }
- self.cnt = self.cnt - calculated_healing;
- if (self.delay)
- {
- self.think = heal_think;
- self.nextthink = time + self.delay;
- }
- dprint("trigger_heal used: [max: ");
- dprint(ftos(self.count));
- dprint(", current: ");
- dprint(ftos(self.cnt));
- dprint(", using: ");
- dprint(ftos(calculated_healing));
- dprint("]\n");
- }
- if (self.message)
- {
- centerprint(other, self.message);
- }
- T_Heal (other, calculated_healing, 1);
- other.heal_timer = time + self.wait;
- }
-};
-
-void() heal_toggle=
-{
- if(self.touch == SUB_Null)
- self.touch = heal_touch;
- else
- self.touch = SUB_Null;
-};
-
-/*QUAKED trigger_heal (.5 .5 .5) ? HEAL_START_ON HEAL_PLAYER_ONLY HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Any object touching this will be healed
-heal_amount -- the amount to heal each time (default 5)
-wait -- the time between each healing (default 1)
-health_max -- the upper limit for the healing (default 100, max 250)
-sounds -- set to 1 to enable the noise1 field for custom healing sound
-noise -- path to custom sound file
-message -- message to print on heal
-count -- maximum heal before exhausted
-speed -- amount to recharge at a time
-delay -- time before recharging
-message2 -- message to print when exhausted
-*/
-void() trigger_heal =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- //play custom sound for healing if noise key exists
- precache_sound("items/r_item1.wav");
- if (self.noise != "") precache_sound (self.noise);
-
- InitTrigger ();
-
- if (self.wait == 0)
- self.wait = 1;
- if (self.heal_amount == 0)
- self.heal_amount = 5;
- if (self.health_max == 0)
- self.health_max = 100;
- else if (self.health_max > 250)
- self.health_max = 250;
-
- if (self.count)
- {
- self.cnt = self.count;
-
- if (self.speed && !self.delay)
- {
- self.delay = 10;
- } else if (!self.speed && self.delay)
- {
- self.speed = 5;
- }
- }
-
- // if(self.targetname)
- // {
- // self.use = heal_toggle;
- // if(self.spawnflags & HEAL_START_ON)
- // self.touch = heal_touch;
- // else
- // self.touch = SUB_Null;
- // }
- // else
- self.touch = heal_touch;
-
- SUB_CheckWaiting();
-};
+//a collection of various pieces of mods and some new code -- dumptruck_ds
+
+/* Miscelanneous QuickC program
+ Copyright (c)1996 Hipnotic Interactive, Inc.
+ All rights reserved.
+ Distributed (unsupported) on 3.12.97
+*/
+
+void() play_sound_use =
+ {
+ if (self.spawnflags & 1)
+ {
+ if (self.state == 0)
+ {
+ self.state = 1;
+ sound (self, self.impulse, self.noise, self.volume, self.speed);
+ }
+ else
+ {
+ self.state = 0;
+ sound (self, self.impulse, "misc/null.wav", self.volume, self.speed);
+ }
+ }
+ else
+ {
+ sound (self, self.impulse, self.noise, self.volume, self.speed);
+ }
+ };
+
+void() PlaySoundThink =
+ {
+ local float t;
+ t = self.wait * random();
+ if (t < self.delay)
+ t = self.delay;
+ self.nextthink = time + t;
+ play_sound_use();
+ };
+
+/*QUAKED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) toggle
+play a sound when it is used
+"toggle" determines whether sound should be stopped when triggered again
+"volume" how loud (1 default full volume)
+"noise" sound to play
+"impulse" channel on which to play sound (0-7) (0 automatic is default)
+"speed" attenuation factor
+ -1 - no attenuation
+ 1 - normal
+ 2 - idle
+ 3 - static
+*/
+void() play_sound_triggered =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+ precache_sound (self.noise);
+ precache_sound ("misc/null.wav");
+ if (self.volume == 0)
+ self.volume = 1;
+ if (self.speed == 0)
+ self.speed = 1;
+ if (self.speed == -1)
+ // self.speed = 0;
+ self.speed = ATTN_NONE;
+ if (self.spawnflags & 1)
+ if (self.impulse == 0)
+ self.impulse = 7;
+ self.use = play_sound_use;
+ };
+
+/*QUAKED play_sound (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
+play a sound on a periodic basis
+"volume" how loud (1 default full volume)
+"noise" sound to play
+"wait" random time between sounds (default 20)
+"delay" minimum delay between sounds (default 2)
+"impulse" channel on which to play sound (0-7) (0 automatic is default)
+"speed" attenuation factor
+ -1 - no attenuation
+ 1 - normal
+ 2 - idle
+ 3 - static
+*/
+void() play_sound =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float t;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+
+ play_sound_triggered();
+ if (self.wait == 0)
+ self.wait = 20;
+ if (self.delay == 0)
+ self.delay = 2;
+ self.think = PlaySoundThink;
+ t = self.wait * random();
+ if (t < self.delay)
+ t = self.delay;
+ self.nextthink = time + t;
+ };
+
+
+ //johnfitz -- ambient_general (this is from Rubicon Rumble dev kit)
+
+/*QUAKED ambient_general (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Plays any looped sound
+
+Keys:
+
+"noise" is the wav file to play
+
+"volume" default 1
+
+"speed" attenuation, default 3
+*/
+void () ambient_general =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.noise) //dumptruck_ds
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove(self);
+ return;
+ }
+
+ precache_sound (self.noise);
+ if (!self.speed)
+ {
+ self.speed = ATTN_NORM;
+ }
+ if (self.speed == 0)
+ self.speed = 1;
+ if (self.speed == -1)
+ // self.speed = 0;
+ self.speed = ATTN_NONE;
+ if (!self.volume)
+ {
+ self.volume = 0.5;
+ }
+ ambientsound (self.origin, self.noise, self.volume, self.speed);
+ remove(self);
+};
+//johnfitz
+
+/*QUAKED tele_fog (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, tele_fog shows the teleport particle effects and sounds.
+
+Use this when killtageting an entity if the player can see.
+
+*/
+
+void () play_tfog = //thanks Khreathor -- dumptruck_ds
+
+{
+ spawn_tfog(self.origin);
+}
+
+void() tele_fog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_tfog;
+};
+
+/*QUAKED play_tele (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, tele_fog shows the teleport particle effects and sounds.
+Same os tele_fog.
+
+Use this when killtageting an entity if the player can see.
+
+*/
+void() play_tele = //same as tele_fog, added for "play_xxxx" consistancy
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_tfog;
+};
+
+/*QUAKED play_explosion (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, creates a explosion at it's origin. Causes damage.
+
+*/
+
+void () play_explosion_fx = //thanks Khreathor -- dumptruck_ds
+
+{
+ self.owner = self; // GrenadeExplode uses self.owner as the attacker -- iw
+ GrenadeExplode();
+}
+
+void() play_explosion =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_explosion_fx;
+};
+
+/*QUAKED play_lavasplash (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays the lavasplash effect from E1M7.
+
+Use noise key for a custom sound.
+
+*/
+
+void () play_lavasplash_fx = //thanks Khreathor -- dumptruck_ds
+{
+ if (self.noise != "")
+ {
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
+ }
+WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+WriteCoord (MSG_BROADCAST, self.origin_x);
+WriteCoord (MSG_BROADCAST, self.origin_y);
+WriteCoord (MSG_BROADCAST, self.origin_z);
+};
+
+void () play_lavasplash =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.noise != "") precache_sound (self.noise);
+ precache_sound("boss1/out1.wav");
+ self.use = play_lavasplash_fx;
+};
+
+/*QUAKED meat_shower (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays a gib effect.
+
+Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
+
+*/
+
+void () play_meatspray = //-- dumptruck_ds -- thanks to Spike for helping with errors
+{
+ if (self.style == 1)
+ {
+ ThrowGib ("progs/gib1.mdl", random()*-80);
+ ThrowGib ("progs/gib2.mdl", random()*-80);
+ ThrowGib ("progs/gib3.mdl", random()*-80);
+ ThrowGib ("progs/gib1.mdl", random()*-75);
+ ThrowGib ("progs/gib2.mdl", random()*-75);
+ ThrowGib ("progs/gib3.mdl", random()*-75);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", random()*-65);
+ ThrowGib ("progs/gib2.mdl", random()*-65);
+ ThrowGib ("progs/gib3.mdl", random()*-65);
+ }
+ {
+ if (self.fly_sound != 1)
+ return;
+ }
+ {
+ if (random() < 0.5)
+ sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+}
+};
+
+void() meat_shower =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_meatspray;
+}
+
+/*QUAKED play_gibs (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+
+When triggered, plays a gib effect. Same as meat_shower.
+
+Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.
+
+*/
+void() play_gibs = //same as meat_shower, added for "play_xxxx" consistancy
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = play_meatspray;
+}
+
+void() mflash_use =
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+};
+
+/*QUAKED play_mflash (0 .5 .8) (-8 -8 -8) (8 8 8)
+triggable muzzle flash effect entity
+*/
+
+void() play_mflash =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ self.use = mflash_use;
+};
+
+//
+// play_bfield triggerable effect
+//
+
+void() bfield_toggle =
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_BRIGHTFIELD;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_BRIGHTFIELD);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_bfield (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable, spherical field of yellow particles
+state 1 = start on
+*/
+
+void() play_bfield =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin( self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_BRIGHTFIELD;
+ self.use = bfield_toggle;
+};
+
+//
+// play_brlight triggerable effect
+//
+
+void() brlight_toggle = //dumptruck_ds -- thanks to c0burn
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_BRIGHTLIGHT;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_BRIGHTLIGHT);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_brlight (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable bright lighting effect
+state 1 = start on
+*/
+
+void() play_brlight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_BRIGHTLIGHT;
+ self.use = brlight_toggle;
+};
+//
+// play_dimlight triggerable effect
+//
+void() dim_toggle =
+{
+ if (!self.state)
+ {
+ self.state = 1;
+ self.effects = self.effects | EF_DIMLIGHT;
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ self.state = 0;
+ self.effects = self.effects - (self.effects & EF_DIMLIGHT);
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ }
+};
+
+/*QUAKED play_dimlight (0 .5 .8) (-8 -8 -8) (8 8 8)
+a triggerable lighting effect
+state 1 = start on
+*/
+
+void() play_dimlight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/s_null.spr");
+ if (self.noise != "") precache_sound (self.noise);
+
+ setmodel (self, "progs/s_null.spr");
+ // setorigin (self, self.origin);
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setsize (self, '0 0 0', '0 0 0');
+ if (self.state)
+ self.effects = self.effects | EF_DIMLIGHT;
+ setorigin (self, self.origin);
+ self.use = dim_toggle;
+};
+
+/* misc gore */
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+/*
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+deadstuff version 1.0 - tony collen - manero@canweb.net - EfNet IRC #QuakeEd or #Trinity
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+*/
+
+/*QUAKED gib_head_demon (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_demon.mdl");
+}
+*/
+void() gib_head_demon =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_demon.mdl");
+ setmodel(self, "progs/h_demon.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-13.64 -16.77 -0.11','17.44 16.22 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_dog (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_dog.mdl");
+}
+*/
+void() gib_head_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_dog.mdl");
+ setmodel(self, "progs/h_dog.mdl");
+ self.frame = 0; //was 1 -- dumptruck_ds
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_army (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_guard.mdl");
+}
+*/
+void() gib_head_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_guard.mdl");
+ setmodel(self, "progs/h_guard.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_hell_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_hellkn.mdl");
+}*/
+void() gib_head_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_hellkn.mdl");
+ setmodel(self, "progs/h_hellkn.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_knight.mdl");
+}*/
+void() gib_head_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_knight.mdl");
+ setmodel(self, "progs/h_knight.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-8.17 -7.47 -0.13','8.36 6.5 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_enforcer (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_mega.mdl");
+}
+*/
+void() gib_head_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_mega.mdl");
+ setmodel(self, "progs/h_mega.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-10.63 -10.23 -0.05','9.27 8.25 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_ogre (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_ogre.mdl");
+}*/
+void() gib_head_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_ogre.mdl");
+ setmodel(self, "progs/h_ogre.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-12.35 -15.7 -0.17','10.67 13.88 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_player.mdl");
+}*/
+void() gib_head_player =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_player.mdl");
+ setmodel(self, "progs/h_player.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-9.67 -12.38 -2.1','11.49 50.7 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_shal.mdl");
+}*/
+void() gib_head_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_shal.mdl");
+ setmodel(self, "progs/h_shal.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-19.85 -19.09 -1.44','13.72 16.8 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_shambler (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_shams.mdl");
+}*/
+void() gib_head_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_shams.mdl");
+ setmodel(self, "progs/h_shams.mdl");
+ self.frame = 0; //was 1, caused an error -- dumptruck_ds
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-15.15 -20.638 -0.45','21.44 21.76 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_head_wizard (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/h_wizard.mdl");
+}*/
+void() gib_head_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/h_wizard.mdl");
+ setmodel(self, "progs/h_wizard.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-10.41 -8.66 -0.54','6.52 10.82 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib1.mdl");
+}*/
+void() gib_misc_1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib1.mdl");
+ setmodel(self, "progs/gib1.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-3.57 -8.06 -3.34','3.69 8.31 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib2.mdl");
+}*/
+void() gib_misc_2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib2.mdl");
+ setmodel(self, "progs/gib2.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-12.68 -14.83 -6.19','13.53 14.57 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+
+/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/gib3.mdl");
+}*/
+void() gib_misc_3 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/gib3.mdl");
+ setmodel(self, "progs/gib3.mdl");
+ self.frame = 0;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-18.95 -15.92 -3.13','13.17 15.66 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};
+/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+// /*==============================================================================
+// func_fall from RennyC
+//
+// A brush that drops and fades away when touched or triggered.
+//
+// dumptruck_ds
+// noise = sound to play when triggered
+// wait = wait this long before falling
+// ==============================================================================*/
+float DONT_FADE = 1;
+float SILENT = 2;
+
+void() func_fall_think =
+{
+ if (self.cnt == TRUE && self.attack_finished < time)
+ {
+ self.solid = SOLID_BBOX;
+ // self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_TOSS;
+
+ if (!(self.spawnflags & DONT_FADE))
+ {
+
+ if (self.alpha > 0.1)
+ self.alpha = self.alpha - 0.03;
+ else
+ {
+ remove(self);
+ return;
+ }
+ }
+ }
+ self.nextthink = time + 0.1;
+};
+
+void() fall_touch =
+{
+ if (other.classname == "player")
+ {
+ if (!(other.flags & FL_ONGROUND))
+ other.flags = other.flags | FL_ONGROUND;
+ }
+
+ else if (other.flags & FL_MONSTER)
+ T_Damage (other, self, other, 50000);
+
+ else
+ return;
+
+ if (self.cnt == TRUE)
+ return;
+
+ self.attack_finished = time + self.wait;
+ self.cnt = TRUE;
+
+ if (!(self.spawnflags & SILENT))
+ {
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
+ }
+};
+
+void() fall_use = // thanks again RennyC for help on revisions --dumptruck_ds
+ {
+ self.attack_finished = time + self.wait;
+ self.cnt = TRUE;
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
+ };
+
+/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A brush that drops and fades away when touched and/or triggered.
+Add some spice to your jumping puzzles or other scripted sequences!
+Monsters will not trigger func_fall but will be gibbed if one falls on them.
+NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
+noise = sound to play when triggered, the default is a switch sound.
+wait = wait this long before falling.
+Use the DONT_FADE spawnflag if desired.
+
+Falling brush upon touch
+*/
+
+void() func_fall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound("buttons/switch21.wav");
+ if (self.noise != "") precache_sound (self.noise);
+
+
+ self.alpha = 1;
+ self.cnt = FALSE;
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ self.think = func_fall_think;
+ self.nextthink = time;
+ self.touch = fall_touch;
+ self.use = fall_use;
+ setmodel (self, self.model);
+};
+
+//=START PARTICLE-STREAM==================================================
+// from Zerstrorer mod -- dumptruck_ds
+
+void(vector start, vector end, float color1, float color2, float pdensity) Particle_Beam =
+{
+local vector spray, next;
+local float dist, loop, clr;
+
+ clr = color1;
+ spray = start - end;
+ dist = vlen(spray);
+ loop = dist / 24;
+ spray = normalize(spray);
+ next = spray * 24;
+ while(loop > 0)
+ {
+ particle (end, spray, clr, pdensity);
+ end = end + next;
+ loop = loop - 1;
+ if (clr == color1)
+ clr = color2;
+ else
+ clr = color1;
+ }
+};
+
+
+void() particle_use =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ Particle_Beam(self.origin, self.enemy.origin, self.dmg, self.cnt, 15); // was 40 - too many particles for my taste --dumptruck_ds
+};
+
+void() particle_stream_start =
+{
+local entity pspot;
+
+ pspot = find(world, targetname, self.target);
+ if(!pspot)
+ {
+ dprint("Particle stream can't find target!");
+ return;
+ }
+
+ self.enemy = pspot;
+};
+
+/*QUAKED misc_particle_stream (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A particle stream! It appears when triggered. This entity is
+one end of the stream, target another entity as the other end-point.
+I used the info_notnull, but you should be able to target anything
+(like monsters).
+
+"target" This entities origin is the end-point of the stream
+"dmg" 1st Color - Use if you want a single color stream
+"cnt" 2nd Color - Mixes particles of both colors
+"noise" Sound to play when triggered
+*/
+void() misc_particle_stream =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if(!self.target)
+ objerror("misc_particle_stream with not target!");
+
+ if(!self.dmg)
+ self.dmg = 73;
+ if(!self.cnt)
+ self.cnt = self.dmg;
+ if(!self.noise)
+ self.noise = "misc/null.wav";
+
+ precache_sound(self.noise);
+
+ self.use = particle_use;
+ self.think = particle_stream_start;
+ self.nextthink = time + 0.2;
+};
+// from custents, modified by dumptruck_ds
+//##########################################
+//#### HEAL TRIGGER ####
+//##########################################
+// Original entity submitted by Jan Martin Mathiassen, aka. TGR
+
+void() heal_think =
+{
+ if (self.cnt == self.count)
+ {
+ dprint("trigger_heal think: full\n");
+ self.think = SUB_Null;
+ return;
+ }
+ local float recharge_amount = self.speed;
+ if (self.count < (self.cnt + self.speed))
+ {
+ recharge_amount = self.count - self.cnt;
+ }
+ dprint("trigger_heal think: [max: ");
+ dprint(ftos(self.count));
+ dprint(", current: ");
+ dprint(ftos(self.cnt));
+ dprint(", recharging: ");
+ dprint(ftos(recharge_amount));
+ dprint("]\n");
+
+ self.cnt = self.cnt + recharge_amount;
+ self.nextthink = time + self.delay;
+};
+
+void() heal_touch =
+{
+ if (self.estate != STATE_ACTIVE)
+ return;
+ if (other.movetype == MOVETYPE_NOCLIP) // from Copper -- dumptruck_ds
+ return FALSE;
+ if(self.spawnflags & HEAL_PLAYER_ONLY && other.classname != "player")
+ return;
+ if(self.spawnflags & HEAL_MONSTER_ONLY && !(other.flags & FL_MONSTER))
+ return;
+ if(other.classname != "player" && !(other.flags & FL_MONSTER))
+ return;
+
+ if(other.heal_timer > time)
+ return;
+
+ if(self.count && self.cnt <= 0)
+ {
+ if(self.message2)
+ centerprint(other, self.message2);
+ return;
+ }
+
+ if ((other.takedamage) && (other.health < self.health_max))
+ {
+
+ if (self.noise != "")
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound (self, CHAN_AUTO, "items/r_item1.wav", 1, ATTN_NORM);
+ local float calculated_healing;
+ if ((other.health + self.heal_amount) > self.health_max)
+ {
+ calculated_healing = self.health_max - other.health;
+ }
+ else
+ {
+ calculated_healing = self.heal_amount;
+ }
+
+ if (self.count)
+ {
+
+ if (calculated_healing > self.cnt)
+ {
+ calculated_healing = self.cnt;
+ }
+ self.cnt = self.cnt - calculated_healing;
+ if (self.delay)
+ {
+ self.think = heal_think;
+ self.nextthink = time + self.delay;
+ }
+ dprint("trigger_heal used: [max: ");
+ dprint(ftos(self.count));
+ dprint(", current: ");
+ dprint(ftos(self.cnt));
+ dprint(", using: ");
+ dprint(ftos(calculated_healing));
+ dprint("]\n");
+ }
+ if (self.message)
+ {
+ centerprint(other, self.message);
+ }
+ T_Heal (other, calculated_healing, 1);
+ other.heal_timer = time + self.wait;
+ }
+};
+
+void() heal_toggle=
+{
+ if(self.touch == SUB_Null)
+ self.touch = heal_touch;
+ else
+ self.touch = SUB_Null;
+};
+
+/*QUAKED trigger_heal (.5 .5 .5) ? HEAL_START_ON HEAL_PLAYER_ONLY HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Any object touching this will be healed
+heal_amount -- the amount to heal each time (default 5)
+wait -- the time between each healing (default 1)
+health_max -- the upper limit for the healing (default 100, max 250)
+sounds -- set to 1 to enable the noise1 field for custom healing sound
+noise -- path to custom sound file
+message -- message to print on heal
+count -- maximum heal before exhausted
+speed -- amount to recharge at a time
+delay -- time before recharging
+message2 -- message to print when exhausted
+*/
+void() trigger_heal =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+ //play custom sound for healing if noise key exists
+ precache_sound("items/r_item1.wav");
+ if (self.noise != "") precache_sound (self.noise);
+
+ InitTrigger ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+ if (self.heal_amount == 0)
+ self.heal_amount = 5;
+ if (self.health_max == 0)
+ self.health_max = 100;
+ else if (self.health_max > 250)
+ self.health_max = 250;
+
+ if (self.count)
+ {
+ self.cnt = self.count;
+
+ if (self.speed && !self.delay)
+ {
+ self.delay = 10;
+ } else if (!self.speed && self.delay)
+ {
+ self.speed = 5;
+ }
+ }
+
+ // if(self.targetname)
+ // {
+ // self.use = heal_toggle;
+ // if(self.spawnflags & HEAL_START_ON)
+ // self.touch = heal_touch;
+ // else
+ // self.touch = SUB_Null;
+ // }
+ // else
+ self.touch = heal_touch;
+
+ SUB_CheckWaiting();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/dtquake.qc

diff --git a/qc/dtquake.qc b/qc/dtquake.qc
index e3b0c83..db407e7 100644
--- a/qc/dtquake.qc
+++ b/qc/dtquake.qc
@@ -1,103 +1,103 @@
-// /*this is a point entity from Rubicon Rumble Pack Devkit; REQUIRES A TARGETNAME*/
-//
-// // ===== TRIGGER_SHAKE =======================================================
-//
-float VIEWONLY = 1;
-
-void() shake_think =
-{
- if (self.attack_finished < time) // Done
- {
- self.nextthink = -1;
-
- if (self.noise1 != "")
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- return;
- }
-
- local entity plyr;
-
- // Shake all players in the effect radius...
-
- plyr = findradius(self.origin, self.count);
-
- while(plyr)
- {
- if (plyr.flags & FL_CLIENT)
- {
- local float d;
-
- // Scale effect by distance
- d = vlen(self.origin - plyr.origin);
- d = (self.count - d)/self.count;
-
- if (d > 0)
- {
- // shake up the view
- plyr.punchangle_x = -1 * (random() + (0.025*self.dmg*d));
-
- // push the player around
- if (plyr.flags & FL_ONGROUND && !(self.spawnflags & VIEWONLY))
- {
- d = self.dmg*d;
- plyr.velocity_x = plyr.velocity_x + (random()*d*2 - d);
- plyr.velocity_y = plyr.velocity_y + (random()*d*2 - d);
- plyr.velocity_z = plyr.velocity_z + (random()*d);// always push up
- }
- }
- }
-
- plyr = plyr.chain;
- }
-
- // keep going
- self.nextthink = time + 0.1;
-};
-
-void() shake_use =
-{
- if (self.attack_finished > time) return;// already active
-
- // Start...
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- self.attack_finished = time + self.wait;
- self.nextthink = time + 0.1;
-};
-
-/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Earthquake trigger - shakes players in it's radius when active.
-Strength of tremor is greatest at the centre.
-dmg Strength at center (default is 120)
-wait Duration of shake (default is 1)
-count Affect radius (defalt is 200)
-noise Noise to play when starting to shake
-noise1 Noise to play when stopping
-targetname Must be triggered
-Spawnflags
-VIEWONLY Shakes the view, but player movement is not affected
-*/
-void() trigger_shake =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.targetname) objerror("trigger_shake without name");
-
- if (self.noise != "") precache_sound (self.noise);
- if (self.noise1 != "") precache_sound (self.noise1);
-
- if (!self.dmg) self.dmg = 120;
- if (self.count <= 0) self.count = 200;
- if (self.wait <= 0) self.wait = 1.0;
-
- setorigin(self, self.origin);
-
- self.nextthink = -1;
- self.think = shake_think;
- self.use = shake_use;
-};
+// /*this is a point entity from Rubicon Rumble Pack Devkit; REQUIRES A TARGETNAME*/
+//
+// // ===== TRIGGER_SHAKE =======================================================
+//
+float VIEWONLY = 1;
+
+void() shake_think =
+{
+ if (self.attack_finished < time) // Done
+ {
+ self.nextthink = -1;
+
+ if (self.noise1 != "")
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ return;
+ }
+
+ local entity plyr;
+
+ // Shake all players in the effect radius...
+
+ plyr = findradius(self.origin, self.count);
+
+ while(plyr)
+ {
+ if (plyr.flags & FL_CLIENT)
+ {
+ local float d;
+
+ // Scale effect by distance
+ d = vlen(self.origin - plyr.origin);
+ d = (self.count - d)/self.count;
+
+ if (d > 0)
+ {
+ // shake up the view
+ plyr.punchangle_x = -1 * (random() + (0.025*self.dmg*d));
+
+ // push the player around
+ if (plyr.flags & FL_ONGROUND && !(self.spawnflags & VIEWONLY))
+ {
+ d = self.dmg*d;
+ plyr.velocity_x = plyr.velocity_x + (random()*d*2 - d);
+ plyr.velocity_y = plyr.velocity_y + (random()*d*2 - d);
+ plyr.velocity_z = plyr.velocity_z + (random()*d);// always push up
+ }
+ }
+ }
+
+ plyr = plyr.chain;
+ }
+
+ // keep going
+ self.nextthink = time + 0.1;
+};
+
+void() shake_use =
+{
+ if (self.attack_finished > time) return;// already active
+
+ // Start...
+
+ if (self.noise != "")
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ self.attack_finished = time + self.wait;
+ self.nextthink = time + 0.1;
+};
+
+/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Earthquake trigger - shakes players in it's radius when active.
+Strength of tremor is greatest at the centre.
+dmg Strength at center (default is 120)
+wait Duration of shake (default is 1)
+count Affect radius (defalt is 200)
+noise Noise to play when starting to shake
+noise1 Noise to play when stopping
+targetname Must be triggered
+Spawnflags
+VIEWONLY Shakes the view, but player movement is not affected
+*/
+void() trigger_shake =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.targetname) objerror("trigger_shake without name");
+
+ if (self.noise != "") precache_sound (self.noise);
+ if (self.noise1 != "") precache_sound (self.noise1);
+
+ if (!self.dmg) self.dmg = 120;
+ if (self.count <= 0) self.count = 200;
+ if (self.wait <= 0) self.wait = 1.0;
+
+ setorigin(self, self.origin);
+
+ self.nextthink = -1;
+ self.think = shake_think;
+ self.use = shake_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/fight.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/fteqcc.ini

diff --git a/qc/fteqcc.ini b/qc/fteqcc.ini
index 2dd0b2c..151ecc1 100644
--- a/qc/fteqcc.ini
+++ b/qc/fteqcc.ini
@@ -1,240 +1,240 @@
-optimisation t off # c = a*b is performed in one operation rather than two, and can
- # cause older decompilers to fail.
-optimisation i off # if (!a) was traditionally compiled in two statements. This optimisation
- # does it in one, but can cause some decompilers to get confused.
-optimisation p off # In the original qcc, function parameters were specified as a vector
- # store even for floats. This fixes that.
-optimisation c default # This optimisation strips out the names of constants (but not strings)
- # from your progs, resulting in smaller files. It makes decompilers
- # leave out names or fabricate numerical ones.
-optimisation cs default # This optimisation strips out the names of string constants from
- # your progs. However, this can break addons, so don't use it in
- # those cases.
-optimisation d off # This will merge definitions of constants which are the same value.
- # Pay extra attention to assignment to constant warnings.
-optimisation s off # This will compact the string table that is stored in the progs.
- # It will be considerably smaller with this.
-optimisation l default # Strips out local names and definitions. Most decompiles will break
- # on this.
-optimisation n default # This strips out the names of functions which are never called.
- # Doesn't make much of an impact though.
-optimisation f default # This strips out the filenames of the progs. This can confuse the
- # really old decompilers, but is nothing to the more recent ones.
-optimisation u off # Removes the entries of unreferenced variables. Doesn't make a
- # difference in well maintained code.
-optimisation r off # Optimises the pr_globals count by overlapping temporaries. In
- # QC, every multiplication, division or operation in general produces
- # a temporary variable. This optimisation prevents excess, and in
- # the case of Hexen2's gamecode, reduces the count by 50k. This
- # is the most important optimisation, ever.
-optimisation a off # 5*6 actually emits an operation into the progs. This prevents
- # that happening, effectivly making the compiler see 30
-optimisation pf default # Strip out stuff wasted used in function calls and strings to the
- # precache_file builtin (which is actually a stub in quake).
-optimisation ro default # Functions ending in a return statement do not need a done statement
- # at the end of the function. This can confuse some decompilers,
- # making functions appear larger than they were.
-optimisation cj default # This optimisation plays an effect mostly with nested if/else statements,
- # instead of jumping to an unconditional jump statement, it'll jump
- # to the final destination instead. This will bewilder decompilers.
-optimisation sf default # Strips out the 'defs' of functions that were only ever called
- # directly. This does not affect saved games, but will prevent FTE_MULTIPROGS/mutators
- # from being able to hook functions.
-optimisation lo default # Store all locals in a single section of the pr_globals. Vastly
- # reducing it. This effectivly does the job of overlaptemps.
- # However, locals are no longer automatically initialised to 0 (and
- # never were in the case of recursion, but at least then its the
- # same type).
- # If locals appear uninitialised, fteqcc will disable this optimisation
- # for the affected functions, you can optionally get a warning about
- # these locals using: #pragma warning enable F302
-optimisation vc default # Where a function is called with just a vector, this causes the
- # function call to store three floats instead of one vector. This
- # can save a good number of pr_globals where those vectors contain
- # many duplicate coordinates but do not match entirly.
-optimisation cf default # Strip class field names. This will harm debugging and can result
- # in 'gibberish' names appearing in saved games. Has no effect on
- # engines other than FTEQW, which will not recognise these anyway.
-optimisation uf default # Strips any fields that have no references. This may result in
- # extra warnings at load time, or disabling support for mapper-specified
- # alpha in engines that do not provide that. FIXME: this is a little
- # pointless until relocs are properly implemented.
-keyword asm true # Disables the 'asm' keyword. Use the writeasm flag to see an example
- # of the asm.
-keyword break true # Disables the 'break' keyword.
-keyword case true # Disables the 'case' keyword.
-keyword class true # Disables the 'class' keyword.
-keyword const true # Disables the 'const' keyword.
-keyword continue true # Disables the 'continue' keyword.
-keyword default true # Disables the 'default' keyword.
-keyword entity true # Disables the 'entity' keyword.
-keyword enum true # Disables the 'enum' keyword.
-keyword enumflags true # Disables the 'enumflags' keyword.
-keyword extern true # Disables the 'extern' keyword. Use only on functions inside addons.
-keyword float true # Disables the 'float' keyword. (Disables the float keyword without
- # 'local' preceeding it)
-keyword for true # Disables the 'for' keyword. Syntax: for(assignment; while; increment)
- # {codeblock;}
-keyword goto true # Disables the 'goto' keyword.
-keyword int true # Disables the 'int' keyword.
-keyword integer true # Disables the 'integer' keyword.
-keyword noref true # Disables the 'noref' keyword.
-keyword unused false # Disables the 'unused' keyword. 'unused' means that the variable
- # is unused, you're aware that its unused, and you'd rather not
- # know about all the warnings this results in.
-keyword used false # Disables the 'used' keyword. 'used' means that the variable is
- # used even if the qcc can't see how - thus preventing it from ever
- # being stripped.
-keyword static true # Disables the 'static' keyword. 'static' means that a variable
- # has altered scope. On globals, the variable is visible only to
- # the current .qc file. On locals, the variable's value does not
- # change between calls to the function. On class variables, specifies
- # that the field is a scoped global instead of a local. On class
- # functions, specifies that 'this' is expected to be invalid and
- # that the function will access any memembers via it.
-keyword nonstatic true # Disables the 'nonstatic' keyword. 'nonstatic' acts upon globals+functions,
- # reverting the defaultstatic pragma on a per-variable basis. For
- # use by people who prefer to keep their APIs explicit.
-keyword ignore false # Disables the 'ignore' keyword. 'ignore' is expected to typically
- # be hidden behind a 'csqconly' define, and in such a context can
- # be used to conditionally compile functions a little more gracefully.
- # The opposite of the 'used' keyword. These variables/functions/members
- # are ALWAYS stripped, and effectively ignored.
-keyword nosave true # Disables the 'nosave' keyword.
-keyword inline true # Disables the 'inline' keyword.
-keyword strip true # Disables the 'strip' keyword.
-keyword shared true # Disables the 'shared' keyword.
-keyword state false # Disables the 'state' keyword.
-keyword optional true # Disables the 'optional' keyword.
-keyword inout false # Disables the 'inout' keyword.
-keyword string true # Disables the 'string' keyword.
-keyword struct true # Disables the 'struct' keyword.
-keyword switch true # Disables the 'switch' keyword.
-keyword thinktime false # Disables the 'thinktime' keyword which is used in HexenC
-keyword until false # Disables the 'until' keyword which is used in HexenC
-keyword loop false # Disables the 'loop' keyword which is used in HexenC
-keyword typedef true # Disables the 'typedef' keyword.
-keyword union true # Disables the 'union' keyword.
-keyword var true # Disables the 'var' keyword.
-keyword vector true # Disables the 'vector' keyword.
-keyword wrap true # Disables the 'wrap' keyword.
-keyword weak true # Disables the 'weak' keyword.
-keyword accumulate false # Disables the 'accumulate' keyword.
-flag acc false # Reacc is a pascall like compiler. It was released before the Quake
- # source was released. This flag has a few effects. It sorts all
- # qc files in the current directory into alphabetical order to compile
- # them. It also allows Reacc global/field distinctions, as well
- # as allows | for linebreaks. Whilst case insensitivity and lax
- # type checking are supported by reacc, they are seperate compiler
- # flags in fteqcc.
-flag qccx false # WARNING: This syntax makes mods inherantly engine specific.
- # Do NOT use unless you know what you're doing.This is provided
- # for compatibility only
- # Any entity hacks will be unsupported in FTEQW, DP, and others,
- # resulting in engine crashes if the code in question is executed.
-flag kce true # If you want keywords to NOT be disabled when they a variable by
- # the same name is defined, check here.
-flag parms false # if PARM0 PARM1 etc should be defined by the compiler. These are
- # useful if you make use of the asm keyword for function calls,
- # or you wish to create your own variable arguments. This is an
- # easy way to break decompilers.
-flag autoproto false # Causes compilation to take two passes instead of one. The first
- # pass, only the definitions are read. The second pass actually
- # compiles your code. This means you never have to remember to prototype
- # functions again.
-flag wasm false # Writes out a qc.asm which contains all your functions but in assembler.
- # This is a great way to look for bugs in fteqcc, but can also be
- # used to see exactly what your functions turn into, and thus how
- # to optimise statements better.
-flag annotate false # Annotate source code with assembler statements on compile (requires
- # gui).
-flag nullemptystr false # Empty string immediates will have the raw value 0 instead of 1.
-flag ifstring true # Causes if(string) to behave identically to if(string!=) This is
- # most useful with addons of course, but also has adverse effects
- # with FRIK_FILE's fgets, where it becomes impossible to determin
- # the end of the file. In such a case, you can still use asm {IF
- # string 2;RETURN} to detect eof and leave the function.
-flag iffloat false # Fixes certain floating point logic.
-flag ifvector true # Fixes conditional vector logic.
-flag vectorlogic true # Fixes conditional vector logic.
-flag brokenarray false # Treat references to arrays as references to the first index of
- # said array, to replicate an old fteqcc bug.
-flag rootconstructor false # When enabled, the root constructor should be called first like
- # in c++.
-flag caseinsens false # Causes fteqcc to become case insensitive whilst compiling names.
- # It's generally not advised to use this as it compiles a little
- # more slowly and provides little benefit. However, it is required
- # for full reacc support.
-flag lax false # Disables many errors (generating warnings instead) when function
- # calls or operations refer to two normally incompatible types.
- # This is required for reacc support, and can also allow certain
- # (evil) mods to compile that were originally written for frikqcc.
-flag hashonly false # Allows use of only #constant for precompiler constants, allows
- # certain preqcc using mods to compile
-flag lo false # This changes the behaviour of your code. It generates additional
- # if operations to early-out in if statements. With this flag, the
- # line if (0 && somefunction()) will never call the function. It
- # can thus be considered an optimisation. However, due to the change
- # of behaviour, it is not considered so by fteqcc. Note that due
- # to inprecisions with floats, this flag can cause runaway loop
- # errors within the player walk and run functions (without iffloat
- # also enabled). This code is advised:
- # player_stand1:
- # if (self.velocity_x || self.velocity_y)
- # player_run
- # if (!(self.velocity_x || self.velocity_y))
-flag msvcstyle false # Generates warning and error messages in a format that msvc understands,
- # to facilitate ide integration.
-flag debugmacros false # Print out the contents of macros that are expanded. This can help
- # look inside macros that are expanded and is especially handy if
- # people are using preprocessor hacks.
-flag filetimes false # Recompiles the progs only if the file times are modified.
-flag fastarrays false # Generates extra instructions inside array handling functions to
- # detect engine and use extension opcodes only in supporting engines.
- # Adds a global which is set by the engine if the engine supports
- # the extra opcodes. Note that this applies to all arrays or none.
-flag assumeint false # Numerical constants are assumed to be integers, instead of floats.
-flag subscope false # Restrict the scope of locals to the block they are actually defined
- # within, as in C.
-flag verbose false # Lots of extra compiler messages.
-flag typeexplicit false # All type conversions must be explicit or directly supported by
- # instruction set.
-flag boundchecks true # Disable array index checks, speeding up array access but can result
- # in your code misbehaving.
-flag attributes false # WARNING: This syntax conflicts with vector constructors.
-flag assumevar false # Initialised globals will be considered non-const by default.
-flag ssp false # Treat ** as an operator for exponents, instead of multiplying
- # by a dereferenced pointer.
-flag cpriority false # QC treats !a&&b as equivelent to !(a&&b). When this is set, behaviour
- # will be (!a)&&b as in C. Other operators are also affected in
- # similar ways.
-flag allowuninit false # Permit optimisations that may result in locals being uninitialised.
- # This may allow for greater reductions in temps.
-flag nofileline false # Ignores #pragma file(foo) and #pragma line(foo), so that errors
- # and symbols reflect the actual lines, instead of the original
- # source.
-flag utf8 false # String immediates will use utf-8 encoding, instead of quake's
- # encoding.
-flag embedsrc false # Write the sourcecode into the output file. The resulting .dat
- # can be opened as a standard zip archive (or by fteqccgui).
- # Good for GPL compliance!
-showall off # Show all keyword options in the gui
-compileonstart off # Recompile on GUI startup
-log off # Write out a compile log
-enginebinary d:\Quakec\fteqw64.exe # Location of the engine binary to run. Change this to something
- # else to run a different engine, but not all support debugging.
-basedir d:\Quakec # The base directory of the game that contains your sub directory
-engineargs "-game progs_dump +exec fte.cfg"
- # The engine commandline to use when debugging. You'll likely want
- # to ensure this contains -window as well as the appropriate -game
- # argument.
-srcfile progs.src # The progs.src file to load to find ordering of other qc files.
-src # Additional subdir to read qc files from. Typically blank (ie:
- # the working directory).
-tabsize 8 # Specifies the size of tabs in scintilla windows.
-extramargins off # Enables line number and folding margins.
-hexen2 off # Enable the extra tweaks needed for compatibility with hexen2 engines.
-extendedopcodes off # Utilise an extended instruction set, providing support for pointers
- # and faster arrays and other speedups.
-parameters # Other additional parameters that are not supported by the gui.
- # Likely including -DFOO
+optimisation t off # c = a*b is performed in one operation rather than two, and can
+ # cause older decompilers to fail.
+optimisation i off # if (!a) was traditionally compiled in two statements. This optimisation
+ # does it in one, but can cause some decompilers to get confused.
+optimisation p off # In the original qcc, function parameters were specified as a vector
+ # store even for floats. This fixes that.
+optimisation c default # This optimisation strips out the names of constants (but not strings)
+ # from your progs, resulting in smaller files. It makes decompilers
+ # leave out names or fabricate numerical ones.
+optimisation cs default # This optimisation strips out the names of string constants from
+ # your progs. However, this can break addons, so don't use it in
+ # those cases.
+optimisation d off # This will merge definitions of constants which are the same value.
+ # Pay extra attention to assignment to constant warnings.
+optimisation s off # This will compact the string table that is stored in the progs.
+ # It will be considerably smaller with this.
+optimisation l default # Strips out local names and definitions. Most decompiles will break
+ # on this.
+optimisation n default # This strips out the names of functions which are never called.
+ # Doesn't make much of an impact though.
+optimisation f default # This strips out the filenames of the progs. This can confuse the
+ # really old decompilers, but is nothing to the more recent ones.
+optimisation u off # Removes the entries of unreferenced variables. Doesn't make a
+ # difference in well maintained code.
+optimisation r off # Optimises the pr_globals count by overlapping temporaries. In
+ # QC, every multiplication, division or operation in general produces
+ # a temporary variable. This optimisation prevents excess, and in
+ # the case of Hexen2's gamecode, reduces the count by 50k. This
+ # is the most important optimisation, ever.
+optimisation a off # 5*6 actually emits an operation into the progs. This prevents
+ # that happening, effectivly making the compiler see 30
+optimisation pf default # Strip out stuff wasted used in function calls and strings to the
+ # precache_file builtin (which is actually a stub in quake).
+optimisation ro default # Functions ending in a return statement do not need a done statement
+ # at the end of the function. This can confuse some decompilers,
+ # making functions appear larger than they were.
+optimisation cj default # This optimisation plays an effect mostly with nested if/else statements,
+ # instead of jumping to an unconditional jump statement, it'll jump
+ # to the final destination instead. This will bewilder decompilers.
+optimisation sf default # Strips out the 'defs' of functions that were only ever called
+ # directly. This does not affect saved games, but will prevent FTE_MULTIPROGS/mutators
+ # from being able to hook functions.
+optimisation lo default # Store all locals in a single section of the pr_globals. Vastly
+ # reducing it. This effectivly does the job of overlaptemps.
+ # However, locals are no longer automatically initialised to 0 (and
+ # never were in the case of recursion, but at least then its the
+ # same type).
+ # If locals appear uninitialised, fteqcc will disable this optimisation
+ # for the affected functions, you can optionally get a warning about
+ # these locals using: #pragma warning enable F302
+optimisation vc default # Where a function is called with just a vector, this causes the
+ # function call to store three floats instead of one vector. This
+ # can save a good number of pr_globals where those vectors contain
+ # many duplicate coordinates but do not match entirly.
+optimisation cf default # Strip class field names. This will harm debugging and can result
+ # in 'gibberish' names appearing in saved games. Has no effect on
+ # engines other than FTEQW, which will not recognise these anyway.
+optimisation uf default # Strips any fields that have no references. This may result in
+ # extra warnings at load time, or disabling support for mapper-specified
+ # alpha in engines that do not provide that. FIXME: this is a little
+ # pointless until relocs are properly implemented.
+keyword asm true # Disables the 'asm' keyword. Use the writeasm flag to see an example
+ # of the asm.
+keyword break true # Disables the 'break' keyword.
+keyword case true # Disables the 'case' keyword.
+keyword class true # Disables the 'class' keyword.
+keyword const true # Disables the 'const' keyword.
+keyword continue true # Disables the 'continue' keyword.
+keyword default true # Disables the 'default' keyword.
+keyword entity true # Disables the 'entity' keyword.
+keyword enum true # Disables the 'enum' keyword.
+keyword enumflags true # Disables the 'enumflags' keyword.
+keyword extern true # Disables the 'extern' keyword. Use only on functions inside addons.
+keyword float true # Disables the 'float' keyword. (Disables the float keyword without
+ # 'local' preceeding it)
+keyword for true # Disables the 'for' keyword. Syntax: for(assignment; while; increment)
+ # {codeblock;}
+keyword goto true # Disables the 'goto' keyword.
+keyword int true # Disables the 'int' keyword.
+keyword integer true # Disables the 'integer' keyword.
+keyword noref true # Disables the 'noref' keyword.
+keyword unused false # Disables the 'unused' keyword. 'unused' means that the variable
+ # is unused, you're aware that its unused, and you'd rather not
+ # know about all the warnings this results in.
+keyword used false # Disables the 'used' keyword. 'used' means that the variable is
+ # used even if the qcc can't see how - thus preventing it from ever
+ # being stripped.
+keyword static true # Disables the 'static' keyword. 'static' means that a variable
+ # has altered scope. On globals, the variable is visible only to
+ # the current .qc file. On locals, the variable's value does not
+ # change between calls to the function. On class variables, specifies
+ # that the field is a scoped global instead of a local. On class
+ # functions, specifies that 'this' is expected to be invalid and
+ # that the function will access any memembers via it.
+keyword nonstatic true # Disables the 'nonstatic' keyword. 'nonstatic' acts upon globals+functions,
+ # reverting the defaultstatic pragma on a per-variable basis. For
+ # use by people who prefer to keep their APIs explicit.
+keyword ignore false # Disables the 'ignore' keyword. 'ignore' is expected to typically
+ # be hidden behind a 'csqconly' define, and in such a context can
+ # be used to conditionally compile functions a little more gracefully.
+ # The opposite of the 'used' keyword. These variables/functions/members
+ # are ALWAYS stripped, and effectively ignored.
+keyword nosave true # Disables the 'nosave' keyword.
+keyword inline true # Disables the 'inline' keyword.
+keyword strip true # Disables the 'strip' keyword.
+keyword shared true # Disables the 'shared' keyword.
+keyword state false # Disables the 'state' keyword.
+keyword optional true # Disables the 'optional' keyword.
+keyword inout false # Disables the 'inout' keyword.
+keyword string true # Disables the 'string' keyword.
+keyword struct true # Disables the 'struct' keyword.
+keyword switch true # Disables the 'switch' keyword.
+keyword thinktime false # Disables the 'thinktime' keyword which is used in HexenC
+keyword until false # Disables the 'until' keyword which is used in HexenC
+keyword loop false # Disables the 'loop' keyword which is used in HexenC
+keyword typedef true # Disables the 'typedef' keyword.
+keyword union true # Disables the 'union' keyword.
+keyword var true # Disables the 'var' keyword.
+keyword vector true # Disables the 'vector' keyword.
+keyword wrap true # Disables the 'wrap' keyword.
+keyword weak true # Disables the 'weak' keyword.
+keyword accumulate false # Disables the 'accumulate' keyword.
+flag acc false # Reacc is a pascall like compiler. It was released before the Quake
+ # source was released. This flag has a few effects. It sorts all
+ # qc files in the current directory into alphabetical order to compile
+ # them. It also allows Reacc global/field distinctions, as well
+ # as allows | for linebreaks. Whilst case insensitivity and lax
+ # type checking are supported by reacc, they are seperate compiler
+ # flags in fteqcc.
+flag qccx false # WARNING: This syntax makes mods inherantly engine specific.
+ # Do NOT use unless you know what you're doing.This is provided
+ # for compatibility only
+ # Any entity hacks will be unsupported in FTEQW, DP, and others,
+ # resulting in engine crashes if the code in question is executed.
+flag kce true # If you want keywords to NOT be disabled when they a variable by
+ # the same name is defined, check here.
+flag parms false # if PARM0 PARM1 etc should be defined by the compiler. These are
+ # useful if you make use of the asm keyword for function calls,
+ # or you wish to create your own variable arguments. This is an
+ # easy way to break decompilers.
+flag autoproto false # Causes compilation to take two passes instead of one. The first
+ # pass, only the definitions are read. The second pass actually
+ # compiles your code. This means you never have to remember to prototype
+ # functions again.
+flag wasm false # Writes out a qc.asm which contains all your functions but in assembler.
+ # This is a great way to look for bugs in fteqcc, but can also be
+ # used to see exactly what your functions turn into, and thus how
+ # to optimise statements better.
+flag annotate false # Annotate source code with assembler statements on compile (requires
+ # gui).
+flag nullemptystr false # Empty string immediates will have the raw value 0 instead of 1.
+flag ifstring true # Causes if(string) to behave identically to if(string!=) This is
+ # most useful with addons of course, but also has adverse effects
+ # with FRIK_FILE's fgets, where it becomes impossible to determin
+ # the end of the file. In such a case, you can still use asm {IF
+ # string 2;RETURN} to detect eof and leave the function.
+flag iffloat false # Fixes certain floating point logic.
+flag ifvector true # Fixes conditional vector logic.
+flag vectorlogic true # Fixes conditional vector logic.
+flag brokenarray false # Treat references to arrays as references to the first index of
+ # said array, to replicate an old fteqcc bug.
+flag rootconstructor false # When enabled, the root constructor should be called first like
+ # in c++.
+flag caseinsens false # Causes fteqcc to become case insensitive whilst compiling names.
+ # It's generally not advised to use this as it compiles a little
+ # more slowly and provides little benefit. However, it is required
+ # for full reacc support.
+flag lax false # Disables many errors (generating warnings instead) when function
+ # calls or operations refer to two normally incompatible types.
+ # This is required for reacc support, and can also allow certain
+ # (evil) mods to compile that were originally written for frikqcc.
+flag hashonly false # Allows use of only #constant for precompiler constants, allows
+ # certain preqcc using mods to compile
+flag lo false # This changes the behaviour of your code. It generates additional
+ # if operations to early-out in if statements. With this flag, the
+ # line if (0 && somefunction()) will never call the function. It
+ # can thus be considered an optimisation. However, due to the change
+ # of behaviour, it is not considered so by fteqcc. Note that due
+ # to inprecisions with floats, this flag can cause runaway loop
+ # errors within the player walk and run functions (without iffloat
+ # also enabled). This code is advised:
+ # player_stand1:
+ # if (self.velocity_x || self.velocity_y)
+ # player_run
+ # if (!(self.velocity_x || self.velocity_y))
+flag msvcstyle false # Generates warning and error messages in a format that msvc understands,
+ # to facilitate ide integration.
+flag debugmacros false # Print out the contents of macros that are expanded. This can help
+ # look inside macros that are expanded and is especially handy if
+ # people are using preprocessor hacks.
+flag filetimes false # Recompiles the progs only if the file times are modified.
+flag fastarrays false # Generates extra instructions inside array handling functions to
+ # detect engine and use extension opcodes only in supporting engines.
+ # Adds a global which is set by the engine if the engine supports
+ # the extra opcodes. Note that this applies to all arrays or none.
+flag assumeint false # Numerical constants are assumed to be integers, instead of floats.
+flag subscope false # Restrict the scope of locals to the block they are actually defined
+ # within, as in C.
+flag verbose false # Lots of extra compiler messages.
+flag typeexplicit false # All type conversions must be explicit or directly supported by
+ # instruction set.
+flag boundchecks true # Disable array index checks, speeding up array access but can result
+ # in your code misbehaving.
+flag attributes false # WARNING: This syntax conflicts with vector constructors.
+flag assumevar false # Initialised globals will be considered non-const by default.
+flag ssp false # Treat ** as an operator for exponents, instead of multiplying
+ # by a dereferenced pointer.
+flag cpriority false # QC treats !a&&b as equivelent to !(a&&b). When this is set, behaviour
+ # will be (!a)&&b as in C. Other operators are also affected in
+ # similar ways.
+flag allowuninit false # Permit optimisations that may result in locals being uninitialised.
+ # This may allow for greater reductions in temps.
+flag nofileline false # Ignores #pragma file(foo) and #pragma line(foo), so that errors
+ # and symbols reflect the actual lines, instead of the original
+ # source.
+flag utf8 false # String immediates will use utf-8 encoding, instead of quake's
+ # encoding.
+flag embedsrc false # Write the sourcecode into the output file. The resulting .dat
+ # can be opened as a standard zip archive (or by fteqccgui).
+ # Good for GPL compliance!
+showall off # Show all keyword options in the gui
+compileonstart off # Recompile on GUI startup
+log off # Write out a compile log
+enginebinary d:\Quakec\fteqw64.exe # Location of the engine binary to run. Change this to something
+ # else to run a different engine, but not all support debugging.
+basedir d:\Quakec # The base directory of the game that contains your sub directory
+engineargs "-game progs_dump +exec fte.cfg"
+ # The engine commandline to use when debugging. You'll likely want
+ # to ensure this contains -window as well as the appropriate -game
+ # argument.
+srcfile progs.src # The progs.src file to load to find ordering of other qc files.
+src # Additional subdir to read qc files from. Typically blank (ie:
+ # the working directory).
+tabsize 8 # Specifies the size of tabs in scintilla windows.
+extramargins off # Enables line number and folding margins.
+hexen2 off # Enable the extra tweaks needed for compatibility with hexen2 engines.
+extendedopcodes off # Utilise an extended instruction set, providing support for pointers
+ # and faster arrays and other speedups.
+parameters # Other additional parameters that are not supported by the gui.
+ # Likely including -DFOO

Return to the top of this page or return to the overview of this repo.

Diff qc/items.qc

diff --git a/qc/items.qc b/qc/items.qc
index 7bbbf1f..e6af21b 100644
--- a/qc/items.qc
+++ b/qc/items.qc
@@ -1,2441 +1,2441 @@
-void (vector org) spawn_tfog;
-void() W_SetCurrentAmmo;
-/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
-BE .8 .3 .4 IN COLOR */
-
-float ITEM_SPAWNSILENT = 32;
-float ITEM_SPAWNED = 64;
-float ITEM_SUSPENDED = 128;
-float ITEM_RESPAWNDM = 16384;
-float ITEM_DONTDROP = 8388608;
-
-.vector particles_offset;
-
-void() SUB_regen =
-{
- self.model = self.mdl; // restore original model
- self.solid = SOLID_TRIGGER; // allow it to be touched again
- if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM)) // Respawn with DM effects
- sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound
- else
- spawn_tfog (self.origin + self.particles_offset); // play teleport sound and display particles
- setorigin (self, self.origin);
-};
-
-// Supa, Quoth respawning items support Respawn item like in DM if 'ritem' TRUE,
-// override respawn time with 'respawndelay' if set, inc 'cnt' with each respawn
-// and if 'respawncount' is set we'll remove the item if cnt > respawncount
-// remember that SUB_Regen is already set on every item that can respawn, all we
-// need to do is give a nextthink time in order to trigger it
-.float ritem,
- respawndelay,
- respawncount;
-
-void(entity whatitem, float defaultdelay) CheckItemRespawn =
-{
- if (!whatitem.ritem) // respawn item if true, otherwise abort
- return;
-
- whatitem.cnt = whatitem.cnt + 1; // inc before check to account for zero indexing
-
- if (whatitem.respawncount) // limited respawns
- if (whatitem.respawncount < whatitem.cnt)
- return;
-
- // okay, we're clear to set up a respawn
-
- if (whatitem.respawndelay) // custom respawn delay?
- whatitem.nextthink = time + whatitem.respawndelay;
- else
- whatitem.nextthink = time + defaultdelay;
-};
-
-
-/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
-prints a warning message when spawned
-*/
-void() noclass =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- dprint ("noclass spawned at");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove (self);
-};
-
-/*
-============
-DelaySpawnItem //this is from rmq-items.qc
-
-Makes a SPAWNED item ready for pickup on a trigger event - modified a bit -- dumptruck_ds
-============
-*/
-void() DelaySpawnItem =
-{
- self.solid = SOLID_TRIGGER;
- setmodel (self, self.mdl);
- setsize (self, self.pos1, self.pos2);
-
- if (!(self.spawnflags & ITEM_SPAWNSILENT)) // SILENT, gb
- // sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
- spawn_tfog (self.origin + self.particles_offset);
-
- if (self.spawnflags & ITEM_SUSPENDED)
- self.movetype = MOVETYPE_FLY;
- else
- self.movetype = MOVETYPE_TOSS;
-
- self.use = SUB_Null;
-};
-
-
-// Supa, restore old hull and lock movement
-void() RefreshHull =
-{
- // setsize (self, self.dest, self.dest2);
- setsize (self, '0 0 0', '32 32 56'); //dumptruck_ds -- fix for bounding boxes
-
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
-};
-
-
-/*
-============
-PlaceItem
-
-plants the object on the floor
-============
-*/
-void() PlaceItem =
-{
- // local float oldz;
- self.mdl = self.model; // so it can be restored on respawn
- self.flags = FL_ITEM; // make extra wide
- self.solid = SOLID_TRIGGER;
- self.velocity = '0 0 0';
-
- if (self.spawnflags & ITEM_SUSPENDED) //ijed Don't drop spawnflag
- {
- self.movetype = MOVETYPE_FLY;
- }
- else
- {
- // The following hack for item_health was inherited from the RMQ
- // code, and was here when the func_mapjamx maps were created.
- // It would have been nice to remove this code entirely, because
- // progs_dump doesn't need it, and it breaks item_health's
- // collision with entities that have MOVETYPE_PUSH. However,
- // removing this code would cause some of the item_health
- // entities in some of the func_mapjamx maps to "fall out of the
- // level", because they're accidentally touching solid surfaces.
- // So, to maintain backwards-compatibility, this code has been
- // left in, but will only be run if one of the func_mapjamx maps
- // is being played. -- iw
- //
- if (known_release == KNOWN_RELEASE_FUNC_MAPJAMX)
- {
- if (self.classname == "item_health") // Supa, CTF
- {
-
- // hacking around hull issues..
- setsize (self, '0 0 0', '0 0 0'); // void hull for now
-
- self.think = RefreshHull;
- self.nextthink = time + 0.2;
- }
- }
-
- self.movetype = MOVETYPE_TOSS;
-
- if (!(self.spawnflags & ITEM_DONTDROP))
- {
- setorigin (self, self.origin + '0 0 6');
-
- if (!droptofloor())
- {
- print_self ("bonus item", "fell out of level");
- remove(self);
- return;
- }
- }
- }
-
- if ((self.spawnflags & ITEM_SPAWNED)) // SPAWNED, gb
- {
- self.pos1 = self.mins;
- self.pos2 = self.maxs;
-
- self.model = "";
- self.solid = SOLID_NOT;
-
- if (self.spawnflags & ITEM_DONTDROP) self.movetype = MOVETYPE_NONE;
-
- self.use = DelaySpawnItem;
- }
-};
-
-
-/*
-============
-StartItem
-
-Sets the clipping size and plants the object on the floor
-============
-*/
-void() StartItem =
-{
- self.nextthink = time + 0.3; // items start after other solids || was 0.2 -- dumptruck_ds
- self.think = PlaceItem;
-};
-
-/*
-=========================================================================
-
-HEALTH BOX
-
-=========================================================================
-*/
-//
-// T_Heal: add health to an entity, limiting health to max_health
-// "ignore" will ignore max_health limit
-//
-float (entity e, float healamount, float ignore) T_Heal =
-{
- if (e.health <= 0)
- return 0;
- if ((!ignore) && (e.health >= other.max_health))
- return 0;
- healamount = ceil(healamount);
-
- e.health = e.health + healamount;
- if ((!ignore) && (e.health >= other.max_health))
- e.health = other.max_health;
-
- if (e.health > 250)
- e.health = 250;
- return 1;
-};
-
-/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) ROTTEN MEGAHEALTH X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_bh10.bsp" }, spawnflags & 2 -> { "path" : "maps/b_bh100.bsp" },
- "maps/b_bh25.bsp" }} );
-}
-Health box. Normally gives 25 points.
-Rotten box heals 15 points.
-Megahealth will add 100 health, then start to
-rot the player back down to 100 health after 5 seconds.
-*/
-
-float H_ROTTEN = 1;
-float H_MEGA = 2;
-float H_VIAL = 4;
-.float healamount, healtype;
-void() health_touch;
-// void() item_megahealth_rot;
-
-void() item_health =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = health_touch;
-
-
-
- if (self.spawnflags & H_ROTTEN)
- {
- if (!self.mdl_body && world.h_15_mdl)
- {
- self.mdl_body = world.h_15_mdl;
- }
- // precache_model("maps/b_bh10.bsp"); // dumptruck_ds custom health models and sounds START
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h15.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h15.mdl");
- }
- else
- {
- // setmodel(self, "maps/b_bh10.bsp");
- precache_body_model ("maps/b_bh10.bsp");
- body_model ("maps/b_bh10.bsp");
- }
- // precache_sound("items/r_item1.wav");
- precache_sound_misc("items/r_item1.wav");
- // self.noise = "items/r_item1.wav";
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item1.wav";
- self.noise = self.snd_misc;
-
- // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
- self.healamount = 15;
- self.healtype = 0;
- if !(self.particles_offset)
- self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
-
- }
- else
- if (self.spawnflags & H_MEGA)
- {
- if (!self.mdl_body && world.h_mega_mdl)
- {
- self.mdl_body = world.h_mega_mdl;
- }
- // precache_model("maps/b_bh100.bsp");
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h100.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h100.mdl");
- }
- else
- {
- // setmodel(self, "maps/b_bh100.bsp");
- precache_body_model ("maps/b_bh100.bsp");
- body_model ("maps/b_bh100.bsp");
- }
- precache_sound_misc("items/r_item2.wav");
- // self.noise = "items/r_item2.wav";
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item2.wav";
- self.noise = self.snd_misc;
-
- // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
- self.healamount = 100;
- self.healtype = 2;
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- }
- else
- {
- if (!self.mdl_body && world.h_25_mdl)
- {
- self.mdl_body = world.h_25_mdl;
- }
- if (world.style)
- {
- precache_body_model ("progs/h_mdls/m_h25.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/h_mdls/m_h25.mdl");
- }
- else
- {
- precache_body_model ("maps/b_bh25.bsp");
- body_model ("maps/b_bh25.bsp");
- }
- precache_sound_misc("items/health1.wav");
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/health1.wav";
- self.noise = self.snd_misc;
-
- self.healamount = 25;
- self.healtype = 1;
- if !(self.particles_offset)
- self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
- }
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-void() item_health_vial =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = health_touch;
-
- if (!self.mdl_body && world.h_vial_mdl)
- {
- self.mdl_body = world.h_vial_mdl;
- }
-
- precache_body_model ("progs/h_mdls/pd_vial.mdl"); // model from Hexen 2 -- dumptruck_ds
- body_model("progs/h_mdls/pd_vial.mdl");
- precache_sound_misc("items/r_item1.wav");
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "items/r_item1.wav";
- self.noise = self.snd_misc;
-
- self.healamount = 5;
- self.healtype = 2; // over heal and count down like mega health -- dumptruck_ds
- setsize (self, '-16 -16 0', '16 16 56');
- if !(self.particles_offset)
- self.particles_offset = '0 0 0';
- StartItem ();
-};
-
-void() health_touch =
-{
- local float amount;
- local string s;
- amount = self.healamount;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.healtype == 2) // Megahealth? Ignore max_health...
- {
- if (other.health >= 250)
- return;
- if (!T_Heal(other, amount, 1))
- return;
- }
- else
- {
- if (!T_Heal(other, amount, 0))
- return;
- }
-
- sprint(other, "You receive ");
- s = ftos(amount);
- sprint(other, s);
- sprint(other, " health\n");
-
-// health touch sound
- // sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- sound_misc(other, CHAN_AUTO, self.noise, 1, ATTN_NORM); //custom sounds -- dumptruck_ds
-
- stuffcmd (other, "bf\n");
-
- self.model = string_null;
- self.solid = SOLID_NOT;
-
- self.think = SUB_regen;
-
- // Megahealth = rot down the player's super health
- if (self.healtype == 2)
- {
- other.megahealth_rottime = time + 5; //thanks ydrol!!!
- other.items = other.items | IT_SUPERHEALTH;
- self.owner = other;
-
- // Regarding the deathmatch respawn time below: id's original
- // code made the megahealth respawn 20 seconds after the health
- // of the player who collected it finished rotting down.
- // However, this mod has already got rid of the weird old
- // megahealth behavior whereby it monitored the player who
- // touched it, so the original respawn logic isn't applicable.
- // As a solution, the code below uses a respawn time of 125
- // seconds for deathmatch, because that was the worst-case
- // scenario of id's original code (5 seconds before the player's
- // health started to rot, plus 100 seconds to rot down 100
- // health points, plus the original 20 second delay before the
- // item respawned). -- iw
- //
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 125;
- }
- else
- {
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- }
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*
-===============================================================================
-
-ARMOR
-
-===============================================================================
-*/
-
-void() armor_touch;
-void() shard_touch;
-
-
-void() shard_touch = // this from RMQ shard_touch
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- local float bit;
-
- if ((other.items & IT_ARMOR1) ||
- (other.items & IT_ARMOR2) ||
- (other.items & IT_ARMOR3) ) // has armor
- {
- // Supa, check bounds, original armourvalue + 25
- if (other.items & IT_ARMOR1 && other.armorvalue >= 125) return;
- if (other.items & IT_ARMOR2 && other.armorvalue >= 175) return;
- if (other.items & IT_ARMOR3 && other.armorvalue >= 225) return;
-
- other.armorvalue = other.armorvalue + 5; // was 2, RMQ team
-
- // Supa, now cap armourvalue to bounds
- if (other.items & IT_ARMOR1 && other.armorvalue >= 125) other.armorvalue = 125;
- else if (other.items & IT_ARMOR2 && other.armorvalue >= 175) other.armorvalue = 175;
- else if (other.items & IT_ARMOR3 && other.armorvalue >= 225) other.armorvalue = 225;
- }
- else
- {
- other.armortype = 0.3; // shard = Green armor level
- other.armorvalue = 5;
- bit = IT_ARMOR1;
- other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
- }
- self.solid = SOLID_NOT;
- self.model = string_null;
-
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- self.think = SUB_regen;
-
- if (self.obit_name != "")
- {
- sprint (other, "You got ");
- sprint (other, self.obit_name); // custom armor name
- sprint (other, "\n");
- }
- else
- sprint(other, "You got armor\n");
- // armor touch sound
- // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
- if (self.snd_misc != "")
- sound_misc(other, CHAN_AUTO, self.snd_misc, 1, ATTN_NORM);
- else
- sound_misc(other, CHAN_AUTO,"dump/armsh1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
- stuffcmd (other, "bf\n");
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-void() armor_touch =
-{
- local float type, value, bit;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (self.classname == "item_armor1")
- {
- type = 0.3;
- value = 100;
- bit = IT_ARMOR1;
- }
- else if (self.classname == "item_armor2")
- {
- type = 0.6;
- value = 150;
- bit = IT_ARMOR2;
- }
- else if (self.classname == "item_armorInv")
- {
- type = 0.8;
- value = 200;
- bit = IT_ARMOR3;
- }
- else
- {
- dprint ("WARNING: armor_touch: unknown classname: ");
- dprint (self.classname);
- dprint ("\n");
- return;
- }
-
- if (other.armortype*other.armorvalue >= type*value)
- return;
-
- other.armortype = type;
- other.armorvalue = value;
-
- other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
-
- self.solid = SOLID_NOT;
- self.model = string_null;
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
- self.think = SUB_regen;
-
- if (self.obit_name != "")
- {
- sprint (other, "You got ");
- sprint (other, self.obit_name); // custom armor name
- sprint (other, "\n");
- }
- else
- sprint(other, "You got armor\n");
-// armor touch sound
- // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
- if (self.snd_misc != "")
- sound_misc(other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
- else
- sound_misc(other, CHAN_ITEM,"items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
- stuffcmd (other, "bf\n");
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ("progs/armor.mdl");
-}
-*/
-
-void() item_armor_shard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_shr_mdl)
- {
- self.mdl_body = world.a_shr_mdl;
- }
-
- self.touch = shard_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armshr.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armshr.mdl");
- precache_sound_misc ("dump/armsh1.wav");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 0;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-void() item_armor1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_grn_mdl)
- {
- self.mdl_body = world.a_grn_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- precache_sound_misc ("items/armor1.wav");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 0;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model({ "path": ":progs/armor.mdl", "skin": 1 }); }
-*/
-
-void() item_armor2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_ylw_mdl)
- {
- self.mdl_body = world.a_ylw_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 1;
- precache_sound_misc ("items/armor1.wav");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model({ "path": ":progs/armor.mdl", "skin": 2 });
-}
-*/
-
-void() item_armorInv =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl_body && world.a_red_mdl)
- {
- self.mdl_body = world.a_red_mdl;
- }
-
- self.touch = armor_touch;
- // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
- precache_body_model ("progs/armor.mdl");
- // setmodel (self, "progs/armor.mdl");
- body_model ("progs/armor.mdl");
- if !(self.skin) // dumptruck_ds custom models and sounds END
- self.skin = 2;
- precache_sound_misc ("items/armor1.wav");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-
-/*
-===============================================================================
-
-WEAPONS
-
-===============================================================================
-*/
-
-void() bound_other_ammo =
-{
- if (other.ammo_shells > 100)
- other.ammo_shells = 100;
- if (other.ammo_nails > 200)
- other.ammo_nails = 200;
- if (other.ammo_rockets > 100)
- other.ammo_rockets = 100;
- if (other.ammo_cells > 100)
- other.ammo_cells = 100;
-};
-
-
-float(float w) RankForWeapon =
-{
- if (self.waterlevel <= 1 && w == IT_LIGHTNING) // 1997-12-23 Thunderbolt fix by Maddes recognize waterlevel
- return 1;
- if (w == IT_ROCKET_LAUNCHER)
- return 2;
- if (w == IT_SUPER_NAILGUN)
- return 3;
- if (w == IT_GRENADE_LAUNCHER)
- return 4;
- if (w == IT_SUPER_SHOTGUN)
- return 5;
- if (w == IT_NAILGUN)
- return 6;
- if (w == IT_SHOTGUN)
- return 7;
- return 8;
-};
-
-/*
-=============
-Deathmatch_Weapon
-
-Deathmatch weapon change rules for picking up a weapon
-
-.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
-=============
-*/
-void(float old, float new) Deathmatch_Weapon =
-{
- local float or, nr;
-
-// change self.weapon if desired
- or = RankForWeapon (self.weapon);
- nr = RankForWeapon (new);
- if ( nr < or )
- self.weapon = new;
-};
-
-/*
-=============
-weapon_touch
-=============
-*/
-float() W_BestWeapon;
-
-void() weapon_touch =
-{
- local float hadammo, best, new, old;
- local entity stemp;
- local float leave;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
- if (deathmatch == 2 || coop)
- {
- leave = 1;
-
- // fix weapon items never firing their targets in coop or
- // "deathmatch 2" -- iw
- activator = other;
- SUB_UseAndForgetTargets ();
- }
- else
- {
- leave = 0;
- }
-
- // johnfitz added for axe, shotgun items --dumptruck_ds from RRP /rubicon2
- if (self.classname == "weapon_axe")
- {
- if (leave && (other.items & IT_AXE) )
- return;
- new = IT_AXE;
- }
- else if (self.classname == "weapon_shotgun")
- {
- if (leave && (other.items & IT_SHOTGUN) )
- return;
- hadammo = other.ammo_shells;
- new = IT_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
- }
- // johnfitz
-
- else if (self.classname == "weapon_nailgun")
- {
- if (leave && (other.items & IT_NAILGUN) )
- return;
- hadammo = other.ammo_nails;
- new = IT_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
- }
- else if (self.classname == "weapon_supernailgun")
- {
- if (leave && (other.items & IT_SUPER_NAILGUN) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_SUPER_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
- }
- else if (self.classname == "weapon_supershotgun")
- {
- if (leave && (other.items & IT_SUPER_SHOTGUN) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_SUPER_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
- }
- else if (self.classname == "weapon_rocketlauncher")
- {
- if (leave && (other.items & IT_ROCKET_LAUNCHER) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_ROCKET_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
- }
- else if (self.classname == "weapon_grenadelauncher")
- {
- if (leave && (other.items & IT_GRENADE_LAUNCHER) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_GRENADE_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
- }
- else if (self.classname == "weapon_lightning")
- {
- if (leave && (other.items & IT_LIGHTNING) )
- return;
- hadammo = other.ammo_rockets;
- new = IT_LIGHTNING;
- other.ammo_cells = other.ammo_cells + 15;
- }
- else
- {
- objerror ("weapon_touch: unknown classname");
- return;
- }
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other, "\n");
-// weapon touch sound
- sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
- bound_other_ammo ();
-
-// change to the weapon
- old = other.items;
- other.items = other.items | new;
-
- stemp = self;
- self = other;
-
-// 1997-12-23 Thunderbolt fix by Maddes start
-/* don't separate between SinglePlayer/Coop and Deathmatch
- if (!deathmatch)
- self.weapon = new;
- else
-*/
-// 1997-12-23 Thunderbolt fix by Maddes end
- Deathmatch_Weapon (old, new);
-
- W_SetCurrentAmmo();
-
- self = stemp;
-
- if (leave)
- return;
-
-// remove it in single player, or setup for respawning in deathmatch
- self.model = string_null;
- self.solid = SOLID_NOT;
- // Supa, SP respawning items support
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // weapons never disappear in "deathmatch 2"
- self.nextthink = time + 30;
-
- self.think = SUB_regen;
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-// johnfitz new items -- dumptruck_ds from RRP and rubicon2
-/*QUAKED weapon_axe (0 .5 .8) (-16 -16 0) (16 16 32)
-Axe
-*/
-void() weapon_axe =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_axe.mdl");
- setmodel (self, "progs/g_axe.mdl");
- self.weapon = IT_AXE;
- self.netname = "Axe";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-/*QUAKED weapon_shotgun (0 .5 .8) (-16 -16 0) (16 16 32) X STYLE_1 STYLE_2 X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_shotgn.mdl"); }
-This is a pickup model that should be used when you want a player to spawn with only an axe and then later get the shotgun: (trigger_take_weapon or reset_items 2 in worldspawn). There are two models to choose from. Spawnflag 2 (the default) selects an unused “classic look” model from Rubicon 2 by metlslime. Spawnflag 4 is an alternate from Slapmap and has been used in a few mods.
-Single-barrelled Shotgun
-Shotgun
-*/
-
-void() weapon_shotgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_shotgu.mdl");
- setmodel (self, "progs/g_shotgu.mdl"); //new shotgun model by Starshipwaters -dumptruck_ds - removed 2 older shotguns that used spawnflags
- self.weapon = IT_SHOTGUN;
- self.netname = "Shotgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
-// johnfitz
-
-/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_shot.mdl"); }
-Double-barrelled Shotgun
-*/
-
-void() weapon_supershotgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_shot.mdl");
- setmodel (self, "progs/g_shot.mdl");
- self.weapon = IT_SUPER_SHOTGUN;
- self.netname = "Double-barrelled Shotgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 33';
- StartItem ();
-};
-
-/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_nail.mdl"); }
-Nailgun
-*/
-
-void() weapon_nailgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_nail.mdl");
- setmodel (self, "progs/g_nail.mdl");
- self.weapon = IT_NAILGUN;
- self.netname = "nailgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 31';
- StartItem ();
-};
-
-/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_nail2.mdl"); }
-Perforator
-*/
-
-void() weapon_supernailgun =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_nail2.mdl");
- setmodel (self, "progs/g_nail2.mdl");
- self.weapon = IT_SUPER_NAILGUN;
- self.netname = "Super Nailgun";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 34';
- StartItem ();
-};
-
-/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_rock.mdl"); }
-Grenade Launcher
-*/
-
-void() weapon_grenadelauncher =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_rock.mdl");
- setmodel (self, "progs/g_rock.mdl");
- self.weapon = 3;
- self.netname = "Grenade Launcher";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 28';
- StartItem ();
-};
-
-/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_rock2.mdl"); }
-Rocket Launcher
-*/
-
-void() weapon_rocketlauncher =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_rock2.mdl");
- setmodel (self, "progs/g_rock2.mdl");
- self.weapon = 3;
- self.netname = "Rocket Launcher";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 32';
- StartItem ();
-};
-
-
-/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/g_light.mdl"); }
-Thunderbolt
-*/
-
-void() weapon_lightning =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/g_light.mdl");
- setmodel (self, "progs/g_light.mdl");
- self.weapon = 3;
- self.netname = "Thunderbolt";
- self.touch = weapon_touch;
- setsize (self, '-16 -16 0', '16 16 56');
- self.particles_offset = '0 0 31';
- StartItem ();
-};
-
-
-/*
-===============================================================================
-
-AMMO
-
-===============================================================================
-*/
-
-void() ammo_touch =
-{
-local entity stemp;
-local float best;
-
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
-
-// shotgun
- if (self.weapon == 1)
- {
- if (other.ammo_shells >= 100)
- return;
- other.ammo_shells = other.ammo_shells + self.aflag;
- }
-
-// spikes
- if (self.weapon == 2)
- {
- if (other.ammo_nails >= 200)
- return;
- other.ammo_nails = other.ammo_nails + self.aflag;
- }
-
-// rockets
- if (self.weapon == 3)
- {
- if (other.ammo_rockets >= 100)
- return;
- other.ammo_rockets = other.ammo_rockets + self.aflag;
- }
-
-// cells
- if (self.weapon == 4)
- {
- if (other.ammo_cells >= 100)
- return;
- other.ammo_cells = other.ammo_cells + self.aflag;
- }
-
- bound_other_ammo ();
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other, "\n");
-// ammo touch sound
- sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// change to a better weapon if appropriate
-
- if ( other.weapon == best )
- {
- stemp = self;
- self = other;
- self.weapon = W_BestWeapon();
- W_SetCurrentAmmo ();
- self = stemp;
- }
-
-// if changed current ammo, update it
- stemp = self;
- self = other;
- W_SetCurrentAmmo();
- self = stemp;
-
-// remove it in single player, or setup for respawning in deathmatch
- self.model = string_null;
- self.solid = SOLID_NOT;
- if (!deathmatch)
- CheckItemRespawn(self, 30);
- else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
- self.nextthink = time + 30;
- self.think = SUB_regen;
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-
-
-
-float WEAPON_BIG2 = 1;
-
-/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_shell1.bsp" }, "maps/b_shell0.bsp" }} );
-}
-Box of 20 shells.
-LARGE_BOX is a box of 40 shells.
-*/
-
-void() item_shells =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
-
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.s_lg_mdl) self.mdl_body = world.s_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_shell2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_shell2.mdl");
- }
- // precache_model ("maps/b_shell1.bsp");
- // setmodel (self, "maps/b_shell1.bsp");
- else
- {
- precache_body_model ("maps/b_shell1.bsp");
- body_model ("maps/b_shell1.bsp");
- }
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 40;
- }
- else
- {
- if (!self.mdl_body && world.s_sm_mdl) self.mdl_body = world.s_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_shell1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_shell1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_shell0.bsp");
- body_model ("maps/b_shell0.bsp");
- }
- // precache_model ("maps/b_shell0.bsp");
- // setmodel (self, "maps/b_shell0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 20;
- }
- self.weapon = 1;
- self.netname = "shells";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_nail1.bsp" }, "maps/b_nail0.bsp" }} );
-}
-Box of 25 nails.
-LARGE_BOX is a box of 50 nails.
-*/
-
-void() item_spikes =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.n_lg_mdl) self.mdl_body = world.n_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_nails2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_nails2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_nail1.bsp");
- body_model ("maps/b_nail1.bsp");
- }
- // precache_model ("maps/b_nail1.bsp");
- // setmodel (self, "maps/b_nail1.bsp");
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 50;
- }
- else
- {
-
- if (!self.mdl_body && world.n_sm_mdl) self.mdl_body = world.n_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_nails1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_nails1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_nail0.bsp");
- body_model ("maps/b_nail0.bsp");
- }
- // precache_model ("maps/b_nail0.bsp");
- // setmodel (self, "maps/b_nail0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 25;
- }
- self.weapon = 2;
- self.netname = "nails";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_rock1.bsp" }, "maps/b_rock0.bsp" }} );
-}
-*/
-
-void() item_rockets =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
-
- if (!self.mdl_body && world.r_lg_mdl) self.mdl_body = world.r_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_rock2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_rock2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_rock1.bsp");
- body_model ("maps/b_rock1.bsp");
- }
- // precache_model ("maps/b_rock1.bsp");
- // setmodel (self, "maps/b_rock1.bsp");
- self.particles_offset = '16 8 16';
- self.aflag = 10;
- }
- else
- {
- if (!self.mdl_body && world.r_sm_mdl) self.mdl_body = world.r_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_rock1.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_rock1.mdl");
- }
- else
- {
- precache_body_model ("maps/b_rock0.bsp");
- body_model ("maps/b_rock0.bsp");
- }
- // precache_model ("maps/b_rock0.bsp");
- // setmodel (self, "maps/b_rock0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '8 8 16';
- self.aflag = 5;
- }
- self.weapon = 3;
- self.netname = "rockets";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-
-/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "maps/b_batt1.bsp" }, "maps/b_batt0.bsp" }} );
-}
-Box of 6 cells.
-LARGE_BOX is a box of 12 cells.
-*/
-
-void() item_cells =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = ammo_touch;
-
- if (self.spawnflags & WEAPON_BIG2)
- {
- if (!self.mdl_body && world.c_lg_mdl) self.mdl_body = world.c_lg_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_cells2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_batt1.bsp");
- body_model ("maps/b_batt1.bsp");
- }
- // precache_model ("maps/b_batt1.bsp");
- // setmodel (self, "maps/b_batt1.bsp");
- if !(self.particles_offset)
- self.particles_offset = '16 16 16';
- self.aflag = 12;
- }
- else
- {
- if (!self.mdl_body && world.c_sm_mdl) self.mdl_body = world.c_sm_mdl;
- if (world.style)
- {
- precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
- body_model("progs/a_mdls/m_cells2.mdl");
- }
- else
- {
- precache_body_model ("maps/b_batt0.bsp");
- body_model ("maps/b_batt0.bsp");
- }
- // precache_model ("maps/b_batt0.bsp");
- // setmodel (self, "maps/b_batt0.bsp");
- if !(self.particles_offset)
- self.particles_offset = '12 12 12';
- self.aflag = 6;
- }
- self.weapon = 4;
- self.netname = "cells";
- setsize (self, '0 0 0', '32 32 56');
- StartItem ();
-};
-
-
-/*
-===============================================================================
-
-KEYS
-
-===============================================================================
-*/
-
-
-void() key_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-// support for item_key_custom -- iw
- if (HasKeys (other, self.items, self.customkeys))
- return;
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other,"\n");
-
- sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// support for item_key_custom -- iw
- GiveKeys (other, self.items, self.customkeys);
-
- if (!coop)
- {
- self.solid = SOLID_NOT;
- self.model = string_null;
- }
-
- activator = other;
-// fix key items firing their targets multiple times in coop -- iw
-// SUB_UseTargets(); // fire all targets / killtargets
- SUB_UseAndForgetTargets();
-};
-
-
-void() key_setsounds =
-{
-// support for item_key_custom -- iw
- if (self.noise != "")
- {
- precache_sound (self.noise);
- return;
- }
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_sound ("misc/medkey.wav");
- self.noise = "misc/medkey.wav";
- }
- if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_sound ("misc/runekey.wav");
- self.noise = "misc/runekey.wav";
- }
- if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_sound2 ("misc/basekey.wav");
- self.noise = "misc/basekey.wav";
- }
-};
-
-
-/*
-============
-key_start
-
-Finish initializing self as a key item. -- iw
-============
-*/
-void() key_start =
-{
- key_setsounds ();
- self.particles_offset = '0 0 18';
- self.touch = key_touch;
- setsize (self, '-16 -16 -24', '16 16 32');
- StartItem ();
-};
-
-
-/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/w_s_key.mdl"); }
-SILVER key
-In order for keys to work you MUST set your map's worldtype to one of the following:
-0: medieval
-1: metal
-2: base
-*/
-
-void() item_key1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_body_model ("progs/w_s_key.mdl");
- body_model ("progs/w_s_key.mdl");
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_body_model ("progs/m_s_key.mdl");
- body_model ("progs/m_s_key.mdl");
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_body_model2 ("progs/b_s_key.mdl");
- body_model ("progs/b_s_key.mdl");
- }
-
- if (self.keyname != "") self.netname = self.keyname;
- else self.netname = SilverKeyName ();
-
- self.items = IT_KEY1;
-
-// support for item_key_custom -- iw
- self.customkeys = 0; // ignore any mapper-set value
- self.noise = ""; // ignore any mapper-set value
-
- key_start ();
-};
-
-
-/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/w_g_key.mdl");
-}
-GOLD key
-In order for keys to work you MUST set your map's worldtype to one of the following:
-0: medieval
-1: metal
-2: base
-*/
-
-void() item_key2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- precache_body_model ("progs/w_g_key.mdl");
- body_model ("progs/w_g_key.mdl");
- }
- if (world.worldtype == WORLDTYPE_METAL)
- {
- precache_body_model ("progs/m_g_key.mdl");
- body_model ("progs/m_g_key.mdl");
- }
- if (world.worldtype == WORLDTYPE_BASE)
- {
- precache_body_model2 ("progs/b_g_key.mdl");
- body_model ("progs/b_g_key.mdl");
- }
-
- if (self.keyname != "") self.keyname = "";
- else self.netname = GoldKeyName ();
-
- self.items = IT_KEY2;
-
-// support for item_key_custom -- iw
- self.customkeys = 0; // ignore any mapper-set value
- self.noise = ""; // ignore any mapper-set value
-
- key_start ();
-};
-
-
-// item_key_custom is a brand-spanking-new entity class created for
-// progs_dump -- iw
-
-/*QUAKED item_key_custom (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path" : "progs/pd_w_key.mdl", "skin" : 1});
-}
-A customizable key item.
-
-"keyname" name of the key, e.g. "bronze key" (required)
-"mdl" model file (required)
-"noise" sound file for the pickup sound (default is per worldtype)
-"skin" skin index (default 0)
-
-The "keyname" value is used both for the pickup message and to associate
-the key with the entity that it unlocks.
-
-To make a func_door or trigger_usekey require this key, set the
-"keyname" value of that entity so that it matches the "keyname" value of
-the key.
-
-If different item_key_custom entities have the same "keyname" value,
-they will be treated as different copies of the same key and may be used
-interchangeably.
-
-A map may have a maximum of 23 unique "keyname" values across all
-entities.
-
-The behavior of an item_key_custom should be as the player expects
-(based on the behavior of the silver and gold keys), except for the fact
-that it will not appear as an icon in the player's status bar when
-picked up. This is a limitation of the engine.
-*/
-
-void() item_key_custom =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.keyname == "")
- {
- objerror ("no keyname specified");
- return;
- }
-
- if (self.mdl == "")
- {
- objerror ("no mdl specified");
- return;
- }
-
- precache_model (self.mdl);
- setmodel (self, self.mdl);
- self.mdl = ""; // this should not be referenced again
-
- self.netname = self.keyname;
- self.keyname = ""; // this should not be referenced again
-
- self.items = 0; // ignore any mapper-set value
- self.customkeys = CustomKeyFlag (self.netname);
-
- key_start ();
-};
-
-
-/*
-===============================================================================
-
-END OF LEVEL RUNES
-
-===============================================================================
-*/
-
-void() sigil_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- centerprint (other, "You got the rune!");
-
- sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- self.model = string_null;
- serverflags = serverflags | (self.spawnflags & 15);
- self.classname = ""; // so rune doors won't find it
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-void() sigil_touch2 = //replacement for Skill Select Rune hack -- uses info_player_start2 if spawnflag 16 -- dumptruck_ds
-{
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- // centerprint (other, "You got the rune!");
-
- // sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
- // stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- self.model = string_null;
- serverflags = serverflags | (self.spawnflags & 16);
- self.classname = ""; // so rune doors won't find it
-
- activator = other;
- // SUB_UseTargets(); // fire all targets / killtargets
-};
-
-
-/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "progs/end1.mdl" }, spawnflags & 2 -> { "path" : "progs/end2.mdl" },
- spawnflags & 4 -> { "path" : "progs/end3.mdl" }, spawnflags & 8 -> { "path" : "progs/end4.mdl" },
- "progs/end1.mdl" }} );
-}
-End of episode rune. Use in conjuction with func_bossgate and func_episodegate.
-Spawnflag must be set to the appropriate episode.
-Episode 1 - Dimension of the Doomed - Rune of Earth Magic
-Episode 2 - The Realm of Black Magic - Rune of Black Magic
-Episode 3 - The Netherworld - Rune of Hell Magic
-Episode 4 - The Elder World - Run of Elder Magic
-*/
-
-void() item_sigil =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.spawnflags)
- objerror ("no spawnflags");
-
- precache_sound ("misc/runekey.wav");
- self.noise = "misc/runekey.wav";
-
- if (self.spawnflags & 1)
- {
- precache_model ("progs/end1.mdl");
- setmodel (self, "progs/end1.mdl");
- }
- if (self.spawnflags & 2)
- {
- precache_model2 ("progs/end2.mdl");
- setmodel (self, "progs/end2.mdl");
- }
- if (self.spawnflags & 4)
- {
- precache_model2 ("progs/end3.mdl");
- setmodel (self, "progs/end3.mdl");
- }
- if (self.spawnflags & 8)
- {
- precache_model2 ("progs/end4.mdl");
- setmodel (self, "progs/end4.mdl");
- }
-
- self.touch = sigil_touch;
- setsize (self, '-16 -16 -24', '16 16 32');
- self.particles_offset = '0 0 18';
- StartItem ();
-};
-
-/*
-===============================================================================
-
-POWERUPS
-
-===============================================================================
-*/
-
-void() powerup_touch;
-
-
-void() powerup_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- sprint (other, "You got the ");
- sprint (other, self.netname);
- sprint (other,"\n");
-
- // if (deathmatch)
- // {
- // self.mdl = self.model;
- //
- // if ((self.classname == "item_artifact_invulnerability") ||
- // (self.classname == "item_artifact_invisibility"))
- // self.nextthink = time + 60*5;
- // else
- // self.nextthink = time + 60;
- //
- // self.think = SUB_regen;
- // }
-
- // Supa, SP respawning items support
- self.mdl = self.model;
- self.think = SUB_regen;
-
- if (!deathmatch)
- {
- local float spawndelay;
-
- if (self.classname == "item_artifact_invulnerability" ||
- self.classname == "item_artifact_invisibility" ) spawndelay = 300;
- // else if (self.classname == "item_grappling_hook" ) spawndelay = 30;
- else spawndelay = 60;
-
- CheckItemRespawn(self, spawndelay);
- }
- else
- {
- if ((self.classname == "item_artifact_invulnerability") ||
- (self.classname == "item_artifact_invisibility"))
- self.nextthink = time + 60*5;
- else
- self.nextthink = time + 60;
- }
-
- sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- self.solid = SOLID_NOT;
- other.items = other.items | self.items;
- self.model = string_null;
-
-// do the apropriate action
- if (self.classname == "item_artifact_envirosuit")
- {
- other.rad_time = 1;
- other.radsuit_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_invulnerability")
- {
- other.invincible_time = 1;
- other.invincible_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_invisibility")
- {
- other.invisible_time = 1;
- other.invisible_finished = time + 30;
- }
-
- if (self.classname == "item_artifact_super_damage")
- {
- other.super_time = 1;
- other.super_damage_finished = time + 30;
- }
-
- activator = other;
- SUB_UseTargets(); // fire all targets / killtargets
-};
-
-/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/invulner.mdl"); }
-Pentagram of Protection
-Player is invulnerable for 30 seconds
-*/
-void() item_artifact_invulnerability =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- // precache_model ("progs/invulner.mdl");
- precache_body_model ("progs/invulner.mdl");
- precache_sound ("items/protect.wav");
- precache_sound ("items/protect2.wav"); // called in client.qc -- dumptruck_ds
- precache_sound ("items/protect3.wav"); // called in combat.qc -- dumptruck_ds
- self.noise = "items/protect.wav";
- // setmodel (self, "progs/invulner.mdl");
- body_model ("progs/invulner.mdl");
- self.netname = "Pentagram of Protection";
- self.items = IT_INVULNERABILITY;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 16';
- StartItem ();
-};
-
-/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/suit.mdl"); }
-Biosuit
-Player takes no damage from water or slime for 30 seconds
-*/
-void() item_artifact_envirosuit =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/suit.mdl");
- precache_sound ("items/suit.wav");
- precache_sound ("items/suit2.wav");
- self.noise = "items/suit.wav";
- // setmodel (self, "progs/suit.mdl");
- body_model ("progs/suit.mdl");
- self.netname = "Biosuit";
- self.items = IT_SUIT;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 32';
- StartItem ();
-};
-
-
-/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/invisibl.mdl"); }
-Ring of Shadows
-Player is invisible for 30 seconds
-*/
-void() item_artifact_invisibility =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/invisibl.mdl");
- precache_sound ("items/inv1.wav");
- precache_sound ("items/inv2.wav");
- precache_sound ("items/inv3.wav");
- self.noise = "items/inv1.wav";
- // setmodel (self, "progs/invisibl.mdl");
- body_model ("progs/invisibl.mdl");
- self.netname = "Ring of Shadows";
- self.items = IT_INVISIBILITY;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 0';
- StartItem ();
-};
-
-
-/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/quaddama.mdl"); }
-Quad Damage
-Player does 4x damage for 30 seconds
-*/
-void() item_artifact_super_damage =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.touch = powerup_touch;
-
- precache_body_model ("progs/quaddama.mdl");
- precache_sound ("items/damage.wav");
- precache_sound ("items/damage3.wav");
- self.noise = "items/damage.wav";
- // setmodel (self, "progs/quaddama.mdl");
- body_model ("progs/quaddama.mdl");
- if !(self.netname) // custom name -- dumptruck_ds
- self.netname = "Quad Damage";
- self.items = IT_QUAD;
- setsize (self, '-16 -16 -24', '16 16 32');
- if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
- self.particles_offset = '0 0 16';
- StartItem ();
-};
-
-
-
-/*
-===============================================================================
-
-PLAYER BACKPACKS
-
-===============================================================================
-*/
-
-void() BackpackTouch =
-{
- local string s;
- local float best, old, new;
- local entity stemp;
- local float acount;
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- acount = 0;
- sprint (other, "You get ");
-
- if (self.items)
- if ((other.items & self.items) == 0)
- {
- acount = 1;
- sprint (other, "the ");
- sprint (other, self.netname);
- }
-
-// if the player was using his best weapon, change up to the new one if better
- stemp = self;
- self = other;
- best = W_BestWeapon();
- self = stemp;
-
-// change weapons
- other.ammo_shells = other.ammo_shells + self.ammo_shells;
- other.ammo_nails = other.ammo_nails + self.ammo_nails;
- other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
- other.ammo_cells = other.ammo_cells + self.ammo_cells;
-
- new = self.items;
- if (!new)
- new = other.weapon;
- old = other.items;
- other.items = other.items | new;
-
- bound_other_ammo ();
-
- if (self.ammo_shells) // hack to fix an issue with custom Grunt, Ogre and Enf ammo types. - dumptruck_ds
- // if (self.ammo_shells < 100)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_shells);
- sprint (other, s);
- sprint (other, " shells");
- }
- if (self.ammo_nails)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_nails);
- sprint (other, s);
- sprint (other, " nails");
- }
- if (self.ammo_rockets)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_rockets);
- sprint (other, s);
- sprint (other, " rockets");
- }
- if (self.ammo_cells)
- {
- if (acount)
- sprint(other, ", ");
- acount = 1;
- s = ftos(self.ammo_cells);
- sprint (other, s);
- sprint (other, " cells");
- }
-
- sprint (other, "\n");
-// backpack touch sound
- sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
-
-// remove the backpack, change self to the player
- remove(self);
- self = other;
-
-// change to the weapon
-// 1997-12-23 Thunderbolt fix by Maddes start
-/* don't separate between SinglePlayer/Coop and Deathmatch
- if (!deathmatch)
- self.weapon = new;
- else
-*/
-// 1997-12-23 Thunderbolt fix by Maddes end
- Deathmatch_Weapon (old, new);
-
- W_SetCurrentAmmo ();
-
-};
-
-/*
-===============
-DropStuff -- dumptruck_ds
-
-set drops_item on a monster to a number:
-
-1 = Silver Key
-2 = Gold Key
-3 = Health Vial
-4 = Armor Shard
-5 = Health Vial & Armor Shard
-6 = random combination of 3 Vials and/or Shards
-===============
-*/
-
-void() DropKey1 =
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- // precache_model ("progs/w_s_key.mdl");
- setmodel (item, "progs/w_s_key.mdl");
- item.noise = "misc/medkey.wav";
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- // precache_model ("progs/m_s_key.mdl");
- setmodel (item, "progs/m_s_key.mdl");
- item.noise = "misc/runekey.wav";
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- // precache_model2 ("progs/b_s_key.mdl");
- setmodel (item, "progs/b_s_key.mdl");
- item.noise = "misc/basekey.wav";
- }
- item.netname = SilverKeyName ();
- item.effects = 8;
- item.flags = FL_ITEM;
- item.items = IT_KEY1;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = key_touch;
-};
-
-void() DropKey2 =
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- if (world.worldtype == WORLDTYPE_MEDIEVAL)
- {
- // precache_model ("progs/w_s_key.mdl");
- setmodel (item, "progs/w_g_key.mdl");
- item.noise = "misc/medkey.wav";
- }
- else if (world.worldtype == WORLDTYPE_METAL)
- {
- // precache_model ("progs/m_s_key.mdl");
- setmodel (item, "progs/m_g_key.mdl");
- item.noise = "misc/runekey.wav";
- }
- else if (world.worldtype == WORLDTYPE_BASE)
- {
- // precache_model2 ("progs/b_s_key.mdl");
- setmodel (item, "progs/b_g_key.mdl");
- item.noise = "misc/basekey.wav";
- }
- item.netname = GoldKeyName ();
- item.effects = 8;
- item.flags = FL_ITEM;
- item.items = IT_KEY2;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = key_touch;
-};
-
-void() DropVial = //
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- setmodel(item, "progs/h_mdls/pd_vial.mdl");
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = health_touch;
- item.healamount = 5;
- item.healtype = 0;
- item.noise = "items/r_item1.wav";
-
- StartItem ();
-};
-
-void() DropShard = //
-{
- local entity item;
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- setmodel(item, "progs/armshr.mdl");
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = shard_touch;
- item.snd_misc = "dump/armsh1.wav";
-
- StartItem ();
-};
-
-void() DropStuff =
-{
- local float rand_drop;
-
- if (self.drop_item == 1)
- {
- DropKey1();
- }
- if (self.drop_item == 2)
- {
- DropKey2();
- }
- if (self.drop_item == 3)
- {
- DropVial();
- }
- if (self.drop_item == 4)
- {
- DropShard();
- }
- if (self.drop_item == 5)
- {
- DropVial();
- DropShard();
- }
- else if (self.drop_item == 6)
- {
- rand_drop = rint(random() * 3);
- if (rand_drop == 1)
- {
- DropShard();
- DropVial();
- DropVial();
- }
- else if (rand_drop == 2)
- {
- DropShard();
- DropShard();
- DropVial();
- }
- else if (rand_drop == 0)
- {
- DropShard();
- DropShard();
- DropShard();
- }
- else
- {
- DropVial();
- DropVial();
- DropVial();
- }
- }
- return;
-};
-
-/*
-===============
-DropBackpack
-===============
-*/
-void() DropBackpack =
-{
- local entity item;
-
- if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
- return; // nothing in it
-
- item = spawn();
- item.origin = self.origin - '0 0 24';
-
- item.items = self.weapon;
- if (item.items == IT_AXE)
- item.netname = "Axe";
- else if (item.items == IT_SHOTGUN)
- item.netname = "Shotgun";
- else if (item.items == IT_SUPER_SHOTGUN)
- item.netname = "Double-barrelled Shotgun";
- else if (item.items == IT_NAILGUN)
- item.netname = "Nailgun";
- else if (item.items == IT_SUPER_NAILGUN)
- item.netname = "Super Nailgun";
- else if (item.items == IT_GRENADE_LAUNCHER)
- item.netname = "Grenade Launcher";
- else if (item.items == IT_ROCKET_LAUNCHER)
- item.netname = "Rocket Launcher";
- else if (item.items == IT_LIGHTNING)
- item.netname = "Thunderbolt";
- else
- item.netname = "";
-
- item.ammo_shells = self.ammo_shells;
- item.ammo_nails = self.ammo_nails;
- item.ammo_rockets = self.ammo_rockets;
- item.ammo_cells = self.ammo_cells;
-
- item.velocity_z = 300;
- item.velocity_x = -100 + (random() * 200);
- item.velocity_y = -100 + (random() * 200);
-
- item.flags = FL_ITEM;
- item.solid = SOLID_TRIGGER;
- item.movetype = MOVETYPE_TOSS;
- setmodel (item, "progs/backpack.mdl");
- setsize (item, '-16 -16 0', '16 16 56');
- item.touch = BackpackTouch;
-
- item.nextthink = time + 120; // remove after 2 minutes
- item.think = SUB_Remove;
-};
-
-// dumptruck_ds
-float DEFAULT = 1;
-float SHELLS = 2;
-float NAILS = 4;
-float ROCKETS = 8;
-float CELLS = 16;
-
-void() item_backpack_message =
-{
-
- if (!CheckValidTouch()) return; // from Copper -- dumptruck_ds
-
- other.ammo_shells = other.ammo_shells + self.ammo_shells;
- other.ammo_nails = other.ammo_nails + self.ammo_nails;
- other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
- other.ammo_cells = other.ammo_cells + self.ammo_cells;
-
- if (self.netname != "")
- {
- sprint (other, "You got ");
- sprint (other, self.netname);
- sprint (other, "\n");
- }
- else
- sprint (other, "You got a backpack!\n");
-
- // backpack touch sound
- // sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
- sound_misc (other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
- stuffcmd (other, "bf\n");
- remove(self);
- self = other;
- bound_other_ammo();
- W_SetCurrentAmmo ();
-
-};
-// Some of this text is from Drake -- dumptruck_ds
-/*QUAKED item_backpack (0 .5 .8) (-16 -16 0) (16 16 72) SHELLS NAILS ROCKETS CELLS X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/backpack.mdl"); }
-By default, gives roughly half the ammo from the 4 standard pickups:
-
-10 Shells
-12 Nails
-2 Rockets
-3 Cells
-
-Or you can use the spawnflags to mix and match types.
-Override the spawnflags defaults by adding custom amounts to:
-
-ammo_shells
-ammo_nails
-ammo_rockets
-ammo_cells
-
-Can trigger spawn and suspend in air, but not respawn. You can set a skin
-index if you are using a custom model with skins.
-
-The default pickup message is `You got a backpack.` But you can
-set a custom message with the netname key. 'You got' will be the prefix
-and the mapper chooses the rest of the message.
-
-e.g. For 'You got a bunch of rockets!' the netname key would be
-'a bunch of rockets!'
-*/
-void() item_backpack =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- self.flags = FL_ITEM;
- self.solid = SOLID_TRIGGER;
- self.movetype = MOVETYPE_TOSS;
- self.classname = "item_backpack";
- // self.netname = self.netname;
- if !(self.spawnflags)
- {
- objerror ("\bNO SPAWNFLAG SET ON item_backpack");
- return;
- }
-
- if (self.spawnflags & DEFAULT)
- {
- self.ammo_shells = 10;
- self.ammo_nails = 12;
- self.ammo_rockets = 2;
- self.ammo_cells = 3;
- }
-
- if (self.spawnflags & SHELLS)
- {
- if !(self.ammo_shells)
- {
- self.ammo_shells = 10;
- }
- }
- if (self.spawnflags & NAILS)
- {
- if !(self.ammo_nails)
- {
- self.ammo_nails = 12;
- }
- }
- if (self.spawnflags & ROCKETS)
- {
- if !(self.ammo_rockets)
- {
- self.ammo_rockets = 2;
- }
- }
- if (self.spawnflags & CELLS)
- {
- if !(self.ammo_cells)
- {
- self.ammo_cells = 3;
- }
- }
-
- self.touch = item_backpack_message;
-
- if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
- self.snd_misc = "weapons/lock4.wav";
- precache_sound_misc(self.snd_misc);
- precache_body_model ("progs/pd_bpack.mdl");
- body_model ("progs/pd_bpack.mdl");
- // setmodel (self, "progs/backpack.mdl");
- setsize (self, '-16 -16 0', '16 16 56');
- StartItem ();
-};
+void (vector org) spawn_tfog;
+void() W_SetCurrentAmmo;
+/* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
+BE .8 .3 .4 IN COLOR */
+
+float ITEM_SPAWNSILENT = 32;
+float ITEM_SPAWNED = 64;
+float ITEM_SUSPENDED = 128;
+float ITEM_RESPAWNDM = 16384;
+float ITEM_DONTDROP = 8388608;
+
+.vector particles_offset;
+
+void() SUB_regen =
+{
+ self.model = self.mdl; // restore original model
+ self.solid = SOLID_TRIGGER; // allow it to be touched again
+ if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM)) // Respawn with DM effects
+ sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM); // play respawn sound
+ else
+ spawn_tfog (self.origin + self.particles_offset); // play teleport sound and display particles
+ setorigin (self, self.origin);
+};
+
+// Supa, Quoth respawning items support Respawn item like in DM if 'ritem' TRUE,
+// override respawn time with 'respawndelay' if set, inc 'cnt' with each respawn
+// and if 'respawncount' is set we'll remove the item if cnt > respawncount
+// remember that SUB_Regen is already set on every item that can respawn, all we
+// need to do is give a nextthink time in order to trigger it
+.float ritem,
+ respawndelay,
+ respawncount;
+
+void(entity whatitem, float defaultdelay) CheckItemRespawn =
+{
+ if (!whatitem.ritem) // respawn item if true, otherwise abort
+ return;
+
+ whatitem.cnt = whatitem.cnt + 1; // inc before check to account for zero indexing
+
+ if (whatitem.respawncount) // limited respawns
+ if (whatitem.respawncount < whatitem.cnt)
+ return;
+
+ // okay, we're clear to set up a respawn
+
+ if (whatitem.respawndelay) // custom respawn delay?
+ whatitem.nextthink = time + whatitem.respawndelay;
+ else
+ whatitem.nextthink = time + defaultdelay;
+};
+
+
+/*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
+prints a warning message when spawned
+*/
+void() noclass =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ dprint ("noclass spawned at");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove (self);
+};
+
+/*
+============
+DelaySpawnItem //this is from rmq-items.qc
+
+Makes a SPAWNED item ready for pickup on a trigger event - modified a bit -- dumptruck_ds
+============
+*/
+void() DelaySpawnItem =
+{
+ self.solid = SOLID_TRIGGER;
+ setmodel (self, self.mdl);
+ setsize (self, self.pos1, self.pos2);
+
+ if (!(self.spawnflags & ITEM_SPAWNSILENT)) // SILENT, gb
+ // sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
+ spawn_tfog (self.origin + self.particles_offset);
+
+ if (self.spawnflags & ITEM_SUSPENDED)
+ self.movetype = MOVETYPE_FLY;
+ else
+ self.movetype = MOVETYPE_TOSS;
+
+ self.use = SUB_Null;
+};
+
+
+// Supa, restore old hull and lock movement
+void() RefreshHull =
+{
+ // setsize (self, self.dest, self.dest2);
+ setsize (self, '0 0 0', '32 32 56'); //dumptruck_ds -- fix for bounding boxes
+
+ self.movetype = MOVETYPE_NONE;
+ self.velocity = '0 0 0';
+};
+
+
+/*
+============
+PlaceItem
+
+plants the object on the floor
+============
+*/
+void() PlaceItem =
+{
+ // local float oldz;
+ self.mdl = self.model; // so it can be restored on respawn
+ self.flags = FL_ITEM; // make extra wide
+ self.solid = SOLID_TRIGGER;
+ self.velocity = '0 0 0';
+
+ if (self.spawnflags & ITEM_SUSPENDED) //ijed Don't drop spawnflag
+ {
+ self.movetype = MOVETYPE_FLY;
+ }
+ else
+ {
+ // The following hack for item_health was inherited from the RMQ
+ // code, and was here when the func_mapjamx maps were created.
+ // It would have been nice to remove this code entirely, because
+ // progs_dump doesn't need it, and it breaks item_health's
+ // collision with entities that have MOVETYPE_PUSH. However,
+ // removing this code would cause some of the item_health
+ // entities in some of the func_mapjamx maps to "fall out of the
+ // level", because they're accidentally touching solid surfaces.
+ // So, to maintain backwards-compatibility, this code has been
+ // left in, but will only be run if one of the func_mapjamx maps
+ // is being played. -- iw
+ //
+ if (known_release == KNOWN_RELEASE_FUNC_MAPJAMX)
+ {
+ if (self.classname == "item_health") // Supa, CTF
+ {
+
+ // hacking around hull issues..
+ setsize (self, '0 0 0', '0 0 0'); // void hull for now
+
+ self.think = RefreshHull;
+ self.nextthink = time + 0.2;
+ }
+ }
+
+ self.movetype = MOVETYPE_TOSS;
+
+ if (!(self.spawnflags & ITEM_DONTDROP))
+ {
+ setorigin (self, self.origin + '0 0 6');
+
+ if (!droptofloor())
+ {
+ print_self ("bonus item", "fell out of level");
+ remove(self);
+ return;
+ }
+ }
+ }
+
+ if ((self.spawnflags & ITEM_SPAWNED)) // SPAWNED, gb
+ {
+ self.pos1 = self.mins;
+ self.pos2 = self.maxs;
+
+ self.model = "";
+ self.solid = SOLID_NOT;
+
+ if (self.spawnflags & ITEM_DONTDROP) self.movetype = MOVETYPE_NONE;
+
+ self.use = DelaySpawnItem;
+ }
+};
+
+
+/*
+============
+StartItem
+
+Sets the clipping size and plants the object on the floor
+============
+*/
+void() StartItem =
+{
+ self.nextthink = time + 0.3; // items start after other solids || was 0.2 -- dumptruck_ds
+ self.think = PlaceItem;
+};
+
+/*
+=========================================================================
+
+HEALTH BOX
+
+=========================================================================
+*/
+//
+// T_Heal: add health to an entity, limiting health to max_health
+// "ignore" will ignore max_health limit
+//
+float (entity e, float healamount, float ignore) T_Heal =
+{
+ if (e.health <= 0)
+ return 0;
+ if ((!ignore) && (e.health >= other.max_health))
+ return 0;
+ healamount = ceil(healamount);
+
+ e.health = e.health + healamount;
+ if ((!ignore) && (e.health >= other.max_health))
+ e.health = other.max_health;
+
+ if (e.health > 250)
+ e.health = 250;
+ return 1;
+};
+
+/*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) ROTTEN MEGAHEALTH X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_bh10.bsp" }, spawnflags & 2 -> { "path" : "maps/b_bh100.bsp" },
+ "maps/b_bh25.bsp" }} );
+}
+Health box. Normally gives 25 points.
+Rotten box heals 15 points.
+Megahealth will add 100 health, then start to
+rot the player back down to 100 health after 5 seconds.
+*/
+
+float H_ROTTEN = 1;
+float H_MEGA = 2;
+float H_VIAL = 4;
+.float healamount, healtype;
+void() health_touch;
+// void() item_megahealth_rot;
+
+void() item_health =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = health_touch;
+
+
+
+ if (self.spawnflags & H_ROTTEN)
+ {
+ if (!self.mdl_body && world.h_15_mdl)
+ {
+ self.mdl_body = world.h_15_mdl;
+ }
+ // precache_model("maps/b_bh10.bsp"); // dumptruck_ds custom health models and sounds START
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h15.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h15.mdl");
+ }
+ else
+ {
+ // setmodel(self, "maps/b_bh10.bsp");
+ precache_body_model ("maps/b_bh10.bsp");
+ body_model ("maps/b_bh10.bsp");
+ }
+ // precache_sound("items/r_item1.wav");
+ precache_sound_misc("items/r_item1.wav");
+ // self.noise = "items/r_item1.wav";
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item1.wav";
+ self.noise = self.snd_misc;
+
+ // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
+ self.healamount = 15;
+ self.healtype = 0;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
+
+ }
+ else
+ if (self.spawnflags & H_MEGA)
+ {
+ if (!self.mdl_body && world.h_mega_mdl)
+ {
+ self.mdl_body = world.h_mega_mdl;
+ }
+ // precache_model("maps/b_bh100.bsp");
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h100.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h100.mdl");
+ }
+ else
+ {
+ // setmodel(self, "maps/b_bh100.bsp");
+ precache_body_model ("maps/b_bh100.bsp");
+ body_model ("maps/b_bh100.bsp");
+ }
+ precache_sound_misc("items/r_item2.wav");
+ // self.noise = "items/r_item2.wav";
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item2.wav";
+ self.noise = self.snd_misc;
+
+ // if !(self.healamount) //set your custom health amount here -- dumptruck_ds
+ self.healamount = 100;
+ self.healtype = 2;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ }
+ else
+ {
+ if (!self.mdl_body && world.h_25_mdl)
+ {
+ self.mdl_body = world.h_25_mdl;
+ }
+ if (world.style)
+ {
+ precache_body_model ("progs/h_mdls/m_h25.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/h_mdls/m_h25.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_bh25.bsp");
+ body_model ("maps/b_bh25.bsp");
+ }
+ precache_sound_misc("items/health1.wav");
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/health1.wav";
+ self.noise = self.snd_misc;
+
+ self.healamount = 25;
+ self.healtype = 1;
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 8'; // dumptruck_ds custom health models and sounds END
+ }
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+void() item_health_vial =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = health_touch;
+
+ if (!self.mdl_body && world.h_vial_mdl)
+ {
+ self.mdl_body = world.h_vial_mdl;
+ }
+
+ precache_body_model ("progs/h_mdls/pd_vial.mdl"); // model from Hexen 2 -- dumptruck_ds
+ body_model("progs/h_mdls/pd_vial.mdl");
+ precache_sound_misc("items/r_item1.wav");
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "items/r_item1.wav";
+ self.noise = self.snd_misc;
+
+ self.healamount = 5;
+ self.healtype = 2; // over heal and count down like mega health -- dumptruck_ds
+ setsize (self, '-16 -16 0', '16 16 56');
+ if !(self.particles_offset)
+ self.particles_offset = '0 0 0';
+ StartItem ();
+};
+
+void() health_touch =
+{
+ local float amount;
+ local string s;
+ amount = self.healamount;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.healtype == 2) // Megahealth? Ignore max_health...
+ {
+ if (other.health >= 250)
+ return;
+ if (!T_Heal(other, amount, 1))
+ return;
+ }
+ else
+ {
+ if (!T_Heal(other, amount, 0))
+ return;
+ }
+
+ sprint(other, "You receive ");
+ s = ftos(amount);
+ sprint(other, s);
+ sprint(other, " health\n");
+
+// health touch sound
+ // sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ sound_misc(other, CHAN_AUTO, self.noise, 1, ATTN_NORM); //custom sounds -- dumptruck_ds
+
+ stuffcmd (other, "bf\n");
+
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+
+ self.think = SUB_regen;
+
+ // Megahealth = rot down the player's super health
+ if (self.healtype == 2)
+ {
+ other.megahealth_rottime = time + 5; //thanks ydrol!!!
+ other.items = other.items | IT_SUPERHEALTH;
+ self.owner = other;
+
+ // Regarding the deathmatch respawn time below: id's original
+ // code made the megahealth respawn 20 seconds after the health
+ // of the player who collected it finished rotting down.
+ // However, this mod has already got rid of the weird old
+ // megahealth behavior whereby it monitored the player who
+ // touched it, so the original respawn logic isn't applicable.
+ // As a solution, the code below uses a respawn time of 125
+ // seconds for deathmatch, because that was the worst-case
+ // scenario of id's original code (5 seconds before the player's
+ // health started to rot, plus 100 seconds to rot down 100
+ // health points, plus the original 20 second delay before the
+ // item respawned). -- iw
+ //
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 125;
+ }
+ else
+ {
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ }
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*
+===============================================================================
+
+ARMOR
+
+===============================================================================
+*/
+
+void() armor_touch;
+void() shard_touch;
+
+
+void() shard_touch = // this from RMQ shard_touch
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ local float bit;
+
+ if ((other.items & IT_ARMOR1) ||
+ (other.items & IT_ARMOR2) ||
+ (other.items & IT_ARMOR3) ) // has armor
+ {
+ // Supa, check bounds, original armourvalue + 25
+ if (other.items & IT_ARMOR1 && other.armorvalue >= 125) return;
+ if (other.items & IT_ARMOR2 && other.armorvalue >= 175) return;
+ if (other.items & IT_ARMOR3 && other.armorvalue >= 225) return;
+
+ other.armorvalue = other.armorvalue + 5; // was 2, RMQ team
+
+ // Supa, now cap armourvalue to bounds
+ if (other.items & IT_ARMOR1 && other.armorvalue >= 125) other.armorvalue = 125;
+ else if (other.items & IT_ARMOR2 && other.armorvalue >= 175) other.armorvalue = 175;
+ else if (other.items & IT_ARMOR3 && other.armorvalue >= 225) other.armorvalue = 225;
+ }
+ else
+ {
+ other.armortype = 0.3; // shard = Green armor level
+ other.armorvalue = 5;
+ bit = IT_ARMOR1;
+ other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
+ }
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ self.think = SUB_regen;
+
+ if (self.obit_name != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.obit_name); // custom armor name
+ sprint (other, "\n");
+ }
+ else
+ sprint(other, "You got armor\n");
+ // armor touch sound
+ // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
+ if (self.snd_misc != "")
+ sound_misc(other, CHAN_AUTO, self.snd_misc, 1, ATTN_NORM);
+ else
+ sound_misc(other, CHAN_AUTO,"dump/armsh1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
+ stuffcmd (other, "bf\n");
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+void() armor_touch =
+{
+ local float type, value, bit;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (self.classname == "item_armor1")
+ {
+ type = 0.3;
+ value = 100;
+ bit = IT_ARMOR1;
+ }
+ else if (self.classname == "item_armor2")
+ {
+ type = 0.6;
+ value = 150;
+ bit = IT_ARMOR2;
+ }
+ else if (self.classname == "item_armorInv")
+ {
+ type = 0.8;
+ value = 200;
+ bit = IT_ARMOR3;
+ }
+ else
+ {
+ dprint ("WARNING: armor_touch: unknown classname: ");
+ dprint (self.classname);
+ dprint ("\n");
+ return;
+ }
+
+ if (other.armortype*other.armorvalue >= type*value)
+ return;
+
+ other.armortype = type;
+ other.armorvalue = value;
+
+ other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
+
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 20;
+ self.think = SUB_regen;
+
+ if (self.obit_name != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.obit_name); // custom armor name
+ sprint (other, "\n");
+ }
+ else
+ sprint(other, "You got armor\n");
+// armor touch sound
+ // sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds START
+ if (self.snd_misc != "")
+ sound_misc(other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
+ else
+ sound_misc(other, CHAN_ITEM,"items/armor1.wav", 1, ATTN_NORM); // dumptruck_ds custom models and sounds END
+ stuffcmd (other, "bf\n");
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/armor.mdl");
+}
+*/
+
+void() item_armor_shard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_shr_mdl)
+ {
+ self.mdl_body = world.a_shr_mdl;
+ }
+
+ self.touch = shard_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armshr.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armshr.mdl");
+ precache_sound_misc ("dump/armsh1.wav");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 0;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+void() item_armor1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_grn_mdl)
+ {
+ self.mdl_body = world.a_grn_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ precache_sound_misc ("items/armor1.wav");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 0;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model({ "path": ":progs/armor.mdl", "skin": 1 }); }
+*/
+
+void() item_armor2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_ylw_mdl)
+ {
+ self.mdl_body = world.a_ylw_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 1;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model({ "path": ":progs/armor.mdl", "skin": 2 });
+}
+*/
+
+void() item_armorInv =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl_body && world.a_red_mdl)
+ {
+ self.mdl_body = world.a_red_mdl;
+ }
+
+ self.touch = armor_touch;
+ // precache_model ("progs/armor.mdl"); // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ if !(self.skin) // dumptruck_ds custom models and sounds END
+ self.skin = 2;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*
+===============================================================================
+
+WEAPONS
+
+===============================================================================
+*/
+
+void() bound_other_ammo =
+{
+ if (other.ammo_shells > 100)
+ other.ammo_shells = 100;
+ if (other.ammo_nails > 200)
+ other.ammo_nails = 200;
+ if (other.ammo_rockets > 100)
+ other.ammo_rockets = 100;
+ if (other.ammo_cells > 100)
+ other.ammo_cells = 100;
+};
+
+
+float(float w) RankForWeapon =
+{
+ if (self.waterlevel <= 1 && w == IT_LIGHTNING) // 1997-12-23 Thunderbolt fix by Maddes recognize waterlevel
+ return 1;
+ if (w == IT_ROCKET_LAUNCHER)
+ return 2;
+ if (w == IT_SUPER_NAILGUN)
+ return 3;
+ if (w == IT_GRENADE_LAUNCHER)
+ return 4;
+ if (w == IT_SUPER_SHOTGUN)
+ return 5;
+ if (w == IT_NAILGUN)
+ return 6;
+ if (w == IT_SHOTGUN)
+ return 7;
+ return 8;
+};
+
+/*
+=============
+Deathmatch_Weapon
+
+Deathmatch weapon change rules for picking up a weapon
+
+.float ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
+=============
+*/
+void(float old, float new) Deathmatch_Weapon =
+{
+ local float or, nr;
+
+// change self.weapon if desired
+ or = RankForWeapon (self.weapon);
+ nr = RankForWeapon (new);
+ if ( nr < or )
+ self.weapon = new;
+};
+
+/*
+=============
+weapon_touch
+=============
+*/
+float() W_BestWeapon;
+
+void() weapon_touch =
+{
+ local float hadammo, best, new, old;
+ local entity stemp;
+ local float leave;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+ if (deathmatch == 2 || coop)
+ {
+ leave = 1;
+
+ // fix weapon items never firing their targets in coop or
+ // "deathmatch 2" -- iw
+ activator = other;
+ SUB_UseAndForgetTargets ();
+ }
+ else
+ {
+ leave = 0;
+ }
+
+ // johnfitz added for axe, shotgun items --dumptruck_ds from RRP /rubicon2
+ if (self.classname == "weapon_axe")
+ {
+ if (leave && (other.items & IT_AXE) )
+ return;
+ new = IT_AXE;
+ }
+ else if (self.classname == "weapon_shotgun")
+ {
+ if (leave && (other.items & IT_SHOTGUN) )
+ return;
+ hadammo = other.ammo_shells;
+ new = IT_SHOTGUN;
+ other.ammo_shells = other.ammo_shells + 5;
+ }
+ // johnfitz
+
+ else if (self.classname == "weapon_nailgun")
+ {
+ if (leave && (other.items & IT_NAILGUN) )
+ return;
+ hadammo = other.ammo_nails;
+ new = IT_NAILGUN;
+ other.ammo_nails = other.ammo_nails + 30;
+ }
+ else if (self.classname == "weapon_supernailgun")
+ {
+ if (leave && (other.items & IT_SUPER_NAILGUN) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_NAILGUN;
+ other.ammo_nails = other.ammo_nails + 30;
+ }
+ else if (self.classname == "weapon_supershotgun")
+ {
+ if (leave && (other.items & IT_SUPER_SHOTGUN) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_SUPER_SHOTGUN;
+ other.ammo_shells = other.ammo_shells + 5;
+ }
+ else if (self.classname == "weapon_rocketlauncher")
+ {
+ if (leave && (other.items & IT_ROCKET_LAUNCHER) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_ROCKET_LAUNCHER;
+ other.ammo_rockets = other.ammo_rockets + 5;
+ }
+ else if (self.classname == "weapon_grenadelauncher")
+ {
+ if (leave && (other.items & IT_GRENADE_LAUNCHER) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_GRENADE_LAUNCHER;
+ other.ammo_rockets = other.ammo_rockets + 5;
+ }
+ else if (self.classname == "weapon_lightning")
+ {
+ if (leave && (other.items & IT_LIGHTNING) )
+ return;
+ hadammo = other.ammo_rockets;
+ new = IT_LIGHTNING;
+ other.ammo_cells = other.ammo_cells + 15;
+ }
+ else
+ {
+ objerror ("weapon_touch: unknown classname");
+ return;
+ }
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+// weapon touch sound
+ sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+ bound_other_ammo ();
+
+// change to the weapon
+ old = other.items;
+ other.items = other.items | new;
+
+ stemp = self;
+ self = other;
+
+// 1997-12-23 Thunderbolt fix by Maddes start
+/* don't separate between SinglePlayer/Coop and Deathmatch
+ if (!deathmatch)
+ self.weapon = new;
+ else
+*/
+// 1997-12-23 Thunderbolt fix by Maddes end
+ Deathmatch_Weapon (old, new);
+
+ W_SetCurrentAmmo();
+
+ self = stemp;
+
+ if (leave)
+ return;
+
+// remove it in single player, or setup for respawning in deathmatch
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+ // Supa, SP respawning items support
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // weapons never disappear in "deathmatch 2"
+ self.nextthink = time + 30;
+
+ self.think = SUB_regen;
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+// johnfitz new items -- dumptruck_ds from RRP and rubicon2
+/*QUAKED weapon_axe (0 .5 .8) (-16 -16 0) (16 16 32)
+Axe
+*/
+void() weapon_axe =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_axe.mdl");
+ setmodel (self, "progs/g_axe.mdl");
+ self.weapon = IT_AXE;
+ self.netname = "Axe";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+/*QUAKED weapon_shotgun (0 .5 .8) (-16 -16 0) (16 16 32) X STYLE_1 STYLE_2 X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_shotgn.mdl"); }
+This is a pickup model that should be used when you want a player to spawn with only an axe and then later get the shotgun: (trigger_take_weapon or reset_items 2 in worldspawn). There are two models to choose from. Spawnflag 2 (the default) selects an unused “classic look” model from Rubicon 2 by metlslime. Spawnflag 4 is an alternate from Slapmap and has been used in a few mods.
+Single-barrelled Shotgun
+Shotgun
+*/
+
+void() weapon_shotgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_shotgu.mdl");
+ setmodel (self, "progs/g_shotgu.mdl"); //new shotgun model by Starshipwaters -dumptruck_ds - removed 2 older shotguns that used spawnflags
+ self.weapon = IT_SHOTGUN;
+ self.netname = "Shotgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+// johnfitz
+
+/*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_shot.mdl"); }
+Double-barrelled Shotgun
+*/
+
+void() weapon_supershotgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_shot.mdl");
+ setmodel (self, "progs/g_shot.mdl");
+ self.weapon = IT_SUPER_SHOTGUN;
+ self.netname = "Double-barrelled Shotgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 33';
+ StartItem ();
+};
+
+/*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_nail.mdl"); }
+Nailgun
+*/
+
+void() weapon_nailgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_nail.mdl");
+ setmodel (self, "progs/g_nail.mdl");
+ self.weapon = IT_NAILGUN;
+ self.netname = "nailgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 31';
+ StartItem ();
+};
+
+/*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_nail2.mdl"); }
+Perforator
+*/
+
+void() weapon_supernailgun =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_nail2.mdl");
+ setmodel (self, "progs/g_nail2.mdl");
+ self.weapon = IT_SUPER_NAILGUN;
+ self.netname = "Super Nailgun";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 34';
+ StartItem ();
+};
+
+/*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_rock.mdl"); }
+Grenade Launcher
+*/
+
+void() weapon_grenadelauncher =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_rock.mdl");
+ setmodel (self, "progs/g_rock.mdl");
+ self.weapon = 3;
+ self.netname = "Grenade Launcher";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 28';
+ StartItem ();
+};
+
+/*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_rock2.mdl"); }
+Rocket Launcher
+*/
+
+void() weapon_rocketlauncher =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_rock2.mdl");
+ setmodel (self, "progs/g_rock2.mdl");
+ self.weapon = 3;
+ self.netname = "Rocket Launcher";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 32';
+ StartItem ();
+};
+
+
+/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/g_light.mdl"); }
+Thunderbolt
+*/
+
+void() weapon_lightning =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/g_light.mdl");
+ setmodel (self, "progs/g_light.mdl");
+ self.weapon = 3;
+ self.netname = "Thunderbolt";
+ self.touch = weapon_touch;
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.particles_offset = '0 0 31';
+ StartItem ();
+};
+
+
+/*
+===============================================================================
+
+AMMO
+
+===============================================================================
+*/
+
+void() ammo_touch =
+{
+local entity stemp;
+local float best;
+
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+
+// shotgun
+ if (self.weapon == 1)
+ {
+ if (other.ammo_shells >= 100)
+ return;
+ other.ammo_shells = other.ammo_shells + self.aflag;
+ }
+
+// spikes
+ if (self.weapon == 2)
+ {
+ if (other.ammo_nails >= 200)
+ return;
+ other.ammo_nails = other.ammo_nails + self.aflag;
+ }
+
+// rockets
+ if (self.weapon == 3)
+ {
+ if (other.ammo_rockets >= 100)
+ return;
+ other.ammo_rockets = other.ammo_rockets + self.aflag;
+ }
+
+// cells
+ if (self.weapon == 4)
+ {
+ if (other.ammo_cells >= 100)
+ return;
+ other.ammo_cells = other.ammo_cells + self.aflag;
+ }
+
+ bound_other_ammo ();
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+// ammo touch sound
+ sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// change to a better weapon if appropriate
+
+ if ( other.weapon == best )
+ {
+ stemp = self;
+ self = other;
+ self.weapon = W_BestWeapon();
+ W_SetCurrentAmmo ();
+ self = stemp;
+ }
+
+// if changed current ammo, update it
+ stemp = self;
+ self = other;
+ W_SetCurrentAmmo();
+ self = stemp;
+
+// remove it in single player, or setup for respawning in deathmatch
+ self.model = string_null;
+ self.solid = SOLID_NOT;
+ if (!deathmatch)
+ CheckItemRespawn(self, 30);
+ else if (deathmatch == 1) // doesn't respawn in "deathmatch 2"
+ self.nextthink = time + 30;
+ self.think = SUB_regen;
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+
+
+
+float WEAPON_BIG2 = 1;
+
+/*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_shell1.bsp" }, "maps/b_shell0.bsp" }} );
+}
+Box of 20 shells.
+LARGE_BOX is a box of 40 shells.
+*/
+
+void() item_shells =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.s_lg_mdl) self.mdl_body = world.s_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_shell2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_shell2.mdl");
+ }
+ // precache_model ("maps/b_shell1.bsp");
+ // setmodel (self, "maps/b_shell1.bsp");
+ else
+ {
+ precache_body_model ("maps/b_shell1.bsp");
+ body_model ("maps/b_shell1.bsp");
+ }
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 40;
+ }
+ else
+ {
+ if (!self.mdl_body && world.s_sm_mdl) self.mdl_body = world.s_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_shell1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_shell1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_shell0.bsp");
+ body_model ("maps/b_shell0.bsp");
+ }
+ // precache_model ("maps/b_shell0.bsp");
+ // setmodel (self, "maps/b_shell0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 20;
+ }
+ self.weapon = 1;
+ self.netname = "shells";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+/*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_nail1.bsp" }, "maps/b_nail0.bsp" }} );
+}
+Box of 25 nails.
+LARGE_BOX is a box of 50 nails.
+*/
+
+void() item_spikes =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.n_lg_mdl) self.mdl_body = world.n_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_nails2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_nails2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_nail1.bsp");
+ body_model ("maps/b_nail1.bsp");
+ }
+ // precache_model ("maps/b_nail1.bsp");
+ // setmodel (self, "maps/b_nail1.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 50;
+ }
+ else
+ {
+
+ if (!self.mdl_body && world.n_sm_mdl) self.mdl_body = world.n_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_nails1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_nails1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_nail0.bsp");
+ body_model ("maps/b_nail0.bsp");
+ }
+ // precache_model ("maps/b_nail0.bsp");
+ // setmodel (self, "maps/b_nail0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 25;
+ }
+ self.weapon = 2;
+ self.netname = "nails";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+/*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_rock1.bsp" }, "maps/b_rock0.bsp" }} );
+}
+*/
+
+void() item_rockets =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+
+ if (!self.mdl_body && world.r_lg_mdl) self.mdl_body = world.r_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_rock2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_rock2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_rock1.bsp");
+ body_model ("maps/b_rock1.bsp");
+ }
+ // precache_model ("maps/b_rock1.bsp");
+ // setmodel (self, "maps/b_rock1.bsp");
+ self.particles_offset = '16 8 16';
+ self.aflag = 10;
+ }
+ else
+ {
+ if (!self.mdl_body && world.r_sm_mdl) self.mdl_body = world.r_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_rock1.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_rock1.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_rock0.bsp");
+ body_model ("maps/b_rock0.bsp");
+ }
+ // precache_model ("maps/b_rock0.bsp");
+ // setmodel (self, "maps/b_rock0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '8 8 16';
+ self.aflag = 5;
+ }
+ self.weapon = 3;
+ self.netname = "rockets";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+
+/*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) LARGE_BOX X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "maps/b_batt1.bsp" }, "maps/b_batt0.bsp" }} );
+}
+Box of 6 cells.
+LARGE_BOX is a box of 12 cells.
+*/
+
+void() item_cells =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = ammo_touch;
+
+ if (self.spawnflags & WEAPON_BIG2)
+ {
+ if (!self.mdl_body && world.c_lg_mdl) self.mdl_body = world.c_lg_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_cells2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_batt1.bsp");
+ body_model ("maps/b_batt1.bsp");
+ }
+ // precache_model ("maps/b_batt1.bsp");
+ // setmodel (self, "maps/b_batt1.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '16 16 16';
+ self.aflag = 12;
+ }
+ else
+ {
+ if (!self.mdl_body && world.c_sm_mdl) self.mdl_body = world.c_sm_mdl;
+ if (world.style)
+ {
+ precache_body_model ("progs/a_mdls/m_cells2.mdl"); // models courtesy Lunaran -- dumptruck_ds
+ body_model("progs/a_mdls/m_cells2.mdl");
+ }
+ else
+ {
+ precache_body_model ("maps/b_batt0.bsp");
+ body_model ("maps/b_batt0.bsp");
+ }
+ // precache_model ("maps/b_batt0.bsp");
+ // setmodel (self, "maps/b_batt0.bsp");
+ if !(self.particles_offset)
+ self.particles_offset = '12 12 12';
+ self.aflag = 6;
+ }
+ self.weapon = 4;
+ self.netname = "cells";
+ setsize (self, '0 0 0', '32 32 56');
+ StartItem ();
+};
+
+
+/*
+===============================================================================
+
+KEYS
+
+===============================================================================
+*/
+
+
+void() key_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+// support for item_key_custom -- iw
+ if (HasKeys (other, self.items, self.customkeys))
+ return;
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other,"\n");
+
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// support for item_key_custom -- iw
+ GiveKeys (other, self.items, self.customkeys);
+
+ if (!coop)
+ {
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ }
+
+ activator = other;
+// fix key items firing their targets multiple times in coop -- iw
+// SUB_UseTargets(); // fire all targets / killtargets
+ SUB_UseAndForgetTargets();
+};
+
+
+void() key_setsounds =
+{
+// support for item_key_custom -- iw
+ if (self.noise != "")
+ {
+ precache_sound (self.noise);
+ return;
+ }
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_sound ("misc/medkey.wav");
+ self.noise = "misc/medkey.wav";
+ }
+ if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_sound ("misc/runekey.wav");
+ self.noise = "misc/runekey.wav";
+ }
+ if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_sound2 ("misc/basekey.wav");
+ self.noise = "misc/basekey.wav";
+ }
+};
+
+
+/*
+============
+key_start
+
+Finish initializing self as a key item. -- iw
+============
+*/
+void() key_start =
+{
+ key_setsounds ();
+ self.particles_offset = '0 0 18';
+ self.touch = key_touch;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ StartItem ();
+};
+
+
+/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/w_s_key.mdl"); }
+SILVER key
+In order for keys to work you MUST set your map's worldtype to one of the following:
+0: medieval
+1: metal
+2: base
+*/
+
+void() item_key1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_body_model ("progs/w_s_key.mdl");
+ body_model ("progs/w_s_key.mdl");
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_body_model ("progs/m_s_key.mdl");
+ body_model ("progs/m_s_key.mdl");
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_body_model2 ("progs/b_s_key.mdl");
+ body_model ("progs/b_s_key.mdl");
+ }
+
+ if (self.keyname != "") self.netname = self.keyname;
+ else self.netname = SilverKeyName ();
+
+ self.items = IT_KEY1;
+
+// support for item_key_custom -- iw
+ self.customkeys = 0; // ignore any mapper-set value
+ self.noise = ""; // ignore any mapper-set value
+
+ key_start ();
+};
+
+
+/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/w_g_key.mdl");
+}
+GOLD key
+In order for keys to work you MUST set your map's worldtype to one of the following:
+0: medieval
+1: metal
+2: base
+*/
+
+void() item_key2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ precache_body_model ("progs/w_g_key.mdl");
+ body_model ("progs/w_g_key.mdl");
+ }
+ if (world.worldtype == WORLDTYPE_METAL)
+ {
+ precache_body_model ("progs/m_g_key.mdl");
+ body_model ("progs/m_g_key.mdl");
+ }
+ if (world.worldtype == WORLDTYPE_BASE)
+ {
+ precache_body_model2 ("progs/b_g_key.mdl");
+ body_model ("progs/b_g_key.mdl");
+ }
+
+ if (self.keyname != "") self.keyname = "";
+ else self.netname = GoldKeyName ();
+
+ self.items = IT_KEY2;
+
+// support for item_key_custom -- iw
+ self.customkeys = 0; // ignore any mapper-set value
+ self.noise = ""; // ignore any mapper-set value
+
+ key_start ();
+};
+
+
+// item_key_custom is a brand-spanking-new entity class created for
+// progs_dump -- iw
+
+/*QUAKED item_key_custom (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path" : "progs/pd_w_key.mdl", "skin" : 1});
+}
+A customizable key item.
+
+"keyname" name of the key, e.g. "bronze key" (required)
+"mdl" model file (required)
+"noise" sound file for the pickup sound (default is per worldtype)
+"skin" skin index (default 0)
+
+The "keyname" value is used both for the pickup message and to associate
+the key with the entity that it unlocks.
+
+To make a func_door or trigger_usekey require this key, set the
+"keyname" value of that entity so that it matches the "keyname" value of
+the key.
+
+If different item_key_custom entities have the same "keyname" value,
+they will be treated as different copies of the same key and may be used
+interchangeably.
+
+A map may have a maximum of 23 unique "keyname" values across all
+entities.
+
+The behavior of an item_key_custom should be as the player expects
+(based on the behavior of the silver and gold keys), except for the fact
+that it will not appear as an icon in the player's status bar when
+picked up. This is a limitation of the engine.
+*/
+
+void() item_key_custom =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.keyname == "")
+ {
+ objerror ("no keyname specified");
+ return;
+ }
+
+ if (self.mdl == "")
+ {
+ objerror ("no mdl specified");
+ return;
+ }
+
+ precache_model (self.mdl);
+ setmodel (self, self.mdl);
+ self.mdl = ""; // this should not be referenced again
+
+ self.netname = self.keyname;
+ self.keyname = ""; // this should not be referenced again
+
+ self.items = 0; // ignore any mapper-set value
+ self.customkeys = CustomKeyFlag (self.netname);
+
+ key_start ();
+};
+
+
+/*
+===============================================================================
+
+END OF LEVEL RUNES
+
+===============================================================================
+*/
+
+void() sigil_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ centerprint (other, "You got the rune!");
+
+ sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ serverflags = serverflags | (self.spawnflags & 15);
+ self.classname = ""; // so rune doors won't find it
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+void() sigil_touch2 = //replacement for Skill Select Rune hack -- uses info_player_start2 if spawnflag 16 -- dumptruck_ds
+{
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ // centerprint (other, "You got the rune!");
+
+ // sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ // stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ self.model = string_null;
+ serverflags = serverflags | (self.spawnflags & 16);
+ self.classname = ""; // so rune doors won't find it
+
+ activator = other;
+ // SUB_UseTargets(); // fire all targets / killtargets
+};
+
+
+/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "progs/end1.mdl" }, spawnflags & 2 -> { "path" : "progs/end2.mdl" },
+ spawnflags & 4 -> { "path" : "progs/end3.mdl" }, spawnflags & 8 -> { "path" : "progs/end4.mdl" },
+ "progs/end1.mdl" }} );
+}
+End of episode rune. Use in conjuction with func_bossgate and func_episodegate.
+Spawnflag must be set to the appropriate episode.
+Episode 1 - Dimension of the Doomed - Rune of Earth Magic
+Episode 2 - The Realm of Black Magic - Rune of Black Magic
+Episode 3 - The Netherworld - Rune of Hell Magic
+Episode 4 - The Elder World - Run of Elder Magic
+*/
+
+void() item_sigil =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.spawnflags)
+ objerror ("no spawnflags");
+
+ precache_sound ("misc/runekey.wav");
+ self.noise = "misc/runekey.wav";
+
+ if (self.spawnflags & 1)
+ {
+ precache_model ("progs/end1.mdl");
+ setmodel (self, "progs/end1.mdl");
+ }
+ if (self.spawnflags & 2)
+ {
+ precache_model2 ("progs/end2.mdl");
+ setmodel (self, "progs/end2.mdl");
+ }
+ if (self.spawnflags & 4)
+ {
+ precache_model2 ("progs/end3.mdl");
+ setmodel (self, "progs/end3.mdl");
+ }
+ if (self.spawnflags & 8)
+ {
+ precache_model2 ("progs/end4.mdl");
+ setmodel (self, "progs/end4.mdl");
+ }
+
+ self.touch = sigil_touch;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ self.particles_offset = '0 0 18';
+ StartItem ();
+};
+
+/*
+===============================================================================
+
+POWERUPS
+
+===============================================================================
+*/
+
+void() powerup_touch;
+
+
+void() powerup_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ sprint (other, "You got the ");
+ sprint (other, self.netname);
+ sprint (other,"\n");
+
+ // if (deathmatch)
+ // {
+ // self.mdl = self.model;
+ //
+ // if ((self.classname == "item_artifact_invulnerability") ||
+ // (self.classname == "item_artifact_invisibility"))
+ // self.nextthink = time + 60*5;
+ // else
+ // self.nextthink = time + 60;
+ //
+ // self.think = SUB_regen;
+ // }
+
+ // Supa, SP respawning items support
+ self.mdl = self.model;
+ self.think = SUB_regen;
+
+ if (!deathmatch)
+ {
+ local float spawndelay;
+
+ if (self.classname == "item_artifact_invulnerability" ||
+ self.classname == "item_artifact_invisibility" ) spawndelay = 300;
+ // else if (self.classname == "item_grappling_hook" ) spawndelay = 30;
+ else spawndelay = 60;
+
+ CheckItemRespawn(self, spawndelay);
+ }
+ else
+ {
+ if ((self.classname == "item_artifact_invulnerability") ||
+ (self.classname == "item_artifact_invisibility"))
+ self.nextthink = time + 60*5;
+ else
+ self.nextthink = time + 60;
+ }
+
+ sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ self.solid = SOLID_NOT;
+ other.items = other.items | self.items;
+ self.model = string_null;
+
+// do the apropriate action
+ if (self.classname == "item_artifact_envirosuit")
+ {
+ other.rad_time = 1;
+ other.radsuit_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_invulnerability")
+ {
+ other.invincible_time = 1;
+ other.invincible_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_invisibility")
+ {
+ other.invisible_time = 1;
+ other.invisible_finished = time + 30;
+ }
+
+ if (self.classname == "item_artifact_super_damage")
+ {
+ other.super_time = 1;
+ other.super_damage_finished = time + 30;
+ }
+
+ activator = other;
+ SUB_UseTargets(); // fire all targets / killtargets
+};
+
+/*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/invulner.mdl"); }
+Pentagram of Protection
+Player is invulnerable for 30 seconds
+*/
+void() item_artifact_invulnerability =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ // precache_model ("progs/invulner.mdl");
+ precache_body_model ("progs/invulner.mdl");
+ precache_sound ("items/protect.wav");
+ precache_sound ("items/protect2.wav"); // called in client.qc -- dumptruck_ds
+ precache_sound ("items/protect3.wav"); // called in combat.qc -- dumptruck_ds
+ self.noise = "items/protect.wav";
+ // setmodel (self, "progs/invulner.mdl");
+ body_model ("progs/invulner.mdl");
+ self.netname = "Pentagram of Protection";
+ self.items = IT_INVULNERABILITY;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 16';
+ StartItem ();
+};
+
+/*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/suit.mdl"); }
+Biosuit
+Player takes no damage from water or slime for 30 seconds
+*/
+void() item_artifact_envirosuit =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/suit.mdl");
+ precache_sound ("items/suit.wav");
+ precache_sound ("items/suit2.wav");
+ self.noise = "items/suit.wav";
+ // setmodel (self, "progs/suit.mdl");
+ body_model ("progs/suit.mdl");
+ self.netname = "Biosuit";
+ self.items = IT_SUIT;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 32';
+ StartItem ();
+};
+
+
+/*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/invisibl.mdl"); }
+Ring of Shadows
+Player is invisible for 30 seconds
+*/
+void() item_artifact_invisibility =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/invisibl.mdl");
+ precache_sound ("items/inv1.wav");
+ precache_sound ("items/inv2.wav");
+ precache_sound ("items/inv3.wav");
+ self.noise = "items/inv1.wav";
+ // setmodel (self, "progs/invisibl.mdl");
+ body_model ("progs/invisibl.mdl");
+ self.netname = "Ring of Shadows";
+ self.items = IT_INVISIBILITY;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 0';
+ StartItem ();
+};
+
+
+/*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32) X X X X X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER RESPAWN_WITH_DM_EFFECTS NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/quaddama.mdl"); }
+Quad Damage
+Player does 4x damage for 30 seconds
+*/
+void() item_artifact_super_damage =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.touch = powerup_touch;
+
+ precache_body_model ("progs/quaddama.mdl");
+ precache_sound ("items/damage.wav");
+ precache_sound ("items/damage3.wav");
+ self.noise = "items/damage.wav";
+ // setmodel (self, "progs/quaddama.mdl");
+ body_model ("progs/quaddama.mdl");
+ if !(self.netname) // custom name -- dumptruck_ds
+ self.netname = "Quad Damage";
+ self.items = IT_QUAD;
+ setsize (self, '-16 -16 -24', '16 16 32');
+ if !(self.particles_offset) // t_fog fix for custom models dumptruck_ds
+ self.particles_offset = '0 0 16';
+ StartItem ();
+};
+
+
+
+/*
+===============================================================================
+
+PLAYER BACKPACKS
+
+===============================================================================
+*/
+
+void() BackpackTouch =
+{
+ local string s;
+ local float best, old, new;
+ local entity stemp;
+ local float acount;
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ acount = 0;
+ sprint (other, "You get ");
+
+ if (self.items)
+ if ((other.items & self.items) == 0)
+ {
+ acount = 1;
+ sprint (other, "the ");
+ sprint (other, self.netname);
+ }
+
+// if the player was using his best weapon, change up to the new one if better
+ stemp = self;
+ self = other;
+ best = W_BestWeapon();
+ self = stemp;
+
+// change weapons
+ other.ammo_shells = other.ammo_shells + self.ammo_shells;
+ other.ammo_nails = other.ammo_nails + self.ammo_nails;
+ other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
+ other.ammo_cells = other.ammo_cells + self.ammo_cells;
+
+ new = self.items;
+ if (!new)
+ new = other.weapon;
+ old = other.items;
+ other.items = other.items | new;
+
+ bound_other_ammo ();
+
+ if (self.ammo_shells) // hack to fix an issue with custom Grunt, Ogre and Enf ammo types. - dumptruck_ds
+ // if (self.ammo_shells < 100)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_shells);
+ sprint (other, s);
+ sprint (other, " shells");
+ }
+ if (self.ammo_nails)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_nails);
+ sprint (other, s);
+ sprint (other, " nails");
+ }
+ if (self.ammo_rockets)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_rockets);
+ sprint (other, s);
+ sprint (other, " rockets");
+ }
+ if (self.ammo_cells)
+ {
+ if (acount)
+ sprint(other, ", ");
+ acount = 1;
+ s = ftos(self.ammo_cells);
+ sprint (other, s);
+ sprint (other, " cells");
+ }
+
+ sprint (other, "\n");
+// backpack touch sound
+ sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+
+// remove the backpack, change self to the player
+ remove(self);
+ self = other;
+
+// change to the weapon
+// 1997-12-23 Thunderbolt fix by Maddes start
+/* don't separate between SinglePlayer/Coop and Deathmatch
+ if (!deathmatch)
+ self.weapon = new;
+ else
+*/
+// 1997-12-23 Thunderbolt fix by Maddes end
+ Deathmatch_Weapon (old, new);
+
+ W_SetCurrentAmmo ();
+
+};
+
+/*
+===============
+DropStuff -- dumptruck_ds
+
+set drops_item on a monster to a number:
+
+1 = Silver Key
+2 = Gold Key
+3 = Health Vial
+4 = Armor Shard
+5 = Health Vial & Armor Shard
+6 = random combination of 3 Vials and/or Shards
+===============
+*/
+
+void() DropKey1 =
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ // precache_model ("progs/w_s_key.mdl");
+ setmodel (item, "progs/w_s_key.mdl");
+ item.noise = "misc/medkey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ // precache_model ("progs/m_s_key.mdl");
+ setmodel (item, "progs/m_s_key.mdl");
+ item.noise = "misc/runekey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ // precache_model2 ("progs/b_s_key.mdl");
+ setmodel (item, "progs/b_s_key.mdl");
+ item.noise = "misc/basekey.wav";
+ }
+ item.netname = SilverKeyName ();
+ item.effects = 8;
+ item.flags = FL_ITEM;
+ item.items = IT_KEY1;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = key_touch;
+};
+
+void() DropKey2 =
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ if (world.worldtype == WORLDTYPE_MEDIEVAL)
+ {
+ // precache_model ("progs/w_s_key.mdl");
+ setmodel (item, "progs/w_g_key.mdl");
+ item.noise = "misc/medkey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_METAL)
+ {
+ // precache_model ("progs/m_s_key.mdl");
+ setmodel (item, "progs/m_g_key.mdl");
+ item.noise = "misc/runekey.wav";
+ }
+ else if (world.worldtype == WORLDTYPE_BASE)
+ {
+ // precache_model2 ("progs/b_s_key.mdl");
+ setmodel (item, "progs/b_g_key.mdl");
+ item.noise = "misc/basekey.wav";
+ }
+ item.netname = GoldKeyName ();
+ item.effects = 8;
+ item.flags = FL_ITEM;
+ item.items = IT_KEY2;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = key_touch;
+};
+
+void() DropVial = //
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ setmodel(item, "progs/h_mdls/pd_vial.mdl");
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = health_touch;
+ item.healamount = 5;
+ item.healtype = 0;
+ item.noise = "items/r_item1.wav";
+
+ StartItem ();
+};
+
+void() DropShard = //
+{
+ local entity item;
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ setmodel(item, "progs/armshr.mdl");
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = shard_touch;
+ item.snd_misc = "dump/armsh1.wav";
+
+ StartItem ();
+};
+
+void() DropStuff =
+{
+ local float rand_drop;
+
+ if (self.drop_item == 1)
+ {
+ DropKey1();
+ }
+ if (self.drop_item == 2)
+ {
+ DropKey2();
+ }
+ if (self.drop_item == 3)
+ {
+ DropVial();
+ }
+ if (self.drop_item == 4)
+ {
+ DropShard();
+ }
+ if (self.drop_item == 5)
+ {
+ DropVial();
+ DropShard();
+ }
+ else if (self.drop_item == 6)
+ {
+ rand_drop = rint(random() * 3);
+ if (rand_drop == 1)
+ {
+ DropShard();
+ DropVial();
+ DropVial();
+ }
+ else if (rand_drop == 2)
+ {
+ DropShard();
+ DropShard();
+ DropVial();
+ }
+ else if (rand_drop == 0)
+ {
+ DropShard();
+ DropShard();
+ DropShard();
+ }
+ else
+ {
+ DropVial();
+ DropVial();
+ DropVial();
+ }
+ }
+ return;
+};
+
+/*
+===============
+DropBackpack
+===============
+*/
+void() DropBackpack =
+{
+ local entity item;
+
+ if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
+ return; // nothing in it
+
+ item = spawn();
+ item.origin = self.origin - '0 0 24';
+
+ item.items = self.weapon;
+ if (item.items == IT_AXE)
+ item.netname = "Axe";
+ else if (item.items == IT_SHOTGUN)
+ item.netname = "Shotgun";
+ else if (item.items == IT_SUPER_SHOTGUN)
+ item.netname = "Double-barrelled Shotgun";
+ else if (item.items == IT_NAILGUN)
+ item.netname = "Nailgun";
+ else if (item.items == IT_SUPER_NAILGUN)
+ item.netname = "Super Nailgun";
+ else if (item.items == IT_GRENADE_LAUNCHER)
+ item.netname = "Grenade Launcher";
+ else if (item.items == IT_ROCKET_LAUNCHER)
+ item.netname = "Rocket Launcher";
+ else if (item.items == IT_LIGHTNING)
+ item.netname = "Thunderbolt";
+ else
+ item.netname = "";
+
+ item.ammo_shells = self.ammo_shells;
+ item.ammo_nails = self.ammo_nails;
+ item.ammo_rockets = self.ammo_rockets;
+ item.ammo_cells = self.ammo_cells;
+
+ item.velocity_z = 300;
+ item.velocity_x = -100 + (random() * 200);
+ item.velocity_y = -100 + (random() * 200);
+
+ item.flags = FL_ITEM;
+ item.solid = SOLID_TRIGGER;
+ item.movetype = MOVETYPE_TOSS;
+ setmodel (item, "progs/backpack.mdl");
+ setsize (item, '-16 -16 0', '16 16 56');
+ item.touch = BackpackTouch;
+
+ item.nextthink = time + 120; // remove after 2 minutes
+ item.think = SUB_Remove;
+};
+
+// dumptruck_ds
+float DEFAULT = 1;
+float SHELLS = 2;
+float NAILS = 4;
+float ROCKETS = 8;
+float CELLS = 16;
+
+void() item_backpack_message =
+{
+
+ if (!CheckValidTouch()) return; // from Copper -- dumptruck_ds
+
+ other.ammo_shells = other.ammo_shells + self.ammo_shells;
+ other.ammo_nails = other.ammo_nails + self.ammo_nails;
+ other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
+ other.ammo_cells = other.ammo_cells + self.ammo_cells;
+
+ if (self.netname != "")
+ {
+ sprint (other, "You got ");
+ sprint (other, self.netname);
+ sprint (other, "\n");
+ }
+ else
+ sprint (other, "You got a backpack!\n");
+
+ // backpack touch sound
+ // sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
+ sound_misc (other, CHAN_ITEM, self.snd_misc, 1, ATTN_NORM);
+ stuffcmd (other, "bf\n");
+ remove(self);
+ self = other;
+ bound_other_ammo();
+ W_SetCurrentAmmo ();
+
+};
+// Some of this text is from Drake -- dumptruck_ds
+/*QUAKED item_backpack (0 .5 .8) (-16 -16 0) (16 16 72) SHELLS NAILS ROCKETS CELLS X SPAWN_SILENT TRIGGER_SPAWNED SUSPENDED_IN_AIR NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/backpack.mdl"); }
+By default, gives roughly half the ammo from the 4 standard pickups:
+
+10 Shells
+12 Nails
+2 Rockets
+3 Cells
+
+Or you can use the spawnflags to mix and match types.
+Override the spawnflags defaults by adding custom amounts to:
+
+ammo_shells
+ammo_nails
+ammo_rockets
+ammo_cells
+
+Can trigger spawn and suspend in air, but not respawn. You can set a skin
+index if you are using a custom model with skins.
+
+The default pickup message is `You got a backpack.` But you can
+set a custom message with the netname key. 'You got' will be the prefix
+and the mapper chooses the rest of the message.
+
+e.g. For 'You got a bunch of rockets!' the netname key would be
+'a bunch of rockets!'
+*/
+void() item_backpack =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ self.flags = FL_ITEM;
+ self.solid = SOLID_TRIGGER;
+ self.movetype = MOVETYPE_TOSS;
+ self.classname = "item_backpack";
+ // self.netname = self.netname;
+ if !(self.spawnflags)
+ {
+ objerror ("\bNO SPAWNFLAG SET ON item_backpack");
+ return;
+ }
+
+ if (self.spawnflags & DEFAULT)
+ {
+ self.ammo_shells = 10;
+ self.ammo_nails = 12;
+ self.ammo_rockets = 2;
+ self.ammo_cells = 3;
+ }
+
+ if (self.spawnflags & SHELLS)
+ {
+ if !(self.ammo_shells)
+ {
+ self.ammo_shells = 10;
+ }
+ }
+ if (self.spawnflags & NAILS)
+ {
+ if !(self.ammo_nails)
+ {
+ self.ammo_nails = 12;
+ }
+ }
+ if (self.spawnflags & ROCKETS)
+ {
+ if !(self.ammo_rockets)
+ {
+ self.ammo_rockets = 2;
+ }
+ }
+ if (self.spawnflags & CELLS)
+ {
+ if !(self.ammo_cells)
+ {
+ self.ammo_cells = 3;
+ }
+ }
+
+ self.touch = item_backpack_message;
+
+ if !(self.snd_misc) //set the custom noise in editor -- dumptruck_ds
+ self.snd_misc = "weapons/lock4.wav";
+ precache_sound_misc(self.snd_misc);
+ precache_body_model ("progs/pd_bpack.mdl");
+ body_model ("progs/pd_bpack.mdl");
+ // setmodel (self, "progs/backpack.mdl");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/math.qc

diff --git a/qc/math.qc b/qc/math.qc
index 13985d0..6dbe27d 100644
--- a/qc/math.qc
+++ b/qc/math.qc
@@ -1,209 +1,209 @@
-/*
- * math.qc
- *
- * Author: Joshua Skelton joshua.skelton@gmail.com
- *
- * A collection of helpful math functions.
- */
-
-// Forward declarations
-float(float value, float minValue, float maxValue) clamp;
-float(float a, float b) mod;
-float(float x) sign;
-float(float value, float minValue, float maxValue) wrap;
-
-/*
- * clamp
- *
- * Limits the given value to the given range.
- *
- * value: A number
- *
- * minValue: The minimum value of the range
- *
- * maxValue: The maximum value of the range
- *
- * Returns: A number within the given range.
- */
-float(float value, float minValue, float maxValue) clamp = {
- if (value < minValue) {
- return minValue;
- }
- else if (value > maxValue) {
- return maxValue;
- }
-
- return value;
-};
-
-/*
- * mod
- *
- * Returns the remainder after the division of a by n
- *
- * a: The dividend
- *
- * b: The divisor
- *
- * Returns: The remainder of a divided by n
- */
-float(float a, float n) mod = {
- return a - (n * floor(a / n));
-};
-
-/*
- * sign
- *
- * Returns an indication of the sign of the given number.
- *
- * x: A number
- *
- * Returns: -1 if x < 0, 0 if x == 0, 1 if x > 0.
- */
-float(float x) sign = {
- if (x > 0) {
- return 1;
- }
- else if (x < 0) {
- return -1;
- }
-
- return 0;
-};
-
-/*
- * wrap
- *
- * Limits the given value to the given range and will wrap the value to the
- * the other end of the range if exceeded.
- *
- * value: A number
- *
- * minValue: The minimum value of the range
- *
- * maxValue: The maximum value of the range
- *
- * Returns: A number within the given range.
- */
-float(float value, float minValue, float maxValue) wrap = {
- local float range = maxValue - minValue;
-
- return mod(value - minValue, range + 1) + minValue;
-};
-
-
-
-float(float a, float b, float mix) lerp =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
- return (b * mix + a * ( 1 - mix ) );
-}
-
-vector(vector a, vector b, float mix) lerpVector =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
- return (b * mix + a * ( 1 - mix ) );
-}
-
-// for a relaxing lerp: hermite lerp.
-float(float a, float b, float mix) lerpHermite =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
-
- local float h01;
-
- h01 = mix * mix;
- h01 *= 3 - 2 * mix;
-
- return (b * h01 + a * ( 1 - h01 ) );
-}
-
-vector(vector a, vector b, float mix) lerpVectorHermite =
-{
- if (mix <= 0) return a;
- if (mix >= 1) return b;
-
- local float h01;
-
- h01 = mix * mix;
- h01 *= 3 - 2 * mix;
-
- return (b * h01 + a * ( 1 - h01 ) );
-}
-
-float(float anga, float angb) angledif =
-{
- float dif;
- dif = fabs(anga - angb);
- if (dif > 180)
- dif = 360 - dif;
- return dif;
-}
-
-float(vector ang, vector base_ang, vector offset) isInAngle = {
- if (angledif(ang_x, base_ang_x) > offset_x || angledif(ang_y, base_ang_y) > offset_y)
- return FALSE;
- else
- return TRUE;
-};
-
-
-// normalizes an angle vector to the 0/+359 range
-vector(vector ang) normalizeAngles = {
-
- ang_x = ang_x - floor(ang_x/360) * 360;
- ang_y = ang_y - floor(ang_y/360) * 360;
- ang_z = ang_z - floor(ang_z/360) * 360;
-
- /*
- while (ang_x > 360)
- ang_x = ang_x - 360;
-
- while (ang_x < 0)
- ang_x = ang_x + 360;
-
- while (ang_y > 360)
- ang_y = ang_y - 360;
-
- while (ang_y < 0)
- ang_y = ang_y + 360;
-
- while (ang_z > 360)
- ang_z = ang_z - 360;
-
- while (ang_z < 0)
- ang_z = ang_z + 360;
- */
- return ang;
-};
-
-// normalizes an angle vector to the -180/+179 range
-vector(vector ang) normalizeAngles180 = {
- ang_x = ((ang_x+180) - floor((ang_x+180)/360) * 360) - 180;
- ang_y = ((ang_y+180) - floor((ang_y+180)/360) * 360) - 180;
- ang_z = ((ang_z+180) - floor((ang_z+180)/360) * 360) - 180;
-
- /*
- while (ang_x > 180)
- ang_x = ang_x - 360;
-
- while (ang_x < -180)
- ang_x = ang_x + 360;
-
- while (ang_y > 180)
- ang_y = ang_y - 360;
-
- while (ang_y < -180)
- ang_y = ang_y + 360;
-
- while (ang_z > 180)
- ang_z = ang_z - 360;
-
- while (ang_z < -180)
- ang_z = ang_z + 360;
- */
- return ang;
-};
\ No newline at end of file
+/*
+ * math.qc
+ *
+ * Author: Joshua Skelton joshua.skelton@gmail.com
+ *
+ * A collection of helpful math functions.
+ */
+
+// Forward declarations
+float(float value, float minValue, float maxValue) clamp;
+float(float a, float b) mod;
+float(float x) sign;
+float(float value, float minValue, float maxValue) wrap;
+
+/*
+ * clamp
+ *
+ * Limits the given value to the given range.
+ *
+ * value: A number
+ *
+ * minValue: The minimum value of the range
+ *
+ * maxValue: The maximum value of the range
+ *
+ * Returns: A number within the given range.
+ */
+float(float value, float minValue, float maxValue) clamp = {
+ if (value < minValue) {
+ return minValue;
+ }
+ else if (value > maxValue) {
+ return maxValue;
+ }
+
+ return value;
+};
+
+/*
+ * mod
+ *
+ * Returns the remainder after the division of a by n
+ *
+ * a: The dividend
+ *
+ * b: The divisor
+ *
+ * Returns: The remainder of a divided by n
+ */
+float(float a, float n) mod = {
+ return a - (n * floor(a / n));
+};
+
+/*
+ * sign
+ *
+ * Returns an indication of the sign of the given number.
+ *
+ * x: A number
+ *
+ * Returns: -1 if x < 0, 0 if x == 0, 1 if x > 0.
+ */
+float(float x) sign = {
+ if (x > 0) {
+ return 1;
+ }
+ else if (x < 0) {
+ return -1;
+ }
+
+ return 0;
+};
+
+/*
+ * wrap
+ *
+ * Limits the given value to the given range and will wrap the value to the
+ * the other end of the range if exceeded.
+ *
+ * value: A number
+ *
+ * minValue: The minimum value of the range
+ *
+ * maxValue: The maximum value of the range
+ *
+ * Returns: A number within the given range.
+ */
+float(float value, float minValue, float maxValue) wrap = {
+ local float range = maxValue - minValue;
+
+ return mod(value - minValue, range + 1) + minValue;
+};
+
+
+
+float(float a, float b, float mix) lerp =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+ return (b * mix + a * ( 1 - mix ) );
+}
+
+vector(vector a, vector b, float mix) lerpVector =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+ return (b * mix + a * ( 1 - mix ) );
+}
+
+// for a relaxing lerp: hermite lerp.
+float(float a, float b, float mix) lerpHermite =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+
+ local float h01;
+
+ h01 = mix * mix;
+ h01 *= 3 - 2 * mix;
+
+ return (b * h01 + a * ( 1 - h01 ) );
+}
+
+vector(vector a, vector b, float mix) lerpVectorHermite =
+{
+ if (mix <= 0) return a;
+ if (mix >= 1) return b;
+
+ local float h01;
+
+ h01 = mix * mix;
+ h01 *= 3 - 2 * mix;
+
+ return (b * h01 + a * ( 1 - h01 ) );
+}
+
+float(float anga, float angb) angledif =
+{
+ float dif;
+ dif = fabs(anga - angb);
+ if (dif > 180)
+ dif = 360 - dif;
+ return dif;
+}
+
+float(vector ang, vector base_ang, vector offset) isInAngle = {
+ if (angledif(ang_x, base_ang_x) > offset_x || angledif(ang_y, base_ang_y) > offset_y)
+ return FALSE;
+ else
+ return TRUE;
+};
+
+
+// normalizes an angle vector to the 0/+359 range
+vector(vector ang) normalizeAngles = {
+
+ ang_x = ang_x - floor(ang_x/360) * 360;
+ ang_y = ang_y - floor(ang_y/360) * 360;
+ ang_z = ang_z - floor(ang_z/360) * 360;
+
+ /*
+ while (ang_x > 360)
+ ang_x = ang_x - 360;
+
+ while (ang_x < 0)
+ ang_x = ang_x + 360;
+
+ while (ang_y > 360)
+ ang_y = ang_y - 360;
+
+ while (ang_y < 0)
+ ang_y = ang_y + 360;
+
+ while (ang_z > 360)
+ ang_z = ang_z - 360;
+
+ while (ang_z < 0)
+ ang_z = ang_z + 360;
+ */
+ return ang;
+};
+
+// normalizes an angle vector to the -180/+179 range
+vector(vector ang) normalizeAngles180 = {
+ ang_x = ((ang_x+180) - floor((ang_x+180)/360) * 360) - 180;
+ ang_y = ((ang_y+180) - floor((ang_y+180)/360) * 360) - 180;
+ ang_z = ((ang_z+180) - floor((ang_z+180)/360) * 360) - 180;
+
+ /*
+ while (ang_x > 180)
+ ang_x = ang_x - 360;
+
+ while (ang_x < -180)
+ ang_x = ang_x + 360;
+
+ while (ang_y > 180)
+ ang_y = ang_y - 360;
+
+ while (ang_y < -180)
+ ang_y = ang_y + 360;
+
+ while (ang_z > 180)
+ ang_z = ang_z - 360;
+
+ while (ang_z < -180)
+ ang_z = ang_z + 360;
+ */
+ return ang;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/misc.qc

diff --git a/qc/misc.qc b/qc/misc.qc
index 062b6d0..74b10f1 100644
--- a/qc/misc.qc
+++ b/qc/misc.qc
@@ -1,1871 +1,1871 @@
-// these were moved for various reasons -- dumptruck_ds
-// /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
-// Used as a positional target for spotlights, etc.
-// */
-// /void() info_null =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// 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 =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-// };
-//
-// //============================================================================
-//
-// float START_OFF = 1;
-//
-// void() light_use =
-// {
-// if (self.spawnflags & START_OFF)
-// {
-// lightstyle(self.style, "m");
-// self.spawnflags = self.spawnflags - START_OFF;
-// }
-// else
-// {
-// lightstyle(self.style, "a");
-// self.spawnflags = self.spawnflags + START_OFF;
-// }
-// };
-//
-// /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Non-displayed light.
-// Default light value is 300
-// Default style is 0
-// If targeted, it will toggle between on or off.
-// */
-// void() light =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (!self.targetname)
-// { // inert light
-// remove(self);
-// return;
-// }
-//
-// if (self.style >= 32)
-// {
-// self.use = light_use;
-// if (self.spawnflags & START_OFF)
-// lightstyle(self.style, "a");
-// else
-// lightstyle(self.style, "m");
-// }
-// };
-//
-// /*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Non-displayed light.
-// Default light value is 300
-// Default style is 0
-// If targeted, it will toggle between on or off.
-// Makes steady fluorescent humming sound
-// */
-// void() light_fluoro =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (self.style >= 32)
-// {
-// self.use = light_use;
-// if (self.spawnflags & START_OFF)
-// lightstyle(self.style, "a");
-// else
-// lightstyle(self.style, "m");
-// }
-//
-// precache_sound ("ambience/fl_hum1.wav");
-// ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
-// };
-//
-// /*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
-// Non-displayed light.
-// Default light value is 300
-// Default style is 10
-// Makes sparking, broken fluorescent sound
-// */
-// void() light_fluorospark =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// if (!self.style)
-// self.style = 10;
-//
-// precache_sound ("ambience/buzz1.wav");
-// ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
-// };
-//
-// /*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
-// Sphere globe light.
-// Default light value is 300
-// Default style is 0
-// */
-// void() light_globe =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/s_light.spr");
-// setmodel (self, "progs/s_light.spr");
-// makestatic (self);
-// };
-//
-/*QUAKED FireAmbient (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
-*/
-void() FireAmbient =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/fire1.wav");
-// attenuate fast
- ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
-};
-
-/*QUAKED ambient_fire (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-ambinet fire sound effects added for consistency
-same as FireAmbient
-*/
-void() ambient_fire =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-FireAmbient();
-};
-
-//
-// /*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
-// Short wall torch
-// Default light value is 200
-// Default style is 0
-// */
-// void() light_torch_small_walltorch =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame.mdl");
-// setmodel (self, "progs/flame.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
-// Large yellow flame ball
-// */
-// void() light_flame_large_yellow =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// self.frame = 1;
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
-// Small yellow flame ball
-// */
-// void() light_flame_small_yellow =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-// /*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
-// Small white flame ball
-// */
-// void() light_flame_small_white =
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// precache_model ("progs/flame2.mdl");
-// setmodel (self, "progs/flame2.mdl");
-// FireAmbient ();
-// makestatic (self);
-// };
-//
-/*QUAKED light_candle (0 1 0) (-10 -10 -40) (10 10 40) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/candle.mdl"); }
-==========
-Spawnflags
-==========
-START_OFF - switchable lights only - light is off by default
-FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
-
-==========
-Keys
-==========
-"light" "n"
-Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
-
-"wait" "n"
-Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
-
-"delay" "n"
-Select an attenuation formaula for the light:
-0 => Linear attenuation (default)
-1 => 1/x attenuation
-2 => 1/(x^2) attenuation
-3 => No attenuation (same brightness at any distance)
-4 => "local minlight" - No attenuation and like minlight,
-it won't raise the lighting above it's light value.
-Unlike minlight, it will only affect surfaces within
-line of sight of the entity.
-5 => 1/(x^2) attenuation, but slightly more attenuated and
-without the extra bright effect that "delay 2" has
-near the source.
-
-"_falloff" "n"
-Sets the distance at which the light drops to 0, in map units.
-In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
-Only supported on linear attenuation (delay 0) lights currently.
-
-"_color" "r g b"
-Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
-
-"target" "name"
-Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
-"mangle" "yaw pitch roll"
-Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
-
-"angle" "n"
-Specifies the angle in degrees for a spotlight cone. Default 40.
-
-"_softangle" "n"
-Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
-
-"targetname" "name"
-Turns the light into a switchable light, toggled by another entity targeting it�s name.
-
-"speed" "n"
-If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
-
-"style" "n"
-Set the animated light style. Default 0.
-
-"style2" "n"
-Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
-
-"_anglescale" "n" | "_anglesense" "n"
-Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
-
-"_dirtscale" "n" | "_dirtgain" "n"
-Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
-
-"_dirt" "n"
-Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
-
-"_deviance" "n"
-Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
-
-"_samples" "n"
-Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
-
-"_surface" "texturename"
-Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
-
-"_surface_offset" "n"
-Controls the offset lights are placed above surfaces for "_surface". Default 2.
-
-"_surface_spotlight" "n"
-For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
-
-"_project_texture" "texture"
-Specifies that a light should project this texture. The texture must be used in the map somewhere.
-
-"_project_mangle" "yaw pitch roll"
-Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
-
-"_project_fov" "n"
-Specifies the fov angle for a texture projection. Default 90.
-
-"_bouncescale" "n"
-Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
-
-"_sun" "n"
-Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
-
-The following light properties correspond to these sunlight settings:
-light => _sunlight
-mangle => _sunlight_mangle
-deviance => _sunlight_penumbra
-_color => _sunlight_color
-_dirt => _sunlight_dirt
-_anglescale => _anglescale
-
- //dumptruck_ds taken from honey (originally from Rogue)
-White candle
-*/
-void() light_candle =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/candle.mdl");
- setmodel (self, "progs/candle.mdl");
- makestatic (self);
-};
-
-void() model_candle_think =
-{
- self.frame = self.frame + 1;
- if (self.frame > 3)
- self.frame = 0;
- self.nextthink = time + 0.1;
-};
-
-void() model_candle =
-{
-
- precache_model ("progs/candle.mdl");
-
- setmodel (self, "progs/candle.mdl");
-
- self.think = model_candle_think;
- self.nextthink = time + 0.1;
-};
-
-
-//============================================================================
-
-
-/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model ("progs/lavaball.mdl"); }
-Flying lava balls
-speed - set vertical speed of fireballs. default 1000.
-*/
-
-void() fire_fly;
-void() fire_touch;
-void() misc_fireball =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/lavaball.mdl");
- self.classname = "fireball";
-// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
-// self.nextthink = time + (random() * 5);
- self.nextthink = time + 0.1 + (random() * 5);
-// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
- self.think = fire_fly;
- if (!self.speed)
- self.speed = 1000; // fixed typo QIP - dumptruck_ds
-};
-
-void() fire_fly =
-{
-local entity fireball;
-
- fireball = spawn();
- fireball.solid = SOLID_TRIGGER;
- fireball.movetype = MOVETYPE_TOSS;
- fireball.velocity = '0 0 1000';
- fireball.velocity_x = (random() * 100) - 50;
- fireball.velocity_y = (random() * 100) - 50;
- fireball.velocity_z = self.speed + (random() * 200);
- fireball.classname = "fireball";
- setmodel (fireball, "progs/lavaball.mdl");
- setsize (fireball, '0 0 0', '0 0 0');
- setorigin (fireball, self.origin);
- fireball.nextthink = time + 5;
- fireball.think = SUB_Remove;
- fireball.touch = fire_touch;
-
- self.nextthink = time + (random() * 5) + 3;
- self.think = fire_fly;
-};
-
-
-void() fire_touch =
-{
- T_Damage (other, self, self, 20);
- remove(self);
-};
-
-//============================================================================
-
-
-void() barrel_explode =
-{
- self.takedamage = DAMAGE_NO;
- self.classname = "explo_box";
- // did say self.owner
- T_RadiusDamage (self, self, 160, world);
- sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- particle (self.origin, '0 0 0', 75, 255);
-
- self.origin_z = self.origin_z + 32;
- BecomeExplosion ();
-};
-
-
-
-/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model("maps/b_explob.bsp");
-}
-Explosive box
-*/
-
-void() misc_explobox =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float oldz;
-
- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model ("maps/b_explob.bsp");
- setmodel (self, "maps/b_explob.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove(self);
- }
-};
-
-
-
-
-/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model("maps/b_exbox2.bsp");
-}
-Smaller explosive box
-*/
-
-void() misc_explobox2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local float oldz;
-
- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model2 ("maps/b_exbox2.bsp");
- setmodel (self, "maps/b_exbox2.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-
- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove(self);
- }
-};
-
-/*==============================================================================
-trap_spikeshooter from Hipnotic -- with additions by dumptruck_ds
-==============================================================================*/
-
-//MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds
-float SPAWNFLAG_SUPERSPIKE = 1;
-float SPAWNFLAG_LASER = 2;
-float SPAWNFLAG_LAVABALL = 4;
-float SPAWNFLAG_ROCKET = 8;
-float SPAWNFLAG_VOREBALL = 16;
-float SPAWNFLAG_GRENADE = 32;
-float SPAWNFLAG_GIBS = 64;
-float SPAWNFLAG_SILENT = 128;
-
-void() ShalMissileTouch = //moved from Shalrath to enable shooter version
-{
- if (other == self.owner)
- return; // don't explode on owner
-
- if (other.classname == "monster_zombie")
- T_Damage (other, self, self, 110);
- T_RadiusDamage (self, self.owner, 40, world);
- sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-
-
- // self.velocity = '0 0 0';
- // self.touch = SUB_Null;
- // setmodel (self, "progs/s_explod.spr");
- // self.solid = SOLID_NOT;
- // s_explode1 ();
-};
-
-void() ZombieGrenadeTouch = //moved from zombie.qc to enable shooter version
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage)
- {
- T_Damage (other, self, self.owner, 10 );
- sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
- remove (self);
- return;
- }
- sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
- self.velocity = '0 0 0';
- self.avelocity = '0 0 0';
- self.touch = SUB_Remove;
-};
-
-
-void(vector org, vector vec) LaunchLaser;
-
-//MED 11/09/96 added lava ball and rocket
-//dumptruck_ds added voreball and grenades
-void() spikeshooter_use =
-{
- local entity lavaball;
- local entity voreball;
- local entity rockettrap;
- local entity gnade;
- local entity zgibs;
-
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
- LaunchLaser (self.origin, self.movedir);
- newmis.spawnflags = self.spawnflags;
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "boss1/throw.wav", 1, ATTN_NORM); //dms
- // sound (self, CHAN_VOICE, "knight/sword2.wav", 1, ATTN_NORM); //dms
- // sound (self, CHAN_VOICE, "weapons/ax1.wav", 1, ATTN_NORM); //dms
- lavaball = spawn();
- lavaball.movetype = MOVETYPE_FLYMISSILE;
- lavaball.solid = SOLID_BBOX;
- lavaball.classname = "lavaball";
- // set lavaball speed
- lavaball.velocity = self.movedir * 600; //was 300 dms
- lavaball.angles = vectoangles(lavaball.velocity);
- lavaball.owner = self;
- lavaball.touch = ShalMissileTouch;
- setmodel (lavaball, "progs/lavaball.mdl"); //dms
- setsize (lavaball, '0 0 0', '0 0 0');
- setorigin (lavaball, self.origin);
- lavaball.avelocity = '0 0 400';
- lavaball.nextthink = time + 5;
- lavaball.think = SUB_Remove;
- }
-
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/sgun1.wav", 1, ATTN_NORM);
- rockettrap = spawn();
- rockettrap.movetype = MOVETYPE_FLYMISSILE;
- rockettrap.solid = SOLID_BBOX;
- rockettrap.classname = "rockettrap";
- // set rocket speed
- rockettrap.velocity = self.movedir * 1000;
- rockettrap.angles = vectoangles(rockettrap.velocity);
- rockettrap.owner = self;
- rockettrap.touch = T_MissileTouch;
- setmodel (rockettrap, "progs/missile.mdl"); //dms
- setsize (rockettrap, '0 0 0', '0 0 0');
- setorigin (rockettrap, self.origin);
- // rockettrap.avelocity = '0 0 400';
- rockettrap.nextthink = time + 5;
- rockettrap.think = SUB_Remove;
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "shalrath/attack2.wav", 1, ATTN_NORM);
- voreball = spawn();
- voreball.movetype = MOVETYPE_FLYMISSILE;
- voreball.solid = SOLID_BBOX;
- voreball.classname = "voreball";
- // set voreball speed
- voreball.velocity = self.movedir * 600; //was 300 dms
- voreball.angles = vectoangles(voreball.velocity);
- voreball.owner = self;
- voreball.touch = ShalMissileTouch;
- setmodel (voreball, "progs/v_spike.mdl"); //dms
- setsize (voreball, '0 0 0', '0 0 0');
- setorigin (voreball, self.origin);
- voreball.avelocity = '0 0 400';
- voreball.nextthink = time + 5;
- voreball.think = SUB_Remove;
- }
-
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/grenade.wav", 1, ATTN_NORM);
- gnade = spawn();
- gnade.movetype = MOVETYPE_BOUNCE;
- // gnade.movetype = MOVETYPE_FLYMISSILE;
- gnade.solid = SOLID_BBOX;
- gnade.classname = "gnade";
- // set grenade speed
- // gnade.velocity = self.movedir * 600; //was 300 dms
- gnade.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- gnade.angles = vectoangles(gnade.velocity);
- gnade.owner = self;
- gnade.touch = GrenadeTouch;
- setmodel (gnade, "progs/grenade.mdl"); //dms
- setsize (gnade, '0 0 0', '0 0 0');
- setorigin (gnade, self.origin);
- gnade.avelocity = '300 300 300';
- gnade.nextthink = time + 2.5;
- gnade.think = GrenadeExplode;
- }
-
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "zombie/z_shot1.wav", 1, ATTN_NORM);
- zgibs = spawn ();
- zgibs.owner = self;
- zgibs.movetype = MOVETYPE_BOUNCE;
- zgibs.solid = SOLID_BBOX;
- zgibs.classname = "zgibs";
- setmodel (zgibs, "progs/zom_gib.mdl");
- setsize (zgibs, '0 0 0', '0 0 0');
- setorigin (zgibs, self.origin);
- zgibs.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- zgibs.avelocity = '3000 1000 2000';
- zgibs.touch = ZombieGrenadeTouch;
- // set missile duration
- zgibs.nextthink = time + 2.5;
- zgibs.think = SUB_Remove;
- }
-
- else
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
- launch_spike (self.origin, self.movedir);
- newmis.velocity = self.movedir * 500;
- if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
- newmis.touch = superspike_touch;
- }
-};
-
-//MED 11/01/96 added state capability
-void() shooter_think =
-{
- if (self.state)
- {
- spikeshooter_use ();
- }
- self.nextthink = time + self.wait;
-};
-
-
-/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-When triggered, fires a spike in the direction set in QuakeEd.
-Laser is only for REGISTERED.
-*/
-
-//MED 11/01/96 commented out setmovedir
-void() trap_spikeshooter =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.proj_speed_mod <= 0)
- self.proj_speed_mod = 1;
- SetMovedir ();
- self.use = spikeshooter_use;
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- precache_model2 ("progs/laser.mdl");
-
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- precache_model ("progs/lavaball.mdl");
- // precache_sound2 ("knight/sword2.wav"); //dms
- precache_sound2 ("boss1/throw.wav"); //dms
- }
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
- {
- precache_model ("progs/missile.mdl");
- precache_sound ("weapons/sgun1.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- precache_model ("progs/v_spike.mdl");
- precache_sound ("shalrath/attack2.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- precache_model ("progs/grenade.mdl");
- precache_sound ("weapons/grenade.wav"); // grenade launcher
- }
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- precache_model ("progs/zom_gib.mdl");
- precache_sound ("zombie/z_shot1.wav"); // Zombie gibs
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- }
-
- else
- precache_sound ("weapons/spike2.wav");
-};
-
-
-/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-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 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- trap_spikeshooter ();
-
- if (self.wait == 0)
- self.wait = 1;
-//MED 11/01/96 added state capability
- self.state = 1;
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
-};
-
-//MED 11/01/96 added new use function
-void() trap_shooter_use =
- {
- self.state = 1 - self.state;
- };
-//MED 11/01/96 added new function
-/*QUAKED trap_switched_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Continuously fires spikes.
-"wait" time between spike (1.0 default)
-"nextthink" delay before firing first spike, so multiple shooters can be stagered.
-"state" 0 initially off, 1 initially on. (0 default)
-*/
-void() trap_switched_shooter =
- {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- trap_spikeshooter ();
-
- if (self.wait == 0)
- self.wait = 1;
-//MED 11/01/96 added state capability
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
- self.use = trap_shooter_use;
- };
-
-/*
-===============================================================================
-
-
-===============================================================================
-*/
-
-
-void() make_bubbles;
-void() bubble_remove;
-void() bubble_bob;
-
-/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-air bubbles entity
-
-*/
-
-void() air_bubbles =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove (self);
- return;
- }
- precache_model ("progs/s_bubble.spr");
- self.nextthink = time + 1;
- self.think = make_bubbles;
-};
-
-void() make_bubbles =
-{
-local entity bubble;
-
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = '0 0 15';
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 0;
- bubble.cnt = 0;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.nextthink = time + random() + 0.5;
- self.think = make_bubbles;
-};
-
-void() bubble_split =
-{
-local entity bubble;
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = self.velocity;
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 1;
- bubble.cnt = 10;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.frame = 1;
- self.cnt = 10;
- if (self.waterlevel != 3)
- remove (self);
-};
-
-void() bubble_remove =
-{
- if (other.classname == self.classname)
- {
-// dprint ("bump");
- return;
- }
- remove(self);
-};
-
-void() bubble_bob =
-{
-local float rnd1, rnd2, rnd3;
-
-
- self.cnt = self.cnt + 1;
- if (self.cnt == 4)
- bubble_split();
- if (self.cnt == 20)
- remove(self);
-
- rnd1 = self.velocity_x + (-10 + (random() * 20));
- rnd2 = self.velocity_y + (-10 + (random() * 20));
- rnd3 = self.velocity_z + 10 + random() * 10;
-
- if (rnd1 > 10)
- rnd1 = 5;
- if (rnd1 < -10)
- rnd1 = -5;
-
- if (rnd2 > 10)
- rnd2 = 5;
- if (rnd2 < -10)
- rnd2 = -5;
-
- if (rnd3 < 10)
- rnd3 = 15;
- if (rnd3 > 30)
- rnd3 = 25;
-
- self.velocity_x = rnd1;
- self.velocity_y = rnd2;
- self.velocity_z = rnd3;
-
- self.nextthink = time + 0.5;
- self.think = bubble_bob;
-};
-
-/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
-~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
-
-/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
-
-Just for the debugging level. Don't use
-*/
-
-void() viewthing =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- precache_model ("progs/player.mdl");
- setmodel (self, "progs/player.mdl");
-};
-
-
-/*
-==============================================================================
-
-SIMPLE BMODELS
-
-==============================================================================
-*/
-
-void() func_wall_use =
-{ // change to alternate textures
- self.frame = 1 - self.frame;
-};
-
-/*QUAKED func_wall (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This is just a solid wall if not inhibitted
-*/
-void() func_wall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-
-/*QUAKED func_illusionary (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A simple entity that looks solid but lets you walk through it.
-*/
-void() func_illusionary =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setmodel (self, self.model);
- makestatic (self);
-};
-
-
-float GATE_REVERSE = 16; // For func_episodegate and func_bossgate appear when player has all runes
-
-/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 REVERSE_FUNCTIONALITY
-This bmodel will appear if the episode has allready been completed, so players can't reenter it.
-*/
-void() func_episodegate =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & GATE_REVERSE)
- {
- self.spawnflags = self.spawnflags - GATE_REVERSE; // this is to avoid a possible issue with sigil_touch2
- if (serverflags & self.spawnflags)
- return; // Haven't gotten rune yet
- }
- else
- {
- if (!(serverflags & self.spawnflags))
- return; // can still enter episode
- }
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-/*QUAKED func_bossgate (0 .5 .8) ? X X X X REVERSE_FUNCTIONALITY
-This bmodel appears unless players have all of the episode sigils.
-*/
-void() func_bossgate =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & GATE_REVERSE)
- {
- if (!((serverflags & 15) == 15))
- {
- return; // not all complete
- }
- }
- else
- {
- if ( (serverflags & 15) == 15 )
- return; // all episodes completed
- }
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
-};
-
-/*****************
-func_togglevisiblewall
-
-A bmodel which you can toggle its visibility. Behaves much like a traditional func_wall in any other way,
-but you can target it to toggle visible/invisible.
-If the entity has a switchable shadow it also toggles.
-
-spawnflag 1: starts invisible
-spawnflag 2: set brush as non-solid
-
-******************/
-
-float TOGGLEVISWALL_STARTOFF = 1;
-float TOGGLEVISWALL_NOTSOLID = 2;
-
-void() func_togglevisiblewall_use =
-{
- if(!self.state) {
- if(!(self.spawnflags & TOGGLEVISWALL_NOTSOLID)) {
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- }
- setmodel (self, self.origmodel);
- if(self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
- self.state = 1;
- } else {
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, "");
- if(self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- self.state = 0;
- }
-
-};
-
-void() func_togglevisiblewall =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.use = func_togglevisiblewall_use;
-
- self.origmodel = self.model;
-
- if(self.spawnflags & TOGGLEVISWALL_STARTOFF) self.state = 1;
- else self.state = 0;
-
- if(self.spawnflags & TOGGLEVISWALL_NOTSOLID) {
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- }
-
- func_togglevisiblewall_use();
-
-};
-
-
-/*****************
-func_shadow
-
-An invisible bmodel that can be used to only cast shadows.
-
-******************/
-
-void() func_shadow = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
-
- self.modelindex = 0;
- self.model = "";
-
-}
-
-
-
-/********************
-misc_shadowcontroller
-
-Controls switchable shadows on any bmodel entity (except doors).
-Target entity must have set _switchableshadow set to 1.
-
-speed: Controls the time in seconds it takes to fade the shadow in. Default is 0.5, and setting it to -1 disables fading.
-speed2: Same as 'speed' but for the fade out animation. If unset it's the same value as 'speed'.
-spawnflag 1: target shadow starts as disabled
-
-*********************/
-
-float SHADOWCONTROLLER_STARTOFF = 1;
-
-void() shadow_fade_out =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint(ftos(self.count));dprint("\n");
-
- lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count + self.dmg;
- if (self.count > 12)
- return;
-
- self.think = shadow_fade_out;
- self.nextthink = time + self.delay;
-};
-
-void() shadow_fade_in =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint(ftos(self.count));dprint("\n");
-
- lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count - self.dmg;
- if (self.count < 0)
- return;
-
- self.think = shadow_fade_in;
- self.nextthink = time + self.delay;
-
-};
-
-void(float speed) misc_shadowcontroller_setsteps = {
- // self.delay -> time between steps
- // self.dmg -> step size
- if(speed >= 0.24) {
- self.delay = (speed/12);
- self.dmg = 1;
- }
- else if(speed >= 0.12) {
- self.delay = (speed/6);
- self.dmg = 2;
- }
- else if(speed >= 0.06) {
- self.delay = (speed/3);
- self.dmg = 4;
- }
- else if(speed >= 0.04) {
- self.delay = (speed/2);
- self.dmg = 6;
- }
- else {
- self.delay = 0;
- self.dmg = 12;
- }
-
-}
-
-void() misc_shadowcontroller_use = {
-
- if(self.shadowoff) {
- dprint("Fade in:\n");
-
- misc_shadowcontroller_setsteps(self.speed);
-
- shadow_fade_in();
-
- self.shadowoff = 0;
- } else {
- dprint("Fade out:\n");
-
- misc_shadowcontroller_setsteps(self.speed2);
-
- shadow_fade_out();
-
- self.shadowoff = 1;
- }
-}
-
-void() misc_shadowcontroller = {
- entity t1;
-
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
-
- // doesn't search for a target if switchshadstyle is already set
- // used for built-in shadow controllers
- if(!self.switchshadstyle) {
-
- // we need to find only the first target entity with switchable shadows set, since shadow lightstyles are bound by targetname
-
-
- t1 = find(world, targetname2, self.target);
-
- while(t1 != world && !t1.switchshadstyle) {
- t1 = find(t1, targetname2, self.target);
- }
-
- if(t1 == world) {
- t1 = find(world, targetname, self.target);
-
- while(t1 != world && !t1.switchshadstyle) {
- t1 = find(t1, targetname, self.target);
- }
- }
-
-
- if(t1 == world) {
- dprint("\b[misc_shadowcontroller]\b _switchableshadow not set in target ");dprint(self.target);dprint("\n");
- return;
- }
-
- self.switchshadstyle = t1.switchshadstyle;
- }
-
- if(!self.speed) self.speed = 0.5;
- if(!self.speed2) self.speed2 = self.speed;
-
- if(self.spawnflags & SHADOWCONTROLLER_STARTOFF) {
- lightstyle(self.switchshadstyle, "m");
-
- self.shadowoff = 1;
- self.count = 12;
-
- misc_shadowcontroller_setsteps(self.speed2);
- }
- else {
- lightstyle(self.switchshadstyle, "a");
- self.shadowoff = 0;
- self.count = 0;
- misc_shadowcontroller_setsteps(self.speed);
- }
-
- self.use = misc_shadowcontroller_use;
-}
-
-
-/*
-misc_infight
-
-target = monster that gets mad
-target2 = who target1 will be angry at
-
-spawnflag 1 = mutual hate, both targets get angry at each other instantly
-spawnflag 2 = maintain activator, makes it so the player that triggers the infighting sees centerprints triggered by it
-*/
-
-float INFIGHT_MUTUAL = 1;
-float INFIGHT_PLAYER_ACTIVATION = 2;
-
-void(entity t1, entity t2) make_angry_at =
-{
- if (t2.health > 0 && t1.health > 0) { // checks if targets are alive
- if (t1.enemy.classname == "player")
- t1.oldenemy = t1.enemy;
- t1.enemy = t2;
-
- entity oself = self;
- self = t1; // FoundTarget() only acts on self
- FoundTarget();
- self = oself;
- }
-};
-
-void() misc_infight_use =
-{
- local entity t1, t2;
-
- for (t1 = world; (t1 = find(t1, targetname, self.target)); )
- {
- for (t2 = world; (t2 = find(t2, targetname, self.target2)); )
- {
- // t1 = find(world, targetname, self.target);
- // t2 = find(world, targetname, self.target2);
-
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname2\n");
- t1 = find(world, targetname2, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname3\n");
- t1 = find(world, targetname3, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, checking targetname4\n");
- t1 = find(world, targetname4, self.target);
- }
- if (!t1)
- {
- dprint("[trigger_infight] Cannot find target, exhausted all targetnames\n");
- return;
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname2\n");
- t2 = find(world, targetname2, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname3\n");
- t2 = find(world, targetname3, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2 checking targetname4\n");
- t2 = find(world, targetname4, self.target2);
- }
- if (!t2)
- {
- dprint("[trigger_infight] Cannot find target2, exhausted all targetnames\n");
- return;
- }
-
- make_angry_at(t1, t2);
-
- if (self.spawnflags & INFIGHT_PLAYER_ACTIVATION)
- {
- t1.infight_activator = activator;
- t2.infight_activator = activator;
- }
-
- if (self.spawnflags & INFIGHT_MUTUAL)
- make_angry_at(t2, t1);
- }
- }
-};
-
-void() misc_infight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = misc_infight_use;
-};
-
-
-
-
-
-//============================================================================
-/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_suck_wind =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/suck1.wav");
- ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
-};
-
-/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_drone =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/drone6.wav");
- ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
-};
-
-/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_flouro_buzz =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_drip =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-*/
-void() ambient_comp_hum =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/comp1.wav");
- ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
-};
-/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_light_buzz =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_swamp1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_swamp2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/swamp2.wav");
- ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
-};
-/////////////////////////////////////////////////////////////
-////////// dumptruck_ds ////////////////////////////////////
-///////////////////////////////////////////////////////////
-
-/* Additions to Ambient Sound effects. These are hard coded into the engine and
- usually play back automatically when the sky or water textures are used. If
- you'd prefer to use these in custom setups, you can use the command line
- switch -nomabient in when you VIS your map to disable the hard coded sounds. */
-
-/*QUAKED ambient_water1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_water1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/water1.wav");
- ambientsound (self.origin, "ambience/water1.wav", 1, ATTN_STATIC);
-};
-/*QUAKED ambient_wind2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-*/
-void() ambient_wind2 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound ("ambience/wind2.wav");
- ambientsound (self.origin, "ambience/wind2.wav", 1, ATTN_STATIC);
-};
-/////////////////////////////////////////////////////////////
-////////// dumptruck_ds ////////////////////////////////////
-///////////////////////////////////////////////////////////
-
-/* The original ambient_thunder was included in Quake but the code was missing.
- This version is borrowed from the Zerstörer mod but modified to only play the
- original thumder1.wav included in the game. This is also different than the
- other ambient sounds as it plays back randomly as opposed to looping. You
- only need one of these in your level. It will play everywhere. */
-
-void() thunder_go_boom =
-{
- if (random() < 0.5)
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NONE);
- else
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 1, ATTN_NONE);
-
- self.think = thunder_go_boom;
- self.nextthink = time + 40*random();
-};
-
-/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-The original ambient_thunder was included in Quake but the code was missing.
-This version is borrowed from the Zerstörer mod but modified to only play the
-original thumder1.wav included in the game. This is also different than the
-other ambient sounds as it plays back randomly as opposed to looping. You
-only need one of these in your level. It will play everywhere.
-*/
-void() ambient_thunder =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // changed from ambient to delayed sound (sounds better)
- precache_sound ("ambience/thunder1.wav");
- // precache_sound ("ambience/thunder2.wav"); this file in not included in the game
- self.think = thunder_go_boom;
- self.nextthink = time + random();
-};
-
-
-
-//============================================================================
-
-void() noise_think =
-{
- self.nextthink = time + 0.5;
- sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
- sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
- sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
- sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
- sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
- sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
- sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
-};
-
-/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-For optimzation testing, starts a lot of sounds.
-*/
-
-void() misc_noisemaker =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2 ("enforcer/sight4.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/idle1.wav");
-
- self.nextthink = time + 0.1 + random();
- self.think = noise_think;
-};
-
-
-/***********************************************
-
-target_autosave
-from Copper
-
-***********************************************/
-
-void() target_autosave_use =
-{
- if (self.enemy)
- {
- activator = self.enemy;
- self.enemy = world;
- }
- if (activator.classname != "player") return;
- if (time < 2) // make sure an autosave fired from a player start doesn't happen too early
- {
- //if (serverflags & SVFL_RESPAWNING)
- //{
- // dprint("RESPAWNING flag set, skipping autosave\n");
- // return;
- //}
- self.enemy = activator;
- self.think = target_autosave_use;
- self.nextthink = 2;
- return;
- }
- // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
- autosave(activator, self.message);
-}
-
-void() toggle_autosave =
-{
- entity e = world;
- float printed = FALSE;
- do {
- e = find(e, classname, "target_autosave");
- if (!e) break;
-
- if (e.use == target_autosave_use)
- {
- e.use = SUB_Null;
- if (!printed)
- {
- bprint("Autosaves disabled\n");
- printed = TRUE;
- }
- } else {
- e.use = target_autosave_use;
- if (!printed)
- {
- bprint("Autosaves reenabled\n");
- printed = TRUE;
- }
- }
-
- } while (e != world);
-}
-
-/*QUAKED target_autosave (1 .0 .5) (-8 -8 -8) (8 8 8)
-Saves the game when triggered by a player. Never appears in multiplayer. the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb.
-
-Keys:
-"message" change save file name, defaults to 'auto'
-*/
-/*FGD
-@Pointclass base(Target, Targetname, Appearflags) color(255 0 128) size(32 32 32) = target_autosave :
-"Saves the game when triggered by a player. Never appears in multiplayer.
-the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb."
-[
- message(string) : "Change save filename" : "auto"
-]
-*/
-void() target_autosave =
-{
- if (deathmatch || coop)
- {
- remove(self);
- return;
- }
-
-
- if (self.message == string_null)
- self.message = "auto";
- // precache_sound2("misc/sav.wav");
- self.use = target_autosave_use;
-}
-
-
-/*
-=============================================================
-
-trigger_textstory
-
-=============================================================
-*/
-
-float TEXTSTORY_SILENT = 1;
-float TEXTSTORY_NOFADE = 2;
-
-void(entity controller) textstory_hide = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
-
- self.enemy.suppressCenterPrint = FALSE;
- centerprint(self.enemy, "");
-
- if (controller.noise2)
- sound(self.enemy, CHAN_BODY, controller.noise2, 1, ATTN_NORM);
-
- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- csf_fade(self.enemy, 0, '0 0 0', 0.5);
-
-};
-
-void(entity controller) textstory_show = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
-
- self.enemy.suppressCenterPrint = TRUE;
-
- centerprint_builtin(self.enemy, controller.message);
-
- if (!self.state) {
- if (controller.noise1)
- sound(self.enemy, CHAN_BODY, controller.noise1, 1, ATTN_NORM);
-
- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- if (!self.fade_amt) //custom fade amount --dumptruck_ds
- {
- csf_fade(self.enemy, 160, '0 0 0', 1);
- }
- else
- csf_fade(self.enemy, self.fade_amt, '0 0 0', 1);
- }
-
-
- self.state = 1;
-};
-
-//----------------------------------------
-
-void() trigger_textstory_hide = {
- textstory_hide(self);
-
- self.enemy = world;
- self.state = 0;
-};
-
-void() trigger_textstory_show = {
- textstory_show(self);
-
- self.think = trigger_textstory_hide;
- self.nextthink = time + 0.2;
-
-};
-
-void() trigger_textstory_touch = {
-
- if (!(other.flags & FL_CLIENT)) return;
- if (self.estate != STATE_ACTIVE) return;
-
- // don't show message if another player is already triggering it
- if (other != self.enemy && self.state == 1) return;
-
- if (self.mangle && !isInAngle(other.v_angle, self.mangle, self.view_ofs))
- return;
-
- if (self.attack_finished < time) {
-
- self.attack_finished = time + 0.1;
- self.enemy = other;
-
- trigger_textstory_show();
- }
-};
-
-void() trigger_textstory = {
- InitTrigger();
- self.touch = trigger_textstory_touch;
-
- if (self.view_ofs == '0 0 0')
- self.view_ofs = '90 90 0';
-
- if (self.mangle) self.mangle = normalizeAngles180(self.mangle);
-
- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
-
- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
-
- if (self.spawnflags & TEXTSTORY_SILENT) {
- self.noise1 = "";
- self.noise2 = "";
- }
-
-
- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
-
- SUB_CheckWaiting();
-};
-
-
-//-----------------------------
-
-
-void() target_textstory_helper_hide = {
-
- textstory_hide(self.owner);
- remove(self);
-};
-
-void() target_textstory_helper_show = {
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) {
- remove(self);
- return;
- }
-
- textstory_show(self.owner);
-
- if (self.attack_finished < time) self.think = target_textstory_helper_hide;
-
- self.nextthink = time + 0.1;
-};
-
-void(entity tgt) target_textstory_spawn_helper = {
- entity e;
-
- e = spawn();
- e.classname = "target_textstory_helper";
- e.owner = self;
- e.think = target_textstory_helper_show;
- e.nextthink = time + 0.1;
- e.attack_finished = time + self.wait;
- e.enemy = tgt;
-};
-
-void() target_textstory_use = {
-
- if (!(activator.flags & FL_CLIENT)) return;
- if (self.estate != STATE_ACTIVE) return;
-
- entity t;
-
- if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
- t = find(world, classname, "player");
- while (t) {
- target_textstory_spawn_helper(t);
- t = find(t, classname, "player");
- }
- }
- else
- target_textstory_spawn_helper(activator);
-};
-
-void() target_textstory = {
- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
-
- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
-
- if (self.spawnflags & TEXTSTORY_SILENT) {
- self.noise1 = "";
- self.noise2 = "";
- }
-
- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
-
- if (!self.wait)
- self.wait = 5;
-
- self.use = target_textstory_use;
-};
+// these were moved for various reasons -- dumptruck_ds
+// /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4)
+// Used as a positional target for spotlights, etc.
+// */
+// /void() info_null =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// 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 =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+// };
+//
+// //============================================================================
+//
+// float START_OFF = 1;
+//
+// void() light_use =
+// {
+// if (self.spawnflags & START_OFF)
+// {
+// lightstyle(self.style, "m");
+// self.spawnflags = self.spawnflags - START_OFF;
+// }
+// else
+// {
+// lightstyle(self.style, "a");
+// self.spawnflags = self.spawnflags + START_OFF;
+// }
+// };
+//
+// /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Non-displayed light.
+// Default light value is 300
+// Default style is 0
+// If targeted, it will toggle between on or off.
+// */
+// void() light =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (!self.targetname)
+// { // inert light
+// remove(self);
+// return;
+// }
+//
+// if (self.style >= 32)
+// {
+// self.use = light_use;
+// if (self.spawnflags & START_OFF)
+// lightstyle(self.style, "a");
+// else
+// lightstyle(self.style, "m");
+// }
+// };
+//
+// /*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Non-displayed light.
+// Default light value is 300
+// Default style is 0
+// If targeted, it will toggle between on or off.
+// Makes steady fluorescent humming sound
+// */
+// void() light_fluoro =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (self.style >= 32)
+// {
+// self.use = light_use;
+// if (self.spawnflags & START_OFF)
+// lightstyle(self.style, "a");
+// else
+// lightstyle(self.style, "m");
+// }
+//
+// precache_sound ("ambience/fl_hum1.wav");
+// ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
+// };
+//
+// /*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8)
+// Non-displayed light.
+// Default light value is 300
+// Default style is 10
+// Makes sparking, broken fluorescent sound
+// */
+// void() light_fluorospark =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// if (!self.style)
+// self.style = 10;
+//
+// precache_sound ("ambience/buzz1.wav");
+// ambientsound (self.origin, "ambience/buzz1.wav", 0.5, ATTN_STATIC);
+// };
+//
+// /*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8)
+// Sphere globe light.
+// Default light value is 300
+// Default style is 0
+// */
+// void() light_globe =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/s_light.spr");
+// setmodel (self, "progs/s_light.spr");
+// makestatic (self);
+// };
+//
+/*QUAKED FireAmbient (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
+*/
+void() FireAmbient =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/fire1.wav");
+// attenuate fast
+ ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
+};
+
+/*QUAKED ambient_fire (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ambinet fire sound effects added for consistency
+same as FireAmbient
+*/
+void() ambient_fire =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+FireAmbient();
+};
+
+//
+// /*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20)
+// Short wall torch
+// Default light value is 200
+// Default style is 0
+// */
+// void() light_torch_small_walltorch =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame.mdl");
+// setmodel (self, "progs/flame.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18)
+// Large yellow flame ball
+// */
+// void() light_flame_large_yellow =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// self.frame = 1;
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) START_OFF
+// Small yellow flame ball
+// */
+// void() light_flame_small_yellow =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+// /*QUAKED light_flame_small_white (0 1 0) (-10 -10 -40) (10 10 40) START_OFF
+// Small white flame ball
+// */
+// void() light_flame_small_white =
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// precache_model ("progs/flame2.mdl");
+// setmodel (self, "progs/flame2.mdl");
+// FireAmbient ();
+// makestatic (self);
+// };
+//
+/*QUAKED light_candle (0 1 0) (-10 -10 -40) (10 10 40) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/candle.mdl"); }
+==========
+Spawnflags
+==========
+START_OFF - switchable lights only - light is off by default
+FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
+
+==========
+Keys
+==========
+"light" "n"
+Set the light intensity. Negative values are also allowed and will cause the entity to subtract light cast by other entities. Default 300.
+
+"wait" "n"
+Scale the fade distance of the light by "n". Values of n > 1 make the light fade more quickly with distance, and values < 1 make the light fade more slowly (and thus reach further). Default 1.
+
+"delay" "n"
+Select an attenuation formaula for the light:
+0 => Linear attenuation (default)
+1 => 1/x attenuation
+2 => 1/(x^2) attenuation
+3 => No attenuation (same brightness at any distance)
+4 => "local minlight" - No attenuation and like minlight,
+it won't raise the lighting above it's light value.
+Unlike minlight, it will only affect surfaces within
+line of sight of the entity.
+5 => 1/(x^2) attenuation, but slightly more attenuated and
+without the extra bright effect that "delay 2" has
+near the source.
+
+"_falloff" "n"
+Sets the distance at which the light drops to 0, in map units.
+In this mode, "wait" is ignored and "light" only controls the brightness at the center of the light, and no longer affects the falloff distance.
+Only supported on linear attenuation (delay 0) lights currently.
+
+"_color" "r g b"
+Specify red(r), green(g) and blue(b) components for the colour of the light. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light ("255 255 255").
+
+"target" "name"
+Turns the light into a spotlight, with the direction of light being towards another entity with it�s "targetname" key set to "name".
+"mangle" "yaw pitch roll"
+Turns the light into a spotlight and specifies the direction of light using yaw, pitch and roll in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Often easier than the "target" method.
+
+"angle" "n"
+Specifies the angle in degrees for a spotlight cone. Default 40.
+
+"_softangle" "n"
+Specifies the angle in degrees for an inner spotlight cone (must be less than the "angle" cone. Creates a softer transition between the full brightness of the inner cone to the edge of the outer cone. Default 0 (disabled).
+
+"targetname" "name"
+Turns the light into a switchable light, toggled by another entity targeting it�s name.
+
+"speed" "n"
+If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
+
+"style" "n"
+Set the animated light style. Default 0.
+
+"style2" "n"
+Set the animated light style for a switchable light, because style will be overriden if a targetname is set. Default 0.
+
+"_anglescale" "n" | "_anglesense" "n"
+Sets a scaling factor for how much influence the angle of incidence of light on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5.
+
+"_dirtscale" "n" | "_dirtgain" "n"
+Override the global "_dirtscale" or "_dirtgain" settings to change how this light is affected by dirtmapping (ambient occlusion). See descriptions of these keys in the worldspawn section.
+
+"_dirt" "n"
+Overrides the worldspawn setting of "_dirt" for this particular light. -1 to disable dirtmapping (ambient occlusion) for this light, making it illuminate the dirtmapping shadows. 1 to enable ambient occlusion for this light. Default is to defer to the worldspawn setting.
+
+"_deviance" "n"
+Split up the light into a sphere of randomly positioned lights within radius "n" (in world units). Useful to give shadows a wider penumbra. "_samples" specifies the number of lights in the sphere. The "light" value is automatically scaled down for most lighting formulas (except linear and non-additive minlight) to attempt to keep the brightness equal. Default is 0, do not split up lights.
+
+"_samples" "n"
+Number of lights to use for "_deviance". Default 16 (only used if "_deviance" is set).
+
+"_surface" "texturename"
+Makes surfaces with the given texture name emit light, by using this light as a template which is copied across those surfaces. Lights are spaced about 128 units (though possibly closer due to bsp splitting) apart and positioned 2 units above the surfaces.
+
+"_surface_offset" "n"
+Controls the offset lights are placed above surfaces for "_surface". Default 2.
+
+"_surface_spotlight" "n"
+For a surface light template (i.e. a light with "_surface" set), setting this to "1" makes each instance into a spotlight, with the direction of light pointing along the surface normal. In other words, it automatically sets "mangle" on each of the generated lights.
+
+"_project_texture" "texture"
+Specifies that a light should project this texture. The texture must be used in the map somewhere.
+
+"_project_mangle" "yaw pitch roll"
+Specifies the yaw/pitch/roll angles for a texture projection (overriding mangle).
+
+"_project_fov" "n"
+Specifies the fov angle for a texture projection. Default 90.
+
+"_bouncescale" "n"
+Scales the amount of light that is contributed by bounces. Default is 1.0, 0.0 disables bounce lighting for this light.
+
+"_sun" "n"
+Set to 1 to make this entity a sun, as an alternative to using the sunlight worldspawn keys. If the light targets an info_null entity, the direction towards that entity sets sun direction. The light itself is disabled, so it can be placed anywhere in the map.
+
+The following light properties correspond to these sunlight settings:
+light => _sunlight
+mangle => _sunlight_mangle
+deviance => _sunlight_penumbra
+_color => _sunlight_color
+_dirt => _sunlight_dirt
+_anglescale => _anglescale
+
+ //dumptruck_ds taken from honey (originally from Rogue)
+White candle
+*/
+void() light_candle =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/candle.mdl");
+ setmodel (self, "progs/candle.mdl");
+ makestatic (self);
+};
+
+void() model_candle_think =
+{
+ self.frame = self.frame + 1;
+ if (self.frame > 3)
+ self.frame = 0;
+ self.nextthink = time + 0.1;
+};
+
+void() model_candle =
+{
+
+ precache_model ("progs/candle.mdl");
+
+ setmodel (self, "progs/candle.mdl");
+
+ self.think = model_candle_think;
+ self.nextthink = time + 0.1;
+};
+
+
+//============================================================================
+
+
+/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model ("progs/lavaball.mdl"); }
+Flying lava balls
+speed - set vertical speed of fireballs. default 1000.
+*/
+
+void() fire_fly;
+void() fire_touch;
+void() misc_fireball =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/lavaball.mdl");
+ self.classname = "fireball";
+// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+// self.nextthink = time + (random() * 5);
+ self.nextthink = time + 0.1 + (random() * 5);
+// 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+ self.think = fire_fly;
+ if (!self.speed)
+ self.speed = 1000; // fixed typo QIP - dumptruck_ds
+};
+
+void() fire_fly =
+{
+local entity fireball;
+
+ fireball = spawn();
+ fireball.solid = SOLID_TRIGGER;
+ fireball.movetype = MOVETYPE_TOSS;
+ fireball.velocity = '0 0 1000';
+ fireball.velocity_x = (random() * 100) - 50;
+ fireball.velocity_y = (random() * 100) - 50;
+ fireball.velocity_z = self.speed + (random() * 200);
+ fireball.classname = "fireball";
+ setmodel (fireball, "progs/lavaball.mdl");
+ setsize (fireball, '0 0 0', '0 0 0');
+ setorigin (fireball, self.origin);
+ fireball.nextthink = time + 5;
+ fireball.think = SUB_Remove;
+ fireball.touch = fire_touch;
+
+ self.nextthink = time + (random() * 5) + 3;
+ self.think = fire_fly;
+};
+
+
+void() fire_touch =
+{
+ T_Damage (other, self, self, 20);
+ remove(self);
+};
+
+//============================================================================
+
+
+void() barrel_explode =
+{
+ self.takedamage = DAMAGE_NO;
+ self.classname = "explo_box";
+ // did say self.owner
+ T_RadiusDamage (self, self, 160, world);
+ sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ particle (self.origin, '0 0 0', 75, 255);
+
+ self.origin_z = self.origin_z + 32;
+ BecomeExplosion ();
+};
+
+
+
+/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model("maps/b_explob.bsp");
+}
+Explosive box
+*/
+
+void() misc_explobox =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float oldz;
+
+ self.solid = SOLID_BBOX;
+ self.movetype = MOVETYPE_NONE;
+ precache_model ("maps/b_explob.bsp");
+ setmodel (self, "maps/b_explob.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ self.health = 20;
+ self.th_die = barrel_explode;
+ self.takedamage = DAMAGE_AIM;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+ self.origin_z = self.origin_z + 2;
+ oldz = self.origin_z;
+ droptofloor();
+ if (oldz - self.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove(self);
+ }
+};
+
+
+
+
+/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model("maps/b_exbox2.bsp");
+}
+Smaller explosive box
+*/
+
+void() misc_explobox2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local float oldz;
+
+ self.solid = SOLID_BBOX;
+ self.movetype = MOVETYPE_NONE;
+ precache_model2 ("maps/b_exbox2.bsp");
+ setmodel (self, "maps/b_exbox2.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ self.health = 20;
+ self.th_die = barrel_explode;
+ self.takedamage = DAMAGE_AIM;
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+
+ self.origin_z = self.origin_z + 2;
+ oldz = self.origin_z;
+ droptofloor();
+ if (oldz - self.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ remove(self);
+ }
+};
+
+/*==============================================================================
+trap_spikeshooter from Hipnotic -- with additions by dumptruck_ds
+==============================================================================*/
+
+//MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds
+float SPAWNFLAG_SUPERSPIKE = 1;
+float SPAWNFLAG_LASER = 2;
+float SPAWNFLAG_LAVABALL = 4;
+float SPAWNFLAG_ROCKET = 8;
+float SPAWNFLAG_VOREBALL = 16;
+float SPAWNFLAG_GRENADE = 32;
+float SPAWNFLAG_GIBS = 64;
+float SPAWNFLAG_SILENT = 128;
+
+void() ShalMissileTouch = //moved from Shalrath to enable shooter version
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (other.classname == "monster_zombie")
+ T_Damage (other, self, self, 110);
+ T_RadiusDamage (self, self.owner, 40, world);
+ sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+
+
+ // self.velocity = '0 0 0';
+ // self.touch = SUB_Null;
+ // setmodel (self, "progs/s_explod.spr");
+ // self.solid = SOLID_NOT;
+ // s_explode1 ();
+};
+
+void() ZombieGrenadeTouch = //moved from zombie.qc to enable shooter version
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage)
+ {
+ T_Damage (other, self, self.owner, 10 );
+ sound (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+ remove (self);
+ return;
+ }
+ sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+ self.velocity = '0 0 0';
+ self.avelocity = '0 0 0';
+ self.touch = SUB_Remove;
+};
+
+
+void(vector org, vector vec) LaunchLaser;
+
+//MED 11/09/96 added lava ball and rocket
+//dumptruck_ds added voreball and grenades
+void() spikeshooter_use =
+{
+ local entity lavaball;
+ local entity voreball;
+ local entity rockettrap;
+ local entity gnade;
+ local entity zgibs;
+
+ if (self.spawnflags & SPAWNFLAG_LASER)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "enforcer/enfire.wav", 1, ATTN_NORM);
+ LaunchLaser (self.origin, self.movedir);
+ newmis.spawnflags = self.spawnflags;
+ }
+ else if (self.spawnflags & SPAWNFLAG_LAVABALL)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "boss1/throw.wav", 1, ATTN_NORM); //dms
+ // sound (self, CHAN_VOICE, "knight/sword2.wav", 1, ATTN_NORM); //dms
+ // sound (self, CHAN_VOICE, "weapons/ax1.wav", 1, ATTN_NORM); //dms
+ lavaball = spawn();
+ lavaball.movetype = MOVETYPE_FLYMISSILE;
+ lavaball.solid = SOLID_BBOX;
+ lavaball.classname = "lavaball";
+ // set lavaball speed
+ lavaball.velocity = self.movedir * 600; //was 300 dms
+ lavaball.angles = vectoangles(lavaball.velocity);
+ lavaball.owner = self;
+ lavaball.touch = ShalMissileTouch;
+ setmodel (lavaball, "progs/lavaball.mdl"); //dms
+ setsize (lavaball, '0 0 0', '0 0 0');
+ setorigin (lavaball, self.origin);
+ lavaball.avelocity = '0 0 400';
+ lavaball.nextthink = time + 5;
+ lavaball.think = SUB_Remove;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_ROCKET)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/sgun1.wav", 1, ATTN_NORM);
+ rockettrap = spawn();
+ rockettrap.movetype = MOVETYPE_FLYMISSILE;
+ rockettrap.solid = SOLID_BBOX;
+ rockettrap.classname = "rockettrap";
+ // set rocket speed
+ rockettrap.velocity = self.movedir * 1000;
+ rockettrap.angles = vectoangles(rockettrap.velocity);
+ rockettrap.owner = self;
+ rockettrap.touch = T_MissileTouch;
+ setmodel (rockettrap, "progs/missile.mdl"); //dms
+ setsize (rockettrap, '0 0 0', '0 0 0');
+ setorigin (rockettrap, self.origin);
+ // rockettrap.avelocity = '0 0 400';
+ rockettrap.nextthink = time + 5;
+ rockettrap.think = SUB_Remove;
+ }
+ else if (self.spawnflags & SPAWNFLAG_VOREBALL)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "shalrath/attack2.wav", 1, ATTN_NORM);
+ voreball = spawn();
+ voreball.movetype = MOVETYPE_FLYMISSILE;
+ voreball.solid = SOLID_BBOX;
+ voreball.classname = "voreball";
+ // set voreball speed
+ voreball.velocity = self.movedir * 600; //was 300 dms
+ voreball.angles = vectoangles(voreball.velocity);
+ voreball.owner = self;
+ voreball.touch = ShalMissileTouch;
+ setmodel (voreball, "progs/v_spike.mdl"); //dms
+ setsize (voreball, '0 0 0', '0 0 0');
+ setorigin (voreball, self.origin);
+ voreball.avelocity = '0 0 400';
+ voreball.nextthink = time + 5;
+ voreball.think = SUB_Remove;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_GRENADE)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/grenade.wav", 1, ATTN_NORM);
+ gnade = spawn();
+ gnade.movetype = MOVETYPE_BOUNCE;
+ // gnade.movetype = MOVETYPE_FLYMISSILE;
+ gnade.solid = SOLID_BBOX;
+ gnade.classname = "gnade";
+ // set grenade speed
+ // gnade.velocity = self.movedir * 600; //was 300 dms
+ gnade.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ gnade.angles = vectoangles(gnade.velocity);
+ gnade.owner = self;
+ gnade.touch = GrenadeTouch;
+ setmodel (gnade, "progs/grenade.mdl"); //dms
+ setsize (gnade, '0 0 0', '0 0 0');
+ setorigin (gnade, self.origin);
+ gnade.avelocity = '300 300 300';
+ gnade.nextthink = time + 2.5;
+ gnade.think = GrenadeExplode;
+ }
+
+ else if (self.spawnflags & SPAWNFLAG_GIBS)
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "zombie/z_shot1.wav", 1, ATTN_NORM);
+ zgibs = spawn ();
+ zgibs.owner = self;
+ zgibs.movetype = MOVETYPE_BOUNCE;
+ zgibs.solid = SOLID_BBOX;
+ zgibs.classname = "zgibs";
+ setmodel (zgibs, "progs/zom_gib.mdl");
+ setsize (zgibs, '0 0 0', '0 0 0');
+ setorigin (zgibs, self.origin);
+ zgibs.velocity = self.movedir * 600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ zgibs.avelocity = '3000 1000 2000';
+ zgibs.touch = ZombieGrenadeTouch;
+ // set missile duration
+ zgibs.nextthink = time + 2.5;
+ zgibs.think = SUB_Remove;
+ }
+
+ else
+ {
+ if (!(self.spawnflags & SPAWNFLAG_SILENT))
+ sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
+ launch_spike (self.origin, self.movedir);
+ newmis.velocity = self.movedir * 500;
+ if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
+ newmis.touch = superspike_touch;
+ }
+};
+
+//MED 11/01/96 added state capability
+void() shooter_think =
+{
+ if (self.state)
+ {
+ spikeshooter_use ();
+ }
+ self.nextthink = time + self.wait;
+};
+
+
+/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+When triggered, fires a spike in the direction set in QuakeEd.
+Laser is only for REGISTERED.
+*/
+
+//MED 11/01/96 commented out setmovedir
+void() trap_spikeshooter =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.proj_speed_mod <= 0)
+ self.proj_speed_mod = 1;
+ SetMovedir ();
+ self.use = spikeshooter_use;
+ if (self.spawnflags & SPAWNFLAG_LASER)
+ {
+ precache_model2 ("progs/laser.mdl");
+
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_LAVABALL)
+ {
+ precache_model ("progs/lavaball.mdl");
+ // precache_sound2 ("knight/sword2.wav"); //dms
+ precache_sound2 ("boss1/throw.wav"); //dms
+ }
+ else if (self.spawnflags & SPAWNFLAG_ROCKET)
+ {
+ precache_model ("progs/missile.mdl");
+ precache_sound ("weapons/sgun1.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_VOREBALL)
+ {
+ precache_model ("progs/v_spike.mdl");
+ precache_sound ("shalrath/attack2.wav");
+ }
+ else if (self.spawnflags & SPAWNFLAG_GRENADE)
+ {
+ precache_model ("progs/grenade.mdl");
+ precache_sound ("weapons/grenade.wav"); // grenade launcher
+ }
+ else if (self.spawnflags & SPAWNFLAG_GIBS)
+ {
+ precache_model ("progs/zom_gib.mdl");
+ precache_sound ("zombie/z_shot1.wav"); // Zombie gibs
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ }
+
+ else
+ precache_sound ("weapons/spike2.wav");
+};
+
+
+/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+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 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ trap_spikeshooter ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+//MED 11/01/96 added state capability
+ self.state = 1;
+ self.nextthink = self.nextthink + self.wait + self.ltime;
+ self.think = shooter_think;
+};
+
+//MED 11/01/96 added new use function
+void() trap_shooter_use =
+ {
+ self.state = 1 - self.state;
+ };
+//MED 11/01/96 added new function
+/*QUAKED trap_switched_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Continuously fires spikes.
+"wait" time between spike (1.0 default)
+"nextthink" delay before firing first spike, so multiple shooters can be stagered.
+"state" 0 initially off, 1 initially on. (0 default)
+*/
+void() trap_switched_shooter =
+ {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ trap_spikeshooter ();
+
+ if (self.wait == 0)
+ self.wait = 1;
+//MED 11/01/96 added state capability
+ self.nextthink = self.nextthink + self.wait + self.ltime;
+ self.think = shooter_think;
+ self.use = trap_shooter_use;
+ };
+
+/*
+===============================================================================
+
+
+===============================================================================
+*/
+
+
+void() make_bubbles;
+void() bubble_remove;
+void() bubble_bob;
+
+/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+air bubbles entity
+
+*/
+
+void() air_bubbles =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove (self);
+ return;
+ }
+ precache_model ("progs/s_bubble.spr");
+ self.nextthink = time + 1;
+ self.think = make_bubbles;
+};
+
+void() make_bubbles =
+{
+local entity bubble;
+
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.origin);
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = '0 0 15';
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.touch = bubble_remove;
+ bubble.classname = "bubble";
+ bubble.frame = 0;
+ bubble.cnt = 0;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+ self.nextthink = time + random() + 0.5;
+ self.think = make_bubbles;
+};
+
+void() bubble_split =
+{
+local entity bubble;
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.origin);
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = self.velocity;
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.touch = bubble_remove;
+ bubble.classname = "bubble";
+ bubble.frame = 1;
+ bubble.cnt = 10;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+ self.frame = 1;
+ self.cnt = 10;
+ if (self.waterlevel != 3)
+ remove (self);
+};
+
+void() bubble_remove =
+{
+ if (other.classname == self.classname)
+ {
+// dprint ("bump");
+ return;
+ }
+ remove(self);
+};
+
+void() bubble_bob =
+{
+local float rnd1, rnd2, rnd3;
+
+
+ self.cnt = self.cnt + 1;
+ if (self.cnt == 4)
+ bubble_split();
+ if (self.cnt == 20)
+ remove(self);
+
+ rnd1 = self.velocity_x + (-10 + (random() * 20));
+ rnd2 = self.velocity_y + (-10 + (random() * 20));
+ rnd3 = self.velocity_z + 10 + random() * 10;
+
+ if (rnd1 > 10)
+ rnd1 = 5;
+ if (rnd1 < -10)
+ rnd1 = -5;
+
+ if (rnd2 > 10)
+ rnd2 = 5;
+ if (rnd2 < -10)
+ rnd2 = -5;
+
+ if (rnd3 < 10)
+ rnd3 = 15;
+ if (rnd3 > 30)
+ rnd3 = 25;
+
+ self.velocity_x = rnd1;
+ self.velocity_y = rnd2;
+ self.velocity_z = rnd3;
+
+ self.nextthink = time + 0.5;
+ self.think = bubble_bob;
+};
+
+/*~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
+~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~*/
+
+/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)
+
+Just for the debugging level. Don't use
+*/
+
+void() viewthing =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ precache_model ("progs/player.mdl");
+ setmodel (self, "progs/player.mdl");
+};
+
+
+/*
+==============================================================================
+
+SIMPLE BMODELS
+
+==============================================================================
+*/
+
+void() func_wall_use =
+{ // change to alternate textures
+ self.frame = 1 - self.frame;
+};
+
+/*QUAKED func_wall (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This is just a solid wall if not inhibitted
+*/
+void() func_wall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+
+/*QUAKED func_illusionary (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A simple entity that looks solid but lets you walk through it.
+*/
+void() func_illusionary =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ setmodel (self, self.model);
+ makestatic (self);
+};
+
+
+float GATE_REVERSE = 16; // For func_episodegate and func_bossgate appear when player has all runes
+
+/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 REVERSE_FUNCTIONALITY
+This bmodel will appear if the episode has allready been completed, so players can't reenter it.
+*/
+void() func_episodegate =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & GATE_REVERSE)
+ {
+ self.spawnflags = self.spawnflags - GATE_REVERSE; // this is to avoid a possible issue with sigil_touch2
+ if (serverflags & self.spawnflags)
+ return; // Haven't gotten rune yet
+ }
+ else
+ {
+ if (!(serverflags & self.spawnflags))
+ return; // can still enter episode
+ }
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+/*QUAKED func_bossgate (0 .5 .8) ? X X X X REVERSE_FUNCTIONALITY
+This bmodel appears unless players have all of the episode sigils.
+*/
+void() func_bossgate =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & GATE_REVERSE)
+ {
+ if (!((serverflags & 15) == 15))
+ {
+ return; // not all complete
+ }
+ }
+ else
+ {
+ if ( (serverflags & 15) == 15 )
+ return; // all episodes completed
+ }
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything
+ self.solid = SOLID_BSP;
+ self.use = func_wall_use;
+ setmodel (self, self.model);
+};
+
+/*****************
+func_togglevisiblewall
+
+A bmodel which you can toggle its visibility. Behaves much like a traditional func_wall in any other way,
+but you can target it to toggle visible/invisible.
+If the entity has a switchable shadow it also toggles.
+
+spawnflag 1: starts invisible
+spawnflag 2: set brush as non-solid
+
+******************/
+
+float TOGGLEVISWALL_STARTOFF = 1;
+float TOGGLEVISWALL_NOTSOLID = 2;
+
+void() func_togglevisiblewall_use =
+{
+ if(!self.state) {
+ if(!(self.spawnflags & TOGGLEVISWALL_NOTSOLID)) {
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ }
+ setmodel (self, self.origmodel);
+ if(self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
+ self.state = 1;
+ } else {
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ setmodel (self, "");
+ if(self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ self.state = 0;
+ }
+
+};
+
+void() func_togglevisiblewall =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.use = func_togglevisiblewall_use;
+
+ self.origmodel = self.model;
+
+ if(self.spawnflags & TOGGLEVISWALL_STARTOFF) self.state = 1;
+ else self.state = 0;
+
+ if(self.spawnflags & TOGGLEVISWALL_NOTSOLID) {
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ }
+
+ func_togglevisiblewall_use();
+
+};
+
+
+/*****************
+func_shadow
+
+An invisible bmodel that can be used to only cast shadows.
+
+******************/
+
+void() func_shadow = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.angles = '0 0 0';
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+
+ self.modelindex = 0;
+ self.model = "";
+
+}
+
+
+
+/********************
+misc_shadowcontroller
+
+Controls switchable shadows on any bmodel entity (except doors).
+Target entity must have set _switchableshadow set to 1.
+
+speed: Controls the time in seconds it takes to fade the shadow in. Default is 0.5, and setting it to -1 disables fading.
+speed2: Same as 'speed' but for the fade out animation. If unset it's the same value as 'speed'.
+spawnflag 1: target shadow starts as disabled
+
+*********************/
+
+float SHADOWCONTROLLER_STARTOFF = 1;
+
+void() shadow_fade_out =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ dprint(ftos(self.count));dprint("\n");
+
+ lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
+ self.count = self.count + self.dmg;
+ if (self.count > 12)
+ return;
+
+ self.think = shadow_fade_out;
+ self.nextthink = time + self.delay;
+};
+
+void() shadow_fade_in =
+{
+ if (self.count < 0)
+ self.count = 0;
+ if (self.count > 12)
+ self.count = 12;
+
+ dprint(ftos(self.count));dprint("\n");
+
+ lightstyle(self.switchshadstyle, lightstyle_fade_lookup(self.count));
+ self.count = self.count - self.dmg;
+ if (self.count < 0)
+ return;
+
+ self.think = shadow_fade_in;
+ self.nextthink = time + self.delay;
+
+};
+
+void(float speed) misc_shadowcontroller_setsteps = {
+ // self.delay -> time between steps
+ // self.dmg -> step size
+ if(speed >= 0.24) {
+ self.delay = (speed/12);
+ self.dmg = 1;
+ }
+ else if(speed >= 0.12) {
+ self.delay = (speed/6);
+ self.dmg = 2;
+ }
+ else if(speed >= 0.06) {
+ self.delay = (speed/3);
+ self.dmg = 4;
+ }
+ else if(speed >= 0.04) {
+ self.delay = (speed/2);
+ self.dmg = 6;
+ }
+ else {
+ self.delay = 0;
+ self.dmg = 12;
+ }
+
+}
+
+void() misc_shadowcontroller_use = {
+
+ if(self.shadowoff) {
+ dprint("Fade in:\n");
+
+ misc_shadowcontroller_setsteps(self.speed);
+
+ shadow_fade_in();
+
+ self.shadowoff = 0;
+ } else {
+ dprint("Fade out:\n");
+
+ misc_shadowcontroller_setsteps(self.speed2);
+
+ shadow_fade_out();
+
+ self.shadowoff = 1;
+ }
+}
+
+void() misc_shadowcontroller = {
+ entity t1;
+
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+
+ // doesn't search for a target if switchshadstyle is already set
+ // used for built-in shadow controllers
+ if(!self.switchshadstyle) {
+
+ // we need to find only the first target entity with switchable shadows set, since shadow lightstyles are bound by targetname
+
+
+ t1 = find(world, targetname2, self.target);
+
+ while(t1 != world && !t1.switchshadstyle) {
+ t1 = find(t1, targetname2, self.target);
+ }
+
+ if(t1 == world) {
+ t1 = find(world, targetname, self.target);
+
+ while(t1 != world && !t1.switchshadstyle) {
+ t1 = find(t1, targetname, self.target);
+ }
+ }
+
+
+ if(t1 == world) {
+ dprint("\b[misc_shadowcontroller]\b _switchableshadow not set in target ");dprint(self.target);dprint("\n");
+ return;
+ }
+
+ self.switchshadstyle = t1.switchshadstyle;
+ }
+
+ if(!self.speed) self.speed = 0.5;
+ if(!self.speed2) self.speed2 = self.speed;
+
+ if(self.spawnflags & SHADOWCONTROLLER_STARTOFF) {
+ lightstyle(self.switchshadstyle, "m");
+
+ self.shadowoff = 1;
+ self.count = 12;
+
+ misc_shadowcontroller_setsteps(self.speed2);
+ }
+ else {
+ lightstyle(self.switchshadstyle, "a");
+ self.shadowoff = 0;
+ self.count = 0;
+ misc_shadowcontroller_setsteps(self.speed);
+ }
+
+ self.use = misc_shadowcontroller_use;
+}
+
+
+/*
+misc_infight
+
+target = monster that gets mad
+target2 = who target1 will be angry at
+
+spawnflag 1 = mutual hate, both targets get angry at each other instantly
+spawnflag 2 = maintain activator, makes it so the player that triggers the infighting sees centerprints triggered by it
+*/
+
+float INFIGHT_MUTUAL = 1;
+float INFIGHT_PLAYER_ACTIVATION = 2;
+
+void(entity t1, entity t2) make_angry_at =
+{
+ if (t2.health > 0 && t1.health > 0) { // checks if targets are alive
+ if (t1.enemy.classname == "player")
+ t1.oldenemy = t1.enemy;
+ t1.enemy = t2;
+
+ entity oself = self;
+ self = t1; // FoundTarget() only acts on self
+ FoundTarget();
+ self = oself;
+ }
+};
+
+void() misc_infight_use =
+{
+ local entity t1, t2;
+
+ for (t1 = world; (t1 = find(t1, targetname, self.target)); )
+ {
+ for (t2 = world; (t2 = find(t2, targetname, self.target2)); )
+ {
+ // t1 = find(world, targetname, self.target);
+ // t2 = find(world, targetname, self.target2);
+
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname2\n");
+ t1 = find(world, targetname2, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname3\n");
+ t1 = find(world, targetname3, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, checking targetname4\n");
+ t1 = find(world, targetname4, self.target);
+ }
+ if (!t1)
+ {
+ dprint("[trigger_infight] Cannot find target, exhausted all targetnames\n");
+ return;
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname2\n");
+ t2 = find(world, targetname2, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname3\n");
+ t2 = find(world, targetname3, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2 checking targetname4\n");
+ t2 = find(world, targetname4, self.target2);
+ }
+ if (!t2)
+ {
+ dprint("[trigger_infight] Cannot find target2, exhausted all targetnames\n");
+ return;
+ }
+
+ make_angry_at(t1, t2);
+
+ if (self.spawnflags & INFIGHT_PLAYER_ACTIVATION)
+ {
+ t1.infight_activator = activator;
+ t2.infight_activator = activator;
+ }
+
+ if (self.spawnflags & INFIGHT_MUTUAL)
+ make_angry_at(t2, t1);
+ }
+ }
+};
+
+void() misc_infight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.use = misc_infight_use;
+};
+
+
+
+
+
+//============================================================================
+/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_suck_wind =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/suck1.wav");
+ ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
+};
+
+/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_drone =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/drone6.wav");
+ ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
+};
+
+/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_flouro_buzz =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_drip =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+*/
+void() ambient_comp_hum =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/comp1.wav");
+ ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
+};
+/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_light_buzz =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_swamp1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ 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) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_swamp2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/swamp2.wav");
+ ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
+};
+/////////////////////////////////////////////////////////////
+////////// dumptruck_ds ////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+/* Additions to Ambient Sound effects. These are hard coded into the engine and
+ usually play back automatically when the sky or water textures are used. If
+ you'd prefer to use these in custom setups, you can use the command line
+ switch -nomabient in when you VIS your map to disable the hard coded sounds. */
+
+/*QUAKED ambient_water1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_water1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/water1.wav");
+ ambientsound (self.origin, "ambience/water1.wav", 1, ATTN_STATIC);
+};
+/*QUAKED ambient_wind2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+*/
+void() ambient_wind2 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound ("ambience/wind2.wav");
+ ambientsound (self.origin, "ambience/wind2.wav", 1, ATTN_STATIC);
+};
+/////////////////////////////////////////////////////////////
+////////// dumptruck_ds ////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+/* The original ambient_thunder was included in Quake but the code was missing.
+ This version is borrowed from the Zerstörer mod but modified to only play the
+ original thumder1.wav included in the game. This is also different than the
+ other ambient sounds as it plays back randomly as opposed to looping. You
+ only need one of these in your level. It will play everywhere. */
+
+void() thunder_go_boom =
+{
+ if (random() < 0.5)
+ sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NONE);
+ else
+ sound (self, CHAN_AUTO, "ambience/thunder1.wav", 1, ATTN_NONE);
+
+ self.think = thunder_go_boom;
+ self.nextthink = time + 40*random();
+};
+
+/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+The original ambient_thunder was included in Quake but the code was missing.
+This version is borrowed from the Zerstörer mod but modified to only play the
+original thumder1.wav included in the game. This is also different than the
+other ambient sounds as it plays back randomly as opposed to looping. You
+only need one of these in your level. It will play everywhere.
+*/
+void() ambient_thunder =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // changed from ambient to delayed sound (sounds better)
+ precache_sound ("ambience/thunder1.wav");
+ // precache_sound ("ambience/thunder2.wav"); this file in not included in the game
+ self.think = thunder_go_boom;
+ self.nextthink = time + random();
+};
+
+
+
+//============================================================================
+
+void() noise_think =
+{
+ self.nextthink = time + 0.5;
+ sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
+ sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
+ sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
+ sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
+ sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
+ sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
+ sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
+};
+
+/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+For optimzation testing, starts a lot of sounds.
+*/
+
+void() misc_noisemaker =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2 ("enforcer/sight4.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/idle1.wav");
+
+ self.nextthink = time + 0.1 + random();
+ self.think = noise_think;
+};
+
+
+/***********************************************
+
+target_autosave
+from Copper
+
+***********************************************/
+
+void() target_autosave_use =
+{
+ if (self.enemy)
+ {
+ activator = self.enemy;
+ self.enemy = world;
+ }
+ if (activator.classname != "player") return;
+ if (time < 2) // make sure an autosave fired from a player start doesn't happen too early
+ {
+ //if (serverflags & SVFL_RESPAWNING)
+ //{
+ // dprint("RESPAWNING flag set, skipping autosave\n");
+ // return;
+ //}
+ self.enemy = activator;
+ self.think = target_autosave_use;
+ self.nextthink = 2;
+ return;
+ }
+ // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
+ autosave(activator, self.message);
+}
+
+void() toggle_autosave =
+{
+ entity e = world;
+ float printed = FALSE;
+ do {
+ e = find(e, classname, "target_autosave");
+ if (!e) break;
+
+ if (e.use == target_autosave_use)
+ {
+ e.use = SUB_Null;
+ if (!printed)
+ {
+ bprint("Autosaves disabled\n");
+ printed = TRUE;
+ }
+ } else {
+ e.use = target_autosave_use;
+ if (!printed)
+ {
+ bprint("Autosaves reenabled\n");
+ printed = TRUE;
+ }
+ }
+
+ } while (e != world);
+}
+
+/*QUAKED target_autosave (1 .0 .5) (-8 -8 -8) (8 8 8)
+Saves the game when triggered by a player. Never appears in multiplayer. the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb.
+
+Keys:
+"message" change save file name, defaults to 'auto'
+*/
+/*FGD
+@Pointclass base(Target, Targetname, Appearflags) color(255 0 128) size(32 32 32) = target_autosave :
+"Saves the game when triggered by a player. Never appears in multiplayer.
+the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb."
+[
+ message(string) : "Change save filename" : "auto"
+]
+*/
+void() target_autosave =
+{
+ if (deathmatch || coop)
+ {
+ remove(self);
+ return;
+ }
+
+
+ if (self.message == string_null)
+ self.message = "auto";
+ // precache_sound2("misc/sav.wav");
+ self.use = target_autosave_use;
+}
+
+
+/*
+=============================================================
+
+trigger_textstory
+
+=============================================================
+*/
+
+float TEXTSTORY_SILENT = 1;
+float TEXTSTORY_NOFADE = 2;
+
+void(entity controller) textstory_hide = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
+
+ self.enemy.suppressCenterPrint = FALSE;
+ centerprint(self.enemy, "");
+
+ if (controller.noise2)
+ sound(self.enemy, CHAN_BODY, controller.noise2, 1, ATTN_NORM);
+
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ csf_fade(self.enemy, 0, '0 0 0', 0.5);
+
+};
+
+void(entity controller) textstory_show = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) return;
+
+ self.enemy.suppressCenterPrint = TRUE;
+
+ centerprint_builtin(self.enemy, controller.message);
+
+ if (!self.state) {
+ if (controller.noise1)
+ sound(self.enemy, CHAN_BODY, controller.noise1, 1, ATTN_NORM);
+
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ if (!self.fade_amt) //custom fade amount --dumptruck_ds
+ {
+ csf_fade(self.enemy, 160, '0 0 0', 1);
+ }
+ else
+ csf_fade(self.enemy, self.fade_amt, '0 0 0', 1);
+ }
+
+
+ self.state = 1;
+};
+
+//----------------------------------------
+
+void() trigger_textstory_hide = {
+ textstory_hide(self);
+
+ self.enemy = world;
+ self.state = 0;
+};
+
+void() trigger_textstory_show = {
+ textstory_show(self);
+
+ self.think = trigger_textstory_hide;
+ self.nextthink = time + 0.2;
+
+};
+
+void() trigger_textstory_touch = {
+
+ if (!(other.flags & FL_CLIENT)) return;
+ if (self.estate != STATE_ACTIVE) return;
+
+ // don't show message if another player is already triggering it
+ if (other != self.enemy && self.state == 1) return;
+
+ if (self.mangle && !isInAngle(other.v_angle, self.mangle, self.view_ofs))
+ return;
+
+ if (self.attack_finished < time) {
+
+ self.attack_finished = time + 0.1;
+ self.enemy = other;
+
+ trigger_textstory_show();
+ }
+};
+
+void() trigger_textstory = {
+ InitTrigger();
+ self.touch = trigger_textstory_touch;
+
+ if (self.view_ofs == '0 0 0')
+ self.view_ofs = '90 90 0';
+
+ if (self.mangle) self.mangle = normalizeAngles180(self.mangle);
+
+ if (self.noise1 == "")
+ self.noise1 = "misc/talk.wav";
+
+ if (self.noise2 == "")
+ self.noise2 = "misc/null.wav";
+
+ if (self.spawnflags & TEXTSTORY_SILENT) {
+ self.noise1 = "";
+ self.noise2 = "";
+ }
+
+
+ if (self.noise1 != "")
+ precache_sound (self.noise1);
+ if (self.noise2 != "")
+ precache_sound (self.noise2);
+
+ SUB_CheckWaiting();
+};
+
+
+//-----------------------------
+
+
+void() target_textstory_helper_hide = {
+
+ textstory_hide(self.owner);
+ remove(self);
+};
+
+void() target_textstory_helper_show = {
+ if (!self.enemy || !(self.enemy.flags & FL_CLIENT)) {
+ remove(self);
+ return;
+ }
+
+ textstory_show(self.owner);
+
+ if (self.attack_finished < time) self.think = target_textstory_helper_hide;
+
+ self.nextthink = time + 0.1;
+};
+
+void(entity tgt) target_textstory_spawn_helper = {
+ entity e;
+
+ e = spawn();
+ e.classname = "target_textstory_helper";
+ e.owner = self;
+ e.think = target_textstory_helper_show;
+ e.nextthink = time + 0.1;
+ e.attack_finished = time + self.wait;
+ e.enemy = tgt;
+};
+
+void() target_textstory_use = {
+
+ if (!(activator.flags & FL_CLIENT)) return;
+ if (self.estate != STATE_ACTIVE) return;
+
+ entity t;
+
+ if (self.spawnflags & TRIGGER_CENTERPRINTALL) {
+ t = find(world, classname, "player");
+ while (t) {
+ target_textstory_spawn_helper(t);
+ t = find(t, classname, "player");
+ }
+ }
+ else
+ target_textstory_spawn_helper(activator);
+};
+
+void() target_textstory = {
+ if (self.noise1 == "")
+ self.noise1 = "misc/talk.wav";
+
+ if (self.noise2 == "")
+ self.noise2 = "misc/null.wav";
+
+ if (self.spawnflags & TEXTSTORY_SILENT) {
+ self.noise1 = "";
+ self.noise2 = "";
+ }
+
+ if (self.noise1 != "")
+ precache_sound (self.noise1);
+ if (self.noise2 != "")
+ precache_sound (self.noise2);
+
+ if (!self.wait)
+ self.wait = 5;
+
+ self.use = target_textstory_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/misc_model.qc

diff --git a/qc/misc_model.qc b/qc/misc_model.qc
index 833b3dd..0730297 100644
--- a/qc/misc_model.qc
+++ b/qc/misc_model.qc
@@ -1,170 +1,170 @@
-/*
- * misc_model.qc requires math.qc
- *
- * Author: Joshua Skelton joshua.skelton@gmail.com
- * Edited by: Inky 20201219 Minor changes for a better integration with my own code
- * Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
- * Edited by: dumptruck_ds to add start and stop animations
- */
-
-// The starting frame of the animation
-.float first_frame;
-
-// The ending frame of the animation
-.float last_frame;
-
-// Forward declarations
-void() misc_model_think;
-
-/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path" : mdl, "skin" : skin, "frame": frame});
-}
-An entity for displaying models. A frame range can be given to animate the
-model.
-
-mdl: The model to display. Can be of type mdl, bsp, or spr.
-
-frame: The frame to display. Can be used to offset the animation.
-
-first_frame: The starting frame of the animation.
-
-last_frame: The last frame of the animation.
-*/
-
-float MISC_MODEL_GRAVITY = 1;
-float MISC_MODEL_SOLID = 2;
-float MISC_MODEL_BACK_AND_FORTH = 4;
-float MISC_MODEL_ONLY_ONCE = 8;
-float MISC_MODEL_PLAY_COUNT = 16;
-float MISC_MODEL_STARTOFF = 32;
-
-
-void() misc_model_use = {
- if (self.state == STATE_ACTIVE) {
- if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_NOT;
- self.model = "";
-
- self.state = STATE_INVISIBLE;
- setorigin(self, self.origin);
- }
- else {
- if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
- self.model = self.mdl;
-
- self.state = STATE_ACTIVE;
- setorigin(self, self.origin);
- }
-};
-
-void() misc_model = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.mdl || self.mdl == "")
- objerror("Model not defined");
-
- if(!self.centeroffset) self.centeroffset = '0 0 0';
- if(!self.mdlsz) self.mdlsz = '32 32 32';
-
- vector vmin, vmax;
-
- vmin_x = self.centeroffset_x - (self.mdlsz_x / 2);
- vmin_y = self.centeroffset_y - (self.mdlsz_y / 2);
- vmin_z = self.centeroffset_z - (self.mdlsz_z / 2);
-
- vmax_x = self.centeroffset_x + (self.mdlsz_x / 2);
- vmax_y = self.centeroffset_y + (self.mdlsz_y / 2);
- vmax_z = self.centeroffset_z + (self.mdlsz_z / 2);
-
- precache_model(self.mdl);
- setmodel(self, self.mdl);
-
- setsize(self, vmin, vmax);
-
- if(self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
- else self.solid = SOLID_NOT;
-
- if(self.spawnflags & MISC_MODEL_GRAVITY) self.movetype = MOVETYPE_TOSS;
- else self.movetype = MOVETYPE_NONE;
-
- self.use = misc_model_use;
-
- if (!self.frame) {
- self.frame = self.first_frame;
- }
-
- // Make static (not animate) if not given a frame range, and not affected by gravity
- // also remains active if it has a targetname (so it can be killtargeted/toggled)
- if (!self.last_frame
- && !(self.spawnflags & MISC_MODEL_GRAVITY)
- && !(self.spawnflags & MISC_MODEL_SOLID)
- && !self.targetname
- && !self.targetname2
- // && !(self.spawnflags & MISC_MODEL_DONTMAKESTATIC)
- ) makestatic(self);
- // Make static (not animate) if not given a frame range, and not affected by gravity
- //changed by bmFbr
- // if (!self.last_frame && !(self.spawnflags & MISC_MODEL_GRAVITY)) {
- // makestatic(self);
- // return;
- // }
-
- if (self.last_frame) { // if it as a custom animation range
- // Default animation speed to 10 fps
- if (!self.speed) {
- self.speed = 0.1;
- }
- self.nextthink = time + self.speed;
- self.think = misc_model_think;
- }
-
- if (self.spawnflags & MISC_MODEL_STARTOFF)
- self.state = STATE_ACTIVE;
- else
- self.state = STATE_INVISIBLE;
-
- misc_model_use();
-
-};
-
-/*
- * misc_model_think
- *
- * Handles animation for misc_model entity.
- */
-void() misc_model_think = {
- self.nextthink = time + fabs(self.speed);
- if (self.estate != STATE_ACTIVE) return;
-
- self.frame = self.frame + sign(self.speed);
-
- if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame < self.first_frame)
- {
- self.speed = -1 * self.speed;
- self.frame+=2;
- }
- else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame > self.last_frame)
- {
- self.speed = -1 * self.speed;
- self.frame-=2;
- }
- else
- self.frame = wrap(self.frame, self.first_frame, self.last_frame);
-
- if(self.spawnflags & MISC_MODEL_ONLY_ONCE && self.frame==self.last_frame && self.last_frame!=self.first_frame)
- self.nextthink = -1;
-
- if(self.spawnflags & MISC_MODEL_PLAY_COUNT && self.frame==self.last_frame && self.last_frame!=self.first_frame)
- {
- if !(self.count)
- objerror ("Error: set count to the number of animation cycles!");
- self.cnt = self.cnt +1;
- dprint (ftos(self.cnt));
- dprint ("\n");
- if (self.cnt != self.count)
- return FALSE;
- else
- self.nextthink = -1;
- }
-};
+/*
+ * misc_model.qc requires math.qc
+ *
+ * Author: Joshua Skelton joshua.skelton@gmail.com
+ * Edited by: Inky 20201219 Minor changes for a better integration with my own code
+ * Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
+ * Edited by: dumptruck_ds to add start and stop animations
+ */
+
+// The starting frame of the animation
+.float first_frame;
+
+// The ending frame of the animation
+.float last_frame;
+
+// Forward declarations
+void() misc_model_think;
+
+/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path" : mdl, "skin" : skin, "frame": frame});
+}
+An entity for displaying models. A frame range can be given to animate the
+model.
+
+mdl: The model to display. Can be of type mdl, bsp, or spr.
+
+frame: The frame to display. Can be used to offset the animation.
+
+first_frame: The starting frame of the animation.
+
+last_frame: The last frame of the animation.
+*/
+
+float MISC_MODEL_GRAVITY = 1;
+float MISC_MODEL_SOLID = 2;
+float MISC_MODEL_BACK_AND_FORTH = 4;
+float MISC_MODEL_ONLY_ONCE = 8;
+float MISC_MODEL_PLAY_COUNT = 16;
+float MISC_MODEL_STARTOFF = 32;
+
+
+void() misc_model_use = {
+ if (self.state == STATE_ACTIVE) {
+ if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_NOT;
+ self.model = "";
+
+ self.state = STATE_INVISIBLE;
+ setorigin(self, self.origin);
+ }
+ else {
+ if (self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
+ self.model = self.mdl;
+
+ self.state = STATE_ACTIVE;
+ setorigin(self, self.origin);
+ }
+};
+
+void() misc_model = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.mdl || self.mdl == "")
+ objerror("Model not defined");
+
+ if(!self.centeroffset) self.centeroffset = '0 0 0';
+ if(!self.mdlsz) self.mdlsz = '32 32 32';
+
+ vector vmin, vmax;
+
+ vmin_x = self.centeroffset_x - (self.mdlsz_x / 2);
+ vmin_y = self.centeroffset_y - (self.mdlsz_y / 2);
+ vmin_z = self.centeroffset_z - (self.mdlsz_z / 2);
+
+ vmax_x = self.centeroffset_x + (self.mdlsz_x / 2);
+ vmax_y = self.centeroffset_y + (self.mdlsz_y / 2);
+ vmax_z = self.centeroffset_z + (self.mdlsz_z / 2);
+
+ precache_model(self.mdl);
+ setmodel(self, self.mdl);
+
+ setsize(self, vmin, vmax);
+
+ if(self.spawnflags & MISC_MODEL_SOLID) self.solid = SOLID_BBOX;
+ else self.solid = SOLID_NOT;
+
+ if(self.spawnflags & MISC_MODEL_GRAVITY) self.movetype = MOVETYPE_TOSS;
+ else self.movetype = MOVETYPE_NONE;
+
+ self.use = misc_model_use;
+
+ if (!self.frame) {
+ self.frame = self.first_frame;
+ }
+
+ // Make static (not animate) if not given a frame range, and not affected by gravity
+ // also remains active if it has a targetname (so it can be killtargeted/toggled)
+ if (!self.last_frame
+ && !(self.spawnflags & MISC_MODEL_GRAVITY)
+ && !(self.spawnflags & MISC_MODEL_SOLID)
+ && !self.targetname
+ && !self.targetname2
+ // && !(self.spawnflags & MISC_MODEL_DONTMAKESTATIC)
+ ) makestatic(self);
+ // Make static (not animate) if not given a frame range, and not affected by gravity
+ //changed by bmFbr
+ // if (!self.last_frame && !(self.spawnflags & MISC_MODEL_GRAVITY)) {
+ // makestatic(self);
+ // return;
+ // }
+
+ if (self.last_frame) { // if it as a custom animation range
+ // Default animation speed to 10 fps
+ if (!self.speed) {
+ self.speed = 0.1;
+ }
+ self.nextthink = time + self.speed;
+ self.think = misc_model_think;
+ }
+
+ if (self.spawnflags & MISC_MODEL_STARTOFF)
+ self.state = STATE_ACTIVE;
+ else
+ self.state = STATE_INVISIBLE;
+
+ misc_model_use();
+
+};
+
+/*
+ * misc_model_think
+ *
+ * Handles animation for misc_model entity.
+ */
+void() misc_model_think = {
+ self.nextthink = time + fabs(self.speed);
+ if (self.estate != STATE_ACTIVE) return;
+
+ self.frame = self.frame + sign(self.speed);
+
+ if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame < self.first_frame)
+ {
+ self.speed = -1 * self.speed;
+ self.frame+=2;
+ }
+ else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH && self.frame > self.last_frame)
+ {
+ self.speed = -1 * self.speed;
+ self.frame-=2;
+ }
+ else
+ self.frame = wrap(self.frame, self.first_frame, self.last_frame);
+
+ if(self.spawnflags & MISC_MODEL_ONLY_ONCE && self.frame==self.last_frame && self.last_frame!=self.first_frame)
+ self.nextthink = -1;
+
+ if(self.spawnflags & MISC_MODEL_PLAY_COUNT && self.frame==self.last_frame && self.last_frame!=self.first_frame)
+ {
+ if !(self.count)
+ objerror ("Error: set count to the number of animation cycles!");
+ self.cnt = self.cnt +1;
+ dprint (ftos(self.cnt));
+ dprint ("\n");
+ if (self.cnt != self.count)
+ return FALSE;
+ else
+ self.nextthink = -1;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters.qc

diff --git a/qc/monsters.qc b/qc/monsters.qc
index cc045ce..0b9a16a 100644
--- a/qc/monsters.qc
+++ b/qc/monsters.qc
@@ -1,518 +1,518 @@
-/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
-
-// name =[framenum, nexttime, nextthink] {code}
-// expands to:
-// name ()
-// {
-// self.frame=framenum;
-// self.nextthink = time + nexttime;
-// self.think = nextthink
-// <code>
-// };
-
-/*
-================
-monster_update_total
-
-Call this function to safely update total_monsters when the game is in
-progress. It adds "n" to total_monsters, then notifies all clients of
-the change. -- iw
-================
-*/
-void(float n) monster_update_total =
-{
- total_monsters = total_monsters + n;
-
- WriteByte (MSG_ALL, SVC_UPDATESTAT);
- WriteByte (MSG_ALL, STAT_TOTALMONSTERS);
- WriteLong (MSG_ALL, total_monsters);
-};
-
-/* From Preach's tutorial here: https://tomeofpreach.wordpress.com/2017/10/08/teleporting-monsters-flag/#more-2281 */
-
-//define Preach's new fields dumptruck_ds
-
-.string tele_model;
-.vector tele_mins;
-.vector tele_maxs;
-.float tele_solid;
-.float tele_movetype;
-
-void(vector org) spawn_tfog;
-void(vector org, entity death_owner) spawn_tdeath;
-
-void() monster_teleport_go =
-{
-self.solid = self.tele_solid;
-self.movetype = self.tele_movetype;
-setmodel(self, self.tele_model);
-setsize (self, self.tele_mins, self.tele_maxs);
-
-self.delay = 0; //fix for cumulative delays for counters etc. -- dumptruck_ds
-
-self.think1();
-//override the random delay some go functions apply
-self.nextthink = time + 0.1;
- {
- if !(self.spawnflags & SPAWN_SILENTLY)
- {
- if (self.wait == 0) //dumptruck_ds: if wait value is > 0 spawn silently or use a spawnflag
- spawn_tfog (self.origin);
- spawn_tdeath(self.origin, self);
- }
- }
-
-}
-
-void() monster_teleport_delay = //new from Qmaster func coding help thread
-{
-self.think = monster_teleport_go;
- if (self.delay == -1)
- {
- self.nextthink = time + 0.1 + random(); //if delay is set to -1 random delay from 0.1 to 1 second - dumptruck_ds
- return;
- }
-self.nextthink = time + 0.1 + self.delay;
-};
-
-/*
-================
-monster_teleport_check
-
-This detects and eliminates a common map bug: a trigger-spawned monster
-which can't be activated either because it has no targetname or because
-its targetname isn't targeted by any other entity. (This map bug would
-otherwise make it impossible for the player to get 100% kills.) -- iw
-================
-*/
-void() monster_teleport_check =
-{
- if (!SUB_IsTargeted ())
- {
- dprint ("WARNING: removed untargeted trigger-spawned ");
- dprint (self.classname);
- dprint (" at ");
- dprint (vtos (self.origin));
- dprint ("\n");
-
- remove (self);
- return;
- }
-
- // the targetname appears to be OK, so let's finish setting up the
- // trigger-spawned monster -- iw
- self.use = monster_teleport_delay; // qmaster
- monster_update_total (1);
-};
-
-float (void() monster_start_fn) monster_teleport =
-{
-if(!(self.spawnflags & 8))
- return FALSE;
-
-//PREACH: This monster is to be teleported in, so hide it
-self.tele_model= self.model;
-self.tele_mins = self.mins;
-self.tele_maxs = self.maxs;
-self.tele_solid = self.solid;
-self.tele_movetype = self.movetype;
-
-self.model = "";
-self.modelindex = 0;
-self.solid = SOLID_NOT;
-self.movetype = MOVETYPE_NONE;
-self.think1 = monster_start_fn;
-
-// wait for other entities to finish spawning, then check that
-// something targets this -- iw
-self.think = monster_teleport_check;
-self.nextthink = time + 0.1;
-
-return TRUE;
-}
-
-//end of Preach's new fields here
-
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-/*
-================
-by: Philip Martin aka: Kryten
-When on top of monsters or players you slide. This is a QuakeC problem.
-The function below fixes that problem.
-based on code given to Kryten by: Michael Turitzin (MaNiAc)
-================
-*/
-void() monster_touch =
-{
- //can cause problems for monsters on top of a player, so only players
- if (other.classname != "player")
- return;
- if (other.health <= 0)
- return;
-
- if ((!(other.flags & FL_ONGROUND)) && ((other.absmin_z >= self.absmax_z - 2)))
- other.flags = other.flags + FL_ONGROUND;
-
- //you can add other stuff like pushable players/monsters here
-};
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
-
-/*
-================
-monster_use
-
-Using a monster makes it angry at the current activator
-================
-*/
-void() monster_use =
-{
- if (self.enemy)
- return;
- if (self.health <= 0)
- return;
- if (activator.items & IT_INVISIBILITY)
- return;
- if (activator.flags & FL_NOTARGET)
- return;
- if (activator.movetype == MOVETYPE_NOCLIP) // Copper -- dumptruck_ds
- return FALSE;
- if (activator.classname != "player")
- return;
-
-
-// delay reaction so if the monster is teleported, its sound is still
-// heard
- self.enemy = activator;
- self.nextthink = time + 0.1;
- self.think = FoundTarget;
-};
-
-/*
-================
-monster_death_use
-
-When a mosnter dies, it fires all of its targets with the current
-enemy as activator.
-================
-*/
-void() monster_death_use =
-{
-// fall to ground
- if (self.flags & FL_FLY)
- self.flags = self.flags - FL_FLY;
- if (self.flags & FL_SWIM)
- self.flags = self.flags - FL_SWIM;
-
- if (!self.target)
- return;
-
- if(self.infight_activator)
- {
- activator = self.infight_activator;
- }
- else
- {
- activator = self.enemy;
- }
- SUB_UseTargets ();
-};
-
-/*
-================
-monster_pain_use //dumptruck_ds
-
-When a monster reaches pain_threshold, it fires all of its pain_targets
-with the current enemy as activator.
-================
-*/
-void() monster_pain_use =
-{
- if (!self.pain_target)
- return;
-
- activator = self.enemy;
- SUB_UsePain ();
-};
-
-//============================================================================
-
-void() walkmonster_start_go =
-{
- self.origin_z = self.origin_z + 1; // raise off floor a bit
-//Preach's "check" here
-
-// if(time <= 0.5)
-if(!(self.spawnflags & 8))
-{
- droptofloor();
-
- if !(self.spawnflags & I_AM_TURRET) // fixes an incorrect dprint -- dumptruck_ds
- {
- if (!walkmove(0,0))
- {
- dprint ("\n\n");
- dprint (self.classname);
- dprint (" in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n\n");
- }
- }
-}
-
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 20;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- {
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- // if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
- // {
- // monster_use();
- // }
- local entity pl; //dumptruck_ds -- this is Shamblernaut's method
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-};
-
-
-void() walkmonster_start =
-
- //Preach's tutorial
-{
-
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
-
- if(monster_teleport(walkmonster_start_go))
- return;
-
-// delay drop to floor to make sure all doors have been spawned
-// spread think times so they don't all happen at same time
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = walkmonster_start_go;
- total_monsters = total_monsters + 1;
- /// Trigger enemy after spawn (khreathor)
-
-};
-
-
-
-void() flymonster_start_go =
-{
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 25';
- self.use = monster_use;
-
- self.flags = self.flags | FL_FLY;
- self.flags = self.flags | FL_MONSTER;
-
- if (!walkmove(0,0))
- {
- dprint ("flymonster in wall at: ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- if (self.movetarget.classname == "path_corner")
- {
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
- self.nextthink = time + 0.1 + random()*0.5; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
- local entity pl;
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-
-};
-
-void() flymonster_start =
-{
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
-
- //Preach's tutorial
-
- if(monster_teleport(flymonster_start_go))
- return;
-
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_FLY; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = flymonster_start_go;
- total_monsters = total_monsters + 1;
-};
-
-
-void() swimmonster_start_go =
-{
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- self.takedamage = DAMAGE_AIM;
-
- self.ideal_yaw = self.angles * '0 1 0';
- if (!self.yaw_speed)
- self.yaw_speed = 10;
- self.view_ofs = '0 0 10';
- self.use = monster_use;
-
- self.flags = self.flags | FL_SWIM;
- self.flags = self.flags | FL_MONSTER;
-
- if (self.target != "")
- {
- self.goalentity = self.movetarget = find(world, targetname, self.target);
- if (!self.movetarget)
- {
- dprint ("Monster can't find target at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- }
-// this used to be an objerror
- self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
- self.th_walk ();
- }
- else
- {
- self.pausetime = 99999999;
- self.th_stand ();
- }
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
- local entity pl;
-
- pl = find (world, classname, "player");
-
- if (self.spawn_angry == 1)
- {
- activator = pl;
- monster_use();
- }
-};
-
-void() swimmonster_start =
-{
- if (cvar("nomonsters")) {
- remove(self);
- return;
- }
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_SWIM; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
-
- //Preach's tutorial
-
- if(monster_teleport(swimmonster_start_go))
- return;
-
-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
- self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- self.think = swimmonster_start_go;
- total_monsters = total_monsters + 1;
-};
+/* ALL MONSTERS SHOULD BE 1 0 0 IN COLOR */
+
+// name =[framenum, nexttime, nextthink] {code}
+// expands to:
+// name ()
+// {
+// self.frame=framenum;
+// self.nextthink = time + nexttime;
+// self.think = nextthink
+// <code>
+// };
+
+/*
+================
+monster_update_total
+
+Call this function to safely update total_monsters when the game is in
+progress. It adds "n" to total_monsters, then notifies all clients of
+the change. -- iw
+================
+*/
+void(float n) monster_update_total =
+{
+ total_monsters = total_monsters + n;
+
+ WriteByte (MSG_ALL, SVC_UPDATESTAT);
+ WriteByte (MSG_ALL, STAT_TOTALMONSTERS);
+ WriteLong (MSG_ALL, total_monsters);
+};
+
+/* From Preach's tutorial here: https://tomeofpreach.wordpress.com/2017/10/08/teleporting-monsters-flag/#more-2281 */
+
+//define Preach's new fields dumptruck_ds
+
+.string tele_model;
+.vector tele_mins;
+.vector tele_maxs;
+.float tele_solid;
+.float tele_movetype;
+
+void(vector org) spawn_tfog;
+void(vector org, entity death_owner) spawn_tdeath;
+
+void() monster_teleport_go =
+{
+self.solid = self.tele_solid;
+self.movetype = self.tele_movetype;
+setmodel(self, self.tele_model);
+setsize (self, self.tele_mins, self.tele_maxs);
+
+self.delay = 0; //fix for cumulative delays for counters etc. -- dumptruck_ds
+
+self.think1();
+//override the random delay some go functions apply
+self.nextthink = time + 0.1;
+ {
+ if !(self.spawnflags & SPAWN_SILENTLY)
+ {
+ if (self.wait == 0) //dumptruck_ds: if wait value is > 0 spawn silently or use a spawnflag
+ spawn_tfog (self.origin);
+ spawn_tdeath(self.origin, self);
+ }
+ }
+
+}
+
+void() monster_teleport_delay = //new from Qmaster func coding help thread
+{
+self.think = monster_teleport_go;
+ if (self.delay == -1)
+ {
+ self.nextthink = time + 0.1 + random(); //if delay is set to -1 random delay from 0.1 to 1 second - dumptruck_ds
+ return;
+ }
+self.nextthink = time + 0.1 + self.delay;
+};
+
+/*
+================
+monster_teleport_check
+
+This detects and eliminates a common map bug: a trigger-spawned monster
+which can't be activated either because it has no targetname or because
+its targetname isn't targeted by any other entity. (This map bug would
+otherwise make it impossible for the player to get 100% kills.) -- iw
+================
+*/
+void() monster_teleport_check =
+{
+ if (!SUB_IsTargeted ())
+ {
+ dprint ("WARNING: removed untargeted trigger-spawned ");
+ dprint (self.classname);
+ dprint (" at ");
+ dprint (vtos (self.origin));
+ dprint ("\n");
+
+ remove (self);
+ return;
+ }
+
+ // the targetname appears to be OK, so let's finish setting up the
+ // trigger-spawned monster -- iw
+ self.use = monster_teleport_delay; // qmaster
+ monster_update_total (1);
+};
+
+float (void() monster_start_fn) monster_teleport =
+{
+if(!(self.spawnflags & 8))
+ return FALSE;
+
+//PREACH: This monster is to be teleported in, so hide it
+self.tele_model= self.model;
+self.tele_mins = self.mins;
+self.tele_maxs = self.maxs;
+self.tele_solid = self.solid;
+self.tele_movetype = self.movetype;
+
+self.model = "";
+self.modelindex = 0;
+self.solid = SOLID_NOT;
+self.movetype = MOVETYPE_NONE;
+self.think1 = monster_start_fn;
+
+// wait for other entities to finish spawning, then check that
+// something targets this -- iw
+self.think = monster_teleport_check;
+self.nextthink = time + 0.1;
+
+return TRUE;
+}
+
+//end of Preach's new fields here
+
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+/*
+================
+by: Philip Martin aka: Kryten
+When on top of monsters or players you slide. This is a QuakeC problem.
+The function below fixes that problem.
+based on code given to Kryten by: Michael Turitzin (MaNiAc)
+================
+*/
+void() monster_touch =
+{
+ //can cause problems for monsters on top of a player, so only players
+ if (other.classname != "player")
+ return;
+ if (other.health <= 0)
+ return;
+
+ if ((!(other.flags & FL_ONGROUND)) && ((other.absmin_z >= self.absmax_z - 2)))
+ other.flags = other.flags + FL_ONGROUND;
+
+ //you can add other stuff like pushable players/monsters here
+};
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+
+/*
+================
+monster_use
+
+Using a monster makes it angry at the current activator
+================
+*/
+void() monster_use =
+{
+ if (self.enemy)
+ return;
+ if (self.health <= 0)
+ return;
+ if (activator.items & IT_INVISIBILITY)
+ return;
+ if (activator.flags & FL_NOTARGET)
+ return;
+ if (activator.movetype == MOVETYPE_NOCLIP) // Copper -- dumptruck_ds
+ return FALSE;
+ if (activator.classname != "player")
+ return;
+
+
+// delay reaction so if the monster is teleported, its sound is still
+// heard
+ self.enemy = activator;
+ self.nextthink = time + 0.1;
+ self.think = FoundTarget;
+};
+
+/*
+================
+monster_death_use
+
+When a mosnter dies, it fires all of its targets with the current
+enemy as activator.
+================
+*/
+void() monster_death_use =
+{
+// fall to ground
+ if (self.flags & FL_FLY)
+ self.flags = self.flags - FL_FLY;
+ if (self.flags & FL_SWIM)
+ self.flags = self.flags - FL_SWIM;
+
+ if (!self.target)
+ return;
+
+ if(self.infight_activator)
+ {
+ activator = self.infight_activator;
+ }
+ else
+ {
+ activator = self.enemy;
+ }
+ SUB_UseTargets ();
+};
+
+/*
+================
+monster_pain_use //dumptruck_ds
+
+When a monster reaches pain_threshold, it fires all of its pain_targets
+with the current enemy as activator.
+================
+*/
+void() monster_pain_use =
+{
+ if (!self.pain_target)
+ return;
+
+ activator = self.enemy;
+ SUB_UsePain ();
+};
+
+//============================================================================
+
+void() walkmonster_start_go =
+{
+ self.origin_z = self.origin_z + 1; // raise off floor a bit
+//Preach's "check" here
+
+// if(time <= 0.5)
+if(!(self.spawnflags & 8))
+{
+ droptofloor();
+
+ if !(self.spawnflags & I_AM_TURRET) // fixes an incorrect dprint -- dumptruck_ds
+ {
+ if (!walkmove(0,0))
+ {
+ dprint ("\n\n");
+ dprint (self.classname);
+ dprint (" in wall at: ");
+ dprint (vtos(self.origin));
+ dprint ("\n\n");
+ }
+ }
+}
+
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 20;
+ self.view_ofs = '0 0 25';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_MONSTER;
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ if (self.movetarget.classname == "path_corner")
+ {
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+ // {
+ // monster_use();
+ // }
+ local entity pl; //dumptruck_ds -- this is Shamblernaut's method
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+};
+
+
+void() walkmonster_start =
+
+ //Preach's tutorial
+{
+
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+
+ if(monster_teleport(walkmonster_start_go))
+ return;
+
+// delay drop to floor to make sure all doors have been spawned
+// spread think times so they don't all happen at same time
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = walkmonster_start_go;
+ total_monsters = total_monsters + 1;
+ /// Trigger enemy after spawn (khreathor)
+
+};
+
+
+
+void() flymonster_start_go =
+{
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 10;
+ self.view_ofs = '0 0 25';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_FLY;
+ self.flags = self.flags | FL_MONSTER;
+
+ if (!walkmove(0,0))
+ {
+ dprint ("flymonster in wall at: ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ if (self.movetarget.classname == "path_corner")
+ {
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+ self.nextthink = time + 0.1 + random()*0.5; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+// {
+// monster_use();
+// }
+//dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+
+};
+
+void() flymonster_start =
+{
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+
+ //Preach's tutorial
+
+ if(monster_teleport(flymonster_start_go))
+ return;
+
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.flags = self.flags | FL_FLY; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = flymonster_start_go;
+ total_monsters = total_monsters + 1;
+};
+
+
+void() swimmonster_start_go =
+{
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ self.takedamage = DAMAGE_AIM;
+
+ self.ideal_yaw = self.angles * '0 1 0';
+ if (!self.yaw_speed)
+ self.yaw_speed = 10;
+ self.view_ofs = '0 0 10';
+ self.use = monster_use;
+
+ self.flags = self.flags | FL_SWIM;
+ self.flags = self.flags | FL_MONSTER;
+
+ if (self.target != "")
+ {
+ self.goalentity = self.movetarget = find(world, targetname, self.target);
+ if (!self.movetarget)
+ {
+ dprint ("Monster can't find target at ");
+ dprint (vtos(self.origin));
+ dprint ("\n");
+ }
+// this used to be an objerror
+ self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
+ self.th_walk ();
+ }
+ else
+ {
+ self.pausetime = 99999999;
+ self.th_stand ();
+ }
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+// {
+// monster_use();
+// }
+//dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;
+
+ pl = find (world, classname, "player");
+
+ if (self.spawn_angry == 1)
+ {
+ activator = pl;
+ monster_use();
+ }
+};
+
+void() swimmonster_start =
+{
+ if (cvar("nomonsters")) {
+ remove(self);
+ return;
+ }
+ self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+ self.flags = self.flags | FL_SWIM; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+
+ //Preach's tutorial
+
+ if(monster_teleport(swimmonster_start_go))
+ return;
+
+// spread think times so they don't all happen at same time
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+// self.nextthink = self.nextthink + random()*0.5;
+ self.nextthink = time + 0.1 + random()*0.5;
+// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ self.think = swimmonster_start_go;
+ total_monsters = total_monsters + 1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/boss.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/demon.qc

diff --git a/qc/monsters/demon.qc b/qc/monsters/demon.qc
index 4c13b4a..5d338c6 100644
--- a/qc/monsters/demon.qc
+++ b/qc/monsters/demon.qc
@@ -1,502 +1,502 @@
-/*
-==============================================================================
-
-DEMON
-
-==============================================================================
-*/
-
-$cd id1/models/demon3
-$scale 0.8
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-$frame stand10 stand11 stand12 stand13
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-
-$frame run1 run2 run3 run4 run5 run6
-
-$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
-$frame leap11 leap12
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
-$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
-
-//============================================================================
-
-void() Demon_JumpTouch;
-
-void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
-void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
-void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
-void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
-void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
-void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
-void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
-void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
-void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
-void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
-void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
-void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
-void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
-
-void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_walk(8);
-};
-void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
-void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
-void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
-void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
-void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
-void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
-void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
-
-void() demon1_run1 =[ $run1, demon1_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
-ai_run(20);};
-void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
-void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
-void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
-void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
-void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
-
-void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
-void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
-void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
-void() demon1_jump4 =[ $leap4, demon1_jump5 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Demon_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 600 + '0 0 250';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
-void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
-void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
-void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
-void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
-void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
-self.nextthink = time + 3;
-// if three seconds pass, assume demon is stuck and jump again
-};
-
-void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
-void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
-
-
-void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
-void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
-void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
-void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
-void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
-void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
-void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
-void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
-void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
-void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
-void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
-void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
-void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
-void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
-void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
-
-void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
-void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
-void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
-void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
-void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
-void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
-
-void(entity attacker, float damage) demon1_pain =
-{
- if (self.touch == Demon_JumpTouch)
- return;
-
- if (self.pain_finished > time)
- return;
-
- self.pain_finished = time + 1;
- sound_pain (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
-
- if (random()*200 > damage)
- return; // didn't flinch
-
- demon1_pain1 ();
-};
-
-void() demon1_die1 =[ $death1, demon1_die2 ] {
-sound_death (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
-void() demon1_die2 =[ $death2, demon1_die3 ] {};
-void() demon1_die3 =[ $death3, demon1_die4 ] {};
-void() demon1_die4 =[ $death4, demon1_die5 ] {};
-void() demon1_die5 =[ $death5, demon1_die6 ] {};
-void() demon1_die6 =[ $death6, demon1_die7 ]
-{self.solid = SOLID_NOT;};
-void() demon1_die7 =[ $death7, demon1_die8 ] {};
-void() demon1_die8 =[ $death8, demon1_die9 ] {};
-void() demon1_die9 =[ $death9, demon1_die9 ] {};
-
-void() demon_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_demon.mdl", self.health);
- }
- // ThrowHead ("progs/h_demon.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- DropStuff();
- demon1_die1 ();
-};
-
-
-void() Demon_MeleeAttack =
-{
- demon1_atta1 ();
-};
-
-
-/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/demon.mdl");
-}
-Fiend.
-
-Default heath = 300"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : ""Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_hit(string) : "Path to custom hit sound (DEMON SLASHING)"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_demon1 =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/demon.mdl");
- precache_head_model ("progs/h_demon.mdl");
-
- precache_sound_death ("demon/ddeath.wav");
- precache_sound_hit ("demon/dhit2.wav");
- precache_sound_attack ("demon/djump.wav");
- precache_sound_pain ("demon/dpain1.wav");
- precache_sound_idle ("demon/idle1.wav");
- precache_sound_sight ("demon/sight2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- // precache_gib2 ("progs/gib2.mdl");
- // precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/demon.mdl");
- // setmodel (self, "progs/demon.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 300;
-
- self.th_stand = demon1_stand1;
- self.th_walk = demon1_walk1;
- self.th_run = demon1_run1;
- self.th_die = demon_die;
- self.th_melee = Demon_MeleeAttack; // one of two attacks
- self.th_missile = demon1_jump1; // jump attack
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = demon1_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-
-/*
-==============================================================================
-
-DEMON
-
-==============================================================================
-*/
-
-/*
-==============
-CheckDemonMelee
-
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDemonMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- return FALSE;
-};
-
-/*
-==============
-CheckDemonJump
-
-==============
-*/
-float() CheckDemonJump =
-{
- local vector dist;
- local float d;
-
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
- return FALSE;
-
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
-
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
-
- d = vlen(dist);
-
- if (d < 100)
- return FALSE;
-
- if (d > 200)
- {
- if (random() < 0.9)
- return FALSE;
- }
-
- return TRUE;
-};
-
-float() DemonCheckAttack =
-{
-
-// if close enough for slashing, go for it
- if (CheckDemonMelee ())
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
-
- if (CheckDemonJump ())
- {
- self.attack_state = AS_MISSILE;
- sound_attack (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-//===========================================================================
-
-void(float side) Demon_Melee =
-{
- local float ldmg;
- local vector delta;
-
- ai_face ();
- walkmove (self.ideal_yaw, 12); // allow a little closing
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- sound_hit (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
- ldmg = 10 + 5*random();
- T_Damage (self.enemy, self, self, ldmg);
-
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
-};
-
-
-void() Demon_JumpTouch =
-{
- local float ldmg;
-
- if (self.health <= 0)
- return;
-
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 400 )
- {
- if !(self.worldtype)
- {
- ldmg = 40 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
-
- if (!checkbottom(self))
- {
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = demon1_jump11;
- self.nextthink = time + 0.1;
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_demon (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/demon.mdl","frame":53});
-}
-*/
-void() monster_dead_demon =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/demon.mdl");
- setmodel(self, "progs/demon.mdl");
- self.frame = $death9;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-43.63 -47.26 -50.53','32.48 24.65 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
+/*
+==============================================================================
+
+DEMON
+
+==============================================================================
+*/
+
+$cd id1/models/demon3
+$scale 0.8
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+$frame stand10 stand11 stand12 stand13
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+
+$frame run1 run2 run3 run4 run5 run6
+
+$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9 leap10
+$frame leap11 leap12
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame attacka1 attacka2 attacka3 attacka4 attacka5 attacka6 attacka7 attacka8
+$frame attacka9 attacka10 attacka11 attacka12 attacka13 attacka14 attacka15
+
+//============================================================================
+
+void() Demon_JumpTouch;
+
+void() demon1_stand1 =[ $stand1, demon1_stand2 ] {ai_stand();};
+void() demon1_stand2 =[ $stand2, demon1_stand3 ] {ai_stand();};
+void() demon1_stand3 =[ $stand3, demon1_stand4 ] {ai_stand();};
+void() demon1_stand4 =[ $stand4, demon1_stand5 ] {ai_stand();};
+void() demon1_stand5 =[ $stand5, demon1_stand6 ] {ai_stand();};
+void() demon1_stand6 =[ $stand6, demon1_stand7 ] {ai_stand();};
+void() demon1_stand7 =[ $stand7, demon1_stand8 ] {ai_stand();};
+void() demon1_stand8 =[ $stand8, demon1_stand9 ] {ai_stand();};
+void() demon1_stand9 =[ $stand9, demon1_stand10 ] {ai_stand();};
+void() demon1_stand10 =[ $stand10, demon1_stand11 ] {ai_stand();};
+void() demon1_stand11 =[ $stand11, demon1_stand12 ] {ai_stand();};
+void() demon1_stand12 =[ $stand12, demon1_stand13 ] {ai_stand();};
+void() demon1_stand13 =[ $stand13, demon1_stand1 ] {ai_stand();};
+
+void() demon1_walk1 =[ $walk1, demon1_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
+ai_walk(8);
+};
+void() demon1_walk2 =[ $walk2, demon1_walk3 ] {ai_walk(6);};
+void() demon1_walk3 =[ $walk3, demon1_walk4 ] {ai_walk(6);};
+void() demon1_walk4 =[ $walk4, demon1_walk5 ] {ai_walk(7);};
+void() demon1_walk5 =[ $walk5, demon1_walk6 ] {ai_walk(4);};
+void() demon1_walk6 =[ $walk6, demon1_walk7 ] {ai_walk(6);};
+void() demon1_walk7 =[ $walk7, demon1_walk8 ] {ai_walk(10);};
+void() demon1_walk8 =[ $walk8, demon1_walk1 ] {ai_walk(10);};
+
+void() demon1_run1 =[ $run1, demon1_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "demon/idle1.wav", 1, ATTN_IDLE);
+ai_run(20);};
+void() demon1_run2 =[ $run2, demon1_run3 ] {ai_run(15);};
+void() demon1_run3 =[ $run3, demon1_run4 ] {ai_run(36);};
+void() demon1_run4 =[ $run4, demon1_run5 ] {ai_run(20);};
+void() demon1_run5 =[ $run5, demon1_run6 ] {ai_run(15);};
+void() demon1_run6 =[ $run6, demon1_run1 ] {ai_run(36);};
+
+void() demon1_jump1 =[ $leap1, demon1_jump2 ] {ai_face();};
+void() demon1_jump2 =[ $leap2, demon1_jump3 ] {ai_face();};
+void() demon1_jump3 =[ $leap3, demon1_jump4 ] {ai_face();};
+void() demon1_jump4 =[ $leap4, demon1_jump5 ]
+{
+ ai_face();
+ self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
+ self.touch = Demon_JumpTouch;
+ makevectors (self.angles);
+ self.origin_z = self.origin_z + 1;
+ self.velocity = v_forward * 600 + '0 0 250';
+ if (self.flags & FL_ONGROUND)
+ self.flags = self.flags - FL_ONGROUND;
+};
+void() demon1_jump5 =[ $leap5, demon1_jump6 ] {};
+void() demon1_jump6 =[ $leap6, demon1_jump7 ] {};
+void() demon1_jump7 =[ $leap7, demon1_jump8 ] {};
+void() demon1_jump8 =[ $leap8, demon1_jump9 ] {};
+void() demon1_jump9 =[ $leap9, demon1_jump10 ] {};
+void() demon1_jump10 =[ $leap10, demon1_jump1 ] {
+self.nextthink = time + 3;
+// if three seconds pass, assume demon is stuck and jump again
+};
+
+void() demon1_jump11 =[ $leap11, demon1_jump12 ] {};
+void() demon1_jump12 =[ $leap12, demon1_run1 ] {};
+
+
+void() demon1_atta1 =[ $attacka1, demon1_atta2 ] {ai_charge(4);};
+void() demon1_atta2 =[ $attacka2, demon1_atta3 ] {ai_charge(0);};
+void() demon1_atta3 =[ $attacka3, demon1_atta4 ] {ai_charge(0);};
+void() demon1_atta4 =[ $attacka4, demon1_atta5 ] {ai_charge(1);};
+void() demon1_atta5 =[ $attacka5, demon1_atta6 ] {ai_charge(2); Demon_Melee(200);};
+void() demon1_atta6 =[ $attacka6, demon1_atta7 ] {ai_charge(1);};
+void() demon1_atta7 =[ $attacka7, demon1_atta8 ] {ai_charge(6);};
+void() demon1_atta8 =[ $attacka8, demon1_atta9 ] {ai_charge(8);};
+void() demon1_atta9 =[ $attacka9, demon1_atta10] {ai_charge(4);};
+void() demon1_atta10 =[ $attacka10, demon1_atta11] {ai_charge(2);};
+void() demon1_atta11 =[ $attacka11, demon1_atta12] {Demon_Melee(-200);};
+void() demon1_atta12 =[ $attacka12, demon1_atta13] {ai_charge(5);};
+void() demon1_atta13 =[ $attacka13, demon1_atta14] {ai_charge(8);};
+void() demon1_atta14 =[ $attacka14, demon1_atta15] {ai_charge(4);};
+void() demon1_atta15 =[ $attacka15, demon1_run1] {ai_charge(4);};
+
+void() demon1_pain1 =[ $pain1, demon1_pain2 ] {};
+void() demon1_pain2 =[ $pain2, demon1_pain3 ] {};
+void() demon1_pain3 =[ $pain3, demon1_pain4 ] {};
+void() demon1_pain4 =[ $pain4, demon1_pain5 ] {};
+void() demon1_pain5 =[ $pain5, demon1_pain6 ] {};
+void() demon1_pain6 =[ $pain6, demon1_run1 ] {};
+
+void(entity attacker, float damage) demon1_pain =
+{
+ if (self.touch == Demon_JumpTouch)
+ return;
+
+ if (self.pain_finished > time)
+ return;
+
+ self.pain_finished = time + 1;
+ sound_pain (self, CHAN_VOICE, "demon/dpain1.wav", 1, ATTN_NORM);
+
+ if (random()*200 > damage)
+ return; // didn't flinch
+
+ demon1_pain1 ();
+};
+
+void() demon1_die1 =[ $death1, demon1_die2 ] {
+sound_death (self, CHAN_VOICE, "demon/ddeath.wav", 1, ATTN_NORM);};
+void() demon1_die2 =[ $death2, demon1_die3 ] {};
+void() demon1_die3 =[ $death3, demon1_die4 ] {};
+void() demon1_die4 =[ $death4, demon1_die5 ] {};
+void() demon1_die5 =[ $death5, demon1_die6 ] {};
+void() demon1_die6 =[ $death6, demon1_die7 ]
+{self.solid = SOLID_NOT;};
+void() demon1_die7 =[ $death7, demon1_die8 ] {};
+void() demon1_die8 =[ $death8, demon1_die9 ] {};
+void() demon1_die9 =[ $death9, demon1_die9 ] {};
+
+void() demon_die =
+{
+// check for gib
+ if (self.health < -80)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_demon.mdl", self.health);
+ }
+ // ThrowHead ("progs/h_demon.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ DropStuff();
+ demon1_die1 ();
+};
+
+
+void() Demon_MeleeAttack =
+{
+ demon1_atta1 ();
+};
+
+
+/*QUAKED monster_demon1 (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/demon.mdl");
+}
+Fiend.
+
+Default heath = 300"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : ""Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_hit(string) : "Path to custom hit sound (DEMON SLASHING)"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_demon1 =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model ("progs/demon.mdl");
+ precache_head_model ("progs/h_demon.mdl");
+
+ precache_sound_death ("demon/ddeath.wav");
+ precache_sound_hit ("demon/dhit2.wav");
+ precache_sound_attack ("demon/djump.wav");
+ precache_sound_pain ("demon/dpain1.wav");
+ precache_sound_idle ("demon/idle1.wav");
+ precache_sound_sight ("demon/sight2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ // precache_gib2 ("progs/gib2.mdl");
+ // precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/demon.mdl");
+ // setmodel (self, "progs/demon.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 300;
+
+ self.th_stand = demon1_stand1;
+ self.th_walk = demon1_walk1;
+ self.th_run = demon1_run1;
+ self.th_die = demon_die;
+ self.th_melee = Demon_MeleeAttack; // one of two attacks
+ self.th_missile = demon1_jump1; // jump attack
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = demon1_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+
+/*
+==============================================================================
+
+DEMON
+
+==============================================================================
+*/
+
+/*
+==============
+CheckDemonMelee
+
+Returns TRUE if a melee attack would hit right now
+==============
+*/
+float() CheckDemonMelee =
+{
+ if (enemy_range == RANGE_MELEE)
+ { // FIXME: check canreach
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+};
+
+/*
+==============
+CheckDemonJump
+
+==============
+*/
+float() CheckDemonJump =
+{
+ local vector dist;
+ local float d;
+
+ if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ + 0.75 * self.enemy.size_z)
+ return FALSE;
+
+ if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ + 0.25 * self.enemy.size_z)
+ return FALSE;
+
+ dist = self.enemy.origin - self.origin;
+ dist_z = 0;
+
+ d = vlen(dist);
+
+ if (d < 100)
+ return FALSE;
+
+ if (d > 200)
+ {
+ if (random() < 0.9)
+ return FALSE;
+ }
+
+ return TRUE;
+};
+
+float() DemonCheckAttack =
+{
+
+// if close enough for slashing, go for it
+ if (CheckDemonMelee ())
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+
+ if (CheckDemonJump ())
+ {
+ self.attack_state = AS_MISSILE;
+ sound_attack (self, CHAN_VOICE, "demon/djump.wav", 1, ATTN_NORM);
+ return TRUE;
+ }
+
+ return FALSE;
+};
+
+
+//===========================================================================
+
+void(float side) Demon_Melee =
+{
+ local float ldmg;
+ local vector delta;
+
+ ai_face ();
+ walkmove (self.ideal_yaw, 12); // allow a little closing
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ sound_hit (self, CHAN_WEAPON, "demon/dhit2.wav", 1, ATTN_NORM);
+ ldmg = 10 + 5*random();
+ T_Damage (self.enemy, self, self, ldmg);
+
+ makevectors (self.angles);
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+};
+
+
+void() Demon_JumpTouch =
+{
+ local float ldmg;
+
+ if (self.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if ( vlen(self.velocity) > 400 )
+ {
+ if !(self.worldtype)
+ {
+ ldmg = 40 + 10*random();
+ T_Damage (other, self, self, ldmg);
+ if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
+ self.worldtype = 1;
+ }
+ }
+ }
+
+ if (!checkbottom(self))
+ {
+ if (self.flags & FL_ONGROUND)
+ { // jump randomly to not get hung up
+//dprint ("popjump\n");
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+// self.touch = SUB_Null;
+ self.touch = monster_touch;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = demon1_jump1;
+ self.nextthink = time + 0.1;
+
+// self.velocity_x = (random() - 0.5) * 600;
+// self.velocity_y = (random() - 0.5) * 600;
+// self.velocity_z = 200;
+// self.flags = self.flags - FL_ONGROUND;
+ }
+ return; // not on ground yet
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+ // self.touch = SUB_Null;
+ self.touch = monster_touch;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = demon1_jump11;
+ self.nextthink = time + 0.1;
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_demon (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/demon.mdl","frame":53});
+}
+*/
+void() monster_dead_demon =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/demon.mdl");
+ setmodel(self, "progs/demon.mdl");
+ self.frame = $death9;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-43.63 -47.26 -50.53','32.48 24.65 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/dog.qc

diff --git a/qc/monsters/dog.qc b/qc/monsters/dog.qc
index 6da85bb..2ded26e 100644
--- a/qc/monsters/dog.qc
+++ b/qc/monsters/dog.qc
@@ -1,503 +1,503 @@
-/*
-==============================================================================
-
-DOG
-
-==============================================================================
-*/
-$cd id1/models/dog
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14 painb15 painb16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
-
-$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
-
-
-void() dog_leap1;
-void() dog_run1;
-
-/*
-================
-dog_bite
-
-================
-*/
-void() dog_bite =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
-
- ai_charge(10);
-
- if (!CanDamage (self.enemy, self))
- return;
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 8;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() Dog_JumpTouch =
-{
- local float ldmg;
-
- if (self.health <= 0)
- return;
-
- if (other.takedamage)
- {
- if ( vlen(self.velocity) > 300 )
- {
- if !(self.worldtype)
- {
- ldmg = 10 + 10*random();
- T_Damage (other, self, self, ldmg);
- if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
- self.worldtype = 1;
- }
- }
- }
-
- if (!checkbottom(self))
- {
- if (self.flags & FL_ONGROUND)
- { // jump randomly to not get hung up
-//dprint ("popjump\n");
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
- self.touch = monster_touch;
-// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_leap1;
- self.nextthink = time + 0.1;
-
-// self.velocity_x = (random() - 0.5) * 600;
-// self.velocity_y = (random() - 0.5) * 600;
-// self.velocity_z = 200;
-// self.flags = self.flags - FL_ONGROUND;
- }
- return; // not on ground yet
- }
-
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
- self.touch = monster_touch;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
- self.think = dog_run1;
- self.nextthink = time + 0.1;
-};
-
-
-void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
-void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
-void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
-void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
-void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
-void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
-void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
-void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
-void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
-
-void() dog_walk1 =[ $walk1 , dog_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(8);};
-void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
-void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
-void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
-void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
-void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
-void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
-void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
-
-void() dog_run1 =[ $run1 , dog_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(16);};
-void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
-void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
-void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
-void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
-void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
-void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
-void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
-void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
-void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
-void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
-void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
-
-void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
-void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
-void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
-void() dog_atta4 =[ $attack4, dog_atta5 ] {
-sound_attack (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); //dumptruck_ds
-dog_bite();};
-void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
-void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
-void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
-void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
-
-void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
-void() dog_leap2 =[ $leap2, dog_leap3 ]
-{
- ai_face();
- self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
- self.touch = Dog_JumpTouch;
- makevectors (self.angles);
- self.origin_z = self.origin_z + 1;
- self.velocity = v_forward * 300 + '0 0 200';
- if (self.flags & FL_ONGROUND)
- self.flags = self.flags - FL_ONGROUND;
-};
-
-void() dog_leap3 =[ $leap3, dog_leap4 ] {};
-void() dog_leap4 =[ $leap4, dog_leap5 ] {};
-void() dog_leap5 =[ $leap5, dog_leap6 ] {};
-void() dog_leap6 =[ $leap6, dog_leap7 ] {};
-void() dog_leap7 =[ $leap7, dog_leap8 ] {};
-void() dog_leap8 =[ $leap8, dog_leap9 ] {};
-void() dog_leap9 =[ $leap9, dog_leap9 ] {};
-
-void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
-void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
-void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
-void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
-void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
-void() dog_pain6 =[ $pain6 , dog_run1 ] {};
-
-void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
-void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
-void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
-void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
-void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
-void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
-void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
-void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
-void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
-void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
-void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
-void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
-void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
-void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
-void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
-void() dog_painb16 =[ $painb16 , dog_run1 ] {};
-
-void(entity attacker, float damage) dog_pain =
-{
- sound_pain (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); //dumptruck_ds
-
- if (random() > 0.5)
- dog_pain1 ();
- else
- dog_painb1 ();
-};
-
-void() dog_die1 =[ $death1, dog_die2 ] {};
-void() dog_die2 =[ $death2, dog_die3 ] {};
-void() dog_die3 =[ $death3, dog_die4 ] {};
-void() dog_die4 =[ $death4, dog_die5 ] {};
-void() dog_die5 =[ $death5, dog_die6 ] {};
-void() dog_die6 =[ $death6, dog_die7 ] {};
-void() dog_die7 =[ $death7, dog_die8 ] {};
-void() dog_die8 =[ $death8, dog_die9 ] {};
-void() dog_die9 =[ $death9, dog_die9 ] {};
-
-void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
-void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
-void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
-void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
-void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
-void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
-void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
-void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
-void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
-
-
-void() dog_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); //dumptruck_ds
- self.solid = SOLID_NOT;
-
- DropStuff();
-
- if (random() > 0.5)
- dog_die1 ();
- else
- dog_dieb1 ();
-};
-
-//============================================================================
-
-/*
-==============
-CheckDogMelee
-
-Returns TRUE if a melee attack would hit right now
-==============
-*/
-float() CheckDogMelee =
-{
- if (enemy_range == RANGE_MELEE)
- { // FIXME: check canreach
- self.attack_state = AS_MELEE;
- return TRUE;
- }
- return FALSE;
-};
-
-/*
-==============
-CheckDogJump
-
-==============
-*/
-float() CheckDogJump =
-{
- local vector dist;
- local float d;
-
- if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
- + 0.75 * self.enemy.size_z)
- return FALSE;
-
- if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
- + 0.25 * self.enemy.size_z)
- return FALSE;
-
- dist = self.enemy.origin - self.origin;
- dist_z = 0;
-
- d = vlen(dist);
-
- if (d < 80)
- return FALSE;
-
- if (d > 150)
- return FALSE;
-
- return TRUE;
-};
-
-float() DogCheckAttack =
-{
-
-// if close enough for slashing, go for it
- if (CheckDogMelee ())
- {
- self.attack_state = AS_MELEE;
- return TRUE;
- }
-
- if (CheckDogJump ())
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- return FALSE;
-};
-
-
-//===========================================================================
-
-/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/dog.mdl");
-}
-Rottweiler.
-
-Default health = 25
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds -- model_custom and sounds changes
- precache_head_model ("progs/h_dog.mdl");
- precache_body_model ("progs/dog.mdl");
- precache_sound_attack ("dog/dattack1.wav");
- precache_sound_death ("dog/ddeath.wav");
- precache_sound_pain ("dog/dpain1.wav");
- precache_sound_sight ("dog/dsight.wav");
- precache_sound_idle ("dog/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- // dumptruck_ds
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/dog.mdl"); //dumptruck_ds
- // setmodel (self, "progs/dog.mdl");
-
- setsize (self, '-32 -32 -24', '32 32 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
-
- self.th_stand = dog_stand1;
- self.th_walk = dog_walk1;
- self.th_run = dog_run1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = dog_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = dog_die;
- self.th_melee = dog_atta1;
- self.th_missile = dog_leap1;
-
- walkmonster_start();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_dog (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/dog.mdl","frame":16});
-}
-*/
-void() monster_dead_dog =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/dog.mdl");
- setmodel(self, "progs/dog.mdl");
- self.frame = $death8;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-24.51 -16.5 -50.37','28.2 13.81 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
+/*
+==============================================================================
+
+DOG
+
+==============================================================================
+*/
+$cd id1/models/dog
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8 death9
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14 painb15 painb16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
+
+$frame leap1 leap2 leap3 leap4 leap5 leap6 leap7 leap8 leap9
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8
+
+
+void() dog_leap1;
+void() dog_run1;
+
+/*
+================
+dog_bite
+
+================
+*/
+void() dog_bite =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+
+ ai_charge(10);
+
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 8;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+void() Dog_JumpTouch =
+{
+ local float ldmg;
+
+ if (self.health <= 0)
+ return;
+
+ if (other.takedamage)
+ {
+ if ( vlen(self.velocity) > 300 )
+ {
+ if !(self.worldtype)
+ {
+ ldmg = 10 + 10*random();
+ T_Damage (other, self, self, ldmg);
+ if (other.health > 0) // is the player still alive? Preach's instakill bug check - dumptruck_ds
+ self.worldtype = 1;
+ }
+ }
+ }
+
+ if (!checkbottom(self))
+ {
+ if (self.flags & FL_ONGROUND)
+ { // jump randomly to not get hung up
+//dprint ("popjump\n");
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+// self.touch = SUB_Null;
+ self.touch = monster_touch;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = dog_leap1;
+ self.nextthink = time + 0.1;
+
+// self.velocity_x = (random() - 0.5) * 600;
+// self.velocity_y = (random() - 0.5) * 600;
+// self.velocity_z = 200;
+// self.flags = self.flags - FL_ONGROUND;
+ }
+ return; // not on ground yet
+ }
+
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
+ // self.touch = SUB_Null;
+ self.touch = monster_touch;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
+ self.think = dog_run1;
+ self.nextthink = time + 0.1;
+};
+
+
+void() dog_stand1 =[ $stand1, dog_stand2 ] {ai_stand();};
+void() dog_stand2 =[ $stand2, dog_stand3 ] {ai_stand();};
+void() dog_stand3 =[ $stand3, dog_stand4 ] {ai_stand();};
+void() dog_stand4 =[ $stand4, dog_stand5 ] {ai_stand();};
+void() dog_stand5 =[ $stand5, dog_stand6 ] {ai_stand();};
+void() dog_stand6 =[ $stand6, dog_stand7 ] {ai_stand();};
+void() dog_stand7 =[ $stand7, dog_stand8 ] {ai_stand();};
+void() dog_stand8 =[ $stand8, dog_stand9 ] {ai_stand();};
+void() dog_stand9 =[ $stand9, dog_stand1 ] {ai_stand();};
+
+void() dog_walk1 =[ $walk1 , dog_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_walk(8);};
+void() dog_walk2 =[ $walk2 , dog_walk3 ] {ai_walk(8);};
+void() dog_walk3 =[ $walk3 , dog_walk4 ] {ai_walk(8);};
+void() dog_walk4 =[ $walk4 , dog_walk5 ] {ai_walk(8);};
+void() dog_walk5 =[ $walk5 , dog_walk6 ] {ai_walk(8);};
+void() dog_walk6 =[ $walk6 , dog_walk7 ] {ai_walk(8);};
+void() dog_walk7 =[ $walk7 , dog_walk8 ] {ai_walk(8);};
+void() dog_walk8 =[ $walk8 , dog_walk1 ] {ai_walk(8);};
+
+void() dog_run1 =[ $run1 , dog_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "dog/idle.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_run(16);};
+void() dog_run2 =[ $run2 , dog_run3 ] {ai_run(32);};
+void() dog_run3 =[ $run3 , dog_run4 ] {ai_run(32);};
+void() dog_run4 =[ $run4 , dog_run5 ] {ai_run(20);};
+void() dog_run5 =[ $run5 , dog_run6 ] {ai_run(64);};
+void() dog_run6 =[ $run6 , dog_run7 ] {ai_run(32);};
+void() dog_run7 =[ $run7 , dog_run8 ] {ai_run(16);};
+void() dog_run8 =[ $run8 , dog_run9 ] {ai_run(32);};
+void() dog_run9 =[ $run9 , dog_run10 ] {ai_run(32);};
+void() dog_run10 =[ $run10 , dog_run11 ] {ai_run(20);};
+void() dog_run11 =[ $run11 , dog_run12 ] {ai_run(64);};
+void() dog_run12 =[ $run12 , dog_run1 ] {ai_run(32);};
+
+void() dog_atta1 =[ $attack1, dog_atta2 ] {ai_charge(10);};
+void() dog_atta2 =[ $attack2, dog_atta3 ] {ai_charge(10);};
+void() dog_atta3 =[ $attack3, dog_atta4 ] {ai_charge(10);};
+void() dog_atta4 =[ $attack4, dog_atta5 ] {
+sound_attack (self, CHAN_VOICE, "dog/dattack1.wav", 1, ATTN_NORM); //dumptruck_ds
+dog_bite();};
+void() dog_atta5 =[ $attack5, dog_atta6 ] {ai_charge(10);};
+void() dog_atta6 =[ $attack6, dog_atta7 ] {ai_charge(10);};
+void() dog_atta7 =[ $attack7, dog_atta8 ] {ai_charge(10);};
+void() dog_atta8 =[ $attack8, dog_run1 ] {ai_charge(10);};
+
+void() dog_leap1 =[ $leap1, dog_leap2 ] {ai_face();};
+void() dog_leap2 =[ $leap2, dog_leap3 ]
+{
+ ai_face();
+ self.worldtype = 0; //fix for instakill bug -- dumptruck_ds
+ self.touch = Dog_JumpTouch;
+ makevectors (self.angles);
+ self.origin_z = self.origin_z + 1;
+ self.velocity = v_forward * 300 + '0 0 200';
+ if (self.flags & FL_ONGROUND)
+ self.flags = self.flags - FL_ONGROUND;
+};
+
+void() dog_leap3 =[ $leap3, dog_leap4 ] {};
+void() dog_leap4 =[ $leap4, dog_leap5 ] {};
+void() dog_leap5 =[ $leap5, dog_leap6 ] {};
+void() dog_leap6 =[ $leap6, dog_leap7 ] {};
+void() dog_leap7 =[ $leap7, dog_leap8 ] {};
+void() dog_leap8 =[ $leap8, dog_leap9 ] {};
+void() dog_leap9 =[ $leap9, dog_leap9 ] {};
+
+void() dog_pain1 =[ $pain1 , dog_pain2 ] {};
+void() dog_pain2 =[ $pain2 , dog_pain3 ] {};
+void() dog_pain3 =[ $pain3 , dog_pain4 ] {};
+void() dog_pain4 =[ $pain4 , dog_pain5 ] {};
+void() dog_pain5 =[ $pain5 , dog_pain6 ] {};
+void() dog_pain6 =[ $pain6 , dog_run1 ] {};
+
+void() dog_painb1 =[ $painb1 , dog_painb2 ] {};
+void() dog_painb2 =[ $painb2 , dog_painb3 ] {};
+void() dog_painb3 =[ $painb3 , dog_painb4 ] {ai_pain(4);};
+void() dog_painb4 =[ $painb4 , dog_painb5 ] {ai_pain(12);};
+void() dog_painb5 =[ $painb5 , dog_painb6 ] {ai_pain(12);};
+void() dog_painb6 =[ $painb6 , dog_painb7 ] {ai_pain(2);};
+void() dog_painb7 =[ $painb7 , dog_painb8 ] {};
+void() dog_painb8 =[ $painb8 , dog_painb9 ] {ai_pain(4);};
+void() dog_painb9 =[ $painb9 , dog_painb10 ] {};
+void() dog_painb10 =[ $painb10 , dog_painb11 ] {ai_pain(10);};
+void() dog_painb11 =[ $painb11 , dog_painb12 ] {};
+void() dog_painb12 =[ $painb12 , dog_painb13 ] {};
+void() dog_painb13 =[ $painb13 , dog_painb14 ] {};
+void() dog_painb14 =[ $painb14 , dog_painb15 ] {};
+void() dog_painb15 =[ $painb15 , dog_painb16 ] {};
+void() dog_painb16 =[ $painb16 , dog_run1 ] {};
+
+void(entity attacker, float damage) dog_pain =
+{
+ sound_pain (self, CHAN_VOICE, "dog/dpain1.wav", 1, ATTN_NORM); //dumptruck_ds
+
+ if (random() > 0.5)
+ dog_pain1 ();
+ else
+ dog_painb1 ();
+};
+
+void() dog_die1 =[ $death1, dog_die2 ] {};
+void() dog_die2 =[ $death2, dog_die3 ] {};
+void() dog_die3 =[ $death3, dog_die4 ] {};
+void() dog_die4 =[ $death4, dog_die5 ] {};
+void() dog_die5 =[ $death5, dog_die6 ] {};
+void() dog_die6 =[ $death6, dog_die7 ] {};
+void() dog_die7 =[ $death7, dog_die8 ] {};
+void() dog_die8 =[ $death8, dog_die9 ] {};
+void() dog_die9 =[ $death9, dog_die9 ] {};
+
+void() dog_dieb1 =[ $deathb1, dog_dieb2 ] {};
+void() dog_dieb2 =[ $deathb2, dog_dieb3 ] {};
+void() dog_dieb3 =[ $deathb3, dog_dieb4 ] {};
+void() dog_dieb4 =[ $deathb4, dog_dieb5 ] {};
+void() dog_dieb5 =[ $deathb5, dog_dieb6 ] {};
+void() dog_dieb6 =[ $deathb6, dog_dieb7 ] {};
+void() dog_dieb7 =[ $deathb7, dog_dieb8 ] {};
+void() dog_dieb8 =[ $deathb8, dog_dieb9 ] {};
+void() dog_dieb9 =[ $deathb9, dog_dieb9 ] {};
+
+
+void() dog_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "dog/ddeath.wav", 1, ATTN_NORM); //dumptruck_ds
+ self.solid = SOLID_NOT;
+
+ DropStuff();
+
+ if (random() > 0.5)
+ dog_die1 ();
+ else
+ dog_dieb1 ();
+};
+
+//============================================================================
+
+/*
+==============
+CheckDogMelee
+
+Returns TRUE if a melee attack would hit right now
+==============
+*/
+float() CheckDogMelee =
+{
+ if (enemy_range == RANGE_MELEE)
+ { // FIXME: check canreach
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+ return FALSE;
+};
+
+/*
+==============
+CheckDogJump
+
+==============
+*/
+float() CheckDogJump =
+{
+ local vector dist;
+ local float d;
+
+ if (self.origin_z + self.mins_z > self.enemy.origin_z + self.enemy.mins_z
+ + 0.75 * self.enemy.size_z)
+ return FALSE;
+
+ if (self.origin_z + self.maxs_z < self.enemy.origin_z + self.enemy.mins_z
+ + 0.25 * self.enemy.size_z)
+ return FALSE;
+
+ dist = self.enemy.origin - self.origin;
+ dist_z = 0;
+
+ d = vlen(dist);
+
+ if (d < 80)
+ return FALSE;
+
+ if (d > 150)
+ return FALSE;
+
+ return TRUE;
+};
+
+float() DogCheckAttack =
+{
+
+// if close enough for slashing, go for it
+ if (CheckDogMelee ())
+ {
+ self.attack_state = AS_MELEE;
+ return TRUE;
+ }
+
+ if (CheckDogJump ())
+ {
+ self.attack_state = AS_MISSILE;
+ return TRUE;
+ }
+
+ return FALSE;
+};
+
+
+//===========================================================================
+
+/*QUAKED monster_dog (1 0 0) (-32 -32 -24) (32 32 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/dog.mdl");
+}
+Rottweiler.
+
+Default health = 25
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds -- model_custom and sounds changes
+ precache_head_model ("progs/h_dog.mdl");
+ precache_body_model ("progs/dog.mdl");
+ precache_sound_attack ("dog/dattack1.wav");
+ precache_sound_death ("dog/ddeath.wav");
+ precache_sound_pain ("dog/dpain1.wav");
+ precache_sound_sight ("dog/dsight.wav");
+ precache_sound_idle ("dog/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ // dumptruck_ds
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/dog.mdl"); //dumptruck_ds
+ // setmodel (self, "progs/dog.mdl");
+
+ setsize (self, '-32 -32 -24', '32 32 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 25;
+
+ self.th_stand = dog_stand1;
+ self.th_walk = dog_walk1;
+ self.th_run = dog_run1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = dog_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = dog_die;
+ self.th_melee = dog_atta1;
+ self.th_missile = dog_leap1;
+
+ walkmonster_start();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_dog (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/dog.mdl","frame":16});
+}
+*/
+void() monster_dead_dog =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/dog.mdl");
+ setmodel(self, "progs/dog.mdl");
+ self.frame = $death8;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-24.51 -16.5 -50.37','28.2 13.81 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/enforcer.qc

diff --git a/qc/monsters/enforcer.qc b/qc/monsters/enforcer.qc
index 2b4b594..5460d7b 100644
--- a/qc/monsters/enforcer.qc
+++ b/qc/monsters/enforcer.qc
@@ -1,1044 +1,1044 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
-
-$cd id1/models/enforcer
-$origin 0 -6 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
-$frame walk11 walk12 walk13 walk14 walk15 walk16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6
-$frame attack7 attack8 attack9 attack10
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10 death11 death12 death13 death14
-
-$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
-$frame fdeath9 fdeath10 fdeath11
-
-$frame paina1 paina2 paina3 paina4
-
-$frame painb1 painb2 painb3 painb4 painb5
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
-$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
-$frame paind17 paind18 paind19
-
-
-void() Laser_Touch =
-{
- local vector org;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); //dumptruck_ds
- org = self.origin - 8*normalize(self.velocity);
-
- if (other.health)
- {
- SpawnBlood (org, self.velocity*0.2, 15);
- T_Damage (other, self, self.owner, 15);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-
- remove(self);
-};
-
-void(vector org, vector vec) LaunchLaser =
-{
-
- local float projspeed = self.proj_speed_mod * 600;
-
- if (self.classname == "monster_enforcer" || self.classname == "monster_army")
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
-
- vec = normalize(vec);
-
- newmis = spawn();
- newmis.snd_hit = self.snd_hit; // dumptruck_ds
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLY;
- newmis.solid = SOLID_BBOX;
- newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/laser.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // setmodel (newmis, "progs/laser.mdl");
- setsize (newmis, '0 0 0', '0 0 0');
-
- setorigin (newmis, org);
-
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
- if (self.homing > 0)
- {
- SetupHoming(newmis, projspeed);
- }
- else
- {
- newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
- }
- newmis.touch = Laser_Touch;
-};
-
-void(vector org, vector vec) EnfLaunchSpike =
-{
-
- local float projspeed = self.proj_speed_mod * 600;
-
- sound_attack (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
-
- vec = normalize(vec);
-
- newmis = spawn();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLY;
- newmis.solid = SOLID_BBOX;
- // newmis.effects = EF_DIMLIGHT;
- newmis.skin = self.skin_proj; //dumptruck_ds
- // setmodel (newmis, "progs/s_spike.mdl");
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
-// dumptruck_ds - end
- setsize (newmis, '0 0 0', '0 0 0');
-
- setorigin (newmis, org);
-
- SetSpeed(newmis, vec, projspeed);
- newmis.angles = vectoangles(newmis.velocity);
-
- if (self.homing > 0)
- {
- SetupHoming(newmis, projspeed);
- }
- else
- {
- newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
- }
- newmis.touch = superspike_touch;
-};
-
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
-void() EnfMisTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = 30 + random()*2; //dumptruck_ds
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, 40, other); //dumptruck_ds
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-/*
-================
-EnfRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
-void() EnfRocket =
-{
- local entity missile;
- local float projspeed = 900 * self.proj_speed_mod;
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = EnfMisTouch;
-
- // makevectors (self.v_angle);
- // missile.velocity = aim(self, 1000);
- // missile.velocity = missile.velocity * 1000;
- // missile.angles = vectoangles(missile.velocity);
-
- // missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, projspeed);
- }
- else
- {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
- // setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 12'); //last number was 16 - dumptruck_ds
- // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-//end dumptruck_ds grunt missle end
-/*
-================
-EnfFireGrenade
-================
-*/
-void() EnfFireGrenade =
-{
- local entity missile;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-
- // setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16');
- // setorigin (missile, self.origin);
-};
-
-void() EnfLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 4);
-};
-
-
-// style stuff -- dumptruck_ds
-void() enforcer_fire =
-{
-
-if (self.style == 1)
-
- {
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
-
- EnfRocket();
- return;
- }
-
-else if (self.style == 2)
-
- {
- self.effects = self.effects | EF_MUZZLEFLASH;
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
- {
- PreachFireGrenade(self.attack_elevation);
- }
- else
- EnfFireGrenade();
- return;
- }
-
-else if (self.style == 3 || self.style ==5)
-
- {
- local vector foo;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- foo = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- EnfLaunchSpike(foo, self.enemy.origin - self.origin);
- return;
- }
-
-else
-
- local vector org;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
-};
-
-//============================================================================
-
-void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
-void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
-void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
-void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
-void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
-void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
-void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
-
-void() enf_walk1 =[ $walk1 , enf_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_walk(2);};
-void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
-void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
-void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
-void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
-void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
-void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
-void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
-void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
-void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
-void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
-void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
-void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
-void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
-void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
-void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
-
-void() enf_run1 =[ $run1 , enf_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
-ai_run(18);};
-void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
-void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
-void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
-void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
-void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
-void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
-void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
-
-void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
-void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
-void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
-void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
-void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
-void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
-void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
-void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
-void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
-void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
-void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
-void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
-void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
-void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_atk1);
-};
-/* modified animation frames for style Enforcers */ // dumptruck_ds
-void() enf_2atk7;
-void() enf_2atk1 =[ $attack1, enf_2atk2 ] {ai_face();self.count = 0;self.t_length= 8 + floor(random()*6);};
-void() enf_2atk2 =[ $attack2, enf_2atk3 ] {ai_face();};
-void() enf_2atk3 =[ $attack3, enf_2atk4 ] {ai_face();};
-void() enf_2atk4 =[ $attack4, enf_2atk5 ] {ai_face();};
-void() enf_2atk5 =[ $attack5, enf_2atk6 ] {ai_face();};
-
-void() enf_2atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = enf_2atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2atk7 =[ $attack7, enf_2atk8 ] {ai_face();};
-void() enf_2atk8 =[ $attack8, enf_2atk9 ] {ai_face();};
-void() enf_2atk9 =[ $attack9, enf_2atk10 ] {ai_face();};
-void() enf_2atk10 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-
-void() enf_4atk1 =[ $attack1, enf_4atk2 ] {ai_face();};
-void() enf_4atk2 =[ $attack2, enf_4atk3 ] {ai_face();};
-void() enf_4atk3 =[ $attack3, enf_4atk4 ] {ai_face();};
-void() enf_4atk4 =[ $attack4, enf_4atk5 ] {ai_face();};
-void() enf_4atk5 =[ $attack5, enf_4atk6 ] {ai_face();};
-void() enf_4atk6 =[ $attack6, enf_4atk7 ] {EnfLightning();};
-void() enf_4atk7 =[ $attack6, enf_4atk8 ] {EnfLightning();};
-void() enf_4atk8 =[ $attack6, enf_4atk9 ] {EnfLightning();};
-void() enf_4atk9 =[ $attack7, enf_4atk10 ] {ai_face();};
-void() enf_4atk10 =[ $attack8, enf_4atk11 ] {ai_face();};
-void() enf_4atk11 =[ $attack9, enf_4atk12 ] {ai_face();};
-void() enf_4atk12 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
-};
-////////////////////////////
-// new frames for turret mode START
-////////////////////////////
-
-void() enf_turret_atk1 =[ $attack1, enf_turret_atk2 ] {ai_face();};
-void() enf_turret_atk2 =[ $attack2, enf_turret_atk3 ] {ai_face();};
-void() enf_turret_atk3 =[ $attack3, enf_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk4 =[ $attack4, enf_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk5 =[ $attack5, enf_turret_atk6 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk6 =[ $attack6, enf_turret_atk7 ] {enforcer_fire();};
-void() enf_turret_atk7 =[ $attack7, enf_turret_atk8 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() enf_turret_atk8 =[ $attack8, enf_turret_atk9 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk9 =[ $attack5, enf_turret_atk10 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() enf_turret_atk10 =[ $attack6, enf_turret_atk11 ] {enforcer_fire();};
-void() enf_turret_atk11 =[ $attack7, enf_turret_atk12 ] {ai_face();};
-void() enf_turret_atk12 =[ $attack8, enf_turret_atk13 ] {ai_face();};
-void() enf_turret_atk13 =[ $attack9, enf_turret_atk14 ] {ai_face();};
-void() enf_turret_atk14 =[ $attack10, enf_seek_stand1 ] {ai_face();SUB_CheckRefire (enf_turret_atk1);
-};
-void() enf_seek_stand1 =[ $stand1, enf_seek_stand2 ] {ai_run(0);};
-void() enf_seek_stand2 =[ $stand2, enf_seek_stand3 ] {ai_run(0);};
-void() enf_seek_stand3 =[ $stand3, enf_seek_stand4 ] {ai_run(0);};
-void() enf_seek_stand4 =[ $stand4, enf_seek_stand5 ] {ai_run(0);};
-void() enf_seek_stand5 =[ $stand5, enf_seek_stand6 ] {ai_run(0);};
-void() enf_seek_stand6 =[ $stand6, enf_seek_stand7 ] {ai_run(0);};
-void() enf_seek_stand7 =[ $stand7, enf_seek_stand1 ] {ai_run(0);};
-
-void() enf_2turret_atk7;
-void() enf_2turret_atk1 =[ $attack1, enf_2turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() enf_2turret_atk2 =[ $attack2, enf_2turret_atk3 ] {ai_face();};
-void() enf_2turret_atk3 =[ $attack3, enf_2turret_atk4 ] {ai_face();};
-void() enf_2turret_atk4 =[ $attack4, enf_2turret_atk5 ] {ai_face();};
-void() enf_2turret_atk5 =[ $attack5, enf_2turret_atk6 ] {ai_face();};
-
-void() enf_2turret_atk6 ={
-self.frame = $attack6;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = enf_2turret_atk7;
-}
-ai_face();
-enforcer_fire();};
-void() enf_2turret_atk7 =[ $attack7, enf_2turret_atk8 ] {ai_face();};
-void() enf_2turret_atk8 =[ $attack8, enf_2turret_atk9 ] {ai_face();};
-void() enf_2turret_atk9 =[ $attack9, enf_2turret_atk10 ] {ai_face();};
-void() enf_2turret_atk10 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_4turret_atk1 =[ $attack1, enf_4turret_atk2 ] {ai_face();};
-void() enf_4turret_atk2 =[ $attack2, enf_4turret_atk3 ] {ai_face();};
-void() enf_4turret_atk3 =[ $attack3, enf_4turret_atk4 ] {ai_face();};
-void() enf_4turret_atk4 =[ $attack4, enf_4turret_atk5 ] {ai_face();};
-void() enf_4turret_atk5 =[ $attack5, enf_4turret_atk6 ] {ai_face();};
-void() enf_4turret_atk6 =[ $attack6, enf_4turret_atk7 ] {EnfLightning();};
-void() enf_4turret_atk7 =[ $attack6, enf_4turret_atk8 ] {EnfLightning();};
-void() enf_4turret_atk8 =[ $attack6, enf_4turret_atk9 ] {EnfLightning();};
-void() enf_4turret_atk9 =[ $attack7, enf_4turret_atk10 ] {ai_face();};
-void() enf_4turret_atk10 =[ $attack8, enf_4turret_atk11 ] {ai_face();};
-void() enf_4turret_atk11 =[ $attack9, enf_4turret_atk12 ] {ai_face();};
-void() enf_4turret_atk12 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
-};
-void() enf_2stand1 =[ $stand1, enf_2stand2 ] {ai_run(0);};
-void() enf_2stand2 =[ $stand2, enf_2stand3 ] {ai_run(0);};
-void() enf_2stand3 =[ $stand3, enf_2stand4 ] {ai_run(0);};
-void() enf_2stand4 =[ $stand4, enf_2stand5 ] {ai_run(0);};
-void() enf_2stand5 =[ $stand5, enf_2stand6 ] {ai_run(0);};
-void() enf_2stand6 =[ $stand6, enf_2stand7 ] {ai_run(0);};
-void() enf_2stand7 =[ $stand7, enf_2stand1 ] {ai_run(0);};
-////////////////////////////
-// new frames for turret mode END
-////////////////////////////
-void() enf_paina1 =[ $paina1, enf_paina2 ] {};
-void() enf_paina2 =[ $paina2, enf_paina3 ] {};
-void() enf_paina3 =[ $paina3, enf_paina4 ] {};
-void() enf_paina4 =[ $paina4, enf_run1 ] {};
-
-void() enf_painb1 =[ $painb1, enf_painb2 ] {};
-void() enf_painb2 =[ $painb2, enf_painb3 ] {};
-void() enf_painb3 =[ $painb3, enf_painb4 ] {};
-void() enf_painb4 =[ $painb4, enf_painb5 ] {};
-void() enf_painb5 =[ $painb5, enf_run1 ] {};
-
-void() enf_painc1 =[ $painc1, enf_painc2 ] {};
-void() enf_painc2 =[ $painc2, enf_painc3 ] {};
-void() enf_painc3 =[ $painc3, enf_painc4 ] {};
-void() enf_painc4 =[ $painc4, enf_painc5 ] {};
-void() enf_painc5 =[ $painc5, enf_painc6 ] {};
-void() enf_painc6 =[ $painc6, enf_painc7 ] {};
-void() enf_painc7 =[ $painc7, enf_painc8 ] {};
-void() enf_painc8 =[ $painc8, enf_run1 ] {};
-
-void() enf_paind1 =[ $paind1, enf_paind2 ] {};
-void() enf_paind2 =[ $paind2, enf_paind3 ] {};
-void() enf_paind3 =[ $paind3, enf_paind4 ] {};
-void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
-void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
-void() enf_paind6 =[ $paind6, enf_paind7 ] {};
-void() enf_paind7 =[ $paind7, enf_paind8 ] {};
-void() enf_paind8 =[ $paind8, enf_paind9 ] {};
-void() enf_paind9 =[ $paind9, enf_paind10 ] {};
-void() enf_paind10 =[ $paind10, enf_paind11 ] {};
-void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
-void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
-void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
-void() enf_paind14 =[ $paind14, enf_paind15 ] {};
-void() enf_paind15 =[ $paind15, enf_paind16 ] {};
-void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
-void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
-void() enf_paind18 =[ $paind18, enf_paind19 ] {};
-void() enf_paind19 =[ $paind19, enf_run1 ] {};
-
-void(entity attacker, float damage) enf_pain =
-{
- local float r;
-
- r = random ();
-
- if (self.pain_finished > time)
- return;
-
- if (r < 0.5)
- sound_pain (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); //dumptruck_ds
- else
- sound_misc3 (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); // dumptruck_ds
-
- if (r < 0.2)
- {
- self.pain_finished = time + 1;
- // moved these here to avoid spamming pain sounds - dumptruck_ds
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paina1 ();
- }
- else if (r < 0.4)
- {
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painb1 ();
- }
- else if (r < 0.7)
- {
- self.pain_finished = time + 1;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_painc1 ();
- }
- else
- {
- self.pain_finished = time + 2;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- enf_paind1 ();
- }
-};
-
-//============================================================================
-
-
-
-
-void() enf_die1 =[ $death1, enf_die2 ] {};
-void() enf_die2 =[ $death2, enf_die3 ] {};
-void() enf_die3 =[ $death3, enf_die4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)DropBackpack();
-};
-void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
-void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
-void() enf_die6 =[ $death6, enf_die7 ] {};
-void() enf_die7 =[ $death7, enf_die8 ] {};
-void() enf_die8 =[ $death8, enf_die9 ] {};
-void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
-void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
-void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
-void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
-void() enf_die13 =[ $death13, enf_die14 ] {};
-void() enf_die14 =[ $death14, enf_die14 ] {};
-
-void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
-
-};
-void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
-void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
-{
- self.solid = SOLID_NOT;
-
- if (self.style == 1) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2) // style ammotype check -- dumptruck_ds
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
- {
- self.ammo_nails = 5;
- }
- if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
- {
- self.ammo_cells = 5;
- }
- if(!self.keep_ammo)DropBackpack();
-};
-void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
-void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
-void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
-void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
-void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
-void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
-void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
-void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
-
-
-void() enf_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_mega.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); //dumptruck_ds
- DropStuff();
- if (random() > 0.5)
- enf_die1 ();
- else
- enf_fdie1 ();
-};
-
-
-/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/enforcer.mdl");
-}
-Enforcer.
-
-Default health = 80
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-
-style(Choices) : "Attack type"
-0 : "Default (lasers)"
-1 : "rockets"
-2 : "grenades"
-3 : "nails"
-
-snd_death(string) : Path to custom death sound"
-snd_pain(string) : "Path to 1st custom pain sound"
-snd_sight(string) : "Path to custom sight sound for STOP!"
-snd_attack(string) : Path to custom attack sound e.g laser firing"
-snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sight sound for FREEZE!"
-snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
-snd_misc2(string) : "Path to custom sight sound for HALT!"
-snd_misc3(string) : "Path to 2nd custom pain sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- if (self.style >= 6)
- objerror("style key set too high\n");
-
- precache_body_model2 ("progs/enforcer.mdl"); // custom_mdls function -- dumptruck_ds
- precache_head_model2 ("progs/h_mega.mdl");
- precache_proj_model2 ("progs/laser.mdl");
- precache_proj_model2 ("progs/s_spike.mdl");
- precache_proj_model2 ("progs/missile.mdl");
- //dumptruck_ds
- precache_sound2_death ("enforcer/death1.wav");
- precache_sound2_attack ("enforcer/enfire.wav");
- precache_sound2_hit ("enforcer/enfstop.wav");
- precache_sound2_idle ("enforcer/idle1.wav");
- precache_sound2_pain ("enforcer/pain1.wav");
- precache_sound2_misc3 ("enforcer/pain2.wav");
- precache_sound2_sight ("enforcer/sight1.wav");
- precache_sound2_misc ("enforcer/sight2.wav"); // these will be replaced with custom noise fields eventually - dumptruck_ds
- precache_sound2_misc1 ("enforcer/sight3.wav");
- precache_sound2_misc2 ("enforcer/sight4.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/enforcer.mdl"); // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
- // // setmodel (self, "progs/enforcer.mdl"); //orginal dumptruck_ds
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
-
- self.th_stand = enf_stand1;
- self.th_walk = enf_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = enf_2stand1;
- }
- else
- {
- self.th_run = enf_run1;
- }
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = enf_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = enf_die;
- if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_2turret_atk1;
- }
- self.th_missile = enf_2atk1;
- }
- else if (self.style == 0 || self.style == 3 ) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_turret_atk1;
- }
- self.th_missile = enf_atk1;
- }
- else if (self.style == 4) // new animation frame check -- dumptruck_ds
- {
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_turret = enf_4turret_atk1;
- }
- self.th_missile = enf_4atk1;
- }
- walkmonster_start();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_enforcer (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/enforcer.mdl","frame":54});
-}
-*/
-void() monster_dead_enforcer =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/enforcer.mdl");
- setmodel(self, "progs/enforcer.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $fdeath11;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-41.16 -45.65 -51.95','21.45 25.49 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $death14;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};
+/*
+==============================================================================
+
+SOLDIER / PLAYER
+
+==============================================================================
+*/
+
+$cd id1/models/enforcer
+$origin 0 -6 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
+$frame walk11 walk12 walk13 walk14 walk15 walk16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6
+$frame attack7 attack8 attack9 attack10
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10 death11 death12 death13 death14
+
+$frame fdeath1 fdeath2 fdeath3 fdeath4 fdeath5 fdeath6 fdeath7 fdeath8
+$frame fdeath9 fdeath10 fdeath11
+
+$frame paina1 paina2 paina3 paina4
+
+$frame painb1 painb2 painb3 painb4 painb5
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8
+$frame paind9 paind10 paind11 paind12 paind13 paind14 paind15 paind16
+$frame paind17 paind18 paind19
+
+
+void() Laser_Touch =
+{
+ local vector org;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ sound_hit (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC); //dumptruck_ds
+ org = self.origin - 8*normalize(self.velocity);
+
+ if (other.health)
+ {
+ SpawnBlood (org, self.velocity*0.2, 15);
+ T_Damage (other, self, self.owner, 15);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+
+ remove(self);
+};
+
+void(vector org, vector vec) LaunchLaser =
+{
+
+ local float projspeed = self.proj_speed_mod * 600;
+
+ if (self.classname == "monster_enforcer" || self.classname == "monster_army")
+ sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
+
+ vec = normalize(vec);
+
+ newmis = spawn();
+ newmis.snd_hit = self.snd_hit; // dumptruck_ds
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLY;
+ newmis.solid = SOLID_BBOX;
+ newmis.effects = EF_DIMLIGHT;
+ newmis.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/laser.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // setmodel (newmis, "progs/laser.mdl");
+ setsize (newmis, '0 0 0', '0 0 0');
+
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, vec, projspeed);
+ newmis.angles = vectoangles(newmis.velocity);
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, projspeed);
+ }
+ else
+ {
+ newmis.nextthink = time + 5;
+ newmis.think = SUB_Remove;
+ }
+ newmis.touch = Laser_Touch;
+};
+
+void(vector org, vector vec) EnfLaunchSpike =
+{
+
+ local float projspeed = self.proj_speed_mod * 600;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+
+ vec = normalize(vec);
+
+ newmis = spawn();
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLY;
+ newmis.solid = SOLID_BBOX;
+ // newmis.effects = EF_DIMLIGHT;
+ newmis.skin = self.skin_proj; //dumptruck_ds
+ // setmodel (newmis, "progs/s_spike.mdl");
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/s_spike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+// dumptruck_ds - end
+ setsize (newmis, '0 0 0', '0 0 0');
+
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, vec, projspeed);
+ newmis.angles = vectoangles(newmis.velocity);
+
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, projspeed);
+ }
+ else
+ {
+ newmis.nextthink = time + 5;
+ newmis.think = SUB_Remove;
+ }
+ newmis.touch = superspike_touch;
+};
+
+//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+
+void() EnfMisTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = 30 + random()*2; //dumptruck_ds
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, 40, other); //dumptruck_ds
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+/*
+================
+EnfRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+================
+*/
+void() EnfRocket =
+{
+ local entity missile;
+ local float projspeed = 900 * self.proj_speed_mod;
+ // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = EnfMisTouch;
+
+ // makevectors (self.v_angle);
+ // missile.velocity = aim(self, 1000);
+ // missile.velocity = missile.velocity * 1000;
+ // missile.angles = vectoangles(missile.velocity);
+
+ // missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, projspeed);
+ }
+ else
+ {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+ // setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 12'); //last number was 16 - dumptruck_ds
+ // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+//end dumptruck_ds grunt missle end
+/*
+================
+EnfFireGrenade
+================
+*/
+void() EnfFireGrenade =
+{
+ local entity missile;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+
+ // setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16');
+ // setorigin (missile, self.origin);
+};
+
+void() EnfLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
+ ai_face ();
+ makevectors (self.angles);
+ org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ dir = self.enemy.origin - self.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 4);
+};
+
+
+// style stuff -- dumptruck_ds
+void() enforcer_fire =
+{
+
+if (self.style == 1)
+
+ {
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ ai_face();
+ sound_attack (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
+
+ EnfRocket();
+ return;
+ }
+
+else if (self.style == 2)
+
+ {
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ ai_face();
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ PreachFireGrenade(self.attack_elevation);
+ }
+ else
+ EnfFireGrenade();
+ return;
+ }
+
+else if (self.style == 3 || self.style ==5)
+
+ {
+ local vector foo;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ makevectors (self.angles);
+
+ foo = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ EnfLaunchSpike(foo, self.enemy.origin - self.origin);
+ return;
+ }
+
+else
+
+ local vector org;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ makevectors (self.angles);
+
+ org = self.origin + v_forward * 30 + v_right * 8.5 + '0 0 16';
+
+ LaunchLaser(org, self.enemy.origin - self.origin);
+};
+
+//============================================================================
+
+void() enf_stand1 =[ $stand1, enf_stand2 ] {ai_stand();};
+void() enf_stand2 =[ $stand2, enf_stand3 ] {ai_stand();};
+void() enf_stand3 =[ $stand3, enf_stand4 ] {ai_stand();};
+void() enf_stand4 =[ $stand4, enf_stand5 ] {ai_stand();};
+void() enf_stand5 =[ $stand5, enf_stand6 ] {ai_stand();};
+void() enf_stand6 =[ $stand6, enf_stand7 ] {ai_stand();};
+void() enf_stand7 =[ $stand7, enf_stand1 ] {ai_stand();};
+
+void() enf_walk1 =[ $walk1 , enf_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_walk(2);};
+void() enf_walk2 =[ $walk2 , enf_walk3 ] {ai_walk(4);};
+void() enf_walk3 =[ $walk3 , enf_walk4 ] {ai_walk(4);};
+void() enf_walk4 =[ $walk4 , enf_walk5 ] {ai_walk(3);};
+void() enf_walk5 =[ $walk5 , enf_walk6 ] {ai_walk(1);};
+void() enf_walk6 =[ $walk6 , enf_walk7 ] {ai_walk(2);};
+void() enf_walk7 =[ $walk7 , enf_walk8 ] {ai_walk(2);};
+void() enf_walk8 =[ $walk8 , enf_walk9 ] {ai_walk(1);};
+void() enf_walk9 =[ $walk9 , enf_walk10 ] {ai_walk(2);};
+void() enf_walk10 =[ $walk10, enf_walk11 ] {ai_walk(4);};
+void() enf_walk11 =[ $walk11, enf_walk12 ] {ai_walk(4);};
+void() enf_walk12 =[ $walk12, enf_walk13 ] {ai_walk(1);};
+void() enf_walk13 =[ $walk13, enf_walk14 ] {ai_walk(2);};
+void() enf_walk14 =[ $walk14, enf_walk15 ] {ai_walk(3);};
+void() enf_walk15 =[ $walk15, enf_walk16 ] {ai_walk(4);};
+void() enf_walk16 =[ $walk16, enf_walk1 ] {ai_walk(2);};
+
+void() enf_run1 =[ $run1 , enf_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "enforcer/idle1.wav", 1, ATTN_IDLE); //dumptruck_ds
+ai_run(18);};
+void() enf_run2 =[ $run2 , enf_run3 ] {ai_run(14);};
+void() enf_run3 =[ $run3 , enf_run4 ] {ai_run(7);};
+void() enf_run4 =[ $run4 , enf_run5 ] {ai_run(12);};
+void() enf_run5 =[ $run5 , enf_run6 ] {ai_run(14);};
+void() enf_run6 =[ $run6 , enf_run7 ] {ai_run(14);};
+void() enf_run7 =[ $run7 , enf_run8 ] {ai_run(7);};
+void() enf_run8 =[ $run8 , enf_run1 ] {ai_run(11);};
+
+void() enf_atk1 =[ $attack1, enf_atk2 ] {ai_face();};
+void() enf_atk2 =[ $attack2, enf_atk3 ] {ai_face();};
+void() enf_atk3 =[ $attack3, enf_atk4 ] {ai_face();};
+void() enf_atk4 =[ $attack4, enf_atk5 ] {ai_face();};
+void() enf_atk5 =[ $attack5, enf_atk6 ] {ai_face();};
+void() enf_atk6 =[ $attack6, enf_atk7 ] {enforcer_fire();};
+void() enf_atk7 =[ $attack7, enf_atk8 ] {ai_face();};
+void() enf_atk8 =[ $attack8, enf_atk9 ] {ai_face();};
+void() enf_atk9 =[ $attack5, enf_atk10 ] {ai_face();};
+void() enf_atk10 =[ $attack6, enf_atk11 ] {enforcer_fire();};
+void() enf_atk11 =[ $attack7, enf_atk12 ] {ai_face();};
+void() enf_atk12 =[ $attack8, enf_atk13 ] {ai_face();};
+void() enf_atk13 =[ $attack9, enf_atk14 ] {ai_face();};
+void() enf_atk14 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_atk1);
+};
+/* modified animation frames for style Enforcers */ // dumptruck_ds
+void() enf_2atk7;
+void() enf_2atk1 =[ $attack1, enf_2atk2 ] {ai_face();self.count = 0;self.t_length= 8 + floor(random()*6);};
+void() enf_2atk2 =[ $attack2, enf_2atk3 ] {ai_face();};
+void() enf_2atk3 =[ $attack3, enf_2atk4 ] {ai_face();};
+void() enf_2atk4 =[ $attack4, enf_2atk5 ] {ai_face();};
+void() enf_2atk5 =[ $attack5, enf_2atk6 ] {ai_face();};
+
+void() enf_2atk6 ={
+self.frame = $attack6;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = enf_2atk7;
+}
+ai_face();
+enforcer_fire();};
+void() enf_2atk7 =[ $attack7, enf_2atk8 ] {ai_face();};
+void() enf_2atk8 =[ $attack8, enf_2atk9 ] {ai_face();};
+void() enf_2atk9 =[ $attack9, enf_2atk10 ] {ai_face();};
+void() enf_2atk10 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
+};
+
+void() enf_4atk1 =[ $attack1, enf_4atk2 ] {ai_face();};
+void() enf_4atk2 =[ $attack2, enf_4atk3 ] {ai_face();};
+void() enf_4atk3 =[ $attack3, enf_4atk4 ] {ai_face();};
+void() enf_4atk4 =[ $attack4, enf_4atk5 ] {ai_face();};
+void() enf_4atk5 =[ $attack5, enf_4atk6 ] {ai_face();};
+void() enf_4atk6 =[ $attack6, enf_4atk7 ] {EnfLightning();};
+void() enf_4atk7 =[ $attack6, enf_4atk8 ] {EnfLightning();};
+void() enf_4atk8 =[ $attack6, enf_4atk9 ] {EnfLightning();};
+void() enf_4atk9 =[ $attack7, enf_4atk10 ] {ai_face();};
+void() enf_4atk10 =[ $attack8, enf_4atk11 ] {ai_face();};
+void() enf_4atk11 =[ $attack9, enf_4atk12 ] {ai_face();};
+void() enf_4atk12 =[ $attack10, enf_run1 ] {ai_face();SUB_CheckRefire (enf_2atk1);
+};
+////////////////////////////
+// new frames for turret mode START
+////////////////////////////
+
+void() enf_turret_atk1 =[ $attack1, enf_turret_atk2 ] {ai_face();};
+void() enf_turret_atk2 =[ $attack2, enf_turret_atk3 ] {ai_face();};
+void() enf_turret_atk3 =[ $attack3, enf_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() enf_turret_atk4 =[ $attack4, enf_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk5 =[ $attack5, enf_turret_atk6 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk6 =[ $attack6, enf_turret_atk7 ] {enforcer_fire();};
+void() enf_turret_atk7 =[ $attack7, enf_turret_atk8 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() enf_turret_atk8 =[ $attack8, enf_turret_atk9 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk9 =[ $attack5, enf_turret_atk10 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() enf_turret_atk10 =[ $attack6, enf_turret_atk11 ] {enforcer_fire();};
+void() enf_turret_atk11 =[ $attack7, enf_turret_atk12 ] {ai_face();};
+void() enf_turret_atk12 =[ $attack8, enf_turret_atk13 ] {ai_face();};
+void() enf_turret_atk13 =[ $attack9, enf_turret_atk14 ] {ai_face();};
+void() enf_turret_atk14 =[ $attack10, enf_seek_stand1 ] {ai_face();SUB_CheckRefire (enf_turret_atk1);
+};
+void() enf_seek_stand1 =[ $stand1, enf_seek_stand2 ] {ai_run(0);};
+void() enf_seek_stand2 =[ $stand2, enf_seek_stand3 ] {ai_run(0);};
+void() enf_seek_stand3 =[ $stand3, enf_seek_stand4 ] {ai_run(0);};
+void() enf_seek_stand4 =[ $stand4, enf_seek_stand5 ] {ai_run(0);};
+void() enf_seek_stand5 =[ $stand5, enf_seek_stand6 ] {ai_run(0);};
+void() enf_seek_stand6 =[ $stand6, enf_seek_stand7 ] {ai_run(0);};
+void() enf_seek_stand7 =[ $stand7, enf_seek_stand1 ] {ai_run(0);};
+
+void() enf_2turret_atk7;
+void() enf_2turret_atk1 =[ $attack1, enf_2turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() enf_2turret_atk2 =[ $attack2, enf_2turret_atk3 ] {ai_face();};
+void() enf_2turret_atk3 =[ $attack3, enf_2turret_atk4 ] {ai_face();};
+void() enf_2turret_atk4 =[ $attack4, enf_2turret_atk5 ] {ai_face();};
+void() enf_2turret_atk5 =[ $attack5, enf_2turret_atk6 ] {ai_face();};
+
+void() enf_2turret_atk6 ={
+self.frame = $attack6;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = enf_2turret_atk7;
+}
+ai_face();
+enforcer_fire();};
+void() enf_2turret_atk7 =[ $attack7, enf_2turret_atk8 ] {ai_face();};
+void() enf_2turret_atk8 =[ $attack8, enf_2turret_atk9 ] {ai_face();};
+void() enf_2turret_atk9 =[ $attack9, enf_2turret_atk10 ] {ai_face();};
+void() enf_2turret_atk10 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
+};
+void() enf_4turret_atk1 =[ $attack1, enf_4turret_atk2 ] {ai_face();};
+void() enf_4turret_atk2 =[ $attack2, enf_4turret_atk3 ] {ai_face();};
+void() enf_4turret_atk3 =[ $attack3, enf_4turret_atk4 ] {ai_face();};
+void() enf_4turret_atk4 =[ $attack4, enf_4turret_atk5 ] {ai_face();};
+void() enf_4turret_atk5 =[ $attack5, enf_4turret_atk6 ] {ai_face();};
+void() enf_4turret_atk6 =[ $attack6, enf_4turret_atk7 ] {EnfLightning();};
+void() enf_4turret_atk7 =[ $attack6, enf_4turret_atk8 ] {EnfLightning();};
+void() enf_4turret_atk8 =[ $attack6, enf_4turret_atk9 ] {EnfLightning();};
+void() enf_4turret_atk9 =[ $attack7, enf_4turret_atk10 ] {ai_face();};
+void() enf_4turret_atk10 =[ $attack8, enf_4turret_atk11 ] {ai_face();};
+void() enf_4turret_atk11 =[ $attack9, enf_4turret_atk12 ] {ai_face();};
+void() enf_4turret_atk12 =[ $attack10, enf_2stand1 ] {ai_face();SUB_CheckRefire (enf_2turret_atk1);
+};
+void() enf_2stand1 =[ $stand1, enf_2stand2 ] {ai_run(0);};
+void() enf_2stand2 =[ $stand2, enf_2stand3 ] {ai_run(0);};
+void() enf_2stand3 =[ $stand3, enf_2stand4 ] {ai_run(0);};
+void() enf_2stand4 =[ $stand4, enf_2stand5 ] {ai_run(0);};
+void() enf_2stand5 =[ $stand5, enf_2stand6 ] {ai_run(0);};
+void() enf_2stand6 =[ $stand6, enf_2stand7 ] {ai_run(0);};
+void() enf_2stand7 =[ $stand7, enf_2stand1 ] {ai_run(0);};
+////////////////////////////
+// new frames for turret mode END
+////////////////////////////
+void() enf_paina1 =[ $paina1, enf_paina2 ] {};
+void() enf_paina2 =[ $paina2, enf_paina3 ] {};
+void() enf_paina3 =[ $paina3, enf_paina4 ] {};
+void() enf_paina4 =[ $paina4, enf_run1 ] {};
+
+void() enf_painb1 =[ $painb1, enf_painb2 ] {};
+void() enf_painb2 =[ $painb2, enf_painb3 ] {};
+void() enf_painb3 =[ $painb3, enf_painb4 ] {};
+void() enf_painb4 =[ $painb4, enf_painb5 ] {};
+void() enf_painb5 =[ $painb5, enf_run1 ] {};
+
+void() enf_painc1 =[ $painc1, enf_painc2 ] {};
+void() enf_painc2 =[ $painc2, enf_painc3 ] {};
+void() enf_painc3 =[ $painc3, enf_painc4 ] {};
+void() enf_painc4 =[ $painc4, enf_painc5 ] {};
+void() enf_painc5 =[ $painc5, enf_painc6 ] {};
+void() enf_painc6 =[ $painc6, enf_painc7 ] {};
+void() enf_painc7 =[ $painc7, enf_painc8 ] {};
+void() enf_painc8 =[ $painc8, enf_run1 ] {};
+
+void() enf_paind1 =[ $paind1, enf_paind2 ] {};
+void() enf_paind2 =[ $paind2, enf_paind3 ] {};
+void() enf_paind3 =[ $paind3, enf_paind4 ] {};
+void() enf_paind4 =[ $paind4, enf_paind5 ] {ai_painforward(2);};
+void() enf_paind5 =[ $paind5, enf_paind6 ] {ai_painforward(1);};
+void() enf_paind6 =[ $paind6, enf_paind7 ] {};
+void() enf_paind7 =[ $paind7, enf_paind8 ] {};
+void() enf_paind8 =[ $paind8, enf_paind9 ] {};
+void() enf_paind9 =[ $paind9, enf_paind10 ] {};
+void() enf_paind10 =[ $paind10, enf_paind11 ] {};
+void() enf_paind11 =[ $paind11, enf_paind12 ] {ai_painforward(1);};
+void() enf_paind12 =[ $paind12, enf_paind13 ] {ai_painforward(1);};
+void() enf_paind13 =[ $paind13, enf_paind14 ] {ai_painforward(1);};
+void() enf_paind14 =[ $paind14, enf_paind15 ] {};
+void() enf_paind15 =[ $paind15, enf_paind16 ] {};
+void() enf_paind16 =[ $paind16, enf_paind17 ] {ai_pain(1);};
+void() enf_paind17 =[ $paind17, enf_paind18 ] {ai_pain(1);};
+void() enf_paind18 =[ $paind18, enf_paind19 ] {};
+void() enf_paind19 =[ $paind19, enf_run1 ] {};
+
+void(entity attacker, float damage) enf_pain =
+{
+ local float r;
+
+ r = random ();
+
+ if (self.pain_finished > time)
+ return;
+
+ if (r < 0.5)
+ sound_pain (self, CHAN_VOICE, "enforcer/pain1.wav", 1, ATTN_NORM); //dumptruck_ds
+ else
+ sound_misc3 (self, CHAN_VOICE, "enforcer/pain2.wav", 1, ATTN_NORM); // dumptruck_ds
+
+ if (r < 0.2)
+ {
+ self.pain_finished = time + 1;
+ // moved these here to avoid spamming pain sounds - dumptruck_ds
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_paina1 ();
+ }
+ else if (r < 0.4)
+ {
+ self.pain_finished = time + 1;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_painb1 ();
+ }
+ else if (r < 0.7)
+ {
+ self.pain_finished = time + 1;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_painc1 ();
+ }
+ else
+ {
+ self.pain_finished = time + 2;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ enf_paind1 ();
+ }
+};
+
+//============================================================================
+
+
+
+
+void() enf_die1 =[ $death1, enf_die2 ] {};
+void() enf_die2 =[ $death2, enf_die3 ] {};
+void() enf_die3 =[ $death3, enf_die4 ]
+{
+ self.solid = SOLID_NOT;
+
+ if (self.style == 1) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_cells = 5;
+ }
+ if(!self.keep_ammo)DropBackpack();
+};
+void() enf_die4 =[ $death4, enf_die5 ] {ai_forward(14);};
+void() enf_die5 =[ $death5, enf_die6 ] {ai_forward(2);};
+void() enf_die6 =[ $death6, enf_die7 ] {};
+void() enf_die7 =[ $death7, enf_die8 ] {};
+void() enf_die8 =[ $death8, enf_die9 ] {};
+void() enf_die9 =[ $death9, enf_die10 ] {ai_forward(3);};
+void() enf_die10 =[ $death10, enf_die11 ] {ai_forward(5);};
+void() enf_die11 =[ $death11, enf_die12 ] {ai_forward(5);};
+void() enf_die12 =[ $death12, enf_die13 ] {ai_forward(5);};
+void() enf_die13 =[ $death13, enf_die14 ] {};
+void() enf_die14 =[ $death14, enf_die14 ] {};
+
+void() enf_fdie1 =[ $fdeath1, enf_fdie2 ] {
+
+};
+void() enf_fdie2 =[ $fdeath2, enf_fdie3 ] {};
+void() enf_fdie3 =[ $fdeath3, enf_fdie4 ]
+{
+ self.solid = SOLID_NOT;
+
+ if (self.style == 1) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3 || self.style == 5) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 0 || self.style == 4) // style ammotype check -- dumptruck_ds
+ {
+ self.ammo_cells = 5;
+ }
+ if(!self.keep_ammo)DropBackpack();
+};
+void() enf_fdie4 =[ $fdeath4, enf_fdie5 ] {};
+void() enf_fdie5 =[ $fdeath5, enf_fdie6 ] {};
+void() enf_fdie6 =[ $fdeath6, enf_fdie7 ] {};
+void() enf_fdie7 =[ $fdeath7, enf_fdie8 ] {};
+void() enf_fdie8 =[ $fdeath8, enf_fdie9 ] {};
+void() enf_fdie9 =[ $fdeath9, enf_fdie10 ] {};
+void() enf_fdie10 =[ $fdeath10, enf_fdie11 ] {};
+void() enf_fdie11 =[ $fdeath11, enf_fdie11 ] {};
+
+
+void() enf_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_mega.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "enforcer/death1.wav", 1, ATTN_NORM); //dumptruck_ds
+ DropStuff();
+ if (random() > 0.5)
+ enf_die1 ();
+ else
+ enf_fdie1 ();
+};
+
+
+/*QUAKED monster_enforcer (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/enforcer.mdl");
+}
+Enforcer.
+
+Default health = 80
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+
+style(Choices) : "Attack type"
+0 : "Default (lasers)"
+1 : "rockets"
+2 : "grenades"
+3 : "nails"
+
+snd_death(string) : Path to custom death sound"
+snd_pain(string) : "Path to 1st custom pain sound"
+snd_sight(string) : "Path to custom sight sound for STOP!"
+snd_attack(string) : Path to custom attack sound e.g laser firing"
+snd_hit(string) : "Path to custom hit sound e.g. laser hits wall"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sight sound for FREEZE!"
+snd_misc1(string) : "Path to custom sight sound for YOU THERE!"
+snd_misc2(string) : "Path to custom sight sound for HALT!"
+snd_misc3(string) : "Path to 2nd custom pain sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ if (self.style >= 6)
+ objerror("style key set too high\n");
+
+ precache_body_model2 ("progs/enforcer.mdl"); // custom_mdls function -- dumptruck_ds
+ precache_head_model2 ("progs/h_mega.mdl");
+ precache_proj_model2 ("progs/laser.mdl");
+ precache_proj_model2 ("progs/s_spike.mdl");
+ precache_proj_model2 ("progs/missile.mdl");
+ //dumptruck_ds
+ precache_sound2_death ("enforcer/death1.wav");
+ precache_sound2_attack ("enforcer/enfire.wav");
+ precache_sound2_hit ("enforcer/enfstop.wav");
+ precache_sound2_idle ("enforcer/idle1.wav");
+ precache_sound2_pain ("enforcer/pain1.wav");
+ precache_sound2_misc3 ("enforcer/pain2.wav");
+ precache_sound2_sight ("enforcer/sight1.wav");
+ precache_sound2_misc ("enforcer/sight2.wav"); // these will be replaced with custom noise fields eventually - dumptruck_ds
+ precache_sound2_misc1 ("enforcer/sight3.wav");
+ precache_sound2_misc2 ("enforcer/sight4.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/enforcer.mdl"); // SPIKE to the RESCUE!!!! - got this fixed. -- dumptruck_ds
+ // // setmodel (self, "progs/enforcer.mdl"); //orginal dumptruck_ds
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 80;
+
+ self.th_stand = enf_stand1;
+ self.th_walk = enf_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = enf_2stand1;
+ }
+ else
+ {
+ self.th_run = enf_run1;
+ }
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = enf_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = enf_die;
+ if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_2turret_atk1;
+ }
+ self.th_missile = enf_2atk1;
+ }
+ else if (self.style == 0 || self.style == 3 ) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_turret_atk1;
+ }
+ self.th_missile = enf_atk1;
+ }
+ else if (self.style == 4) // new animation frame check -- dumptruck_ds
+ {
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_turret = enf_4turret_atk1;
+ }
+ self.th_missile = enf_4atk1;
+ }
+ walkmonster_start();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_enforcer (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/enforcer.mdl","frame":54});
+}
+*/
+void() monster_dead_enforcer =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/enforcer.mdl");
+ setmodel(self, "progs/enforcer.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $fdeath11;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-41.16 -45.65 -51.95','21.45 25.49 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $death14;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/fish.qc

diff --git a/qc/monsters/fish.qc b/qc/monsters/fish.qc
index b4aead5..c5ac5c6 100644
--- a/qc/monsters/fish.qc
+++ b/qc/monsters/fish.qc
@@ -1,306 +1,306 @@
-$cd id1/models/fish
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6
-$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
-$frame attack14 attack15 attack16 attack17 attack18
-
-$frame death1 death2 death3 death4 death5 death6 death7
-$frame death8 death9 death10 death11 death12 death13 death14 death15
-$frame death16 death17 death18 death19 death20 death21
-
-$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
-$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
-$frame swim18
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
-$frame pain9
-
-void() swimmonster_start;
-
-void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
-void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
-void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
-void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
-void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
-void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
-void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
-void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
-void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
-void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
-void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
-void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
-void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
-void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
-void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
-void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
-void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
-void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
-
-void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
-void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
-void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
-void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
-void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
-void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
-void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
-void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
-void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
-void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
-void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
-void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
-void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
-void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
-void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
-void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
-void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
-void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
-
-void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
- if (random() < 0.5)
- sound_idle (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
-};
-void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
-void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
-void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
-void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
-void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
-void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
-void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
-void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
-
-void() fish_melee =
-{
- local vector delta;
- local float ldmg;
-
- if (!self.enemy)
- return; // removed before stroke
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 60)
- return;
-
- sound_attack (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- ldmg = (random() + random()) * 3;
- T_Damage (self.enemy, self, self, ldmg);
-};
-
-void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
-void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
-void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
-void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
-void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
-void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
-void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
-void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
-void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
-void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
-void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
-void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
-void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
-void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
-void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
-void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
-void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
-void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
-
-void() f_death1 =[ $death1, f_death2 ]
- {
- self.solid = SOLID_NOT;
- sound_death (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
- };
-void() f_death2 =[ $death2, f_death3 ] {};
-void() f_death3 =[ $death3, f_death4 ] {};
-void() f_death4 =[ $death4, f_death5 ] {};
-void() f_death5 =[ $death5, f_death6 ] {};
-void() f_death6 =[ $death6, f_death7 ] {};
-void() f_death7 =[ $death7, f_death8 ] {};
-void() f_death8 =[ $death8, f_death9 ] {};
-void() f_death9 =[ $death9, f_death10 ] {};
-void() f_death10 =[ $death10, f_death11 ] {};
-void() f_death11 =[ $death11, f_death12 ] {};
-void() f_death12 =[ $death12, f_death13 ] {};
-void() f_death13 =[ $death13, f_death14 ] {};
-void() f_death14 =[ $death14, f_death15 ] {};
-void() f_death15 =[ $death15, f_death16 ] {};
-void() f_death16 =[ $death16, f_death17 ] {};
-void() f_death17 =[ $death17, f_death18 ] {};
-void() f_death18 =[ $death18, f_death19 ] {};
-void() f_death19 =[ $death19, f_death20 ] {};
-void() f_death20 =[ $death20, f_death21 ] {};
-void() f_death21 =[ $death21, f_death21 ] {};
-
-void() fish_die =
-{
- if (self.health < -35) //fish gibs -- dumptruck_ds
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_head != "")
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_dog.mdl", self.health);
- }
- DropStuff();
- SUB_Remove();
- }
- // regular death
- else
- {
- DropStuff();
- f_death1();
- }
-};
-
-void() f_pain1 =[ $pain1, f_pain2 ] {};
-void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
-void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
-void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
-void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
-void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
-void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
-void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
-void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
-
-void(entity attacker, float damage) fish_pain =
-{
-// fish always do pain frames
- f_pain1 ();
-};
-
-
-
-/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/fish.mdl");
-}
-Rotfish.
-
-Default health = 25"
-
-snd_death(string) : "Path to custom death sound (BUBBLES)"
-snd_attack(string) : "Path to custom attack sound (CRUNCHY BITE)"
-snd_idle(string) : "Path to custom idle sound"
-
-mdl_body(string) : "Path to custom body model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_fish =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- precache_body_model2 ("progs/fish.mdl");
- // precache_model2 ("progs/fish.mdl");
-
- precache_sound2_death ("fish/death.wav");
- precache_sound2_attack ("fish/bite.wav");
- precache_sound2_idle ("fish/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/fish.mdl");
- // setmodel (self, "progs/fish.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 24');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 25;
-
- self.th_stand = f_stand1;
- self.th_walk = f_walk1;
- self.th_run = f_run1;
- // self.th_die = f_death1;
- self.th_die = fish_die;
- if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = fish_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_melee = f_attack1;
-
- swimmonster_start ();
-};
+$cd id1/models/fish
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6
+$frame attack7 attack8 attack9 attack10 attack11 attack12 attack13
+$frame attack14 attack15 attack16 attack17 attack18
+
+$frame death1 death2 death3 death4 death5 death6 death7
+$frame death8 death9 death10 death11 death12 death13 death14 death15
+$frame death16 death17 death18 death19 death20 death21
+
+$frame swim1 swim2 swim3 swim4 swim5 swim6 swim7 swim8
+$frame swim9 swim10 swim11 swim12 swim13 swim14 swim15 swim16 swim17
+$frame swim18
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6 pain7 pain8
+$frame pain9
+
+void() swimmonster_start;
+
+void() f_stand1 =[ $swim1, f_stand2 ] {ai_stand();};
+void() f_stand2 =[ $swim2, f_stand3 ] {ai_stand();};
+void() f_stand3 =[ $swim3, f_stand4 ] {ai_stand();};
+void() f_stand4 =[ $swim4, f_stand5 ] {ai_stand();};
+void() f_stand5 =[ $swim5, f_stand6 ] {ai_stand();};
+void() f_stand6 =[ $swim6, f_stand7 ] {ai_stand();};
+void() f_stand7 =[ $swim7, f_stand8 ] {ai_stand();};
+void() f_stand8 =[ $swim8, f_stand9 ] {ai_stand();};
+void() f_stand9 =[ $swim9, f_stand10 ] {ai_stand();};
+void() f_stand10 =[ $swim10, f_stand11 ] {ai_stand();};
+void() f_stand11 =[ $swim11, f_stand12 ] {ai_stand();};
+void() f_stand12 =[ $swim12, f_stand13 ] {ai_stand();};
+void() f_stand13 =[ $swim13, f_stand14 ] {ai_stand();};
+void() f_stand14 =[ $swim14, f_stand15 ] {ai_stand();};
+void() f_stand15 =[ $swim15, f_stand16 ] {ai_stand();};
+void() f_stand16 =[ $swim16, f_stand17 ] {ai_stand();};
+void() f_stand17 =[ $swim17, f_stand18 ] {ai_stand();};
+void() f_stand18 =[ $swim18, f_stand1 ] {ai_stand();};
+
+void() f_walk1 =[ $swim1, f_walk2 ] {ai_walk(8);};
+void() f_walk2 =[ $swim2, f_walk3 ] {ai_walk(8);};
+void() f_walk3 =[ $swim3, f_walk4 ] {ai_walk(8);};
+void() f_walk4 =[ $swim4, f_walk5 ] {ai_walk(8);};
+void() f_walk5 =[ $swim5, f_walk6 ] {ai_walk(8);};
+void() f_walk6 =[ $swim6, f_walk7 ] {ai_walk(8);};
+void() f_walk7 =[ $swim7, f_walk8 ] {ai_walk(8);};
+void() f_walk8 =[ $swim8, f_walk9 ] {ai_walk(8);};
+void() f_walk9 =[ $swim9, f_walk10 ] {ai_walk(8);};
+void() f_walk10 =[ $swim10, f_walk11 ] {ai_walk(8);};
+void() f_walk11 =[ $swim11, f_walk12 ] {ai_walk(8);};
+void() f_walk12 =[ $swim12, f_walk13 ] {ai_walk(8);};
+void() f_walk13 =[ $swim13, f_walk14 ] {ai_walk(8);};
+void() f_walk14 =[ $swim14, f_walk15 ] {ai_walk(8);};
+void() f_walk15 =[ $swim15, f_walk16 ] {ai_walk(8);};
+void() f_walk16 =[ $swim16, f_walk17 ] {ai_walk(8);};
+void() f_walk17 =[ $swim17, f_walk18 ] {ai_walk(8);};
+void() f_walk18 =[ $swim18, f_walk1 ] {ai_walk(8);};
+
+void() f_run1 =[ $swim1, f_run2 ] {ai_run(12);
+ if (random() < 0.5)
+ sound_idle (self, CHAN_VOICE, "fish/idle.wav", 1, ATTN_NORM);
+};
+void() f_run2 =[ $swim3, f_run3 ] {ai_run(12);};
+void() f_run3 =[ $swim5, f_run4 ] {ai_run(12);};
+void() f_run4 =[ $swim7, f_run5 ] {ai_run(12);};
+void() f_run5 =[ $swim9, f_run6 ] {ai_run(12);};
+void() f_run6 =[ $swim11, f_run7 ] {ai_run(12);};
+void() f_run7 =[ $swim13, f_run8 ] {ai_run(12);};
+void() f_run8 =[ $swim15, f_run9 ] {ai_run(12);};
+void() f_run9 =[ $swim17, f_run1 ] {ai_run(12);};
+
+void() fish_melee =
+{
+ local vector delta;
+ local float ldmg;
+
+ if (!self.enemy)
+ return; // removed before stroke
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 60)
+ return;
+
+ sound_attack (self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ ldmg = (random() + random()) * 3;
+ T_Damage (self.enemy, self, self, ldmg);
+};
+
+void() f_attack1 =[ $attack1, f_attack2 ] {ai_charge(10);};
+void() f_attack2 =[ $attack2, f_attack3 ] {ai_charge(10);};
+void() f_attack3 =[ $attack3, f_attack4 ] {fish_melee();};
+void() f_attack4 =[ $attack4, f_attack5 ] {ai_charge(10);};
+void() f_attack5 =[ $attack5, f_attack6 ] {ai_charge(10);};
+void() f_attack6 =[ $attack6, f_attack7 ] {ai_charge(10);};
+void() f_attack7 =[ $attack7, f_attack8 ] {ai_charge(10);};
+void() f_attack8 =[ $attack8, f_attack9 ] {ai_charge(10);};
+void() f_attack9 =[ $attack9, f_attack10] {fish_melee();};
+void() f_attack10 =[ $attack10, f_attack11] {ai_charge(10);};
+void() f_attack11 =[ $attack11, f_attack12] {ai_charge(10);};
+void() f_attack12 =[ $attack12, f_attack13] {ai_charge(10);};
+void() f_attack13 =[ $attack13, f_attack14] {ai_charge(10);};
+void() f_attack14 =[ $attack14, f_attack15] {ai_charge(10);};
+void() f_attack15 =[ $attack15, f_attack16] {fish_melee();};
+void() f_attack16 =[ $attack16, f_attack17] {ai_charge(10);};
+void() f_attack17 =[ $attack17, f_attack18] {ai_charge(10);};
+void() f_attack18 =[ $attack18, f_run1 ] {ai_charge(10);};
+
+void() f_death1 =[ $death1, f_death2 ]
+ {
+ self.solid = SOLID_NOT;
+ sound_death (self, CHAN_VOICE, "fish/death.wav", 1, ATTN_NORM);
+ };
+void() f_death2 =[ $death2, f_death3 ] {};
+void() f_death3 =[ $death3, f_death4 ] {};
+void() f_death4 =[ $death4, f_death5 ] {};
+void() f_death5 =[ $death5, f_death6 ] {};
+void() f_death6 =[ $death6, f_death7 ] {};
+void() f_death7 =[ $death7, f_death8 ] {};
+void() f_death8 =[ $death8, f_death9 ] {};
+void() f_death9 =[ $death9, f_death10 ] {};
+void() f_death10 =[ $death10, f_death11 ] {};
+void() f_death11 =[ $death11, f_death12 ] {};
+void() f_death12 =[ $death12, f_death13 ] {};
+void() f_death13 =[ $death13, f_death14 ] {};
+void() f_death14 =[ $death14, f_death15 ] {};
+void() f_death15 =[ $death15, f_death16 ] {};
+void() f_death16 =[ $death16, f_death17 ] {};
+void() f_death17 =[ $death17, f_death18 ] {};
+void() f_death18 =[ $death18, f_death19 ] {};
+void() f_death19 =[ $death19, f_death20 ] {};
+void() f_death20 =[ $death20, f_death21 ] {};
+void() f_death21 =[ $death21, f_death21 ] {};
+
+void() fish_die =
+{
+ if (self.health < -35) //fish gibs -- dumptruck_ds
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_head != "")
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_dog.mdl", self.health);
+ }
+ DropStuff();
+ SUB_Remove();
+ }
+ // regular death
+ else
+ {
+ DropStuff();
+ f_death1();
+ }
+};
+
+void() f_pain1 =[ $pain1, f_pain2 ] {};
+void() f_pain2 =[ $pain2, f_pain3 ] {ai_pain(6);};
+void() f_pain3 =[ $pain3, f_pain4 ] {ai_pain(6);};
+void() f_pain4 =[ $pain4, f_pain5 ] {ai_pain(6);};
+void() f_pain5 =[ $pain5, f_pain6 ] {ai_pain(6);};
+void() f_pain6 =[ $pain6, f_pain7 ] {ai_pain(6);};
+void() f_pain7 =[ $pain7, f_pain8 ] {ai_pain(6);};
+void() f_pain8 =[ $pain8, f_pain9 ] {ai_pain(6);};
+void() f_pain9 =[ $pain9, f_run1 ] {ai_pain(6);};
+
+void(entity attacker, float damage) fish_pain =
+{
+// fish always do pain frames
+ f_pain1 ();
+};
+
+
+
+/*QUAKED monster_fish (1 0 0) (-16 -16 -24) (16 16 24) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/fish.mdl");
+}
+Rotfish.
+
+Default health = 25"
+
+snd_death(string) : "Path to custom death sound (BUBBLES)"
+snd_attack(string) : "Path to custom attack sound (CRUNCHY BITE)"
+snd_idle(string) : "Path to custom idle sound"
+
+mdl_body(string) : "Path to custom body model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_fish =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ precache_body_model2 ("progs/fish.mdl");
+ // precache_model2 ("progs/fish.mdl");
+
+ precache_sound2_death ("fish/death.wav");
+ precache_sound2_attack ("fish/bite.wav");
+ precache_sound2_idle ("fish/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/fish.mdl");
+ // setmodel (self, "progs/fish.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 24');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 25;
+
+ self.th_stand = f_stand1;
+ self.th_walk = f_walk1;
+ self.th_run = f_run1;
+ // self.th_die = f_death1;
+ self.th_die = fish_die;
+ if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = fish_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_melee = f_attack1;
+
+ swimmonster_start ();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/hknight.qc

diff --git a/qc/monsters/hknight.qc b/qc/monsters/hknight.qc
index 10aa2a3..f0942a4 100644
--- a/qc/monsters/hknight.qc
+++ b/qc/monsters/hknight.qc
@@ -1,755 +1,755 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
-
-$cd id1/models/knight2
-$origin 0 0 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
-$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
-$frame walk18 walk19 walk20
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10 death11 death12
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
-$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
-
-$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
-$frame magica9 magica10 magica11 magica12 magica13 magica14
-
-$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
-$frame magicb9 magicb10 magicb11 magicb12 magicb13
-
-$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
-
-$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
-$frame smash11
-
-$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
-$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
-$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
-$frame w_attack21 w_attack22
-
-$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
-$frame magicc9 magicc10 magicc11
-
-
-void() hknight_char_a1;
-void() hknight_run1;
-void() hk_idle_sound;
-
-void(float offset) hknight_shot =
-{
- local vector offang;
- local vector org, vec;
- local float exploding = self.projexpl == 1 || (self.projexpl == 2 && offset % 2 == 0) || (self.projexpl == 3 && random()*2 < 1);
- offang = vectoangles (self.enemy.origin - self.origin);
- offang_y = offang_y + offset * 6;
-
- makevectors (offang);
-
- org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
-
-// set missile speed
- vec = normalize (v_forward);
- vec_z = 0 - vec_z + (random() - 0.5)*0.1;
-
- launch_spike2 (org, vec, 300);
- newmis.classname = "knightspike";
- // setmodel (newmis, "progs/k_spike.mdl");
- if (exploding)
- {
- newmis.touch = T_HellKnightMisTouch;
- if (self.mdl_exproj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_exproj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike2.mdl");
- }
-
- if (self.skin_exproj) // dumptruck_ds
- {
- newmis.skin = self.skin_exproj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- else
- {
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/k_spike.mdl");
- }
-
- if (self.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- }
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- sound_attack (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
-};
-
-void() CheckForCharge =
-{
-// check for mad charge
-if (!enemy_vis)
- return;
-if (time < self.attack_finished)
- return;
-if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
- return; // too much height change
-if ( vlen (self.origin - self.enemy.origin) < 80)
- return; // use regular attack
-
-// charge
- SUB_AttackFinished (2);
- hknight_char_a1 ();
-
-};
-
-void() CheckContinueCharge =
-{
- if (time > self.attack_finished)
- {
- SUB_AttackFinished (3);
- hknight_run1 ();
- return; // done charging
- }
- if (random() > 0.5)
- sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-};
-
-//===========================================================================
-
-void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
-void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
-void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
-void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
-void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
-void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
-void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
-void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
-void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
-
-//===========================================================================
-
-void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
-hk_idle_sound();
-ai_walk(2);};
-void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
-void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
-void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
-void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
-void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
-void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
-void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
-void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
-void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
-void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
-void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
-void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
-void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
-void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
-void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
-void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
-void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
-void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
-void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
-
-//===========================================================================
-
-void() hknight_run1 =[ $run1, hknight_run2 ] {
-hk_idle_sound();
-ai_run (20); CheckForCharge (); };
-void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
-void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
-void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
-void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
-void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
-void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
-void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
-
-//============================================================================
-
-void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);};
-void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
-void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
-void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
-void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
-
-//============================================================================
-
-void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
-void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
-void() hknight_die3 =[ $death3, hknight_die4 ]{self.solid = SOLID_NOT;ai_forward(7);};
-void() hknight_die4 =[ $death4, hknight_die5 ] {};
-void() hknight_die5 =[ $death5, hknight_die6 ] {};
-void() hknight_die6 =[ $death6, hknight_die7 ] {};
-void() hknight_die7 =[ $death7, hknight_die8 ] {};
-void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
-void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
-void() hknight_die10 =[ $death10, hknight_die11 ] {};
-void() hknight_die11 =[ $death11, hknight_die12 ] {};
-void() hknight_die12 =[ $death12, hknight_die12 ] {};
-
-void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
-void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
-void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] {self.solid = SOLID_NOT;};
-void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
-void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
-void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
-void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
-void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
-void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
-
-void() hknight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_hellkn.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() > 0.5)
- hknight_die1 ();
- else
- hknight_dieb1 ();
-};
-
-
-//============================================================================
-
-void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
-void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
-void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
-void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
-void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
-void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
-void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
-void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
-void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
-void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
-void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
-void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
-void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
-void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
-
-//============================================================================
-
-void() HellKnightLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
- ai_face ();
- makevectors (self.angles);
- org = self.origin + v_forward * 50 + '0 0 20';
-
- dir = self.enemy.origin - self.enemy.velocity * 0.075;
- dir = normalize (dir - org + '0 0 16');
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 20);
-};
-void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
-void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
-void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
-void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
-void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
-void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
-void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {ai_face();};
-void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {ai_face();};
-void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {ai_face();};
-void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {ai_face();};
-void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {ai_face();};
-void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
-
-//============================================================================
-
-void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
-void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
-void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
-void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
-void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
-void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
-void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
-void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
-void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
-void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
-void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
-
-//============================================================================
-///////////////////////////////////////
-////// turret frames START - revisions
-//////////////////////////////////////
-void() hknight_turret_magicc1 =[ $magicc1, hknight_turret_magicc2 ] {ai_face();};
-void() hknight_turret_magicc2 =[ $magicc2, hknight_turret_magicc3 ] {ai_face();};
-void() hknight_turret_magicc3 =[ $magicc3, hknight_turret_magicc4 ] {ai_face();};
-void() hknight_turret_magicc4 =[ $magicc4, hknight_turret_magicc5 ] {ai_face();};
-void() hknight_turret_magicc5 =[ $magicc5, hknight_turret_magicc6 ] {ai_face();};
-void() hknight_turret_magicc6 =[ $magicc6, hknight_turret_magicc7 ] {hknight_shot(-2);};
-void() hknight_turret_magicc7 =[ $magicc7, hknight_turret_magicc8 ] {hknight_shot(-1);};
-void() hknight_turret_magicc8 =[ $magicc8, hknight_turret_magicc9 ] {hknight_shot(0);};
-void() hknight_turret_magicc9 =[ $magicc9, hknight_turret_magicc10] {hknight_shot(1);};
-void() hknight_turret_magicc10 =[ $magicc10, hknight_turret_magicc11] {hknight_shot(2);};
-void() hknight_turret_magicc11 =[ $magicc11, hknight_turret_magicc12] {ai_face();};
-void() hknight_turret_magicc12 =[ $stand1, hknight_turret_magicc13 ] {ai_face();};
-void() hknight_turret_magicc13 =[ $stand2, hknight_turret_magicc14 ] {ai_face();};
-void() hknight_turret_magicc14 =[ $stand3, hknight_turret_magicc15 ] {ai_face();};
-void() hknight_turret_magicc15 =[ $stand4, hknight_seek_stand1 ] {ai_run(0);};
-void() hknight_seek_stand1 =[ $stand1, hknight_seek_stand2 ] {ai_run(0);};
-void() hknight_seek_stand2 =[ $stand2, hknight_seek_stand3 ] {ai_run(0);};
-void() hknight_seek_stand3 =[ $stand3, hknight_seek_stand4 ] {ai_run(0);};
-void() hknight_seek_stand4 =[ $stand4, hknight_seek_stand5 ] {ai_run(0);};
-void() hknight_seek_stand5 =[ $stand5, hknight_seek_stand6 ] {ai_run(0);};
-void() hknight_seek_stand6 =[ $stand6, hknight_seek_stand7 ] {ai_run(0);};
-void() hknight_seek_stand7 =[ $stand7, hknight_seek_stand8 ] {ai_run(0);};
-void() hknight_seek_stand8 =[ $stand8, hknight_seek_stand9 ] {ai_run(0);};
-void() hknight_seek_stand9 =[ $stand9, hknight_seek_stand1 ] {ai_run(0);};
-
-void() hknight_turret_magicb1 =[ $magicb1, hknight_turret_magicb2 ] {ai_face();};
-void() hknight_turret_magicb2 =[ $magicb2, hknight_turret_magicb3 ] {ai_face();};
-void() hknight_turret_magicb3 =[ $magicb3, hknight_turret_magicb4 ] {ai_face();};
-void() hknight_turret_magicb4 =[ $magicb4, hknight_turret_magicb5 ] {ai_face();};
-void() hknight_turret_magicb5 =[ $magicb5, hknight_turret_magicb6 ] {ai_face();};
-void() hknight_turret_magicb6 =[ $magicb6, hknight_turret_magicb7 ] {ai_face();};
-void() hknight_turret_magicb7 =[ $magicb7, hknight_turret_magicb8 ] {ai_face();};
-void() hknight_turret_magicb8 =[ $magicb8, hknight_turret_magicb9 ] {ai_face();};
-void() hknight_turret_magicb9 =[ $magicb9, hknight_turret_magicb10] {ai_face();};
-void() hknight_turret_magicb10 =[ $magicb10, hknight_turret_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
-void() hknight_turret_magicb11 =[ $magicb11, hknight_turret_magicb12] {ai_face();};
-void() hknight_turret_magicb12 =[ $magicb12, hknight_turret_magicb13] {ai_face();};
-void() hknight_turret_magicb13 =[ $magicb13, hknight_seek_stand1] {ai_face();};
-/////////////////////////
-////// turret frames END
-/////////////////////////
-
-//===========================================================================
-
-void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
-void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
-void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
-void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
-void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
-void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
-void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
-void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
-void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
-void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
-void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
-void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
-void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
-void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
-
-//===========================================================================
-
-void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
-{CheckContinueCharge (); ai_charge(23); ai_melee();};
-void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
-void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
-void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
-void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
-void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
-
-//===========================================================================
-
-void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
-void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
-void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
-void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
-void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
-void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
-void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
-void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
-void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
-void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
-
-//===========================================================================
-
-void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
-void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
-void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
-void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
-void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
-void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
-void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
-void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
-void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
-void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
-void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
-
-//============================================================================
-
-void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
-void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
-void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
-void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
-void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
-void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
-void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
-void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
-void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
-void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
-void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
-void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
-void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
-void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
-void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
-void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
-void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
-void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
-void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
-void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
-void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
-void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
-
-//============================================================================
-
-void() hk_idle_sound =
-{
- if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
-};
-
-void(entity attacker, float damage) hknight_pain =
-{
- local float r;
-
- r = random();
-
- if (self.pain_finished > time)
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- {
- if (r < 0.5)
- {
- self.pain_finished = time + 1.5;
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
- }
- return;
- }
-
- sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
-
- if (time - self.pain_finished > 5)
- { // always go into pain frame if it has been a while
- hknight_pain1 ();
- self.pain_finished = time + 1;
- return;
- }
-
- if ((random()*30 > damage) )
- return; // didn't flinch
-
- self.pain_finished = time + 1;
- hknight_pain1 ();
-};
-
-float hknight_type;
-
-void() hknight_melee =
-{
- hknight_type = hknight_type + 1;
-
- sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
- if (hknight_type == 1)
- hknight_slice1 ();
- else if (hknight_type == 2)
- hknight_smash1 ();
- else if (hknight_type == 3)
- {
- hknight_watk1 ();
- hknight_type = 0;
- }
-};
-
-/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/hknight.mdl");
-}
-Hellknight.
-
-Default health = 250"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (MAGIC BOING)"
-snd_idle(string) : Path to custom idle sound"
-snd_misc(string) : Path to custom SWORD SLASH sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-mdl_exproj(string) : "Path to custom projectile model for exploding projectiles"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-skin_exproj(float) : "Skin index of custom projectile model for exploding projectiles"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-projexpl(choices) : "Exploding projectiles"
-0 : "No explosions"
-1 : "All projectiles explode"
-2 : "Every other projectile explodes"
-3 : "Random per projectile"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/hknight.mdl");
- precache_head_model2 ("progs/h_hellkn.mdl");
- precache_proj_model2 ("progs/k_spike.mdl");
- precache_exproj_model2 ("progs/k_spike2.mdl"); // this needed a unique name defiined in custom_mdls.qc -- dumptruck_ds
-// dumptruck_ds
-
- precache_sound2_attack ("hknight/attack1.wav");
- precache_sound2_death ("hknight/death1.wav");
- precache_sound2_pain ("hknight/pain1.wav");
- precache_sound2_sight ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
- precache_sound2_misc ("hknight/slash1.wav");
- precache_sound2_idle ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav"); // what??? never knew about this! -- dumptruck_ds
-
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/hknight.mdl"); // custom_mdls dumptruck_ds
- // setmodel (self, "progs/hknight.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 250;
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- self.th_stand = hknight_stand1;
- self.th_walk = hknight_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = hknight_seek_stand1;
- }
- else
- {
- self.th_run = hknight_run1;
- }
- self.th_melee = hknight_melee;
- if (self.style == 1)
- {
- self.th_missile = hknight_magicb1;
- self.th_turret = hknight_turret_magicb1;
- }
- else
- {
- self.th_missile = hknight_magicc1;
- self.th_turret = hknight_turret_magicc1;
- }
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = hknight_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = hknight_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_hell_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/hknight.mdl","frame":62});
-}
-*/
-void() monster_dead_hell_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/hknight.mdl");
- setmodel(self, "progs/hknight.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $deathb9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-68.96 -20.43 -53.98','34.8 21.15 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $death12;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-42.05 -31.07 -51.56','46.34 25.02 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};
+/*
+==============================================================================
+
+KNIGHT
+
+==============================================================================
+*/
+
+$cd id1/models/knight2
+$origin 0 0 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
+$frame walk10 walk11 walk12 walk13 walk14 walk15 walk16 walk17
+$frame walk18 walk19 walk20
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10 death11 death12
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame char_a1 char_a2 char_a3 char_a4 char_a5 char_a6 char_a7 char_a8
+$frame char_a9 char_a10 char_a11 char_a12 char_a13 char_a14 char_a15 char_a16
+
+$frame magica1 magica2 magica3 magica4 magica5 magica6 magica7 magica8
+$frame magica9 magica10 magica11 magica12 magica13 magica14
+
+$frame magicb1 magicb2 magicb3 magicb4 magicb5 magicb6 magicb7 magicb8
+$frame magicb9 magicb10 magicb11 magicb12 magicb13
+
+$frame char_b1 char_b2 char_b3 char_b4 char_b5 char_b6
+
+$frame slice1 slice2 slice3 slice4 slice5 slice6 slice7 slice8 slice9 slice10
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7 smash8 smash9 smash10
+$frame smash11
+
+$frame w_attack1 w_attack2 w_attack3 w_attack4 w_attack5 w_attack6 w_attack7
+$frame w_attack8 w_attack9 w_attack10 w_attack11 w_attack12 w_attack13 w_attack14
+$frame w_attack15 w_attack16 w_attack17 w_attack18 w_attack19 w_attack20
+$frame w_attack21 w_attack22
+
+$frame magicc1 magicc2 magicc3 magicc4 magicc5 magicc6 magicc7 magicc8
+$frame magicc9 magicc10 magicc11
+
+
+void() hknight_char_a1;
+void() hknight_run1;
+void() hk_idle_sound;
+
+void(float offset) hknight_shot =
+{
+ local vector offang;
+ local vector org, vec;
+ local float exploding = self.projexpl == 1 || (self.projexpl == 2 && offset % 2 == 0) || (self.projexpl == 3 && random()*2 < 1);
+ offang = vectoangles (self.enemy.origin - self.origin);
+ offang_y = offang_y + offset * 6;
+
+ makevectors (offang);
+
+ org = self.origin + self.mins + self.size*0.5 + v_forward * 20;
+
+// set missile speed
+ vec = normalize (v_forward);
+ vec_z = 0 - vec_z + (random() - 0.5)*0.1;
+
+ launch_spike2 (org, vec, 300);
+ newmis.classname = "knightspike";
+ // setmodel (newmis, "progs/k_spike.mdl");
+ if (exploding)
+ {
+ newmis.touch = T_HellKnightMisTouch;
+ if (self.mdl_exproj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_exproj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/k_spike2.mdl");
+ }
+
+ if (self.skin_exproj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_exproj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ }
+ else
+ {
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/k_spike.mdl");
+ }
+
+ if (self.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ }
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ sound_attack (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
+};
+
+void() CheckForCharge =
+{
+// check for mad charge
+if (!enemy_vis)
+ return;
+if (time < self.attack_finished)
+ return;
+if ( fabs(self.origin_z - self.enemy.origin_z) > 20)
+ return; // too much height change
+if ( vlen (self.origin - self.enemy.origin) < 80)
+ return; // use regular attack
+
+// charge
+ SUB_AttackFinished (2);
+ hknight_char_a1 ();
+
+};
+
+void() CheckContinueCharge =
+{
+ if (time > self.attack_finished)
+ {
+ SUB_AttackFinished (3);
+ hknight_run1 ();
+ return; // done charging
+ }
+ if (random() > 0.5)
+ sound (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+};
+
+//===========================================================================
+
+void() hknight_stand1 =[ $stand1, hknight_stand2 ] {ai_stand();};
+void() hknight_stand2 =[ $stand2, hknight_stand3 ] {ai_stand();};
+void() hknight_stand3 =[ $stand3, hknight_stand4 ] {ai_stand();};
+void() hknight_stand4 =[ $stand4, hknight_stand5 ] {ai_stand();};
+void() hknight_stand5 =[ $stand5, hknight_stand6 ] {ai_stand();};
+void() hknight_stand6 =[ $stand6, hknight_stand7 ] {ai_stand();};
+void() hknight_stand7 =[ $stand7, hknight_stand8 ] {ai_stand();};
+void() hknight_stand8 =[ $stand8, hknight_stand9 ] {ai_stand();};
+void() hknight_stand9 =[ $stand9, hknight_stand1 ] {ai_stand();};
+
+//===========================================================================
+
+void() hknight_walk1 =[ $walk1, hknight_walk2 ] {
+hk_idle_sound();
+ai_walk(2);};
+void() hknight_walk2 =[ $walk2, hknight_walk3 ] {ai_walk(5);};
+void() hknight_walk3 =[ $walk3, hknight_walk4 ] {ai_walk(5);};
+void() hknight_walk4 =[ $walk4, hknight_walk5 ] {ai_walk(4);};
+void() hknight_walk5 =[ $walk5, hknight_walk6 ] {ai_walk(4);};
+void() hknight_walk6 =[ $walk6, hknight_walk7 ] {ai_walk(2);};
+void() hknight_walk7 =[ $walk7, hknight_walk8 ] {ai_walk(2);};
+void() hknight_walk8 =[ $walk8, hknight_walk9 ] {ai_walk(3);};
+void() hknight_walk9 =[ $walk9, hknight_walk10 ] {ai_walk(3);};
+void() hknight_walk10 =[ $walk10, hknight_walk11 ] {ai_walk(4);};
+void() hknight_walk11 =[ $walk11, hknight_walk12 ] {ai_walk(3);};
+void() hknight_walk12 =[ $walk12, hknight_walk13 ] {ai_walk(4);};
+void() hknight_walk13 =[ $walk13, hknight_walk14 ] {ai_walk(6);};
+void() hknight_walk14 =[ $walk14, hknight_walk15 ] {ai_walk(2);};
+void() hknight_walk15 =[ $walk15, hknight_walk16 ] {ai_walk(2);};
+void() hknight_walk16 =[ $walk16, hknight_walk17 ] {ai_walk(4);};
+void() hknight_walk17 =[ $walk17, hknight_walk18 ] {ai_walk(3);};
+void() hknight_walk18 =[ $walk18, hknight_walk19 ] {ai_walk(3);};
+void() hknight_walk19 =[ $walk19, hknight_walk20 ] {ai_walk(3);};
+void() hknight_walk20 =[ $walk20, hknight_walk1 ] {ai_walk(2);};
+
+//===========================================================================
+
+void() hknight_run1 =[ $run1, hknight_run2 ] {
+hk_idle_sound();
+ai_run (20); CheckForCharge (); };
+void() hknight_run2 =[ $run2, hknight_run3 ] {ai_run(25);};
+void() hknight_run3 =[ $run3, hknight_run4 ] {ai_run(18);};
+void() hknight_run4 =[ $run4, hknight_run5 ] {ai_run(16);};
+void() hknight_run5 =[ $run5, hknight_run6 ] {ai_run(14);};
+void() hknight_run6 =[ $run6, hknight_run7 ] {ai_run(25);};
+void() hknight_run7 =[ $run7, hknight_run8 ] {ai_run(21);};
+void() hknight_run8 =[ $run8, hknight_run1 ] {ai_run(13);};
+
+//============================================================================
+
+void() hknight_pain1 =[ $pain1, hknight_pain2 ] {sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);};
+void() hknight_pain2 =[ $pain2, hknight_pain3 ] {};
+void() hknight_pain3 =[ $pain3, hknight_pain4 ] {};
+void() hknight_pain4 =[ $pain4, hknight_pain5 ] {};
+void() hknight_pain5 =[ $pain5, hknight_run1 ] {};
+
+//============================================================================
+
+void() hknight_die1 =[ $death1, hknight_die2 ] {ai_forward(10);};
+void() hknight_die2 =[ $death2, hknight_die3 ] {ai_forward(8);};
+void() hknight_die3 =[ $death3, hknight_die4 ]{self.solid = SOLID_NOT;ai_forward(7);};
+void() hknight_die4 =[ $death4, hknight_die5 ] {};
+void() hknight_die5 =[ $death5, hknight_die6 ] {};
+void() hknight_die6 =[ $death6, hknight_die7 ] {};
+void() hknight_die7 =[ $death7, hknight_die8 ] {};
+void() hknight_die8 =[ $death8, hknight_die9 ] {ai_forward(10);};
+void() hknight_die9 =[ $death9, hknight_die10 ] {ai_forward(11);};
+void() hknight_die10 =[ $death10, hknight_die11 ] {};
+void() hknight_die11 =[ $death11, hknight_die12 ] {};
+void() hknight_die12 =[ $death12, hknight_die12 ] {};
+
+void() hknight_dieb1 =[ $deathb1, hknight_dieb2 ] {};
+void() hknight_dieb2 =[ $deathb2, hknight_dieb3 ] {};
+void() hknight_dieb3 =[ $deathb3, hknight_dieb4 ] {self.solid = SOLID_NOT;};
+void() hknight_dieb4 =[ $deathb4, hknight_dieb5 ] {};
+void() hknight_dieb5 =[ $deathb5, hknight_dieb6 ] {};
+void() hknight_dieb6 =[ $deathb6, hknight_dieb7 ] {};
+void() hknight_dieb7 =[ $deathb7, hknight_dieb8 ] {};
+void() hknight_dieb8 =[ $deathb8, hknight_dieb9 ] {};
+void() hknight_dieb9 =[ $deathb9, hknight_dieb9 ] {};
+
+void() hknight_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_hellkn.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "hknight/death1.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() > 0.5)
+ hknight_die1 ();
+ else
+ hknight_dieb1 ();
+};
+
+
+//============================================================================
+
+void() hknight_magica1 =[ $magica1, hknight_magica2 ] {ai_face();};
+void() hknight_magica2 =[ $magica2, hknight_magica3 ] {ai_face();};
+void() hknight_magica3 =[ $magica3, hknight_magica4 ] {ai_face();};
+void() hknight_magica4 =[ $magica4, hknight_magica5 ] {ai_face();};
+void() hknight_magica5 =[ $magica5, hknight_magica6 ] {ai_face();};
+void() hknight_magica6 =[ $magica6, hknight_magica7 ] {ai_face();};
+void() hknight_magica7 =[ $magica7, hknight_magica8 ] {hknight_shot(-2);};
+void() hknight_magica8 =[ $magica8, hknight_magica9 ] {hknight_shot(-1);};
+void() hknight_magica9 =[ $magica9, hknight_magica10] {hknight_shot(0);};
+void() hknight_magica10 =[ $magica10, hknight_magica11] {hknight_shot(1);};
+void() hknight_magica11 =[ $magica11, hknight_magica12] {hknight_shot(2);};
+void() hknight_magica12 =[ $magica12, hknight_magica13] {hknight_shot(3);};
+void() hknight_magica13 =[ $magica13, hknight_magica14] {ai_face();};
+void() hknight_magica14 =[ $magica14, hknight_run1 ] {ai_face();};
+
+//============================================================================
+
+void() HellKnightLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_attack(self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM);
+ ai_face ();
+ makevectors (self.angles);
+ org = self.origin + v_forward * 50 + '0 0 20';
+
+ dir = self.enemy.origin - self.enemy.velocity * 0.075;
+ dir = normalize (dir - org + '0 0 16');
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 20);
+};
+void() hknight_magicb1 =[ $magicb1, hknight_magicb2 ] {ai_face();};
+void() hknight_magicb2 =[ $magicb2, hknight_magicb3 ] {ai_face();};
+void() hknight_magicb3 =[ $magicb3, hknight_magicb4 ] {ai_face();};
+void() hknight_magicb4 =[ $magicb4, hknight_magicb5 ] {ai_face();};
+void() hknight_magicb5 =[ $magicb5, hknight_magicb6 ] {ai_face();};
+void() hknight_magicb6 =[ $magicb6, hknight_magicb7 ] {ai_face();};
+void() hknight_magicb7 =[ $magicb7, hknight_magicb8 ] {ai_face();};
+void() hknight_magicb8 =[ $magicb8, hknight_magicb9 ] {ai_face();};
+void() hknight_magicb9 =[ $magicb9, hknight_magicb10] {ai_face();};
+void() hknight_magicb10 =[ $magicb10, hknight_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
+void() hknight_magicb11 =[ $magicb11, hknight_magicb12] {ai_face();};
+void() hknight_magicb12 =[ $magicb12, hknight_magicb13] {ai_face();};
+void() hknight_magicb13 =[ $magicb13, hknight_run1] {ai_face();};
+
+//============================================================================
+
+void() hknight_magicc1 =[ $magicc1, hknight_magicc2 ] {ai_face();};
+void() hknight_magicc2 =[ $magicc2, hknight_magicc3 ] {ai_face();};
+void() hknight_magicc3 =[ $magicc3, hknight_magicc4 ] {ai_face();};
+void() hknight_magicc4 =[ $magicc4, hknight_magicc5 ] {ai_face();};
+void() hknight_magicc5 =[ $magicc5, hknight_magicc6 ] {ai_face();};
+void() hknight_magicc6 =[ $magicc6, hknight_magicc7 ] {hknight_shot(-2);};
+void() hknight_magicc7 =[ $magicc7, hknight_magicc8 ] {hknight_shot(-1);};
+void() hknight_magicc8 =[ $magicc8, hknight_magicc9 ] {hknight_shot(0);};
+void() hknight_magicc9 =[ $magicc9, hknight_magicc10] {hknight_shot(1);};
+void() hknight_magicc10 =[ $magicc10, hknight_magicc11] {hknight_shot(2);};
+void() hknight_magicc11 =[ $magicc11, hknight_run1] {hknight_shot(3);};
+
+//============================================================================
+///////////////////////////////////////
+////// turret frames START - revisions
+//////////////////////////////////////
+void() hknight_turret_magicc1 =[ $magicc1, hknight_turret_magicc2 ] {ai_face();};
+void() hknight_turret_magicc2 =[ $magicc2, hknight_turret_magicc3 ] {ai_face();};
+void() hknight_turret_magicc3 =[ $magicc3, hknight_turret_magicc4 ] {ai_face();};
+void() hknight_turret_magicc4 =[ $magicc4, hknight_turret_magicc5 ] {ai_face();};
+void() hknight_turret_magicc5 =[ $magicc5, hknight_turret_magicc6 ] {ai_face();};
+void() hknight_turret_magicc6 =[ $magicc6, hknight_turret_magicc7 ] {hknight_shot(-2);};
+void() hknight_turret_magicc7 =[ $magicc7, hknight_turret_magicc8 ] {hknight_shot(-1);};
+void() hknight_turret_magicc8 =[ $magicc8, hknight_turret_magicc9 ] {hknight_shot(0);};
+void() hknight_turret_magicc9 =[ $magicc9, hknight_turret_magicc10] {hknight_shot(1);};
+void() hknight_turret_magicc10 =[ $magicc10, hknight_turret_magicc11] {hknight_shot(2);};
+void() hknight_turret_magicc11 =[ $magicc11, hknight_turret_magicc12] {ai_face();};
+void() hknight_turret_magicc12 =[ $stand1, hknight_turret_magicc13 ] {ai_face();};
+void() hknight_turret_magicc13 =[ $stand2, hknight_turret_magicc14 ] {ai_face();};
+void() hknight_turret_magicc14 =[ $stand3, hknight_turret_magicc15 ] {ai_face();};
+void() hknight_turret_magicc15 =[ $stand4, hknight_seek_stand1 ] {ai_run(0);};
+void() hknight_seek_stand1 =[ $stand1, hknight_seek_stand2 ] {ai_run(0);};
+void() hknight_seek_stand2 =[ $stand2, hknight_seek_stand3 ] {ai_run(0);};
+void() hknight_seek_stand3 =[ $stand3, hknight_seek_stand4 ] {ai_run(0);};
+void() hknight_seek_stand4 =[ $stand4, hknight_seek_stand5 ] {ai_run(0);};
+void() hknight_seek_stand5 =[ $stand5, hknight_seek_stand6 ] {ai_run(0);};
+void() hknight_seek_stand6 =[ $stand6, hknight_seek_stand7 ] {ai_run(0);};
+void() hknight_seek_stand7 =[ $stand7, hknight_seek_stand8 ] {ai_run(0);};
+void() hknight_seek_stand8 =[ $stand8, hknight_seek_stand9 ] {ai_run(0);};
+void() hknight_seek_stand9 =[ $stand9, hknight_seek_stand1 ] {ai_run(0);};
+
+void() hknight_turret_magicb1 =[ $magicb1, hknight_turret_magicb2 ] {ai_face();};
+void() hknight_turret_magicb2 =[ $magicb2, hknight_turret_magicb3 ] {ai_face();};
+void() hknight_turret_magicb3 =[ $magicb3, hknight_turret_magicb4 ] {ai_face();};
+void() hknight_turret_magicb4 =[ $magicb4, hknight_turret_magicb5 ] {ai_face();};
+void() hknight_turret_magicb5 =[ $magicb5, hknight_turret_magicb6 ] {ai_face();};
+void() hknight_turret_magicb6 =[ $magicb6, hknight_turret_magicb7 ] {ai_face();};
+void() hknight_turret_magicb7 =[ $magicb7, hknight_turret_magicb8 ] {ai_face();};
+void() hknight_turret_magicb8 =[ $magicb8, hknight_turret_magicb9 ] {ai_face();};
+void() hknight_turret_magicb9 =[ $magicb9, hknight_turret_magicb10] {ai_face();};
+void() hknight_turret_magicb10 =[ $magicb10, hknight_turret_magicb11] {ai_face();sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);HellKnightLightning();};
+void() hknight_turret_magicb11 =[ $magicb11, hknight_turret_magicb12] {ai_face();};
+void() hknight_turret_magicb12 =[ $magicb12, hknight_turret_magicb13] {ai_face();};
+void() hknight_turret_magicb13 =[ $magicb13, hknight_seek_stand1] {ai_face();};
+/////////////////////////
+////// turret frames END
+/////////////////////////
+
+//===========================================================================
+
+void() hknight_char_a1 =[ $char_a1, hknight_char_a2 ] {ai_charge(20);};
+void() hknight_char_a2 =[ $char_a2, hknight_char_a3 ] {ai_charge(25);};
+void() hknight_char_a3 =[ $char_a3, hknight_char_a4 ] {ai_charge(18);};
+void() hknight_char_a4 =[ $char_a4, hknight_char_a5 ] {ai_charge(16);};
+void() hknight_char_a5 =[ $char_a5, hknight_char_a6 ] {ai_charge(14);};
+void() hknight_char_a6 =[ $char_a6, hknight_char_a7 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a7 =[ $char_a7, hknight_char_a8 ] {ai_charge(21); ai_melee();};
+void() hknight_char_a8 =[ $char_a8, hknight_char_a9 ] {ai_charge(13); ai_melee();};
+void() hknight_char_a9 =[ $char_a9, hknight_char_a10 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a10=[ $char_a10, hknight_char_a11 ] {ai_charge(20); ai_melee();};
+void() hknight_char_a11=[ $char_a11, hknight_char_a12 ] {ai_charge(18); ai_melee();};
+void() hknight_char_a12=[ $char_a12, hknight_char_a13 ] {ai_charge(16);};
+void() hknight_char_a13=[ $char_a13, hknight_char_a14 ] {ai_charge(14);};
+void() hknight_char_a14=[ $char_a14, hknight_char_a15 ] {ai_charge(25);};
+void() hknight_char_a15=[ $char_a15, hknight_char_a16 ] {ai_charge(21);};
+void() hknight_char_a16=[ $char_a16, hknight_run1 ] {ai_charge(13);};
+
+//===========================================================================
+
+void() hknight_char_b1 =[ $char_b1, hknight_char_b2 ]
+{CheckContinueCharge (); ai_charge(23); ai_melee();};
+void() hknight_char_b2 =[ $char_b2, hknight_char_b3 ] {ai_charge(17); ai_melee();};
+void() hknight_char_b3 =[ $char_b3, hknight_char_b4 ] {ai_charge(12); ai_melee();};
+void() hknight_char_b4 =[ $char_b4, hknight_char_b5 ] {ai_charge(22); ai_melee();};
+void() hknight_char_b5 =[ $char_b5, hknight_char_b6 ] {ai_charge(18); ai_melee();};
+void() hknight_char_b6 =[ $char_b6, hknight_char_b1 ] {ai_charge(8); ai_melee();};
+
+//===========================================================================
+
+void() hknight_slice1 =[ $slice1, hknight_slice2 ] {ai_charge(9);};
+void() hknight_slice2 =[ $slice2, hknight_slice3 ] {ai_charge(6);};
+void() hknight_slice3 =[ $slice3, hknight_slice4 ] {ai_charge(13);};
+void() hknight_slice4 =[ $slice4, hknight_slice5 ] {ai_charge(4);};
+void() hknight_slice5 =[ $slice5, hknight_slice6 ] {ai_charge(7); ai_melee();};
+void() hknight_slice6 =[ $slice6, hknight_slice7 ] {ai_charge(15); ai_melee();};
+void() hknight_slice7 =[ $slice7, hknight_slice8 ] {ai_charge(8); ai_melee();};
+void() hknight_slice8 =[ $slice8, hknight_slice9 ] {ai_charge(2); ai_melee();};
+void() hknight_slice9 =[ $slice9, hknight_slice10 ] {ai_melee();};
+void() hknight_slice10 =[ $slice10, hknight_run1 ] {ai_charge(3);};
+
+//===========================================================================
+
+void() hknight_smash1 =[ $smash1, hknight_smash2 ] {ai_charge(1);};
+void() hknight_smash2 =[ $smash2, hknight_smash3 ] {ai_charge(13);};
+void() hknight_smash3 =[ $smash3, hknight_smash4 ] {ai_charge(9);};
+void() hknight_smash4 =[ $smash4, hknight_smash5 ] {ai_charge(11);};
+void() hknight_smash5 =[ $smash5, hknight_smash6 ] {ai_charge(10); ai_melee();};
+void() hknight_smash6 =[ $smash6, hknight_smash7 ] {ai_charge(7); ai_melee();};
+void() hknight_smash7 =[ $smash7, hknight_smash8 ] {ai_charge(12); ai_melee();};
+void() hknight_smash8 =[ $smash8, hknight_smash9 ] {ai_charge(2); ai_melee();};
+void() hknight_smash9 =[ $smash9, hknight_smash10 ] {ai_charge(3); ai_melee();};
+void() hknight_smash10 =[ $smash10, hknight_smash11 ] {ai_charge(0);};
+void() hknight_smash11 =[ $smash11, hknight_run1 ] {ai_charge(0);};
+
+//============================================================================
+
+void() hknight_watk1 =[ $w_attack1, hknight_watk2 ] {ai_charge(2);};
+void() hknight_watk2 =[ $w_attack2, hknight_watk3 ] {ai_charge(0);};
+void() hknight_watk3 =[ $w_attack3, hknight_watk4 ] {ai_charge(0);};
+void() hknight_watk4 =[ $w_attack4, hknight_watk5 ] {ai_melee();};
+void() hknight_watk5 =[ $w_attack5, hknight_watk6 ] {ai_melee();};
+void() hknight_watk6 =[ $w_attack6, hknight_watk7 ] {ai_melee();};
+void() hknight_watk7 =[ $w_attack7, hknight_watk8 ] {ai_charge(1);};
+void() hknight_watk8 =[ $w_attack8, hknight_watk9 ] {ai_charge(4);};
+void() hknight_watk9 =[ $w_attack9, hknight_watk10 ] {ai_charge(5);};
+void() hknight_watk10 =[ $w_attack10, hknight_watk11 ] {ai_charge(3); ai_melee();};
+void() hknight_watk11 =[ $w_attack11, hknight_watk12 ] {ai_charge(2); ai_melee();};
+void() hknight_watk12 =[ $w_attack12, hknight_watk13 ] {ai_charge(2); ai_melee();};
+void() hknight_watk13 =[ $w_attack13, hknight_watk14 ] {ai_charge(0);};
+void() hknight_watk14 =[ $w_attack14, hknight_watk15 ] {ai_charge(0);};
+void() hknight_watk15 =[ $w_attack15, hknight_watk16 ] {ai_charge(0);};
+void() hknight_watk16 =[ $w_attack16, hknight_watk17 ] {ai_charge(1);};
+void() hknight_watk17 =[ $w_attack17, hknight_watk18 ] {ai_charge(1); ai_melee();};
+void() hknight_watk18 =[ $w_attack18, hknight_watk19 ] {ai_charge(3); ai_melee();};
+void() hknight_watk19 =[ $w_attack19, hknight_watk20 ] {ai_charge(4); ai_melee();};
+void() hknight_watk20 =[ $w_attack20, hknight_watk21 ] {ai_charge(6);};
+void() hknight_watk21 =[ $w_attack21, hknight_watk22 ] {ai_charge(7);};
+void() hknight_watk22 =[ $w_attack22, hknight_run1 ] {ai_charge(3);};
+
+//============================================================================
+
+void() hk_idle_sound =
+{
+ if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "hknight/idle.wav", 1, ATTN_NORM);
+};
+
+void(entity attacker, float damage) hknight_pain =
+{
+ local float r;
+
+ r = random();
+
+ if (self.pain_finished > time)
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ if (r < 0.5)
+ {
+ self.pain_finished = time + 1.5;
+ sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
+ }
+ return;
+ }
+
+ sound_pain (self, CHAN_VOICE, "hknight/pain1.wav", 1, ATTN_NORM);
+
+ if (time - self.pain_finished > 5)
+ { // always go into pain frame if it has been a while
+ hknight_pain1 ();
+ self.pain_finished = time + 1;
+ return;
+ }
+
+ if ((random()*30 > damage) )
+ return; // didn't flinch
+
+ self.pain_finished = time + 1;
+ hknight_pain1 ();
+};
+
+float hknight_type;
+
+void() hknight_melee =
+{
+ hknight_type = hknight_type + 1;
+
+ sound_misc (self, CHAN_WEAPON, "hknight/slash1.wav", 1, ATTN_NORM);
+ if (hknight_type == 1)
+ hknight_slice1 ();
+ else if (hknight_type == 2)
+ hknight_smash1 ();
+ else if (hknight_type == 3)
+ {
+ hknight_watk1 ();
+ hknight_type = 0;
+ }
+};
+
+/*QUAKED monster_hell_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/hknight.mdl");
+}
+Hellknight.
+
+Default health = 250"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (MAGIC BOING)"
+snd_idle(string) : Path to custom idle sound"
+snd_misc(string) : Path to custom SWORD SLASH sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+mdl_exproj(string) : "Path to custom projectile model for exploding projectiles"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+skin_exproj(float) : "Skin index of custom projectile model for exploding projectiles"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+projexpl(choices) : "Exploding projectiles"
+0 : "No explosions"
+1 : "All projectiles explode"
+2 : "Every other projectile explodes"
+3 : "Random per projectile"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ //dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/hknight.mdl");
+ precache_head_model2 ("progs/h_hellkn.mdl");
+ precache_proj_model2 ("progs/k_spike.mdl");
+ precache_exproj_model2 ("progs/k_spike2.mdl"); // this needed a unique name defiined in custom_mdls.qc -- dumptruck_ds
+// dumptruck_ds
+
+ precache_sound2_attack ("hknight/attack1.wav");
+ precache_sound2_death ("hknight/death1.wav");
+ precache_sound2_pain ("hknight/pain1.wav");
+ precache_sound2_sight ("hknight/sight1.wav");
+ precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
+ precache_sound2_misc ("hknight/slash1.wav");
+ precache_sound2_idle ("hknight/idle.wav");
+ precache_sound2 ("hknight/grunt.wav"); // what??? never knew about this! -- dumptruck_ds
+
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/hknight.mdl"); // custom_mdls dumptruck_ds
+ // setmodel (self, "progs/hknight.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 250;
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ self.th_stand = hknight_stand1;
+ self.th_walk = hknight_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = hknight_seek_stand1;
+ }
+ else
+ {
+ self.th_run = hknight_run1;
+ }
+ self.th_melee = hknight_melee;
+ if (self.style == 1)
+ {
+ self.th_missile = hknight_magicb1;
+ self.th_turret = hknight_turret_magicb1;
+ }
+ else
+ {
+ self.th_missile = hknight_magicc1;
+ self.th_turret = hknight_turret_magicc1;
+ }
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = hknight_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = hknight_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_hell_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/hknight.mdl","frame":62});
+}
+*/
+void() monster_dead_hell_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/hknight.mdl");
+ setmodel(self, "progs/hknight.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $deathb9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-68.96 -20.43 -53.98','34.8 21.15 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $death12;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-42.05 -31.07 -51.56','46.34 25.02 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/knight.qc

diff --git a/qc/monsters/knight.qc b/qc/monsters/knight.qc
index bdfbb0e..c15368c 100644
--- a/qc/monsters/knight.qc
+++ b/qc/monsters/knight.qc
@@ -1,418 +1,418 @@
-/*
-==============================================================================
-
-KNIGHT
-
-==============================================================================
-*/
-
-$cd id1/models/knight
-$origin 0 0 24
-$base base
-$skin badass3
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
-
-//frame runc1 runc2 runc3 runc4 runc5 runc6
-
-$frame runattack1 runattack2 runattack3 runattack4 runattack5
-$frame runattack6 runattack7 runattack8 runattack9 runattack10
-$frame runattack11
-
-$frame pain1 pain2 pain3
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
-$frame painb10 painb11
-
-//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
-//frame attack8 attack9 attack10 attack11
-
-$frame attackdummy
-$frame attackb1 attackb2 attackb3 attackb4 attackb5
-$frame attackb6 attackb7 attackb8 attackb9 attackb10
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
-$frame walk10 walk11 walk12 walk13 walk14
-
-$frame kneel1 kneel2 kneel3 kneel4 kneel5
-
-$frame standing2 standing3 standing4 standing5
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9 deathb10 deathb11
-
-void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
-void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
-void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
-void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
-void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
-void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
-void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
-void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
-void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
-
-void() knight_walk1 =[ $walk1, knight_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_walk(3);};
-void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
-void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
-void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
-void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
-void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
-void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
-void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
-void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
-void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
-void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
-void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
-void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
-void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
-
-
-void() knight_run1 =[ $runb1, knight_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
-ai_run(16);};
-void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
-void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
-void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
-void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
-void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
-void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
-void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
-
-
-void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
-{
-if (random() > 0.5)
- sound_misc (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
-else
- sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(20);
-};
-void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
-void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
-void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
-void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
-void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
-void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
-void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
-void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
-void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
-void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
-
-void() knight_atk1 =[ $attackb1, knight_atk2 ]
-{
-sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
-ai_charge(0);};
-void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
-void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
-void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
-void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
-void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
-void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
-void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
-ai_melee();};
-void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
-void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
-
-//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
-//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
-//void() knight_atk11 =[ $attack11, knight_run1 ] {};
-
-//===========================================================================
-
-void() knight_pain1 =[ $pain1, knight_pain2 ] {};
-void() knight_pain2 =[ $pain2, knight_pain3 ] {};
-void() knight_pain3 =[ $pain3, knight_run1 ] {};
-
-void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
-void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
-void() knight_painb3 =[ $painb3, knight_painb4 ] {};
-void() knight_painb4 =[ $painb4, knight_painb5 ] {};
-void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
-void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
-void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
-void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
-void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
-void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
-void() knight_painb11 =[ $painb11, knight_run1 ] {};
-
-void(entity attacker, float damage) knight_pain =
-{
- local float r;
-
- if (self.pain_finished > time)
- return;
-
- r = random();
-
- sound_pain (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
- if (r < 0.85)
- {
- knight_pain1 ();
- self.pain_finished = time + 1;
- }
- else
- {
- knight_painb1 ();
- self.pain_finished = time + 1;
- }
-
-};
-
-//===========================================================================
-
-void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
-void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
-void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
-void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
-
-void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
-
-void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
-void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
-void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
-void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
-void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
-
-
-
-void() knight_die1 =[ $death1, knight_die2 ] {};
-void() knight_die2 =[ $death2, knight_die3 ] {};
-void() knight_die3 =[ $death3, knight_die4 ] {self.solid = SOLID_NOT;};
-void() knight_die4 =[ $death4, knight_die5 ] {};
-void() knight_die5 =[ $death5, knight_die6 ] {};
-void() knight_die6 =[ $death6, knight_die7 ] {};
-void() knight_die7 =[ $death7, knight_die8 ] {};
-void() knight_die8 =[ $death8, knight_die9 ] {};
-void() knight_die9 =[ $death9, knight_die10] {};
-void() knight_die10=[ $death10, knight_die10] {};
-
-
-void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
-void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
-void() knight_dieb3 =[ $deathb3, knight_dieb4 ] {self.solid = SOLID_NOT;};
-void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
-void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
-void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
-void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
-void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
-void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
-void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
-void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
-
-
-void() knight_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_knight.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() < 0.5)
- knight_die1 ();
- else
- knight_dieb1 ();
-};
-
-
-/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/knight.mdl");
-}
-Knight.
-
-Default heath = 75"
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (SWORD SLASH 1)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (SWORD SLASH 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/knight.mdl");
- precache_head_model ("progs/h_knight.mdl");
- //// dumptruck_ds
- precache_sound_death ("knight/kdeath.wav");
- precache_sound_pain ("knight/khurt.wav");
- precache_sound_sight ("knight/ksight.wav");
- precache_sound_attack ("knight/sword1.wav");
- precache_sound_misc ("knight/sword2.wav");
- precache_sound_idle ("knight/idle.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
- // setmodel (self, "progs/knight.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 75;
-
- self.th_stand = knight_stand1;
- self.th_walk = knight_walk1;
- self.th_run = knight_run1;
- self.th_melee = knight_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = knight_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = knight_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/knight.mdl","frame":96});
-}
-*/
-void() monster_dead_knight =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/knight.mdl");
- setmodel(self, "progs/knight.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death10;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-25.56 -14.56 -50.49','26.45 40.2 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $deathb11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-30.36 -45.6 -50.18','28.29 11.59 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};
+/*
+==============================================================================
+
+KNIGHT
+
+==============================================================================
+*/
+
+$cd id1/models/knight
+$origin 0 0 24
+$base base
+$skin badass3
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame runb1 runb2 runb3 runb4 runb5 runb6 runb7 runb8
+
+//frame runc1 runc2 runc3 runc4 runc5 runc6
+
+$frame runattack1 runattack2 runattack3 runattack4 runattack5
+$frame runattack6 runattack7 runattack8 runattack9 runattack10
+$frame runattack11
+
+$frame pain1 pain2 pain3
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9
+$frame painb10 painb11
+
+//frame attack1 attack2 attack3 attack4 attack5 attack6 attack7
+//frame attack8 attack9 attack10 attack11
+
+$frame attackdummy
+$frame attackb1 attackb2 attackb3 attackb4 attackb5
+$frame attackb6 attackb7 attackb8 attackb9 attackb10
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9
+$frame walk10 walk11 walk12 walk13 walk14
+
+$frame kneel1 kneel2 kneel3 kneel4 kneel5
+
+$frame standing2 standing3 standing4 standing5
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9 deathb10 deathb11
+
+void() knight_stand1 =[ $stand1, knight_stand2 ] {ai_stand();};
+void() knight_stand2 =[ $stand2, knight_stand3 ] {ai_stand();};
+void() knight_stand3 =[ $stand3, knight_stand4 ] {ai_stand();};
+void() knight_stand4 =[ $stand4, knight_stand5 ] {ai_stand();};
+void() knight_stand5 =[ $stand5, knight_stand6 ] {ai_stand();};
+void() knight_stand6 =[ $stand6, knight_stand7 ] {ai_stand();};
+void() knight_stand7 =[ $stand7, knight_stand8 ] {ai_stand();};
+void() knight_stand8 =[ $stand8, knight_stand9 ] {ai_stand();};
+void() knight_stand9 =[ $stand9, knight_stand1 ] {ai_stand();};
+
+void() knight_walk1 =[ $walk1, knight_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
+ai_walk(3);};
+void() knight_walk2 =[ $walk2, knight_walk3 ] {ai_walk(2);};
+void() knight_walk3 =[ $walk3, knight_walk4 ] {ai_walk(3);};
+void() knight_walk4 =[ $walk4, knight_walk5 ] {ai_walk(4);};
+void() knight_walk5 =[ $walk5, knight_walk6 ] {ai_walk(3);};
+void() knight_walk6 =[ $walk6, knight_walk7 ] {ai_walk(3);};
+void() knight_walk7 =[ $walk7, knight_walk8 ] {ai_walk(3);};
+void() knight_walk8 =[ $walk8, knight_walk9 ] {ai_walk(4);};
+void() knight_walk9 =[ $walk9, knight_walk10 ] {ai_walk(3);};
+void() knight_walk10 =[ $walk10, knight_walk11 ] {ai_walk(3);};
+void() knight_walk11 =[ $walk11, knight_walk12 ] {ai_walk(2);};
+void() knight_walk12 =[ $walk12, knight_walk13 ] {ai_walk(3);};
+void() knight_walk13 =[ $walk13, knight_walk14 ] {ai_walk(4);};
+void() knight_walk14 =[ $walk14, knight_walk1 ] {ai_walk(3);};
+
+
+void() knight_run1 =[ $runb1, knight_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "knight/idle.wav", 1, ATTN_IDLE);
+ai_run(16);};
+void() knight_run2 =[ $runb2, knight_run3 ] {ai_run(20);};
+void() knight_run3 =[ $runb3, knight_run4 ] {ai_run(13);};
+void() knight_run4 =[ $runb4, knight_run5 ] {ai_run(7);};
+void() knight_run5 =[ $runb5, knight_run6 ] {ai_run(16);};
+void() knight_run6 =[ $runb6, knight_run7 ] {ai_run(20);};
+void() knight_run7 =[ $runb7, knight_run8 ] {ai_run(14);};
+void() knight_run8 =[ $runb8, knight_run1 ] {ai_run(6);};
+
+
+void() knight_runatk1 =[ $runattack1, knight_runatk2 ]
+{
+if (random() > 0.5)
+ sound_misc (self, CHAN_WEAPON, "knight/sword2.wav", 1, ATTN_NORM);
+else
+ sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+ai_charge(20);
+};
+void() knight_runatk2 =[ $runattack2, knight_runatk3 ] {ai_charge_side();};
+void() knight_runatk3 =[ $runattack3, knight_runatk4 ] {ai_charge_side();};
+void() knight_runatk4 =[ $runattack4, knight_runatk5 ] {ai_charge_side();};
+void() knight_runatk5 =[ $runattack5, knight_runatk6 ] {ai_melee_side();};
+void() knight_runatk6 =[ $runattack6, knight_runatk7 ] {ai_melee_side();};
+void() knight_runatk7 =[ $runattack7, knight_runatk8 ] {ai_melee_side();};
+void() knight_runatk8 =[ $runattack8, knight_runatk9 ] {ai_melee_side();};
+void() knight_runatk9 =[ $runattack9, knight_runatk10 ] {ai_melee_side();};
+void() knight_runatk10 =[ $runattack10, knight_runatk11 ] {ai_charge_side();};
+void() knight_runatk11 =[ $runattack11, knight_run1 ] {ai_charge(10);};
+
+void() knight_atk1 =[ $attackb1, knight_atk2 ]
+{
+sound_attack(self, CHAN_WEAPON, "knight/sword1.wav", 1, ATTN_NORM);
+ai_charge(0);};
+void() knight_atk2 =[ $attackb2, knight_atk3 ] {ai_charge(7);};
+void() knight_atk3 =[ $attackb3, knight_atk4 ] {ai_charge(4);};
+void() knight_atk4 =[ $attackb4, knight_atk5 ] {ai_charge(0);};
+void() knight_atk5 =[ $attackb5, knight_atk6 ] {ai_charge(3);};
+void() knight_atk6 =[ $attackb6, knight_atk7 ] {ai_charge(4); ai_melee();};
+void() knight_atk7 =[ $attackb7, knight_atk8 ] {ai_charge(1); ai_melee();};
+void() knight_atk8 =[ $attackb8, knight_atk9 ] {ai_charge(3);
+ai_melee();};
+void() knight_atk9 =[ $attackb9, knight_atk10] {ai_charge(1);};
+void() knight_atk10=[ $attackb10, knight_run1 ] {ai_charge(5);};
+
+//void() knight_atk9 =[ $attack9, knight_atk10 ] {};
+//void() knight_atk10 =[ $attack10, knight_atk11 ] {};
+//void() knight_atk11 =[ $attack11, knight_run1 ] {};
+
+//===========================================================================
+
+void() knight_pain1 =[ $pain1, knight_pain2 ] {};
+void() knight_pain2 =[ $pain2, knight_pain3 ] {};
+void() knight_pain3 =[ $pain3, knight_run1 ] {};
+
+void() knight_painb1 =[ $painb1, knight_painb2 ] {ai_painforward(0);};
+void() knight_painb2 =[ $painb2, knight_painb3 ] {ai_painforward(3);};
+void() knight_painb3 =[ $painb3, knight_painb4 ] {};
+void() knight_painb4 =[ $painb4, knight_painb5 ] {};
+void() knight_painb5 =[ $painb5, knight_painb6 ] {ai_painforward(2);};
+void() knight_painb6 =[ $painb6, knight_painb7 ] {ai_painforward(4);};
+void() knight_painb7 =[ $painb7, knight_painb8 ] {ai_painforward(2);};
+void() knight_painb8 =[ $painb8, knight_painb9 ] {ai_painforward(5);};
+void() knight_painb9 =[ $painb9, knight_painb10 ] {ai_painforward(5);};
+void() knight_painb10 =[ $painb10, knight_painb11 ] {ai_painforward(0);};
+void() knight_painb11 =[ $painb11, knight_run1 ] {};
+
+void(entity attacker, float damage) knight_pain =
+{
+ local float r;
+
+ if (self.pain_finished > time)
+ return;
+
+ r = random();
+
+ sound_pain (self, CHAN_VOICE, "knight/khurt.wav", 1, ATTN_NORM);
+ if (r < 0.85)
+ {
+ knight_pain1 ();
+ self.pain_finished = time + 1;
+ }
+ else
+ {
+ knight_painb1 ();
+ self.pain_finished = time + 1;
+ }
+
+};
+
+//===========================================================================
+
+void() knight_bow1 =[ $kneel1, knight_bow2 ] {ai_turn();};
+void() knight_bow2 =[ $kneel2, knight_bow3 ] {ai_turn();};
+void() knight_bow3 =[ $kneel3, knight_bow4 ] {ai_turn();};
+void() knight_bow4 =[ $kneel4, knight_bow5 ] {ai_turn();};
+
+void() knight_bow5 =[ $kneel5, knight_bow5 ] {ai_turn();};
+
+void() knight_bow6 =[ $kneel4, knight_bow7 ] {ai_turn();};
+void() knight_bow7 =[ $kneel3, knight_bow8 ] {ai_turn();};
+void() knight_bow8 =[ $kneel2, knight_bow9 ] {ai_turn();};
+void() knight_bow9 =[ $kneel1, knight_bow10 ] {ai_turn();};
+void() knight_bow10 =[ $walk1, knight_walk1 ] {ai_turn();};
+
+
+
+void() knight_die1 =[ $death1, knight_die2 ] {};
+void() knight_die2 =[ $death2, knight_die3 ] {};
+void() knight_die3 =[ $death3, knight_die4 ] {self.solid = SOLID_NOT;};
+void() knight_die4 =[ $death4, knight_die5 ] {};
+void() knight_die5 =[ $death5, knight_die6 ] {};
+void() knight_die6 =[ $death6, knight_die7 ] {};
+void() knight_die7 =[ $death7, knight_die8 ] {};
+void() knight_die8 =[ $death8, knight_die9 ] {};
+void() knight_die9 =[ $death9, knight_die10] {};
+void() knight_die10=[ $death10, knight_die10] {};
+
+
+void() knight_dieb1 =[ $deathb1, knight_dieb2 ] {};
+void() knight_dieb2 =[ $deathb2, knight_dieb3 ] {};
+void() knight_dieb3 =[ $deathb3, knight_dieb4 ] {self.solid = SOLID_NOT;};
+void() knight_dieb4 =[ $deathb4, knight_dieb5 ] {};
+void() knight_dieb5 =[ $deathb5, knight_dieb6 ] {};
+void() knight_dieb6 =[ $deathb6, knight_dieb7 ] {};
+void() knight_dieb7 =[ $deathb7, knight_dieb8 ] {};
+void() knight_dieb8 =[ $deathb8, knight_dieb9 ] {};
+void() knight_dieb9 =[ $deathb9, knight_dieb10] {};
+void() knight_dieb10 = [ $deathb10, knight_dieb11] {};
+void() knight_dieb11 = [ $deathb11, knight_dieb11] {};
+
+
+void() knight_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_knight.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "knight/kdeath.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() < 0.5)
+ knight_die1 ();
+ else
+ knight_dieb1 ();
+};
+
+
+/*QUAKED monster_knight (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/knight.mdl");
+}
+Knight.
+
+Default heath = 75"
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (SWORD SLASH 1)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (SWORD SLASH 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/knight.mdl");
+ precache_head_model ("progs/h_knight.mdl");
+ //// dumptruck_ds
+ precache_sound_death ("knight/kdeath.wav");
+ precache_sound_pain ("knight/khurt.wav");
+ precache_sound_sight ("knight/ksight.wav");
+ precache_sound_attack ("knight/sword1.wav");
+ precache_sound_misc ("knight/sword2.wav");
+ precache_sound_idle ("knight/idle.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/knight.mdl"); // dumptruck_ds custom_mdls
+ // setmodel (self, "progs/knight.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 75;
+
+ self.th_stand = knight_stand1;
+ self.th_walk = knight_walk1;
+ self.th_run = knight_run1;
+ self.th_melee = knight_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = knight_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = knight_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_knight (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/knight.mdl","frame":96});
+}
+*/
+void() monster_dead_knight =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/knight.mdl");
+ setmodel(self, "progs/knight.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death10;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-25.56 -14.56 -50.49','26.45 40.2 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $deathb11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-30.36 -45.6 -50.18','28.29 11.59 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/ogre.qc

diff --git a/qc/monsters/ogre.qc b/qc/monsters/ogre.qc
index 0a1f132..66822b0 100644
--- a/qc/monsters/ogre.qc
+++ b/qc/monsters/ogre.qc
@@ -1,1571 +1,1571 @@
-float MONSTER_FLAK_OGRE = 4;
-float FL_NOSELECT = 8192; //ignored by entity selector
-.float spikecount; //bdw - saves up flak hits to do a single damage next frame - currently only used for flak ogre
-
-/*
-==============================================================================
-
-OGRE
-
-==============================================================================
-*/
-
-$cd id1/models/ogre_c
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
-$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
-$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
-$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
-
-$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame painb1 painb2 painb3
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
-$frame paind11 paind12 paind13 paind14 paind15 paind16
-
-$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
-$frame paine11 paine12 paine13 paine14 paine15
-
-$frame death1 death2 death3 death4 death5 death6
-$frame death7 death8 death9 death10 death11 death12
-$frame death13 death14
-
-$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
-$frame bdeath7 bdeath8 bdeath9 bdeath10
-
-$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
-
-//=============================================================================
-
-
-void() OgreGrenadeExplode =
-{
- T_RadiusDamage (self, self.owner, 40, world);
- sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- self.velocity = '0 0 0';
- self.touch = SUB_Null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
-};
-
-void() OgreGrenadeTouch =
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- OgreGrenadeExplode();
- return;
- }
- if (self.count < time) {
- sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- }
- self.count = time + .02;
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-//BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack... from Marcher -- dumptruck_ds
-
-void() FlakDoDamage =
-{
- self.origin = self.oldenemy.origin + self.oldorigin; //get correct gib direction
- T_Damage(self.oldenemy, self, self.owner, self.oldenemy.spikecount);
- self.oldenemy.spikecount = 0;
- remove(self);
-};
-
-void() FlakTouch =
-{
- if (other.solid == SOLID_TRIGGER)
- return;
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood(self.dmg);
-
- sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
-
- if (other.spikecount) //not the first one
- {
- other.spikecount = other.spikecount + self.dmg;
- remove(self);
- return;
- }
-
- // the first one...
-
- other.spikecount = self.dmg;
-
- // stick around for a little while...
- self.velocity = '0 0 0';
- self.solid = SOLID_NOT;
- self.touch = SUB_Null;
- self.model = string_null;
- self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
- self.oldenemy = other;
- self.think = FlakDoDamage;
- self.nextthink = time + 0.05;
- return;
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- if (self.spawnflags & MONSTER_FLAK_OGRE) //bit of a hack
- {
- remove(self);
- return;
- }
-
- self.dmg = self.dmg - 5; //gets weaker with each bounce. also stops them getting stuck in world.
- if (self.dmg <= 0)
- {
- remove(self);
- return;
- }
- self.velocity = self.velocity * 0.5; //reduce crazy ricochets
- self.movetype = MOVETYPE_BOUNCE;
-};
-
-void() BDW_OgreFireFlak =
-{
- local float flakcount;
- local vector dir, ang;
- local entity flak;
- local float projspeed = 800 * self.proj_speed_mod;
-
- flakcount = 8;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound(self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
-
-// make angles out of the current displacement vector...
- ang = vectoangles(self.enemy.origin - self.origin);
-// then get the required components...
- makevectors(ang);
-
- while (flakcount > 0)
- {
- //tighter spread...
- dir = v_forward*10 + crandom()*v_right + crandom()*v_up;
- dir = normalize(dir);
- // f*cking hack...is this a v_forward problem?
- dir_z = dir_z * -1;
- //dir = dir*1000;
- //dir = dir*800;
-
-
- flak = spawn();
-
- flak.owner = self;
- //flymissile is a bit too all-seeing for this gun...
- flak.movetype = MOVETYPE_FLY;
- //flak.movetype = MOVETYPE_FLYMISSILE;
- flak.solid = SOLID_BBOX;
- flak.flags = FL_NOSELECT;
- flak.touch = FlakTouch;
- flak.angles = vectoangles(dir);
- SetSpeed(flak, dir, projspeed);
- if (self.homing > 0)
- {
- SetupHoming(flak, projspeed);
- }
- else
- {
- flak.nextthink = time + 6;
- flak.think = SUB_Remove;
- }
- flak.dmg = 4;
-
- flak.spawnflags = MONSTER_FLAK_OGRE; //this is a hack to tell FlakTouch that it came from an ogre
- // setmodel(flak, "progs/spike.mdl");
- flak.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (flak, self.mdl_proj);
- }
- else
- {
- setmodel (flak, "progs/spike.mdl");
- }
-
- if (!flak.skin_proj) // dumptruck_ds
- {
- flak.skin = self.skin_proj;
- }
- else
- {
- flak.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize(flak, '0 0 0', '0 0 0');
- setorigin(flak, self.origin + '0 0 16');
-
- flakcount = flakcount - 1;
- }
-};
-/////////////////////////////////////////////////////////////
-/* start Preach Ogre Marksman tutorial here -- dumptruck_ds*/
-/////////////////////////////////////////////////////////////
-
-//speed an ogre grenade is fired at
-float OGRE_G_VEL = 600;
-
-//fixme: get the correct gravity strength for the level
-float pgrav = 800;
-
-//a default angle to fire at if the enemy is too far away
-float OGRE_DEFAULT_ELEVATION = 30;
-
-//uses QuakeC builtins to calculate tan of angle
-//WARNING: uses makevectors! This overwrites the v_forward... globals
-float(float theta) tan =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_y = theta; //assign theta to the yaw to simplify reasoning
- makevectors(ang);
- return v_forward_y / v_forward_x;
-}
-
-//inverse tan function
-//takes two parameters, numerator and denominator
-//this copes better with denominator 0 and gets quadrant correct
-/*
-float(float y, float x) atan2 =
-{
- local vector ang; //temporary used to calculate trig values
- ang = '0 0 0';
- ang_x = x;
- ang_y = y;
- return vectoyaw(ang);
-}
-*/
-
-float(float theta, vector dest) IterateElevation =
-{
- local float a, b, c; //constants in the equation to be solved
- local vector ofs; //displacement we wish the projectile to travel
- local float y, z; //horizontal and vertical components of ofs
- local float tan_theta; //trig values of the angle theta
-
- //calculate how far we are firing
- ofs = dest - self.origin;
- z = ofs_z;
- ofs_z = 0;
- y = vlen(ofs);
-
- //find the coefficients of the quadratic in tan(theta)
- a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
- b = -y;
- c = a + z;
-
- //check if the destination is too far to reach
- if(b*b < 4*a*c)
- return OGRE_DEFAULT_ELEVATION;
-
- //calculate the tan value of the given theta
- tan_theta = tan(theta);
-
- //reuse ang to create the improved firing direction
- theta = atan2(a*tan_theta*tan_theta - c,
- 2*a*tan_theta + b);
-
- //constrain the values to stop anything too mad happening
- while(theta > 90)
- theta = theta - 180;
- return theta;
-}
-/*
-================
-PreachFireGrenade
-================
-*/
-void(float elevation) PreachFireGrenade =
-{
- local entity missile;
- local vector ang;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-PreachFireZombie
-for Z-Aware Zombies in Turret Mode only
-================
-*/
-void(float elevation) PreachFireZombie =
-{
- local entity missile;
- local vector ang;
-
- // self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
- ang = self.angles;
- ang_x = -elevation;
- makevectors (ang);
-
- missile.velocity = v_forward * OGRE_G_VEL;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-// end Preach tutorial
-
-/*
-================
-OgreFireGrenade
-================
-*/
-void() MultiGrenadeTouch;
-void() MultiGrenadeExplode;
-
-void() OgreFireGrenade =
-{
- local entity missile;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-// set missile speed
-
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
- // set missile duration
- if(self.style == 3)
- {
- missile.touch = MultiGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- missile.classname = "MultiGrenade";
- }
- else
- {
- missile.touch = OgreGrenadeTouch;
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
- // setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
- }
- };
-
- // missile.touch = OgreGrenadeTouch;
-
-// // set missile duration
-// missile.nextthink = time + 2.5;
-// missile.think = OgreGrenadeExplode;
-//
-// setmodel (missile, "progs/grenade.mdl");
-// setsize (missile, '0 0 0', '0 0 0');
-// setorigin (missile, self.origin);
-// };
-
-/*
-================
-OgreFireSpike from insideqc tutorial here: http://www.insideqc.com/qctut/lesson-33.shtml
-================
-*/
-void() OgreFireSpike =
-{
- local vector dir;
- // local entity old;
-
-
- sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
- self.attack_finished = time + .7;
- // self.attack_finished = time + 0.2;
- self.effects = self.effects | EF_MUZZLEFLASH; // -- dumptruck_ds
-
- dir = normalize (self.enemy.origin - self.origin);
-
- launch_spike (self.origin + v_right * 4 + '0 0 16', dir);
-
- newmis.touch = superduperspike_touch; //dumptruck_ds found in client.qc
- // setmodel (newmis, "progs/lspike.mdl");
- newmis.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lspike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
-//=============================================================================
-// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
-//=============================================================================
-void() MultiGrenadeTouch;
-
-//================================
-//================================
-void() MiniGrenadeExplode =
-{
- if ( self.owner.classname == "player")
- T_RadiusDamage (self, self.owner, 90, world);
- else
- T_RadiusDamage (self, self.owner, 60, world);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- WriteByte (MSG_BROADCAST, 230);
- WriteByte (MSG_BROADCAST, 5);
-
- BecomeExplosion ();
-};
-
-//================================
-//================================
-void(float offsetAngle) MiniGrenadeLaunch =
-{
- local entity missile/*, mpuff*/;
- local float tempRand;
-
- missile = spawn ();
- missile.owner = self.owner;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "MiniGrenade";
-
-// set missile speed
- missile.v_angle = self.v_angle;
- missile.v_angle_y = missile.v_angle_y + offsetAngle;
- makevectors (missile.v_angle);
-
- missile.velocity = v_forward*100 + v_up*400;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_forward;
- tempRand = (crandom()*40) - 20;
- missile.velocity = missile.velocity + tempRand * v_right;
- tempRand = (crandom()*60) - 30;
- missile.velocity = missile.velocity + tempRand * v_up;
-
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
- missile.touch = MultiGrenadeTouch;
-
- setmodel (missile, "progs/mervup.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-
-// set missile duration
- missile.nextthink = time + 1 + (crandom() * 0.5);
- missile.think = MiniGrenadeExplode;
-};
-
-//================================
-//================================
-void() MultiGrenadeExplode =
-{
- MiniGrenadeLaunch(0);
- MiniGrenadeLaunch(72);
- MiniGrenadeLaunch(144);
- MiniGrenadeLaunch(216);
- MiniGrenadeLaunch(288);
-
- remove (self);
-};
-
-//================================
-//================================
-void() MultiGrenadeTouch =
-{
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- if (self.classname == "MiniGrenade")
- MiniGrenadeExplode();
- else
- {
- if (self.owner.classname == "player")
- GrenadeExplode();
- else
- MiniGrenadeExplode();
- }
- return;
- }
- // bounce sound
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-//================================
-//================================
-void() W_FireMultiGrenade =
-{
- local entity missile/*, mpuff*/;
-
- // self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
- // UpdateAmmoCounts (self);
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- // self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "MultiGrenade";
-
- makevectors (self.angles);
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- missile.avelocity = '300 300 300';
- missile.angles = vectoangles(missile.velocity);
-
-
-// set missile speed
- // makevectors (self.v_angle);
- // if (self.v_angle_x)
- // missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- // else
- // {
- // missile.velocity = aim(self, 10000);
- // missile.velocity = missile.velocity * 600;
- // missile.velocity_z = 200;
- // }
- //
- // missile.avelocity = '300 300 300';
- // missile.angles = vectoangles(missile.velocity);
- missile.touch = MultiGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 1;
- missile.think = MultiGrenadeExplode;
- setmodel (missile, "progs/mervup.mdl");
- missile.skin = self.skin_proj; //dumptruck_ds
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 16');
-};
-
-//=============================================================================
-//end doe qc -- dumptruck_ds
-//=============================================================================
-/*
-================
-OgreFireLavaBall by jaycie erysdren 2021-09-14
-================
-*/
-
-void() OgreFireLavaBall =
-{
- local vector offang;
- local vector org, vec, d;
- // local float t;
-
- offang = vectoangles (self.enemy.origin - self.origin);
- makevectors (offang);
-
- org = self.origin; // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
-
-// lead the player on hard mode
- // if (skill > 1)
- // {
- // t = vlen(self.enemy.origin - org) / 300;
- // vec = self.enemy.velocity;
- // vec_z = 0;
- // d = self.enemy.origin + t * vec;
- // }
- // else
- // {
- d = self.enemy.origin;
- // }
-
- vec = normalize (d - org);
-
- // launch_spike (org, vec);
- launch_spike2 (self.origin + v_right * 4 + '0 0 16', vec, 600);
- self.effects = self.effects | EF_MUZZLEFLASH;
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/lavaball.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- newmis.avelocity = self.cust_avelocity;
- if !(newmis.avelocity)
- newmis.avelocity = '200 100 300';
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- // newmis.touch = T_MissileTouch; // rocket explosion
- newmis.touch = OgreGrenadeExplode;
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
-
-};
-
-/*
-================
-chainsaw
-
-FIXME
-================
-*/
-void(float side) chainsaw =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- ai_charge(10);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 4;
- T_Damage (self.enemy, self, self, ldmg);
-
- if (side)
- {
- makevectors (self.angles);
- if (side == 1)
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
- else
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
-
-void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
-void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
-void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
-void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
-void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-ai_stand();
-};
-void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
-void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
-void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
-void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
-
-void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
-void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
-void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
-ai_walk(2);
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
-void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
-void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
-ai_walk(5);
-if (random() < 0.1)
- sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
-};
-void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
-void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
-void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
-void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
-void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
-void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
-void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
-void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
-void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
-void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
-
-void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
-if (random() < 0.2)
- sound_misc1 (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
-};
-void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
-void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
-void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
-void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
-void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
-void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
-void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
-
-void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
-void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
-void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
-void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
-void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
-void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
-void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
-void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
-
-void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
-sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
-};
-void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
-void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
-void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
-void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
-void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
-void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
-void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
-void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
-void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
-// self.nextthink = self.nextthink + random()*0.2;}; // slight variation
-self.nextthink = time + 0.1 + random()*0.2;}; // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
-void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);};
-void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
-void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
-
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-.float attack_elevation;
-void() ogre2_nail1 =[ $shoot1, ogre2_nail2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_nail2 =[ $shoot2, ogre2_nail3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail3 =[ $shoot2, ogre2_nail4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);
-};
-// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
-// these are for the turret version of monster_ogre_marksman
-.float attack_elevation;
-void() ogre2_turret_attack1 =[ $shoot1, ogre2_turret_attack2 ] {ai_face();
-self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() ogre2_turret_attack2 =[ $shoot2, ogre2_turret_attack3 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack3 =[ $shoot2, ogre2_turret_attack4 ] {ai_face();
-self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() ogre2_turret_attack4 =[ $shoot3, ogre2_turret_attack5 ] {ai_face();
- PreachFireGrenade(self.attack_elevation);};
-void() ogre2_turret_attack5 =[ $shoot4, ogre2_turret_attack6 ] {ai_face();};
-void() ogre2_turret_attack6 =[ $shoot5, ogre2_turret_attack7 ] {ai_face();};
-void() ogre2_turret_attack7 =[ $shoot5, ogre2_turret_attack8 ] {ai_face();};
-void() ogre2_turret_attack8 =[ $shoot6, ogre2_turret_attack9 ] {ai_face();};
-void() ogre2_turret_attack9 =[ $shoot6, ogre2_turret_seek1 ] {ai_face();};
-void() ogre2_turret_seek1 =[ $stand1, ogre2_turret_seek2 ] {ai_run(0);};
-void() ogre2_turret_seek2 =[ $stand2, ogre2_turret_seek3 ] {ai_run(0);};
-void() ogre2_turret_seek3 =[ $stand3, ogre2_turret_seek4 ] {ai_run(0);};
-void() ogre2_turret_seek4 =[ $stand4, ogre2_turret_seek5 ] {ai_run(0);};
-void() ogre2_turret_seek5 =[ $stand5, ogre2_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre2_turret_seek6 =[ $stand6, ogre2_turret_seek7 ] {ai_run(0);};
-void() ogre2_turret_seek7 =[ $stand7, ogre2_turret_seek8 ] {ai_run(0);};
-void() ogre2_turret_seek8 =[ $stand8, ogre2_turret_seek9 ] {ai_run(0);};
-void() ogre2_turret_seek9 =[ $stand9, ogre2_turret_seek1 ] {ai_run(0);};
-
-//end Preach -- dumptruck_ds
-void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
-void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
-void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
-void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
- if (self.style == 0)
- {
- OgreFireGrenade();
- }
- if (self.style == 1)
- {
- BDW_OgreFireFlak();
- // OgreFireSpike();
- }
- else if (self.style == 2)
- {
- OgreFireSpike();
- }
- if (self.style == 3)
- {
- W_FireMultiGrenade();
- }
- if (self.style == 4) // jaycie erysdren 2021-09-14
- {
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
- }
-};
-void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
-void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
-void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
-//
-////////////////////////
-// turret frames START
-////////////////////////
-//
-void() ogre_turret_attack1 =[ $shoot1, ogre_turret_attack2 ] {ai_face();};
-void() ogre_turret_attack2 =[ $shoot2, ogre_turret_attack3 ] {ai_face();};
-void() ogre_turret_attack3 =[ $shoot2, ogre_turret_attack4 ] {ai_face();};
-void() ogre_turret_attack4 =[ $shoot3, ogre_turret_attack5 ] {ai_face();
- if (self.style == 0)
- {
- OgreFireGrenade();
- }
- if (self.style == 1)
- {
- BDW_OgreFireFlak();
- // OgreFireSpike();
- }
- else if (self.style == 2)
- {
- OgreFireSpike();
- }
- if (self.style == 3)
- {
- W_FireMultiGrenade();
- }
- if (self.style == 4) // jaycie erysdren 2021-09-14
- {
- OgreFireLavaBall();
- sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
- }
-};
-void() ogre_turret_attack5 =[ $shoot4, ogre_turret_attack6 ] {ai_face();};
-
-void() ogre_turret_attack6=[ $shoot5, ogre_turret_attack7 ] {ai_face();};
-void() ogre_turret_attack7=[ $shoot5, ogre_turret_attack8 ] {ai_face();};
-void() ogre_turret_attack8=[ $shoot6, ogre_turret_attack9 ] {ai_face();};
-void() ogre_turret_attack9=[ $shoot6, ogre_turret_seek1 ] {ai_face();};
-void() ogre_turret_seek1 =[ $stand1, ogre_turret_seek2 ] {ai_run(0);};
-void() ogre_turret_seek2 =[ $stand2, ogre_turret_seek3 ] {ai_run(0);};
-void() ogre_turret_seek3 =[ $stand3, ogre_turret_seek4 ] {ai_run(0);};
-void() ogre_turret_seek4 =[ $stand4, ogre_turret_seek5 ] {ai_run(0);};
-void() ogre_turret_seek5 =[ $stand5, ogre_turret_seek6 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
- ai_run(0);
-};
-void() ogre_turret_seek6 =[ $stand6, ogre_turret_seek7 ] {ai_run(0);};
-void() ogre_turret_seek7 =[ $stand7, ogre_turret_seek8 ] {ai_run(0);};
-void() ogre_turret_seek8 =[ $stand8, ogre_turret_seek9 ] {ai_run(0);};
-void() ogre_turret_seek9 =[ $stand9, ogre_turret_seek1 ] {ai_run(0);};
-////////////////////////
-//turret frames END
-///////////////////////
-void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
-void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
-void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
-void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
-void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
-
-
-void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
-void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
-void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
-
-
-void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
-void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
-void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
-void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
-void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
-void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
-
-
-void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
-void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
-void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
-void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
-void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
-void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
-void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
-void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
-void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
-void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
-void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
-void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
-void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
-void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
-void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
-void() ogre_paind16=[ $paind16, ogre_run1 ] {};
-
-void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
-void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
-void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
-void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
-void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
-void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
-void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
-void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
-void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
-void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
-void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
-void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
-void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
-void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
-void() ogre_paine15=[ $paine15, ogre_run1 ] {};
-
-
-void(entity attacker, float damage) ogre_pain =
-{
- local float r;
-
-// don't make multiple pain sounds right after each other
- if (self.pain_finished > time)
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- return;
-
- sound_pain (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
-
- r = random();
-
- if (r < 0.25)
- {
- ogre_pain1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.5)
- {
- ogre_painb1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.75)
- {
- ogre_painc1 ();
- self.pain_finished = time + 1;
- }
- else if (r < 0.88)
- {
- ogre_paind1 ();
- self.pain_finished = time + 2;
- }
- else
- {
- ogre_paine1 ();
- self.pain_finished = time + 2;
- }
-};
-
-void() ogre_die1 =[ $death1, ogre_die2 ] {};
-void() ogre_die2 =[ $death2, ogre_die3 ] {};
-void() ogre_die3 =[ $death3, ogre_die4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1) // flak style
- {
- self.ammo_nails = 5;
- }
- if (self.style == 2) // super nail style
- {
- self.ammo_nails = 5;
- }
- if (self.style == 3) //DOE multi-grenade
- {
- self.ammo_rockets = 2;
- }
- else if (self.style == 0) //default Ogre
- {
- self.ammo_rockets = 2;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() ogre_die4 =[ $death4, ogre_die5 ] {};
-void() ogre_die5 =[ $death5, ogre_die6 ] {};
-void() ogre_die6 =[ $death6, ogre_die7 ] {};
-void() ogre_die7 =[ $death7, ogre_die8 ] {};
-void() ogre_die8 =[ $death8, ogre_die9 ] {};
-void() ogre_die9 =[ $death9, ogre_die10 ] {};
-void() ogre_die10 =[ $death10, ogre_die11 ] {};
-void() ogre_die11 =[ $death11, ogre_die12 ] {};
-void() ogre_die12 =[ $death12, ogre_die13 ] {};
-void() ogre_die13 =[ $death13, ogre_die14 ] {};
-void() ogre_die14 =[ $death14, ogre_die14 ] {};
-
-void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
-void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
-void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
-{self.solid = SOLID_NOT;
- // style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_nails = 5;
- }
- if (self.style == 2)
- {
- self.ammo_nails = 5;
- }
- if (self.style == 3) //DOE multi-grenade
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 4) // lavaball ogre jaycie erysdren 2021-09-14
- {
- self.ammo_rockets = 2;
- }
- else if (self.style == 0)
- {
- self.ammo_rockets = 2;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
-void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
-void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
-void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
-void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
-void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
-void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
-
-void() ogre_die =
-{
-// check for gib
- if (self.health < -80)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_ogre.mdl", self.health);
- }
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
- sound_death (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
-
- DropStuff();
- if (random() < 0.5)
- ogre_die1 ();
- else
- ogre_bdie1 ();
-};
-
-void() ogre_melee =
-{
- if (random() > 0.5)
- ogre_smash1 ();
- else
- ogre_swing1 ();
-};
-
-
-/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/ogre.mdl");
-}
-Ogre.
-
-Default health = 200"
-
-style(Choices) : "Attack type" =
-0 : "Default (grenade)"
-1 : "Flak Ogre (Marcher, Quoth)"
-2 : "sniper (shoots single, deadly lava round)"
-3 : "multi-grenade (Mission Pack 2)"
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
-snd_idle(string) : "Path to custom idle sound (IDLE)"
-snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
-snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- // custom_mdls dumptruck_ds
- precache_model ("progs/mervup.mdl"); //for style 3 Orge dumptruck_ds
- precache_model ("progs/lspike.mdl"); //for style 2 Ogre dumptruck_ds
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
- precache_sound_misc2 ("shalrath/attack2.wav");
- precache_sound ("fish/bite.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
-
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = ogre_turret_seek1;
- }
- else
- {
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre_nail1;
- self.th_turret = ogre_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
-model ({ "path" : "progs/ogre.mdl", "frame": 63 });
-}
-Ogre Marksman.
-Unlike vanilla Quake, this is a slightly more accurate Orge.
-
-keep_ammo(integer) : "1 = Don't drop backpack upon death"
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
-snd_idle(string) : "Path to custom idle sound (IDLE)"
-snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
-snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_ogre_marksman =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- // custom_mdls dumptruck_ds
- precache_body_model ("progs/ogre.mdl");
- precache_head_model ("progs/h_ogre.mdl");
- precache_proj_model ("progs/grenade.mdl");
-
- precache_sound_misc ("ogre/ogdrag.wav");
- precache_sound_death ("ogre/ogdth.wav");
- precache_sound_idle ("ogre/ogidle.wav");
- precache_sound_misc1 ("ogre/ogidle2.wav");
- precache_sound_pain ("ogre/ogpain1.wav");
- precache_sound_attack ("ogre/ogsawatk.wav");
- precache_sound_sight ("ogre/ogwake.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- // custom_mdls dumptruck_ds
- body_model ("progs/ogre.mdl");
- // setmodel (self, "progs/ogre.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 200;
-
- self.th_stand = ogre_stand1;
- self.th_walk = ogre_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = ogre2_turret_seek1;
- }
- else
- {
- self.th_run = ogre_run1;
- }
- self.th_die = ogre_die;
- self.th_melee = ogre_melee;
- self.th_missile = ogre2_nail1;
- self.th_turret = ogre2_turret_attack1; //dumptruck_ds
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = ogre_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-
-// {
-// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
-// return;
-//
-// monster_ogre ();
-// };
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_ogre (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/ogre.mdl","frame":135});
-}
-*/
-void() monster_dead_ogre =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/ogre.mdl");
- setmodel(self, "progs/ogre.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death14;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-40.64 -54.06 -54.1','29.42 54.63 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $bdeath10;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-45.64 -29.46 -54.52','33.87 39.18 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};
+float MONSTER_FLAK_OGRE = 4;
+float FL_NOSELECT = 8192; //ignored by entity selector
+.float spikecount; //bdw - saves up flak hits to do a single damage next frame - currently only used for flak ogre
+
+/*
+==============================================================================
+
+OGRE
+
+==============================================================================
+*/
+
+$cd id1/models/ogre_c
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
+$frame walk8 walk9 walk10 walk11 walk12 walk13 walk14 walk15 walk16
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame swing1 swing2 swing3 swing4 swing5 swing6 swing7
+$frame swing8 swing9 swing10 swing11 swing12 swing13 swing14
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
+$frame smash8 smash9 smash10 smash11 smash12 smash13 smash14
+
+$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame painb1 painb2 painb3
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
+$frame paind11 paind12 paind13 paind14 paind15 paind16
+
+$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
+$frame paine11 paine12 paine13 paine14 paine15
+
+$frame death1 death2 death3 death4 death5 death6
+$frame death7 death8 death9 death10 death11 death12
+$frame death13 death14
+
+$frame bdeath1 bdeath2 bdeath3 bdeath4 bdeath5 bdeath6
+$frame bdeath7 bdeath8 bdeath9 bdeath10
+
+$frame pull1 pull2 pull3 pull4 pull5 pull6 pull7 pull8 pull9 pull10 pull11
+
+//=============================================================================
+
+
+void() OgreGrenadeExplode =
+{
+ T_RadiusDamage (self, self.owner, 40, world);
+ sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ self.velocity = '0 0 0';
+ self.touch = SUB_Null;
+ setmodel (self, "progs/s_explod.spr");
+ self.solid = SOLID_NOT;
+ s_explode1 ();
+};
+
+void() OgreGrenadeTouch =
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ OgreGrenadeExplode();
+ return;
+ }
+ if (self.count < time) {
+ sound (self, CHAN_VOICE, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
+ }
+ self.count = time + .02;
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+//BDW 31/08/00 - evil, nasty red-hot nail cluster-bomb attack... from Marcher -- dumptruck_ds
+
+void() FlakDoDamage =
+{
+ self.origin = self.oldenemy.origin + self.oldorigin; //get correct gib direction
+ T_Damage(self.oldenemy, self, self.owner, self.oldenemy.spikecount);
+ self.oldenemy.spikecount = 0;
+ remove(self);
+};
+
+void() FlakTouch =
+{
+ if (other.solid == SOLID_TRIGGER)
+ return;
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood(self.dmg);
+
+ sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+
+ if (other.spikecount) //not the first one
+ {
+ other.spikecount = other.spikecount + self.dmg;
+ remove(self);
+ return;
+ }
+
+ // the first one...
+
+ other.spikecount = self.dmg;
+
+ // stick around for a little while...
+ self.velocity = '0 0 0';
+ self.solid = SOLID_NOT;
+ self.touch = SUB_Null;
+ self.model = string_null;
+ self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
+ self.oldenemy = other;
+ self.think = FlakDoDamage;
+ self.nextthink = time + 0.05;
+ return;
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ if (self.spawnflags & MONSTER_FLAK_OGRE) //bit of a hack
+ {
+ remove(self);
+ return;
+ }
+
+ self.dmg = self.dmg - 5; //gets weaker with each bounce. also stops them getting stuck in world.
+ if (self.dmg <= 0)
+ {
+ remove(self);
+ return;
+ }
+ self.velocity = self.velocity * 0.5; //reduce crazy ricochets
+ self.movetype = MOVETYPE_BOUNCE;
+};
+
+void() BDW_OgreFireFlak =
+{
+ local float flakcount;
+ local vector dir, ang;
+ local entity flak;
+ local float projspeed = 800 * self.proj_speed_mod;
+
+ flakcount = 8;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound(self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+
+// make angles out of the current displacement vector...
+ ang = vectoangles(self.enemy.origin - self.origin);
+// then get the required components...
+ makevectors(ang);
+
+ while (flakcount > 0)
+ {
+ //tighter spread...
+ dir = v_forward*10 + crandom()*v_right + crandom()*v_up;
+ dir = normalize(dir);
+ // f*cking hack...is this a v_forward problem?
+ dir_z = dir_z * -1;
+ //dir = dir*1000;
+ //dir = dir*800;
+
+
+ flak = spawn();
+
+ flak.owner = self;
+ //flymissile is a bit too all-seeing for this gun...
+ flak.movetype = MOVETYPE_FLY;
+ //flak.movetype = MOVETYPE_FLYMISSILE;
+ flak.solid = SOLID_BBOX;
+ flak.flags = FL_NOSELECT;
+ flak.touch = FlakTouch;
+ flak.angles = vectoangles(dir);
+ SetSpeed(flak, dir, projspeed);
+ if (self.homing > 0)
+ {
+ SetupHoming(flak, projspeed);
+ }
+ else
+ {
+ flak.nextthink = time + 6;
+ flak.think = SUB_Remove;
+ }
+ flak.dmg = 4;
+
+ flak.spawnflags = MONSTER_FLAK_OGRE; //this is a hack to tell FlakTouch that it came from an ogre
+ // setmodel(flak, "progs/spike.mdl");
+ flak.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (flak, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (flak, "progs/spike.mdl");
+ }
+
+ if (!flak.skin_proj) // dumptruck_ds
+ {
+ flak.skin = self.skin_proj;
+ }
+ else
+ {
+ flak.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize(flak, '0 0 0', '0 0 0');
+ setorigin(flak, self.origin + '0 0 16');
+
+ flakcount = flakcount - 1;
+ }
+};
+/////////////////////////////////////////////////////////////
+/* start Preach Ogre Marksman tutorial here -- dumptruck_ds*/
+/////////////////////////////////////////////////////////////
+
+//speed an ogre grenade is fired at
+float OGRE_G_VEL = 600;
+
+//fixme: get the correct gravity strength for the level
+float pgrav = 800;
+
+//a default angle to fire at if the enemy is too far away
+float OGRE_DEFAULT_ELEVATION = 30;
+
+//uses QuakeC builtins to calculate tan of angle
+//WARNING: uses makevectors! This overwrites the v_forward... globals
+float(float theta) tan =
+{
+ local vector ang; //temporary used to calculate trig values
+ ang = '0 0 0';
+ ang_y = theta; //assign theta to the yaw to simplify reasoning
+ makevectors(ang);
+ return v_forward_y / v_forward_x;
+}
+
+//inverse tan function
+//takes two parameters, numerator and denominator
+//this copes better with denominator 0 and gets quadrant correct
+/*
+float(float y, float x) atan2 =
+{
+ local vector ang; //temporary used to calculate trig values
+ ang = '0 0 0';
+ ang_x = x;
+ ang_y = y;
+ return vectoyaw(ang);
+}
+*/
+
+float(float theta, vector dest) IterateElevation =
+{
+ local float a, b, c; //constants in the equation to be solved
+ local vector ofs; //displacement we wish the projectile to travel
+ local float y, z; //horizontal and vertical components of ofs
+ local float tan_theta; //trig values of the angle theta
+
+ //calculate how far we are firing
+ ofs = dest - self.origin;
+ z = ofs_z;
+ ofs_z = 0;
+ y = vlen(ofs);
+
+ //find the coefficients of the quadratic in tan(theta)
+ a = 0.5 * pgrav * y * y / (OGRE_G_VEL * OGRE_G_VEL);
+ b = -y;
+ c = a + z;
+
+ //check if the destination is too far to reach
+ if(b*b < 4*a*c)
+ return OGRE_DEFAULT_ELEVATION;
+
+ //calculate the tan value of the given theta
+ tan_theta = tan(theta);
+
+ //reuse ang to create the improved firing direction
+ theta = atan2(a*tan_theta*tan_theta - c,
+ 2*a*tan_theta + b);
+
+ //constrain the values to stop anything too mad happening
+ while(theta > 90)
+ theta = theta - 180;
+ return theta;
+}
+/*
+================
+PreachFireGrenade
+================
+*/
+void(float elevation) PreachFireGrenade =
+{
+ local entity missile;
+ local vector ang;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+ ang = self.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+// end Preach tutorial
+
+/*
+================
+PreachFireZombie
+for Z-Aware Zombies in Turret Mode only
+================
+*/
+void(float elevation) PreachFireZombie =
+{
+ local entity missile;
+ local vector ang;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+ ang = self.angles;
+ ang_x = -elevation;
+ makevectors (ang);
+
+ missile.velocity = v_forward * OGRE_G_VEL;
+
+ missile.avelocity = '3000 1000 2000';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = ZombieGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = SUB_Remove;
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/zom_gib.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+// end Preach tutorial
+
+/*
+================
+OgreFireGrenade
+================
+*/
+void() MultiGrenadeTouch;
+void() MultiGrenadeExplode;
+
+void() OgreFireGrenade =
+{
+ local entity missile;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+// set missile speed
+
+ makevectors (self.angles);
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+
+ // set missile duration
+ if(self.style == 3)
+ {
+ missile.touch = MultiGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+ missile.classname = "MultiGrenade";
+ }
+ else
+ {
+ missile.touch = OgreGrenadeTouch;
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+ // setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+ }
+ };
+
+ // missile.touch = OgreGrenadeTouch;
+
+// // set missile duration
+// missile.nextthink = time + 2.5;
+// missile.think = OgreGrenadeExplode;
+//
+// setmodel (missile, "progs/grenade.mdl");
+// setsize (missile, '0 0 0', '0 0 0');
+// setorigin (missile, self.origin);
+// };
+
+/*
+================
+OgreFireSpike from insideqc tutorial here: http://www.insideqc.com/qctut/lesson-33.shtml
+================
+*/
+void() OgreFireSpike =
+{
+ local vector dir;
+ // local entity old;
+
+
+ sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
+ self.attack_finished = time + .7;
+ // self.attack_finished = time + 0.2;
+ self.effects = self.effects | EF_MUZZLEFLASH; // -- dumptruck_ds
+
+ dir = normalize (self.enemy.origin - self.origin);
+
+ launch_spike (self.origin + v_right * 4 + '0 0 16', dir);
+
+ newmis.touch = superduperspike_touch; //dumptruck_ds found in client.qc
+ // setmodel (newmis, "progs/lspike.mdl");
+ newmis.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lspike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+};
+//=============================================================================
+// Multi Grenade Code from doe progs MULT_WPN.QC -- dumptruck_ds
+//=============================================================================
+void() MultiGrenadeTouch;
+
+//================================
+//================================
+void() MiniGrenadeExplode =
+{
+ if ( self.owner.classname == "player")
+ T_RadiusDamage (self, self.owner, 90, world);
+ else
+ T_RadiusDamage (self, self.owner, 60, world);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION2);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ WriteByte (MSG_BROADCAST, 230);
+ WriteByte (MSG_BROADCAST, 5);
+
+ BecomeExplosion ();
+};
+
+//================================
+//================================
+void(float offsetAngle) MiniGrenadeLaunch =
+{
+ local entity missile/*, mpuff*/;
+ local float tempRand;
+
+ missile = spawn ();
+ missile.owner = self.owner;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "MiniGrenade";
+
+// set missile speed
+ missile.v_angle = self.v_angle;
+ missile.v_angle_y = missile.v_angle_y + offsetAngle;
+ makevectors (missile.v_angle);
+
+ missile.velocity = v_forward*100 + v_up*400;
+ tempRand = (crandom()*60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_forward;
+ tempRand = (crandom()*40) - 20;
+ missile.velocity = missile.velocity + tempRand * v_right;
+ tempRand = (crandom()*60) - 30;
+ missile.velocity = missile.velocity + tempRand * v_up;
+
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = MultiGrenadeTouch;
+
+ setmodel (missile, "progs/mervup.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+
+// set missile duration
+ missile.nextthink = time + 1 + (crandom() * 0.5);
+ missile.think = MiniGrenadeExplode;
+};
+
+//================================
+//================================
+void() MultiGrenadeExplode =
+{
+ MiniGrenadeLaunch(0);
+ MiniGrenadeLaunch(72);
+ MiniGrenadeLaunch(144);
+ MiniGrenadeLaunch(216);
+ MiniGrenadeLaunch(288);
+
+ remove (self);
+};
+
+//================================
+//================================
+void() MultiGrenadeTouch =
+{
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ if (self.classname == "MiniGrenade")
+ MiniGrenadeExplode();
+ else
+ {
+ if (self.owner.classname == "player")
+ GrenadeExplode();
+ else
+ MiniGrenadeExplode();
+ }
+ return;
+ }
+ // bounce sound
+ sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+//================================
+//================================
+void() W_FireMultiGrenade =
+{
+ local entity missile/*, mpuff*/;
+
+ // self.currentammo = self.ammo_multi_rockets = self.ammo_multi_rockets - 1;
+ // UpdateAmmoCounts (self);
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ // self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "MultiGrenade";
+
+ makevectors (self.angles);
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ missile.avelocity = '300 300 300';
+ missile.angles = vectoangles(missile.velocity);
+
+
+// set missile speed
+ // makevectors (self.v_angle);
+ // if (self.v_angle_x)
+ // missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ // else
+ // {
+ // missile.velocity = aim(self, 10000);
+ // missile.velocity = missile.velocity * 600;
+ // missile.velocity_z = 200;
+ // }
+ //
+ // missile.avelocity = '300 300 300';
+ // missile.angles = vectoangles(missile.velocity);
+ missile.touch = MultiGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 1;
+ missile.think = MultiGrenadeExplode;
+ setmodel (missile, "progs/mervup.mdl");
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 16');
+};
+
+//=============================================================================
+//end doe qc -- dumptruck_ds
+//=============================================================================
+/*
+================
+OgreFireLavaBall by jaycie erysdren 2021-09-14
+================
+*/
+
+void() OgreFireLavaBall =
+{
+ local vector offang;
+ local vector org, vec, d;
+ // local float t;
+
+ offang = vectoangles (self.enemy.origin - self.origin);
+ makevectors (offang);
+
+ org = self.origin; // + p_x*v_forward + p_y*v_right + p_z*'0 0 1';
+
+// lead the player on hard mode
+ // if (skill > 1)
+ // {
+ // t = vlen(self.enemy.origin - org) / 300;
+ // vec = self.enemy.velocity;
+ // vec_z = 0;
+ // d = self.enemy.origin + t * vec;
+ // }
+ // else
+ // {
+ d = self.enemy.origin;
+ // }
+
+ vec = normalize (d - org);
+
+ // launch_spike (org, vec);
+ launch_spike2 (self.origin + v_right * 4 + '0 0 16', vec, 600);
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/lavaball.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ newmis.avelocity = self.cust_avelocity;
+ if !(newmis.avelocity)
+ newmis.avelocity = '200 100 300';
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ // newmis.touch = T_MissileTouch; // rocket explosion
+ newmis.touch = OgreGrenadeExplode;
+ sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+
+};
+
+/*
+================
+chainsaw
+
+FIXME
+================
+*/
+void(float side) chainsaw =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ ai_charge(10);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 4;
+ T_Damage (self.enemy, self, self, ldmg);
+
+ if (side)
+ {
+ makevectors (self.angles);
+ if (side == 1)
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+ else
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+ }
+};
+
+void() ogre_stand1 =[ $stand1, ogre_stand2 ] {ai_stand();};
+void() ogre_stand2 =[ $stand2, ogre_stand3 ] {ai_stand();};
+void() ogre_stand3 =[ $stand3, ogre_stand4 ] {ai_stand();};
+void() ogre_stand4 =[ $stand4, ogre_stand5 ] {ai_stand();};
+void() ogre_stand5 =[ $stand5, ogre_stand6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ai_stand();
+};
+void() ogre_stand6 =[ $stand6, ogre_stand7 ] {ai_stand();};
+void() ogre_stand7 =[ $stand7, ogre_stand8 ] {ai_stand();};
+void() ogre_stand8 =[ $stand8, ogre_stand9 ] {ai_stand();};
+void() ogre_stand9 =[ $stand9, ogre_stand1 ] {ai_stand();};
+
+void() ogre_walk1 =[ $walk1, ogre_walk2 ] {ai_walk(3);};
+void() ogre_walk2 =[ $walk2, ogre_walk3 ] {ai_walk(2);};
+void() ogre_walk3 =[ $walk3, ogre_walk4 ] {
+ai_walk(2);
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+};
+void() ogre_walk4 =[ $walk4, ogre_walk5 ] {ai_walk(2);};
+void() ogre_walk5 =[ $walk5, ogre_walk6 ] {ai_walk(2);};
+void() ogre_walk6 =[ $walk6, ogre_walk7 ] {
+ai_walk(5);
+if (random() < 0.1)
+ sound_misc (self, CHAN_VOICE, "ogre/ogdrag.wav", 1, ATTN_IDLE);
+};
+void() ogre_walk7 =[ $walk7, ogre_walk8 ] {ai_walk(3);};
+void() ogre_walk8 =[ $walk8, ogre_walk9 ] {ai_walk(2);};
+void() ogre_walk9 =[ $walk9, ogre_walk10 ] {ai_walk(3);};
+void() ogre_walk10 =[ $walk10, ogre_walk11 ] {ai_walk(1);};
+void() ogre_walk11 =[ $walk11, ogre_walk12 ] {ai_walk(2);};
+void() ogre_walk12 =[ $walk12, ogre_walk13 ] {ai_walk(3);};
+void() ogre_walk13 =[ $walk13, ogre_walk14 ] {ai_walk(3);};
+void() ogre_walk14 =[ $walk14, ogre_walk15 ] {ai_walk(3);};
+void() ogre_walk15 =[ $walk15, ogre_walk16 ] {ai_walk(3);};
+void() ogre_walk16 =[ $walk16, ogre_walk1 ] {ai_walk(4);};
+
+void() ogre_run1 =[ $run1, ogre_run2 ] {ai_run(9);
+if (random() < 0.2)
+ sound_misc1 (self, CHAN_VOICE, "ogre/ogidle2.wav", 1, ATTN_IDLE);
+};
+void() ogre_run2 =[ $run2, ogre_run3 ] {ai_run(12);};
+void() ogre_run3 =[ $run3, ogre_run4 ] {ai_run(8);};
+void() ogre_run4 =[ $run4, ogre_run5 ] {ai_run(22);};
+void() ogre_run5 =[ $run5, ogre_run6 ] {ai_run(16);};
+void() ogre_run6 =[ $run6, ogre_run7 ] {ai_run(4);};
+void() ogre_run7 =[ $run7, ogre_run8 ] {ai_run(13);};
+void() ogre_run8 =[ $run8, ogre_run1 ] {ai_run(24);};
+
+void() ogre_swing1 =[ $swing1, ogre_swing2 ] {ai_charge(11);
+sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
+};
+void() ogre_swing2 =[ $swing2, ogre_swing3 ] {ai_charge(1);};
+void() ogre_swing3 =[ $swing3, ogre_swing4 ] {ai_charge(4);};
+void() ogre_swing4 =[ $swing4, ogre_swing5 ] {ai_charge(13);};
+void() ogre_swing5 =[ $swing5, ogre_swing6 ] {ai_charge(9); chainsaw(0);self.angles_y = self.angles_y + random()*25;};
+void() ogre_swing6 =[ $swing6, ogre_swing7 ] {chainsaw(200);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing7 =[ $swing7, ogre_swing8 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing8 =[ $swing8, ogre_swing9 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing9 =[ $swing9, ogre_swing10 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing10 =[ $swing10, ogre_swing11 ] {chainsaw(-200);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing11 =[ $swing11, ogre_swing12 ] {chainsaw(0);self.angles_y = self.angles_y + random()* 25;};
+void() ogre_swing12 =[ $swing12, ogre_swing13 ] {ai_charge(3);};
+void() ogre_swing13 =[ $swing13, ogre_swing14 ] {ai_charge(8);};
+void() ogre_swing14 =[ $swing14, ogre_run1 ] {ai_charge(9);};
+
+void() ogre_smash1 =[ $smash1, ogre_smash2 ] {ai_charge(6);
+sound_attack (self, CHAN_WEAPON, "ogre/ogsawatk.wav", 1, ATTN_NORM);
+};
+void() ogre_smash2 =[ $smash2, ogre_smash3 ] {ai_charge(0);};
+void() ogre_smash3 =[ $smash3, ogre_smash4 ] {ai_charge(0);};
+void() ogre_smash4 =[ $smash4, ogre_smash5 ] {ai_charge(1);};
+void() ogre_smash5 =[ $smash5, ogre_smash6 ] {ai_charge(4);};
+void() ogre_smash6 =[ $smash6, ogre_smash7 ] {ai_charge(4); chainsaw(0);};
+void() ogre_smash7 =[ $smash7, ogre_smash8 ] {ai_charge(4); chainsaw(0);};
+void() ogre_smash8 =[ $smash8, ogre_smash9 ] {ai_charge(10); chainsaw(0);};
+void() ogre_smash9 =[ $smash9, ogre_smash10 ] {ai_charge(13); chainsaw(0);};
+void() ogre_smash10 =[ $smash10, ogre_smash11 ] {chainsaw(1);};
+void() ogre_smash11 =[ $smash11, ogre_smash12 ] {ai_charge(2); chainsaw(0);
+// self.nextthink = self.nextthink + random()*0.2;}; // slight variation
+self.nextthink = time + 0.1 + random()*0.2;}; // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
+void() ogre_smash12 =[ $smash12, ogre_smash13 ] {ai_charge(0);};
+void() ogre_smash13 =[ $smash13, ogre_smash14 ] {ai_charge(4);};
+void() ogre_smash14 =[ $smash14, ogre_run1 ] {ai_charge(12);};
+
+// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
+.float attack_elevation;
+void() ogre2_nail1 =[ $shoot1, ogre2_nail2 ] {ai_face();
+self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() ogre2_nail2 =[ $shoot2, ogre2_nail3 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_nail3 =[ $shoot2, ogre2_nail4 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
+ PreachFireGrenade(self.attack_elevation);
+};
+// Preach tutorial alternate animation frames for monster_ogre_marksman -- dumptruck_ds
+// these are for the turret version of monster_ogre_marksman
+.float attack_elevation;
+void() ogre2_turret_attack1 =[ $shoot1, ogre2_turret_attack2 ] {ai_face();
+self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() ogre2_turret_attack2 =[ $shoot2, ogre2_turret_attack3 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_turret_attack3 =[ $shoot2, ogre2_turret_attack4 ] {ai_face();
+self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() ogre2_turret_attack4 =[ $shoot3, ogre2_turret_attack5 ] {ai_face();
+ PreachFireGrenade(self.attack_elevation);};
+void() ogre2_turret_attack5 =[ $shoot4, ogre2_turret_attack6 ] {ai_face();};
+void() ogre2_turret_attack6 =[ $shoot5, ogre2_turret_attack7 ] {ai_face();};
+void() ogre2_turret_attack7 =[ $shoot5, ogre2_turret_attack8 ] {ai_face();};
+void() ogre2_turret_attack8 =[ $shoot6, ogre2_turret_attack9 ] {ai_face();};
+void() ogre2_turret_attack9 =[ $shoot6, ogre2_turret_seek1 ] {ai_face();};
+void() ogre2_turret_seek1 =[ $stand1, ogre2_turret_seek2 ] {ai_run(0);};
+void() ogre2_turret_seek2 =[ $stand2, ogre2_turret_seek3 ] {ai_run(0);};
+void() ogre2_turret_seek3 =[ $stand3, ogre2_turret_seek4 ] {ai_run(0);};
+void() ogre2_turret_seek4 =[ $stand4, ogre2_turret_seek5 ] {ai_run(0);};
+void() ogre2_turret_seek5 =[ $stand5, ogre2_turret_seek6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ ai_run(0);
+};
+void() ogre2_turret_seek6 =[ $stand6, ogre2_turret_seek7 ] {ai_run(0);};
+void() ogre2_turret_seek7 =[ $stand7, ogre2_turret_seek8 ] {ai_run(0);};
+void() ogre2_turret_seek8 =[ $stand8, ogre2_turret_seek9 ] {ai_run(0);};
+void() ogre2_turret_seek9 =[ $stand9, ogre2_turret_seek1 ] {ai_run(0);};
+
+//end Preach -- dumptruck_ds
+void() ogre_nail1 =[ $shoot1, ogre_nail2 ] {ai_face();};
+void() ogre_nail2 =[ $shoot2, ogre_nail3 ] {ai_face();};
+void() ogre_nail3 =[ $shoot2, ogre_nail4 ] {ai_face();};
+void() ogre_nail4 =[ $shoot3, ogre_nail5 ] {ai_face();
+ if (self.style == 0)
+ {
+ OgreFireGrenade();
+ }
+ if (self.style == 1)
+ {
+ BDW_OgreFireFlak();
+ // OgreFireSpike();
+ }
+ else if (self.style == 2)
+ {
+ OgreFireSpike();
+ }
+ if (self.style == 3)
+ {
+ W_FireMultiGrenade();
+ }
+ if (self.style == 4) // jaycie erysdren 2021-09-14
+ {
+ OgreFireLavaBall();
+ sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ }
+};
+void() ogre_nail5 =[ $shoot4, ogre_nail6 ] {ai_face();};
+void() ogre_nail6 =[ $shoot5, ogre_nail7 ] {ai_face();};
+void() ogre_nail7 =[ $shoot6, ogre_run1 ] {ai_face();};
+//
+////////////////////////
+// turret frames START
+////////////////////////
+//
+void() ogre_turret_attack1 =[ $shoot1, ogre_turret_attack2 ] {ai_face();};
+void() ogre_turret_attack2 =[ $shoot2, ogre_turret_attack3 ] {ai_face();};
+void() ogre_turret_attack3 =[ $shoot2, ogre_turret_attack4 ] {ai_face();};
+void() ogre_turret_attack4 =[ $shoot3, ogre_turret_attack5 ] {ai_face();
+ if (self.style == 0)
+ {
+ OgreFireGrenade();
+ }
+ if (self.style == 1)
+ {
+ BDW_OgreFireFlak();
+ // OgreFireSpike();
+ }
+ else if (self.style == 2)
+ {
+ OgreFireSpike();
+ }
+ if (self.style == 3)
+ {
+ W_FireMultiGrenade();
+ }
+ if (self.style == 4) // jaycie erysdren 2021-09-14
+ {
+ OgreFireLavaBall();
+ sound_misc2 (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM); // used for initial attack sound dumptruck_ds
+ }
+};
+void() ogre_turret_attack5 =[ $shoot4, ogre_turret_attack6 ] {ai_face();};
+
+void() ogre_turret_attack6=[ $shoot5, ogre_turret_attack7 ] {ai_face();};
+void() ogre_turret_attack7=[ $shoot5, ogre_turret_attack8 ] {ai_face();};
+void() ogre_turret_attack8=[ $shoot6, ogre_turret_attack9 ] {ai_face();};
+void() ogre_turret_attack9=[ $shoot6, ogre_turret_seek1 ] {ai_face();};
+void() ogre_turret_seek1 =[ $stand1, ogre_turret_seek2 ] {ai_run(0);};
+void() ogre_turret_seek2 =[ $stand2, ogre_turret_seek3 ] {ai_run(0);};
+void() ogre_turret_seek3 =[ $stand3, ogre_turret_seek4 ] {ai_run(0);};
+void() ogre_turret_seek4 =[ $stand4, ogre_turret_seek5 ] {ai_run(0);};
+void() ogre_turret_seek5 =[ $stand5, ogre_turret_seek6 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "ogre/ogidle.wav", 1, ATTN_IDLE);
+ ai_run(0);
+};
+void() ogre_turret_seek6 =[ $stand6, ogre_turret_seek7 ] {ai_run(0);};
+void() ogre_turret_seek7 =[ $stand7, ogre_turret_seek8 ] {ai_run(0);};
+void() ogre_turret_seek8 =[ $stand8, ogre_turret_seek9 ] {ai_run(0);};
+void() ogre_turret_seek9 =[ $stand9, ogre_turret_seek1 ] {ai_run(0);};
+////////////////////////
+//turret frames END
+///////////////////////
+void() ogre_pain1 =[ $pain1, ogre_pain2 ] {};
+void() ogre_pain2 =[ $pain2, ogre_pain3 ] {};
+void() ogre_pain3 =[ $pain3, ogre_pain4 ] {};
+void() ogre_pain4 =[ $pain4, ogre_pain5 ] {};
+void() ogre_pain5 =[ $pain5, ogre_run1 ] {};
+
+
+void() ogre_painb1 =[ $painb1, ogre_painb2 ] {};
+void() ogre_painb2 =[ $painb2, ogre_painb3 ] {};
+void() ogre_painb3 =[ $painb3, ogre_run1 ] {};
+
+
+void() ogre_painc1 =[ $painc1, ogre_painc2 ] {};
+void() ogre_painc2 =[ $painc2, ogre_painc3 ] {};
+void() ogre_painc3 =[ $painc3, ogre_painc4 ] {};
+void() ogre_painc4 =[ $painc4, ogre_painc5 ] {};
+void() ogre_painc5 =[ $painc5, ogre_painc6 ] {};
+void() ogre_painc6 =[ $painc6, ogre_run1 ] {};
+
+
+void() ogre_paind1 =[ $paind1, ogre_paind2 ] {};
+void() ogre_paind2 =[ $paind2, ogre_paind3 ] {ai_pain(10);};
+void() ogre_paind3 =[ $paind3, ogre_paind4 ] {ai_pain(9);};
+void() ogre_paind4 =[ $paind4, ogre_paind5 ] {ai_pain(4);};
+void() ogre_paind5 =[ $paind5, ogre_paind6 ] {};
+void() ogre_paind6 =[ $paind6, ogre_paind7 ] {};
+void() ogre_paind7 =[ $paind7, ogre_paind8 ] {};
+void() ogre_paind8 =[ $paind8, ogre_paind9 ] {};
+void() ogre_paind9 =[ $paind9, ogre_paind10 ] {};
+void() ogre_paind10=[ $paind10, ogre_paind11 ] {};
+void() ogre_paind11=[ $paind11, ogre_paind12 ] {};
+void() ogre_paind12=[ $paind12, ogre_paind13 ] {};
+void() ogre_paind13=[ $paind13, ogre_paind14 ] {};
+void() ogre_paind14=[ $paind14, ogre_paind15 ] {};
+void() ogre_paind15=[ $paind15, ogre_paind16 ] {};
+void() ogre_paind16=[ $paind16, ogre_run1 ] {};
+
+void() ogre_paine1 =[ $paine1, ogre_paine2 ] {};
+void() ogre_paine2 =[ $paine2, ogre_paine3 ] {ai_pain(10);};
+void() ogre_paine3 =[ $paine3, ogre_paine4 ] {ai_pain(9);};
+void() ogre_paine4 =[ $paine4, ogre_paine5 ] {ai_pain(4);};
+void() ogre_paine5 =[ $paine5, ogre_paine6 ] {};
+void() ogre_paine6 =[ $paine6, ogre_paine7 ] {};
+void() ogre_paine7 =[ $paine7, ogre_paine8 ] {};
+void() ogre_paine8 =[ $paine8, ogre_paine9 ] {};
+void() ogre_paine9 =[ $paine9, ogre_paine10 ] {};
+void() ogre_paine10=[ $paine10, ogre_paine11 ] {};
+void() ogre_paine11=[ $paine11, ogre_paine12 ] {};
+void() ogre_paine12=[ $paine12, ogre_paine13 ] {};
+void() ogre_paine13=[ $paine13, ogre_paine14 ] {};
+void() ogre_paine14=[ $paine14, ogre_paine15 ] {};
+void() ogre_paine15=[ $paine15, ogre_run1 ] {};
+
+
+void(entity attacker, float damage) ogre_pain =
+{
+ local float r;
+
+// don't make multiple pain sounds right after each other
+ if (self.pain_finished > time)
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+
+ sound_pain (self, CHAN_VOICE, "ogre/ogpain1.wav", 1, ATTN_NORM);
+
+ r = random();
+
+ if (r < 0.25)
+ {
+ ogre_pain1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.5)
+ {
+ ogre_painb1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.75)
+ {
+ ogre_painc1 ();
+ self.pain_finished = time + 1;
+ }
+ else if (r < 0.88)
+ {
+ ogre_paind1 ();
+ self.pain_finished = time + 2;
+ }
+ else
+ {
+ ogre_paine1 ();
+ self.pain_finished = time + 2;
+ }
+};
+
+void() ogre_die1 =[ $death1, ogre_die2 ] {};
+void() ogre_die2 =[ $death2, ogre_die3 ] {};
+void() ogre_die3 =[ $death3, ogre_die4 ]
+{self.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (self.style == 1) // flak style
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 2) // super nail style
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 3) //DOE multi-grenade
+ {
+ self.ammo_rockets = 2;
+ }
+ else if (self.style == 0) //default Ogre
+ {
+ self.ammo_rockets = 2;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() ogre_die4 =[ $death4, ogre_die5 ] {};
+void() ogre_die5 =[ $death5, ogre_die6 ] {};
+void() ogre_die6 =[ $death6, ogre_die7 ] {};
+void() ogre_die7 =[ $death7, ogre_die8 ] {};
+void() ogre_die8 =[ $death8, ogre_die9 ] {};
+void() ogre_die9 =[ $death9, ogre_die10 ] {};
+void() ogre_die10 =[ $death10, ogre_die11 ] {};
+void() ogre_die11 =[ $death11, ogre_die12 ] {};
+void() ogre_die12 =[ $death12, ogre_die13 ] {};
+void() ogre_die13 =[ $death13, ogre_die14 ] {};
+void() ogre_die14 =[ $death14, ogre_die14 ] {};
+
+void() ogre_bdie1 =[ $bdeath1, ogre_bdie2 ] {};
+void() ogre_bdie2 =[ $bdeath2, ogre_bdie3 ] {ai_forward(5);};
+void() ogre_bdie3 =[ $bdeath3, ogre_bdie4 ]
+{self.solid = SOLID_NOT;
+ // style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_nails = 5;
+ }
+ if (self.style == 3) //DOE multi-grenade
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 4) // lavaball ogre jaycie erysdren 2021-09-14
+ {
+ self.ammo_rockets = 2;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_rockets = 2;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() ogre_bdie4 =[ $bdeath4, ogre_bdie5 ] {ai_forward(1);};
+void() ogre_bdie5 =[ $bdeath5, ogre_bdie6 ] {ai_forward(3);};
+void() ogre_bdie6 =[ $bdeath6, ogre_bdie7 ] {ai_forward(7);};
+void() ogre_bdie7 =[ $bdeath7, ogre_bdie8 ] {ai_forward(25);};
+void() ogre_bdie8 =[ $bdeath8, ogre_bdie9 ] {};
+void() ogre_bdie9 =[ $bdeath9, ogre_bdie10 ] {};
+void() ogre_bdie10 =[ $bdeath10, ogre_bdie10 ] {};
+
+void() ogre_die =
+{
+// check for gib
+ if (self.health < -80)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_ogre.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+ sound_death (self, CHAN_VOICE, "ogre/ogdth.wav", 1, ATTN_NORM);
+
+ DropStuff();
+ if (random() < 0.5)
+ ogre_die1 ();
+ else
+ ogre_bdie1 ();
+};
+
+void() ogre_melee =
+{
+ if (random() > 0.5)
+ ogre_smash1 ();
+ else
+ ogre_swing1 ();
+};
+
+
+/*QUAKED monster_ogre (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/ogre.mdl");
+}
+Ogre.
+
+Default health = 200"
+
+style(Choices) : "Attack type" =
+0 : "Default (grenade)"
+1 : "Flak Ogre (Marcher, Quoth)"
+2 : "sniper (shoots single, deadly lava round)"
+3 : "multi-grenade (Mission Pack 2)"
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
+snd_idle(string) : "Path to custom idle sound (IDLE)"
+snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
+snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
+
+ // custom_mdls dumptruck_ds
+ precache_model ("progs/mervup.mdl"); //for style 3 Orge dumptruck_ds
+ precache_model ("progs/lspike.mdl"); //for style 2 Ogre dumptruck_ds
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
+ precache_sound_misc2 ("shalrath/attack2.wav");
+ precache_sound ("fish/bite.wav");
+ precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (self, "progs/ogre.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 200;
+
+ self.th_stand = ogre_stand1;
+ self.th_walk = ogre_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = ogre_turret_seek1;
+ }
+ else
+ {
+ self.th_run = ogre_run1;
+ }
+ self.th_die = ogre_die;
+ self.th_melee = ogre_melee;
+ self.th_missile = ogre_nail1;
+ self.th_turret = ogre_turret_attack1; //dumptruck_ds
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = ogre_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+/*QUAKED monster_ogre_marksman (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ({ "path" : "progs/ogre.mdl", "frame": 63 });
+}
+Ogre Marksman.
+Unlike vanilla Quake, this is a slightly more accurate Orge.
+
+keep_ammo(integer) : "1 = Don't drop backpack upon death"
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (CHAINSAW)"
+snd_idle(string) : "Path to custom idle sound (IDLE)"
+snd_misc(string) : "Path to custom sound (IDLE CHAINSAW DRAG)"
+snd_misc1(string) : "Path to custom sound (ATTACK GRUNT)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_ogre_marksman =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ // custom_mdls dumptruck_ds
+ precache_body_model ("progs/ogre.mdl");
+ precache_head_model ("progs/h_ogre.mdl");
+ precache_proj_model ("progs/grenade.mdl");
+
+ precache_sound_misc ("ogre/ogdrag.wav");
+ precache_sound_death ("ogre/ogdth.wav");
+ precache_sound_idle ("ogre/ogidle.wav");
+ precache_sound_misc1 ("ogre/ogidle2.wav");
+ precache_sound_pain ("ogre/ogpain1.wav");
+ precache_sound_attack ("ogre/ogsawatk.wav");
+ precache_sound_sight ("ogre/ogwake.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ // custom_mdls dumptruck_ds
+ body_model ("progs/ogre.mdl");
+ // setmodel (self, "progs/ogre.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 200;
+
+ self.th_stand = ogre_stand1;
+ self.th_walk = ogre_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = ogre2_turret_seek1;
+ }
+ else
+ {
+ self.th_run = ogre_run1;
+ }
+ self.th_die = ogre_die;
+ self.th_melee = ogre_melee;
+ self.th_missile = ogre2_nail1;
+ self.th_turret = ogre2_turret_attack1; //dumptruck_ds
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = ogre_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+
+// {
+// if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+// return;
+//
+// monster_ogre ();
+// };
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_ogre (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID ON_SIDE X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/ogre.mdl","frame":135});
+}
+*/
+void() monster_dead_ogre =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/ogre.mdl");
+ setmodel(self, "progs/ogre.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death14;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-40.64 -54.06 -54.1','29.42 54.63 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $bdeath10;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-45.64 -29.46 -54.52','33.87 39.18 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/oldone.qc

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

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/shalrath.qc

diff --git a/qc/monsters/shalrath.qc b/qc/monsters/shalrath.qc
index f799fe4..ee97ab0 100644
--- a/qc/monsters/shalrath.qc
+++ b/qc/monsters/shalrath.qc
@@ -1,433 +1,433 @@
-/*
-==============================================================================
-
-SHAL-RATH
-
-==============================================================================
-*/
-$cd id1/models/shalrath
-$origin 0 0 24
-$base base
-$skin skin
-$scale 0.7
-
-$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
-$frame attack9 attack10 attack11
-
-$frame pain1 pain2 pain3 pain4 pain5
-
-$frame death1 death2 death3 death4 death5 death6 death7
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
-$frame walk11 walk12
-
-void(entity attacker, float damage) shalrath_pain;
-void() ShalMissile;
-void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
-
-void() shal_walk1 =[ $walk2, shal_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_walk(6);};
-void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
-void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
-void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
-void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
-void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
-void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
-void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
-void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
-void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
-void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
-void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
-
-void() shal_run1 =[ $walk2, shal_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
-ai_run(6);};
-void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
-void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
-void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
-void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
-void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
-void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
-void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
-void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
-void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
-void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
-void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
-
-void() shal_attack1 =[ $attack1, shal_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
-void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
-void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
-void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
-void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
-void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
-void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
-void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
-void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
-void() shal_attack11 =[ $attack11, shal_run1 ] {};
-//////////////////////////
-/// new frames for turret mode START
-//////////////////////////
-void() shal_turret_attack1 =[ $attack1, shal_turret_attack2 ] {
-sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
-ai_face();
-};
-void() shal_turret_attack2 =[ $attack2, shal_turret_attack3 ] {ai_face();};
-void() shal_turret_attack3 =[ $attack3, shal_turret_attack4 ] {ai_face();};
-void() shal_turret_attack4 =[ $attack4, shal_turret_attack5 ] {ai_face();};
-void() shal_turret_attack5 =[ $attack5, shal_turret_attack6 ] {ai_face();};
-void() shal_turret_attack6 =[ $attack6, shal_turret_attack7 ] {ai_face();};
-void() shal_turret_attack7 =[ $attack7, shal_turret_attack8 ] {ai_face();};
-void() shal_turret_attack8 =[ $attack8, shal_turret_attack9 ] {ai_face();};
-void() shal_turret_attack9 =[ $attack9, shal_turret_attack10 ] {ShalMissile();};
-void() shal_turret_attack10 =[ $attack10, shal_turret_attack11 ] {ai_face();};
-void() shal_turret_attack11 =[ $attack11, shal_turret_attack12 ] {ai_face();};
-void() shal_turret_attack12 =[ $walk1, shal_turret_attack13 ] {ai_face();};
-void() shal_turret_attack13 =[ $walk1, shal_turret_attack14 ] {ai_face();};
-void() shal_turret_attack14 =[ $walk1, shal_turret_attack15 ] {ai_face();};
-void() shal_turret_attack15 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-void() shal_seek_stand1 =[ $walk1, shal_seek_stand2 ] {ai_run(0);};
-void() shal_seek_stand2 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
-//////////////////////////
-/// new frames for turret mode END
-//////////////////////////
-void() shal_pain1 =[ $pain1, shal_pain2 ] {};
-void() shal_pain2 =[ $pain2, shal_pain3 ] {};
-void() shal_pain3 =[ $pain3, shal_pain4 ] {};
-void() shal_pain4 =[ $pain4, shal_pain5 ] {};
-void() shal_pain5 =[ $pain5, shal_run1 ] {};
-
-void() shal_death1 =[ $death1, shal_death2 ] {};
-void() shal_death2 =[ $death2, shal_death3 ] {};
-void() shal_death3 =[ $death3, shal_death4 ] {};
-void() shal_death4 =[ $death4, shal_death5 ] {};
-void() shal_death5 =[ $death5, shal_death6 ] {};
-void() shal_death6 =[ $death6, shal_death7 ] {};
-void() shal_death7 =[ $death7, shal_death7 ] {};
-
-
-void(entity attacker, float damage) shalrath_pain =
-{
- if (self.pain_finished > time)
- return;
-
- sound_pain (self, CHAN_AUTO, "shalrath/pain.wav", 1, ATTN_NORM); //CHAN_AUTO was voice - dumptruck_ds
- self.pain_finished = time + 3;
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- shal_pain1();
-};
-
-void() shalrath_die =
-{
-// check for gib
- if (self.health < -90)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_shal.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
- // insert death sounds here
- sound_death (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
- DropStuff();
- shal_death1();
- self.solid = SOLID_NOT;
-};
-
-/*
-================
-ShalMissile
-================
-*/
-void() ShalMissileTouch;
-void() ShalMissile =
-{
- local entity missile;
- local vector dir;
- local float dist, flytime;
-
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
- dist = vlen (self.enemy.origin - self.origin);
- flytime = dist * 0.002 * (1/self.proj_speed_mod);
- if (flytime < 0.1)
- flytime = 0.1;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
- sound_misc (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
-
- missile.solid = SOLID_BBOX;
- missile.movetype = MOVETYPE_FLYMISSILE;
-
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/v_spike.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- // setmodel (missile, "progs/v_spike.mdl");
-
- setsize (missile, '0 0 0', '0 0 0');
-
- missile.origin = self.origin + '0 0 10';
- SetSpeed(missile, dir, 400 * self.proj_speed_mod);
- missile.avelocity = self.avelocity; // custom spin on projectile --dumptruck_ds
- if !(missile.avelocity)
- missile.avelocity = '300 300 300';
- if (self.homing > 0) // If homing is off, don't bother doing any thinking
- {
- missile.homing = self.homing;
- missile.nextthink = flytime + time;
- missile.think = MissileHome;
- }
- if (skill == 3)
- missile.proj_basespeed = 350 * self.proj_speed_mod;
- else
- missile.proj_basespeed = 250 * self.proj_speed_mod;
- missile.enemy = self.enemy;
- missile.touch = ShalMissileTouch;
-};
-
-
-// void() ShalMissileTouch = --moved to misc.qc for voreball shooter --dumptruck_ds
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-//
-// if (other.classname == "monster_zombie")
-// T_Damage (other, self, self, 110);
-// T_RadiusDamage (self, self.owner, 40, world);
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
-//
-// WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-// WriteByte (MSG_BROADCAST, TE_EXPLOSION);
-// WriteCoord (MSG_BROADCAST, self.origin_x);
-// WriteCoord (MSG_BROADCAST, self.origin_y);
-// WriteCoord (MSG_BROADCAST, self.origin_z);
-//
-// self.velocity = '0 0 0';
-// self.touch = SUB_Null;
-// setmodel (self, "progs/s_explod.spr");
-// self.solid = SOLID_NOT;
-// s_explode1 ();
-// };
-
-//=================================================================
-
-/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({ "path" : "progs/shalrath.mdl", "frame": 23 });
-}
-Vore.
-
-Default health = 400
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (VORE SNARL)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom attack2 sound (VOREBALL FIRE)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
-
-*/
-void() monster_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model2 ("progs/shalrath.mdl");
- precache_head_model2 ("progs/h_shal.mdl");
- precache_proj_model2 ("progs/v_spike.mdl");
-// dumptruck_ds
- precache_sound2_attack ("shalrath/attack.wav");
- precache_sound2_misc ("shalrath/attack2.wav");
- precache_sound2_death ("shalrath/death.wav");
- precache_sound2_idle ("shalrath/idle.wav");
- precache_sound2_pain ("shalrath/pain.wav");
- precache_sound2_sight ("shalrath/sight.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/shalrath.mdl");
- // setmodel (self, "progs/shalrath.mdl");
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 400;
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.homing) // default to normal
- {
- self.homing = 1;
- }
- else if (self.homing < 0) // disable with negative
- {
- self.homing = 0;
- }
-
- self.th_stand = shal_stand;
- self.th_walk = shal_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = shal_seek_stand1;
- }
- else
- {
- self.th_run = shal_run1;
- }
-
- self.th_die = shalrath_die;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = shalrath_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_missile = shal_attack1;
- self.th_turret = shal_turret_attack1;
- self.think = walkmonster_start;
- self.nextthink = time + 0.1 + random ()*0.1;
-
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/shalrath.mdl","frame":22});
-}
-*/
-void() monster_dead_shalrath =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/shalrath.mdl");
- setmodel(self, "progs/shalrath.mdl");
- self.frame = $death7;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-41.41 -40.06 -49.38','34.52 24.32 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
+/*
+==============================================================================
+
+SHAL-RATH
+
+==============================================================================
+*/
+$cd id1/models/shalrath
+$origin 0 0 24
+$base base
+$skin skin
+$scale 0.7
+
+$frame attack1 attack2 attack3 attack4 attack5 attack6 attack7 attack8
+$frame attack9 attack10 attack11
+
+$frame pain1 pain2 pain3 pain4 pain5
+
+$frame death1 death2 death3 death4 death5 death6 death7
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10
+$frame walk11 walk12
+
+void(entity attacker, float damage) shalrath_pain;
+void() ShalMissile;
+void() shal_stand =[ $walk1, shal_stand ] {ai_stand();};
+
+void() shal_walk1 =[ $walk2, shal_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
+ai_walk(6);};
+void() shal_walk2 =[ $walk3, shal_walk3 ] {ai_walk(4);};
+void() shal_walk3 =[ $walk4, shal_walk4 ] {ai_walk(0);};
+void() shal_walk4 =[ $walk5, shal_walk5 ] {ai_walk(0);};
+void() shal_walk5 =[ $walk6, shal_walk6 ] {ai_walk(0);};
+void() shal_walk6 =[ $walk7, shal_walk7 ] {ai_walk(0);};
+void() shal_walk7 =[ $walk8, shal_walk8 ] {ai_walk(5);};
+void() shal_walk8 =[ $walk9, shal_walk9 ] {ai_walk(6);};
+void() shal_walk9 =[ $walk10, shal_walk10 ] {ai_walk(5);};
+void() shal_walk10 =[ $walk11, shal_walk11 ] {ai_walk(0);};
+void() shal_walk11 =[ $walk12, shal_walk12 ] {ai_walk(4);};
+void() shal_walk12 =[ $walk1, shal_walk1 ] {ai_walk(5);};
+
+void() shal_run1 =[ $walk2, shal_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "shalrath/idle.wav", 1, ATTN_IDLE);
+ai_run(6);};
+void() shal_run2 =[ $walk3, shal_run3 ] {ai_run(4);};
+void() shal_run3 =[ $walk4, shal_run4 ] {ai_run(0);};
+void() shal_run4 =[ $walk5, shal_run5 ] {ai_run(0);};
+void() shal_run5 =[ $walk6, shal_run6 ] {ai_run(0);};
+void() shal_run6 =[ $walk7, shal_run7 ] {ai_run(0);};
+void() shal_run7 =[ $walk8, shal_run8 ] {ai_run(5);};
+void() shal_run8 =[ $walk9, shal_run9 ] {ai_run(6);};
+void() shal_run9 =[ $walk10, shal_run10 ] {ai_run(5);};
+void() shal_run10 =[ $walk11, shal_run11 ] {ai_run(0);};
+void() shal_run11 =[ $walk12, shal_run12 ] {ai_run(4);};
+void() shal_run12 =[ $walk1, shal_run1 ] {ai_run(5);};
+
+void() shal_attack1 =[ $attack1, shal_attack2 ] {
+sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
+ai_face();
+};
+void() shal_attack2 =[ $attack2, shal_attack3 ] {ai_face();};
+void() shal_attack3 =[ $attack3, shal_attack4 ] {ai_face();};
+void() shal_attack4 =[ $attack4, shal_attack5 ] {ai_face();};
+void() shal_attack5 =[ $attack5, shal_attack6 ] {ai_face();};
+void() shal_attack6 =[ $attack6, shal_attack7 ] {ai_face();};
+void() shal_attack7 =[ $attack7, shal_attack8 ] {ai_face();};
+void() shal_attack8 =[ $attack8, shal_attack9 ] {ai_face();};
+void() shal_attack9 =[ $attack9, shal_attack10 ] {ShalMissile();};
+void() shal_attack10 =[ $attack10, shal_attack11 ] {ai_face();};
+void() shal_attack11 =[ $attack11, shal_run1 ] {};
+//////////////////////////
+/// new frames for turret mode START
+//////////////////////////
+void() shal_turret_attack1 =[ $attack1, shal_turret_attack2 ] {
+sound_attack (self, CHAN_VOICE, "shalrath/attack.wav", 1, ATTN_NORM);
+ai_face();
+};
+void() shal_turret_attack2 =[ $attack2, shal_turret_attack3 ] {ai_face();};
+void() shal_turret_attack3 =[ $attack3, shal_turret_attack4 ] {ai_face();};
+void() shal_turret_attack4 =[ $attack4, shal_turret_attack5 ] {ai_face();};
+void() shal_turret_attack5 =[ $attack5, shal_turret_attack6 ] {ai_face();};
+void() shal_turret_attack6 =[ $attack6, shal_turret_attack7 ] {ai_face();};
+void() shal_turret_attack7 =[ $attack7, shal_turret_attack8 ] {ai_face();};
+void() shal_turret_attack8 =[ $attack8, shal_turret_attack9 ] {ai_face();};
+void() shal_turret_attack9 =[ $attack9, shal_turret_attack10 ] {ShalMissile();};
+void() shal_turret_attack10 =[ $attack10, shal_turret_attack11 ] {ai_face();};
+void() shal_turret_attack11 =[ $attack11, shal_turret_attack12 ] {ai_face();};
+void() shal_turret_attack12 =[ $walk1, shal_turret_attack13 ] {ai_face();};
+void() shal_turret_attack13 =[ $walk1, shal_turret_attack14 ] {ai_face();};
+void() shal_turret_attack14 =[ $walk1, shal_turret_attack15 ] {ai_face();};
+void() shal_turret_attack15 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
+void() shal_seek_stand1 =[ $walk1, shal_seek_stand2 ] {ai_run(0);};
+void() shal_seek_stand2 =[ $walk1, shal_seek_stand1 ] {ai_run(0);};
+//////////////////////////
+/// new frames for turret mode END
+//////////////////////////
+void() shal_pain1 =[ $pain1, shal_pain2 ] {};
+void() shal_pain2 =[ $pain2, shal_pain3 ] {};
+void() shal_pain3 =[ $pain3, shal_pain4 ] {};
+void() shal_pain4 =[ $pain4, shal_pain5 ] {};
+void() shal_pain5 =[ $pain5, shal_run1 ] {};
+
+void() shal_death1 =[ $death1, shal_death2 ] {};
+void() shal_death2 =[ $death2, shal_death3 ] {};
+void() shal_death3 =[ $death3, shal_death4 ] {};
+void() shal_death4 =[ $death4, shal_death5 ] {};
+void() shal_death5 =[ $death5, shal_death6 ] {};
+void() shal_death6 =[ $death6, shal_death7 ] {};
+void() shal_death7 =[ $death7, shal_death7 ] {};
+
+
+void(entity attacker, float damage) shalrath_pain =
+{
+ if (self.pain_finished > time)
+ return;
+
+ sound_pain (self, CHAN_AUTO, "shalrath/pain.wav", 1, ATTN_NORM); //CHAN_AUTO was voice - dumptruck_ds
+ self.pain_finished = time + 3;
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ shal_pain1();
+};
+
+void() shalrath_die =
+{
+// check for gib
+ if (self.health < -90)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shal.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+ // insert death sounds here
+ sound_death (self, CHAN_VOICE, "shalrath/death.wav", 1, ATTN_NORM);
+ DropStuff();
+ shal_death1();
+ self.solid = SOLID_NOT;
+};
+
+/*
+================
+ShalMissile
+================
+*/
+void() ShalMissileTouch;
+void() ShalMissile =
+{
+ local entity missile;
+ local vector dir;
+ local float dist, flytime;
+
+ dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+ dist = vlen (self.enemy.origin - self.origin);
+ flytime = dist * 0.002 * (1/self.proj_speed_mod);
+ if (flytime < 0.1)
+ flytime = 0.1;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+ sound_misc (self, CHAN_WEAPON, "shalrath/attack2.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+
+ missile.solid = SOLID_BBOX;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/v_spike.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ // setmodel (missile, "progs/v_spike.mdl");
+
+ setsize (missile, '0 0 0', '0 0 0');
+
+ missile.origin = self.origin + '0 0 10';
+ SetSpeed(missile, dir, 400 * self.proj_speed_mod);
+ missile.avelocity = self.avelocity; // custom spin on projectile --dumptruck_ds
+ if !(missile.avelocity)
+ missile.avelocity = '300 300 300';
+ if (self.homing > 0) // If homing is off, don't bother doing any thinking
+ {
+ missile.homing = self.homing;
+ missile.nextthink = flytime + time;
+ missile.think = MissileHome;
+ }
+ if (skill == 3)
+ missile.proj_basespeed = 350 * self.proj_speed_mod;
+ else
+ missile.proj_basespeed = 250 * self.proj_speed_mod;
+ missile.enemy = self.enemy;
+ missile.touch = ShalMissileTouch;
+};
+
+
+// void() ShalMissileTouch = --moved to misc.qc for voreball shooter --dumptruck_ds
+// {
+// if (other == self.owner)
+// return; // don't explode on owner
+//
+// if (other.classname == "monster_zombie")
+// T_Damage (other, self, self, 110);
+// T_RadiusDamage (self, self.owner, 40, world);
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+//
+// WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+// WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+// WriteCoord (MSG_BROADCAST, self.origin_x);
+// WriteCoord (MSG_BROADCAST, self.origin_y);
+// WriteCoord (MSG_BROADCAST, self.origin_z);
+//
+// self.velocity = '0 0 0';
+// self.touch = SUB_Null;
+// setmodel (self, "progs/s_explod.spr");
+// self.solid = SOLID_NOT;
+// s_explode1 ();
+// };
+
+//=================================================================
+
+/*QUAKED monster_shalrath (1 0 0) (-32 -32 -24) (32 32 48) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({ "path" : "progs/shalrath.mdl", "frame": 23 });
+}
+Vore.
+
+Default health = 400
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (VORE SNARL)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom attack2 sound (VOREBALL FIRE)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+homing(float) : "Amount that the projectile should home in target. 1 is default, 0 is none."
+
+*/
+void() monster_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model2 ("progs/shalrath.mdl");
+ precache_head_model2 ("progs/h_shal.mdl");
+ precache_proj_model2 ("progs/v_spike.mdl");
+// dumptruck_ds
+ precache_sound2_attack ("shalrath/attack.wav");
+ precache_sound2_misc ("shalrath/attack2.wav");
+ precache_sound2_death ("shalrath/death.wav");
+ precache_sound2_idle ("shalrath/idle.wav");
+ precache_sound2_pain ("shalrath/pain.wav");
+ precache_sound2_sight ("shalrath/sight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/shalrath.mdl");
+ // setmodel (self, "progs/shalrath.mdl");
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 400;
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.homing) // default to normal
+ {
+ self.homing = 1;
+ }
+ else if (self.homing < 0) // disable with negative
+ {
+ self.homing = 0;
+ }
+
+ self.th_stand = shal_stand;
+ self.th_walk = shal_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = shal_seek_stand1;
+ }
+ else
+ {
+ self.th_run = shal_run1;
+ }
+
+ self.th_die = shalrath_die;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = shalrath_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_missile = shal_attack1;
+ self.th_turret = shal_turret_attack1;
+ self.think = walkmonster_start;
+ self.nextthink = time + 0.1 + random ()*0.1;
+
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_shalrath (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/shalrath.mdl","frame":22});
+}
+*/
+void() monster_dead_shalrath =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/shalrath.mdl");
+ setmodel(self, "progs/shalrath.mdl");
+ self.frame = $death7;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-41.41 -40.06 -49.38','34.52 24.32 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/shambler.qc

diff --git a/qc/monsters/shambler.qc b/qc/monsters/shambler.qc
index cfa6a01..9da3c81 100644
--- a/qc/monsters/shambler.qc
+++ b/qc/monsters/shambler.qc
@@ -1,727 +1,727 @@
-/*
-==============================================================================
-
-SHAMBLER
-
-==============================================================================
-
-================
-ShamRocket
-================
-*/
-void() ShamRocket =
-{
- local entity missile;
- local float projspeed = 900 * self.proj_speed_mod;
-
- sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
- missile.angles = vectoangles(missile.velocity);
- missile.avelocity = self.cust_avelocity; //custom spin of projectile
- if !(missile.avelocity)
- missile.avelocity = '200 100 300';
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, projspeed);
- }
- else
- {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- missile.skin = self.skin_proj; //dumptruck_ds
-
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/lavaball.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward*8 + '0 0 24');
-};
-
-
-$cd id1/models/shams
-$origin 0 0 24
-$base base
-$skin base
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
-$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
-$frame walk8 walk9 walk10 walk11 walk12
-
-$frame run1 run2 run3 run4 run5 run6
-
-$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
-$frame smash8 smash9 smash10 smash11 smash12
-
-$frame swingr1 swingr2 swingr3 swingr4 swingr5
-$frame swingr6 swingr7 swingr8 swingr9
-
-$frame swingl1 swingl2 swingl3 swingl4 swingl5
-$frame swingl6 swingl7 swingl8 swingl9
-
-$frame magic1 magic2 magic3 magic4 magic5
-$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame death1 death2 death3 death4 death5 death6
-$frame death7 death8 death9 death10 death11
-
-void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
-void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
-void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
-void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
-void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
-void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
-void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
-void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
-void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
-void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
-void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
-void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
-void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
-void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
-void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
-void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
-void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
-
-void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
-void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
-void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
-void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
-void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
-void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
-void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
-void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
-void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
-void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
-void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
-void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
-
-void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
-void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
-void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
-void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
-void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
-void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
-if (random() > 0.8)
- sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
-};
-
-void() sham_smash1 =[ $smash1, sham_smash2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(2);};
-void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
-void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
-void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
-void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
-void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
-void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
-void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
-void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
-void() sham_smash10 =[ $smash10, sham_smash11 ] {
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- ai_charge(0);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
- if (!CanDamage (self.enemy, self))
- return;
-
- ldmg = (random() + random() + random()) * 40;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
-
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
- SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
-};
-void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
-void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
-/////////////////////////////////////
-// new frames for projectile style
-////////////////////////////////////
-void() sham_proj1 =[ $smash1, sham_proj2 ] {ai_face();};
-void() sham_proj2 =[ $smash2, sham_proj3 ] {ai_face();};
-void() sham_proj3 =[ $smash3, sham_proj4 ] {ai_face();};
-void() sham_proj4 =[ $smash4, sham_proj5 ] {ai_face();};
-void() sham_proj5 =[ $smash5, sham_proj6 ] {ai_face();};
-void() sham_proj6 =[ $smash6, sham_proj7 ] {ai_face();};
-void() sham_proj7 =[ $smash7, sham_proj8 ] {ai_face();};
-void() sham_proj8 =[ $smash8, sham_proj9 ] {ai_face();};
-void() sham_proj9 =[ $smash9, sham_proj10 ] {ai_face();};
-void() sham_proj10 =[ $smash10, sham_proj11 ]
-{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
-};
-void() sham_proj11 =[ $smash11, sham_proj12 ] {ai_face();};
-void() sham_proj12 =[ $smash12, sham_run1 ] {ai_face();};
-/// projectile frames for turret mode
-void() sham_turret_proj1 =[ $smash1, sham_turret_proj2 ] {ai_face();};
-void() sham_turret_proj2 =[ $smash2, sham_turret_proj3 ] {ai_face();};
-void() sham_turret_proj3 =[ $smash3, sham_turret_proj4 ] {ai_face();};
-void() sham_turret_proj4 =[ $smash4, sham_turret_proj5 ] {ai_face();};
-void() sham_turret_proj5 =[ $smash5, sham_turret_proj6 ] {ai_face();};
-void() sham_turret_proj6 =[ $smash6, sham_turret_proj7 ] {ai_face();};
-void() sham_turret_proj7 =[ $smash7, sham_turret_proj8 ] {ai_face();};
-void() sham_turret_proj8 =[ $smash8, sham_turret_proj9 ] {ai_face();};
-void() sham_turret_proj9 =[ $smash9, sham_turret_proj10 ] {ai_face();};
-void() sham_turret_proj10 =[ $smash10, sham_turret_proj11 ]
-{
-ShamRocket();
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
-};
-void() sham_turret_proj11 =[ $smash11, sham_turret_proj12 ] {ai_face();};
-void() sham_turret_proj12 =[ $smash12, sham_seek_1 ] {ai_face();};
-
-void() sham_swingr1;
-
-void(float side) ShamClaw =
-{
-local vector delta;
-local float ldmg;
-
- if (!self.enemy)
- return;
- ai_charge(10);
-
- delta = self.enemy.origin - self.origin;
-
- if (vlen(delta) > 100)
- return;
-
- ldmg = (random() + random() + random()) * 20;
- T_Damage (self.enemy, self, self, ldmg);
- sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
-
- if (side)
- {
- makevectors (self.angles);
- SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
- }
-};
-
-void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
-sound_misc (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
-ai_charge(5);};
-void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
-void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
-void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
-void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
-void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
-void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
-void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
-void() sham_swingl9 =[ $swingl9, sham_run1 ] {
-ai_charge(8);
-if (random()<0.5)
- self.think = sham_swingr1;
-};
-
-void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
-sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
-ai_charge(1);};
-void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
-void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
-void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
-void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
-void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
-void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
-void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
-void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
-ai_charge(10);
-if (random()<0.5)
- self.think = sham_swingl1;
-};
-
-void() sham_melee2 =
-{
- local float chance;
-
- chance = random();
-
- if (chance > 0.6)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
-
-void() sham_melee =
-{
- local float chance;
-
- chance = random();
-
- if (chance > 0.6 || self.health == 600) // changed to >= as you can set custom health
- sham_smash1 ();
- else if (chance > 0.3)
- sham_swingr1 ();
- else
- sham_swingl1 ();
-};
-
-
-//============================================================================
-
-
-void() sham_arc_think =
-{
- if (self.owner != world && self.owner.trigger_field == self)
- self.owner.trigger_field = world;
- remove (self);
-};
-
-
-void() CastLightning =
-{
- local vector org, dir;
-
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- ai_face ();
-
- org = self.origin + '0 0 40';
-
- dir = self.enemy.origin + '0 0 16' - org;
- dir = normalize (dir);
-
- if (self.spawnflags & I_AM_TURRET)
- {
- traceline (org, self.origin + dir*900, TRUE, self);
- }
- else
- {
- traceline (org, self.origin + dir*600, TRUE, self);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (org, trace_endpos, self, 10);
-};
-
-void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
-void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_magic4 =[ $magic4, sham_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_magic5 =[ $magic5, sham_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_magic6 =[ $magic6, sham_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_magic9 =[ $magic9, sham_magic10 ]
-{CastLightning();};
-void() sham_magic10 =[ $magic10, sham_magic11 ]
-{CastLightning();};
-void() sham_magic11 =[ $magic11, sham_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_magic12 =[ $magic12, sham_run1 ] {};
-/////////////////////////
-//// turret start
-////////////////////////
-void() sham_turret_magic1 =[ $magic1, sham_turret_magic2 ] {ai_face();
- sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic2 =[ $magic2, sham_turret_magic3 ] {ai_face();};
-void() sham_turret_magic3 =[ $magic3, sham_turret_magic4 ] {ai_face();self.nextthink = time + 0.2;
-local entity o;
-
-self.effects = self.effects | EF_MUZZLEFLASH;
-ai_face();
-self.trigger_field = spawn();
-o = self.trigger_field;
-setmodel (o, "progs/s_light.mdl");
-setorigin (o, self.origin);
-o.owner = self;
-o.angles = self.angles;
-o.nextthink = time + 0.7;
-o.think = sham_arc_think;
-};
-void() sham_turret_magic4 =[ $magic4, sham_turret_magic5 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 1;
-};
-void() sham_turret_magic5 =[ $magic5, sham_turret_magic6 ]
-{
-self.effects = self.effects | EF_MUZZLEFLASH;
-self.trigger_field.frame = 2;
-};
-void() sham_turret_magic6 =[ $magic6, sham_turret_magic9 ]
-{
-remove (self.trigger_field);
-self.trigger_field = world;
-CastLightning();
-sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
-};
-void() sham_turret_magic9 =[ $magic9, sham_turret_magic10 ]
-{CastLightning();};
-void() sham_turret_magic10 =[ $magic10, sham_turret_magic11 ]
-{CastLightning();};
-void() sham_turret_magic11 =[ $magic11, sham_turret_magic12 ]
-{
-if (skill == 3)
- CastLightning();
-};
-void() sham_turret_magic12 =[ $magic12, sham_turret_magic13 ] {};
-void() sham_turret_magic13 =[ $stand14, sham_turret_magic14 ] {ai_face();};
-void() sham_turret_magic14 =[ $stand15, sham_turret_magic15 ] {ai_face();};
-void() sham_turret_magic15 =[ $stand16, sham_turret_magic16 ] {ai_face();};
-void() sham_turret_magic16 =[ $stand17, sham_seek_1 ] {};
-void() sham_seek_1 =[ $stand1, sham_seek_2 ] {ai_run(0);};
-void() sham_seek_2 =[ $stand2, sham_seek_3 ] {ai_run(0);};
-void() sham_seek_3 =[ $stand3, sham_seek_4 ] {ai_run(0);};
-void() sham_seek_4 =[ $stand4, sham_seek_5 ] {ai_run(0);};
-void() sham_seek_5 =[ $stand5, sham_seek_6 ] {ai_run(0);};
-void() sham_seek_6 =[ $stand6, sham_seek_7 ] {ai_run(0);};
-void() sham_seek_7 =[ $stand7, sham_seek_8 ] {ai_run(0);};
-void() sham_seek_8 =[ $stand8, sham_seek_9 ] {ai_run(0);};
-void() sham_seek_9 =[ $stand9, sham_seek_10] {ai_run(0);};
-void() sham_seek_10 =[ $stand10, sham_seek_11] {ai_run(0);};
-void() sham_seek_11 =[ $stand11, sham_seek_12] {ai_run(0);};
-void() sham_seek_12 =[ $stand12, sham_seek_13] {ai_run(0);};
-void() sham_seek_13 =[ $stand13, sham_seek_14] {ai_run(0);};
-void() sham_seek_14 =[ $stand14, sham_seek_15] {ai_run(0);};
-void() sham_seek_15 =[ $stand15, sham_seek_16] {ai_run(0);};
-void() sham_seek_16 =[ $stand16, sham_seek_17] {ai_run(0);};
-void() sham_seek_17 =[ $stand17, sham_seek_1 ] {ai_run(0);};
-/////////////////////////
-//// turret end
-////////////////////////
-
-void() sham_pain1 =[ $pain1, sham_pain2 ] {};
-void() sham_pain2 =[ $pain2, sham_pain3 ] {};
-void() sham_pain3 =[ $pain3, sham_pain4 ] {};
-void() sham_pain4 =[ $pain4, sham_pain5 ] {};
-void() sham_pain5 =[ $pain5, sham_pain6 ] {};
-void() sham_pain6 =[ $pain6, sham_run1 ] {};
-
-void(entity attacker, float damage) sham_pain =
-{
- sound_pain (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
-
- if (self.spawnflags & I_AM_TURRET)
- return;
-
- if (self.health <= 0)
- return; // allready dying, don't go into pain frame
-
- if (random()*400 > damage)
- return; // didn't flinch
-
- if (self.pain_finished > time)
- return;
- self.pain_finished = time + 2;
-
- if (self.trigger_field != world && self.trigger_field.owner == self)
- self.trigger_field.frame = 2;
- self.trigger_field = world;
-
- sham_pain1 ();
-};
-
-
-//============================================================================
-
-void() sham_death1 =[ $death1, sham_death2 ] {};
-void() sham_death2 =[ $death2, sham_death3 ] {};
-void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
-void() sham_death4 =[ $death4, sham_death5 ] {};
-void() sham_death5 =[ $death5, sham_death6 ] {};
-void() sham_death6 =[ $death6, sham_death7 ] {};
-void() sham_death7 =[ $death7, sham_death8 ] {};
-void() sham_death8 =[ $death8, sham_death9 ] {};
-void() sham_death9 =[ $death9, sham_death10 ] {};
-void() sham_death10 =[ $death10, sham_death11 ] {};
-void() sham_death11 =[ $death11, sham_death11 ] {};
-
-void() sham_die =
-{
-// check for gib
- if (self.health < -60)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_shams.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
- DropStuff();
- sham_death1 ();
-};
-
-//============================================================================
-
-
-/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/shambler.mdl");
-}
-Shambler.
-
-Default health = 600
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound (GRUNT)"
-snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (GRUNT 2)"
-snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
-snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- precache_body_model ("progs/shambler.mdl"); // custom_mdls dumptruck_ds
- precache_head_model ("progs/h_shams.mdl"); // custom_mdls dumptruck_ds
- // precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- // precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
- precache_proj_model ("progs/lavaball.mdl");
-
- precache_sound_misc1 ("shambler/sattck1.wav");
- precache_sound_misc2 ("shambler/sboom.wav");
- precache_sound_death ("shambler/sdeath.wav");
- precache_sound_pain ("shambler/shurt2.wav");
- precache_sound_idle ("shambler/sidle.wav");
- precache_sound_sight ("shambler/ssight.wav");
- precache_sound_attack ("shambler/melee1.wav");
- precache_sound_misc ("shambler/melee2.wav");
- precache_sound_hit ("shambler/smack.wav");
- precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
- body_model ("progs/shambler.mdl");
- // setmodel (self, "progs/shambler.mdl");
-
- setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 600;
- if (self.proj_speed_mod <= 0)
- {
- self.proj_speed_mod = 1;
- }
-
- self.th_stand = sham_stand1;
- self.th_walk = sham_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = sham_seek_1;
- }
- else
- {
- self.th_run = sham_run1;
- }
- self.th_die = sham_die;
- if (self.style == 1)
- self.th_melee = sham_melee2;
- else
- self.th_melee = sham_melee;
- if (self.style == 1)
- self.th_missile = sham_proj1;
- else
- self.th_missile = sham_magic1;
- if (self.style == 1)
- self.th_turret = sham_turret_proj1;
- else
- self.th_turret = sham_turret_magic1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = sham_pain;
- else
- self.th_pain = SUB_NullPain;
-
- walkmonster_start();
-};
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_shambler (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/shambler.mdl","frame":93});
-}
-*/
-void() monster_dead_shambler =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/shambler.mdl");
- setmodel(self, "progs/shambler.mdl");
- self.frame = $death11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-77.09 -72.17 -51.52','47.44 98.15 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-};
+/*
+==============================================================================
+
+SHAMBLER
+
+==============================================================================
+
+================
+ShamRocket
+================
+*/
+void() ShamRocket =
+{
+ local entity missile;
+ local float projspeed = 900 * self.proj_speed_mod;
+
+ sound_attack (self, CHAN_AUTO, "boss1/throw.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ SetSpeed(missile, normalize(self.enemy.origin - self.origin), projspeed);
+ missile.angles = vectoangles(missile.velocity);
+ missile.avelocity = self.cust_avelocity; //custom spin of projectile
+ if !(missile.avelocity)
+ missile.avelocity = '200 100 300';
+
+ missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, projspeed);
+ }
+ else
+ {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ missile.skin = self.skin_proj; //dumptruck_ds
+
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/lavaball.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward*8 + '0 0 24');
+};
+
+
+$cd id1/models/shams
+$origin 0 0 24
+$base base
+$skin base
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8 stand9
+$frame stand10 stand11 stand12 stand13 stand14 stand15 stand16 stand17
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7
+$frame walk8 walk9 walk10 walk11 walk12
+
+$frame run1 run2 run3 run4 run5 run6
+
+$frame smash1 smash2 smash3 smash4 smash5 smash6 smash7
+$frame smash8 smash9 smash10 smash11 smash12
+
+$frame swingr1 swingr2 swingr3 swingr4 swingr5
+$frame swingr6 swingr7 swingr8 swingr9
+
+$frame swingl1 swingl2 swingl3 swingl4 swingl5
+$frame swingl6 swingl7 swingl8 swingl9
+
+$frame magic1 magic2 magic3 magic4 magic5
+$frame magic6 magic7 magic8 magic9 magic10 magic11 magic12
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame death1 death2 death3 death4 death5 death6
+$frame death7 death8 death9 death10 death11
+
+void() sham_stand1 =[ $stand1, sham_stand2 ] {ai_stand();};
+void() sham_stand2 =[ $stand2, sham_stand3 ] {ai_stand();};
+void() sham_stand3 =[ $stand3, sham_stand4 ] {ai_stand();};
+void() sham_stand4 =[ $stand4, sham_stand5 ] {ai_stand();};
+void() sham_stand5 =[ $stand5, sham_stand6 ] {ai_stand();};
+void() sham_stand6 =[ $stand6, sham_stand7 ] {ai_stand();};
+void() sham_stand7 =[ $stand7, sham_stand8 ] {ai_stand();};
+void() sham_stand8 =[ $stand8, sham_stand9 ] {ai_stand();};
+void() sham_stand9 =[ $stand9, sham_stand10] {ai_stand();};
+void() sham_stand10 =[ $stand10, sham_stand11] {ai_stand();};
+void() sham_stand11 =[ $stand11, sham_stand12] {ai_stand();};
+void() sham_stand12 =[ $stand12, sham_stand13] {ai_stand();};
+void() sham_stand13 =[ $stand13, sham_stand14] {ai_stand();};
+void() sham_stand14 =[ $stand14, sham_stand15] {ai_stand();};
+void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
+void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
+void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
+
+void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
+void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
+void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
+void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
+void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
+void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
+void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
+void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
+void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
+void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
+void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
+void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
+if (random() > 0.8)
+ sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
+
+void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
+void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
+void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
+void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
+void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
+void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
+if (random() > 0.8)
+ sound_idle (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
+};
+
+void() sham_smash1 =[ $smash1, sham_smash2 ] {
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
+ai_charge(2);};
+void() sham_smash2 =[ $smash2, sham_smash3 ] {ai_charge(6);};
+void() sham_smash3 =[ $smash3, sham_smash4 ] {ai_charge(6);};
+void() sham_smash4 =[ $smash4, sham_smash5 ] {ai_charge(5);};
+void() sham_smash5 =[ $smash5, sham_smash6 ] {ai_charge(4);};
+void() sham_smash6 =[ $smash6, sham_smash7 ] {ai_charge(1);};
+void() sham_smash7 =[ $smash7, sham_smash8 ] {ai_charge(0);};
+void() sham_smash8 =[ $smash8, sham_smash9 ] {ai_charge(0);};
+void() sham_smash9 =[ $smash9, sham_smash10 ] {ai_charge(0);};
+void() sham_smash10 =[ $smash10, sham_smash11 ] {
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ ai_charge(0);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+ if (!CanDamage (self.enemy, self))
+ return;
+
+ ldmg = (random() + random() + random()) * 40;
+ T_Damage (self.enemy, self, self, ldmg);
+ sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
+
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+ SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
+};
+void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(5);};
+void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(4);};
+/////////////////////////////////////
+// new frames for projectile style
+////////////////////////////////////
+void() sham_proj1 =[ $smash1, sham_proj2 ] {ai_face();};
+void() sham_proj2 =[ $smash2, sham_proj3 ] {ai_face();};
+void() sham_proj3 =[ $smash3, sham_proj4 ] {ai_face();};
+void() sham_proj4 =[ $smash4, sham_proj5 ] {ai_face();};
+void() sham_proj5 =[ $smash5, sham_proj6 ] {ai_face();};
+void() sham_proj6 =[ $smash6, sham_proj7 ] {ai_face();};
+void() sham_proj7 =[ $smash7, sham_proj8 ] {ai_face();};
+void() sham_proj8 =[ $smash8, sham_proj9 ] {ai_face();};
+void() sham_proj9 =[ $smash9, sham_proj10 ] {ai_face();};
+void() sham_proj10 =[ $smash10, sham_proj11 ]
+{
+ShamRocket();
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
+};
+void() sham_proj11 =[ $smash11, sham_proj12 ] {ai_face();};
+void() sham_proj12 =[ $smash12, sham_run1 ] {ai_face();};
+/// projectile frames for turret mode
+void() sham_turret_proj1 =[ $smash1, sham_turret_proj2 ] {ai_face();};
+void() sham_turret_proj2 =[ $smash2, sham_turret_proj3 ] {ai_face();};
+void() sham_turret_proj3 =[ $smash3, sham_turret_proj4 ] {ai_face();};
+void() sham_turret_proj4 =[ $smash4, sham_turret_proj5 ] {ai_face();};
+void() sham_turret_proj5 =[ $smash5, sham_turret_proj6 ] {ai_face();};
+void() sham_turret_proj6 =[ $smash6, sham_turret_proj7 ] {ai_face();};
+void() sham_turret_proj7 =[ $smash7, sham_turret_proj8 ] {ai_face();};
+void() sham_turret_proj8 =[ $smash8, sham_turret_proj9 ] {ai_face();};
+void() sham_turret_proj9 =[ $smash9, sham_turret_proj10 ] {ai_face();};
+void() sham_turret_proj10 =[ $smash10, sham_turret_proj11 ]
+{
+ShamRocket();
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM); ai_face();
+};
+void() sham_turret_proj11 =[ $smash11, sham_turret_proj12 ] {ai_face();};
+void() sham_turret_proj12 =[ $smash12, sham_seek_1 ] {ai_face();};
+
+void() sham_swingr1;
+
+void(float side) ShamClaw =
+{
+local vector delta;
+local float ldmg;
+
+ if (!self.enemy)
+ return;
+ ai_charge(10);
+
+ delta = self.enemy.origin - self.origin;
+
+ if (vlen(delta) > 100)
+ return;
+
+ ldmg = (random() + random() + random()) * 20;
+ T_Damage (self.enemy, self, self, ldmg);
+ sound_hit (self, CHAN_VOICE, "shambler/smack.wav", 1, ATTN_NORM);
+
+ if (side)
+ {
+ makevectors (self.angles);
+ SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
+ }
+};
+
+void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
+sound_misc (self, CHAN_VOICE, "shambler/melee2.wav", 1, ATTN_NORM);
+ai_charge(5);};
+void() sham_swingl2 =[ $swingl2, sham_swingl3 ] {ai_charge(3);};
+void() sham_swingl3 =[ $swingl3, sham_swingl4 ] {ai_charge(7);};
+void() sham_swingl4 =[ $swingl4, sham_swingl5 ] {ai_charge(3);};
+void() sham_swingl5 =[ $swingl5, sham_swingl6 ] {ai_charge(7);};
+void() sham_swingl6 =[ $swingl6, sham_swingl7 ] {ai_charge(9);};
+void() sham_swingl7 =[ $swingl7, sham_swingl8 ] {ai_charge(5); ShamClaw(250);};
+void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(4);};
+void() sham_swingl9 =[ $swingl9, sham_run1 ] {
+ai_charge(8);
+if (random()<0.5)
+ self.think = sham_swingr1;
+};
+
+void() sham_swingr1 =[ $swingr1, sham_swingr2 ] {
+sound_attack (self, CHAN_VOICE, "shambler/melee1.wav", 1, ATTN_NORM);
+ai_charge(1);};
+void() sham_swingr2 =[ $swingr2, sham_swingr3 ] {ai_charge(8);};
+void() sham_swingr3 =[ $swingr3, sham_swingr4 ] {ai_charge(14);};
+void() sham_swingr4 =[ $swingr4, sham_swingr5 ] {ai_charge(7);};
+void() sham_swingr5 =[ $swingr5, sham_swingr6 ] {ai_charge(3);};
+void() sham_swingr6 =[ $swingr6, sham_swingr7 ] {ai_charge(6);};
+void() sham_swingr7 =[ $swingr7, sham_swingr8 ] {ai_charge(6); ShamClaw(-250);};
+void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(3);};
+void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(1);
+ai_charge(10);
+if (random()<0.5)
+ self.think = sham_swingl1;
+};
+
+void() sham_melee2 =
+{
+ local float chance;
+
+ chance = random();
+
+ if (chance > 0.6)
+ sham_swingr1 ();
+ else
+ sham_swingl1 ();
+};
+
+void() sham_melee =
+{
+ local float chance;
+
+ chance = random();
+
+ if (chance > 0.6 || self.health == 600) // changed to >= as you can set custom health
+ sham_smash1 ();
+ else if (chance > 0.3)
+ sham_swingr1 ();
+ else
+ sham_swingl1 ();
+};
+
+
+//============================================================================
+
+
+void() sham_arc_think =
+{
+ if (self.owner != world && self.owner.trigger_field == self)
+ self.owner.trigger_field = world;
+ remove (self);
+};
+
+
+void() CastLightning =
+{
+ local vector org, dir;
+
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ ai_face ();
+
+ org = self.origin + '0 0 40';
+
+ dir = self.enemy.origin + '0 0 16' - org;
+ dir = normalize (dir);
+
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ traceline (org, self.origin + dir*900, TRUE, self);
+ }
+ else
+ {
+ traceline (org, self.origin + dir*600, TRUE, self);
+ }
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING1);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (org, trace_endpos, self, 10);
+};
+
+void() sham_magic1 =[ $magic1, sham_magic2 ] {ai_face();
+ sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
+};
+void() sham_magic2 =[ $magic2, sham_magic3 ] {ai_face();};
+void() sham_magic3 =[ $magic3, sham_magic4 ] {ai_face();self.nextthink = time + 0.2;
+local entity o;
+
+self.effects = self.effects | EF_MUZZLEFLASH;
+ai_face();
+self.trigger_field = spawn();
+o = self.trigger_field;
+setmodel (o, "progs/s_light.mdl");
+setorigin (o, self.origin);
+o.owner = self;
+o.angles = self.angles;
+o.nextthink = time + 0.7;
+o.think = sham_arc_think;
+};
+void() sham_magic4 =[ $magic4, sham_magic5 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 1;
+};
+void() sham_magic5 =[ $magic5, sham_magic6 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 2;
+};
+void() sham_magic6 =[ $magic6, sham_magic9 ]
+{
+remove (self.trigger_field);
+self.trigger_field = world;
+CastLightning();
+sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
+};
+void() sham_magic9 =[ $magic9, sham_magic10 ]
+{CastLightning();};
+void() sham_magic10 =[ $magic10, sham_magic11 ]
+{CastLightning();};
+void() sham_magic11 =[ $magic11, sham_magic12 ]
+{
+if (skill == 3)
+ CastLightning();
+};
+void() sham_magic12 =[ $magic12, sham_run1 ] {};
+/////////////////////////
+//// turret start
+////////////////////////
+void() sham_turret_magic1 =[ $magic1, sham_turret_magic2 ] {ai_face();
+ sound_misc1 (self, CHAN_WEAPON, "shambler/sattck1.wav", 1, ATTN_NORM);
+};
+void() sham_turret_magic2 =[ $magic2, sham_turret_magic3 ] {ai_face();};
+void() sham_turret_magic3 =[ $magic3, sham_turret_magic4 ] {ai_face();self.nextthink = time + 0.2;
+local entity o;
+
+self.effects = self.effects | EF_MUZZLEFLASH;
+ai_face();
+self.trigger_field = spawn();
+o = self.trigger_field;
+setmodel (o, "progs/s_light.mdl");
+setorigin (o, self.origin);
+o.owner = self;
+o.angles = self.angles;
+o.nextthink = time + 0.7;
+o.think = sham_arc_think;
+};
+void() sham_turret_magic4 =[ $magic4, sham_turret_magic5 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 1;
+};
+void() sham_turret_magic5 =[ $magic5, sham_turret_magic6 ]
+{
+self.effects = self.effects | EF_MUZZLEFLASH;
+self.trigger_field.frame = 2;
+};
+void() sham_turret_magic6 =[ $magic6, sham_turret_magic9 ]
+{
+remove (self.trigger_field);
+self.trigger_field = world;
+CastLightning();
+sound_misc2 (self, CHAN_WEAPON, "shambler/sboom.wav", 1, ATTN_NORM);
+};
+void() sham_turret_magic9 =[ $magic9, sham_turret_magic10 ]
+{CastLightning();};
+void() sham_turret_magic10 =[ $magic10, sham_turret_magic11 ]
+{CastLightning();};
+void() sham_turret_magic11 =[ $magic11, sham_turret_magic12 ]
+{
+if (skill == 3)
+ CastLightning();
+};
+void() sham_turret_magic12 =[ $magic12, sham_turret_magic13 ] {};
+void() sham_turret_magic13 =[ $stand14, sham_turret_magic14 ] {ai_face();};
+void() sham_turret_magic14 =[ $stand15, sham_turret_magic15 ] {ai_face();};
+void() sham_turret_magic15 =[ $stand16, sham_turret_magic16 ] {ai_face();};
+void() sham_turret_magic16 =[ $stand17, sham_seek_1 ] {};
+void() sham_seek_1 =[ $stand1, sham_seek_2 ] {ai_run(0);};
+void() sham_seek_2 =[ $stand2, sham_seek_3 ] {ai_run(0);};
+void() sham_seek_3 =[ $stand3, sham_seek_4 ] {ai_run(0);};
+void() sham_seek_4 =[ $stand4, sham_seek_5 ] {ai_run(0);};
+void() sham_seek_5 =[ $stand5, sham_seek_6 ] {ai_run(0);};
+void() sham_seek_6 =[ $stand6, sham_seek_7 ] {ai_run(0);};
+void() sham_seek_7 =[ $stand7, sham_seek_8 ] {ai_run(0);};
+void() sham_seek_8 =[ $stand8, sham_seek_9 ] {ai_run(0);};
+void() sham_seek_9 =[ $stand9, sham_seek_10] {ai_run(0);};
+void() sham_seek_10 =[ $stand10, sham_seek_11] {ai_run(0);};
+void() sham_seek_11 =[ $stand11, sham_seek_12] {ai_run(0);};
+void() sham_seek_12 =[ $stand12, sham_seek_13] {ai_run(0);};
+void() sham_seek_13 =[ $stand13, sham_seek_14] {ai_run(0);};
+void() sham_seek_14 =[ $stand14, sham_seek_15] {ai_run(0);};
+void() sham_seek_15 =[ $stand15, sham_seek_16] {ai_run(0);};
+void() sham_seek_16 =[ $stand16, sham_seek_17] {ai_run(0);};
+void() sham_seek_17 =[ $stand17, sham_seek_1 ] {ai_run(0);};
+/////////////////////////
+//// turret end
+////////////////////////
+
+void() sham_pain1 =[ $pain1, sham_pain2 ] {};
+void() sham_pain2 =[ $pain2, sham_pain3 ] {};
+void() sham_pain3 =[ $pain3, sham_pain4 ] {};
+void() sham_pain4 =[ $pain4, sham_pain5 ] {};
+void() sham_pain5 =[ $pain5, sham_pain6 ] {};
+void() sham_pain6 =[ $pain6, sham_run1 ] {};
+
+void(entity attacker, float damage) sham_pain =
+{
+ sound_pain (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
+
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+
+ if (self.health <= 0)
+ return; // allready dying, don't go into pain frame
+
+ if (random()*400 > damage)
+ return; // didn't flinch
+
+ if (self.pain_finished > time)
+ return;
+ self.pain_finished = time + 2;
+
+ if (self.trigger_field != world && self.trigger_field.owner == self)
+ self.trigger_field.frame = 2;
+ self.trigger_field = world;
+
+ sham_pain1 ();
+};
+
+
+//============================================================================
+
+void() sham_death1 =[ $death1, sham_death2 ] {};
+void() sham_death2 =[ $death2, sham_death3 ] {};
+void() sham_death3 =[ $death3, sham_death4 ] {self.solid = SOLID_NOT;};
+void() sham_death4 =[ $death4, sham_death5 ] {};
+void() sham_death5 =[ $death5, sham_death6 ] {};
+void() sham_death6 =[ $death6, sham_death7 ] {};
+void() sham_death7 =[ $death7, sham_death8 ] {};
+void() sham_death8 =[ $death8, sham_death9 ] {};
+void() sham_death9 =[ $death9, sham_death10 ] {};
+void() sham_death10 =[ $death10, sham_death11 ] {};
+void() sham_death11 =[ $death11, sham_death11 ] {};
+
+void() sham_die =
+{
+// check for gib
+ if (self.health < -60)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_shams.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "shambler/sdeath.wav", 1, ATTN_NORM);
+ DropStuff();
+ sham_death1 ();
+};
+
+//============================================================================
+
+
+/*QUAKED monster_shambler (1 0 0) (-32 -32 -24) (32 32 64) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/shambler.mdl");
+}
+Shambler.
+
+Default health = 600
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound (GRUNT)"
+snd_hit(string) : "Path to custom hit sound (FLESH TEARING)"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (GRUNT 2)"
+snd_misc1(string) : "Path to custom sound (LIGHTNING ZAP)"
+snd_misc2(string) : "Path to custom sound (LIGHTNING BOOM)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ precache_body_model ("progs/shambler.mdl"); // custom_mdls dumptruck_ds
+ precache_head_model ("progs/h_shams.mdl"); // custom_mdls dumptruck_ds
+ // precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ // precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+ precache_proj_model ("progs/lavaball.mdl");
+
+ precache_sound_misc1 ("shambler/sattck1.wav");
+ precache_sound_misc2 ("shambler/sboom.wav");
+ precache_sound_death ("shambler/sdeath.wav");
+ precache_sound_pain ("shambler/shurt2.wav");
+ precache_sound_idle ("shambler/sidle.wav");
+ precache_sound_sight ("shambler/ssight.wav");
+ precache_sound_attack ("shambler/melee1.wav");
+ precache_sound_misc ("shambler/melee2.wav");
+ precache_sound_hit ("shambler/smack.wav");
+ precache_sound ("boss1/throw.wav"); // jaycie erysdren 2021-09-14
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+ body_model ("progs/shambler.mdl");
+ // setmodel (self, "progs/shambler.mdl");
+
+ setsize (self, VEC_HULL2_MIN, VEC_HULL2_MAX);
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 600;
+ if (self.proj_speed_mod <= 0)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ self.th_stand = sham_stand1;
+ self.th_walk = sham_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = sham_seek_1;
+ }
+ else
+ {
+ self.th_run = sham_run1;
+ }
+ self.th_die = sham_die;
+ if (self.style == 1)
+ self.th_melee = sham_melee2;
+ else
+ self.th_melee = sham_melee;
+ if (self.style == 1)
+ self.th_missile = sham_proj1;
+ else
+ self.th_missile = sham_magic1;
+ if (self.style == 1)
+ self.th_turret = sham_turret_proj1;
+ else
+ self.th_turret = sham_turret_magic1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = sham_pain;
+ else
+ self.th_pain = SUB_NullPain;
+
+ walkmonster_start();
+};
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_shambler (0 0.5 0.8) (-32 -32 -24) (32 32 64) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/shambler.mdl","frame":93});
+}
+*/
+void() monster_dead_shambler =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/shambler.mdl");
+ setmodel(self, "progs/shambler.mdl");
+ self.frame = $death11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-77.09 -72.17 -51.52','47.44 98.15 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/soldier.qc

diff --git a/qc/monsters/soldier.qc b/qc/monsters/soldier.qc
index 5c22745..3a5034e 100644
--- a/qc/monsters/soldier.qc
+++ b/qc/monsters/soldier.qc
@@ -1,709 +1,709 @@
-/*
-==============================================================================
-
-SOLDIER / PLAYER
-
-==============================================================================
-*/
-
-$cd id1/models/soldier3
-$origin 0 -6 24
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-$frame death9 death10
-
-$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
-$frame deathc9 deathc10 deathc11
-
-$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11
-
-$frame pain1 pain2 pain3 pain4 pain5 pain6
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
-$frame painc11 painc12 painc13
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8
-
-$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9
-
-$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
-$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
-$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
-
-/*
-==============================================================================
-SOLDIER CODE
-==============================================================================
-*/
-void() genforcer_fire =
-{
- local vector org;
-
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
- makevectors (self.angles);
-
- org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
-
- LaunchLaser(org, self.enemy.origin - self.origin);
-};
-/*
-================
-GruntFireGrenade
-================
-*/
-void() GruntFireGrenade =
-{
- local entity missile;
-
- // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = OgreGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = OgreGrenadeExplode;
-
- // setmodel (missile, "progs/grenade.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/grenade.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 16'); //dumptruck_ds
-};
-
-/*
-================
-MonFireSpike // used for Grunts
-================
-*/
-
-void() MonFireSpike =
-{
- local vector dir;
- // local entity old;
-
- sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- if (self.style == 5)
- self.attack_finished = time + 1.5;
- else
- self.attack_finished = time + 0.2;
-
- dir = normalize (self.enemy.origin - self.origin);
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
-
- launch_spike (self.origin + v_forward * 30 + v_right * 5 + '0 0 12', dir); //dumptruck_ds
- // launch_spike (self.origin + '0 0 16', dir);
-
- //newmis.touch = superspike_touch;
- // setmodel (newmis, "progs/s_spike.mdl");
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (newmis, self.mdl_proj);
- }
- else
- {
- setmodel (newmis, "progs/s_spike.mdl");
- }
-
- if (!newmis.skin_proj) // dumptruck_ds
- {
- newmis.skin = self.skin_proj;
- }
- else
- {
- newmis.skin = 0;
- }
- // dumptruck_ds - end
-
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-};
-
-void() army_fire;
-
-void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
-void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
-void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
-void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
-void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
-void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
-void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
-void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
-
-void() army_walk1 =[ $prowl_1, army_walk2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_walk(1);};
-void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
-void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
-void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
-void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
-void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
-void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
-void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
-void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
-void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
-void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
-void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
-void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
-void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
-void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
-void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
-void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
-void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
-void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
-void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
-void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
-void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
-void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
-void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
-
-void() army_run1 =[ $run1, army_run2 ] {
-if (random() < 0.2)
- sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
-ai_run(11);};
-void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
-void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
-void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
-void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
-void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
-void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
-void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
-
-
-void() army_atk6;
-void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
-void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
-void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
-void() army_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
-void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
-void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
-void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
-// new frames for turrets
-void() army_turret_atk6;
-void() army_turret_atk1 =[ $shoot1, army_turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
-void() army_turret_atk2 =[ $shoot2, army_turret_atk3 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() army_turret_atk3 =[ $shoot3, army_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk4 =[ $shoot4, army_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() army_turret_atk5 ={
-self.frame = $shoot5;
-self.nextthink = time + .1;
-if (self.style == 5 && self.count < self.t_length)
-{
- self.count +=1;
-}
-else
-{
- self.think = army_turret_atk6;
-}
-ai_face();
-army_fire();
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() army_turret_atk6 =[ $shoot6, army_turret_atk7 ] {ai_face();};
-void() army_turret_atk7 =[ $shoot7, army_turret_atk8 ] {ai_face();SUB_CheckRefire (army_turret_atk1);};
-void() army_turret_atk8 =[ $shoot8, army_turret_atk9 ] {ai_face();};
-void() army_turret_atk9 =[ $stand4, army_turret_atk10 ] {ai_face();};
-void() army_turret_atk10 =[ $stand5, army_seeking_stand1 ] {ai_face();};
-void() army_seeking_stand1 =[ $stand1, army_seeking_stand2 ] {ai_run(0);};
-void() army_seeking_stand2 =[ $stand2, army_seeking_stand3 ] {ai_run(0);};
-void() army_seeking_stand3 =[ $stand3, army_seeking_stand4 ] {ai_run(0);};
-void() army_seeking_stand4 =[ $stand4, army_seeking_stand5 ] {ai_run(0);};
-void() army_seeking_stand5 =[ $stand5, army_seeking_stand6 ] {ai_run(0);};
-void() army_seeking_stand6 =[ $stand6, army_seeking_stand7 ] {ai_run(0);};
-void() army_seeking_stand7 =[ $stand7, army_seeking_stand8 ] {ai_run(0);};
-void() army_seeking_stand8 =[ $stand8, army_seeking_stand1 ] {ai_run(0);};
-// new frames for turrets end
-
-void() army_pain1 =[ $pain1, army_pain2 ] {};
-void() army_pain2 =[ $pain2, army_pain3 ] {};
-void() army_pain3 =[ $pain3, army_pain4 ] {};
-void() army_pain4 =[ $pain4, army_pain5 ] {};
-void() army_pain5 =[ $pain5, army_pain6 ] {};
-void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
-
-void() army_painb1 =[ $painb1, army_painb2 ] {};
-void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
-void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
-void() army_painb4 =[ $painb4, army_painb5 ] {};
-void() army_painb5 =[ $painb5, army_painb6 ] {};
-void() army_painb6 =[ $painb6, army_painb7 ] {};
-void() army_painb7 =[ $painb7, army_painb8 ] {};
-void() army_painb8 =[ $painb8, army_painb9 ] {};
-void() army_painb9 =[ $painb9, army_painb10] {};
-void() army_painb10=[ $painb10, army_painb11] {};
-void() army_painb11=[ $painb11, army_painb12] {};
-void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
-void() army_painb13=[ $painb13, army_painb14] {};
-void() army_painb14=[ $painb14, army_run1 ] {};
-
-void() army_painc1 =[ $painc1, army_painc2 ] {};
-void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
-void() army_painc3 =[ $painc3, army_painc4 ] {};
-void() army_painc4 =[ $painc4, army_painc5 ] {};
-void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
-void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
-void() army_painc7 =[ $painc7, army_painc8 ] {};
-void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
-void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
-void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
-void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
-void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
-void() army_painc13=[ $painc13, army_run1] {};
-
-void(entity attacker, float damage) army_pain =
-{
- local float r;
-
- if (self.pain_finished > time)
- return;
-
- r = random();
-
- if (r < 0.2)
- { // turret checks moved here to play pain sounds correctly - dumptruck_ds
- self.pain_finished = time + 0.6;
- sound_pain (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_pain1 ();
- }
- else if (r < 0.6)
- {
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_painb1 ();
- }
- else
- {
- self.pain_finished = time + 1.1;
- sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
- if (self.spawnflags & I_AM_TURRET)
- return;
- else
- army_painc1 ();
- }
-};
-
-void() army_fire =
-{ //dumptruck_ds start rocket grunt stuff
-
-if (self.style == 1)
-
- {
- ai_face();
-
- W_GruntRocket();
- }
-
-else if (self.style == 2)
-
- {
- ai_face();
- if (self.spawnflags & I_AM_TURRET)
- {
- PreachFireGrenade(self.attack_elevation);
- }
- else
- GruntFireGrenade();
- }
-
-else if (self.style == 3)
-
- {
- ai_face();
- genforcer_fire();
- }
-
-else if (self.style == 4 || self.style == 5)
-
- {
- ai_face();
- MonFireSpike();
- }
-
-else
-
- {
- local vector dir;
- local entity en;
-
- ai_face();
-
- sound_attack (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
-
- // fire somewhat behind the player, so a dodging player is harder to hit
- en = self.enemy;
-
- dir = en.origin - en.velocity*0.2;
- dir = normalize (dir - self.origin);
-
- FireBullets (4, dir, '0.1 0.1 0');
- }
-
-};
-
-void() army_die1 =[ $death1, army_die2 ] {};
-void() army_die2 =[ $death2, army_die3 ] {};
-void() army_die3 =[ $death3, army_die4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
- {
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
- {
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
- {
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)DropBackpack();};
-void() army_die4 =[ $death4, army_die5 ] {};
-void() army_die5 =[ $death5, army_die6 ] {};
-void() army_die6 =[ $death6, army_die7 ] {};
-void() army_die7 =[ $death7, army_die8 ] {};
-void() army_die8 =[ $death8, army_die9 ] {};
-void() army_die9 =[ $death9, army_die10 ] {};
-void() army_die10 =[ $death10, army_die10 ] {};
-
-void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
-void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
-void() army_cdie3 =[ $deathc3, army_cdie4 ]
-{self.solid = SOLID_NOT;
-// style ammotype check -- dumptruck_ds
- if (self.style == 1)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 2)
- {
- self.ammo_rockets = 2;
- }
- if (self.style == 3)
- {
- self.ammo_cells = 5;
- }
- if (self.style == 4 || self.style == 5)
- {
- self.ammo_nails = 5;
- }
- else if (self.style == 0)
- {
- self.ammo_shells = 5;
- }
-if(!self.keep_ammo)DropBackpack();ai_back(4);}; //dumptruck_ds
-void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
-void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
-void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
-void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
-void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
-void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
-void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
-void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
-
-
-void() army_die =
-{
-// check for gib
- if (self.health < -35)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_guard.mdl", self.health);
- }
- // ThrowGib ("progs/gib1.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib3.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
- return;
- }
-
-// regular death
- sound_death (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
- DropStuff();
- if (random() < 0.5)
- army_die1 ();
- else
- army_cdie1 ();
-};
-
-
-/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/soldier.mdl");
-}
-Grunt.
-
-Default health = 30"
-
-keep_ammo "1 = Don't drop backpack upon death"
-snd_death "Path to custom death sound"
-snd_pain "Path to custom pain sound"
-snd_sight "Path to custom sight sound"
-snd_attack "Path to custom attack sound (GUNSHOT)"
-snd_idle "Path to custom idle sound"
-snd_misc "Path to custom sound (PAIN 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-style "Attack type"
-0 "Default (shotgun)"
-1 "Rockets"
-2 "Grenades"
-3 "lasers"
-4 "Nails"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
- //dumptruck_ds custom_mdls
- precache_body_model ("progs/soldier.mdl");
- precache_head_model ("progs/h_guard.mdl");
- precache_proj_model ("progs/missile.mdl"); // used if style == 1
- precache_proj_model ("progs/grenade.mdl"); // used if style == 2
- precache_model2 ("progs/laser.mdl"); // used if style == 3
- //dumptruck_ds custom_mdls
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound_death ("soldier/death1.wav");
- precache_sound_idle ("soldier/idle.wav");
- precache_sound_pain ("soldier/pain1.wav");
- precache_sound_misc ("soldier/pain2.wav");
- precache_sound_attack ("soldier/sattck1.wav");
- precache_sound_sight ("soldier/sight1.wav");
- precache_sound2 ("enforcer/enfire.wav"); // used if style == 3
- precache_sound2 ("enforcer/enfstop.wav"); // used if style == 3
-
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- //dumptruck_ds custom_mdls
- body_model ("progs/soldier.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 30;
-
- self.th_stand = army_stand1;
- self.th_walk = army_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = army_seeking_stand1;
- }
- else
- {
- self.th_run = army_run1;
- }
- self.th_missile = army_atk1;
- self.th_turret = army_turret_atk1;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = army_pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = army_die;
-
- walkmonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_army (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/soldier.mdl","frame":28});
-}
-*/
-void() monster_dead_army =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/soldier.mdl");
- setmodel(self, "progs/soldier.mdl");
- if (self.spawnflags & 2)
- {
- self.frame = $death10;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.27 -30.47 -50.3','22.1 25.35 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
- else
- {
- self.frame = $deathc11;
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
- }
-};
+/*
+==============================================================================
+
+SOLDIER / PLAYER
+
+==============================================================================
+*/
+
+$cd id1/models/soldier3
+$origin 0 -6 24
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+$frame death9 death10
+
+$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
+$frame deathc9 deathc10 deathc11
+
+$frame load1 load2 load3 load4 load5 load6 load7 load8 load9 load10 load11
+
+$frame pain1 pain2 pain3 pain4 pain5 pain6
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
+$frame painc11 painc12 painc13
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8
+
+$frame shoot1 shoot2 shoot3 shoot4 shoot5 shoot6 shoot7 shoot8 shoot9
+
+$frame prowl_1 prowl_2 prowl_3 prowl_4 prowl_5 prowl_6 prowl_7 prowl_8
+$frame prowl_9 prowl_10 prowl_11 prowl_12 prowl_13 prowl_14 prowl_15 prowl_16
+$frame prowl_17 prowl_18 prowl_19 prowl_20 prowl_21 prowl_22 prowl_23 prowl_24
+
+/*
+==============================================================================
+SOLDIER CODE
+==============================================================================
+*/
+void() genforcer_fire =
+{
+ local vector org;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
+ makevectors (self.angles);
+
+ org = self.origin + v_forward * 30 + v_right * 5 + '0 0 12';
+
+ LaunchLaser(org, self.enemy.origin - self.origin);
+};
+/*
+================
+GruntFireGrenade
+================
+*/
+void() GruntFireGrenade =
+{
+ local entity missile;
+
+ // self.effects = self.effects | EF_MUZZLEFLASH; //redundant -- dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = OgreGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = OgreGrenadeExplode;
+
+ // setmodel (missile, "progs/grenade.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/grenade.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 16'); //dumptruck_ds
+};
+
+/*
+================
+MonFireSpike // used for Grunts
+================
+*/
+
+void() MonFireSpike =
+{
+ local vector dir;
+ // local entity old;
+
+ sound_attack (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ if (self.style == 5)
+ self.attack_finished = time + 1.5;
+ else
+ self.attack_finished = time + 0.2;
+
+ dir = normalize (self.enemy.origin - self.origin);
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+
+ launch_spike (self.origin + v_forward * 30 + v_right * 5 + '0 0 12', dir); //dumptruck_ds
+ // launch_spike (self.origin + '0 0 16', dir);
+
+ //newmis.touch = superspike_touch;
+ // setmodel (newmis, "progs/s_spike.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (newmis, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (newmis, "progs/s_spike.mdl");
+ }
+
+ if (!newmis.skin_proj) // dumptruck_ds
+ {
+ newmis.skin = self.skin_proj;
+ }
+ else
+ {
+ newmis.skin = 0;
+ }
+ // dumptruck_ds - end
+
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+};
+
+void() army_fire;
+
+void() army_stand1 =[ $stand1, army_stand2 ] {ai_stand();};
+void() army_stand2 =[ $stand2, army_stand3 ] {ai_stand();};
+void() army_stand3 =[ $stand3, army_stand4 ] {ai_stand();};
+void() army_stand4 =[ $stand4, army_stand5 ] {ai_stand();};
+void() army_stand5 =[ $stand5, army_stand6 ] {ai_stand();};
+void() army_stand6 =[ $stand6, army_stand7 ] {ai_stand();};
+void() army_stand7 =[ $stand7, army_stand8 ] {ai_stand();};
+void() army_stand8 =[ $stand8, army_stand1 ] {ai_stand();};
+
+void() army_walk1 =[ $prowl_1, army_walk2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
+ai_walk(1);};
+void() army_walk2 =[ $prowl_2, army_walk3 ] {ai_walk(1);};
+void() army_walk3 =[ $prowl_3, army_walk4 ] {ai_walk(1);};
+void() army_walk4 =[ $prowl_4, army_walk5 ] {ai_walk(1);};
+void() army_walk5 =[ $prowl_5, army_walk6 ] {ai_walk(2);};
+void() army_walk6 =[ $prowl_6, army_walk7 ] {ai_walk(3);};
+void() army_walk7 =[ $prowl_7, army_walk8 ] {ai_walk(4);};
+void() army_walk8 =[ $prowl_8, army_walk9 ] {ai_walk(4);};
+void() army_walk9 =[ $prowl_9, army_walk10 ] {ai_walk(2);};
+void() army_walk10 =[ $prowl_10, army_walk11 ] {ai_walk(2);};
+void() army_walk11 =[ $prowl_11, army_walk12 ] {ai_walk(2);};
+void() army_walk12 =[ $prowl_12, army_walk13 ] {ai_walk(1);};
+void() army_walk13 =[ $prowl_13, army_walk14 ] {ai_walk(0);};
+void() army_walk14 =[ $prowl_14, army_walk15 ] {ai_walk(1);};
+void() army_walk15 =[ $prowl_15, army_walk16 ] {ai_walk(1);};
+void() army_walk16 =[ $prowl_16, army_walk17 ] {ai_walk(1);};
+void() army_walk17 =[ $prowl_17, army_walk18 ] {ai_walk(3);};
+void() army_walk18 =[ $prowl_18, army_walk19 ] {ai_walk(3);};
+void() army_walk19 =[ $prowl_19, army_walk20 ] {ai_walk(3);};
+void() army_walk20 =[ $prowl_20, army_walk21 ] {ai_walk(3);};
+void() army_walk21 =[ $prowl_21, army_walk22 ] {ai_walk(2);};
+void() army_walk22 =[ $prowl_22, army_walk23 ] {ai_walk(1);};
+void() army_walk23 =[ $prowl_23, army_walk24 ] {ai_walk(1);};
+void() army_walk24 =[ $prowl_24, army_walk1 ] {ai_walk(1);};
+
+void() army_run1 =[ $run1, army_run2 ] {
+if (random() < 0.2)
+ sound_idle (self, CHAN_VOICE, "soldier/idle.wav", 1, ATTN_IDLE);
+ai_run(11);};
+void() army_run2 =[ $run2, army_run3 ] {ai_run(15);};
+void() army_run3 =[ $run3, army_run4 ] {ai_run(10);};
+void() army_run4 =[ $run4, army_run5 ] {ai_run(10);};
+void() army_run5 =[ $run5, army_run6 ] {ai_run(8);};
+void() army_run6 =[ $run6, army_run7 ] {ai_run(15);};
+void() army_run7 =[ $run7, army_run8 ] {ai_run(10);};
+void() army_run8 =[ $run8, army_run1 ] {ai_run(8);};
+
+
+void() army_atk6;
+void() army_atk1 =[ $shoot1, army_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() army_atk2 =[ $shoot2, army_atk3 ] {ai_face();};
+void() army_atk3 =[ $shoot3, army_atk4 ] {ai_face();};
+void() army_atk4 =[ $shoot4, army_atk5 ] {ai_face();};
+void() army_atk5 ={
+self.frame = $shoot5;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = army_atk6;
+}
+ai_face();
+army_fire();
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() army_atk6 =[ $shoot6, army_atk7 ] {ai_face();};
+void() army_atk7 =[ $shoot7, army_atk8 ] {ai_face();SUB_CheckRefire (army_atk1);};
+void() army_atk8 =[ $shoot8, army_atk9 ] {ai_face();};
+void() army_atk9 =[ $shoot9, army_run1 ] {ai_face();};
+// new frames for turrets
+void() army_turret_atk6;
+void() army_turret_atk1 =[ $shoot1, army_turret_atk2 ] {ai_face();self.count = 0;self.t_length= 4 + floor(random()*4);};
+void() army_turret_atk2 =[ $shoot2, army_turret_atk3 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() army_turret_atk3 =[ $shoot3, army_turret_atk4 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() army_turret_atk4 =[ $shoot4, army_turret_atk5 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() army_turret_atk5 ={
+self.frame = $shoot5;
+self.nextthink = time + .1;
+if (self.style == 5 && self.count < self.t_length)
+{
+ self.count +=1;
+}
+else
+{
+ self.think = army_turret_atk6;
+}
+ai_face();
+army_fire();
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() army_turret_atk6 =[ $shoot6, army_turret_atk7 ] {ai_face();};
+void() army_turret_atk7 =[ $shoot7, army_turret_atk8 ] {ai_face();SUB_CheckRefire (army_turret_atk1);};
+void() army_turret_atk8 =[ $shoot8, army_turret_atk9 ] {ai_face();};
+void() army_turret_atk9 =[ $stand4, army_turret_atk10 ] {ai_face();};
+void() army_turret_atk10 =[ $stand5, army_seeking_stand1 ] {ai_face();};
+void() army_seeking_stand1 =[ $stand1, army_seeking_stand2 ] {ai_run(0);};
+void() army_seeking_stand2 =[ $stand2, army_seeking_stand3 ] {ai_run(0);};
+void() army_seeking_stand3 =[ $stand3, army_seeking_stand4 ] {ai_run(0);};
+void() army_seeking_stand4 =[ $stand4, army_seeking_stand5 ] {ai_run(0);};
+void() army_seeking_stand5 =[ $stand5, army_seeking_stand6 ] {ai_run(0);};
+void() army_seeking_stand6 =[ $stand6, army_seeking_stand7 ] {ai_run(0);};
+void() army_seeking_stand7 =[ $stand7, army_seeking_stand8 ] {ai_run(0);};
+void() army_seeking_stand8 =[ $stand8, army_seeking_stand1 ] {ai_run(0);};
+// new frames for turrets end
+
+void() army_pain1 =[ $pain1, army_pain2 ] {};
+void() army_pain2 =[ $pain2, army_pain3 ] {};
+void() army_pain3 =[ $pain3, army_pain4 ] {};
+void() army_pain4 =[ $pain4, army_pain5 ] {};
+void() army_pain5 =[ $pain5, army_pain6 ] {};
+void() army_pain6 =[ $pain6, army_run1 ] {ai_pain(1);};
+
+void() army_painb1 =[ $painb1, army_painb2 ] {};
+void() army_painb2 =[ $painb2, army_painb3 ] {ai_painforward(13);};
+void() army_painb3 =[ $painb3, army_painb4 ] {ai_painforward(9);};
+void() army_painb4 =[ $painb4, army_painb5 ] {};
+void() army_painb5 =[ $painb5, army_painb6 ] {};
+void() army_painb6 =[ $painb6, army_painb7 ] {};
+void() army_painb7 =[ $painb7, army_painb8 ] {};
+void() army_painb8 =[ $painb8, army_painb9 ] {};
+void() army_painb9 =[ $painb9, army_painb10] {};
+void() army_painb10=[ $painb10, army_painb11] {};
+void() army_painb11=[ $painb11, army_painb12] {};
+void() army_painb12=[ $painb12, army_painb13] {ai_pain(2);};
+void() army_painb13=[ $painb13, army_painb14] {};
+void() army_painb14=[ $painb14, army_run1 ] {};
+
+void() army_painc1 =[ $painc1, army_painc2 ] {};
+void() army_painc2 =[ $painc2, army_painc3 ] {ai_pain(1);};
+void() army_painc3 =[ $painc3, army_painc4 ] {};
+void() army_painc4 =[ $painc4, army_painc5 ] {};
+void() army_painc5 =[ $painc5, army_painc6 ] {ai_painforward(1);};
+void() army_painc6 =[ $painc6, army_painc7 ] {ai_painforward(1);};
+void() army_painc7 =[ $painc7, army_painc8 ] {};
+void() army_painc8 =[ $painc8, army_painc9 ] {ai_pain(1);};
+void() army_painc9 =[ $painc9, army_painc10] {ai_painforward(4);};
+void() army_painc10=[ $painc10, army_painc11] {ai_painforward(3);};
+void() army_painc11=[ $painc11, army_painc12] {ai_painforward(6);};
+void() army_painc12=[ $painc12, army_painc13] {ai_painforward(8);};
+void() army_painc13=[ $painc13, army_run1] {};
+
+void(entity attacker, float damage) army_pain =
+{
+ local float r;
+
+ if (self.pain_finished > time)
+ return;
+
+ r = random();
+
+ if (r < 0.2)
+ { // turret checks moved here to play pain sounds correctly - dumptruck_ds
+ self.pain_finished = time + 0.6;
+ sound_pain (self, CHAN_VOICE, "soldier/pain1.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_pain1 ();
+ }
+ else if (r < 0.6)
+ {
+ self.pain_finished = time + 1.1;
+ sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_painb1 ();
+ }
+ else
+ {
+ self.pain_finished = time + 1.1;
+ sound_misc (self, CHAN_VOICE, "soldier/pain2.wav", 1, ATTN_NORM);
+ if (self.spawnflags & I_AM_TURRET)
+ return;
+ else
+ army_painc1 ();
+ }
+};
+
+void() army_fire =
+{ //dumptruck_ds start rocket grunt stuff
+
+if (self.style == 1)
+
+ {
+ ai_face();
+
+ W_GruntRocket();
+ }
+
+else if (self.style == 2)
+
+ {
+ ai_face();
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ PreachFireGrenade(self.attack_elevation);
+ }
+ else
+ GruntFireGrenade();
+ }
+
+else if (self.style == 3)
+
+ {
+ ai_face();
+ genforcer_fire();
+ }
+
+else if (self.style == 4 || self.style == 5)
+
+ {
+ ai_face();
+ MonFireSpike();
+ }
+
+else
+
+ {
+ local vector dir;
+ local entity en;
+
+ ai_face();
+
+ sound_attack (self, CHAN_WEAPON, "soldier/sattck1.wav", 1, ATTN_NORM);
+
+ // fire somewhat behind the player, so a dodging player is harder to hit
+ en = self.enemy;
+
+ dir = en.origin - en.velocity*0.2;
+ dir = normalize (dir - self.origin);
+
+ FireBullets (4, dir, '0.1 0.1 0');
+ }
+
+};
+
+void() army_die1 =[ $death1, army_die2 ] {};
+void() army_die2 =[ $death2, army_die3 ] {};
+void() army_die3 =[ $death3, army_die4 ]
+{self.solid = SOLID_NOT;
+// style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3)
+ {
+ self.ammo_cells = 5;
+ }
+ if (self.style == 4 || self.style == 5)
+ {
+ self.ammo_nails = 5;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_shells = 5;
+ }
+if(!self.keep_ammo)DropBackpack();};
+void() army_die4 =[ $death4, army_die5 ] {};
+void() army_die5 =[ $death5, army_die6 ] {};
+void() army_die6 =[ $death6, army_die7 ] {};
+void() army_die7 =[ $death7, army_die8 ] {};
+void() army_die8 =[ $death8, army_die9 ] {};
+void() army_die9 =[ $death9, army_die10 ] {};
+void() army_die10 =[ $death10, army_die10 ] {};
+
+void() army_cdie1 =[ $deathc1, army_cdie2 ] {};
+void() army_cdie2 =[ $deathc2, army_cdie3 ] {ai_back(5);};
+void() army_cdie3 =[ $deathc3, army_cdie4 ]
+{self.solid = SOLID_NOT;
+// style ammotype check -- dumptruck_ds
+ if (self.style == 1)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 2)
+ {
+ self.ammo_rockets = 2;
+ }
+ if (self.style == 3)
+ {
+ self.ammo_cells = 5;
+ }
+ if (self.style == 4 || self.style == 5)
+ {
+ self.ammo_nails = 5;
+ }
+ else if (self.style == 0)
+ {
+ self.ammo_shells = 5;
+ }
+if(!self.keep_ammo)DropBackpack();ai_back(4);}; //dumptruck_ds
+void() army_cdie4 =[ $deathc4, army_cdie5 ] {ai_back(13);};
+void() army_cdie5 =[ $deathc5, army_cdie6 ] {ai_back(3);};
+void() army_cdie6 =[ $deathc6, army_cdie7 ] {ai_back(4);};
+void() army_cdie7 =[ $deathc7, army_cdie8 ] {};
+void() army_cdie8 =[ $deathc8, army_cdie9 ] {};
+void() army_cdie9 =[ $deathc9, army_cdie10 ] {};
+void() army_cdie10 =[ $deathc10, army_cdie11 ] {};
+void() army_cdie11 =[ $deathc11, army_cdie11 ] {};
+
+
+void() army_die =
+{
+// check for gib
+ if (self.health < -35)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_guard.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib3.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+
+// regular death
+ sound_death (self, CHAN_VOICE, "soldier/death1.wav", 1, ATTN_NORM);
+ DropStuff();
+ if (random() < 0.5)
+ army_die1 ();
+ else
+ army_cdie1 ();
+};
+
+
+/*QUAKED monster_army (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/soldier.mdl");
+}
+Grunt.
+
+Default health = 30"
+
+keep_ammo "1 = Don't drop backpack upon death"
+snd_death "Path to custom death sound"
+snd_pain "Path to custom pain sound"
+snd_sight "Path to custom sight sound"
+snd_attack "Path to custom attack sound (GUNSHOT)"
+snd_idle "Path to custom idle sound"
+snd_misc "Path to custom sound (PAIN 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+style "Attack type"
+0 "Default (shotgun)"
+1 "Rockets"
+2 "Grenades"
+3 "lasers"
+4 "Nails"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+ //dumptruck_ds custom_mdls
+ precache_body_model ("progs/soldier.mdl");
+ precache_head_model ("progs/h_guard.mdl");
+ precache_proj_model ("progs/missile.mdl"); // used if style == 1
+ precache_proj_model ("progs/grenade.mdl"); // used if style == 2
+ precache_model2 ("progs/laser.mdl"); // used if style == 3
+ //dumptruck_ds custom_mdls
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound_death ("soldier/death1.wav");
+ precache_sound_idle ("soldier/idle.wav");
+ precache_sound_pain ("soldier/pain1.wav");
+ precache_sound_misc ("soldier/pain2.wav");
+ precache_sound_attack ("soldier/sattck1.wav");
+ precache_sound_sight ("soldier/sight1.wav");
+ precache_sound2 ("enforcer/enfire.wav"); // used if style == 3
+ precache_sound2 ("enforcer/enfstop.wav"); // used if style == 3
+
+ precache_sound ("player/udeath.wav"); // gib death
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ //dumptruck_ds custom_mdls
+ body_model ("progs/soldier.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 30;
+
+ self.th_stand = army_stand1;
+ self.th_walk = army_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = army_seeking_stand1;
+ }
+ else
+ {
+ self.th_run = army_run1;
+ }
+ self.th_missile = army_atk1;
+ self.th_turret = army_turret_atk1;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = army_pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = army_die;
+
+ walkmonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_army (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID FACE_UP X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/soldier.mdl","frame":28});
+}
+*/
+void() monster_dead_army =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/soldier.mdl");
+ setmodel(self, "progs/soldier.mdl");
+ if (self.spawnflags & 2)
+ {
+ self.frame = $death10;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.27 -30.47 -50.3','22.1 25.35 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+ else
+ {
+ self.frame = $deathc11;
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-39.85 -29.35 -49.07','20.52 33.17 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/wizard.qc

diff --git a/qc/monsters/wizard.qc b/qc/monsters/wizard.qc
index dfde2b0..6c28995 100644
--- a/qc/monsters/wizard.qc
+++ b/qc/monsters/wizard.qc
@@ -1,580 +1,580 @@
-/*
-==============================================================================
-
-WIZARD
-
-==============================================================================
-*/
-
-$cd id1/models/a_wizard
-$origin 0 0 24
-$base wizbase
-$skin wizbase
-
-$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
-$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
-
-$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
-$frame fly11 fly12 fly13 fly14
-
-$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
-$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
-
-$frame pain1 pain2 pain3 pain4
-
-$frame death1 death2 death3 death4 death5 death6 death7 death8
-
-/*
-==============================================================================
-
-WIZARD
-
-If the player moves behind cover before the missile is launched, launch it
-at the last visible spot with no velocity leading, in hopes that the player
-will duck back out and catch it.
-==============================================================================
-*/
-
-/*
-=============
-LaunchMissile
-
-Sets the given entities velocity and angles so that it will hit self.enemy
-if self.enemy maintains it's current velocity
-0.1 is moderately accurate, 0.0 is totally accurate
-=============
-*/
-void(entity missile, float mspeed, float accuracy) LaunchMissile =
-{
- local vector vec, move;
- local float fly;
-
- makevectors (self.angles);
-
-// set missile speed
- vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
-
-// calc aproximate time for missile to reach vec
- fly = vlen (vec) / mspeed;
-
-// get the entities xy velocity
- move = self.enemy.velocity;
- move_z = 0;
-
-// project the target forward in time
- vec = vec + move * fly;
-
- vec = normalize(vec);
- vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
-
- missile.velocity = vec * mspeed;
-
- missile.angles = '0 0 0';
- missile.angles_y = vectoyaw(missile.velocity);
-
- if (self.projexpl)
- {
- missile.touch = T_WizardMisTouch;
- }
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
-};
-
-
-void() wiz_run1;
-void() wiz_side1;
-
-/*
-=================
-WizardCheckAttack
-=================
-*/
-float() WizardCheckAttack =
-{
- local vector spot1, spot2;
- local entity targ;
- local float chance;
-
- if (time < self.attack_finished)
- return FALSE;
- if (!enemy_vis)
- return FALSE;
-
- if (enemy_range == RANGE_FAR)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- targ = self.enemy;
-
-// see if any entities are in the way of the shot
- spot1 = self.origin + self.view_ofs;
- spot2 = targ.origin + targ.view_ofs;
-
- traceline (spot1, spot2, FALSE, self);
-
- if (trace_ent != targ)
- { // don't have a clear shot, so move to a side
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- return FALSE;
- }
-
- if (enemy_range == RANGE_MELEE)
- chance = 0.9;
- else if (enemy_range == RANGE_NEAR)
- chance = 0.6;
- else if (enemy_range == RANGE_MID)
- chance = 0.2;
- else
- chance = 0;
-
- if (random () < chance)
- {
- self.attack_state = AS_MISSILE;
- return TRUE;
- }
-
- if (enemy_range == RANGE_MID)
- {
- if (self.attack_state != AS_STRAIGHT)
- {
- self.attack_state = AS_STRAIGHT;
- wiz_run1 ();
- }
- }
- else
- {
- if (self.attack_state != AS_SLIDING)
- {
- self.attack_state = AS_SLIDING;
- wiz_side1 ();
- }
- }
-
- return FALSE;
-};
-
-/*
-=================
-WizardAttackFinished
-=================
-*/
-void() WizardAttackFinished =
-{
- if (enemy_range >= RANGE_MID || !enemy_vis)
- {
- self.attack_state = AS_STRAIGHT;
- self.think = wiz_run1;
- }
- else
- {
- self.attack_state = AS_SLIDING;
- self.think = wiz_side1;
- }
-};
-
-/*
-==============================================================================
-
-FAST ATTACKS
-
-==============================================================================
-*/
-void() Wiz_AttackSound = // this is a hack to fix Wizard custom attack sounds
-{
- sound_attack (self, CHAN_AUTO, "wizard/wattack.wav", 1, ATTN_NORM);
-};
-
-void() Wiz_FastFire =
-{
- local vector vec;
- local vector dst;
- local entity oldself;
- local float projspeed = self.owner.proj_speed_mod * 600;
-
- if (self.owner.health > 0)
- {
- self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
-
- makevectors (self.enemy.angles);
- dst = self.enemy.origin - 13*self.movedir;
-
- vec = normalize(dst - self.origin);
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
- launch_spike (self.origin, vec);
- SetSpeed(newmis, vec, projspeed);
- newmis.owner = self.owner;
- newmis.classname = "wizspike";
- if (self.owner.projexpl)
- {
- // dprint("spawning exploding wizard proj from fastfire\n");
- newmis.touch = T_WizardMisTouch;
- }
- if (self.owner.homing)
- {
- oldself = self;
- self = self.owner;
- SetupHoming(newmis, projspeed);
- self = oldself;
- }
- setmodel(newmis, self.owner.mdl_proj);
- newmis.skin = self.owner.skin_proj;
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
-
- }
-
- remove (self);
-};
-
-
-void() Wiz_StartFast =
-{
- local entity missile;
-
- // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
- self.v_angle = self.angles;
- makevectors (self.angles);
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 0.6;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.8;
- missile.think = Wiz_FastFire;
- missile.movedir = v_right;
-
- missile = spawn ();
- missile.owner = self;
- missile.nextthink = time + 1;
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
- missile.enemy = self.enemy;
- missile.nextthink = time + 0.3;
- missile.think = Wiz_FastFire;
- missile.movedir = VEC_ORIGIN - v_right;
-};
-
-void() Wiz_idlesound =
-{
-local float wr;
- wr = random() * 5;
-
- if (self.fly_sound < time)
- {
- self.fly_sound = time + 2;
- if (wr > 4.5)
- sound_idle (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
- if (wr < 1.5)
- sound_misc (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
- }
- return;
-};
-
-void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
-void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
-void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
-void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
-void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
-void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
-void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
-void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
-
-void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
-Wiz_idlesound();};
-void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
-void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
-void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
-void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
-void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
-void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
-void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
-
-void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
-Wiz_idlesound();};
-void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
-void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
-void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
-void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
-void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
-void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
-void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
-
-void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
-Wiz_idlesound();
-};
-void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
-void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
-void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
-void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
-void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
-void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
-void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
-void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
-void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
-void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
-void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
-void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
-void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
-
-void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();Wiz_AttackSound();};
-void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
-void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
-void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
-void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
-void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
-void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();Wiz_AttackSound();};
-void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
-void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
-void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
-
-void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
-void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
-void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
-void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
-
-void() wiz_death1 =[ $death1, wiz_death2 ] {
-
-self.velocity_x = -200 + 400*random();
-self.velocity_y = -200 + 400*random();
-self.velocity_z = 100 + 100*random();
-self.flags = self.flags - (self.flags & FL_ONGROUND);
-sound_death (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
-};
-void() wiz_death2 =[ $death2, wiz_death3 ] {};
-void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
-void() wiz_death4 =[ $death4, wiz_death5 ] {};
-void() wiz_death5 =[ $death5, wiz_death6 ] {};
-void() wiz_death6 =[ $death6, wiz_death7 ] {};
-void() wiz_death7 =[ $death7, wiz_death8 ] {};
-void() wiz_death8 =[ $death8, wiz_death8 ] {};
-
-void() wiz_die =
-{
-// check for gib
- if (self.health < -40)
- {
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_wizard.mdl", self.health);
- }
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- // ThrowGib ("progs/gib2.mdl", self.health);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- DropStuff();
- return;
- }
- DropStuff();
- wiz_death1 ();
-};
-
-void(entity attacker, float damage) Wiz_Pain =
-{
- sound_pain (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
- if (random()*70 > damage)
- return; // didn't flinch
-
- wiz_pain1 ();
-};
-
-
-void() Wiz_Missile =
-{
- wiz_fast1();
-};
-
-/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ("progs/wizard.mdl");
-}
-Wizard a.k.a. Scrag.
-
-Default health = 80
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_attack(string) : "Path to custom attack sound"
-snd_idle(string) : "Path to custom idle sound"
-snd_misc(string) : "Path to custom sound (IDLE 2)"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-skin_head(float) : "Skin index of custom head model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-projexpl(choices) : "Exploding projectiles"
-0 : "No explosions"
-1 : "All projectiles explode"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-*/
-void() monster_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (self.spawnflags & I_AM_TURRET)
- objerror("Incompatible spawnflag: TURRET_MODE\n");
-
- if (deathmatch)
- {
- remove(self);
- return;
- }
-
- if (!self.mdl_proj)
- {
- self.mdl_proj = "progs/w_spike.mdl";
- }
-
- // dumptruck_ds custom_mdls
- precache_body_model ("progs/wizard.mdl");
- precache_head_model ("progs/h_wizard.mdl");
- precache_proj_model ("progs/w_spike.mdl");
- ////dumptruck_ds
- precache_sound_hit ("wizard/hit.wav"); // used by c code
- precache_sound_attack ("wizard/wattack.wav");
- precache_sound_death ("wizard/wdeath.wav");
- precache_sound_idle ("wizard/widle1.wav");
- precache_sound_misc ("wizard/widle2.wav");
- precache_sound_pain ("wizard/wpain.wav");
- precache_sound_sight ("wizard/wsight.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/wizard.mdl");
- // setmodel (self, "progs/wizard.mdl"); //dumptruck_ds
-
- setsize (self, '-16 -16 -24', '16 16 40');
-
- if (!self.proj_speed_mod)
- {
- self.proj_speed_mod = 1;
- }
-
- if (!self.health) //thanks RennyC -- dumptruck_ds
- self.health = 80;
-
- self.th_stand = wiz_stand1;
- self.th_walk = wiz_walk1;
- self.th_run = wiz_run1;
- self.th_missile = Wiz_Missile;
- if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
- self.th_pain = Wiz_Pain;
- else
- self.th_pain = SUB_NullPain;
- self.th_die = wiz_die;
-
- flymonster_start ();
-};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED monster_dead_wizard (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/wizard.mdl","frame":53});
-}
-*/
-void() monster_dead_wizard =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/wizard.mdl");
- setmodel(self, "progs/wizard.mdl");
- self.frame = $death8;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-50.75 -27.46 -55.19','31.81 33.61 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
+/*
+==============================================================================
+
+WIZARD
+
+==============================================================================
+*/
+
+$cd id1/models/a_wizard
+$origin 0 0 24
+$base wizbase
+$skin wizbase
+
+$frame hover1 hover2 hover3 hover4 hover5 hover6 hover7 hover8
+$frame hover9 hover10 hover11 hover12 hover13 hover14 hover15
+
+$frame fly1 fly2 fly3 fly4 fly5 fly6 fly7 fly8 fly9 fly10
+$frame fly11 fly12 fly13 fly14
+
+$frame magatt1 magatt2 magatt3 magatt4 magatt5 magatt6 magatt7
+$frame magatt8 magatt9 magatt10 magatt11 magatt12 magatt13
+
+$frame pain1 pain2 pain3 pain4
+
+$frame death1 death2 death3 death4 death5 death6 death7 death8
+
+/*
+==============================================================================
+
+WIZARD
+
+If the player moves behind cover before the missile is launched, launch it
+at the last visible spot with no velocity leading, in hopes that the player
+will duck back out and catch it.
+==============================================================================
+*/
+
+/*
+=============
+LaunchMissile
+
+Sets the given entities velocity and angles so that it will hit self.enemy
+if self.enemy maintains it's current velocity
+0.1 is moderately accurate, 0.0 is totally accurate
+=============
+*/
+void(entity missile, float mspeed, float accuracy) LaunchMissile =
+{
+ local vector vec, move;
+ local float fly;
+
+ makevectors (self.angles);
+
+// set missile speed
+ vec = self.enemy.origin + self.enemy.mins + self.enemy.size * 0.7 - missile.origin;
+
+// calc aproximate time for missile to reach vec
+ fly = vlen (vec) / mspeed;
+
+// get the entities xy velocity
+ move = self.enemy.velocity;
+ move_z = 0;
+
+// project the target forward in time
+ vec = vec + move * fly;
+
+ vec = normalize(vec);
+ vec = vec + accuracy*v_up*(random()- 0.5) + accuracy*v_right*(random()- 0.5);
+
+ missile.velocity = vec * mspeed;
+
+ missile.angles = '0 0 0';
+ missile.angles_y = vectoyaw(missile.velocity);
+
+ if (self.projexpl)
+ {
+ missile.touch = T_WizardMisTouch;
+ }
+
+// set missile duration
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+};
+
+
+void() wiz_run1;
+void() wiz_side1;
+
+/*
+=================
+WizardCheckAttack
+=================
+*/
+float() WizardCheckAttack =
+{
+ local vector spot1, spot2;
+ local entity targ;
+ local float chance;
+
+ if (time < self.attack_finished)
+ return FALSE;
+ if (!enemy_vis)
+ return FALSE;
+
+ if (enemy_range == RANGE_FAR)
+ {
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ return FALSE;
+ }
+
+ targ = self.enemy;
+
+// see if any entities are in the way of the shot
+ spot1 = self.origin + self.view_ofs;
+ spot2 = targ.origin + targ.view_ofs;
+
+ traceline (spot1, spot2, FALSE, self);
+
+ if (trace_ent != targ)
+ { // don't have a clear shot, so move to a side
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ return FALSE;
+ }
+
+ if (enemy_range == RANGE_MELEE)
+ chance = 0.9;
+ else if (enemy_range == RANGE_NEAR)
+ chance = 0.6;
+ else if (enemy_range == RANGE_MID)
+ chance = 0.2;
+ else
+ chance = 0;
+
+ if (random () < chance)
+ {
+ self.attack_state = AS_MISSILE;
+ return TRUE;
+ }
+
+ if (enemy_range == RANGE_MID)
+ {
+ if (self.attack_state != AS_STRAIGHT)
+ {
+ self.attack_state = AS_STRAIGHT;
+ wiz_run1 ();
+ }
+ }
+ else
+ {
+ if (self.attack_state != AS_SLIDING)
+ {
+ self.attack_state = AS_SLIDING;
+ wiz_side1 ();
+ }
+ }
+
+ return FALSE;
+};
+
+/*
+=================
+WizardAttackFinished
+=================
+*/
+void() WizardAttackFinished =
+{
+ if (enemy_range >= RANGE_MID || !enemy_vis)
+ {
+ self.attack_state = AS_STRAIGHT;
+ self.think = wiz_run1;
+ }
+ else
+ {
+ self.attack_state = AS_SLIDING;
+ self.think = wiz_side1;
+ }
+};
+
+/*
+==============================================================================
+
+FAST ATTACKS
+
+==============================================================================
+*/
+void() Wiz_AttackSound = // this is a hack to fix Wizard custom attack sounds
+{
+ sound_attack (self, CHAN_AUTO, "wizard/wattack.wav", 1, ATTN_NORM);
+};
+
+void() Wiz_FastFire =
+{
+ local vector vec;
+ local vector dst;
+ local entity oldself;
+ local float projspeed = self.owner.proj_speed_mod * 600;
+
+ if (self.owner.health > 0)
+ {
+ self.owner.effects = self.owner.effects | EF_MUZZLEFLASH;
+
+ makevectors (self.enemy.angles);
+ dst = self.enemy.origin - 13*self.movedir;
+
+ vec = normalize(dst - self.origin);
+ // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
+ launch_spike (self.origin, vec);
+ SetSpeed(newmis, vec, projspeed);
+ newmis.owner = self.owner;
+ newmis.classname = "wizspike";
+ if (self.owner.projexpl)
+ {
+ // dprint("spawning exploding wizard proj from fastfire\n");
+ newmis.touch = T_WizardMisTouch;
+ }
+ if (self.owner.homing)
+ {
+ oldself = self;
+ self = self.owner;
+ SetupHoming(newmis, projspeed);
+ self = oldself;
+ }
+ setmodel(newmis, self.owner.mdl_proj);
+ newmis.skin = self.owner.skin_proj;
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+
+ }
+
+ remove (self);
+};
+
+
+void() Wiz_StartFast =
+{
+ local entity missile;
+
+ // sound_attack (self, CHAN_WEAPON, "wizard/wattack.wav", 1, ATTN_NORM);
+ self.v_angle = self.angles;
+ makevectors (self.angles);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.nextthink = time + 0.6;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right*14);
+ missile.enemy = self.enemy;
+ missile.nextthink = time + 0.8;
+ missile.think = Wiz_FastFire;
+ missile.movedir = v_right;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.nextthink = time + 1;
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + '0 0 30' + v_forward*14 + v_right* -14);
+ missile.enemy = self.enemy;
+ missile.nextthink = time + 0.3;
+ missile.think = Wiz_FastFire;
+ missile.movedir = VEC_ORIGIN - v_right;
+};
+
+void() Wiz_idlesound =
+{
+local float wr;
+ wr = random() * 5;
+
+ if (self.fly_sound < time)
+ {
+ self.fly_sound = time + 2;
+ if (wr > 4.5)
+ sound_idle (self, CHAN_VOICE, "wizard/widle1.wav", 1, ATTN_IDLE);
+ if (wr < 1.5)
+ sound_misc (self, CHAN_VOICE, "wizard/widle2.wav", 1, ATTN_IDLE);
+ }
+ return;
+};
+
+void() wiz_stand1 =[ $hover1, wiz_stand2 ] {ai_stand();};
+void() wiz_stand2 =[ $hover2, wiz_stand3 ] {ai_stand();};
+void() wiz_stand3 =[ $hover3, wiz_stand4 ] {ai_stand();};
+void() wiz_stand4 =[ $hover4, wiz_stand5 ] {ai_stand();};
+void() wiz_stand5 =[ $hover5, wiz_stand6 ] {ai_stand();};
+void() wiz_stand6 =[ $hover6, wiz_stand7 ] {ai_stand();};
+void() wiz_stand7 =[ $hover7, wiz_stand8 ] {ai_stand();};
+void() wiz_stand8 =[ $hover8, wiz_stand1 ] {ai_stand();};
+
+void() wiz_walk1 =[ $hover1, wiz_walk2 ] {ai_walk(8);
+Wiz_idlesound();};
+void() wiz_walk2 =[ $hover2, wiz_walk3 ] {ai_walk(8);};
+void() wiz_walk3 =[ $hover3, wiz_walk4 ] {ai_walk(8);};
+void() wiz_walk4 =[ $hover4, wiz_walk5 ] {ai_walk(8);};
+void() wiz_walk5 =[ $hover5, wiz_walk6 ] {ai_walk(8);};
+void() wiz_walk6 =[ $hover6, wiz_walk7 ] {ai_walk(8);};
+void() wiz_walk7 =[ $hover7, wiz_walk8 ] {ai_walk(8);};
+void() wiz_walk8 =[ $hover8, wiz_walk1 ] {ai_walk(8);};
+
+void() wiz_side1 =[ $hover1, wiz_side2 ] {ai_run(8);
+Wiz_idlesound();};
+void() wiz_side2 =[ $hover2, wiz_side3 ] {ai_run(8);};
+void() wiz_side3 =[ $hover3, wiz_side4 ] {ai_run(8);};
+void() wiz_side4 =[ $hover4, wiz_side5 ] {ai_run(8);};
+void() wiz_side5 =[ $hover5, wiz_side6 ] {ai_run(8);};
+void() wiz_side6 =[ $hover6, wiz_side7 ] {ai_run(8);};
+void() wiz_side7 =[ $hover7, wiz_side8 ] {ai_run(8);};
+void() wiz_side8 =[ $hover8, wiz_side1 ] {ai_run(8);};
+
+void() wiz_run1 =[ $fly1, wiz_run2 ] {ai_run(16);
+Wiz_idlesound();
+};
+void() wiz_run2 =[ $fly2, wiz_run3 ] {ai_run(16);};
+void() wiz_run3 =[ $fly3, wiz_run4 ] {ai_run(16);};
+void() wiz_run4 =[ $fly4, wiz_run5 ] {ai_run(16);};
+void() wiz_run5 =[ $fly5, wiz_run6 ] {ai_run(16);};
+void() wiz_run6 =[ $fly6, wiz_run7 ] {ai_run(16);};
+void() wiz_run7 =[ $fly7, wiz_run8 ] {ai_run(16);};
+void() wiz_run8 =[ $fly8, wiz_run9 ] {ai_run(16);};
+void() wiz_run9 =[ $fly9, wiz_run10 ] {ai_run(16);};
+void() wiz_run10 =[ $fly10, wiz_run11 ] {ai_run(16);};
+void() wiz_run11 =[ $fly11, wiz_run12 ] {ai_run(16);};
+void() wiz_run12 =[ $fly12, wiz_run13 ] {ai_run(16);};
+void() wiz_run13 =[ $fly13, wiz_run14 ] {ai_run(16);};
+void() wiz_run14 =[ $fly14, wiz_run1 ] {ai_run(16);};
+
+void() wiz_fast1 =[ $magatt1, wiz_fast2 ] {ai_face();Wiz_StartFast();Wiz_AttackSound();};
+void() wiz_fast2 =[ $magatt2, wiz_fast3 ] {ai_face();};
+void() wiz_fast3 =[ $magatt3, wiz_fast4 ] {ai_face();};
+void() wiz_fast4 =[ $magatt4, wiz_fast5 ] {ai_face();};
+void() wiz_fast5 =[ $magatt5, wiz_fast6 ] {ai_face();};
+void() wiz_fast6 =[ $magatt6, wiz_fast7 ] {ai_face();};
+void() wiz_fast7 =[ $magatt5, wiz_fast8 ] {ai_face();Wiz_AttackSound();};
+void() wiz_fast8 =[ $magatt4, wiz_fast9 ] {ai_face();};
+void() wiz_fast9 =[ $magatt3, wiz_fast10 ] {ai_face();};
+void() wiz_fast10 =[ $magatt2, wiz_run1 ] {ai_face();SUB_AttackFinished(2);WizardAttackFinished ();};
+
+void() wiz_pain1 =[ $pain1, wiz_pain2 ] {};
+void() wiz_pain2 =[ $pain2, wiz_pain3 ] {};
+void() wiz_pain3 =[ $pain3, wiz_pain4 ] {};
+void() wiz_pain4 =[ $pain4, wiz_run1 ] {};
+
+void() wiz_death1 =[ $death1, wiz_death2 ] {
+
+self.velocity_x = -200 + 400*random();
+self.velocity_y = -200 + 400*random();
+self.velocity_z = 100 + 100*random();
+self.flags = self.flags - (self.flags & FL_ONGROUND);
+sound_death (self, CHAN_VOICE, "wizard/wdeath.wav", 1, ATTN_NORM);
+};
+void() wiz_death2 =[ $death2, wiz_death3 ] {};
+void() wiz_death3 =[ $death3, wiz_death4 ]{self.solid = SOLID_NOT;};
+void() wiz_death4 =[ $death4, wiz_death5 ] {};
+void() wiz_death5 =[ $death5, wiz_death6 ] {};
+void() wiz_death6 =[ $death6, wiz_death7 ] {};
+void() wiz_death7 =[ $death7, wiz_death8 ] {};
+void() wiz_death8 =[ $death8, wiz_death8 ] {};
+
+void() wiz_die =
+{
+// check for gib
+ if (self.health < -40)
+ {
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_wizard.mdl", self.health);
+ }
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ // ThrowGib ("progs/gib2.mdl", self.health);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ DropStuff();
+ return;
+ }
+ DropStuff();
+ wiz_death1 ();
+};
+
+void(entity attacker, float damage) Wiz_Pain =
+{
+ sound_pain (self, CHAN_VOICE, "wizard/wpain.wav", 1, ATTN_NORM);
+ if (random()*70 > damage)
+ return; // didn't flinch
+
+ wiz_pain1 ();
+};
+
+
+void() Wiz_Missile =
+{
+ wiz_fast1();
+};
+
+/*QUAKED monster_wizard (1 0 0) (-16 -16 -24) (16 16 40) AMBUSH X X TRIGGER_SPAWNED X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ("progs/wizard.mdl");
+}
+Wizard a.k.a. Scrag.
+
+Default health = 80
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_attack(string) : "Path to custom attack sound"
+snd_idle(string) : "Path to custom idle sound"
+snd_misc(string) : "Path to custom sound (IDLE 2)"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+skin_head(float) : "Skin index of custom head model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+projexpl(choices) : "Exploding projectiles"
+0 : "No explosions"
+1 : "All projectiles explode"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+*/
+void() monster_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (self.spawnflags & I_AM_TURRET)
+ objerror("Incompatible spawnflag: TURRET_MODE\n");
+
+ if (deathmatch)
+ {
+ remove(self);
+ return;
+ }
+
+ if (!self.mdl_proj)
+ {
+ self.mdl_proj = "progs/w_spike.mdl";
+ }
+
+ // dumptruck_ds custom_mdls
+ precache_body_model ("progs/wizard.mdl");
+ precache_head_model ("progs/h_wizard.mdl");
+ precache_proj_model ("progs/w_spike.mdl");
+ ////dumptruck_ds
+ precache_sound_hit ("wizard/hit.wav"); // used by c code
+ precache_sound_attack ("wizard/wattack.wav");
+ precache_sound_death ("wizard/wdeath.wav");
+ precache_sound_idle ("wizard/widle1.wav");
+ precache_sound_misc ("wizard/widle2.wav");
+ precache_sound_pain ("wizard/wpain.wav");
+ precache_sound_sight ("wizard/wsight.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/wizard.mdl");
+ // setmodel (self, "progs/wizard.mdl"); //dumptruck_ds
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+
+ if (!self.proj_speed_mod)
+ {
+ self.proj_speed_mod = 1;
+ }
+
+ if (!self.health) //thanks RennyC -- dumptruck_ds
+ self.health = 80;
+
+ self.th_stand = wiz_stand1;
+ self.th_walk = wiz_walk1;
+ self.th_run = wiz_run1;
+ self.th_missile = Wiz_Missile;
+ if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
+ self.th_pain = Wiz_Pain;
+ else
+ self.th_pain = SUB_NullPain;
+ self.th_die = wiz_die;
+
+ flymonster_start ();
+};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED monster_dead_wizard (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/wizard.mdl","frame":53});
+}
+*/
+void() monster_dead_wizard =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/wizard.mdl");
+ setmodel(self, "progs/wizard.mdl");
+ self.frame = $death8;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-50.75 -27.46 -55.19','31.81 33.61 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/monsters/zombie.qc

diff --git a/qc/monsters/zombie.qc b/qc/monsters/zombie.qc
index 3230c93..52df0bc 100644
--- a/qc/monsters/zombie.qc
+++ b/qc/monsters/zombie.qc
@@ -1,865 +1,865 @@
-/*
-==============================================================================
-
-ZOMBIES!.qc - Version 1.1
-by Ace_Dave
-http://www.trenton.edu/~weiden/quake
-Weiden@Trenton.EDU
-
-==============================================================================
-*/
-$cd /raid/quake/id1/models/zombie
-
-$origin 0 0 24
-
-$base base
-$skin skin
-
-$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
-$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
-
-$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
-$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
-
-$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
-$frame run13 run14 run15 run16 run17 run18
-
-$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
-$frame atta12 atta13
-
-$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
-$frame attb12 attb13 attb14
-
-$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
-$frame attc12
-
-$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
-$frame paina11 paina12
-
-$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
-$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
-$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
-
-$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
-$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
-
-$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
-$frame paind11 paind12 paind13
-
-$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
-$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
-$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
-$frame paine29 paine30
-
-$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6
-
-float SPAWN_CRUCIFIED = 1;
-float SPAWN_DEAD_CRUCIFIED = 4;
-float SPAWN_SLEEPING = 16; //changed from 2 which was Zer default
-// float SPAWN_DEAD = 4; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-// float SPAWN_DEAD_CRUCIFIED = 8; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
-
-//=============================================================================
-.float inpain;
-
-// motionless crucified zombie
-void() zombie_dead_cruc1 = [$cruc_1, zombie_dead_cruc1] {self.nextthink = time + 1;};
-
-// new "stand" - for sleeping zombies
-void() zombie_stand1 =[ $paine11, zombie_stand2 ]
-{
- self.solid = SOLID_NOT;
- if (self.count == 0) //dumptruck_ds -- count value > 0 to leave the zombie sleeping until triggered!
- ai_stand();
-};
-void() zombie_stand2 =[ $paine11, zombie_stand1 ]
-{
- if (self.count == 0)
- ai_stand();
-};
-
-// old "stand" - called when standing only
-void() alt_zombie_stand1 =[ $stand1, alt_zombie_stand2 ] {self.health = 60; ai_stand();};
-void() alt_zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
-void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
-void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
-void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
-void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
-void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
-void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
-void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
-void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
-void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
-void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
-void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
-void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
-void() zombie_stand15 =[ $stand15, alt_zombie_stand1 ] {ai_stand();};
-
-void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] {
-if (random() < 0.1)
- sound_idle (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);};
-void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;};
-void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;};
-
-void() zombie_walk1 =[ $walk1, zombie_walk2 ] {
- self.solid = SOLID_SLIDEBOX;
- self.health = 60; //so he doesn't fall
- ai_walk(0);};
-void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
-void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
-void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
-void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
-void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
-void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
-void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
-void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
-void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
-void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
-void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
-void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
-void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
-void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
-void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
-void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
-void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
-void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
-ai_walk(0);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
-
-void() zombie_run1 =[ $run1, zombie_run2 ] {
- if (self.spawnflags & SPAWN_SLEEPING)
- { // sloppy hack, but it fixes the illusionary zombie bug
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
- setsize (self, '-16 -16 -24', '16 16 40');
- }
- ai_run(1);
- self.inpain = 0;};
-void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
-void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
-void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
-void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
-void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
-void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
-void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
-void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
-void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
-void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
-void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
-void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
-void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
-void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
-void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
-void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
-void() zombie_run18 =[ $run18, zombie_run1 ] {
-ai_run(8);
-if (random() < 0.2)
- sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-if (random() > 0.8)
- sound_sight (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
-};
-
-/*
-=============================================================================
-
-ATTACKS
-
-=============================================================================
-*/
-// void() Z_hit =
-// {
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// };
-//
-// void() Z_land =
-// {
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// };
-
-// void() ZombieGrenadeTouch2 =
-// {
-// if (other == self.owner)
-// return; // don't explode on owner
-// if (other.takedamage)
-// {
-// // Z_hit();
-// T_Damage (other, self, self.owner, 10 );
-// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
-// remove (self);
-// return;
-// }
-// // Z_land();
-// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
-// self.velocity = '0 0 0';
-// self.avelocity = '0 0 0';
-// self.touch = SUB_Remove;
-// };
-
-/*
-================
-ZombieFireGrenade
-================
-*/
-void(vector st) ZombieFireGrenade =
-{
- local entity missile;
- local vector org;
-
- sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
-
-// calc org
- org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
-
-// set missile speed
-
- makevectors (self.angles);
-
- missile.velocity = normalize(self.enemy.origin - org);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
-
- missile.avelocity = '3000 1000 2000';
-
- missile.touch = ZombieGrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
- // setmodel (missile, "progs/zom_gib.mdl");
- if (self.mdl_proj != "") // dumptruck_ds custom_mdls
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/zom_gib.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, org);
-};
-
-
-void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
-void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
-void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
-void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
-void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
-void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
-void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
-void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
-void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
-void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
-void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
-void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
-void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
-
-void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
-void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
-void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
-void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
-void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
-void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
-void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
-void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
-void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
-void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
-void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
-void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
-void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
-void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
-
-void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
-void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
-void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
-void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
-void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
-void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
-void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
-void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
-void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
-void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
-void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
-void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
-
-void() zombie_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_atta1 ();
- else if (r < 0.6)
- zombie_attb1 ();
- else
- zombie_attc1 ();
-};
-//////////////////////////
-/// turret frames START
-/////////////////////////
-void() zombie_turret_atta1 =[ $atta1, zombie_turret_atta2 ] {self.health = 60;ai_face();};
-void() zombie_turret_atta2 =[ $atta2, zombie_turret_atta3 ] {ai_face();};
-void() zombie_turret_atta3 =[ $atta3, zombie_turret_atta4 ] {ai_face();};
-void() zombie_turret_atta4 =[ $atta4, zombie_turret_atta5 ] {ai_face();};
-void() zombie_turret_atta5 =[ $atta5, zombie_turret_atta6 ] {ai_face();};
-void() zombie_turret_atta6 =[ $atta6, zombie_turret_atta7 ] {ai_face();};
-void() zombie_turret_atta7 =[ $atta7, zombie_turret_atta8 ] {ai_face();};
-void() zombie_turret_atta8 =[ $atta8, zombie_turret_atta9 ] {ai_face();};
-void() zombie_turret_atta9 =[ $atta9, zombie_turret_atta10 ] {ai_face();};
-void() zombie_turret_atta10 =[ $atta10, zombie_turret_atta11 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_atta11 =[ $atta11, zombie_turret_atta12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta12 =[ $atta12, zombie_turret_atta13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_atta13 =[ $atta13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attb1 =[ $attb1, zombie_turret_attb2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attb2 =[ $attb2, zombie_turret_attb3 ] {ai_face();};
-void() zombie_turret_attb3 =[ $attb3, zombie_turret_attb4 ] {ai_face();};
-void() zombie_turret_attb4 =[ $attb4, zombie_turret_attb5 ] {ai_face();};
-void() zombie_turret_attb5 =[ $attb5, zombie_turret_attb6 ] {ai_face();};
-void() zombie_turret_attb6 =[ $attb6, zombie_turret_attb7 ] {ai_face();};
-void() zombie_turret_attb7 =[ $attb7, zombie_turret_attb8 ] {ai_face();};
-void() zombie_turret_attb8 =[ $attb8, zombie_turret_attb9 ] {ai_face();};
-void() zombie_turret_attb9 =[ $attb9, zombie_turret_attb10 ] {ai_face();};
-void() zombie_turret_attb10 =[ $attb10, zombie_turret_attb11 ] {ai_face();};
-void() zombie_turret_attb11 =[ $attb11, zombie_turret_attb12 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attb12 =[ $attb12, zombie_turret_attb13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb13 =[ $attb13, zombie_turret_attb14 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attb14 =[ $attb13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-
-void() zombie_turret_attc1 =[ $attc1, zombie_turret_attc2 ] {self.health = 60;ai_face();};
-void() zombie_turret_attc2 =[ $attc2, zombie_turret_attc3 ] {ai_face();};
-void() zombie_turret_attc3 =[ $attc3, zombie_turret_attc4 ] {ai_face();};
-void() zombie_turret_attc4 =[ $attc4, zombie_turret_attc5 ] {ai_face();};
-void() zombie_turret_attc5 =[ $attc5, zombie_turret_attc6 ] {ai_face();};
-void() zombie_turret_attc6 =[ $attc6, zombie_turret_attc7 ] {ai_face();};
-void() zombie_turret_attc7 =[ $attc7, zombie_turret_attc8 ] {ai_face();};
-void() zombie_turret_attc8 =[ $attc8, zombie_turret_attc9 ] {ai_face();};
-void() zombie_turret_attc9 =[ $attc9, zombie_turret_attc10 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
-void() zombie_turret_attc10 =[ $attc10, zombie_turret_attc11 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc11 =[ $attc11, zombie_turret_attc12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
-void() zombie_turret_attc12 =[ $attc12, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
-void() alt_zombie_seek_stand1 =[ $stand1, alt_zombie_seek_stand2 ] {self.health = 60; ai_run(0);};
-void() alt_zombie_seek_stand2 =[ $stand2, zombie_seek_stand3 ] {ai_run(0);};
-void() zombie_seek_stand3 =[ $stand3, zombie_seek_stand4 ] {ai_run(0);};
-void() zombie_seek_stand4 =[ $stand4, zombie_seek_stand5 ] {ai_run(0);};
-void() zombie_seek_stand5 =[ $stand5, zombie_seek_stand6 ] {ai_run(0);};
-void() zombie_seek_stand6 =[ $stand6, zombie_seek_stand7 ] {ai_run(0);};
-void() zombie_seek_stand7 =[ $stand7, zombie_seek_stand8 ] {ai_run(0);};
-void() zombie_seek_stand8 =[ $stand8, zombie_seek_stand9 ] {ai_run(0);};
-void() zombie_seek_stand9 =[ $stand9, zombie_seek_stand10 ] {ai_run(0);};
-void() zombie_seek_stand10 =[ $stand10, zombie_seek_stand11 ] {ai_run(0);};
-void() zombie_seek_stand11 =[ $stand11, zombie_seek_stand12 ] {ai_run(0);};
-void() zombie_seek_stand12 =[ $stand12, zombie_seek_stand13 ] {ai_run(0);};
-void() zombie_seek_stand13 =[ $stand13, zombie_seek_stand14 ] {ai_run(0);};
-void() zombie_seek_stand14 =[ $stand14, zombie_seek_stand15 ] {ai_run(0);};
-void() zombie_seek_stand15 =[ $stand15, alt_zombie_seek_stand1 ] {ai_run(0);};
-
-void() zombie_turret_missile =
-{
- local float r;
-
- r = random();
-
- if (r < 0.3)
- zombie_turret_attb1 ();
- else if (r < 0.6)
- zombie_turret_atta1 ();
- else
- zombie_turret_attc1 ();
-};
-//////////////////////////
-/// turret frames END
-/////////////////////////
-
-/*
-=============================================================================
-
-PAIN
-
-=============================================================================
-*/
-
-void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
-void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
-void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
-void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
-void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
-void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
-void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
-void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
-void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
-void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
-void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
-
-void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
-void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
-void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
-void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
-void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
-void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
-void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
-void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
-void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
-void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
-void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
-void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
-void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
-void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
-void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
-void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
-void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
-void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
-void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
-void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
-void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
-void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
-void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
-void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
-void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
-void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
-void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
-
-void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
-void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
-void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
-void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
-void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
-void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
-void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
-void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
-void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
-void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
-void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
-void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
-void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
-void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
-void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
-void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
-void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
-void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
-
-void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
-void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
-void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
-void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
-void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
-void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
-void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
-void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
-void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
-void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
-void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
-void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
-void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
-
-void() zombie_paine1 =[ $paine1, zombie_paine2 ] {
-if (self.axhitme == 2) // Chainsaw will gib zombie
-{
- T_Damage(self, world, world, 80);
- return;
-}
-sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
-self.health = 60;
-};
-void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
-void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
-void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
-void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
-void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
-void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
-void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
-void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
-void() zombie_paine10 =[ $paine10, zombie_paine11 ] {
-sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
-self.solid = SOLID_NOT;
-};
-void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;};
-void() zombie_paine12 =[ $paine12, zombie_paine13 ]{
-// see if ok to stand up
-self.health = 60;
-sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
-self.solid = SOLID_SLIDEBOX;
-if (!walkmove (0, 0))
-{
- self.think = zombie_paine11;
- self.solid = SOLID_NOT;
- return;
-}
-};
-void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
-void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
-void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
-void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
-void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
-void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
-void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
-void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
-void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
-void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
-void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
-void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
-void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
-void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
-void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
-void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
-void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
-void() zombie_paine30 =[ $paine30, zombie_run1 ] {};
-
-void() zombie_die =
-{
- sound_death (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
- if (self.mdl_head != "") //dumptruck_ds custom_mdls
- {
- ThrowHead (self.mdl_head, self.health);
- }
- else
- {
- ThrowHead ("progs/h_zombie.mdl", self.health/*, self.dest*/); //commented out dest -- dumptruck_ds
- }
- // ThrowGib ("progs/gib1.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib2.mdl", self.health/*, self.dest*/);
- // ThrowGib ("progs/gib3.mdl", self.health/*, self.dest*/);
- if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
- {
- ThrowGib (self.mdl_gib1, self.health);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", self.health);
- }
- if (self.mdl_gib2 != "")
- {
- ThrowGib (self.mdl_gib2, self.health);
- }
- else
- {
- ThrowGib ("progs/gib2.mdl", self.health);
- }
- if (self.mdl_gib3 != "")
- {
- ThrowGib (self.mdl_gib3, self.health);
- }
- else
- {
- ThrowGib ("progs/gib3.mdl", self.health);
- }
- DropStuff();
-};
-
-/*
-=================
-zombie_pain
-
-Zombies can only be killed (gibbed) by doing 60 hit points of damage
-in a single frame (rockets, grenades, quad shotgun, quad nailgun).
-
-A hit of 25 points or more (super shotgun, quad nailgun) will always put it
-down to the ground.
-
-A hit of from 10 to 40 points in one frame will cause it to go down if it
-has been twice in two seconds, otherwise it goes into one of the four
-fast pain frames.
-
-A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
-
-FIXME: don't use pain_finished because of nightmare hack
-=================
-*/
-void(entity attacker, float take) zombie_pain =
-{
- if (self.spawnflags & I_AM_TURRET)
- {
- self.health = 60; // always reset health
-
- if (take >= 60)
- {
- zombie_die();
- }
- else
- return;
- }
-
- local float r;
-
- self.health = 60; // always reset health
-
- if (take < 9)
- return; // totally ignore
-
- if (self.inpain == 2)
- return; // down on ground, so don't reset any counters
-
-// go down immediately if a big enough hit
- if ((take >= 25) || (self.axhitme == 2))
- {
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
- if (self.inpain)
- {
-// if hit again in next gre seconds while not in pain frames, definately drop
- self.pain_finished = time + 3;
- return; // currently going through an animation, don't change
- }
-
- if (self.pain_finished > time)
- {
-// hit again, so drop down
- self.inpain = 2;
- zombie_paine1 ();
- return;
- }
-
-// gp into one of the fast pain animations
- self.inpain = 1;
-
- r = random();
- if (r < 0.25)
- zombie_paina1 ();
- else if (r < 0.5)
- zombie_painb1 ();
- else if (r < 0.75)
- zombie_painc1 ();
- else
- zombie_paind1 ();
-};
-
-void() zombie_decide = // stand up if orig. lying down, else just start running
-{
- if (self.health==61)
- zombie_paine12();
- else
- zombie_run1();
-
- self.th_run = zombie_run1;
-};
-
-void() zombie_use = // wake up a sleeping zombie!
-
-{
- self.count = 0;
- //attacker = other;
- monster_use();
-};
-
-void() zombie_start = // determine if zombie is to be lying down, or standing
-{
- self.count = 1; //dumptruck_ds -- Don't start zombie_stand1 yet!
- self.use = zombie_use; //dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
-
- if (self.spawnflags & SPAWN_SLEEPING)
- {
- if (!SUB_IsTargeted ())
- {
- dprint ("WARNING: removed untargeted sleeping zombie at ");
- dprint (vtos (self.origin));
- dprint ("\n");
-
- monster_update_total (-1);
- remove (self);
- return;
- }
- self.inpain = 2;
- zombie_stand1 ();
- }
- else
- {
- alt_zombie_stand1 ();
- }
-
- self.th_stand = alt_zombie_stand1;
-};
-
-// void() zombie_start2 = //unused in progs_dump -- dumptruck_ds
-// {
-// local vector org;
-// local entity teldeath;
-//
-// if (self.style)
-// {
-// makevectors (self.angles);
-// org = self.origin + 16 * v_forward;
-// spawn_tfog (org);
-// teldeath = spawn();
-// teldeath.origin = org;
-// teldeath.owner = self;
-// // teldeath.think = sf64_teledeath; -- not used in progs_dump -- dumptruck_ds
-// teldeath.nextthink = time + 0.1;
-// }
-//
-// self.solid = SOLID_SLIDEBOX;
-// self.movetype = MOVETYPE_STEP;
-//
-// setmodel (self, "progs/zombie.mdl");
-//
-// setsize (self, '-16 -16 -24', '16 16 40');
-// self.health = 61;
-//
-// walkmonster_start();
-// };
-
-//============================================================================
-
-/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ( {{ spawnflags & 1 -> { "path" : "progs/zombie.mdl", "frame" : 192 }, "progs/zombie.mdl" }} );
-}
-If crucified, stick the bounding box 12 pixels back into a wall to look right.
-
-Default health = 60
-
-If SPAWN_SLEEPING is used there must be a targetname set. The zombie will stand up when targeted. Crucified motionless zombies are silent and do not animate." //dumptruck_ds
-
-snd_death(string) : "Path to custom death sound"
-snd_pain(string) : "Path to custom pain sound"
-snd_attack(string) : "Path to custom attack sound (WHOOSH)"
-snd_idle(string) : "Path to custom idle sound (CRUCIFIED ONLY)"
-snd_misc(string) : "Path to custom (IDLE 2) sound"
-snd_sight(string) : "Path to custom sight sound"
-snd_misc2(string) : "Path to custom (PAIN 2) sound"
-snd_misc3(string) : "Path to custom (FALLING) sound"
-
-mdl_head(string) : "Path to custom head model"
-mdl_body(string) : "Path to custom body model"
-mdl_proj(string) : "Path to custom projectile model"
-skin_head(float) : "Skin index of custom head model"
-skin_proj(float) : "Skin index of custom projectile model"
-mdl_gib1(string) : "Path to custom 1st gib model"
-mdl_gib2(string) : "Path to custom 2nd gib model"
-mdl_gib3(string) : "Path to custom 3rd gib model"
-
-effects(choices) : "Add a visual effect to an entity"
-0 : "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
-0 : "Off (Default)"
-1 : "Berserk (skip pain animations)"
-
-delay(float) : "Delay spawn in for this amount of time"
-
-wait(choices) : "Play an effect when trigger spawned?"
-0 : "Teleport Effects (Default)"
-1 : "Spawn Silently"
-
-spawn_angry(Choices)
-0 : "Only when trigger spawned, default behavior - not angry"
-1 : "Only when trigger spawned, set to 1 to spawn angry at player"
-
-infight_mode(Choices)
-0 : "Default behavior, only with different classnames"
-1 : "Infight with monsters with the same classname but a different mdl_body"
-2 : "Infight with monsters with the same classname and model but a different skin"
-3 : "Infight no matter what"
-
-health(integer) : "Set this to a custom health amount"
-pain_target(string) : "Fire this target when pain_threshold is reached"
-pain_threshold(integer) : "Fire pain_target when health drops below this amount"
-sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
-skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
-obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
-obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
-damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
-
-spawnflags(Flags) =
-1 : "Crucified"
-2 : "Ambush"
-4 : "Crucified motionless"
-16 : "Spawn Sleeping"
-*/
-void() monster_zombie =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (deathmatch /*&& (!(self.spawnflags & SPAWN_DEAD_CRUCIFIED))*/)
- {
- remove(self);
- return;
- }
-
- precache_body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- precache_head_model ("progs/h_zombie.mdl");
- precache_proj_model ("progs/zom_gib.mdl");
- // precache_model ("progs/zombie.mdl");
- // precache_model ("progs/h_zombie.mdl");
- // precache_model ("progs/zom_gib.mdl");
-
- precache_sound_misc ("zombie/z_idle.wav");
- precache_sound_sight ("zombie/z_idle1.wav");
- precache_sound_attack ("zombie/z_shot1.wav");
- precache_sound_death ("zombie/z_gib.wav");
- precache_sound_pain ("zombie/z_pain.wav");
- precache_sound_misc2 ("zombie/z_pain1.wav");
- precache_sound_misc3 ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
-
- precache_sound_idle ("zombie/idle_w2.wav");
-
- precache_gib1 ("progs/gib1.mdl");
- precache_gib2 ("progs/gib2.mdl");
- precache_gib3 ("progs/gib3.mdl");
-
- self.th_stand = zombie_start;
- self.th_walk = zombie_walk1;
- if (self.spawnflags & I_AM_TURRET)
- {
- self.th_run = alt_zombie_seek_stand1;
- }
- else
- {
- self.th_run = zombie_decide;
- }
-
- self.th_pain = zombie_pain;
- self.th_die = zombie_die;
- self.th_turret = zombie_turret_missile;
- self.th_missile = zombie_missile;
- self.solid = SOLID_SLIDEBOX;
- self.movetype = MOVETYPE_STEP;
-
- body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
- // setmodel (self, "progs/zombie.mdl");
-
- setsize (self, '-16 -16 -24', '16 16 40');
- self.health = 61;
-
- if (self.spawnflags & SPAWN_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_cruc1 ();
- }
- else if (self.spawnflags & SPAWN_DEAD_CRUCIFIED)
- {
- self.movetype = MOVETYPE_NONE;
- zombie_dead_cruc1 ();
- }
- else
- walkmonster_start();
-};
+/*
+==============================================================================
+
+ZOMBIES!.qc - Version 1.1
+by Ace_Dave
+http://www.trenton.edu/~weiden/quake
+Weiden@Trenton.EDU
+
+==============================================================================
+*/
+$cd /raid/quake/id1/models/zombie
+
+$origin 0 0 24
+
+$base base
+$skin skin
+
+$frame stand1 stand2 stand3 stand4 stand5 stand6 stand7 stand8
+$frame stand9 stand10 stand11 stand12 stand13 stand14 stand15
+
+$frame walk1 walk2 walk3 walk4 walk5 walk6 walk7 walk8 walk9 walk10 walk11
+$frame walk12 walk13 walk14 walk15 walk16 walk17 walk18 walk19
+
+$frame run1 run2 run3 run4 run5 run6 run7 run8 run9 run10 run11 run12
+$frame run13 run14 run15 run16 run17 run18
+
+$frame atta1 atta2 atta3 atta4 atta5 atta6 atta7 atta8 atta9 atta10 atta11
+$frame atta12 atta13
+
+$frame attb1 attb2 attb3 attb4 attb5 attb6 attb7 attb8 attb9 attb10 attb11
+$frame attb12 attb13 attb14
+
+$frame attc1 attc2 attc3 attc4 attc5 attc6 attc7 attc8 attc9 attc10 attc11
+$frame attc12
+
+$frame paina1 paina2 paina3 paina4 paina5 paina6 paina7 paina8 paina9 paina10
+$frame paina11 paina12
+
+$frame painb1 painb2 painb3 painb4 painb5 painb6 painb7 painb8 painb9 painb10
+$frame painb11 painb12 painb13 painb14 painb15 painb16 painb17 painb18 painb19
+$frame painb20 painb21 painb22 painb23 painb24 painb25 painb26 painb27 painb28
+
+$frame painc1 painc2 painc3 painc4 painc5 painc6 painc7 painc8 painc9 painc10
+$frame painc11 painc12 painc13 painc14 painc15 painc16 painc17 painc18
+
+$frame paind1 paind2 paind3 paind4 paind5 paind6 paind7 paind8 paind9 paind10
+$frame paind11 paind12 paind13
+
+$frame paine1 paine2 paine3 paine4 paine5 paine6 paine7 paine8 paine9 paine10
+$frame paine11 paine12 paine13 paine14 paine15 paine16 paine17 paine18 paine19
+$frame paine20 paine21 paine22 paine23 paine24 paine25 paine26 paine27 paine28
+$frame paine29 paine30
+
+$frame cruc_1 cruc_2 cruc_3 cruc_4 cruc_5 cruc_6
+
+float SPAWN_CRUCIFIED = 1;
+float SPAWN_DEAD_CRUCIFIED = 4;
+float SPAWN_SLEEPING = 16; //changed from 2 which was Zer default
+// float SPAWN_DEAD = 4; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
+// float SPAWN_DEAD_CRUCIFIED = 8; -- not used in progs_dump -- dumptruck_ds -- this is from Zer src for my reference
+
+//=============================================================================
+.float inpain;
+
+// motionless crucified zombie
+void() zombie_dead_cruc1 = [$cruc_1, zombie_dead_cruc1] {self.nextthink = time + 1;};
+
+// new "stand" - for sleeping zombies
+void() zombie_stand1 =[ $paine11, zombie_stand2 ]
+{
+ self.solid = SOLID_NOT;
+ if (self.count == 0) //dumptruck_ds -- count value > 0 to leave the zombie sleeping until triggered!
+ ai_stand();
+};
+void() zombie_stand2 =[ $paine11, zombie_stand1 ]
+{
+ if (self.count == 0)
+ ai_stand();
+};
+
+// old "stand" - called when standing only
+void() alt_zombie_stand1 =[ $stand1, alt_zombie_stand2 ] {self.health = 60; ai_stand();};
+void() alt_zombie_stand2 =[ $stand2, zombie_stand3 ] {ai_stand();};
+void() zombie_stand3 =[ $stand3, zombie_stand4 ] {ai_stand();};
+void() zombie_stand4 =[ $stand4, zombie_stand5 ] {ai_stand();};
+void() zombie_stand5 =[ $stand5, zombie_stand6 ] {ai_stand();};
+void() zombie_stand6 =[ $stand6, zombie_stand7 ] {ai_stand();};
+void() zombie_stand7 =[ $stand7, zombie_stand8 ] {ai_stand();};
+void() zombie_stand8 =[ $stand8, zombie_stand9 ] {ai_stand();};
+void() zombie_stand9 =[ $stand9, zombie_stand10 ] {ai_stand();};
+void() zombie_stand10 =[ $stand10, zombie_stand11 ] {ai_stand();};
+void() zombie_stand11 =[ $stand11, zombie_stand12 ] {ai_stand();};
+void() zombie_stand12 =[ $stand12, zombie_stand13 ] {ai_stand();};
+void() zombie_stand13 =[ $stand13, zombie_stand14 ] {ai_stand();};
+void() zombie_stand14 =[ $stand14, zombie_stand15 ] {ai_stand();};
+void() zombie_stand15 =[ $stand15, alt_zombie_stand1 ] {ai_stand();};
+
+void() zombie_cruc1 = [ $cruc_1, zombie_cruc2 ] {
+if (random() < 0.1)
+ sound_idle (self, CHAN_VOICE, "zombie/idle_w2.wav", 1, ATTN_STATIC);};
+void() zombie_cruc2 = [ $cruc_2, zombie_cruc3 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc3 = [ $cruc_3, zombie_cruc4 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc4 = [ $cruc_4, zombie_cruc5 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc5 = [ $cruc_5, zombie_cruc6 ] {self.nextthink = time + 0.1 + random()*0.1;};
+void() zombie_cruc6 = [ $cruc_6, zombie_cruc1 ] {self.nextthink = time + 0.1 + random()*0.1;};
+
+void() zombie_walk1 =[ $walk1, zombie_walk2 ] {
+ self.solid = SOLID_SLIDEBOX;
+ self.health = 60; //so he doesn't fall
+ ai_walk(0);};
+void() zombie_walk2 =[ $walk2, zombie_walk3 ] {ai_walk(2);};
+void() zombie_walk3 =[ $walk3, zombie_walk4 ] {ai_walk(3);};
+void() zombie_walk4 =[ $walk4, zombie_walk5 ] {ai_walk(2);};
+void() zombie_walk5 =[ $walk5, zombie_walk6 ] {ai_walk(1);};
+void() zombie_walk6 =[ $walk6, zombie_walk7 ] {ai_walk(0);};
+void() zombie_walk7 =[ $walk7, zombie_walk8 ] {ai_walk(0);};
+void() zombie_walk8 =[ $walk8, zombie_walk9 ] {ai_walk(0);};
+void() zombie_walk9 =[ $walk9, zombie_walk10 ] {ai_walk(0);};
+void() zombie_walk10 =[ $walk10, zombie_walk11 ] {ai_walk(0);};
+void() zombie_walk11 =[ $walk11, zombie_walk12 ] {ai_walk(2);};
+void() zombie_walk12 =[ $walk12, zombie_walk13 ] {ai_walk(2);};
+void() zombie_walk13 =[ $walk13, zombie_walk14 ] {ai_walk(1);};
+void() zombie_walk14 =[ $walk14, zombie_walk15 ] {ai_walk(0);};
+void() zombie_walk15 =[ $walk15, zombie_walk16 ] {ai_walk(0);};
+void() zombie_walk16 =[ $walk16, zombie_walk17 ] {ai_walk(0);};
+void() zombie_walk17 =[ $walk17, zombie_walk18 ] {ai_walk(0);};
+void() zombie_walk18 =[ $walk18, zombie_walk19 ] {ai_walk(0);};
+void() zombie_walk19 =[ $walk19, zombie_walk1 ] {
+ai_walk(0);
+if (random() < 0.2)
+ sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);};
+
+void() zombie_run1 =[ $run1, zombie_run2 ] {
+ if (self.spawnflags & SPAWN_SLEEPING)
+ { // sloppy hack, but it fixes the illusionary zombie bug
+ body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/zombie.mdl");
+ setsize (self, '-16 -16 -24', '16 16 40');
+ }
+ ai_run(1);
+ self.inpain = 0;};
+void() zombie_run2 =[ $run2, zombie_run3 ] {ai_run(1);};
+void() zombie_run3 =[ $run3, zombie_run4 ] {ai_run(0);};
+void() zombie_run4 =[ $run4, zombie_run5 ] {ai_run(1);};
+void() zombie_run5 =[ $run5, zombie_run6 ] {ai_run(2);};
+void() zombie_run6 =[ $run6, zombie_run7 ] {ai_run(3);};
+void() zombie_run7 =[ $run7, zombie_run8 ] {ai_run(4);};
+void() zombie_run8 =[ $run8, zombie_run9 ] {ai_run(4);};
+void() zombie_run9 =[ $run9, zombie_run10 ] {ai_run(2);};
+void() zombie_run10 =[ $run10, zombie_run11 ] {ai_run(0);};
+void() zombie_run11 =[ $run11, zombie_run12 ] {ai_run(0);};
+void() zombie_run12 =[ $run12, zombie_run13 ] {ai_run(0);};
+void() zombie_run13 =[ $run13, zombie_run14 ] {ai_run(2);};
+void() zombie_run14 =[ $run14, zombie_run15 ] {ai_run(4);};
+void() zombie_run15 =[ $run15, zombie_run16 ] {ai_run(6);};
+void() zombie_run16 =[ $run16, zombie_run17 ] {ai_run(7);};
+void() zombie_run17 =[ $run17, zombie_run18 ] {ai_run(3);};
+void() zombie_run18 =[ $run18, zombie_run1 ] {
+ai_run(8);
+if (random() < 0.2)
+ sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
+if (random() > 0.8)
+ sound_sight (self, CHAN_VOICE, "zombie/z_idle1.wav", 1, ATTN_IDLE);
+};
+
+/*
+=============================================================================
+
+ATTACKS
+
+=============================================================================
+*/
+// void() Z_hit =
+// {
+// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+// };
+//
+// void() Z_land =
+// {
+// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+// };
+
+// void() ZombieGrenadeTouch2 =
+// {
+// if (other == self.owner)
+// return; // don't explode on owner
+// if (other.takedamage)
+// {
+// // Z_hit();
+// T_Damage (other, self, self.owner, 10 );
+// sound_hit (self, CHAN_WEAPON, "zombie/z_hit.wav", 1, ATTN_NORM);
+// remove (self);
+// return;
+// }
+// // Z_land();
+// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
+// self.velocity = '0 0 0';
+// self.avelocity = '0 0 0';
+// self.touch = SUB_Remove;
+// };
+
+/*
+================
+ZombieFireGrenade
+================
+*/
+void(vector st) ZombieFireGrenade =
+{
+ local entity missile;
+ local vector org;
+
+ sound_attack (self, CHAN_WEAPON, "zombie/z_shot1.wav", 1, ATTN_NORM);
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+
+// calc org
+ org = self.origin + st_x * v_forward + st_y * v_right + (st_z - 24) * v_up;
+
+// set missile speed
+
+ makevectors (self.angles);
+
+ missile.velocity = normalize(self.enemy.origin - org);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+
+ missile.avelocity = '3000 1000 2000';
+
+ missile.touch = ZombieGrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = SUB_Remove;
+ // setmodel (missile, "progs/zom_gib.mdl");
+ if (self.mdl_proj != "") // dumptruck_ds custom_mdls
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/zom_gib.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, org);
+};
+
+
+void() zombie_atta1 =[ $atta1, zombie_atta2 ] {ai_face();};
+void() zombie_atta2 =[ $atta2, zombie_atta3 ] {ai_face();};
+void() zombie_atta3 =[ $atta3, zombie_atta4 ] {ai_face();};
+void() zombie_atta4 =[ $atta4, zombie_atta5 ] {ai_face();};
+void() zombie_atta5 =[ $atta5, zombie_atta6 ] {ai_face();};
+void() zombie_atta6 =[ $atta6, zombie_atta7 ] {ai_face();};
+void() zombie_atta7 =[ $atta7, zombie_atta8 ] {ai_face();};
+void() zombie_atta8 =[ $atta8, zombie_atta9 ] {ai_face();};
+void() zombie_atta9 =[ $atta9, zombie_atta10 ] {ai_face();};
+void() zombie_atta10 =[ $atta10, zombie_atta11 ] {ai_face();};
+void() zombie_atta11 =[ $atta11, zombie_atta12 ] {ai_face();};
+void() zombie_atta12 =[ $atta12, zombie_atta13 ] {ai_face();};
+void() zombie_atta13 =[ $atta13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -22 30');};
+
+void() zombie_attb1 =[ $attb1, zombie_attb2 ] {ai_face();};
+void() zombie_attb2 =[ $attb2, zombie_attb3 ] {ai_face();};
+void() zombie_attb3 =[ $attb3, zombie_attb4 ] {ai_face();};
+void() zombie_attb4 =[ $attb4, zombie_attb5 ] {ai_face();};
+void() zombie_attb5 =[ $attb5, zombie_attb6 ] {ai_face();};
+void() zombie_attb6 =[ $attb6, zombie_attb7 ] {ai_face();};
+void() zombie_attb7 =[ $attb7, zombie_attb8 ] {ai_face();};
+void() zombie_attb8 =[ $attb8, zombie_attb9 ] {ai_face();};
+void() zombie_attb9 =[ $attb9, zombie_attb10 ] {ai_face();};
+void() zombie_attb10 =[ $attb10, zombie_attb11 ] {ai_face();};
+void() zombie_attb11 =[ $attb11, zombie_attb12 ] {ai_face();};
+void() zombie_attb12 =[ $attb12, zombie_attb13 ] {ai_face();};
+void() zombie_attb13 =[ $attb13, zombie_attb14 ] {ai_face();};
+void() zombie_attb14 =[ $attb13, zombie_run1 ] {ai_face();ZombieFireGrenade('-10 -24 29');};
+
+void() zombie_attc1 =[ $attc1, zombie_attc2 ] {ai_face();};
+void() zombie_attc2 =[ $attc2, zombie_attc3 ] {ai_face();};
+void() zombie_attc3 =[ $attc3, zombie_attc4 ] {ai_face();};
+void() zombie_attc4 =[ $attc4, zombie_attc5 ] {ai_face();};
+void() zombie_attc5 =[ $attc5, zombie_attc6 ] {ai_face();};
+void() zombie_attc6 =[ $attc6, zombie_attc7 ] {ai_face();};
+void() zombie_attc7 =[ $attc7, zombie_attc8 ] {ai_face();};
+void() zombie_attc8 =[ $attc8, zombie_attc9 ] {ai_face();};
+void() zombie_attc9 =[ $attc9, zombie_attc10 ] {ai_face();};
+void() zombie_attc10 =[ $attc10, zombie_attc11 ] {ai_face();};
+void() zombie_attc11 =[ $attc11, zombie_attc12 ] {ai_face();};
+void() zombie_attc12 =[ $attc12, zombie_run1 ] {ai_face();ZombieFireGrenade('-12 -19 29');};
+
+void() zombie_missile =
+{
+ local float r;
+
+ r = random();
+
+ if (r < 0.3)
+ zombie_atta1 ();
+ else if (r < 0.6)
+ zombie_attb1 ();
+ else
+ zombie_attc1 ();
+};
+//////////////////////////
+/// turret frames START
+/////////////////////////
+void() zombie_turret_atta1 =[ $atta1, zombie_turret_atta2 ] {self.health = 60;ai_face();};
+void() zombie_turret_atta2 =[ $atta2, zombie_turret_atta3 ] {ai_face();};
+void() zombie_turret_atta3 =[ $atta3, zombie_turret_atta4 ] {ai_face();};
+void() zombie_turret_atta4 =[ $atta4, zombie_turret_atta5 ] {ai_face();};
+void() zombie_turret_atta5 =[ $atta5, zombie_turret_atta6 ] {ai_face();};
+void() zombie_turret_atta6 =[ $atta6, zombie_turret_atta7 ] {ai_face();};
+void() zombie_turret_atta7 =[ $atta7, zombie_turret_atta8 ] {ai_face();};
+void() zombie_turret_atta8 =[ $atta8, zombie_turret_atta9 ] {ai_face();};
+void() zombie_turret_atta9 =[ $atta9, zombie_turret_atta10 ] {ai_face();};
+void() zombie_turret_atta10 =[ $atta10, zombie_turret_atta11 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_atta11 =[ $atta11, zombie_turret_atta12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_atta12 =[ $atta12, zombie_turret_atta13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_atta13 =[ $atta13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+
+void() zombie_turret_attb1 =[ $attb1, zombie_turret_attb2 ] {self.health = 60;ai_face();};
+void() zombie_turret_attb2 =[ $attb2, zombie_turret_attb3 ] {ai_face();};
+void() zombie_turret_attb3 =[ $attb3, zombie_turret_attb4 ] {ai_face();};
+void() zombie_turret_attb4 =[ $attb4, zombie_turret_attb5 ] {ai_face();};
+void() zombie_turret_attb5 =[ $attb5, zombie_turret_attb6 ] {ai_face();};
+void() zombie_turret_attb6 =[ $attb6, zombie_turret_attb7 ] {ai_face();};
+void() zombie_turret_attb7 =[ $attb7, zombie_turret_attb8 ] {ai_face();};
+void() zombie_turret_attb8 =[ $attb8, zombie_turret_attb9 ] {ai_face();};
+void() zombie_turret_attb9 =[ $attb9, zombie_turret_attb10 ] {ai_face();};
+void() zombie_turret_attb10 =[ $attb10, zombie_turret_attb11 ] {ai_face();};
+void() zombie_turret_attb11 =[ $attb11, zombie_turret_attb12 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_attb12 =[ $attb12, zombie_turret_attb13 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attb13 =[ $attb13, zombie_turret_attb14 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attb14 =[ $attb13, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+
+void() zombie_turret_attc1 =[ $attc1, zombie_turret_attc2 ] {self.health = 60;ai_face();};
+void() zombie_turret_attc2 =[ $attc2, zombie_turret_attc3 ] {ai_face();};
+void() zombie_turret_attc3 =[ $attc3, zombie_turret_attc4 ] {ai_face();};
+void() zombie_turret_attc4 =[ $attc4, zombie_turret_attc5 ] {ai_face();};
+void() zombie_turret_attc5 =[ $attc5, zombie_turret_attc6 ] {ai_face();};
+void() zombie_turret_attc6 =[ $attc6, zombie_turret_attc7 ] {ai_face();};
+void() zombie_turret_attc7 =[ $attc7, zombie_turret_attc8 ] {ai_face();};
+void() zombie_turret_attc8 =[ $attc8, zombie_turret_attc9 ] {ai_face();};
+void() zombie_turret_attc9 =[ $attc9, zombie_turret_attc10 ] {ai_face();self.attack_elevation = IterateElevation(OGRE_DEFAULT_ELEVATION, self.enemy.origin);};
+void() zombie_turret_attc10 =[ $attc10, zombie_turret_attc11 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attc11 =[ $attc11, zombie_turret_attc12 ] {ai_face();self.attack_elevation = IterateElevation(self.attack_elevation, self.enemy.origin);};
+void() zombie_turret_attc12 =[ $attc12, alt_zombie_seek_stand1 ] {ai_run(0);PreachFireZombie(self.attack_elevation);};
+void() alt_zombie_seek_stand1 =[ $stand1, alt_zombie_seek_stand2 ] {self.health = 60; ai_run(0);};
+void() alt_zombie_seek_stand2 =[ $stand2, zombie_seek_stand3 ] {ai_run(0);};
+void() zombie_seek_stand3 =[ $stand3, zombie_seek_stand4 ] {ai_run(0);};
+void() zombie_seek_stand4 =[ $stand4, zombie_seek_stand5 ] {ai_run(0);};
+void() zombie_seek_stand5 =[ $stand5, zombie_seek_stand6 ] {ai_run(0);};
+void() zombie_seek_stand6 =[ $stand6, zombie_seek_stand7 ] {ai_run(0);};
+void() zombie_seek_stand7 =[ $stand7, zombie_seek_stand8 ] {ai_run(0);};
+void() zombie_seek_stand8 =[ $stand8, zombie_seek_stand9 ] {ai_run(0);};
+void() zombie_seek_stand9 =[ $stand9, zombie_seek_stand10 ] {ai_run(0);};
+void() zombie_seek_stand10 =[ $stand10, zombie_seek_stand11 ] {ai_run(0);};
+void() zombie_seek_stand11 =[ $stand11, zombie_seek_stand12 ] {ai_run(0);};
+void() zombie_seek_stand12 =[ $stand12, zombie_seek_stand13 ] {ai_run(0);};
+void() zombie_seek_stand13 =[ $stand13, zombie_seek_stand14 ] {ai_run(0);};
+void() zombie_seek_stand14 =[ $stand14, zombie_seek_stand15 ] {ai_run(0);};
+void() zombie_seek_stand15 =[ $stand15, alt_zombie_seek_stand1 ] {ai_run(0);};
+
+void() zombie_turret_missile =
+{
+ local float r;
+
+ r = random();
+
+ if (r < 0.3)
+ zombie_turret_attb1 ();
+ else if (r < 0.6)
+ zombie_turret_atta1 ();
+ else
+ zombie_turret_attc1 ();
+};
+//////////////////////////
+/// turret frames END
+/////////////////////////
+
+/*
+=============================================================================
+
+PAIN
+
+=============================================================================
+*/
+
+void() zombie_paina1 =[ $paina1, zombie_paina2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
+void() zombie_paina2 =[ $paina2, zombie_paina3 ] {ai_painforward(3);};
+void() zombie_paina3 =[ $paina3, zombie_paina4 ] {ai_painforward(1);};
+void() zombie_paina4 =[ $paina4, zombie_paina5 ] {ai_pain(1);};
+void() zombie_paina5 =[ $paina5, zombie_paina6 ] {ai_pain(3);};
+void() zombie_paina6 =[ $paina6, zombie_paina7 ] {ai_pain(1);};
+void() zombie_paina7 =[ $paina7, zombie_paina8 ] {};
+void() zombie_paina8 =[ $paina8, zombie_paina9 ] {};
+void() zombie_paina9 =[ $paina9, zombie_paina10 ] {};
+void() zombie_paina10 =[ $paina10, zombie_paina11 ] {};
+void() zombie_paina11 =[ $paina11, zombie_paina12 ] {};
+void() zombie_paina12 =[ $paina12, zombie_run1 ] {};
+
+void() zombie_painb1 =[ $painb1, zombie_painb2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
+void() zombie_painb2 =[ $painb2, zombie_painb3 ] {ai_pain(2);};
+void() zombie_painb3 =[ $painb3, zombie_painb4 ] {ai_pain(8);};
+void() zombie_painb4 =[ $painb4, zombie_painb5 ] {ai_pain(6);};
+void() zombie_painb5 =[ $painb5, zombie_painb6 ] {ai_pain(2);};
+void() zombie_painb6 =[ $painb6, zombie_painb7 ] {};
+void() zombie_painb7 =[ $painb7, zombie_painb8 ] {};
+void() zombie_painb8 =[ $painb8, zombie_painb9 ] {};
+void() zombie_painb9 =[ $painb9, zombie_painb10 ] {sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);};
+void() zombie_painb10 =[ $painb10, zombie_painb11 ] {};
+void() zombie_painb11 =[ $painb11, zombie_painb12 ] {};
+void() zombie_painb12 =[ $painb12, zombie_painb13 ] {};
+void() zombie_painb13 =[ $painb13, zombie_painb14 ] {};
+void() zombie_painb14 =[ $painb14, zombie_painb15 ] {};
+void() zombie_painb15 =[ $painb15, zombie_painb16 ] {};
+void() zombie_painb16 =[ $painb16, zombie_painb17 ] {};
+void() zombie_painb17 =[ $painb17, zombie_painb18 ] {};
+void() zombie_painb18 =[ $painb18, zombie_painb19 ] {};
+void() zombie_painb19 =[ $painb19, zombie_painb20 ] {};
+void() zombie_painb20 =[ $painb20, zombie_painb21 ] {};
+void() zombie_painb21 =[ $painb21, zombie_painb22 ] {};
+void() zombie_painb22 =[ $painb22, zombie_painb23 ] {};
+void() zombie_painb23 =[ $painb23, zombie_painb24 ] {};
+void() zombie_painb24 =[ $painb24, zombie_painb25 ] {};
+void() zombie_painb25 =[ $painb25, zombie_painb26 ] {ai_painforward(1);};
+void() zombie_painb26 =[ $painb26, zombie_painb27 ] {};
+void() zombie_painb27 =[ $painb27, zombie_painb28 ] {};
+void() zombie_painb28 =[ $painb28, zombie_run1 ] {};
+
+void() zombie_painc1 =[ $painc1, zombie_painc2 ] {sound_misc2 (self, CHAN_VOICE, "zombie/z_pain1.wav", 1, ATTN_NORM);};
+void() zombie_painc2 =[ $painc2, zombie_painc3 ] {};
+void() zombie_painc3 =[ $painc3, zombie_painc4 ] {ai_pain(3);};
+void() zombie_painc4 =[ $painc4, zombie_painc5 ] {ai_pain(1);};
+void() zombie_painc5 =[ $painc5, zombie_painc6 ] {};
+void() zombie_painc6 =[ $painc6, zombie_painc7 ] {};
+void() zombie_painc7 =[ $painc7, zombie_painc8 ] {};
+void() zombie_painc8 =[ $painc8, zombie_painc9 ] {};
+void() zombie_painc9 =[ $painc9, zombie_painc10 ] {};
+void() zombie_painc10 =[ $painc10, zombie_painc11 ] {};
+void() zombie_painc11 =[ $painc11, zombie_painc12 ] {ai_painforward(1);};
+void() zombie_painc12 =[ $painc12, zombie_painc13 ] {ai_painforward(1);};
+void() zombie_painc13 =[ $painc13, zombie_painc14 ] {};
+void() zombie_painc14 =[ $painc14, zombie_painc15 ] {};
+void() zombie_painc15 =[ $painc15, zombie_painc16 ] {};
+void() zombie_painc16 =[ $painc16, zombie_painc17 ] {};
+void() zombie_painc17 =[ $painc17, zombie_painc18 ] {};
+void() zombie_painc18 =[ $painc18, zombie_run1 ] {};
+
+void() zombie_paind1 =[ $paind1, zombie_paind2 ] {sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);};
+void() zombie_paind2 =[ $paind2, zombie_paind3 ] {};
+void() zombie_paind3 =[ $paind3, zombie_paind4 ] {};
+void() zombie_paind4 =[ $paind4, zombie_paind5 ] {};
+void() zombie_paind5 =[ $paind5, zombie_paind6 ] {};
+void() zombie_paind6 =[ $paind6, zombie_paind7 ] {};
+void() zombie_paind7 =[ $paind7, zombie_paind8 ] {};
+void() zombie_paind8 =[ $paind8, zombie_paind9 ] {};
+void() zombie_paind9 =[ $paind9, zombie_paind10 ] {ai_pain(1);};
+void() zombie_paind10 =[ $paind10, zombie_paind11 ] {};
+void() zombie_paind11 =[ $paind11, zombie_paind12 ] {};
+void() zombie_paind12 =[ $paind12, zombie_paind13 ] {};
+void() zombie_paind13 =[ $paind13, zombie_run1 ] {};
+
+void() zombie_paine1 =[ $paine1, zombie_paine2 ] {
+if (self.axhitme == 2) // Chainsaw will gib zombie
+{
+ T_Damage(self, world, world, 80);
+ return;
+}
+sound_pain (self, CHAN_VOICE, "zombie/z_pain.wav", 1, ATTN_NORM);
+self.health = 60;
+};
+void() zombie_paine2 =[ $paine2, zombie_paine3 ] {ai_pain(8);};
+void() zombie_paine3 =[ $paine3, zombie_paine4 ] {ai_pain(5);};
+void() zombie_paine4 =[ $paine4, zombie_paine5 ] {ai_pain(3);};
+void() zombie_paine5 =[ $paine5, zombie_paine6 ] {ai_pain(1);};
+void() zombie_paine6 =[ $paine6, zombie_paine7 ] {ai_pain(2);};
+void() zombie_paine7 =[ $paine7, zombie_paine8 ] {ai_pain(1);};
+void() zombie_paine8 =[ $paine8, zombie_paine9 ] {ai_pain(1);};
+void() zombie_paine9 =[ $paine9, zombie_paine10 ] {ai_pain(2);};
+void() zombie_paine10 =[ $paine10, zombie_paine11 ] {
+sound_misc3 (self, CHAN_BODY, "zombie/z_fall.wav", 1, ATTN_NORM);
+self.solid = SOLID_NOT;
+};
+void() zombie_paine11 =[ $paine11, zombie_paine12 ] {self.nextthink = self.nextthink + 5;self.health = 60;};
+void() zombie_paine12 =[ $paine12, zombie_paine13 ]{
+// see if ok to stand up
+self.health = 60;
+sound_misc (self, CHAN_VOICE, "zombie/z_idle.wav", 1, ATTN_IDLE);
+self.solid = SOLID_SLIDEBOX;
+if (!walkmove (0, 0))
+{
+ self.think = zombie_paine11;
+ self.solid = SOLID_NOT;
+ return;
+}
+};
+void() zombie_paine13 =[ $paine13, zombie_paine14 ] {};
+void() zombie_paine14 =[ $paine14, zombie_paine15 ] {};
+void() zombie_paine15 =[ $paine15, zombie_paine16 ] {};
+void() zombie_paine16 =[ $paine16, zombie_paine17 ] {};
+void() zombie_paine17 =[ $paine17, zombie_paine18 ] {};
+void() zombie_paine18 =[ $paine18, zombie_paine19 ] {};
+void() zombie_paine19 =[ $paine19, zombie_paine20 ] {};
+void() zombie_paine20 =[ $paine20, zombie_paine21 ] {};
+void() zombie_paine21 =[ $paine21, zombie_paine22 ] {};
+void() zombie_paine22 =[ $paine22, zombie_paine23 ] {};
+void() zombie_paine23 =[ $paine23, zombie_paine24 ] {};
+void() zombie_paine24 =[ $paine24, zombie_paine25 ] {};
+void() zombie_paine25 =[ $paine25, zombie_paine26 ] {ai_painforward(5);};
+void() zombie_paine26 =[ $paine26, zombie_paine27 ] {ai_painforward(3);};
+void() zombie_paine27 =[ $paine27, zombie_paine28 ] {ai_painforward(1);};
+void() zombie_paine28 =[ $paine28, zombie_paine29 ] {ai_pain(1);};
+void() zombie_paine29 =[ $paine29, zombie_paine30 ] {};
+void() zombie_paine30 =[ $paine30, zombie_run1 ] {};
+
+void() zombie_die =
+{
+ sound_death (self, CHAN_VOICE, "zombie/z_gib.wav", 1, ATTN_NORM);
+ if (self.mdl_head != "") //dumptruck_ds custom_mdls
+ {
+ ThrowHead (self.mdl_head, self.health);
+ }
+ else
+ {
+ ThrowHead ("progs/h_zombie.mdl", self.health/*, self.dest*/); //commented out dest -- dumptruck_ds
+ }
+ // ThrowGib ("progs/gib1.mdl", self.health/*, self.dest*/);
+ // ThrowGib ("progs/gib2.mdl", self.health/*, self.dest*/);
+ // ThrowGib ("progs/gib3.mdl", self.health/*, self.dest*/);
+ if (self.mdl_gib1 != "") // custom models -- dumptruck_ds
+ {
+ ThrowGib (self.mdl_gib1, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", self.health);
+ }
+ if (self.mdl_gib2 != "")
+ {
+ ThrowGib (self.mdl_gib2, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib2.mdl", self.health);
+ }
+ if (self.mdl_gib3 != "")
+ {
+ ThrowGib (self.mdl_gib3, self.health);
+ }
+ else
+ {
+ ThrowGib ("progs/gib3.mdl", self.health);
+ }
+ DropStuff();
+};
+
+/*
+=================
+zombie_pain
+
+Zombies can only be killed (gibbed) by doing 60 hit points of damage
+in a single frame (rockets, grenades, quad shotgun, quad nailgun).
+
+A hit of 25 points or more (super shotgun, quad nailgun) will always put it
+down to the ground.
+
+A hit of from 10 to 40 points in one frame will cause it to go down if it
+has been twice in two seconds, otherwise it goes into one of the four
+fast pain frames.
+
+A hit of less than 10 points of damage (winged by a shotgun) will be ignored.
+
+FIXME: don't use pain_finished because of nightmare hack
+=================
+*/
+void(entity attacker, float take) zombie_pain =
+{
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.health = 60; // always reset health
+
+ if (take >= 60)
+ {
+ zombie_die();
+ }
+ else
+ return;
+ }
+
+ local float r;
+
+ self.health = 60; // always reset health
+
+ if (take < 9)
+ return; // totally ignore
+
+ if (self.inpain == 2)
+ return; // down on ground, so don't reset any counters
+
+// go down immediately if a big enough hit
+ if ((take >= 25) || (self.axhitme == 2))
+ {
+ self.inpain = 2;
+ zombie_paine1 ();
+ return;
+ }
+
+ if (self.inpain)
+ {
+// if hit again in next gre seconds while not in pain frames, definately drop
+ self.pain_finished = time + 3;
+ return; // currently going through an animation, don't change
+ }
+
+ if (self.pain_finished > time)
+ {
+// hit again, so drop down
+ self.inpain = 2;
+ zombie_paine1 ();
+ return;
+ }
+
+// gp into one of the fast pain animations
+ self.inpain = 1;
+
+ r = random();
+ if (r < 0.25)
+ zombie_paina1 ();
+ else if (r < 0.5)
+ zombie_painb1 ();
+ else if (r < 0.75)
+ zombie_painc1 ();
+ else
+ zombie_paind1 ();
+};
+
+void() zombie_decide = // stand up if orig. lying down, else just start running
+{
+ if (self.health==61)
+ zombie_paine12();
+ else
+ zombie_run1();
+
+ self.th_run = zombie_run1;
+};
+
+void() zombie_use = // wake up a sleeping zombie!
+
+{
+ self.count = 0;
+ //attacker = other;
+ monster_use();
+};
+
+void() zombie_start = // determine if zombie is to be lying down, or standing
+{
+ self.count = 1; //dumptruck_ds -- Don't start zombie_stand1 yet!
+ self.use = zombie_use; //dumptruck_ds -- makes self.count = 0 so zombie_stand1 is called
+
+ if (self.spawnflags & SPAWN_SLEEPING)
+ {
+ if (!SUB_IsTargeted ())
+ {
+ dprint ("WARNING: removed untargeted sleeping zombie at ");
+ dprint (vtos (self.origin));
+ dprint ("\n");
+
+ monster_update_total (-1);
+ remove (self);
+ return;
+ }
+ self.inpain = 2;
+ zombie_stand1 ();
+ }
+ else
+ {
+ alt_zombie_stand1 ();
+ }
+
+ self.th_stand = alt_zombie_stand1;
+};
+
+// void() zombie_start2 = //unused in progs_dump -- dumptruck_ds
+// {
+// local vector org;
+// local entity teldeath;
+//
+// if (self.style)
+// {
+// makevectors (self.angles);
+// org = self.origin + 16 * v_forward;
+// spawn_tfog (org);
+// teldeath = spawn();
+// teldeath.origin = org;
+// teldeath.owner = self;
+// // teldeath.think = sf64_teledeath; -- not used in progs_dump -- dumptruck_ds
+// teldeath.nextthink = time + 0.1;
+// }
+//
+// self.solid = SOLID_SLIDEBOX;
+// self.movetype = MOVETYPE_STEP;
+//
+// setmodel (self, "progs/zombie.mdl");
+//
+// setsize (self, '-16 -16 -24', '16 16 40');
+// self.health = 61;
+//
+// walkmonster_start();
+// };
+
+//============================================================================
+
+/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ( {{ spawnflags & 1 -> { "path" : "progs/zombie.mdl", "frame" : 192 }, "progs/zombie.mdl" }} );
+}
+If crucified, stick the bounding box 12 pixels back into a wall to look right.
+
+Default health = 60
+
+If SPAWN_SLEEPING is used there must be a targetname set. The zombie will stand up when targeted. Crucified motionless zombies are silent and do not animate." //dumptruck_ds
+
+snd_death(string) : "Path to custom death sound"
+snd_pain(string) : "Path to custom pain sound"
+snd_attack(string) : "Path to custom attack sound (WHOOSH)"
+snd_idle(string) : "Path to custom idle sound (CRUCIFIED ONLY)"
+snd_misc(string) : "Path to custom (IDLE 2) sound"
+snd_sight(string) : "Path to custom sight sound"
+snd_misc2(string) : "Path to custom (PAIN 2) sound"
+snd_misc3(string) : "Path to custom (FALLING) sound"
+
+mdl_head(string) : "Path to custom head model"
+mdl_body(string) : "Path to custom body model"
+mdl_proj(string) : "Path to custom projectile model"
+skin_head(float) : "Skin index of custom head model"
+skin_proj(float) : "Skin index of custom projectile model"
+mdl_gib1(string) : "Path to custom 1st gib model"
+mdl_gib2(string) : "Path to custom 2nd gib model"
+mdl_gib3(string) : "Path to custom 3rd gib model"
+
+effects(choices) : "Add a visual effect to an entity"
+0 : "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+berserk(choices) "Skips certain pain animations similar to skill 3 (Makes a semi-nightmare monster!)"
+0 : "Off (Default)"
+1 : "Berserk (skip pain animations)"
+
+delay(float) : "Delay spawn in for this amount of time"
+
+wait(choices) : "Play an effect when trigger spawned?"
+0 : "Teleport Effects (Default)"
+1 : "Spawn Silently"
+
+spawn_angry(Choices)
+0 : "Only when trigger spawned, default behavior - not angry"
+1 : "Only when trigger spawned, set to 1 to spawn angry at player"
+
+infight_mode(Choices)
+0 : "Default behavior, only with different classnames"
+1 : "Infight with monsters with the same classname but a different mdl_body"
+2 : "Infight with monsters with the same classname and model but a different skin"
+3 : "Infight no matter what"
+
+health(integer) : "Set this to a custom health amount"
+pain_target(string) : "Fire this target when pain_threshold is reached"
+pain_threshold(integer) : "Fire pain_target when health drops below this amount"
+sight_trigger(integer) : "1 = Fire target upon seeing the player instead of death"
+skin(integer) : "Skin index (default 0) Use this when your custom model has more than one skin to select"
+obit_name(string) : "When used with obit_method, this will set part of the text for a custom obituary. e.g. a Super Soldier! Using the examples here, the obituary would read: Player was eviscerated by a Super Solider!"
+obit_method(string) : "When used with obit_name, will set part of the text for a custom obituary. e.g. eviscerated - If empty, defaults to killed."
+damage_mod(float) : "USE WITH CAUTION! Multiply all damage from this monster by this number (e.g. 4 = Quad damage)"
+
+spawnflags(Flags) =
+1 : "Crucified"
+2 : "Ambush"
+4 : "Crucified motionless"
+16 : "Spawn Sleeping"
+*/
+void() monster_zombie =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (deathmatch /*&& (!(self.spawnflags & SPAWN_DEAD_CRUCIFIED))*/)
+ {
+ remove(self);
+ return;
+ }
+
+ precache_body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ precache_head_model ("progs/h_zombie.mdl");
+ precache_proj_model ("progs/zom_gib.mdl");
+ // precache_model ("progs/zombie.mdl");
+ // precache_model ("progs/h_zombie.mdl");
+ // precache_model ("progs/zom_gib.mdl");
+
+ precache_sound_misc ("zombie/z_idle.wav");
+ precache_sound_sight ("zombie/z_idle1.wav");
+ precache_sound_attack ("zombie/z_shot1.wav");
+ precache_sound_death ("zombie/z_gib.wav");
+ precache_sound_pain ("zombie/z_pain.wav");
+ precache_sound_misc2 ("zombie/z_pain1.wav");
+ precache_sound_misc3 ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+
+ precache_sound_idle ("zombie/idle_w2.wav");
+
+ precache_gib1 ("progs/gib1.mdl");
+ precache_gib2 ("progs/gib2.mdl");
+ precache_gib3 ("progs/gib3.mdl");
+
+ self.th_stand = zombie_start;
+ self.th_walk = zombie_walk1;
+ if (self.spawnflags & I_AM_TURRET)
+ {
+ self.th_run = alt_zombie_seek_stand1;
+ }
+ else
+ {
+ self.th_run = zombie_decide;
+ }
+
+ self.th_pain = zombie_pain;
+ self.th_die = zombie_die;
+ self.th_turret = zombie_turret_missile;
+ self.th_missile = zombie_missile;
+ self.solid = SOLID_SLIDEBOX;
+ self.movetype = MOVETYPE_STEP;
+
+ body_model ("progs/zombie.mdl"); //custom_mdls dumptruck_ds
+ // setmodel (self, "progs/zombie.mdl");
+
+ setsize (self, '-16 -16 -24', '16 16 40');
+ self.health = 61;
+
+ if (self.spawnflags & SPAWN_CRUCIFIED)
+ {
+ self.movetype = MOVETYPE_NONE;
+ zombie_cruc1 ();
+ }
+ else if (self.spawnflags & SPAWN_DEAD_CRUCIFIED)
+ {
+ self.movetype = MOVETYPE_NONE;
+ zombie_dead_cruc1 ();
+ }
+ else
+ walkmonster_start();
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/plats.qc

diff --git a/qc/plats.qc b/qc/plats.qc
index f6c5166..ef4d56a 100644
--- a/qc/plats.qc
+++ b/qc/plats.qc
@@ -1,786 +1,786 @@
-
-
-void() plat_center_touch;
-void() plat_outside_touch;
-void() plat_trigger_use;
-void() plat_go_up;
-void() plat_go_down;
-void() plat_crush;
-float PLAT_LOW_TRIGGER = 1;
-
-void() plat_spawn_inside_trigger =
-{
- local entity trigger;
- local vector tmin, tmax;
-
-//
-// middle trigger
-//
- trigger = spawn();
- trigger.touch = plat_center_touch;
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.enemy = self;
-
- tmin = self.mins + '25 25 0';
- tmax = self.maxs - '25 25 -8';
- tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
- if (self.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
-
- if (self.size_x <= 50)
- {
- tmin_x = (self.mins_x + self.maxs_x) / 2;
- tmax_x = tmin_x + 1;
- }
- if (self.size_y <= 50)
- {
- tmin_y = (self.mins_y + self.maxs_y) / 2;
- tmax_y = tmin_y + 1;
- }
-
- setsize (trigger, tmin, tmax);
-};
-
-void() plat_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- self.think = plat_go_down;
- self.nextthink = self.ltime + 3;
-};
-
-void() plat_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
-
-void() plat_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
-};
-
-void() plat_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
-};
-
-void() plat_center_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- self = self.enemy;
- if (self.state == STATE_BOTTOM)
- plat_go_up ();
- else if (self.state == STATE_TOP)
- self.nextthink = self.ltime + 1; // delay going down
-};
-
-void() plat_outside_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
-//dprint ("plat_outside_touch\n");
- self = self.enemy;
- if (self.state == STATE_TOP)
- plat_go_down ();
-};
-
-void() plat_trigger_use =
-{
- if (self.think)
- return; // allready activated
- plat_go_down();
-};
-
-
-void() plat_crush =
-{
-//dprint ("plat_crush\n");
-
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- plat_go_down ();
- else if (self.state == STATE_DOWN)
- plat_go_up ();
- else
- objerror ("plat_crush: bad self.state\n");
-};
-
-void() plat_use =
-{
- self.use = SUB_Null;
- if (self.state != STATE_UP)
- objerror ("plat_use: not in up state");
- plat_go_down();
-};
-
-
-/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-speed default 150
-
-Plats are always drawn in the extended position, so they will light correctly.
-
-If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
-
-If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
-Set "sounds" to one of the following:
-1) base fast
-2) chain slow
-*/
-
-
-void() func_plat =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
-
- if (self.sounds == 0)
- self.sounds = 2;
-// FIX THIS TO LOAD A GENERIC PLAT SOUND
-
- if (self.sounds == 1)
- {
- precache_sound ("plats/plat1.wav");
- precache_sound ("plats/plat2.wav");
- self.noise = "plats/plat1.wav";
- self.noise1 = "plats/plat2.wav";
- }
-
- if (self.sounds == 2)
- {
- precache_sound ("plats/medplat1.wav");
- precache_sound ("plats/medplat2.wav");
- self.noise = "plats/medplat1.wav";
- self.noise1 = "plats/medplat2.wav";
- }
-
-
- self.mangle = self.angles;
- self.angles = '0 0 0';
-
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
-
- self.blocked = plat_crush;
- if (!self.speed)
- self.speed = 150;
-
-// pos1 is the top position, pos2 is the bottom
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- if (self.height)
- self.pos2_z = self.origin_z - self.height;
- else
- self.pos2_z = self.origin_z - self.size_z + 8;
-
- self.use = plat_trigger_use;
-
- plat_spawn_inside_trigger (); // the "start moving" trigger
-
- if (self.targetname != "")
- {
- self.state = STATE_UP;
- self.use = plat_use;
- }
- else
- {
- setorigin (self, self.pos2);
- self.state = STATE_BOTTOM;
- }
-};
-
-//============================================================================
-// TRAINS
-//============================================================================
-void() train_next;
-void() func_train_find;
-
-float TRAIN_RETRIGGER = 1;
-float TRAIN_MOVEONTRIGGER = 2;
-float TRAIN_STOPONTRIGGER = 4;
-float TRAIN_NONSOLID = 8;
-float TRAIN_NOROTATE = 16;
-float TRAIN_ROTATEY = 32;
-float TRAIN_CUSTOMALIGN = 64;
-
-float TRAIN_NEXT_WAIT = 0; //normal movement
-float TRAIN_NEXT_STOP = 1; // force a stop on the next path_corner
-float TRAIN_NEXT_CONTINUE = 2; // force continue on the next path_corner (ignores wait time)
-
-float TRAIN_STYLE_SINGLEANIM = 1;
-
-float TRAIN_ANIMTYPE_FORWARD = 1;
-float TRAIN_ANIMTYPE_BACKFORTH = 2;
-
-void() train_blocked = {
- if (time < self.attack_finished) return;
-
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
-
-
-// Use function for when the train is stopped.
-// Makes the train continue on path_corners with wait -1,
-// or forces a continue if the "move on trigger" spawnflag is set.
-void() train_use = {
-
- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0) {
- train_next();
- return;
- }
-
- // Train has already moved after startup, and has no "stop on trigger" flag,
- // so ignore activation.
- if (self.think != func_train_find && self.cnt != TRAIN_NEXT_STOP)
- return;
-
- train_next();
-};
-
-// Use function for when the train is moving.
-// Forces a stop or an instant continue on the next path_corner depending on the spawnflag set
-void() train_moving_use = {
- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
- self.cnt = TRAIN_NEXT_CONTINUE;
- else if (self.spawnflags & TRAIN_STOPONTRIGGER)
- self.cnt = TRAIN_NEXT_STOP;
-}
-
-// path_corner has been reached, so decide what to do next
-void() train_wait = {
- float localtime;
- if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
- else localtime = time;
-
- self.use = train_use; //ready to be re-triggered
-
- // from Copper
- // Trains now fire their path_corners' targets on arrival.
- // If a player is riding the train, treat them as activator.
- activator = nextent(world);
- while (!EntitiesTouching(self,activator) && activator.classname == "player")
- activator = nextent(activator);
- if (activator.classname != "player")
- activator = nextent(world); // default to player1 wherever they are
- SUB_UseEntTargets(self.enemy);
-
- if (self.enemy.speed) self.speed2 = self.enemy.speed; // sets the speed from the current path_corner
-
- // copies the modeltrain animation parameters set in the path_corner, if any
- if (self.classname == "misc_modeltrain") {
- if (self.enemy.first_frame) self.first_frame = self.enemy.first_frame;
- if (self.enemy.last_frame) self.last_frame = self.enemy.last_frame;
- if (self.enemy.first_frame2) self.first_frame2 = self.enemy.first_frame2;
- if (self.enemy.last_frame2) self.last_frame2 = self.enemy.last_frame2;
- if (self.enemy.frtime) self.frtime = self.enemy.frtime;
- if (self.enemy.frtime2) self.frtime2 = self.enemy.frtime2;
- if (self.enemy.animtype) self.animtype = self.enemy.animtype;
- if (self.enemy.animtype2) self.animtype2 = self.enemy.animtype2;
- if (self.enemy.multiplier) self.multiplier = self.enemy.multiplier;
- }
-
- self.think = train_next;
-
- // train is moving normally and path_corner has a wait set, so pause for that time.
- if (self.wait > 0 && self.cnt == TRAIN_NEXT_WAIT && !(self.spawnflags & TRAIN_RETRIGGER)) {
- // state: stopped
- self.state = 0;
- if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- self.nextthink = localtime + self.wait;
-
- //play stopping sound. If path_corner has a custom sound, play that instead
- if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
- else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- // train is moving normally and path_corner has no wait time,
- // or has been forced to move instantly through a triggering.
- else if (self.cnt != TRAIN_NEXT_STOP && !self.wait && !(self.spawnflags & TRAIN_RETRIGGER)) {
-
- //play "passing by" sound, if any. If path_corner has a custom one, play that instead
- if (self.enemy.noise2 != "") sound(self, CHAN_WEAPON, self.enemy.noise2, 1, ATTN_NORM);
- else if (self.noise2 != "") sound(self, CHAN_WEAPON, self.noise2, 1, ATTN_NORM);
-
- self.nextthink = -1; // move instantly
- train_next();
- }
- // path_corner has wait -1, or train has been forced to stop through a triggering.
- // Also catches the backwards compatible case for the original rubicon2 "retrigger" flag.
- else {
- //play stopping sound. If path_corner has a custom sound, play that instead
- if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
- else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- // state: stopped
- self.state = 0;
-
- if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- self.nextthink = -1;
- }
-
-
-};
-
-// searches for the next path_corner and sends the train on its way
-void() train_next = {
- local entity targ;
- vector destang, displ;
-
- targ = find(world, targetname, self.target);
-
- if (!targ || self.target == "")
- objerror("train_next: no next target");
-
- self.target = targ.target;
-
- // gets the wait time from the upcoming path_corner if set
- if (targ.wait){
- // wait -2 on the path_corner forces it to continue moving (no wait),
- // even if the train has a default wait time
- if (targ.wait == -2) self.wait = 0;
- else self.wait = targ.wait;
- }
- // uses train's current wait time otherwise
- else
- self.wait = self.pausetime;
-
- self.enemy = targ;
-
- sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- if(!(!self.wait && self.cnt == TRAIN_NEXT_CONTINUE)) self.cnt = TRAIN_NEXT_WAIT;
-
- //store up any premature triggerings until current movement is finished
- self.use = train_moving_use;
-
- if (self.classname == "misc_modeltrain") {
- if (!(self.spawnflags & TRAIN_NOROTATE)) {
- destang = vectoangles(targ.origin - self.origin);
- if (self.spawnflags & TRAIN_ROTATEY) {
- destang_x = self.angles_x;
- destang_z = self.angles_z;
- }
- if (self.multiplier > 0) SUB_CalcAngleMoveController(destang, self.speed2*self.multiplier, SUB_Null, self.rotatecontroller);
- else self.angles = destang;
- }
- }
-
- if (!self.state) {
- self.state = 1;
- if (self.classname == "misc_modeltrain" && self.style != TRAIN_STYLE_SINGLEANIM)
- SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
- }
- // if the TRAIN_CUSTOMALIGN flag is checked then the train should align
- // with its path_corners based on the location of an "origin" brush added
- // to the train by the mapper instead of the mins corner
- // -therektafire
- float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
- else doDisplace = 1.0;
-
- if (self.classname != "misc_modeltrain") displ = self.mins;
-
- SUB_CalcMove(targ.origin - (displ * doDisplace), self.speed2, train_wait);
-};
-
-// searches for the first path_corner after the train entity is initialized
-void() func_train_find = {
- local entity targ;
- float localtime;
- vector displ;
-
- if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
- else localtime = time;
-
- targ = find(world, targetname, self.target);
- self.target = targ.target;
-
- float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
- else doDisplace = 1.0;
-
- if (self.classname != "misc_modeltrain") displ = self.mins;
- self.enemy = targ;
- setorigin(self, targ.origin - (displ * doDisplace));
- if (targ.speed) self.speed2 = targ.speed; // uses speed from the 1st path corner if set
-
- if (!self.targetname)
- { // not triggered, so start immediately
- self.nextthink = localtime + 0.1;
- self.think = train_next;
- }
-};
-
-/*QUAKED func_train (0 .5 .8) ? RETRIGGER
-Trains are moving platforms that players can ride.
-The targets origin specifies the min point of the train at each corner.
-The train spawns at the first target it is pointing at.
-If the train is the target of a button or trigger, it will not begin moving until activated.
-
-RETRIGGER: stop at each path_corner and don't resume until triggered again (ignores wait time)
-
-speed default 100
-dmg default 2
-sounds
-1) ratchet metal
-2) base
-
-*/
-void() func_train =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.speed)
- self.speed = 100;
- if (!self.target)
- objerror ("func_train without a target");
- if (!self.dmg)
- self.dmg = 2;
-
- if(self.spawnflags & TRAIN_STOPONTRIGGER && self.spawnflags & TRAIN_MOVEONTRIGGER)
- objerror("func_train: Stop and move on trigger set at the same time");
-
-
-
- if (self.sounds == 1) {
- if (self.noise == "") self.noise = ("plats/train2.wav");
- if (self.noise1 == "") self.noise1 = ("plats/train1.wav");
- }
- else if (self.sounds == 2) { // base door sound
- if (self.noise == "") self.noise = "doors/hydro2.wav";
- if (self.noise1 == "") self.noise1 = "doors/hydro1.wav";
- }
- else {
- if (self.noise == "") self.noise = ("misc/null.wav");
- if (self.noise1 == "") self.noise1 = ("misc/null.wav");
- }
-
- // backwards compatibility with previous version
- if (self.noise3 != "") self.noise = self.noise3;
- if (self.noise4 != "") self.noise1 = self.noise4;
-
- precache_sound(self.noise);
- precache_sound(self.noise1);
- if (self.noise2 != "") precache_sound(self.noise2);
-
-
- self.cnt = TRAIN_NEXT_WAIT;
-
- if (self.spawnflags & TRAIN_NONSOLID) {
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NOCLIP;
- }
- else {
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- }
-
- self.blocked = train_blocked;
- self.use = train_use;
- //self.classname = "train";
-
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
- setorigin (self, self.origin);
-
- // start trains on the second frame, to make sure their targets have had
- // a chance to spawn
-
- if (self.movetype == MOVETYPE_PUSH) self.nextthink = self.ltime + 0.1;
- else self.nextthink = time + 0.1;
-
- self.think = func_train_find;
-
- self.speed2 = self.speed;
-};
-
-
-//===================================================
-
-
-void() animcontroller_think = {
- entity tr;
- tr = self.owner;
-
- float first, last, step, atype, dir, nextframe;
-
- // train just went from stopped to moving or vice-versa,
- // and have both animations set
- if (self.state != tr.state && tr.style != TRAIN_STYLE_SINGLEANIM) {
- if (tr.state) { // just started moving
- tr.frame = zeroconvert(tr.first_frame2);
- }
- else { // just stopped
- tr.frame = zeroconvert(tr.first_frame);
- }
- tr.distance = 1; // reset back/forth status
- self.state = tr.state;
- }
-
- else {
- if (self.state && tr.style != TRAIN_STYLE_SINGLEANIM) { // moving train animation, if set
- first = zeroconvert(tr.first_frame2);
- last = zeroconvert(tr.last_frame2);
- atype = tr.animtype2;
- }
- else { // stopped/default train animation
- first = zeroconvert(tr.first_frame);
- last = zeroconvert(tr.last_frame);
- atype = tr.animtype;
- }
-
- if (first > last) step = dir = -1; // reverse direction
- else step = dir = 1;
-
- // back-and-forth is going the other way, so invert the step's signal
- if (tr.distance < 0) step = step * (-1);
-
- nextframe = tr.frame + step;
-
- if (atype == TRAIN_ANIMTYPE_BACKFORTH){
- if (dir > 0 && (nextframe > last || nextframe < first) ||
- dir < 0 && (nextframe > first || nextframe < last)
- ) {
- nextframe = tr.frame - step;
- tr.distance = tr.distance * (-1);
- }
- }
-
- if (dir > 0) nextframe = wrap(nextframe, first, last);
- else nextframe = wrap(nextframe, last, first);
-
- tr.frame = nextframe;
-
- }
-
- self.think = animcontroller_think;
- if (self.state || tr.style == TRAIN_STYLE_SINGLEANIM) self.nextthink = time + tr.frtime;
- else self.nextthink = time + tr.frtime2;
-};
-
-void() misc_modeltrain = {
-
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model(self.mdl);
-
- func_train();
-
- if (self.spawnflags & TRAIN_NONSOLID)
- self.solid = SOLID_NOT;
- else {
- self.solid = SOLID_BBOX;
- if (self.cmins == VEC_ORIGIN) self.cmins = '-8 -8 -8';
- if (self.cmaxs == VEC_ORIGIN) self.cmaxs = '8 8 8';
- }
-
- self.movetype = MOVETYPE_NOCLIP;
- setmodel (self, self.mdl);
- setsize (self, self.cmins , self.cmaxs);
- setorigin (self, self.origin);
-
- entity rot, anim;
-
- rot = spawn();
- self.rotatecontroller = rot;
- rot.classname = "rotatecontroller";
- rot.owner = self;
-
- anim = spawn();
- self.animcontroller = anim;
- anim.classname = "animcontroller";
- anim.owner = self;
-
- anim.think = animcontroller_think;
- anim.nextthink = time + 0.2;
-
- self.distance = 1;
-
- if (!self.frtime) self.frtime = 0.1;
- if (!self.frtime2) self.frtime2 = self.frtime;
- if (!self.multiplier) self.multiplier = 1;
-
-
- // make sure all first and last frame fields are filled
- if (self.first_frame && !self.last_frame) self.last_frame = self.first_frame;
- else if (!self.first_frame && self.last_frame) self.first_frame = self.last_frame;
-
- if (self.first_frame2 && !self.last_frame2) self.last_frame2 = self.first_frame2;
- else if (!self.first_frame2 && self.last_frame2) self.first_frame2 = self.last_frame2;
-
- if (!self.first_frame2) self.style = TRAIN_STYLE_SINGLEANIM;
-
- if (!self.animtype) self.animtype = TRAIN_ANIMTYPE_FORWARD;
- if (!self.animtype2) self.animtype2 = self.animtype;
-
- self.frame = self.first_frame;
-
-};
-
-
-//===================================================
-
-
-//Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
-void() teleporttrain_calcmove;
-void() teleporttrain_next =
-{
- local vector dir;
- setorigin(self, self.enemy.origin + '16 16 16');
-
- if (!self.target)
- {
- self.enemy = world;
- return;
- }
- self.enemy = find(world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- dir = normalize((self.enemy.origin + '16 16 16') - self.origin);
- self.velocity = dir * self.speed;
- self.target = self.enemy.target;
- }
- else
- {
- objerror("unable to find target\n");
- remove(self);
- }
- teleporttrain_calcmove();
-};
-void() teleporttrain_wait =
-{
- local float wait_time;
- if (self.enemy.wait > 0)
- wait_time = self.enemy.wait;
- else
- wait_time = .1;
- self.velocity = '0 0 0';
- self.nextthink = time + wait_time;
- self.think = teleporttrain_next;
-
-}
-void() teleporttrain_calcmove =
-{
- local float len;
- local vector delta;
- local float spd;
-
- delta = (self.enemy.origin + '16 16 16') - self.origin;
- len = vlen(delta);
- spd = vlen(self.velocity);
- self.nextthink = time + (len / spd);
- self.think = teleporttrain_wait;
-};
-void() teleporttrain_use =
-{
- if (self.velocity == '0 0 0')
- {
- teleporttrain_next();
- }
-};
-void() teleporttrain_find =
-{
- // always start positioned on the first path_corner
- self.enemy = find(world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- setorigin (self, self.enemy.origin + '16 16 16');
- self.target = self.enemy.target;
- }
- else
- {
- objerror("unable to find target\n");
- remove(self);
- return;
- }
-
- if (self.spawnflags & 4) // start immediately even with a targetname
- {
- teleporttrain_next();
- }
- // not triggered, so start immediately
- else if (!self.targetname)
- {
- teleporttrain_next();
- }
- else
- {
- self.use = teleporttrain_use;
- }
-};
-/*QUAKED misc_teleporttrain (.5 .5 .5) (-16 -16 -16) (16 16 16) X DONT_ROTATE START_ON_WITH_TARGETNAME INVISIBLE X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{ model("progs/teleport.mdl"); }
-This was used for the final boss level in the original game. In progs_dump you can use this as a moving decoration or even target it as a spawn point for a func_monster_spawner. Make sure and select the Don't Rotate spawnflag though or you'll experience a pretty hilarious effect!
-
-You set this up like a func_train using path_corners. By default, it will move automatically between path corners upon map load. However, you can have it wait to move by giving it a targetname. If you need to target it as a spawner and want it to move on map load, use the Start On spawnflag.
-
-You can add effects, use a custom model using the mdl_body keyvalue and even make it invisible with spawnflag 8.
-
-Effects
-0: "None (Default)"
-1 : "Brightfield (yellow particles)"
-4 : "Bright light"
-8 : "Dim light"
-
-
-Teleporter target for final boss level. Must target a series of 'path_corner' entities.
-It will position itself on its first target at map load.
-If a targetname is set, it must be triggered to start moving, otherwise it will start automatically.
-*/
-void() misc_teleporttrain =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.target)
- {
- objerror ("misc_teleporttrain has no target");
- remove(self);
- return;
- }
- if (self.speed <= 0)
- {
- self.speed = 100;
- }
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_FLY;
- precache_body_model ("progs/teleport.mdl"); // custom custom_mdls -- dumptruck_ds
- precache_model ("progs/s_null.spr"); // invisble -- dumptruck_ds
- if (self.spawnflags & 8)
- // setmodel (self, "progs/s_null.spr");
- body_model ("progs/s_null.spr");
- else
- body_model ("progs/teleport.mdl");
- // precache_model ("progs/teleport.mdl");
- setsize (self, '-16 -16 -16', '16 16 16');
-
- //Causes the ball to spin around like it was originally intended to.
- if (!(self.spawnflags & 2)) //don't spin - helpful for invisible spawner -- dumptruck_ds
- self.avelocity = '40 80 120';
- // self.avelocity = '100 200 300';
-
- self.think = teleporttrain_find;
- self.nextthink = time + 0.1;
-};
+
+
+void() plat_center_touch;
+void() plat_outside_touch;
+void() plat_trigger_use;
+void() plat_go_up;
+void() plat_go_down;
+void() plat_crush;
+float PLAT_LOW_TRIGGER = 1;
+
+void() plat_spawn_inside_trigger =
+{
+ local entity trigger;
+ local vector tmin, tmax;
+
+//
+// middle trigger
+//
+ trigger = spawn();
+ trigger.touch = plat_center_touch;
+ trigger.movetype = MOVETYPE_NONE;
+ trigger.solid = SOLID_TRIGGER;
+ trigger.enemy = self;
+
+ tmin = self.mins + '25 25 0';
+ tmax = self.maxs - '25 25 -8';
+ tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
+ if (self.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;
+
+ if (self.size_x <= 50)
+ {
+ tmin_x = (self.mins_x + self.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+ if (self.size_y <= 50)
+ {
+ tmin_y = (self.mins_y + self.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }
+
+ setsize (trigger, tmin, tmax);
+};
+
+void() plat_hit_top =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_TOP;
+ self.think = plat_go_down;
+ self.nextthink = self.ltime + 3;
+};
+
+void() plat_hit_bottom =
+{
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ self.state = STATE_BOTTOM;
+};
+
+void() plat_go_down =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_DOWN;
+ SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
+};
+
+void() plat_go_up =
+{
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ self.state = STATE_UP;
+ SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
+};
+
+void() plat_center_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ self = self.enemy;
+ if (self.state == STATE_BOTTOM)
+ plat_go_up ();
+ else if (self.state == STATE_TOP)
+ self.nextthink = self.ltime + 1; // delay going down
+};
+
+void() plat_outside_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+//dprint ("plat_outside_touch\n");
+ self = self.enemy;
+ if (self.state == STATE_TOP)
+ plat_go_down ();
+};
+
+void() plat_trigger_use =
+{
+ if (self.think)
+ return; // allready activated
+ plat_go_down();
+};
+
+
+void() plat_crush =
+{
+//dprint ("plat_crush\n");
+
+ T_Damage (other, self, self, 1);
+
+ if (self.state == STATE_UP)
+ plat_go_down ();
+ else if (self.state == STATE_DOWN)
+ plat_go_up ();
+ else
+ objerror ("plat_crush: bad self.state\n");
+};
+
+void() plat_use =
+{
+ self.use = SUB_Null;
+ if (self.state != STATE_UP)
+ objerror ("plat_use: not in up state");
+ plat_go_down();
+};
+
+
+/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+speed default 150
+
+Plats are always drawn in the extended position, so they will light correctly.
+
+If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
+
+If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
+Set "sounds" to one of the following:
+1) base fast
+2) chain slow
+*/
+
+
+void() func_plat =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.t_length)
+ self.t_length = 80;
+ if (!self.t_width)
+ self.t_width = 10;
+
+ if (self.sounds == 0)
+ self.sounds = 2;
+// FIX THIS TO LOAD A GENERIC PLAT SOUND
+
+ if (self.sounds == 1)
+ {
+ precache_sound ("plats/plat1.wav");
+ precache_sound ("plats/plat2.wav");
+ self.noise = "plats/plat1.wav";
+ self.noise1 = "plats/plat2.wav";
+ }
+
+ if (self.sounds == 2)
+ {
+ precache_sound ("plats/medplat1.wav");
+ precache_sound ("plats/medplat2.wav");
+ self.noise = "plats/medplat1.wav";
+ self.noise1 = "plats/medplat2.wav";
+ }
+
+
+ self.mangle = self.angles;
+ self.angles = '0 0 0';
+
+ self.classname = "plat";
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setorigin (self, self.origin);
+ setmodel (self, self.model);
+ setsize (self, self.mins , self.maxs);
+
+ self.blocked = plat_crush;
+ if (!self.speed)
+ self.speed = 150;
+
+// pos1 is the top position, pos2 is the bottom
+ self.pos1 = self.origin;
+ self.pos2 = self.origin;
+ if (self.height)
+ self.pos2_z = self.origin_z - self.height;
+ else
+ self.pos2_z = self.origin_z - self.size_z + 8;
+
+ self.use = plat_trigger_use;
+
+ plat_spawn_inside_trigger (); // the "start moving" trigger
+
+ if (self.targetname != "")
+ {
+ self.state = STATE_UP;
+ self.use = plat_use;
+ }
+ else
+ {
+ setorigin (self, self.pos2);
+ self.state = STATE_BOTTOM;
+ }
+};
+
+//============================================================================
+// TRAINS
+//============================================================================
+void() train_next;
+void() func_train_find;
+
+float TRAIN_RETRIGGER = 1;
+float TRAIN_MOVEONTRIGGER = 2;
+float TRAIN_STOPONTRIGGER = 4;
+float TRAIN_NONSOLID = 8;
+float TRAIN_NOROTATE = 16;
+float TRAIN_ROTATEY = 32;
+float TRAIN_CUSTOMALIGN = 64;
+
+float TRAIN_NEXT_WAIT = 0; //normal movement
+float TRAIN_NEXT_STOP = 1; // force a stop on the next path_corner
+float TRAIN_NEXT_CONTINUE = 2; // force continue on the next path_corner (ignores wait time)
+
+float TRAIN_STYLE_SINGLEANIM = 1;
+
+float TRAIN_ANIMTYPE_FORWARD = 1;
+float TRAIN_ANIMTYPE_BACKFORTH = 2;
+
+void() train_blocked = {
+ if (time < self.attack_finished) return;
+
+ self.attack_finished = time + 0.5;
+ T_Damage (other, self, self, self.dmg);
+};
+
+
+// Use function for when the train is stopped.
+// Makes the train continue on path_corners with wait -1,
+// or forces a continue if the "move on trigger" spawnflag is set.
+void() train_use = {
+
+ if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0) {
+ train_next();
+ return;
+ }
+
+ // Train has already moved after startup, and has no "stop on trigger" flag,
+ // so ignore activation.
+ if (self.think != func_train_find && self.cnt != TRAIN_NEXT_STOP)
+ return;
+
+ train_next();
+};
+
+// Use function for when the train is moving.
+// Forces a stop or an instant continue on the next path_corner depending on the spawnflag set
+void() train_moving_use = {
+ if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
+ self.cnt = TRAIN_NEXT_CONTINUE;
+ else if (self.spawnflags & TRAIN_STOPONTRIGGER)
+ self.cnt = TRAIN_NEXT_STOP;
+}
+
+// path_corner has been reached, so decide what to do next
+void() train_wait = {
+ float localtime;
+ if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
+ else localtime = time;
+
+ self.use = train_use; //ready to be re-triggered
+
+ // from Copper
+ // Trains now fire their path_corners' targets on arrival.
+ // If a player is riding the train, treat them as activator.
+ activator = nextent(world);
+ while (!EntitiesTouching(self,activator) && activator.classname == "player")
+ activator = nextent(activator);
+ if (activator.classname != "player")
+ activator = nextent(world); // default to player1 wherever they are
+ SUB_UseEntTargets(self.enemy);
+
+ if (self.enemy.speed) self.speed2 = self.enemy.speed; // sets the speed from the current path_corner
+
+ // copies the modeltrain animation parameters set in the path_corner, if any
+ if (self.classname == "misc_modeltrain") {
+ if (self.enemy.first_frame) self.first_frame = self.enemy.first_frame;
+ if (self.enemy.last_frame) self.last_frame = self.enemy.last_frame;
+ if (self.enemy.first_frame2) self.first_frame2 = self.enemy.first_frame2;
+ if (self.enemy.last_frame2) self.last_frame2 = self.enemy.last_frame2;
+ if (self.enemy.frtime) self.frtime = self.enemy.frtime;
+ if (self.enemy.frtime2) self.frtime2 = self.enemy.frtime2;
+ if (self.enemy.animtype) self.animtype = self.enemy.animtype;
+ if (self.enemy.animtype2) self.animtype2 = self.enemy.animtype2;
+ if (self.enemy.multiplier) self.multiplier = self.enemy.multiplier;
+ }
+
+ self.think = train_next;
+
+ // train is moving normally and path_corner has a wait set, so pause for that time.
+ if (self.wait > 0 && self.cnt == TRAIN_NEXT_WAIT && !(self.spawnflags & TRAIN_RETRIGGER)) {
+ // state: stopped
+ self.state = 0;
+ if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ self.nextthink = localtime + self.wait;
+
+ //play stopping sound. If path_corner has a custom sound, play that instead
+ if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
+ else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ }
+ // train is moving normally and path_corner has no wait time,
+ // or has been forced to move instantly through a triggering.
+ else if (self.cnt != TRAIN_NEXT_STOP && !self.wait && !(self.spawnflags & TRAIN_RETRIGGER)) {
+
+ //play "passing by" sound, if any. If path_corner has a custom one, play that instead
+ if (self.enemy.noise2 != "") sound(self, CHAN_WEAPON, self.enemy.noise2, 1, ATTN_NORM);
+ else if (self.noise2 != "") sound(self, CHAN_WEAPON, self.noise2, 1, ATTN_NORM);
+
+ self.nextthink = -1; // move instantly
+ train_next();
+ }
+ // path_corner has wait -1, or train has been forced to stop through a triggering.
+ // Also catches the backwards compatible case for the original rubicon2 "retrigger" flag.
+ else {
+ //play stopping sound. If path_corner has a custom sound, play that instead
+ if (self.enemy.noise != "") sound(self, CHAN_WEAPON, self.enemy.noise, 1, ATTN_NORM);
+ else sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ // state: stopped
+ self.state = 0;
+
+ if (self.classname == "misc_modeltrain") SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ self.nextthink = -1;
+ }
+
+
+};
+
+// searches for the next path_corner and sends the train on its way
+void() train_next = {
+ local entity targ;
+ vector destang, displ;
+
+ targ = find(world, targetname, self.target);
+
+ if (!targ || self.target == "")
+ objerror("train_next: no next target");
+
+ self.target = targ.target;
+
+ // gets the wait time from the upcoming path_corner if set
+ if (targ.wait){
+ // wait -2 on the path_corner forces it to continue moving (no wait),
+ // even if the train has a default wait time
+ if (targ.wait == -2) self.wait = 0;
+ else self.wait = targ.wait;
+ }
+ // uses train's current wait time otherwise
+ else
+ self.wait = self.pausetime;
+
+ self.enemy = targ;
+
+ sound(self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ if(!(!self.wait && self.cnt == TRAIN_NEXT_CONTINUE)) self.cnt = TRAIN_NEXT_WAIT;
+
+ //store up any premature triggerings until current movement is finished
+ self.use = train_moving_use;
+
+ if (self.classname == "misc_modeltrain") {
+ if (!(self.spawnflags & TRAIN_NOROTATE)) {
+ destang = vectoangles(targ.origin - self.origin);
+ if (self.spawnflags & TRAIN_ROTATEY) {
+ destang_x = self.angles_x;
+ destang_z = self.angles_z;
+ }
+ if (self.multiplier > 0) SUB_CalcAngleMoveController(destang, self.speed2*self.multiplier, SUB_Null, self.rotatecontroller);
+ else self.angles = destang;
+ }
+ }
+
+ if (!self.state) {
+ self.state = 1;
+ if (self.classname == "misc_modeltrain" && self.style != TRAIN_STYLE_SINGLEANIM)
+ SUB_CallAsSelf(self.animcontroller.think, self.animcontroller);
+ }
+ // if the TRAIN_CUSTOMALIGN flag is checked then the train should align
+ // with its path_corners based on the location of an "origin" brush added
+ // to the train by the mapper instead of the mins corner
+ // -therektafire
+ float doDisplace;
+ if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
+ else doDisplace = 1.0;
+
+ if (self.classname != "misc_modeltrain") displ = self.mins;
+
+ SUB_CalcMove(targ.origin - (displ * doDisplace), self.speed2, train_wait);
+};
+
+// searches for the first path_corner after the train entity is initialized
+void() func_train_find = {
+ local entity targ;
+ float localtime;
+ vector displ;
+
+ if (self.movetype == MOVETYPE_PUSH) localtime = self.ltime;
+ else localtime = time;
+
+ targ = find(world, targetname, self.target);
+ self.target = targ.target;
+
+ float doDisplace;
+ if (self.spawnflags & TRAIN_CUSTOMALIGN) doDisplace = 0.0;
+ else doDisplace = 1.0;
+
+ if (self.classname != "misc_modeltrain") displ = self.mins;
+ self.enemy = targ;
+ setorigin(self, targ.origin - (displ * doDisplace));
+ if (targ.speed) self.speed2 = targ.speed; // uses speed from the 1st path corner if set
+
+ if (!self.targetname)
+ { // not triggered, so start immediately
+ self.nextthink = localtime + 0.1;
+ self.think = train_next;
+ }
+};
+
+/*QUAKED func_train (0 .5 .8) ? RETRIGGER
+Trains are moving platforms that players can ride.
+The targets origin specifies the min point of the train at each corner.
+The train spawns at the first target it is pointing at.
+If the train is the target of a button or trigger, it will not begin moving until activated.
+
+RETRIGGER: stop at each path_corner and don't resume until triggered again (ignores wait time)
+
+speed default 100
+dmg default 2
+sounds
+1) ratchet metal
+2) base
+
+*/
+void() func_train =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.speed)
+ self.speed = 100;
+ if (!self.target)
+ objerror ("func_train without a target");
+ if (!self.dmg)
+ self.dmg = 2;
+
+ if(self.spawnflags & TRAIN_STOPONTRIGGER && self.spawnflags & TRAIN_MOVEONTRIGGER)
+ objerror("func_train: Stop and move on trigger set at the same time");
+
+
+
+ if (self.sounds == 1) {
+ if (self.noise == "") self.noise = ("plats/train2.wav");
+ if (self.noise1 == "") self.noise1 = ("plats/train1.wav");
+ }
+ else if (self.sounds == 2) { // base door sound
+ if (self.noise == "") self.noise = "doors/hydro2.wav";
+ if (self.noise1 == "") self.noise1 = "doors/hydro1.wav";
+ }
+ else {
+ if (self.noise == "") self.noise = ("misc/null.wav");
+ if (self.noise1 == "") self.noise1 = ("misc/null.wav");
+ }
+
+ // backwards compatibility with previous version
+ if (self.noise3 != "") self.noise = self.noise3;
+ if (self.noise4 != "") self.noise1 = self.noise4;
+
+ precache_sound(self.noise);
+ precache_sound(self.noise1);
+ if (self.noise2 != "") precache_sound(self.noise2);
+
+
+ self.cnt = TRAIN_NEXT_WAIT;
+
+ if (self.spawnflags & TRAIN_NONSOLID) {
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NOCLIP;
+ }
+ else {
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ }
+
+ self.blocked = train_blocked;
+ self.use = train_use;
+ //self.classname = "train";
+
+ setmodel (self, self.model);
+ setsize (self, self.mins , self.maxs);
+ setorigin (self, self.origin);
+
+ // start trains on the second frame, to make sure their targets have had
+ // a chance to spawn
+
+ if (self.movetype == MOVETYPE_PUSH) self.nextthink = self.ltime + 0.1;
+ else self.nextthink = time + 0.1;
+
+ self.think = func_train_find;
+
+ self.speed2 = self.speed;
+};
+
+
+//===================================================
+
+
+void() animcontroller_think = {
+ entity tr;
+ tr = self.owner;
+
+ float first, last, step, atype, dir, nextframe;
+
+ // train just went from stopped to moving or vice-versa,
+ // and have both animations set
+ if (self.state != tr.state && tr.style != TRAIN_STYLE_SINGLEANIM) {
+ if (tr.state) { // just started moving
+ tr.frame = zeroconvert(tr.first_frame2);
+ }
+ else { // just stopped
+ tr.frame = zeroconvert(tr.first_frame);
+ }
+ tr.distance = 1; // reset back/forth status
+ self.state = tr.state;
+ }
+
+ else {
+ if (self.state && tr.style != TRAIN_STYLE_SINGLEANIM) { // moving train animation, if set
+ first = zeroconvert(tr.first_frame2);
+ last = zeroconvert(tr.last_frame2);
+ atype = tr.animtype2;
+ }
+ else { // stopped/default train animation
+ first = zeroconvert(tr.first_frame);
+ last = zeroconvert(tr.last_frame);
+ atype = tr.animtype;
+ }
+
+ if (first > last) step = dir = -1; // reverse direction
+ else step = dir = 1;
+
+ // back-and-forth is going the other way, so invert the step's signal
+ if (tr.distance < 0) step = step * (-1);
+
+ nextframe = tr.frame + step;
+
+ if (atype == TRAIN_ANIMTYPE_BACKFORTH){
+ if (dir > 0 && (nextframe > last || nextframe < first) ||
+ dir < 0 && (nextframe > first || nextframe < last)
+ ) {
+ nextframe = tr.frame - step;
+ tr.distance = tr.distance * (-1);
+ }
+ }
+
+ if (dir > 0) nextframe = wrap(nextframe, first, last);
+ else nextframe = wrap(nextframe, last, first);
+
+ tr.frame = nextframe;
+
+ }
+
+ self.think = animcontroller_think;
+ if (self.state || tr.style == TRAIN_STYLE_SINGLEANIM) self.nextthink = time + tr.frtime;
+ else self.nextthink = time + tr.frtime2;
+};
+
+void() misc_modeltrain = {
+
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model(self.mdl);
+
+ func_train();
+
+ if (self.spawnflags & TRAIN_NONSOLID)
+ self.solid = SOLID_NOT;
+ else {
+ self.solid = SOLID_BBOX;
+ if (self.cmins == VEC_ORIGIN) self.cmins = '-8 -8 -8';
+ if (self.cmaxs == VEC_ORIGIN) self.cmaxs = '8 8 8';
+ }
+
+ self.movetype = MOVETYPE_NOCLIP;
+ setmodel (self, self.mdl);
+ setsize (self, self.cmins , self.cmaxs);
+ setorigin (self, self.origin);
+
+ entity rot, anim;
+
+ rot = spawn();
+ self.rotatecontroller = rot;
+ rot.classname = "rotatecontroller";
+ rot.owner = self;
+
+ anim = spawn();
+ self.animcontroller = anim;
+ anim.classname = "animcontroller";
+ anim.owner = self;
+
+ anim.think = animcontroller_think;
+ anim.nextthink = time + 0.2;
+
+ self.distance = 1;
+
+ if (!self.frtime) self.frtime = 0.1;
+ if (!self.frtime2) self.frtime2 = self.frtime;
+ if (!self.multiplier) self.multiplier = 1;
+
+
+ // make sure all first and last frame fields are filled
+ if (self.first_frame && !self.last_frame) self.last_frame = self.first_frame;
+ else if (!self.first_frame && self.last_frame) self.first_frame = self.last_frame;
+
+ if (self.first_frame2 && !self.last_frame2) self.last_frame2 = self.first_frame2;
+ else if (!self.first_frame2 && self.last_frame2) self.first_frame2 = self.last_frame2;
+
+ if (!self.first_frame2) self.style = TRAIN_STYLE_SINGLEANIM;
+
+ if (!self.animtype) self.animtype = TRAIN_ANIMTYPE_FORWARD;
+ if (!self.animtype2) self.animtype2 = self.animtype;
+
+ self.frame = self.first_frame;
+
+};
+
+
+//===================================================
+
+
+//Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
+void() teleporttrain_calcmove;
+void() teleporttrain_next =
+{
+ local vector dir;
+ setorigin(self, self.enemy.origin + '16 16 16');
+
+ if (!self.target)
+ {
+ self.enemy = world;
+ return;
+ }
+ self.enemy = find(world, targetname, self.target);
+ if (self.enemy.classname == "path_corner")
+ {
+ dir = normalize((self.enemy.origin + '16 16 16') - self.origin);
+ self.velocity = dir * self.speed;
+ self.target = self.enemy.target;
+ }
+ else
+ {
+ objerror("unable to find target\n");
+ remove(self);
+ }
+ teleporttrain_calcmove();
+};
+void() teleporttrain_wait =
+{
+ local float wait_time;
+ if (self.enemy.wait > 0)
+ wait_time = self.enemy.wait;
+ else
+ wait_time = .1;
+ self.velocity = '0 0 0';
+ self.nextthink = time + wait_time;
+ self.think = teleporttrain_next;
+
+}
+void() teleporttrain_calcmove =
+{
+ local float len;
+ local vector delta;
+ local float spd;
+
+ delta = (self.enemy.origin + '16 16 16') - self.origin;
+ len = vlen(delta);
+ spd = vlen(self.velocity);
+ self.nextthink = time + (len / spd);
+ self.think = teleporttrain_wait;
+};
+void() teleporttrain_use =
+{
+ if (self.velocity == '0 0 0')
+ {
+ teleporttrain_next();
+ }
+};
+void() teleporttrain_find =
+{
+ // always start positioned on the first path_corner
+ self.enemy = find(world, targetname, self.target);
+ if (self.enemy.classname == "path_corner")
+ {
+ setorigin (self, self.enemy.origin + '16 16 16');
+ self.target = self.enemy.target;
+ }
+ else
+ {
+ objerror("unable to find target\n");
+ remove(self);
+ return;
+ }
+
+ if (self.spawnflags & 4) // start immediately even with a targetname
+ {
+ teleporttrain_next();
+ }
+ // not triggered, so start immediately
+ else if (!self.targetname)
+ {
+ teleporttrain_next();
+ }
+ else
+ {
+ self.use = teleporttrain_use;
+ }
+};
+/*QUAKED misc_teleporttrain (.5 .5 .5) (-16 -16 -16) (16 16 16) X DONT_ROTATE START_ON_WITH_TARGETNAME INVISIBLE X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{ model("progs/teleport.mdl"); }
+This was used for the final boss level in the original game. In progs_dump you can use this as a moving decoration or even target it as a spawn point for a func_monster_spawner. Make sure and select the Don't Rotate spawnflag though or you'll experience a pretty hilarious effect!
+
+You set this up like a func_train using path_corners. By default, it will move automatically between path corners upon map load. However, you can have it wait to move by giving it a targetname. If you need to target it as a spawner and want it to move on map load, use the Start On spawnflag.
+
+You can add effects, use a custom model using the mdl_body keyvalue and even make it invisible with spawnflag 8.
+
+Effects
+0: "None (Default)"
+1 : "Brightfield (yellow particles)"
+4 : "Bright light"
+8 : "Dim light"
+
+
+Teleporter target for final boss level. Must target a series of 'path_corner' entities.
+It will position itself on its first target at map load.
+If a targetname is set, it must be triggered to start moving, otherwise it will start automatically.
+*/
+void() misc_teleporttrain =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.target)
+ {
+ objerror ("misc_teleporttrain has no target");
+ remove(self);
+ return;
+ }
+ if (self.speed <= 0)
+ {
+ self.speed = 100;
+ }
+
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_FLY;
+ precache_body_model ("progs/teleport.mdl"); // custom custom_mdls -- dumptruck_ds
+ precache_model ("progs/s_null.spr"); // invisble -- dumptruck_ds
+ if (self.spawnflags & 8)
+ // setmodel (self, "progs/s_null.spr");
+ body_model ("progs/s_null.spr");
+ else
+ body_model ("progs/teleport.mdl");
+ // precache_model ("progs/teleport.mdl");
+ setsize (self, '-16 -16 -16', '16 16 16');
+
+ //Causes the ball to spin around like it was originally intended to.
+ if (!(self.spawnflags & 2)) //don't spin - helpful for invisible spawner -- dumptruck_ds
+ self.avelocity = '40 80 120';
+ // self.avelocity = '100 200 300';
+
+ self.think = teleporttrain_find;
+ self.nextthink = time + 0.1;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/player.qc

diff --git a/qc/player.qc b/qc/player.qc
index ec61c1c..6d7e89a 100644
--- a/qc/player.qc
+++ b/qc/player.qc
@@ -1,762 +1,762 @@
-
-void() bubble_bob;
-
-/*
-==============================================================================
-
-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
-
-$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
-$frame deatha9 deatha10 deatha11
-
-$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
-$frame deathb9
-
-$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
-$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
-
-$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
-$frame deathd8 deathd9
-
-$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
-$frame deathe8 deathe9
-
-//
-// attacks
-//
-$frame nailatt1 nailatt2
-
-$frame light1 light2
-
-$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
-
-$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
-
-$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
-
-$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
-
-$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
-
-$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
-
-
-/*
-==============================================================================
-PLAYER
-==============================================================================
-*/
-
-void() player_run;
-
-void() player_stand1 =[ $axstnd1, player_stand1 ]
-{
- self.weaponframe=0;
- if (self.velocity_x || self.velocity_y)
- {
- self.walkframe=0;
- player_run();
- return;
- }
-
- if (self.weapon == IT_AXE)
- {
- if (self.walkframe >= 12)
- self.walkframe = 0;
- self.frame = $axstnd1 + self.walkframe;
- }
- else
- {
- if (self.walkframe >= 5)
- self.walkframe = 0;
- self.frame = $stand1 + self.walkframe;
- }
- self.walkframe = self.walkframe + 1;
-};
-
-void() player_run =[ $rockrun1, player_run ]
-{
- self.weaponframe=0;
- if (!self.velocity_x && !self.velocity_y)
- {
- self.walkframe=0;
- player_stand1();
- return;
- }
-
- if (self.weapon == IT_AXE)
- {
- if (self.walkframe == 6)
- self.walkframe = 0;
- self.frame = $axrun1 + self.walkframe;
- }
- else
- {
- if (self.walkframe == 6)
- self.walkframe = 0;
- self.frame = self.frame + self.walkframe;
- }
- self.walkframe = self.walkframe + 1;
-};
-
-
-void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;};
-void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;};
-void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;};
-void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;};
-void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;};
-
-void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;};
-void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;};
-void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();};
-void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;};
-
-void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;};
-void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;};
-void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();};
-void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;};
-
-void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;};
-void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;};
-void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();};
-void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;};
-
-void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;};
-void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;};
-void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
-void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
-
-
-//============================================================================
-
-void() player_nail1 =[$nailatt1, player_nail2 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 9)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireSpikes (4);
- self.attack_finished = time + 0.2;
-};
-void() player_nail2 =[$nailatt2, player_nail1 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 9)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireSpikes (-4);
- self.attack_finished = time + 0.2;
-};
-
-//============================================================================
-
-void() player_light1 =[$light1, player_light2 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 5)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireLightning();
- self.attack_finished = time + 0.2;
-};
-void() player_light2 =[$light2, player_light1 ]
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (!self.button0)
- {player_run ();return;}
- self.weaponframe = self.weaponframe + 1;
- if (self.weaponframe == 5)
- self.weaponframe = 1;
- SuperDamageSound();
- W_FireLightning();
- self.attack_finished = time + 0.2;
-};
-
-//============================================================================
-
-
-void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
-self.effects = self.effects | EF_MUZZLEFLASH;};
-void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;};
-void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;};
-void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;};
-void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;};
-void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;};
-void(float num_bubbles) DeathBubbles;
-
-void() PainSound =
-{
-local float rs;
-
- if (self.health < 0)
- return;
-
- if (damage_attacker.classname == "teledeath")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
-// water pain sounds
- if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
- {
- DeathBubbles(1);
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM);
- return;
- }
-
-// slime pain sounds
- if (self.watertype == CONTENT_SLIME)
- {
-// FIX ME put in some steam here
-// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes start
- if (self.waterlevel == 3)
- DeathBubbles(1);
-// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes end
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
- return;
- }
-
- if (self.watertype == CONTENT_LAVA)
- {
- if (random() > 0.5)
- sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
- return;
- }
-
- if (self.pain_finished > time)
- {
- self.axhitme = 0;
- return;
- }
- self.pain_finished = time + 0.5;
-
-// don't make multiple pain sounds right after each other
-
-// ax pain sound
- if (self.axhitme == 1)
- {
- self.axhitme = 0;
- sound (self, CHAN_VOICE, "player/axhit1.wav", 1, ATTN_NORM);
- return;
- }
-
-
- rs = rint((random() * 5) + 1);
-
- self.noise = "";
- if (rs == 1)
- self.noise = "player/pain1.wav";
- else if (rs == 2)
- self.noise = "player/pain2.wav";
- else if (rs == 3)
- self.noise = "player/pain3.wav";
- else if (rs == 4)
- self.noise = "player/pain4.wav";
- else if (rs == 5)
- self.noise = "player/pain5.wav";
- else
- self.noise = "player/pain6.wav";
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- return;
-};
-
-void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;};
-void() player_pain2 = [ $pain2, player_pain3 ] {};
-void() player_pain3 = [ $pain3, player_pain4 ] {};
-void() player_pain4 = [ $pain4, player_pain5 ] {};
-void() player_pain5 = [ $pain5, player_pain6 ] {};
-void() player_pain6 = [ $pain6, player_run ] {};
-
-void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;};
-void() player_axpain2 = [ $axpain2, player_axpain3 ] {};
-void() player_axpain3 = [ $axpain3, player_axpain4 ] {};
-void() player_axpain4 = [ $axpain4, player_axpain5 ] {};
-void() player_axpain5 = [ $axpain5, player_axpain6 ] {};
-void() player_axpain6 = [ $axpain6, player_run ] {};
-
-void(entity attacker, float damage) player_pain =
-{
- if (self.weaponframe)
- return;
-
- if (self.invisible_finished > time)
- return; // eyes don't have pain frames
-
- if (self.weapon == IT_AXE)
- player_axpain1 ();
- else
- player_pain1 ();
-};
-
-void() player_diea1;
-void() player_dieb1;
-void() player_diec1;
-void() player_died1;
-void() player_diee1;
-void() player_die_ax1;
-
-void() DeathBubblesSpawn =
-{
-local entity bubble;
- if ((self.owner.waterlevel != 3) && (self.owner.health > 0)) // 1998-08-14 Improved bubble spawn by Maddes
-// 1998-08-14 Bubblespawner remove fix by Perged start
-{
- remove(self); // remove bubble spawner
-// 1998-08-14 Bubblespawner remove fix by Perged end
- return;
-} // 1998-08-14 Bubblespawner remove fix by Perged return;
- bubble = spawn();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.owner.origin + '0 0 24');
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = '0 0 15';
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.classname = "bubble";
- bubble.frame = 0;
- bubble.cnt = 0;
- setsize (bubble, '-8 -8 -8', '8 8 8');
-// 1998-08-14 Improved bubble spawn by Maddes start
-// self.nextthink = time + 0.1;
- self.nextthink = time + 0.01;
-// 1998-08-14 Improved bubble spawn by Maddes end
- self.think = DeathBubblesSpawn;
- self.air_finished = self.air_finished + 1;
- if (self.air_finished >= self.bubble_count)
- remove(self);
-};
-
-void(float num_bubbles) DeathBubbles =
-{
-local entity bubble_spawner;
-
- bubble_spawner = spawn();
- setorigin (bubble_spawner, self.origin);
- bubble_spawner.movetype = MOVETYPE_NONE;
- bubble_spawner.solid = SOLID_NOT;
-// 1998-08-14 Improved bubble spawn by Maddes start
-// bubble_spawner.nextthink = time + 0.1;
- bubble_spawner.nextthink = time + 0.01;
-// 1998-08-14 Improved bubble spawn by Maddes end
- bubble_spawner.think = DeathBubblesSpawn;
- bubble_spawner.air_finished = 0;
- bubble_spawner.owner = self;
- bubble_spawner.bubble_count = num_bubbles;
-// return; // 1998-08-14 unnecessary by Maddes
-};
-
-
-void() DeathSound =
-{
-local float rs;
-
- // water death sounds
- if (self.waterlevel == 3)
- {
- DeathBubbles(20);
- sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
- return;
- }
-
- rs = rint ((random() * 4) + 1);
- if (rs == 1)
- self.noise = "player/death1.wav";
- if (rs == 2)
- self.noise = "player/death2.wav";
- if (rs == 3)
- self.noise = "player/death3.wav";
- if (rs == 4)
- self.noise = "player/death4.wav";
- if (rs == 5)
- self.noise = "player/death5.wav";
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
- return;
-};
-
-
-void() PlayerDead =
-{
- self.nextthink = -1;
-// allow respawn after a certain time
- self.deadflag = DEAD_DEAD;
-};
-
-vector(float dm) VelocityForDamage =
-{
- local vector v;
-
- v_x = 100 * crandom();
- v_y = 100 * crandom();
- v_z = 200 + 100 * random();
-
- if (dm > -50)
- {
-// dprint ("level 1\n");
- v = v * 0.7;
- }
- else if (dm > -200)
- {
-// dprint ("level 3\n");
- v = v * 2;
- }
- else
- v = v * 10;
-
- return v;
-};
-
-void(string gibname, float dm) ThrowGib =
-{
- local entity new;
-
- new = spawn();
- new.origin = self.origin;
- setmodel (new, gibname);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (dm);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.frame = 0;
- new.flags = 0;
-};
-
-void(string gibname, float dm) ThrowHead =
-{
- setmodel (self, gibname);
- self.skin = self.skin_head; // dumptruck_ds custom_mdl changes
- if !(self.skin_head)
- self.skin_head = 0;
- // end dumptruck_ds
- self.frame = 0;
- self.nextthink = -1;
- self.movetype = MOVETYPE_BOUNCE;
- self.takedamage = DAMAGE_NO;
- self.solid = SOLID_NOT;
- self.view_ofs = '0 0 8';
- setsize (self, '-16 -16 0', '16 16 56');
- self.velocity = VelocityForDamage (dm);
- self.origin_z = self.origin_z - 24;
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- self.avelocity = crandom() * '0 600 0';
-};
-
-
-void() GibPlayer =
-{
- ThrowHead ("progs/h_player.mdl", self.health);
- ThrowGib ("progs/gib1.mdl", self.health);
- ThrowGib ("progs/gib2.mdl", self.health);
- ThrowGib ("progs/gib3.mdl", self.health);
-
- self.deadflag = DEAD_DEAD;
-
- if (damage_attacker.classname == "teledeath")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
- if (damage_attacker.classname == "teledeath2")
- {
- sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
- return;
- }
-
- if (random() < 0.5)
- sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
- else
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
-};
-
-void() PlayerDie =
-{
- local float i;
-
-// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes start
-// self.items = self.items - (self.items & IT_INVISIBILITY);
- self.items = self.items - (self.items & (IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
-// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes end self.invisible_finished = 0; // don't die as eyes
- self.invincible_finished = 0;
- self.super_damage_finished = 0;
- self.radsuit_finished = 0;
- self.effects = 0; // 1998-07-23 Glowing corpse of players which had quad/pentagram until respawn fix by Maddes
- self.modelindex = modelindex_player; // don't use eyes
-
- if (deathmatch || coop)
- DropBackpack();
-
- self.weaponmodel="";
- self.view_ofs = '0 0 -8';
- self.deadflag = DEAD_DYING;
- self.solid = SOLID_NOT;
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- self.movetype = MOVETYPE_TOSS;
- if (self.velocity_z < 10)
- self.velocity_z = self.velocity_z + random()*300;
-
- if (self.health < -40)
- {
- GibPlayer ();
- return;
- }
-
- DeathSound();
-
- self.angles_x = 0;
- self.angles_z = 0;
-
- if (self.weapon == IT_AXE)
- {
- player_die_ax1 ();
- return;
- }
-
- i = cvar("temp1");
- if (!i)
- i = 1 + floor(random()*6);
-
- if (i == 1)
- player_diea1();
- else if (i == 2)
- player_dieb1();
- else if (i == 3)
- player_diec1();
- else if (i == 4)
- player_died1();
- else
- player_diee1();
-
-};
-
-void() set_suicide_frame =
-{ // used by klill command and diconnect command
- if (self.model != "progs/player.mdl")
- return; // allready gibbed
- self.frame = $deatha11;
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_TOSS;
- self.deadflag = DEAD_DEAD;
- self.nextthink = -1;
-};
-
-
-void() player_diea1 = [ $deatha1, player_diea2 ] {};
-void() player_diea2 = [ $deatha2, player_diea3 ] {};
-void() player_diea3 = [ $deatha3, player_diea4 ] {};
-void() player_diea4 = [ $deatha4, player_diea5 ] {};
-void() player_diea5 = [ $deatha5, player_diea6 ] {};
-void() player_diea6 = [ $deatha6, player_diea7 ] {};
-void() player_diea7 = [ $deatha7, player_diea8 ] {};
-void() player_diea8 = [ $deatha8, player_diea9 ] {};
-void() player_diea9 = [ $deatha9, player_diea10 ] {};
-void() player_diea10 = [ $deatha10, player_diea11 ] {};
-void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();};
-
-void() player_dieb1 = [ $deathb1, player_dieb2 ] {};
-void() player_dieb2 = [ $deathb2, player_dieb3 ] {};
-void() player_dieb3 = [ $deathb3, player_dieb4 ] {};
-void() player_dieb4 = [ $deathb4, player_dieb5 ] {};
-void() player_dieb5 = [ $deathb5, player_dieb6 ] {};
-void() player_dieb6 = [ $deathb6, player_dieb7 ] {};
-void() player_dieb7 = [ $deathb7, player_dieb8 ] {};
-void() player_dieb8 = [ $deathb8, player_dieb9 ] {};
-void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();};
-
-void() player_diec1 = [ $deathc1, player_diec2 ] {};
-void() player_diec2 = [ $deathc2, player_diec3 ] {};
-void() player_diec3 = [ $deathc3, player_diec4 ] {};
-void() player_diec4 = [ $deathc4, player_diec5 ] {};
-void() player_diec5 = [ $deathc5, player_diec6 ] {};
-void() player_diec6 = [ $deathc6, player_diec7 ] {};
-void() player_diec7 = [ $deathc7, player_diec8 ] {};
-void() player_diec8 = [ $deathc8, player_diec9 ] {};
-void() player_diec9 = [ $deathc9, player_diec10 ] {};
-void() player_diec10 = [ $deathc10, player_diec11 ] {};
-void() player_diec11 = [ $deathc11, player_diec12 ] {};
-void() player_diec12 = [ $deathc12, player_diec13 ] {};
-void() player_diec13 = [ $deathc13, player_diec14 ] {};
-void() player_diec14 = [ $deathc14, player_diec15 ] {};
-void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();};
-
-void() player_died1 = [ $deathd1, player_died2 ] {};
-void() player_died2 = [ $deathd2, player_died3 ] {};
-void() player_died3 = [ $deathd3, player_died4 ] {};
-void() player_died4 = [ $deathd4, player_died5 ] {};
-void() player_died5 = [ $deathd5, player_died6 ] {};
-void() player_died6 = [ $deathd6, player_died7 ] {};
-void() player_died7 = [ $deathd7, player_died8 ] {};
-void() player_died8 = [ $deathd8, player_died9 ] {};
-void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();};
-
-void() player_diee1 = [ $deathe1, player_diee2 ] {};
-void() player_diee2 = [ $deathe2, player_diee3 ] {};
-void() player_diee3 = [ $deathe3, player_diee4 ] {};
-void() player_diee4 = [ $deathe4, player_diee5 ] {};
-void() player_diee5 = [ $deathe5, player_diee6 ] {};
-void() player_diee6 = [ $deathe6, player_diee7 ] {};
-void() player_diee7 = [ $deathe7, player_diee8 ] {};
-void() player_diee8 = [ $deathe8, player_diee9 ] {};
-void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();};
-
-void() player_die_ax1 = [ $axdeth1, player_die_ax2 ] {};
-void() player_die_ax2 = [ $axdeth2, player_die_ax3 ] {};
-void() player_die_ax3 = [ $axdeth3, player_die_ax4 ] {};
-void() player_die_ax4 = [ $axdeth4, player_die_ax5 ] {};
-void() player_die_ax5 = [ $axdeth5, player_die_ax6 ] {};
-void() player_die_ax6 = [ $axdeth6, player_die_ax7 ] {};
-void() player_die_ax7 = [ $axdeth7, player_die_ax8 ] {};
-void() player_die_ax8 = [ $axdeth8, player_die_ax9 ] {};
-void() player_die_ax9 = [ $axdeth9, player_die_ax9 ] {PlayerDead();};
-
-/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
-
-/*QUAKED player_dead_axe (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":49});
-}
-*/
-void() player_dead_axe =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $axdeth9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-
-/*QUAKED player_dead_face_down (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":84});
-}
-*/
-void() player_dead_face_down =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $deathc14;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-50.28 -23.55 -49.85','30.66 14.49 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-
-/*QUAKED player_dead_on_side (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-{
- model ({"path":"progs/player.mdl","frame":102});
-}
-*/
-void() player_dead_on_side =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model("progs/player.mdl");
- setmodel(self, "progs/player.mdl");
- self.frame = $deathe9;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
-
-};
-/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+void() bubble_bob;
+
+/*
+==============================================================================
+
+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
+
+$frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
+$frame deatha9 deatha10 deatha11
+
+$frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
+$frame deathb9
+
+$frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
+$frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
+
+$frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
+$frame deathd8 deathd9
+
+$frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
+$frame deathe8 deathe9
+
+//
+// attacks
+//
+$frame nailatt1 nailatt2
+
+$frame light1 light2
+
+$frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
+
+$frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
+
+$frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
+
+$frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
+
+$frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
+
+$frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
+
+
+/*
+==============================================================================
+PLAYER
+==============================================================================
+*/
+
+void() player_run;
+
+void() player_stand1 =[ $axstnd1, player_stand1 ]
+{
+ self.weaponframe=0;
+ if (self.velocity_x || self.velocity_y)
+ {
+ self.walkframe=0;
+ player_run();
+ return;
+ }
+
+ if (self.weapon == IT_AXE)
+ {
+ if (self.walkframe >= 12)
+ self.walkframe = 0;
+ self.frame = $axstnd1 + self.walkframe;
+ }
+ else
+ {
+ if (self.walkframe >= 5)
+ self.walkframe = 0;
+ self.frame = $stand1 + self.walkframe;
+ }
+ self.walkframe = self.walkframe + 1;
+};
+
+void() player_run =[ $rockrun1, player_run ]
+{
+ self.weaponframe=0;
+ if (!self.velocity_x && !self.velocity_y)
+ {
+ self.walkframe=0;
+ player_stand1();
+ return;
+ }
+
+ if (self.weapon == IT_AXE)
+ {
+ if (self.walkframe == 6)
+ self.walkframe = 0;
+ self.frame = $axrun1 + self.walkframe;
+ }
+ else
+ {
+ if (self.walkframe == 6)
+ self.walkframe = 0;
+ self.frame = self.frame + self.walkframe;
+ }
+ self.walkframe = self.walkframe + 1;
+};
+
+
+void() player_shot1 = [$shotatt1, player_shot2 ] {self.weaponframe=1;
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() player_shot2 = [$shotatt2, player_shot3 ] {self.weaponframe=2;};
+void() player_shot3 = [$shotatt3, player_shot4 ] {self.weaponframe=3;};
+void() player_shot4 = [$shotatt4, player_shot5 ] {self.weaponframe=4;};
+void() player_shot5 = [$shotatt5, player_shot6 ] {self.weaponframe=5;};
+void() player_shot6 = [$shotatt6, player_run ] {self.weaponframe=6;};
+
+void() player_axe1 = [$axatt1, player_axe2 ] {self.weaponframe=1;};
+void() player_axe2 = [$axatt2, player_axe3 ] {self.weaponframe=2;};
+void() player_axe3 = [$axatt3, player_axe4 ] {self.weaponframe=3;W_FireAxe();};
+void() player_axe4 = [$axatt4, player_run ] {self.weaponframe=4;};
+
+void() player_axeb1 = [$axattb1, player_axeb2 ] {self.weaponframe=5;};
+void() player_axeb2 = [$axattb2, player_axeb3 ] {self.weaponframe=6;};
+void() player_axeb3 = [$axattb3, player_axeb4 ] {self.weaponframe=7;W_FireAxe();};
+void() player_axeb4 = [$axattb4, player_run ] {self.weaponframe=8;};
+
+void() player_axec1 = [$axattc1, player_axec2 ] {self.weaponframe=1;};
+void() player_axec2 = [$axattc2, player_axec3 ] {self.weaponframe=2;};
+void() player_axec3 = [$axattc3, player_axec4 ] {self.weaponframe=3;W_FireAxe();};
+void() player_axec4 = [$axattc4, player_run ] {self.weaponframe=4;};
+
+void() player_axed1 = [$axattd1, player_axed2 ] {self.weaponframe=5;};
+void() player_axed2 = [$axattd2, player_axed3 ] {self.weaponframe=6;};
+void() player_axed3 = [$axattd3, player_axed4 ] {self.weaponframe=7;W_FireAxe();};
+void() player_axed4 = [$axattd4, player_run ] {self.weaponframe=8;};
+
+
+//============================================================================
+
+void() player_nail1 =[$nailatt1, player_nail2 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 9)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireSpikes (4);
+ self.attack_finished = time + 0.2;
+};
+void() player_nail2 =[$nailatt2, player_nail1 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 9)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireSpikes (-4);
+ self.attack_finished = time + 0.2;
+};
+
+//============================================================================
+
+void() player_light1 =[$light1, player_light2 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 5)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireLightning();
+ self.attack_finished = time + 0.2;
+};
+void() player_light2 =[$light2, player_light1 ]
+{
+ self.effects = self.effects | EF_MUZZLEFLASH;
+
+ if (!self.button0)
+ {player_run ();return;}
+ self.weaponframe = self.weaponframe + 1;
+ if (self.weaponframe == 5)
+ self.weaponframe = 1;
+ SuperDamageSound();
+ W_FireLightning();
+ self.attack_finished = time + 0.2;
+};
+
+//============================================================================
+
+
+void() player_rocket1 =[$rockatt1, player_rocket2 ] {self.weaponframe=1;
+self.effects = self.effects | EF_MUZZLEFLASH;};
+void() player_rocket2 =[$rockatt2, player_rocket3 ] {self.weaponframe=2;};
+void() player_rocket3 =[$rockatt3, player_rocket4 ] {self.weaponframe=3;};
+void() player_rocket4 =[$rockatt4, player_rocket5 ] {self.weaponframe=4;};
+void() player_rocket5 =[$rockatt5, player_rocket6 ] {self.weaponframe=5;};
+void() player_rocket6 =[$rockatt6, player_run ] {self.weaponframe=6;};
+void(float num_bubbles) DeathBubbles;
+
+void() PainSound =
+{
+local float rs;
+
+ if (self.health < 0)
+ return;
+
+ if (damage_attacker.classname == "teledeath")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+// water pain sounds
+ if (self.watertype == CONTENT_WATER && self.waterlevel == 3)
+ {
+ DeathBubbles(1);
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+// slime pain sounds
+ if (self.watertype == CONTENT_SLIME)
+ {
+// FIX ME put in some steam here
+// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes start
+ if (self.waterlevel == 3)
+ DeathBubbles(1);
+// 1998-08-10 Player gulps bubbles when hurt in slime by Maddes end
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+ if (self.watertype == CONTENT_LAVA)
+ {
+ if (random() > 0.5)
+ sound (self, CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM);
+ else
+ sound (self, CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM);
+ return;
+ }
+
+ if (self.pain_finished > time)
+ {
+ self.axhitme = 0;
+ return;
+ }
+ self.pain_finished = time + 0.5;
+
+// don't make multiple pain sounds right after each other
+
+// ax pain sound
+ if (self.axhitme == 1)
+ {
+ self.axhitme = 0;
+ sound (self, CHAN_VOICE, "player/axhit1.wav", 1, ATTN_NORM);
+ return;
+ }
+
+
+ rs = rint((random() * 5) + 1);
+
+ self.noise = "";
+ if (rs == 1)
+ self.noise = "player/pain1.wav";
+ else if (rs == 2)
+ self.noise = "player/pain2.wav";
+ else if (rs == 3)
+ self.noise = "player/pain3.wav";
+ else if (rs == 4)
+ self.noise = "player/pain4.wav";
+ else if (rs == 5)
+ self.noise = "player/pain5.wav";
+ else
+ self.noise = "player/pain6.wav";
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ return;
+};
+
+void() player_pain1 = [ $pain1, player_pain2 ] {PainSound();self.weaponframe=0;};
+void() player_pain2 = [ $pain2, player_pain3 ] {};
+void() player_pain3 = [ $pain3, player_pain4 ] {};
+void() player_pain4 = [ $pain4, player_pain5 ] {};
+void() player_pain5 = [ $pain5, player_pain6 ] {};
+void() player_pain6 = [ $pain6, player_run ] {};
+
+void() player_axpain1 = [ $axpain1, player_axpain2 ] {PainSound();self.weaponframe=0;};
+void() player_axpain2 = [ $axpain2, player_axpain3 ] {};
+void() player_axpain3 = [ $axpain3, player_axpain4 ] {};
+void() player_axpain4 = [ $axpain4, player_axpain5 ] {};
+void() player_axpain5 = [ $axpain5, player_axpain6 ] {};
+void() player_axpain6 = [ $axpain6, player_run ] {};
+
+void(entity attacker, float damage) player_pain =
+{
+ if (self.weaponframe)
+ return;
+
+ if (self.invisible_finished > time)
+ return; // eyes don't have pain frames
+
+ if (self.weapon == IT_AXE)
+ player_axpain1 ();
+ else
+ player_pain1 ();
+};
+
+void() player_diea1;
+void() player_dieb1;
+void() player_diec1;
+void() player_died1;
+void() player_diee1;
+void() player_die_ax1;
+
+void() DeathBubblesSpawn =
+{
+local entity bubble;
+ if ((self.owner.waterlevel != 3) && (self.owner.health > 0)) // 1998-08-14 Improved bubble spawn by Maddes
+// 1998-08-14 Bubblespawner remove fix by Perged start
+{
+ remove(self); // remove bubble spawner
+// 1998-08-14 Bubblespawner remove fix by Perged end
+ return;
+} // 1998-08-14 Bubblespawner remove fix by Perged return;
+ bubble = spawn();
+ setmodel (bubble, "progs/s_bubble.spr");
+ setorigin (bubble, self.owner.origin + '0 0 24');
+ bubble.movetype = MOVETYPE_NOCLIP;
+ bubble.solid = SOLID_NOT;
+ bubble.velocity = '0 0 15';
+ bubble.nextthink = time + 0.5;
+ bubble.think = bubble_bob;
+ bubble.classname = "bubble";
+ bubble.frame = 0;
+ bubble.cnt = 0;
+ setsize (bubble, '-8 -8 -8', '8 8 8');
+// 1998-08-14 Improved bubble spawn by Maddes start
+// self.nextthink = time + 0.1;
+ self.nextthink = time + 0.01;
+// 1998-08-14 Improved bubble spawn by Maddes end
+ self.think = DeathBubblesSpawn;
+ self.air_finished = self.air_finished + 1;
+ if (self.air_finished >= self.bubble_count)
+ remove(self);
+};
+
+void(float num_bubbles) DeathBubbles =
+{
+local entity bubble_spawner;
+
+ bubble_spawner = spawn();
+ setorigin (bubble_spawner, self.origin);
+ bubble_spawner.movetype = MOVETYPE_NONE;
+ bubble_spawner.solid = SOLID_NOT;
+// 1998-08-14 Improved bubble spawn by Maddes start
+// bubble_spawner.nextthink = time + 0.1;
+ bubble_spawner.nextthink = time + 0.01;
+// 1998-08-14 Improved bubble spawn by Maddes end
+ bubble_spawner.think = DeathBubblesSpawn;
+ bubble_spawner.air_finished = 0;
+ bubble_spawner.owner = self;
+ bubble_spawner.bubble_count = num_bubbles;
+// return; // 1998-08-14 unnecessary by Maddes
+};
+
+
+void() DeathSound =
+{
+local float rs;
+
+ // water death sounds
+ if (self.waterlevel == 3)
+ {
+ DeathBubbles(20);
+ sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ rs = rint ((random() * 4) + 1);
+ if (rs == 1)
+ self.noise = "player/death1.wav";
+ if (rs == 2)
+ self.noise = "player/death2.wav";
+ if (rs == 3)
+ self.noise = "player/death3.wav";
+ if (rs == 4)
+ self.noise = "player/death4.wav";
+ if (rs == 5)
+ self.noise = "player/death5.wav";
+
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NONE);
+ return;
+};
+
+
+void() PlayerDead =
+{
+ self.nextthink = -1;
+// allow respawn after a certain time
+ self.deadflag = DEAD_DEAD;
+};
+
+vector(float dm) VelocityForDamage =
+{
+ local vector v;
+
+ v_x = 100 * crandom();
+ v_y = 100 * crandom();
+ v_z = 200 + 100 * random();
+
+ if (dm > -50)
+ {
+// dprint ("level 1\n");
+ v = v * 0.7;
+ }
+ else if (dm > -200)
+ {
+// dprint ("level 3\n");
+ v = v * 2;
+ }
+ else
+ v = v * 10;
+
+ return v;
+};
+
+void(string gibname, float dm) ThrowGib =
+{
+ local entity new;
+
+ new = spawn();
+ new.origin = self.origin;
+ setmodel (new, gibname);
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (dm);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.frame = 0;
+ new.flags = 0;
+};
+
+void(string gibname, float dm) ThrowHead =
+{
+ setmodel (self, gibname);
+ self.skin = self.skin_head; // dumptruck_ds custom_mdl changes
+ if !(self.skin_head)
+ self.skin_head = 0;
+ // end dumptruck_ds
+ self.frame = 0;
+ self.nextthink = -1;
+ self.movetype = MOVETYPE_BOUNCE;
+ self.takedamage = DAMAGE_NO;
+ self.solid = SOLID_NOT;
+ self.view_ofs = '0 0 8';
+ setsize (self, '-16 -16 0', '16 16 56');
+ self.velocity = VelocityForDamage (dm);
+ self.origin_z = self.origin_z - 24;
+ self.flags = self.flags - (self.flags & FL_ONGROUND);
+ self.avelocity = crandom() * '0 600 0';
+};
+
+
+void() GibPlayer =
+{
+ ThrowHead ("progs/h_player.mdl", self.health);
+ ThrowGib ("progs/gib1.mdl", self.health);
+ ThrowGib ("progs/gib2.mdl", self.health);
+ ThrowGib ("progs/gib3.mdl", self.health);
+
+ self.deadflag = DEAD_DEAD;
+
+ if (damage_attacker.classname == "teledeath")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ if (damage_attacker.classname == "teledeath2")
+ {
+ sound (self, CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NONE);
+ return;
+ }
+
+ if (random() < 0.5)
+ sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NONE);
+ else
+ sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NONE);
+};
+
+void() PlayerDie =
+{
+ local float i;
+
+// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes start
+// self.items = self.items - (self.items & IT_INVISIBILITY);
+ self.items = self.items - (self.items & (IT_INVISIBILITY | IT_INVULNERABILITY | IT_SUIT | IT_QUAD) );
+// 1998-07-23 Palette shift when player dies with quad/pentagram fix by Maddes end self.invisible_finished = 0; // don't die as eyes
+ self.invincible_finished = 0;
+ self.super_damage_finished = 0;
+ self.radsuit_finished = 0;
+ self.effects = 0; // 1998-07-23 Glowing corpse of players which had quad/pentagram until respawn fix by Maddes
+ self.modelindex = modelindex_player; // don't use eyes
+
+ if (deathmatch || coop)
+ DropBackpack();
+
+ self.weaponmodel="";
+ self.view_ofs = '0 0 -8';
+ self.deadflag = DEAD_DYING;
+ self.solid = SOLID_NOT;
+ self.flags = self.flags - (self.flags & FL_ONGROUND);
+ self.movetype = MOVETYPE_TOSS;
+ if (self.velocity_z < 10)
+ self.velocity_z = self.velocity_z + random()*300;
+
+ if (self.health < -40)
+ {
+ GibPlayer ();
+ return;
+ }
+
+ DeathSound();
+
+ self.angles_x = 0;
+ self.angles_z = 0;
+
+ if (self.weapon == IT_AXE)
+ {
+ player_die_ax1 ();
+ return;
+ }
+
+ i = cvar("temp1");
+ if (!i)
+ i = 1 + floor(random()*6);
+
+ if (i == 1)
+ player_diea1();
+ else if (i == 2)
+ player_dieb1();
+ else if (i == 3)
+ player_diec1();
+ else if (i == 4)
+ player_died1();
+ else
+ player_diee1();
+
+};
+
+void() set_suicide_frame =
+{ // used by klill command and diconnect command
+ if (self.model != "progs/player.mdl")
+ return; // allready gibbed
+ self.frame = $deatha11;
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_TOSS;
+ self.deadflag = DEAD_DEAD;
+ self.nextthink = -1;
+};
+
+
+void() player_diea1 = [ $deatha1, player_diea2 ] {};
+void() player_diea2 = [ $deatha2, player_diea3 ] {};
+void() player_diea3 = [ $deatha3, player_diea4 ] {};
+void() player_diea4 = [ $deatha4, player_diea5 ] {};
+void() player_diea5 = [ $deatha5, player_diea6 ] {};
+void() player_diea6 = [ $deatha6, player_diea7 ] {};
+void() player_diea7 = [ $deatha7, player_diea8 ] {};
+void() player_diea8 = [ $deatha8, player_diea9 ] {};
+void() player_diea9 = [ $deatha9, player_diea10 ] {};
+void() player_diea10 = [ $deatha10, player_diea11 ] {};
+void() player_diea11 = [ $deatha11, player_diea11 ] {PlayerDead();};
+
+void() player_dieb1 = [ $deathb1, player_dieb2 ] {};
+void() player_dieb2 = [ $deathb2, player_dieb3 ] {};
+void() player_dieb3 = [ $deathb3, player_dieb4 ] {};
+void() player_dieb4 = [ $deathb4, player_dieb5 ] {};
+void() player_dieb5 = [ $deathb5, player_dieb6 ] {};
+void() player_dieb6 = [ $deathb6, player_dieb7 ] {};
+void() player_dieb7 = [ $deathb7, player_dieb8 ] {};
+void() player_dieb8 = [ $deathb8, player_dieb9 ] {};
+void() player_dieb9 = [ $deathb9, player_dieb9 ] {PlayerDead();};
+
+void() player_diec1 = [ $deathc1, player_diec2 ] {};
+void() player_diec2 = [ $deathc2, player_diec3 ] {};
+void() player_diec3 = [ $deathc3, player_diec4 ] {};
+void() player_diec4 = [ $deathc4, player_diec5 ] {};
+void() player_diec5 = [ $deathc5, player_diec6 ] {};
+void() player_diec6 = [ $deathc6, player_diec7 ] {};
+void() player_diec7 = [ $deathc7, player_diec8 ] {};
+void() player_diec8 = [ $deathc8, player_diec9 ] {};
+void() player_diec9 = [ $deathc9, player_diec10 ] {};
+void() player_diec10 = [ $deathc10, player_diec11 ] {};
+void() player_diec11 = [ $deathc11, player_diec12 ] {};
+void() player_diec12 = [ $deathc12, player_diec13 ] {};
+void() player_diec13 = [ $deathc13, player_diec14 ] {};
+void() player_diec14 = [ $deathc14, player_diec15 ] {};
+void() player_diec15 = [ $deathc15, player_diec15 ] {PlayerDead();};
+
+void() player_died1 = [ $deathd1, player_died2 ] {};
+void() player_died2 = [ $deathd2, player_died3 ] {};
+void() player_died3 = [ $deathd3, player_died4 ] {};
+void() player_died4 = [ $deathd4, player_died5 ] {};
+void() player_died5 = [ $deathd5, player_died6 ] {};
+void() player_died6 = [ $deathd6, player_died7 ] {};
+void() player_died7 = [ $deathd7, player_died8 ] {};
+void() player_died8 = [ $deathd8, player_died9 ] {};
+void() player_died9 = [ $deathd9, player_died9 ] {PlayerDead();};
+
+void() player_diee1 = [ $deathe1, player_diee2 ] {};
+void() player_diee2 = [ $deathe2, player_diee3 ] {};
+void() player_diee3 = [ $deathe3, player_diee4 ] {};
+void() player_diee4 = [ $deathe4, player_diee5 ] {};
+void() player_diee5 = [ $deathe5, player_diee6 ] {};
+void() player_diee6 = [ $deathe6, player_diee7 ] {};
+void() player_diee7 = [ $deathe7, player_diee8 ] {};
+void() player_diee8 = [ $deathe8, player_diee9 ] {};
+void() player_diee9 = [ $deathe9, player_diee9 ] {PlayerDead();};
+
+void() player_die_ax1 = [ $axdeth1, player_die_ax2 ] {};
+void() player_die_ax2 = [ $axdeth2, player_die_ax3 ] {};
+void() player_die_ax3 = [ $axdeth3, player_die_ax4 ] {};
+void() player_die_ax4 = [ $axdeth4, player_die_ax5 ] {};
+void() player_die_ax5 = [ $axdeth5, player_die_ax6 ] {};
+void() player_die_ax6 = [ $axdeth6, player_die_ax7 ] {};
+void() player_die_ax7 = [ $axdeth7, player_die_ax8 ] {};
+void() player_die_ax8 = [ $axdeth8, player_die_ax9 ] {};
+void() player_die_ax9 = [ $axdeth9, player_die_ax9 ] {PlayerDead();};
+
+/* Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */
+
+/*QUAKED player_dead_axe (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":49});
+}
+*/
+void() player_dead_axe =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $axdeth9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+
+/*QUAKED player_dead_face_down (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":84});
+}
+*/
+void() player_dead_face_down =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $deathc14;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-50.28 -23.55 -49.85','30.66 14.49 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+
+/*QUAKED player_dead_on_side (0 0.5 0.8) (-16 -16 -24) (16 16 32) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+ model ({"path":"progs/player.mdl","frame":102});
+}
+*/
+void() player_dead_on_side =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model("progs/player.mdl");
+ setmodel(self, "progs/player.mdl");
+ self.frame = $deathe9;
+
+ if (self.spawnflags & 1)
+ {
+ self.solid = SOLID_BBOX;
+ setsize(self,'-38.72 -5.83 -50.45','28.73 33.85 30');
+ }
+ else
+ {
+ self.solid = SOLID_NOT;
+ }
+
+};
+/* END Scenic Dead Monster Patch stuff here from DeadStuff mod -- dumptruck_ds */

Return to the top of this page or return to the overview of this repo.

Diff qc/pmove.qc

diff --git a/qc/pmove.qc b/qc/pmove.qc
new file mode 100644
index 0000000..888b2db
--- /dev/null
+++ b/qc/pmove.qc
@@ -0,0 +1,1180 @@
+/*==============================================================================
+ PMOVE.QC
+==============================================================================*/
+
+#define PM_AIRACCEL 8 // 10 in Q1; now 8
+#define PM_AIRACCELQ3 0.8 // 1.0 in Q3; now 0.8
+#define PM_AIRACCELFWD 1.1 // 1 feels close to Q3 / CPM
+#define PM_BOOSTACCEL 12 // 12 is fast, 10 is enough
+#define PM_BOOSTFRICTION 4 // Q1 friction (4) is plenty low
+#define PM_FRICTION 8 // 4 for Q1, 6 for Q3, 8 for CPM
+#define PM_GROUNDACCEL 15 // 10 is standard ground accel
+#define PM_GROUNDDIST_V '0 0 1' // distance for ground check
+#define PM_GRAVITY 800 // 800 always
+#define PM_OVERCLIP 1.0f // Quake3's OVERCLIP is 1.001f
+#define PM_STEPHEIGHT 18 // 18 for Q1, 22 for later games?
+#define PM_WALLDIST_V '0 0 40' // min. distance from ground for wj
+
+#define PM_JUMPSPEED 270 // standard jump Z velocity; 90 * 3
+#define PM_DOUBLEJUMPSPEED 360 // 270 * 1.5 in CPM?; 360 = 90 * 4
+#define PM_TRIPLEJUMPSPEED 225 // reduced Z velocity; 90 * 2.5
+#define PM_TELEJUMPSPEED 360 // same as DOUBLEJUMPSPEED
+#define PM_WALLJUMPFORCE 90 // amount of push away from wall
+#define PM_WALLJUMPSPEED PM_JUMPSPEED // upward vel for walljumps
+#define PM_MAXSPEED 320 // 320 always
+#define PM_MAXAIRSPEED 30 // 30 for Q1 air control
+#define PM_STOPSPEED 100
+#define PM_WATERSINKSPEED 60
+
+#define PM_JUMP_WINDOW 0.2 // minimum jump interval
+#define PM_DOUBLEJUMP_WINDOW 0.4 // 2 jumps in this time is a double
+#define PM_DOUBLEJUMP_COOLDOWN 0.4 //
+#define PM_TELEJUMP_WINDOW 0.4 // duration to allow a telejump
+#define PM_WALLJUMP_WINDOW 0.2 // duration between walljumps
+#define PM_WALLCLIP_WINDOW 0.25 //
+#define PM_BOOST_WINDOW 0.4 // groundboost duration
+
+.entity groundentity;
+.vector groundnormal;
+
+static void(entity tother) phys_dotouch =
+{
+ entity oself;
+
+ if (tother.touch == __NULL__)
+ return;
+
+ oself = self;
+ other = self;
+ self = tother;
+ self.touch();
+ self = oself;
+};
+
+// from the GPL2 CSQCTest code that comes with FTEQW
+float() phys_nudge =
+{
+ vector test, org = self.origin;
+
+ // check current position.
+ tracebox(org, self.mins, self.maxs, org, FALSE, self);
+ if (!trace_startsolid)
+ return TRUE;
+
+ // truncate to network accuracy
+ org_x = floor (org_x * 8 + (1.0 / 16)) * 0.125;
+ org_y = floor (org_y * 8 + (1.0 / 16)) * 0.125;
+ org_z = floor (org_z * 8 + (1.0 / 16)) * 0.125;
+
+ test = org;
+
+ static float offsets[] = {0, -1./8, 1./8, -2./8, 2./8};
+ for (float z = 0; z < offsets.length; z++)
+ {
+ test.z = org.z + offsets[z];
+ for (float y = 0; y < offsets.length; y++)
+ {
+ test.y = org.y + offsets[y];
+ for (float x = 0; x < offsets.length; x++)
+ {
+ test.x = org.x + offsets[x];
+ tracebox(test, self.mins, self.maxs, test,
+ FALSE, self);
+ if (!trace_startsolid)
+ {
+ // okay, that'll do
+ self.origin = test;
+ return TRUE;
+ }
+ }
+ }
+ }
+ self.origin = org;
+ return FALSE;
+};
+
+#define STOP_EPSILON 0.1
+vector(vector vel, vector normal, float ob, float oneside) phys_clipvelocity =
+{
+ local float backoff, backoffz;
+
+ backoff = vel * normal;
+ backoffz = 0;
+
+ if (backoff < 0)
+ backoff *= ob;
+ else
+ if (oneside)
+ // backoff = 0;
+ backoff *= -0.001;
+ else
+ backoff /= ob;
+
+ vel -= normal * backoff;
+
+ if (vel_x > -STOP_EPSILON && vel_x < STOP_EPSILON) vel_x = 0;
+ if (vel_y > -STOP_EPSILON && vel_y < STOP_EPSILON) vel_y = 0;
+ if (vel_z > -STOP_EPSILON && vel_z < STOP_EPSILON) vel_z = 0;
+
+ return vel;
+};
+
+// from Xonotic's source code, qcsrc/lib/vector.qh -- CEV
+/*
+vector cross(vector a, vector b)
+{
+ return
+ '1 0 0' * (a.y * b.z - a.z * b.y)
+ + '0 1 0' * (a.z * b.x - a.x * b.z)
+ + '0 0 1' * (a.x * b.y - a.y * b.x);
+};
+*/
+
+#define PHYS_SLIDE_NUMBUMPS 4
+#define PHYS_SLIDE_MAX_CLIP_PLANES 5
+int(float dogravity) phys_slidemove =
+{
+ vector planes[PHYS_SLIDE_MAX_CLIP_PLANES];
+ vector dir, end, new_v, start_v;
+ vector grav_v, gnew_v;
+ int blocked, bumpcount, numplanes, i, j, k;
+ float d, time_left, ent_grav;
+
+ blocked = 0;
+
+ // initialize all these vectors
+ for (i = 0; i < PHYS_SLIDE_MAX_CLIP_PLANES; i++)
+ planes[i] = '0 0 0';
+ dir = end = new_v = grav_v = gnew_v = '0 0 0';
+ start_v = self.velocity;
+
+ if (dogravity)
+ {
+ grav_v = self.velocity;
+ if (self.gravity)
+ ent_grav = self.gravity;
+ else
+ ent_grav = 1.0;
+ grav_v_z -= ent_grav * cvar("sv_gravity") * input_timelength;
+ self.velocity_z = (self.velocity_z + grav_v_z) * 0.5;
+ start_v_z = grav_v_z;
+ if (self.groundnormal)
+ {
+ self.velocity = phys_clipvelocity (self.velocity,
+ self.groundnormal, PM_OVERCLIP, FALSE);
+ }
+ }
+
+ if (self.groundnormal)
+ {
+ numplanes = 1;
+ planes[0] = self.groundnormal;
+ }
+ else
+ numplanes = 0;
+
+ // never turn against original velocity
+ planes[numplanes] = normalize (self.velocity);
+ numplanes++;
+
+ for (bumpcount = 0, time_left = input_timelength;
+ time_left > 0 && bumpcount < PHYS_SLIDE_NUMBUMPS; bumpcount++)
+ {
+ end = self.origin + self.velocity * time_left;
+ tracebox(self.origin, self.mins, self.maxs, end, FALSE, self);
+
+ if (trace_allsolid || trace_startsolid)
+ {
+ // entity is trapped in a solid; attempt to nudge out
+ if (phys_nudge()) continue;
+
+ // nah, we're stuck. don't build up falling damage
+ // but allow sideways acceleration
+ dprint ("phys_slidemove: entity trapped in a solid\n");
+ self.velocity_z = 0;
+ return 3;
+ }
+
+ float cur_fraction = trace_fraction;
+ vector cur_plane = trace_plane_normal;
+
+ if (cur_fraction > 0)
+ self.origin = trace_endpos;
+
+ if (cur_fraction == 1) break;
+
+ /*
+ // this isn't working for some reason -- CEV
+ if (cur_plane.z)
+ if (cur_plane.z > 0.7)
+ {
+ blocked |= 1;
+ self.flags |= FL_ONGROUND;
+ self.groundnormal = cur_plane;
+ self.groundentity = trace_ent;
+ }
+ else
+ blocked |= 2;
+ */
+
+ phys_dotouch (trace_ent);
+ time_left -= time_left * cur_fraction;
+
+ if (numplanes >= PHYS_SLIDE_MAX_CLIP_PLANES)
+ {
+ // this shouldn't really happen
+ if (cvar("developer"))
+ {
+ dprint ("phys_slidemove: numplanes >= max: ");
+ dprint (ftos(numplanes));
+ dprint ("\n");
+ }
+ self.velocity = '0 0 0';
+ return 7;
+ }
+
+ // comment from Q3 source:
+ // if this is the same plane we hit before nudge velocity out
+ // along it; this fixes some issues with non-axial planes
+ for (i = 0; i < numplanes; i++)
+ {
+ if (cur_plane * planes[i] > 0.99)
+ {
+ dprint ("phys_slidemove: non-axial plane\n");
+ self.velocity += cur_plane;
+ break;
+ }
+ }
+
+ if (i < numplanes) continue;
+
+ planes[numplanes] = cur_plane;
+ numplanes++;
+
+ // modify velocity so it parallels all of the clip planes
+ // find a plane that it enters
+ for (i = 0; i < numplanes; i++)
+ {
+ if (self.velocity * planes[i] >= 0.1)
+ continue;
+
+ // slide along the plane
+ new_v = phys_clipvelocity (self.velocity, planes[i],
+ PM_OVERCLIP, FALSE);
+ if (dogravity)
+ gnew_v = phys_clipvelocity (grav_v,
+ planes[i], PM_OVERCLIP, FALSE);
+
+ for (j = 0; j < numplanes; j++)
+ {
+ if (new_v * planes[j] >= 0.1) continue;
+
+ // try clipping the move to the plane
+ new_v = phys_clipvelocity (new_v, planes[j],
+ PM_OVERCLIP, FALSE);
+ if (dogravity)
+ gnew_v = phys_clipvelocity (gnew_v,
+ planes[j], PM_OVERCLIP, FALSE);
+
+ // see if it goes back into the first clip plane
+ if (new_v * planes[i] >= 0) continue;
+
+ // slide along the crease
+ dir = crossproduct (planes[i], planes[j]);
+ dir = normalize (dir);
+ d = dir * self.velocity;
+ new_v = dir * d;
+
+ if (dogravity)
+ {
+ dir = crossproduct(planes[i],planes[j]);
+ dir = normalize (dir);
+ d = dir * grav_v;
+ gnew_v = dir * d;
+ }
+
+ // see if the move enters a third plane
+ for (k = 0; k < numplanes; k++)
+ {
+ if (k == i || k == j)
+ continue;
+
+ if (new_v * planes[k] >= 0.1)
+ // no interaction
+ continue;
+
+ // testing something here -- CEV
+ if (numplanes < 3)
+ continue;
+
+ // stop at a triple plane interaction
+ if (cvar("developer"))
+ {
+ // laugh at my 80 col terminal
+ dprint ("phys_slidemove: ");
+ dprint ("triple plane inter");
+ dprint ("action; numplanes: ");
+ dprint (ftos(numplanes));
+ dprint ("\n");
+ }
+ self.velocity = '0 0 0';
+ return 7;
+ }
+ }
+
+ // if we've fixed all interaction try another move
+ self.velocity = new_v;
+ if (dogravity) grav_v = gnew_v;
+ break;
+ }
+ }
+
+ // final gravity check here
+ if (dogravity) self.velocity = grav_v;
+
+ // wallclip / wall skim timer check
+ if ((self.primal_speed > PM_MAXSPEED) &&
+ (self.jump_time) &&
+ (!(self.flags & FL_WATERJUMP)) &&
+ (self.teleport_time <= (time - 0.1)) &&
+ (self.boost_time <= time - PM_BOOST_WINDOW) &&
+ (self.jump_time > (time - PM_WALLCLIP_WINDOW)) &&
+ (vlen(start_v) > vlen(self.velocity)))
+ {
+ // dprint ("phys_slidemove: restoring velocity...\n");
+ self.velocity = start_v;
+ }
+
+ if (bumpcount > 0) blocked |= 8;
+ return blocked;
+};
+
+int(float dogravity, float onesided) phys_q1flymove =
+{
+ vector planes[PHYS_SLIDE_MAX_CLIP_PLANES];
+ vector dir, end, new_v, start_v;
+ int blocked, bumpcount, numplanes, i, j;
+ float d, ent_grav, grav, time_left;
+
+ blocked = numplanes = 0;
+
+ // initialize all these vectors
+ for (i = 0; i < PHYS_SLIDE_MAX_CLIP_PLANES; i++)
+ planes[i] = '0 0 0';
+ dir = end = new_v = '0 0 0';
+
+ if (dogravity)
+ {
+ if (self.gravity)
+ ent_grav = self.gravity;
+ else
+ ent_grav = 1.0;
+ grav = ent_grav * cvar("sv_gravity") * input_timelength;
+ // we'll do half of it now, half later -- CEV
+ self.velocity_z -= grav * 0.5;
+ }
+
+ // set start_v after gravity check above
+ start_v = self.velocity;
+
+ for (bumpcount = 0, time_left = input_timelength;
+ time_left > 0 && bumpcount < PHYS_SLIDE_NUMBUMPS; bumpcount++)
+ {
+ end = self.origin + self.velocity * time_left;
+ tracebox (self.origin, self.mins, self.maxs, end, FALSE, self);
+
+ if (trace_allsolid || trace_startsolid)
+ {
+ // entity is trapped in a solid; attempt to nudge out
+ if (phys_nudge()) continue;
+
+ // nah, we're stuck. don't build up falling damage
+ // but allow sideways acceleration
+ dprint ("phys_q1flymove: entity trapped in a solid\n");
+ self.velocity_z = 0;
+ return 3;
+ }
+
+ if (trace_fraction >= 0.001)
+ self.origin = trace_endpos;
+
+ if (trace_fraction == 1) break;
+
+ if (trace_plane_normal_z > 0.7)
+ {
+ blocked |= 1;
+ self.groundnormal = trace_plane_normal;
+ self.groundentity = trace_ent;
+ }
+
+ if (!(trace_plane_normal_z))
+ blocked |= 2;
+
+ phys_dotouch (trace_ent);
+ time_left -= time_left * trace_fraction;
+
+ if (numplanes >= PHYS_SLIDE_MAX_CLIP_PLANES)
+ {
+ // this shouldn't really happen
+ if (cvar("developer"))
+ {
+ dprint ("phys_q1flymove: numplanes >= max: ");
+ dprint (ftos(numplanes));
+ dprint ("\n");
+ }
+ self.velocity = '0 0 0';
+ blocked = 7;
+ break;
+ }
+
+ planes[numplanes] = trace_plane_normal;
+ numplanes++;
+
+ for (i = 0; i < numplanes; i++)
+ {
+ // slide along the plane
+ new_v = phys_clipvelocity (self.velocity,
+ planes[i], PM_OVERCLIP, onesided);
+
+ for (j = 0; j < numplanes; j++)
+ if (j != i)
+ // not ok (the comment says)
+ if ((new_v * planes[j]) < 0) break;
+
+ if (j == numplanes) break;
+ }
+
+ if (i == numplanes)
+ {
+ if (numplanes != 2)
+ {
+ dprint ("phys_q1flymove: stopping dead\n");
+ self.velocity = '0 0 0';
+ blocked = 7;
+ break;
+ }
+
+ // slide along the crease
+ dir = crossproduct (planes[0], planes[1]);
+ dir = normalize (dir);
+ d = (dir * self.velocity);
+ new_v = dir * d;
+ }
+
+ self.velocity = new_v;
+
+ if ((self.velocity * start_v) <= 0)
+ {
+ // dprint ("phys_q1flymove: turned against orig vel\n");
+ self.velocity = '0 0 0';
+ break;
+ }
+ }
+
+ // wallclip / wall skim timer check
+ if ( // (self.primal_speed > PM_MAXSPEED) &&
+ (self.jump_time) &&
+ (!(self.flags & FL_WATERJUMP)) &&
+ (self.teleport_time <= (time - 0.1)) &&
+ (self.boost_time <= time - PM_BOOST_WINDOW) &&
+ (self.jump_time > (time - PM_WALLCLIP_WINDOW)) &&
+ (vlen(start_v) > vlen(self.velocity)))
+ {
+ dprint ("phys_q1flymove: restoring velocity...\n");
+ if (dogravity)
+ start_v_z -= grav * 0.5;
+ self.velocity = start_v;
+ }
+ else
+ {
+ // final gravity check here
+ if (dogravity)
+ self.velocity_z -= grav * 0.5;
+ }
+
+ return blocked;
+};
+
+void(float dogravity, float onesided) phys_stepslidemove =
+{
+ vector start_o, start_v, first_o, first_v;
+ vector up, down;
+ float stepsize;
+ int clip, first_clip;
+ int start_onground;
+
+ clip = first_clip = 0;
+ start_o = self.origin;
+ start_v = self.velocity;
+ start_onground = (self.flags & FL_ONGROUND);
+
+ // first try let's go
+ first_clip = phys_q1flymove (dogravity, onesided);
+
+ if (!(first_clip & 2) && !(first_clip & 8))
+ {
+ // we got where we wanted to go right away
+ // dprint ("phys_stepslidemove: accepting first move\n");
+ if (first_clip & 1)
+ self.flags |= FL_ONGROUND;
+ else
+ self.flags &= ~FL_ONGROUND;
+ return;
+ }
+
+ if (self.movetype != MOVETYPE_WALK)
+ // gibbed by a trigger?
+ return;
+
+ if (cvar("sv_nostep"))
+ // no stepping. useful for testing -- CEV
+ return;
+
+ first_o = self.origin;
+ first_v = self.velocity;
+
+ self.origin = start_o;
+ self.velocity = start_v;
+
+ up = start_o;
+ up_z += PM_STEPHEIGHT;
+ tracebox (start_o, self.mins, self.maxs, up, FALSE, self);
+
+ if (trace_allsolid)
+ {
+ dprint ("phys_stepslidemove: can't step up\n");
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.flags |= FL_ONGROUND;
+ else
+ self.flags &= ~FL_ONGROUND;
+ return;
+ }
+
+ // try slidemove from this position (in air)
+ stepsize = trace_endpos_z - start_o_z;
+ self.origin = trace_endpos;
+ self.velocity = start_v;
+ clip = phys_q1flymove (dogravity, onesided);
+
+ // push down the final amount
+ down = self.origin;
+ down_z -= stepsize;
+ tracebox (self.origin, self.mins, self.maxs, down, FALSE, self);
+
+ if (trace_allsolid)
+ {
+ dprint ("phys_stepslidemove: second move is in a solid\n");
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.flags |= FL_ONGROUND;
+ else
+ self.flags &= ~FL_ONGROUND;
+ return;
+ }
+
+ if (!trace_plane_normal_z || trace_plane_normal_z > 0.7)
+ {
+ // we're on 'good ground', accept the second slidemove
+ // dprint ("phys_stepslidemove: accepting second slidemove\n");
+ self.origin = trace_endpos;
+ if (trace_fraction < 1.0)
+ {
+ // if (onesided)
+ // dprint ("phys_stepslidemove: onesided\n");
+ // clip to step
+ self.velocity = phys_clipvelocity (self.velocity,
+ trace_plane_normal, PM_OVERCLIP, onesided);
+ }
+ if (trace_plane_normal_z > 0.7)
+ self.flags |= FL_ONGROUND;
+ else
+ self.flags &= ~FL_ONGROUND;
+ }
+ else
+ {
+ // not on 'good ground', revert to first slidemove
+ // see the similar section of SV_WalkMove
+ // dprint ("phys_stepslidemove: reverting to first move\n");
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.flags |= FL_ONGROUND;
+ else
+ self.flags &= ~FL_ONGROUND;
+ }
+
+ // this is a complicated check.
+ // if we started in the air and we're now on the ground
+ // and we stepped up and we lost some Z velocity then we've
+ // clipped to ground on a step up
+ if (!start_onground && (self.flags & FL_ONGROUND) &&
+ (start_v_z > self.velocity_z) &&
+ (self.velocity_z < 1) &&
+ (self.origin_z - start_o_z > 0))
+ {
+ if (!self.boost_time &&
+ self.boost_time <= time - PM_BOOST_WINDOW)
+ self.boost_time = time;
+
+ if (cvar("developer"))
+ {
+ stepsize = self.origin_z - start_o_z;
+ dprint ("phys_stepslidemove: step up: ");
+ dprint (ftos(stepsize));
+ dprint ("\n");
+ }
+ }
+};
+
+// based on the GPL2 Quake 3 sourcecode. No idea what it does other than
+// make strafejumping feel, I dunno, more "right". -- CEV
+float(float speed, float forward, float side, float up) phys_pm_cmdscale =
+{
+ float scale, total;
+ int max;
+
+ max = fabs (forward);
+ if (fabs(side) > max)
+ max = fabs (side);
+ if (fabs(up) > max)
+ max = fabs (up);
+ if (!max)
+ return 0;
+
+ total = sqrt (forward * forward + side * side + up * up);
+ scale = speed * max / (127.0 * total);
+
+ return scale;
+};
+
+void(float friction) phys_friction =
+{
+ float control, newspeed, speed;
+
+ speed = vlen(self.velocity);
+
+ if (speed < 1)
+ {
+ self.velocity = '0 0 0';
+ return;
+ }
+
+ // calculate what their new speed should be
+ control = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
+ newspeed = speed - control * friction * input_timelength;
+
+ // and slow them
+ if (newspeed < 0) newspeed = 0;
+ self.velocity = self.velocity * (newspeed / speed);
+};
+
+// function based on GPL2 purecsqc pmove.qc
+void() phys_categorizeposition =
+{
+ vector p;
+ float pc;
+
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ // noclip is never on ground
+ self.flags &= ~FL_ONGROUND;
+ }
+ else
+ {
+ tracebox(self.origin, self.mins, self.maxs,
+ self.origin - PM_GROUNDDIST_V, FALSE, self);
+ // only onground if we hit it, it faces upwards,
+ // and we're actually moving towards it
+ // if (trace_fraction < 1 && trace_plane_normal_z > 0.7 &&
+ // self.velocity * trace_plane_normal < 0.01)
+ if (trace_fraction < 1 && trace_plane_normal_z > 0.7)
+ {
+ // on ground
+ self.flags |= FL_ONGROUND;
+ self.flags &= ~FL_WALLJUMP;
+ self.groundnormal = trace_plane_normal;
+ self.groundentity = trace_ent;
+ }
+ else
+ {
+ // not on ground
+ self.flags &= ~FL_ONGROUND;
+ self.groundnormal = __NULL__;
+ self.groundentity = __NULL__;
+ }
+ }
+
+ // clear doublejumped if outside of DOUBLEJUMP_COOLDOWN
+ if ((self.flags & FL_DOUBLEJUMPED)
+ && self.jump_time < (time - PM_DOUBLEJUMP_COOLDOWN))
+ {
+ // dprint ("phys_categorize: clear FL_DOUBLEJUMPED\n");
+ self.flags &= ~FL_DOUBLEJUMPED;
+ }
+
+ // check water levels
+ p = self.origin;
+ p_z = self.origin_z + self.mins_z + 1;
+ pc = pointcontents(p);
+ if (pc < CONTENT_SOLID)
+ {
+ self.watertype = pc;
+ p_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5;
+ if (pointcontents(p) < CONTENT_SOLID)
+ {
+ p_z = self.origin_z + self.maxs_z;
+ if (pointcontents(p) < CONTENT_SOLID)
+ self.waterlevel = 3;
+ else
+ self.waterlevel = 2;
+ }
+ else
+ self.waterlevel = 1;
+ }
+ else
+ {
+ self.watertype = CONTENT_EMPTY;
+ self.waterlevel = 0;
+ }
+};
+
+void(vector wishdir, float wishspeed, float accel) phys_accelerate =
+{
+ float addspeed, accelspeed, curspeed;
+
+ curspeed = self.velocity * wishdir;
+ addspeed = wishspeed - curspeed;
+
+ if (addspeed <= 0) return;
+
+ accelspeed = accel * input_timelength * wishspeed;
+ if (accelspeed > addspeed) accelspeed = addspeed;
+
+ self.velocity = self.velocity + accelspeed * wishdir;
+};
+
+void(vector wishvel, float wishspeed, float accel) phys_q1airaccelerate =
+{
+ float addspeed, wishspd, accelspeed, currentspeed;
+
+ currentspeed = self.velocity * wishvel;
+
+ wishvel = normalize (wishvel);
+ wishspd = vlen (wishvel);
+ if (wishspd > PM_MAXAIRSPEED) wishspd = PM_MAXAIRSPEED;
+
+ addspeed = wishspd - currentspeed;
+ if (addspeed <= 0) return;
+
+ accelspeed = accel * input_timelength * wishspeed;
+ if (accelspeed > addspeed) accelspeed = addspeed;
+
+ self.velocity = self.velocity + accelspeed * wishvel;
+};
+
+// based on code from Xonotic -- CEV
+void(vector wishdir, float wishspeed, float accel) phys_aircontrol =
+{
+ float addspeed, accelspeed, curspeed, speed, dot, k, z;
+
+ z = self.velocity_z;
+ self.velocity_z = 0;
+ speed = vlen (self.velocity);
+ curspeed = self.velocity * wishdir;
+ addspeed = wishspeed - curspeed;
+
+ self.velocity = normalize (self.velocity);
+ dot = self.velocity * wishdir;
+ k = 4800 * dot * dot * input_timelength;
+
+ if (dot > 0)
+ self.velocity = self.velocity * speed + wishdir * k;
+
+ self.velocity = normalize (self.velocity);
+ self.velocity = self.velocity * speed;
+
+ if (addspeed > 0)
+ {
+ accelspeed = accel * input_timelength * wishspeed;
+ if (accelspeed > addspeed) accelspeed = addspeed;
+
+ self.velocity = self.velocity + accelspeed * wishdir;
+ }
+
+ self.velocity_z = z;
+};
+
+void() phys_jump =
+{
+ // are we already waterjumping?
+ if (self.flags & FL_WATERJUMP) return;
+
+ // are we noclipping?
+ if (self.movetype == MOVETYPE_NOCLIP) return;
+
+ // don't pogo
+ if (!(self.flags & FL_JUMPRELEASED)) return;
+
+ // don't let the player jump more often than JUMP_WINDOW -- CEV
+ if ((self.jump_time) && (self.jump_time > time - PM_JUMP_WINDOW))
+ return;
+
+ // player jumping sound
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
+
+ // make sure we get at least jumpspeed upwards from
+ // the ground plane by clamping it first.
+ if (self.groundnormal && (self.velocity * self.groundnormal < 0))
+ {
+ // dprint("phys_jump: clamping to ground\n");
+ self.velocity -= self.groundnormal *
+ (self.velocity * self.groundnormal);
+ }
+
+ // teleport jumps; allow a larger (+0.2) window to account for
+ // time to travel thru teleporter. -- CEV
+ if ((self.jump_time > time - PM_TELEJUMP_WINDOW) &&
+ (self.teleport_time > time - (PM_TELEJUMP_WINDOW + 0.2)))
+ {
+ dprint("phys_jump: telejump\n");
+ self.velocity_z += PM_TELEJUMPSPEED;
+ if !(self.flags & FL_DOUBLEJUMPED)
+ self.flags |= FL_DOUBLEJUMPED;
+ }
+ // A doublejump is two jumps within 400ms, usually +50% Z velocity.
+ else if (self.jump_time > (time - PM_DOUBLEJUMP_WINDOW))
+ {
+ if (self.boost_time && self.boost_time > time - PM_BOOST_WINDOW)
+ dprint("phys_jump: stairjump\n");
+ else
+ dprint("phys_jump: doublejump\n");
+ if (self.flags & FL_DOUBLEJUMPED)
+ {
+ self.velocity_z += PM_TRIPLEJUMPSPEED;
+ }
+ else
+ {
+ self.velocity_z += PM_DOUBLEJUMPSPEED;
+ self.flags |= FL_DOUBLEJUMPED;
+ }
+ }
+ // normal jump
+ else
+ {
+ self.velocity_z += PM_JUMPSPEED;
+ }
+
+ // clear flags
+ self.flags &~= FL_ONGROUND;
+ self.flags &~= FL_JUMPRELEASED;
+ self.button2 = 0;
+ // clear ground fields
+ self.groundnormal = __NULL__;
+ self.groundentity = __NULL__;
+ // timers
+ self.jump_time = time;
+ if (self.boost_time)
+ {
+ // dprint ("phys_jump: clearing boost_time\n");
+ self.boost_time = 0;
+ }
+};
+
+void(vector checkdir) phys_walljump =
+{
+ // is our upward speed greater than walljump speed?
+ if (self.velocity_z > PM_WALLJUMPSPEED) return;
+
+ // are we already waterjumping?
+ if (self.flags & FL_WATERJUMP) return;
+
+ // are we already walljumping?
+ if (self.flags & FL_WALLJUMP) return;
+
+ // are we noclipping?
+ if (self.movetype == MOVETYPE_NOCLIP) return;
+
+ // don't pogo
+ if (!(self.flags & FL_JUMPRELEASED)) return;
+
+ // don't let the player jump more often than WALLJUMP_WINDOW -- CEV
+ if ((self.jump_time) && (self.jump_time > time - PM_WALLJUMP_WINDOW))
+ return;
+
+ // TODO CEV
+ return;
+
+ // don't walljump if within 32 units of ground
+ tracebox (self.origin, self.mins, self.maxs,
+ self.origin - PM_WALLDIST_V, FALSE, self);
+ if (trace_fraction < 1) return;
+
+ tracebox (self.origin, self.mins, self.maxs,
+ self.origin + self.velocity * 100, FALSE, self);
+ if (trace_fraction < 1 && trace_plane_normal_z < 0.2 &&
+ (vlen(self.origin - trace_endpos) < 10))
+ {
+ dprint ("phys_walljump: walljump dist ");
+ dprint (ftos(vlen(self.origin - trace_endpos)));
+ dprint ("\n");
+ // player jumping sound
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
+ // modify X and Y velocity
+ self.velocity_x += trace_plane_normal_x * PM_WALLJUMPFORCE;
+ self.velocity_y += trace_plane_normal_y * PM_WALLJUMPFORCE;
+ // now modify Z
+ if (self.jump_time > (time - PM_DOUBLEJUMP_WINDOW))
+ {
+ self.velocity_z += PM_DOUBLEJUMPSPEED;
+ // if (self.velocity_z > PM_DOUBLEJUMPSPEED)
+ // self.velocity_z = PM_DOUBLEJUMPSPEED;
+ }
+ else if (self.velocity_z < (PM_WALLJUMPSPEED / 0.5))
+ self.velocity_z = PM_WALLJUMPSPEED;
+ else
+ self.velocity_z += PM_WALLJUMPSPEED;
+ // set walljump flag
+ self.flags |= FL_WALLJUMP;
+ // clear misc flags & ground fields
+ self.button2 = 0;
+ self.groundnormal = __NULL__;
+ self.groundentity = __NULL__;
+ // set jump timer
+ self.jump_time = time;
+ }
+};
+
+void() phys_waterjump =
+{
+ // can't be waterjumping if we're on ground
+ if ((self.flags & FL_WATERJUMP) &&
+ (((time > self.teleport_time) && !(self.waterlevel)) ||
+ (self.flags & FL_ONGROUND)))
+ {
+ dprint ("phys_waterjump: clearing FL_WATERJUMP\n");
+ self.flags &= ~FL_WATERJUMP;
+ self.teleport_time = 0;
+ }
+};
+
+int() phys_walkaccelerate =
+{
+ vector forward, right, up;
+ vector wishvel, wishdir, wishang;
+ vector curang;
+ float tempf, wishspeed;
+ int onesided;
+
+ onesided = FALSE;
+
+ makevectors (input_angles);
+
+ forward = v_forward;
+ right = v_right;
+ up = v_up;
+
+ forward_z = 0;
+ right_z = 0;
+ forward = normalize (forward);
+ right = normalize (right);
+
+ wishvel = forward * input_movevalues_x + right * input_movevalues_y;
+ if (self.movetype != MOVETYPE_WALK)
+ wishvel_z = input_movevalues_z;
+
+ wishspeed = vlen (wishvel);
+ wishdir = normalize (wishvel);
+
+ /*
+ * TODO CEV 2023-09
+ if (self.primal_speed > PM_MAXSPEED * 0.1)
+ {
+ scale = phys_pm_cmdscale (self.primal_speed, input_movevalues_x,
+ input_movevalues_y, input_movevalues_z);
+ if (scale > 0) wishspeed *= scale;
+ }
+ */
+
+ if (wishspeed > PM_MAXSPEED) wishspeed = PM_MAXSPEED;
+
+ if (input_buttons & 2)
+ if (self.flags & FL_ONGROUND)
+ phys_jump ();
+ else
+ phys_walljump (right);
+ else
+ self.flags |= FL_JUMPRELEASED;
+
+ if (self.flags & FL_ONGROUND)
+ {
+ if (self.boost_time > time - PM_BOOST_WINDOW)
+ {
+ phys_friction (PM_BOOSTFRICTION);
+ phys_accelerate (wishdir, wishspeed, PM_BOOSTACCEL);
+ }
+ else
+ {
+ phys_friction (PM_FRICTION);
+ phys_accelerate (wishdir, wishspeed, PM_GROUNDACCEL);
+ }
+ }
+ else
+ {
+ // Q3 strafejumping if requesting both X and Y
+ // -- CEV
+ if (input_movevalues_x && input_movevalues_y)
+ {
+ phys_accelerate (wishdir, wishspeed, PM_AIRACCELQ3);
+ }
+ else
+ {
+ // I'm a little afraid doing this is expensive
+ // CPU-wise but it seems to be the right way.
+ // this is inspired by the old Slide mod -- CEV
+ if (self.primal_speed > 30)
+ {
+ wishang = vectoangles (wishdir);
+ curang = vectoangles (self.velocity);
+ wishang_y = anglemod (wishang_y);
+ curang_y = anglemod (curang_y);
+
+ tempf = fabs (wishang_y - curang_y);
+ if (tempf >= 180) tempf = fabs (tempf - 360);
+ /*
+ dprint ("phys_walkaccelerate: tempf ");
+ dprint (ftos(tempf));
+ dprint (", input_movevalues_x: ");
+ dprint (ftos(input_movevalues_x));
+ dprint (", input_movevalues_y: ");
+ dprint (ftos(input_movevalues_y));
+ dprint ("\n");
+ */
+ }
+ else
+ {
+ tempf = 0;
+ }
+
+ // Q1 air control when requesting movement within
+ // 45 to 130 degrees of current movement -- CEV
+ if ((tempf > 45) && (tempf < 135))
+ {
+ phys_q1airaccelerate (wishvel, wishspeed,
+ PM_AIRACCEL);
+ }
+ // +direction style air control otherwise -- CEV
+ else
+ {
+ phys_aircontrol (wishdir, wishspeed,
+ PM_AIRACCELFWD);
+ }
+ }
+ }
+ return onesided;
+};
+
+void(float scale) phys_noclipaccelerate =
+{
+ vector wishdir;
+ float wishspeed;
+
+ makevectors (input_angles);
+
+ wishdir = v_forward * input_movevalues_x +
+ v_right * input_movevalues_y +
+ v_up * input_movevalues_z;
+
+ if (input_buttons & 2)
+ // should be water:100, slime:80, lava:50, but lets
+ // just bake smartjump in here instead (we don't have
+ // the client's cl_upspeed value in ssqc though).
+ wishdir_z = max (PM_MAXSPEED, wishdir_z);
+ else if (wishdir == '0 0 0' && scale < 1)
+ wishdir_z = -PM_WATERSINKSPEED;
+
+ wishspeed = vlen (wishdir) * scale;
+ wishdir = normalize (wishdir);
+
+ phys_friction (PM_FRICTION);
+ phys_accelerate (wishdir, wishspeed, PM_GROUNDACCEL);
+};
+
+void(entity ent) phys_move =
+{
+ float dogravity, onesided;
+
+ self = ent;
+ onesided = FALSE;
+
+ phys_nudge ();
+ phys_categorizeposition ();
+ phys_waterjump ();
+
+ if (self.boost_time && self.boost_time <= time - PM_BOOST_WINDOW)
+ {
+ // Clear the boost timer if it's set
+ // dprint ("phys_move: clearing boost_time\n");
+ self.boost_time = 0;
+ }
+
+ if (input_timelength >= 0)
+ {
+ switch(self.movetype)
+ {
+ case MOVETYPE_WALK:
+ if (self.waterlevel >= 2)
+ {
+ phys_noclipaccelerate (0.7);
+ // water friction
+ self.velocity -= 0.8 * self.waterlevel *
+ input_timelength * self.velocity;
+ }
+ else
+ onesided = phys_walkaccelerate ();
+
+ // onesided if outside DOUBLEJUMP_WINDOW time
+ if (self.jump_time <= (time - PM_DOUBLEJUMP_WINDOW))
+ onesided = TRUE;
+
+ // don't stick to the floor when stepping up if we've
+ // doublejumped recently
+ if (self.flags & FL_DOUBLEJUMPED)
+ onesided = TRUE;
+
+ // don't stick to the floor when jumping out of water
+ if ((self.flags & FL_WATERJUMP) ||
+ (self.flags & FL_WALLJUMP))
+ onesided = TRUE;
+
+ // apply gravity when in the air
+ dogravity = !(self.flags & FL_ONGROUND);
+
+ // apply gravity when we're on a ramp
+ if (self.groundnormal && self.groundnormal_z < 1 &&
+ self.groundnormal_z > 0.7)
+ dogravity = TRUE;
+
+ phys_stepslidemove (dogravity, onesided);
+ break;
+ case MOVETYPE_FLY:
+ phys_noclipaccelerate (1.0);
+ phys_slidemove (FALSE);
+ break;
+ case MOVETYPE_NOCLIP:
+ phys_noclipaccelerate (1.0);
+ self.origin += self.velocity * input_timelength;
+ break;
+ case MOVETYPE_NONE:
+ break;
+ }
+
+ if (self.groundentity)
+ phys_dotouch (self.groundentity);
+ phys_categorizeposition ();
+ touchtriggers (self);
+ }
+ else print(sprintf("phys_move: timelength %g\n", input_timelength));
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/progs.src

diff --git a/qc/progs.src b/qc/progs.src
index 381f092..1655f8d 100644
--- a/qc/progs.src
+++ b/qc/progs.src
@@ -1,76 +1,79 @@
-../progs.dat
-#pragma autoproto
-
-fteopts.qc
-defs_globalvars.qc // globalvars_t
-defs_entvars.qc // entvars_t
-defs_builtins.qc // builtin functions (& overrides)
-defs_misc.qc // additional
-newflags.qc // new spawnflags for all entities
-math.qc // Code by Joshua Skelton
-utility.qc
-
-subs.qc // modified targets, triggers and killtargets
-
-fight.qc
-custom_snd.qc // mapper-settable sound FX for monsters - iw
-custom_mdls.qc // mapper-settable models for monsters - iw
-ai.qc
-combat.qc
-keydata.qc // functions which deal with key item bitflags + names
-items.qc
-weapons.qc
-world.qc
-intermission.qc
-client.qc
-cutscene.qc // Drake version -- dumptruck_ds
-player.qc
-keylock.qc // common code for entities unlockable with keys
-doors.qc
-buttons.qc
-triggers.qc // added trigger_push_custom based on Hipnotic
-plats.qc
-misc.qc
-lights.qc // c0burn's excellent switchable lights
-fog.qc // fog triggers
-cshift.qc // background color shift controller
-
-// monsters
-monsters.qc // modified by dumptruck_ds from Preach's
- // spawning tutorial | fish count fixed
-monsters/boss.qc
-monsters/boss2.qc // killable Chthon
-monsters/dog.qc
-monsters/demon.qc
-monsters/knight.qc
-monsters/ogre.qc
-monsters/shambler.qc
-monsters/soldier.qc
-monsters/wizard.qc
-monsters/zombie.qc // modified ver. of Ace_Dave's zombies from Rubicon2
-monsters/enforcer.qc // registered
-monsters/fish.qc // registered
-monsters/hknight.qc // registered
-monsters/oldone.qc // registered
-monsters/oldone2.qc // killable Shub
-monsters/shalrath.qc // registered
-
-dtmisc.qc // sound code from Hipnotic & Rubicon Rumble
- // and misc visual effects
-
-misc_model.qc // Code by Joshua Skelton
-
-hip_count.qc // Hipnotic counter
-hip_part.qc // Hipnotic particlefield and func_togglewall
-hip_rotate.qc // from Hipnotic thanks RennyC
-hip_trig.qc // Hipnotic triggers qc
-doe_elbutton.qc // Rogue elevator code
-doe_ltrail.qc // from DOE lightnin.qc
-doe_plats.qc // Rogue MP newplats.qc
-
-rubicon2.qc // selections from Rubicon2 QC
-dtquake.qc // triggerable earthquake from Zer cutscenes
-func_bob.qc // RennyC's stand alone version based on AD
-func_fall2.qc // Renny's improved version.
-mobot.qc // Using "bot" creation code for func_monster_spawner
-
+../progs.dat
+#pragma autoproto
+
+fteopts.qc
+defs_constants.qc // compiler defines (fixed constant values)
+defs_globalvars.qc // globalvars_t
+defs_entvars.qc // entvars_t
+defs_builtins.qc // builtin functions (& overrides)
+defs_misc.qc // additional
+newflags.qc // new spawnflags for all entities
+math.qc // Code by Joshua Skelton
+utility.qc
+
+subs.qc // modified targets, triggers and killtargets
+
+fight.qc
+custom_snd.qc // mapper-settable sound FX for monsters - iw
+custom_mdls.qc // mapper-settable models for monsters - iw
+ai.qc
+combat.qc
+keydata.qc // functions which deal with key item bitflags + names
+items.qc
+weapons.qc
+world.qc
+intermission.qc
+pmove.qc // QC player movement code -- CEV
+sv_runclient.qc // hook into SV_RunClientCommand FTE extension -- CEV
+client.qc
+cutscene.qc // Drake version -- dumptruck_ds
+player.qc
+keylock.qc // common code for entities unlockable with keys
+doors.qc
+buttons.qc
+triggers.qc // added trigger_push_custom based on Hipnotic
+plats.qc
+misc.qc
+lights.qc // c0burn's excellent switchable lights
+fog.qc // fog triggers
+cshift.qc // background color shift controller
+
+// monsters
+monsters.qc // modified by dumptruck_ds from Preach's
+ // spawning tutorial | fish count fixed
+monsters/boss.qc
+monsters/boss2.qc // killable Chthon
+monsters/dog.qc
+monsters/demon.qc
+monsters/knight.qc
+monsters/ogre.qc
+monsters/shambler.qc
+monsters/soldier.qc
+monsters/wizard.qc
+monsters/zombie.qc // modified ver. of Ace_Dave's zombies from Rubicon2
+monsters/enforcer.qc // registered
+monsters/fish.qc // registered
+monsters/hknight.qc // registered
+monsters/oldone.qc // registered
+monsters/oldone2.qc // killable Shub
+monsters/shalrath.qc // registered
+
+dtmisc.qc // sound code from Hipnotic & Rubicon Rumble
+ // and misc visual effects
+
+misc_model.qc // Code by Joshua Skelton
+
+hip_count.qc // Hipnotic counter
+hip_part.qc // Hipnotic particlefield and func_togglewall
+hip_rotate.qc // from Hipnotic thanks RennyC
+hip_trig.qc // Hipnotic triggers qc
+doe_elbutton.qc // Rogue elevator code
+doe_ltrail.qc // from DOE lightnin.qc
+doe_plats.qc // Rogue MP newplats.qc
+
+rubicon2.qc // selections from Rubicon2 QC
+dtquake.qc // triggerable earthquake from Zer cutscenes
+func_bob.qc // RennyC's stand alone version based on AD
+func_fall2.qc // Renny's improved version.
+mobot.qc // Using "bot" creation code for func_monster_spawner
+

Return to the top of this page or return to the overview of this repo.

Diff qc/rubicon2.qc

diff --git a/qc/rubicon2.qc b/qc/rubicon2.qc
index 0e9280f..4e54653 100644
--- a/qc/rubicon2.qc
+++ b/qc/rubicon2.qc
@@ -1,1010 +1,1010 @@
-//selections from Rubicon 2 qc by john fitzgibbons
-//and AD breakable code modified by Qmaster,iw and dumptruck_ds
-float BREAKABLE_NO_MONSTERS = 1;
-float BREAK_EXPLODE = 2;
-float BREAK_CUSTOM = 4;
-float START_OFF = 1;
-float SPARKS_BLUE = 2;
-float SPARKS_PALE = 4;
-
-void() make_breakable_debris;
-
-/*
-===============================================================================
-func_explobox
-===============================================================================
-*/
-
-void () func_explobox_explode_silent =
-{
- self.takedamage = DAMAGE_NO;
- self.origin = ((self.absmin + self.absmax) * 0.5);
- self.classname = "explo_box";
- T_RadiusDamage (self, self, self.dmg, 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);
- BecomeExplosion ();
-
-};
-
-void () func_explobox_explode = {
- // sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- func_explobox_explode_silent();
-};
-
-void () func_explobox_die =
-{
- self.nextthink = 0.2; //for some reason, time + 0.2 doesn't work
- self.think = func_explobox_explode;
-};
-
-/*QUAKED func_explobox (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-An exploding brush entity. Works just like misc_explobox.
-
-Keys:
-
-"health" Default 20
-
-"dmg" default 100
-
-*/
-void () func_explobox =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- precache_sound ("weapons/r_exp3.wav");
- if (!self.health)
- {
- self.health = 20;
- }
- if (!self.dmg)
- {
- self.dmg = 100;
- }
- self.th_die = func_explobox_die;
- self.takedamage = DAMAGE_AIM;
-};
-
-
-/*
-===============================================================================
-func_breakable
-===============================================================================
-*/
-
-.string break_template1;
-.string break_template2;
-.string break_template3;
-.string break_template4;
-.string break_template5;
-.float brk_obj_count1;
-.float brk_obj_count2;
-.float brk_obj_count3;
-.float brk_obj_count4;
-.float brk_obj_count5;
-
-
-// template system from Qmaster -- dumptruck_ds
-void() make_breakable_templates_debris = {
- local float i;
- local entity new;
-
- i = 0;
- if (self.break_template1 != "") {
- while (i < self.brk_obj_count1) {
- new = spawn();
- new.model = self.break_template1;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template2 != "") {
- while (i < self.brk_obj_count2) {
- new = spawn();
- new.model = self.break_template2;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template3 != "") {
- while (i < self.brk_obj_count3) {
- new = spawn();
- new.model = self.break_template3;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template4 != "") {
- while (i < self.brk_obj_count4) {
- new = spawn();
- new.model = self.break_template4;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template5 != "") {
- while (i < self.brk_obj_count5) {
- new = spawn();
- new.model = self.break_template5;
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- setmodel (new, new.model); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
- i++;
- }
- }
-};
-
-
-//Below this is from Rubicon2 -- dumptruck_ds
-
-void() make_breakable_debris = {
- local float i;
- i = 0;
- while (i < self.cnt)
- {
- local entity new;
-
- new = spawn();
- new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
- // setmodel (new, "progs/debris.mdl"); this was originally just an mdl from Rubicon2, now you set custom model via spawnflag or use the builtin from Rubicon2 -- dumptruck_ds
- setmodel (new, self.mdl_debris); //dumptruck_ds
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health*2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random()*600;
- new.avelocity_y = random()*600;
- new.avelocity_z = random()*600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random()*10;
- new.flags = 0;
-
- // randomly choose size
- if (random() > 0.333)
- new.frame = 1; //larger
- else
- new.frame = 2; //smaller
-
- // choose skin based on "style" key
- if (self.style == 1)
- new.skin = 1;
- if (self.style == 2)
- new.skin = 2;
- if (self.style == 3) // new debris skins start here - dumptruck_ds
- new.skin = 3;
- if (self.style == 4)
- new.skin = 4;
- if (self.style == 5)
- new.skin = 5;
- if (self.style == 6)
- new.skin = 6;
- if (self.style == 7)
- new.skin = 7;
- if (self.style == 8)
- new.skin = 8;
- if (self.style == 9)
- new.skin = 9;
- if (self.style == 10)
- new.skin = 10;
- if (self.style == 11)
- new.skin = 11;
- if (self.style == 12)
- new.skin = 12;
- if (self.style == 13)
- new.skin = 13;
- if (self.style == 14)
- new.skin = 14;
- if (self.style == 15)
- new.skin = 15;
- if (self.style == 16)
- new.skin = 16;
- if (self.style == 17)
- new.skin = 17;
- if (self.style == 18)
- new.skin = 18;
- if (self.style == 19)
- new.skin = 19;
- if (self.style == 20)
- new.skin = 20;
- if (self.style == 21)
- new.skin = 21;
- if (self.style == 22)
- new.skin = 22;
- if (self.style == 23)
- new.skin = 23;
- if (self.style == 24)
- new.skin = 24;
- if (self.style == 25)
- new.skin = 25;
- if (self.style == 26)
- new.skin = 26;
- if (self.style == 27)
- new.skin = 27;
- if (self.style == 28)
- new.skin = 28;
- if (self.style == 29)
- new.skin = 29;
- if (self.style == 30)
- new.skin = 30;
- if (self.style == 31)// new debris skins end here - dumptruck_ds
- new.skin = 31;
-
- i = i + 1;
- }
-};
-
-void () func_breakable_die = {
- //dumptruck_ds -- set the spawnflag for cosmetic explosion effect; use "dmg" value to hurt the player
- {
- local entity ent; //thanks to Qmaster!!! He helped me sort out noise1 playing from 0 0 0 with this temp entity - dumptruck_ds
-
- ent = spawn();
- ent.origin = ((self.absmin + self.absmax) * 0.5);
- setsize (ent, '0 0 0', '0 0 0');
- ent.solid = SOLID_NOT;
- ent.think = SUB_Remove;
- // ent.ltime = time;
- ent.nextthink = time + 60;
-
- sound(ent, CHAN_AUTO, self.noise1, 1, ATTN_NORM);
- // remove (self);
- }
-
- // this is to ensure that any debris from another func_breakable
- // which is resting on top of this func_breakable is not left
- // floating in mid-air after this entity is removed -- iw
- SUB_DislodgeRestingEntities ();
-
- if (self.spawnflags & BREAK_EXPLODE) {
- if (self.spawnflags & BREAK_CUSTOM) {
- make_breakable_templates_debris ();
- } else {
- make_breakable_debris ();
- }
- func_explobox_explode_silent(); // to let us use noise2
- // sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); this is broken as of 1.1.0 no custom explosion sound for now -- dumptruck_ds
- remove (self);
- } else {
- self.origin = ((self.absmin + self.absmax) * 0.5);
- setorigin (self, self.origin);
- DropStuff();
- if (self.spawnflags & BREAK_CUSTOM) {
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- make_breakable_templates_debris ();
- remove (self);
- } else {
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
- make_breakable_debris ();
- remove (self);
- }
- }
-};
-
-void () func_breakable_killed =
-{
- activator = damage_attacker;
- SUB_UseTargets ();
- func_breakable_die ();
-};
-
-void () func_breakable_use =
-{
- activator = other;
- SUB_UseTargets ();
- func_breakable_die ();
-};
-
-/*QUAKED func_breakable (0 .5 .8) ? NO_MONSTERS X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-"Breakable - See manual for full details
-
-Defaults to built-in .mdl file with 32 styles, cnt is number of pieces of debris to spawn (built-in only)
-Or use spawnflag 4 and break_template1-4 to set path of custom .mdl or .bsp models.
-brk_object_count1-4 sets the number of pieces of each break_template when using custom .mdl or bsp models.
-If noise1 is not set it will default to various sounds in sounds/break folder
-Use spawnflag 2 for an explosion, dmg is amount of damage inflicted"
-
-spawnflags(flags)
-1 : "No Monster Damage" : 0 : "Only the player can break"
-2 : "Explosion" : 0 : "Produces explosion effect and sound"
-4 : "Use custom mdls or bsp models" : 0 : "Uses models specified in break_template1, 2, etc"
-
-style(choices) : "Built-in debris style" : 0
-0 : "Green Metal (default)"
-1 : "Red Metal"
-2 : "Concrete"
-3 : "Pine wood"
-4 : "Brown wood"
-5 : "Red wood"
-6 : "Stained Glass Yellow Flames"
-7 : "Stained Glass Red Rays"
-8 : "Stained Glass Yellow Dragon"
-9 : "Stained Glass Blue Dragon"
-10 : "Stained Glass Red Dragon"
-11 : "Light Copper"
-12 : "Dark Copper"
-13 : "Tan Bricks Large"
-14 : "Brown Bricks Large"
-15 : "Green Bricks Large"
-16 : "Generic Light Brown"
-17 : "Red Brown Computer"
-18 : "Grey Black Computer"
-19 : "Blue Green Metal"
-20 : "Blue Green Runic Wall"
-21 : "Brown Metal"
-22 : "Dark Brown Metal"
-23 : "Medium Brown Metal"
-24 : "Blue Metal"
-25 : "Green Stonework"
-26 : "Blue Stonework"
-27 : "Brown Bricks"
-28 : "Tan Blue Bricks"
-29 : "Red Bricks"
-30 : "Blue Bricks"
-31 : "Metal Rivets"
-
-noise1(string) : "Break noise (overrides default sounds)"
-cnt(integer) : "Number of pieces of debris to spawn" : 5
-health(integer) : "Health of breakable" : 20
-dmg(integer) : "Amount of Explosive Damage" : 20
-break_template1(string) : "Template 1 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template2(string) : "Template 2 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template3(string) : "Template 3 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template4(string) : "Template 4 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-break_template5(string) : "Template 5 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
-brk_obj_count1(integer) : "Template 1 spawn count"
-brk_obj_count2(integer) : "Template 2 spawn count"
-brk_obj_count3(integer) : "Template 3 spawn count"
-brk_obj_count4(integer) : "Template 4 spawn count"
-brk_obj_count5(integer) : "Template 5 spawn count"
-*/
-
-void() break_template_setup = {
- if (self.break_template1 != "") precache_model(self.break_template1);
- if (self.break_template2 != "") precache_model(self.break_template2);
- if (self.break_template3 != "") precache_model(self.break_template3);
- if (self.break_template4 != "") precache_model(self.break_template4);
- if (self.break_template5 != "") precache_model(self.break_template5);
-};
-
-void () func_breakable = {
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- break_template_setup();
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- self.mdl_debris = "progs/debris.mdl";
- precache_model (self.mdl_debris);
- precache_sound ("blob/hit1.wav");
-
- if (self.noise1 != "") precache_sound(self.noise1);
-// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
-// here's genreic metal breaking
- if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
- || self.style == 24 || self.style == 31)
- if !(self.noise1)
- {
- precache_sound("break/metal2.wav");
- self.noise1 = "break/metal2.wav";
- }
- if (self.style == 3 || self.style == 4 || self.style == 5)
- if !(self.noise1)
- {
- precache_sound("break/wood1.wav");
- precache_sound("break/wood2.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/wood1.wav";
- else
- self.noise1 = "break/wood2.wav";
- }
- // glass sounds -- this is more of a shattering sound anyway
- if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
- if !(self.noise1)
- {
- precache_sound("break/metal1.wav");
- self.noise1 = "break/metal1.wav";
- }
- if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
- || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
- || self.style == 22 || self.style == 23)
- if !(self.noise1)
- {
- precache_sound("break/stones1.wav");
- precache_sound("break/bricks1.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/bricks1.wav";
- else
- self.noise1 = "break/stones1.wav";
- }
- if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
- if !(self.noise1)
- {
- precache_sound("break/stones1.wav");
- precache_sound("break/bricks1.wav");
- if (random() > 0.6) // wood only randomized
- self.noise1 = "break/stones1.wav";
- else
- self.noise1 = "break/bricks1.wav";
- }
- // else
- // (self.noise1 = "blob/hit1.wav");
-
- if (!self.health)
- self.health = 20;
- if (!self.cnt)
- self.cnt = 5; // was 6 dumptruck_ds
-
- if (self.targetname != "")
- {
- self.use = func_breakable_use;
- }
- else
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = func_breakable_killed;
- }
-
- if (self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
-};
-
-/*
-===============================================================================
-trigger_ladder
-===============================================================================
-*/
-
-void() ladder_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch()) return;
-
- // prevent the player "sticking" to a ladder if they are standing on
- // the platform at the top of the ladder with the bottom of their
- // bounding box flush with the top of the trigger -- iw
- if (other.absmin_z + 1 >= self.absmax_z - 1)
- return;
-
- // if the trigger has an angles field, check player's facing direction
- if (self.movedir != '0 0 0')
- {
- makevectors (other.angles);
- if (v_forward * self.movedir < 0)
- return; // not facing the right way
- }
- other.onladder = 1;
-}
-
-/*QUAKED trigger_ladder (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-invisible ladder entity. when player is touching this entity, he can climb by pushing 'jump'
-
-Keys:
-
-"angle" the direction player must be facing to climb ladder
-*/
-void() trigger_ladder =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- // ignore an "up" or "down" angle (doesn't make sense for a ladder)
- if (self.angles_y == -1 || self.angles_y == -2)
- {
- dprint ("WARNING: trigger_ladder ignored bad 'angle' value: ");
- dprint (ftos (self.angles_y));
- dprint ("\n");
-
- self.angles_y = 0;
- }
-
- InitTrigger ();
- self.touch = ladder_touch;
-
- SUB_CheckWaiting();
-};
-/*
-===============================================================================
-func_laser
-===============================================================================
-*/
-float LASER_SOLID = 2;
-.string message2;
-.float alpha;
-
-
-void() laser_helper_think =
-{
- if (!self.owner || self.owner.classname != "func_laser")
- {
- remove(self);
- return;
- }
-
-
- if (!(self.owner.spawnflags & START_OFF))
- self.owner.alpha = self.alpha * 0.8 + self.alpha * random() * 0.4;
-
- self.nextthink = time + 0.05;
-};
-
-void() func_laser_touch =
-{
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (other.takedamage && self.attack_finished < time)
- {
- T_Damage (other, self, self, self.dmg);
- self.attack_finished = time + 0.1;
- }
-
-};
-
-void () func_laser_use =
-{
- if (self.spawnflags & START_OFF)
- {
- setorigin(self, '0 0 0');
- self.spawnflags = self.spawnflags - START_OFF;
-
- // changed for progs_dump: the laser sound is now emitted from
- // the func_laser itself instead of from the activator -- iw
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- if (activator.classname == "player" && self.message != "")
- {
- centerprint (activator, self.message);
- }
- }
- else
- {
- // changed for progs_dump: the laser sound is now emitted from
- // the func_laser itself instead of from the activator -- iw
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-
- setorigin(self, '0 0 9000');
- self.spawnflags = self.spawnflags + START_OFF;
-
- if (activator.classname == "player" && self.message2 != "")
- {
- centerprint (activator, self.message2);
- }
- }
-};
-
-/*QUAKED func_laser (0 .5 .8) ? START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-A toggleable laser, hurts to touch, can be used to block players
-
-START_OFF: Laser starts off.
-
-LASER_SOLID: Laser blocks movement while turned on.
-
-Keys:
-
-"dmg" damage to do on touch. default 1
-
-"alpha" approximate alpha you want the laser drawn at. default 0.5. alpha will vary by 20% of this value.
-
-"message" message to display when activated
-
-"message2" message to display when deactivated
-
-*/
-void () func_laser =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- local entity helper;
-
- setmodel (self, self.model);
-
- precache_sound ("buttons/switch02.wav");
- precache_sound ("buttons/switch04.wav");
-
- if (self.spawnflags & LASER_SOLID)
- {
- self.solid = SOLID_BSP; //so you can shoot between lasers in a single bmodel
- self.movetype = MOVETYPE_PUSH; //required becuase of SOLID_BSP
- }
- else
- {
- self.solid = SOLID_TRIGGER;
- self.movetype = MOVETYPE_NONE;
- }
-
- if (!self.alpha)
- self.alpha = 0.5;
-
- if (!self.dmg)
- self.dmg = 1;
-
- self.use = func_laser_use;
- self.touch = func_laser_touch;
-
- if (self.spawnflags & START_OFF)
- setorigin(self, '0 0 9000');
- {
- if (self.noise != "") precache_sound(self.noise);
-
- else
- (self.noise = "buttons/switch02.wav");
- }
- {
- if (self.noise1 != "") precache_sound(self.noise1);
-
- else
- (self.noise1 = "buttons/switch04.wav");
- }
-
-
-
-
- //spawn a second entity to handle alpha changes, since MOVETYPE_PUSH doesn't support think functions
- helper = spawn();
- helper.alpha = self.alpha;
- helper.owner = self;
- helper.nextthink = 0.05;
- helper.think = laser_helper_think;
-};
-
-/*
-===============================================================================
-misc_sparks
-===============================================================================
-*/
-
-void() sparks_fade1 = [0, sparks_fade2] {self.alpha = 0.8; self.nextthink = time + 0.05;};
-void() sparks_fade2 = [0, sparks_fade3] {self.alpha = 0.6; self.nextthink = time + 0.05;};
-void() sparks_fade3 = [0, sparks_fade4] {self.alpha = 0.4; self.nextthink = time + 0.05;};
-void() sparks_fade4 = [0, SUB_Remove] {self.alpha = 0.2; self.nextthink = time + 0.05;};
-
-void() sparks_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
-
-void() make_sparks;
-
-void() spark_turnofflight =
-{
- SUB_UseTargets();
- self.think = make_sparks;
- self.nextthink = time + (random() + 0.5)*self.wait - 0.15;
-}
-
-void() make_sparks =
-{
-
- if (self.spawnflags & START_OFF)
- {
- self.nextthink = time + 0.1;
- self.think = make_sparks;
- }
- else
- {
- local float i;
- i = -0.25*self.cnt + random()*0.5*self.cnt;
- while (i < self.cnt)
- {
-
- local entity spark;
- spark = spawn();
- spark.owner = self;
- setmodel (spark, "progs/spark.mdl");
- setorigin (spark, self.origin);
- spark.movetype = MOVETYPE_BOUNCE;
- spark.solid = SOLID_TRIGGER;
- spark.gravity = 0.3;
- spark.velocity_x = -40 + random() * 80;
- spark.velocity_y = -40 + random() * 80;
- spark.velocity_z = -40 + random() * 80;
- spark.avelocity = '3000 3000 3000';
- spark.nextthink = time + 0.5 + 1.5*random();
- spark.think = sparks_fade1;
- spark.classname = "spark";
-
- if (random() < 0.33)
- spark.skin = 0;
- else if (random() < 0.5)
- spark.skin = 1;
- else
- spark.skin = 2;
-
- if (self.spawnflags & SPARKS_PALE)
- spark.skin = spark.skin + 6;
- else if (self.spawnflags & SPARKS_BLUE)
- spark.skin = spark.skin + 3;
-
- setsize (spark, '0 0 0', '0 0 0');
- i = i + 1;
- }
- if (self.sounds == 1)
- {
- if (self.noise != "")
- {
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_STATIC);
- }
- else
- sound (self, CHAN_AUTO, "enforcer/enfstop.wav", 1, ATTN_STATIC);
- }
- SUB_UseTargets();
- self.nextthink = time + 0.1 + random() * 0.1;
- self.think = spark_turnofflight;
-
- }
-
-};
-
-/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF SPARKS_BLUE SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.
-
-SPARKS_BLUE: sparks are blue in color
-
-SPARKS_PALE: sparks are pale yellow in color
-
-Keys:
-
-"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
-
-"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.
-
-"sounds"
-0) no sound
-1) sparks
-*/
-void() misc_sparks =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- precache_model ("progs/spark.mdl");
- if (!self.noise)
- precache_sound ("dump/spark.wav");
- else
- precache_sound (self.noise);
-
- if (!self.movedir)
- self.movedir = '0 0 -30';
- if (!self.wait)
- self.wait = 2;
- if (!self.cnt)
- self.cnt = 15;
-
- self.use = sparks_use;
- self.nextthink = time + random()*0.1;
- self.think = make_sparks;
-};
-
-/*
-===============================================================================
-misc_particles a.k.a. misc_splash
-===============================================================================
-*/
-void() splash_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
-
-void() splash_think =
-{
- if (self.spawnflags & START_OFF)
- {
- self.nextthink = time + 0.1;
- self.think = splash_think;
- }
- else
- {
- local vector vec;
- local float variance;
- variance = vlen(self.movedir) / 2;
- vec_x = self.movedir_x - variance + random() * variance * 2;
- vec_y = self.movedir_y - variance + random() * variance * 2;
- vec_z = self.movedir_z - variance + random() * variance * 2;
- particle (self.origin, vec, self.color, self.volume);
- self.nextthink = time + self.wait;
- }
-};
-
-//
-//misc_particles
-//
-// renamed from misc_splash (Rubcion 2) --dumptruck_ds
-//
-
-/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Produces a continuous particle splash for waterfalls and other effects
-
-"color" color of particles. 0 through 15, corresponds to a row of the quake palette. (default 0)
-
-"movedir" average movement vector of particles (default 0 0 4)
-
-"wait" time between particle generation cycles. (default 0.1)
-
-"volume" density of particles. (default 10)
-
-
-*/
-void() misc_particles =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if (!self.wait)
- self.wait = 0.1;
- if (!self.movedir)
- self.movedir = '0 0 4';
- if (!self.volume)
- self.volume = 10;
- self.color = self.color * 16;
-
- self.use = splash_use;
- self.nextthink = time + self.wait;
- self.think = splash_think;
-};
-
-//##########################################
-//#### Particle Sprayer ####
-//##########################################
-
-//this is from Custents not Rubicon2 -- dumptruck_ds
-//renamed from func to misc
-
-/*QUAKED misc_particlespray (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Shoots particles either when triggered, or contiuously when not triggered by anything.
-"color" is the palette color of the particles
-
-"count" is the number of particles to make each time
-
-"delay" is the delay between each triggering
-
-"noise" is the name of the wav file to play when triggered
-
-"movedir" is the vector distance that the particles will travel before disappearing. (in x y z)
-
-"duration" is the amount of time that the it will continue to release particles so that it can release a long stream of particles with only one triggering.
-*/
-
-.float endtime;
-.float duration;
-
-void() partspray_think =
-{
- particle (self.origin, self.movedir, self.color, self.count);
-
- if(!self.targetname || self.endtime > time)
- self.nextthink = time + self.delay;
-
- if(self.noise != "")
- sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound(self, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
-
-};
-
-void() partspray_use =
-{
- self.endtime = time + self.duration;
- partspray_think();
-};
-
-void() misc_particlespray =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- if ( !self.color )
- self.color = 47;
- if ( self.count <= 0 )
- self.count = 15;
- if(self.delay <= 0)
- self.delay = 0.1;
- self.classname = "particlespray";
- if (self.noise != "")
- precache_sound(self.noise);
- precache_sound ("misc/null.wav");
- self.think = partspray_think;
- if(!self.targetname)
- self.nextthink = time + 0.1 + self.delay;
- else
- self.use = partspray_use;
-};
+//selections from Rubicon 2 qc by john fitzgibbons
+//and AD breakable code modified by Qmaster,iw and dumptruck_ds
+float BREAKABLE_NO_MONSTERS = 1;
+float BREAK_EXPLODE = 2;
+float BREAK_CUSTOM = 4;
+float START_OFF = 1;
+float SPARKS_BLUE = 2;
+float SPARKS_PALE = 4;
+
+void() make_breakable_debris;
+
+/*
+===============================================================================
+func_explobox
+===============================================================================
+*/
+
+void () func_explobox_explode_silent =
+{
+ self.takedamage = DAMAGE_NO;
+ self.origin = ((self.absmin + self.absmax) * 0.5);
+ self.classname = "explo_box";
+ T_RadiusDamage (self, self, self.dmg, 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);
+ BecomeExplosion ();
+
+};
+
+void () func_explobox_explode = {
+ // sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ func_explobox_explode_silent();
+};
+
+void () func_explobox_die =
+{
+ self.nextthink = 0.2; //for some reason, time + 0.2 doesn't work
+ self.think = func_explobox_explode;
+};
+
+/*QUAKED func_explobox (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+An exploding brush entity. Works just like misc_explobox.
+
+Keys:
+
+"health" Default 20
+
+"dmg" default 100
+
+*/
+void () func_explobox =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setmodel (self, self.model);
+ precache_sound ("weapons/r_exp3.wav");
+ if (!self.health)
+ {
+ self.health = 20;
+ }
+ if (!self.dmg)
+ {
+ self.dmg = 100;
+ }
+ self.th_die = func_explobox_die;
+ self.takedamage = DAMAGE_AIM;
+};
+
+
+/*
+===============================================================================
+func_breakable
+===============================================================================
+*/
+
+.string break_template1;
+.string break_template2;
+.string break_template3;
+.string break_template4;
+.string break_template5;
+.float brk_obj_count1;
+.float brk_obj_count2;
+.float brk_obj_count3;
+.float brk_obj_count4;
+.float brk_obj_count5;
+
+
+// template system from Qmaster -- dumptruck_ds
+void() make_breakable_templates_debris = {
+ local float i;
+ local entity new;
+
+ i = 0;
+ if (self.break_template1 != "") {
+ while (i < self.brk_obj_count1) {
+ new = spawn();
+ new.model = self.break_template1;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template2 != "") {
+ while (i < self.brk_obj_count2) {
+ new = spawn();
+ new.model = self.break_template2;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template3 != "") {
+ while (i < self.brk_obj_count3) {
+ new = spawn();
+ new.model = self.break_template3;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template4 != "") {
+ while (i < self.brk_obj_count4) {
+ new = spawn();
+ new.model = self.break_template4;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+
+ i = 0;
+ if (self.break_template5 != "") {
+ while (i < self.brk_obj_count5) {
+ new = spawn();
+ new.model = self.break_template5;
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ setmodel (new, new.model); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+ i++;
+ }
+ }
+};
+
+
+//Below this is from Rubicon2 -- dumptruck_ds
+
+void() make_breakable_debris = {
+ local float i;
+ i = 0;
+ while (i < self.cnt)
+ {
+ local entity new;
+
+ new = spawn();
+ new.origin_x = (self.maxs_x - self.mins_x)*random() + self.mins_x;
+ new.origin_y = (self.maxs_y - self.mins_y)*random() + self.mins_y;
+ new.origin_z = (self.maxs_z - self.mins_z)*random() + self.mins_z;
+ // setmodel (new, "progs/debris.mdl"); this was originally just an mdl from Rubicon2, now you set custom model via spawnflag or use the builtin from Rubicon2 -- dumptruck_ds
+ setmodel (new, self.mdl_debris); //dumptruck_ds
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (self.health*2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random()*600;
+ new.avelocity_y = random()*600;
+ new.avelocity_z = random()*600;
+ new.think = SUB_Remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random()*10;
+ new.flags = 0;
+
+ // randomly choose size
+ if (random() > 0.333)
+ new.frame = 1; //larger
+ else
+ new.frame = 2; //smaller
+
+ // choose skin based on "style" key
+ if (self.style == 1)
+ new.skin = 1;
+ if (self.style == 2)
+ new.skin = 2;
+ if (self.style == 3) // new debris skins start here - dumptruck_ds
+ new.skin = 3;
+ if (self.style == 4)
+ new.skin = 4;
+ if (self.style == 5)
+ new.skin = 5;
+ if (self.style == 6)
+ new.skin = 6;
+ if (self.style == 7)
+ new.skin = 7;
+ if (self.style == 8)
+ new.skin = 8;
+ if (self.style == 9)
+ new.skin = 9;
+ if (self.style == 10)
+ new.skin = 10;
+ if (self.style == 11)
+ new.skin = 11;
+ if (self.style == 12)
+ new.skin = 12;
+ if (self.style == 13)
+ new.skin = 13;
+ if (self.style == 14)
+ new.skin = 14;
+ if (self.style == 15)
+ new.skin = 15;
+ if (self.style == 16)
+ new.skin = 16;
+ if (self.style == 17)
+ new.skin = 17;
+ if (self.style == 18)
+ new.skin = 18;
+ if (self.style == 19)
+ new.skin = 19;
+ if (self.style == 20)
+ new.skin = 20;
+ if (self.style == 21)
+ new.skin = 21;
+ if (self.style == 22)
+ new.skin = 22;
+ if (self.style == 23)
+ new.skin = 23;
+ if (self.style == 24)
+ new.skin = 24;
+ if (self.style == 25)
+ new.skin = 25;
+ if (self.style == 26)
+ new.skin = 26;
+ if (self.style == 27)
+ new.skin = 27;
+ if (self.style == 28)
+ new.skin = 28;
+ if (self.style == 29)
+ new.skin = 29;
+ if (self.style == 30)
+ new.skin = 30;
+ if (self.style == 31)// new debris skins end here - dumptruck_ds
+ new.skin = 31;
+
+ i = i + 1;
+ }
+};
+
+void () func_breakable_die = {
+ //dumptruck_ds -- set the spawnflag for cosmetic explosion effect; use "dmg" value to hurt the player
+ {
+ local entity ent; //thanks to Qmaster!!! He helped me sort out noise1 playing from 0 0 0 with this temp entity - dumptruck_ds
+
+ ent = spawn();
+ ent.origin = ((self.absmin + self.absmax) * 0.5);
+ setsize (ent, '0 0 0', '0 0 0');
+ ent.solid = SOLID_NOT;
+ ent.think = SUB_Remove;
+ // ent.ltime = time;
+ ent.nextthink = time + 60;
+
+ sound(ent, CHAN_AUTO, self.noise1, 1, ATTN_NORM);
+ // remove (self);
+ }
+
+ // this is to ensure that any debris from another func_breakable
+ // which is resting on top of this func_breakable is not left
+ // floating in mid-air after this entity is removed -- iw
+ SUB_DislodgeRestingEntities ();
+
+ if (self.spawnflags & BREAK_EXPLODE) {
+ if (self.spawnflags & BREAK_CUSTOM) {
+ make_breakable_templates_debris ();
+ } else {
+ make_breakable_debris ();
+ }
+ func_explobox_explode_silent(); // to let us use noise2
+ // sound(self, CHAN_VOICE, self.noise2, 1, ATTN_NORM); this is broken as of 1.1.0 no custom explosion sound for now -- dumptruck_ds
+ remove (self);
+ } else {
+ self.origin = ((self.absmin + self.absmax) * 0.5);
+ setorigin (self, self.origin);
+ DropStuff();
+ if (self.spawnflags & BREAK_CUSTOM) {
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ make_breakable_templates_debris ();
+ remove (self);
+ } else {
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "m");
+ make_breakable_debris ();
+ remove (self);
+ }
+ }
+};
+
+void () func_breakable_killed =
+{
+ activator = damage_attacker;
+ SUB_UseTargets ();
+ func_breakable_die ();
+};
+
+void () func_breakable_use =
+{
+ activator = other;
+ SUB_UseTargets ();
+ func_breakable_die ();
+};
+
+/*QUAKED func_breakable (0 .5 .8) ? NO_MONSTERS X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+"Breakable - See manual for full details
+
+Defaults to built-in .mdl file with 32 styles, cnt is number of pieces of debris to spawn (built-in only)
+Or use spawnflag 4 and break_template1-4 to set path of custom .mdl or .bsp models.
+brk_object_count1-4 sets the number of pieces of each break_template when using custom .mdl or bsp models.
+If noise1 is not set it will default to various sounds in sounds/break folder
+Use spawnflag 2 for an explosion, dmg is amount of damage inflicted"
+
+spawnflags(flags)
+1 : "No Monster Damage" : 0 : "Only the player can break"
+2 : "Explosion" : 0 : "Produces explosion effect and sound"
+4 : "Use custom mdls or bsp models" : 0 : "Uses models specified in break_template1, 2, etc"
+
+style(choices) : "Built-in debris style" : 0
+0 : "Green Metal (default)"
+1 : "Red Metal"
+2 : "Concrete"
+3 : "Pine wood"
+4 : "Brown wood"
+5 : "Red wood"
+6 : "Stained Glass Yellow Flames"
+7 : "Stained Glass Red Rays"
+8 : "Stained Glass Yellow Dragon"
+9 : "Stained Glass Blue Dragon"
+10 : "Stained Glass Red Dragon"
+11 : "Light Copper"
+12 : "Dark Copper"
+13 : "Tan Bricks Large"
+14 : "Brown Bricks Large"
+15 : "Green Bricks Large"
+16 : "Generic Light Brown"
+17 : "Red Brown Computer"
+18 : "Grey Black Computer"
+19 : "Blue Green Metal"
+20 : "Blue Green Runic Wall"
+21 : "Brown Metal"
+22 : "Dark Brown Metal"
+23 : "Medium Brown Metal"
+24 : "Blue Metal"
+25 : "Green Stonework"
+26 : "Blue Stonework"
+27 : "Brown Bricks"
+28 : "Tan Blue Bricks"
+29 : "Red Bricks"
+30 : "Blue Bricks"
+31 : "Metal Rivets"
+
+noise1(string) : "Break noise (overrides default sounds)"
+cnt(integer) : "Number of pieces of debris to spawn" : 5
+health(integer) : "Health of breakable" : 20
+dmg(integer) : "Amount of Explosive Damage" : 20
+break_template1(string) : "Template 1 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template2(string) : "Template 2 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template3(string) : "Template 3 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template4(string) : "Template 4 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+break_template5(string) : "Template 5 model path, e.g. maps/break/brk.bsp or progs/brick.mdl"
+brk_obj_count1(integer) : "Template 1 spawn count"
+brk_obj_count2(integer) : "Template 2 spawn count"
+brk_obj_count3(integer) : "Template 3 spawn count"
+brk_obj_count4(integer) : "Template 4 spawn count"
+brk_obj_count5(integer) : "Template 5 spawn count"
+*/
+
+void() break_template_setup = {
+ if (self.break_template1 != "") precache_model(self.break_template1);
+ if (self.break_template2 != "") precache_model(self.break_template2);
+ if (self.break_template3 != "") precache_model(self.break_template3);
+ if (self.break_template4 != "") precache_model(self.break_template4);
+ if (self.break_template5 != "") precache_model(self.break_template5);
+};
+
+void () func_breakable = {
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ break_template_setup();
+
+ self.solid = SOLID_BSP;
+ self.movetype = MOVETYPE_PUSH;
+ setmodel (self, self.model);
+ self.mdl_debris = "progs/debris.mdl";
+ precache_model (self.mdl_debris);
+ precache_sound ("blob/hit1.wav");
+
+ if (self.noise1 != "") precache_sound(self.noise1);
+// adding new default sounds for "simple" breakables in 1.2.0 -- dumptruck_ds
+// here's genreic metal breaking
+ if (self.style == 0 || self.style == 11 || self.style == 12 || self.style == 17 || self.style == 18 || self.style == 19
+ || self.style == 24 || self.style == 31)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal2.wav");
+ self.noise1 = "break/metal2.wav";
+ }
+ if (self.style == 3 || self.style == 4 || self.style == 5)
+ if !(self.noise1)
+ {
+ precache_sound("break/wood1.wav");
+ precache_sound("break/wood2.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/wood1.wav";
+ else
+ self.noise1 = "break/wood2.wav";
+ }
+ // glass sounds -- this is more of a shattering sound anyway
+ if (self.style == 6 || self.style == 7 || self.style == 8 || self.style == 9 || self.style == 10)
+ if !(self.noise1)
+ {
+ precache_sound("break/metal1.wav");
+ self.noise1 = "break/metal1.wav";
+ }
+ if (self.style == 1 || self.style == 2 || self.style == 13 || self.style == 14
+ || self.style == 15 || self.style == 16 || self.style == 20 || self.style == 21
+ || self.style == 22 || self.style == 23)
+ if !(self.noise1)
+ {
+ precache_sound("break/stones1.wav");
+ precache_sound("break/bricks1.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/bricks1.wav";
+ else
+ self.noise1 = "break/stones1.wav";
+ }
+ if (self.style == 25 || self.style == 26 || self.style == 27 || self.style == 28 || self.style == 29 || self.style == 30)
+ if !(self.noise1)
+ {
+ precache_sound("break/stones1.wav");
+ precache_sound("break/bricks1.wav");
+ if (random() > 0.6) // wood only randomized
+ self.noise1 = "break/stones1.wav";
+ else
+ self.noise1 = "break/bricks1.wav";
+ }
+ // else
+ // (self.noise1 = "blob/hit1.wav");
+
+ if (!self.health)
+ self.health = 20;
+ if (!self.cnt)
+ self.cnt = 5; // was 6 dumptruck_ds
+
+ if (self.targetname != "")
+ {
+ self.use = func_breakable_use;
+ }
+ else
+ {
+ self.takedamage = DAMAGE_YES;
+ self.th_die = func_breakable_killed;
+ }
+
+ if (self.switchshadstyle) lightstyle(self.switchshadstyle, "a");
+};
+
+/*
+===============================================================================
+trigger_ladder
+===============================================================================
+*/
+
+void() ladder_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch()) return;
+
+ // prevent the player "sticking" to a ladder if they are standing on
+ // the platform at the top of the ladder with the bottom of their
+ // bounding box flush with the top of the trigger -- iw
+ if (other.absmin_z + 1 >= self.absmax_z - 1)
+ return;
+
+ // if the trigger has an angles field, check player's facing direction
+ if (self.movedir != '0 0 0')
+ {
+ makevectors (other.angles);
+ if (v_forward * self.movedir < 0)
+ return; // not facing the right way
+ }
+ other.onladder = 1;
+}
+
+/*QUAKED trigger_ladder (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+invisible ladder entity. when player is touching this entity, he can climb by pushing 'jump'
+
+Keys:
+
+"angle" the direction player must be facing to climb ladder
+*/
+void() trigger_ladder =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ // ignore an "up" or "down" angle (doesn't make sense for a ladder)
+ if (self.angles_y == -1 || self.angles_y == -2)
+ {
+ dprint ("WARNING: trigger_ladder ignored bad 'angle' value: ");
+ dprint (ftos (self.angles_y));
+ dprint ("\n");
+
+ self.angles_y = 0;
+ }
+
+ InitTrigger ();
+ self.touch = ladder_touch;
+
+ SUB_CheckWaiting();
+};
+/*
+===============================================================================
+func_laser
+===============================================================================
+*/
+float LASER_SOLID = 2;
+.string message2;
+.float alpha;
+
+
+void() laser_helper_think =
+{
+ if (!self.owner || self.owner.classname != "func_laser")
+ {
+ remove(self);
+ return;
+ }
+
+
+ if (!(self.owner.spawnflags & START_OFF))
+ self.owner.alpha = self.alpha * 0.8 + self.alpha * random() * 0.4;
+
+ self.nextthink = time + 0.05;
+};
+
+void() func_laser_touch =
+{
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (other.takedamage && self.attack_finished < time)
+ {
+ T_Damage (other, self, self, self.dmg);
+ self.attack_finished = time + 0.1;
+ }
+
+};
+
+void () func_laser_use =
+{
+ if (self.spawnflags & START_OFF)
+ {
+ setorigin(self, '0 0 0');
+ self.spawnflags = self.spawnflags - START_OFF;
+
+ // changed for progs_dump: the laser sound is now emitted from
+ // the func_laser itself instead of from the activator -- iw
+ sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+
+ if (activator.classname == "player" && self.message != "")
+ {
+ centerprint (activator, self.message);
+ }
+ }
+ else
+ {
+ // changed for progs_dump: the laser sound is now emitted from
+ // the func_laser itself instead of from the activator -- iw
+ sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+
+ setorigin(self, '0 0 9000');
+ self.spawnflags = self.spawnflags + START_OFF;
+
+ if (activator.classname == "player" && self.message2 != "")
+ {
+ centerprint (activator, self.message2);
+ }
+ }
+};
+
+/*QUAKED func_laser (0 .5 .8) ? START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+A toggleable laser, hurts to touch, can be used to block players
+
+START_OFF: Laser starts off.
+
+LASER_SOLID: Laser blocks movement while turned on.
+
+Keys:
+
+"dmg" damage to do on touch. default 1
+
+"alpha" approximate alpha you want the laser drawn at. default 0.5. alpha will vary by 20% of this value.
+
+"message" message to display when activated
+
+"message2" message to display when deactivated
+
+*/
+void () func_laser =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ local entity helper;
+
+ setmodel (self, self.model);
+
+ precache_sound ("buttons/switch02.wav");
+ precache_sound ("buttons/switch04.wav");
+
+ if (self.spawnflags & LASER_SOLID)
+ {
+ self.solid = SOLID_BSP; //so you can shoot between lasers in a single bmodel
+ self.movetype = MOVETYPE_PUSH; //required becuase of SOLID_BSP
+ }
+ else
+ {
+ self.solid = SOLID_TRIGGER;
+ self.movetype = MOVETYPE_NONE;
+ }
+
+ if (!self.alpha)
+ self.alpha = 0.5;
+
+ if (!self.dmg)
+ self.dmg = 1;
+
+ self.use = func_laser_use;
+ self.touch = func_laser_touch;
+
+ if (self.spawnflags & START_OFF)
+ setorigin(self, '0 0 9000');
+ {
+ if (self.noise != "") precache_sound(self.noise);
+
+ else
+ (self.noise = "buttons/switch02.wav");
+ }
+ {
+ if (self.noise1 != "") precache_sound(self.noise1);
+
+ else
+ (self.noise1 = "buttons/switch04.wav");
+ }
+
+
+
+
+ //spawn a second entity to handle alpha changes, since MOVETYPE_PUSH doesn't support think functions
+ helper = spawn();
+ helper.alpha = self.alpha;
+ helper.owner = self;
+ helper.nextthink = 0.05;
+ helper.think = laser_helper_think;
+};
+
+/*
+===============================================================================
+misc_sparks
+===============================================================================
+*/
+
+void() sparks_fade1 = [0, sparks_fade2] {self.alpha = 0.8; self.nextthink = time + 0.05;};
+void() sparks_fade2 = [0, sparks_fade3] {self.alpha = 0.6; self.nextthink = time + 0.05;};
+void() sparks_fade3 = [0, sparks_fade4] {self.alpha = 0.4; self.nextthink = time + 0.05;};
+void() sparks_fade4 = [0, SUB_Remove] {self.alpha = 0.2; self.nextthink = time + 0.05;};
+
+void() sparks_use =
+{
+ if (self.spawnflags & START_OFF)
+ self.spawnflags = self.spawnflags - START_OFF;
+ else
+ self.spawnflags = self.spawnflags + START_OFF;
+};
+
+void() make_sparks;
+
+void() spark_turnofflight =
+{
+ SUB_UseTargets();
+ self.think = make_sparks;
+ self.nextthink = time + (random() + 0.5)*self.wait - 0.15;
+}
+
+void() make_sparks =
+{
+
+ if (self.spawnflags & START_OFF)
+ {
+ self.nextthink = time + 0.1;
+ self.think = make_sparks;
+ }
+ else
+ {
+ local float i;
+ i = -0.25*self.cnt + random()*0.5*self.cnt;
+ while (i < self.cnt)
+ {
+
+ local entity spark;
+ spark = spawn();
+ spark.owner = self;
+ setmodel (spark, "progs/spark.mdl");
+ setorigin (spark, self.origin);
+ spark.movetype = MOVETYPE_BOUNCE;
+ spark.solid = SOLID_TRIGGER;
+ spark.gravity = 0.3;
+ spark.velocity_x = -40 + random() * 80;
+ spark.velocity_y = -40 + random() * 80;
+ spark.velocity_z = -40 + random() * 80;
+ spark.avelocity = '3000 3000 3000';
+ spark.nextthink = time + 0.5 + 1.5*random();
+ spark.think = sparks_fade1;
+ spark.classname = "spark";
+
+ if (random() < 0.33)
+ spark.skin = 0;
+ else if (random() < 0.5)
+ spark.skin = 1;
+ else
+ spark.skin = 2;
+
+ if (self.spawnflags & SPARKS_PALE)
+ spark.skin = spark.skin + 6;
+ else if (self.spawnflags & SPARKS_BLUE)
+ spark.skin = spark.skin + 3;
+
+ setsize (spark, '0 0 0', '0 0 0');
+ i = i + 1;
+ }
+ if (self.sounds == 1)
+ {
+ if (self.noise != "")
+ {
+ sound (self, CHAN_AUTO, self.noise, 1, ATTN_STATIC);
+ }
+ else
+ sound (self, CHAN_AUTO, "enforcer/enfstop.wav", 1, ATTN_STATIC);
+ }
+ SUB_UseTargets();
+ self.nextthink = time + 0.1 + random() * 0.1;
+ self.think = spark_turnofflight;
+
+ }
+
+};
+
+/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF SPARKS_BLUE SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.
+
+SPARKS_BLUE: sparks are blue in color
+
+SPARKS_PALE: sparks are pale yellow in color
+
+Keys:
+
+"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
+
+"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.
+
+"sounds"
+0) no sound
+1) sparks
+*/
+void() misc_sparks =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ precache_model ("progs/spark.mdl");
+ if (!self.noise)
+ precache_sound ("dump/spark.wav");
+ else
+ precache_sound (self.noise);
+
+ if (!self.movedir)
+ self.movedir = '0 0 -30';
+ if (!self.wait)
+ self.wait = 2;
+ if (!self.cnt)
+ self.cnt = 15;
+
+ self.use = sparks_use;
+ self.nextthink = time + random()*0.1;
+ self.think = make_sparks;
+};
+
+/*
+===============================================================================
+misc_particles a.k.a. misc_splash
+===============================================================================
+*/
+void() splash_use =
+{
+ if (self.spawnflags & START_OFF)
+ self.spawnflags = self.spawnflags - START_OFF;
+ else
+ self.spawnflags = self.spawnflags + START_OFF;
+};
+
+void() splash_think =
+{
+ if (self.spawnflags & START_OFF)
+ {
+ self.nextthink = time + 0.1;
+ self.think = splash_think;
+ }
+ else
+ {
+ local vector vec;
+ local float variance;
+ variance = vlen(self.movedir) / 2;
+ vec_x = self.movedir_x - variance + random() * variance * 2;
+ vec_y = self.movedir_y - variance + random() * variance * 2;
+ vec_z = self.movedir_z - variance + random() * variance * 2;
+ particle (self.origin, vec, self.color, self.volume);
+ self.nextthink = time + self.wait;
+ }
+};
+
+//
+//misc_particles
+//
+// renamed from misc_splash (Rubcion 2) --dumptruck_ds
+//
+
+/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+Produces a continuous particle splash for waterfalls and other effects
+
+"color" color of particles. 0 through 15, corresponds to a row of the quake palette. (default 0)
+
+"movedir" average movement vector of particles (default 0 0 4)
+
+"wait" time between particle generation cycles. (default 0.1)
+
+"volume" density of particles. (default 10)
+
+
+*/
+void() misc_particles =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if (!self.wait)
+ self.wait = 0.1;
+ if (!self.movedir)
+ self.movedir = '0 0 4';
+ if (!self.volume)
+ self.volume = 10;
+ self.color = self.color * 16;
+
+ self.use = splash_use;
+ self.nextthink = time + self.wait;
+ self.think = splash_think;
+};
+
+//##########################################
+//#### Particle Sprayer ####
+//##########################################
+
+//this is from Custents not Rubicon2 -- dumptruck_ds
+//renamed from func to misc
+
+/*QUAKED misc_particlespray (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Shoots particles either when triggered, or contiuously when not triggered by anything.
+"color" is the palette color of the particles
+
+"count" is the number of particles to make each time
+
+"delay" is the delay between each triggering
+
+"noise" is the name of the wav file to play when triggered
+
+"movedir" is the vector distance that the particles will travel before disappearing. (in x y z)
+
+"duration" is the amount of time that the it will continue to release particles so that it can release a long stream of particles with only one triggering.
+*/
+
+.float endtime;
+.float duration;
+
+void() partspray_think =
+{
+ particle (self.origin, self.movedir, self.color, self.count);
+
+ if(!self.targetname || self.endtime > time)
+ self.nextthink = time + self.delay;
+
+ if(self.noise != "")
+ sound(self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ else
+ sound(self, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
+
+};
+
+void() partspray_use =
+{
+ self.endtime = time + self.duration;
+ partspray_think();
+};
+
+void() misc_particlespray =
+{
+ if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ return;
+
+ if ( !self.color )
+ self.color = 47;
+ if ( self.count <= 0 )
+ self.count = 15;
+ if(self.delay <= 0)
+ self.delay = 0.1;
+ self.classname = "particlespray";
+ if (self.noise != "")
+ precache_sound(self.noise);
+ precache_sound ("misc/null.wav");
+ self.think = partspray_think;
+ if(!self.targetname)
+ self.nextthink = time + 0.1 + self.delay;
+ else
+ self.use = partspray_use;
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/subs.qc

diff --git a/qc/subs.qc b/qc/subs.qc
index 71c715a..91343f3 100644
--- a/qc/subs.qc
+++ b/qc/subs.qc
@@ -738,4 +738,4 @@ void() SUB_CheckWaiting = {
dprint(self.target);
dprint("\n");
}
-};
\ No newline at end of file
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/sv_runclient.qc

diff --git a/qc/sv_runclient.qc b/qc/sv_runclient.qc
new file mode 100644
index 0000000..4f33511
--- /dev/null
+++ b/qc/sv_runclient.qc
@@ -0,0 +1,7 @@
+void(entity ent) phys_move;
+
+void() SV_RunClientCommand =
+{
+ //should match the one used by csqc.
+ phys_move (self);
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/triggers.qc

diff --git a/qc/triggers.qc b/qc/triggers.qc
index cda0c06..a7617d9 100644
--- a/qc/triggers.qc
+++ b/qc/triggers.qc
@@ -582,8 +582,9 @@ if (!(self.spawnflags & TELE_STEALTH))

other.fixangle = 1; // turn this way immediately
other.teleport_time = time + 0.7;
- if (other.flags & FL_ONGROUND)
- other.flags = other.flags - FL_ONGROUND;
+ // TODO CEV
+ // if (other.flags & FL_ONGROUND)
+ // other.flags = other.flags - FL_ONGROUND;
other.velocity = v_forward * 300;
}
other.flags = other.flags - other.flags & FL_ONGROUND;
@@ -598,6 +599,7 @@ if (!(self.spawnflags & TELE_STEALTH))
}
other.flags = other.flags - other.flags & FL_ONGROUND;
};
+
// this is from Qmaster:

// "I created an info_teleport_changedest
@@ -675,16 +677,46 @@ This is the destination marker for a teleporter. It should have a "targetname"
*/
void() info_teleport_destination =
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
+ vector end;
+
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
return;

-// 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 = "";
- self.origin = self.origin + '0 0 27';
+ // drop teleporter exit to the floor if within 64 units -- CEV
+ end = self.origin + PM_TELEDROP;
+ tracebox(self.origin, self.mins, self.maxs, end, FALSE, self);
+ if (trace_allsolid || trace_startsolid || trace_fraction < 1)
+ {
+ droptofloor ();
+ // bump origin up so the player won't exit into the floor
+ self.origin = self.origin + '0 0 24';
+ }
+ else
+ // instead apply the standard fixed Z offset
+ self.origin = self.origin + '0 0 27';
+
if (!self.targetname)
- objerror ("no targetname");
+ if (self.target)
+ // quake 3 compat -- CEV
+ self.targetname = self.target;
+ else
+ objerror ("no targetname");
+};
+
+// quake 3 compat -- CEV
+void() misc_teleporter_dest =
+{
+ info_teleport_destination();
+};
+
+void() misc_teleporter_destination =
+{
+ info_teleport_destination();
};

/*QUAKED info_teleport_random (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -911,18 +943,24 @@ void() trigger_push_touch =
{
other.velocity = self.speed * self.movedir * 10;
if (other.classname == "player")
- if (!(self.spawnflags & DT_SILENT))
{
- if (other.fly_sound < time)
- if (!(self.spawnflags & DT_NOISE))
- {
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO, "ambience/windfly.wav", 1, ATTN_NORM);
- }
- else
+ if (!(self.spawnflags & DT_SILENT))
{
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ if (other.fly_sound < time)
+ if (!(self.spawnflags & DT_NOISE))
+ {
+ other.fly_sound = time + 1.5;
+ sound (other, CHAN_AUTO,
+ "ambience/windfly.wav",
+ 1, ATTN_NORM);
+ }
+ else
+ {
+ other.fly_sound = time + 1.5;
+ sound (other, CHAN_AUTO,
+ self.noise,
+ 1, ATTN_NORM);
+ }
}
}
}

Return to the top of this page or return to the overview of this repo.

Diff qc/weapons.qc

diff --git a/qc/weapons.qc b/qc/weapons.qc
index 8dacf7b..3182504 100644
--- a/qc/weapons.qc
+++ b/qc/weapons.qc
@@ -1,1807 +1,1807 @@
-/*
-*/
-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(vector org, vector vel, float damage) SpawnBlood;
-void() SuperDamageSound;
-void() create_mobot; //dumptruck_ds mobot.qc
-void(entity mis, float speed) SetupHoming;
-
-void(entity mis, vector dir, float speed) SetSpeed =
-{
- if (cvar("sv_maxvelocity") > speed)
- {
- mis.velocity = dir * speed;
- }
- else {
- mis.velocity = dir * cvar("sv_maxvelocity");
- }
-};
-
-// called by worldspawn
-void() W_Precache =
-{
- precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
- precache_sound ("weapons/rocket1i.wav"); // spike gun
- precache_sound ("weapons/sgun1.wav");
- precache_sound ("weapons/guncock.wav"); // player shotgun
- precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
- precache_sound ("weapons/spike2.wav"); // super spikes
- precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
- precache_sound ("weapons/grenade.wav"); // grenade launcher
- precache_sound ("weapons/bounce.wav"); // grenade bounce
- precache_sound ("weapons/shotgn2.wav"); // super shotgun
-
-// dumptruck_ds mobot.qc precaches START
-
- precache_model ("progs/ogre.mdl");
- precache_model ("progs/h_ogre.mdl");
- precache_model ("progs/grenade.mdl");
- precache_sound ("ogre/ogdrag.wav");
- precache_sound ("ogre/ogdth.wav");
- precache_sound ("ogre/ogidle.wav");
- precache_sound ("ogre/ogidle2.wav");
- precache_sound ("ogre/ogpain1.wav");
- precache_sound ("ogre/ogsawatk.wav");
- precache_sound ("ogre/ogwake.wav");
-
- precache_model ("progs/demon.mdl");
- precache_model ("progs/h_demon.mdl");
-
- precache_sound ("demon/ddeath.wav");
- precache_sound ("demon/dhit2.wav");
- precache_sound ("demon/djump.wav");
- precache_sound ("demon/dpain1.wav");
- precache_sound ("demon/idle1.wav");
- precache_sound ("demon/sight2.wav");
-
- precache_model2 ("progs/enforcer.mdl");
- precache_model2 ("progs/h_mega.mdl");
- precache_model2 ("progs/laser.mdl");
- precache_model2 ("progs/s_spike.mdl");
-
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2("enforcer/idle1.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2("enforcer/sight4.wav");
-
- precache_model ("progs/soldier.mdl");
- precache_model ("progs/h_guard.mdl");
-
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound ("soldier/death1.wav");
- precache_sound ("soldier/idle.wav");
- precache_sound ("soldier/pain1.wav");
- precache_sound ("soldier/pain2.wav");
- precache_sound ("soldier/sattck1.wav");
- precache_sound ("soldier/sight1.wav");
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_model ("progs/h_dog.mdl");
- precache_model ("progs/dog.mdl");
- precache_sound ("dog/dattack1.wav");
- precache_sound("dog/ddeath.wav");
- precache_sound ("dog/dpain1.wav");
- precache_sound ("dog/dsight.wav");
- precache_sound ("dog/idle.wav");
-
- precache_model ("progs/wizard.mdl");
- precache_model ("progs/h_wizard.mdl");
- precache_model ("progs/w_spike.mdl");
-
- precache_sound ("wizard/hit.wav"); // used by c code
- precache_sound ("wizard/wattack.wav");
- precache_sound ("wizard/wdeath.wav");
- precache_sound ("wizard/widle1.wav");
- precache_sound ("wizard/widle2.wav");
- precache_sound ("wizard/wpain.wav");
- precache_sound ("wizard/wsight.wav");
-
- precache_model2 ("progs/shalrath.mdl");
- precache_model2 ("progs/h_shal.mdl");
- precache_model2 ("progs/v_spike.mdl");
-
- precache_sound2 ("shalrath/attack.wav");
- precache_sound2 ("shalrath/attack2.wav");
- precache_sound2 ("shalrath/death.wav");
- precache_sound2 ("shalrath/idle.wav");
- precache_sound2 ("shalrath/pain.wav");
- precache_sound2 ("shalrath/sight.wav");
-
- precache_model ("progs/knight.mdl");
- precache_model ("progs/h_knight.mdl");
-
- precache_sound ("knight/kdeath.wav");
- precache_sound ("knight/khurt.wav");
- precache_sound ("knight/ksight.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
- precache_sound ("knight/idle.wav");
-
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/k_spike.mdl");
-
- precache_sound2 ("hknight/attack1.wav");
- precache_sound2 ("hknight/death1.wav");
- precache_sound2 ("hknight/pain1.wav");
- precache_sound2 ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
- precache_sound2 ("hknight/slash1.wav");
- precache_sound2 ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
-
- precache_sound2 ("blob/death1.wav");
- precache_sound2 ("blob/hit1.wav");
- precache_sound2 ("blob/land1.wav");
- precache_sound2 ("blob/sight1.wav");
-
- precache_model ("progs/zombie.mdl");
- precache_model ("progs/h_zombie.mdl");
- precache_model ("progs/zom_gib.mdl");
-
- precache_sound ("zombie/z_idle.wav");
- precache_sound ("zombie/z_idle1.wav");
- precache_sound ("zombie/z_shot1.wav");
- precache_sound ("zombie/z_gib.wav");
- precache_sound ("zombie/z_pain.wav");
- precache_sound ("zombie/z_pain1.wav");
- precache_sound ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- precache_sound ("zombie/idle_w2.wav");
-
- precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
-
- precache_sound ("shambler/sattck1.wav");
- precache_sound ("shambler/sboom.wav");
- precache_sound ("shambler/sdeath.wav");
- precache_sound ("shambler/shurt2.wav");
- precache_sound ("shambler/sidle.wav");
- precache_sound ("shambler/ssight.wav");
- precache_sound ("shambler/melee1.wav");
- precache_sound ("shambler/melee2.wav");
- precache_sound ("shambler/smack.wav");
-
- // dumptruck_ds mobot.qc END
-};
-
-float() crandom =
-{
- return 2*(random() - 0.5);
-};
-
-/*
-================
-W_FireAxe
-================
-*/
-void() W_FireAxe =
-{
- local vector source;
- local vector org;
-
- makevectors (self.v_angle);
- source = self.origin + '0 0 16';
- traceline (source, source + v_forward*64, FALSE, self);
- if (trace_fraction == 1.0)
- return;
- org = trace_endpos - v_forward*4;
-
- if (trace_ent.takedamage)
- {
- trace_ent.axhitme = 1;
- SpawnBlood (org, '0 0 0', 20);
- T_Damage (trace_ent, self, self, 20);
- }
- else
- { // hit wall
- sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
- 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);
- }
-};
-
-
-//============================================================================
-
-
-vector() wall_velocity =
-{
- local vector vel;
-
- vel = normalize (self.velocity);
- vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
- vel = vel + 2*trace_plane_normal;
- vel = vel * 200;
-
- return vel;
-};
-
-
-/*
-================
-SpawnMeatSpray
-================
-*/
-void(vector org, vector vel) SpawnMeatSpray =
-{
- local entity missile;
-
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_NOT;
-
- makevectors (self.angles);
-
- missile.velocity = vel;
- missile.velocity_z = missile.velocity_z + 250 + 50*random();
-
- missile.avelocity = '3000 1000 2000';
-
-// set missile duration
- missile.nextthink = time + 1;
- missile.think = SUB_Remove;
-
- setmodel (missile, "progs/zom_gib.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, org);
-};
-
-/*
-================
-SpawnBlood
-================
-*/
-void(vector org, vector vel, float damage) SpawnBlood =
-{
- particle (org, vel*0.1, 73, damage*2);
-};
-
-/*
-================
-spawn_touchblood
-================
-*/
-void(float damage) spawn_touchblood =
-{
- local vector vel;
-
- vel = wall_velocity () * 0.2;
- SpawnBlood (self.origin + vel*0.01, vel, damage);
-};
-
-
-/*
-================
-SpawnChunk
-================
-*/
-void(vector org, vector vel) SpawnChunk =
-{
- particle (org, vel*0.02, 0, 10);
-};
-
-/*
-==============================================================================
-
-MULTI-DAMAGE
-
-Collects multiple small damages into a single damage
-
-==============================================================================
-*/
-
-entity multi_ent;
-float multi_damage;
-
-void() ClearMultiDamage =
-{
- multi_ent = world;
- multi_damage = 0;
-};
-
-void() ApplyMultiDamage =
-{
- if (!multi_ent)
- return;
- T_Damage (multi_ent, self, self, multi_damage);
-};
-
-void(entity hit, float damage) AddMultiDamage =
-{
- if (!hit)
- return;
-
- if (hit != multi_ent)
- {
- ApplyMultiDamage ();
- multi_damage = damage;
- multi_ent = hit;
- }
- else
- multi_damage = multi_damage + damage;
-};
-
-/*
-==============================================================================
-
-BULLETS
-
-==============================================================================
-*/
-
-/*
-================
-TraceAttack
-================
-*/
-void(float damage, vector dir) TraceAttack =
-{
- local vector vel, org;
-
- vel = normalize(dir + v_up*crandom() + v_right*crandom());
- vel = vel + 2*trace_plane_normal;
- vel = vel * 200;
-
- org = trace_endpos - dir*4;
-
- if (trace_ent.takedamage)
- {
- SpawnBlood (org, vel*0.2, damage);
- AddMultiDamage (trace_ent, damage);
- }
- 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);
- }
-};
-
-/*
-================
-FireBullets
-
-Used by shotgun, super shotgun, and enemy soldier firing
-Go to the trouble of combining multiple pellets into a single damage call.
-================
-*/
-void(float shotcount, vector dir, vector spread) FireBullets =
-{
- local vector direction;
- local vector src;
-
- makevectors(self.v_angle);
-
- src = self.origin + v_forward*10;
- src_z = self.absmin_z + self.size_z * 0.7;
-
- ClearMultiDamage ();
- 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)
- TraceAttack (4, direction);
-
- shotcount = shotcount - 1;
- }
- ApplyMultiDamage ();
-};
-
-/*
-================
-W_FireShotgun
-================
-*/
-void() W_FireShotgun =
-{
- local vector dir;
-
- sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 1;
- dir = aim (self, 100000);
- FireBullets (6, dir, '0.04 0.04 0');
-};
-
-
-/*
-================
-W_FireSuperShotgun
-================
-*/
-void() W_FireSuperShotgun =
-{
- local vector dir;
-
- if (self.currentammo == 1)
- {
- W_FireShotgun ();
- return;
- }
-
- sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -4;
-
- self.currentammo = self.ammo_shells = self.ammo_shells - 2;
- dir = aim (self, 100000);
- FireBullets (14, dir, '0.14 0.08 0');
-};
-
-
-/*
-==============================================================================
-
-ROCKETS
-
-==============================================================================
-*/
-
-void() s_explode1 = [0, s_explode2] {};
-void() s_explode2 = [1, s_explode3] {};
-void() s_explode3 = [2, s_explode4] {};
-void() s_explode4 = [3, s_explode5] {};
-void() s_explode5 = [4, s_explode6] {};
-void() s_explode6 = [5, SUB_Remove] {};
-
-void() BecomeExplosion =
-{
- self.movetype = MOVETYPE_NONE;
- self.velocity = '0 0 0';
- self.touch = SUB_Null;
- setmodel (self, "progs/s_explod.spr");
- self.solid = SOLID_NOT;
- s_explode1 ();
-};
-
-void() T_MissileTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = 100 + random()*20;
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, 120, other);
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-
-};
-//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-
-void(float direct, float splash) T_MonsterMisTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
- damg = direct + random()*2; //dumptruck_ds
-
- if (other.health)
- {
- if (other.classname == "monster_shambler")
- damg = damg * 0.5; // mostly immune
- T_Damage (other, self, self.owner, damg );
- }
-
- // don't do radius damage to the other, because all the damage
- // was done in the impact
- T_RadiusDamage (self, self.owner, splash, other); //dumptruck_ds
-
-// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
- self.origin = self.origin - 8*normalize(self.velocity);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-void() T_GruntMisTouch =
-{
- T_MonsterMisTouch(30, 40);
-};
-
- // less direct damage, more splash than grunt
- // TODO: add damage modifier
-void() T_HellKnightMisTouch =
-{
- T_MonsterMisTouch(20, 50);
-};
-
-// big damage. explody scrag should be beefy.
-// TODO: add damage modifier
-void() T_WizardMisTouch =
-{
- T_MonsterMisTouch(50, 50);
-};
-//dumptruck_ds end
-
-/*
-================
-W_FireRocket
-================
-*/
-void() W_FireRocket =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed
-
- makevectors (self.v_angle);
- missile.velocity = aim(self, 1000);
- missile.velocity = missile.velocity * 1000;
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = T_MissileTouch;
-
-// set missile duration
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
-
- setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-/*
-================
-W_GruntRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
-================
-*/
-void() W_GruntRocket =
-{
- local entity missile;
-
- // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
-
- sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_FLYMISSILE;
- missile.solid = SOLID_BBOX;
- missile.classname = "missile";
-
-// set missile speed -- dumptruck_ds below
-
- missile.velocity = normalize(self.enemy.origin - self.origin);
- SetSpeed(missile, missile.velocity, 900*self.proj_speed_mod);
- missile.angles = vectoangles(missile.velocity);
- missile.touch = T_GruntMisTouch;
-
- // makevectors (self.v_angle);
- // missile.velocity = aim(self, 1000);
- // missile.velocity = missile.velocity * 1000;
- // missile.angles = vectoangles(missile.velocity);
-
- // missile.touch = T_MissileTouch;
-
-// set missile duration
- if (self.homing > 0)
- {
- SetupHoming(missile, 900 * self.proj_speed_mod);
- }
- else {
- missile.nextthink = time + 5;
- missile.think = SUB_Remove;
- }
- if (self.mdl_proj != "") // dumptruck_ds
- {
- setmodel (missile, self.mdl_proj);
- }
- else
- {
- setmodel (missile, "progs/missile.mdl");
- }
-
- if (!missile.skin_proj) // dumptruck_ds
- {
- missile.skin = self.skin_proj;
- }
- else
- {
- missile.skin = 0;
- }
-// dumptruck_ds - end
-
- // setmodel (missile, "progs/missile.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
- setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 12');
- // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
-};
-
-//end dumptruck_ds grunt missle end
-
-/*
-===============================================================================
-
-LIGHTNING
-
-===============================================================================
-*/
-
-/*
-=================
-LightningDamage
-=================
-*/
-void(vector p1, vector p2, entity from, float damage) LightningDamage =
-{
- local entity e1, e2;
- local vector f;
-
- f = p2 - p1;
- normalize (f);
- f_x = 0 - f_y;
- f_y = f_x;
- f_z = 0;
- f = f*16;
-
- e1 = e2 = world;
-
- traceline (p1, p2, FALSE, self);
- if (trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- if (self.classname == "player")
- {
- if (other.classname == "player")
- trace_ent.velocity_z = trace_ent.velocity_z + 400;
- }
- }
- e1 = trace_ent;
-
- traceline (p1 + f, p2 + f, FALSE, self);
- if (trace_ent != e1 && trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- }
- e2 = trace_ent;
-
- traceline (p1 - f, p2 - f, FALSE, self);
- if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
- {
- particle (trace_endpos, '0 0 100', 225, damage*4);
- T_Damage (trace_ent, from, from, damage);
- }
-};
-
-
-void() W_FireLightning =
-{
- local vector org;
- local float cells;
-
- if (self.ammo_cells < 1)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- return;
- }
-
-// 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 (self.t_width < time)
- {
- sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
- self.t_width = time + 0.6;
- }
- self.punchangle_x = -2;
-
- self.currentammo = self.ammo_cells = self.ammo_cells - 1;
-
- org = self.origin + '0 0 16';
-
- traceline (org, org + v_forward*600, TRUE, self);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- WriteCoord (MSG_BROADCAST, trace_endpos_x);
- WriteCoord (MSG_BROADCAST, trace_endpos_y);
- WriteCoord (MSG_BROADCAST, trace_endpos_z);
-
- LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
-};
-
-
-//=============================================================================
-
-
-/*
-================
-GrenadeExplode2
-
-This is the same as the original GrenadeExplode function except that it
-will ignore the entity specified by the "ignore" parameter when dealing
-damage. -- iw
-================
-*/
-void(entity ignore) GrenadeExplode2 =
-{
- T_RadiusDamage (self, self.owner, 120, ignore);
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
-
- BecomeExplosion ();
-};
-
-
-/*
-================
-GrenadeExplode
-
-Refactored. -- iw
-================
-*/
-void() GrenadeExplode =
-{
- GrenadeExplode2 (world);
-};
-
-
-/*
-================
-GrenadeTouch
-
-This has been modified to fix a bug in the original code, which is that
-an entity with a very large bounding box (e.g. the size of monster_boss
-or monster_oldone) would receive little or no damage from a grenade
-impact. (In the original game, this bug didn't really matter because
-the largest DAMAGE_AIM entities were Shambler-sized.)
-
-In the original code, this function simply called GrenadeExplode, which
-called T_RadiusDamage, which deals an amount of damage based on the
-distance to the center of the victim's bounding box. Therefore, the
-larger the victim's bounding box, the lower the amount of damage that
-a grenade impact could deal.
-
-This modified version of GrenadeTouch adds a hack so that an entity
-which is larger than Shambler-size is treated differently: damage will
-be dealt to it using the same logic as a rocket impact, i.e. T_Damage
-will be called to deal damage to the impacted entity, and then radius
-damage will be dealt to any other entities in the vicinity. Grenades
-and rockets have always dealt the same amount of radius damage, so
-making the impact damage the same seemed a reasonable solution.
-
-The reason this logic is only used for very large entities is because
-I didn't want to affect the amount of damage that grenades deal to any
-of the original monsters under any circumstances. -- iw
-================
-*/
-void() GrenadeTouch =
-{
- local float damg;
-
- if (other == self.owner)
- return; // don't explode on owner
- if (other.takedamage == DAMAGE_AIM)
- {
- // see the explanation above -- iw
- if (other.size_x > VEC_HULL2_SIZE_x ||
- other.size_y > VEC_HULL2_SIZE_y ||
- other.size_z > VEC_HULL2_SIZE_z)
- {
- // note that the logic for monster_shambler's partial immunity
- // to explosions is not required because this is only for
- // entities which are larger than monster_shambler -- iw
- damg = 100 + random () * 20;
- T_Damage (other, self, self.owner, damg);
- GrenadeExplode2 (other);
- return;
- }
- GrenadeExplode ();
- return;
- }
- if (self.count < time) {
- sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
- }
- self.count = time + .02;
- if (self.velocity == '0 0 0')
- self.avelocity = '0 0 0';
-};
-
-
-/*
-================
-W_FireGrenade
-================
-*/
-void() W_FireGrenade =
-{
- local entity missile;
-
- self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
-
- sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
-
- self.punchangle_x = -2;
-
- missile = spawn ();
- missile.owner = self;
- missile.movetype = MOVETYPE_BOUNCE;
- missile.solid = SOLID_BBOX;
- missile.classname = "grenade";
-
-// set missile speed
-
- makevectors (self.v_angle);
-
- if (self.v_angle_x)
- missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
- else
- {
- missile.velocity = aim(self, 10000);
- missile.velocity = missile.velocity * 600;
- missile.velocity_z = 200;
- }
-
- missile.avelocity = '300 300 300';
-
- missile.angles = vectoangles(missile.velocity);
-
- missile.touch = GrenadeTouch;
-
-// set missile duration
- missile.nextthink = time + 2.5;
- missile.think = GrenadeExplode;
-
- setmodel (missile, "progs/grenade.mdl");
- setsize (missile, '0 0 0', '0 0 0');
- setorigin (missile, self.origin);
-};
-
-
-//=============================================================================
-
-void() spike_touch;
-void() superspike_touch;
-
-
-/*
-===============
-launch_spike
-
-Used for both the player and the ogre
-===============
-*/
-
-void(vector org, vector dir, float speed) launch_spike2 = {
- newmis = spawn ();
- newmis.owner = self;
- newmis.movetype = MOVETYPE_FLYMISSILE;
- newmis.solid = SOLID_BBOX;
-
- newmis.angles = vectoangles(dir);
-
- newmis.touch = spike_touch;
- newmis.classname = "spike";
- if (self.homing > 0)
- {
- SetupHoming(newmis, speed);
- }
- else
- {
- newmis.think = SUB_Remove;
- newmis.nextthink = time + 6;
- }
- setmodel (newmis, "progs/spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- setorigin (newmis, org);
-
- SetSpeed(newmis, dir, speed * (self.proj_speed_mod ? self.proj_speed_mod : 1));
-};
-void(vector org, vector dir) launch_spike = {
- launch_spike2(org,dir,1000);
-};
-
-void() W_FireSuperSpikes =
-{
- local vector dir;
-
- 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;
- dir = aim (self, 1000);
- launch_spike (self.origin + '0 0 16', dir);
- newmis.touch = superspike_touch;
- setmodel (newmis, "progs/s_spike.mdl");
- setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
- self.punchangle_x = -2;
-};
-
-void(float ox) W_FireSpikes =
-{
- local vector dir;
-
- makevectors (self.v_angle);
-
- if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
- {
- W_FireSuperSpikes ();
- return;
- }
-
- if (self.ammo_nails < 1)
- {
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
- return;
- }
-
- sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
- self.attack_finished = time + 0.2;
- self.currentammo = self.ammo_nails = self.ammo_nails - 1;
- dir = aim (self, 1000);
- // launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
- launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
-
- self.punchangle_x = -2;
-
- };
-
-
-
-void() spike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (9);
- T_Damage (other, self, self.owner, 9);
- }
- else
- {
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- if (self.owner.snd_hit)
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
-
- else if (self.classname == "wizspike")
- WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
- else if (self.classname == "knightspike")
- WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
- else
- WriteByte (MSG_BROADCAST, TE_SPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-
-void() superspike_touch =
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (18);
- T_Damage (other, self, self.owner, 18);
- }
- else
- {
- if (self.owner.snd_hit)
- {
- sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_GUNSHOT);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- }
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-
-};
-void() superduperspike_touch = //dumptruck_ds for Style 2 Ogre see ogre.qc
-{
- if (other == self.owner)
- return;
-
- if (other.solid == SOLID_TRIGGER)
- return; // trigger field, do nothing
-
- if (pointcontents(self.origin) == CONTENT_SKY)
- {
- remove(self);
- return;
- }
-
-// hit something that bleeds
- if (other.takedamage)
- {
- spawn_touchblood (36);
- T_Damage (other, self, self.owner, 36);
- sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
- }
- else
- {
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- }
-
- remove(self);
-};
-
-/*
-===============================================================================
-
-PLAYER WEAPON USE
-
-===============================================================================
-*/
-
-void() W_SetCurrentAmmo =
-{
- player_run (); // get out of any weapon firing states
-
- self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
-
- if (self.weapon == IT_AXE)
- {
- self.currentammo = 0;
- self.weaponmodel = "progs/v_axe.mdl";
- self.weaponframe = 0;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- self.currentammo = self.ammo_cells;
- self.weaponmodel = "progs/v_light.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_CELLS;
- }
- else
- {
- self.currentammo = 0;
- self.weaponmodel = "";
- self.weaponframe = 0;
- }
-};
-
-float() W_BestWeapon =
-{
- local float it;
-
- it = self.items;
-
- if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
- return IT_LIGHTNING;
- if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
- return IT_SUPER_NAILGUN;
- if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
- return IT_SUPER_SHOTGUN;
- if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
- return IT_NAILGUN;
- if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
- return IT_SHOTGUN;
- return IT_AXE;
-};
-
-float() W_CheckNoAmmo =
-{
- if (self.currentammo > 0)
- return TRUE;
-
- if (self.weapon == IT_AXE)
- return TRUE;
-
- self.weapon = W_BestWeapon ();
-
- W_SetCurrentAmmo ();
-
-// drop the weapon down
- return FALSE;
-};
-
-/*
-============
-W_Attack
-
-An attack impulse can be triggered now
-============
-*/
-void() player_axe1;
-void() player_axeb1;
-void() player_axec1;
-void() player_axed1;
-void() player_shot1;
-void() player_nail1;
-void() player_light1;
-void() player_rocket1;
-
-void() W_Attack =
-{
- local float r;
-
- if (!W_CheckNoAmmo ())
- return;
-
- makevectors (self.v_angle); // calculate forward angle for velocity
- self.show_hostile = time + 1; // wake monsters up
-
- if (self.weapon == IT_AXE)
- {
- sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
- r = random();
- if (r < 0.25)
- player_axe1 ();
- else if (r<0.5)
- player_axeb1 ();
- else if (r<0.75)
- player_axec1 ();
- else
- player_axed1 ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- player_shot1 ();
- W_FireShotgun ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- player_shot1 ();
- W_FireSuperShotgun ();
- self.attack_finished = time + 0.7;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- player_rocket1();
- W_FireGrenade();
- self.attack_finished = time + 0.6;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- player_rocket1();
- W_FireRocket();
- self.attack_finished = time + 0.8;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- player_light1();
- self.attack_finished = time + 0.1;
- sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
- }
-};
-
-/*
-============
-W_ChangeWeapon
-
-============
-*/
-void() W_ChangeWeapon =
-{
- local float it, am, fl;
-
- it = self.items;
- am = 0;
-
- if (self.impulse == 1)
- {
- fl = IT_AXE;
- }
- else if (self.impulse == 2)
- {
- fl = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.impulse == 3)
- {
- fl = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.impulse == 4)
- {
- fl = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.impulse == 5)
- {
- fl = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.impulse == 6)
- {
- fl = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 7)
- {
- fl = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 8)
- {
- fl = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
- else
- {
- dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
- dprint (ftos (self.impulse));
- dprint ("\n");
- return;
- }
-
- self.impulse = 0;
-
- if (!(self.items & fl))
- { // don't have the weapon or the ammo
- sprint (self, "no weapon.\n");
- return;
- }
-
- if (am)
- { // don't have the ammo
- sprint (self, "not enough ammo.\n");
- return;
- }
-
-//
-// set weapon, set ammo
-//
- self.weapon = fl;
- W_SetCurrentAmmo ();
-};
-
-/*
-============
-CheatCommand
-============
-*/
-void() CheatCommand =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
-// if (deathmatch || coop)
- if (deathmatch)
-// 1998-07-29 Cheats coop fix by Maddes end
- return;
-
- self.ammo_rockets = 100;
- self.ammo_nails = 200;
- self.ammo_shells = 100;
- self.items = self.items |
- IT_AXE |
- IT_SHOTGUN |
- IT_SUPER_SHOTGUN |
- IT_NAILGUN |
- IT_SUPER_NAILGUN |
- IT_GRENADE_LAUNCHER |
- IT_ROCKET_LAUNCHER;
- GiveAllKeys (self); // support for item_key_custom -- iw
-
- self.ammo_cells = 200;
- self.items = self.items | IT_LIGHTNING;
-
- self.weapon = IT_ROCKET_LAUNCHER;
- self.impulse = 0;
- W_SetCurrentAmmo ();
-};
-
-/*
-============
-CycleWeaponCommand
-
-Go to the next weapon with ammo
-============
-*/
-void() CycleWeaponCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-CycleWeaponReverseCommand
-
-Go to the prev weapon with ammo
-============
-*/
-void() CycleWeaponReverseCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-ServerflagsCommand
-
-Just for development
-============
-*/
-void() ServerflagsCommand =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
- if (deathmatch)
- return;
-// 1998-07-29 Cheats coop fix by Maddes end
- serverflags = serverflags * 2 + 1;
-};
-
-void() QuadCheat =
-{
-// 1998-07-29 Cheats coop fix by Maddes start
-// if (deathmatch || coop)
- if (deathmatch)
-// 1998-07-29 Cheats coop fix by Maddes end
- return;
- self.super_time = 1;
- self.super_damage_finished = time + 30;
- self.items = self.items | IT_QUAD;
- dprint ("quad cheat\n");
-};
-
-/*
-============
-ImpulseCommands
-
-============
-*/
-void() ImpulseCommands =
-{
- if (self.impulse >= 1 && self.impulse <= 8)
- W_ChangeWeapon ();
-
- if (self.impulse == 9)
- CheatCommand ();
- if (self.impulse == 10)
- CycleWeaponCommand ();
- if (self.impulse == 11)
- ServerflagsCommand ();
- if (self.impulse == 12)
- CycleWeaponReverseCommand ();
-
- if (self.impulse == 255)
- QuadCheat ();
-// dumptruck_ds version inspired by Copper
- if (self.impulse == 100)
- sprint(self, version);
-
- // if (self.impulse == 101) // debugging armor shards -- dumptruck_ds
- // dprint ("Armortype is");
- // dprint (ftos(self.armortype));
- // dprint ("\n");
-
- self.impulse = 0;
-};
-
-/*
-============
-W_WeaponFrame
-
-Called every frame so impulse events can be handled as well as possible
-============
-*/
-void() W_WeaponFrame =
-{
- if (time < self.attack_finished)
- return;
-
-if (self.impulse) // 1998-08-14 Constantly checking all impulses fix by Perged
- ImpulseCommands ();
-
-// check for attack
- if (self.button0)
- {
- SuperDamageSound ();
- W_Attack ();
- }
-};
-
-/*
-========
-SuperDamageSound
-
-Plays sound if needed
-========
-*/
-void() SuperDamageSound =
-{
- if (self.super_damage_finished > time)
- {
- if (self.super_sound < time)
- {
- self.super_sound = time + 1;
- sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
- }
- }
- return;
-};
-
-void() MissileHome =
-{
- local vector dir, vtemp;
- vtemp = self.enemy.origin + '0 0 10';
-
- if (self.enemy.health < 1)
- {
- remove(self);
- return;
- }
- dir = normalize(vtemp - self.origin);
- if (self.homing < 1 && self.homing > 0) // can't do better than 100% homing
- {
- /*
- This finds a vector somewhere between the vector the projectile is currently
- travelling on and the vector that it would normally snap to for homing
-
- homing = .25 means it will go 25% to the new direction, but keep 75% of the
- original vector, resulting in a wider turning range.
- */
- dir = normalize((dir * self.homing) + normalize(self.velocity * (1 - self.homing)));
- }
- if (!self.avelocity)
- self.angles = vectoangles(dir);
- SetSpeed(self, dir, self.proj_basespeed);
-
- if (self.homing > 0)
- {
- if (self.homing < 1 && self.attack_finished && self.attack_finished < time )
- {
- //dprint("incrementing homing | ");
- //dprint("old: ");
- //dprint(ftos(self.homing));
- //dprint(" | new: ");
- self.homing = self.homing + 0.005;
- //dprint(ftos(self.homing));
- //dprint("\n");
- }
- self.nextthink = time + 0.2;
- self.think = MissileHome;
- }
-};
-
-void(entity mis, float speed) SetupHoming =
-{
- local vector dir;
- local float dist, flytime, speedmod;
- if (self.proj_speed_mod > 1)
- {
- speedmod = 1/self.proj_speed_mod;
- }
- else if (speed > 250)
- {
- speedmod = 1 / (speed / 250);
- }
- else
- {
- speedmod = 1;
- }
- dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
- dist = vlen (self.enemy.origin - self.origin);
- flytime = dist * 0.002 * speedmod;
- if (flytime < 0.1)
- flytime = 0.1;
-
- mis.enemy = self.enemy;
- mis.proj_basespeed = speed;
- mis.homing = self.homing;
- mis.nextthink = flytime + time;
- mis.think = MissileHome;
- if (self.waitmin > 0)
- {
- mis.attack_finished = time + self.waitmin; // store time to start increasing
- }
-};
+/*
+*/
+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(vector org, vector vel, float damage) SpawnBlood;
+void() SuperDamageSound;
+void() create_mobot; //dumptruck_ds mobot.qc
+void(entity mis, float speed) SetupHoming;
+
+void(entity mis, vector dir, float speed) SetSpeed =
+{
+ if (cvar("sv_maxvelocity") > speed)
+ {
+ mis.velocity = dir * speed;
+ }
+ else {
+ mis.velocity = dir * cvar("sv_maxvelocity");
+ }
+};
+
+// called by worldspawn
+void() W_Precache =
+{
+ precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
+ precache_sound ("weapons/rocket1i.wav"); // spike gun
+ precache_sound ("weapons/sgun1.wav");
+ precache_sound ("weapons/guncock.wav"); // player shotgun
+ precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/spike2.wav"); // super spikes
+ precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
+ precache_sound ("weapons/grenade.wav"); // grenade launcher
+ precache_sound ("weapons/bounce.wav"); // grenade bounce
+ precache_sound ("weapons/shotgn2.wav"); // super shotgun
+
+// dumptruck_ds mobot.qc precaches START
+
+ precache_model ("progs/ogre.mdl");
+ precache_model ("progs/h_ogre.mdl");
+ precache_model ("progs/grenade.mdl");
+ precache_sound ("ogre/ogdrag.wav");
+ precache_sound ("ogre/ogdth.wav");
+ precache_sound ("ogre/ogidle.wav");
+ precache_sound ("ogre/ogidle2.wav");
+ precache_sound ("ogre/ogpain1.wav");
+ precache_sound ("ogre/ogsawatk.wav");
+ precache_sound ("ogre/ogwake.wav");
+
+ precache_model ("progs/demon.mdl");
+ precache_model ("progs/h_demon.mdl");
+
+ precache_sound ("demon/ddeath.wav");
+ precache_sound ("demon/dhit2.wav");
+ precache_sound ("demon/djump.wav");
+ precache_sound ("demon/dpain1.wav");
+ precache_sound ("demon/idle1.wav");
+ precache_sound ("demon/sight2.wav");
+
+ precache_model2 ("progs/enforcer.mdl");
+ precache_model2 ("progs/h_mega.mdl");
+ precache_model2 ("progs/laser.mdl");
+ precache_model2 ("progs/s_spike.mdl");
+
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2("enforcer/idle1.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2("enforcer/sight4.wav");
+
+ precache_model ("progs/soldier.mdl");
+ precache_model ("progs/h_guard.mdl");
+
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound ("soldier/death1.wav");
+ precache_sound ("soldier/idle.wav");
+ precache_sound ("soldier/pain1.wav");
+ precache_sound ("soldier/pain2.wav");
+ precache_sound ("soldier/sattck1.wav");
+ precache_sound ("soldier/sight1.wav");
+ precache_sound ("player/udeath.wav"); // gib death
+
+ precache_model ("progs/h_dog.mdl");
+ precache_model ("progs/dog.mdl");
+ precache_sound ("dog/dattack1.wav");
+ precache_sound("dog/ddeath.wav");
+ precache_sound ("dog/dpain1.wav");
+ precache_sound ("dog/dsight.wav");
+ precache_sound ("dog/idle.wav");
+
+ precache_model ("progs/wizard.mdl");
+ precache_model ("progs/h_wizard.mdl");
+ precache_model ("progs/w_spike.mdl");
+
+ precache_sound ("wizard/hit.wav"); // used by c code
+ precache_sound ("wizard/wattack.wav");
+ precache_sound ("wizard/wdeath.wav");
+ precache_sound ("wizard/widle1.wav");
+ precache_sound ("wizard/widle2.wav");
+ precache_sound ("wizard/wpain.wav");
+ precache_sound ("wizard/wsight.wav");
+
+ precache_model2 ("progs/shalrath.mdl");
+ precache_model2 ("progs/h_shal.mdl");
+ precache_model2 ("progs/v_spike.mdl");
+
+ precache_sound2 ("shalrath/attack.wav");
+ precache_sound2 ("shalrath/attack2.wav");
+ precache_sound2 ("shalrath/death.wav");
+ precache_sound2 ("shalrath/idle.wav");
+ precache_sound2 ("shalrath/pain.wav");
+ precache_sound2 ("shalrath/sight.wav");
+
+ precache_model ("progs/knight.mdl");
+ precache_model ("progs/h_knight.mdl");
+
+ precache_sound ("knight/kdeath.wav");
+ precache_sound ("knight/khurt.wav");
+ precache_sound ("knight/ksight.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+ precache_sound ("knight/idle.wav");
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+
+ precache_sound2 ("hknight/attack1.wav");
+ precache_sound2 ("hknight/death1.wav");
+ precache_sound2 ("hknight/pain1.wav");
+ precache_sound2 ("hknight/sight1.wav");
+ precache_sound ("hknight/hit.wav"); // used by C code, so don't sound2
+ precache_sound2 ("hknight/slash1.wav");
+ precache_sound2 ("hknight/idle.wav");
+ precache_sound2 ("hknight/grunt.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_sound2 ("blob/death1.wav");
+ precache_sound2 ("blob/hit1.wav");
+ precache_sound2 ("blob/land1.wav");
+ precache_sound2 ("blob/sight1.wav");
+
+ precache_model ("progs/zombie.mdl");
+ precache_model ("progs/h_zombie.mdl");
+ precache_model ("progs/zom_gib.mdl");
+
+ precache_sound ("zombie/z_idle.wav");
+ precache_sound ("zombie/z_idle1.wav");
+ precache_sound ("zombie/z_shot1.wav");
+ precache_sound ("zombie/z_gib.wav");
+ precache_sound ("zombie/z_pain.wav");
+ precache_sound ("zombie/z_pain1.wav");
+ precache_sound ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ precache_sound ("zombie/idle_w2.wav");
+
+ precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+
+ precache_sound ("shambler/sattck1.wav");
+ precache_sound ("shambler/sboom.wav");
+ precache_sound ("shambler/sdeath.wav");
+ precache_sound ("shambler/shurt2.wav");
+ precache_sound ("shambler/sidle.wav");
+ precache_sound ("shambler/ssight.wav");
+ precache_sound ("shambler/melee1.wav");
+ precache_sound ("shambler/melee2.wav");
+ precache_sound ("shambler/smack.wav");
+
+ // dumptruck_ds mobot.qc END
+};
+
+float() crandom =
+{
+ return 2*(random() - 0.5);
+};
+
+/*
+================
+W_FireAxe
+================
+*/
+void() W_FireAxe =
+{
+ local vector source;
+ local vector org;
+
+ makevectors (self.v_angle);
+ source = self.origin + '0 0 16';
+ traceline (source, source + v_forward*64, FALSE, self);
+ if (trace_fraction == 1.0)
+ return;
+ org = trace_endpos - v_forward*4;
+
+ if (trace_ent.takedamage)
+ {
+ trace_ent.axhitme = 1;
+ SpawnBlood (org, '0 0 0', 20);
+ T_Damage (trace_ent, self, self, 20);
+ }
+ else
+ { // hit wall
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ 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);
+ }
+};
+
+
+//============================================================================
+
+
+vector() wall_velocity =
+{
+ local vector vel;
+
+ vel = normalize (self.velocity);
+ vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
+ vel = vel + 2*trace_plane_normal;
+ vel = vel * 200;
+
+ return vel;
+};
+
+
+/*
+================
+SpawnMeatSpray
+================
+*/
+void(vector org, vector vel) SpawnMeatSpray =
+{
+ local entity missile;
+
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_NOT;
+
+ makevectors (self.angles);
+
+ missile.velocity = vel;
+ missile.velocity_z = missile.velocity_z + 250 + 50*random();
+
+ missile.avelocity = '3000 1000 2000';
+
+// set missile duration
+ missile.nextthink = time + 1;
+ missile.think = SUB_Remove;
+
+ setmodel (missile, "progs/zom_gib.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, org);
+};
+
+/*
+================
+SpawnBlood
+================
+*/
+void(vector org, vector vel, float damage) SpawnBlood =
+{
+ particle (org, vel*0.1, 73, damage*2);
+};
+
+/*
+================
+spawn_touchblood
+================
+*/
+void(float damage) spawn_touchblood =
+{
+ local vector vel;
+
+ vel = wall_velocity () * 0.2;
+ SpawnBlood (self.origin + vel*0.01, vel, damage);
+};
+
+
+/*
+================
+SpawnChunk
+================
+*/
+void(vector org, vector vel) SpawnChunk =
+{
+ particle (org, vel*0.02, 0, 10);
+};
+
+/*
+==============================================================================
+
+MULTI-DAMAGE
+
+Collects multiple small damages into a single damage
+
+==============================================================================
+*/
+
+entity multi_ent;
+float multi_damage;
+
+void() ClearMultiDamage =
+{
+ multi_ent = world;
+ multi_damage = 0;
+};
+
+void() ApplyMultiDamage =
+{
+ if (!multi_ent)
+ return;
+ T_Damage (multi_ent, self, self, multi_damage);
+};
+
+void(entity hit, float damage) AddMultiDamage =
+{
+ if (!hit)
+ return;
+
+ if (hit != multi_ent)
+ {
+ ApplyMultiDamage ();
+ multi_damage = damage;
+ multi_ent = hit;
+ }
+ else
+ multi_damage = multi_damage + damage;
+};
+
+/*
+==============================================================================
+
+BULLETS
+
+==============================================================================
+*/
+
+/*
+================
+TraceAttack
+================
+*/
+void(float damage, vector dir) TraceAttack =
+{
+ local vector vel, org;
+
+ vel = normalize(dir + v_up*crandom() + v_right*crandom());
+ vel = vel + 2*trace_plane_normal;
+ vel = vel * 200;
+
+ org = trace_endpos - dir*4;
+
+ if (trace_ent.takedamage)
+ {
+ SpawnBlood (org, vel*0.2, damage);
+ AddMultiDamage (trace_ent, damage);
+ }
+ 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);
+ }
+};
+
+/*
+================
+FireBullets
+
+Used by shotgun, super shotgun, and enemy soldier firing
+Go to the trouble of combining multiple pellets into a single damage call.
+================
+*/
+void(float shotcount, vector dir, vector spread) FireBullets =
+{
+ local vector direction;
+ local vector src;
+
+ makevectors(self.v_angle);
+
+ src = self.origin + v_forward*10;
+ src_z = self.absmin_z + self.size_z * 0.7;
+
+ ClearMultiDamage ();
+ 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)
+ TraceAttack (4, direction);
+
+ shotcount = shotcount - 1;
+ }
+ ApplyMultiDamage ();
+};
+
+/*
+================
+W_FireShotgun
+================
+*/
+void() W_FireShotgun =
+{
+ local vector dir;
+
+ sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 1;
+ dir = aim (self, 100000);
+ FireBullets (6, dir, '0.04 0.04 0');
+};
+
+
+/*
+================
+W_FireSuperShotgun
+================
+*/
+void() W_FireSuperShotgun =
+{
+ local vector dir;
+
+ if (self.currentammo == 1)
+ {
+ W_FireShotgun ();
+ return;
+ }
+
+ sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -4;
+
+ self.currentammo = self.ammo_shells = self.ammo_shells - 2;
+ dir = aim (self, 100000);
+ FireBullets (14, dir, '0.14 0.08 0');
+};
+
+
+/*
+==============================================================================
+
+ROCKETS
+
+==============================================================================
+*/
+
+void() s_explode1 = [0, s_explode2] {};
+void() s_explode2 = [1, s_explode3] {};
+void() s_explode3 = [2, s_explode4] {};
+void() s_explode4 = [3, s_explode5] {};
+void() s_explode5 = [4, s_explode6] {};
+void() s_explode6 = [5, SUB_Remove] {};
+
+void() BecomeExplosion =
+{
+ self.movetype = MOVETYPE_NONE;
+ self.velocity = '0 0 0';
+ self.touch = SUB_Null;
+ setmodel (self, "progs/s_explod.spr");
+ self.solid = SOLID_NOT;
+ s_explode1 ();
+};
+
+void() T_MissileTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = 100 + random()*20;
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, 120, other);
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+
+};
+//dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+
+void(float direct, float splash) T_MonsterMisTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+ damg = direct + random()*2; //dumptruck_ds
+
+ if (other.health)
+ {
+ if (other.classname == "monster_shambler")
+ damg = damg * 0.5; // mostly immune
+ T_Damage (other, self, self.owner, damg );
+ }
+
+ // don't do radius damage to the other, because all the damage
+ // was done in the impact
+ T_RadiusDamage (self, self.owner, splash, other); //dumptruck_ds
+
+// sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ self.origin = self.origin - 8*normalize(self.velocity);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+void() T_GruntMisTouch =
+{
+ T_MonsterMisTouch(30, 40);
+};
+
+ // less direct damage, more splash than grunt
+ // TODO: add damage modifier
+void() T_HellKnightMisTouch =
+{
+ T_MonsterMisTouch(20, 50);
+};
+
+// big damage. explody scrag should be beefy.
+// TODO: add damage modifier
+void() T_WizardMisTouch =
+{
+ T_MonsterMisTouch(50, 50);
+};
+//dumptruck_ds end
+
+/*
+================
+W_FireRocket
+================
+*/
+void() W_FireRocket =
+{
+ local entity missile;
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed
+
+ makevectors (self.v_angle);
+ missile.velocity = aim(self, 1000);
+ missile.velocity = missile.velocity * 1000;
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = T_MissileTouch;
+
+// set missile duration
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+
+ setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+/*
+================
+W_GruntRocket //dumptruck_ds start -- from inside qc tut http://www.insideqc.com/qctut/lesson-32.shtml
+================
+*/
+void() W_GruntRocket =
+{
+ local entity missile;
+
+ // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; dumptruck_ds
+
+ sound_attack (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_FLYMISSILE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "missile";
+
+// set missile speed -- dumptruck_ds below
+
+ missile.velocity = normalize(self.enemy.origin - self.origin);
+ SetSpeed(missile, missile.velocity, 900*self.proj_speed_mod);
+ missile.angles = vectoangles(missile.velocity);
+ missile.touch = T_GruntMisTouch;
+
+ // makevectors (self.v_angle);
+ // missile.velocity = aim(self, 1000);
+ // missile.velocity = missile.velocity * 1000;
+ // missile.angles = vectoangles(missile.velocity);
+
+ // missile.touch = T_MissileTouch;
+
+// set missile duration
+ if (self.homing > 0)
+ {
+ SetupHoming(missile, 900 * self.proj_speed_mod);
+ }
+ else {
+ missile.nextthink = time + 5;
+ missile.think = SUB_Remove;
+ }
+ if (self.mdl_proj != "") // dumptruck_ds
+ {
+ setmodel (missile, self.mdl_proj);
+ }
+ else
+ {
+ setmodel (missile, "progs/missile.mdl");
+ }
+
+ if (!missile.skin_proj) // dumptruck_ds
+ {
+ missile.skin = self.skin_proj;
+ }
+ else
+ {
+ missile.skin = 0;
+ }
+// dumptruck_ds - end
+
+ // setmodel (missile, "progs/missile.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ makevectors (self.angles); //thanks Voidforce -- dumptruck_ds
+ setorigin (missile, self.origin + v_forward * 30 + v_right * 5 + '0 0 12');
+ // setorigin (missile, self.origin + v_forward*8 + '0 0 16');
+};
+
+//end dumptruck_ds grunt missle end
+
+/*
+===============================================================================
+
+LIGHTNING
+
+===============================================================================
+*/
+
+/*
+=================
+LightningDamage
+=================
+*/
+void(vector p1, vector p2, entity from, float damage) LightningDamage =
+{
+ local entity e1, e2;
+ local vector f;
+
+ f = p2 - p1;
+ normalize (f);
+ f_x = 0 - f_y;
+ f_y = f_x;
+ f_z = 0;
+ f = f*16;
+
+ e1 = e2 = world;
+
+ traceline (p1, p2, FALSE, self);
+ if (trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ if (self.classname == "player")
+ {
+ if (other.classname == "player")
+ trace_ent.velocity_z = trace_ent.velocity_z + 400;
+ }
+ }
+ e1 = trace_ent;
+
+ traceline (p1 + f, p2 + f, FALSE, self);
+ if (trace_ent != e1 && trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ }
+ e2 = trace_ent;
+
+ traceline (p1 - f, p2 - f, FALSE, self);
+ if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
+ {
+ particle (trace_endpos, '0 0 100', 225, damage*4);
+ T_Damage (trace_ent, from, from, damage);
+ }
+};
+
+
+void() W_FireLightning =
+{
+ local vector org;
+ local float cells;
+
+ if (self.ammo_cells < 1)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ return;
+ }
+
+// 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 (self.t_width < time)
+ {
+ sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
+ self.t_width = time + 0.6;
+ }
+ self.punchangle_x = -2;
+
+ self.currentammo = self.ammo_cells = self.ammo_cells - 1;
+
+ org = self.origin + '0 0 16';
+
+ traceline (org, org + v_forward*600, TRUE, self);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, self);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ WriteCoord (MSG_BROADCAST, trace_endpos_x);
+ WriteCoord (MSG_BROADCAST, trace_endpos_y);
+ WriteCoord (MSG_BROADCAST, trace_endpos_z);
+
+ LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
+};
+
+
+//=============================================================================
+
+
+/*
+================
+GrenadeExplode2
+
+This is the same as the original GrenadeExplode function except that it
+will ignore the entity specified by the "ignore" parameter when dealing
+damage. -- iw
+================
+*/
+void(entity ignore) GrenadeExplode2 =
+{
+ T_RadiusDamage (self, self.owner, 120, ignore);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+
+ BecomeExplosion ();
+};
+
+
+/*
+================
+GrenadeExplode
+
+Refactored. -- iw
+================
+*/
+void() GrenadeExplode =
+{
+ GrenadeExplode2 (world);
+};
+
+
+/*
+================
+GrenadeTouch
+
+This has been modified to fix a bug in the original code, which is that
+an entity with a very large bounding box (e.g. the size of monster_boss
+or monster_oldone) would receive little or no damage from a grenade
+impact. (In the original game, this bug didn't really matter because
+the largest DAMAGE_AIM entities were Shambler-sized.)
+
+In the original code, this function simply called GrenadeExplode, which
+called T_RadiusDamage, which deals an amount of damage based on the
+distance to the center of the victim's bounding box. Therefore, the
+larger the victim's bounding box, the lower the amount of damage that
+a grenade impact could deal.
+
+This modified version of GrenadeTouch adds a hack so that an entity
+which is larger than Shambler-size is treated differently: damage will
+be dealt to it using the same logic as a rocket impact, i.e. T_Damage
+will be called to deal damage to the impacted entity, and then radius
+damage will be dealt to any other entities in the vicinity. Grenades
+and rockets have always dealt the same amount of radius damage, so
+making the impact damage the same seemed a reasonable solution.
+
+The reason this logic is only used for very large entities is because
+I didn't want to affect the amount of damage that grenades deal to any
+of the original monsters under any circumstances. -- iw
+================
+*/
+void() GrenadeTouch =
+{
+ local float damg;
+
+ if (other == self.owner)
+ return; // don't explode on owner
+ if (other.takedamage == DAMAGE_AIM)
+ {
+ // see the explanation above -- iw
+ if (other.size_x > VEC_HULL2_SIZE_x ||
+ other.size_y > VEC_HULL2_SIZE_y ||
+ other.size_z > VEC_HULL2_SIZE_z)
+ {
+ // note that the logic for monster_shambler's partial immunity
+ // to explosions is not required because this is only for
+ // entities which are larger than monster_shambler -- iw
+ damg = 100 + random () * 20;
+ T_Damage (other, self, self.owner, damg);
+ GrenadeExplode2 (other);
+ return;
+ }
+ GrenadeExplode ();
+ return;
+ }
+ if (self.count < time) {
+ sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
+ }
+ self.count = time + .02;
+ if (self.velocity == '0 0 0')
+ self.avelocity = '0 0 0';
+};
+
+
+/*
+================
+W_FireGrenade
+================
+*/
+void() W_FireGrenade =
+{
+ local entity missile;
+
+ self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
+
+ sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
+
+ self.punchangle_x = -2;
+
+ missile = spawn ();
+ missile.owner = self;
+ missile.movetype = MOVETYPE_BOUNCE;
+ missile.solid = SOLID_BBOX;
+ missile.classname = "grenade";
+
+// set missile speed
+
+ makevectors (self.v_angle);
+
+ if (self.v_angle_x)
+ missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
+ else
+ {
+ missile.velocity = aim(self, 10000);
+ missile.velocity = missile.velocity * 600;
+ missile.velocity_z = 200;
+ }
+
+ missile.avelocity = '300 300 300';
+
+ missile.angles = vectoangles(missile.velocity);
+
+ missile.touch = GrenadeTouch;
+
+// set missile duration
+ missile.nextthink = time + 2.5;
+ missile.think = GrenadeExplode;
+
+ setmodel (missile, "progs/grenade.mdl");
+ setsize (missile, '0 0 0', '0 0 0');
+ setorigin (missile, self.origin);
+};
+
+
+//=============================================================================
+
+void() spike_touch;
+void() superspike_touch;
+
+
+/*
+===============
+launch_spike
+
+Used for both the player and the ogre
+===============
+*/
+
+void(vector org, vector dir, float speed) launch_spike2 = {
+ newmis = spawn ();
+ newmis.owner = self;
+ newmis.movetype = MOVETYPE_FLYMISSILE;
+ newmis.solid = SOLID_BBOX;
+
+ newmis.angles = vectoangles(dir);
+
+ newmis.touch = spike_touch;
+ newmis.classname = "spike";
+ if (self.homing > 0)
+ {
+ SetupHoming(newmis, speed);
+ }
+ else
+ {
+ newmis.think = SUB_Remove;
+ newmis.nextthink = time + 6;
+ }
+ setmodel (newmis, "progs/spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ setorigin (newmis, org);
+
+ SetSpeed(newmis, dir, speed * (self.proj_speed_mod ? self.proj_speed_mod : 1));
+};
+void(vector org, vector dir) launch_spike = {
+ launch_spike2(org,dir,1000);
+};
+
+void() W_FireSuperSpikes =
+{
+ local vector dir;
+
+ 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;
+ dir = aim (self, 1000);
+ launch_spike (self.origin + '0 0 16', dir);
+ newmis.touch = superspike_touch;
+ setmodel (newmis, "progs/s_spike.mdl");
+ setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
+ self.punchangle_x = -2;
+};
+
+void(float ox) W_FireSpikes =
+{
+ local vector dir;
+
+ makevectors (self.v_angle);
+
+ if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
+ {
+ W_FireSuperSpikes ();
+ return;
+ }
+
+ if (self.ammo_nails < 1)
+ {
+ self.weapon = W_BestWeapon ();
+ W_SetCurrentAmmo ();
+ return;
+ }
+
+ sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
+ self.attack_finished = time + 0.2;
+ self.currentammo = self.ammo_nails = self.ammo_nails - 1;
+ dir = aim (self, 1000);
+ // launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
+ launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds
+
+ self.punchangle_x = -2;
+
+ };
+
+
+
+void() spike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (9);
+ T_Damage (other, self, self.owner, 9);
+ }
+ else
+ {
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ if (self.owner.snd_hit)
+ {
+ sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+
+ else if (self.classname == "wizspike")
+ WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
+ else if (self.classname == "knightspike")
+ WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
+ else
+ WriteByte (MSG_BROADCAST, TE_SPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+
+};
+
+void() superspike_touch =
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (18);
+ T_Damage (other, self, self.owner, 18);
+ }
+ else
+ {
+ if (self.owner.snd_hit)
+ {
+ sound (self, CHAN_WEAPON, self.owner.snd_hit, 1, ATTN_STATIC); //dumptruck_ds
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_GUNSHOT);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ }
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+
+};
+void() superduperspike_touch = //dumptruck_ds for Style 2 Ogre see ogre.qc
+{
+ if (other == self.owner)
+ return;
+
+ if (other.solid == SOLID_TRIGGER)
+ return; // trigger field, do nothing
+
+ if (pointcontents(self.origin) == CONTENT_SKY)
+ {
+ remove(self);
+ return;
+ }
+
+// hit something that bleeds
+ if (other.takedamage)
+ {
+ spawn_touchblood (36);
+ T_Damage (other, self, self.owner, 36);
+ sound(self, CHAN_VOICE, "fish/bite.wav", 1, ATTN_NORM);
+ }
+ else
+ {
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
+ WriteCoord (MSG_BROADCAST, self.origin_x);
+ WriteCoord (MSG_BROADCAST, self.origin_y);
+ WriteCoord (MSG_BROADCAST, self.origin_z);
+ }
+
+ remove(self);
+};
+
+/*
+===============================================================================
+
+PLAYER WEAPON USE
+
+===============================================================================
+*/
+
+void() W_SetCurrentAmmo =
+{
+ player_run (); // get out of any weapon firing states
+
+ self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
+
+ if (self.weapon == IT_AXE)
+ {
+ self.currentammo = 0;
+ self.weaponmodel = "progs/v_axe.mdl";
+ self.weaponframe = 0;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.currentammo = self.ammo_shells;
+ self.weaponmodel = "progs/v_shot.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_SHELLS;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.currentammo = self.ammo_shells;
+ self.weaponmodel = "progs/v_shot2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_SHELLS;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.currentammo = self.ammo_nails;
+ self.weaponmodel = "progs/v_nail.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_NAILS;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.currentammo = self.ammo_nails;
+ self.weaponmodel = "progs/v_nail2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_NAILS;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.currentammo = self.ammo_rockets;
+ self.weaponmodel = "progs/v_rock.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_ROCKETS;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.currentammo = self.ammo_rockets;
+ self.weaponmodel = "progs/v_rock2.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_ROCKETS;
+ }
+ else if (self.weapon == IT_LIGHTNING)
+ {
+ self.currentammo = self.ammo_cells;
+ self.weaponmodel = "progs/v_light.mdl";
+ self.weaponframe = 0;
+ self.items = self.items | IT_CELLS;
+ }
+ else
+ {
+ self.currentammo = 0;
+ self.weaponmodel = "";
+ self.weaponframe = 0;
+ }
+};
+
+float() W_BestWeapon =
+{
+ local float it;
+
+ it = self.items;
+
+ if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
+ return IT_LIGHTNING;
+ if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
+ return IT_SUPER_NAILGUN;
+ if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
+ return IT_SUPER_SHOTGUN;
+ if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
+ return IT_NAILGUN;
+ if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
+ return IT_SHOTGUN;
+ return IT_AXE;
+};
+
+float() W_CheckNoAmmo =
+{
+ if (self.currentammo > 0)
+ return TRUE;
+
+ if (self.weapon == IT_AXE)
+ return TRUE;
+
+ self.weapon = W_BestWeapon ();
+
+ W_SetCurrentAmmo ();
+
+// drop the weapon down
+ return FALSE;
+};
+
+/*
+============
+W_Attack
+
+An attack impulse can be triggered now
+============
+*/
+void() player_axe1;
+void() player_axeb1;
+void() player_axec1;
+void() player_axed1;
+void() player_shot1;
+void() player_nail1;
+void() player_light1;
+void() player_rocket1;
+
+void() W_Attack =
+{
+ local float r;
+
+ if (!W_CheckNoAmmo ())
+ return;
+
+ makevectors (self.v_angle); // calculate forward angle for velocity
+ self.show_hostile = time + 1; // wake monsters up
+
+ if (self.weapon == IT_AXE)
+ {
+ sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
+ r = random();
+ if (r < 0.25)
+ player_axe1 ();
+ else if (r<0.5)
+ player_axeb1 ();
+ else if (r<0.75)
+ player_axec1 ();
+ else
+ player_axed1 ();
+ self.attack_finished = time + 0.5;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ player_shot1 ();
+ W_FireShotgun ();
+ self.attack_finished = time + 0.5;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ player_shot1 ();
+ W_FireSuperShotgun ();
+ self.attack_finished = time + 0.7;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ player_nail1 ();
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ player_nail1 ();
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ player_rocket1();
+ W_FireGrenade();
+ self.attack_finished = time + 0.6;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ player_rocket1();
+ W_FireRocket();
+ self.attack_finished = time + 0.8;
+ }
+ else if (self.weapon == IT_LIGHTNING)
+ {
+ player_light1();
+ self.attack_finished = time + 0.1;
+ sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
+ }
+};
+
+/*
+============
+W_ChangeWeapon
+
+============
+*/
+void() W_ChangeWeapon =
+{
+ local float it, am, fl;
+
+ it = self.items;
+ am = 0;
+
+ if (self.impulse == 1)
+ {
+ fl = IT_AXE;
+ }
+ else if (self.impulse == 2)
+ {
+ fl = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.impulse == 3)
+ {
+ fl = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.impulse == 4)
+ {
+ fl = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.impulse == 5)
+ {
+ fl = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.impulse == 6)
+ {
+ fl = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.impulse == 7)
+ {
+ fl = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.impulse == 8)
+ {
+ fl = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+ else
+ {
+ dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
+ dprint (ftos (self.impulse));
+ dprint ("\n");
+ return;
+ }
+
+ self.impulse = 0;
+
+ if (!(self.items & fl))
+ { // don't have the weapon or the ammo
+ sprint (self, "no weapon.\n");
+ return;
+ }
+
+ if (am)
+ { // don't have the ammo
+ sprint (self, "not enough ammo.\n");
+ return;
+ }
+
+//
+// set weapon, set ammo
+//
+ self.weapon = fl;
+ W_SetCurrentAmmo ();
+};
+
+/*
+============
+CheatCommand
+============
+*/
+void() CheatCommand =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+// if (deathmatch || coop)
+ if (deathmatch)
+// 1998-07-29 Cheats coop fix by Maddes end
+ return;
+
+ self.ammo_rockets = 100;
+ self.ammo_nails = 200;
+ self.ammo_shells = 100;
+ self.items = self.items |
+ IT_AXE |
+ IT_SHOTGUN |
+ IT_SUPER_SHOTGUN |
+ IT_NAILGUN |
+ IT_SUPER_NAILGUN |
+ IT_GRENADE_LAUNCHER |
+ IT_ROCKET_LAUNCHER;
+ GiveAllKeys (self); // support for item_key_custom -- iw
+
+ self.ammo_cells = 200;
+ self.items = self.items | IT_LIGHTNING;
+
+ self.weapon = IT_ROCKET_LAUNCHER;
+ self.impulse = 0;
+ W_SetCurrentAmmo ();
+};
+
+/*
+============
+CycleWeaponCommand
+
+Go to the next weapon with ammo
+============
+*/
+void() CycleWeaponCommand =
+{
+ local float it, am;
+
+ it = self.items;
+ self.impulse = 0;
+
+ while (1)
+ {
+ am = 0;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+
+ if ( (it & self.weapon) && am == 0)
+ {
+ W_SetCurrentAmmo ();
+ return;
+ }
+ }
+
+};
+
+/*
+============
+CycleWeaponReverseCommand
+
+Go to the prev weapon with ammo
+============
+*/
+void() CycleWeaponReverseCommand =
+{
+ local float it, am;
+
+ it = self.items;
+ self.impulse = 0;
+
+ while (1)
+ {
+ am = 0;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ am = 1;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ am = 1;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ am = 1;
+ }
+
+ if ( (it & self.weapon) && am == 0)
+ {
+ W_SetCurrentAmmo ();
+ return;
+ }
+ }
+
+};
+
+/*
+============
+ServerflagsCommand
+
+Just for development
+============
+*/
+void() ServerflagsCommand =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+ if (deathmatch)
+ return;
+// 1998-07-29 Cheats coop fix by Maddes end
+ serverflags = serverflags * 2 + 1;
+};
+
+void() QuadCheat =
+{
+// 1998-07-29 Cheats coop fix by Maddes start
+// if (deathmatch || coop)
+ if (deathmatch)
+// 1998-07-29 Cheats coop fix by Maddes end
+ return;
+ self.super_time = 1;
+ self.super_damage_finished = time + 30;
+ self.items = self.items | IT_QUAD;
+ dprint ("quad cheat\n");
+};
+
+/*
+============
+ImpulseCommands
+
+============
+*/
+void() ImpulseCommands =
+{
+ if (self.impulse >= 1 && self.impulse <= 8)
+ W_ChangeWeapon ();
+
+ if (self.impulse == 9)
+ CheatCommand ();
+ if (self.impulse == 10)
+ CycleWeaponCommand ();
+ if (self.impulse == 11)
+ ServerflagsCommand ();
+ if (self.impulse == 12)
+ CycleWeaponReverseCommand ();
+
+ if (self.impulse == 255)
+ QuadCheat ();
+// dumptruck_ds version inspired by Copper
+ if (self.impulse == 100)
+ sprint(self, version);
+
+ // if (self.impulse == 101) // debugging armor shards -- dumptruck_ds
+ // dprint ("Armortype is");
+ // dprint (ftos(self.armortype));
+ // dprint ("\n");
+
+ self.impulse = 0;
+};
+
+/*
+============
+W_WeaponFrame
+
+Called every frame so impulse events can be handled as well as possible
+============
+*/
+void() W_WeaponFrame =
+{
+ if (time < self.attack_finished)
+ return;
+
+if (self.impulse) // 1998-08-14 Constantly checking all impulses fix by Perged
+ ImpulseCommands ();
+
+// check for attack
+ if (self.button0)
+ {
+ SuperDamageSound ();
+ W_Attack ();
+ }
+};
+
+/*
+========
+SuperDamageSound
+
+Plays sound if needed
+========
+*/
+void() SuperDamageSound =
+{
+ if (self.super_damage_finished > time)
+ {
+ if (self.super_sound < time)
+ {
+ self.super_sound = time + 1;
+ sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
+ }
+ }
+ return;
+};
+
+void() MissileHome =
+{
+ local vector dir, vtemp;
+ vtemp = self.enemy.origin + '0 0 10';
+
+ if (self.enemy.health < 1)
+ {
+ remove(self);
+ return;
+ }
+ dir = normalize(vtemp - self.origin);
+ if (self.homing < 1 && self.homing > 0) // can't do better than 100% homing
+ {
+ /*
+ This finds a vector somewhere between the vector the projectile is currently
+ travelling on and the vector that it would normally snap to for homing
+
+ homing = .25 means it will go 25% to the new direction, but keep 75% of the
+ original vector, resulting in a wider turning range.
+ */
+ dir = normalize((dir * self.homing) + normalize(self.velocity * (1 - self.homing)));
+ }
+ if (!self.avelocity)
+ self.angles = vectoangles(dir);
+ SetSpeed(self, dir, self.proj_basespeed);
+
+ if (self.homing > 0)
+ {
+ if (self.homing < 1 && self.attack_finished && self.attack_finished < time )
+ {
+ //dprint("incrementing homing | ");
+ //dprint("old: ");
+ //dprint(ftos(self.homing));
+ //dprint(" | new: ");
+ self.homing = self.homing + 0.005;
+ //dprint(ftos(self.homing));
+ //dprint("\n");
+ }
+ self.nextthink = time + 0.2;
+ self.think = MissileHome;
+ }
+};
+
+void(entity mis, float speed) SetupHoming =
+{
+ local vector dir;
+ local float dist, flytime, speedmod;
+ if (self.proj_speed_mod > 1)
+ {
+ speedmod = 1/self.proj_speed_mod;
+ }
+ else if (speed > 250)
+ {
+ speedmod = 1 / (speed / 250);
+ }
+ else
+ {
+ speedmod = 1;
+ }
+ dir = normalize((self.enemy.origin + '0 0 10') - self.origin);
+ dist = vlen (self.enemy.origin - self.origin);
+ flytime = dist * 0.002 * speedmod;
+ if (flytime < 0.1)
+ flytime = 0.1;
+
+ mis.enemy = self.enemy;
+ mis.proj_basespeed = speed;
+ mis.homing = self.homing;
+ mis.nextthink = flytime + time;
+ mis.think = MissileHome;
+ if (self.waitmin > 0)
+ {
+ mis.attack_finished = time + self.waitmin; // store time to start increasing
+ }
+};

Return to the top of this page or return to the overview of this repo.

Diff qc/world.qc

diff --git a/qc/world.qc b/qc/world.qc
index 84555aa..fdb3f3f 100644
--- a/qc/world.qc
+++ b/qc/world.qc
@@ -1,621 +1,621 @@
-
-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");
-};
-
-
-/*
-================
-DetectKnownRelease
-
-This detects whether the current map is from a known release for which
-a backwards-compatibility hack should be applied, and sets the
-known_release global accordingly. -- iw
-================
-*/
-void() DetectKnownRelease =
-{
- local string release_name;
-
- known_release = KNOWN_RELEASE_NOT;
- release_name = "";
-
- if (mapname == "dm1" ||
- mapname == "dm2" ||
- mapname == "dm3" ||
- mapname == "dm4" ||
- mapname == "dm5" ||
- mapname == "dm6" ||
- mapname == "e1m1" ||
- mapname == "e1m2" ||
- mapname == "e1m3" ||
- mapname == "e1m4" ||
- mapname == "e1m5" ||
- mapname == "e1m6" ||
- mapname == "e1m7" ||
- mapname == "e1m8" ||
- mapname == "e2m1" ||
- mapname == "e2m2" ||
- mapname == "e2m3" ||
- mapname == "e2m4" ||
- mapname == "e2m5" ||
- mapname == "e2m6" ||
- mapname == "e2m7" ||
- mapname == "e3m1" ||
- mapname == "e3m2" ||
- mapname == "e3m3" ||
- mapname == "e3m4" ||
- mapname == "e3m5" ||
- mapname == "e3m6" ||
- mapname == "e3m7" ||
- mapname == "e4m1" ||
- mapname == "e4m2" ||
- mapname == "e4m3" ||
- mapname == "e4m4" ||
- mapname == "e4m5" ||
- mapname == "e4m6" ||
- mapname == "e4m7" ||
- mapname == "e4m8" ||
- mapname == "end" ||
- (mapname == "start" && world.message == "Introduction"))
- {
- known_release = KNOWN_RELEASE_ID1;
- release_name = "id1";
- }
-
- if (mapname == "jamx_artistical" ||
- mapname == "jamx_bloodshot" ||
- mapname == "jamx_fw" ||
- mapname == "jamx_hcm" ||
- mapname == "jamx_ionous" ||
- mapname == "jamx_jcr" ||
- mapname == "jamx_kalebclark" ||
- mapname == "jamx_mafon" ||
- //mapname == "jamx_mugwump" || // dummy map
- mapname == "jamx_naitelveni" ||
- mapname == "jamx_newhouse" ||
- mapname == "jamx_pinchy" ||
- mapname == "jamx_strwrk" ||
- mapname == "jamx_ukko" ||
- mapname == "jamx_yoder" ||
- (mapname == "start" && world.message == "An Unending Dusk"))
- {
- known_release = KNOWN_RELEASE_FUNC_MAPJAMX;
- release_name = "func_mapjamx";
- }
-
- if (release_name != "")
- {
- dprint ("WARNING: progs.dat detected a map from ");
- dprint (release_name);
- dprint (", attempting to behave compatibly\n");
- }
-};
-
-
-entity lastspawn;
-
-//=======================
-/*QUAKED worldspawn (0 0 0) ?
-Only used for the world entity.
-
-Optionally set reset_items to one of the following values:
-0: don't reset the player's inventory
-1: reset to shotgun, axe, and 25 shells
-2: reset to axe only
-
-message(string) : "Level name"
-
-worldtype(choices) : "Ambience" : 0 =
-0 : "Medieval"
-1 : "Runic (metal)"
-2 : "Present (base)"
-
-sounds(integer) : "CD track to play" : 0
-
-light(integer) : "Ambient light" : 0 : "Set a global minimum light level of 'n' across the whole map. This is an easy way to eliminate completely dark areas of the level, however you may lose some contrast as a result, so use with care. Default 0"
-
-reset_items(choices) : "Reset the player's inventory on spawn" : 0 =
-0 "Don't reset the player's inventory"
-1 "Reset to shotgun, axe, and 25 shells"
-2 "Reset to axe only"
-
-_sunlight(integer) : "Sunlight" : 0 : "Set the brightness of the sunlight coming from an unseen sun in the sky. Sky brushes (or more accurately bsp leafs with sky contents) will emit sunlight at an angle specified by the _sun_mangle key. Default 0"
-
-_sun_mangle(string) : "Sun mangle (Yaw pitch roll)" : "0 -90 0" : "Specifies the direction of sunlight using yaw(x), pitch(y) and roll(z) in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Default is straight down (0 -90 0)"
-
-_sunlight_penumbra(integer) : "Sunlight penumbra in degrees" : 0 : "Specifies the penumbra width, in degrees, of sunlight. Useful values are 3-4 for a gentle soft edge, or 10-20+ for more diffuse sunlight. Default is 0"
-
-_sunlight_color(color255) : "Sunlight color R G B" : "255 255 255" : "Specify red(r), green(g) and blue(b) components for the colour of the sunlight. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light (255 255 255)"
-
-_sunlight2(integer) : "Sunlight 2 brightness" : 0 : "Set the brightness of a large dome of lights positioned around the map (16K unit radius). Useful for simulating higly diffused light (e.g. cloudy skies) in outdoor areas. Default 0"
-
-_sunlight2_color(color255) : "Sunlight 2 color R G B" : "255 255 255" : "Specifies the colour of _sunlight2, same format as _sunlight_color. Default is white light (255 255 255)"
-
-_sunlight3(integer) : "Sunlight 3 brightness" : 0 : "Same as _sunlight2 but creates lights on the bottom hemisphere. Default 0"
-
-_sunlight3_color(color255) : "Sunlight 3 color R G B" : "255 255 255" : "Specifies the colour of _sunlight3, same format as _sunlight_color. Default is white light (255 255 255)"
-
-_dist(integer) : "Global light scale" : 1 : "Scales the fade distance of all lights by a factor of n. If n is more than 1 lights fade more quickly with distance and if n is less than 1, lights fade more slowly with distance and light reaches further"
-
-_range(float) : "Global light range" : "0.5" : "Scales the brightness range of all lights without affecting their fade discance. Values of n more than 0.5 makes lights brighter and n less than 0.5 makes lights less bright. The same effect can be achieved on individual lights by adjusting both the 'light' and 'wait' attributes"
-
-_anglescale(float) : "Light angle scale" : "0.5" : "Sets a scaling factor for how much influence the angle of incidence of sunlight on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5"
-
-_dirt(integer) : "Dirt mapping (AO)" : -1 : "1 enables dirtmapping (ambient occlusion) on all lights, borrowed from q3map2. This adds shadows to corners and crevices. You can override the global setting for specific lights with the _dirt light entity key or _sunlight_dirt, _sunlight2_dirt, and _minlight_dirt worldspawn keys. Default is no dirtmapping (-1)"
-
-_sunlight_dirt(integer) : "Sunlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight, -1 to disable (making it illuminate the dirtmapping shadows). Default is to use the value of '_dirt'"
-
-_sunlight2_dirt(integer) : "Sublight 2 dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight2, -1 to disable. Default is to use the value of '_dirt'"
-
-_minlight_dirt(integer) : "Minlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on minlight, -1 to disable. Default is to use the value of '_dirt'"
-
-_dirtmode(integer) : "Dirt mode" : 0 : "Choose between ordered (0, default) and randomized (1) dirtmapping."
-
-_dirtdepth(integer) : "Dirt depth" : 128 : "Maximum depth of occlusion checking for dirtmapping, default 128."
-
-_dirtscale(integer) : "Dirt scale" : 1 : "Scale factor used in dirt calculations, default 1. Lower values (e.g. 0.5) make the dirt fainter, 2.0 would create much darker shadows"
-
-_dirtgain(integer) : "Dirt gain" : 1 : "Exponent used in dirt calculation, default 1. Lower values (e.g. 0.5) make the shadows darker and stretch further away from corners"
-
-_gamma(integer) : "Lightmap gamma" : 1 : "Adjust brightness of final lightmap. Default 1, >1 is brighter, <1 is darker"
-
-fog(string) : "Fog Command" : : "ENGINE only 'console command' for setting fog parameters, Density/R/G/B example = (0.05 0.3 0.3 0.3)."
-
-fog_density(string) : "Fog Density example = (0.05)"
-
-fog_color(string) : "Fog Color R/G/B example = (0.3 0.3 0.3)"
-
-sky(string) : "Sky Texture" : : "Must have compatible skybox textures in gfx/env folder."
-*/
-//=======================
-void() worldspawn =
-{
- DetectKnownRelease ();
-
- InitNewSpawnflags (); // new spawnflags for all entities -- iw
-
- lastspawn = world;
-
- if (cvar("pr_checkextension"))
- {
- clientstat (CLIENT_VELOCITY_X, EV_FLOAT, velocity_x);
- clientstat (CLIENT_VELOCITY_Y, EV_FLOAT, velocity_y);
- }
-
- InitBodyQue ();
-
-// custom map attributes
- if (self.model == "maps/e1m8.bsp" && self.skip_id1_overrides == 0)
- cvar_set ("sv_gravity", "100");
- else
- cvar_set ("sv_gravity", "800");
-
- cutscene = 0; // No cutscene is active during worldspawn. Drake -- dumptruck_ds
-
- world_sounds = &world.sounds; //Spike via dumptruck_ds || not read-only yet...
-
-// the area based ambient sounds MUST be the first precache_sounds
-
-// player precaches
- W_Precache (); // get weapon precaches
-
-// sounds used from C physics code
- precache_sound_land ("demon/dland2.wav"); // landing thud
- precache_sound ("misc/h2ohit1.wav"); // landing splash
-
-// setup precaches always needed
- precache_sound ("items/itembk2.wav"); // item respawn sound
- precache_sound ("player/plyrjmp8.wav"); // player jump
- precache_sound ("player/land.wav"); // player landing
- precache_sound ("player/land2.wav"); // player hurt landing
- precache_sound ("player/drown1.wav"); // drowning pain
- precache_sound ("player/drown2.wav"); // drowning pain
- precache_sound ("player/gasp1.wav"); // gasping for air
- precache_sound ("player/gasp2.wav"); // taking breath
- precache_sound ("player/h2odeath.wav"); // drowning death
-
- precache_sound ("misc/talk.wav"); // talk
- precache_sound ("player/teledth1.wav"); // telefrag
- precache_sound ("misc/r_tele1.wav"); // teleport sounds
- precache_sound ("misc/r_tele2.wav");
- precache_sound ("misc/r_tele3.wav");
- precache_sound ("misc/r_tele4.wav");
- precache_sound ("misc/r_tele5.wav");
- precache_sound ("weapons/lock4.wav"); // ammo pick up
- precache_sound ("weapons/pkup.wav"); // weapon up
- precache_sound ("items/armor1.wav"); // armor up
- precache_sound ("weapons/lhit.wav"); //lightning
- precache_sound ("weapons/lstart.wav"); //lightning start
-
- // iw -- fix powerup cheat sounds // noticed this in Copper so why not? --ds
- // sounds used by cheats
- precache_sound ("items/suit2.wav"); // suit (finish)
- precache_sound ("items/protect2.wav"); // pent (finish)
- precache_sound ("items/protect3.wav"); // pent (protect)
- precache_sound ("items/inv2.wav"); // ring (finish)
- precache_sound ("items/inv3.wav"); // ring (idle)
- precache_sound ("items/damage2.wav"); // quad (finish)
- precache_sound ("items/damage3.wav"); // quad (attack)
- // iw -- END
-
- precache_sound ("misc/power.wav"); //lightning for boss
-
-// player gib sounds
- precache_sound ("player/gib.wav"); // player gib sound
- precache_sound ("player/udeath.wav"); // player gib sound
- precache_sound ("player/tornoff2.wav"); // gib sound
-
-// player pain sounds
-
- precache_sound ("player/pain1.wav");
- precache_sound ("player/pain2.wav");
- precache_sound ("player/pain3.wav");
- precache_sound ("player/pain4.wav");
- precache_sound ("player/pain5.wav");
- precache_sound ("player/pain6.wav");
-
-// player death sounds
- precache_sound ("player/death1.wav");
- precache_sound ("player/death2.wav");
- precache_sound ("player/death3.wav");
- precache_sound ("player/death4.wav");
- precache_sound ("player/death5.wav");
-
-// ax sounds
- precache_sound ("weapons/ax1.wav"); // ax swoosh
- precache_sound ("player/axhit1.wav"); // ax hit meat
- precache_sound ("player/axhit2.wav"); // ax hit world
-
- precache_sound ("player/h2ojump.wav"); // player jumping into water
- precache_sound ("player/slimbrn2.wav"); // player enter slime
- precache_sound ("player/inh2o.wav"); // player enter water
- precache_sound ("player/inlava.wav"); // player enter lava
- precache_sound ("misc/outwater.wav"); // leaving water sound
-
- precache_sound ("player/lburn1.wav"); // lava burn
- precache_sound ("player/lburn2.wav"); // lava burn
-
- precache_sound ("misc/water1.wav"); // swimming
- precache_sound ("misc/water2.wav"); // swimming
-
- precache_model ("progs/player.mdl");
- precache_model ("progs/s_null.spr"); // Invisible -- Drake -- dumptruck_ds
- // precache_model ("progs/null_256.spr"); // Invisible -- Drake -- dumptruck_ds
- precache_model ("progs/eyes.mdl");
- precache_model ("progs/h_player.mdl");
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_model ("progs/s_bubble.spr"); // drowning bubbles
- precache_model ("progs/s_explod.spr"); // sprite explosion
-
- precache_model ("progs/v_axe.mdl");
- precache_model ("progs/v_shot.mdl");
- precache_model ("progs/v_nail.mdl");
- precache_model ("progs/v_rock.mdl");
- precache_model ("progs/v_shot2.mdl");
- precache_model ("progs/v_nail2.mdl");
- precache_model ("progs/v_rock2.mdl");
-
- precache_model ("progs/bolt.mdl"); // for lightning gun
- precache_model ("progs/bolt2.mdl"); // for lightning gun
- precache_model ("progs/bolt3.mdl"); // for boss shock
- precache_model ("progs/lavaball.mdl"); // for testing
-
- precache_model ("progs/missile.mdl");
- precache_model ("progs/grenade.mdl");
- precache_model ("progs/spike.mdl");
- // dumptruck_ds added w_spike due to errors
- // with custom_mdls in precache_proj_model in wizard.qc
- // precache_model ("progs/w_spike.mdl");
- // this is on hold for now head and body are working
- precache_model ("progs/s_spike.mdl");
-
- precache_model ("progs/backpack.mdl");
-
- precache_model ("progs/zom_gib.mdl");
-
- precache_model ("progs/v_light.mdl");
-
- precache_model ("progs/w_s_key.mdl"); // dumptruck_ds needed for DropStuff
- precache_model ("progs/w_g_key.mdl"); //
- precache_sound ("misc/medkey.wav");
- precache_sound ("misc/runekey.wav");
- precache_model ("progs/m_s_key.mdl");
- precache_model ("progs/m_g_key.mdl");
- precache_sound2 ("misc/basekey.wav");
- precache_model2 ("progs/b_s_key.mdl");
- precache_model2 ("progs/b_g_key.mdl");
- precache_model ("progs/h_mdls/pd_vial.mdl"); // DropVial -- dumptruck_ds
- precache_sound ("items/r_item1.wav");
- precache_sound ("dump/armsh1.wav"); // DropShard -- dumptruck_ds
- precache_model ("progs/armshr.mdl");
-
-//
-// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
-//
-
- // 0 normal
- lightstyle(0, "m");
-
- // 1 FLICKER (first variety)
- lightstyle(1, "mmnmmommommnonmmonqnmmo");
-
- // 2 SLOW STRONG PULSE
- lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
-
- // 3 CANDLE (first variety)
- lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
-
- // 4 FAST STROBE
- lightstyle(4, "mamamamamama");
-
- // 5 GENTLE PULSE 1
- lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
-
- // 6 FLICKER (second variety)
- lightstyle(6, "nmonqnmomnmomomno");
-
- // 7 CANDLE (second variety)
- lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
-
- // 8 CANDLE (third variety)
- lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
-
- // 9 SLOW STROBE (fourth variety)
- lightstyle(9, "aaaaaaaazzzzzzzz");
-
- // 10 FLUORESCENT FLICKER
- lightstyle(10, "mmamammmmammamamaaamammma");
-
- // 11 SLOW PULSE NOT FADE TO BLACK
- lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
-
- // styles 32-62 are assigned by the light program for switchable lights
-
- // 63 testing
- lightstyle(63, "a");
-};
-
-void() RestartLoopSounds_think = {
- sound(self, self.impulse, self.noise, self.volume, self.speed);
-};
-
-void() RestartLoopSounds = {
- entity e;
- e = find(world, classname, "play_sound_triggered");
- while (e) {
-
- if (e.spawnflags & 3 == 3) { // both "toggle" and "looped" need to be set
- if (e.state == 1) {
- e.nextthink = time + 0.1;
- e.think = RestartLoopSounds_think;
- }
- }
-
- e = find(e, classname, "play_sound_triggered");
- }
-};
-
-
-void() StartFrame =
-{
- if (!done_inhibition_summary) // new spawnflags for all entities -- iw
- PrintInhibitionSummary ();
-
- teamplay = cvar("teamplay");
- skill = cvar("skill");
- framecount = framecount + 1;
-
- if (cleanUpClientStuff) {
- cleanUpClientStuff -= 1;
-
- RestartLoopSounds();
- }
- else if (!gamestarted && framecount > 2)
- {
- if (framecount != 3)
- cleanUpClientStuff += 2;
-
- gamestarted = TRUE;
- }
-};
-
-/*
-==============================================================================
-
-BODY QUE
-
-==============================================================================
-*/
-
-entity bodyque_head;
-
-void() bodyque =
-{ // just here so spawn functions don't complain after the world
- // creates bodyques
-};
-
-void() InitBodyQue =
-{
- bodyque_head = spawn();
- bodyque_head.classname = "bodyque";
- bodyque_head.owner = spawn();
- bodyque_head.owner.classname = "bodyque";
- bodyque_head.owner.owner = spawn();
- bodyque_head.owner.owner.classname = "bodyque";
- bodyque_head.owner.owner.owner = spawn();
- bodyque_head.owner.owner.owner.classname = "bodyque";
- bodyque_head.owner.owner.owner.owner = bodyque_head;
-};
-
-
-// make a body que entry for the given ent so the ent can be
-// respawned elsewhere
-void(entity ent) CopyToBodyQue =
-{
- 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;
-};
+
+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");
+};
+
+
+/*
+================
+DetectKnownRelease
+
+This detects whether the current map is from a known release for which
+a backwards-compatibility hack should be applied, and sets the
+known_release global accordingly. -- iw
+================
+*/
+void() DetectKnownRelease =
+{
+ local string release_name;
+
+ known_release = KNOWN_RELEASE_NOT;
+ release_name = "";
+
+ if (mapname == "dm1" ||
+ mapname == "dm2" ||
+ mapname == "dm3" ||
+ mapname == "dm4" ||
+ mapname == "dm5" ||
+ mapname == "dm6" ||
+ mapname == "e1m1" ||
+ mapname == "e1m2" ||
+ mapname == "e1m3" ||
+ mapname == "e1m4" ||
+ mapname == "e1m5" ||
+ mapname == "e1m6" ||
+ mapname == "e1m7" ||
+ mapname == "e1m8" ||
+ mapname == "e2m1" ||
+ mapname == "e2m2" ||
+ mapname == "e2m3" ||
+ mapname == "e2m4" ||
+ mapname == "e2m5" ||
+ mapname == "e2m6" ||
+ mapname == "e2m7" ||
+ mapname == "e3m1" ||
+ mapname == "e3m2" ||
+ mapname == "e3m3" ||
+ mapname == "e3m4" ||
+ mapname == "e3m5" ||
+ mapname == "e3m6" ||
+ mapname == "e3m7" ||
+ mapname == "e4m1" ||
+ mapname == "e4m2" ||
+ mapname == "e4m3" ||
+ mapname == "e4m4" ||
+ mapname == "e4m5" ||
+ mapname == "e4m6" ||
+ mapname == "e4m7" ||
+ mapname == "e4m8" ||
+ mapname == "end" ||
+ (mapname == "start" && world.message == "Introduction"))
+ {
+ known_release = KNOWN_RELEASE_ID1;
+ release_name = "id1";
+ }
+
+ if (mapname == "jamx_artistical" ||
+ mapname == "jamx_bloodshot" ||
+ mapname == "jamx_fw" ||
+ mapname == "jamx_hcm" ||
+ mapname == "jamx_ionous" ||
+ mapname == "jamx_jcr" ||
+ mapname == "jamx_kalebclark" ||
+ mapname == "jamx_mafon" ||
+ //mapname == "jamx_mugwump" || // dummy map
+ mapname == "jamx_naitelveni" ||
+ mapname == "jamx_newhouse" ||
+ mapname == "jamx_pinchy" ||
+ mapname == "jamx_strwrk" ||
+ mapname == "jamx_ukko" ||
+ mapname == "jamx_yoder" ||
+ (mapname == "start" && world.message == "An Unending Dusk"))
+ {
+ known_release = KNOWN_RELEASE_FUNC_MAPJAMX;
+ release_name = "func_mapjamx";
+ }
+
+ if (release_name != "")
+ {
+ dprint ("WARNING: progs.dat detected a map from ");
+ dprint (release_name);
+ dprint (", attempting to behave compatibly\n");
+ }
+};
+
+
+entity lastspawn;
+
+//=======================
+/*QUAKED worldspawn (0 0 0) ?
+Only used for the world entity.
+
+Optionally set reset_items to one of the following values:
+0: don't reset the player's inventory
+1: reset to shotgun, axe, and 25 shells
+2: reset to axe only
+
+message(string) : "Level name"
+
+worldtype(choices) : "Ambience" : 0 =
+0 : "Medieval"
+1 : "Runic (metal)"
+2 : "Present (base)"
+
+sounds(integer) : "CD track to play" : 0
+
+light(integer) : "Ambient light" : 0 : "Set a global minimum light level of 'n' across the whole map. This is an easy way to eliminate completely dark areas of the level, however you may lose some contrast as a result, so use with care. Default 0"
+
+reset_items(choices) : "Reset the player's inventory on spawn" : 0 =
+0 "Don't reset the player's inventory"
+1 "Reset to shotgun, axe, and 25 shells"
+2 "Reset to axe only"
+
+_sunlight(integer) : "Sunlight" : 0 : "Set the brightness of the sunlight coming from an unseen sun in the sky. Sky brushes (or more accurately bsp leafs with sky contents) will emit sunlight at an angle specified by the _sun_mangle key. Default 0"
+
+_sun_mangle(string) : "Sun mangle (Yaw pitch roll)" : "0 -90 0" : "Specifies the direction of sunlight using yaw(x), pitch(y) and roll(z) in degrees. Yaw specifies the angle around the Z-axis from 0 to 359 degrees and pitch specifies the angle from 90 (straight up) to -90 (straight down). Roll has no effect, so use any value (e.g. 0). Default is straight down (0 -90 0)"
+
+_sunlight_penumbra(integer) : "Sunlight penumbra in degrees" : 0 : "Specifies the penumbra width, in degrees, of sunlight. Useful values are 3-4 for a gentle soft edge, or 10-20+ for more diffuse sunlight. Default is 0"
+
+_sunlight_color(color255) : "Sunlight color R G B" : "255 255 255" : "Specify red(r), green(g) and blue(b) components for the colour of the sunlight. RGB component values are between 0 and 255 (between 0 and 1 is also accepted). Default is white light (255 255 255)"
+
+_sunlight2(integer) : "Sunlight 2 brightness" : 0 : "Set the brightness of a large dome of lights positioned around the map (16K unit radius). Useful for simulating higly diffused light (e.g. cloudy skies) in outdoor areas. Default 0"
+
+_sunlight2_color(color255) : "Sunlight 2 color R G B" : "255 255 255" : "Specifies the colour of _sunlight2, same format as _sunlight_color. Default is white light (255 255 255)"
+
+_sunlight3(integer) : "Sunlight 3 brightness" : 0 : "Same as _sunlight2 but creates lights on the bottom hemisphere. Default 0"
+
+_sunlight3_color(color255) : "Sunlight 3 color R G B" : "255 255 255" : "Specifies the colour of _sunlight3, same format as _sunlight_color. Default is white light (255 255 255)"
+
+_dist(integer) : "Global light scale" : 1 : "Scales the fade distance of all lights by a factor of n. If n is more than 1 lights fade more quickly with distance and if n is less than 1, lights fade more slowly with distance and light reaches further"
+
+_range(float) : "Global light range" : "0.5" : "Scales the brightness range of all lights without affecting their fade discance. Values of n more than 0.5 makes lights brighter and n less than 0.5 makes lights less bright. The same effect can be achieved on individual lights by adjusting both the 'light' and 'wait' attributes"
+
+_anglescale(float) : "Light angle scale" : "0.5" : "Sets a scaling factor for how much influence the angle of incidence of sunlight on a surface has on the brightness of the surface. n must be between 0.0 and 1.0. Smaller values mean less attenuation, with zero meaning that angle of incidence has no effect at all on the brightness. Default 0.5"
+
+_dirt(integer) : "Dirt mapping (AO)" : -1 : "1 enables dirtmapping (ambient occlusion) on all lights, borrowed from q3map2. This adds shadows to corners and crevices. You can override the global setting for specific lights with the _dirt light entity key or _sunlight_dirt, _sunlight2_dirt, and _minlight_dirt worldspawn keys. Default is no dirtmapping (-1)"
+
+_sunlight_dirt(integer) : "Sunlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight, -1 to disable (making it illuminate the dirtmapping shadows). Default is to use the value of '_dirt'"
+
+_sunlight2_dirt(integer) : "Sublight 2 dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on sunlight2, -1 to disable. Default is to use the value of '_dirt'"
+
+_minlight_dirt(integer) : "Minlight dirt" : -1 : "1 enables dirtmapping (ambient occlusion) on minlight, -1 to disable. Default is to use the value of '_dirt'"
+
+_dirtmode(integer) : "Dirt mode" : 0 : "Choose between ordered (0, default) and randomized (1) dirtmapping."
+
+_dirtdepth(integer) : "Dirt depth" : 128 : "Maximum depth of occlusion checking for dirtmapping, default 128."
+
+_dirtscale(integer) : "Dirt scale" : 1 : "Scale factor used in dirt calculations, default 1. Lower values (e.g. 0.5) make the dirt fainter, 2.0 would create much darker shadows"
+
+_dirtgain(integer) : "Dirt gain" : 1 : "Exponent used in dirt calculation, default 1. Lower values (e.g. 0.5) make the shadows darker and stretch further away from corners"
+
+_gamma(integer) : "Lightmap gamma" : 1 : "Adjust brightness of final lightmap. Default 1, >1 is brighter, <1 is darker"
+
+fog(string) : "Fog Command" : : "ENGINE only 'console command' for setting fog parameters, Density/R/G/B example = (0.05 0.3 0.3 0.3)."
+
+fog_density(string) : "Fog Density example = (0.05)"
+
+fog_color(string) : "Fog Color R/G/B example = (0.3 0.3 0.3)"
+
+sky(string) : "Sky Texture" : : "Must have compatible skybox textures in gfx/env folder."
+*/
+//=======================
+void() worldspawn =
+{
+ DetectKnownRelease ();
+
+ InitNewSpawnflags (); // new spawnflags for all entities -- iw
+
+ lastspawn = world;
+
+ if (cvar("pr_checkextension"))
+ {
+ clientstat (CLIENT_VELOCITY_X, EV_FLOAT, velocity_x);
+ clientstat (CLIENT_VELOCITY_Y, EV_FLOAT, velocity_y);
+ }
+
+ InitBodyQue ();
+
+// custom map attributes
+ if (self.model == "maps/e1m8.bsp" && self.skip_id1_overrides == 0)
+ cvar_set ("sv_gravity", "100");
+ else
+ cvar_set ("sv_gravity", "800");
+
+ cutscene = 0; // No cutscene is active during worldspawn. Drake -- dumptruck_ds
+
+ world_sounds = &world.sounds; //Spike via dumptruck_ds || not read-only yet...
+
+// the area based ambient sounds MUST be the first precache_sounds
+
+// player precaches
+ W_Precache (); // get weapon precaches
+
+// sounds used from C physics code
+ precache_sound_land ("demon/dland2.wav"); // landing thud
+ precache_sound ("misc/h2ohit1.wav"); // landing splash
+
+// setup precaches always needed
+ precache_sound ("items/itembk2.wav"); // item respawn sound
+ precache_sound ("player/plyrjmp8.wav"); // player jump
+ precache_sound ("player/land.wav"); // player landing
+ precache_sound ("player/land2.wav"); // player hurt landing
+ precache_sound ("player/drown1.wav"); // drowning pain
+ precache_sound ("player/drown2.wav"); // drowning pain
+ precache_sound ("player/gasp1.wav"); // gasping for air
+ precache_sound ("player/gasp2.wav"); // taking breath
+ precache_sound ("player/h2odeath.wav"); // drowning death
+
+ precache_sound ("misc/talk.wav"); // talk
+ precache_sound ("player/teledth1.wav"); // telefrag
+ precache_sound ("misc/r_tele1.wav"); // teleport sounds
+ precache_sound ("misc/r_tele2.wav");
+ precache_sound ("misc/r_tele3.wav");
+ precache_sound ("misc/r_tele4.wav");
+ precache_sound ("misc/r_tele5.wav");
+ precache_sound ("weapons/lock4.wav"); // ammo pick up
+ precache_sound ("weapons/pkup.wav"); // weapon up
+ precache_sound ("items/armor1.wav"); // armor up
+ precache_sound ("weapons/lhit.wav"); //lightning
+ precache_sound ("weapons/lstart.wav"); //lightning start
+
+ // iw -- fix powerup cheat sounds // noticed this in Copper so why not? --ds
+ // sounds used by cheats
+ precache_sound ("items/suit2.wav"); // suit (finish)
+ precache_sound ("items/protect2.wav"); // pent (finish)
+ precache_sound ("items/protect3.wav"); // pent (protect)
+ precache_sound ("items/inv2.wav"); // ring (finish)
+ precache_sound ("items/inv3.wav"); // ring (idle)
+ precache_sound ("items/damage2.wav"); // quad (finish)
+ precache_sound ("items/damage3.wav"); // quad (attack)
+ // iw -- END
+
+ precache_sound ("misc/power.wav"); //lightning for boss
+
+// player gib sounds
+ precache_sound ("player/gib.wav"); // player gib sound
+ precache_sound ("player/udeath.wav"); // player gib sound
+ precache_sound ("player/tornoff2.wav"); // gib sound
+
+// player pain sounds
+
+ precache_sound ("player/pain1.wav");
+ precache_sound ("player/pain2.wav");
+ precache_sound ("player/pain3.wav");
+ precache_sound ("player/pain4.wav");
+ precache_sound ("player/pain5.wav");
+ precache_sound ("player/pain6.wav");
+
+// player death sounds
+ precache_sound ("player/death1.wav");
+ precache_sound ("player/death2.wav");
+ precache_sound ("player/death3.wav");
+ precache_sound ("player/death4.wav");
+ precache_sound ("player/death5.wav");
+
+// ax sounds
+ precache_sound ("weapons/ax1.wav"); // ax swoosh
+ precache_sound ("player/axhit1.wav"); // ax hit meat
+ precache_sound ("player/axhit2.wav"); // ax hit world
+
+ precache_sound ("player/h2ojump.wav"); // player jumping into water
+ precache_sound ("player/slimbrn2.wav"); // player enter slime
+ precache_sound ("player/inh2o.wav"); // player enter water
+ precache_sound ("player/inlava.wav"); // player enter lava
+ precache_sound ("misc/outwater.wav"); // leaving water sound
+
+ precache_sound ("player/lburn1.wav"); // lava burn
+ precache_sound ("player/lburn2.wav"); // lava burn
+
+ precache_sound ("misc/water1.wav"); // swimming
+ precache_sound ("misc/water2.wav"); // swimming
+
+ precache_model ("progs/player.mdl");
+ precache_model ("progs/s_null.spr"); // Invisible -- Drake -- dumptruck_ds
+ // precache_model ("progs/null_256.spr"); // Invisible -- Drake -- dumptruck_ds
+ precache_model ("progs/eyes.mdl");
+ precache_model ("progs/h_player.mdl");
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_model ("progs/s_bubble.spr"); // drowning bubbles
+ precache_model ("progs/s_explod.spr"); // sprite explosion
+
+ precache_model ("progs/v_axe.mdl");
+ precache_model ("progs/v_shot.mdl");
+ precache_model ("progs/v_nail.mdl");
+ precache_model ("progs/v_rock.mdl");
+ precache_model ("progs/v_shot2.mdl");
+ precache_model ("progs/v_nail2.mdl");
+ precache_model ("progs/v_rock2.mdl");
+
+ precache_model ("progs/bolt.mdl"); // for lightning gun
+ precache_model ("progs/bolt2.mdl"); // for lightning gun
+ precache_model ("progs/bolt3.mdl"); // for boss shock
+ precache_model ("progs/lavaball.mdl"); // for testing
+
+ precache_model ("progs/missile.mdl");
+ precache_model ("progs/grenade.mdl");
+ precache_model ("progs/spike.mdl");
+ // dumptruck_ds added w_spike due to errors
+ // with custom_mdls in precache_proj_model in wizard.qc
+ // precache_model ("progs/w_spike.mdl");
+ // this is on hold for now head and body are working
+ precache_model ("progs/s_spike.mdl");
+
+ precache_model ("progs/backpack.mdl");
+
+ precache_model ("progs/zom_gib.mdl");
+
+ precache_model ("progs/v_light.mdl");
+
+ precache_model ("progs/w_s_key.mdl"); // dumptruck_ds needed for DropStuff
+ precache_model ("progs/w_g_key.mdl"); //
+ precache_sound ("misc/medkey.wav");
+ precache_sound ("misc/runekey.wav");
+ precache_model ("progs/m_s_key.mdl");
+ precache_model ("progs/m_g_key.mdl");
+ precache_sound2 ("misc/basekey.wav");
+ precache_model2 ("progs/b_s_key.mdl");
+ precache_model2 ("progs/b_g_key.mdl");
+ precache_model ("progs/h_mdls/pd_vial.mdl"); // DropVial -- dumptruck_ds
+ precache_sound ("items/r_item1.wav");
+ precache_sound ("dump/armsh1.wav"); // DropShard -- dumptruck_ds
+ precache_model ("progs/armshr.mdl");
+
+//
+// Setup light animation tables. 'a' is total darkness, 'z' is maxbright.
+//
+
+ // 0 normal
+ lightstyle(0, "m");
+
+ // 1 FLICKER (first variety)
+ lightstyle(1, "mmnmmommommnonmmonqnmmo");
+
+ // 2 SLOW STRONG PULSE
+ lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
+
+ // 3 CANDLE (first variety)
+ lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg");
+
+ // 4 FAST STROBE
+ lightstyle(4, "mamamamamama");
+
+ // 5 GENTLE PULSE 1
+ lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj");
+
+ // 6 FLICKER (second variety)
+ lightstyle(6, "nmonqnmomnmomomno");
+
+ // 7 CANDLE (second variety)
+ lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm");
+
+ // 8 CANDLE (third variety)
+ lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa");
+
+ // 9 SLOW STROBE (fourth variety)
+ lightstyle(9, "aaaaaaaazzzzzzzz");
+
+ // 10 FLUORESCENT FLICKER
+ lightstyle(10, "mmamammmmammamamaaamammma");
+
+ // 11 SLOW PULSE NOT FADE TO BLACK
+ lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba");
+
+ // styles 32-62 are assigned by the light program for switchable lights
+
+ // 63 testing
+ lightstyle(63, "a");
+};
+
+void() RestartLoopSounds_think = {
+ sound(self, self.impulse, self.noise, self.volume, self.speed);
+};
+
+void() RestartLoopSounds = {
+ entity e;
+ e = find(world, classname, "play_sound_triggered");
+ while (e) {
+
+ if (e.spawnflags & 3 == 3) { // both "toggle" and "looped" need to be set
+ if (e.state == 1) {
+ e.nextthink = time + 0.1;
+ e.think = RestartLoopSounds_think;
+ }
+ }
+
+ e = find(e, classname, "play_sound_triggered");
+ }
+};
+
+
+void() StartFrame =
+{
+ if (!done_inhibition_summary) // new spawnflags for all entities -- iw
+ PrintInhibitionSummary ();
+
+ teamplay = cvar("teamplay");
+ skill = cvar("skill");
+ framecount = framecount + 1;
+
+ if (cleanUpClientStuff) {
+ cleanUpClientStuff -= 1;
+
+ RestartLoopSounds();
+ }
+ else if (!gamestarted && framecount > 2)
+ {
+ if (framecount != 3)
+ cleanUpClientStuff += 2;
+
+ gamestarted = TRUE;
+ }
+};
+
+/*
+==============================================================================
+
+BODY QUE
+
+==============================================================================
+*/
+
+entity bodyque_head;
+
+void() bodyque =
+{ // just here so spawn functions don't complain after the world
+ // creates bodyques
+};
+
+void() InitBodyQue =
+{
+ bodyque_head = spawn();
+ bodyque_head.classname = "bodyque";
+ bodyque_head.owner = spawn();
+ bodyque_head.owner.classname = "bodyque";
+ bodyque_head.owner.owner = spawn();
+ bodyque_head.owner.owner.classname = "bodyque";
+ bodyque_head.owner.owner.owner = spawn();
+ bodyque_head.owner.owner.owner.classname = "bodyque";
+ bodyque_head.owner.owner.owner.owner = bodyque_head;
+};
+
+
+// make a body que entry for the given ent so the ent can be
+// respawned elsewhere
+void(entity ent) CopyToBodyQue =
+{
+ 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;
+};

Return to the top of this page or return to the overview of this repo.