djcev.com

//

Git Repos / fte_dogmode / commit 88eaf44

Commit: 88eaf44e792f9eb40e2150a1c6e82cb289861e08
Parent: a011b58e574d39b9f30f11dff01c2f8451893407
Author: Cameron Vanderzanden, 2023-10-14 22:19
Committer: Cameron Vanderzanden, 2023-10-14 22:19

Commit Message

Q3 jumppads (from Nexuiz), Refactors & removals

I copied some code from Nexuiz to implement targeted trigger_push
entities (Quake 3 jump pads). Had to fiddle with it a little bit
but it seems to work OK. Those changes are in qc/triggers_push.qc .

Also moved armors and health into their own files in qc/items_armor.qc
and qc/items_health.qc respectively. Added some functions there for
Q3 compatibility as well.

Removed some old not-really-functional code from qc/pmove.qc, notably
pm_slidemove, an implementation of Quake 3's slidemove in FTE Quake C.
It didn't quite work correctly for reasons I wasn't able to figure out.
Maybe some day I'll revisit it.

Also reworked the code that manages the onground flag in qc/pmove.qc .

Also moved the #defines out of qc/pmove.qc into qc/defs_constants.qc .
I'm not convinced that doing compiler #defines is the right way to go,
maybe static variables would be better? (Or maybe exposing these values
to the users in cvars would be better). For not I'm leaving them as
defines.

Change List

?File Add Del
M qc/defs_constants.qc +36 -1
M qc/items.qc +1947 -2441
A qc/items_armor.qc +303
A qc/items_health.qc +274
M qc/pmove.qc +69 -305
M qc/progs.src +3
M qc/triggers.qc +10 -180
A qc/triggers_push.qc +458

Diff qc/defs_constants.qc

diff --git a/qc/defs_constants.qc b/qc/defs_constants.qc
index 7f920bb..fce7c2f 100644
--- a/qc/defs_constants.qc
+++ b/qc/defs_constants.qc
@@ -2,5 +2,40 @@
CONSTANT VALS COLLECTED HERE
==============================================================================*/

-#define PM_TELEDROP '0 0 -64' // drop tele to floor if within Z val
+#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.5 // 1 feels close to Q3 / CPM
+#define PM_AIRACCELBACK 5 // Air stop speed in Q3?
+#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
+
+#define PM_TELEDROP '0 0 -64' // drop teleporter exit to floor if
+ // floor is within this distance
+#define PM_TELEEXITSPEED 400 // exit teleporters at this speed

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 e6af21b..797f8a0 100644
--- a/qc/items.qc
+++ b/qc/items.qc
@@ -1,2441 +1,1947 @@
-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
+ // TODO CEV
+ // 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;
+};
+
+/*
+===============================================================================
+
+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/items_armor.qc

diff --git a/qc/items_armor.qc b/qc/items_armor.qc
new file mode 100644
index 0000000..31f87ce
--- /dev/null
+++ b/qc/items_armor.qc
@@ -0,0 +1,303 @@
+/*==============================================================================
+ ARMOR.QC
+==============================================================================*/
+
+void() armor_touch;
+void() shard_touch;
+
+//======================================================================
+// shard_touch
+// this is from RMQ shard_touch
+//----------------------------------------------------------------------
+void() 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;
+
+ // was 2, RMQ team
+ other.armorvalue = other.armorvalue + 5;
+
+ // 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
+ {
+ // shard = Green armor level
+ other.armortype = 0.3;
+ 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 ");
+ // custom armor name
+ sprint (other, self.obit_name);
+ sprint (other, "\n");
+ }
+ else
+ {
+ sprint(other, "You got armor\n");
+ }
+
+ // armor touch sound
+ // 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;
+
+ // fire all targets / killtargets
+ SUB_UseTargets();
+};
+
+//======================================================================
+// armor_touch function
+//----------------------------------------------------------------------
+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" ||
+ self.classname == "item_armor_combat")
+ {
+ type = 0.6;
+ value = 150;
+ bit = IT_ARMOR2;
+ }
+ else if (self.classname == "item_armorInv" ||
+ self.classname == "item_armor_body")
+ {
+ 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 ");
+ // custom armor name
+ sprint (other, self.obit_name);
+ sprint (other, "\n");
+ }
+ else
+ {
+ sprint(other, "You got armor\n");
+ }
+
+ // armor touch sound
+ // 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;
+ // fire all targets / killtargets
+ SUB_UseTargets();
+};
+
+//======================================================================
+// item_armor_shard
+//----------------------------------------------------------------------
+void() item_armor_shard =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!self.mdl_body && world.a_shr_mdl)
+ self.mdl_body = world.a_shr_mdl;
+
+ self.touch = shard_touch;
+ // 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");
+ // dumptruck_ds custom models and sounds END
+ if !(self.skin)
+ self.skin = 0;
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+/*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");
+}
+*/
+
+//======================================================================
+// item_armor1 (Green Armor)
+//----------------------------------------------------------------------
+void() item_armor1 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!self.mdl_body && world.a_grn_mdl)
+ self.mdl_body = world.a_grn_mdl;
+
+ self.touch = armor_touch;
+ // 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");
+ // dumptruck_ds custom models and sounds END
+ if !(self.skin)
+ 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 }); }
+*/
+
+//======================================================================
+// item_armor2 (Yellow Armor)
+//----------------------------------------------------------------------
+void() item_armor2 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!self.mdl_body && world.a_ylw_mdl)
+ self.mdl_body = world.a_ylw_mdl;
+
+ self.touch = armor_touch;
+ // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ // dumptruck_ds custom models and sounds END
+ if !(self.skin)
+ self.skin = 1;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+// for Quake3 entity compatibility -- CEV
+void() item_armor_combat =
+{
+ item_armor2();
+};
+
+/*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 });
+}
+*/
+
+//======================================================================
+// item_armorInv (Red Armor)
+//----------------------------------------------------------------------
+void() item_armorInv =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ if (!self.mdl_body && world.a_red_mdl)
+ self.mdl_body = world.a_red_mdl;
+
+ self.touch = armor_touch;
+ // dumptruck_ds custom models and sounds START
+ precache_body_model ("progs/armor.mdl");
+ // setmodel (self, "progs/armor.mdl");
+ body_model ("progs/armor.mdl");
+ // dumptruck_ds custom models and sounds END
+ if !(self.skin)
+ self.skin = 2;
+ precache_sound_misc ("items/armor1.wav");
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+// for Quake3 entity compatibility -- CEV
+void() item_armor_body =
+{
+ item_armorInv();
+};
+

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

Diff qc/items_health.qc

diff --git a/qc/items_health.qc b/qc/items_health.qc
new file mode 100644
index 0000000..7ae7ada
--- /dev/null
+++ b/qc/items_health.qc
@@ -0,0 +1,274 @@
+/*==============================================================================
+ HEALTH BOXES
+==============================================================================*/
+
+//======================================================================
+// 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;
+
+//======================================================================
+// item_health
+//----------------------------------------------------------------------
+void() item_health =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ 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;
+
+ // dumptruck_ds custom health models and sounds START
+ if (world.style)
+ {
+ // models courtesy Lunaran -- dumptruck_ds
+ precache_body_model ("progs/h_mdls/m_h15.mdl");
+ 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)
+ {
+ // models courtesy Lunaran -- dumptruck_ds
+ precache_body_model ("progs/h_mdls/m_h100.mdl");
+ 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)
+ // custom health amount -- 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)
+ {
+ // models courtesy Lunaran -- dumptruck_ds
+ precache_body_model ("progs/h_mdls/m_h25.mdl");
+ 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 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 ();
+};
+
+//======================================================================
+// item_health_vial
+//----------------------------------------------------------------------
+void() item_health_vial =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ self.touch = health_touch;
+
+ if (!self.mdl_body && world.h_vial_mdl)
+ self.mdl_body = world.h_vial_mdl;
+
+ // model from Hexen 2 -- dumptruck_ds
+ precache_body_model ("progs/h_mdls/pd_vial.mdl");
+ 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;
+ // over heal and count down like mega health -- dumptruck_ds
+ self.healtype = 2;
+ setsize (self, '-16 -16 0', '16 16 56');
+ if !(self.particles_offset)
+ self.particles_offset = '0 0 0';
+ StartItem ();
+};
+
+//======================================================================
+// health_touch
+//----------------------------------------------------------------------
+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);
+ // custom sounds -- dumptruck_ds
+ sound_misc (other, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+
+ 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)
+ {
+ // thanks ydrol!!!
+ other.megahealth_rottime = time + 5;
+ 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;
+ // fire all targets / killtargets
+ SUB_UseTargets ();
+};
+
+// Q3 entity support -- CEV
+void() item_health_small =
+{
+ item_health_vial ();
+};
+

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
index 6e1a8cf..b2ca7cc 100644
--- a/qc/pmove.qc
+++ b/qc/pmove.qc
@@ -2,39 +2,6 @@
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.5 // 1 feels close to Q3 / CPM
-#define PM_AIRACCELBACK 5 // Air stop speed in Q3?
-#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;

@@ -120,236 +87,8 @@ vector(vector vel, vector normal, float ob, float oneside) phys_clipvelocity =
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];
@@ -399,7 +138,8 @@ int(float dogravity, float onesided) phys_q1flymove =
if (trace_fraction >= 0.001)
self.origin = trace_endpos;

- if (trace_fraction == 1) break;
+ if (trace_fraction == 1)
+ break;

if (trace_plane_normal_z > 0.7)
{
@@ -440,9 +180,11 @@ int(float dogravity, float onesided) phys_q1flymove =
for (j = 0; j < numplanes; j++)
if (j != i)
// not ok (the comment says)
- if ((new_v * planes[j]) < 0) break;
+ if ((new_v * planes[j]) < 0)
+ break;

- if (j == numplanes) break;
+ if (j == numplanes)
+ break;
}

if (i == numplanes)
@@ -466,7 +208,7 @@ int(float dogravity, float onesided) phys_q1flymove =

if ((self.velocity * start_v) <= 0)
{
- // dprint ("phys_q1flymove: turned against orig vel\n");
+ dprint ("phys_q1flymove: turned against orig vel\n");
self.velocity = '0 0 0';
break;
}
@@ -584,8 +326,6 @@ void(float dogravity, float onesided) phys_stepslidemove =
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);
@@ -624,9 +364,8 @@ void(float dogravity, float onesided) phys_stepslidemove =
if (cvar("developer"))
{
stepsize = self.origin_z - start_o_z;
- dprint ("phys_stepslidemove: step up: ");
- dprint (ftos(stepsize));
- dprint ("\n");
+ dprint (sprintf("phys_stepslidemove: step up: %g\n",
+ stepsize));
}
}
};
@@ -673,20 +412,12 @@ void(float friction) phys_friction =
self.velocity = self.velocity * (newspeed / speed);
};

-// function based on GPL2 purecsqc pmove.qc
-void() phys_categorizeposition =
+void(entity ground_e, vector ground_v, int docheck) phys_setonground =
{
- vector p;
- float pc;
-
- if (self.movetype == MOVETYPE_NOCLIP)
- {
- // noclip is never on ground
- self.flags &= ~FL_ONGROUND;
- }
- else
+ // look for ground with tracebox if requested
+ if (docheck)
{
- tracebox(self.origin, self.mins, self.maxs,
+ 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
@@ -695,19 +426,47 @@ void() phys_categorizeposition =
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;
+ self.groundnormal = trace_plane_normal;
}
else
{
- // not on ground
- self.flags &= ~FL_ONGROUND;
- self.groundnormal = __NULL__;
self.groundentity = __NULL__;
+ self.groundnormal = __NULL__;
}
}
+ else
+ {
+ self.groundentity = ground_e;
+ self.groundnormal = ground_v;
+ }
+
+ // assume we're on ground if we have a groundnormal field -- CEV
+ // is there a situation where groundnormal could be '0 0 0'? -- CEV
+ if (self.groundnormal != __NULL__)
+ {
+ // on ground
+ self.flags |= FL_ONGROUND;
+ self.flags &= ~FL_WALLJUMP;
+ }
+ else
+ {
+ // not on ground
+ self.flags &= ~FL_ONGROUND;
+ }
+};
+
+// function based on GPL2 purecsqc pmove.qc
+void() phys_categorizeposition =
+{
+ vector p;
+ float pc;
+
+ if (self.movetype == MOVETYPE_NOCLIP)
+ // noclip is never on ground
+ phys_setonground (__NULL__, __NULL__, FALSE);
+ else
+ phys_setonground (__NULL__, __NULL__, TRUE);

// clear doublejumped if outside of DOUBLEJUMP_COOLDOWN
if ((self.flags & FL_DOUBLEJUMPED)
@@ -841,7 +600,7 @@ void() phys_jump =
if ((self.jump_time > time - PM_TELEJUMP_WINDOW) &&
(self.teleport_time > time - (PM_TELEJUMP_WINDOW + 0.2)))
{
- dprint("phys_jump: telejump\n");
+ dprint ("phys_jump: telejump\n");
self.velocity_z += PM_TELEJUMPSPEED;
if !(self.flags & FL_DOUBLEJUMPED)
self.flags |= FL_DOUBLEJUMPED;
@@ -850,9 +609,9 @@ void() phys_jump =
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");
+ dprint ("phys_jump: stairjump\n");
else
- dprint("phys_jump: doublejump\n");
+ dprint ("phys_jump: doublejump\n");
if (self.flags & FL_DOUBLEJUMPED)
{
self.velocity_z += PM_TRIPLEJUMPSPEED;
@@ -870,12 +629,9 @@ void() phys_jump =
}

// clear flags
- self.flags &~= FL_ONGROUND;
+ phys_setonground (__NULL__, __NULL__, FALSE);
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)
@@ -919,9 +675,8 @@ void(vector checkdir) phys_walljump =
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");
+ dprint (sprintf("phys_walljump: walljump dist %g\n",
+ vlen(self.origin - trace_endpos)));
// player jumping sound
sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
// modify X and Y velocity
@@ -968,6 +723,7 @@ int() phys_walkaccelerate =
vector wishvel, wishdir, wishang;
vector curang;
float tempf, wishspeed;
+ float scale;
int onesided;

onesided = FALSE;
@@ -990,15 +746,20 @@ int() phys_walkaccelerate =
wishspeed = vlen (wishvel);
wishdir = normalize (wishvel);

- /*
- * TODO CEV 2023-09
+ /* TODO CEV
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 (scale > 0)
+ {
+ dprint ("phys_walkaccelerate: applying scale ");
+ dprint (ftos(scale));
+ dprint ("\n");
+ wishspeed *= scale;
+ }
}
- */
+ */

if (wishspeed > PM_MAXSPEED) wishspeed = PM_MAXSPEED;

@@ -1168,7 +929,7 @@ void(entity ent) phys_move =
break;
case MOVETYPE_FLY:
phys_noclipaccelerate (1.0);
- phys_slidemove (FALSE);
+ phys_q1flymove (FALSE, TRUE);
break;
case MOVETYPE_NOCLIP:
phys_noclipaccelerate (1.0);
@@ -1180,8 +941,11 @@ void(entity ent) phys_move =

if (self.groundentity)
phys_dotouch (self.groundentity);
- phys_categorizeposition ();
+ phys_setonground (self.groundentity, self.groundnormal, TRUE);
touchtriggers (self);
}
- else print(sprintf("phys_move: timelength %g\n", input_timelength));
+ 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 1655f8d..b542459 100644
--- a/qc/progs.src
+++ b/qc/progs.src
@@ -20,6 +20,8 @@ ai.qc
combat.qc
keydata.qc // functions which deal with key item bitflags + names
items.qc
+items_armor.qc
+items_health.qc
weapons.qc
world.qc
intermission.qc
@@ -32,6 +34,7 @@ keylock.qc // common code for entities unlockable with keys
doors.qc
buttons.qc
triggers.qc // added trigger_push_custom based on Hipnotic
+triggers_push.qc // wind/push brushes, jumppads -- CEV
plats.qc
misc.qc
lights.qc // c0burn's excellent switchable lights

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 a7617d9..1413a00 100644
--- a/qc/triggers.qc
+++ b/qc/triggers.qc
@@ -1,3 +1,6 @@
+/*==============================================================================
+ TRIGGERS.QC
+==============================================================================*/

// entity s;

@@ -585,7 +588,7 @@ if (!(self.spawnflags & TELE_STEALTH))
// TODO CEV
// if (other.flags & FL_ONGROUND)
// other.flags = other.flags - FL_ONGROUND;
- other.velocity = v_forward * 300;
+ other.velocity = v_forward * PM_TELEEXITSPEED;
}
other.flags = other.flags - other.flags & FL_ONGROUND;

@@ -595,7 +598,7 @@ if (!(self.spawnflags & TELE_STEALTH))
other.teleport_time = time + 0.7;
if (other.flags & FL_ONGROUND)
other.flags = other.flags - FL_ONGROUND;
- other.velocity = v_forward * 300;
+ other.velocity = v_forward * PM_TELEEXITSPEED;
}
other.flags = other.flags - other.flags & FL_ONGROUND;
};
@@ -719,6 +722,11 @@ void() misc_teleporter_destination =
info_teleport_destination();
};

+void() target_teleporter =
+{
+ 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
{
model ("progs/player.mdl");
@@ -919,184 +927,6 @@ void() trigger_hurt =
SUB_CheckWaiting();
};

-//============================================================================
-
-//////////////////////////////////////////////////////////////////////////////
-// start dumptruck_ds additions //////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-float PUSH_ONCE = 1;
-float DT_STARTOFF = 8; // trigger will start off
-float DT_SILENT = 16; // push silently
-float DT_NOISE = 32; // use custom sound using noise key/value
-
-void() trigger_push_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (other.classname == "grenade")
- other.velocity = self.speed * self.movedir * 10;
- else if (other.health > 0)
- {
- 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
- {
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO,
- self.noise,
- 1, ATTN_NORM);
- }
- }
- }
- }
- if (self.spawnflags & PUSH_ONCE)
- remove(self);
-};
-
-// void() trigger_push_use = //dumptruck_ds
-// {
-// self.is_waiting = !self.is_waiting;
-// }
-
-/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE 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
-Pushes the player
-*/
-void() trigger_push = //dumptruck_ds
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger ();
- precache_sound ("ambience/windfly.wav");
- self.touch = trigger_push_touch;
-
- if (!self.speed)
- self.speed = 1000;
-
- SUB_CheckWaiting();
-};
-
-void() push_toggle = //dumptruck_ds was based on hipnotic blocker_use now Alklaine estate
-
-{
- if (self.estate != STATE_ACTIVE)
- self.estate = STATE_ACTIVE;
- else
- self.estate = STATE_INACTIVE;
-};
-
-/*QUAKED trigger_push_custom (.5 .5 .5) ? PUSH_ONCE DT_STARTOFF DT_SILENT 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
-
-
-dumptruck_ds
-
-trigger_push_custom is a new entity. This can be used to create traps,
-jumppads, currents in water and more.
-
-If DT_STARTOFF flag is set, this disables the trigger. This can be targeted and
-toggled off and on. If the DT_SILENT flag is set it won't make the windfly
-sound. Use DT_CUSTOM spawnflag and the noise key/value to use a custom push
-sound. Custom sounds should be "one off" sounds NOT be looping.
-
-Adapted from Hipnotic's func_togglewall */
-
-void() trigger_push_custom =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- InitTrigger();
- precache_sound ("ambience/windfly.wav");
- self.use = push_toggle;
- self.touch = trigger_push_touch;
-
- if ( self.spawnflags & DT_STARTOFF )
- {
- self.estate = STATE_INACTIVE;
- }
-
- if ( self.noise != "" )
- {
- precache_sound(self.noise);
- }
-
- if (!self.speed)
- self.speed = 1000;
-
- SUB_CheckWaiting();
-};
-
-
-//============================================================================
-
-void() trigger_monsterjump_touch =
-{
- if (self.estate != STATE_ACTIVE) return;
-
- if ( other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER )
- return;
-
-// set XY even if not on ground, so the jump will clear lips
- other.velocity_x = self.movedir_x * self.speed;
- other.velocity_y = self.movedir_y * self.speed;
-
- if ( !(other.flags & FL_ONGROUND) )
- return;
-
- other.flags = other.flags - FL_ONGROUND;
-
- other.velocity_z = self.height;
-};
-
-/*QUAKED trigger_monsterjump (.5 .5 .5) ? X X X DT_STARTOFF 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
-
-Walking monsters that touch this will jump in the direction of the trigger's angle
-"speed" default to 200, the speed thrown forward
-"height" default to 200, the speed thrown upwards
-
-If DT_STARTOFF flag is set, this makes the trigger
-inactive. This can be targeted and toggled off and on.
-*/
-void() trigger_monsterjump =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-
- self.use = push_toggle;
- if ( self.spawnflags & DT_STARTOFF ) // dumptruck_ds
- {
- self.estate = STATE_INACTIVE;
- }
- if (!self.speed)
- self.speed = 200;
- if (!self.height)
- self.height = 200;
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
- InitTrigger ();
- self.touch = trigger_monsterjump_touch;
-
- SUB_CheckWaiting();
-};
-//////////////////////////////////////////////////////////////////////////////
-// end dumptruck_ds additions //////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
//This is necros' trigger_void from Lost Chapters pack, modified by dumptruck_ds

float MONSTER_SAFE = 1;

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

Diff qc/triggers_push.qc

diff --git a/qc/triggers_push.qc b/qc/triggers_push.qc
new file mode 100644
index 0000000..975fcd8
--- /dev/null
+++ b/qc/triggers_push.qc
@@ -0,0 +1,458 @@
+/*==============================================================================
+ TRIGGER_PUSH.QC
+==============================================================================*/
+
+//======================================================================
+// trigger_push
+//----------------------------------------------------------------------
+
+////////////////////////////////////////////////////////////////////////
+// start dumptruck_ds additions ////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+float PUSH_ONCE = 1;
+float DT_STARTOFF = 8; // trigger will start off
+float DT_SILENT = 16; // push silently
+float DT_NOISE = 32; // use custom sound via noise key/value
+
+////////////////////////////////////////////////////////////////////////
+// start code CEV copied from Nexuiz ///////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+// from Nexuiz source code; copied from
+// https://github.com/smlinux/nexuiz/blob/master/data/qcsrc/common/util.qc
+// ax^2 + bx + c = 0
+vector(float a, float b, float c) solve_quadratic =
+{
+ vector v;
+ float D;
+ v = '0 0 0';
+ if (a == 0)
+ {
+ if (b != 0)
+ {
+ v_x = v_y = -c / b;
+ v_z = 1;
+ }
+ else
+ {
+ if (c == 0)
+ {
+ // actually, every number solves the equation!
+ v_z = 1;
+ }
+ }
+ }
+ else
+ {
+ D = b*b - 4*a*c;
+ if (D >= 0)
+ {
+ D = sqrt (D);
+ if (a > 0)
+ {
+ // put the smaller solution first
+ v_x = ((-b)-D) / (2*a);
+ v_y = ((-b)+D) / (2*a);
+ }
+ else
+ {
+ v_x = (-b+D) / (2*a);
+ v_y = (-b-D) / (2*a);
+ }
+ v_z = 1;
+ }
+ else
+ {
+ // complex solutions!
+ D = sqrt (-D);
+ v_x = -b / (2*a);
+ if (a > 0)
+ v_y = D / (2*a);
+ else
+ v_y = -D / (2*a);
+ v_z = 0;
+ }
+ }
+ return v;
+}
+
+/*
+ trigger_push_calculatevelocity
+
+ Arguments:
+ org - origin of the object which is to be pushed
+ tgt - target entity (can be either a point or a model entity; if it
+ is the latter, its midpoint is used)
+ ht - jump height, measured from the higher one of org and tgt's
+ midpoint
+
+ Returns: velocity for the jump
+ the global trigger_push_calculatevelocity_flighttime is set to the
+ total jump time
+ */
+
+// from Nexuiz source code; copied from
+// https://github.com/smlinux/nexuiz/blob/master/data/qcsrc/server/t_jumppads.qc
+vector(vector org, entity tgt, float ht) trigger_push_calculatevelocity =
+{
+ local float grav, sdist, zdist, vs, vz, jumpheight;
+ local vector sdir, torg;
+ vector solution;
+ float trigger_push_calculatevelocity_flighttime;
+
+ torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
+
+ grav = cvar ("sv_gravity");
+
+ zdist = torg_z - org_z;
+ sdist = vlen (torg - org - zdist * '0 0 1');
+ sdir = normalize (torg - org - zdist * '0 0 1');
+
+ // how high do we need to push the player?
+ jumpheight = fabs (ht);
+ if (zdist > 0)
+ jumpheight = jumpheight + zdist;
+
+ /*
+ STOP.
+
+ You will not understand the following equations anyway...
+ But here is what I did to get them.
+
+ I used the functions
+
+ s(t) = t * vs
+ z(t) = t * vz - 1/2 grav t^2
+
+ and solved for:
+
+ s(ti) = sdist
+ z(ti) = zdist
+ max(z, ti) = jumpheight
+
+ From these three equations, you will find the three
+ parameters vs, vz and ti.
+ */
+
+ // push him so high... NOTE: sqrt(positive)!
+ vz = sqrt (2 * grav * jumpheight);
+
+ // we start with downwards velocity only if it's a downjump
+ // and the jump apex should be outside the jump!
+ if (ht < 0)
+ if (zdist < 0)
+ vz = -vz;
+
+ // equation "z(ti) = zdist"
+ solution = solve_quadratic (0.5 * grav, -vz, zdist);
+ // ALWAYS solvable because jumpheight >= zdist
+ if (!solution_z)
+ // just in case it is not solvable due to roundoff errors,
+ // assume two equal solutions at their center (this is
+ // mainly for the usual case with ht == 0)
+ solution_y = solution_x;
+ if (zdist == 0)
+ // solution_x is 0 in this case, so don't use it, but rather
+ // use solution_y (which will be sqrt(0.5 * jumpheight / grav),
+ // actually)
+ solution_x = solution_y;
+
+ if (zdist < 0)
+ {
+ // down-jump
+ if (ht < 0)
+ {
+ // almost straight line type
+ // jump apex is before the jump
+ // we must take the larger one
+ trigger_push_calculatevelocity_flighttime = solution_y;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one too
+ trigger_push_calculatevelocity_flighttime = solution_y;
+ }
+ }
+ else
+ {
+ // up-jump
+ if (ht < 0)
+ {
+ // almost straight line type
+ // jump apex is after the jump
+ // we must take the smaller one
+ trigger_push_calculatevelocity_flighttime = solution_x;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one
+ trigger_push_calculatevelocity_flighttime = solution_y;
+ }
+ }
+ vs = sdist / trigger_push_calculatevelocity_flighttime;
+
+ // finally calculate the velocity
+ return sdir * vs + '0 0 1' * vz;
+};
+
+void() trigger_push_findtarget =
+{
+ self.enemy = find (world, targetname, self.target);
+ if (self.enemy)
+ {
+ local vector org;
+ org = (self.absmin + self.absmax) * 0.5;
+ org_z = self.absmax_z - -24; // - PL_MIN_z;
+ self.movedir = trigger_push_calculatevelocity (org,
+ self.enemy, self.height);
+ }
+};
+
+////////////////////////////////////////////////////////////////////////
+// end code CEV copied from Nexuiz /////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+void() trigger_push_touch =
+{
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ // try to find target again if necessary
+ if (self.target && (!self.enemy))
+ trigger_push_findtarget ();
+
+ // we have a target, set movedir accordingly
+ if (self.target && self.enemy)
+ self.movedir = trigger_push_calculatevelocity (other.origin,
+ self.enemy, self.height);
+
+ if (other.classname == "grenade")
+ {
+ if (self.target && self.enemy)
+ other.velocity = self.movedir;
+ else
+ other.velocity = self.speed * self.movedir * 10;
+ }
+ else if (other.health > 0)
+ {
+ if (self.target && self.enemy)
+ other.velocity = self.movedir;
+ else
+ other.velocity = self.speed * self.movedir * 10;
+
+ if (other.classname == "player")
+ {
+ /*
+ // for debugging -- CEV
+ dprint ("trigger_push_touch: target ");
+ dprint (self.target);
+ dprint (" movedir ");
+ dprint (vtos(self.movedir));
+ dprint ("\n");
+ */
+
+ 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
+ {
+ other.fly_sound = time + 1.5;
+ sound (other, CHAN_AUTO,
+ self.noise,
+ 1, ATTN_NORM);
+ }
+ }
+ }
+ }
+
+ if (self.spawnflags & PUSH_ONCE)
+ remove (self);
+};
+
+// // dumptruck_ds
+// void() trigger_push_use =
+// {
+// self.is_waiting = !self.is_waiting;
+// }
+
+/*QUAKED trigger_push (.5 .5 .5) ? PUSH_ONCE 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
+Pushes the player
+*/
+void() trigger_push =
+{
+ // dumptruck_ds
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ InitTrigger ();
+ precache_sound ("ambience/windfly.wav");
+ self.touch = trigger_push_touch;
+
+ if (!self.speed)
+ self.speed = 1000;
+
+ if (self.target)
+ {
+ // attempt to find the target
+ trigger_push_findtarget ();
+ if (!self.enemy)
+ if (!self.movedir)
+ // TODO CEV is this up? I don't remember
+ self.movedir = '0 0 180';
+ }
+
+ SUB_CheckWaiting ();
+};
+
+// dumptruck_ds was based on hipnotic blocker_use now Alklaine estate
+void() push_toggle =
+{
+ if (self.estate != STATE_ACTIVE)
+ self.estate = STATE_ACTIVE;
+ else
+ self.estate = STATE_INACTIVE;
+};
+
+/*QUAKED trigger_push_custom (.5 .5 .5) ? PUSH_ONCE DT_STARTOFF DT_SILENT 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
+
+
+dumptruck_ds
+
+trigger_push_custom is a new entity. This can be used to create traps,
+jumppads, currents in water and more.
+
+If DT_STARTOFF flag is set, this disables the trigger. This can be targeted
+and toggled off and on. If the DT_SILENT flag is set it won't make the windfly
+sound. Use DT_CUSTOM spawnflag and the noise key/value to use a custom push
+sound. Custom sounds should be "one off" sounds NOT be looping.
+
+Adapted from Hipnotic's func_togglewall */
+void() trigger_push_custom =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ InitTrigger ();
+ precache_sound ("ambience/windfly.wav");
+ self.use = push_toggle;
+ self.touch = trigger_push_touch;
+
+ if (self.spawnflags & DT_STARTOFF)
+ {
+ self.estate = STATE_INACTIVE;
+ }
+
+ if (self.noise != "")
+ {
+ precache_sound(self.noise);
+ }
+
+ if (!self.speed)
+ self.speed = 1000;
+
+ SUB_CheckWaiting ();
+};
+
+// push target entities for Quake 3 compatibility -- CEV
+void() target_push =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ if (!self.targetname)
+ if (self.target)
+ // quake 3 compat -- CEV
+ self.targetname = self.target;
+ else
+ objerror ("no targetname");
+};
+
+void() target_position =
+{
+ target_push ();
+};
+
+//======================================================================
+// monsterjump
+//----------------------------------------------------------------------
+
+void() trigger_monsterjump_touch =
+{
+ if (self.estate != STATE_ACTIVE)
+ return;
+
+ if (other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
+ return;
+
+ // set XY even if not on ground, so the jump will clear lips
+ other.velocity_x = self.movedir_x * self.speed;
+ other.velocity_y = self.movedir_y * self.speed;
+
+ if (!(other.flags & FL_ONGROUND))
+ return;
+
+ other.flags = other.flags - FL_ONGROUND;
+
+ other.velocity_z = self.height;
+};
+
+/*QUAKED trigger_monsterjump (.5 .5 .5) ? X X X DT_STARTOFF 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
+
+Walking monsters that touch this will jump in the direction of the
+trigger's angle
+"speed" default to 200, the speed thrown forward
+"height" default to 200, the speed thrown upwards
+
+If DT_STARTOFF flag is set, this makes the trigger inactive. This can
+be targeted and toggled off and on.
+*/
+void() trigger_monsterjump =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ self.use = push_toggle;
+
+ // dumptruck_ds
+ if (self.spawnflags & DT_STARTOFF)
+ {
+ self.estate = STATE_INACTIVE;
+ }
+
+ if (!self.speed)
+ self.speed = 200;
+ if (!self.height)
+ self.height = 200;
+ if (self.angles == '0 0 0')
+ self.angles = '0 360 0';
+
+ InitTrigger ();
+ self.touch = trigger_monsterjump_touch;
+
+ SUB_CheckWaiting ();
+};
+
+////////////////////////////////////////////////////////////////////////
+// end dumptruck_ds additions //////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+

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