djcev.com

//

Git Repos / fte_dogmode / commit 9ed77a9

Commit: 9ed77a98ac7b77f00bb9316145097040cb0e17e3
Parent: 689b89135916beb05b98056dc5fbbf5ad0b7dbd4
Author: Cameron Vanderzanden, 2023-12-09 18:29
Committer: Cameron Vanderzanden, 2023-12-09 18:29

Commit Message

Start OO / class-based refactor, work on items

This is a commit in-progress, a task half done. I've started
reworking the various entities in the game into FTEQCC compatible
classes. Most of the triggers and misc entities are done, next
is to do func and then items and then monsters. Then I'll attempt
to untangle the various functions those entities depend on into
base classes, working my way through ai, combat, subs, et cetera
as I go.

I'm doing this as a further excuse to familiarize myself with the
program, and also because I think it makes more sense expressed
in an object-oriented fashion. This approach has some advantages
that I'm looking forward to, class-specific fields for example, and
Transmitting entities from server to client.

It's pretty slow going so I'll be splitting the task into multiple
commits.

Looking over the files that changed I see other things I did before
I started the class rewrite, things I've now forgotten.

Change List

?File Add Del
M README.md +12
M autoexec.cfg +12 -4
M qc/ai.qc +9
A qc/classes/base_trigger.qc +46
D qc/client.qc -1493
A qc/client/connect.qc +37
M qc/client/impulse.qc +247 -21
A qc/client/levelparms.qc +88
A qc/client/maprules.qc +91
A qc/client/obituary.qc +336
A qc/client/playerspawn.qc +345
M qc/compat_quake3.qc +11 -20
M qc/csqc/csqc_defsclient.qc +7 -4
M qc/csqc/csqc_entrypoints.qc +13 -11
M qc/csqc/csqc_player.qc +7 -6
M qc/csqc/csqc_progs.src +4 -3
M qc/cutscene.qc +770 -855
M qc/defs_builtins.qc +12 -17
A qc/defs_classtype.qc +141
M qc/defs_entvars.qc +4 -4
M qc/defs_globalvars.qc +3 -5
M qc/defs_misc.qc +159 -171
M qc/fight.qc +3 -1
M qc/func/breakable.qc -3
M qc/func/laser.qc +8 -7
M qc/func/rotate.qc +4 -2
M qc/func/shadow.qc +2
M qc/func/togglewall.qc +6 -3
M qc/func/train.qc +2
A qc/info/camera.qc +68
A qc/info/notnull.qc +21
A qc/info/null.qc +22
A qc/info/teleport_changedest.qc +96
A qc/info/teleport_destination.qc +79
M qc/items/ammo.qc +50 -28
M qc/items/armor.qc +63 -23
A qc/items/axe.qc +88
M qc/items/backpacks.qc +34 -21
M qc/items/health.qc +48 -34
M qc/items/misc.qc +1 -1
A qc/items/nailguns.qc +46
M qc/items/powerups.qc +14 -13
A qc/items/shotguns.qc +59
M qc/items/weapons.qc +50 -149
M qc/math.qc +3 -3
M qc/misc/air_bubbles.qc +108 -108
M qc/misc/ambient_sound.qc +307 -141
M qc/misc/deadstuff.qc +320 -238
M qc/misc/explobox.qc +76 -61
M qc/misc/fireball.qc +49 -45
M qc/misc/infight.qc +99 -89
M qc/misc/light_candle.qc +37 -29
M qc/misc/lights.qc +227 -196
M qc/misc/model.qc +165 -154
M qc/misc/modeltrain.qc +2 -2
M qc/misc/noisemaker.qc +35 -29
M qc/misc/particle_stream.qc +74 -66
M qc/misc/particles.qc +58 -51
M qc/misc/particlespray.qc +56 -56
M qc/misc/play.qc +386 -304
M qc/misc/sparks.qc +138 -129
M qc/misc/target_autosave.qc +92 -74
M qc/misc/teleporttrain.qc +136 -130
M qc/misc/viewthing.qc +15 -12
M qc/monsters/zombie.qc -28
M qc/newflags.qc +21 -28
D qc/player.qc -747
A qc/player/player.qc +1043
A qc/player/playerthink.qc +616
A qc/player/pmove.qc +2165
D qc/pmove.qc -2139
M qc/progs.src +42 -13
M qc/subs.qc +14 -43
A qc/triggers/camera.qc +209
M qc/triggers/changelevel.qc +126 -117
M qc/triggers/changemusic.qc +87 -69
M qc/triggers/changetarget.qc +31 -23
M qc/triggers/counter.qc +57 -45
A qc/triggers/cvarset.qc +56
A qc/triggers/everything.qc +38
M qc/triggers/filter.qc +177 -167
M qc/triggers/fog.qc +387 -360
M qc/triggers/heal.qc +174 -153
M qc/triggers/hurt.qc +75 -76
M qc/triggers/ladder.qc +52 -50
M qc/triggers/look.qc +106 -103
D qc/triggers/misc.qc -506
M qc/triggers/monsterface.qc +44 -38
M qc/triggers/monsterjump.qc +61 -41
A qc/triggers/multiple.qc +255
M qc/triggers/onlyregistered.qc +40 -36
M qc/triggers/push.qc +229 -225
A qc/triggers/relay.qc +21
M qc/triggers/remove.qc +4 -3
M qc/triggers/secret.qc +26 -21
A qc/triggers/setcount.qc +76
M qc/triggers/setgravity.qc +73 -68
M qc/triggers/setskill.qc +22 -15
A qc/triggers/setstate.qc +177
M qc/triggers/shake.qc +102 -98
M qc/triggers/take_weapon.qc +41 -30
M qc/triggers/teleport.qc +202 -321
M qc/triggers/textstory.qc +211 -166
M qc/triggers/usekey.qc +117 -100
M qc/triggers/void.qc +67 -46
M qc/weapons.qc +46 -701
M qc/world.qc +205 -67
A sound/items/armor_shard_q3.wav
A sound/items/item_respawn_q3.wav

Diff README.md

diff --git a/README.md b/README.md
index 9cec2dd..8b4ed6d 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,8 @@

### Credits, Sources, & License

+#### Quake C (Mod Source)
+
Client side Quake C based on Arcane Dimensions by Simon O'Callaghan (Sock)
and others, original available at:
<https://github.com/SimsOCallaghan/ArcaneDimensions>
@@ -12,6 +14,16 @@ Server side Quake C based on progs_dump version 3.0, which can be found at:
Both above sources licensed GPL 2.0; Dog Mode (this mod, and the Quake C
source in this repo) is presented under the same license.

+#### Models & Sounds
+
+Models
+
+Sounds
+
+* sound/items/armor_shard_q3.wav Armor shard sound from Quake 3 (id Software).
+* sound/items/item_respawn_q3.wav item repsawning sound from Q3 (id Software).
+* sound/oldone2/pd_pop2.wav from progs_dump version 3.0
+
### The Name "Dog Mode"

I have a (now foggy) memory of a night of PQL duels where, inbetween

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

Diff autoexec.cfg

diff --git a/autoexec.cfg b/autoexec.cfg
index e46d21f..ed12c6c 100644
--- a/autoexec.cfg
+++ b/autoexec.cfg
@@ -1,4 +1,12 @@
-cl_run 0
-pm_airstep 1
-pm_walljump 1
-sv_bigcoords 1
+// don't autoswitch weapons
+seta cg_autoswitch 0
+//
+seta cl_run 0
+// enable air stepping
+seta pm_airstep 1
+// enable wall jumps
+seta pm_walljump 1
+// transmit large coords from server to client
+seta sv_bigcoords 1
+// save in FTE format
+seta sv_savefmt 1

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

Diff qc/ai.qc

diff --git a/qc/ai.qc b/qc/ai.qc
index f123707..24a28a8 100644
--- a/qc/ai.qc
+++ b/qc/ai.qc
@@ -330,6 +330,15 @@ void() SightSound =
sound_sight (self, CHAN_VOICE, "boss2/sight.wav", 1, ATTN_NONE);
};

+// TODO CEV
+void(entity ent) FoundTargetForEntity =
+{
+ entity oself = self;
+ self = ent;
+ FoundTarget ();
+ self = oself;
+}
+
void() FoundTarget =
{
if (self.enemy.classname == "player")

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

Diff qc/classes/base_trigger.qc

diff --git a/qc/classes/base_trigger.qc b/qc/classes/base_trigger.qc
new file mode 100644
index 0000000..957cfc5
--- /dev/null
+++ b/qc/classes/base_trigger.qc
@@ -0,0 +1,46 @@
+//==============================================================================
+// base_trigger.qc -- trigger base class
+//==============================================================================
+
+//------------------------------------------------------------------------------
+class base_trigger: entity
+{
+ //--------------------------------------------------------------
+ // InitTrigger
+ //--------------------------------------------------------------
+ nonvirtual void() init_trigger =
+ {
+ // trigger angles are used for one-way touches.
+ // An angle of 0 is assumed to mean no restrictions, so use a
+ // yaw of 360 instead.
+ if (this.angles != '0 0 0')
+ SetMovedir ();
+
+ this.solid = SOLID_TRIGGER;
+ // set size and link into world
+ setmodel (this, this.model);
+ this.movetype = MOVETYPE_NONE;
+ this.modelindex = 0;
+ this.model = "";
+ };
+
+ //--------------------------------------------------------------
+ // InitPointTrigger -- Drake -- dumptruck_ds
+ // PM: The point trigger version of InitTrigger.
+ //--------------------------------------------------------------
+ nonvirtual void() init_point_trigger =
+ {
+ local vector v1, v2;
+
+ v1 = this.origin;
+ v2 = v1 + this.mangle;
+ this.model = "";
+ setorigin (this, '0 0 0');
+
+ // Calls 'setmodel', so do first.
+ init_trigger ();
+
+ // Calling 'setmodel' resets entity size.
+ setsize (this, v1, v2);
+ };
+};

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

Diff qc/client.qc

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

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

Diff qc/client/connect.qc

diff --git a/qc/client/connect.qc b/qc/client/connect.qc
new file mode 100644
index 0000000..6b2fe77
--- /dev/null
+++ b/qc/client/connect.qc
@@ -0,0 +1,37 @@
+//==============================================================================
+// client/connect.qc
+//==============================================================================
+
+//----------------------------------------------------------------------
+// ClientConnect
+// called when a player connects to a server
+//----------------------------------------------------------------------
+void() ClientConnect =
+{
+ bprint (self.netname);
+ bprint (" entered the game\n");
+
+ // a client connecting during an intermission can cause problems
+ if (intermission_running)
+ ExitIntermission ();
+};
+
+//----------------------------------------------------------------------
+// ClientDisconnect
+// called when a player disconnects from a server
+//----------------------------------------------------------------------
+void() ClientDisconnect =
+{
+ // if the level end trigger has been activated, just return
+ // since they aren't *really* leaving
+ if (gameover)
+ return;
+
+ // let everyone else know
+ bprint (self.netname);
+ bprint (" left the game with ");
+ bprint (ftos(self.frags));
+ bprint (" frags\n");
+ sound (self, CHAN_BODY, "player/tornoff2.wav", 1, ATTN_NONE);
+ set_suicide_frame ();
+};

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

Diff qc/client/impulse.qc

diff --git a/qc/client/impulse.qc b/qc/client/impulse.qc
index aebefa5..19f897a 100644
--- a/qc/client/impulse.qc
+++ b/qc/client/impulse.qc
@@ -26,7 +26,7 @@ void() CheatCommand =

self.weapon = IT_ROCKET_LAUNCHER;
self.impulse = 0;
- W_SetCurrentAmmo ();
+ PlayerSetCurrentAmmo ();
};

//----------------------------------------------------------------------
@@ -58,30 +58,256 @@ void() ServerflagsCommand =
};

//----------------------------------------------------------------------
+// ChangeWeaponCommand -- was W_ChangeWeapon
+//----------------------------------------------------------------------
+void() ChangeWeaponCommand =
+{
+ local float it, haveammo, fl;
+
+ // assign fl to silence a warning -- CEV
+ fl = IT_AXE;
+ it = self.items;
+ haveammo = TRUE;
+
+ switch (self.impulse)
+ {
+ case 1:
+ fl = IT_AXE;
+ break;
+ case 2:
+ fl = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ haveammo = FALSE;
+ break;
+ case 3:
+ fl = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ haveammo = FALSE;
+ break;
+ case 4:
+ fl = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ haveammo = FALSE;
+ break;
+ case 5:
+ fl = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ haveammo = FALSE;
+ break;
+ case 6:
+ fl = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ break;
+ case 7:
+ fl = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ break;
+ case 8:
+ fl = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ haveammo = FALSE;
+ break;
+ default:
+ dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
+ dprint (ftos (self.impulse));
+ dprint ("\n");
+ return;
+ }
+
+ self.impulse = 0;
+
+ if (!(self.items & fl))
+ { // don't have the weapon or the ammo
+ sprint (self, "no weapon.\n");
+ return;
+ }
+
+ if (haveammo == FALSE)
+ { // don't have the ammo
+ sprint (self, "not enough ammo.\n");
+ return;
+ }
+
+ // set weapon, set ammo
+ self.weapon = fl;
+ PlayerSetCurrentAmmo ();
+};
+
+//----------------------------------------------------------------------
+// CycleWeaponCommand -- Go to the next weapon with ammo
+//----------------------------------------------------------------------
+void() CycleWeaponCommand =
+{
+ local float haveammo;
+
+ self.impulse = 0;
+
+ while (1)
+ {
+ haveammo = TRUE;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ haveammo = FALSE;
+ }
+
+ if ((self.items & self.weapon) && haveammo == TRUE)
+ {
+ PlayerSetCurrentAmmo ();
+ return;
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+// CycleWeaponReverseCommand -- Go to the prev weapon with ammo
+//----------------------------------------------------------------------
+void() CycleWeaponReverseCommand =
+{
+ local float haveammo;
+
+ self.impulse = 0;
+
+ while (1)
+ {
+ haveammo = TRUE;
+
+ if (self.weapon == IT_LIGHTNING)
+ {
+ self.weapon = IT_ROCKET_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_ROCKET_LAUNCHER)
+ {
+ self.weapon = IT_GRENADE_LAUNCHER;
+ if (self.ammo_rockets < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_GRENADE_LAUNCHER)
+ {
+ self.weapon = IT_SUPER_NAILGUN;
+ if (self.ammo_nails < 2)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SUPER_NAILGUN)
+ {
+ self.weapon = IT_NAILGUN;
+ if (self.ammo_nails < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_NAILGUN)
+ {
+ self.weapon = IT_SUPER_SHOTGUN;
+ if (self.ammo_shells < 2)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SUPER_SHOTGUN)
+ {
+ self.weapon = IT_SHOTGUN;
+ if (self.ammo_shells < 1)
+ haveammo = FALSE;
+ }
+ else if (self.weapon == IT_SHOTGUN)
+ {
+ self.weapon = IT_AXE;
+ }
+ else if (self.weapon == IT_AXE)
+ {
+ self.weapon = IT_LIGHTNING;
+ if (self.ammo_cells < 1)
+ haveammo = FALSE;
+ }
+
+ if ((self.items & self.weapon) && haveammo == TRUE)
+ {
+ PlayerSetCurrentAmmo ();
+ return;
+ }
+ }
+};
+
+//----------------------------------------------------------------------
// ImpulseCommands
//----------------------------------------------------------------------
void() ImpulseCommands =
{
- if (self.impulse >= 1 && self.impulse <= 8)
- W_ChangeWeapon ();
-
- if (self.impulse == 9)
- CheatCommand ();
- if (self.impulse == 10)
- CycleWeaponCommand ();
- if (self.impulse == 11)
- ServerflagsCommand ();
- if (self.impulse == 12)
- CycleWeaponReverseCommand ();
-
- if (self.impulse == 255)
- QuadCheat ();
-
- // dumptruck_ds version inspired by Copper
- if (self.impulse == 100)
- sprint (self, version);
-
- // if (self.impulse == 101) // debugging armor shards -- dumptruck_ds
+ switch (self.impulse)
+ {
+ case 1..8:
+ ChangeWeaponCommand ();
+ return;
+ case 9:
+ CheatCommand ();
+ break;
+ case 10:
+ CycleWeaponCommand ();
+ break;
+ case 11:
+ ServerflagsCommand ();
+ break;
+ case 12:
+ CycleWeaponReverseCommand ();
+ break;
+ case 100:
+ // dumptruck_ds version inspired by Copper
+ sprint (self, version);
+ break;
+ case 255:
+ QuadCheat ();
+ break;
+ default:
+ dprint (sprintf("ImpulseCommand: unknown impulse %g\n",
+ self.impulse));
+ break;
+ }
+
+ // debugging armor shards -- dumptruck_ds
+ // if (self.impulse == 101)
// dprint ("Armortype is");
// dprint (ftos(self.armortype));
// dprint ("\n");

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

Diff qc/client/levelparms.qc

diff --git a/qc/client/levelparms.qc b/qc/client/levelparms.qc
new file mode 100644
index 0000000..7ed4462
--- /dev/null
+++ b/qc/client/levelparms.qc
@@ -0,0 +1,88 @@
+//==============================================================================
+// client/levelparms.qc
+//==============================================================================
+
+//----------------------------------------------------------------------
+void() SetChangeParms =
+{
+ if (self.health <= 0)
+ {
+ SetNewParms ();
+ return;
+ }
+
+ // remove items
+ self.items = self.items - (self.items &
+ (IT_KEY1 | IT_KEY2 | IT_INVISIBILITY | IT_INVULNERABILITY
+ | IT_SUIT | IT_QUAD)
+ );
+
+ // cap super health
+ if (self.health > 100)
+ self.health = 100;
+ if (self.health < 50)
+ self.health = 50;
+ parm1 = self.items;
+ parm2 = self.health;
+ parm3 = self.armorvalue;
+ if (self.ammo_shells < 25)
+ parm4 = 25;
+ else
+ parm4 = self.ammo_shells;
+ parm5 = self.ammo_nails;
+ parm6 = self.ammo_rockets;
+ parm7 = self.ammo_cells;
+ parm8 = self.weapon;
+ parm9 = self.armortype * 100;
+};
+
+//----------------------------------------------------------------------
+void() SetNewParms =
+{
+ parm2 = 100; // self.health
+ parm3 = 0; // self.armorvalue
+ parm5 = 0; // self.ammo_nails
+ parm6 = 0; // self.ammo_rockets
+ parm7 = 0; // self.ammo_cells
+ parm9 = 0; // self.armortype * 100
+
+ // "reset_items 2" makes the player start with only the axe -- iw
+ if (world.reset_items == 2)
+ {
+ parm1 = IT_AXE; // self.items
+ parm4 = 0; // self.ammo_shells
+ parm8 = IT_AXE; // self.weapon
+ }
+ else
+ {
+ parm1 = IT_AXE | IT_SHOTGUN; // self.items
+ parm4 = 25; // self.ammo_shells
+ parm8 = IT_SHOTGUN; // self.weapon
+ }
+};
+
+//----------------------------------------------------------------------
+void() DecodeLevelParms =
+{
+ // Reset the player's inventory if they returned to the start map
+ // with a rune, or if the mapper set the "reset_items" field of
+ // worldspawn to a non-zero value. (The old "reset_items" check,
+ // which this replaces, had a comment from dumptruck_ds thanking
+ // Spike.) -- iw
+ if ((serverflags != 0 && world.model == "maps/start.bsp") ||
+ world.reset_items != 0)
+ {
+ SetNewParms ();
+ }
+
+ self.items = parm1;
+ self.health = parm2;
+ self.armorvalue = parm3;
+ self.ammo_shells = parm4;
+ self.ammo_nails = parm5;
+ self.ammo_rockets = parm6;
+ self.ammo_cells = parm7;
+ self.weapon = parm8;
+ self.armortype = parm9 * 0.01;
+};
+

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

Diff qc/client/maprules.qc

diff --git a/qc/client/maprules.qc b/qc/client/maprules.qc
new file mode 100644
index 0000000..40d3005
--- /dev/null
+++ b/qc/client/maprules.qc
@@ -0,0 +1,91 @@
+//==============================================================================
+// client/maprules.qc -- RULES
+//==============================================================================
+
+//----------------------------------------------------------------------
+// NextLevel -- go to the next level for deathmatch
+// only called if a time or frag limit has expired
+//----------------------------------------------------------------------
+void() NextLevel =
+{
+ local trigger_changelevel t_level;
+
+ if (mapname == "start")
+ {
+ if (!cvar ("registered"))
+ {
+ mapname = "e1m1";
+ }
+ else if (!(serverflags & 1))
+ {
+ mapname = "e1m1";
+ serverflags = serverflags | 1;
+ }
+ else if (!(serverflags & 2))
+ {
+ mapname = "e2m1";
+ serverflags = serverflags | 2;
+ }
+ else if (!(serverflags & 4))
+ {
+ mapname = "e3m1";
+ serverflags = serverflags | 4;
+ }
+ else if (!(serverflags & 8))
+ {
+ mapname = "e4m1";
+ serverflags = serverflags - 7;
+ }
+
+ t_level = spawn (trigger_changelevel, map:mapname);
+ }
+ else
+ {
+ // find a trigger changelevel
+ local entity e;
+ e = findfloat (world, classtype, CT_TRIGGER_CHANGELEVEL);
+ t_level = (trigger_changelevel)e;
+
+ // go back to start if no trigger_changelevel
+ if (!t_level)
+ t_level = spawn (trigger_changelevel, map:"start");
+ }
+
+ nextmap = t_level.map;
+ gameover = TRUE;
+
+ if (t_level.nextthink < time)
+ {
+ t_level.think = trigger_changelevel::changelevel_execute;
+ t_level.nextthink = time + 0.1;
+ }
+};
+
+//----------------------------------------------------------------------
+// CheckRules -- // Exit deathmatch games upon conditions
+//----------------------------------------------------------------------
+void() CheckRules =
+{
+ local float fraglimit, timelimit;
+
+ // someone else quit the game already
+ if (gameover)
+ return;
+
+ timelimit = cvar ("timelimit") * 60;
+ fraglimit = cvar ("fraglimit");
+
+ // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ if (deathmatch && timelimit && time >= timelimit)
+ {
+ NextLevel ();
+ return;
+ }
+
+ // 1998-07-27 Timelimit/Fraglimit fix by Maddes
+ if (deathmatch && fraglimit && self.frags >= fraglimit)
+ {
+ NextLevel ();
+ return;
+ }
+};

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

Diff qc/client/obituary.qc

diff --git a/qc/client/obituary.qc b/qc/client/obituary.qc
new file mode 100644
index 0000000..3a5ff7e
--- /dev/null
+++ b/qc/client/obituary.qc
@@ -0,0 +1,336 @@
+//==============================================================================
+// client/obituary.qc
+//==============================================================================
+
+//----------------------------------------------------------------------
+// ClientObituary -- called when a player dies
+//----------------------------------------------------------------------
+void(entity targ, entity inflictor, entity attacker) ClientObituary =
+{
+ local float rnum;
+ local string deathstring, deathstring2;
+
+ rnum = random ();
+ deathstring = deathstring2 = "";
+
+ // refactored to remove one level of indentation -- CEV
+ if (targ.classname != "player")
+ return;
+
+ if (attacker.classname == "teledeath")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("\n");
+
+ attacker.owner.frags = attacker.owner.frags + 1;
+ return;
+ }
+
+ if (attacker.classname == "teledeath2")
+ {
+ bprint ("Satan's power deflects ");
+ bprint (targ.netname);
+ bprint ("'s telefrag\n");
+
+ targ.frags = targ.frags - 1;
+ return;
+ }
+
+ // 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
+ // double 666 telefrag
+ // (can happen often in deathmatch 4 and levels with more
+ // than one pentagram)
+ if (attacker.classname == "teledeath3")
+ {
+ bprint (targ.netname);
+ bprint (" was telefragged by ");
+ bprint (attacker.owner.netname);
+ bprint ("'s Satan's power\n");
+ // 1998-07-26 only tfrag player on spot by Maddes start
+ // targ.frags = targ.frags - 1;
+ attacker.owner.frags = attacker.owner.frags + 1;
+ // 1998-07-26 only tfrag player on spot by Maddes end
+ return;
+ }
+
+ // 1998-07-26 Pentagram telefrag fix by Zoid/Maddes end
+ if (attacker.classname == "player")
+ {
+ if (targ == attacker)
+ {
+ // killed self
+ attacker.frags = attacker.frags - 1;
+ bprint (targ.netname);
+
+ if (targ.weapon == 64 &&
+ targ.waterlevel > WATERLEVEL_FEET)
+ {
+ bprint (" discharges into the water.\n");
+ return;
+ }
+ if (targ.weapon == IT_GRENADE_LAUNCHER)
+ bprint (" tries to put the pin back in\n");
+ else
+ bprint (" becomes bored with life\n");
+ return;
+ }
+ else if ((teamplay == 2) && (targ.team > 0) &&
+ (targ.team == attacker.team))
+ {
+ if (rnum < 0.25)
+ deathstring = " mows down a teammate\n";
+ else if (rnum < 0.50)
+ deathstring = " checks his glasses\n";
+ else if (rnum < 0.75)
+ deathstring = " gets a frag for the other "
+ "team\n";
+ else
+ deathstring = " loses another friend\n";
+ bprint (attacker.netname);
+ bprint (deathstring);
+ attacker.frags = attacker.frags - 1;
+ return;
+ }
+ else
+ {
+ attacker.frags = attacker.frags + 1;
+
+ rnum = attacker.weapon;
+ if (rnum == IT_AXE)
+ {
+ deathstring = " was ax-murdered by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_SHOTGUN)
+ {
+ deathstring = " chewed on ";
+ deathstring2 = "'s boomstick\n";
+ }
+ if (rnum == IT_SUPER_SHOTGUN)
+ {
+ deathstring = " ate 2 loads of ";
+ deathstring2 = "'s buckshot\n";
+ }
+ if (rnum == IT_NAILGUN)
+ {
+ deathstring = " was nailed by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_SUPER_NAILGUN)
+ {
+ deathstring = " was punctured by ";
+ deathstring2 = "\n";
+ }
+ if (rnum == IT_GRENADE_LAUNCHER)
+ {
+ deathstring = " eats ";
+ deathstring2 = "'s pineapple\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s grenade\n";
+ }
+ }
+ if (rnum == IT_ROCKET_LAUNCHER)
+ {
+ deathstring = " rides ";
+ deathstring2 = "'s rocket\n";
+ if (targ.health < -40)
+ {
+ deathstring = " was gibbed by ";
+ deathstring2 = "'s rocket\n" ;
+ }
+ }
+ if (rnum == IT_LIGHTNING)
+ {
+ deathstring = " accepts ";
+ if (attacker.waterlevel > WATERLEVEL_FEET)
+ deathstring2 = "'s discharge\n";
+ else
+ deathstring2 = "'s shaft\n";
+ }
+ bprint (targ.netname);
+ bprint (deathstring);
+ bprint (attacker.netname);
+ bprint (deathstring2);
+ }
+ return;
+ }
+ else
+ {
+ targ.frags = targ.frags - 1;
+ bprint (targ.netname);
+
+ // custom obituary messages
+ if (inflictor.deathtype != "")
+ {
+ bprint (" ");
+ bprint (inflictor.deathtype);
+ bprint ("\n");
+ return;
+ }
+ if (attacker.deathtype != "")
+ {
+ bprint (" ");
+ bprint (attacker.deathtype);
+ bprint ("\n");
+ return;
+ }
+
+ // killed by a monster?
+ // if (attacker.flags & FL_MONSTER)
+ if ((attacker.flags & FL_MONSTER) && (attacker.obit_name == ""))
+ {
+ if (attacker.classname == "monster_army")
+ bprint (" was shot by a Grunt\n");
+ if (attacker.classname == "monster_demon1")
+ bprint (" was eviscerated by a Fiend\n");
+ if (attacker.classname == "monster_dog")
+ bprint (" was mauled by a Rottweiler\n");
+ if (attacker.classname == "monster_dragon")
+ bprint (" was fried by a Dragon\n");
+ if (attacker.classname == "monster_enforcer")
+ bprint (" was blasted by an Enforcer\n");
+ if (attacker.classname == "monster_fish")
+ bprint (" was fed to the Rotfish\n");
+ if (attacker.classname == "monster_hell_knight")
+ bprint (" was slain by a Death Knight\n");
+ if (attacker.classname == "monster_knight")
+ bprint (" was slashed by a Knight\n");
+ if (attacker.classname == "monster_ogre")
+ bprint (" was destroyed by an Ogre\n");
+ if (attacker.classname == "monster_ogre_marksman")
+ // dumptruck_ds
+ bprint (" was felled by a Marksman\n");
+ if (attacker.classname == "monster_oldone")
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_oldone2")
+ // dumptruck_ds
+ bprint (" became one with Shub-Niggurath\n");
+ if (attacker.classname == "monster_boss2")
+ // dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_boss")
+ // dumptruck_ds
+ bprint (" was exploded by Chthon\n");
+ if (attacker.classname == "monster_shalrath")
+ bprint (" was exploded by a Vore\n");
+ if (attacker.classname == "monster_shambler")
+ bprint (" was smashed by a Shambler\n");
+ if (attacker.classname == "monster_vomit")
+ bprint (" was vomited on by a Vomitus\n");
+ if (attacker.classname == "monster_wizard")
+ bprint (" was scragged by a Scrag\n");
+ if (attacker.classname == "monster_zombie")
+ bprint (" joins the Zombies\n");
+
+ return;
+ }
+
+ // obits for custom monsters -- progs_dump -- dumptruck_ds
+ if (attacker.obit_name != "")
+ {
+ bprint (" was ");
+ if !(attacker.obit_method)
+ bprint ("killed");
+ else
+ // e.g. ripped apart
+ bprint (attacker.obit_method);
+ bprint (" by ");
+ // a bad monster
+ bprint (attacker.obit_name);
+ bprint ("\n");
+ return;
+ }
+
+ // tricks and traps
+ if (attacker.classname == "explo_box" ||
+ attacker.classname == "play_explosion")
+ {
+ bprint (" blew up\n");
+ return;
+ }
+ if (attacker.classname == "func_laser")
+ {
+ bprint (" discovered that lasers are hot\n");
+ return;
+ }
+ if ((attacker.solid == SOLID_BSP &&
+ attacker != world &&
+ attacker.classname != "togglewall") ||
+ (inflictor.classname == "func_movewall" &&
+ !(inflictor.spawnflags & MOVEWALL_TOUCH)))
+ {
+ bprint (" was squished\n");
+ return;
+ }
+ if (attacker.classname == "trap_shooter" ||
+ attacker.classname == "trap_spikeshooter" ||
+ attacker.classname == "trap_switched_shooter")
+ {
+ // bprint (" was spiked\n");
+ // changed for custom shooters -- dumptruck_ds
+ bprint (" was unlucky\n");
+ return;
+ }
+ if (attacker.classname == "ltrail_start" ||
+ attacker.classname == "ltrail_relay")
+ {
+ bprint (" had an electrifying experience\n");
+ return;
+ }
+ if (attacker.classname == "fireball")
+ {
+ bprint (" ate a lavaball\n");
+ return;
+ }
+ if (attacker.classname == "trigger_changelevel")
+ {
+ bprint (" tried to leave\n");
+ return;
+ }
+
+ // in-liquid deaths
+ if (targ.deathtype == "drowning")
+ {
+ if (random() < 0.5)
+ bprint (" sleeps with the fishes\n");
+ else
+ bprint (" sucks it down\n");
+ return;
+ }
+ if (targ.deathtype == "slime")
+ {
+ if (random() < 0.5)
+ bprint (" gulped a load of slime\n");
+ else
+ bprint (" can't exist on slime alone\n");
+ return;
+ }
+ if (targ.deathtype == "lava")
+ {
+ if (targ.health < -15)
+ {
+ bprint (" burst into flames\n");
+ return;
+ }
+ if (random() < 0.5)
+ bprint (" turned into hot slag\n");
+ else
+ bprint (" visits the Volcano God\n");
+ return;
+ }
+
+ // fell to their death?
+ if (targ.deathtype == "falling")
+ {
+ bprint (" fell to his death\n");
+ return;
+ }
+
+ // hell if I know; he's just dead!!!
+ bprint (" died\n");
+ }
+};

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

Diff qc/client/playerspawn.qc

diff --git a/qc/client/playerspawn.qc b/qc/client/playerspawn.qc
new file mode 100644
index 0000000..6536f6a
--- /dev/null
+++ b/qc/client/playerspawn.qc
@@ -0,0 +1,345 @@
+//==============================================================================
+// client/playerspawn.qc -- PLAYER GAME EDGE FUNCTIONS
+//==============================================================================
+
+// globals
+float modelindex_eyes, modelindex_player;
+
+// prototypes
+void() set_suicide_frame;
+void() DecodeLevelParms;
+void() PlayerDie;
+// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
+void() monster_touch;
+
+//----------------------------------------------------------------------
+// respawn -- called by ClientKill and DeadThink
+//----------------------------------------------------------------------
+void() respawn =
+{
+ if (coop)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // get the spawn parms as they were at level start
+ setspawnparms (self);
+ // respawn
+ PutClientInServer ();
+ }
+ else if (deathmatch)
+ {
+ // make a copy of the dead body for appearances sake
+ CopyToBodyQue (self);
+ // set default spawn parms
+ SetNewParms ();
+ // respawn
+ PutClientInServer ();
+ }
+ else
+ { // restart the entire server
+ localcmd ("restart\n");
+ }
+};
+
+//----------------------------------------------------------------------
+// ClientKill -- Player entered the suicide command
+//----------------------------------------------------------------------
+void() ClientKill =
+{
+ // 1998-07-27 Suicide during intermission fix by Zhenga start
+ // not allowed during intermission
+ if ((intermission_running) && ((coop) || (deathmatch)))
+ return;
+ // 1998-07-27 Suicide during intermission fix by Zhenga end
+ bprint (self.netname);
+ bprint (" suicides\n");
+ set_suicide_frame ();
+ self.modelindex = modelindex_player;
+ // extra penalty
+ self.frags = self.frags - 2;
+ respawn ();
+};
+
+//----------------------------------------------------------------------
+float(vector v) CheckSpawnPoint =
+{
+ return FALSE;
+};
+
+//----------------------------------------------------------------------
+// SelectSpawnPoint -- Returns the entity to spawn at
+//----------------------------------------------------------------------
+entity() SelectSpawnPoint =
+{
+ local entity spot, thing;
+ local float pcount;
+
+ // testinfo_player_start is only found in regioned levels
+ spot = find (world, classname, "testplayerstart");
+ if (spot)
+ return spot;
+
+ // choose a info_player_deathmatch point
+ if (coop)
+ {
+ lastspawn = find (lastspawn, classname, "info_player_coop");
+ if (lastspawn == world)
+ lastspawn = find (lastspawn, classname,
+ "info_player_start");
+ if (lastspawn != world)
+ return lastspawn;
+ }
+ else if (deathmatch)
+ {
+ spot = lastspawn;
+ // TODO CEV this loops infinitely if no info_player_deathmatch
+ while (1)
+ {
+ spot = find (spot, classname, "info_player_deathmatch");
+ if (spot != world)
+ {
+ if (spot == lastspawn)
+ return lastspawn;
+ pcount = 0;
+ thing = findradius (spot.origin, 32);
+ while (thing)
+ {
+ if (thing.classname == "player")
+ pcount = pcount + 1;
+ thing = thing.chain;
+ }
+ if (pcount == 0)
+ {
+ lastspawn = spot;
+ return spot;
+ }
+ }
+ }
+ }
+
+ if (serverflags)
+ {
+ // return with a rune to start
+ spot = find (world, classname, "info_player_start2");
+ if (spot)
+ return spot;
+ }
+
+ spot = find (world, classname, "info_player_start");
+ if (!spot)
+ error ("PutClientInServer: no info_player_start on level");
+
+ return spot;
+};
+
+//----------------------------------------------------------------------
+// SendPlayer -- transmit player updates from server to client -- CEV
+//----------------------------------------------------------------------
+float(entity to, float fl) SendPlayer =
+{
+ WriteByte (MSG_ENTITY, CT_PLAYER);
+ WriteByte (MSG_ENTITY, self.frame);
+ WriteCoord (MSG_ENTITY, self.origin_x);
+ WriteCoord (MSG_ENTITY, self.origin_y);
+ WriteCoord (MSG_ENTITY, self.origin_z);
+ WriteShort (MSG_ENTITY, self.angles_x * 32767 / 360);
+ WriteShort (MSG_ENTITY, self.angles_y * 32767 / 360);
+ WriteShort (MSG_ENTITY, self.angles_z * 32767 / 360);
+ WriteShort (MSG_ENTITY, self.velocity_x);
+ WriteShort (MSG_ENTITY, self.velocity_y);
+ WriteShort (MSG_ENTITY, self.velocity_z);
+ WriteFloat (MSG_ENTITY, self.flags);
+ WriteFloat (MSG_ENTITY, self.pmove_flags);
+ WriteFloat (MSG_ENTITY, self.doublejump_timer);
+ WriteFloat (MSG_ENTITY, self.groundboost_timer);
+ return TRUE;
+};
+
+//----------------------------------------------------------------------
+// PutClientInServer -- called each time a player is spawned
+//----------------------------------------------------------------------
+void() PutClientInServer =
+{
+ local entity spot;
+
+ spot = SelectSpawnPoint ();
+
+ self.classname = "player";
+ self.classtype = CT_PLAYER;
+ self.health = 100;
+ self.takedamage = DAMAGE_AIM;
+ self.solid = SOLID_SLIDEBOX;
+ // self.solid = SOLID_BBOX;
+ self.movetype = MOVETYPE_WALK;
+ self.show_hostile = 0;
+ self.max_health = 100;
+ self.flags = FL_CLIENT;
+ self.air_finished = time + 12;
+ // initial water damage
+ self.dmg = 2;
+ self.super_damage_finished = 0;
+ self.radsuit_finished = 0;
+ self.invisible_finished = 0;
+ self.invincible_finished = 0;
+ self.effects = 0;
+ self.invincible_time = 0;
+ self.deathtype = "";
+ self.gravity = 0;
+ self.wantedgravity = 0;
+ // support for item_key_custom -- iw
+ self.customkeys = 0;
+
+ // Setup cutscene stuff. Legacy code from Zerstorer. -- dumptruck_ds
+ self.script_count = 2;
+ self.script_delay = 1;
+ self.script_time = 0;
+
+ DecodeLevelParms ();
+ PlayerSetCurrentAmmo ();
+
+ self.attack_finished = time;
+ self.th_pain = player_pain;
+ self.th_die = PlayerDie;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix
+ // by Maddes/Kryten
+ self.touch = monster_touch;
+ self.deadflag = DEAD_NO;
+ // pausetime is set by teleporters to keep the player from moving
+ // for a while
+ self.pausetime = 0;
+
+ // spot = SelectSpawnPoint ();
+
+ self.origin = spot.origin + '0 0 1';
+ self.angles = spot.angles;
+ // turn this way immediately
+ self.fixangle = TRUE;
+
+ // fog control.
+ // Looks if there's any fog values set at the current spawn point.
+ // If not, looks for those in worldspawn instead
+ if (spot.fog_density)
+ fog_save (self, spot.fog_density, spot.fog_color);
+ else if (world.fog_density)
+ fog_save (self, world.fog_density, world.fog_color);
+
+ if (spot.skyfog_density)
+ skyfog_save (self, spot.skyfog_density);
+ else if (world.skyfog_density)
+ skyfog_save (self, world.skyfog_density);
+
+ // decreased on subsequent frames, used to start some fog-related stuff
+ cleanUpClientStuff = 2;
+
+ // oh, this is a hack!
+ setmodel (self, "progs/eyes.mdl");
+ modelindex_eyes = self.modelindex;
+
+ // Drake -- dumptruck_ds
+ setmodel (self, "progs/s_null.spr");
+ // Drake -- dumptruck_ds
+ // setmodel (self, "progs/null_256.spr");
+ mindex_inviso = self.modelindex;
+
+ setmodel (self, "progs/player.mdl");
+ modelindex_player = self.modelindex;
+
+ setsize (self, VEC_HULL_MIN, VEC_HULL_MAX);
+
+ self.view_ofs = '0 0 22';
+ // Mod - Xian (May.20.97)
+ // Bug where player would have velocity from their last kill
+ self.velocity = '0 0 0';
+ // 1998-07-21 Player moves after respawn fix by Xian
+
+ // TODO CEV
+ self.SendEntity = SendPlayer;
+ self.SendFlags = 0xffffff;
+
+ player_stand1 ();
+
+ if (deathmatch || coop)
+ {
+ makevectors (self.angles);
+ spawn_tfog (self.origin + v_forward*20);
+ }
+
+ spawn_tdeath (self.origin, self);
+};
+
+//======================================================================
+// Player spawnpoint entities
+//======================================================================
+
+/*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+The normal starting point for a level.
+*/
+void() info_player_start =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+};
+
+/*QUAKED info_player_start2 (1 0 0) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+Only used on start map for the return point from an episode.
+*/
+void() info_player_start2 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+};
+
+//----------------------------------------------------------------------
+// testplayerstart -- saved out by quaked in region mode
+//----------------------------------------------------------------------
+void() testplayerstart =
+{
+ // empty function
+};
+
+/*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for deathmatch games
+*/
+void() info_player_deathmatch =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+};
+
+/*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/player.mdl");
+}
+potential spawning position for coop games
+*/
+void() info_player_coop =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+};
+
+/*QUAKED info_monster_spawnpoint (1 0 1) (-16 -16 -24) (16 16 24) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+{
+model ("progs/teleport.mdl");
+}
+ spawning position for func_monster_spawner
+*/
+void() info_monster_spawnpoint =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+};

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

Diff qc/compat_quake3.qc

diff --git a/qc/compat_quake3.qc b/qc/compat_quake3.qc
index d437bf5..cd434d3 100644
--- a/qc/compat_quake3.qc
+++ b/qc/compat_quake3.qc
@@ -2,6 +2,7 @@
// Quake 3 compatibility entrypoints / functions
//==============================================================================

+// prototypes / foward declarations
void() item_armor1;
void() item_armor2;
void() item_armorInv;
@@ -12,7 +13,6 @@ void() item_rockets;
void() item_shells;
void() item_spikes;
void() weapon_supernailgun;
-void() info_teleport_destination;

//======================================================================
// Quake 3 armor item support -- CEV
@@ -47,7 +47,7 @@ void() spawnfunc_item_armor_body =

//======================================================================
// Quake 3 health item support -- CEV
-//----------------------------------------------------------------------
+//======================================================================

//----------------------------------------------------------------------
void() spawnfunc_item_health_mega =
@@ -66,6 +66,8 @@ void() spawnfunc_item_health_small =

//======================================================================
// Quake 3 ammo & weapons -- CEV
+//======================================================================
+
//----------------------------------------------------------------------
void() spawnfunc_ammo_cells =
{
@@ -110,6 +112,8 @@ void() weapon_plasmagun =

//======================================================================
// Quake 3 push target entities -- CEV
+//======================================================================
+
//----------------------------------------------------------------------
void() spawnfunc_target_push =
{
@@ -134,23 +138,10 @@ void() spawnfunc_target_position =

//======================================================================
// Quake 3 Teleporter targets -- CEV
-//----------------------------------------------------------------------
-void() spawnfunc_misc_teleporter_dest =
-{
- self.classname = "info_teleport_destination";
- info_teleport_destination ();
-};
+//======================================================================

-//----------------------------------------------------------------------
-void() spawnfunc_misc_teleporter_destination =
-{
- self.classname = "info_teleport_destination";
- info_teleport_destination ();
-};
+class misc_teleport_dest: info_teleport_destination {};
+class misc_teleporter_dest: info_teleport_destination {};
+class misc_teleporter_destination: info_teleport_destination {};
+class target_teleporter: info_teleport_destination {};

-//----------------------------------------------------------------------
-void() spawnfunc_target_teleporter =
-{
- self.classname = "info_teleport_destination";
- info_teleport_destination ();
-};

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

Diff qc/csqc/csqc_defsclient.qc

diff --git a/qc/csqc/csqc_defsclient.qc b/qc/csqc/csqc_defsclient.qc
index 0a11eb6..d6defb6 100644
--- a/qc/csqc/csqc_defsclient.qc
+++ b/qc/csqc/csqc_defsclient.qc
@@ -60,7 +60,7 @@ vector VEC_HULL2_MIN = '-32 -32 -24';
vector VEC_HULL2_MAX = '32 32 64';

entity viewentity; // camera -- CEV
-vector vieworg; // origin for viewentity -- CEV
+vector view_origin; // origin for viewentity -- CEV
vector view_angles; // +x=DOWN

entity player_local; // handle to the local player entity
@@ -191,8 +191,6 @@ enumflags {
RF_USEAXIS
};

-const float CLASS_PLAYER = 77; // TODO CEV
-
// edict.flags
const float FL_FLY = 1;
const float FL_SWIM = 2;
@@ -267,8 +265,14 @@ const float VF_ANGLES = 15;
const float VF_ANGLES_X = 16;
const float VF_ANGLES_Y = 17;
const float VF_ANGLES_Z = 18;
+const float VF_DRAWWORLD = 19;
const float VF_DRAWENGINESBAR = 20;
const float VF_DRAWCROSSHAIR = 21;
+const float VF_CL_VIEWANGLES = 33;
+const float VF_CL_VIEWANGLES_X = 34;
+const float VF_CL_VIEWANGLES_Y = 35;
+const float VF_CL_VIEWANGLES_Z = 36;
+const float VF_VIEWENTITY = 206;

//----------------------------------------------------------------------
// Supported Extension Constants
@@ -404,4 +408,3 @@ const float K_YBUTTON = 829;
const float K_LTRIGGER = 830;
const float K_RTRIGGER = 831;
const float K_PAUSE = 153;
-

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

Diff qc/csqc/csqc_entrypoints.qc

diff --git a/qc/csqc/csqc_entrypoints.qc b/qc/csqc/csqc_entrypoints.qc
index fcf11bc..cd40038 100644
--- a/qc/csqc/csqc_entrypoints.qc
+++ b/qc/csqc/csqc_entrypoints.qc
@@ -115,7 +115,8 @@ void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =

// TODO CEV
// addentities (MASK_ENGINE|MASK_VIEWMODEL);
- addentities (MASK_NORMAL | MASK_ENGINE | MASK_VIEWMODEL);
+ addentities (MASK_NORMAL | MASK_ENGINE);
+ setproperty (VF_DRAWWORLD, (float)1);
setproperty (VF_MIN, '0 0');
setproperty (VF_SIZE, ssize);

@@ -127,18 +128,26 @@ void(float vwidth, float vheight, float notmenu) CSQC_UpdateView =
if (self.entnum == player_localentnum)
{
// read our smoothed & predicted view origin
- setproperty (VF_ORIGIN, vieworg);
+ setproperty (VF_VIEWENTITY, player_localentnum);
+ setproperty (VF_ORIGIN, view_origin);
setproperty (VF_ANGLES, view_angles);
+ // setproperty (VF_ANGLES, player_local.angles);
+ setproperty (VF_CL_VIEWANGLES, view_angles);
+ // setproperty (VF_CL_VIEWANGLES, player_local.angles);

makevectors (view_angles);
- SetListener (vieworg, v_forward, v_right, v_up);
+ SetListener (view_origin, v_forward, v_right, v_up);

if (intermission)
+ {
// don't draw crosshair in intermission
setproperty (VF_DRAWCROSSHAIR, FALSE);
+ }
else
+ {
// draw view model when not in intermission
CSQC_DrawViewModel (viewentity);
+ }
}
else
{
@@ -222,17 +231,10 @@ void(float isnew) CSQC_Ent_Update =

switch (classtype)
{
- case CLASS_PLAYER:
+ case CT_PLAYER:
PlayerUpdate (isnew);
break;
}
-
- /*
- if (classtype == CLASS_PLAYER)
- {
- PlayerUpdate (isnew);
- }
- */
};

//----------------------------------------------------------------------

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

Diff qc/csqc/csqc_player.qc

diff --git a/qc/csqc/csqc_player.qc b/qc/csqc/csqc_player.qc
index ab3a326..f8cb736 100644
--- a/qc/csqc/csqc_player.qc
+++ b/qc/csqc/csqc_player.qc
@@ -102,6 +102,7 @@ void(entity ent, float endframe) PlayerRunMovement =

// add anything that was applied after (for low packet
// rate protocols)
+ // TODO CEV
input_angles = view_angles;
};

@@ -147,21 +148,21 @@ float() PlayerPreDraw =
else if (viewheight > 7)
viewheight = 7;

- vieworg = self.origin;
- vieworg_z += getstatf (STAT_VIEWHEIGHT) + viewheight;
- viewentity.origin = vieworg;
+ view_origin = self.origin;
+ view_origin_z += getstatf (STAT_VIEWHEIGHT) + viewheight;
+ viewentity.origin = view_origin;

// correct the view position to compensate for any errors,
// slowly over time, 0.1 seconds.
if (pmove_errortime - time > 0)
{
dprint ("PlayerPreDraw: pmove error\n");
- vieworg += (pmove_errortime - time) *
+ view_origin += (pmove_errortime - time) *
ERRORTIME * pmove_error;
}

if (player_steptime - time > 0)
- vieworg_z += (player_steptime - time) *
+ view_origin_z += (player_steptime - time) *
STEPTIME * player_step;

if (self.lerptime)
@@ -206,7 +207,7 @@ void() PlayerNew =
//======================================================================
// PlayerUpdate
//
-// called from CSQC_Ent_Update for CLASS_PLAYER entities
+// called from CSQC_Ent_Update for CT_PLAYER entities
//----------------------------------------------------------------------
void(float isnew) PlayerUpdate =
{

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

Diff qc/csqc/csqc_progs.src

diff --git a/qc/csqc/csqc_progs.src b/qc/csqc/csqc_progs.src
index 0df5b11..395faf9 100644
--- a/qc/csqc/csqc_progs.src
+++ b/qc/csqc/csqc_progs.src
@@ -12,13 +12,14 @@
../defs_globalvars.qc // globalvars_t
../defs_entvars.qc // entvars_t
csqc_defsbuiltins.qc // curated builtings list
-csqc_defsclient.qc
-csqc_defs.qc
+csqc_defsclient.qc // from Sock's AD CSQC
+csqc_defs.qc // from Sock's AD CSQC
+../defs_classtype.qc // global class list

//----------------------------------------------------------------------
// movement & client prediction, HUD, entity handling
//----------------------------------------------------------------------
-../pmove.qc // player movement code
+../player/pmove.qc // player movement code
csqc_player.qc // player handling
csqc_hudvanilla.qc // HUD
csqc_entrypoints.qc //

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

Diff qc/cutscene.qc

diff --git a/qc/cutscene.qc b/qc/cutscene.qc
index d113c71..fbecb3b 100644
--- a/qc/cutscene.qc
+++ b/qc/cutscene.qc
@@ -1,940 +1,855 @@
-// Heavily modified for Drake.
+//==============================================================================
+// cutscene.qc -- Heavily modified for Drake -- Drake version -- dumptruck_ds
+//==============================================================================

-// player_run prototype is in proto.qc.
void() DHM_CalcMoveDone;
void() move_camera;
-//- - - - - - - - - - - - - - - - - - -
-// This resets air capacity and drowning damage.
+
+//----------------------------------------------------------------------
+// more_air -- This resets air capacity and drowning damage.
+//----------------------------------------------------------------------
void(entity ent) more_air =
{
-//- - - - - - - - -
- ent.air_finished = time + 12;
- ent.dmg = 2; // initial water damage
+ ent.air_finished = time + 12;
+ // initial water damage
+ ent.dmg = 2;
};

-// ============================================ //
-// | Movie camera trigger - dhm | //
-// ============================================ //
-
+//======================================================================
+// Movie camera trigger - dhm
+//======================================================================

+//----------------------------------------------------------------------
+// spawn_dummy
// 'o' should be other, who in turn is the player who touched camera trigger.
+//----------------------------------------------------------------------
void(entity o) spawn_dummy =
{
-local entity s;
-
- s = spawn ();
-// s.origin = o.origin;
- s.velocity = o.velocity;
- s.angles = o.angles;
- s.health = o.health;
- s.weapon = o.weapon;
- s.classname = "dummy";
- s.movetype = MOVETYPE_NONE;
- s.solid = SOLID_NOT;
- setmodel (s, "progs/player.mdl"); // set temp player model in case camera can see -- dumptruck_ds
- if (s.weapon == IT_AXE)
- {
- s.frame = 0; // standing there with axe -- dumptruck_ds
- }
- else
- s.frame = 12; // standing there with gun -- dumptruck_ds
- s.weaponmodel = o.weaponmodel;
- s.flags = o.flags;
- s.effects = o.effects;
- s.items = o.items;
- s.enemy = o.enemy; // PM: o.enemy changed to camera later.
-
-// Save powerups
-// Pentagram
- if (o.invincible_finished)
- { s.invincible_finished = o.invincible_finished - time;
- if (o.invincible_time)
- s.invincible_time = o.invincible_time - time;
- }
- else
- s.invincible_finished = s.invincible_time = 0;
-// Ring of Shadows
- if (o.invisible_finished)
- { s.invisible_finished = o.invisible_finished - time;
- if (o.invisible_time)
- s.invisible_time = o.invisible_time - time;
- }
- else
- s.invisible_finished = s.invisible_time = 0;
-// Quad Damage
- if (o.super_damage_finished)
- { s.super_damage_finished = o.super_damage_finished - time;
- if (o.super_time)
- s.super_time = o.super_time - time;
- }
- else
- s.super_damage_finished = s.super_time = 0;
-// Biosuit
- if (o.radsuit_finished)
- { s.radsuit_finished = o.radsuit_finished - time;
- if (o.rad_time)
- s.rad_time = o.rad_time - time;
- }
- else
- s.radsuit_finished = s.rad_time = 0;
-// // Empathy Shields
-// if (o.thorns_finished)
-// { s.thorns_finished = o.thorns_finished - time;
-// if (o.thorns_time)
-// s.thorns_time = o.thorns_time - time;
-// }
-// else
-// s.thorns_finished = s.thorns_time = 0;
-// // Cross of Deflection
-// if (o.cross_finished)
-// { s.cross_finished = o.cross_finished - time;
-// if (o.cross_time)
-// s.cross_time = o.cross_time - time;
-// }
-// else
-// s.cross_finished = s.cross_time = 0;
-// // Dark Angel Wings
-// if (o.wing_finished)
-// { s.wing_finished = o.wing_finished - time;
-// if (o.wing_time)
-// s.wing_time = o.wing_time - time;
-// }
-// else
-// s.wing_finished = s.wing_time = 0;
-// // Amulet of Reflection
-// if (o.mirror_finished)
-// { s.mirror_finished = o.mirror_finished - time;
-// if (o.mirror_time)
-// s.mirror_time = o.mirror_time - time;
-// }
-// else
-// s.mirror_finished = s.mirror_time = 0;
-// // Tome of Power
-// if (o.tome_finished)
-// { s.tome_finished = o.tome_finished - time;
-// if (o.tome_time)
-// s.tome_time = o.tome_time - time;
-// }
-// else
-// s.tome_finished = s.tome_time = 0;
-
-// FIXME: Called during touch func, don't set directly?
- setorigin (s, o.origin);
-
-// PM: Link player to dummy, for now.
- if (o) //.classname == "player")
- if (!o.trigger_field)
- o.trigger_field = s;
+ local entity s;
+
+ s = spawn ();
+ // s.origin = o.origin;
+ s.velocity = o.velocity;
+ s.angles = o.angles;
+ s.health = o.health;
+ s.weapon = o.weapon;
+ s.classname = "dummy";
+ s.movetype = MOVETYPE_NONE;
+ s.solid = SOLID_NOT;
+ // set temp player model in case camera can see -- dumptruck_ds
+ setmodel (s, "progs/player.mdl");
+ if (s.weapon == IT_AXE)
+ {
+ // standing there with axe -- dumptruck_ds
+ s.frame = 0;
+ }
+ else
+ {
+ // standing there with gun -- dumptruck_ds
+ s.frame = 12;
+ }
+ s.weaponmodel = o.weaponmodel;
+ s.flags = o.flags;
+ s.effects = o.effects;
+ s.items = o.items;
+ // PM: o.enemy changed to camera later.
+ s.enemy = o.enemy;
+
+ // Save powerups; first Pentagram
+ if (o.invincible_finished)
+ {
+ s.invincible_finished = o.invincible_finished - time;
+ if (o.invincible_time)
+ s.invincible_time = o.invincible_time - time;
+ }
+ else
+ {
+ s.invincible_finished = s.invincible_time = 0;
+ }
+
+ // Ring of Shadows
+ if (o.invisible_finished)
+ {
+ s.invisible_finished = o.invisible_finished - time;
+ if (o.invisible_time)
+ s.invisible_time = o.invisible_time - time;
+ }
+ else
+ {
+ s.invisible_finished = s.invisible_time = 0;
+ }
+
+ // Quad Damage
+ if (o.super_damage_finished)
+ {
+ s.super_damage_finished = o.super_damage_finished - time;
+ if (o.super_time)
+ s.super_time = o.super_time - time;
+ }
+ else
+ {
+ s.super_damage_finished = s.super_time = 0;
+ }
+
+ // Biosuit
+ if (o.radsuit_finished)
+ {
+ s.radsuit_finished = o.radsuit_finished - time;
+ if (o.rad_time)
+ s.rad_time = o.rad_time - time;
+ }
+ else
+ {
+ s.radsuit_finished = s.rad_time = 0;
+ }
+
+ /*
+ // Empathy Shields
+ if (o.thorns_finished)
+ {
+ s.thorns_finished = o.thorns_finished - time;
+ if (o.thorns_time)
+ s.thorns_time = o.thorns_time - time;
+ }
+ else
+ {
+ s.thorns_finished = s.thorns_time = 0;
+ }
+
+ // Cross of Deflection
+ if (o.cross_finished)
+ {
+ s.cross_finished = o.cross_finished - time;
+ if (o.cross_time)
+ s.cross_time = o.cross_time - time;
+ }
+ else
+ {
+ s.cross_finished = s.cross_time = 0;
+ }
+
+ // Dark Angel Wings
+ if (o.wing_finished)
+ {
+ s.wing_finished = o.wing_finished - time;
+ if (o.wing_time)
+ s.wing_time = o.wing_time - time;
+ }
+ else
+ {
+ s.wing_finished = s.wing_time = 0;
+ }
+
+ // Amulet of Reflection
+ if (o.mirror_finished)
+ {
+ s.mirror_finished = o.mirror_finished - time;
+ if (o.mirror_time)
+ s.mirror_time = o.mirror_time - time;
+ }
+ else
+ {
+ s.mirror_finished = s.mirror_time = 0;
+ }
+
+ // Tome of Power
+ if (o.tome_finished)
+ {
+ s.tome_finished = o.tome_finished - time;
+ if (o.tome_time)
+ s.tome_time = o.tome_time - time;
+ }
+ else
+ {
+ s.tome_finished = s.tome_time = 0;
+ }
+ */
+
+ // FIXME: Called during touch func, don't set directly?
+ setorigin (s, o.origin);
+
+ // PM: Link player to dummy, for now.
+ // if (o.classname == "player")
+ if (o)
+ if (!o.trigger_field)
+ o.trigger_field = s;
};

-// PM: Removed 'name_player'; no longer needed.
+//======================================================================
+// PM: Removed 'name_player'; no longer needed.
+//======================================================================

+//----------------------------------------------------------------------
void() go_back =
{
-local entity t, c, cvars, old;
-local string val;
-
- t = find (world, classname, "dummy");
- if (!t)
- objerror ("couldn't find dummy");
- t.solid = SOLID_NOT; // So player won't bounce back.
- setmodel (t, ""); // remove temp player model upon return -- dumptruck_ds
-
- c = find (world, classname, "camera");
- if (!c)
- objerror ("couldn't find camera");
-
- c.oldorigin = t.origin; // So player won't bounce back to cam.
-
-// FIXME: Check the new vars.
- setorigin (c, t.origin);
- c.velocity = t.velocity;
- c.view_ofs = '0 0 22'; // PM: Morph should take care of itself.
- c.angles_x = t.angles_x;
- c.angles_y = t.angles_y;
- c.angles_z = 0;
- c.health = t.health;
- c.weapon = t.weapon;
- c.weaponframe = 0;
- c.weaponmodel = t.weaponmodel;
- c.flags = t.flags;
- c.effects = t.effects;
- c.items = t.items;
- c.enemy = t.enemy; // PM: Restore client's original enemy.
-
-// Restore powerups
- if (t.invincible_finished)
- { c.invincible_finished = time + t.invincible_finished;
- if (t.invincible_time)
- c.invincible_time = time + t.invincible_time;
- }
- if (t.invisible_finished)
- { c.invisible_finished = time + t.invisible_finished;
- if (t.invisible_time)
- c.invisible_time = time + t.invisible_time;
- }
- if (t.super_damage_finished)
- { c.super_damage_finished = time + t.super_damage_finished;
- if (t.super_time)
- c.super_time = time + t.super_time;
- }
- if (t.radsuit_finished)
- { c.radsuit_finished = time + t.radsuit_finished;
- if (t.rad_time)
- c.rad_time = time + t.rad_time;
- }
- // if (t.thorns_finished)
- // { c.thorns_finished = time + t.thorns_finished;
- // if (t.thorns_time)
- // c.thorns_time = time + t.thorns_time;
- // }
- // if (t.cross_finished)
- // { c.cross_finished = time + t.cross_finished;
- // if (t.cross_time)
- // c.cross_time = time + t.cross_time;
- // }
- // if (t.wing_finished)
- // { c.wing_finished = time + t.wing_finished;
- // if (t.wing_time)
- // c.wing_time = time + t.wing_time;
- // }
- // if (t.mirror_finished)
- // { c.mirror_finished = time + t.mirror_finished;
- // if (t.mirror_time)
- // c.mirror_time = time + t.mirror_time;
- // }
- // if (t.tome_finished)
- // { c.tome_finished = time + t.tome_finished;
- // if (t.tome_time)
- // c.tome_time = time + t.tome_time;
- // }
-
- c.fixangle = 1; // turn this way immediately
- c.takedamage = DAMAGE_AIM;
- c.solid = SOLID_SLIDEBOX;
- c.movetype = MOVETYPE_WALK;
- c.nextthink = time;
- c.think = player_run; // PM: Reset player anim frames.
- more_air (c); // No gasping from you!
-
- // c.xfl = c.xfl | XFL_ITEMS; // Restore pickup again. Drake -- dumptruck_ds
-
-// Yes, you CAN change the classname here since the 'find' command already
-// found the camera. It is best to change the classname back to player now.
- c.classname = "player";
- cutscene = 0; // Cutscene OFF
- stuffcmd (c, "-forward\n");
- stuffcmd (c, "-strafe\n");
-
-// Look for any CVARSET entities to restore old cvars that
-// were changed for the cut-scene
- if (c.ideal_yaw == -1)
- {
- cvars = find(world, classname, "cvar_done");
- while (cvars) // != world)
- {
- if (!cvars.message)
- cvars.message = cvars.model;
- cvar_set (cvars.netname, cvars.script);
- old = cvars;
- cvars = find (cvars, classname, "cvar_done");
- remove (old);
- }
- c.ideal_yaw = 0;
- }
-
- val = ftos (c.cnt);
- cvar_set ("viewsize", val); //restore old viewsize
-// stuffcmd (c, "sizedown\nsizeup\n"); //hack-fix for GLquake
-
- t.nextthink = time + 0.1;
- t.think = SUB_Remove;
- remove (self);
+ local entity t, c, cvars, old;
+ local string val;
+
+ t = find (world, classname, "dummy");
+ if (!t)
+ objerror ("couldn't find dummy");
+ // So player won't bounce back.
+ t.solid = SOLID_NOT;
+ // remove temp player model upon return -- dumptruck_ds
+ setmodel (t, "");
+
+ c = find (world, classname, "camera");
+ if (!c)
+ objerror ("couldn't find camera");
+
+ // So player won't bounce back to cam.
+ c.oldorigin = t.origin;
+
+ // FIXME: Check the new vars.
+ setorigin (c, t.origin);
+ c.velocity = t.velocity;
+ // PM: Morph should take care of itself.
+ c.view_ofs = '0 0 22';
+ c.angles_x = t.angles_x;
+ c.angles_y = t.angles_y;
+ c.angles_z = 0;
+ c.health = t.health;
+ c.weapon = t.weapon;
+ c.weaponframe = 0;
+ c.weaponmodel = t.weaponmodel;
+ c.flags = t.flags;
+ c.effects = t.effects;
+ c.items = t.items;
+ // PM: Restore client's original enemy.
+ c.enemy = t.enemy;
+
+ // Restore powerups
+ if (t.invincible_finished)
+ {
+ c.invincible_finished = time + t.invincible_finished;
+ if (t.invincible_time)
+ c.invincible_time = time + t.invincible_time;
+ }
+
+ if (t.invisible_finished)
+ {
+ c.invisible_finished = time + t.invisible_finished;
+ if (t.invisible_time)
+ c.invisible_time = time + t.invisible_time;
+ }
+
+ if (t.super_damage_finished)
+ {
+ c.super_damage_finished = time + t.super_damage_finished;
+ if (t.super_time)
+ c.super_time = time + t.super_time;
+ }
+
+ if (t.radsuit_finished)
+ {
+ c.radsuit_finished = time + t.radsuit_finished;
+ if (t.rad_time)
+ c.rad_time = time + t.rad_time;
+ }
+
+ /*
+ if (t.thorns_finished)
+ {
+ c.thorns_finished = time + t.thorns_finished;
+ if (t.thorns_time)
+ c.thorns_time = time + t.thorns_time;
+ }
+
+ if (t.cross_finished)
+ {
+ c.cross_finished = time + t.cross_finished;
+ if (t.cross_time)
+ c.cross_time = time + t.cross_time;
+ }
+
+ if (t.wing_finished)
+ {
+ c.wing_finished = time + t.wing_finished;
+ if (t.wing_time)
+ c.wing_time = time + t.wing_time;
+ }
+
+ if (t.mirror_finished)
+ {
+ c.mirror_finished = time + t.mirror_finished;
+ if (t.mirror_time)
+ c.mirror_time = time + t.mirror_time;
+ }
+
+ if (t.tome_finished)
+ {
+ c.tome_finished = time + t.tome_finished;
+ if (t.tome_time)
+ c.tome_time = time + t.tome_time;
+ }
+ */
+
+ // turn this way immediately
+ c.fixangle = 1;
+ c.takedamage = DAMAGE_AIM;
+ c.solid = SOLID_SLIDEBOX;
+ c.movetype = MOVETYPE_WALK;
+ c.nextthink = time;
+ // PM: Reset player anim frames.
+ c.think = player_run;
+ // No gasping from you!
+ more_air (c);
+
+ // Restore pickup again. Drake -- dumptruck_ds
+ // c.xfl = c.xfl | XFL_ITEMS;
+
+ // Yes, you CAN change the classname here since the 'find' command
+ // already found the camera. It is best to change the classname back
+ // to player now.
+ c.classname = "player";
+ // Cutscene OFF
+ cutscene = 0;
+ stuffcmd (c, "-forward\n");
+ stuffcmd (c, "-strafe\n");
+
+ // Look for any CVARSET entities to restore old cvars that
+ // were changed for the cut-scene
+ if (c.ideal_yaw == -1)
+ {
+ cvars = find(world, classname, "cvar_done");
+ while (cvars) // != world)
+ {
+ if (!cvars.message)
+ cvars.message = cvars.model;
+ cvar_set (cvars.netname, cvars.script);
+ old = cvars;
+ cvars = find (cvars, classname, "cvar_done");
+ remove (old);
+ }
+ c.ideal_yaw = 0;
+ }
+
+ val = ftos (c.cnt);
+ // restore old viewsize
+ cvar_set ("viewsize", val);
+ // hack-fix for GLquake
+ // stuffcmd (c, "sizedown\nsizeup\n");
+
+ t.nextthink = time + 0.1;
+ t.think = SUB_Remove;
+ remove (self);
};

-//===============
+//----------------------------------------------------------------------
// This routine short-circuits player turning and movement while in camera
// mode. self.oldorigin is used as self.angles, and self.mangle is used as
// self.velocity. This allows me to compute these figures in code, and
// overwrite what the game thinks they should be. Called from 'client.qc'.
-//===============
+//----------------------------------------------------------------------
void() look_ahead =
{
-// PM: Vision style cam sets angles to mangle and velocity to zeroes.
-// The camera in vision mode cutscenes cannot move.
-// if (vision)
-// {
-// self.angles = self.enemy.mangle;
-// self.fixangle = 1;
-// // self.nextthink removed since it's done in PlayerPreThink.
-// return;
-// }
-
-// PM: Using Zerstorer style cutscene code...
- self.angles = self.oldorigin;
- self.velocity = self.mangle;
- self.fixangle = 1;
- cvar_set ("viewsize", "120"); //keep screen maximized
-
- if (self.delay == 0)
- {
- local vector looky;
-
- looky_x = self.movedir_x - self.origin_x;
- looky_y = self.movedir_y - self.origin_y;
- looky_z = self.origin_z - self.movedir_z;
- self.oldorigin = vectoangles (looky);
- }
+ // PM: Vision style cam sets angles to mangle and velocity to zeroes.
+ // The camera in vision mode cutscenes cannot move.
+ /*
+ if (vision)
+ {
+ self.angles = self.enemy.mangle;
+ self.fixangle = 1;
+ self.nextthink removed since it's done in PlayerPreThink.
+ return;
+ }
+ */
+
+ // PM: Using Zerstorer style cutscene code...
+ self.angles = self.oldorigin;
+ self.velocity = self.mangle;
+ self.fixangle = 1;
+ // keep screen maximized
+ cvar_set ("viewsize", "120");
+
+ if (self.delay == 0)
+ {
+ local vector looky;
+
+ looky_x = self.movedir_x - self.origin_x;
+ looky_y = self.movedir_y - self.origin_y;
+ looky_z = self.origin_z - self.movedir_z;
+ self.oldorigin = vectoangles (looky);
+ }
};

-// This is a modified SUB_CalcMove routine.
+//----------------------------------------------------------------------
+// DHM_CalcMove -- This is a modified SUB_CalcMove routine.
+//----------------------------------------------------------------------
void(vector tdest, float tspeed, entity cam) DHM_CalcMove =
{
-local vector vdestdelta;
-local float len, traveltime;
+ local vector vdestdelta;
+ local float len, traveltime;

- self.finaldest = tdest;
- self.think = DHM_CalcMoveDone;
+ self.finaldest = tdest;
+ self.think = DHM_CalcMoveDone;

- if (tdest == cam.origin)
- {
- cam.velocity = cam.mangle = '0 0 0';
- self.nextthink = time + 0.01;
- return;
- }
+ if (tdest == cam.origin)
+ {
+ cam.velocity = cam.mangle = '0 0 0';
+ self.nextthink = time + 0.01;
+ return;
+ }

-// set destdelta to the vector needed to move
- vdestdelta = tdest - cam.origin;
+ // set destdelta to the vector needed to move
+ vdestdelta = tdest - cam.origin;

-// calculate length of vector
- len = vlen (vdestdelta);
+ // calculate length of vector
+ len = vlen (vdestdelta);

-// divide by speed to get time to reach dest
- traveltime = len / tspeed;
+ // divide by speed to get time to reach dest
+ traveltime = len / tspeed;

- if (traveltime < 0.1)
- {
- cam.velocity = cam.mangle = '0 0 0';
- self.nextthink = time + 0.01;
- return;
- }
+ if (traveltime < 0.1)
+ {
+ cam.velocity = cam.mangle = '0 0 0';
+ self.nextthink = time + 0.01;
+ return;
+ }

-// set nextthink to trigger a think when dest is reached
- self.nextthink = time + traveltime;
+ // set nextthink to trigger a think when dest is reached
+ self.nextthink = time + traveltime;

-// scale the destdelta vector by the time spent traveling to get velocity
- cam.velocity = cam.mangle = vdestdelta * (1/traveltime);
+ // scale the destdelta vector by the time spent traveling to get vel
+ cam.velocity = cam.mangle = vdestdelta * (1 / traveltime);
};

-//- - - - - - - - -
-// Zerstorer-only cutscene code.
+//----------------------------------------------------------------------
+// wait_camera -- Zerstorer-only cutscene code.
+//----------------------------------------------------------------------
void() wait_camera =
{
- if (!self.wait)
- {move_camera (); return;}
-
- self.nextthink = time + self.wait;
- self.think = move_camera;
+ if (!self.wait)
+ {
+ move_camera ();
+ return;
+ }
+
+ self.nextthink = time + self.wait;
+ self.think = move_camera;
};

-//============
-// After moving, set origin to exact final destination
-//============
+//----------------------------------------------------------------------
+// DHM_CalcMoveDone -- After moving, set origin to exact final destination
+//----------------------------------------------------------------------
void() DHM_CalcMoveDone =
{
- if (!cutscene) // Old check: if (self.enemy.classname != "camera")
- {remove (self); return;}
-
- setorigin(self.enemy, self.finaldest);
- self.enemy.velocity = self.enemy.mangle = '0 0 0';
-
- if (self.cnt == -1)
- {remove (self); return;}
-
- self.nextthink = time + 0.01;
- self.think = wait_camera;
+ // Old check: if (self.enemy.classname != "camera")
+ if (!cutscene)
+ {
+ remove (self);
+ return;
+ }
+
+ setorigin (self.enemy, self.finaldest);
+ self.enemy.velocity = self.enemy.mangle = '0 0 0';
+
+ if (self.cnt == -1)
+ {
+ remove (self);
+ return;
+ }
+
+ self.nextthink = time + 0.01;
+ self.think = wait_camera;
};

+//----------------------------------------------------------------------
void() move_camera =
{
-local entity cpt, fpt;
-local vector looky;
-
- if (!cutscene) // Old check: if (self.enemy.classname != "camera")
- {remove (self); return;}
-
- cpt = find (world, targetname, self.target);
- if (!cpt.target) //if this is the end of the line, stop camera
- {
- self.think = SUB_Null;
- self.enemy.velocity = '0 0 0';
- self.enemy.mangle = '0 0 0'; //mangle == velocity in cut-scene
- DHM_CalcMoveDone();
- self.cnt = -1; // remove control entity in DHM_CalcMoveDone
- //return;
- }
- if (cpt.focal_point != __NULL__ && cpt.focal_point != "")
- {
- // is there a new focal point?
- fpt = find (world, targetname, cpt.focal_point);
- if (!fpt)
- objerror("Couldn't find new focal point!");
-
- self.enemy.movedir = fpt.origin;
- looky_x = self.enemy.movedir_x - self.enemy.origin_x;
- looky_y = self.enemy.movedir_y - self.enemy.origin_y;
- looky_z = self.enemy.origin_z - self.enemy.movedir_z;
- self.enemy.oldorigin = vectoangles (looky);
- self.enemy.angles = self.enemy.oldorigin; //oldorigin == angles in CS
- }
-// Check for auto-focus or still camera angle
- if (cpt.delay)
- self.enemy.delay = cpt.delay;
- else
- self.enemy.delay = 0;
-
- self.target = cpt.target;
- self.wait = cpt.wait;
- if(cpt.speed)
- self.speed = cpt.speed;
- DHM_CalcMove (cpt.origin, self.speed, self.enemy);
+ local entity cpt, fpt;
+ local vector looky;
+
+ // Old check: if (self.enemy.classname != "camera")
+ if (!cutscene)
+ {
+ remove (self);
+ return;
+ }
+
+ // if this is the end of the line, stop camera
+ cpt = find (world, targetname, self.target);
+ if (!cpt.target)
+ {
+ self.think = SUB_Null;
+ self.enemy.velocity = '0 0 0';
+ // mangle == velocity in cut-scene
+ self.enemy.mangle = '0 0 0';
+ DHM_CalcMoveDone ();
+ // remove control entity in DHM_CalcMoveDone
+ self.cnt = -1;
+ // return;
+ }
+ if (cpt.focal_point != __NULL__ && cpt.focal_point != "")
+ {
+ // is there a new focal point?
+ fpt = find (world, targetname, cpt.focal_point);
+ if (!fpt)
+ objerror ("Couldn't find new focal point!");
+
+ self.enemy.movedir = fpt.origin;
+ looky_x = self.enemy.movedir_x - self.enemy.origin_x;
+ looky_y = self.enemy.movedir_y - self.enemy.origin_y;
+ looky_z = self.enemy.origin_z - self.enemy.movedir_z;
+ self.enemy.oldorigin = vectoangles (looky);
+ // oldorigin == angles in CS
+ self.enemy.angles = self.enemy.oldorigin;
+ }
+
+ // Check for auto-focus or still camera angle
+ if (cpt.delay)
+ self.enemy.delay = cpt.delay;
+ else
+ self.enemy.delay = 0;
+
+ self.target = cpt.target;
+ self.wait = cpt.wait;
+ if (cpt.speed)
+ self.speed = cpt.speed;
+ DHM_CalcMove (cpt.origin, self.speed, self.enemy);
};
-//- - - - - - - - -

+//----------------------------------------------------------------------
void() go_camera =
{
-local vector looky;
-
- cutscene = 1; // Cutscene ON.
-
-// Don't let player-turned-camera pick up items.
- // self.xfl = self.xfl - (self.xfl & XFL_ITEMS);
-
-// Change the player into a camera
-// PM: Ok, you win! Too much stuff checks for 'player', so use 'camera'
-// to be safe. Just make sure alignment stuff doesn't break, namely
-// friendly monsters getting mad at a player when they shouldn't.
- self.classname = "camera";
- self.velocity = '0 0 0';
- self.view_ofs = '0 0 0';
- // PM: Change the modelindex to a non-zero number that points to an
- // invisible model so that the camera entity is invisible if seen
- // because of reflective textures or builtin chasecam (chase_active 1).
- // Requires my custom invisible model (which is a sprite).
- self.modelindex = mindex_inviso;
- // Turn off glowing effects.
- self.effects = 0;
- self.items = 0;
- self.weaponmodel = ""; // Remove weapon from the screen.
-//- - - - - - - - - - - - - - - - - - -
-// if (vision)
-// {
-// self.angles = self.enemy.mangle;
-// self.fixangle = 1;
-// self.movetype = MOVETYPE_NONE;
-// self.takedamage = DAMAGE_NO;
-// self.solid = SOLID_NOT;
-// self.weaponmodel= "";
-
- // Removed thinking since it's done by PlayerPreThink->Cutscene_Think.
-// }
-//- - - - - - - - - - - - - - - - - - -
-// else // Default to Zerstorer style cutscene.
- {
- looky_x = self.movedir_x - self.enemy.origin_x;
- looky_y = self.movedir_y - self.enemy.origin_y;
- looky_z = self.enemy.origin_z - self.movedir_z;
- self.oldorigin = vectoangles (looky);
- self.angles = self.oldorigin; //oldorigin == angles in CS
-
- // Check if camera is auto-focus or not
- if (self.enemy.delay)
- self.delay = self.enemy.delay;
- else
- self.delay = 0;
-
- self.velocity = self.mangle = '0 0 0';
-
- self.dmg = 0; // PM: Do we need this?
- self.fixangle = 1; // turn this way immediately
- self.movetype = MOVETYPE_NOCLIP;
- self.takedamage = DAMAGE_NO;
- // PM: Solid cannot be 0 or else camera can't trigger stuff by touch.
-
- // Spawn a control function to handle moving the camera
- if (self.enemy.target != __NULL__ && self.enemy.target != "")
- {
- local entity control;
-
- control = spawn();
- control.classname = "camcontrol";
- control.enemy = self;
- control.target = self.enemy.target;
- control.speed = self.enemy.speed;
- control.nextthink = time + self.enemy.wait + 0.05;
- control.think = move_camera;
- }
- }
-
-// Setting script_count to 0 is what triggers the script to play,
-// It will then play the script number.
- if (!self.script)
- dprint ("trigger_camera needs a script number!");
- self.script_count = 0;
-
- self.cnt = cvar("viewsize");
- cvar_set ("viewsize", "120"); //Full screen
- // PM: Vision sets 'v_idlescale' for swaying screen. Not in Drake!
- stuffcmd (self, "sizedown\nsizeup\n"); //hack-fix for GLquake
- stuffcmd (self, "+strafe\n");
-
- setorigin (self, self.enemy.origin);
-
-//- - - - - - - - -
-// PM: Space invasion prevention.
-// Make the dummy solid to prevent monsters or other junk from occupying
-// the space where the player stood before the cutscene started.
-// After all, the player will be placed back when the cutscene ends,
-// and we don't want him stuck inside a monster or something.
-//
-// We need to wait until after the player becomes the camera, before we can
-// make the dummy solid. If we make the dummy solid as it spawned, the
-// player could get stuck inside the dummy (instead of moving) between
-// trigger activation and transformation to camera.
-//
-// In Vision code, player becomes camera a frame or so after trigger
-// activation. In Zer code, player becomes camera at the same time
-// the trigger activates.
-//
-// Note: If you still have trouble getting a Vision cutscene to work in a
-// certain level, move the following code to the top of 'look_ahead'.
-// Doing so would be less than ideal since the check would get called every
-// frame during the cutscene, instead of just once here.
-// The only level that still has problems with dummy made solid now
-// is 'vision.bsp', which has its own pak. Tronyn's maps, the levels
-// that really matter, have no problems.
-//- - - - - - - - -
-// 'self' is the player-turned-camera entity.
- // '!self.trigger_field' is the world, and its classname is worldspawn.
- if (self.trigger_field.classname == "dummy")
- {
- self.trigger_field.solid = SOLID_BBOX;
- setsize (self.trigger_field, self.mins, self.maxs);
-
- self.trigger_field = world; // Unlink now that it's done.
- }
-//- - - - - - - - -
-};
-
-// PM: Called from either touch or use.
-void(entity who) camera_activate =
-{
-// only activate for player, 1st time touched
- if (who.health <= 0)
- return;
- if (who.deadflag) // In case of Alien Quake facehugger kill.
- return;
- if (who.classname != "player")
- return;
-
-// You can't touch/use this again.
- self.touch = self.use = SUB_Null;
-
-// If player is on ground, take him off ground so no one gets confused
- who.flags = who.flags - (who.flags & FL_ONGROUND);
-
-// put a dummy where the player was
- spawn_dummy (who);
-
-// find camera
- local entity t;
-
- t = find (world, targetname, self.target);
-// if (vision)
-// {
-// if (!t)
-// objerror ("couldn't find target");
-// }
-// else
- {
- local entity fpt;
-
- while ((t != world) && (t.classname != "info_movie_camera"))
- t = find (t, targetname, self.target);
- if (!t)
- objerror ("couldn't find target");
-
- // find focal point
- fpt = find (world, targetname, self.focal_point);
- if (!fpt)
- objerror ("You must have a focal point!\n");
- else
- who.movedir = fpt.origin; //movedir used to calc focal dir
- }
-
-// Go to the camera - not in this function, because touch functions are
-// called while looping through c code, and you don't want to move the
-// player, or something like that?
- who.enemy = t; //save camera position, etc.
- who.script = self.script; //save script number
- who.script_delay = self.script_delay; //save delay for page 1
-
-// if (vision)
-// { // PM: Don't try instant start because that breaks soeexit.bsp.
-// who.nextthink = time + 0.05;
-// who.think = go_camera;
-// }
-// else
- SUB_Think (who, go_camera);
-
- activator = self;
- SUB_UseTargets ();
-
-//Remove the trigger_camera from level
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
-};
-
-void() camera_touch =
-{
- if (self.targetname != __NULL__ && self.targetname != "")
- if (self.nextthink < time)
- return;
- if (self.cnt == -1)
- return;
- camera_activate (other);
+ local vector looky;
+
+ // Cutscene ON.
+ cutscene = 1;
+
+ // Don't let player-turned-camera pick up items.
+ // self.xfl = self.xfl - (self.xfl & XFL_ITEMS);
+
+ // Change the player into a camera
+ // PM: Ok, you win! Too much stuff checks for 'player', so use
+ // 'camera' to be safe. Just make sure alignment stuff doesn't
+ // break, namely friendly monsters getting mad at a player when
+ // they shouldn't.
+ self.classname = "camera";
+ self.velocity = '0 0 0';
+ self.view_ofs = '0 0 0';
+ // PM: Change the modelindex to a non-zero number that points to an
+ // invisible model so that the camera entity is invisible if seen
+ // because of reflective textures or builtin chasecam (chase_active 1).
+ // Requires my custom invisible model (which is a sprite).
+ self.modelindex = mindex_inviso;
+ // Turn off glowing effects.
+ self.effects = 0;
+ self.items = 0;
+ // Remove weapon from the screen.
+ self.weaponmodel = "";
+
+ /*
+ if (vision)
+ {
+ self.angles = self.enemy.mangle;
+ self.fixangle = 1;
+ self.movetype = MOVETYPE_NONE;
+ self.takedamage = DAMAGE_NO;
+ self.solid = SOLID_NOT;
+ self.weaponmodel = "";
+
+ Removed thinking since it's done by
+ PlayerPreThink->Cutscene_Think.
+ }
+ else
+ {
+ */
+ // Default to Zerstorer style cutscene.
+ looky_x = self.movedir_x - self.enemy.origin_x;
+ looky_y = self.movedir_y - self.enemy.origin_y;
+ looky_z = self.enemy.origin_z - self.movedir_z;
+ self.oldorigin = vectoangles (looky);
+ // oldorigin == angles in CS
+ self.angles = self.oldorigin;
+
+ // Check if camera is auto-focus or not
+ if (self.enemy.delay)
+ self.delay = self.enemy.delay;
+ else
+ self.delay = 0;
+
+ self.velocity = self.mangle = '0 0 0';
+
+ // PM: Do we need this?
+ self.dmg = 0;
+ // turn this way immediately
+ self.fixangle = 1;
+ self.movetype = MOVETYPE_NOCLIP;
+ self.takedamage = DAMAGE_NO;
+ // PM: Solid cannot be 0 or else camera can't trigger
+ // stuff by touch.
+
+ // Spawn a control function to handle moving the camera
+ if (self.enemy.target != __NULL__ && self.enemy.target != "")
+ {
+ local entity control;
+
+ control = spawn ();
+ control.classname = "camcontrol";
+ control.enemy = self;
+ control.target = self.enemy.target;
+ control.speed = self.enemy.speed;
+ control.nextthink = time + self.enemy.wait + 0.05;
+ control.think = move_camera;
+ }
+ /*
+ }
+ */
+
+ // Setting script_count to 0 is what triggers the script to play,
+ // It will then play the script number.
+ if (!self.script)
+ dprint ("trigger_camera needs a script number!");
+ self.script_count = 0;
+
+ self.cnt = cvar ("viewsize");
+ // Full screen
+ cvar_set ("viewsize", "120");
+ // PM: Vision sets 'v_idlescale' for swaying screen. Not in Drake!
+ // hack-fix for GLquake
+ stuffcmd (self, "sizedown\nsizeup\n");
+ stuffcmd (self, "+strafe\n");
+
+ setorigin (self, self.enemy.origin);
+
+ // PM: Space invasion prevention.
+ // Make the dummy solid to prevent monsters or other junk from occupying
+ // the space where the player stood before the cutscene started.
+ // After all, the player will be placed back when the cutscene ends,
+ // and we don't want him stuck inside a monster or something.
+ //
+ // We need to wait until after the player becomes the camera, before
+ // we can make the dummy solid. If we make the dummy solid as it
+ // spawned, the player could get stuck inside the dummy (instead of
+ // moving) between trigger activation and transformation to camera.
+ //
+ // In Vision code, player becomes camera a frame or so after trigger
+ // activation. In Zer code, player becomes camera at the same time
+ // the trigger activates.
+ //
+ // Note: If you still have trouble getting a Vision cutscene to work
+ // in a certain level, move the following code to the top of
+ // 'look_ahead'. Doing so would be less than ideal since the check
+ // would get called every frame during the cutscene, instead of just
+ // once here. The only level that still has problems with dummy made
+ // solid now is 'vision.bsp', which has its own pak. Tronyn's maps,
+ // the levels that really matter, have no problems.
+
+ // 'self' is the player-turned-camera entity.
+ // '!self.trigger_field' is the world, and its classname is worldspawn.
+ if (self.trigger_field.classname == "dummy")
+ {
+ self.trigger_field.solid = SOLID_BBOX;
+ setsize (self.trigger_field, self.mins, self.maxs);
+
+ // Unlink now that it's done.
+ self.trigger_field = world;
+ }
};
-void() camera_point_touch = {camera_activate (other);};

-//============
-// --> QUAKED info_movie_camera (.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
-
-// This is the destination marker for a camera. It should have a "targetname"
-// field with the same value as a camera-trigger's "target" field.
-//============
-void() imc_touch =
-{
-local string temps;
-
- if (other.classname != "camera")
- return;
- temps = self.target;
- self.target = self.message;
- SUB_UseTargets();
- self.target = temps;
- if (self.cnt)
- return;
-
- self.think = SUB_Remove;
- self.nextthink = time + 10;
- self.solid = SOLID_NOT;
-};
-
-void() info_movie_camera =
-{
-// this does nothing, just serves as a target spot
-// if (vision)
-// return;
-
-// ...more than a spot in Zer mode.
- //self.use = SUB_Null;
- self.solid = SOLID_TRIGGER;
- setorigin(self, self.origin);
- setsize(self, '-8 -8 -8', '8 8 8');
- self.touch = imc_touch;
-};
-
-void() camera_use =
-{
- local entity pl;
-
- pl = find(world, classname, "player"); // Only one in single-player.
- camera_activate (pl);
-
-// Old code.
-// self.nextthink = time + 100000;
-// force_retouch = 2; // make sure even still objects get hit
-// self.think = SUB_Null;
-};
-
-//- - - - - - - - -
-// Zerstorer-only cutscene code.
+//----------------------------------------------------------------------
+// gocam_use -- Zerstorer-only cutscene code.
+//----------------------------------------------------------------------
void() gocam_use =
{
-local entity control, temp;
-
- control = find(world, classname, "camcontrol");
- if (control == world)
- dprint ("Can't find camcontrol!\n");
-
- temp = self;
- self = control;
- DHM_CalcMoveDone ();
- self = temp;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
+ local entity control, temp;
+
+ control = find (world, classname, "camcontrol");
+ if (control == world)
+ dprint ("Can't find camcontrol!\n");
+
+ temp = self;
+ self = control;
+ DHM_CalcMoveDone ();
+ self = temp;
+ self.nextthink = time + 0.1;
+ self.think = SUB_Remove;
};

-void() trigger_gocamera = {self.use = gocam_use;};
-
-/*QUAKED info_focal_point (.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
-This is the point that the camera will face. It should have a "targetname"
-field with the same value as a camera-trigger's "focal_point" field.
-*/
-// PM: This entity is kept only for map compatibility reasons.
-// Otherwise, this entity is redundant. Use 'info_notnull' instead.
-void() info_focal_point = {}; // just holds a spot for the focal point.
-
-void(float pt) trigger_camera_spawn =
+//----------------------------------------------------------------------
+void() trigger_gocamera =
{
-// Update: Don't let dmsp muck up cutscenes and vice versa.
- if (deathmatch || coop)
- {remove (self); return;} // PM: Fix -- abort if removed.
-
- if (pt)
- { // The new way, this is for you Tronyn.
- InitPointTrigger ();
- if (!self.targetname)
- self.touch = camera_point_touch;
- }
- else
- { // The old way...
- InitTrigger ();
- // PM: Must always allow touch because some old maps need it.
- self.touch = camera_touch;
- }
- // find the destination
- if (!self.target)
- objerror ("Camera trigger with no target");
- self.use = camera_use;
+ self.use = gocam_use;
};

-/*QUAKED trigger_camera (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A player touching this will be transported to the corresponding
-info_movie_camera entity. You must set the "target" field, and put a
-info_movie_camera with a "targetname" field that matches. The "script"
-key gives a starting script number, and the "script_delay" key is the
-amount of time(seconds) to stay on the first script page.
-
-If the trigger_camera has a targetname, it will only enter camera mode
-after it has been fired.
-*/
-void() trigger_camera = {trigger_camera_spawn (FALSE);};
-
-/*QUAKED trigger_camera_point (.5 .5 .5) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-When this is triggered the player will be transported to the corresponding
-info_movie_camera entity. You must set the "target" field, and put a
-info_movie_camera with a "targetname" field that matches. The "script"
-key gives a starting script number, and the "script_delay" key is the
-amount of time(seconds) to stay on the first script page.
-*/
-void() trigger_camera_point = {trigger_camera_spawn (TRUE);};
-
-//----------------------------------
-// Scripting function - dhm
-//----------------------------------
-// The original timing idea for scripts was inspired by Zoid. Study the
+//======================================================================
+// Scripting function - dhm
+//
+// The original timing idea for scripts was inspired by Zoid. Study the
// code for Zoid's CTF, it is an excellent example of good Quake-C coding.
-// Also look at all of Quake Command's stuff. Wedge rules.
-//----------------------------------
+// Also look at all of Quake Command's stuff. Wedge rules.
+//======================================================================
+
+//----------------------------------------------------------------------
// Script_play is called from PlayerPreThink()
// 'self' is the player (camera)
-//----------------------------------
+//----------------------------------------------------------------------
void() Script_play =
{
-local entity scrpt;
-
- scrpt = find (world, script_num, self.script);
- if (!scrpt)
- dprint ("Error: script not found!");
-
- // If script has a target, trigger it once.
-// if (!vision)
- if (scrpt.target != __NULL__ && scrpt.target != "")
- {
- local entity temp;
-
- temp = self;
- self = scrpt;
- SUB_UseTargets ();
- self.target = world.null_string;
- self = temp;
- }
-
- self.script_delay = scrpt.script_delay;
- self.script_time = time + 1;
- self.script_count = self.script_count + 1;
- centerprint (self, scrpt.message);
-
- if (self.script_count == self.script_delay)
- {
- self.script = scrpt.next_script;
- if (self.script != "0")
- self.script_count = 0;
- else
- {
- scrpt.nextthink = time + 3;
- scrpt.classname = "going_back";
- scrpt.think = go_back;
- }
- }
+ local entity scrpt;
+
+ scrpt = find (world, script_num, self.script);
+ if (!scrpt)
+ dprint ("Error: script not found!");
+
+ // If script has a target, trigger it once.
+ // if (!vision)
+ if (scrpt.target != __NULL__ && scrpt.target != "")
+ {
+ local entity temp;
+
+ temp = self;
+ self = scrpt;
+ SUB_UseTargets ();
+ self.target = world.null_string;
+ self = temp;
+ }
+
+ self.script_delay = scrpt.script_delay;
+ self.script_time = time + 1;
+ self.script_count = self.script_count + 1;
+ centerprint (self, scrpt.message);
+
+ if (self.script_count == self.script_delay)
+ {
+ self.script = scrpt.next_script;
+ if (self.script != "0")
+ {
+ self.script_count = 0;
+ }
+ else
+ {
+ scrpt.nextthink = time + 3;
+ scrpt.classname = "going_back";
+ scrpt.think = go_back;
+ }
+ }
};

-
-//- - - - - - - - -
-// PM: Player thinking during a cutscene. Called by 'PlayerPreThink'.
+//----------------------------------------------------------------------
+// PM: Player thinking during a cutscene. Called by 'PlayerPreThink'.
+//----------------------------------------------------------------------
void() Cutscene_Think =
{
- /* --------------------------------------------
- If we are in camera mode, play the script.
- -------------------------------------------- */
- // PM: Allow player to stop cutscene on any map.
- if (self.impulse)
- if (self.script_count != 1000000)
- {
- local entity goback; // PM: dhm's cutscene code.
-
- self.script_count = 1000000;
- // if (world.model == "maps/soeexit.bsp")
- // { // Hack: Jump directly to intermission/credits.
- // NextLevel ();
- // return;
- // }
- // If cut-scene has ended, and user tries to exit, don't
- // spawn a second go_back control entity.
- goback = find(world, classname, "going_back");
- if (!goback)
- {
- sprint(self, "...\n");
- goback = spawn();
- goback.nextthink = time + 1.5;
- goback.think = go_back;
- self.impulse = 0; // PM: New -- just kill cutscene.
- }
- }
-
- if (cutscene) // PM: Vision didn't look_ahead here, but do it
- look_ahead (); // anyway instead of thinking about it.
- if (self.script_count < self.script_delay)
- if (self.script_time < time)
- Script_play ();
+ // If we are in camera mode, play the script.
+ // PM: Allow player to stop cutscene on any map.
+ if (self.impulse)
+ {
+ if (self.script_count != 1000000)
+ {
+ // PM: dhm's cutscene code.
+ local entity goback;
+
+ self.script_count = 1000000;
+
+ /*
+ if (world.model == "maps/soeexit.bsp")
+ {
+ // Hack: Jump directly to intermission/credits.
+ NextLevel ();
+ return;
+ }
+ */
+
+ // If cut-scene has ended, and user tries to exit, don't
+ // spawn a second go_back control entity.
+ goback = find (world, classname, "going_back");
+ if (!goback)
+ {
+ sprint (self, "...\n");
+ goback = spawn ();
+ goback.nextthink = time + 1.5;
+ goback.think = go_back;
+ // PM: New -- just kill cutscene.
+ self.impulse = 0;
+ }
+ }
+ }
+
+ // PM: Vision didn't look_ahead here, but do it
+ if (cutscene)
+ // anyway instead of thinking about it.
+ look_ahead ();
+
+ if (self.script_count < self.script_delay)
+ if (self.script_time < time)
+ Script_play ();
};

+//----------------------------------------------------------------------
void() script_sound_play =
{
- if (self.noise != "")
- sound (other, CHAN_AUTO, self.noise, 1, ATTN_NONE);
- else
- sound (other, CHAN_AUTO, self.noise1, 1, ATTN_NONE);
+ if (self.noise != "")
+ sound (other, CHAN_AUTO, self.noise, 1, ATTN_NONE);
+ else
+ sound (other, CHAN_AUTO, self.noise1, 1, ATTN_NONE);
};
-//- - - - - - - - -
-//============
-// --> QUAKED info_script_sound (.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

-// This is the noise player for a script.
+/*QUAKED info_script_sound (.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

+This is the noise player for a script.
+*/
void() info_script_sound =
{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
- //play all the sounds available for a normal trigger
- if (self.sounds == 0)
- {
- precache_sound ("misc/null.wav");
- self.noise = "misc/null.wav";
- }
- else if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
- else if (self.sounds == 4)
- {
- if (!self.noise1) //dumptruck_ds
- {
- objerror ("no soundfile set in noise1!\n");
- remove(self);
- return;
- }
- else
- precache_sound (self.noise1);
- self.noise = self.noise1;
- }
- self.use = script_sound_play;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ // play all the sounds available for a normal trigger
+ if (self.sounds == 0)
+ {
+ precache_sound ("misc/null.wav");
+ self.noise = "misc/null.wav";
+ }
+ else if (self.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ self.noise = "misc/secret.wav";
+ }
+ else if (self.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ self.noise = "misc/talk.wav";
+ }
+ else if (self.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ self.noise = "misc/trigger1.wav";
+ }
+ else if (self.sounds == 4)
+ {
+ // dumptruck_ds
+ if (!self.noise1)
+ {
+ objerror ("no soundfile set in noise1!\n");
+ remove (self);
+ return;
+ }
+ else
+ {
+ precache_sound (self.noise1);
+ }
+
+ self.noise = self.noise1;
+ }
+ self.use = script_sound_play;
};

-//============
-// --> QUAKED info_script (.5 .5 .5) (-8 -8 -8) (8 8 32)
-// This is the destination marker for a script.
-// It should have a "script_num" field that signifies the script number, and
-// a "next_script" to signal the next script ("0" if this is the last page of
-// the script), a "script_delay" to signify how many seconds to display this
-// page, and of course a "message" field with the text to display.
-//
-// PM: Use 'info_notnull' instead.
-//============
-void() info_script =
-{
- if (SUB_Inhibit ()) // new spawnflags for all entities -- iw
- return;
-};
-
-
-// ------------------------------ //
-// | trigger_cvarset | //
-// ------------------------------ //
-//============
-// --> QUAKED trigger_cvarset (.5 .5 .5) (-8 -8 -8) (8 8 32)
-// You can set any CVAR on the server with this trigger. Put the CVAR name
-// in "netname" and put the value in "message". Useful CVAR's are
-// sv_gravity, sv_friction, fov, and v_idlescale.
-//============
-void() change_cvar =
-{
-local entity check;
+/*QUAKED info_script (.5 .5 .5) (-8 -8 -8) (8 8 32)
+This is the destination marker for a script.
+It should have a "script_num" field that signifies the script number, and
+a "next_script" to signal the next script ("0" if this is the last page of
+the script), a "script_delay" to signify how many seconds to display this
+page, and of course a "message" field with the text to display.

- cvar_set (self.netname, self.message);
- bprint("\n\n\n\n");
-
- self.classname = "cvar_done";
- check = find(world, classname, "player");
- if (!check)
- check = find(world, classname, "camera");
-
- check.ideal_yaw = -1;
-
- self.nextthink = time + 0.02;
- self.think = SUB_UseTargets;
-};
-
-void() cvarset_touch =
-{
- if (self.cnt > time || other.health <= 0 || other.classname != "player")
- return;
-
- change_cvar ();
-};
-
-void() trigger_cvarset =
+PM: Use 'info_notnull' instead.
+*/
+void() info_script =
{
- if (deathmatch || coop)
- remove (self);
-
- InitTrigger ();
- self.use = change_cvar;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
};

-
-// PM: Removed gravity and earthquake entities.
-
-//===========================/ END OF FILE /===========================//
+//===========================/ END OF FILE /===========================/

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

Diff qc/defs_builtins.qc

diff --git a/qc/defs_builtins.qc b/qc/defs_builtins.qc
index c961148..0546a71 100644
--- a/qc/defs_builtins.qc
+++ b/qc/defs_builtins.qc
@@ -1,6 +1,6 @@
-/*==============================================================================
- BUILTIN FUNCTIONS
-==============================================================================*/
+//==============================================================================
+// BUILTIN FUNCTIONS
+//==============================================================================

void(vector ang) makevectors = #1; // sets v_forward, etc globals
void(entity e, vector o) setorigin = #2;
@@ -76,18 +76,6 @@ void(float to, entity s) WriteEntity = #59;
// otherwise equivalent).
void(float buf, int fl) WriteInt = #0:WriteInt;

-//======================================================================
-// broadcast client message generation
-//======================================================================
-// void(float f) bWriteByte = #59;
-// void(float f) bWriteChar = #60;
-// void(float f) bWriteShort = #61;
-// void(float f) bWriteLong = #62;
-// void(float f) bWriteCoord = #63;
-// void(float f) bWriteAngle = #64;
-// void(string s) bWriteString = #65;
-// void(entity e) bWriteEntity = #66;
-
// Part of DP_QC_SINCOSSQRTPOW Forgive me father, for I have
// trigonometry homework.
// from fteextensions.qc -- CEV
@@ -184,8 +172,8 @@ void(entity e) setspawnparms = #78; // set parm1... to the values at
// Part of DP_QC_TRACEBOX Exactly like traceline, but a box instead
// of a uselessly thin point. Acceptable sizes are limited by bsp format,
// q1bsp has strict acceptable size values.
-// brought in from fteextensions.qc -- CEV
-void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90;
+void(vector start, vector mins, vector maxs, vector end, float nomonsters,
+ entity ent) tracebox = #90;

// Part of DP_QC_MINMAXBOUND Returns the lowest value of its arguments.
float(float a, float b, ...) min = #94;
@@ -197,6 +185,13 @@ float(float minimum, float val, float maximum) bound = #96;
// Part of DP_QC_SINCOSSQRTPOW
float(float value, float exp) pow = #97;

+// Part of DP_QC_FINDFLOAT
+// Equivelent to the find builtin, but instead of comparing strings contents,
+// this builtin compares the raw values. This builtin requires multiple calls
+// in order to scan all entities - set start to the previous call's return
+// value. world is returned when there are no more entities.
+entity(entity start, .__variant fld, __variant match) findfloat = #98;
+
// for CSQC interaction -- CEV
void(float num, float type, .__variant fld) clientstat = #232;

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

Diff qc/defs_classtype.qc

diff --git a/qc/defs_classtype.qc b/qc/defs_classtype.qc
new file mode 100644
index 0000000..53134ac
--- /dev/null
+++ b/qc/defs_classtype.qc
@@ -0,0 +1,141 @@
+//=============================================================================
+// CLASSTYPES
+//=============================================================================
+
+// fields
+.float classtype; // used to identify an entity's type
+
+//----------------------------------------------------------------------
+// global classtype list; shared by client & server
+//----------------------------------------------------------------------
+enum
+{
+ CT_WORLD, // world entity
+
+ // monsters
+ CT_PLAYER, // player (client)
+
+ // items & weapons
+
+ // info
+ CT_INFO_FOCAL_POINT, // cutscenes
+ CT_INFO_MOVIE_CAMERA, // cutscenes
+ CT_INFO_NOTNULL, //
+ CT_INFO_NULL, //
+ CT_INFO_TELEPORT_CHANGEDEST, // teleporters
+ CT_INFO_TELEPORT_DESTINATION, // teleporters
+ CT_INFO_TELEPORT_RANDOM, // teleporters
+
+ // func
+
+ // gibs
+ CT_GIB_HEAD_ARMY, // deadstuff
+ CT_GIB_HEAD_DEMON, //
+ CT_GIB_HEAD_DOG, //
+ CT_GIB_HEAD_ENFORCER, //
+ CT_GIB_HEAD_HELL_KNIGHT, //
+ CT_GIB_HEAD_KNIGHT, //
+ CT_GIB_HEAD_OGRE, //
+ CT_GIB_HEAD_PLAYER, //
+ CT_GIB_HEAD_SHALRATH, //
+ CT_GIB_HEAD_SHAMBLER, //
+ CT_GIB_HEAD_WIZARD, //
+ CT_GIB_MISC_1, //
+ CT_GIB_MISC_2, //
+ CT_GIB_MISC_3, //
+
+ // lights
+ CT_LIGHT, // id1 light
+ CT_LIGHT_CANDLE, // light_candle
+ CT_LIGHT_FLAME_LARGE_YELLOW, // id1
+ CT_LIGHT_FLAME_SMALL_YELLOW, // id1
+ CT_LIGHT_FLUORO, // id1 light_fluoro
+ CT_LIGHT_FLUOROSPARK, // id1 light_fluorospark
+ CT_LIGHT_GLOBE, // id1 light_globe
+ CT_LIGHT_TORCH_SMALL_WALLTORCH, // id1
+
+ // misc
+ CT_MISC_AIR_BUBBLES, // id1 air bubbles
+ CT_MISC_AMBIENT_COMPHUM, // computer hum
+ CT_MISC_AMBIENT_DRIP, // drip sound
+ CT_MISC_AMBIENT_DRONE, // drone sound
+ CT_MISC_AMBIENT_FBUZZ, // fluoro buzz
+ CT_MISC_AMBIENT_GENERAL, // Rubicon Rumble devkit ambient_general
+ CT_MISC_AMBIENT_FIRE, // ambient fire sound
+ CT_MISC_AMBIENT_LBUZZ, // light buzz
+ CT_MISC_AMBIENT_SUCKWIND, // suck wind
+ CT_MISC_AMBIENT_SWAMP1, // swamp 1
+ CT_MISC_AMBIENT_SWAMP2, // swamp 2
+ CT_MISC_AMBIENT_THUNDER, // Zerstorer ambient thunder
+ CT_MISC_AMBIENT_WATER1, // ambient water 1
+ CT_MISC_AMBIENT_WIND2, // ambient wind 2
+ CT_MISC_EXPLOBOX, // id1 misc_explobox
+ CT_MISC_EXPLOBOX2, // id1 misc_explobox2
+ CT_MISC_FIREBALL, // id1 misc_fireball
+ CT_MISC_INFIGHT, // progs_dump 3 misc_infight
+ CT_MISC_MODEL, // misc_model -- Joshua Skelton
+ CT_MISC_NOISEMAKER, // pd3 some kind of testing ent?
+ CT_MISC_PARTICLES, // Rubicon2 misc_splash
+ CT_MISC_PARTICLESPRAY, // custents misc_particlespray
+ CT_MISC_PARTICLE_STREAM, // Zerstorer misc_particle_stream
+ CT_MISC_PLAY_BFIELD, // pd3 play
+ CT_MISC_PLAY_BRLIGHT, // pd3 play
+ CT_MISC_PLAY_DIMLIGHT, // pd3 play
+ CT_MISC_PLAY_EXPLOSION, // pd3 play
+ CT_MISC_PLAY_GIBS, // pd3 play
+ CT_MISC_PLAY_LAVASPLASH, // pd3 play
+ CT_MISC_PLAY_MFLASH, // pd3 play muzzleflash
+ CT_MISC_PLAY_SOUND, // pd3 play_sound
+ CT_MISC_PLAY_SOUND_TRIGGERED, // pd3 play_sound
+ CT_MISC_SPARKS, // misc_sparks
+ CT_MISC_VIEWTHING, // id1?
+ CT_MISC_TELE_FOG, // pd3 play
+ CT_MISC_TELEPORTTRAIN, // id1 teleport train
+
+ // targets
+ CT_TARGET_AUTOSAVE, // target_autosave from copper
+ CT_TARGET_FOGBLEND, // fog
+ CT_TARGET_SETCOUNT, //
+ CT_TARGET_SETSTATE, //
+ CT_TARGET_TEXTSTORY, // progs_dump textstory
+ CT_TARGET_TEXTSTORY_HELPER, // textstory helper subclass
+
+ // triggers
+ CT_TRIGGER_CAMERA, // cutscenes
+ CT_TRIGGER_CAMERA_POINT, // cutscenes
+ CT_TRIGGER_CDTRACK, // progs_dump 3 cd track trigger
+ CT_TRIGGER_CHANGELEVEL, // id1 change level trigger
+ CT_TRIGGER_CHANGEMUSIC, // jleww via changemusic.rar
+ CT_TRIGGER_CHANGETARGET, // change an entity's target field
+ CT_TRIGGER_COUNTER, // id1 trigger_counter
+ CT_TRIGGER_CVARSET, // was in cutscene.qc; from Drake?
+ CT_TRIGGER_EVERYTHING, // progs_dump 3; unknown prior source
+ CT_TRIGGER_FILTER, //
+ CT_TRIGGER_FOG, // fog
+ CT_TRIGGER_FOGBLEND, // fog
+ CT_TRIGGER_HEAL, // custents trigger_heal by TGR
+ CT_TRIGGER_HURT, // Hipnotic trigger_hurt
+ CT_TRIGGER_LADDER, // rubicon2 ladders
+ CT_TRIGGER_LOOK, // trigger_onlookat by NullPointPaladin
+ CT_TRIGGER_MONSTERFACE, // progs_dump 3 monsterface
+ CT_TRIGGER_MONSTERJUMP, // id1 trigger_monsterjump
+ CT_TRIGGER_MULTIPLE, // id1 trigger_multiple
+ CT_TRIGGER_ONCE, // id1 trigger_once
+ CT_TRIGGER_ONLYREGISTERED, // id1 registered content trigger
+ CT_TRIGGER_PUSH, // id1 push/wind brush
+ CT_TRIGGER_PUSH_CUSTOM, // progs_dump push custom
+ CT_TRIGGER_RELAY, // id1 trigger_relay
+ CT_TRIGGER_SECRET, // id1 secret trigger
+ CT_TRIGGER_SETGRAVITY, // Hipnotic gravity trigger
+ CT_TRIGGER_SETSKILL, // id1 setskill trigger
+ CT_TRIGGER_SHAKE, // ground-shake trigger
+ CT_TRIGGER_TAKE_WEAPON, // take_weapon
+ CT_TRIGGER_TELEPORT, // id1 teleporters
+ CT_TRIGGER_TEXTSTORY, // progs_dump textstory
+ CT_TRIGGER_USEKEY, // originally based on Hipnotic code
+ CT_TRIGGER_VOID, // necros' trigger_void, modified
+
+ // temp entities
+ CT_TEMP_BUBBLES, // air bubble
+ CT_TEMP_FOG_CONTROLLER // fog
+};

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

Diff qc/defs_entvars.qc

diff --git a/qc/defs_entvars.qc b/qc/defs_entvars.qc
index 59f5812..8fdc4a8 100644
--- a/qc/defs_entvars.qc
+++ b/qc/defs_entvars.qc
@@ -1,6 +1,6 @@
-/*==============================================================================
- SOURCE FOR ENTVARS_T C STRUCTURE
-==============================================================================*/
+//==============================================================================
+// SOURCE FOR ENTVARS_T C STRUCTURE
+//==============================================================================

//======================================================================
// system fields (*** = do not set in prog code, maintained by C code)
@@ -12,7 +12,7 @@
.float movetype;
.float solid;

-.vector origin; // ***
+.vector origin; // *** only some of the time -- CEV
.vector oldorigin; // ***
.vector velocity;
.vector angles;

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

Diff qc/defs_globalvars.qc

diff --git a/qc/defs_globalvars.qc b/qc/defs_globalvars.qc
index fac70c6..dbfc510 100644
--- a/qc/defs_globalvars.qc
+++ b/qc/defs_globalvars.qc
@@ -1,6 +1,6 @@
-/*==============================================================================
- SOURCE FOR GLOBALVARS_T C STRUCTURE
-==============================================================================*/
+//==============================================================================
+// SOURCE FOR GLOBALVARS_T C STRUCTURE
+//==============================================================================

//======================================================================
// system globals
@@ -31,7 +31,6 @@ float total_monsters;
float found_secrets; // number of secrets found
float killed_monsters; // number of monsters killed

-
// spawnparms are used to encode information about clients across server
// level changes
float parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8,
@@ -80,7 +79,6 @@ void() SetNewParms; // called when a client first connects
void() SetChangeParms; // call to set parms for self so they
// can be saved for a level transition

-
//================================================
void end_sys_globals; // flag for structure dumping
//================================================

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

Diff qc/defs_misc.qc

diff --git a/qc/defs_misc.qc b/qc/defs_misc.qc
index 0ae68d9..de12145 100644
--- a/qc/defs_misc.qc
+++ b/qc/defs_misc.qc
@@ -3,201 +3,203 @@
==============================================================================*/

// inspired by Copper
-string version = "\nprogs_dump devkit\nversion 3.0.0";
+const string version = "\n\"Dog\" mode for FTE\nversion 0.1a";

// constants
-float FALSE = 0;
-float TRUE = 1;
-float NEGATIVE = -1;
+const float FALSE = 0;
+const float TRUE = 1;
+const float NEGATIVE = -1;

// worldtype values
-float WORLDTYPE_MEDIEVAL = 0;
-float WORLDTYPE_METAL = 1;
-float WORLDTYPE_BASE = 2;
+const float WORLDTYPE_MEDIEVAL = 0;
+const float WORLDTYPE_METAL = 1;
+const float WORLDTYPE_BASE = 2;

// edict.flags
-float FL_FLY = 1;
-float FL_SWIM = 2;
-float FL_CLIENT = 8; // set for all client edicts
-float FL_INWATER = 16; // for enter / leave water splash
-float FL_MONSTER = 32;
-float FL_GODMODE = 64; // player cheat
-float FL_NOTARGET = 128; // player cheat
-float FL_ITEM = 256; // extra wide size for bonus items
-float FL_ONGROUND = 512; // standing on something
-float FL_PARTIALGROUND = 1024; // not all corners are valid
-float FL_WATERJUMP = 2048; // player jumping out of water
-float FL_JUMPRELEASED = 4096; // for jump debouncing
-float FL_NOCENTERPRINT = 65536; // don't centerprint entity's message
+const float FL_FLY = 1;
+const float FL_SWIM = 2;
+const float FL_CLIENT = 8; // set for all client edicts
+const float FL_INWATER = 16; // for enter / leave water splash
+const float FL_MONSTER = 32;
+const float FL_GODMODE = 64; // player cheat
+const float FL_NOTARGET = 128; // player cheat
+const float FL_ITEM = 256; // extra wide size for bonus items
+const float FL_ONGROUND = 512; // standing on something
+const float FL_PARTIALGROUND = 1024; // not all corners are valid
+const float FL_WATERJUMP = 2048; // player jumping out of water
+const float FL_JUMPRELEASED = 4096; // for jump debouncing
+const float FL_NOCENTERPRINT = 65536; // don't centerprint entity's message
// field when its targets are used
// edict.movetype values
-float MOVETYPE_NONE = 0; // never moves
-//float MOVETYPE_ANGLENOCLIP = 1;
-//float MOVETYPE_ANGLECLIP = 2;
-float MOVETYPE_WALK = 3; // players only
-float MOVETYPE_STEP = 4; // discrete, not real time unless fall
-float MOVETYPE_FLY = 5;
-float MOVETYPE_TOSS = 6; // gravity
-float MOVETYPE_PUSH = 7; // no clip to world, push and crush
-float MOVETYPE_NOCLIP = 8;
-float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
-float MOVETYPE_BOUNCE = 10;
-float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size
+const float MOVETYPE_NONE = 0; // never moves
+// float MOVETYPE_ANGLENOCLIP = 1;
+// float MOVETYPE_ANGLECLIP = 2;
+const float MOVETYPE_WALK = 3; // players only
+const float MOVETYPE_STEP = 4; // discrete, not real time unless fall
+const float MOVETYPE_FLY = 5;
+const float MOVETYPE_TOSS = 6; // gravity
+const float MOVETYPE_PUSH = 7; // no clip to world, push and crush
+const float MOVETYPE_NOCLIP = 8;
+const float MOVETYPE_FLYMISSILE = 9; // fly with extra size against monsters
+const float MOVETYPE_BOUNCE = 10;
+const float MOVETYPE_BOUNCEMISSILE = 11; // bounce with extra size

// edict.solid values
-float SOLID_NOT = 0; // no interaction with other objects
-float SOLID_TRIGGER = 1; // touch on edge, but not blocking
-float SOLID_BBOX = 2; // touch on edge, block
-float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
-float SOLID_BSP = 4; // bsp clip, touch on edge, block
+const float SOLID_NOT = 0; // no interaction with other objects
+const float SOLID_TRIGGER = 1; // touch on edge, but not blocking
+const float SOLID_BBOX = 2; // touch on edge, block
+const float SOLID_SLIDEBOX = 3; // touch on edge, but not an onground
+const float SOLID_BSP = 4; // bsp clip, touch on edge, block

// range values
-float RANGE_MELEE = 0;
-float RANGE_NEAR = 1;
-float RANGE_MID = 2;
-float RANGE_FAR = 3;
+const float RANGE_MELEE = 0;
+const float RANGE_NEAR = 1;
+const float RANGE_MID = 2;
+const float RANGE_FAR = 3;

// deadflag values
-float DEAD_NO = 0;
-float DEAD_DYING = 1;
-float DEAD_DEAD = 2;
-float DEAD_RESPAWNABLE = 3;
+const float DEAD_NO = 0;
+const float DEAD_DYING = 1;
+const float DEAD_DEAD = 2;
+const float DEAD_RESPAWNABLE = 3;

// takedamage values
-float DAMAGE_NO = 0;
-float DAMAGE_YES = 1;
-float DAMAGE_AIM = 2;
+const float DAMAGE_NO = 0;
+const float DAMAGE_YES = 1;
+const float DAMAGE_AIM = 2;

// items
-float IT_AXE = 4096;
-float IT_SHOTGUN = 1;
-float IT_SUPER_SHOTGUN = 2;
-float IT_NAILGUN = 4;
-float IT_SUPER_NAILGUN = 8;
-float IT_GRENADE_LAUNCHER = 16;
-float IT_ROCKET_LAUNCHER = 32;
-float IT_LIGHTNING = 64;
-float IT_EXTRA_WEAPON = 128;
-
-float IT_SHELLS = 256;
-float IT_NAILS = 512;
-float IT_ROCKETS = 1024;
-float IT_CELLS = 2048;
-
-float IT_ARMOR1 = 8192;
-float IT_ARMOR2 = 16384;
-float IT_ARMOR3 = 32768;
-float IT_SUPERHEALTH = 65536;
-
-float IT_KEY1 = 131072;
-float IT_KEY2 = 262144;
-
-float IT_INVISIBILITY = 524288;
-float IT_INVULNERABILITY = 1048576;
-float IT_SUIT = 2097152;
-float IT_QUAD = 4194304;
+const float IT_AXE = 4096;
+const float IT_SHOTGUN = 1;
+const float IT_SUPER_SHOTGUN = 2;
+const float IT_NAILGUN = 4;
+const float IT_SUPER_NAILGUN = 8;
+const float IT_GRENADE_LAUNCHER = 16;
+const float IT_ROCKET_LAUNCHER = 32;
+const float IT_LIGHTNING = 64;
+const float IT_EXTRA_WEAPON = 128;
+
+const float IT_SHELLS = 256;
+const float IT_NAILS = 512;
+const float IT_ROCKETS = 1024;
+const float IT_CELLS = 2048;
+
+const float IT_ARMOR1 = 8192;
+const float IT_ARMOR2 = 16384;
+const float IT_ARMOR3 = 32768;
+const float IT_SUPERHEALTH = 65536;
+
+const float IT_KEY1 = 131072;
+const float IT_KEY2 = 262144;
+
+const float IT_INVISIBILITY = 524288;
+const float IT_INVULNERABILITY = 1048576;
+const float IT_SUIT = 2097152;
+const float IT_QUAD = 4194304;

// point content values
-float CONTENT_EMPTY = -1;
-float CONTENT_SOLID = -2;
-float CONTENT_WATER = -3;
-float CONTENT_SLIME = -4;
-float CONTENT_LAVA = -5;
-float CONTENT_SKY = -6;
-
-float STATE_TOP = 0;
-float STATE_BOTTOM = 1;
-float STATE_UP = 2;
-float STATE_DOWN = 3;
-
-vector VEC_ORIGIN = '0 0 0';
+const float CONTENT_EMPTY = -1;
+const float CONTENT_SOLID = -2;
+const float CONTENT_WATER = -3;
+const float CONTENT_SLIME = -4;
+const float CONTENT_LAVA = -5;
+const float CONTENT_SKY = -6;
+
+const float STATE_TOP = 0;
+const float STATE_BOTTOM = 1;
+const float STATE_UP = 2;
+const float STATE_DOWN = 3;
+
+const vector VEC_ORIGIN = '0 0 0';
// Player
-vector VEC_HULL_MIN = '-16 -16 -24';
-vector VEC_HULL_MAX = '16 16 32';
-vector VEC_HULL_SIZE = '32 32 56';
+const vector VEC_HULL_MIN = '-16 -16 -24';
+const vector VEC_HULL_MAX = '16 16 32';
+const vector VEC_HULL_SIZE = '32 32 56';
+// Player crouching
+const vector VEC_CHULL_MIN = '-16 -16 -18';
+const vector VEC_CHULL_MAX = '16 16 18';
+const vector VEC_CHULL_SIZE = '32 32 36';
// Ogres, Shalrath, Demon, Shambler
-vector VEC_HULL2_MIN = '-32 -32 -24';
-vector VEC_HULL2_MAX = '32 32 64';
-vector VEC_HULL2_SIZE = '64 64 88';
+const vector VEC_HULL2_MIN = '-32 -32 -24';
+const vector VEC_HULL2_MAX = '32 32 64';
+const vector VEC_HULL2_SIZE = '64 64 88';

// protocol bytes
-float SVC_UPDATESTAT = 3; // required by Hipnotic code
-float SVC_SETVIEWPORT = 5; // Camera Hip. Drake devkit dumptruck_ds
-float SVC_SETVIEWANGLES = 10; // Camera Hip. Drake devkit dumptruck_ds
-float SVC_TEMPENTITY = 23;
-float SVC_KILLEDMONSTER = 27;
-float SVC_FOUNDSECRET = 28;
-float SVC_INTERMISSION = 30;
-float SVC_FINALE = 31;
-float SVC_CDTRACK = 32;
-float SVC_SELLSCREEN = 33;
-float SVC_CUTSCENE = 34; // Hipnotic Drake devkit -- dumptruck_ds
-
-float TE_SPIKE = 0;
-float TE_SUPERSPIKE = 1;
-float TE_GUNSHOT = 2;
-float TE_EXPLOSION = 3;
-float TE_TAREXPLOSION = 4;
-float TE_LIGHTNING1 = 5;
-float TE_LIGHTNING2 = 6;
-float TE_WIZSPIKE = 7;
-float TE_KNIGHTSPIKE = 8;
-float TE_LIGHTNING3 = 9;
-float TE_LAVASPLASH = 10;
-float TE_TELEPORT = 11;
-float TE_EXPLOSION2 = 12; // from doe -- dumptruck_ds
-
-float CLASS_PLAYER = 77; // TODO CEV
-
-// sound channels
-// channel 0 never willingly overrides
-// other channels (1-7) always override a playing sound on that channel
-float CHAN_AUTO = 0;
-float CHAN_WEAPON = 1;
-float CHAN_VOICE = 2;
-float CHAN_ITEM = 3;
-float CHAN_BODY = 4;
-
-float ATTN_NONE = 0;
-float ATTN_NORM = 1;
-float ATTN_IDLE = 2;
-float ATTN_STATIC = 3;
+const float SVC_UPDATESTAT = 3; // required by Hipnotic code
+const float SVC_SETVIEWPORT = 5; // Camera Hip. Drake devkit dumptruck_ds
+const float SVC_SETVIEWANGLES = 10; // Camera Hip. Drake devkit dumptruck_ds
+const float SVC_TEMPENTITY = 23;
+const float SVC_KILLEDMONSTER = 27;
+const float SVC_FOUNDSECRET = 28;
+const float SVC_INTERMISSION = 30;
+const float SVC_FINALE = 31;
+const float SVC_CDTRACK = 32;
+const float SVC_SELLSCREEN = 33;
+const float SVC_CUTSCENE = 34; // Hipnotic Drake devkit -- dumptruck_ds
+
+const float TE_SPIKE = 0;
+const float TE_SUPERSPIKE = 1;
+const float TE_GUNSHOT = 2;
+const float TE_EXPLOSION = 3;
+const float TE_TAREXPLOSION = 4;
+const float TE_LIGHTNING1 = 5;
+const float TE_LIGHTNING2 = 6;
+const float TE_WIZSPIKE = 7;
+const float TE_KNIGHTSPIKE = 8;
+const float TE_LIGHTNING3 = 9;
+const float TE_LAVASPLASH = 10;
+const float TE_TELEPORT = 11;
+const float TE_EXPLOSION2 = 12; // from doe -- dumptruck_ds
+
+// sound channels: channel 0 never willingly overrides, other channels
+// (1-7) always override a playing sound on that channel
+const float CHAN_AUTO = 0;
+const float CHAN_WEAPON = 1;
+const float CHAN_VOICE = 2;
+const float CHAN_ITEM = 3;
+const float CHAN_BODY = 4;
+const float CHAN_FEET = 5; // dedicated channel for steps -- CEV
+
+const float ATTN_NONE = 0;
+const float ATTN_NORM = 1;
+const float ATTN_IDLE = 2;
+const float ATTN_STATIC = 3;

// update types
-float UPDATE_GENERAL = 0;
-float UPDATE_STATIC = 1;
-float UPDATE_BINARY = 2;
-float UPDATE_TEMP = 3;
+const float UPDATE_GENERAL = 0;
+const float UPDATE_STATIC = 1;
+const float UPDATE_BINARY = 2;
+const float UPDATE_TEMP = 3;

// entity effects
-float EF_BRIGHTFIELD = 1;
-float EF_MUZZLEFLASH = 2;
-float EF_BRIGHTLIGHT = 4;
-float EF_DIMLIGHT = 8;
+const float EF_BRIGHTFIELD = 1;
+const float EF_MUZZLEFLASH = 2;
+const float EF_BRIGHTLIGHT = 4;
+const float EF_DIMLIGHT = 8;

// messages
-float MSG_BROADCAST = 0; // unreliable to all
-float MSG_ONE = 1; // reliable to one (msg_entity)
-float MSG_ALL = 2; // reliable to all
-float MSG_INIT = 3; // write to the init string
+const float MSG_BROADCAST = 0; // unreliable to all
+const float MSG_ONE = 1; // reliable to one (msg_entity)
+const float MSG_ALL = 2; // reliable to all
+const float MSG_INIT = 3; // write to the init string
// The byte(s) will be written into the multicast buffer for more
// selective sending. Messages sent this way will never be split across
// packets, and using this for csqc-only messages will not break protocol
// translation.
-float MSG_MULTICAST = 4;
+const float MSG_MULTICAST = 4;
// The byte(s) will be written into the entity buffer. This is a special
// value used only inside 'SendEntity' functions.
-float MSG_ENTITY = 5;
+const float MSG_ENTITY = 5;

// spawnflags for func_movewall
-float MOVEWALL_VISIBLE = 1;
-float MOVEWALL_TOUCH = 2;
-float MOVEWALL_NONBLOCKING = 4;
+const float MOVEWALL_VISIBLE = 1;
+const float MOVEWALL_TOUCH = 2;
+const float MOVEWALL_NONBLOCKING = 4;

// known_release values -- iw
-float KNOWN_RELEASE_NOT = 0;
-float KNOWN_RELEASE_ID1 = 1;
-float KNOWN_RELEASE_FUNC_MAPJAMX = 2;
+const float KNOWN_RELEASE_NOT = 0;
+const float KNOWN_RELEASE_ID1 = 1;
+const float KNOWN_RELEASE_FUNC_MAPJAMX = 2;

const float EV_VOID = 0;
const float EV_STRING = 1;
@@ -413,13 +415,11 @@ string lastnameused; // the targetname that was last used
.float switchshadstyle;
.float shadowoff;
.entity shadowcontroller;
-.float speed2;

void() misc_shadowcontroller;
void() misc_shadowcontroller_use;
void() shadow_fade_in;
void() shadow_fade_out;
-string(float num) lightstyle_fade_lookup;// add. by bmFbr for switchable shadows

//======================================================================
// misc pd_additions
@@ -433,18 +433,6 @@ string(float num) lightstyle_fade_lookup;// add. by bmFbr for switchable shadows
.float damage_mod; // dumptruck_ds

/*==============================================================================
- subs.qc
-==============================================================================*/
-void(vector tdest, float tspeed, void() func) SUB_CalcMove;
-void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
-void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
-void() SUB_CalcMoveDone;
-void() SUB_CalcAngleMoveDone;
-void() SUB_Null;
-void() SUB_UseTargets;
-void() SUB_Remove;
-
-/*==============================================================================
combat.qc
==============================================================================*/
void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
@@ -501,8 +489,6 @@ void(string type, string text) print_self =
};

// TODO CEV
-void() monster_pain_use; // dumptruck_ds
-void() SUB_UsePain; // dumptruck_ds
.float pain_threshold; // dumptruck_ds
.string pain_target; // dumptruck_ds
.float color; // Hipnotic
@@ -600,6 +586,8 @@ float I_AM_TURRET = 262144; // dumptruck_ds
.entity rotatecontroller;
.float multiplier;

+
+// TODO CEV
.float first_frame, last_frame;
.float first_frame2, last_frame2;
.float frtime, frtime2;

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

Diff qc/fight.qc

diff --git a/qc/fight.qc b/qc/fight.qc
index 9ecea5e..ad9f9bd 100644
--- a/qc/fight.qc
+++ b/qc/fight.qc
@@ -1,4 +1,3 @@
-
/*

A monster is in fight mode if it thinks it can effectively attack its
@@ -60,6 +59,9 @@ float() CheckAttack =
local entity targ;
local float chance;

+ // silence a compiler warning -- CEV
+ spot1 = spot2 = '0 0 0';
+
if (self.spawnflags & I_AM_TURRET) //dumptruck_ds
{
// dprint("CheckAttack...\n");

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

Diff qc/func/breakable.qc

diff --git a/qc/func/breakable.qc b/qc/func/breakable.qc
index 3cfb7b8..40f83d4 100644
--- a/qc/func/breakable.qc
+++ b/qc/func/breakable.qc
@@ -6,9 +6,6 @@
const float BREAKABLE_NO_MONSTERS = 1;
const float BREAK_EXPLODE = 2;
const float BREAK_CUSTOM = 4;
-const float START_OFF = 1;
-const float SPARKS_BLUE = 2;
-const float SPARKS_PALE = 4;

// prototypes
void() make_breakable_debris;

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

Diff qc/func/laser.qc

diff --git a/qc/func/laser.qc b/qc/func/laser.qc
index c98ccc6..63967d8 100644
--- a/qc/func/laser.qc
+++ b/qc/func/laser.qc
@@ -7,6 +7,7 @@
.string message2;

// constants
+const float LASER_START_OFF = 1;
const float LASER_SOLID = 2;

//----------------------------------------------------------------------
@@ -18,7 +19,7 @@ void() laser_helper_think =
return;
}

- if (!(self.owner.spawnflags & START_OFF))
+ if (!(self.owner.spawnflags & LASER_START_OFF))
self.owner.alpha = self.alpha * 0.8 +
self.alpha * random() * 0.4;

@@ -43,10 +44,10 @@ void() func_laser_touch =
//----------------------------------------------------------------------
void() func_laser_use =
{
- if (self.spawnflags & START_OFF)
+ if (self.spawnflags & LASER_START_OFF)
{
setorigin (self, '0 0 0');
- self.spawnflags = self.spawnflags - START_OFF;
+ self.spawnflags = self.spawnflags - LASER_START_OFF;

// changed for progs_dump: the laser sound is now emitted from
// the func_laser itself instead of from the activator -- iw
@@ -64,7 +65,7 @@ void() func_laser_use =
sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);

setorigin (self, '0 0 9000');
- self.spawnflags = self.spawnflags + START_OFF;
+ self.spawnflags = self.spawnflags + LASER_START_OFF;

if (activator.classname == "player" && self.message2 != "")
{
@@ -73,11 +74,11 @@ void() func_laser_use =
}
};

-/*QUAKED func_laser (0 .5 .8) ? START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+/*QUAKED func_laser (0 .5 .8) ? LASER_START_OFF LASER_SOLID X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

A toggleable laser, hurts to touch, can be used to block players

-START_OFF: Laser starts off.
+LASER_START_OFF: Laser starts off.

LASER_SOLID: Laser blocks movement while turned on.

@@ -127,7 +128,7 @@ void () func_laser =
self.use = func_laser_use;
self.touch = func_laser_touch;

- if (self.spawnflags & START_OFF)
+ if (self.spawnflags & LASER_START_OFF)
setorigin (self, '0 0 9000');

if (self.noise != "")

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

Diff qc/func/rotate.qc

diff --git a/qc/func/rotate.qc b/qc/func/rotate.qc
index 33be98f..5ba211c 100644
--- a/qc/func/rotate.qc
+++ b/qc/func/rotate.qc
@@ -225,9 +225,11 @@ void(float amount) SetDamageOnTargets =

while (ent)
{
- if (ent.classname == "trigger_hurt")
+ if (ent.classtype == CT_TRIGGER_HURT)
{
- hurt_setdamage (ent, amount);
+ // cast to trigger_hurt -- CEV
+ local trigger_hurt t = (trigger_hurt)ent;
+ t.setdamage (ent, amount);
}
else if (ent.classname == "func_movewall")
{

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

Diff qc/func/shadow.qc

diff --git a/qc/func/shadow.qc b/qc/func/shadow.qc
index b4b6558..daa936e 100644
--- a/qc/func/shadow.qc
+++ b/qc/func/shadow.qc
@@ -2,6 +2,8 @@
// func_shadow -- An invisible bmodel that can be used to only cast shadows.
//==============================================================================

+.float speed2;
+
// constants
const float SHADOWCONTROLLER_STARTOFF = 1;

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

Diff qc/func/togglewall.qc

diff --git a/qc/func/togglewall.qc b/qc/func/togglewall.qc
index d9a86de..88df402 100644
--- a/qc/func/togglewall.qc
+++ b/qc/func/togglewall.qc
@@ -8,6 +8,9 @@
// All rights reserved.
// Distributed (unsupported) on 3.12.97

+// constants
+const float TOGGLEWALL_START_OFF = 1;
+
//----------------------------------------------------------------------
void() blocker_touch =
{
@@ -38,11 +41,11 @@ void() blocker_use =
}
};

-/*QUAKED func_togglewall (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+/*QUAKED func_togglewall (0 .5 .8) ? TOGGLEWALL_START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

Creates a invisible wall that can be toggled on and off.

-START_OFF wall doesn't block until triggered.
+TOGGLEWALL_START_OFF wall doesn't block until triggered.

"noise" is the sound to play when wall is turned off.
"noise1" is the sound to play when wall is blocking.
@@ -78,7 +81,7 @@ void() func_togglewall =
self.solid = SOLID_BSP;
self.model = string_null;

- if (self.spawnflags & START_OFF)
+ if (self.spawnflags & TOGGLEWALL_START_OFF)
{
self.state = 0;
setorigin (self, self.origin + '8000 8000 8000');

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

Diff qc/func/train.qc

diff --git a/qc/func/train.qc b/qc/func/train.qc
index a41bd5e..4e28eb3 100644
--- a/qc/func/train.qc
+++ b/qc/func/train.qc
@@ -2,6 +2,8 @@
// func_train
//==============================================================================

+.float speed2;
+
// constants
const float TRAIN_RETRIGGER = 1;
const float TRAIN_MOVEONTRIGGER = 2;

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

Diff qc/info/camera.qc

diff --git a/qc/info/camera.qc b/qc/info/camera.qc
new file mode 100644
index 0000000..b2fb64a
--- /dev/null
+++ b/qc/info/camera.qc
@@ -0,0 +1,68 @@
+//==============================================================================
+// info_movie_camera, info_focal_point -- was in cutscene.qc
+//==============================================================================
+
+/*QUAKED info_movie_camera (.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
+This is the destination marker for a camera. It should have a "targetname"
+field with the same value as a camera-trigger's "target" field.
+*/
+class info_movie_camera: entity
+{
+ //--------------------------------------------------------------
+ virtual void() imc_touch =
+ {
+ local string temps;
+
+ if (other.classname != "camera")
+ return;
+
+ temps = this.target;
+ this.target = this.message;
+ SUB_UseTargets ();
+ this.target = temps;
+ if (this.cnt)
+ return;
+
+ this.think = SUB_Remove;
+ this.nextthink = time + 10;
+ this.solid = SOLID_NOT;
+ };
+
+ //--------------------------------------------------------------
+ void() info_movie_camera =
+ {
+ // this does nothing, just serves as a target spot
+ /*
+ if (vision)
+ return;
+ */
+
+ // ...more than a spot in Zer mode.
+ // this.use = SUB_Null;
+ this.solid = SOLID_TRIGGER;
+ this.classname = "info_movie_camera";
+ this.classtype = CT_INFO_MOVIE_CAMERA;
+ setorigin (this, this.origin);
+ setsize (this, '-8 -8 -8', '8 8 8');
+ this.touch = this.imc_touch;
+ };
+};
+
+/*QUAKED info_focal_point (.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
+This is the point that the camera will face. It should have a "targetname"
+field with the same value as a camera-trigger's "focal_point" field.
+*/
+class info_focal_point: entity
+{
+ //--------------------------------------------------------------
+ void() info_focal_point =
+ {
+ // PM: This entity is kept only for map compatibility reasons.
+ // Otherwise, this entity is redundant. Use 'info_notnull'
+ // instead.
+
+ // just holds a spot for the focal point.
+ this.classname = "info_focal_point";
+ this.classtype = CT_INFO_FOCAL_POINT;
+ };
+};

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

Diff qc/info/notnull.qc

diff --git a/qc/info/notnull.qc b/qc/info/notnull.qc
new file mode 100644
index 0000000..6d4dbd6
--- /dev/null
+++ b/qc/info/notnull.qc
@@ -0,0 +1,21 @@
+//==============================================================================
+// info_notnull
+//==============================================================================
+
+/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) 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
+
+Never used in the or
+*/
+class info_notnull: entity
+{
+ //--------------------------------------------------------------
+ void() info_notnull =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "info_notnull";
+ this.classtype = CT_INFO_NOTNULL;
+ };
+};

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

Diff qc/info/null.qc

diff --git a/qc/info/null.qc b/qc/info/null.qc
new file mode 100644
index 0000000..42bff05
--- /dev/null
+++ b/qc/info/null.qc
@@ -0,0 +1,22 @@
+//==============================================================================
+// info_null
+//==============================================================================
+
+/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) 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
+
+Used as a positional target for spotlights, etc.
+*/
+class info_null: entity
+{
+ //--------------------------------------------------------------
+ void() info_null =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "info_null";
+ this.classtype = CT_INFO_NULL;
+ remove (this);
+ };
+};

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

Diff qc/info/teleport_changedest.qc

diff --git a/qc/info/teleport_changedest.qc b/qc/info/teleport_changedest.qc
new file mode 100644
index 0000000..2e1a6fc
--- /dev/null
+++ b/qc/info/teleport_changedest.qc
@@ -0,0 +1,96 @@
+//==============================================================================
+// info_teleport_changedest -- by Qmaster, from progs_dump 3
+//==============================================================================
+
+/*QUAKED info_teleport_changedest (0 0.5 0) (-4 -4 -4) (4 4 4) 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
+Allows a mapper to change the target of a teleport_trigger. Useful in maps where
+the player may fall into a void and the mapper wants to update where they "respawn"
+as they progress through the level. Could also be used for teleport puzzles and more.
+target = trigger_teleport to change
+message = new info_teleport_destination's targetname to switch to
+targetname = name of this entity so we can use it
+*/
+class info_teleport_changedest: entity
+{
+ // this is from Qmaster:
+ //
+ // "I created an info_teleport_changedest
+ // target = targetname of trigger_teleport to affect
+ // message = targetname of new info_teleport_destination (or
+ // whatever entity really) to now teleport to
+ //
+ // So that I can automatically update the teleporter under my coagula
+ // map as you progress rather than have a bunch of triggers that I
+ // need to killtarget. Falling is not fatal then, but it does put you
+ // back some. Works as a sorta checkpoint system but also builds on my
+ // older idea for saving time in coop implemented in my Terracity map
+ // eons ago.
+ //
+ // looking at vanilla, you would only need to change trig.target to
+ // match self.message if you were to add this."
+
+ //--------------------------------------------------------------
+ virtual void() changedest_use =
+ {
+ local entity trig;
+
+ trig = find (world, ::targetname, this.target);
+ if (!trig || trig.classtype != CT_TRIGGER_TELEPORT)
+ {
+ dprint ("\b[TELEPORT_DESTCHANGE]\b ");
+ dprint ("Cannot find trigger_teleport\n");
+ return;
+ }
+
+ trig.goalentity = find (world, ::targetname, this.message);
+ if (!trig.goalentity)
+ {
+ dprint ("\b[TELEPORT_DESTCHANGE]\b ");
+ dprint ("Cannot find teleport destination\n");
+ return;
+ }
+
+ makevectors (trig.goalentity.mangle);
+ trig.goalentity.movedir = v_forward;
+ trig.goalentity.pos1 = trig.goalentity.origin + 32 *
+ trig.goalentity.movedir;
+
+ // dumptruck_ds see comment above
+ trig.target = this.message;
+ };
+
+ //--------------------------------------------------------------
+ void() info_teleport_changedest =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "info_teleport_changedest";
+ this.classtype = CT_INFO_TELEPORT_CHANGEDEST;
+ this.use = this.changedest_use;
+
+ if (this.targetname == "")
+ {
+ dprint ("\b[ERROR]\b info_teleport_changedest ");
+ dprint ("with no targetname\n");
+ remove (this);
+ }
+
+ if (this.target == "")
+ {
+ dprint ("\b[ERROR]\b info_teleport_changedest ");
+ dprint ("with no target\n");
+ remove (this);
+ }
+
+ if (this.message == "")
+ {
+ dprint ("\b[ERROR]\b info_teleport_changedest ");
+ dprint ("with no message set for new destination\n");
+ remove (this);
+ }
+ };
+};
+
+

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

Diff qc/info/teleport_destination.qc

diff --git a/qc/info/teleport_destination.qc b/qc/info/teleport_destination.qc
new file mode 100644
index 0000000..d4c09fb
--- /dev/null
+++ b/qc/info/teleport_destination.qc
@@ -0,0 +1,79 @@
+//==============================================================================
+// info_teleport_destination, info_teleport_random -- with additions by CEV
+//==============================================================================
+
+//======================================================================
+// teleporter targets
+//======================================================================
+
+/*QUAKED info_teleport_destination (.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");
+}
+This is the destination marker for a teleporter. It should have a "targetname"
+field with the same value as a teleporter's "target" field.
+*/
+class info_teleport_destination: entity
+{
+ //--------------------------------------------------------------
+ void() info_teleport_destination =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ local vector end;
+
+ // this does nothing, just serves as a target spot
+ this.classname = "info_teleport_destination";
+ this.classtype = CT_INFO_TELEPORT_DESTINATION;
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+ this.model = "";
+
+ // drop teleporter exit to the floor if it's PM_TELEDROP units
+ // away -- CEV
+ end = this.origin + PM_TELEDROP;
+ tracebox (this.origin, this.mins, this.maxs, end, FALSE, this);
+ if (trace_allsolid || trace_startsolid || trace_fraction < 1)
+ {
+ droptofloor ();
+ // bump origin so player won't exit into floor -- CEV
+ // This was '0 0 24' but that was causing issues -- CEV
+ this.origin = this.origin + '0 0 27';
+ }
+ else
+ {
+ // instead apply the standard fixed Z offset -- CEV
+ this.origin = this.origin + '0 0 27';
+ }
+
+ if (!this.targetname)
+ if (this.target != __NULL__ && this.target != "")
+ // quake 3 compat -- CEV
+ this.targetname = this.target;
+ else
+ objerror ("no targetname");
+ };
+};
+
+/*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");
+}
+This is a random destination marker for a teleporter.
+*/
+class info_teleport_random: entity
+{
+ //--------------------------------------------------------------
+ void() info_teleport_random =
+ {
+ // this does nothing, just serves as a target spot
+ this.classname = "info_teleport_random";
+ this.classtype = CT_INFO_TELEPORT_RANDOM;
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+ this.model = "";
+ this.origin = this.origin + '0 0 27';
+ };
+};

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

Diff qc/items/ammo.qc

diff --git a/qc/items/ammo.qc b/qc/items/ammo.qc
index 3f17440..260fa32 100644
--- a/qc/items/ammo.qc
+++ b/qc/items/ammo.qc
@@ -5,11 +5,28 @@
// constants
const float WEAPON_BIG2 = 1;

+// fixed ammo respawn time
+const float AMMO_RESPAWN_TIME = 30; // ammo respawn time; id1 30s
+
+// ammunition maximums & small / big box contents
+const float AMMO_CELLS_SMALL = 6; // id1 6; small box of cells
+const float AMMO_CELLS_BIG = 12; // id1 12; large box of cells
+const float AMMO_CELLS_MAX = 100; // id1 maximum 100
+const float AMMO_NAILS_SMALL = 25; // id1 25; small box of nails
+const float AMMO_NAILS_BIG = 50; // id1 50; large box of nails
+const float AMMO_NAILS_MAX = 200; // id1 maximum 200
+const float AMMO_ROCKETS_SMALL = 5; // id1 5; small box of rockets
+const float AMMO_ROCKETS_BIG = 10; // id1 10; large box of rockets
+const float AMMO_ROCKETS_MAX = 100; // id1 maximum 100
+const float AMMO_SHELLS_SMALL = 20; // id1 20; small box of shells
+const float AMMO_SHELLS_BIG = 40; // id1 40; large box of shells
+const float AMMO_SHELLS_MAX = 100; // id1 maximum 100
+
//----------------------------------------------------------------------
void() ammo_touch =
{
local entity stemp;
- local float best;
+ local float best = 0;

// from Copper -- dumptruck_ds
if (!CheckValidTouch())
@@ -17,16 +34,18 @@ void() ammo_touch =

// 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 (other.classname == "player" && autocvar(cg_autoswitch, TRUE))
+ {
+ stemp = self;
+ self = other;
+ best = PlayerBestWeapon ();
+ self = stemp;
+ }

// shotgun
if (self.weapon == 1)
{
- if (other.ammo_shells >= 100)
+ if (other.ammo_shells >= AMMO_SHELLS_MAX)
return;
other.ammo_shells = other.ammo_shells + self.aflag;
}
@@ -34,7 +53,7 @@ void() ammo_touch =
// spikes
if (self.weapon == 2)
{
- if (other.ammo_nails >= 200)
+ if (other.ammo_nails >= AMMO_NAILS_MAX)
return;
other.ammo_nails = other.ammo_nails + self.aflag;
}
@@ -42,7 +61,7 @@ void() ammo_touch =
// rockets
if (self.weapon == 3)
{
- if (other.ammo_rockets >= 100)
+ if (other.ammo_rockets >= AMMO_ROCKETS_MAX)
return;
other.ammo_rockets = other.ammo_rockets + self.aflag;
}
@@ -50,7 +69,7 @@ void() ammo_touch =
// cells
if (self.weapon == 4)
{
- if (other.ammo_cells >= 100)
+ if (other.ammo_cells >= AMMO_CELLS_MAX)
return;
other.ammo_cells = other.ammo_cells + self.aflag;
}
@@ -65,30 +84,33 @@ void() ammo_touch =
stuffcmd (other, "bf\n");

// change to a better weapon if appropriate
-
- if (other.weapon == best)
+ if (other.classname == "player" && other.weapon == best &&
+ autocvar(cg_autoswitch, TRUE))
{
stemp = self;
self = other;
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
+ self.weapon = PlayerBestWeapon ();
+ PlayerSetCurrentAmmo ();
self = stemp;
}

// if changed current ammo, update it
- stemp = self;
- self = other;
- W_SetCurrentAmmo ();
- self = stemp;
+ if (other.classname == "player")
+ {
+ stemp = self;
+ self = other;
+ PlayerSetCurrentAmmo ();
+ 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);
+ CheckItemRespawn (self, AMMO_RESPAWN_TIME);
else if (deathmatch == 1)
// doesn't respawn in "deathmatch 2"
- self.nextthink = time + 30;
+ self.nextthink = time + AMMO_RESPAWN_TIME;
self.think = SUB_Regen;

activator = other;
@@ -130,7 +152,7 @@ void() item_shells =

if !(self.particles_offset)
self.particles_offset = '16 16 16';
- self.aflag = 40;
+ self.aflag = AMMO_SHELLS_BIG;
}
else
{
@@ -151,7 +173,7 @@ void() item_shells =

if !(self.particles_offset)
self.particles_offset = '12 12 12';
- self.aflag = 20;
+ self.aflag = AMMO_SHELLS_SMALL;
}
self.weapon = 1;
self.netname = "shells";
@@ -193,7 +215,7 @@ void() item_spikes =

if !(self.particles_offset)
self.particles_offset = '16 16 16';
- self.aflag = 50;
+ self.aflag = AMMO_NAILS_BIG;
}
else
{
@@ -214,7 +236,7 @@ void() item_spikes =

if !(self.particles_offset)
self.particles_offset = '12 12 12';
- self.aflag = 25;
+ self.aflag = AMMO_NAILS_SMALL;
}
self.weapon = 2;
self.netname = "nails";
@@ -253,7 +275,7 @@ void() item_rockets =
}

self.particles_offset = '16 8 16';
- self.aflag = 10;
+ self.aflag = AMMO_ROCKETS_BIG;
}
else
{
@@ -274,7 +296,7 @@ void() item_rockets =

if !(self.particles_offset)
self.particles_offset = '8 8 16';
- self.aflag = 5;
+ self.aflag = AMMO_ROCKETS_SMALL;
}
self.weapon = 3;
self.netname = "rockets";
@@ -316,7 +338,7 @@ void() item_cells =

if !(self.particles_offset)
self.particles_offset = '16 16 16';
- self.aflag = 12;
+ self.aflag = AMMO_CELLS_BIG;
}
else
{
@@ -337,7 +359,7 @@ void() item_cells =

if !(self.particles_offset)
self.particles_offset = '12 12 12';
- self.aflag = 6;
+ self.aflag = AMMO_CELLS_SMALL;
}
self.weapon = 4;
self.netname = "cells";

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
index 34aeeb4..7470e1e 100644
--- a/qc/items/armor.qc
+++ b/qc/items/armor.qc
@@ -2,6 +2,24 @@
// armor.qc
//==============================================================================

+// constants
+const float ARMOR_GREEN_ABSORB = 0.3; // absorb percent; id1 0.3
+const float ARMOR_GREEN_AMOUNT = 100; // amount per pickup; id1 100
+const float ARMOR_GREEN_MAX = 125; // id1 125
+
+const float ARMOR_YELLOW_ABSORB = 0.6; // id1 0.6
+const float ARMOR_YELLOW_AMOUNT = 150; // id1 150
+const float ARMOR_YELLOW_MAX = 175; // id1 175
+
+const float ARMOR_RED_ABSORB = 0.8; // id1 0.8
+const float ARMOR_RED_AMOUNT = 200; // id1 200
+const float ARMOR_RED_MAX = 225; // id1 225
+
+const float ARMOR_SHARD_AMOUNT = 5; // Q3 5
+
+const float ARMOR_RESPAWN_SP = 30; // id1 30s
+const float ARMOR_RESPAWN_DM = 20; // id1 20s
+
// prototypes
void() armor_touch;
void() shard_touch;
@@ -22,29 +40,47 @@ void() shard_touch =
{
// has armor
// Supa, check bounds, original armourvalue + 25
- if (other.items & IT_ARMOR1 && other.armorvalue >= 125)
+ if (other.items & IT_ARMOR1 &&
+ other.armorvalue >= ARMOR_GREEN_MAX)
+ {
return;
- if (other.items & IT_ARMOR2 && other.armorvalue >= 175)
+ }
+ if (other.items & IT_ARMOR2 &&
+ other.armorvalue >= ARMOR_YELLOW_MAX)
+ {
return;
- if (other.items & IT_ARMOR3 && other.armorvalue >= 225)
+ }
+ if (other.items & IT_ARMOR3 &&
+ other.armorvalue >= ARMOR_RED_MAX)
+ {
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;
+ if (other.items & IT_ARMOR1 &&
+ other.armorvalue >= ARMOR_GREEN_MAX)
+ {
+ other.armorvalue = ARMOR_GREEN_MAX;
+ }
+ else if (other.items & IT_ARMOR2 &&
+ other.armorvalue >= ARMOR_YELLOW_MAX)
+ {
+ other.armorvalue = ARMOR_YELLOW_MAX;
+ }
+ else if (other.items & IT_ARMOR3 &&
+ other.armorvalue >= ARMOR_RED_MAX)
+ {
+ other.armorvalue = ARMOR_RED_MAX;
+ }
}
else
{
// shard = Green armor level
- other.armortype = 0.3;
- other.armorvalue = 5;
+ other.armortype = ARMOR_GREEN_ABSORB;
+ other.armorvalue = ARMOR_SHARD_AMOUNT;
bit = IT_ARMOR1;
other.items = other.items - (other.items &
(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
@@ -54,10 +90,10 @@ void() shard_touch =

// Supa, SP respawning items support
if (!deathmatch)
- CheckItemRespawn (self, 30);
+ CheckItemRespawn (self, ARMOR_RESPAWN_SP);
else if (deathmatch == 1)
// doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
+ self.nextthink = time + ARMOR_RESPAWN_DM;
self.think = SUB_Regen;

if (self.obit_name != "")
@@ -77,7 +113,8 @@ void() shard_touch =
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);
+ sound_misc (other, CHAN_AUTO,"items/armor_shard_q3.wav",
+ 1, ATTN_NORM);

// dumptruck_ds custom models and sounds END
stuffcmd (other, "bf\n");
@@ -101,22 +138,25 @@ void() armor_touch =

if (self.classname == "item_armor1")
{
- type = 0.3;
- value = 100;
+ // green armor
+ type = ARMOR_GREEN_ABSORB;
+ value = ARMOR_GREEN_AMOUNT;
bit = IT_ARMOR1;
}
else if (self.classname == "item_armor2" ||
self.classname == "item_armor_combat")
{
- type = 0.6;
- value = 150;
+ // yellow armor
+ type = ARMOR_YELLOW_ABSORB;
+ value = ARMOR_YELLOW_AMOUNT;
bit = IT_ARMOR2;
}
else if (self.classname == "item_armorInv" ||
self.classname == "item_armor_body")
{
- type = 0.8;
- value = 200;
+ // red armor
+ type = ARMOR_RED_ABSORB;
+ value = ARMOR_RED_AMOUNT;
bit = IT_ARMOR3;
}
else
@@ -141,10 +181,10 @@ void() armor_touch =

// Supa, SP respawning items support
if (!deathmatch)
- CheckItemRespawn (self, 30);
+ CheckItemRespawn (self, ARMOR_RESPAWN_SP);
else if (deathmatch == 1)
// doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
+ self.nextthink = time + ARMOR_RESPAWN_DM;
self.think = SUB_Regen;

if (self.obit_name != "")
@@ -190,7 +230,7 @@ void() item_armor_shard =
precache_body_model ("progs/armshr.mdl");
// setmodel (self, "progs/armor.mdl");
body_model ("progs/armshr.mdl");
- precache_sound_misc ("dump/armsh1.wav");
+ precache_sound_misc ("items/armor_shard_q3.wav");
// dumptruck_ds custom models and sounds END
if !(self.skin)
self.skin = 0;

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

Diff qc/items/axe.qc

diff --git a/qc/items/axe.qc b/qc/items/axe.qc
new file mode 100644
index 0000000..cd60080
--- /dev/null
+++ b/qc/items/axe.qc
@@ -0,0 +1,88 @@
+//==============================================================================
+// items/axe.qc -- Ranger's Axe
+//==============================================================================
+
+// constants
+const float AXE_ATTACK_COOLDOWN = 0.5; //
+
+// prototypes
+void() player_axe1;
+void() player_axeb1;
+void() player_axec1;
+void() player_axed1;
+
+//----------------------------------------------------------------------
+// W_FireAxe
+//----------------------------------------------------------------------
+void() W_FireAxe =
+{
+ local vector source;
+ local vector org;
+
+ makevectors (self.v_angle);
+ source = self.origin + '0 0 16';
+ traceline (source, source + v_forward * 64, FALSE, self);
+ if (trace_fraction == 1.0)
+ return;
+ org = trace_endpos - v_forward * 4;
+
+ if (trace_ent.takedamage)
+ {
+ trace_ent.axhitme = 1;
+ SpawnBlood (org, '0 0 0', 20);
+ T_Damage (trace_ent, self, self, 20);
+ }
+ else
+ { // hit wall
+ sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_GUNSHOT);
+ WriteCoord (MSG_BROADCAST, org_x);
+ WriteCoord (MSG_BROADCAST, org_y);
+ WriteCoord (MSG_BROADCAST, org_z);
+ }
+};
+
+//----------------------------------------------------------------------
+void() weapon_axe_attack =
+{
+ local float r = random ();
+ sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
+
+ if (r < 0.25)
+ player_axe1 ();
+ else if (r<0.5)
+ player_axeb1 ();
+ else if (r<0.75)
+ player_axec1 ();
+ else
+ player_axed1 ();
+
+ self.attack_finished = time + AXE_ATTACK_COOLDOWN;
+};
+
+//======================================================================
+// 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 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ precache_model ("progs/g_axe.mdl");
+ setmodel (self, "progs/g_axe.mdl");
+ self.weapon = IT_AXE;
+ self.netname = "Axe";
+ self.touch = weapon_touch; // TODO CEV
+ setsize (self, '-16 -16 0', '16 16 56');
+ StartItem ();
+};
+
+//======================================================================
+// johnfitz
+//======================================================================

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

Diff qc/items/backpacks.qc

diff --git a/qc/items/backpacks.qc b/qc/items/backpacks.qc
index 5898e18..415bcc1 100644
--- a/qc/items/backpacks.qc
+++ b/qc/items/backpacks.qc
@@ -39,10 +39,13 @@ void() BackpackTouch =

// 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 (other.classname == "player" && autocvar(cg_autoswitch, TRUE))
+ {
+ stemp = self;
+ self = other;
+ best = PlayerBestWeapon ();
+ self = stemp;
+ }

// change weapons
other.ammo_shells = other.ammo_shells + self.ammo_shells;
@@ -105,19 +108,23 @@ void() BackpackTouch =

// 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
+ if (other.classname == "player")
+ {
+ 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 ();
+ Deathmatch_Weapon (old, new);
+ PlayerSetCurrentAmmo ();
+ }
};

//======================================================================
@@ -231,7 +238,9 @@ void() DropVial =
setsize (item, '-16 -16 0', '16 16 56');
item.touch = health_touch;
item.healamount = 5;
- item.healtype = 0;
+ // changed the healtype from 0 (rotten) to 2 (mega) to reflect
+ // health vial behavior in item_health_vial -- CEV
+ item.healtype = HEALTH_TYPE_MEGA;
item.noise = "items/r_item1.wav";

StartItem ();
@@ -400,11 +409,15 @@ void() item_backpack_message =
// 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 ();
+
+ if (other.classname == "player")
+ {
+ stuffcmd (other, "bf\n");
+ self = other;
+ bound_other_ammo ();
+ PlayerSetCurrentAmmo ();
+ }
};

// Some of this text is from Drake -- dumptruck_ds

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
index 598a4c4..cceb6a9 100644
--- a/qc/items/health.qc
+++ b/qc/items/health.qc
@@ -2,19 +2,33 @@
// HEALTH BOXES
//==============================================================================

-// constants
-const float H_ROTTEN = 1;
-const float H_MEGA = 2;
-const float H_VIAL = 4;
-
// fields
.float healamount, healtype;

+// constants flags
+const float HEALTH_ROTTEN = 1; // rotten health box
+const float HEALTH_MEGA = 2; // megahealth
+const float HEALTH_VIAL = 4; // vial (AKA bubble)
+
+// constants healtypes
+const float HEALTH_TYPE_ROTTEN = 0; // rotten box
+const float HEALTH_TYPE_NORMAL = 1; // normal box
+const float HEALTH_TYPE_MEGA = 2; // megahealth
+
+// constants amounts & respawn times
+const float HEALTH_ROTTEN_AMOUNT = 15; // rotten heal amount; id1 15
+const float HEALTH_NORMAL_AMOUNT = 25; // standard heal amount; id1 25
+const float HEALTH_MEGA_AMOUNT = 100; // megahealth amount; id1 100
+const float HEALTH_VIAL_AMOUNT = 5; // vial heal amount; Quake3 5
+const float HEALTH_RESPAWN_DM = 20; // deathmatch respawn time; id1 20
+const float HEALTH_RESPAWN_SP = 30; // singleplayer respawn time; id1 30
+const float HEALTH_RESPAWN_MEGA = 125; // fixed mega respawn time; pd3 125
+
// primitives
void() health_touch;
// void() item_megahealth_rot;

-//======================================================================
+//----------------------------------------------------------------------
// T_Heal: add health to an entity, limiting health to max_health
// "ignore" will ignore max_health limit
//----------------------------------------------------------------------
@@ -45,9 +59,6 @@ Rotten box heals 15 points.
Megahealth will add 100 health, then start to
rot the player back down to 100 health after 5 seconds.
*/
-//======================================================================
-// item_health
-//----------------------------------------------------------------------
void() item_health =
{
// new spawnflags for all entities -- iw
@@ -56,7 +67,7 @@ void() item_health =

self.touch = health_touch;

- if (self.spawnflags & H_ROTTEN)
+ if (self.spawnflags & HEALTH_ROTTEN)
{
if (!self.mdl_body && world.h_15_mdl)
self.mdl_body = world.h_15_mdl;
@@ -85,15 +96,15 @@ void() item_health =

// if !(self.healamount)
// set your custom health amount here -- dumptruck_ds
- self.healamount = 15;
- self.healtype = 0;
+ self.healamount = HEALTH_ROTTEN_AMOUNT;
+ self.healtype = HEALTH_TYPE_ROTTEN;
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.spawnflags & HEALTH_MEGA)
{
if (!self.mdl_body && world.h_mega_mdl)
self.mdl_body = world.h_mega_mdl;
@@ -120,8 +131,8 @@ void() item_health =

// if !(self.healamount)
// custom health amount -- dumptruck_ds
- self.healamount = 100;
- self.healtype = 2;
+ self.healamount = HEALTH_MEGA_AMOUNT;
+ self.healtype = HEALTH_TYPE_MEGA;
if !(self.particles_offset)
self.particles_offset = '16 16 16';
}
@@ -146,8 +157,8 @@ void() item_health =
self.snd_misc = "items/health1.wav";
self.noise = self.snd_misc;

- self.healamount = 25;
- self.healtype = 1;
+ self.healamount = HEALTH_NORMAL_AMOUNT;
+ self.healtype = HEALTH_TYPE_NORMAL;
if !(self.particles_offset)
self.particles_offset = '16 16 8';
// dumptruck_ds custom health models and sounds END
@@ -157,7 +168,7 @@ void() item_health =
StartItem ();
};

-//======================================================================
+//----------------------------------------------------------------------
// item_health_vial
//----------------------------------------------------------------------
void() item_health_vial =
@@ -180,16 +191,16 @@ void() item_health_vial =
self.snd_misc = "items/r_item1.wav";
self.noise = self.snd_misc;

- self.healamount = 5;
+ self.healamount = HEALTH_VIAL_AMOUNT;
// over heal and count down like mega health -- dumptruck_ds
- self.healtype = 2;
+ self.healtype = HEALTH_TYPE_MEGA;
setsize (self, '-16 -16 0', '16 16 56');
if !(self.particles_offset)
self.particles_offset = '0 0 0';
StartItem ();
};

-//======================================================================
+//----------------------------------------------------------------------
// health_touch
//----------------------------------------------------------------------
void() health_touch =
@@ -201,24 +212,27 @@ void() health_touch =
if (!CheckValidTouch())
return;

- if (self.healtype == 2)
+ if (self.healtype == HEALTH_TYPE_MEGA)
{
// Megahealth? Ignore max_health...
- if (other.health >= 250) return;
- if (!T_Heal(other, amount, 1)) return;
+ if (other.health >= 250)
+ return;
+ if (!T_Heal(other, amount, 1))
+ return;
}
else
{
- if (!T_Heal(other, amount, 0)) return;
+ if (!T_Heal(other, amount, 0))
+ return;
}

- sprint(other, "You receive ");
+ sprint (other, "You receive ");
s = ftos (amount);
- sprint(other, s);
- sprint(other, " health\n");
+ sprint (other, s);
+ sprint (other, " health\n");

// health touch sound
- // sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
+ // sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
// custom sounds -- dumptruck_ds
sound_misc (other, CHAN_AUTO, self.noise, 1, ATTN_NORM);

@@ -230,7 +244,7 @@ void() health_touch =
self.think = SUB_Regen;

// Megahealth = rot down the player's super health
- if (self.healtype == 2)
+ if (self.healtype == HEALTH_TYPE_MEGA)
{
// thanks ydrol!!!
other.megahealth_rottime = time + 5;
@@ -251,18 +265,18 @@ void() health_touch =
// item respawned). -- iw
//
if (!deathmatch)
- CheckItemRespawn (self, 30);
+ CheckItemRespawn (self, HEALTH_RESPAWN_SP);
else if (deathmatch == 1)
// doesn't respawn in "deathmatch 2"
- self.nextthink = time + 125;
+ self.nextthink = time + HEALTH_RESPAWN_MEGA;
}
else
{
if (!deathmatch)
- CheckItemRespawn (self, 30);
+ CheckItemRespawn (self, HEALTH_RESPAWN_SP);
else if (deathmatch == 1)
// doesn't respawn in "deathmatch 2"
- self.nextthink = time + 20;
+ self.nextthink = time + HEALTH_RESPAWN_DM;
}

activator = other;

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

Diff qc/items/misc.qc

diff --git a/qc/items/misc.qc b/qc/items/misc.qc
index 051d938..952722f 100644
--- a/qc/items/misc.qc
+++ b/qc/items/misc.qc
@@ -84,7 +84,7 @@ void() PlaceItem =

if (self.spawnflags & ITEM_SUSPENDED)
{
- //ijed Don't drop spawnflag
+ // ijed Don't drop spawnflag
self.movetype = MOVETYPE_FLY;
}
else

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

Diff qc/items/nailguns.qc

diff --git a/qc/items/nailguns.qc b/qc/items/nailguns.qc
new file mode 100644
index 0000000..3bc7fcb
--- /dev/null
+++ b/qc/items/nailguns.qc
@@ -0,0 +1,46 @@
+//==============================================================================
+// items/nailguns.qc -- nailgun weapons
+//==============================================================================
+
+// constants
+const float AMMO_NAILS_WP = 30; // nails on weapon pickup; id1 30
+
+/*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 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ 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 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ 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 ();
+};

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

Diff qc/items/powerups.qc

diff --git a/qc/items/powerups.qc b/qc/items/powerups.qc
index 4a81ec2..7c73c85 100644
--- a/qc/items/powerups.qc
+++ b/qc/items/powerups.qc
@@ -13,18 +13,20 @@ void() powerup_touch =
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;
- // }
+ /*
+ 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;
@@ -157,7 +159,6 @@ void() item_artifact_envirosuit =
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

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

Diff qc/items/shotguns.qc

diff --git a/qc/items/shotguns.qc b/qc/items/shotguns.qc
new file mode 100644
index 0000000..0b9b898
--- /dev/null
+++ b/qc/items/shotguns.qc
@@ -0,0 +1,59 @@
+//==============================================================================
+// items/shotguns.qc -- shotgun weapons
+//==============================================================================
+
+// constants
+const float AMMO_SHELLS_WP = 5; // shells on weapon pickup; id1 5
+
+//======================================================================
+// johnfitz new items -- dumptruck_ds from RRP and rubicon2
+//======================================================================
+
+/*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 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ precache_model ("progs/g_shotgu.mdl");
+ // new shotgun model by Starshipwaters
+ // - dumptruck_ds - removed 2 older shotguns that used spawnflags
+ setmodel (self, "progs/g_shotgu.mdl");
+ 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 =
+{
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ 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 ();
+};
+
+

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

Diff qc/items/weapons.qc

diff --git a/qc/items/weapons.qc b/qc/items/weapons.qc
index 734167c..876b69f 100644
--- a/qc/items/weapons.qc
+++ b/qc/items/weapons.qc
@@ -2,27 +2,31 @@
// items/weapons.qc -- weapons
//==============================================================================

-// prototypes
-float() W_BestWeapon;
+// constants
+const float AMMO_CELLS_WP = 15; // cells on weapon pickup; id1 15
+const float AMMO_ROCKETS_WP = 5; // rockets on weapon pickup; id1 5
+
+const float WEAPON_RESPAWN_TIME = 30; // as the name suggests; id1 30

//----------------------------------------------------------------------
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;
+ // these constants are defined in items/ammo.qc -- CEV
+ if (other.ammo_shells > AMMO_SHELLS_MAX)
+ other.ammo_shells = AMMO_SHELLS_MAX;
+ if (other.ammo_nails > AMMO_NAILS_MAX)
+ other.ammo_nails = AMMO_NAILS_MAX;
+ if (other.ammo_rockets > AMMO_ROCKETS_MAX)
+ other.ammo_rockets = AMMO_ROCKETS_MAX;
+ if (other.ammo_cells > AMMO_CELLS_MAX)
+ other.ammo_cells = AMMO_CELLS_MAX;
};

//----------------------------------------------------------------------
float(float w) RankForWeapon =
{
// 1997-12-23 Thunderbolt fix by Maddes recognize waterlevel
- if (self.waterlevel <= 1 && w == IT_LIGHTNING)
+ if (self.waterlevel <= WATERLEVEL_FEET && w == IT_LIGHTNING)
return 1;
if (w == IT_ROCKET_LAUNCHER)
return 2;
@@ -71,10 +75,13 @@ void() weapon_touch =

// 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 (other.classname == "player" && autocvar(cg_autoswitch, TRUE))
+ {
+ stemp = self;
+ self = other;
+ best = PlayerBestWeapon ();
+ self = stemp;
+ }

if (deathmatch == 2 || coop)
{
@@ -103,7 +110,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_shells;
new = IT_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
+ other.ammo_shells = other.ammo_shells + AMMO_SHELLS_WP;
}
else if (self.classname == "weapon_nailgun")
{
@@ -112,7 +119,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_nails;
new = IT_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
+ other.ammo_nails = other.ammo_nails + AMMO_NAILS_WP;
}
else if (self.classname == "weapon_supernailgun")
{
@@ -120,7 +127,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_rockets;
new = IT_SUPER_NAILGUN;
- other.ammo_nails = other.ammo_nails + 30;
+ other.ammo_nails = other.ammo_nails + AMMO_NAILS_WP;
}
else if (self.classname == "weapon_supershotgun")
{
@@ -128,7 +135,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_rockets;
new = IT_SUPER_SHOTGUN;
- other.ammo_shells = other.ammo_shells + 5;
+ other.ammo_shells = other.ammo_shells + AMMO_SHELLS_WP;
}
else if (self.classname == "weapon_rocketlauncher")
{
@@ -136,7 +143,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_rockets;
new = IT_ROCKET_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
+ other.ammo_rockets = other.ammo_rockets + AMMO_ROCKETS_WP;
}
else if (self.classname == "weapon_grenadelauncher")
{
@@ -144,7 +151,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_rockets;
new = IT_GRENADE_LAUNCHER;
- other.ammo_rockets = other.ammo_rockets + 5;
+ other.ammo_rockets = other.ammo_rockets + AMMO_ROCKETS_WP;
}
else if (self.classname == "weapon_lightning")
{
@@ -152,7 +159,7 @@ void() weapon_touch =
return;
hadammo = other.ammo_rockets;
new = IT_LIGHTNING;
- other.ammo_cells = other.ammo_cells + 15;
+ other.ammo_cells = other.ammo_cells + AMMO_CELLS_WP;
}
else
{
@@ -173,21 +180,25 @@ void() weapon_touch =
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 (other.classname == "player" && autocvar(cg_autoswitch, TRUE))
+ {
+ 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);
+
+ PlayerSetCurrentAmmo ();
+
+ self = stemp;
+ }

if (leave)
return;
@@ -197,10 +208,10 @@ void() weapon_touch =
self.solid = SOLID_NOT;
// Supa, SP respawning items support
if (!deathmatch)
- CheckItemRespawn (self, 30);
+ CheckItemRespawn (self, WEAPON_RESPAWN_TIME);
else if (deathmatch == 1)
// weapons never disappear in "deathmatch 2"
- self.nextthink = time + 30;
+ self.nextthink = time + WEAPON_RESPAWN_TIME;

self.think = SUB_Regen;

@@ -209,115 +220,6 @@ void() weapon_touch =
SUB_UseTargets ();
};

-//======================================================================
-// 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 =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- 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 =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/g_shotgu.mdl");
- // new shotgun model by Starshipwaters
- // - dumptruck_ds - removed 2 older shotguns that used spawnflags
- setmodel (self, "progs/g_shotgu.mdl");
- 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 =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- 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 =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- 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 =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- 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
@@ -358,7 +260,6 @@ void() weapon_rocketlauncher =
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

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

Diff qc/math.qc

diff --git a/qc/math.qc b/qc/math.qc
index 7559803..3803c1b 100644
--- a/qc/math.qc
+++ b/qc/math.qc
@@ -179,9 +179,9 @@ vector(vector ang) normalizeAngles =
//----------------------------------------------------------------------
vector(vector ang) normalizeAngles180 =
{
- ang_x = ((ang_x + 180) - floor ((ang_x + 180)/360) * 360) - 180;
- ang_y = ((ang_y + 180) - floor ((ang_y + 180)/360) * 360) - 180;
- ang_z = ((ang_z + 180) - floor ((ang_z + 180)/360) * 360) - 180;
+ ang_x = ((ang_x + 180) - floor ((ang_x + 180) / 360) * 360) - 180;
+ ang_y = ((ang_y + 180) - floor ((ang_y + 180) / 360) * 360) - 180;
+ ang_z = ((ang_z + 180) - floor ((ang_z + 180) / 360) * 360) - 180;

return ang;
};

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

Diff qc/misc/air_bubbles.qc

diff --git a/qc/misc/air_bubbles.qc b/qc/misc/air_bubbles.qc
index e9f4ded..1358c53 100644
--- a/qc/misc/air_bubbles.qc
+++ b/qc/misc/air_bubbles.qc
@@ -2,123 +2,123 @@
// air_bubbles
//==============================================================================

-// prototypes
-void() make_bubbles;
-void() bubble_remove;
-void() bubble_bob;
+class temp_bubbles: entity
+{
+ //--------------------------------------------------------------
+ virtual void() bubble_bob =
+ {
+ local float rnd1, rnd2, rnd3;
+
+ this.cnt = this.cnt + 1;
+ if (this.cnt == 4)
+ bubble_split ();
+ if (this.cnt == 20)
+ remove (this);
+
+ rnd1 = this.velocity_x + (-10 + (random() * 20));
+ rnd2 = this.velocity_y + (-10 + (random() * 20));
+ rnd3 = this.velocity_z + 10 + random() * 10;
+
+ if (rnd1 > 10)
+ rnd1 = 5;
+ if (rnd1 < -10)
+ rnd1 = -5;
+
+ if (rnd2 > 10)
+ rnd2 = 5;
+ if (rnd2 < -10)
+ rnd2 = -5;
+
+ if (rnd3 < 10)
+ rnd3 = 15;
+ if (rnd3 > 30)
+ rnd3 = 25;
+
+ this.velocity_x = rnd1;
+ this.velocity_y = rnd2;
+ this.velocity_z = rnd3;
+
+ this.nextthink = time + 0.5;
+ this.think = bubble_bob;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() bubble_remove =
+ {
+ if (other.classtype == this.classtype)
+ {
+ // dprint ("bump");
+ return;
+ }
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() bubble_split =
+ {
+ local temp_bubbles bubble;
+ bubble = spawn (temp_bubbles, frame: 1, cnt: 10,
+ origin: this.origin);
+ this.frame = 1;
+ this.cnt = 10;
+ if (this.waterlevel != WATERLEVEL_EYES)
+ remove (this);
+ };
+
+ void() temp_bubbles =
+ {
+ // make bubbles
+ setmodel (this, "progs/s_bubble.spr");
+ setorigin (this, this.origin);
+ this.movetype = MOVETYPE_NOCLIP;
+ this.solid = SOLID_NOT;
+ this.velocity = '0 0 15';
+ this.nextthink = time + 0.5;
+ this.think = bubble_bob;
+ // no touch function when spawning death bubbles -- CEV
+ this.touch = bubble_remove;
+ this.classname = "bubble";
+ this.classtype = CT_TEMP_BUBBLES;
+ this.frame = 0;
+ this.cnt = 0;
+ setsize (this, '-8 -8 -8', '8 8 8');
+ };
+};

/*QUAKED air_bubbles (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

air bubbles entity

*/
-void() air_bubbles =
+class air_bubbles: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (deathmatch)
+ //--------------------------------------------------------------
+ virtual void() make_bubbles =
{
- remove (self);
- return;
- }
-
- precache_model ("progs/s_bubble.spr");
- self.nextthink = time + 1;
- self.think = make_bubbles;
-};
+ local temp_bubbles bubble;

-//----------------------------------------------------------------------
-void() make_bubbles =
-{
- local entity bubble;
-
- bubble = spawn ();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = '0 0 15';
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 0;
- bubble.cnt = 0;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.nextthink = time + random() + 0.5;
- self.think = make_bubbles;
-};
-
-//----------------------------------------------------------------------
-void() bubble_split =
-{
- local entity bubble;
- bubble = spawn ();
- setmodel (bubble, "progs/s_bubble.spr");
- setorigin (bubble, self.origin);
- bubble.movetype = MOVETYPE_NOCLIP;
- bubble.solid = SOLID_NOT;
- bubble.velocity = self.velocity;
- bubble.nextthink = time + 0.5;
- bubble.think = bubble_bob;
- bubble.touch = bubble_remove;
- bubble.classname = "bubble";
- bubble.frame = 1;
- bubble.cnt = 10;
- setsize (bubble, '-8 -8 -8', '8 8 8');
- self.frame = 1;
- self.cnt = 10;
- if (self.waterlevel != 3)
- remove (self);
-};
+ bubble = spawn (temp_bubbles, origin: this.origin);
+ this.nextthink = time + random() + 0.5;
+ this.think = make_bubbles;
+ };

-//----------------------------------------------------------------------
-void() bubble_remove =
-{
- if (other.classname == self.classname)
+ //--------------------------------------------------------------
+ void() air_bubbles =
{
- // dprint ("bump");
- return;
- }
- remove (self);
-};
-
-//----------------------------------------------------------------------
-void() bubble_bob =
-{
- local float rnd1, rnd2, rnd3;
-
- self.cnt = self.cnt + 1;
- if (self.cnt == 4)
- bubble_split ();
- if (self.cnt == 20)
- remove (self);
-
- rnd1 = self.velocity_x + (-10 + (random() * 20));
- rnd2 = self.velocity_y + (-10 + (random() * 20));
- rnd3 = self.velocity_z + 10 + random() * 10;
-
- if (rnd1 > 10)
- rnd1 = 5;
- if (rnd1 < -10)
- rnd1 = -5;
-
- if (rnd2 > 10)
- rnd2 = 5;
- if (rnd2 < -10)
- rnd2 = -5;
-
- if (rnd3 < 10)
- rnd3 = 15;
- if (rnd3 > 30)
- rnd3 = 25;
-
- self.velocity_x = rnd1;
- self.velocity_y = rnd2;
- self.velocity_z = rnd3;
-
- self.nextthink = time + 0.5;
- self.think = bubble_bob;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (deathmatch)
+ {
+ remove (this);
+ return;
+ }
+
+ this.classname = "air_bubbles";
+ this.classtype = CT_MISC_AIR_BUBBLES;
+ precache_model ("progs/s_bubble.spr");
+ this.nextthink = time + 1;
+ this.think = make_bubbles;
+ };
};

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

Diff qc/misc/ambient_sound.qc

diff --git a/qc/misc/ambient_sound.qc b/qc/misc/ambient_sound.qc
index 8a500c8..9e7ebb2 100644
--- a/qc/misc/ambient_sound.qc
+++ b/qc/misc/ambient_sound.qc
@@ -2,6 +2,101 @@
// ambient_sound -- miscellaneous ambient sound entities
//==============================================================================

+// constants
+const string SND_AMBIENTCOMPHUM = "ambience/comp1.wav";
+const string SND_AMBIENTDRIP = "ambience/drip1.wav";
+const string SND_AMBIENTDRONE = "ambience/drone6.wav";
+const string SND_AMBIENTFIRE = "ambience/fire1.wav";
+const string SND_AMBIENTFBUZZ = "ambience/buzz1.wav";
+const string SND_AMBIENTLBUZZ = "ambience/fl_hum1.wav";
+const string SND_AMBIENTSWIND = "ambience/suck1.wav";
+const string SND_AMBIENTSWAMP1 = "ambience/swamp1.wav";
+const string SND_AMBIENTSWAMP2 = "ambience/swamp2.wav";
+const string SND_AMBIENTWATER1 = "ambience/water1.wav";
+const string SND_AMBIENTWIND2 = "ambience/wind2.wav";
+const string SND_AMBIENTHUNDER = "ambience/thunder1.wav";
+
+class base_ambient_sound: entity
+{
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_fire =
+ {
+ precache_sound (SND_AMBIENTFIRE);
+ // attenuate fast
+ ambientsound (source, SND_AMBIENTFIRE, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_comphum =
+ {
+ precache_sound (SND_AMBIENTCOMPHUM);
+ ambientsound (source, SND_AMBIENTCOMPHUM, 1, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_drip =
+ {
+ precache_sound (SND_AMBIENTDRIP);
+ ambientsound (source, SND_AMBIENTDRIP, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_drone =
+ {
+ precache_sound (SND_AMBIENTDRONE);
+ ambientsound (source, SND_AMBIENTDRONE, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_fbuzz =
+ {
+ precache_sound (SND_AMBIENTFBUZZ);
+ ambientsound (source, SND_AMBIENTFBUZZ, 1, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_lbuzz =
+ {
+ precache_sound (SND_AMBIENTLBUZZ);
+ ambientsound (source, SND_AMBIENTLBUZZ, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_suckwind =
+ {
+ precache_sound (SND_AMBIENTSWIND);
+ ambientsound (source, SND_AMBIENTSWIND, 1, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_swamp1 =
+ {
+ precache_sound (SND_AMBIENTSWAMP1);
+ ambientsound (source, SND_AMBIENTSWAMP1, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_swamp2 =
+ {
+ precache_sound (SND_AMBIENTSWAMP1);
+ ambientsound (source, SND_AMBIENTSWAMP2, 0.5, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_water1 =
+ {
+ precache_sound (SND_AMBIENTWATER1);
+ ambientsound (source, SND_AMBIENTWATER1, 1, ATTN_STATIC);
+ };
+
+ //--------------------------------------------------------------
+ static void(vector source) ambient_sound_wind2 =
+ {
+ precache_sound (SND_AMBIENTWIND2);
+ ambientsound (source, SND_AMBIENTWIND2, 1, ATTN_STATIC);
+ };
+};
+
//======================================================================
//johnfitz -- ambient_general (this is from Rubicon Rumble dev kit)
//======================================================================
@@ -17,68 +112,80 @@ Keys:

"speed" attenuation, default 3
*/
-void() ambient_general =
+class ambient_general: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // dumptruck_ds
- if (!self.noise)
- {
- objerror ("no soundfile set in noise!\n");
- remove (self);
- return;
- }
-
- precache_sound (self.noise);
-
- if (!self.speed)
- {
- self.speed = ATTN_NORM;
- }
-
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
-
- if (!self.volume)
+ //--------------------------------------------------------------
+ void() ambient_general =
{
- self.volume = 0.5;
- }
-
- ambientsound (self.origin, self.noise, self.volume, self.speed);
- remove (self);
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_general";
+ this.classtype = CT_MISC_AMBIENT_GENERAL;
+
+ // dumptruck_ds
+ if (!this.noise)
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove (this);
+ return;
+ }
+
+ precache_sound (this.noise);
+
+ if (!this.speed)
+ this.speed = ATTN_NORM;
+ if (this.speed == 0)
+ this.speed = 1;
+ if (this.speed == -1)
+ // this.speed = 0;
+ this.speed = ATTN_NONE;
+
+ if (!this.volume)
+ this.volume = 0.5;
+
+ ambientsound (this.origin, this.noise, this.volume, this.speed);
+ remove (this);
+ };
};

//======================================================================

/*QUAKED FireAmbient (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
*/
-void() FireAmbient =
+class FireAmbient: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/fire1.wav");
- // attenuate fast
- ambientsound (self.origin, "ambience/fire1.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() FireAmbient =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "FireAmbient";
+ this.classtype = CT_MISC_AMBIENT_FIRE;
+ ambient_sound_fire (this.origin);
+ };
};

/*QUAKED ambient_fire (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
ambinet fire sound effects added for consistency
same as FireAmbient
*/
-void() ambient_fire =
+class ambient_fire: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- FireAmbient ();
+ //--------------------------------------------------------------
+ void() ambient_fire =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_fire";
+ this.classtype = CT_MISC_AMBIENT_FIRE;
+ ambient_sound_fire (this.origin);
+ };
};

//======================================================================
@@ -86,98 +193,138 @@ void() ambient_fire =
/*QUAKED ambient_comp_hum (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

*/
-void() ambient_comp_hum =
+class ambient_comp_hum: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/comp1.wav");
- ambientsound (self.origin, "ambience/comp1.wav", 1, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_comp_hum =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_comp_hum";
+ this.classtype = CT_MISC_AMBIENT_COMPHUM;
+ ambient_sound_comphum (this.origin);
+ };
};

/*QUAKED ambient_drip (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_drip =
+class ambient_drip: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/drip1.wav");
- ambientsound (self.origin, "ambience/drip1.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_drip =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_drip";
+ this.classtype = CT_MISC_AMBIENT_DRIP;
+ ambient_sound_drip (this.origin);
+ };
};

/*QUAKED ambient_drone (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_drone =
+class ambient_drone: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/drone6.wav");
- ambientsound (self.origin, "ambience/drone6.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_drone =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_drone";
+ this.classtype = CT_MISC_AMBIENT_DRONE;
+ ambient_sound_drone (this.origin);
+ };
};

/*QUAKED ambient_flouro_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_flouro_buzz =
+class ambient_flouro_buzz: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/buzz1.wav");
- ambientsound (self.origin, "ambience/buzz1.wav", 1, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_flouro_buzz =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_fluoro_buzz";
+ this.classtype = CT_MISC_AMBIENT_FBUZZ;
+ ambient_sound_fbuzz (this.origin);
+ };
};

/*QUAKED ambient_light_buzz (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_light_buzz =
+class ambient_light_buzz: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/fl_hum1.wav");
- ambientsound (self.origin, "ambience/fl_hum1.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_light_buzz =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_light_buzz";
+ this.classtype = CT_MISC_AMBIENT_LBUZZ;
+ ambient_sound_lbuzz (this.origin);
+ };
};

/*QUAKED ambient_suck_wind (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_suck_wind =
+class ambient_suck_wind: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/suck1.wav");
- ambientsound (self.origin, "ambience/suck1.wav", 1, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_suck_wind =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_suck_wind";
+ this.classtype = CT_MISC_AMBIENT_SUCKWIND;
+ ambient_sound_suckwind (this.origin);
+ };
};

/*QUAKED ambient_swamp1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_swamp1 =
+class ambient_swamp1: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/swamp1.wav");
- ambientsound (self.origin, "ambience/swamp1.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_swamp1 =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_swamp1";
+ this.classtype = CT_MISC_AMBIENT_SWAMP1;
+ ambient_sound_swamp1 (this.origin);
+ };
};

/*QUAKED ambient_swamp2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_swamp2 =
+class ambient_swamp2: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/swamp2.wav");
- ambientsound (self.origin, "ambience/swamp2.wav", 0.5, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_swamp2 =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_swamp2";
+ this.classtype = CT_MISC_AMBIENT_SWAMP2;
+ ambient_sound_swamp2 (this.origin);
+ };
};

//======================================================================
@@ -193,26 +340,36 @@ void() ambient_swamp2 =

/*QUAKED ambient_water1 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_water1 =
+class ambient_water1: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/water1.wav");
- ambientsound (self.origin, "ambience/water1.wav", 1, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_water1 =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_water1";
+ this.classtype = CT_MISC_AMBIENT_WATER1;
+ ambient_sound_water1 (this.origin);
+ };
};

/*QUAKED ambient_wind2 (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
*/
-void() ambient_wind2 =
+class ambient_wind2: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_sound ("ambience/wind2.wav");
- ambientsound (self.origin, "ambience/wind2.wav", 1, ATTN_STATIC);
+ //--------------------------------------------------------------
+ void() ambient_wind2 =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_wind2";
+ this.classtype = CT_MISC_AMBIENT_WIND2;
+ ambient_sound_wind2 (this.origin);
+ };
};

/////////////////////////////////////////////////////////////
@@ -221,22 +378,10 @@ void() ambient_wind2 =

// The original ambient_thunder was included in Quake but the code was missing.
// This version is borrowed from the Zerstörer mod but modified to only play the
-// original thumder1.wav included in the game. This is also different than the
-// other ambient sounds as it plays back randomly as opposed to looping. You
+// original thunder1.wav included in the game. This is also different than the
+// other ambient sounds as it plays back randomly as opposed to looping. You
// only need one of these in your level. It will play everywhere.

-//----------------------------------------------------------------------
-void() thunder_go_boom =
-{
- if (random() < 0.5)
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 0.7, ATTN_NONE);
- else
- sound (self, CHAN_AUTO, "ambience/thunder1.wav", 1, ATTN_NONE);
-
- self.think = thunder_go_boom;
- self.nextthink = time + 40 * random ();
-};
-
/*QUAKED ambient_thunder (0.3 0.1 0.6) (-10 -10 -8) (10 10 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
The original ambient_thunder was included in Quake but the code was missing.
This version is borrowed from the Zerstörer mod but modified to only play the
@@ -244,16 +389,37 @@ original thumder1.wav included in the game. This is also different than the
other ambient sounds as it plays back randomly as opposed to looping. You
only need one of these in your level. It will play everywhere.
*/
-void() ambient_thunder =
+class ambient_thunder: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // changed from ambient to delayed sound (sounds better)
- precache_sound ("ambience/thunder1.wav");
- // this file in not included in the game
- // precache_sound ("ambience/thunder2.wav");
- self.think = thunder_go_boom;
- self.nextthink = time + random ();
+ //--------------------------------------------------------------
+ virtual void() thunder_go_boom =
+ {
+ if (random() < 0.5)
+ sound (this, CHAN_AUTO, SND_AMBIENTHUNDER,
+ 0.7, ATTN_NONE);
+ else
+ sound (this, CHAN_AUTO, SND_AMBIENTHUNDER,
+ 1, ATTN_NONE);
+
+ this.think = thunder_go_boom;
+ this.nextthink = time + 40 * random ();
+ };
+
+ //--------------------------------------------------------------
+ void() ambient_thunder =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "ambient_thunder";
+ this.classtype = CT_MISC_AMBIENT_THUNDER;
+
+ // changed from ambient to delayed sound (sounds better)
+ precache_sound (SND_AMBIENTHUNDER);
+ // this file in not included in the game
+ // precache_sound ("ambience/thunder2.wav");
+ this.think = thunder_go_boom;
+ this.nextthink = time + random ();
+ };
};

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

Diff qc/misc/deadstuff.qc

diff --git a/qc/misc/deadstuff.qc b/qc/misc/deadstuff.qc
index 3bfbd42..d91fd69 100644
--- a/qc/misc/deadstuff.qc
+++ b/qc/misc/deadstuff.qc
@@ -11,25 +11,31 @@
model ("progs/h_demon.mdl");
}
*/
-void() gib_head_demon =
+class gib_head_demon: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_demon.mdl");
- setmodel (self, "progs/h_demon.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize(self,'-13.64 -16.77 -0.11','17.44 16.22 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_demon =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_demon";
+ this.classtype = CT_GIB_HEAD_DEMON;
+ precache_model ("progs/h_demon.mdl");
+ setmodel (this, "progs/h_demon.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-13.64 -16.77 -0.11','17.44 16.22 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_dog (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -37,25 +43,31 @@ void() gib_head_demon =
model ("progs/h_dog.mdl");
}
*/
-void() gib_head_dog =
+class gib_head_dog: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_dog.mdl");
- setmodel (self, "progs/h_dog.mdl");
- self.frame = 0; // was 1 -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_dog =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_dog";
+ this.classtype = CT_GIB_HEAD_DOG;
+ precache_model ("progs/h_dog.mdl");
+ setmodel (this, "progs/h_dog.mdl");
+ this.frame = 0; // was 1 -- dumptruck_ds
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-9.66 -11.89 -0.2','6.57 7.96 13.29');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_army (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -63,75 +75,91 @@ void() gib_head_dog =
model ("progs/h_guard.mdl");
}
*/
-void() gib_head_army =
+class gib_head_army: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_guard.mdl");
- setmodel (self, "progs/h_guard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_army =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ precache_model ("progs/h_guard.mdl");
+ setmodel (this, "progs/h_guard.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-9.67 -8.27 -0.28','4.05 4.8 13.41');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_hell_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_hellkn.mdl");
}*/
-void() gib_head_hell_knight =
+class gib_head_hell_knight: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_hellkn.mdl");
- setmodel (self, "progs/h_hellkn.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
+ //--------------------------------------------------------------
+ void() gib_head_hell_knight =
{
- self.solid = SOLID_BBOX;
- setsize (self,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_hell_knight";
+ this.classtype = CT_GIB_HEAD_HELL_KNIGHT;
+ precache_model ("progs/h_hellkn.mdl");
+ setmodel (this, "progs/h_hellkn.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-7.9 -12.97 -0.63','10.55 8.87 21.06');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_knight (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_knight.mdl");
}*/
-void() gib_head_knight =
+class gib_head_knight: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_knight.mdl");
- setmodel (self, "progs/h_knight.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
+ //--------------------------------------------------------------
+ void() gib_head_knight =
{
- self.solid = SOLID_BBOX;
- setsize (self,'-8.17 -7.47 -0.13','8.36 6.5 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_knight";
+ this.classtype = CT_GIB_HEAD_KNIGHT;
+ precache_model ("progs/h_knight.mdl");
+ setmodel (this, "progs/h_knight.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-8.17 -7.47 -0.13','8.36 6.5 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_enforcer (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -139,223 +167,277 @@ void() gib_head_knight =
model ("progs/h_mega.mdl");
}
*/
-void() gib_head_enforcer =
+class gib_head_enforcer: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_mega.mdl");
- setmodel (self, "progs/h_mega.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-10.63 -10.23 -0.05','9.27 8.25 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_enforcer =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_enforcer";
+ this.classtype = CT_GIB_HEAD_ENFORCER;
+ precache_model ("progs/h_mega.mdl");
+ setmodel (this, "progs/h_mega.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-10.63 -10.23 -0.05','9.27 8.25 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_ogre (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_ogre.mdl");
}*/
-void() gib_head_ogre =
+class gib_head_ogre: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_ogre.mdl");
- setmodel (self, "progs/h_ogre.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-12.35 -15.7 -0.17','10.67 13.88 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_ogre =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_ogre";
+ this.classtype = CT_GIB_HEAD_OGRE;
+ precache_model ("progs/h_ogre.mdl");
+ setmodel (this, "progs/h_ogre.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-12.35 -15.7 -0.17','10.67 13.88 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_player (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_player.mdl");
}*/
-void() gib_head_player =
+class gib_head_player: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_player.mdl");
- setmodel (self, "progs/h_player.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-9.67 -12.38 -2.1','11.49 50.7 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_player =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_player";
+ this.classtype = CT_GIB_HEAD_PLAYER;
+ precache_model ("progs/h_player.mdl");
+ setmodel (this, "progs/h_player.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-9.67 -12.38 -2.1','11.49 50.7 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_shalrath (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_shal.mdl");
}*/
-void() gib_head_shalrath =
+class gib_head_shalrath: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_shal.mdl");
- setmodel (self, "progs/h_shal.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-19.85 -19.09 -1.44','13.72 16.8 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_shalrath =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_shalrath";
+ this.classtype = CT_GIB_HEAD_SHALRATH;
+ precache_model ("progs/h_shal.mdl");
+ setmodel (this, "progs/h_shal.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-19.85 -19.09 -1.44','13.72 16.8 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_shambler (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_shams.mdl");
}*/
-void() gib_head_shambler =
+class gib_head_shambler: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_shams.mdl");
- setmodel (self, "progs/h_shams.mdl");
- self.frame = 0; // was 1, caused an error -- dumptruck_ds
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-15.15 -20.638 -0.45','21.44 21.76 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_head_shambler =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_shambler";
+ this.classtype = CT_GIB_HEAD_SHAMBLER;
+ precache_model ("progs/h_shams.mdl");
+ setmodel (this, "progs/h_shams.mdl");
+ this.frame = 0; // was 1, caused an error -- dumptruck_ds
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-15.15 -20.638 -0.45','21.44 21.76 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_head_wizard (0 0.5 0.8) (-16 -16 0) (16 16 56) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/h_wizard.mdl");
}*/
-void() gib_head_wizard =
+class gib_head_wizard: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/h_wizard.mdl");
- setmodel (self, "progs/h_wizard.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
+ //--------------------------------------------------------------
+ void() gib_head_wizard =
{
- self.solid = SOLID_BBOX;
- setsize (self,'-10.41 -8.66 -0.54','6.52 10.82 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_head_wizard";
+ this.classtype = CT_GIB_HEAD_WIZARD;
+ precache_model ("progs/h_wizard.mdl");
+ setmodel (this, "progs/h_wizard.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-10.41 -8.66 -0.54','6.52 10.82 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_misc_1 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib1.mdl");
}*/
-void() gib_misc_1 =
+class gib_misc_1: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/gib1.mdl");
- setmodel (self, "progs/gib1.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
+ //--------------------------------------------------------------
+ void() gib_misc_1 =
{
- self.solid = SOLID_BBOX;
- setsize (self,'-3.57 -8.06 -3.34','3.69 8.31 30');
- }
- else
- {
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_misc_1";
+ this.classtype = CT_GIB_MISC_1;
+ precache_model ("progs/gib1.mdl");
+ setmodel (this, "progs/gib1.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-3.57 -8.06 -3.34','3.69 8.31 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_misc_2 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib2.mdl");
}*/
-void() gib_misc_2 =
+class gib_misc_2: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/gib2.mdl");
- setmodel (self, "progs/gib2.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-12.68 -14.83 -6.19','13.53 14.57 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_misc_2 =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_misc_2";
+ this.classtype = CT_GIB_MISC_2;
+ precache_model ("progs/gib2.mdl");
+ setmodel (this, "progs/gib2.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-12.68 -14.83 -6.19','13.53 14.57 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

/*QUAKED gib_misc_3 (0 0.5 0.8) (-8 -8 -8) (8 8 8) SOLID X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{
model ("progs/gib3.mdl");
}*/
-void() gib_misc_3 =
+class gib_misc_3: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/gib3.mdl");
- setmodel (self, "progs/gib3.mdl");
- self.frame = 0;
-
- if (self.spawnflags & 1)
- {
- self.solid = SOLID_BBOX;
- setsize (self,'-18.95 -15.92 -3.13','13.17 15.66 30');
- }
- else
+ //--------------------------------------------------------------
+ void() gib_misc_3 =
{
- self.solid = SOLID_NOT;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "gib_misc_3";
+ this.classtype = CT_GIB_MISC_3;
+ precache_model ("progs/gib3.mdl");
+ setmodel (this, "progs/gib3.mdl");
+ this.frame = 0;
+
+ if (this.spawnflags & 1)
+ {
+ this.solid = SOLID_BBOX;
+ setsize (this,'-18.95 -15.92 -3.13','13.17 15.66 30');
+ }
+ else
+ {
+ this.solid = SOLID_NOT;
+ }
+ };
};

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

Diff qc/misc/explobox.qc

diff --git a/qc/misc/explobox.qc b/qc/misc/explobox.qc
index 9fff181..dd3f8c5 100644
--- a/qc/misc/explobox.qc
+++ b/qc/misc/explobox.qc
@@ -3,17 +3,20 @@
//==============================================================================

//----------------------------------------------------------------------
-void() barrel_explode =
+class base_explobox: entity
{
- self.takedamage = DAMAGE_NO;
- self.classname = "explo_box";
- // did say self.owner
- T_RadiusDamage (self, self, 160, world);
- sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- particle (self.origin, '0 0 0', 75, 255);
+ virtual void() barrel_explode =
+ {
+ this.takedamage = DAMAGE_NO;
+ this.classname = "explo_box";
+ // did say this.owner
+ T_RadiusDamage (this, this, 160, world);
+ sound (this, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ particle (this.origin, '0 0 0', 75, 255);

- self.origin_z = self.origin_z + 32;
- BecomeExplosion ();
+ this.origin_z = this.origin_z + 32;
+ BecomeExplosion ();
+ };
};

/*QUAKED misc_explobox (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -22,36 +25,42 @@ void() barrel_explode =
}
Explosive box
*/
-void() misc_explobox =
+class misc_explobox: base_explobox
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() misc_explobox =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- local float oldz;
+ local float oldz;

- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model ("maps/b_explob.bsp");
- setmodel (self, "maps/b_explob.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
- // fix by Maddes/Kryten
- self.touch = monster_touch;
+ this.classname = "misc_explobox";
+ this.classtype = CT_MISC_EXPLOBOX;
+ this.solid = SOLID_BBOX;
+ this.movetype = MOVETYPE_NONE;
+ precache_model ("maps/b_explob.bsp");
+ setmodel (this, "maps/b_explob.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ this.health = 20;
+ this.th_die = barrel_explode;
+ this.takedamage = DAMAGE_AIM;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten
+ this.touch = monster_touch;

- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor ();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove (self);
- }
+ this.origin_z = this.origin_z + 2;
+ oldz = this.origin_z;
+ droptofloor ();
+ if (oldz - this.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(this.origin));
+ dprint ("\n");
+ remove (this);
+ }
+ };
};

/*QUAKED misc_explobox2 (0 .5 .8) (0 0 0) (32 32 64) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -60,34 +69,40 @@ void() misc_explobox =
}
Smaller explosive box
*/
-void() misc_explobox2 =
+class misc_explobox2: base_explobox
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() misc_explobox2 =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- local float oldz;
+ local float oldz;

- self.solid = SOLID_BBOX;
- self.movetype = MOVETYPE_NONE;
- precache_model2 ("maps/b_exbox2.bsp");
- setmodel (self, "maps/b_exbox2.bsp");
- precache_sound ("weapons/r_exp3.wav");
- self.health = 20;
- self.th_die = barrel_explode;
- self.takedamage = DAMAGE_AIM;
- // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
- // fix by Maddes/Kryten
- self.touch = monster_touch;
+ this.classname = "misc_explobox2";
+ this.classtype = CT_MISC_EXPLOBOX2;
+ this.solid = SOLID_BBOX;
+ this.movetype = MOVETYPE_NONE;
+ precache_model2 ("maps/b_exbox2.bsp");
+ setmodel (this, "maps/b_exbox2.bsp");
+ precache_sound ("weapons/r_exp3.wav");
+ this.health = 20;
+ this.th_die = barrel_explode;
+ this.takedamage = DAMAGE_AIM;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten
+ this.touch = monster_touch;

- self.origin_z = self.origin_z + 2;
- oldz = self.origin_z;
- droptofloor ();
- if (oldz - self.origin_z > 250)
- {
- dprint ("item fell out of level at ");
- dprint (vtos(self.origin));
- dprint ("\n");
- remove (self);
- }
+ this.origin_z = this.origin_z + 2;
+ oldz = this.origin_z;
+ droptofloor ();
+ if (oldz - this.origin_z > 250)
+ {
+ dprint ("item fell out of level at ");
+ dprint (vtos(this.origin));
+ dprint ("\n");
+ remove (this);
+ }
+ };
};

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

Diff qc/misc/fireball.qc

diff --git a/qc/misc/fireball.qc b/qc/misc/fireball.qc
index 39427e1..52de1b6 100644
--- a/qc/misc/fireball.qc
+++ b/qc/misc/fireball.qc
@@ -2,60 +2,64 @@
// misc_fireball
//==============================================================================

-// prototypes
-void() fire_fly;
-void() fire_touch;
-
/*QUAKED misc_fireball (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model ("progs/lavaball.mdl"); }
Flying lava balls
speed - set vertical speed of fireballs. default 1000.
*/
-void() misc_fireball =
+class misc_fireball: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() fire_touch =
+ {
+ T_Damage (other, this, this, 20);
+ remove (this);
+ };
+ //--------------------------------------------------------------
+ nonvirtual void() fire_fly =
+ {
+ local entity fireball;

- precache_model ("progs/lavaball.mdl");
- self.classname = "fireball";
- // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
- // self.nextthink = time + (random() * 5);
- self.nextthink = time + 0.1 + (random() * 5);
- // 1998-08-14 Incorrect setting of nextthink fix by Maddes/Lord Sméagol
- self.think = fire_fly;
- if (!self.speed)
- // fixed typo QIP - dumptruck_ds
- self.speed = 1000;
-};
+ fireball = spawn ();
+ fireball.solid = SOLID_TRIGGER;
+ fireball.movetype = MOVETYPE_TOSS;
+ fireball.velocity = '0 0 1000';
+ fireball.velocity_x = (random() * 100) - 50;
+ fireball.velocity_y = (random() * 100) - 50;
+ fireball.velocity_z = this.speed + (random() * 200);
+ fireball.classname = "fireball";
+ setmodel (fireball, "progs/lavaball.mdl");
+ setsize (fireball, '0 0 0', '0 0 0');
+ setorigin (fireball, this.origin);
+ fireball.nextthink = time + 5;
+ fireball.think = SUB_Remove;
+ fireball.touch = fire_touch;

-//----------------------------------------------------------------------
-void() fire_fly =
-{
- local entity fireball;
+ this.nextthink = time + (random() * 5) + 3;
+ this.think = fire_fly;
+ };

- fireball = spawn ();
- fireball.solid = SOLID_TRIGGER;
- fireball.movetype = MOVETYPE_TOSS;
- fireball.velocity = '0 0 1000';
- fireball.velocity_x = (random() * 100) - 50;
- fireball.velocity_y = (random() * 100) - 50;
- fireball.velocity_z = self.speed + (random() * 200);
- fireball.classname = "fireball";
- setmodel (fireball, "progs/lavaball.mdl");
- setsize (fireball, '0 0 0', '0 0 0');
- setorigin (fireball, self.origin);
- fireball.nextthink = time + 5;
- fireball.think = SUB_Remove;
- fireball.touch = fire_touch;
+ //--------------------------------------------------------------
+ void() misc_fireball =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- self.nextthink = time + (random() * 5) + 3;
- self.think = fire_fly;
-};
+ this.classname = "fireball";
+ // this.classname = "misc_fireball";
+ this.classtype = CT_MISC_FIREBALL;
+ precache_model ("progs/lavaball.mdl");
+ // 1998-08-14 Incorrect setting of nextthink fix
+ // by Maddes/Lord Sméagol
+ // this.nextthink = time + (random() * 5);
+ this.nextthink = time + 0.1 + (random() * 5);
+ // 1998-08-14 Incorrect setting of nextthink fix
+ // by Maddes/Lord Sméagol
+ this.think = fire_fly;
+ if (!this.speed)
+ // fixed typo QIP - dumptruck_ds
+ this.speed = 1000;
+ };

-//----------------------------------------------------------------------
-void() fire_touch =
-{
- T_Damage (other, self, self, 20);
- remove (self);
};

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

Diff qc/misc/infight.qc

diff --git a/qc/misc/infight.qc b/qc/misc/infight.qc
index 24f16cb..bac87ad 100644
--- a/qc/misc/infight.qc
+++ b/qc/misc/infight.qc
@@ -14,107 +14,117 @@
//======================================================================

// constants
-float INFIGHT_MUTUAL = 1;
-float INFIGHT_PLAYER_ACTIVATION = 2;
+const float INFIGHT_MUTUAL = 1;
+const float INFIGHT_PLAYER_ACTIVATION = 2;

-//----------------------------------------------------------------------
-void(entity t1, entity t2) make_angry_at =
+class misc_infight: entity
{
- // checks if targets are alive
- if (t2.health > 0 && t1.health > 0)
+ //--------------------------------------------------------------
+ nonvirtual void(entity t1, entity t2) make_angry_at =
{
- if (t1.enemy.classname == "player")
- t1.oldenemy = t1.enemy;
- t1.enemy = t2;
-
- entity oself = self;
- // FoundTarget () only acts on self
- self = t1;
- FoundTarget ();
- self = oself;
- }
-};
+ // checks if targets are alive
+ if (t2.health > 0 && t1.health > 0)
+ {
+ if (t1.enemy.classtype == CT_PLAYER)
+ t1.oldenemy = t1.enemy;
+ t1.enemy = t2;

-//----------------------------------------------------------------------
-void() misc_infight_use =
-{
- local entity t1, t2;
+ // TODO CEV need to rework; this/self/FoundTarget
+ // FoundTarget () only acts on self
+ FoundTargetForEntity (t1);
+ }
+ };

- for (t1 = world; (t1 = find (t1, targetname, self.target)); )
+ //--------------------------------------------------------------
+ virtual void() misc_infight_use =
{
- for (t2 = world; (t2 = find (t2, targetname, self.target2)); )
+ local entity t1, t2;
+
+ for (t1 = world; (t1 = find (t1, ::targetname, this.target)); )
{
- // t1 = find(world, targetname, self.target);
- // t2 = find(world, targetname, self.target2);
- if (!t1)
- {
- dprint ("[trigger_infight] Cannot find target, "
- "checking targetname2\n");
- t1 = find (world, targetname2, self.target);
- }
- if (!t1)
- {
- dprint ("[trigger_infight] Cannot find target, "
- "checking targetname3\n");
- t1 = find (world, targetname3, self.target);
- }
- if (!t1)
- {
- dprint ("[trigger_infight] Cannot find target, "
- "checking targetname4\n");
- t1 = find (world, targetname4, self.target);
- }
- if (!t1)
- {
- dprint ("[trigger_infight] Cannot find target, "
- "exhausted all targetnames\n");
- return;
- }
- if (!t2)
+ for (t2 = world;
+ (t2 = find (t2, ::targetname, this.target2)); )
{
- dprint ("[trigger_infight] Cannot find target2 "
- "checking targetname2\n");
- t2 = find (world, targetname2, self.target2);
- }
- if (!t2)
- {
- dprint ("[trigger_infight] Cannot find target2 "
- "checking targetname3\n");
- t2 = find (world, targetname3, self.target2);
- }
- if (!t2)
- {
- dprint ("[trigger_infight] Cannot find target2 "
- "checking targetname4\n");
- t2 = find (world, targetname4, self.target2);
- }
- if (!t2)
- {
- dprint ("[trigger_infight] Cannot find target2,"
- " exhausted all targetnames\n");
- return;
- }
+ // t1 = find(world, ::targetname, this.target);
+ // t2 = find(world, ::targetname, this.target2);
+ if (!t1)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target, trying targetname2\n");
+ t1 = find (world, ::targetname2,
+ this.target);
+ }
+ if (!t1)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target, trying targetname3\n");
+ t1 = find (world, ::targetname3,
+ this.target);
+ }
+ if (!t1)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target, trying targetname4\n");
+ t1 = find (world, ::targetname4,
+ this.target);
+ }
+ if (!t1)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target, out of targetnames\n");
+ return;
+ }
+ if (!t2)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target2 trying targetname2\n");
+ t2 = find (world, ::targetname2,
+ this.target2);
+ }
+ if (!t2)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target2 trying targetname3\n");
+ t2 = find (world, ::targetname3,
+ this.target2);
+ }
+ if (!t2)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target2 trying targetname4\n");
+ t2 = find (world, ::targetname4,
+ this.target2);
+ }
+ if (!t2)
+ {
+ dprint ("misc_infight_use: Cannot find "
+ "target2 out of targetnames\n");
+ return;
+ }

- make_angry_at (t1, t2);
+ make_angry_at (t1, t2);

- if (self.spawnflags & INFIGHT_PLAYER_ACTIVATION)
- {
- t1.infight_activator = activator;
- t2.infight_activator = activator;
- }
+ if (this.spawnflags & INFIGHT_PLAYER_ACTIVATION)
+ {
+ t1.infight_activator = activator;
+ t2.infight_activator = activator;
+ }

- if (self.spawnflags & INFIGHT_MUTUAL)
- make_angry_at (t2, t1);
+ if (this.spawnflags & INFIGHT_MUTUAL)
+ make_angry_at (t2, t1);
+ }
}
- }
-};
+ };

-//----------------------------------------------------------------------
-void() misc_infight =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() misc_infight =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- self.use = misc_infight_use;
+ this.classname = "misc_infight";
+ this.classtype = CT_MISC_INFIGHT;
+ this.use = misc_infight_use;
+ };
};

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

Diff qc/misc/light_candle.qc

diff --git a/qc/misc/light_candle.qc b/qc/misc/light_candle.qc
index 4d42ea1..d7ee158 100644
--- a/qc/misc/light_candle.qc
+++ b/qc/misc/light_candle.qc
@@ -114,34 +114,42 @@ _anglescale => _anglescale
//dumptruck_ds taken from honey (originally from Rogue)
White candle
*/
-void() light_candle =
+class light_candle: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/candle.mdl");
- setmodel (self, "progs/candle.mdl");
- makestatic (self);
-};
-
-//----------------------------------------------------------------------
-void() model_candle_think =
-{
- self.frame = self.frame + 1;
- if (self.frame > 3)
- self.frame = 0;
- self.nextthink = time + 0.1;
-};
-
-//----------------------------------------------------------------------
-void() model_candle =
-{
-
- precache_model ("progs/candle.mdl");
-
- setmodel (self, "progs/candle.mdl");
-
- self.think = model_candle_think;
- self.nextthink = time + 0.1;
+ // the following block of code doesn't seem to be used anywhere -- CEV
+ /*
+ //--------------------------------------------------------------
+ void() model_candle_think =
+ {
+ this.frame = this.frame + 1;
+ if (this.frame > 3)
+ this.frame = 0;
+ this.nextthink = time + 0.1;
+ };
+
+ //--------------------------------------------------------------
+ void() model_candle =
+ {
+ precache_model ("progs/candle.mdl");
+
+ setmodel (this, "progs/candle.mdl");
+
+ this.think = model_candle_think;
+ this.nextthink = time + 0.1;
+ };
+ */
+
+ //--------------------------------------------------------------
+ void() light_candle =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_candle";
+ this.classtype = CT_LIGHT_CANDLE;
+ precache_model ("progs/candle.mdl");
+ setmodel (this, "progs/candle.mdl");
+ makestatic (this);
+ };
};

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

Diff qc/misc/lights.qc

diff --git a/qc/misc/lights.qc b/qc/misc/lights.qc
index 4680ec0..5f0ebe2 100644
--- a/qc/misc/lights.qc
+++ b/qc/misc/lights.qc
@@ -3,36 +3,9 @@
//==============================================================================

// constants
-const float START_OFF = 1;
-const float FADE_IN_OUT = 2;
-const float SILENT_TORCH = 4; // for silent torch -- dumptruck_ds
-
-// prototypes
-void() FireAmbient;
-
-/*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) 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
-
-Used as a positional target for spotlights, etc.
-*/
-void() info_null =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- remove (self);
-};
-
-/*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) 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
-
-Never used in the or
-*/
-void() info_notnull =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-};
+const float LIGHT_START_OFF = 1;
+const float LIGHT_FADE_IN_OUT = 2;
+const float LIGHT_SILENT_TORCH = 4; // for silent torch -- dumptruck_ds

//----------------------------------------------------------------------
// lightstyle_lookup
@@ -142,76 +115,114 @@ string(float num) lightstyle_fade_lookup =
}
};

-//----------------------------------------------------------------------
-// light_fade_in
-//----------------------------------------------------------------------
-void() light_fade_in =
+class base_light: entity
{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- lightstyle (self.style, lightstyle_fade_lookup(self.count));
- self.count = self.count + 1;
- if (self.count > 12)
- return;
-
- self.think = light_fade_in;
- self.nextthink = time + self.speed;
-};
-
-//----------------------------------------------------------------------
-// light_fade_out
-//----------------------------------------------------------------------
-void() light_fade_out =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- lightstyle (self.style, lightstyle_fade_lookup(self.count));
- self.count = self.count - 1;
- if (self.count < 0)
- return;
-
- self.think = light_fade_out;
- self.nextthink = time + self.speed;
-};
-
-//----------------------------------------------------------------------
-// light_use -- using a light will turn it on and off
-//----------------------------------------------------------------------
-void() light_use =
-{
- if (self.spawnflags & START_OFF)
+ //--------------------------------------------------------------
+ // light_fade_in
+ //--------------------------------------------------------------
+ nonvirtual void() light_fade_in =
+ {
+ if (this.count < 0)
+ this.count = 0;
+ if (this.count > 12)
+ this.count = 12;
+
+ lightstyle (this.style, lightstyle_fade_lookup(this.count));
+ this.count = this.count + 1;
+ if (this.count > 12)
+ return;
+
+ this.think = light_fade_in;
+ this.nextthink = time + this.speed;
+ };
+
+ //--------------------------------------------------------------
+ // light_fade_out
+ //--------------------------------------------------------------
+ nonvirtual void() light_fade_out =
{
- self.spawnflags = self.spawnflags - START_OFF;
- if (self.spawnflags & FADE_IN_OUT && !self.style2)
- light_fade_in ();
+ if (this.count < 0)
+ this.count = 0;
+ if (this.count > 12)
+ this.count = 12;
+
+ lightstyle (this.style, lightstyle_fade_lookup(this.count));
+ this.count = this.count - 1;
+ if (this.count < 0)
+ return;
+
+ this.think = light_fade_out;
+ this.nextthink = time + this.speed;
+ };
+
+ //--------------------------------------------------------------
+ // light_use -- using a light will turn it on and off
+ //--------------------------------------------------------------
+ nonvirtual void() light_use =
+ {
+ if (this.spawnflags & LIGHT_START_OFF)
+ {
+ this.spawnflags = this.spawnflags - LIGHT_START_OFF;
+ if (this.spawnflags & LIGHT_FADE_IN_OUT && !this.style2)
+ light_fade_in ();
+ else
+ lightstyle (this.style,
+ lightstyle_lookup(this.style2));
+ }
else
- lightstyle (self.style, lightstyle_lookup(self.style2));
- }
- else
+ {
+ this.spawnflags = this.spawnflags + LIGHT_START_OFF;
+ if (this.spawnflags & LIGHT_FADE_IN_OUT && !this.style2)
+ light_fade_out ();
+ else
+ lightstyle (this.style, "a");
+ }
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() light_init =
{
- self.spawnflags = self.spawnflags + START_OFF;
- if (self.spawnflags & FADE_IN_OUT && !self.style2)
- light_fade_out ();
+ // default speed for fading in/out
+ if (this.speed <= 0)
+ this.speed = 0.1;
+
+ // non-switchable light
+ if (!this.targetname)
+ {
+ remove (this);
+ return;
+ }
+
+ if (this.style < 32)
+ // return now if this is not a switchable light
+ // removes one level of indentation below -- CEV
+ return;
+
+ // switchable light
+ this.use = light_use;
+ if (this.spawnflags & LIGHT_START_OFF)
+ {
+ this.count = 0;
+ lightstyle (this.style, "a");
+ }
else
- lightstyle (self.style, "a");
- }
+ {
+ this.count = 12;
+ lightstyle (this.style, lightstyle_lookup(this.style2));
+ }
+ };
};

-/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT 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
+
+/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF LIGHT_FADE_IN_OUT 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

Light

==========
Spawnflags
==========
-START_OFF - switchable lights only - light is off by default
-FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.
+LIGHT_START_OFF - switchable lights only - light is off by default
+LIGHT_FADE_IN_OUT - switchable lights only - light fades in and out. can't be combined with animated lights.

==========
Keys
@@ -259,7 +270,7 @@ Specifies the angle in degrees for an inner spotlight cone (must be less than th
Turns the light into a switchable light, toggled by another entity targeting it�s name.

"speed" "n"
-If the light is switchable and FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.
+If the light is switchable and LIGHT_FADE_IN_OUT is set, the speed at which the light transitions. Default 0.1.

"style" "n"
Set the animated light style. Default 0.
@@ -314,57 +325,47 @@ _color => _sunlight_color
_dirt => _sunlight_dirt
_anglescale => _anglescale
*/
-void() light =
+class light: base_light
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // default speed for fading in/out
- if (self.speed <= 0)
- self.speed = 0.1;
-
- // non-switchable light
- if (!self.targetname)
+ //--------------------------------------------------------------
+ void() light =
{
- remove (self);
- return;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- // switchable light
- if (self.style >= 32)
- {
- self.use = light_use;
- if (self.spawnflags & START_OFF)
- {
- self.count = 0;
- lightstyle (self.style, "a");
- }
- else
- {
- self.count = 12;
- lightstyle (self.style, lightstyle_lookup(self.style2));
- }
- }
+ this.classname = "light";
+ this.classtype = CT_LIGHT;
+
+ light_init ();
+ };
};

-/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT 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
+/*QUAKED light_fluoro (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF LIGHT_FADE_IN_OUT 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

Non-displayed light.
Makes steady fluorescent humming sound.
See the "light" entity for a full description.
*/
-void() light_fluoro =
+class light_fluoro: base_light
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() light_fluoro =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_fluoro";
+ this.classtype = CT_LIGHT_FLUORO;

- ambient_light_buzz ();
- light ();
+ // TODO CEV calling lbuzz directly
+ base_ambient_sound::ambient_sound_lbuzz (this.origin);
+ light_init ();
+ };
};

-/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) START_OFF FADE_IN_OUT 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
+/*QUAKED light_fluorospark (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF LIGHT_FADE_IN_OUT 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

Non-displayed light.
Makes sparking, broken fluorescent sound.
@@ -372,16 +373,23 @@ Can't be toggled.
Default style is 10.
See the "light" entity for a full description.
*/
-void() light_fluorospark =
+class light_fluorospark: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.style)
- self.style = 10;
- ambient_flouro_buzz ();
- remove (self);
+ //--------------------------------------------------------------
+ void() light_fluorospark =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_fluorospark";
+ this.classtype = CT_LIGHT_FLUOROSPARK;
+
+ if (!this.style)
+ this.style = 10;
+ ambient_sound_fbuzz (this.origin);
+ remove (this);
+ };
};

/*QUAKED light_globe (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -389,15 +397,22 @@ Sphere globe light.
Can't be toggled.
See the "light" entity for a full description.
*/
-void() light_globe =
+class light_globe: base_light
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() light_globe =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- precache_model ("progs/s_light.spr");
- setmodel (self, "progs/s_light.spr");
- makestatic (self);
+ this.classname = "light_globe";
+ this.classtype = CT_LIGHT_GLOBE;
+
+ precache_model ("progs/s_light.spr");
+ setmodel (this, "progs/s_light.spr");
+ makestatic (this);
+ };
};

/*QUAKED light_torch_small_walltorch (0 .5 0) (-10 -10 -20) (10 10 20) 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
@@ -405,20 +420,26 @@ void() light_globe =
Short wall torch
See the "light" entity for a full description.
*/
-void() light_torch_small_walltorch =
+class light_torch_small_walltorch: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // precache_model ("progs/flame.mdl");
- precache_body_model ("progs/flame.mdl");
- // setmodel (self, "progs/flame.mdl");
- body_model ("progs/flame.mdl");
- // for silent torch -- dumptruck_ds
- if !(self.spawnflags && SILENT_TORCH)
- FireAmbient ();
- makestatic (self);
+ //--------------------------------------------------------------
+ void() light_torch_small_walltorch =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_torch_small_walltorch";
+ this.classtype = CT_LIGHT_TORCH_SMALL_WALLTORCH;
+ // precache_model ("progs/flame.mdl");
+ precache_body_model ("progs/flame.mdl");
+ // setmodel (this, "progs/flame.mdl");
+ body_model ("progs/flame.mdl");
+ // for silent torch -- dumptruck_ds
+ if !(this.spawnflags && LIGHT_SILENT_TORCH)
+ ambient_sound_fire (this.origin);
+ makestatic (this);
+ };
};

/*QUAKED light_flame_large_yellow (0 1 0) (-10 -10 -12) (12 12 18) 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
@@ -426,17 +447,23 @@ void() light_torch_small_walltorch =
Large yellow flame
See the "light" entity for a full description.
*/
-void() light_flame_large_yellow =
+class light_flame_large_yellow: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/flame2.mdl");
- setmodel (self, "progs/flame2.mdl");
- self.frame = 1;
- FireAmbient ();
- makestatic (self);
+ //--------------------------------------------------------------
+ void() light_flame_large_yellow =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_flame_large_yellow";
+ this.classtype = CT_LIGHT_FLAME_LARGE_YELLOW;
+ precache_model ("progs/flame2.mdl");
+ setmodel (this, "progs/flame2.mdl");
+ this.frame = 1;
+ ambient_sound_fire (this.origin);
+ makestatic (this);
+ };
};

/*QUAKED light_flame_small_yellow (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -444,16 +471,21 @@ void() light_flame_large_yellow =
Small yellow flame
See the "light" entity for a full description.
*/
-void() light_flame_small_yellow =
+class light_flame_small_yellow: base_ambient_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/flame2.mdl");
- setmodel (self, "progs/flame2.mdl");
- FireAmbient ();
- makestatic (self);
+ void() light_flame_small_yellow =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "light_flame_small_yellow";
+ this.classtype = CT_LIGHT_FLAME_SMALL_YELLOW;
+ precache_model ("progs/flame2.mdl");
+ setmodel (this, "progs/flame2.mdl");
+ ambient_sound_fire (this.origin);
+ makestatic (this);
+ };
};

/*QUAKED light_flame_small_white (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -461,32 +493,31 @@ void() light_flame_small_yellow =
Left for compatability
Identical to "light_flame_small_yellow"
*/
-void() light_flame_small_white =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- light_flame_small_yellow ();
-};
+class light_flame_small_white: light_flame_small_yellow { };

/*QUAKED light_sprite_flame (0 1 0) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model ("progs/s_flame.spr"); }
Large flame spite*/
-void() light_sprite_flame =
+class light_sprite_flame: base_misc_model
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/s_flame.spr");
- setmodel (self, "progs/s_flame.spr");
- FireAmbient ();
-
- self.frame = rint(random() * 13);
- self.first_frame = 0;
- self.last_frame = 13;
- self.speed = 0.05;
- self.think = misc_model_think;
- self.nextthink = time + 0.1;
+ //--------------------------------------------------------------
+ void() light_sprite_flame =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ precache_model ("progs/s_flame.spr");
+ setmodel (this, "progs/s_flame.spr");
+ // TODO CEV was FireAmbient (), now calling
+ // ambient_sound_fire directly
+ base_ambient_sound::ambient_sound_fire (this.origin);
+
+ this.frame = rint (random() * 13);
+ this.first_frame = 0;
+ this.last_frame = 13;
+ this.speed = 0.05;
+ this.think = misc_model_think;
+ this.nextthink = time + 0.1;
+ };
};

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

Diff qc/misc/model.qc

diff --git a/qc/misc/model.qc b/qc/misc/model.qc
index aa72143..afefc39 100644
--- a/qc/misc/model.qc
+++ b/qc/misc/model.qc
@@ -1,20 +1,11 @@
//==============================================================================
-// misc_model -- Joshua Skelton
-//==============================================================================
-
-//======================================================================
-// misc_model.qc requires math.qc
-//
+// misc_model -- Joshua Skelton -- misc_model.qc requires math.qc
// Author: Joshua Skelton joshua.skelton@gmail.com
// Edited by: Inky 20201219 Minor changes for a better integration with their
// own code
// Edited by: bmFbr for solid and gravity spawnflags and custom bbox sizes
// Edited by: dumptruck_ds to add start and stop animations
-//======================================================================
-
-// fields
-.float first_frame; // The starting frame of the animation
-.float last_frame; // The ending frame of the animation
+//==============================================================================

// constants
const float MISC_MODEL_GRAVITY = 1;
@@ -24,78 +15,88 @@ const float MISC_MODEL_ONLY_ONCE = 8;
const float MISC_MODEL_PLAY_COUNT = 16;
const float MISC_MODEL_STARTOFF = 32;

-//----------------------------------------------------------------------
-void() misc_model_use =
+class base_misc_model: entity
{
- if (self.state == STATE_ACTIVE)
- {
- if (self.spawnflags & MISC_MODEL_SOLID)
- self.solid = SOLID_NOT;
- self.model = "";
-
- self.state = STATE_INVISIBLE;
- setorigin (self, self.origin);
- }
- else
- {
- if (self.spawnflags & MISC_MODEL_SOLID)
- self.solid = SOLID_BBOX;
- self.model = self.mdl;
-
- self.state = STATE_ACTIVE;
- setorigin (self, self.origin);
- }
-};
+ // class fields
+ float first_frame; // The starting frame of the animation
+ float last_frame; // The ending frame of the animation

-//----------------------------------------------------------------------
-// misc_model_think -- Handles animation for misc_model entity.
-//----------------------------------------------------------------------
-void() misc_model_think =
-{
- self.nextthink = time + fabs (self.speed);
- if (self.estate != STATE_ACTIVE)
- return;
-
- self.frame = self.frame + sign (self.speed);
-
- if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH
- && self.frame < self.first_frame)
- {
- self.speed = -1 * self.speed;
- self.frame += 2;
- }
- else if (self.spawnflags & MISC_MODEL_BACK_AND_FORTH
- && self.frame > self.last_frame)
- {
- self.speed = -1 * self.speed;
- self.frame -= 2;
- }
- else
+ //--------------------------------------------------------------
+ virtual void() misc_model_use =
{
- self.frame = wrap (self.frame, self.first_frame,
- self.last_frame);
- }
-
- if (self.spawnflags & MISC_MODEL_ONLY_ONCE
- && self.frame == self.last_frame
- && self.last_frame != self.first_frame)
- self.nextthink = -1;
-
- if (self.spawnflags & MISC_MODEL_PLAY_COUNT
- && self.frame == self.last_frame
- && self.last_frame != self.first_frame)
+ if (this.state == STATE_ACTIVE)
+ {
+ if (this.spawnflags & MISC_MODEL_SOLID)
+ this.solid = SOLID_NOT;
+ this.model = "";
+
+ this.state = STATE_INVISIBLE;
+ setorigin (this, this.origin);
+ }
+ else
+ {
+ if (this.spawnflags & MISC_MODEL_SOLID)
+ this.solid = SOLID_BBOX;
+ this.model = this.mdl;
+
+ this.state = STATE_ACTIVE;
+ setorigin (this, this.origin);
+ }
+ };
+
+ //--------------------------------------------------------------
+ // misc_model_think -- Handles animation for misc_model entity.
+ //--------------------------------------------------------------
+ virtual void() misc_model_think =
{
- if !(self.count)
- objerror ("Error: set count to the number of "
- " animation cycles!");
- self.cnt = self.cnt + 1;
- dprint (ftos(self.cnt));
- dprint ("\n");
- if (self.cnt != self.count)
- return FALSE;
+ this.nextthink = time + fabs (this.speed);
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ this.frame = this.frame + sign (this.speed);
+
+ if (this.spawnflags & MISC_MODEL_BACK_AND_FORTH
+ && this.frame < this.first_frame)
+ {
+ this.speed = -1 * this.speed;
+ this.frame += 2;
+ }
+ else if (this.spawnflags & MISC_MODEL_BACK_AND_FORTH
+ && this.frame > this.last_frame)
+ {
+ this.speed = -1 * this.speed;
+ this.frame -= 2;
+ }
else
- self.nextthink = -1;
- }
+ {
+ this.frame = wrap (this.frame, this.first_frame,
+ this.last_frame);
+ }
+
+ if (this.spawnflags & MISC_MODEL_ONLY_ONCE &&
+ this.frame == this.last_frame &&
+ this.last_frame != this.first_frame)
+ {
+ this.nextthink = -1;
+ }
+
+ if (this.spawnflags & MISC_MODEL_PLAY_COUNT &&
+ this.frame == this.last_frame &&
+ this.last_frame != this.first_frame)
+ {
+ if !(this.count)
+ objerror ("Error: set count to the number of "
+ " animation cycles!");
+ this.cnt = this.cnt + 1;
+ dprint (ftos(this.cnt));
+ dprint ("\n");
+ if (this.cnt != this.count)
+ return FALSE;
+ else
+ this.nextthink = -1;
+ }
+ };
+
};

/*QUAKED misc_model (0 0.5 0.8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -113,82 +114,92 @@ first_frame: The starting frame of the animation.

last_frame: The last frame of the animation.
*/
-void() misc_model =
+class misc_model: base_misc_model
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.mdl || self.mdl == "")
- objerror ("Model not defined");
-
- if (!self.centeroffset)
- self.centeroffset = '0 0 0';
- if (!self.mdlsz)
- self.mdlsz = '32 32 32';
-
- vector vmin, vmax;
-
- vmin_x = self.centeroffset_x - (self.mdlsz_x / 2);
- vmin_y = self.centeroffset_y - (self.mdlsz_y / 2);
- vmin_z = self.centeroffset_z - (self.mdlsz_z / 2);
-
- vmax_x = self.centeroffset_x + (self.mdlsz_x / 2);
- vmax_y = self.centeroffset_y + (self.mdlsz_y / 2);
- vmax_z = self.centeroffset_z + (self.mdlsz_z / 2);
-
- precache_model (self.mdl);
- setmodel (self, self.mdl);
-
- setsize (self, vmin, vmax);
-
- if (self.spawnflags & MISC_MODEL_SOLID)
- self.solid = SOLID_BBOX;
- else self.solid = SOLID_NOT;
-
- if (self.spawnflags & MISC_MODEL_GRAVITY)
- self.movetype = MOVETYPE_TOSS;
- else self.movetype = MOVETYPE_NONE;
-
- self.use = misc_model_use;
-
- if (!self.frame)
- self.frame = self.first_frame;
-
- // Make static (not animate) if not given a frame range, and
- // not affected by gravity; also remains active if it has a
- // targetname (so it can be killtargeted/toggled)
- if (!self.last_frame
- && !(self.spawnflags & MISC_MODEL_GRAVITY)
- && !(self.spawnflags & MISC_MODEL_SOLID)
- && !self.targetname
- && !self.targetname2)
- // && !(self.spawnflags & MISC_MODEL_DONTMAKESTATIC)
- makestatic (self);
-
- // Make static (not animate) if not given a frame range, and
- // not affected by gravity
- // changed by bmFbr
- // if (!self.last_frame && !(self.spawnflags & MISC_MODEL_GRAVITY))
- // {
- // makestatic(self);
- // return;
- // }
-
- // if it as a custom animation range
- if (self.last_frame)
+ //--------------------------------------------------------------
+ void() misc_model =
{
- // Default animation speed to 10 fps
- if (!self.speed)
- self.speed = 0.1;
- self.nextthink = time + self.speed;
- self.think = misc_model_think;
- }
-
- if (self.spawnflags & MISC_MODEL_STARTOFF)
- self.state = STATE_ACTIVE;
- else
- self.state = STATE_INVISIBLE;
-
- misc_model_use ();
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "misc_model";
+ this.classtype = CT_MISC_MODEL;
+
+ if (!this.mdl || this.mdl == "")
+ objerror ("Model not defined");
+
+ if (!this.centeroffset)
+ this.centeroffset = '0 0 0';
+ if (!this.mdlsz)
+ this.mdlsz = '32 32 32';
+
+ vector vmin, vmax;
+
+ vmin_x = this.centeroffset_x - (this.mdlsz_x / 2);
+ vmin_y = this.centeroffset_y - (this.mdlsz_y / 2);
+ vmin_z = this.centeroffset_z - (this.mdlsz_z / 2);
+
+ vmax_x = this.centeroffset_x + (this.mdlsz_x / 2);
+ vmax_y = this.centeroffset_y + (this.mdlsz_y / 2);
+ vmax_z = this.centeroffset_z + (this.mdlsz_z / 2);
+
+ precache_model (this.mdl);
+ setmodel (this, this.mdl);
+
+ setsize (this, vmin, vmax);
+
+ if (this.spawnflags & MISC_MODEL_SOLID)
+ this.solid = SOLID_BBOX;
+ else this.solid = SOLID_NOT;
+
+ if (this.spawnflags & MISC_MODEL_GRAVITY)
+ this.movetype = MOVETYPE_TOSS;
+ else this.movetype = MOVETYPE_NONE;
+
+ this.use = misc_model_use;
+
+ if (!this.frame)
+ this.frame = this.first_frame;
+
+ // Make static (not animate) if not given a frame range, and
+ // not affected by gravity; also remains active if it has a
+ // targetname (so it can be killtargeted/toggled)
+ if (!this.last_frame &&
+ !(this.spawnflags & MISC_MODEL_GRAVITY) &&
+ !(this.spawnflags & MISC_MODEL_SOLID) &&
+ !this.targetname &&
+ !this.targetname2)
+ // !(this.spawnflags & MISC_MODEL_DONTMAKESTATIC) &&
+ {
+ makestatic (this);
+ }
+
+ // Make static (not animate) if not given a frame range, and
+ // not affected by gravity
+ // changed by bmFbr
+ // if (!this.last_frame &&
+ // !(this.spawnflags & MISC_MODEL_GRAVITY))
+ // {
+ // makestatic(this);
+ // return;
+ // }
+
+ // if it as a custom animation range
+ if (this.last_frame)
+ {
+ // Default animation speed to 10 fps
+ if (!this.speed)
+ this.speed = 0.1;
+ this.nextthink = time + this.speed;
+ this.think = misc_model_think;
+ }
+
+ if (this.spawnflags & MISC_MODEL_STARTOFF)
+ this.state = STATE_ACTIVE;
+ else
+ this.state = STATE_INVISIBLE;
+
+ misc_model_use ();
+ };
};

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

Diff qc/misc/modeltrain.qc

diff --git a/qc/misc/modeltrain.qc b/qc/misc/modeltrain.qc
index f303113..c8ff211 100644
--- a/qc/misc/modeltrain.qc
+++ b/qc/misc/modeltrain.qc
@@ -2,7 +2,7 @@
// misc_modeltrain -- was plats.qc
//==============================================================================

-//----------------------------------------------------------------------
+ //--------------------------------------------------------------
void() animcontroller_think =
{
local float first, last, step, atype, dir, nextframe;
@@ -86,7 +86,7 @@ void() animcontroller_think =
self.nextthink = time + tr.frtime2;
};

-//----------------------------------------------------------------------
+ //--------------------------------------------------------------
void() misc_modeltrain =
{
// new spawnflags for all entities -- iw

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

Diff qc/misc/noisemaker.qc

diff --git a/qc/misc/noisemaker.qc b/qc/misc/noisemaker.qc
index 1d536a1..32a0671 100644
--- a/qc/misc/noisemaker.qc
+++ b/qc/misc/noisemaker.qc
@@ -2,40 +2,46 @@
// misc_noisemaker
//==============================================================================

-//----------------------------------------------------------------------
-void() noise_think =
-{
- self.nextthink = time + 0.5;
- sound (self, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
- sound (self, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
- sound (self, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
- sound (self, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
- sound (self, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
- sound (self, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
- sound (self, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
-};
-
/*QUAKED misc_noisemaker (1 0.5 0) (-10 -10 -10) (10 10 10) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

For optimzation testing, starts a lot of sounds.
*/
-void() misc_noisemaker =
+class misc_noisemaker: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() noise_think =
+ {
+ this.nextthink = time + 0.5;
+ sound (this, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
+ sound (this, 2, "enforcer/enfstop.wav", 1, ATTN_NORM);
+ sound (this, 3, "enforcer/sight1.wav", 1, ATTN_NORM);
+ sound (this, 4, "enforcer/sight2.wav", 1, ATTN_NORM);
+ sound (this, 5, "enforcer/sight3.wav", 1, ATTN_NORM);
+ sound (this, 6, "enforcer/sight4.wav", 1, ATTN_NORM);
+ sound (this, 7, "enforcer/pain1.wav", 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ void() misc_noisemaker =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2 ("enforcer/sight4.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/idle1.wav");
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2 ("enforcer/sight4.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/idle1.wav");

- self.nextthink = time + 0.1 + random ();
- self.think = noise_think;
+ this.classname = "misc_noisemaker";
+ this.classtype = CT_MISC_NOISEMAKER;
+ this.nextthink = time + 0.1 + random ();
+ this.think = noise_think;
+ };
};

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

Diff qc/misc/particle_stream.qc

diff --git a/qc/misc/particle_stream.qc b/qc/misc/particle_stream.qc
index 7517999..15a2e34 100644
--- a/qc/misc/particle_stream.qc
+++ b/qc/misc/particle_stream.qc
@@ -4,56 +4,6 @@

//=START PARTICLE-STREAM================================================

-//----------------------------------------------------------------------
-void(vector start, vector end, float color1, float color2, float pdensity)
- Particle_Beam =
-{
- local vector spray, next;
- local float dist, loop, clr;
-
- clr = color1;
- spray = start - end;
- dist = vlen (spray);
- loop = dist / 24;
- spray = normalize (spray);
- next = spray * 24;
-
- while (loop > 0)
- {
- particle (end, spray, clr, pdensity);
- end = end + next;
- loop = loop - 1;
- if (clr == color1)
- clr = color2;
- else
- clr = color1;
- }
-};
-
-//----------------------------------------------------------------------
-void() particle_use =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- // was 40 - too many particles for my taste -- dumptruck_ds
- Particle_Beam(self.origin, self.enemy.origin, self.dmg, self.cnt, 15);
-};
-
-//----------------------------------------------------------------------
-void() particle_stream_start =
-{
- local entity pspot;
-
- pspot = find (world, targetname, self.target);
-
- if (!pspot)
- {
- dprint ("Particle stream can't find target!");
- return;
- }
-
- self.enemy = pspot;
-};
-
/*QUAKED misc_particle_stream (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
A particle stream! It appears when triggered. This entity is
one end of the stream, target another entity as the other end-point.
@@ -65,25 +15,83 @@ I used the info_notnull, but you should be able to target anything
"cnt" 2nd Color - Mixes particles of both colors
"noise" Sound to play when triggered
*/
-void() misc_particle_stream =
+class misc_particle_stream: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void(vector start, vector end, float color1, float color2,
+ float pdensity) particle_beam =
+ {
+ local vector spray, next;
+ local float dist, loop, clr;
+
+ clr = color1;
+ spray = start - end;
+ dist = vlen (spray);
+ loop = dist / 24;
+ spray = normalize (spray);
+ next = spray * 24;
+
+ while (loop > 0)
+ {
+ particle (end, spray, clr, pdensity);
+ end = end + next;
+ loop = loop - 1;
+ if (clr == color1)
+ clr = color2;
+ else
+ clr = color1;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() particle_use =
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ // was 40 - too many particles for my taste -- dumptruck_ds
+ particle_beam (this.origin, this.enemy.origin,
+ this.dmg, this.cnt, 15);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() particle_stream_start =
+ {
+ local entity pspot;
+
+ pspot = find (world, ::targetname, this.target);
+
+ if (!pspot)
+ {
+ dprint ("Particle stream can't find target!");
+ return;
+ }
+
+ this.enemy = pspot;
+ };
+
+ //--------------------------------------------------------------
+ void() misc_particle_stream =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "misc_particle_stream";
+ this.classtype = CT_MISC_PARTICLE_STREAM;

- if (!self.target)
- objerror ("misc_particle_stream with not target!");
+ if (!this.target)
+ objerror ("misc_particle_stream with not target!");

- if (!self.dmg)
- self.dmg = 73;
- if (!self.cnt)
- self.cnt = self.dmg;
- if (!self.noise)
- self.noise = "misc/null.wav";
+ if (!this.dmg)
+ this.dmg = 73;
+ if (!this.cnt)
+ this.cnt = this.dmg;
+ if (!this.noise)
+ this.noise = "misc/null.wav";

- precache_sound(self.noise);
+ precache_sound(this.noise);

- self.use = particle_use;
- self.think = particle_stream_start;
- self.nextthink = time + 0.2;
+ this.use = particle_use;
+ this.think = particle_stream_start;
+ this.nextthink = time + 0.2;
+ };
};

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

Diff qc/misc/particles.qc

diff --git a/qc/misc/particles.qc b/qc/misc/particles.qc
index 7263432..b9a6975 100644
--- a/qc/misc/particles.qc
+++ b/qc/misc/particles.qc
@@ -1,44 +1,13 @@
//==============================================================================
// misc_particles AKA misc_splash
// selections from Rubicon 2 qc by john fitzgibbons
+// renamed from misc_splash (Rubcion 2) -- dumptruck_ds
//==============================================================================

-//======================================================================
-// misc_particles
-// renamed from misc_splash (Rubcion 2) --dumptruck_ds
-//======================================================================
+// constants
+const float PARTICLES_START_OFF;

-//----------------------------------------------------------------------
-void() splash_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
-
-//----------------------------------------------------------------------
-void() splash_think =
-{
- if (self.spawnflags & START_OFF)
- {
- self.nextthink = time + 0.1;
- self.think = splash_think;
- }
- else
- {
- local vector vec;
- local float variance;
- variance = vlen(self.movedir) / 2;
- vec_x = self.movedir_x - variance + random() * variance * 2;
- vec_y = self.movedir_y - variance + random() * variance * 2;
- vec_z = self.movedir_z - variance + random() * variance * 2;
- particle (self.origin, vec, self.color, self.volume);
- self.nextthink = time + self.wait;
- }
-};
-
-/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+/*QUAKED misc_particles (0 .5 .8) (-8 -8 -8) (8 8 8) PARTICLES_START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

Produces a continuous particle splash for waterfalls and other effects

@@ -49,26 +18,64 @@ Produces a continuous particle splash for waterfalls and other effects
"wait" time between particle generation cycles. (default 0.1)

"volume" density of particles. (default 10)
-
-
*/
-void() misc_particles =
+class misc_particles: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() splash_use =
+ {
+ if (this.spawnflags & PARTICLES_START_OFF)
+ this.spawnflags = this.spawnflags - PARTICLES_START_OFF;
+ else
+ this.spawnflags = this.spawnflags + PARTICLES_START_OFF;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() splash_think =
+ {
+ if (this.spawnflags & PARTICLES_START_OFF)
+ {
+ this.nextthink = time + 0.1;
+ this.think = splash_think;
+ }
+ else
+ {
+ local vector vec;
+ local float variance;
+ variance = vlen(this.movedir) / 2;
+ vec_x = this.movedir_x - variance +
+ random() * variance * 2;
+ vec_y = this.movedir_y - variance +
+ random() * variance * 2;
+ vec_z = this.movedir_z - variance +
+ random() * variance * 2;
+ particle (this.origin, vec, this.color, this.volume);
+ this.nextthink = time + this.wait;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() misc_particles =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "misc_particles";
+ this.classtype = CT_MISC_PARTICLES;

- if (!self.wait)
- self.wait = 0.1;
+ if (!this.wait)
+ this.wait = 0.1;

- if (!self.movedir)
- self.movedir = '0 0 4';
+ if (!this.movedir)
+ this.movedir = '0 0 4';

- if (!self.volume)
- self.volume = 10;
+ if (!this.volume)
+ this.volume = 10;

- self.color = self.color * 16;
- self.use = splash_use;
- self.nextthink = time + self.wait;
- self.think = splash_think;
+ this.color = this.color * 16;
+ this.use = splash_use;
+ this.nextthink = time + this.wait;
+ this.think = splash_think;
+ };
};

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

Diff qc/misc/particlespray.qc

diff --git a/qc/misc/particlespray.qc b/qc/misc/particlespray.qc
index 864665c..9e1826f 100644
--- a/qc/misc/particlespray.qc
+++ b/qc/misc/particlespray.qc
@@ -1,37 +1,8 @@
//==============================================================================
-// misc_particlespray
-//==============================================================================
-
-//======================================================================
-// Particle Sprayer
+// misc_particlespray -- Particle Sprayer
// this is from Custents not Rubicon2 -- dumptruck_ds
// renamed from func to misc
-//======================================================================
-
-// fields
-.float endtime;
-.float duration;
-
-//----------------------------------------------------------------------
-void() partspray_think =
-{
- particle (self.origin, self.movedir, self.color, self.count);
-
- if (!self.targetname || self.endtime > time)
- self.nextthink = time + self.delay;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
-};
-
-//----------------------------------------------------------------------
-void() partspray_use =
-{
- self.endtime = time + self.duration;
- partspray_think ();
-};
+//==============================================================================

/*QUAKED misc_particlespray (0 .5 .8) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
Shoots particles either when triggered, or contiuously when not triggered by anything.
@@ -47,30 +18,59 @@ Shoots particles either when triggered, or contiuously when not triggered by any

"duration" is the amount of time that the it will continue to release particles so that it can release a long stream of particles with only one triggering.
*/
-void() misc_particlespray =
+class misc_particlespray: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.color)
- self.color = 47;
-
- if (self.count <= 0)
- self.count = 15;
-
- if (self.delay <= 0)
- self.delay = 0.1;
-
- if (self.noise != "")
- precache_sound (self.noise);
- precache_sound ("misc/null.wav");
-
- self.classname = "particlespray";
- self.think = partspray_think;
-
- if (!self.targetname)
- self.nextthink = time + 0.1 + self.delay;
- else
- self.use = partspray_use;
+ // class fields
+ float endtime;
+ float duration;
+
+ //--------------------------------------------------------------
+ virtual void() particlespray_think =
+ {
+ particle (this.origin, this.movedir, this.color, this.count);
+
+ if (!this.targetname || this.endtime > time)
+ this.nextthink = time + this.delay;
+
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ else
+ sound (this, CHAN_AUTO, "misc/null.wav", 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() particlespray_use =
+ {
+ this.endtime = time + this.duration;
+ particlespray_think ();
+ };
+
+ void() misc_particlespray =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!this.color)
+ this.color = 47;
+
+ if (this.count <= 0)
+ this.count = 15;
+
+ if (this.delay <= 0)
+ this.delay = 0.1;
+
+ if (this.noise != "")
+ precache_sound (this.noise);
+ precache_sound ("misc/null.wav");
+
+ this.classname = "particlespray";
+ this.classtype = CT_MISC_PARTICLESPRAY;
+ this.think = particlespray_think;
+
+ if (!this.targetname)
+ this.nextthink = time + 0.1 + this.delay;
+ else
+ this.use = particlespray_use;
+ };
};

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

Diff qc/misc/play.qc

diff --git a/qc/misc/play.qc b/qc/misc/play.qc
index afd18df..9ed77d9 100644
--- a/qc/misc/play.qc
+++ b/qc/misc/play.qc
@@ -9,41 +9,63 @@
// Distributed (unsupported) on 3.12.97
//======================================================================

-//----------------------------------------------------------------------
-void() play_sound_use =
+class base_play_sound: entity
{
- if (self.spawnflags & 1)
+ //--------------------------------------------------------------
+ virtual void() play_sound_use =
{
- if (self.state == 0)
+ if (this.spawnflags & 1)
{
- self.state = 1;
- sound (self, self.impulse, self.noise, self.volume,
- self.speed);
+ if (this.state == 0)
+ {
+ this.state = 1;
+ sound (this, this.impulse, this.noise,
+ this.volume, this.speed);
+ }
+ else
+ {
+ this.state = 0;
+ sound (this, this.impulse, "misc/null.wav",
+ this.volume, this.speed);
+ }
}
else
{
- self.state = 0;
- sound (self, self.impulse, "misc/null.wav",
- self.volume, self.speed);
+ sound (this, this.impulse, this.noise,
+ this.volume, this.speed);
}
- }
- else
+ };
+
+ //--------------------------------------------------------------
+ virtual void() play_sound_think =
{
- sound (self, self.impulse, self.noise, self.volume, self.speed);
- }
-};
+ local float t;
+ t = this.wait * random ();

-//----------------------------------------------------------------------
-void() PlaySoundThink =
-{
- local float t;
- t = self.wait * random ();
+ if (t < this.delay)
+ t = this.delay;

- if (t < self.delay)
- t = self.delay;
+ this.nextthink = time + t;
+ play_sound_use ();
+ };

- self.nextthink = time + t;
- play_sound_use ();
+ //--------------------------------------------------------------
+ nonvirtual void() play_sound_init =
+ {
+ precache_sound (this.noise);
+ precache_sound ("misc/null.wav");
+ if (this.volume == 0)
+ this.volume = 1;
+ if (this.speed == 0)
+ this.speed = 1;
+ if (this.speed == -1)
+ // this.speed = 0;
+ this.speed = ATTN_NONE;
+ if (this.spawnflags & 1)
+ if (this.impulse == 0)
+ this.impulse = 7;
+ this.use = play_sound_use;
+ };
};

/*QUAKED play_sound_triggered (0.3 0.1 0.6) (-8 -8 -8) (8 8 8) toggle
@@ -58,33 +80,27 @@ play a sound when it is used
2 - idle
3 - static
*/
-void() play_sound_triggered =
+class play_sound_triggered: base_play_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // dumptruck_ds
- if (!self.noise)
+ //--------------------------------------------------------------
+ virtual void() play_sound_triggered =
{
- objerror ("no soundfile set in noise!\n");
- remove (self);
- return;
- }
-
- precache_sound (self.noise);
- precache_sound ("misc/null.wav");
- if (self.volume == 0)
- self.volume = 1;
- if (self.speed == 0)
- self.speed = 1;
- if (self.speed == -1)
- // self.speed = 0;
- self.speed = ATTN_NONE;
- if (self.spawnflags & 1)
- if (self.impulse == 0)
- self.impulse = 7;
- self.use = play_sound_use;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ // dumptruck_ds
+ if (!this.noise)
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove (this);
+ return;
+ }
+
+ this.classname = "play_sound_triggered";
+ this.classtype = CT_MISC_PLAY_SOUND_TRIGGERED;
+ play_sound_init ();
+ };
};

/*QUAKED play_sound (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
@@ -100,36 +116,53 @@ play a sound on a periodic basis
2 - idle
3 - static
*/
-void() play_sound =
+class play_sound: base_play_sound
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() play_sound =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- local float t;
+ local float t;

- // dumptruck_ds
- if (!self.noise)
- {
- objerror ("no soundfile set in noise!\n");
- remove (self);
- return;
- }
+ // dumptruck_ds
+ if (!this.noise)
+ {
+ objerror ("no soundfile set in noise!\n");
+ remove (this);
+ return;
+ }
+
+ this.classname = "play_sound";
+ this.classtype = CT_MISC_PLAY_SOUND;
+ play_sound_init ();
+
+ if (this.wait == 0)
+ this.wait = 20;
+ if (this.delay == 0)
+ this.delay = 2;

- play_sound_triggered ();
+ this.think = play_sound_think;

- if (self.wait == 0)
- self.wait = 20;
- if (self.delay == 0)
- self.delay = 2;
+ t = this.wait * random ();
+ if (t < this.delay)
+ t = this.delay;

- self.think = PlaySoundThink;
+ this.nextthink = time + t;
+ };
+};

- t = self.wait * random ();
- if (t < self.delay)
- t = self.delay;
+class base_tele_fog: entity
+{
+ //--------------------------------------------------------------
+ virtual void() play_tfog =
+ {
+ // thanks Khreathor -- dumptruck_ds
+ spawn_tfog (this.origin);
+ };

- self.nextthink = time + t;
};

/*QUAKED tele_fog (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
@@ -139,21 +172,21 @@ When triggered, tele_fog shows the teleport particle effects and sounds.
Use this when killtageting an entity if the player can see.

*/
-void() play_tfog =
+class tele_fog: base_tele_fog
{
- // thanks Khreathor -- dumptruck_ds
- spawn_tfog (self.origin);
+ //--------------------------------------------------------------
+ void() tele_fog =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "tele_fog";
+ this.classtype = CT_MISC_TELE_FOG;
+ this.use = play_tfog;
+ };
};

-//----------------------------------------------------------------------
-void() tele_fog =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = play_tfog;
-};

/*QUAKED play_tele (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)

@@ -163,15 +196,21 @@ Same os tele_fog.
Use this when killtageting an entity if the player can see.

*/
-void() play_tele =
+class play_tele: base_tele_fog
{
- // same as tele_fog, added for "play_xxxx" consistancy
-
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = play_tfog;
+ //--------------------------------------------------------------
+ void() play_tele =
+ {
+ // same as tele_fog, added for "play_xxxx" consistancy
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "tele_fog";
+ // use same classtype as tele_fog () -- CEV
+ this.classtype = CT_MISC_TELE_FOG;
+ this.use = play_tfog;
+ };
};

/*QUAKED play_explosion (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
@@ -179,22 +218,28 @@ void() play_tele =
When triggered, creates a explosion at it's origin. Causes damage.

*/
-void() play_explosion_fx =
-{
- // thanks Khreathor -- dumptruck_ds
- // GrenadeExplode uses self.owner as the attacker -- iw
- self.owner = self;
- GrenadeExplode ();
-};
-
-//----------------------------------------------------------------------
-void() play_explosion =
+class play_explosion: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = play_explosion_fx;
+ //--------------------------------------------------------------
+ virtual void() play_explosion_fx =
+ {
+ // thanks Khreathor -- dumptruck_ds
+ // GrenadeExplode uses this.owner as the attacker -- iw
+ this.owner = this;
+ GrenadeExplode ();
+ };
+
+ //--------------------------------------------------------------
+ void() play_explosion =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_explosion";
+ this.classtype = CT_MISC_PLAY_EXPLOSION;
+ this.use = play_explosion_fx;
+ };
};

/*QUAKED play_lavasplash (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
@@ -204,37 +249,73 @@ When triggered, plays the lavasplash effect from E1M7.
Use noise key for a custom sound.

*/
-void() play_lavasplash_fx =
+class play_lavasplash: entity
{
- // thanks Khreathor -- dumptruck_ds
- if (self.noise != "")
+ //--------------------------------------------------------------
+ virtual void() play_lavasplash_fx =
{
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
+ // thanks Khreathor -- dumptruck_ds
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ else
+ sound (this, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
+
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ };
+
+ //--------------------------------------------------------------
+ void() play_lavasplash =
{
- sound (self, CHAN_AUTO, "boss1/out1.wav", 1, ATTN_NORM);
- }
-
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LAVASPLASH);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_lavasplash";
+ this.classtype = CT_MISC_PLAY_LAVASPLASH;
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ precache_sound("boss1/out1.wav");
+ this.use = play_lavasplash_fx;
+ };
};

-//----------------------------------------------------------------------
-void() play_lavasplash =
+class base_meat_shower: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() play_meatspray =
+ {
+ // -- dumptruck_ds -- thanks to Spike for helping with errors
+ if (this.style == 1)
+ {
+ ThrowGib ("progs/gib1.mdl", random() * -80);
+ ThrowGib ("progs/gib2.mdl", random() * -80);
+ ThrowGib ("progs/gib3.mdl", random() * -80);
+ ThrowGib ("progs/gib1.mdl", random() * -75);
+ ThrowGib ("progs/gib2.mdl", random() * -75);
+ ThrowGib ("progs/gib3.mdl", random() * -75);
+ }
+ else
+ {
+ ThrowGib ("progs/gib1.mdl", random() * -65);
+ ThrowGib ("progs/gib2.mdl", random() * -65);
+ ThrowGib ("progs/gib3.mdl", random() * -65);
+ }

- if (self.noise != "")
- precache_sound (self.noise);
+ if (this.fly_sound != 1)
+ return;

- precache_sound("boss1/out1.wav");
- self.use = play_lavasplash_fx;
+ if (random() < 0.5)
+ sound (this, CHAN_VOICE, "player/gib.wav",
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_VOICE, "player/udeath.wav",
+ 1, ATTN_NORM);
+ };
};

/*QUAKED meat_shower (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
@@ -244,42 +325,19 @@ When triggered, plays a gib effect.
Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.

*/
-void() play_meatspray =
+class meat_shower: base_meat_shower
{
- // -- dumptruck_ds -- thanks to Spike for helping with errors
- if (self.style == 1)
+ //--------------------------------------------------------------
+ void() meat_shower =
{
- ThrowGib ("progs/gib1.mdl", random() * -80);
- ThrowGib ("progs/gib2.mdl", random() * -80);
- ThrowGib ("progs/gib3.mdl", random() * -80);
- ThrowGib ("progs/gib1.mdl", random() * -75);
- ThrowGib ("progs/gib2.mdl", random() * -75);
- ThrowGib ("progs/gib3.mdl", random() * -75);
- }
- else
- {
- ThrowGib ("progs/gib1.mdl", random() * -65);
- ThrowGib ("progs/gib2.mdl", random() * -65);
- ThrowGib ("progs/gib3.mdl", random() * -65);
- }
-
- if (self.fly_sound != 1)
- return;
-
- if (random() < 0.5)
- sound (self, CHAN_VOICE, "player/gib.wav", 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, "player/udeath.wav", 1, ATTN_NORM);
-};
-
-//----------------------------------------------------------------------
-void() meat_shower =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = play_meatspray;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "meat_shower";
+ this.classtype = CT_MISC_PLAY_GIBS;
+ this.use = play_meatspray;
+ };
};

/*QUAKED play_gibs (0.3 0.1 0.6) (-10 -10 -8) (10 10 8)
@@ -289,180 +347,204 @@ When triggered, plays a gib effect. Same as meat_shower.
Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regular gib sounds.

*/
-void() play_gibs =
+class play_gibs: base_meat_shower
{
- // same as meat_shower, added for "play_xxxx" consistancy
-
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = play_meatspray;
-};
-
-//----------------------------------------------------------------------
-void() mflash_use =
-{
- self.effects = self.effects | EF_MUZZLEFLASH;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ //--------------------------------------------------------------
+ void() play_gibs =
+ {
+ // same as meat_shower, added for "play_xxxx" consistancy
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_gibs";
+ this.classtype = CT_MISC_PLAY_GIBS;
+ this.use = play_meatspray;
+ };
};

/*QUAKED play_mflash (0 .5 .8) (-8 -8 -8) (8 8 8)
triggable muzzle flash effect entity
*/
-void() play_mflash =
+class play_mflash: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "")
- precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- self.use = mflash_use;
-};
+ //--------------------------------------------------------------
+ virtual void() mflash_use =
+ {
+ this.effects = this.effects | EF_MUZZLEFLASH;

-//======================================================================
-// play_bfield triggerable effect
-//======================================================================
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ };

-//----------------------------------------------------------------------
-void() bfield_toggle =
-{
- if (!self.state)
+ //--------------------------------------------------------------
+ void() play_mflash =
{
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTFIELD;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTFIELD);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_mflash";
+ this.classtype = CT_MISC_PLAY_MFLASH;
+
+ precache_model ("progs/s_null.spr");
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ setmodel (this, "progs/s_null.spr");
+ setorigin (this, this.origin);
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ setsize (this, '0 0 0', '0 0 0');
+ this.use = mflash_use;
+ };
};

/*QUAKED play_bfield (0 .5 .8) (-8 -8 -8) (8 8 8)
a triggerable, spherical field of yellow particles
state 1 = start on
*/
-void() play_bfield =
+class play_bfield: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "")
- precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTFIELD;
- self.use = bfield_toggle;
-};
-
-//======================================================================
-// play_brlight triggerable effect
-//======================================================================
-
-//----------------------------------------------------------------------
-void() brlight_toggle =
-{
- // dumptruck_ds -- thanks to c0burn
- if (!self.state)
+ //--------------------------------------------------------------
+ virtual void() bfield_toggle =
{
- self.state = 1;
- self.effects = self.effects | EF_BRIGHTLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
+ if (!this.state)
+ {
+ this.state = 1;
+ this.effects = this.effects | EF_BRIGHTFIELD;
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ this.state = 0;
+ this.effects = this.effects -
+ (this.effects & EF_BRIGHTFIELD);
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() play_bfield =
{
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_BRIGHTLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_bfield";
+ this.classtype = CT_MISC_PLAY_BFIELD;
+
+ precache_model ("progs/s_null.spr");
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ setmodel (this, "progs/s_null.spr");
+ setorigin (this, this.origin);
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ setsize (this, '0 0 0', '0 0 0');
+ if (this.state)
+ this.effects = this.effects | EF_BRIGHTFIELD;
+ this.use = bfield_toggle;
+ };
};

/*QUAKED play_brlight (0 .5 .8) (-8 -8 -8) (8 8 8)
a triggerable bright lighting effect
state 1 = start on
*/
-void() play_brlight =
+class play_brlight: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "")
- precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_BRIGHTLIGHT;
- self.use = brlight_toggle;
-};
-
-//======================================================================
-// play_dimlight triggerable effect
-//======================================================================
-
-//----------------------------------------------------------------------
-void() dim_toggle =
-{
- if (!self.state)
+ //--------------------------------------------------------------
+ virtual void() brlight_toggle =
{
- self.state = 1;
- self.effects = self.effects | EF_DIMLIGHT;
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
- else
+ // dumptruck_ds -- thanks to c0burn
+ if (!this.state)
+ {
+ this.state = 1;
+ this.effects = this.effects | EF_BRIGHTLIGHT;
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ this.state = 0;
+ this.effects = this.effects -
+ (this.effects & EF_BRIGHTLIGHT);
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() play_brlight =
{
- self.state = 0;
- self.effects = self.effects - (self.effects & EF_DIMLIGHT);
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_brlight";
+ this.classtype = CT_MISC_PLAY_BRLIGHT;
+
+ precache_model ("progs/s_null.spr");
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ setmodel (this, "progs/s_null.spr");
+ setorigin (this, this.origin);
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ setsize (this, '0 0 0', '0 0 0');
+ if (this.state)
+ this.effects = this.effects | EF_BRIGHTLIGHT;
+ this.use = brlight_toggle;
+ };
};

/*QUAKED play_dimlight (0 .5 .8) (-8 -8 -8) (8 8 8)
a triggerable lighting effect
state 1 = start on
*/
-void() play_dimlight =
+class play_dimlight: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- precache_model ("progs/s_null.spr");
- if (self.noise != "")
- precache_sound (self.noise);
-
- setmodel (self, "progs/s_null.spr");
- // setorigin (self, self.origin);
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setsize (self, '0 0 0', '0 0 0');
- if (self.state)
- self.effects = self.effects | EF_DIMLIGHT;
- setorigin (self, self.origin);
- self.use = dim_toggle;
+ //--------------------------------------------------------------
+ virtual void() dim_toggle =
+ {
+ if (!this.state)
+ {
+ this.state = 1;
+ this.effects = this.effects | EF_DIMLIGHT;
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ else
+ {
+ this.state = 0;
+ this.effects = this.effects -
+ (this.effects & EF_DIMLIGHT);
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() play_dimlight =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "play_dimlight";
+ this.classtype = CT_MISC_PLAY_DIMLIGHT;
+
+ precache_model ("progs/s_null.spr");
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ setmodel (this, "progs/s_null.spr");
+ // setorigin (this, this.origin);
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ setsize (this, '0 0 0', '0 0 0');
+ if (this.state)
+ this.effects = this.effects | EF_DIMLIGHT;
+ setorigin (this, this.origin);
+ this.use = dim_toggle;
+ };
};

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

Diff qc/misc/sparks.qc

diff --git a/qc/misc/sparks.qc b/qc/misc/sparks.qc
index 5685b0b..58cdee6 100644
--- a/qc/misc/sparks.qc
+++ b/qc/misc/sparks.qc
@@ -2,159 +2,168 @@
// misc_sparks -- selections from Rubicon 2 qc by john fitzgibbons
//==============================================================================

-// prototypes
-void() make_sparks;
+// constants
+const float MISC_SPARKS_START_OFF = 1;
+const float MISC_SPARKS_BLUE = 2;
+const float MISC_SPARKS_PALE = 4;

-//----------------------------------------------------------------------
-void() sparks_fade1 = [0, sparks_fade2]
-{
- self.alpha = 0.8; self.nextthink = time + 0.05;
-};
+/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) MISC_SPARKS_START_OFF MISC_SPARKS_BLUE MISC_SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

-//----------------------------------------------------------------------
-void() sparks_fade2 = [0, sparks_fade3]
-{
- self.alpha = 0.6; self.nextthink = time + 0.05;
-};
+Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.

-//----------------------------------------------------------------------
-void() sparks_fade3 = [0, sparks_fade4]
-{
- self.alpha = 0.4; self.nextthink = time + 0.05;
-};
+SPARKS_BLUE: sparks are blue in color

-//----------------------------------------------------------------------
-void() sparks_fade4 = [0, SUB_Remove]
-{
- self.alpha = 0.2; self.nextthink = time + 0.05;
-};
+SPARKS_PALE: sparks are pale yellow in color

-//----------------------------------------------------------------------
-void() sparks_use =
-{
- if (self.spawnflags & START_OFF)
- self.spawnflags = self.spawnflags - START_OFF;
- else
- self.spawnflags = self.spawnflags + START_OFF;
-};
+Keys:

-//----------------------------------------------------------------------
-void() spark_turnofflight =
-{
- SUB_UseTargets ();
- self.think = make_sparks;
- self.nextthink = time + (random() + 0.5) * self.wait - 0.15;
-};
+"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
+
+"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.

-//----------------------------------------------------------------------
-void() make_sparks =
+"sounds"
+0) no sound
+1) sparks
+*/
+class misc_sparks: entity
{
+ //--------------------------------------------------------------
+ nonvirtual void() sparks_fade1 = [0, sparks_fade2]
+ {
+ this.alpha = 0.8; this.nextthink = time + 0.05;
+ };

- if (self.spawnflags & START_OFF)
+ //--------------------------------------------------------------
+ nonvirtual void() sparks_fade2 = [0, sparks_fade3]
{
- self.nextthink = time + 0.1;
- self.think = make_sparks;
- }
- else
+ this.alpha = 0.6; this.nextthink = time + 0.05;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() sparks_fade3 = [0, sparks_fade4]
{
- local float i;
- i = -0.25 * self.cnt + random() * 0.5 * self.cnt;
- while (i < self.cnt)
- {
+ this.alpha = 0.4; this.nextthink = time + 0.05;
+ };

- local entity spark;
- spark = spawn ();
- spark.owner = self;
- setmodel (spark, "progs/spark.mdl");
- setorigin (spark, self.origin);
- spark.movetype = MOVETYPE_BOUNCE;
- spark.solid = SOLID_TRIGGER;
- spark.gravity = 0.3;
- spark.velocity_x = -40 + random() * 80;
- spark.velocity_y = -40 + random() * 80;
- spark.velocity_z = -40 + random() * 80;
- spark.avelocity = '3000 3000 3000';
- spark.nextthink = time + 0.5 + 1.5 * random();
- spark.think = sparks_fade1;
- spark.classname = "spark";
-
- if (random() < 0.33)
- spark.skin = 0;
- else if (random() < 0.5)
- spark.skin = 1;
- else
- spark.skin = 2;
-
- if (self.spawnflags & SPARKS_PALE)
- spark.skin = spark.skin + 6;
- else if (self.spawnflags & SPARKS_BLUE)
- spark.skin = spark.skin + 3;
-
- setsize (spark, '0 0 0', '0 0 0');
- i = i + 1;
- }
+ //--------------------------------------------------------------
+ nonvirtual void() sparks_fade4 = [0, SUB_Remove]
+ {
+ this.alpha = 0.2; this.nextthink = time + 0.05;
+ };

- if (self.sounds == 1)
+ //--------------------------------------------------------------
+ virtual void() sparks_use =
+ {
+ if (this.spawnflags & MISC_SPARKS_START_OFF)
+ this.spawnflags = this.spawnflags -
+ MISC_SPARKS_START_OFF;
+ else
+ this.spawnflags = this.spawnflags +
+ MISC_SPARKS_START_OFF;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() spark_turnofflight =
+ {
+ SUB_UseTargets ();
+ this.think = this.make_sparks;
+ this.nextthink = time + (random() + 0.5) * this.wait - 0.15;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() make_sparks =
+ {
+ if (this.spawnflags & MISC_SPARKS_START_OFF)
+ {
+ this.nextthink = time + 0.1;
+ this.think = make_sparks;
+ }
+ else
{
- if (self.noise != "")
+ local float i;
+ i = -0.25 * this.cnt + random() * 0.5 * this.cnt;
+ while (i < this.cnt)
{
- sound (self, CHAN_AUTO, self.noise,
- 1, ATTN_STATIC);
+ local entity spark;
+ spark = spawn ();
+ spark.owner = this;
+ setmodel (spark, "progs/spark.mdl");
+ setorigin (spark, this.origin);
+ spark.movetype = MOVETYPE_BOUNCE;
+ spark.solid = SOLID_TRIGGER;
+ spark.gravity = 0.3;
+ spark.velocity_x = -40 + random() * 80;
+ spark.velocity_y = -40 + random() * 80;
+ spark.velocity_z = -40 + random() * 80;
+ spark.avelocity = '3000 3000 3000';
+ spark.nextthink = time + 0.5 + 1.5 * random();
+ spark.think = sparks_fade1;
+ spark.classname = "spark";
+
+ if (random() < 0.33)
+ spark.skin = 0;
+ else if (random() < 0.5)
+ spark.skin = 1;
+ else
+ spark.skin = 2;
+
+ if (this.spawnflags & MISC_SPARKS_PALE)
+ spark.skin = spark.skin + 6;
+ else if (this.spawnflags & MISC_SPARKS_BLUE)
+ spark.skin = spark.skin + 3;
+
+ setsize (spark, '0 0 0', '0 0 0');
+ i = i + 1;
}
- else
+
+ if (this.sounds == 1)
{
- sound (self, CHAN_AUTO, "enforcer/enfstop.wav",
- 1, ATTN_STATIC);
+ if (this.noise != "")
+ {
+ sound (this, CHAN_AUTO, this.noise,
+ 1, ATTN_STATIC);
+ }
+ else
+ {
+ sound (this, CHAN_AUTO,
+ "enforcer/enfstop.wav",
+ 1, ATTN_STATIC);
+ }
}
- }
-
- SUB_UseTargets ();
- self.nextthink = time + 0.1 + random() * 0.1;
- self.think = spark_turnofflight;
- }
-};
-
-/*QUAKED misc_sparks (0 .5 .8) (-8 -8 -8) (8 8 8) START_OFF SPARKS_BLUE SPARKS_PALE X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Produces a burst of yellow sparks at random intervals. If targeted, it will toggle between on or off. If it targets a light, that light will flash allong with each burst of sparks. Note: targeted lights should be set to START_OFF.
-
-SPARKS_BLUE: sparks are blue in color

-SPARKS_PALE: sparks are pale yellow in color
-
-Keys:
-
-"wait" is the average delay between bursts (variance is 1/2 wait). Default is 2.
-
-"cnt" is the average number of sparks in a burst (variance is 1/4 cnt). Default is 15.
+ SUB_UseTargets ();
+ this.nextthink = time + 0.1 + random() * 0.1;
+ this.think = this.spark_turnofflight;
+ }
+ };

-"sounds"
-0) no sound
-1) sparks
-*/
-void() misc_sparks =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() misc_sparks =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- precache_model ("progs/spark.mdl");
+ this.classname = "misc_sparks";
+ this.classtype = CT_MISC_SPARKS;
+ precache_model ("progs/spark.mdl");

- if (!self.noise)
- precache_sound ("dump/spark.wav");
- else
- precache_sound (self.noise);
+ if (!this.noise)
+ precache_sound ("dump/spark.wav");
+ else
+ precache_sound (this.noise);

- if (!self.movedir)
- self.movedir = '0 0 -30';
+ if (!this.movedir)
+ this.movedir = '0 0 -30';

- if (!self.wait)
- self.wait = 2;
+ if (!this.wait)
+ this.wait = 2;

- if (!self.cnt)
- self.cnt = 15;
+ if (!this.cnt)
+ this.cnt = 15;

- self.use = sparks_use;
- self.nextthink = time + random() * 0.1;
- self.think = make_sparks;
+ this.use = sparks_use;
+ this.nextthink = time + random() * 0.1;
+ this.think = make_sparks;
+ };
};

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

Diff qc/misc/target_autosave.qc

diff --git a/qc/misc/target_autosave.qc b/qc/misc/target_autosave.qc
index 43b7553..b192def 100644
--- a/qc/misc/target_autosave.qc
+++ b/qc/misc/target_autosave.qc
@@ -2,71 +2,6 @@
// target_autosave -- from Copper
//==============================================================================

-//----------------------------------------------------------------------
-void() target_autosave_use =
-{
- if (self.enemy)
- {
- activator = self.enemy;
- self.enemy = world;
- }
-
- if (activator.classname != "player")
- return;
-
- // make sure an autosave fired from a player start doesn't
- // happen too early
- if (time < 2)
- {
- // if (serverflags & SVFL_RESPAWNING)
- // {
- // dprint("RESPAWNING flag set, skipping autosave\n");
- // return;
- // }
- self.enemy = activator;
- self.think = target_autosave_use;
- self.nextthink = 2;
- return;
- }
-
- // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
- autosave (activator, self.message);
-};
-
-//----------------------------------------------------------------------
-void() toggle_autosave =
-{
- local entity e = world;
- local float printed = FALSE;
-
- do {
- e = find (e, classname, "target_autosave");
- if (!e)
- break;
-
- if (e.use == target_autosave_use)
- {
- e.use = SUB_Null;
- if (!printed)
- {
- bprint ("Autosaves disabled\n");
- printed = TRUE;
- }
- }
- else
- {
- e.use = target_autosave_use;
- if (!printed)
- {
- bprint ("Autosaves reenabled\n");
- printed = TRUE;
- }
- }
-
- }
- while (e != world);
-};
-
/*QUAKED target_autosave (1 .0 .5) (-8 -8 -8) (8 8 8)
Saves the game when triggered by a player. Never appears in multiplayer. the bprint tends to stomp any other prints on screen in most quake clients, so use a delayed trigger_relay if you fire this from an important pickup/trigger_counter/something else that puts text on screen more important than the autosave blurb.

@@ -81,16 +16,99 @@ the bprint tends to stomp any other prints on screen in most quake clients, so u
message(string) : "Change save filename" : "auto"
]
*/
-void() target_autosave =
+class target_autosave: entity
{
- if (deathmatch || coop)
+ //--------------------------------------------------------------
+ // autosave -- was in client.qc
+ //--------------------------------------------------------------
+ virtual void(entity client, string savename) autosave =
{
- remove (self);
- return;
- }
+ // autosavename = savename;
+ stuffcmd (client, "echo Autosaving...; wait; save ");
+ stuffcmd (client, savename);
+ stuffcmd (client, "\n");
+ };
+
+ //--------------------------------------------------------------
+ virtual void() target_autosave_use =
+ {
+ if (this.enemy)
+ {
+ activator = this.enemy;
+ this.enemy = world;
+ }
+
+ if (activator.classname != "player")
+ return;
+
+ // make sure an autosave fired from a player start doesn't
+ // happen too early
+ if (time < 2)
+ {
+ // if (serverflags & SVFL_RESPAWNING)
+ // {
+ // dprint("RESPAWNING flag set, skipping "
+ // "autosave\n");
+ // return;
+ // }
+ this.enemy = activator;
+ this.think = target_autosave_use;
+ this.nextthink = 2;
+ return;
+ }
+
+ // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
+ autosave (activator, this.message);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() toggle_autosave =
+ {
+ local entity e = world;
+ local float printed = FALSE;
+
+ do {
+ e = findfloat (e, ::classtype, CT_TARGET_AUTOSAVE);
+ if (!e)
+ break;
+
+ if (e.use == target_autosave_use)
+ {
+ e.use = SUB_Null;
+ if (!printed)
+ {
+ bprint ("Autosaves disabled\n");
+ printed = TRUE;
+ }
+ }
+ else
+ {
+ e.use = target_autosave_use;
+ if (!printed)
+ {
+ bprint ("Autosaves reenabled\n");
+ printed = TRUE;
+ }
+ }
+ }
+ while (e != world);
+ };
+
+ //--------------------------------------------------------------
+ void() target_autosave =
+ {
+ if (deathmatch || coop)
+ {
+ remove (this);
+ return;
+ }
+
+ this.classname = "target_autosave";
+ this.classtype = CT_TARGET_AUTOSAVE;

- if (self.message == string_null)
- self.message = "auto";
- // precache_sound2 ("misc/sav.wav");
- self.use = target_autosave_use;
+ if (this.message == string_null)
+ this.message = "auto";
+ // precache_sound2 ("misc/sav.wav");
+ this.use = target_autosave_use;
+ };
};

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

Diff qc/misc/teleporttrain.qc

diff --git a/qc/misc/teleporttrain.qc b/qc/misc/teleporttrain.qc
index 032363d..56e6418 100644
--- a/qc/misc/teleporttrain.qc
+++ b/qc/misc/teleporttrain.qc
@@ -3,101 +3,6 @@
// Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
//==============================================================================

-// prototypes
-void() teleporttrain_calcmove;
-
-//----------------------------------------------------------------------
-void() teleporttrain_next =
-{
- local vector dir;
-
- setorigin (self, self.enemy.origin + '16 16 16');
-
- if (!self.target)
- {
- self.enemy = world;
- return;
- }
-
- self.enemy = find (world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- dir = normalize ((self.enemy.origin + '16 16 16') -
- self.origin);
- self.velocity = dir * self.speed;
- self.target = self.enemy.target;
- }
- else
- {
- objerror ("unable to find target\n");
- remove (self);
- }
-
- teleporttrain_calcmove ();
-};
-
-//----------------------------------------------------------------------
-void() teleporttrain_wait =
-{
- local float wait_time;
-
- if (self.enemy.wait > 0)
- wait_time = self.enemy.wait;
- else
- wait_time = 0.1;
-
- self.velocity = '0 0 0';
- self.nextthink = time + wait_time;
- self.think = teleporttrain_next;
-};
-
-//----------------------------------------------------------------------
-void() teleporttrain_calcmove =
-{
- local vector delta;
- local float len, spd;
-
- delta = (self.enemy.origin + '16 16 16') - self.origin;
- len = vlen (delta);
- spd = vlen (self.velocity);
- self.nextthink = time + (len / spd);
- self.think = teleporttrain_wait;
-};
-
-//----------------------------------------------------------------------
-void() teleporttrain_use =
-{
- if (self.velocity == '0 0 0')
- teleporttrain_next ();
-};
-
-//----------------------------------------------------------------------
-void() teleporttrain_find =
-{
- // always start positioned on the first path_corner
- self.enemy = find (world, targetname, self.target);
- if (self.enemy.classname == "path_corner")
- {
- setorigin (self, self.enemy.origin + '16 16 16');
- self.target = self.enemy.target;
- }
- else
- {
- objerror ("unable to find target\n");
- remove (self);
- return;
- }
-
- if (self.spawnflags & 4)
- // start immediately even with a targetname
- teleporttrain_next ();
- else if (!self.targetname)
- // not triggered, so start immediately
- teleporttrain_next ();
- else
- self.use = teleporttrain_use;
-};
-
/*QUAKED misc_teleporttrain (.5 .5 .5) (-16 -16 -16) (16 16 16) X DONT_ROTATE START_ON_WITH_TARGETNAME INVISIBLE X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
{ model("progs/teleport.mdl"); }
This was used for the final boss level in the original game. In progs_dump you can use this as a moving decoration or even target it as a spawn point for a func_monster_spawner. Make sure and select the Don't Rotate spawnflag though or you'll experience a pretty hilarious effect!
@@ -117,42 +22,143 @@ Teleporter target for final boss level. Must target a series of 'path_corner' en
It will position itself on its first target at map load.
If a targetname is set, it must be triggered to start moving, otherwise it will start automatically.
*/
-void() misc_teleporttrain =
+class misc_teleporttrain: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() teleporttrain_next =
+ {
+ local vector dir;
+
+ setorigin (this, this.enemy.origin + '16 16 16');
+
+ if (!this.target)
+ {
+ this.enemy = world;
+ return;
+ }
+
+ this.enemy = find (world, ::targetname, this.target);
+ if (this.enemy.classname == "path_corner")
+ {
+ dir = normalize ((this.enemy.origin + '16 16 16') -
+ this.origin);
+ this.velocity = dir * this.speed;
+ this.target = this.enemy.target;
+ }
+ else
+ {
+ objerror ("unable to find target\n");
+ remove (this);
+ }
+
+ teleporttrain_calcmove ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() teleporttrain_wait =
+ {
+ local float wait_time;
+
+ if (this.enemy.wait > 0)
+ wait_time = this.enemy.wait;
+ else
+ wait_time = 0.1;
+
+ this.velocity = '0 0 0';
+ this.nextthink = time + wait_time;
+ this.think = teleporttrain_next;
+ };

- if (!self.target)
+ //--------------------------------------------------------------
+ virtual void() teleporttrain_calcmove =
+ {
+ local vector delta;
+ local float len, spd;
+
+ delta = (this.enemy.origin + '16 16 16') - this.origin;
+ len = vlen (delta);
+ spd = vlen (this.velocity);
+ this.nextthink = time + (len / spd);
+ this.think = teleporttrain_wait;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() teleporttrain_use =
+ {
+ if (this.velocity == '0 0 0')
+ teleporttrain_next ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() teleporttrain_find =
+ {
+ // always start positioned on the first path_corner
+ this.enemy = find (world, ::targetname, this.target);
+ if (this.enemy.classname == "path_corner")
+ {
+ setorigin (this, this.enemy.origin + '16 16 16');
+ this.target = this.enemy.target;
+ }
+ else
+ {
+ objerror ("unable to find target\n");
+ remove (this);
+ return;
+ }
+
+ if (this.spawnflags & 4)
+ // start immediately even with a targetname
+ teleporttrain_next ();
+ else if (!this.targetname)
+ // not triggered, so start immediately
+ teleporttrain_next ();
+ else
+ this.use = teleporttrain_use;
+ };
+
+ //--------------------------------------------------------------
+ void() misc_teleporttrain =
{
- objerror ("misc_teleporttrain has no target");
- remove (self);
- return;
- }
-
- if (self.speed <= 0)
- self.speed = 100;
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_FLY;
- // custom custom_mdls -- dumptruck_ds
- precache_body_model ("progs/teleport.mdl");
- // invisble -- dumptruck_ds
- precache_model ("progs/s_null.spr");
- if (self.spawnflags & 8)
- // setmodel (self, "progs/s_null.spr");
- body_model ("progs/s_null.spr");
- else
- body_model ("progs/teleport.mdl");
- // precache_model ("progs/teleport.mdl");
- setsize (self, '-16 -16 -16', '16 16 16');
-
- // Causes the ball to spin around like it was originally intended to.
- if (!(self.spawnflags & 2))
- // don't spin - helpful for invisible spawner -- dumptruck_ds
- self.avelocity = '40 80 120';
- // self.avelocity = '100 200 300';
-
- self.think = teleporttrain_find;
- self.nextthink = time + 0.1;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "misc_teleporttrain";
+ this.classtype = CT_MISC_TELEPORTTRAIN;
+
+ if (!this.target)
+ {
+ objerror ("misc_teleporttrain has no target");
+ remove (this);
+ return;
+ }
+
+ if (this.speed <= 0)
+ this.speed = 100;
+
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_FLY;
+ // custom custom_mdls -- dumptruck_ds
+ precache_body_model ("progs/teleport.mdl");
+ // invisble -- dumptruck_ds
+ precache_model ("progs/s_null.spr");
+ if (this.spawnflags & 8)
+ // setmodel (this, "progs/s_null.spr");
+ body_model ("progs/s_null.spr");
+ else
+ body_model ("progs/teleport.mdl");
+ // precache_model ("progs/teleport.mdl");
+ setsize (this, '-16 -16 -16', '16 16 16');
+
+ // Causes the ball to spin around like it was
+ // originally intended to.
+ if (!(this.spawnflags & 2))
+ // don't spin - helpful for invisible
+ // spawner -- dumptruck_ds
+ this.avelocity = '40 80 120';
+ // this.avelocity = '100 200 300';
+
+ this.think = teleporttrain_find;
+ this.nextthink = time + 0.1;
+ };
};

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

Diff qc/misc/viewthing.qc

diff --git a/qc/misc/viewthing.qc b/qc/misc/viewthing.qc
index 985dd4a..21ae6e4 100644
--- a/qc/misc/viewthing.qc
+++ b/qc/misc/viewthing.qc
@@ -1,21 +1,24 @@
-//==============================================================================
+//~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
// viewthing -- was in misc.qc
-//==============================================================================
-
-//~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>
+//~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>~<~>

/*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8)

Just for the debugging level. Don't use
*/
-void() viewthing =
+class viewthing: entity
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ void() viewthing =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- precache_model ("progs/player.mdl");
- setmodel (self, "progs/player.mdl");
+ this.classname = "viewthing";
+ this.classtype = CT_MISC_VIEWTHING;
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ precache_model ("progs/player.mdl");
+ setmodel (this, "progs/player.mdl");
+ };
};

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

Diff qc/monsters/zombie.qc

diff --git a/qc/monsters/zombie.qc b/qc/monsters/zombie.qc
index 52df0bc..63cf23d 100644
--- a/qc/monsters/zombie.qc
+++ b/qc/monsters/zombie.qc
@@ -693,34 +693,6 @@ void() zombie_start = // determine if zombie is to be lying down, or standing
self.th_stand = alt_zombie_stand1;
};

-// void() zombie_start2 = //unused in progs_dump -- dumptruck_ds
-// {
-// local vector org;
-// local entity teldeath;
-//
-// if (self.style)
-// {
-// makevectors (self.angles);
-// org = self.origin + 16 * v_forward;
-// spawn_tfog (org);
-// teldeath = spawn();
-// teldeath.origin = org;
-// teldeath.owner = self;
-// // teldeath.think = sf64_teledeath; -- not used in progs_dump -- dumptruck_ds
-// teldeath.nextthink = time + 0.1;
-// }
-//
-// self.solid = SOLID_SLIDEBOX;
-// self.movetype = MOVETYPE_STEP;
-//
-// setmodel (self, "progs/zombie.mdl");
-//
-// setsize (self, '-16 -16 -24', '16 16 40');
-// self.health = 61;
-//
-// walkmonster_start();
-// };
-
//============================================================================

/*QUAKED monster_zombie (1 0 0) (-16 -16 -24) (16 16 32) CRUCIFIED AMBUSH CRUCIFIED_MOTIONLESS TRIGGER_SPAWNED SPAWN_SLEEPING X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

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

Diff qc/newflags.qc

diff --git a/qc/newflags.qc b/qc/newflags.qc
index a7ac7ba..ef462ad 100644
--- a/qc/newflags.qc
+++ b/qc/newflags.qc
@@ -1,11 +1,9 @@
-/*
-========================================================================
-
-NEW SPAWNFLAGS FOR ALL ENTITIES
+//==============================================================================
+// NEW SPAWNFLAGS FOR ALL ENTITIES
+//==============================================================================

+/*
========================================================================
-
-
This file was created for progs_dump by Ian "iw" Walshaw, August 2019.

It defines functions which can be called to implement the following new
@@ -52,7 +50,6 @@ The new "Not on Hard Only" and "Not on Nightmare Only" spawnflags allow
the mapper to exclude an entity from one of these skill levels without
affecting the other.

-
========================================================================
*/

@@ -71,14 +68,12 @@ float total_not_on_skill3;
// TRUE if the developer summary has been printed.
float done_inhibition_summary;

-/*
-================
-InitNewSpawnflags
-
-This function is intended to be called from the top of the worldspawn
-function (in world.qc). -- iw
-================
-*/
+//----------------------------------------------------------------------
+// InitNewSpawnflags
+//
+// This function is intended to be called from the top of the worldspawn
+// function (in world.qc). -- iw
+//----------------------------------------------------------------------
void() InitNewSpawnflags =
{
// Initialize the global variables.
@@ -96,7 +91,7 @@ void() InitNewSpawnflags =
};

/*
-================
+------------------------------------------------------------------------
SUB_Inhibit

This function is intended to be called from the top of every spawn
@@ -109,7 +104,7 @@ If the entity's spawnflags mean that it should be inhibited in the
current game mode or on the current skill level, this function will
remove the entity and return TRUE, otherwise this function will take no
action and return FALSE. -- iw
-================
+------------------------------------------------------------------------
*/
float() SUB_Inhibit =
{
@@ -149,15 +144,13 @@ float() SUB_Inhibit =
return FALSE;
};

-/*
-================
-PrintInhibitionTotal
-
-This just dprints the summary line about the total number of entities
-inhibited by one of the new spawnflags (see PrintInhibitionSummary
-below). -- iw
-================
-*/
+//----------------------------------------------------------------------
+// PrintInhibitionTotal
+//
+// This just dprints the summary line about the total number of entities
+// inhibited by one of the new spawnflags (see PrintInhibitionSummary
+// below). -- iw
+//----------------------------------------------------------------------
void(float total, string spawnflag_name) PrintInhibitionTotal =
{
if (total == 0)
@@ -171,7 +164,7 @@ void(float total, string spawnflag_name) PrintInhibitionTotal =
};

/*
-================
+------------------------------------------------------------------------
PrintInhibitionSummary

This function is intended to be called from the top of the StartFrame
@@ -183,7 +176,7 @@ function (in world.qc), like this:
The engine already logs a developer message about the number of entities
inhibited by the built-in spawnflags; this function logs a message about
the number of entities inhibited by the new spawnflags. -- iw
-================
+------------------------------------------------------------------------
*/
void() PrintInhibitionSummary =
{

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

Diff qc/player.qc

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

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

Diff qc/player/player.qc

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

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

Diff qc/player/playerthink.qc

diff --git a/qc/player/playerthink.qc b/qc/player/playerthink.qc
new file mode 100644
index 0000000..625f97a
--- /dev/null
+++ b/qc/player/playerthink.qc
@@ -0,0 +1,616 @@
+//==============================================================================
+// player/playerthink.qc
+//==============================================================================
+
+// fields
+.float dmgtime;
+
+//----------------------------------------------------------------------
+void() PlayerDeathThink =
+{
+ local float forward;
+
+ if ((self.flags & FL_ONGROUND))
+ {
+ forward = vlen (self.velocity);
+ forward = forward - 20;
+ if (forward <= 0)
+ self.velocity = '0 0 0';
+ else
+ self.velocity = forward * normalize (self.velocity);
+ }
+
+ // wait for all buttons released
+ if (self.deadflag == DEAD_DEAD)
+ {
+ if (self.button2 || self.button1 || self.button0)
+ return;
+ self.deadflag = DEAD_RESPAWNABLE;
+ return;
+ }
+
+ // wait for any button down
+ if (!self.button2 && !self.button1 && !self.button0)
+ return;
+
+ self.button0 = 0;
+ self.button1 = 0;
+ self.button2 = 0;
+ respawn ();
+};
+
+//----------------------------------------------------------------------
+// PlayerClimb -- johnfitz
+//----------------------------------------------------------------------
+void() PlayerClimb =
+{
+ self.velocity = '0 0 160';
+}
+
+//----------------------------------------------------------------------
+// PlayerJump
+//----------------------------------------------------------------------
+void() PlayerJump =
+{
+ if (self.flags & FL_WATERJUMP)
+ return;
+
+ if (self.waterlevel >= 2)
+ {
+ if (self.watertype == CONTENT_WATER)
+ self.velocity_z = 100;
+ else if (self.watertype == CONTENT_SLIME)
+ self.velocity_z = 80;
+ else
+ self.velocity_z = 50;
+
+ // play swiming sound
+ if (self.swim_flag < time)
+ {
+ self.swim_flag = time + 1;
+ if (random() < 0.5)
+ sound (self, CHAN_BODY, "misc/water1.wav",
+ 1, ATTN_NORM);
+ else
+ sound (self, CHAN_BODY, "misc/water2.wav",
+ 1, ATTN_NORM);
+ }
+ return;
+ }
+
+ // refactoring from Copper -- dumptruck_ds
+ if (self.movetype != MOVETYPE_NOCLIP)
+ {
+ if (!(self.flags & FL_ONGROUND))
+ return;
+ // don't pogo stick
+ if ( !(self.flags & FL_JUMPRELEASED) )
+ return;
+ // player jumping sound (h00rt)
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
+ }
+
+ self.flags = self.flags - (self.flags & FL_JUMPRELEASED);
+
+ // don't stairwalk
+ self.flags = self.flags - FL_ONGROUND;
+
+ self.button2 = 0;
+ self.velocity_z = self.velocity_z + 270;
+};
+
+//----------------------------------------------------------------------
+// WaterMove
+//----------------------------------------------------------------------
+void() WaterMove =
+{
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.air_finished = time + 120;
+ return;
+ }
+
+ if (self.health < 0)
+ return;
+
+ if (self.waterlevel != 3)
+ {
+ if (self.air_finished < time)
+ sound (self, CHAN_VOICE, "player/gasp2.wav",
+ 1, ATTN_NORM);
+ else if (self.air_finished < time + 9)
+ sound (self, CHAN_VOICE, "player/gasp1.wav",
+ 1, ATTN_NORM);
+ self.air_finished = time + 12;
+ self.dmg = 2;
+ }
+ else if (self.air_finished < time)
+ {
+ // drown!
+ if (self.pain_finished < time)
+ {
+ self.dmg = self.dmg + 2;
+ if (self.dmg > 15)
+ self.dmg = 10;
+ self.deathtype = "drowning";
+ T_Damage (self, world, world, self.dmg);
+ self.deathtype = "";
+ self.pain_finished = time + 1;
+ }
+ }
+
+ if (!self.waterlevel)
+ {
+ if (self.flags & FL_INWATER)
+ {
+ // play leave water sound
+ sound (self, CHAN_BODY, "misc/outwater.wav",
+ 1, ATTN_NORM);
+ self.flags = self.flags - FL_INWATER;
+ }
+ return;
+ }
+
+ if (self.watertype == CONTENT_LAVA)
+ {
+ // do damage
+ if (self.dmgtime < time)
+ {
+ if (self.radsuit_finished > time)
+ self.dmgtime = time + 1;
+ else
+ self.dmgtime = time + 0.2;
+
+ self.deathtype = "lava";
+ T_Damage (self, world, world, 10 * self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+ else if (self.watertype == CONTENT_SLIME)
+ {
+ // do damage
+ if (self.dmgtime < time && self.radsuit_finished < time)
+ {
+ self.dmgtime = time + 1;
+ self.deathtype = "slime";
+ T_Damage (self, world, world, 4 * self.waterlevel);
+ self.deathtype = "";
+ }
+ }
+
+ if ( !(self.flags & FL_INWATER) )
+ {
+
+ // player enter water sound
+ if (self.watertype == CONTENT_LAVA)
+ sound (self, CHAN_BODY, "player/inlava.wav",
+ 1, ATTN_NORM);
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/inh2o.wav",
+ 1, ATTN_NORM);
+ if (self.watertype == CONTENT_SLIME)
+ sound (self, CHAN_BODY, "player/slimbrn2.wav",
+ 1, ATTN_NORM);
+
+ self.flags = self.flags + FL_INWATER;
+ self.dmgtime = 0;
+ }
+};
+
+//----------------------------------------------------------------------
+// CheckWaterJump
+//----------------------------------------------------------------------
+void() CheckWaterJump =
+{
+ // from Copper -- dumptruck_ds
+ if (self.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ local vector start, end;
+
+ // check for a jump-out-of-water
+ makevectors (self.angles);
+ start = self.origin;
+ start_z = start_z + 8;
+ v_forward_z = 0;
+ normalize (v_forward);
+ end = start + v_forward * 24;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction < 1)
+ {
+ // solid at waist
+ start_z = start_z + self.maxs_z - 8;
+ end = start + v_forward * 24;
+ self.movedir = trace_plane_normal * -50;
+ traceline (start, end, TRUE, self);
+ if (trace_fraction == 1)
+ {
+ // open at eye level
+ self.flags = self.flags | FL_WATERJUMP;
+ self.velocity_z = 225;
+ self.flags -= self.flags & FL_JUMPRELEASED;
+ // safety net
+ self.teleport_time = time + 2; // safety net
+ return;
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+// PlayerPreThink -- Called every frame before physics are run
+//----------------------------------------------------------------------
+void() PlayerPreThink =
+{
+ local float do_ladder_physics = FALSE;
+
+ if (intermission_running)
+ {
+ // otherwise a button could be missed between the think tics
+ IntermissionThink ();
+ return;
+ }
+
+ if (self.view_ofs == '0 0 0')
+ {
+ // Check for cutscene stuff.
+ Cutscene_Think ();
+ // intermission or finale
+ return;
+ }
+
+ // note that this code block is here, before the tests which check
+ // whether the player is dead, so that the player's gravity will be
+ // correctly updated even if they e.g. fell off a ladder because
+ // they died -- iw
+ if (autocvar(pm_standardphysics, FALSE))
+ {
+ if (self.pmove_flags & PMF_ONLADDER)
+ {
+ do_ladder_physics = TRUE;
+ // not zero, because zero means "default"
+ self.gravity = 0.0000001;
+ self.pmove_flags &= ~PMF_ONLADDER;
+ }
+ else
+ {
+ do_ladder_physics = FALSE;
+ self.gravity = self.wantedgravity;
+ }
+ }
+ else
+ {
+ self.gravity = self.wantedgravity;
+ }
+
+ // If just spawned in, try to recover previous fog values from
+ // own client entity, if any
+ if (cleanUpClientStuff)
+ fog_setFromEnt(self, self);
+
+ // is this still used?
+ makevectors (self.v_angle);
+
+ CheckRules ();
+ WaterMove ();
+
+ // Run legacy CheckWaterJump if we're doing standard physics -- CEV
+ if (autocvar(pm_standardphysics, FALSE))
+ if (self.waterlevel == 2)
+ CheckWaterJump ();
+
+ if (self.deadflag >= DEAD_DEAD)
+ {
+ PlayerDeathThink ();
+ return;
+ }
+
+ if (self.deadflag == DEAD_DYING)
+ // dying, so do nothing
+ return;
+
+ // johnfitz ladder conditions, added from Rubicon2 -- dumptruck_ds
+ if (autocvar(pm_standardphysics, FALSE))
+ {
+ if (do_ladder_physics)
+ {
+ if (self.button2)
+ {
+ PlayerClimb ();
+ /*
+ // no ladder footsteps for now
+ if (time > self.ladder_step_finished)
+ {
+ r = random();
+ if (r > 0.66)
+ sound (self, CHAN_BODY,
+ "ladder/metal1.wav",
+ 0.5, ATTN_NORM);
+ else if (r > 0.33)
+ sound (self, CHAN_BODY,
+ "ladder/metal2.wav",
+ 0.5, ATTN_NORM);
+ else
+ sound (self, CHAN_BODY,
+ "ladder/metal3.wav",
+ 0.5, ATTN_NORM);
+ self.ladder_step_finished = time + 0.3;
+ }
+ */
+ }
+ else
+ {
+ self.flags = self.flags | FL_JUMPRELEASED;
+ self.velocity = 0.9 * self.velocity;
+ self.velocity_z = 0;
+ }
+ }
+ else
+ {
+ if (self.button2)
+ PlayerJump ();
+ else
+ self.flags = self.flags | FL_JUMPRELEASED;
+ }
+ }
+
+ // teleporters can force a non-moving pause time
+ if (time < self.pausetime)
+ self.velocity = '0 0 0';
+
+ if (time > self.attack_finished && self.currentammo == 0
+ && self.weapon != IT_AXE)
+ {
+ self.weapon = PlayerBestWeapon ();
+ PlayerSetCurrentAmmo ();
+ }
+
+ // from copper -- dumptruck_ds
+ if (autocvar(pm_standardphysics, FALSE))
+ {
+ if (self.movetype == MOVETYPE_NOCLIP)
+ {
+ self.flags = self.flags | FL_FLY;
+ }
+ }
+
+ // TODO CEV
+ if (self.groundboost_timer <= 0 && (self.teleport_time > time - 0.1))
+ self.groundboost_timer = PM_GROUNDBOOST_WINDOW;
+};
+
+//----------------------------------------------------------------------
+// CheckPowerups -- Check for turning off powerups
+//----------------------------------------------------------------------
+void() CheckPowerups =
+{
+ if (self.health <= 0) return;
+
+ // invisibility
+ if (self.invisible_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.invisible_sound < time)
+ {
+ sound (self, CHAN_AUTO, "items/inv3.wav",
+ 0.5, ATTN_IDLE);
+ self.invisible_sound = time + ((random() * 3) + 1);
+ }
+
+ if (self.invisible_finished < time + 3)
+ {
+ if (self.invisible_time == 1)
+ {
+ sprint (self, "Ring of Shadows magic is "
+ "fading\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/inv2.wav",
+ 1, ATTN_NORM);
+ self.invisible_time = time + 1;
+ }
+
+ if (self.invisible_time < time)
+ {
+ self.invisible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invisible_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_INVISIBILITY;
+ self.invisible_finished = 0;
+ self.invisible_time = 0;
+ }
+
+ // use the eyes
+ self.frame = 0;
+ self.modelindex = modelindex_eyes;
+ }
+ else
+ {
+ // don't use the eyes
+ self.modelindex = modelindex_player;
+ }
+
+ // invincibility
+ if (self.invincible_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.invincible_finished < time + 3)
+ {
+ if (self.invincible_time == 1)
+ {
+ sprint (self, "Protection is almost burned "
+ "out\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/protect2.wav",
+ 1, ATTN_NORM);
+ self.invincible_time = time + 1;
+ }
+
+ if (self.invincible_time < time)
+ {
+ self.invincible_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.invincible_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_INVULNERABILITY;
+ self.invincible_time = 0;
+ self.invincible_finished = 0;
+ }
+ if (self.invincible_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects -= self.effects & EF_DIMLIGHT;
+ }
+
+ // super damage
+ if (self.super_damage_finished)
+ {
+ // sound and screen flash when items starts to run out
+ if (self.super_damage_finished < time + 3)
+ {
+ if (self.super_time == 1)
+ {
+ sprint (self, "Quad Damage is wearing off\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/damage2.wav",
+ 1, ATTN_NORM);
+ self.super_time = time + 1;
+ }
+
+ if (self.super_time < time)
+ {
+ self.super_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.super_damage_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_QUAD;
+ self.super_damage_finished = 0;
+ self.super_time = 0;
+ }
+ if (self.super_damage_finished > time)
+ self.effects = self.effects | EF_DIMLIGHT;
+ else
+ self.effects -= self.effects & EF_DIMLIGHT;
+ }
+
+ // suit
+ if (self.radsuit_finished)
+ {
+ // don't drown
+ self.air_finished = time + 12;
+
+ // sound and screen flash when items starts to run out
+ if (self.radsuit_finished < time + 3)
+ {
+ if (self.rad_time == 1)
+ {
+ sprint (self, "Air supply in Biosuit "
+ "expiring\n");
+ stuffcmd (self, "bf\n");
+ sound (self, CHAN_AUTO, "items/suit2.wav",
+ 1, ATTN_NORM);
+ self.rad_time = time + 1;
+ }
+
+ if (self.rad_time < time)
+ {
+ self.rad_time = time + 1;
+ stuffcmd (self, "bf\n");
+ }
+ }
+
+ if (self.radsuit_finished < time)
+ {
+ // just stopped
+ self.items = self.items - IT_SUIT;
+ self.rad_time = 0;
+ self.radsuit_finished = 0;
+ }
+ }
+};
+
+//----------------------------------------------------------------------
+// PlayerPostThink -- Called every frame after physics are run
+//----------------------------------------------------------------------
+void() PlayerPostThink =
+{
+ // TODO CEV
+ self.SendFlags = 0xffffff;
+
+ if (self.view_ofs == '0 0 0')
+ // intermission or finale
+ return;
+ if (self.deadflag)
+ return;
+
+ // next block was in W_WeaponFrame -- CEV
+ if (time >= self.attack_finished)
+ {
+ if (self.impulse)
+ ImpulseCommands ();
+ if (self.button0)
+ {
+ SuperDamageSound ();
+ PlayerAttack ();
+ }
+ }
+
+ // check to see if player landed and play landing sound
+ if ((self.jump_flag < -300) && (self.flags & FL_ONGROUND) &&
+ (self.health > 0))
+ {
+ if (self.watertype == CONTENT_WATER)
+ sound (self, CHAN_BODY, "player/h2ojump.wav",
+ 1, ATTN_NORM);
+ else if (self.jump_flag < -650)
+ {
+ self.deathtype = "falling";
+ T_Damage (self, world, world, 5);
+ self.deathtype = "";
+ sound (self, CHAN_VOICE, "player/land2.wav",
+ 1, ATTN_NORM);
+ }
+ else
+ sound (self, CHAN_VOICE, "player/land.wav",
+ 1, ATTN_NORM);
+
+ self.jump_flag = 0;
+ }
+
+ if (!(self.flags & FL_ONGROUND))
+ self.jump_flag = self.velocity_z;
+
+ // dumptruck_ds -- this replaces item_megahealth_rot in items.qc
+ if (self.health > self.max_health)
+ {
+ if (self.megahealth_rottime < time)
+ {
+ self.megahealth_rottime = time + 1;
+ self.health = self.health - 1;
+ }
+ else if (self.health <= 100)
+ {
+ // thanks ydrol!!!
+ self.items = self.items - (self.items & IT_SUPERHEALTH);
+ }
+ }
+
+ CheckPowerups ();
+
+ // from Copper -- dumptruck_ds
+ if (autocvar(pm_standardphysics, FALSE))
+ if (self.movetype != MOVETYPE_NOCLIP)
+ // self.flags = not(self.flags, FL_FLY);
+ self.flags &= ~FL_FLY;
+};

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

Diff qc/player/pmove.qc

diff --git a/qc/player/pmove.qc b/qc/player/pmove.qc
new file mode 100644
index 0000000..561f5d6
--- /dev/null
+++ b/qc/player/pmove.qc
@@ -0,0 +1,2165 @@
+//==============================================================================
+// PMOVE
+//==============================================================================
+
+// TODO CEV: crouching
+// TODO CEV: crouch sliding (useful for sliding up stairs)
+// TODO CEV: crouch-wall-thing (wallrunning? wall sliding?)
+// TODO CEV: improved player unstick function
+// TODO CEV: more work on walking
+// TODO CEV: varied sounds (footsteps, different jump sounds)
+
+// globals managed by FTEQW, from fteextensions.qc -- CEV
+float input_buttons;
+// float input_impulse;
+float input_timelength;
+vector input_angles; // +x = DOWN
+vector input_movevalues;
+
+// fields
+// note: timers are expensive, require synch between server and client -- CEV
+.entity groundentity;
+.vector groundnormal;
+.float pmove_flags; // custom movement flags -- CEV
+.float doublejump_timer; // time in which a player can doublejump
+.float groundboost_timer; // time to apply low friction -- CEV
+.void() customphysics;
+
+// pmove constants; it's definitely possible to rework these as cvars -- CEV
+// acceleration & friction
+const float PM_AIRACCEL = 8.0f; // 10 in Q1; now 7.5
+const float PM_AIRACCELQ3 = 0.8f; // 1.0 in Q3 ?; now 0.75
+const float PM_AIRACCELFWD = 1.0f; // 1 feels close to Q3 / CPM
+const float PM_AIRACCELBACK = 5.0f; // Air stop speed in Q3?
+const float PM_AIRACCELTURN = 100.0f; // affects +fwd style turning radius
+const float PM_BOOSTACCEL = 12.0f; // ground boost accel; 10 is enough
+const float PM_BOOSTFRICTION = 4.0f; // ground boost friction; 4 is Q1
+const float PM_GROUNDACCEL = 15.0f; // 10 is normal, 15 is CPM
+const float PM_GROUNDFRICTION = 8.0f; // 4 for Q1, 6 for Q3, 8 for CPM
+const vector PM_GROUNDDIST_V = '0 0 1'; // distance for ground check
+const float PM_WATERACCEL = 10.0f; // water acceleration
+const float PM_WATERFRICTION = 4.0f; // friction in water
+
+// horizontal speeds (mostly)
+const float PM_CROUCHSPEED = 120.0f; // ???
+const float PM_MAXSPEED = 320.0f; // 320 always
+const float PM_MAXAIRSPEED = 30.0f; // 30 for Q1 air control
+const float PM_RUNSPEED = 400.0f; // run speed override
+const float PM_STOPSPEED = 100.0f;
+const float PM_TELEEXITSPEED = 400.0f; // exit teleporters at this speed
+const float PM_WALKSPEED = 200.0f; // walk speed override
+const float PM_WATERMAXSPEED = 224.0f; // 320 * 0.7
+const float PM_WATERSINKSPEED = 60.0f;
+
+// vertical speeds (mostly)
+const float PM_GRAVITY = 800.0f; // unless sv_gravity, scaled by .gravity
+const float PM_JUMPSPEED = 270.0f; // standard jump Z velocity; 90 * 3
+const float PM_DOUBLEJUMPSPEED = 270.0f;// 270 * 1.5 in CPM; 360 here
+const float PM_STAIRJUMPSPEED = 360.0f; // 360 = 90 * 4
+const float PM_TELEJUMPSPEED = 360.0f; // same as STAIRJUMPSPEED
+const float PM_WALLJUMPFORCE = 90.0f; // 90 * 2; push away from wall
+const float PM_WALLJUMPGROUND = 36.0f; // distance from ground to allow WJ
+const float PM_WALLJUMPLIMIT = -180.f; // no walljump if Z vel below this
+const float PM_WALLJUMPSPEED = 270.0f; // 225 = 90 * 2.5; wall jump
+const float PM_WALLJUMPDOUBLE = 360.0f; // 315 = 90 * 3.5; wall doublejump
+
+// timing
+const float PM_DOUBLEJUMP_WINDOW = 0.4f;// 2 jumps in this time is a double
+const float PM_GROUNDBOOST_WINDOW = 0.4f;// groundboost duration
+const float PM_TELEJUMP_WINDOW = 0.4f; // duration to perform a telejump
+const float PM_WALLJUMP_WINDOW = 0.2f; // duration between walljumps
+const float PM_WALLCLIP_WINDOW = 0.25f; //
+
+// misc
+const float PM_OVERCLIP = 1.0f; // Quake3's OVERCLIP is 1.001f
+const float PM_ONESIDEDCLIP = -0.1; // -0.001;
+const float PM_STEPHEIGHT = 18.0f; // 18 for Q1, 22 for later games?
+const vector PM_TELEDROP = '0 0 -64'; // drop teleporter exit to floor if
+ // floor is within this distance
+// water level
+const int WATERLEVEL_NONE = 0;
+const int WATERLEVEL_FEET = 1;
+const int WATERLEVEL_WAIST = 2;
+const int WATERLEVEL_EYES = 3;
+
+//
+const vector CROUCHED_MINS = '-16 -16 -18';// VEC_HULL_MIN is '-16 -16 -24'
+const vector CROUCHED_MAXS = '16 16 18';// VEC_HULL_MAX is '16 16 32'
+
+// pmove_flags
+enumflags
+{
+ PMF_ONGROUND, // entity is on ground
+ PMF_STARTGROUND, // entity started the move on ground
+ PMF_ONLADDER, // entity is on a ladder
+ PMF_INWATER, // entity is in water
+ PMF_CROUCH_HELD, // player is holding the crouch key
+ PMF_CROUCHED, // entity is crouching
+ PMF_JUMP_HELD, // player is holding the jump key
+ PMF_DOUBLEJUMPED, // entity has doublejumped
+ PMF_WALLJUMPED, // entity has walljumped
+ PMF_WATERJUMPED, // entity has waterjumped
+ PMF_PRE_MOVE // hint that origin hasn't updated yet
+};
+
+// prototypes
+static void(entity ent) PM_DoTouch;
+float() PM_Nudge;
+void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove;
+void() PM_CategorizePosition;
+void(float friction, float move_time) PM_Friction;
+void(vector wishdir, float wishspeed, float accel, float move_time)
+ PM_Accelerate;
+void(vector wishvel, float wishspeed, float accel, float move_time)
+ PM_AirAccelerate;
+void(vector wishdir, float wishspeed, float move_time) PM_AirControl;
+void() PM_Jump;
+void() PM_WallJump;
+void(vector wishvel, float move_time) PM_WalkAccelerate;
+void(vector wishvel, float move_time) PM_SwimAccelerate;
+void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate;
+void(float move_time) PM_ManageTimers;
+void(entity target) PM_Move;
+
+#ifdef SSQC
+//----------------------------------------------------------------------
+// SV_RunClientCommand -- server-side movement entrypoint -- CEV
+//----------------------------------------------------------------------
+void() SV_RunClientCommand =
+{
+ // should match the one used by csqc.
+ if (autocvar(pm_standardphysics, FALSE))
+ // for testing -- CEV
+ runstandardplayerphysics (self);
+ else
+ // for real
+ PM_Move (self);
+};
+#endif
+
+//----------------------------------------------------------------------
+// PM_DoTouch
+//----------------------------------------------------------------------
+static void(entity ent) PM_DoTouch =
+{
+ if (ent && ent.touch != __NULL__)
+ {
+ local entity orig_self;
+
+ orig_self = self;
+ other = self;
+ self = ent;
+ self.touch ();
+ self = orig_self;
+ }
+};
+
+//----------------------------------------------------------------------
+// PM_Nudge
+// from the GPL2 CSQCTest code that comes with FTEQW; is called often
+// to nudge player origin due to float/network precision errors -- CEV
+//----------------------------------------------------------------------
+float() PM_Nudge =
+{
+ vector test, org = self.origin;
+
+ // check current position.
+ tracebox (org, self.mins, self.maxs, org, FALSE, self);
+ if (!trace_startsolid)
+ return TRUE;
+
+ // truncate to network accuracy
+ org_x = floor (org_x * 8 + (1.0 / 16)) * 0.125;
+ org_y = floor (org_y * 8 + (1.0 / 16)) * 0.125;
+ org_z = floor (org_z * 8 + (1.0 / 16)) * 0.125;
+
+ test = org;
+
+ static float offsets[] = {0, -1./8, 1./8, -2./8, 2./8};
+ for (float z = 0; z < offsets.length; z++)
+ {
+ test.z = org.z + offsets[z];
+ for (float y = 0; y < offsets.length; y++)
+ {
+ test.y = org.y + offsets[y];
+ for (float x = 0; x < offsets.length; x++)
+ {
+ test.x = org.x + offsets[x];
+ tracebox (test, self.mins, self.maxs, test,
+ FALSE, self);
+ if (!trace_startsolid)
+ {
+ // okay, that'll do
+ self.origin = test;
+ return TRUE;
+ }
+ }
+ }
+ }
+ self.origin = org;
+ return FALSE;
+};
+
+//----------------------------------------------------------------------
+// PM_DanceMove
+//
+// Updates origin according to velocity, moves the player through the world.
+// Same as Q3 SlideMove and Q1 FlyMove. This version handles steps, applies
+// gravity, and restores velocity based on a timer check (those latter two
+// are features of Q3's SlideMove). I've inlined a number of functions
+// (ClipVelocity, DoTouch) to hopefully improve performance.
+//
+// Based on code from the Nuclide SDK (presumably by Eukara), specifically
+// the function PMoveCustom_Move found in the file pmove_custom.qc. This
+// in turn appears to be based on a similar function in the CSQCTest code
+// that comes with FTEQW. -- CEV
+//----------------------------------------------------------------------
+void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
+{
+ vector end, prev_plane, prev_plane2, plane, start_v;
+ float backoff, grav, stepsize, time_left;
+ int i;
+ entity touched_ent;
+
+ // silence some FTEQCC warnings -- CEV
+ end = prev_plane = prev_plane2 = plane = start_v = '0 0 0';
+ backoff = grav = stepsize = time_left = 0;
+
+ if (dogravity)
+ {
+ if (self.gravity)
+ grav = self.gravity;
+ else
+ grav = 1.0;
+ grav = grav * autocvar (sv_gravity, PM_GRAVITY) *
+ input_timelength;
+ // Half now, half later. Apparently affects framerate
+ // dependence. -- CEV
+ self.velocity_z -= grav * 0.5;
+ }
+
+ start_v = self.velocity;
+
+ // Borrowing FTEQW's pm_airstep cvar here. If false, don't step up
+ // while in the air (changes stairs) -- CEV
+ if (!(autocvar(pm_airstep, TRUE)) && !(self.pmove_flags & PMF_ONGROUND))
+ dostep = FALSE;
+
+ // no stepping. useful for testing -- CEV
+ if (autocvar(pm_nostep, FALSE))
+ dostep = FALSE;
+
+ // we need to bounce off surfaces (in order to slide along them),
+ // so we need at 2 attempts -- comment from the Nuclide SDK
+ // I've changed this to a larger number of attempts (from 3 to 5)
+ // to accommodate more complex plane interactions -- CEV
+ for (i = 5, time_left = input_timelength; time_left > 0 && i; i--)
+ {
+ // set our destination & test the move -- CEV
+ 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 (PM_Nudge())
+ continue;
+
+ // nah, we're stuck. don't build up falling damage
+ // but allow sideways acceleration -- CEV
+ /*
+ #ifdef CSQC
+ dprint ("PM_DanceMove: client ");
+ #endif
+ #ifdef SSQC
+ dprint ("PM_DanceMove: server ");
+ #endif
+ #if defined(CSQC) || defined(SSQC)
+ dprint ("entity trapped in a solid!\n");
+ #endif
+ */
+ self.velocity_z = 0;
+ break;
+ }
+
+ // accept the move -- CEV
+ self.origin = trace_endpos;
+
+ if (trace_fraction >= 1.0f)
+ // no obstructions, made the whole move -- CEV
+ break;
+
+ // zero out stepsize, then store the plane normal and touched
+ // ent for later, then reduce time_left -- CEV
+ stepsize = 0;
+ plane = trace_plane_normal;
+ touched_ent = trace_ent;
+ time_left -= time_left * trace_fraction;
+
+ // integrated StepSlideMove from Nuclide / CSQCTest -- CEV
+ // only attempt to step if there's time left, stepping was
+ // requested, and we hit something like a vertical plane
+ if (dostep && time_left && plane_z >= 0 && plane_z <= 0.7f)
+ {
+ // first: move up
+ trace_endpos = self.origin;
+ trace_endpos_z += PM_STEPHEIGHT;
+ tracebox (self.origin, self.mins, self.maxs,
+ trace_endpos, FALSE, self);
+
+ // don't like having to store another float & vector
+ // but this solves more interactions (ztndm3) -- CEV
+ local float roof_fraction = trace_fraction;
+ local vector roof_plane = trace_plane_normal;
+
+ // second: move forward
+ stepsize = trace_endpos_z - self.origin_z;
+ end = trace_endpos + (self.velocity * time_left);
+ end_z = trace_endpos_z;
+ tracebox (trace_endpos, self.mins, self.maxs, end,
+ FALSE, self);
+
+ // save trace_ent if it has a touch function
+ if (trace_ent && trace_ent.touch != __NULL__)
+ touched_ent = trace_ent;
+
+ if (trace_allsolid || trace_startsolid)
+ {
+ // reject the move immediately -- CEV
+ #ifdef SSQC
+ dprint ("PM_DanceMove: fwd move solid\n");
+ #endif
+ stepsize = 0;
+ self.velocity = '0 0 0';
+ break;
+ }
+ else if (trace_fraction >= 1.0f)
+ {
+ // storing another vector, disappointed in
+ // myself -- CEV
+ local vector fwd_plane = trace_plane_normal;
+
+ // forward move didn't hit anything
+ // third: move down
+ end = trace_endpos;
+ end_z -= stepsize + 1;
+ tracebox (trace_endpos, self.mins, self.maxs,
+ end, FALSE, self);
+
+ if (trace_allsolid || trace_startsolid)
+ {
+ // again reject the move -- CEV
+ #ifdef SSQC
+ dprint ("PM_DanceMove: down move "
+ "solid\n");
+ #endif
+ stepsize = 0;
+ self.velocity = '0 0 0';
+ break;
+ }
+ else if (trace_fraction < 1.0f &&
+ trace_plane_normal_z > 0.7f)
+ {
+ // good ground, accept the move
+ if (roof_fraction < 1.0f &&
+ roof_plane != fwd_plane &&
+ roof_plane != plane)
+ {
+ // do a simple clipvel to the
+ // roof plane right now -- CEV
+ self.velocity -= roof_plane *
+ (self.velocity *
+ roof_plane);
+ }
+
+ stepsize = trace_endpos_z -
+ self.origin_z;
+ self.origin = trace_endpos;
+ time_left -= time_left * trace_fraction;
+
+ prev_plane2 = __NULL__;
+ prev_plane = fwd_plane;
+ plane = trace_plane_normal;
+
+ if (trace_ent &&
+ trace_ent.touch != __NULL__)
+ touched_ent = trace_ent;
+
+ // don't attempt to step again
+ dostep = FALSE;
+ }
+ else
+ {
+ // down move didn't hit and/or
+ // it hit a plane too steep to
+ // be ground -- CEV
+ stepsize = 0;
+ }
+ }
+ else if (trace_plane_normal != plane)
+ {
+ // raised forward move hit something different
+ // than the initial move so clip velocity to
+ // it. solves issues with weird ceilings and
+ // complex movement on stairs. note that we're
+ // not updating origin. -- CEV
+ prev_plane2 = __NULL__;
+ prev_plane = __NULL__;
+ time_left -= time_left * trace_fraction;
+ stepsize = 0;
+
+ if (roof_fraction < 1.0f &&
+ roof_plane != trace_plane_normal)
+ {
+ // save the roof plane & fwd plane
+ prev_plane = roof_plane;
+ plane = trace_plane_normal;
+ }
+ else if (roof_plane == trace_plane_normal)
+ {
+ // roof plane is fwd plane, so save
+ // first and fwd plane
+ prev_plane = plane;
+ plane = trace_plane_normal;
+ }
+ else
+ {
+ // only save fwd plane
+ plane = trace_plane_normal;
+ }
+ }
+ }
+
+ // need to do the ground check & touch the saved ent before
+ // we might stop the loop early -- CEV
+ if (plane_z > 0.7)
+ {
+ if (touched_ent.solid == SOLID_BSP)
+ {
+ self.groundentity = touched_ent;
+ self.groundnormal = plane;
+ self.flags |= FL_ONGROUND;
+ self.pmove_flags |= PMF_ONGROUND;
+ }
+ }
+ else
+ {
+ self.groundentity = __NULL__;
+ self.groundnormal = __NULL__;
+ self.flags &= ~FL_ONGROUND;
+ self.pmove_flags &= ~PMF_ONGROUND;
+ }
+
+ // touch the saved entity; inline PM_DoTouch -- CEV
+ if (touched_ent && touched_ent.touch != __NULL__)
+ {
+ local entity orig_self;
+
+ orig_self = self;
+ other = self;
+ self = touched_ent;
+ self.touch ();
+ self = orig_self;
+ }
+
+ // clip velocity to the saved plane
+ // inline PM_Rebound aka PM_ClipVelocity -- CEV
+ backoff = self.velocity * plane;
+
+ if (backoff < 0)
+ backoff *= PM_OVERCLIP;
+ else
+ if (sticky)
+ backoff /= PM_OVERCLIP;
+ else
+ backoff *= PM_ONESIDEDCLIP;
+
+ self.velocity -= plane * backoff;
+
+ // if velocity interacts with prev_plane then clip to it.
+ // I'm duplicating a little code here (ClipVelocity),
+ // hopefully the audience will forgive me. -- CEV
+ if (prev_plane && prev_plane != plane &&
+ self.velocity * prev_plane < 0)
+ {
+ backoff = self.velocity * prev_plane;
+
+ if (backoff < 0)
+ backoff *= PM_OVERCLIP;
+ else
+ if (sticky)
+ backoff /= PM_OVERCLIP;
+ else
+ backoff *= PM_ONESIDEDCLIP;
+
+ self.velocity -= prev_plane * backoff;
+
+ // Slide along the crease of previous plane and
+ // current plane if the two still interact -- CEV
+ if (self.velocity * plane < 0)
+ {
+ end = crossproduct (prev_plane, plane);
+ end = normalize (end);
+ self.velocity = end * (end * self.velocity);
+ }
+
+ // An optimization from Quake 3 -- CEV
+ if (prev_plane2 && prev_plane2 != plane &&
+ prev_plane2 != prev_plane &&
+ self.velocity * prev_plane2 < 0)
+ {
+ // Stop if we interact with three planes -- CEV
+ #ifdef SSQC
+ dprint ("PM_DanceMove: triple plane stop\n");
+ #endif
+ self.velocity = '0 0 0';
+ break;
+ }
+ }
+
+ // an optimization from Quake 1; is this necessary? -- CEV
+ if ((self.velocity * start_v) <= 0)
+ {
+ // we've turned against original velocity so
+ // clear vel and stop the loop
+ self.velocity = '0 0 0';
+ break;
+ }
+
+ // store current plane and prev_plane for later -- CEV
+ if (prev_plane)
+ prev_plane2 = prev_plane;
+ prev_plane = plane;
+ }
+
+ // wallclip / wall skim timer check
+ // if doskim is true and velocity is non-zero and we lost speed
+ // during the move then restore velocity -- CEV
+ if (doskim && self.velocity && (vlen(start_v) > vlen(self.velocity)))
+ {
+ /*
+ #ifdef SSQC
+ dprint ("PM_DanceMove: wall skim, restoring velocity...\n");
+ #endif
+ */
+ // take the start Z or clipped Z, whichever is lower -- CEV
+ if (start_v_z > self.velocity_z)
+ self.velocity = [start_v_x, start_v_y, self.velocity_z];
+ else
+ self.velocity = start_v;
+ }
+
+ // final gravity check here -- CEV
+ if (dogravity)
+ self.velocity_z -= grav * 0.5;
+
+ // if stepsize is nonzero and we changed from inair to onground then
+ // we've airstepped. this check is here as a placeholder for possible
+ // functionality later -- CEV
+ #ifdef SSQC
+ if (stepsize > 0 && !(self.pmove_flags & PMF_STARTGROUND) &&
+ self.pmove_flags & PMF_ONGROUND)
+ {
+ // more debugging -- CEV
+ dprint (sprintf("PM_DanceMove: airstep: %g\n", stepsize));
+ }
+ #endif
+
+ // a final call to setorigin to update links -- CEV
+ setorigin (self, self.origin);
+
+ /*
+ #ifdef SSQC
+ if (cvar("developer"))
+ // for debugging purposes -- CEV
+ dprint (sprintf("PM_DanceMove: %g bumps\n", 5 - i));
+ #endif
+ */
+};
+
+//----------------------------------------------------------------------
+// PM_CategorizePosition
+// Based on similarly-named function in the GPL2 purecsqc pmove.qc
+//----------------------------------------------------------------------
+void() PM_CategorizePosition =
+{
+ vector point;
+ float contents;
+
+ if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
+ {
+ // noclip is never on ground
+ self.groundentity = __NULL__;
+ self.groundnormal = __NULL__;
+ self.pmove_flags &= ~PMF_DOUBLEJUMPED;
+ self.pmove_flags &= ~PMF_WALLJUMPED;
+ self.pmove_flags &= ~PMF_ONGROUND;
+ self.flags &= ~FL_ONGROUND;
+ }
+ else
+ {
+ // TODO CEV there must be a way to optimize out this
+ // tracebox ground check some of the time
+
+ // do a trace to check for ground
+ tracebox (self.origin, self.mins, self.maxs,
+ self.origin - PM_GROUNDDIST_V, FALSE, self);
+ // only onground if we hit it & it faces upwards
+ if (trace_fraction < 1.0f && trace_plane_normal_z > 0.7f)
+ {
+ // on ground
+ self.groundentity = trace_ent;
+ self.groundnormal = trace_plane_normal;
+ self.flags |= FL_ONGROUND;
+ self.pmove_flags |= PMF_ONGROUND;
+ self.pmove_flags &= ~PMF_WALLJUMPED;
+ }
+ else
+ {
+ // not on ground
+ self.groundentity = __NULL__;
+ self.groundnormal = __NULL__;
+ self.flags &= ~FL_ONGROUND;
+ self.pmove_flags &= ~PMF_ONGROUND;
+ }
+ }
+
+ // check water levels
+ point = self.origin;
+ point_z = self.origin_z + self.mins_z + 1;
+ contents = pointcontents (point);
+ if (contents < CONTENT_SOLID)
+ {
+ self.watertype = contents;
+ point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5;
+ if (pointcontents(point) < CONTENT_SOLID)
+ {
+ point_z = self.origin_z + self.maxs_z;
+ if (pointcontents(point) < CONTENT_SOLID)
+ self.waterlevel = WATERLEVEL_EYES;
+ else
+ self.waterlevel = WATERLEVEL_WAIST;
+ }
+ else
+ {
+ self.waterlevel = WATERLEVEL_FEET;
+ }
+ }
+ else
+ {
+ self.watertype = CONTENT_EMPTY;
+ self.waterlevel = WATERLEVEL_NONE;
+ }
+
+ // can't be waterjumping if we're on ground
+ if (self.pmove_flags & PMF_WATERJUMPED &&
+ (self.waterlevel == WATERLEVEL_NONE ||
+ self.pmove_flags & PMF_ONGROUND))
+ {
+ #ifdef SSQC
+ dprint ("PM_CategorizePosition: clearing FL_WATERJUMP\n");
+ #endif
+ self.pmove_flags &= ~PMF_WATERJUMPED;
+ self.flags &= ~FL_WATERJUMP;
+ }
+};
+
+//----------------------------------------------------------------------
+// PM_Friction
+// Ground friction
+//----------------------------------------------------------------------
+void(float friction, float move_time) PM_Friction =
+{
+ float control, newspeed, speed;
+
+ speed = vlen (self.velocity);
+
+ if (speed < 1)
+ {
+ self.velocity = '0 0 0';
+ return;
+ }
+
+ // calculate what their new speed should be
+ control = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
+ newspeed = speed - control * friction * move_time;
+
+ // and slow them
+ if (newspeed < 0)
+ newspeed = 0;
+
+ self.velocity = self.velocity * (newspeed / speed);
+};
+
+//----------------------------------------------------------------------
+// PM_Accelerate
+// Ground acceleration & Quake 3 style air acceleration -- CEV
+//----------------------------------------------------------------------
+void(vector wishdir, float wishspeed, float accel, float move_time)
+ PM_Accelerate =
+{
+ float newspeed, speed;
+
+ speed = wishspeed - (self.velocity * wishdir);
+
+ if (speed <= 0)
+ return;
+
+ newspeed = accel * move_time * wishspeed;
+ if (newspeed > speed)
+ newspeed = speed;
+
+ self.velocity += newspeed * wishdir;
+};
+
+//----------------------------------------------------------------------
+// PM_AirAccelerate
+// Quake 1 style air acceleration -- CEV
+//----------------------------------------------------------------------
+void(vector wishvel, float wishspeed, float accel, float move_time)
+ PM_AirAccelerate =
+{
+ float newspeed, speed, wishspd;
+
+ // need to ignore Z velocity -- CEV
+ wishvel = [wishvel_x, wishvel_y, 0];
+ wishspd = vlen (wishvel);
+ wishvel = normalize (wishvel);
+ if (wishspd > PM_MAXAIRSPEED)
+ wishspd = PM_MAXAIRSPEED;
+ speed = self.velocity * wishvel;
+ speed = wishspd - speed;
+
+ if (speed <= 0)
+ return;
+
+ newspeed = accel * move_time * wishspeed;
+ if (newspeed > speed)
+ newspeed = speed;
+ self.velocity += newspeed * wishvel;
+};
+
+//----------------------------------------------------------------------
+// PM_AirControl
+// CPM / Painkiller-like Air Control. Based on Xonotic sources. -- CEV
+//----------------------------------------------------------------------
+void(vector wishdir, float wishspeed, float move_time) PM_AirControl =
+{
+ local float speed, zspeed;
+
+ zspeed = self.velocity_z;
+ self.velocity_z = 0;
+
+ speed = vlen (self.velocity);
+ self.velocity = normalize (self.velocity);
+
+ if ((self.velocity * wishdir) > 0)
+ {
+ self.velocity = normalize (self.velocity * speed +
+ wishdir * PM_AIRACCELTURN);
+ }
+
+ self.velocity *= speed;
+ self.velocity_z = zspeed;
+};
+
+//----------------------------------------------------------------------
+// PM_Jump
+//----------------------------------------------------------------------
+void() PM_Jump =
+{
+ // are we already waterjumping, or is jump being held?
+ if (self.pmove_flags & PMF_WATERJUMPED ||
+ self.pmove_flags & PMF_JUMP_HELD)
+ return;
+
+ #ifdef SSQC
+ local string msg = "";
+ #endif
+
+ // make sure we get at least jumpspeed upwards from
+ // the ground plane by clamping it first.
+ if (self.groundnormal && (self.velocity * self.groundnormal < 0))
+ {
+ // #ifdef SSQC
+ // dprint("PM_Jump: clamping to ground\n");
+ // #endif
+ self.velocity -= self.groundnormal *
+ (self.velocity * self.groundnormal);
+ }
+
+ // make sure we get at least the indicated jump speed
+ // this changes the behavior of downward ramps -- CEV
+ if (self.velocity_z < 0)
+ self.velocity_z = 0;
+
+ if (self.doublejump_timer > 0)
+ {
+ // it may be useful in the future (for a tricks mode, etc)
+ // to distinguish between different jump types -- CEV
+ if (self.teleport_time > time - (PM_TELEJUMP_WINDOW + 0.2))
+ {
+ // a teleport jump: allow a larger (+0.2) window to
+ // account for time to travel thru teleporter -- CEV
+ #ifdef SSQC
+ msg = sprintf ("PM_Jump: telejump %g, ",
+ self.velocity_z);
+ #endif
+ // non-additive jump, though it shouldn't matter -- CEV
+ self.velocity_z = PM_TELEJUMPSPEED;
+ }
+ else if (self.groundnormal && self.groundnormal_z == 1 &&
+ self.groundboost_timer > 0)
+ {
+ #ifdef SSQC
+ msg = sprintf ("PM_Jump: stairjump %g, ",
+ self.velocity_z);
+ #endif
+ // don't do additive stairjumps on flat ground -- CEV
+ self.velocity_z = PM_STAIRJUMPSPEED;
+ }
+ else
+ {
+ #ifdef SSQC
+ msg = sprintf ("PM_Jump: doublejump %g, ",
+ self.velocity_z);
+ #endif
+ // the groundnormal might be weird - some kind of
+ // ramp - so we want an additive doublejump here -- CEV
+ self.velocity_z += PM_DOUBLEJUMPSPEED;
+ }
+
+ // set the doublejump flag -- CEV
+ self.pmove_flags |= PMF_DOUBLEJUMPED;
+ }
+ else
+ {
+ // normal jump
+ #ifdef SSQC
+ if (self.velocity_z > 0)
+ msg = sprintf ("PM_Jump: jump %g, ", self.velocity_z);
+ #endif
+
+ // do an additive jump -- CEV
+ self.velocity_z += PM_JUMPSPEED;
+ }
+
+ // report new Z velocity
+ #ifdef SSQC
+ if (msg != "")
+ dprint (sprintf("%s %g\n", msg, self.velocity_z));
+ #endif
+
+ // manage flags -- CEV
+ self.groundentity = __NULL__;
+ self.groundnormal = __NULL__;
+ self.pmove_flags &= ~PMF_ONGROUND;
+ self.flags &= ~FL_ONGROUND;
+ self.pmove_flags |= PMF_JUMP_HELD;
+ self.button2 = 0;
+ #ifdef SSQC
+ // player jumping sound; copied into pmove from client.qc -- CEV
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
+ #endif
+
+ // timers for all jumps -- CEV
+ self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
+ self.groundboost_timer = PM_GROUNDBOOST_WINDOW;
+};
+
+//----------------------------------------------------------------------
+// PM_WallJump
+//----------------------------------------------------------------------
+void() PM_WallJump =
+{
+ // are we in water, already waterjumping, already walljumping,
+ // or is jump being held?
+ if (self.waterlevel > WATERLEVEL_NONE ||
+ self.pmove_flags & PMF_WATERJUMPED ||
+ self.pmove_flags & PMF_JUMP_HELD ||
+ self.pmove_flags & PMF_WALLJUMPED)
+ {
+ /*
+ #ifdef SSQC
+ dprint ("PM_WallJump: returning in first block\n");
+ #endif
+ */
+ return;
+ }
+
+ // mandatory interval between jump and walljump
+ if (self.doublejump_timer > (PM_DOUBLEJUMP_WINDOW - PM_WALLJUMP_WINDOW))
+ {
+ /*
+ #ifdef SSQC
+ dprint ("PM_WallJump: returning, interval\n");
+ #endif
+ */
+ return;
+ }
+
+ if (self.velocity_z < PM_WALLJUMPLIMIT)
+ {
+ // falling too fast to walljump
+ // TODO CEV it would be a good idea to include a sound here.
+ /*
+ #ifdef SSQC
+ dprint ("PM_WallJump: falling too fast, returning\n");
+ #endif
+ */
+ return;
+ }
+
+ // minimum distance from ground to walljump
+ local vector end = self.origin;
+ end_z -= PM_WALLJUMPGROUND;
+ tracebox (self.origin, self.mins, self.maxs, end, TRUE, self);
+
+ if (trace_fraction < 1.0f)
+ {
+ /*
+ #ifdef SSQC
+ dprint ("PM_WallJump: too close to ground to walljump\n");
+ #endif
+ */
+ return;
+ }
+
+ // start at STEPHEIGHT + 1 to try and clear any steps -- CEV
+ local vector start;
+ start = self.origin;
+ start_z += PM_STEPHEIGHT + 1;
+ end = start;
+
+ for (int i = 0; i < 4; i++)
+ {
+ // I've borrowed a little logic from Quake Champions Classic
+ // here, shoutout to RhapsodyInGeek, check out their good work
+ // https://github.com/RhapsodyInGeek/Quake-Champions-Classic
+ // v_forward and v_right should still correspond to the
+ // makevectors call from PM_Move -- CEV
+ if (i < 2)
+ if (input_movevalues_x == 0)
+ continue;
+ else
+ end = v_forward * 10;
+ if (i > 1)
+ if (input_movevalues_y == 0)
+ continue;
+ else
+ end = v_right * 10;
+ if (i == 1 || i == 3)
+ end = end - end * 2;
+
+ end = start + end;
+
+ // this ends up firing *a lot* when hopping through a map
+ // normally, unfortunately. traceline may be better here -- CEV
+ tracebox (start, self.mins, self.maxs, end, TRUE, self);
+
+ // in order: we hit something, that something is vaguely
+ // vertical, we hit it at a speed greater than -90, and
+ // that something is within 20 (units?) -- CEV
+ if (trace_fraction < 1.0f &&
+ trace_plane_normal_z <= 0.7f &&
+ trace_plane_normal_z >= 0 &&
+ self.velocity * trace_plane_normal >= -90 &&
+ vlen(self.origin - trace_endpos) <= 20)
+ {
+ self.pmove_flags |= PMF_WALLJUMPED;
+ break;
+ }
+ }
+
+ if (self.pmove_flags & PMF_WALLJUMPED)
+ {
+ // bounce off the wall plane -- CEV
+ self.velocity_x += trace_plane_normal_x * PM_WALLJUMPFORCE;
+ self.velocity_y += trace_plane_normal_y * PM_WALLJUMPFORCE;
+
+ // zero out negative Z, quarter positive Z -- CEV
+ if (self.velocity_z < 0)
+ self.velocity_z = 0;
+ else if (self.velocity_z > 0)
+ self.velocity_z *= 0.25;
+
+ if (self.doublejump_timer > 0)
+ {
+ #ifdef SSQC
+ dprint ("PM_WallJump: wall double ");
+ #endif
+ self.velocity_z += PM_WALLJUMPDOUBLE;
+ }
+ else
+ {
+ #ifdef SSQC
+ dprint ("PM_WallJump: walljump ");
+ #endif
+ self.velocity_z += PM_WALLJUMPSPEED;
+ }
+
+ // manage flags & fields; PMF_WALLJUMPED is already set -- CEV
+ self.pmove_flags |= PMF_JUMP_HELD;
+ self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
+
+ // server-side stuff
+ #ifdef SSQC
+ dprint (sprintf("dist %g, normalspeed %g\n",
+ vlen(self.origin - trace_endpos),
+ self.velocity * trace_plane_normal));
+ self.button2 = 0;
+ sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
+ #endif
+ }
+};
+
+//----------------------------------------------------------------------
+// PM_WalkAccelerate
+// Handle accel & friction for MOVETYPE_WALK entities (players). -- CEV
+//----------------------------------------------------------------------
+void(vector wishvel, float move_time) PM_WalkAccelerate =
+{
+ vector wishdir;
+ float accel, friction, newspeed, speed, temp, wishspeed;
+
+ accel = friction = 0;
+
+ wishspeed = vlen (wishvel);
+ wishdir = normalize (wishvel);
+
+ if (wishspeed > PM_MAXSPEED)
+ wishspeed = PM_MAXSPEED;
+
+ if (self.pmove_flags & PMF_PRE_MOVE)
+ {
+ if (self.pmove_flags & PMF_ONLADDER)
+ {
+ // ladder physics
+ // these currently stutter in high ping (or low netfps)
+ // situations because we rely on touch()ing the ladder
+ // trigger to set PMF_ONLADDER and the client doesn't
+ // know about the trigger brush yet -- TODO CEV
+ self.velocity = 0.75 * self.velocity;
+
+ if (input_buttons & 2 || self.button2 > 0 ||
+ input_movevalues_z > 0)
+ {
+ // PlayerClimb -- johnfitz
+ self.velocity_z = 160;
+ }
+ else if (input_movevalues_z < 0)
+ {
+ // PlayerClimbDown -- CEV
+ self.velocity_z = -160;
+ }
+ else
+ {
+ self.flags |= FL_JUMPRELEASED;
+ self.pmove_flags &= ~PMF_JUMP_HELD;
+ self.velocity_z = 0;
+ }
+
+ self.pmove_flags &= ~PMF_ONGROUND;
+ }
+ else
+ {
+ if (input_buttons & 2 || self.button2 > 0 ||
+ input_movevalues_z > 0)
+ {
+ // +jump was pressed
+ if (self.pmove_flags & PMF_ONGROUND)
+ {
+ // normal jump
+ PM_Jump ();
+ }
+ // TODO CEV
+ /*
+ else if (autocvar(pm_walljump, FALSE))
+ */
+ else
+ {
+ // borrow FTE's pm_walljump cvar -- CEV
+ PM_WallJump ();
+ }
+ }
+ else
+ {
+ self.flags |= FL_JUMPRELEASED;
+ }
+ }
+
+ if (self.pmove_flags & PMF_ONGROUND)
+ self.pmove_flags |= PMF_STARTGROUND;
+ else
+ self.pmove_flags &= ~PMF_STARTGROUND;
+ }
+
+ // Test STARTGROUND (the ONGROUND status post jump) to avoid
+ // a ground friction frame when chaining jumps together.
+ // Probably has unintended consequences. -- CEV
+ if (self.pmove_flags & PMF_STARTGROUND)
+ {
+ // we're on ground so pick accel and friction values -- CEV
+ if (self.groundboost_timer > 0)
+ {
+ accel = PM_BOOSTACCEL;
+ friction = PM_BOOSTFRICTION;
+ }
+ else
+ {
+ accel = PM_GROUNDACCEL;
+ friction = PM_GROUNDFRICTION;
+ }
+ }
+ else if (input_movevalues_x == 0)
+ {
+ // Q1 air accel when requesting sideways movement in the air
+ // flag a check below with this -1 -- CEV
+ accel = -1;
+ }
+ else
+ {
+ if (input_movevalues_y == 0)
+ {
+ // Painkiller style air control
+ if (input_movevalues_x < 0)
+ // we're slowing down
+ accel = PM_AIRACCELBACK;
+ else
+ // we're gaining speed
+ accel = PM_AIRACCELFWD;
+
+ // borrow the friction var to flag a conditional below
+ friction = -1;
+ }
+ else
+ {
+ // we're in the air and the player is requesting both
+ // forward/back and sideways movement, so pick the Q3
+ // air accel value -- CEV
+ accel = PM_AIRACCELQ3;
+ }
+ }
+
+ // I've duplicated a fair amount of code below, inlining the various
+ // acceleration functions to hopefully improve performance -- CEV
+
+ // apply friction (ground or otherwise)
+ if (friction > 0)
+ {
+ // inline PM_Friction
+ speed = vlen (self.velocity);
+
+ if (speed < 1)
+ {
+ self.velocity = '0 0 0';
+ }
+ else
+ {
+ // calculate what their new speed should be
+ temp = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
+ newspeed = speed - temp * friction * move_time;
+
+ // and slow them
+ if (newspeed < 0)
+ newspeed = 0;
+
+ self.velocity = self.velocity * (newspeed / speed);
+ }
+ }
+
+ if (accel == -1)
+ {
+ // Quake 1 sideways air acceleration; inline PM_AirAccelerate
+ wishvel_z = 0;
+ temp = vlen (wishvel);
+ wishvel = normalize (wishvel);
+ if (temp > PM_MAXAIRSPEED)
+ temp = PM_MAXAIRSPEED;
+ speed = self.velocity * wishvel;
+ speed = temp - speed;
+
+ if (speed > 0)
+ {
+ newspeed = PM_AIRACCEL * move_time * wishspeed;
+ if (newspeed > speed)
+ newspeed = speed;
+ self.velocity += newspeed * wishvel;
+ }
+ }
+ else if (accel > 0)
+ {
+ // ground & Quake 3 style acceleration; inline PM_Accelerate
+ speed = wishspeed - (self.velocity * wishdir);
+
+ if (speed > 0)
+ {
+ newspeed = accel * move_time * wishspeed;
+ if (newspeed > speed)
+ newspeed = speed;
+
+ self.velocity += newspeed * wishdir;
+ }
+ }
+
+ // CPM & PK-style air control, needs to happen after PM_Accelerate
+ if (friction == -1)
+ {
+ // inline PM_AirControl
+ temp = self.velocity_z;
+ self.velocity_z = 0;
+
+ speed = vlen (self.velocity);
+ self.velocity = normalize (self.velocity);
+
+ if ((self.velocity * wishdir) > 0)
+ {
+ self.velocity = normalize (self.velocity * speed +
+ wishdir * PM_AIRACCELTURN);
+ }
+
+ self.velocity *= speed;
+ self.velocity_z = temp;
+ }
+
+ if (!(self.pmove_flags & PMF_PRE_MOVE))
+ self.pmove_flags &= ~PMF_STARTGROUND;
+};
+
+//----------------------------------------------------------------------
+// PM_SwimAccelerate
+// Largely copied from id Software's WaterMove. Works like NoClipAccelerate.
+//----------------------------------------------------------------------
+void(vector wishvel, float move_time) PM_SwimAccelerate =
+{
+ float wishspeed;
+
+ if (self.pmove_flags & PMF_PRE_MOVE)
+ {
+ // CheckWaterJump
+ if (self.waterlevel == WATERLEVEL_WAIST)
+ {
+ local vector start, end;
+
+ start = self.origin;
+ start_z = start_z + 8;
+ // use wishvel instead of v_forward -- CEV
+ end = [wishvel_x, wishvel_y, 0];
+ end = normalize (end);
+ traceline (start, (start + end * 24), TRUE, self);
+
+ if (trace_fraction < 1)
+ {
+ // solid at the waist
+ start_z = start_z + self.maxs_z - 8;
+ self.movedir = trace_plane_normal * -50;
+ traceline (start, (start + end * 24),
+ TRUE, self);
+
+ if (trace_fraction == 1)
+ {
+ // open at eye level
+ self.flags |= FL_WATERJUMP;
+ self.pmove_flags |= PMF_WATERJUMPED;
+ self.flags &= ~FL_JUMPRELEASED;
+ self.pmove_flags &= ~PMF_JUMP_HELD;
+ // Z velocity was 225
+ self.velocity_z = PM_JUMPSPEED;
+ // we don't care about the 'safety net'
+ // in this movement set (unlike vanilla)
+ // so don't set teleport_time -- CEV
+ // self.teleport_time = time + 2;
+ }
+ }
+ }
+
+ #ifdef SSQC
+ // functionality copied into pmove from client.qc -- CEV
+ if (self.waterlevel >= WATERLEVEL_WAIST)
+ {
+ if (self.swim_flag < time)
+ {
+ // play swimming sound
+ self.swim_flag = time + 1;
+ if (random() < 0.5)
+ sound (self, CHAN_BODY,
+ "misc/water1.wav", 1,ATTN_NORM);
+ else
+ sound (self, CHAN_BODY,
+ "misc/water2.wav", 1,ATTN_NORM);
+ }
+ }
+ #endif
+ }
+
+ if (input_buttons & 2 && !(self.pmove_flags & PMF_WATERJUMPED))
+ // smartjump
+ wishvel_z = max (PM_MAXSPEED, wishvel_z);
+ else if (input_movevalues == '0 0 0')
+ // drift towards bottom -- CEV
+ wishvel_z -= PM_WATERSINKSPEED;
+
+ wishspeed = vlen (wishvel);
+ if (wishspeed > PM_WATERMAXSPEED)
+ wishspeed = PM_WATERMAXSPEED;
+ wishvel = normalize (wishvel);
+
+ // water friction; reuse PM_Friction with a special constant -- CEV
+ if (!(self.pmove_flags & PMF_WATERJUMPED))
+ PM_Friction (PM_WATERFRICTION, move_time);
+
+ // accelerate; reuse PM_Accelerate with a special constant -- CEV
+ PM_Accelerate (wishvel, wishspeed, PM_WATERACCEL, move_time);
+};
+
+//----------------------------------------------------------------------
+// PM_NoClipAccelerate
+//
+// Basic acceleration for flying / noclipping players. Not suitable for
+// swimming. -- CEV
+//----------------------------------------------------------------------
+void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate =
+{
+ float wishspeed;
+
+ // smartjump
+ if (input_buttons & 2)
+ wishvel_z = max (PM_MAXSPEED, wishvel_z);
+
+ wishspeed = vlen (wishvel) * scale;
+ wishvel = normalize (wishvel);
+
+ PM_Friction (PM_GROUNDFRICTION, move_time);
+ PM_Accelerate (wishvel, wishspeed, PM_GROUNDACCEL, move_time);
+};
+
+//----------------------------------------------------------------------
+void(float move_time) PM_ManageTimers =
+{
+ if (self.doublejump_timer > 0 && move_time > 0)
+ self.doublejump_timer -= move_time;
+ else if (self.doublejump_timer < 0)
+ self.doublejump_timer = 0;
+
+ if (self.doublejump_timer == 0)
+ {
+ self.pmove_flags &= ~PMF_DOUBLEJUMPED;
+ }
+
+ if (self.groundboost_timer > 0 && move_time > 0)
+ self.groundboost_timer -= move_time;
+ else if (self.groundboost_timer < 0)
+ self.groundboost_timer = 0;
+};
+
+//----------------------------------------------------------------------
+// PM_Move -- PMOVE entrypoint -- CEV
+//----------------------------------------------------------------------
+void(entity target) PM_Move =
+{
+ if (input_timelength <= 0)
+ // don't process partial frames -- CEV
+ return;
+
+ vector wishvel;
+ entity oldself;
+
+ oldself = self;
+ self = target;
+
+ // Nudge player's origin if the server is sending low-precision
+ // (16 bit?) player coordinates. This can be fixed by setting
+ // sv_bigcoords to 1 (so the server sends float coords). -- CEV
+ if (!autocvar(sv_bigcoords, FALSE))
+ PM_Nudge ();
+
+ // rework user input, copying something like QuakeSpasm's always run
+ // feature here. This turns the +speed button into a hold-to-walk
+ // button when cl_run is 0 (when FTE's always run setting is on).
+ // -- CEV
+ if (autocvar(cl_run, FALSE) == FALSE)
+ {
+ // local float s = 0;
+ for (int i = 0; i < 3; i++)
+ {
+ // this works, it's just commented out to stop calling
+ // autocvar quite so many times. to re-enable change
+ // the check against "PM_RUNSPEED" below to "s" -- CEV
+ /*
+ if (i == 0)
+ s = autocvar (cl_forwardspeed, PM_RUNSPEED);
+ else if (i == 1)
+ s = autocvar (cl_sidespeed, PM_RUNSPEED);
+ else if (i == 2)
+ s = autocvar (cl_upspeed, PM_RUNSPEED);
+ */
+
+ if (fabs(input_movevalues[i]) > PM_RUNSPEED)
+ input_movevalues[i] = PM_WALKSPEED *
+ (input_movevalues[i] /
+ fabs(input_movevalues[i]));
+ // Don't need this, it's already PM_RUNSPEED -- CEV
+ /*
+ else if (input_movevalues[i] != 0)
+ input_movevalues[i] = PM_RUNSPEED *
+ (input_movevalues[i] /
+ fabs(input_movevalues[i]));
+ */
+ }
+ }
+
+ // TODO CEV this is the wrong place to clear PMF_JUMP_HELD
+ if (!(input_buttons & 2))
+ self.pmove_flags &= ~PMF_JUMP_HELD;
+
+ // figure out the properties of the player's position, then clear timers
+ PM_CategorizePosition ();
+ PM_ManageTimers (0);
+
+ switch (self.movetype)
+ {
+ case MOVETYPE_WALK:
+ local float dogravity, doskim, sticky;
+
+ doskim = FALSE;
+ sticky = FALSE;
+
+ // signal acceleration functions that we're pre-move
+ self.pmove_flags |= PMF_PRE_MOVE;
+
+ // split the acceleration in two to reduce
+ // framerate dependence. -- CEV
+ if (self.waterlevel >= WATERLEVEL_WAIST)
+ {
+ // no gravity, velocity-restoring behavior,
+ // or sticky clips underwater -- CEV
+ dogravity = FALSE;
+ doskim = FALSE;
+ sticky = FALSE;
+
+ // figure out wishvel -- CEV
+ makevectors (input_angles);
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+
+ // swim acceleration
+ PM_SwimAccelerate (wishvel,
+ input_timelength * 0.5f);
+ }
+ else
+ {
+ // only yaw matters here -- CEV
+ makevectors ([0, input_angles_y, 0]);
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ // don't need wishvel_z -- CEV
+ // wishvel += v_up * input_movevalues_z;
+
+ PM_WalkAccelerate (wishvel,
+ input_timelength * 0.5f);
+
+ // WalkAccelerate calls Jump which might
+ // alter pmove_flags, so do our feature
+ // checks afterwards -- CEV
+ if (self.doublejump_timer <= 0 ||
+ self.pmove_flags & PMF_DOUBLEJUMPED ||
+ self.pmove_flags & PMF_WALLJUMPED)
+ // don't stick to the floor
+ sticky = FALSE;
+ else
+ // we've jumped & haven't doublejumped,
+ // so do sticky steps -- CEV
+ sticky = TRUE;
+
+ // apply gravity only when in the air or on
+ // a ramp -- CEV
+ if (self.groundnormal &&
+ self.groundnormal_z < 1.0f)
+ dogravity = TRUE;
+ else if (self.pmove_flags & PMF_ONGROUND)
+ dogravity = FALSE;
+ else
+ dogravity = TRUE;
+
+ // skim / wallclipping checks -- CEV
+ if (self.doublejump_timer >
+ (PM_DOUBLEJUMP_WINDOW -
+ PM_WALLCLIP_WINDOW) &&
+ !(self.pmove_flags & PMF_WALLJUMPED) &&
+ self.teleport_time <= (time - 0.1))
+ doskim = TRUE;
+
+ if (self.pmove_flags & PMF_ONLADDER)
+ {
+ // feature set for ladders -- CEV
+ dogravity = FALSE;
+ doskim = FALSE;
+ sticky = FALSE;
+ }
+ }
+
+ // timers (part 1) -- CEV
+ PM_ManageTimers (input_timelength * 0.5f);
+
+ // Do the move. Bounce, Rock, Skate, Roll -- CEV
+ PM_DanceMove (dogravity, sticky, TRUE, doskim);
+
+ // signal accel functions we're post-move
+ self.pmove_flags &= ~PMF_PRE_MOVE;
+
+ // second pass at acceleration
+ if (self.waterlevel >= WATERLEVEL_WAIST)
+ PM_SwimAccelerate (wishvel,
+ input_timelength * 0.5f);
+ else
+ PM_WalkAccelerate (wishvel,
+ input_timelength * 0.5f);
+
+ // timers (part 2) -- CEV
+ PM_ManageTimers (input_timelength * 0.5f);
+
+ // clear ladder flag -- CEV
+ if (self.pmove_flags & PMF_ONLADDER)
+ self.pmove_flags &= ~PMF_ONLADDER;
+ break;
+
+ case MOVETYPE_FLY:
+ // split acceleration in two to reduce framerate
+ // dependence. -- CEV
+ makevectors (input_angles);
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+
+ PM_NoClipAccelerate (wishvel, 1.0f,
+ input_timelength * 0.5f);
+ PM_DanceMove (FALSE, TRUE, TRUE, FALSE);
+ PM_NoClipAccelerate (wishvel, 1.0f,
+ input_timelength * 0.5f);
+ break;
+
+ case MOVETYPE_NOCLIP:
+ // noclip is a debugging feature, no need to
+ // worry about acceleration consistency. -- CEV
+ makevectors (input_angles);
+ wishvel = v_forward * input_movevalues_x;
+ wishvel += v_right * input_movevalues_y;
+ wishvel += v_up * input_movevalues_z;
+
+ PM_NoClipAccelerate (wishvel, 1.0f, input_timelength);
+ // we're noclipping so update origin directly -- CEV
+ self.origin += self.velocity * input_timelength;
+ break;
+
+ case MOVETYPE_NONE:
+ break;
+ }
+
+ // make sure we've touched the ground entity (it might've slipped
+ // through the slidemove above) -- CEV
+ if (self.groundentity && self.groundentity.touch != __NULL__)
+ PM_DoTouch (self.groundentity);
+
+ touchtriggers ();
+ setorigin (self, self.origin);
+ self = oldself;
+};
+
+//==============================================================================
+// Code graveyard below. Saved here for reference purposes. -- CEV
+//==============================================================================
+
+//----------------------------------------------------------------------
+// PM_ClipVelocity
+//----------------------------------------------------------------------
+#if 0
+#define STOP_EPSILON 0.125
+vector(vector vel, vector normal, float ob, float oneside) PM_ClipVelocity =
+{
+ local float backoff;
+
+ backoff = vel * normal;
+
+ if (backoff < 0)
+ backoff *= ob;
+ else
+ if (oneside)
+ // backoff = 0;
+ backoff *= -0.001;
+ else
+ backoff /= ob;
+
+ vel -= normal * backoff;
+
+ if (vel_x > -STOP_EPSILON && vel_x < STOP_EPSILON)
+ vel_x = 0;
+ if (vel_y > -STOP_EPSILON && vel_y < STOP_EPSILON)
+ vel_y = 0;
+ if (vel_z > -STOP_EPSILON && vel_z < STOP_EPSILON)
+ vel_z = 0;
+
+ return vel;
+};
+#endif
+
+//----------------------------------------------------------------------
+// PM_Q3SlideMove
+//
+// Based on Quake 3's PM_SlideMove (found in the Quake III engine GPL2
+// source release, file bg_slidemove.c). This doesn't work reliably for
+// reasons that are unclear to me; I would guess it has to do with its
+// complex use of an array. I've left it here commented out for reference
+// purposes. -- CEV
+//----------------------------------------------------------------------
+#if 0
+int(float dogravity) PM_Q3SlideMove =
+{
+ 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: ");
+ 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 ("PM_Q3SlideMove: restoring velocity...\n");
+ self.velocity = start_v;
+ }
+
+ if (bumpcount > 0) blocked |= 8;
+ return blocked;
+};
+#endif
+
+//----------------------------------------------------------------------
+// PM_Q1FlyMove
+//
+// Based on Quake 1's SV_FlyMove function (found in id's engine, QuakeSpasm,
+// and others). Has the disadvantage of using an array of vectors, and
+// is slow (I assume) in QuakeC. -- CEV
+//----------------------------------------------------------------------
+#if 0
+#define PM_SLIDE_MAX_CLIP_PLANES 5
+#define PM_SLIDE_NUMBUMPS 5
+int(float dogravity, float onesided) PM_Q1FlyMove =
+{
+ vector planes[PM_SLIDE_MAX_CLIP_PLANES];
+ vector dir, end, new_v, start_v;
+ int blocked, bumpcount, numplanes, i, j;
+ float d, ent_grav, grav, time_left;
+
+ blocked = numplanes = 0;
+
+ // initialize all these vectors
+ for (i = 0; i < PM_SLIDE_MAX_CLIP_PLANES; i++)
+ planes[i] = '0 0 0';
+ dir = end = new_v = '0 0 0';
+
+ if (dogravity)
+ {
+ if (self.gravity)
+ ent_grav = self.gravity;
+ else
+ ent_grav = 1.0;
+ grav = ent_grav * autocvar(sv_gravity, 800) * input_timelength;
+ // we'll do half of it now, half later -- CEV
+ self.velocity_z -= grav * 0.5;
+ }
+
+ // set start_v after gravity check above
+ start_v = self.velocity;
+
+ for (bumpcount = 0, time_left = input_timelength;
+ time_left > 0 && bumpcount < PM_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 (PM_Nudge())
+ continue;
+
+ // nah, we're stuck. don't build up falling damage
+ // but allow sideways acceleration
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: entity trapped in a solid\n");
+ #endif
+ self.velocity_z = 0;
+ return 3;
+ }
+
+ if (trace_fraction >= 0.001)
+ self.origin = trace_endpos;
+
+ if (trace_fraction >= 1.0f)
+ break;
+
+ if (trace_plane_normal_z > 0.7)
+ {
+ blocked |= 1;
+ self.groundnormal = trace_plane_normal;
+ self.groundentity = trace_ent;
+ }
+
+ if (!(trace_plane_normal_z))
+ blocked |= 2;
+
+ PM_DoTouch (trace_ent);
+ time_left -= time_left * trace_fraction;
+
+ if (numplanes >= PM_SLIDE_MAX_CLIP_PLANES)
+ {
+ // this shouldn't really happen
+ if (cvar("developer"))
+ {
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: numplanes >= max: ");
+ dprint (ftos(numplanes));
+ dprint ("\n");
+ #endif
+ }
+ self.velocity = '0 0 0';
+ blocked = 7;
+ break;
+ }
+
+ planes[numplanes] = trace_plane_normal;
+ numplanes++;
+
+ for (i = 0; i < numplanes; i++)
+ {
+ // slide along the plane
+ new_v = PM_ClipVelocity (self.velocity,
+ planes[i], PM_OVERCLIP, onesided);
+
+ for (j = 0; j < numplanes; j++)
+ if (j != i)
+ // not ok (the comment says)
+ if ((new_v * planes[j]) < 0)
+ break;
+
+ if (j == numplanes)
+ break;
+ }
+
+ if (i == numplanes)
+ {
+ if (numplanes != 2)
+ {
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: stopping dead\n");
+ #endif
+ self.velocity = '0 0 0';
+ blocked = 7;
+ break;
+ }
+
+ // slide along the crease
+ dir = crossproduct (planes[0], planes[1]);
+ dir = normalize (dir);
+ d = (dir * self.velocity);
+ new_v = dir * d;
+ }
+
+ self.velocity = new_v;
+
+ if ((self.velocity * start_v) <= 0)
+ {
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: turned against orig vel\n");
+ #endif
+ self.velocity = '0 0 0';
+ break;
+ }
+ }
+
+ // wallclip / wall skim timer check
+ if ( // (self.primal_speed > PM_MAXSPEED) &&
+ (self.velocity != '0 0 0') &&
+ (self.jump_time) &&
+ (!(self.pmove_flags & PMF_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)))
+ {
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: restoring velocity...\n");
+ #endif
+ self.velocity = [start_v_x, start_v_y, self.velocity_z];
+ }
+
+ // final gravity check here
+ if (dogravity)
+ self.velocity_z -= grav * 0.5;
+
+ /* for debugging -- CEV
+ #ifdef SSQC
+ dprint ("PM_Q1FlyMove: numplanes ");
+ dprint (ftos(numplanes));
+ dprint ("\n");
+ #endif
+ */
+
+ return blocked;
+};
+#endif
+
+//----------------------------------------------------------------------
+// PM_StepSlideMove
+//
+// Based on the StepSlideMove function found in the Quake III sourcecode.
+// Calls PM_Q1FlyMove several times. This works, but is slow and has
+// some tracking issues (probably my fault). -- CEV
+//----------------------------------------------------------------------
+#if 0
+void(float dogravity, float onesided) PM_StepSlideMove =
+{
+ vector start_o, start_v, first_o, first_v;
+ vector up, down;
+ float stepsize;
+ int clip, first_clip;
+ int start_onground;
+
+ clip = first_clip = 0;
+ start_o = self.origin;
+ start_v = self.velocity;
+ start_onground = (self.pmove_flags & PMF_ONGROUND);
+
+ // first try let's go
+ first_clip = PM_Q1FlyMove (dogravity, onesided);
+
+ if (!(first_clip & 2) && !(first_clip & 8))
+ {
+ // we got where we wanted to go right away
+ // #ifdef SSQC
+ // dprint ("PM_StepSlideMove: accepting first move\n");
+ // #endif
+ if (first_clip & 1)
+ self.pmove_flags |= PMF_ONGROUND;
+ else
+ self.pmove_flags &= ~PMF_ONGROUND;
+ return;
+ }
+
+ if (self.movetype != MOVETYPE_WALK)
+ // gibbed by a trigger?
+ return;
+
+ if (autocvar(pm_nostep, FALSE))
+ // no stepping. useful for testing -- CEV
+ return;
+
+ if (!(autocvar(pm_airstep, TRUE)) && !(self.pmove_flags & PMF_ONGROUND))
+ // Borrowing FTE's pm_airstep cvar here. If false, don't
+ // step up while in the air (changes stairs) -- CEV
+ return;
+
+ first_o = self.origin;
+ first_v = self.velocity;
+
+ self.origin = start_o;
+ self.velocity = start_v;
+
+ up = start_o;
+ up_z += PM_STEPHEIGHT;
+ tracebox (start_o, self.mins, self.maxs, up, FALSE, self);
+
+ if (trace_allsolid)
+ {
+ #ifdef SSQC
+ dprint ("PM_StepSlideMove: can't step up\n");
+ #endif
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.pmove_flags |= PMF_ONGROUND;
+ else
+ self.pmove_flags &= ~PMF_ONGROUND;
+ return;
+ }
+
+ // try slidemove from this position (in air)
+ stepsize = trace_endpos_z - start_o_z;
+ self.origin = trace_endpos;
+ self.velocity = start_v;
+ clip = PM_Q1FlyMove (dogravity, onesided);
+
+ // push down the final amount
+ down = self.origin;
+ down_z -= stepsize;
+ tracebox (self.origin, self.mins, self.maxs, down, FALSE, self);
+
+ if (trace_allsolid)
+ {
+ #ifdef SSQC
+ dprint ("PM_StepSlideMove: second move is in a solid\n");
+ #endif
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.pmove_flags |= PMF_ONGROUND;
+ else
+ self.pmove_flags &= ~PMF_ONGROUND;
+ return;
+ }
+
+ if (!trace_plane_normal_z || trace_plane_normal_z > 0.7)
+ {
+ // we're on 'good ground', accept the second slidemove
+ // #ifdef SSQC
+ // dprint ("PM_StepSlideMove: accepting second slidemove\n");
+ // #endif
+ self.origin = trace_endpos;
+ if (trace_fraction < 1.0)
+ {
+ // clip to step
+ self.velocity = PM_ClipVelocity (self.velocity,
+ trace_plane_normal, PM_OVERCLIP, onesided);
+ }
+ if (trace_plane_normal_z > 0.7)
+ self.pmove_flags |= PMF_ONGROUND;
+ else
+ self.pmove_flags &= ~PMF_ONGROUND;
+ }
+ else
+ {
+ // not on 'good ground', revert to first slidemove
+ // see the similar section of SV_WalkMove
+ // #ifdef SSQC
+ // dprint ("PM_StepSlideMove: reverting to first move\n");
+ // #endif
+ self.origin = first_o;
+ self.velocity = first_v;
+ if (first_clip & 1)
+ self.pmove_flags |= PMF_ONGROUND;
+ else
+ self.pmove_flags &= ~PMF_ONGROUND;
+ }
+
+ // this is a complicated check.
+ // if we started in the air and we're now on the ground
+ // and we stepped up and we lost some Z velocity then we've
+ // clipped to ground on a step up
+ if (!start_onground && (self.pmove_flags & PMF_ONGROUND) &&
+ (start_v_z > self.velocity_z) &&
+ (self.velocity_z < 1) &&
+ (self.origin_z - start_o_z > 0))
+ {
+ if (!self.boost_time &&
+ self.boost_time <= time - PM_BOOST_WINDOW)
+ self.boost_time = time;
+
+ if (cvar("developer"))
+ {
+ #ifdef SSQC
+ stepsize = self.origin_z - start_o_z;
+ dprint (sprintf("PM_StepSlideMove: step up: %g\n",
+ stepsize));
+ #endif
+ }
+ }
+};
+#endif

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
deleted file mode 100644
index 74788fa..0000000
--- a/qc/pmove.qc
+++ /dev/null
@@ -1,2139 +0,0 @@
-//==============================================================================
-// PMOVE
-//==============================================================================
-
-// TODO CEV: crouching
-// TODO CEV: crouch sliding (useful for sliding up stairs)
-// TODO CEV: crouch-wall-thing (wallrunning? wall sliding?)
-// TODO CEV: improved player unstick function
-// TODO CEV: more work on walking
-// TODO CEV: varied sounds (footsteps, different jump sounds)
-
-// globals managed by FTEQW, from fteextensions.qc -- CEV
-float input_buttons;
-// float input_impulse;
-float input_timelength;
-vector input_angles; // +x = DOWN
-vector input_movevalues;
-
-// fields
-// note: timers are expensive, require synch between server and client -- CEV
-.entity groundentity;
-.vector groundnormal;
-.float pmove_flags; // custom movement flags -- CEV
-.float doublejump_timer; // time in which a player can doublejump
-.float groundboost_timer; // time to apply low friction -- CEV
-.void() customphysics;
-
-// pmove constants; it's defnitely possible to rework these as cvars -- CEV
-// acceleration & friction
-const float PM_AIRACCEL = 7.5f; // 10 in Q1; now 7.5
-const float PM_AIRACCELQ3 = 0.75f; // 1.0 in Q3 ?; now 0.75
-const float PM_AIRACCELFWD = 1.5f; // 1 feels close to Q3 / CPM
-const float PM_AIRACCELBACK = 5.0f; // Air stop speed in Q3?
-const float PM_AIRACCELTURN = 100.0f; // affects +fwd style turning radius
-const float PM_BOOSTACCEL = 12.0f; // ground boost accel; 10 is enough
-const float PM_BOOSTFRICTION = 4.0f; // ground boost friction; 4 is Q1
-const float PM_GROUNDACCEL = 15.0f; // 10 is normal, 15 is CPM
-const float PM_GROUNDFRICTION = 8.0f; // 4 for Q1, 6 for Q3, 8 for CPM
-const vector PM_GROUNDDIST_V = '0 0 1'; // distance for ground check
-const float PM_WATERACCEL = 10.0f; // water acceleration
-const float PM_WATERFRICTION = 4.0f; // friction in water
-
-// horizontal speeds (mostly)
-const float PM_CROUCHSPEED = 120.0f; // ???
-const float PM_MAXSPEED = 320.0f; // 320 always
-const float PM_MAXAIRSPEED = 30.0f; // 30 for Q1 air control
-const float PM_RUNSPEED = 400.0f; // run speed override
-const float PM_STOPSPEED = 100.0f;
-const float PM_TELEEXITSPEED = 400.0f; // exit teleporters at this speed
-const float PM_WALKSPEED = 200.0f; // walk speed override
-const float PM_WATERMAXSPEED = 224.0f; // 320 * 0.7
-const float PM_WATERSINKSPEED = 60.0f;
-
-// vertical speeds (mostly)
-const float PM_GRAVITY = 800.0f; // unless sv_gravity, scaled by .gravity
-const float PM_JUMPSPEED = 270.0f; // standard jump Z velocity; 90 * 3
-const float PM_DOUBLEJUMPSPEED = 270.0f;// 270 * 1.5 in CPM; 360 here
-const float PM_STAIRJUMPSPEED = 360.0f; // 360 = 90 * 4
-const float PM_TELEJUMPSPEED = 360.0f; // same as STAIRJUMPSPEED
-const float PM_WALLJUMPFORCE = 90.0f; // 90 * 2; push away from wall
-const float PM_WALLJUMPGROUND = 36.0f; // distance from ground to allow WJ
-const float PM_WALLJUMPLIMIT = -180.f; // no walljump if Z vel below this
-const float PM_WALLJUMPSPEED = 270.0f; // 225 = 90 * 2.5; wall jump
-const float PM_WALLJUMPDOUBLE = 360.0f; // 315 = 90 * 3.5; wall doublejump
-
-// timing
-const float PM_DOUBLEJUMP_WINDOW = 0.4f;// 2 jumps in this time is a double
-const float PM_GROUNDBOOST_WINDOW = 0.4f;// groundboost duration
-const float PM_TELEJUMP_WINDOW = 0.4f; // duration to perform a telejump
-const float PM_WALLJUMP_WINDOW = 0.2f; // duration between walljumps
-const float PM_WALLCLIP_WINDOW = 0.25f; //
-
-// misc
-const float PM_OVERCLIP = 1.0f; // Quake3's OVERCLIP is 1.001f
-const float PM_ONESIDEDCLIP = -0.01; // -0.001;
-const float PM_STEPHEIGHT = 18.0f; // 18 for Q1, 22 for later games?
-const vector PM_TELEDROP = '0 0 -64'; // drop teleporter exit to floor if
- // floor is within this distance
-// water level
-const int WATERLEVEL_NONE = 0;
-const int WATERLEVEL_FEET = 1;
-const int WATERLEVEL_WAIST = 2;
-const int WATERLEVEL_EYES = 3;
-
-//
-const vector CROUCHED_MINS = '-16 -16 -18';// VEC_HULL_MIN is '-16 -16 -24'
-const vector CROUCHED_MAXS = '16 16 18';// VEC_HULL_MAX is '16 16 32'
-
-// pmove_flags
-enumflags
-{
- PMF_ONGROUND, // entity is on ground
- PMF_STARTGROUND, // entity started the move on ground
- PMF_ONLADDER, // entity is on a ladder
- PMF_INWATER, // entity is in water
- PMF_CROUCH_HELD, // player is holding the crouch key
- PMF_CROUCHED, // entity is crouching
- PMF_JUMP_HELD, // player is holding the jump key
- PMF_DOUBLEJUMPED, // entity has doublejumped
- PMF_WALLJUMPED, // entity has walljumped
- PMF_WATERJUMPED, // entity has waterjumped
- PMF_PRE_MOVE // hint that origin hasn't updated yet
-};
-
-// prototypes
-static void(entity ent) PM_DoTouch;
-float() PM_Nudge;
-void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove;
-void() PM_CategorizePosition;
-void(float friction, float move_time) PM_Friction;
-void(vector wishdir, float wishspeed, float accel, float move_time)
- PM_Accelerate;
-void(vector wishvel, float wishspeed, float accel, float move_time)
- PM_AirAccelerate;
-void(vector wishdir, float wishspeed, float move_time) PM_AirControl;
-void() PM_Jump;
-void() PM_WallJump;
-void(vector wishvel, float move_time) PM_WalkAccelerate;
-void(vector wishvel, float move_time) PM_SwimAccelerate;
-void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate;
-void(float move_time) PM_ManageTimers;
-void(entity target) PM_Move;
-
-#ifdef SSQC
-//======================================================================
-// SV_RunClientCommand -- server-side movement entrypoint -- CEV
-//----------------------------------------------------------------------
-void() SV_RunClientCommand =
-{
- // should match the one used by csqc.
- if (autocvar(pm_standardphysics, FALSE))
- // for testing -- CEV
- runstandardplayerphysics (self);
- else
- // for real
- PM_Move (self);
-};
-#endif
-
-//======================================================================
-// PM_DoTouch
-//----------------------------------------------------------------------
-static void(entity ent) PM_DoTouch =
-{
- if (ent && ent.touch != __NULL__)
- {
- local entity orig_self;
-
- orig_self = self;
- other = self;
- self = ent;
- self.touch ();
- self = orig_self;
- }
-};
-
-//======================================================================
-// PM_Nudge
-// from the GPL2 CSQCTest code that comes with FTEQW; is called often
-// to nudge player origin due to float/network precision errors -- CEV
-//----------------------------------------------------------------------
-float() PM_Nudge =
-{
- vector test, org = self.origin;
-
- // check current position.
- tracebox (org, self.mins, self.maxs, org, FALSE, self);
- if (!trace_startsolid)
- return TRUE;
-
- // truncate to network accuracy
- org_x = floor (org_x * 8 + (1.0 / 16)) * 0.125;
- org_y = floor (org_y * 8 + (1.0 / 16)) * 0.125;
- org_z = floor (org_z * 8 + (1.0 / 16)) * 0.125;
-
- test = org;
-
- static float offsets[] = {0, -1./8, 1./8, -2./8, 2./8};
- for (float z = 0; z < offsets.length; z++)
- {
- test.z = org.z + offsets[z];
- for (float y = 0; y < offsets.length; y++)
- {
- test.y = org.y + offsets[y];
- for (float x = 0; x < offsets.length; x++)
- {
- test.x = org.x + offsets[x];
- tracebox (test, self.mins, self.maxs, test,
- FALSE, self);
- if (!trace_startsolid)
- {
- // okay, that'll do
- self.origin = test;
- return TRUE;
- }
- }
- }
- }
- self.origin = org;
- return FALSE;
-};
-
-//======================================================================
-// PM_DanceMove
-//
-// Updates origin according to velocity, moves the player through the world.
-// Same as Q3 SlideMove and Q1 FlyMove. This version handles steps, applies
-// gravity, and restores velocity based on a timer check (those latter two
-// are features of Q3's SlideMove). I've inlined a number of functions
-// (ClipVelocity, DoTouch) to hopefully improve performance.
-//
-// Based on code from the Nuclide SDK (presumably by Eukara), specifically
-// the function PMoveCustom_Move found in the file pmove_custom.qc. This
-// in turn appears to be based on a similar function in the CSQCTest code
-// that comes with FTEQW. -- CEV
-//----------------------------------------------------------------------
-void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
-{
- vector end, prev_plane, prev_plane2, plane, start_v;
- float backoff, grav, stepsize, time_left;
- int i;
- entity touched_ent;
-
- // silence some FTEQCC warnings -- CEV
- end = prev_plane = prev_plane2 = plane = start_v = '0 0 0';
- backoff = grav = stepsize = time_left = 0;
-
- if (dogravity)
- {
- if (self.gravity)
- grav = self.gravity;
- else
- grav = 1.0;
- grav = grav * autocvar (sv_gravity, PM_GRAVITY) *
- input_timelength;
- // Half now, half later. Apparently affects framerate
- // dependence. -- CEV
- self.velocity_z -= grav * 0.5;
- }
-
- start_v = self.velocity;
-
- // Borrowing FTEQW's pm_airstep cvar here. If false, don't step up
- // while in the air (changes stairs) -- CEV
- if (!(autocvar(pm_airstep, TRUE)) && !(self.pmove_flags & PMF_ONGROUND))
- dostep = FALSE;
-
- // no stepping. useful for testing -- CEV
- if (autocvar(pm_nostep, FALSE))
- dostep = FALSE;
-
- // we need to bounce off surfaces (in order to slide along them),
- // so we need at 2 attempts -- comment from the Nuclide SDK
- // I've changed this to a larger number of attempts (from 3 to 5)
- // to accommodate more complex plane interactions -- CEV
- for (i = 5, time_left = input_timelength; time_left > 0 && i; i--)
- {
- // set our destination & test the move -- CEV
- 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 (PM_Nudge())
- continue;
-
- // nah, we're stuck. don't build up falling damage
- // but allow sideways acceleration -- CEV
- /*
- #ifdef CSQC
- dprint ("PM_DanceMove: client ");
- #endif
- #ifdef SSQC
- dprint ("PM_DanceMove: server ");
- #endif
- #if defined(CSQC) || defined(SSQC)
- dprint ("entity trapped in a solid!\n");
- #endif
- */
- self.velocity_z = 0;
- break;
- }
-
- // accept the move -- CEV
- self.origin = trace_endpos;
-
- if (trace_fraction >= 1.0f)
- // no obstructions, made the whole move -- CEV
- break;
-
- // zero out stepsize, then store the plane normal and touched
- // ent for later, then reduce time_left -- CEV
- stepsize = 0;
- plane = trace_plane_normal;
- touched_ent = trace_ent;
- time_left -= time_left * trace_fraction;
-
- // integrated StepSlideMove from Nuclide / CSQCTest -- CEV
- // only attempt to step if there's time left, stepping was
- // requested, and we hit something like a vertical plane
- if (dostep && time_left && plane_z >= 0 && plane_z <= 0.7f)
- {
- // first: move up
- trace_endpos = self.origin;
- trace_endpos_z += PM_STEPHEIGHT;
- tracebox (self.origin, self.mins, self.maxs,
- trace_endpos, FALSE, self);
-
- // don't like having to store another float & vector
- // but this solves more interactions (ztndm3) -- CEV
- local float roof_fraction = trace_fraction;
- local vector roof_plane = trace_plane_normal;
-
- // second: move forward
- stepsize = trace_endpos_z - self.origin_z;
- end = trace_endpos + (self.velocity * time_left);
- end_z = trace_endpos_z;
- tracebox (trace_endpos, self.mins, self.maxs, end,
- FALSE, self);
-
- // save trace_ent if it has a touch function
- if (trace_ent && trace_ent.touch != __NULL__)
- touched_ent = trace_ent;
-
- if (trace_allsolid || trace_startsolid)
- {
- // reject the move immediately -- CEV
- #ifdef SSQC
- dprint ("PM_DanceMove: fwd move solid\n");
- #endif
- stepsize = 0;
- self.velocity = '0 0 0';
- break;
- }
- else if (trace_fraction >= 1.0f)
- {
- // storing another vector, disappointed in
- // myself -- CEV
- local vector fwd_plane = trace_plane_normal;
-
- // forward move didn't hit anything
- // third: move down
- end = trace_endpos;
- end_z -= stepsize + 1;
- tracebox (trace_endpos, self.mins, self.maxs,
- end, FALSE, self);
-
- if (trace_allsolid || trace_startsolid)
- {
- // again reject the move -- CEV
- #ifdef SSQC
- dprint ("PM_DanceMove: down move "
- "solid\n");
- #endif
- stepsize = 0;
- self.velocity = '0 0 0';
- break;
- }
- else if (trace_fraction < 1.0f &&
- trace_plane_normal_z > 0.7f)
- {
- // good ground, accept the move
- if (roof_fraction < 1.0f &&
- roof_plane != fwd_plane &&
- roof_plane != plane)
- {
- // do a simple clipvel to the
- // roof plane right now -- CEV
- self.velocity -= roof_plane *
- (self.velocity *
- roof_plane);
- }
-
- stepsize = trace_endpos_z -
- self.origin_z;
- self.origin = trace_endpos;
- time_left -= time_left * trace_fraction;
-
- prev_plane2 = __NULL__;
- prev_plane = fwd_plane;
- plane = trace_plane_normal;
-
- if (trace_ent &&
- trace_ent.touch != __NULL__)
- touched_ent = trace_ent;
-
- // don't attempt to step again
- dostep = FALSE;
- }
- else
- {
- // down move didn't hit and/or
- // it hit a plane too steep to
- // be ground -- CEV
- stepsize = 0;
- }
- }
- else if (trace_plane_normal != plane)
- {
- // raised forward move hit something different
- // than the initial move so clip velocity to
- // it. solves issues with weird ceilings and
- // complex movement on stairs. note that we're
- // not updating origin. -- CEV
- prev_plane2 = __NULL__;
- prev_plane = __NULL__;
- time_left -= time_left * trace_fraction;
- stepsize = 0;
-
- if (roof_fraction < 1.0f &&
- roof_plane != trace_plane_normal)
- {
- // save the roof plane & fwd plane
- prev_plane = roof_plane;
- plane = trace_plane_normal;
- }
- else if (roof_plane == trace_plane_normal)
- {
- // roof plane is fwd plane, so save
- // first and fwd plane
- prev_plane = plane;
- plane = trace_plane_normal;
- }
- else
- {
- // only save fwd plane
- plane = trace_plane_normal;
- }
- }
- }
-
- // need to do the ground check & touch the saved ent before
- // we might stop the loop early -- CEV
- if (plane_z > 0.7)
- {
- if (touched_ent.solid == SOLID_BSP)
- {
- self.groundentity = touched_ent;
- self.groundnormal = plane;
- self.flags |= FL_ONGROUND;
- self.pmove_flags |= PMF_ONGROUND;
- }
- }
- else
- {
- self.groundentity = __NULL__;
- self.groundnormal = __NULL__;
- self.flags &= ~FL_ONGROUND;
- self.pmove_flags &= ~PMF_ONGROUND;
- }
-
- // touch the saved entity; inline PM_DoTouch -- CEV
- if (touched_ent && touched_ent.touch != __NULL__)
- {
- local entity orig_self;
-
- orig_self = self;
- other = self;
- self = touched_ent;
- self.touch ();
- self = orig_self;
- }
-
- // clip velocity to the saved plane
- // inline PM_Rebound aka PM_ClipVelocity -- CEV
- backoff = self.velocity * plane;
-
- if (backoff < 0)
- backoff *= PM_OVERCLIP;
- else
- if (sticky)
- backoff /= PM_OVERCLIP;
- else
- backoff *= PM_ONESIDEDCLIP;
-
- self.velocity -= plane * backoff;
-
- // if velocity interacts with prev_plane then clip to it.
- // I'm duplicating a little code here (ClipVelocity),
- // hopefully the audience will forgive me. -- CEV
- if (prev_plane && prev_plane != plane &&
- self.velocity * prev_plane < 0)
- {
- backoff = self.velocity * prev_plane;
-
- if (backoff < 0)
- backoff *= PM_OVERCLIP;
- else
- if (sticky)
- backoff /= PM_OVERCLIP;
- else
- backoff *= PM_ONESIDEDCLIP;
-
- self.velocity -= prev_plane * backoff;
-
- // Slide along the crease of previous plane and
- // current plane if the two still interact -- CEV
- if (self.velocity * plane < 0)
- {
- end = crossproduct (prev_plane, plane);
- end = normalize (end);
- self.velocity = end * (end * self.velocity);
- }
-
- // An optimization from Quake 3 -- CEV
- if (prev_plane2 && prev_plane2 != plane &&
- prev_plane2 != prev_plane &&
- self.velocity * prev_plane2 < 0)
- {
- // Stop if we interact with three planes -- CEV
- #ifdef SSQC
- dprint ("PM_DanceMove: triple plane stop\n");
- #endif
- self.velocity = '0 0 0';
- break;
- }
- }
-
- // an optimization from Quake 1; is this necessary? -- CEV
- if ((self.velocity * start_v) <= 0)
- {
- // we've turned against original velocity so
- // clear vel and stop the loop
- self.velocity = '0 0 0';
- break;
- }
-
- // store current plane and prev_plane for later -- CEV
- if (prev_plane)
- prev_plane2 = prev_plane;
- prev_plane = plane;
- }
-
- // wallclip / wall skim timer check
- // if doskim is true and velocity is non-zero and we lost speed
- // during the move then restore velocity -- CEV
- if (doskim && self.velocity && (vlen(start_v) > vlen(self.velocity)))
- {
- /*
- #ifdef SSQC
- dprint ("PM_DanceMove: wall skim, restoring velocity...\n");
- #endif
- */
- // take the start Z or clipped Z, whichever is lower -- CEV
- if (start_v_z > self.velocity_z)
- self.velocity = [start_v_x, start_v_y, self.velocity_z];
- else
- self.velocity = start_v;
- }
-
- // final gravity check here -- CEV
- if (dogravity)
- self.velocity_z -= grav * 0.5;
-
- // if stepsize is nonzero and we changed from inair to onground then
- // we've airstepped. this check is here as a placeholder for possible
- // functionality later -- CEV
- #ifdef SSQC
- if (stepsize > 0 && !(self.pmove_flags & PMF_STARTGROUND) &&
- self.pmove_flags & PMF_ONGROUND)
- {
- // more debugging -- CEV
- dprint (sprintf("PM_DanceMove: airstep: %g\n", stepsize));
- }
- #endif
-
- // a final call to setorigin to update links -- CEV
- setorigin (self, self.origin);
-
- /*
- #ifdef SSQC
- if (cvar("developer"))
- // for debugging purposes -- CEV
- dprint (sprintf("PM_DanceMove: %g bumps\n", 5 - i));
- #endif
- */
-};
-
-//======================================================================
-// PM_CategorizePosition
-// Based on similarly-named function in the GPL2 purecsqc pmove.qc
-//----------------------------------------------------------------------
-void() PM_CategorizePosition =
-{
- vector point;
- float contents;
-
- if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
- {
- // noclip is never on ground
- self.groundentity = __NULL__;
- self.groundnormal = __NULL__;
- self.pmove_flags &= ~PMF_DOUBLEJUMPED;
- self.pmove_flags &= ~PMF_WALLJUMPED;
- self.pmove_flags &= ~PMF_ONGROUND;
- self.flags &= ~FL_ONGROUND;
- }
- else
- {
- // TODO CEV there must be a way to optimize out this
- // tracebox ground check some of the time
-
- // do a trace to check for ground
- tracebox (self.origin, self.mins, self.maxs,
- self.origin - PM_GROUNDDIST_V, FALSE, self);
- // only onground if we hit it & it faces upwards
- if (trace_fraction < 1.0f && trace_plane_normal_z > 0.7f)
- {
- // on ground
- self.groundentity = trace_ent;
- self.groundnormal = trace_plane_normal;
- self.flags |= FL_ONGROUND;
- self.pmove_flags |= PMF_ONGROUND;
- self.pmove_flags &= ~PMF_WALLJUMPED;
- }
- else
- {
- // not on ground
- self.groundentity = __NULL__;
- self.groundnormal = __NULL__;
- self.flags &= ~FL_ONGROUND;
- self.pmove_flags &= ~PMF_ONGROUND;
- }
- }
-
- // check water levels
- point = self.origin;
- point_z = self.origin_z + self.mins_z + 1;
- contents = pointcontents (point);
- if (contents < CONTENT_SOLID)
- {
- self.watertype = contents;
- point_z = self.origin_z + (self.mins_z + self.maxs_z) * 0.5;
- if (pointcontents(point) < CONTENT_SOLID)
- {
- point_z = self.origin_z + self.maxs_z;
- if (pointcontents(point) < CONTENT_SOLID)
- self.waterlevel = WATERLEVEL_EYES;
- else
- self.waterlevel = WATERLEVEL_WAIST;
- }
- else
- {
- self.waterlevel = WATERLEVEL_FEET;
- }
- }
- else
- {
- self.watertype = CONTENT_EMPTY;
- self.waterlevel = WATERLEVEL_NONE;
- }
-
- // can't be waterjumping if we're on ground
- if (self.pmove_flags & PMF_WATERJUMPED &&
- (self.waterlevel == WATERLEVEL_NONE ||
- self.pmove_flags & PMF_ONGROUND))
- {
- #ifdef SSQC
- dprint ("PM_CategorizePosition: clearing FL_WATERJUMP\n");
- #endif
- self.pmove_flags &= ~PMF_WATERJUMPED;
- self.flags &= ~FL_WATERJUMP;
- }
-};
-
-//======================================================================
-// PM_Friction
-// Ground friction
-//----------------------------------------------------------------------
-void(float friction, float move_time) PM_Friction =
-{
- float control, newspeed, speed;
-
- speed = vlen (self.velocity);
-
- if (speed < 1)
- {
- self.velocity = '0 0 0';
- return;
- }
-
- // calculate what their new speed should be
- control = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
- newspeed = speed - control * friction * move_time;
-
- // and slow them
- if (newspeed < 0)
- newspeed = 0;
-
- self.velocity = self.velocity * (newspeed / speed);
-};
-
-//======================================================================
-// PM_Accelerate
-// Ground acceleration & Quake 3 style air acceleration -- CEV
-//----------------------------------------------------------------------
-void(vector wishdir, float wishspeed, float accel, float move_time)
- PM_Accelerate =
-{
- float newspeed, speed;
-
- speed = wishspeed - (self.velocity * wishdir);
-
- if (speed <= 0)
- return;
-
- newspeed = accel * move_time * wishspeed;
- if (newspeed > speed)
- newspeed = speed;
-
- self.velocity += newspeed * wishdir;
-};
-
-//======================================================================
-// PM_AirAccelerate
-// Quake 1 style air acceleration -- CEV
-//----------------------------------------------------------------------
-void(vector wishvel, float wishspeed, float accel, float move_time)
- PM_AirAccelerate =
-{
- float newspeed, speed, wishspd;
-
- // need to ignore Z velocity -- CEV
- wishvel = [wishvel_x, wishvel_y, 0];
- wishspd = vlen (wishvel);
- wishvel = normalize (wishvel);
- if (wishspd > PM_MAXAIRSPEED)
- wishspd = PM_MAXAIRSPEED;
- speed = self.velocity * wishvel;
- speed = wishspd - speed;
-
- if (speed <= 0)
- return;
-
- newspeed = accel * move_time * wishspeed;
- if (newspeed > speed)
- newspeed = speed;
- self.velocity += newspeed * wishvel;
-};
-
-//======================================================================
-// PM_AirControl
-// CPM / Painkiller-like Air Control. Based on Xonotic sources. -- CEV
-//----------------------------------------------------------------------
-void(vector wishdir, float wishspeed, float move_time) PM_AirControl =
-{
- local float speed, zspeed;
-
- zspeed = self.velocity_z;
- self.velocity_z = 0;
-
- speed = vlen (self.velocity);
- self.velocity = normalize (self.velocity);
-
- if ((self.velocity * wishdir) > 0)
- {
- self.velocity = normalize (self.velocity * speed +
- wishdir * PM_AIRACCELTURN);
- }
-
- self.velocity *= speed;
- self.velocity_z = zspeed;
-};
-
-//======================================================================
-// PM_Jump
-//----------------------------------------------------------------------
-void() PM_Jump =
-{
- // are we already waterjumping, or is jump being held?
- if (self.pmove_flags & PMF_WATERJUMPED ||
- self.pmove_flags & PMF_JUMP_HELD)
- return;
-
- #ifdef SSQC
- local string msg = "";
- #endif
-
- // make sure we get at least jumpspeed upwards from
- // the ground plane by clamping it first.
- if (self.groundnormal && (self.velocity * self.groundnormal < 0))
- {
- // #ifdef SSQC
- // dprint("PM_Jump: clamping to ground\n");
- // #endif
- self.velocity -= self.groundnormal *
- (self.velocity * self.groundnormal);
- }
-
- // make sure we get at least the indicated jump speed
- // this changes the behavior of downward ramps -- CEV
- if (self.velocity_z < 0)
- self.velocity_z = 0;
-
- if (self.doublejump_timer > 0)
- {
- // it may be useful in the future (for a tricks mode, etc)
- // to distinguish between different jump types -- CEV
- if (self.teleport_time > time - (PM_TELEJUMP_WINDOW + 0.2))
- {
- // a teleport jump: allow a larger (+0.2) window to
- // account for time to travel thru teleporter -- CEV
- #ifdef SSQC
- msg = sprintf ("PM_Jump: telejump %g, ",
- self.velocity_z);
- #endif
- // non-additive jump, though it shouldn't matter -- CEV
- self.velocity_z = PM_TELEJUMPSPEED;
- }
- else if (self.groundnormal && self.groundnormal_z == 1 &&
- self.groundboost_timer > 0)
- {
- #ifdef SSQC
- msg = sprintf ("PM_Jump: stairjump %g, ",
- self.velocity_z);
- #endif
- // don't do additive stairjumps on flat ground -- CEV
- self.velocity_z = PM_STAIRJUMPSPEED;
- }
- else
- {
- #ifdef SSQC
- msg = sprintf ("PM_Jump: doublejump %g, ",
- self.velocity_z);
- #endif
- // the groundnormal might be weird - some kind of
- // ramp - so we want an additive doublejump here -- CEV
- self.velocity_z += PM_DOUBLEJUMPSPEED;
- }
-
- // set the doublejump flag -- CEV
- self.pmove_flags |= PMF_DOUBLEJUMPED;
- }
- else
- {
- // normal jump
- #ifdef SSQC
- if (self.velocity_z > 0)
- msg = sprintf ("PM_Jump: jump %g, ", self.velocity_z);
- #endif
-
- // do an additive jump -- CEV
- self.velocity_z += PM_JUMPSPEED;
- }
-
- // report new Z velocity
- #ifdef SSQC
- if (msg != "")
- dprint (sprintf("%s %g\n", msg, self.velocity_z));
- #endif
-
- // manage flags -- CEV
- self.groundentity = __NULL__;
- self.groundnormal = __NULL__;
- self.pmove_flags &= ~PMF_ONGROUND;
- self.flags &= ~FL_ONGROUND;
- self.pmove_flags |= PMF_JUMP_HELD;
- self.button2 = 0;
- #ifdef SSQC
- // player jumping sound; copied into pmove from client.qc -- CEV
- sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
- #endif
-
- // timers for all jumps -- CEV
- self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
- self.groundboost_timer = PM_GROUNDBOOST_WINDOW;
-};
-
-//======================================================================
-// PM_WallJump
-//----------------------------------------------------------------------
-void() PM_WallJump =
-{
- // are we in water, already waterjumping, already walljumping,
- // or is jump being held?
- if (self.waterlevel > WATERLEVEL_NONE ||
- self.pmove_flags & PMF_WATERJUMPED ||
- self.pmove_flags & PMF_JUMP_HELD ||
- self.pmove_flags & PMF_WALLJUMPED)
- return;
-
- // mandatory interval between jump and walljump
- if (self.doublejump_timer > (PM_DOUBLEJUMP_WINDOW - PM_WALLJUMP_WINDOW))
- return;
-
- if (self.velocity_z < PM_WALLJUMPLIMIT)
- // falling too fast to walljump
- // TODO CEV it would be a good idea to include a sound here.
- return;
-
- // minimum distance from ground to walljump
- local vector end = self.origin;
- end_z -= PM_WALLJUMPGROUND;
- tracebox (self.origin, self.mins, self.maxs, end, TRUE, self);
-
- if (trace_fraction < 1.0f)
- {
- /*
- #ifdef SSQC
- dprint ("PM_WallJump: too close to ground to walljump\n");
- #endif
- */
- return;
- }
-
- // start at STEPHEIGHT + 1 to try and clear any steps -- CEV
- local vector start;
- start = self.origin;
- start_z += PM_STEPHEIGHT + 1;
- end = start;
-
- for (int i = 0; i < 4; i++)
- {
- // I've borrowed a little logic from Quake Champions Classic
- // here, shoutout to RhapsodyInGeek, check out their good work
- // https://github.com/RhapsodyInGeek/Quake-Champions-Classic
- // v_forward and v_right should still correspond to the
- // makevectors call from PM_Move -- CEV
- if (i < 2)
- if (input_movevalues_x == 0)
- continue;
- else
- end = v_forward * 10;
- if (i > 1)
- if (input_movevalues_y == 0)
- continue;
- else
- end = v_right * 10;
- if (i == 1 || i == 3)
- end = end - end * 2;
-
- end = start + end;
-
- // this ends up firing *a lot* when hopping through a map
- // normally, unfortunately. traceline may be better here -- CEV
- tracebox (start, self.mins, self.maxs, end, TRUE, self);
-
- // in order: we hit something, that something is vaguely
- // vertical, we hit it at a speed greater than -90, and
- // that something is within 20 (units?) -- CEV
- if (trace_fraction < 1.0f &&
- trace_plane_normal_z <= 0.7f &&
- trace_plane_normal_z >= 0 &&
- self.velocity * trace_plane_normal >= -90 &&
- vlen(self.origin - trace_endpos) <= 20)
- {
- self.pmove_flags |= PMF_WALLJUMPED;
- break;
- }
- }
-
- if (self.pmove_flags & PMF_WALLJUMPED)
- {
- // bounce off the wall plane -- CEV
- self.velocity_x += trace_plane_normal_x * PM_WALLJUMPFORCE;
- self.velocity_y += trace_plane_normal_y * PM_WALLJUMPFORCE;
-
- // zero out negative Z, quarter positive Z -- CEV
- if (self.velocity_z < 0)
- self.velocity_z = 0;
- else if (self.velocity_z > 0)
- self.velocity_z *= 0.25;
-
- if (self.doublejump_timer > 0)
- {
- #ifdef SSQC
- dprint ("PM_WallJump: wall double ");
- #endif
- self.velocity_z += PM_WALLJUMPDOUBLE;
- }
- else
- {
- #ifdef SSQC
- dprint ("PM_WallJump: walljump ");
- #endif
- self.velocity_z += PM_WALLJUMPSPEED;
- }
-
- // manage flags & fields; PMF_WALLJUMPED is already set -- CEV
- self.pmove_flags |= PMF_JUMP_HELD;
- self.doublejump_timer = PM_DOUBLEJUMP_WINDOW;
-
- // server-side stuff
- #ifdef SSQC
- dprint (sprintf("dist %g, normalspeed %g\n",
- vlen(self.origin - trace_endpos),
- self.velocity * trace_plane_normal));
- self.button2 = 0;
- sound (self, CHAN_BODY, "player/plyrjmp8.wav", 1, ATTN_NORM);
- #endif
- }
-};
-
-//======================================================================
-// PM_WalkAccelerate
-// Handle accel & friction for MOVETYPE_WALK entities (players). -- CEV
-//----------------------------------------------------------------------
-void(vector wishvel, float move_time) PM_WalkAccelerate =
-{
- vector wishdir;
- float accel, friction, newspeed, speed, temp, wishspeed;
-
- accel = friction = 0;
-
- wishspeed = vlen (wishvel);
- wishdir = normalize (wishvel);
-
- if (wishspeed > PM_MAXSPEED)
- wishspeed = PM_MAXSPEED;
-
- if (self.pmove_flags & PMF_PRE_MOVE)
- {
- if (self.pmove_flags & PMF_ONLADDER)
- {
- // ladder physics
- // these currently stutter in high ping (or low netfps)
- // situations because we rely on touch()ing the ladder
- // trigger to set PMF_ONLADDER and the client doesn't
- // know about the trigger brush yet -- TODO CEV
- self.velocity = 0.75 * self.velocity;
-
- if (input_buttons & 2 || self.button2 > 0 ||
- input_movevalues_z > 0)
- {
- // PlayerClimb -- johnfitz
- self.velocity_z = 160;
- }
- else if (input_movevalues_z < 0)
- {
- // PlayerClimbDown -- CEV
- self.velocity_z = -160;
- }
- else
- {
- self.flags |= FL_JUMPRELEASED;
- self.pmove_flags &= ~PMF_JUMP_HELD;
- self.velocity_z = 0;
- }
-
- self.pmove_flags &= ~PMF_ONGROUND;
- }
- else
- {
- if (input_buttons & 2 || self.button2 > 0 ||
- input_movevalues_z > 0)
- {
- // +jump was pressed
- if (self.pmove_flags & PMF_ONGROUND)
- {
- // normal jump
- PM_Jump ();
- }
- else if (autocvar(pm_walljump, FALSE))
- {
- // borrow FTE's pm_walljump cvar -- CEV
- PM_WallJump ();
- }
- }
- else
- {
- self.flags |= FL_JUMPRELEASED;
- }
- }
-
- if (self.pmove_flags & PMF_ONGROUND)
- self.pmove_flags |= PMF_STARTGROUND;
- else
- self.pmove_flags &= ~PMF_STARTGROUND;
- }
-
- // Test STARTGROUND (the ONGROUND status post jump) to avoid
- // a ground friction frame when chaining jumps together.
- // Probably has unintended consequences. -- CEV
- if (self.pmove_flags & PMF_STARTGROUND)
- {
- // we're on ground so pick accel and friction values -- CEV
- if (self.groundboost_timer > 0)
- {
- accel = PM_BOOSTACCEL;
- friction = PM_BOOSTFRICTION;
- }
- else
- {
- accel = PM_GROUNDACCEL;
- friction = PM_GROUNDFRICTION;
- }
- }
- else if (input_movevalues_x == 0)
- {
- // Q1 air accel when requesting sideways movement in the air
- // flag a check below with this -1 -- CEV
- accel = -1;
- }
- else
- {
- if (input_movevalues_y == 0)
- {
- // Painkiller style air control
- if (input_movevalues_x < 0)
- // we're slowing down
- accel = PM_AIRACCELBACK;
- else
- // we're gaining speed
- accel = PM_AIRACCELFWD;
-
- // borrow the friction var to flag a conditional below
- friction = -1;
- }
- else
- {
- // we're in the air and the player is requesting both
- // forward/back and sideways movement, so pick the Q3
- // air accel value -- CEV
- accel = PM_AIRACCELQ3;
- }
- }
-
- // I've duplicated a fair amount of code below, inlining the various
- // acceleration functions to hopefully improve performance -- CEV
-
- // apply friction (ground or otherwise)
- if (friction > 0)
- {
- // inline PM_Friction
- speed = vlen (self.velocity);
-
- if (speed < 1)
- {
- self.velocity = '0 0 0';
- }
- else
- {
- // calculate what their new speed should be
- temp = speed < PM_STOPSPEED ? PM_STOPSPEED : speed;
- newspeed = speed - temp * friction * move_time;
-
- // and slow them
- if (newspeed < 0)
- newspeed = 0;
-
- self.velocity = self.velocity * (newspeed / speed);
- }
- }
-
- if (accel == -1)
- {
- // Quake 1 sideways air acceleration; inline PM_AirAccelerate
- wishvel_z = 0;
- temp = vlen (wishvel);
- wishvel = normalize (wishvel);
- if (temp > PM_MAXAIRSPEED)
- temp = PM_MAXAIRSPEED;
- speed = self.velocity * wishvel;
- speed = temp - speed;
-
- if (speed > 0)
- {
- newspeed = PM_AIRACCEL * move_time * wishspeed;
- if (newspeed > speed)
- newspeed = speed;
- self.velocity += newspeed * wishvel;
- }
- }
- else if (accel > 0)
- {
- // ground & Quake 3 style acceleration; inline PM_Accelerate
- speed = wishspeed - (self.velocity * wishdir);
-
- if (speed > 0)
- {
- newspeed = accel * move_time * wishspeed;
- if (newspeed > speed)
- newspeed = speed;
-
- self.velocity += newspeed * wishdir;
- }
- }
-
- // CPM & PK-style air control, needs to happen after PM_Accelerate
- if (friction == -1)
- {
- // inline PM_AirControl
- temp = self.velocity_z;
- self.velocity_z = 0;
-
- speed = vlen (self.velocity);
- self.velocity = normalize (self.velocity);
-
- if ((self.velocity * wishdir) > 0)
- {
- self.velocity = normalize (self.velocity * speed +
- wishdir * PM_AIRACCELTURN);
- }
-
- self.velocity *= speed;
- self.velocity_z = temp;
- }
-
- if (!(self.pmove_flags & PMF_PRE_MOVE))
- self.pmove_flags &= ~PMF_STARTGROUND;
-};
-
-//======================================================================
-// PM_SwimAccelerate
-// Largely copied from id Software's WaterMove. Works like NoClipAccelerate.
-//----------------------------------------------------------------------
-void(vector wishvel, float move_time) PM_SwimAccelerate =
-{
- float wishspeed;
-
- if (self.pmove_flags & PMF_PRE_MOVE)
- {
- // CheckWaterJump
- if (self.waterlevel == WATERLEVEL_WAIST)
- {
- local vector start, end;
-
- start = self.origin;
- start_z = start_z + 8;
- // use wishvel instead of v_forward -- CEV
- end = [wishvel_x, wishvel_y, 0];
- end = normalize (end);
- traceline (start, (start + end * 24), TRUE, self);
-
- if (trace_fraction < 1)
- {
- // solid at the waist
- start_z = start_z + self.maxs_z - 8;
- self.movedir = trace_plane_normal * -50;
- traceline (start, (start + end * 24),
- TRUE, self);
-
- if (trace_fraction == 1)
- {
- // open at eye level
- self.flags |= FL_WATERJUMP;
- self.pmove_flags |= PMF_WATERJUMPED;
- self.flags &= ~FL_JUMPRELEASED;
- self.pmove_flags &= ~PMF_JUMP_HELD;
- // Z velocity was 225
- self.velocity_z = PM_JUMPSPEED;
- // we don't care about the 'safety net'
- // in this movement set (unlike vanilla)
- // so don't set teleport_time -- CEV
- // self.teleport_time = time + 2;
- }
- }
- }
-
- #ifdef SSQC
- // functionality copied into pmove from client.qc -- CEV
- if (self.waterlevel >= WATERLEVEL_WAIST)
- {
- if (self.swim_flag < time)
- {
- // play swimming sound
- self.swim_flag = time + 1;
- if (random() < 0.5)
- sound (self, CHAN_BODY,
- "misc/water1.wav", 1,ATTN_NORM);
- else
- sound (self, CHAN_BODY,
- "misc/water2.wav", 1,ATTN_NORM);
- }
- }
- #endif
- }
-
- if (input_buttons & 2 && !(self.pmove_flags & PMF_WATERJUMPED))
- // smartjump
- wishvel_z = max (PM_MAXSPEED, wishvel_z);
- else if (input_movevalues == '0 0 0')
- // drift towards bottom -- CEV
- wishvel_z -= PM_WATERSINKSPEED;
-
- wishspeed = vlen (wishvel);
- if (wishspeed > PM_WATERMAXSPEED)
- wishspeed = PM_WATERMAXSPEED;
- wishvel = normalize (wishvel);
-
- // water friction; reuse PM_Friction with a special constant -- CEV
- if (!(self.pmove_flags & PMF_WATERJUMPED))
- PM_Friction (PM_WATERFRICTION, move_time);
-
- // accelerate; reuse PM_Accelerate with a special constant -- CEV
- PM_Accelerate (wishvel, wishspeed, PM_WATERACCEL, move_time);
-};
-
-//======================================================================
-// PM_NoClipAccelerate
-//
-// Basic acceleration for flying / noclipping players. Not suitable for
-// swimming. -- CEV
-//----------------------------------------------------------------------
-void(vector wishvel, float scale, float move_time) PM_NoClipAccelerate =
-{
- float wishspeed;
-
- // smartjump
- if (input_buttons & 2)
- wishvel_z = max (PM_MAXSPEED, wishvel_z);
-
- wishspeed = vlen (wishvel) * scale;
- wishvel = normalize (wishvel);
-
- PM_Friction (PM_GROUNDFRICTION, move_time);
- PM_Accelerate (wishvel, wishspeed, PM_GROUNDACCEL, move_time);
-};
-
-//----------------------------------------------------------------------
-void(float move_time) PM_ManageTimers =
-{
- if (self.doublejump_timer > 0 && move_time > 0)
- self.doublejump_timer -= move_time;
- else if (self.doublejump_timer < 0)
- self.doublejump_timer = 0;
-
- if (self.doublejump_timer == 0)
- {
- self.pmove_flags &= ~PMF_DOUBLEJUMPED;
- }
-
- if (self.groundboost_timer > 0 && move_time > 0)
- self.groundboost_timer -= move_time;
- else if (self.groundboost_timer < 0)
- self.groundboost_timer = 0;
-};
-
-//======================================================================
-// PM_Move -- PMOVE entrypoint -- CEV
-//----------------------------------------------------------------------
-void(entity target) PM_Move =
-{
- if (input_timelength <= 0)
- // don't process partial frames -- CEV
- return;
-
- vector wishvel;
- entity oldself;
-
- oldself = self;
- self = target;
-
- // Nudge player's origin if the server is sending low-precision
- // (16 bit?) player coordinates. This can be fixed by setting
- // sv_bigcoords to 1 (so the server sends float coords). -- CEV
- if (!autocvar(sv_bigcoords, FALSE))
- PM_Nudge ();
-
- // rework user input, copying something like QuakeSpasm's always run
- // feature here. This turns the +speed button into a hold-to-walk
- // button when cl_run is 0 (when FTE's always run setting is on).
- // -- CEV
- if (autocvar(cl_run, FALSE) == FALSE)
- {
- // local float s = 0;
- for (int i = 0; i < 3; i++)
- {
- // this works, it's just commented out to stop calling
- // autocvar quite so many times. to re-enable change
- // the check against "PM_RUNSPEED" below to "s" -- CEV
- /*
- if (i == 0)
- s = autocvar (cl_forwardspeed, PM_RUNSPEED);
- else if (i == 1)
- s = autocvar (cl_sidespeed, PM_RUNSPEED);
- else if (i == 2)
- s = autocvar (cl_upspeed, PM_RUNSPEED);
- */
-
- if (fabs(input_movevalues[i]) > PM_RUNSPEED)
- input_movevalues[i] = PM_WALKSPEED *
- (input_movevalues[i] /
- fabs(input_movevalues[i]));
- // Don't need this, it's already PM_RUNSPEED -- CEV
- /*
- else if (input_movevalues[i] != 0)
- input_movevalues[i] = PM_RUNSPEED *
- (input_movevalues[i] /
- fabs(input_movevalues[i]));
- */
- }
- }
-
- // TODO CEV this is the wrong place to clear PMF_JUMP_HELD
- if (!(input_buttons & 2))
- self.pmove_flags &= ~PMF_JUMP_HELD;
-
- // figure out the properties of the player's position, then clear timers
- PM_CategorizePosition ();
- PM_ManageTimers (0);
-
- switch (self.movetype)
- {
- case MOVETYPE_WALK:
- local float dogravity, doskim, sticky;
-
- doskim = FALSE;
- sticky = FALSE;
-
- // signal acceleration functions that we're pre-move
- self.pmove_flags |= PMF_PRE_MOVE;
-
- // split the acceleration in two to reduce
- // framerate dependence. -- CEV
- if (self.waterlevel >= WATERLEVEL_WAIST)
- {
- // no gravity, velocity-restoring behavior,
- // or sticky clips underwater -- CEV
- dogravity = FALSE;
- doskim = FALSE;
- sticky = FALSE;
-
- // figure out wishvel -- CEV
- makevectors (input_angles);
- wishvel = v_forward * input_movevalues_x;
- wishvel += v_right * input_movevalues_y;
- wishvel += v_up * input_movevalues_z;
-
- // swim acceleration
- PM_SwimAccelerate (wishvel,
- input_timelength * 0.5f);
- }
- else
- {
- // only yaw matters here -- CEV
- makevectors ([0, input_angles_y, 0]);
- wishvel = v_forward * input_movevalues_x;
- wishvel += v_right * input_movevalues_y;
- // don't need wishvel_z -- CEV
- // wishvel += v_up * input_movevalues_z;
-
- PM_WalkAccelerate (wishvel,
- input_timelength * 0.5f);
-
- // WalkAccelerate calls Jump which might
- // alter pmove_flags, so do our feature
- // checks afterwards -- CEV
- if (self.doublejump_timer <= 0 ||
- self.pmove_flags & PMF_DOUBLEJUMPED ||
- self.pmove_flags & PMF_WALLJUMPED)
- // don't stick to the floor
- sticky = FALSE;
- else
- // we've jumped & haven't doublejumped,
- // so do sticky steps -- CEV
- sticky = TRUE;
-
- // apply gravity only when in the air or on
- // a ramp -- CEV
- if (self.groundnormal &&
- self.groundnormal_z < 1.0f)
- dogravity = TRUE;
- else if (self.pmove_flags & PMF_ONGROUND)
- dogravity = FALSE;
- else
- dogravity = TRUE;
-
- // skim / wallclipping checks -- CEV
- if (self.doublejump_timer >
- (PM_DOUBLEJUMP_WINDOW -
- PM_WALLCLIP_WINDOW) &&
- !(self.pmove_flags & PMF_WALLJUMPED) &&
- self.teleport_time <= (time - 0.1))
- doskim = TRUE;
-
- if (self.pmove_flags & PMF_ONLADDER)
- {
- // feature set for ladders -- CEV
- dogravity = FALSE;
- doskim = FALSE;
- sticky = FALSE;
- }
- }
-
- // timers (part 1) -- CEV
- PM_ManageTimers (input_timelength * 0.5f);
-
- // Do the move. Bounce, Rock, Skate, Roll -- CEV
- PM_DanceMove (dogravity, sticky, TRUE, doskim);
-
- // signal accel functions we're post-move
- self.pmove_flags &= ~PMF_PRE_MOVE;
-
- // second pass at acceleration
- if (self.waterlevel >= WATERLEVEL_WAIST)
- PM_SwimAccelerate (wishvel,
- input_timelength * 0.5f);
- else
- PM_WalkAccelerate (wishvel,
- input_timelength * 0.5f);
-
- // timers (part 2) -- CEV
- PM_ManageTimers (input_timelength * 0.5f);
-
- // clear ladder flag -- CEV
- if (self.pmove_flags & PMF_ONLADDER)
- self.pmove_flags &= ~PMF_ONLADDER;
- break;
-
- case MOVETYPE_FLY:
- // split acceleration in two to reduce framerate
- // dependence. -- CEV
- makevectors (input_angles);
- wishvel = v_forward * input_movevalues_x;
- wishvel += v_right * input_movevalues_y;
- wishvel += v_up * input_movevalues_z;
-
- PM_NoClipAccelerate (wishvel, 1.0f,
- input_timelength * 0.5f);
- PM_DanceMove (FALSE, TRUE, TRUE, FALSE);
- PM_NoClipAccelerate (wishvel, 1.0f,
- input_timelength * 0.5f);
- break;
-
- case MOVETYPE_NOCLIP:
- // noclip is a debugging feature, no need to
- // worry about acceleration consistency. -- CEV
- makevectors (input_angles);
- wishvel = v_forward * input_movevalues_x;
- wishvel += v_right * input_movevalues_y;
- wishvel += v_up * input_movevalues_z;
-
- PM_NoClipAccelerate (wishvel, 1.0f, input_timelength);
- // we're noclipping so update origin directly -- CEV
- self.origin += self.velocity * input_timelength;
- break;
-
- case MOVETYPE_NONE:
- break;
- }
-
- // make sure we've touched the ground entity (it might've slipped
- // through the slidemove above) -- CEV
- if (self.groundentity && self.groundentity.touch != __NULL__)
- PM_DoTouch (self.groundentity);
-
- touchtriggers (self);
- self = oldself;
-};
-
-//------------------------------------------------------------------------------
-// Code graveyard below. Saved here for reference purposes. -- CEV
-//------------------------------------------------------------------------------
-
-//======================================================================
-// PM_ClipVelocity
-//----------------------------------------------------------------------
-#if 0
-#define STOP_EPSILON 0.125
-vector(vector vel, vector normal, float ob, float oneside) PM_ClipVelocity =
-{
- local float backoff;
-
- backoff = vel * normal;
-
- if (backoff < 0)
- backoff *= ob;
- else
- if (oneside)
- // backoff = 0;
- backoff *= -0.001;
- else
- backoff /= ob;
-
- vel -= normal * backoff;
-
- if (vel_x > -STOP_EPSILON && vel_x < STOP_EPSILON)
- vel_x = 0;
- if (vel_y > -STOP_EPSILON && vel_y < STOP_EPSILON)
- vel_y = 0;
- if (vel_z > -STOP_EPSILON && vel_z < STOP_EPSILON)
- vel_z = 0;
-
- return vel;
-};
-#endif
-
-//======================================================================
-// PM_Q3SlideMove
-//
-// Based on Quake 3's PM_SlideMove (found in the Quake III engine GPL2
-// source release, file bg_slidemove.c). This doesn't work reliably for
-// reasons that are unclear to me; I would guess it has to do with its
-// complex use of an array. I've left it here commented out for reference
-// purposes. -- CEV
-//----------------------------------------------------------------------
-#if 0
-int(float dogravity) PM_Q3SlideMove =
-{
- 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: 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 ("PM_Q3SlideMove: ");
- 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 ("PM_Q3SlideMove: restoring velocity...\n");
- self.velocity = start_v;
- }
-
- if (bumpcount > 0) blocked |= 8;
- return blocked;
-};
-#endif
-
-//======================================================================
-// PM_Q1FlyMove
-//
-// Based on Quake 1's SV_FlyMove function (found in id's engine, QuakeSpasm,
-// and others). Has the disadvantage of using an array of vectors, and
-// is slow (I assume) in QuakeC. -- CEV
-//----------------------------------------------------------------------
-#if 0
-#define PM_SLIDE_MAX_CLIP_PLANES 5
-#define PM_SLIDE_NUMBUMPS 5
-int(float dogravity, float onesided) PM_Q1FlyMove =
-{
- vector planes[PM_SLIDE_MAX_CLIP_PLANES];
- vector dir, end, new_v, start_v;
- int blocked, bumpcount, numplanes, i, j;
- float d, ent_grav, grav, time_left;
-
- blocked = numplanes = 0;
-
- // initialize all these vectors
- for (i = 0; i < PM_SLIDE_MAX_CLIP_PLANES; i++)
- planes[i] = '0 0 0';
- dir = end = new_v = '0 0 0';
-
- if (dogravity)
- {
- if (self.gravity)
- ent_grav = self.gravity;
- else
- ent_grav = 1.0;
- grav = ent_grav * autocvar(sv_gravity, 800) * input_timelength;
- // we'll do half of it now, half later -- CEV
- self.velocity_z -= grav * 0.5;
- }
-
- // set start_v after gravity check above
- start_v = self.velocity;
-
- for (bumpcount = 0, time_left = input_timelength;
- time_left > 0 && bumpcount < PM_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 (PM_Nudge())
- continue;
-
- // nah, we're stuck. don't build up falling damage
- // but allow sideways acceleration
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: entity trapped in a solid\n");
- #endif
- self.velocity_z = 0;
- return 3;
- }
-
- if (trace_fraction >= 0.001)
- self.origin = trace_endpos;
-
- if (trace_fraction >= 1.0f)
- break;
-
- if (trace_plane_normal_z > 0.7)
- {
- blocked |= 1;
- self.groundnormal = trace_plane_normal;
- self.groundentity = trace_ent;
- }
-
- if (!(trace_plane_normal_z))
- blocked |= 2;
-
- PM_DoTouch (trace_ent);
- time_left -= time_left * trace_fraction;
-
- if (numplanes >= PM_SLIDE_MAX_CLIP_PLANES)
- {
- // this shouldn't really happen
- if (cvar("developer"))
- {
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: numplanes >= max: ");
- dprint (ftos(numplanes));
- dprint ("\n");
- #endif
- }
- self.velocity = '0 0 0';
- blocked = 7;
- break;
- }
-
- planes[numplanes] = trace_plane_normal;
- numplanes++;
-
- for (i = 0; i < numplanes; i++)
- {
- // slide along the plane
- new_v = PM_ClipVelocity (self.velocity,
- planes[i], PM_OVERCLIP, onesided);
-
- for (j = 0; j < numplanes; j++)
- if (j != i)
- // not ok (the comment says)
- if ((new_v * planes[j]) < 0)
- break;
-
- if (j == numplanes)
- break;
- }
-
- if (i == numplanes)
- {
- if (numplanes != 2)
- {
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: stopping dead\n");
- #endif
- self.velocity = '0 0 0';
- blocked = 7;
- break;
- }
-
- // slide along the crease
- dir = crossproduct (planes[0], planes[1]);
- dir = normalize (dir);
- d = (dir * self.velocity);
- new_v = dir * d;
- }
-
- self.velocity = new_v;
-
- if ((self.velocity * start_v) <= 0)
- {
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: turned against orig vel\n");
- #endif
- self.velocity = '0 0 0';
- break;
- }
- }
-
- // wallclip / wall skim timer check
- if ( // (self.primal_speed > PM_MAXSPEED) &&
- (self.velocity != '0 0 0') &&
- (self.jump_time) &&
- (!(self.pmove_flags & PMF_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)))
- {
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: restoring velocity...\n");
- #endif
- self.velocity = [start_v_x, start_v_y, self.velocity_z];
- }
-
- // final gravity check here
- if (dogravity)
- self.velocity_z -= grav * 0.5;
-
- /* for debugging -- CEV
- #ifdef SSQC
- dprint ("PM_Q1FlyMove: numplanes ");
- dprint (ftos(numplanes));
- dprint ("\n");
- #endif
- */
-
- return blocked;
-};
-#endif
-
-//======================================================================
-// PM_StepSlideMove
-//
-// Based on the StepSlideMove function found in the Quake III sourcecode.
-// Calls PM_Q1FlyMove several times. This works, but is slow and has
-// some tracking issues (probably my fault). -- CEV
-//----------------------------------------------------------------------
-#if 0
-void(float dogravity, float onesided) PM_StepSlideMove =
-{
- vector start_o, start_v, first_o, first_v;
- vector up, down;
- float stepsize;
- int clip, first_clip;
- int start_onground;
-
- clip = first_clip = 0;
- start_o = self.origin;
- start_v = self.velocity;
- start_onground = (self.pmove_flags & PMF_ONGROUND);
-
- // first try let's go
- first_clip = PM_Q1FlyMove (dogravity, onesided);
-
- if (!(first_clip & 2) && !(first_clip & 8))
- {
- // we got where we wanted to go right away
- // #ifdef SSQC
- // dprint ("PM_StepSlideMove: accepting first move\n");
- // #endif
- if (first_clip & 1)
- self.pmove_flags |= PMF_ONGROUND;
- else
- self.pmove_flags &= ~PMF_ONGROUND;
- return;
- }
-
- if (self.movetype != MOVETYPE_WALK)
- // gibbed by a trigger?
- return;
-
- if (autocvar(pm_nostep, FALSE))
- // no stepping. useful for testing -- CEV
- return;
-
- if (!(autocvar(pm_airstep, TRUE)) && !(self.pmove_flags & PMF_ONGROUND))
- // Borrowing FTE's pm_airstep cvar here. If false, don't
- // step up while in the air (changes stairs) -- CEV
- return;
-
- first_o = self.origin;
- first_v = self.velocity;
-
- self.origin = start_o;
- self.velocity = start_v;
-
- up = start_o;
- up_z += PM_STEPHEIGHT;
- tracebox (start_o, self.mins, self.maxs, up, FALSE, self);
-
- if (trace_allsolid)
- {
- #ifdef SSQC
- dprint ("PM_StepSlideMove: can't step up\n");
- #endif
- self.origin = first_o;
- self.velocity = first_v;
- if (first_clip & 1)
- self.pmove_flags |= PMF_ONGROUND;
- else
- self.pmove_flags &= ~PMF_ONGROUND;
- return;
- }
-
- // try slidemove from this position (in air)
- stepsize = trace_endpos_z - start_o_z;
- self.origin = trace_endpos;
- self.velocity = start_v;
- clip = PM_Q1FlyMove (dogravity, onesided);
-
- // push down the final amount
- down = self.origin;
- down_z -= stepsize;
- tracebox (self.origin, self.mins, self.maxs, down, FALSE, self);
-
- if (trace_allsolid)
- {
- #ifdef SSQC
- dprint ("PM_StepSlideMove: second move is in a solid\n");
- #endif
- self.origin = first_o;
- self.velocity = first_v;
- if (first_clip & 1)
- self.pmove_flags |= PMF_ONGROUND;
- else
- self.pmove_flags &= ~PMF_ONGROUND;
- return;
- }
-
- if (!trace_plane_normal_z || trace_plane_normal_z > 0.7)
- {
- // we're on 'good ground', accept the second slidemove
- // #ifdef SSQC
- // dprint ("PM_StepSlideMove: accepting second slidemove\n");
- // #endif
- self.origin = trace_endpos;
- if (trace_fraction < 1.0)
- {
- // clip to step
- self.velocity = PM_ClipVelocity (self.velocity,
- trace_plane_normal, PM_OVERCLIP, onesided);
- }
- if (trace_plane_normal_z > 0.7)
- self.pmove_flags |= PMF_ONGROUND;
- else
- self.pmove_flags &= ~PMF_ONGROUND;
- }
- else
- {
- // not on 'good ground', revert to first slidemove
- // see the similar section of SV_WalkMove
- // #ifdef SSQC
- // dprint ("PM_StepSlideMove: reverting to first move\n");
- // #endif
- self.origin = first_o;
- self.velocity = first_v;
- if (first_clip & 1)
- self.pmove_flags |= PMF_ONGROUND;
- else
- self.pmove_flags &= ~PMF_ONGROUND;
- }
-
- // this is a complicated check.
- // if we started in the air and we're now on the ground
- // and we stepped up and we lost some Z velocity then we've
- // clipped to ground on a step up
- if (!start_onground && (self.pmove_flags & PMF_ONGROUND) &&
- (start_v_z > self.velocity_z) &&
- (self.velocity_z < 1) &&
- (self.origin_z - start_o_z > 0))
- {
- if (!self.boost_time &&
- self.boost_time <= time - PM_BOOST_WINDOW)
- self.boost_time = time;
-
- if (cvar("developer"))
- {
- #ifdef SSQC
- stepsize = self.origin_z - start_o_z;
- dprint (sprintf("PM_StepSlideMove: step up: %g\n",
- stepsize));
- #endif
- }
- }
-};
-#endif

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 761389d..c9bedb7 100644
--- a/qc/progs.src
+++ b/qc/progs.src
@@ -13,6 +13,7 @@ defs_globalvars.qc // globalvars_t
defs_entvars.qc // entvars_t
defs_builtins.qc // builtin functions (& overrides)
defs_misc.qc // additional
+defs_classtype.qc // global class list

//----------------------------------------------------------------------
// utility & helper functions
@@ -28,28 +29,47 @@ custom_snd.qc // mapper-settable sound FX for monsters - iw
custom_mdls.qc // mapper-settable models for monsters - iw

//----------------------------------------------------------------------
-// world -- TODO CEV
+// world
//----------------------------------------------------------------------
world.qc

//----------------------------------------------------------------------
-// combat & monster AI -- TODO CEV
+// base classes
+//----------------------------------------------------------------------
+classes/base_trigger.qc // methods & fields for trigger entities
+
+//----------------------------------------------------------------------
+// combat & monster AI -- TODO CEV need to reformat
//----------------------------------------------------------------------
fight.qc
ai.qc
combat.qc

//----------------------------------------------------------------------
-// client code -- TODO CEV
+// client & player code
//----------------------------------------------------------------------
+cutscene.qc // Drake version -- dumptruck_ds
+client/connect.qc // ClientConnect, ClientDisconnect
client/impulse.qc // impulse cmd handling; was in weapons.qc -- CEV
client/intermission.qc // intermission & exit screen text
+client/levelparms.qc // Level Changing; NextMap
+client/maprules.qc // Deathmatch NextLevel and CheckRules
+client/obituary.qc // ClientObituary
+client/playerspawn.qc // PutClientInServer, info_player ents, etc.
+player/player.qc // player animation frames, pain & death, etc.
+player/playerthink.qc // TODO CEV was in client.qc
+player/pmove.qc // QC player movement code -- CEV

-pmove.qc // QC player movement code -- CEV
-client.qc
-cutscene.qc // Drake version -- dumptruck_ds
-player.qc
-weapons.qc
+weapons.qc // TODO CEV need to reformat
+
+//----------------------------------------------------------------------
+// info entities -- destinations, targets, etc.
+//----------------------------------------------------------------------
+info/camera.qc // was in cutscene.qc
+info/null.qc // info_null; was in lights.qc
+info/notnull.qc // info_notnull; was in lights.qc
+info/teleport_changedest.qc // Qmaster's info_teleport_changedest
+info/teleport_destination.qc // teleporter endpoints

//----------------------------------------------------------------------
// item entities
@@ -64,6 +84,10 @@ items/powerups.qc // envirosuit, pent, ring, quad; was in items.qc
items/runes.qc // end-of-episode runes; was in items.qc
items/weapons.qc // weapon pickups; was in items.qc

+items/axe.qc //
+items/nailguns.qc //
+items/shotguns.qc //
+
//----------------------------------------------------------------------
// func entities
//----------------------------------------------------------------------
@@ -93,27 +117,33 @@ func/train.qc // was plats.qc -- CEV
func/wall.qc // was misc.qc -- CEV

//----------------------------------------------------------------------
-// trigger entities
+// trigger & target entities
//----------------------------------------------------------------------
+triggers/multiple.qc // need to add first, subclassed below -- CEV
+triggers/camera.qc // was in cutscene.qc
triggers/changelevel.qc //
triggers/changemusic.qc //
triggers/changetarget.qc
triggers/counter.qc //
+triggers/cvarset.qc // was in cutscene.qc
+triggers/everything.qc // trigger_everything
triggers/filter.qc //
triggers/fog.qc // fog triggers
triggers/heal.qc // trigger_heal (was in dtmisc.qc) -- CEV
triggers/hurt.qc //
triggers/ladder.qc // ladders (from rubicon2) -- CEV
triggers/look.qc //
-triggers/misc.qc // was triggers.qc -- CEV
triggers/monsterface.qc //
triggers/monsterjump.qc //
triggers/onlyregistered.qc
triggers/push.qc // wind/push brushes, jumppads -- CEV
triggers/remove.qc // was in hip_trig.qc; currently commented out -- CEV
+triggers/relay.qc //
triggers/secret.qc //
+triggers/setcount.qc // target_setcount
triggers/setgravity.qc // was in hip_trig.qc
triggers/setskill.qc //
+triggers/setstate.qc // target_setstate
triggers/shake.qc // triggerable shake from Zer cutscenes; was dtquake.qc
triggers/take_weapon.qc //
triggers/teleport.qc // was in triggers.qc -- CEV
@@ -122,7 +152,7 @@ triggers/usekey.qc // was in hip_trig.qc -- CEV
triggers/void.qc //

//----------------------------------------------------------------------
-// monster entities
+// monster entities -- TODO CEV need to reformat the monster code
//----------------------------------------------------------------------
monsters/boss.qc
monsters/boss2.qc // killable Chthon
@@ -143,7 +173,6 @@ monsters/shalrath.qc // registered

monsters.qc // modified by dumptruck_ds from Preach's
// spawning tutorial | fish count fixed
- // TODO CEV

//----------------------------------------------------------------------
// hazards
@@ -154,6 +183,7 @@ hazards/shooter.qc // was in misc.qc
//----------------------------------------------------------------------
// miscellaneous entities
//----------------------------------------------------------------------
+misc/model.qc // Code by Joshua Skelton
misc/air_bubbles.qc // was in misc.qc -- CEV
misc/ambient_sound.qc // misc. ambient_ entities w/additions by dumptruck_ds
misc/deadstuff.qc // misc gore from DeadStuff mod
@@ -162,7 +192,6 @@ misc/fireball.qc // was in misc.qc -- CEV
misc/infight.qc // was in misc.qc -- CEV
misc/light_candle.qc // was in misc.qc -- CEV
misc/lights.qc // c0burn's excellent switchable lights
-misc/model.qc // Code by Joshua Skelton
misc/modeltrain.qc // was in plats.qc -- CEV
misc/noisemaker.qc // was in misc.qc -- CEV
misc/particles.qc // selections from Rubicon2 QC; was rubicon2.qc -- CEV

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

Diff qc/subs.qc

diff --git a/qc/subs.qc b/qc/subs.qc
index 279a426..ca6a367 100644
--- a/qc/subs.qc
+++ b/qc/subs.qc
@@ -7,10 +7,19 @@
// 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;
-
+.float ritem, respawndelay, respawncount;
+
+// prototypes
+void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove;
+void(vector tdest, float tspeed, void() func) SUB_CalcMove;
+void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt;
+void() SUB_CalcMoveDone;
+void() SUB_CalcAngleMoveDone;
void() SUB_CalcAngleMoveDoneController;
-float (entity targ) visible;
+void() SUB_Null;
+void() SUB_Remove;
+void() SUB_UseTargets;
+float(entity targ) visible;

//----------------------------------------------------------------------
// CheckItemRespawn -- was in items.qc
@@ -86,45 +95,6 @@ void() SetMovedir =
};

//----------------------------------------------------------------------
-// InitTrigger
-//----------------------------------------------------------------------
-void() InitTrigger =
-{
- // trigger angles are used for one-way touches.
- // An angle of 0 is assumed to mean no restrictions, so use a
- // yaw of 360 instead.
- if (self.angles != '0 0 0')
- SetMovedir ();
-
- self.solid = SOLID_TRIGGER;
- // set size and link into world
- setmodel (self, self.model);
- self.movetype = MOVETYPE_NONE;
- self.modelindex = 0;
- self.model = "";
-};
-
-//----------------------------------------------------------------------
-// InitPointTrigger -- Drake -- dumptruck_ds
-// PM: The point trigger version of InitTrigger.
-//----------------------------------------------------------------------
-void() InitPointTrigger =
-{
- local vector v1, v2;
-
- v1 = self.origin;
- v2 = v1 + self.mangle;
- self.model = "";
- setorigin (self, '0 0 0');
-
- // Calls 'setmodel', so do first.
- InitTrigger ();
-
- // Calling 'setmodel' resets entity size.
- setsize (self, v1, v2);
-};
-
-//----------------------------------------------------------------------
void() SUB_Null =
{
// no-op
@@ -805,7 +775,8 @@ void() SUB_Regen =
// Respawn with DM effects
// if (deathmatch || (self.spawnflags & ITEM_RESPAWNDM))
// play respawn sound
- sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);
+ sound (self, CHAN_VOICE, "items/item_respawn_q3.wav",
+ 1, ATTN_NORM);
// else
// play teleport sound and display particles
// spawn_tfog (self.origin + self.particles_offset);

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

Diff qc/triggers/camera.qc

diff --git a/qc/triggers/camera.qc b/qc/triggers/camera.qc
new file mode 100644
index 0000000..2392678
--- /dev/null
+++ b/qc/triggers/camera.qc
@@ -0,0 +1,209 @@
+//==============================================================================
+// trigger_camera, trigger_camera_point -- was in cutscene.qc
+//==============================================================================
+
+class base_trigger_camera: base_trigger
+{
+ //--------------------------------------------------------------
+ // camera_activate -- PM: Called from either touch or use.
+ //--------------------------------------------------------------
+ nonvirtual void(entity who) camera_activate =
+ {
+ // only activate for player, 1st time touched
+ if (who.health <= 0)
+ return;
+ // In case of Alien Quake facehugger kill.
+ if (who.deadflag)
+ return;
+ if (who.classname != "player")
+ return;
+
+ // You can't touch/use this again.
+ this.touch = this.use = SUB_Null;
+
+ // If player is on ground, take him off ground so no one
+ // gets confused
+ who.flags = who.flags - (who.flags & FL_ONGROUND);
+
+ // put a dummy where the player was
+ spawn_dummy (who);
+
+ // find camera
+ local entity t;
+
+ t = find (world, ::targetname, this.target);
+ /*
+ if (vision)
+ {
+ if (!t)
+ objerror ("couldn't find target");
+ }
+ else
+ {
+ */
+ local entity fpt;
+
+ while ((t != world) &&
+ (t.classname != "info_movie_camera"))
+ {
+ t = find (t, ::targetname, this.target);
+ }
+
+ if (!t)
+ objerror ("couldn't find target");
+
+ // find focal point
+ fpt = find (world, ::targetname, this.focal_point);
+ if (!fpt)
+ objerror ("You must have a focal point!\n");
+ else
+ // movedir used to calc focal dir
+ who.movedir = fpt.origin;
+ /*
+ }
+ */
+
+ // Go to the camera - not in this function, because touch
+ // functions are called while looping through c code, and
+ // you don't want to move the player, or something like that?
+
+ // save camera position, etc.
+ who.enemy = t;
+ // save script number
+ who.script = this.script;
+ // save delay for page 1
+ who.script_delay = this.script_delay;
+
+ /*
+ if (vision)
+ {
+ // PM: Don't try instant start because that
+ // breaks soeexit.bsp.
+ who.nextthink = time + 0.05;
+ who.think = go_camera;
+ }
+ else
+ {
+ */
+ SUB_Think (who, go_camera);
+ /*
+ }
+ */
+
+ activator = this;
+ SUB_UseTargets ();
+
+ // Remove the trigger_camera from level
+ this.nextthink = time + 0.1;
+ this.think = SUB_Remove;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() camera_touch =
+ {
+ if (this.targetname != __NULL__ && this.targetname != "")
+ if (this.nextthink < time)
+ return;
+
+ if (this.cnt == -1)
+ return;
+
+ this.camera_activate (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() camera_point_touch =
+ {
+ this.camera_activate (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() camera_use =
+ {
+ local entity pl;
+
+ // Only one in single-player.
+ pl = findfloat (world, ::classtype, CT_PLAYER);
+ this.camera_activate (pl);
+
+ // Old code.
+ /*
+ this.nextthink = time + 100000;
+ // make sure even still objects get hit
+ force_retouch = 2;
+ this.think = SUB_Null;
+ */
+ };
+
+ //--------------------------------------------------------------
+ virtual void(float pt) trigger_camera_spawn =
+ {
+ // Update: Don't let dmsp muck up cutscenes and vice versa.
+ // PM: Fix -- abort if removed.
+ if (deathmatch || coop)
+ {
+ remove (this);
+ return;
+ }
+
+ if (pt)
+ {
+ // The new way, this is for you Tronyn.
+ init_point_trigger ();
+ if (!this.targetname)
+ this.touch = this.camera_point_touch;
+ }
+ else
+ {
+ // The old way...
+ init_trigger ();
+ // PM: Must always allow touch because some
+ // old maps need it.
+ this.touch = this.camera_touch;
+ }
+
+ // find the destination
+ if (!this.target)
+ objerror ("Camera trigger with no target");
+ this.use = this.camera_use;
+ };
+};
+
+/*QUAKED trigger_camera (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A player touching this will be transported to the corresponding
+info_movie_camera entity. You must set the "target" field, and put a
+info_movie_camera with a "targetname" field that matches. The "script"
+key gives a starting script number, and the "script_delay" key is the
+amount of time(seconds) to stay on the first script page.
+
+If the trigger_camera has a targetname, it will only enter camera mode
+after it has been fired.
+*/
+class trigger_camera: base_trigger_camera
+{
+ //--------------------------------------------------------------
+ void() trigger_camera =
+ {
+ this.classname = "trigger_camera";
+ this.classtype = CT_TRIGGER_CAMERA;
+ this.trigger_camera_spawn (FALSE);
+ };
+};
+
+/*QUAKED trigger_camera_point (.5 .5 .5) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+When this is triggered the player will be transported to the corresponding
+info_movie_camera entity. You must set the "target" field, and put a
+info_movie_camera with a "targetname" field that matches. The "script"
+key gives a starting script number, and the "script_delay" key is the
+amount of time(seconds) to stay on the first script page.
+*/
+class trigger_camera_point: base_trigger_camera
+{
+ //--------------------------------------------------------------
+ void() trigger_camera_point =
+ {
+ this.classname = "trigger_camera_point";
+ this.classtype = CT_TRIGGER_CAMERA_POINT;
+ this.trigger_camera_spawn (TRUE);
+ };
+};

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

Diff qc/triggers/changelevel.qc

diff --git a/qc/triggers/changelevel.qc b/qc/triggers/changelevel.qc
index 2540298..52b92be 100644
--- a/qc/triggers/changelevel.qc
+++ b/qc/triggers/changelevel.qc
@@ -2,148 +2,157 @@
// trigger_changelevel
//==============================================================================

-const float DT_EXITOFF = 8;
+// constants
+const float TRIGGER_CHANGELEVEL_EXITOFF = 8; // was DT_EXITOFF

-//----------------------------------------------------------------------
-void() execute_changelevel =
+/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
+*/
+class trigger_changelevel: base_trigger
{
- used_exit = self;
- local entity pos;
+ //--------------------------------------------------------------
+ virtual void() changelevel_execute =
+ {
+ used_exit = this;
+ local entity pos;

- intermission_running = 1;
+ intermission_running = 1;

- // enforce a wait time before allowing changelevel
- if (deathmatch)
- intermission_exittime = time + 5;
- else
- intermission_exittime = time + 2;
+ // enforce a wait time before allowing changelevel
+ if (deathmatch)
+ intermission_exittime = time + 5;
+ else
+ intermission_exittime = time + 2;

- WriteByte (MSG_ALL, SVC_CDTRACK);
- WriteByte (MSG_ALL, 3);
- WriteByte (MSG_ALL, 3);
+ WriteByte (MSG_ALL, SVC_CDTRACK);
+ WriteByte (MSG_ALL, 3);
+ WriteByte (MSG_ALL, 3);

- pos = FindIntermission ();
+ pos = FindIntermission ();

- other = find (world, classname, "player");
- while (other != world)
- {
- other.view_ofs = '0 0 0';
- other.angles = other.v_angle = pos.mangle;
- // turn this way immediately
- other.fixangle = TRUE;
- other.nextthink = time + 0.5;
- other.takedamage = DAMAGE_NO;
- other.solid = SOLID_NOT;
- other.movetype = MOVETYPE_NONE;
- other.modelindex = 0;
- setorigin (other, pos.origin);
- other = find (other, classname, "player");
- fog_setFromEnt (other, pos);
- }
-
- // Drake -- dumptruck_ds
- if (cutscene)
- {
- // If player was in a cutscene when the level ended,
- // restore viewsize.
- pos = find (world, classname, "camera");
- if (pos)
+ other = findfloat (world, ::classtype, CT_PLAYER);
+ while (other != world)
{
- local string val;
-
- val = ftos (pos.cnt);
- cvar_set ("viewsize", val);
+ other.view_ofs = '0 0 0';
+ other.angles = other.v_angle = pos.mangle;
+ // turn this way immediately
+ other.fixangle = TRUE;
+ other.nextthink = time + 0.5;
+ other.takedamage = DAMAGE_NO;
+ other.solid = SOLID_NOT;
+ other.movetype = MOVETYPE_NONE;
+ other.modelindex = 0;
+ setorigin (other, pos.origin);
+ other = findfloat (other, ::classtype, CT_PLAYER);
+ fog_setFromEnt (other, pos);
}
- }

- WriteByte (MSG_ALL, SVC_INTERMISSION);
-};
+ // Drake -- dumptruck_ds
+ if (cutscene)
+ {
+ // If player was in a cutscene when the level ended,
+ // restore viewsize.
+ pos = find (world, ::classname, "camera");
+ if (pos)
+ {
+ local string val;
+
+ val = ftos (pos.cnt);
+ cvar_set ("viewsize", val);
+ }
+ }
+ WriteByte (MSG_ALL, SVC_INTERMISSION);
+ };

-//----------------------------------------------------------------------
-void() changelevel_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
+ //--------------------------------------------------------------
+ virtual void() changelevel_touch =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;

- if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) &&
- (mapname != "start")))
- {
- T_Damage (other, self, self, 50000);
- return;
- }
+ if ((cvar("noexit") == 1) || ((cvar("noexit") == 2) &&
+ (mapname != "start")))
+ {
+ T_Damage (other, this, this, 50000);
+ return;
+ }

- if (coop || deathmatch)
- {
- bprint (other.netname);
- bprint (" exited the level\n");
- }
+ if (coop || deathmatch)
+ {
+ bprint (other.netname);
+ bprint (" exited the level\n");
+ }

- nextmap = self.map;
- SUB_UseTargets ();
+ nextmap = this.map;
+ SUB_UseTargets ();

- if ((self.spawnflags & 16) && (deathmatch == 0))
- {
- // use info_player_start2 -- dumptruck_ds
- sigil_touch2 ();
- }
+ if ((this.spawnflags & 16) && (deathmatch == 0))
+ {
+ // use info_player_start2 -- dumptruck_ds
+ sigil_touch2 ();
+ }

- if ((self.spawnflags & 1) && (deathmatch == 0))
- {
- // NO_INTERMISSION
- GotoNextMap ();
- return;
- }
+ if ((this.spawnflags & 1) && (deathmatch == 0))
+ {
+ // NO_INTERMISSION
+ GotoNextMap ();
+ return;
+ }

- self.touch = SUB_Null;
+ this.touch = SUB_Null;

- // we can't move people right now, because touch functions are called
- // in the middle of C movement code, so set a think time to do it
- self.think = execute_changelevel;
- self.nextthink = time + 0.1;
-};
+ // we can't move people right now, because touch functions
+ // are called in the middle of C movement code, so set a
+ // think time to do it
+ this.think = this.changelevel_execute;
+ this.nextthink = time + 0.1;
+ };

-//----------------------------------------------------------------------
-// dumptruck_ds based on hipnotic blocker_use
-//----------------------------------------------------------------------
-void() dt_exit_toggle =
-{
- if (self.estate != STATE_ACTIVE)
+ //--------------------------------------------------------------
+ // trigger_changelevel_use
+ // dumptruck_ds based on hipnotic blocker_use; was named dt_exit_toggle
+ //--------------------------------------------------------------
+ virtual void() changelevel_use =
{
- self.is_waiting = 0;
- self.estate = STATE_ACTIVE;
- }
- else
- {
- self.is_waiting = 1;
- self.estate = STATE_INACTIVE;
- }
-};
+ if (this.estate != STATE_ACTIVE)
+ {
+ this.is_waiting = 0;
+ this.estate = STATE_ACTIVE;
+ }
+ else
+ {
+ this.is_waiting = 1;
+ this.estate = STATE_INACTIVE;
+ }
+ };

-/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ //--------------------------------------------------------------
+ void() trigger_changelevel =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

-When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats.
-*/
-void() trigger_changelevel =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ this.classname = "trigger_changelevel";
+ this.classtype = CT_TRIGGER_CHANGELEVEL;

- // dumptruck_ds
- if (self.spawnflags & DT_EXITOFF)
- self.is_waiting = 1;
+ // dumptruck_ds
+ if (this.spawnflags & TRIGGER_CHANGELEVEL_EXITOFF)
+ this.is_waiting = 1;

- SUB_CheckWaiting ();
- self.use = dt_exit_toggle;
+ SUB_CheckWaiting ();
+ this.use = this.changelevel_use;

- if (!self.map)
- objerror ("changelevel trigger doesn't have map");
+ if (!this.map)
+ objerror ("changelevel trigger doesn't have map");

- InitTrigger ();
- self.flags = self.flags | FL_NOCENTERPRINT;
- self.touch = changelevel_touch;
+ init_trigger ();
+ this.flags = this.flags | FL_NOCENTERPRINT;
+ this.touch = this.changelevel_touch;
+ };
};

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

Diff qc/triggers/changemusic.qc

diff --git a/qc/triggers/changemusic.qc b/qc/triggers/changemusic.qc
index 0aec200..561929d 100644
--- a/qc/triggers/changemusic.qc
+++ b/qc/triggers/changemusic.qc
@@ -2,70 +2,75 @@
// trigger_changemusic, trigger_cdtrack
//==============================================================================

-void(float newtrack) changemusic =
+class base_changemusic: base_trigger
{
- // changing the field via a pointer
- *world_sounds = newtrack;
-
- // world.sounds has now been changed via our pointer, newly connecting
- // players (like those connecting after the game is loaded) will get
- // sent the new cd track's number.
-
- // let everyone currently on the server know.
- WriteByte(MSG_ALL, SVC_CDTRACK);
- // initial track
- WriteByte(MSG_ALL, newtrack);
- // looped track... should generally be set the same as the initial
- // track as most engines ignore it entirely so it might as well be
- // same for those that care.
- WriteByte(MSG_ALL, newtrack);
-};
-
-// thanks to jleww via changemusic.rar --dumptruck_ds
-void() trigger_changemusic_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
- changemusic (self.sounds);
- self.touch = SUB_Null;
- self.nextthink = (time + 0.1);
- self.think = SUB_Remove;
+ //--------------------------------------------------------------
+ virtual void(float newtrack) changemusic =
+ {
+ // changing the field via a pointer
+ *world_sounds = newtrack;
+
+ // world.sounds has now been changed via our pointer, newly
+ // connecting players (like those connecting after the game
+ // is loaded) will get sent the new cd track's number.
+
+ // let everyone currently on the server know.
+ WriteByte(MSG_ALL, SVC_CDTRACK);
+ // initial track
+ WriteByte(MSG_ALL, newtrack);
+ // looped track... should generally be set the same as the
+ // initial track as most engines ignore it entirely so it
+ // might as well be same for those that care.
+ WriteByte(MSG_ALL, newtrack);
+ };
};

/*QUAKED trigger_changemusic (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
A trigger brush that changes the currently playing music track. The number of the track to play goes in the sounds key (just like worldspawn). */
-void() trigger_changemusic =
+class trigger_changemusic: base_changemusic
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.sounds)
+ //--------------------------------------------------------------
+ // thanks to jleww via changemusic.rar --dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void() changemusic_touch =
{
- // splitting the error string up, FTEQCC does implicit
- // string concatenation -- CEV
- objerror ("ERROR: trigger_changemusic needs valid track"
- " number in sounds field");
- return;
- }
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;

- InitTrigger ();
- self.touch = trigger_changemusic_touch;
-
- SUB_CheckWaiting ();
-};
+ if (!(other.flags & FL_CLIENT))
+ return;

+ this.changemusic (this.sounds);
+ this.touch = SUB_Null;
+ this.nextthink = (time + 0.1);
+ this.think = SUB_Remove;
+ };

-// point entity version uses count for music track number for backwards
-// compatibly in Adoria mod -- dumptruck_ds
-void() trigger_cdtrack_use =
-{
- changemusic (self.count);
+ //--------------------------------------------------------------
+ void() trigger_changemusic =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_changemusic";
+ this.classtype = CT_TRIGGER_CHANGEMUSIC;
+
+ if (!this.sounds)
+ {
+ // splitting the error string up, FTEQCC does implicit
+ // string concatenation -- CEV
+ objerror ("ERROR: trigger_changemusic needs valid track"
+ " number in sounds field");
+ return;
+ }
+
+ init_trigger ();
+ this.touch = this.changemusic_touch;
+
+ SUB_CheckWaiting ();
+ };
};

/*QUAKED trigger_cdtrack (.7 .7 .7) 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
@@ -73,22 +78,35 @@ A point entity that changes the currently playing music track when triggered. Th

NOTE: the track number uses the count key here but trigger_changemusic uses the sound key for the same info.
*/
-void() trigger_cdtrack =
+class trigger_cdtrack: base_changemusic
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ // point entity version uses count for music track number for
+ // backwards compatibly in Adoria mod -- dumptruck_ds
+ virtual void() cdtrack_use =
+ {
+ this.changemusic (this.count);
+ };

- if (!self.count)
+ //--------------------------------------------------------------
+ void() trigger_cdtrack =
{
- // splitting the error string up, FTEQCC does implicit
- // string concatenation -- CEV
- objerror ("ERROR: trigger_cdtrack needs valid track number"
- " in count field");
- return;
- }
-
- InitTrigger ();
- self.use = trigger_cdtrack_use;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_cdtrack";
+ this.classtype = CT_TRIGGER_CDTRACK;
+
+ if (!this.count)
+ {
+ // splitting the error string up, FTEQCC does
+ // implicit string concatenation -- CEV
+ objerror ("ERROR: trigger_cdtrack needs valid track "
+ "number in count field");
+ return;
+ }
+
+ init_trigger ();
+ this.use = this.cdtrack_use;
+ };
};
-

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

Diff qc/triggers/changetarget.qc

diff --git a/qc/triggers/changetarget.qc b/qc/triggers/changetarget.qc
index 2cf1557..e3cbf30 100644
--- a/qc/triggers/changetarget.qc
+++ b/qc/triggers/changetarget.qc
@@ -2,24 +2,6 @@
// trigger_changetarget
//==============================================================================

-void() trigger_target_change_use =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- for (entity e = world; (e = find (e, targetname, self.target)); )
- {
- if (!self.cnt || self.cnt == 1)
- e.target = self.message;
- else if (self.cnt == 2)
- e.target2 = self.message;
- else if (self.cnt == 3)
- e.target3 = self.message;
- else if (self.cnt == 4)
- e.target4 = self.message;
- }
-};
-
/*QUAKED trigger_changetarget (.5 .5 .5) ?
Changes an entity's target field

@@ -28,11 +10,37 @@ message = new value for target field
cnt = target field to change, null defaults to target

*/
-void() trigger_changetarget =
+class trigger_changetarget: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() changetarget_use =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ for (entity e = world;
+ (e = find (e, ::targetname, this.target)); )
+ {
+ if (!this.cnt || this.cnt == 1)
+ e.target = this.message;
+ else if (this.cnt == 2)
+ e.target2 = this.message;
+ else if (this.cnt == 3)
+ e.target3 = this.message;
+ else if (this.cnt == 4)
+ e.target4 = this.message;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_changetarget =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- self.use = trigger_target_change_use;
+ this.classname = "trigger_changetarget";
+ this.classtype = CT_TRIGGER_CHANGETARGET;
+ this.use = this.changetarget_use;
+ };
};

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

Diff qc/triggers/counter.qc

diff --git a/qc/triggers/counter.qc b/qc/triggers/counter.qc
index b0efb8b..17a72e4 100644
--- a/qc/triggers/counter.qc
+++ b/qc/triggers/counter.qc
@@ -2,43 +2,8 @@
// trigger_counter
//==============================================================================

-//----------------------------------------------------------------------
-void() counter_use =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- self.count = self.count - 1;
- if (self.count < 0)
- return;
-
- if (self.count != 0)
- {
- if (activator.classname == "player" &&
- (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
- {
- if (self.count >= 4)
- centerprint (activator, "There are more "
- "to go...");
- else if (self.count == 3)
- centerprint (activator, "Only 3 more to go...");
- else if (self.count == 2)
- centerprint (activator, "Only 2 more to go...");
- else
- centerprint (activator, "Only 1 more to go...");
- }
- return;
- }
-
- if (activator.classname == "player" &&
- (self.spawnflags & SPAWNFLAG_NOMESSAGE) == 0)
- {
- centerprint(activator, "Sequence completed!");
- }
-
- self.enemy = activator;
- multi_trigger ();
-};
+// constants
+const float TRIGGER_COUNTER_NOMESSAGE = 1;

/*QUAKED trigger_counter (.5 .5 .5) ? nomessage 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

@@ -48,16 +13,63 @@ If nomessage is not set, t will print "1 more.. " etc when triggered and "sequen

After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
*/
-void() trigger_counter =
+class trigger_counter: base_multiple
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() counter_use =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ this.count = this.count - 1;
+ if (this.count < 0)
+ return;
+
+ if (this.count != 0)
+ {
+ if (activator.classtype == CT_PLAYER &&
+ (this.spawnflags &
+ TRIGGER_COUNTER_NOMESSAGE) == 0)
+ {
+ if (this.count >= 4)
+ centerprint (activator,
+ "There are more to go...");
+ else if (this.count == 3)
+ centerprint (activator,
+ "Only 3 more to go...");
+ else if (this.count == 2)
+ centerprint (activator,
+ "Only 2 more to go...");
+ else
+ centerprint (activator,
+ "Only 1 more to go...");
+ }
+ return;
+ }

- self.wait = -1;
+ if (activator.classtype == CT_PLAYER &&
+ (this.spawnflags & TRIGGER_COUNTER_NOMESSAGE) == 0)
+ {
+ centerprint (activator, "Sequence completed!");
+ }
+
+ this.enemy = activator;
+ this.multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_counter =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- if (!self.count)
- self.count = 2;
+ this.classname = "trigger_counter";
+ this.classtype = CT_TRIGGER_COUNTER;
+ this.use = this.counter_use;
+ this.wait = -1;

- self.use = counter_use;
+ if (!this.count)
+ this.count = 2;
+ };
};

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

Diff qc/triggers/cvarset.qc

diff --git a/qc/triggers/cvarset.qc b/qc/triggers/cvarset.qc
new file mode 100644
index 0000000..69e4335
--- /dev/null
+++ b/qc/triggers/cvarset.qc
@@ -0,0 +1,56 @@
+//==============================================================================
+// trigger_cvarset -- Drake version -- dumptruck_ds
+//==============================================================================
+
+/*QUAKED trigger_cvarset (.5 .5 .5) (-8 -8 -8) (8 8 32)
+You can set any CVAR on the server with this trigger. Put the CVAR name
+in "netname" and put the value in "message". Useful CVAR's are
+sv_gravity, sv_friction, fov, and v_idlescale.
+*/
+class trigger_cvarset: base_trigger
+{
+ //--------------------------------------------------------------
+ virtual void() change_cvar =
+ {
+ local entity check;
+
+ cvar_set (this.netname, this.message);
+ bprint ("\n\n\n\n");
+
+ this.classname = "cvar_done";
+ check = findfloat (world, ::classtype, CT_PLAYER);
+ if (!check)
+ check = find (world, ::classname, "camera");
+
+ check.ideal_yaw = -1;
+
+ this.nextthink = time + 0.02;
+ this.think = SUB_UseTargets;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() cvarset_touch =
+ {
+ if (this.cnt > time || other.health <= 0 ||
+ other.classtype != CT_PLAYER)
+ {
+ return;
+ }
+
+ this.change_cvar ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_cvarset =
+ {
+ if (deathmatch || coop)
+ remove (this);
+
+ this.classname = "trigger_cvarset";
+ this.classtype = CT_TRIGGER_CVARSET;
+ init_trigger ();
+ // touch wasn't enabled in the original trigger_cvarset -- CEV
+ // this.touch = this.cvarset_touch;
+ this.use = this.change_cvar;
+ };
+};

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

Diff qc/triggers/everything.qc

diff --git a/qc/triggers/everything.qc b/qc/triggers/everything.qc
new file mode 100644
index 0000000..a8ed360
--- /dev/null
+++ b/qc/triggers/everything.qc
@@ -0,0 +1,38 @@
+//==============================================================================
+// trigger_everything
+//==============================================================================
+
+//------------------------------------------------------------------------------
+// trigger_everything
+//------------------------------------------------------------------------------
+class trigger_everything: base_trigger
+{
+ //--------------------------------------------------------------
+ virtual void() everything_touch =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ if (time < this.attack_finished)
+ return;
+
+ activator = other;
+
+ SUB_UseSpecificTarget (this.target, ::targetname);
+
+ if (this.wait)
+ if (!(this.spawnflags & 1))
+ this.attack_finished = time + this.wait;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_everything =
+ {
+ init_trigger ();
+
+ this.classname = "trigger_everything";
+ this.classtype = CT_TRIGGER_EVERYTHING;
+ this.touch = this.everything_touch;
+ SUB_CheckWaiting ();
+ };
+};

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

Diff qc/triggers/filter.qc

diff --git a/qc/triggers/filter.qc b/qc/triggers/filter.qc
index f008c1f..0616af8 100644
--- a/qc/triggers/filter.qc
+++ b/qc/triggers/filter.qc
@@ -2,6 +2,7 @@
// trigger_filter
//==============================================================================

+// constants
const float FILTER_FIELD_STATE = 0;
const float FILTER_FIELD_HEALTH = 1;
const float FILTER_FIELD_WEAPON = 2;
@@ -27,200 +28,209 @@ const float FILTER_OP_GTE = 4;
const float FILTER_OP_BITMASK_AND = 5;
const float FILTER_OP_BITMASK_OR = 6;

-void() trigger_filter_use =
+//------------------------------------------------------------------------------
+// TODO CEV: this needs comments
+//------------------------------------------------------------------------------
+class trigger_filter: base_trigger
{
- self.state = 0;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- entity targ;
- float fieldtype, op, result, targfloat;
- string targstring;
-
- targfloat = fieldtype = op = result = 0;
- targstring = "";
-
- if (self.include != "")
+ //--------------------------------------------------------------
+ virtual void() filter_use =
{
- targ = find (world, targetname, self.include);
- if (!targ)
- targ = find (world, targetname2, self.include);
- if (!targ)
+ this.state = 0;
+
+ if (this.estate != STATE_ACTIVE)
return;
- }
- else
- {
- targ = activator;
- }

- op = self.weapon;
+ entity targ;
+ float fieldtype, op, result, targfloat;
+ string targstring;

- switch (self.style)
- {
- case FILTER_FIELD_STATE:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.state;
- break;
-
- case FILTER_FIELD_ESTATE:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.estate;
- break;
-
- case FILTER_FIELD_HEALTH:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.health;
- break;
-
- case FILTER_FIELD_COUNT:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.count;
- break;
-
- case FILTER_FIELD_CNT:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.cnt;
- break;
-
- case FILTER_FIELD_WEAPON:
- fieldtype = FILTER_FIELDTYPE_FLOAT;
- targfloat = targ.weapon;
- break;
-
- case FILTER_FIELD_FLAGS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.flags;
- break;
-
- case FILTER_FIELD_SPAWNFLAGS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.spawnflags;
- break;
-
- case FILTER_FIELD_ITEMS:
- fieldtype = FILTER_FIELDTYPE_FLAG;
- targfloat = targ.items;
- break;
-
- case FILTER_FIELD_CLASSNAME:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.classname;
- break;
-
- case FILTER_FIELD_TARGETNAME:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.targetname;
- break;
-
- case FILTER_FIELD_TYPE:
- fieldtype = FILTER_FIELDTYPE_STRING;
- targstring = targ.type;
- break;
- }
-
- if (fieldtype == FILTER_FIELDTYPE_FLOAT)
- {
- if (op == FILTER_OP_EQUALS)
- {
- if (targfloat == self.count)
- result = 1;
- }
- else if (op == FILTER_OP_LT)
- {
- if (targfloat < self.count)
- result = 1;
- }
- else if (op == FILTER_OP_LTE)
- {
- if (targfloat <= self.count)
- result = 1;
- }
- else if (op == FILTER_OP_GT)
- {
- if (targfloat > self.count)
- result = 1;
- }
- else if (op == FILTER_OP_GTE)
+ targfloat = fieldtype = op = result = 0;
+ targstring = "";
+
+ if (this.include != "")
{
- if (targfloat >= self.count)
- result = 1;
+ targ = find (world, ::targetname, this.include);
+ if (!targ)
+ targ = find (world, ::targetname2,
+ this.include);
+ if (!targ)
+ return;
}
- else if (op == FILTER_OP_BITMASK_AND)
- {
- if (targfloat & self.count)
- result = 1;
- }
- else if (op == FILTER_OP_BITMASK_OR)
+ else
{
- if (targfloat | self.count)
- result = 1;
+ targ = activator;
}
- else
+
+ op = this.weapon;
+
+ switch (this.style)
{
- if (targfloat == self.count)
- result = 1;
+ case FILTER_FIELD_STATE:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.state;
+ break;
+
+ case FILTER_FIELD_ESTATE:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.estate;
+ break;
+
+ case FILTER_FIELD_HEALTH:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.health;
+ break;
+
+ case FILTER_FIELD_COUNT:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.count;
+ break;
+
+ case FILTER_FIELD_CNT:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.cnt;
+ break;
+
+ case FILTER_FIELD_WEAPON:
+ fieldtype = FILTER_FIELDTYPE_FLOAT;
+ targfloat = targ.weapon;
+ break;
+
+ case FILTER_FIELD_FLAGS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.flags;
+ break;
+
+ case FILTER_FIELD_SPAWNFLAGS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.spawnflags;
+ break;
+
+ case FILTER_FIELD_ITEMS:
+ fieldtype = FILTER_FIELDTYPE_FLAG;
+ targfloat = targ.items;
+ break;
+
+ case FILTER_FIELD_CLASSNAME:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.classname;
+ break;
+
+ case FILTER_FIELD_TARGETNAME:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.targetname;
+ break;
+
+ case FILTER_FIELD_TYPE:
+ fieldtype = FILTER_FIELDTYPE_STRING;
+ targstring = targ.type;
+ break;
}
- }
- else if (fieldtype == FILTER_FIELDTYPE_FLAG)
- {
- if (op == FILTER_OP_EQUALS)
+
+ if (fieldtype == FILTER_FIELDTYPE_FLOAT)
{
- if (targfloat == self.aflag)
- result = 1;
+ if (op == FILTER_OP_EQUALS)
+ {
+ if (targfloat == this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_LT)
+ {
+ if (targfloat < this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_LTE)
+ {
+ if (targfloat <= this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_GT)
+ {
+ if (targfloat > this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_GTE)
+ {
+ if (targfloat >= this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_BITMASK_AND)
+ {
+ if (targfloat & this.count)
+ result = 1;
+ }
+ else if (op == FILTER_OP_BITMASK_OR)
+ {
+ if (targfloat | this.count)
+ result = 1;
+ }
+ else
+ {
+ if (targfloat == this.count)
+ result = 1;
+ }
}
- else if (op == FILTER_OP_BITMASK_AND)
+ else if (fieldtype == FILTER_FIELDTYPE_FLAG)
{
- if (targfloat & self.aflag)
- result = 1;
+ if (op == FILTER_OP_EQUALS)
+ {
+ if (targfloat == this.aflag)
+ result = 1;
+ }
+ else if (op == FILTER_OP_BITMASK_AND)
+ {
+ if (targfloat & this.aflag)
+ result = 1;
+ }
+ else if (op == FILTER_OP_BITMASK_OR)
+ {
+ if (targfloat | this.aflag)
+ result = 1;
+ }
+ else
+ {
+ if (targfloat == this.aflag)
+ result = 1;
+ }
}
- else if (op == FILTER_OP_BITMASK_OR)
+ else if (fieldtype == FILTER_FIELDTYPE_STRING)
{
- if (targfloat | self.aflag)
+ if (targstring == this.type)
result = 1;
}
else
{
- if (targfloat == self.aflag)
- result = 1;
+ objerror ("invalid fieldtype");
+ return;
}
- }
- else if (fieldtype == FILTER_FIELDTYPE_STRING)
- {

- if (targstring == self.type)
- result = 1;
- }
- else
- {
- objerror ("invalid fieldtype");
- return;
- }
+ if (this.spawnflags & 1)
+ // negate
+ result = 1 - result;

- if (self.spawnflags & 1)
- // negate
- result = 1 - result;
+ if (result)
+ {
+ this.state = 1;

- if (result)
- {
- self.state = 1;
+ // relay activator as owner
+ if (this.spawnflags & 2 && activator.owner)
+ activator = activator.owner;

- // relay activator as owner
- if (self.spawnflags & 2 && activator.owner)
- activator = activator.owner;
+ SUB_UseTargets ();

- SUB_UseTargets ();
- if (other.classname == "trigger_everything" &&
- other.spawnflags & 1)
- {
- if (other.wait)
+ if (other.classtype == CT_TRIGGER_EVERYTHING &&
+ other.spawnflags & 1 && other.wait)
+ {
other.attack_finished = time + other.wait;
+ }
}
+ };

- }
-};
-
-void() trigger_filter = {
- self.use = trigger_filter_use;
-
+ //--------------------------------------------------------------
+ void() trigger_filter =
+ {
+ this.classname = "trigger_filter";
+ this.classtype = CT_TRIGGER_FILTER;
+ this.use = this.filter_use;
+ };
};

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

Diff qc/triggers/fog.qc

diff --git a/qc/triggers/fog.qc b/qc/triggers/fog.qc
index a1c7979..0fed77d 100644
--- a/qc/triggers/fog.qc
+++ b/qc/triggers/fog.qc
@@ -18,12 +18,19 @@
// constants
const float FOG_INTERVAL = 0.04166667; // 1/24;

+const float FOGBLEND_ONEWAY = 1;
+const float FOGBLEND_REVERSE = 2;
+const float FOGBLEND_ALLCLIENTS = 4;
+const float FOGBLEND_BLENDTO = 8;
+
+//==============================================================================
+
//----------------------------------------------------------------------
// fog_save
//----------------------------------------------------------------------
void(entity client, float density, vector color) fog_save =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

// save whatever we set the client's fog to in case of saves/loads
@@ -34,7 +41,7 @@ void(entity client, float density, vector color) fog_save =
//----------------------------------------------------------------------
void(entity client) fog_save_to_previous =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

// copies the current fog to the secondary fields to transition
@@ -46,7 +53,7 @@ void(entity client) fog_save_to_previous =
//----------------------------------------------------------------------
void(entity client, float density) skyfog_save =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

client.skyfog_density = density;
@@ -55,7 +62,7 @@ void(entity client, float density) skyfog_save =
//----------------------------------------------------------------------
void(entity client) skyfog_save_to_previous =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

client.skyfog_density2 = client.skyfog_density;
@@ -97,7 +104,7 @@ void(entity client, entity fogger) fog_setFromEnt =
//----------------------------------------------------------------------
void(entity client, float density, vector color) fog_set =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

// dprint9 ("Setting fog: ", ftos(density), " ", ftos(color_x),
@@ -119,7 +126,7 @@ void(entity client, float density, vector color) fog_set =
//----------------------------------------------------------------------
void(entity client, float density) skyfog_set =
{
- if (client.classname != "player")
+ if (client.classtype != CT_PLAYER)
return;

// dprint3 ("Setting skyfog: ", ftos(density), "\n");
@@ -131,327 +138,159 @@ void(entity client, float density) skyfog_set =
skyfog_save (client, density);
};

-//----------------------------------------------------------------------
-// fog_blendTouch
-//----------------------------------------------------------------------
-void() fog_blendTouch =
+//------------------------------------------------------------------------------
+class base_fog_controller: entity
{
- if (other.classname != "player")
- return;
+ float speed2;

- if (other.health <= 0)
- return;
+ //--------------------------------------------------------------
+ virtual void(entity cl, float sTo, float f) skyfog_blendSetFraction =
+ {
+ local float s;

- if (self.estate != STATE_ACTIVE)
- return;
+ s = lerpHermite (cl.skyfog_density2, sTo, f);

- // fix for only first client getting a fog change when
- // multiple coop clients are touching this at once
- if (time != self.rad_time) // because fog is rad
- if (time < self.attack_finished)
- return;
+ // eprint (cl);
+ // dprint3 ("Fraction skyfog density: ", ftos(s), "\n");

- local float f, lerp_density, leaving;
- local float lerp_sdensity;
- local float ent_density, ent_density2, ent_sdensity, ent_sdensity2;
- local vector dorg, mid, ovel;
- local vector lerp_color;
-
- ent_density = zeroconvert (self.fog_density);
- ent_density2 = zeroconvert (self.fog_density2);
-
- ent_sdensity = zeroconvert (self.skyfog_density);
- ent_sdensity2 = zeroconvert (self.skyfog_density2);
-
- // if you run/fall through a fogblend fast enough you can come
- // out the other side partially blended, so check if player will
- // exit the trigger bounds before the next touch (same class of
- // bug as leaping through lasers in Q2)
- ovel = other.velocity * FOG_INTERVAL;
- leaving = ((other.absmax_x + ovel_x < self.absmin_x) ||
- (other.absmax_y + ovel_y < self.absmin_y) ||
- (other.absmax_z + ovel_z < self.absmin_z) ||
- (other.absmin_x + ovel_x > self.absmax_x) ||
- (other.absmin_y + ovel_y > self.absmax_y) ||
- (other.absmin_z + ovel_z > self.absmax_z));
-
- if (leaving)
+ skyfog_set (cl, s);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity cl, vector cTo, float dTo, float f)
+ fog_blendSetFraction =
+ {
+ local float d;
+ local vector c;
+
+ d = lerpHermite (cl.fog_density2, dTo, f);
+ c = lerpVectorHermite (cl.fog_color2, cTo, f);
+
+ /*
+ eprint (cl);
+ dprint3 ("fog density: ", ftos(d), "\n");
+ dprint3 ("color: ", vtos(c), "\n");
+ dprint3 ("fraction: ", ftos(f), "\n");
+ */
+
+ fog_set (cl, d, c);
+ };
+
+ //--------------------------------------------------------------
+ // fog_blendTimeThink -- used by both trigger_fog and target_fogblend
+ //--------------------------------------------------------------
+ virtual void() fog_blendTimeThink =
{
- // last chance to set fog correctly, so snap it to the
- // final values
- leaving = other.velocity * self.movedir;
- if (leaving > 0)
+ local float f;
+ local float dTo, sTo;
+ local vector cTo;
+
+ if (time >= this.pain_finished)
{
- lerp_density = ent_density2;
- lerp_color = self.fog_color2;
- lerp_sdensity = ent_sdensity2;
+ f = 1;
}
else
{
- lerp_density = ent_density;
- lerp_color = self.fog_color;
- lerp_sdensity = ent_sdensity;
+ this.nextthink = time + FOG_INTERVAL;
+ if (this.state && this.speed)
+ f = 1 - (this.pain_finished - time) /
+ this.speed;
+ else if (this.speed2)
+ f = 1 - (this.pain_finished - time) /
+ this.speed2;
+ else
+ f = 1;
}
- }
- else
- {
- // in transition, blend proportionally between the two fogs
- mid = (self.mins + self.maxs) * 0.5;
- dorg = other.origin + other.view_ofs - mid;
-
- f = dorg * self.movedir;
- f = (f / self.distance) + 0.5;
-
- lerp_density = lerp (ent_density, ent_density2, f);
- lerp_color = lerpVector (self.fog_color, self.fog_color2, f);
- lerp_sdensity = lerp (ent_sdensity, ent_sdensity2, f);
- }
-
- if (self.fog_density || self.fog_density2)
- fog_set (other, lerp_density, lerp_color);
- if (self.skyfog_density || self.skyfog_density2)
- skyfog_set (other, lerp_sdensity);
-
- self.rad_time = time;
- self.attack_finished = time + FOG_INTERVAL;
-
- // reset client's fogblend_entity in case it's currently being
- // transitioned by another entity
- other.fogblend_entity = world;
-};
-
-/*QUAKED trigger_fogblend (.5 .5 .2) ?
-Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between "fog_color"/"fog_density" and "fog_color2"/"fog_density2" proportional to their position within the trigger.
-The axis of motion on which the blend happens is defined by "angle", pointing to whatever zone has color2 and density2. Trigger therefore has two 'sides' - the side that "angle" points to, and the opposite side.
-
-"distance" - override the length of the blend period in world units - defaults to bounds size
- on 'angle' otherwise. this is only useful for diagonal triggers.
-
-CAVEATS:
-- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
-*/
-/*FGD
-@SolidClass base(Appearflags, Targetname, Target, FogShift) = trigger_fogblend :
-"Trigger: Fog Blend
-Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between start and end values proportional to their position within the trigger.
-
-- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
-- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
-[
- distance(integer) : "Length of blend distance (defaults to size of trigger)"
- angle(integer) : "Axis of motion of blend (points toward end values)"
-]
-*/
-void() trigger_fogblend =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;

- // InitTrigger assumes angle 0 means no angle
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
-
- InitTrigger ();
- self.touch = fog_blendTouch;
- self.distance = zeroconvertdefault (self.distance,
- BoundsAngleSize(self.movedir, self.size));
-
- SUB_CheckWaiting ();
-};
-
-//======================================================================
-// fog_blendTimeThink -- used by both trigger_fog and target_fogblend
-//======================================================================
-
-// constants
-const float FOGBLEND_ONEWAY = 1;
-const float FOGBLEND_REVERSE = 2;
-const float FOGBLEND_ALLCLIENTS = 4;
-const float FOGBLEND_BLENDTO = 8;
-
-//----------------------------------------------------------------------
-void(entity cl, float sTo, float f) skyfog_blendSetFraction =
-{
- local float s;
-
- s = lerpHermite (cl.skyfog_density2, sTo, f);
-
- // eprint (cl);
- // dprint3 ("Fraction skyfog density: ", ftos(s), "\n");
-
- skyfog_set (cl, s);
-};
-
-//----------------------------------------------------------------------
-void(entity cl, vector cTo, float dTo, float f) fog_blendSetFraction =
-{
- local float d;
- local vector c;
-
- d = lerpHermite (cl.fog_density2, dTo, f);
- c = lerpVectorHermite (cl.fog_color2, cTo, f);
-
- /*
- eprint (cl);
- dprint3 ("fog density: ", ftos(d), "\n");
- dprint3 ("color: ", vtos(c), "\n");
- dprint3 ("fraction: ", ftos(f), "\n");
- */
-
- fog_set (cl, d, c);
-};
-
-//----------------------------------------------------------------------
-void() fog_blendTimeThink =
-{
- local float f;
- local float dTo, sTo;
- local vector cTo;
-
- if (time >= self.pain_finished)
- {
- f = 1;
- }
- else
- {
- self.nextthink = time + FOG_INTERVAL;
- if (self.state && self.speed)
- f = 1 - (self.pain_finished - time) / self.speed;
- else if (self.speed2)
- f = 1 - (self.pain_finished - time) / self.speed2;
+ if (this.state)
+ {
+ dTo = this.fog_density2;
+ cTo = this.fog_color2;
+ sTo = this.skyfog_density2;
+ }
else
- f = 1;
- }
+ {
+ dTo = this.fog_density;
+ cTo = this.fog_color;
+ sTo = this.skyfog_density;
+ }

- if (self.state)
- {
- dTo = self.fog_density2;
- cTo = self.fog_color2;
- sTo = self.skyfog_density2;
- }
- else
- {
- dTo = self.fog_density;
- cTo = self.fog_color;
- sTo = self.skyfog_density;
- }
+ if (this.spawnflags & FOGBLEND_ALLCLIENTS)
+ {
+ entity pl;
+ pl = nextent (world);
+ while (pl.flags & FL_CLIENT)
+ {
+ if (pl.fogblend_entity == this)
+ {
+ if (dTo && !(pl.fog_density2 == dTo &&
+ pl.fog_color2 == cTo))
+ {
+ fog_blendSetFraction (pl, cTo,
+ zeroconvert(dTo), f);
+ }
+
+ if (sTo)
+ {
+ skyfog_blendSetFraction (pl,
+ zeroconvert(sTo), f);
+ }
+
+ if (time >= this.pain_finished)
+ {
+ pl.fogblend_entity = world;
+ }
+ }

- if (self.spawnflags & FOGBLEND_ALLCLIENTS)
- {
- entity pl;
- pl = nextent (world);
- while (pl.flags & FL_CLIENT)
+ pl = nextent (pl);
+ }
+ }
+ else
{
- if (pl.fogblend_entity == self)
+ if (this.enemy.fogblend_entity == this)
{
- if (dTo && !(pl.fog_density2 == dTo &&
- pl.fog_color2 == cTo))
+ if (dTo && !(this.enemy.fog_density2 == dTo &&
+ this.enemy.fog_color2 == cTo))
{
- fog_blendSetFraction (pl, cTo,
+ fog_blendSetFraction (this.enemy, cTo,
zeroconvert(dTo), f);
}

if (sTo)
{
- skyfog_blendSetFraction (pl,
+ skyfog_blendSetFraction (this.enemy,
zeroconvert(sTo), f);
}

- if (time >= self.pain_finished)
+ if (time >= this.pain_finished)
{
- pl.fogblend_entity = world;
+ this.enemy.fogblend_entity = world;
}
}
-
- pl = nextent (pl);
}
- }
- else
- {
- if (self.enemy.fogblend_entity == self)
- {
- if (dTo && !(self.enemy.fog_density2 == dTo &&
- self.enemy.fog_color2 == cTo))
- {
- fog_blendSetFraction (self.enemy, cTo,
- zeroconvert(dTo), f);
- }
-
- if (sTo)
- {
- skyfog_blendSetFraction (self.enemy,
- zeroconvert(sTo), f);
- }

- if (time >= self.pain_finished)
+ if (this.classtype == CT_TEMP_FOG_CONTROLLER)
+ {
+ if (this.enemy.fogblend_entity != this ||
+ time >= this.pain_finished)
{
- self.enemy.fogblend_entity = world;
-
+ remove (this);
+ return;
}
}
- }
-
- if (self.classname == "fog_controller")
- {
- if (self.enemy.fogblend_entity != self ||
- time >= self.pain_finished)
- {
- remove (self);
- return;
- }
- }
+ };
};

-//======================================================================
-// target_fogblend
-//======================================================================
-
-//----------------------------------------------------------------------
-void() target_fogblend_use =
+//------------------------------------------------------------------------------
+class temp_fog_controller: base_fog_controller
{
-
- self.enemy = activator;
- if (self.enemy.classname != "player")
- return;
-
- if (!(self.spawnflags & FOGBLEND_ONEWAY))
- self.state = 1 - self.state;
-
- if (self.state)
- self.pain_finished = time + self.delay + self.speed;
- else
- self.pain_finished = time + self.delay + self.speed2;
-
-
- if (self.spawnflags & FOGBLEND_ALLCLIENTS)
- {
- entity pl;
- pl = nextent (world);
- while (pl.flags & FL_CLIENT)
- {
- if (self.fog_density)
- fog_save_to_previous (pl);
- if (self.skyfog_density)
- skyfog_save_to_previous (pl);
-
- pl.fogblend_entity = self;
-
- pl = nextent(pl);
- }
- }
- else
+ //--------------------------------------------------------------
+ void() temp_fog_controller =
{
- if (self.fog_density)
- fog_save_to_previous (self.enemy);
- if (self.skyfog_density)
- skyfog_save_to_previous (self.enemy);
-
- self.enemy.fogblend_entity = self;
- }
-
- self.nextthink = time + self.delay;
+ this.classname = "temp_fog_controller";
+ this.classtype = CT_TEMP_FOG_CONTROLLER;
+ this.think = this.fog_blendTimeThink;
+ };
};

/*QUAKED target_fogblend (.5 .5 .2) (-8 -8 -8) (8 8 8) ONE_WAY REVERSE GLOBAL BLENDTO
@@ -486,85 +325,227 @@ Activator's fog will be blended over time from start to end values.
speed2(string) : "Time to blend back, if different (-1 for instant)"
]
*/
-void() target_fogblend =
+class target_fogblend: base_fog_controller
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() fogblend_use =
+ {
+ this.enemy = activator;
+ if (this.enemy.classtype != CT_PLAYER)
+ return;
+
+ if (!(this.spawnflags & FOGBLEND_ONEWAY))
+ this.state = 1 - this.state;
+
+ if (this.state)
+ this.pain_finished = time + this.delay + this.speed;
+ else
+ this.pain_finished = time + this.delay + this.speed2;
+
+ if (this.spawnflags & FOGBLEND_ALLCLIENTS)
+ {
+ entity pl;
+ pl = nextent (world);
+ while (pl.flags & FL_CLIENT)
+ {
+ if (this.fog_density)
+ fog_save_to_previous (pl);
+ if (this.skyfog_density)
+ skyfog_save_to_previous (pl);
+
+ pl.fogblend_entity = this;
+
+ pl = nextent(pl);
+ }
+ }
+ else
+ {
+ if (this.fog_density)
+ fog_save_to_previous (this.enemy);
+ if (this.skyfog_density)
+ skyfog_save_to_previous (this.enemy);
+
+ this.enemy.fogblend_entity = this;
+ }
+
+ this.nextthink = time + this.delay;
+ };

- if (!self.fog_density && !self.skyfog_density)
+ //--------------------------------------------------------------
+ void() target_fogblend =
{
- objerror ("Neither fog density nor skyfog density set");
- return;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!this.fog_density && !this.skyfog_density)
+ {
+ objerror ("Neither fog density nor skyfog density set");
+ return;
+ }

- self.use = target_fogblend_use;
- self.think = fog_blendTimeThink;
+ this.classname = "target_fogblend";
+ this.classtype = CT_TARGET_FOGBLEND;
+ this.use = this.fogblend_use;
+ this.think = this.fog_blendTimeThink;

- if (self.spawnflags & FOGBLEND_REVERSE)
- self.state = 1;
- else
- self.state = 0;
+ if (this.spawnflags & FOGBLEND_REVERSE)
+ this.state = 1;
+ else
+ this.state = 0;

- if (self.spawnflags & FOGBLEND_ONEWAY)
- self.state = 1 - self.state;
+ if (this.spawnflags & FOGBLEND_ONEWAY)
+ this.state = 1 - this.state;

- if (!self.speed)
- self.speed = 1;
- if (!self.speed2)
- self.speed2 = self.speed;
+ if (!this.speed)
+ this.speed = 1;
+ if (!this.speed2)
+ this.speed2 = this.speed;

- if (self.speed == -1)
- self.speed = 0;
- if (self.speed2 == -1)
- self.speed2 = 0;
+ if (this.speed == -1)
+ this.speed = 0;
+ if (this.speed2 == -1)
+ this.speed2 = 0;
+ };
};

-//======================================================================
-// trigger_fog
-//======================================================================
+/*QUAKED trigger_fogblend (.5 .5 .2) ?
+Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between "fog_color"/"fog_density" and "fog_color2"/"fog_density2" proportional to their position within the trigger.
+The axis of motion on which the blend happens is defined by "angle", pointing to whatever zone has color2 and density2. Trigger therefore has two 'sides' - the side that "angle" points to, and the opposite side.

-//----------------------------------------------------------------------
-void() trigger_fog_touch =
+"distance" - override the length of the blend period in world units - defaults to bounds size
+ on 'angle' otherwise. this is only useful for diagonal triggers.
+
+CAVEATS:
+- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
+*/
+/*FGD
+@SolidClass base(Appearflags, Targetname, Target, FogShift) = trigger_fogblend :
+"Trigger: Fog Blend
+Acts as a smoothly blending portal between two zones of different fog. Sets the fog for any client passing through it, blending their global fog settings between start and end values proportional to their position within the trigger.
+
+- will 'stuffcmd' 2 dozen times per frame so try not to make these huge
+- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering."
+[
+ distance(integer) : "Length of blend distance (defaults to size of trigger)"
+ angle(integer) : "Axis of motion of blend (points toward end values)"
+]
+*/
+class trigger_fogblend: base_trigger
{
- if (self.estate != STATE_ACTIVE)
- return;
+ //--------------------------------------------------------------
+ // fog_blendTouch
+ //--------------------------------------------------------------
+ virtual void() fog_blendTouch =
+ {
+ if (other.classtype != CT_PLAYER)
+ return;

- if (!(other.flags & FL_CLIENT))
- return;
+ if (other.health <= 0)
+ return;

- // fog already set to this value
- if (other.fog_color == self.fog_color &&
- other.fog_density == self.fog_density)
- return;
+ if (this.estate != STATE_ACTIVE)
+ return;

- // transition already occurring from this trigger
- if (other.fogblend_entity.owner == self)
- return;
+ // fix for only first client getting a fog change when
+ // multiple coop clients are touching this at once
+ if (time != this.rad_time) // because fog is rad
+ if (time < this.attack_finished)
+ return;
+
+ local float f, lerp_density, leaving;
+ local float lerp_sdensity;
+ local float ent_density, ent_density2;
+ local float ent_sdensity, ent_sdensity2;
+ local vector dorg, mid, ovel;
+ local vector lerp_color;
+
+ ent_density = zeroconvert (this.fog_density);
+ ent_density2 = zeroconvert (this.fog_density2);
+
+ ent_sdensity = zeroconvert (this.skyfog_density);
+ ent_sdensity2 = zeroconvert (this.skyfog_density2);
+
+ // if you run/fall through a fogblend fast enough you can come
+ // out the other side partially blended, so check if player will
+ // exit the trigger bounds before the next touch (same class of
+ // bug as leaping through lasers in Q2)
+ ovel = other.velocity * FOG_INTERVAL;
+ leaving = ((other.absmax_x + ovel_x < this.absmin_x) ||
+ (other.absmax_y + ovel_y < this.absmin_y) ||
+ (other.absmax_z + ovel_z < this.absmin_z) ||
+ (other.absmin_x + ovel_x > this.absmax_x) ||
+ (other.absmin_y + ovel_y > this.absmax_y) ||
+ (other.absmin_z + ovel_z > this.absmax_z));
+
+ if (leaving)
+ {
+ // last chance to set fog correctly, so snap it to the
+ // final values
+ leaving = other.velocity * this.movedir;
+ if (leaving > 0)
+ {
+ lerp_density = ent_density2;
+ lerp_color = this.fog_color2;
+ lerp_sdensity = ent_sdensity2;
+ }
+ else
+ {
+ lerp_density = ent_density;
+ lerp_color = this.fog_color;
+ lerp_sdensity = ent_sdensity;
+ }
+ }
+ else
+ {
+ // in transition, blend proportionally between
+ // the two fogs
+ mid = (this.mins + this.maxs) * 0.5;
+ dorg = other.origin + other.view_ofs - mid;
+
+ f = dorg * this.movedir;
+ f = (f / this.distance) + 0.5;
+
+ lerp_density = lerp (ent_density, ent_density2, f);
+ lerp_color = lerpVector (this.fog_color,
+ this.fog_color2, f);
+ lerp_sdensity = lerp (ent_sdensity, ent_sdensity2, f);
+ }
+
+ if (this.fog_density || this.fog_density2)
+ fog_set (other, lerp_density, lerp_color);
+ if (this.skyfog_density || this.skyfog_density2)
+ skyfog_set (other, lerp_sdensity);

- if (self.fog_density)
- fog_save_to_previous (other);
- if (self.skyfog_density)
- skyfog_save_to_previous (other);
+ this.rad_time = time;
+ this.attack_finished = time + FOG_INTERVAL;

- // spawn a temp entity to control the transition for this client
- entity controller;
+ // reset client's fogblend_entity in case it's currently being
+ // transitioned by another entity
+ other.fogblend_entity = world;
+ };

- controller = spawn ();
- controller.classname = "fog_controller";
- controller.owner = self;
- controller.enemy = other;
- controller.speed2 = self.speed; // speed2 is used when state is 0
- controller.fog_color = self.fog_color;
- controller.fog_density = self.fog_density;
- controller.skyfog_density = self.skyfog_density;
+ //--------------------------------------------------------------
+ void() trigger_fogblend =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- controller.pain_finished = time + self.delay + self.speed;
+ // InitTrigger (now init_trigger) assumes angle 0 means no angle
+ if (this.angles == '0 0 0')
+ this.angles = '0 360 0';

- controller.think = fog_blendTimeThink;
- controller.nextthink = time + controller.delay;
+ this.classname = "trigger_fogblend";
+ this.classtype = CT_TRIGGER_FOGBLEND;
+ init_trigger ();
+ this.touch = this.fog_blendTouch;
+ this.distance = zeroconvertdefault (this.distance,
+ BoundsAngleSize(this.movedir, this.size));

- other.fogblend_entity = controller;
+ SUB_CheckWaiting ();
+ };
};

/*QUAKED trigger_fog (.5 .5 .2) ?
@@ -577,22 +558,68 @@ CAVEATS:
- will 'stuffcmd' 2 dozen times per second so try not to make these huge
- a bug in most quake engine ports will reset the eye position smoothing that happens when climbing stairs or riding a plat on every frame that a 'stuffcmd' is sent, so fog transitions during upwards motion will cause noticeable stuttering.
*/
-void() trigger_fog =
+class trigger_fog: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() fog_touch =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

- if (!self.fog_density && !self.skyfog_density)
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+ // fog already set to this value
+ if (other.fog_color == this.fog_color &&
+ other.fog_density == this.fog_density)
+ return;
+
+ // transition already occurring from this trigger
+ if (other.fogblend_entity.owner == this)
+ return;
+
+ if (this.fog_density)
+ fog_save_to_previous (other);
+ if (this.skyfog_density)
+ skyfog_save_to_previous (other);
+
+ // spawn a temp entity to control the transition for this client
+ temp_fog_controller controller;
+
+ // TODO CEV
+ controller = spawn (temp_fog_controller,
+ owner:this,
+ enemy:other,
+ // speed2 is used when state is 0
+ speed2: this.speed,
+ fog_color: this.fog_color,
+ fog_density: this.fog_density,
+ skyfog_density: this.skyfog_density,
+ pain_finished: time + this.delay + this.speed);
+ controller.nextthink = time + controller.delay;
+ other.fogblend_entity = controller;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_fog =
{
- objerror ("Neither fog density nor skyfog density set");
- return;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ if (!this.fog_density && !this.skyfog_density)
+ {
+ objerror ("Neither fog density nor skyfog density set");
+ return;
+ }

- InitTrigger ();
- self.touch = trigger_fog_touch;
- if (!self.speed)
- self.speed = 1;
+ this.classname = "trigger_fog";
+ this.classtype = CT_TRIGGER_FOG;
+ init_trigger ();
+ this.touch = this.fog_touch;
+ if (!this.speed)
+ this.speed = 1;

- SUB_CheckWaiting ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/heal.qc

diff --git a/qc/triggers/heal.qc b/qc/triggers/heal.qc
index 4e60b69..247be3e 100644
--- a/qc/triggers/heal.qc
+++ b/qc/triggers/heal.qc
@@ -1,129 +1,18 @@
//==============================================================================
-// HEAL TRIGGER
-//==============================================================================
-
-// from custents, modified by dumptruck_ds
+// trigger_heal -- from custents, modified by dumptruck_ds
// Original entity submitted by Jan Martin Mathiassen, aka. TGR
-
// was in dtmisc.qc -- CEV
+//==============================================================================

-// fields for healing trigger
+// entity fields
.float heal_timer;
-.float heal_amount;
-.float health_max;

// Constants for the healing trigger
-float HEAL_START_ON = 1;
-float HEAL_PLAYER_ONLY = 2;
-float HEAL_MONSTER_ONLY = 4;
-
-//----------------------------------------------------------------------
-void() heal_think =
-{
- if (self.cnt == self.count)
- {
- dprint ("trigger_heal think: full\n");
- self.think = SUB_Null;
- return;
- }
-
- local float recharge_amount = self.speed;
-
- if (self.count < (self.cnt + self.speed))
- recharge_amount = self.count - self.cnt;
-
- dprint ("trigger_heal think: [max: ");
- dprint (ftos(self.count));
- dprint (", current: ");
- dprint (ftos(self.cnt));
- dprint (", recharging: ");
- dprint (ftos(recharge_amount));
- dprint ("]\n");
-
- self.cnt = self.cnt + recharge_amount;
- self.nextthink = time + self.delay;
-};
-
-//----------------------------------------------------------------------
-void() heal_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
- if (self.spawnflags & HEAL_PLAYER_ONLY && other.classname != "player")
- return;
- if (self.spawnflags & HEAL_MONSTER_ONLY && !(other.flags & FL_MONSTER))
- return;
- if (other.classname != "player" && !(other.flags & FL_MONSTER))
- return;
- if (other.heal_timer > time)
- return;
-
- if (self.count && self.cnt <= 0)
- {
- if (self.message2 != __NULL__ && self.message2 != "")
- centerprint (other, self.message2);
- return;
- }
-
- if ((other.takedamage) && (other.health < self.health_max))
- {
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "items/r_item1.wav", 1,
- ATTN_NORM);
-
- local float calculated_healing;
-
- if ((other.health + self.heal_amount) > self.health_max)
- calculated_healing = self.health_max - other.health;
- else
- calculated_healing = self.heal_amount;
-
- if (self.count)
- {
- if (calculated_healing > self.cnt)
- calculated_healing = self.cnt;
+const float TRIGGER_HEAL_START_ON = 1;
+const float TRIGGER_HEAL_PLAYER_ONLY = 2;
+const float TRIGGER_HEAL_MONSTER_ONLY = 4;

- self.cnt = self.cnt - calculated_healing;
-
- if (self.delay)
- {
- self.think = heal_think;
- self.nextthink = time + self.delay;
- }
-
- dprint ("trigger_heal used: [max: ");
- dprint (ftos(self.count));
- dprint (", current: ");
- dprint (ftos(self.cnt));
- dprint (", using: ");
- dprint (ftos(calculated_healing));
- dprint ("]\n");
- }
-
- if (self.message != __NULL__ && self.message != "")
- centerprint (other, self.message);
-
- T_Heal (other, calculated_healing, 1);
- other.heal_timer = time + self.wait;
- }
-};
-
-//----------------------------------------------------------------------
-void() heal_toggle =
-{
- if (self.touch == SUB_Null)
- self.touch = heal_touch;
- else
- self.touch = SUB_Null;
-};
-
-/*QUAKED trigger_heal (.5 .5 .5) ? HEAL_START_ON HEAL_PLAYER_ONLY HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+/*QUAKED trigger_heal (.5 .5 .5) ? TRIGGER_HEAL_START_ON TRIGGER_HEAL_PLAYER_ONLY TRIGGER_HEAL_MONSTER_ONLY X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

Any object touching this will be healed
heal_amount -- the amount to heal each time (default 5)
@@ -137,53 +26,185 @@ speed -- amount to recharge at a time
delay -- time before recharging
message2 -- message to print when exhausted
*/
-void() trigger_heal =
+class trigger_heal: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
+ // class fields
+ float heal_amount;
+ float health_max;

- // play custom sound for healing if noise key exists
- precache_sound ("items/r_item1.wav");
- if (self.noise != "")
- precache_sound (self.noise);
+ //--------------------------------------------------------------
+ virtual void() heal_think =
+ {
+ if (this.cnt == this.count)
+ {
+ dprint ("trigger_heal think: full\n");
+ this.think = SUB_Null;
+ return;
+ }

- InitTrigger ();
+ local float recharge_amount = this.speed;

- if (self.wait == 0)
- self.wait = 1;
+ if (this.count < (this.cnt + this.speed))
+ recharge_amount = this.count - this.cnt;

- if (self.heal_amount == 0)
- self.heal_amount = 5;
+ dprint ("trigger_heal think: [max: ");
+ dprint (ftos(this.count));
+ dprint (", current: ");
+ dprint (ftos(this.cnt));
+ dprint (", recharging: ");
+ dprint (ftos(recharge_amount));
+ dprint ("]\n");

- if (self.health_max == 0)
- self.health_max = 100;
- else if (self.health_max > 250)
- self.health_max = 250;
+ this.cnt = this.cnt + recharge_amount;
+ this.nextthink = time + this.delay;
+ };

- if (self.count)
+ //--------------------------------------------------------------
+ virtual void() heal_touch =
{
- self.cnt = self.count;
+ if (this.estate != STATE_ACTIVE)
+ return;

- if (self.speed && !self.delay)
- self.delay = 10;
- else if (!self.speed && self.delay)
- self.speed = 5;
- }
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ {
+ return;
+ }

- /*
- if (self.targetname)
+ if (this.spawnflags & TRIGGER_HEAL_PLAYER_ONLY &&
+ other.classtype != CT_PLAYER)
+ {
+ return;
+ }
+
+ if (this.spawnflags & TRIGGER_HEAL_MONSTER_ONLY &&
+ !(other.flags & FL_MONSTER))
+ {
+ return;
+ }
+
+ if (other.classtype != CT_PLAYER && !(other.flags & FL_MONSTER))
+ {
+ return;
+ }
+
+ if (other.heal_timer > time)
+ {
+ return;
+ }
+
+ if (this.count && this.cnt <= 0)
+ {
+ if (this.message2 != __NULL__ && this.message2 != "")
+ centerprint (other, this.message2);
+ return;
+ }
+
+ if ((other.takedamage) && (other.health < this.health_max))
+ {
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise,
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_AUTO, "items/r_item1.wav",
+ 1, ATTN_NORM);
+
+ local float calc_healing;
+
+ if ((other.health + this.heal_amount) > this.health_max)
+ calc_healing = this.health_max - other.health;
+ else
+ calc_healing = this.heal_amount;
+
+ if (this.count)
+ {
+ if (calc_healing > this.cnt)
+ calc_healing = this.cnt;
+
+ this.cnt = this.cnt - calc_healing;
+
+ if (this.delay)
+ {
+ this.think = this.heal_think;
+ this.nextthink = time + this.delay;
+ }
+
+ dprint ("trigger_heal used: [max: ");
+ dprint (ftos(this.count));
+ dprint (", current: ");
+ dprint (ftos(this.cnt));
+ dprint (", using: ");
+ dprint (ftos(calc_healing));
+ dprint ("]\n");
+ }
+
+ if (this.message != __NULL__ && this.message != "")
+ centerprint (other, this.message);
+
+ T_Heal (other, calc_healing, 1);
+ other.heal_timer = time + this.wait;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() heal_toggle =
{
- self.use = heal_toggle;
- if (self.spawnflags & HEAL_START_ON)
- self.touch = heal_touch;
+ if (this.touch == SUB_Null)
+ this.touch = this.heal_touch;
else
- self.touch = SUB_Null;
- }
- else
- */
+ this.touch = SUB_Null;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_heal =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit ())
+ return;
+
+ // play custom sound for healing if noise key exists
+ precache_sound ("items/r_item1.wav");
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ this.classname = "trigger_heal";
+ this.classtype = CT_TRIGGER_HEAL;
+ init_trigger ();
+
+ if (this.wait == 0)
+ this.wait = 1;
+
+ if (this.heal_amount == 0)
+ this.heal_amount = 5;

- self.touch = heal_touch;
+ if (this.health_max == 0)
+ this.health_max = 100;
+ else if (this.health_max > 250)
+ this.health_max = 250;
+
+ if (this.count)
+ {
+ this.cnt = this.count;
+
+ if (this.speed && !this.delay)
+ this.delay = 10;
+ else if (!this.speed && this.delay)
+ this.speed = 5;
+ }
+
+ /*
+ if (this.targetname)
+ {
+ this.use = this.heal_toggle;
+ if (this.spawnflags & TRIGGER_HEAL_START_ON)
+ this.touch = this.heal_touch;
+ else
+ this.touch = SUB_Null;
+ }
+ else
+ */

- SUB_CheckWaiting ();
+ this.touch = this.heal_touch;
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/hurt.qc

diff --git a/qc/triggers/hurt.qc b/qc/triggers/hurt.qc
index 679ed19..da3e19d 100644
--- a/qc/triggers/hurt.qc
+++ b/qc/triggers/hurt.qc
@@ -1,89 +1,88 @@
//==============================================================================
-// trigger_hurt
+// trigger_hurt -- from hip_rotate.qc by Jim Dose' 10/17/96
//==============================================================================

-//----------------------------------------------------------------------
-
-// 1998-07-03 hurt_touch fix by Robert Field start
-//
-// triggers.qc
-//
-.float hurt_together_time;
-.float hurt_nextthink;
-// 1998-07-03 hurt_touch fix by Robert Field end
-
-//----------------------------------------------------------------------
-
-// from hip_rotate.qc by Jim Dose' 10/17/96
-void(entity ent, float amount) hurt_setdamage =
-{
- ent.dmg = amount;
-
- if (!amount)
- ent.solid = SOLID_NOT;
- else
- ent.solid = SOLID_TRIGGER;
-
- ent.nextthink = -1;
-};
-
-//----------------------------------------------------------------------
-
-// 1998-07-03 hurt_touch fix by Robert Field start
-/*
-void() hurt_on =
-{
- self.solid = SOLID_TRIGGER;
- self.nextthink = -1;
-};
+/*QUAKED trigger_hurt (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Any object touching this will be hurt
+set dmg to damage amount
+defalt dmg = 5
*/
-// 1998-07-03 hurt_touch fix by Robert Field end
-
-void() hurt_touch =
+class trigger_hurt: base_trigger
{
+ // class fields
+ // 1998-07-03 hurt_touch fix by Robert Field start
+ float hurt_together_time;
+ float hurt_nextthink;
+ // 1998-07-03 hurt_touch fix by Robert Field end
+
+ //--------------------------------------------------------------
+ virtual void(entity ent, float amount) setdamage =
+ {
+ ent.dmg = amount;

- if (self.estate != STATE_ACTIVE)
- return;
+ if (!amount)
+ ent.solid = SOLID_NOT;
+ else
+ ent.solid = SOLID_TRIGGER;

- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
+ ent.nextthink = -1;
+ };

- if (other.takedamage && self.nextthink < time)
+ //--------------------------------------------------------------
+ // 1998-07-03 hurt_touch fix by Robert Field start
+ /*
+ void() hurt_on =
{
- // 1998-07-03 hurt_touch fix by Robert Field start
- // self.solid = SOLID_NOT;
- if (time != self.hurt_together_time)
- if (time < self.hurt_nextthink)
- return;
- // 1998-07-03 hurt_touch fix by Robert Field end
- T_Damage (other, self, self, self.dmg);
- // 1998-07-03 hurt_touch fix by Robert Field start
- // self.think = hurt_on;
- // self.nextthink = time + 1;
- self.hurt_together_time = time;
- self.hurt_nextthink = time + 1;
- // 1998-07-03 hurt_touch fix by Robert Field end
- }
-
- return;
-};
+ this.solid = SOLID_TRIGGER;
+ this.nextthink = -1;
+ };
+ */
+ // 1998-07-03 hurt_touch fix by Robert Field end
+
+ //--------------------------------------------------------------
+ virtual void() hurt_touch =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (other.takedamage && this.nextthink < time)
+ {
+ // 1998-07-03 trigger_hurt_touch fix by Robert Field
+ // this.solid = SOLID_NOT;
+ if (time != this.hurt_together_time)
+ if (time < this.hurt_nextthink)
+ return;
+ // 1998-07-03 hurt_touch fix by Robert Field end
+ T_Damage (other, this, this, this.dmg);
+ // 1998-07-03 hurt_touch fix by Robert Field start
+ // this.think = hurt_on;
+ // this.nextthink = time + 1;
+ this.hurt_together_time = time;
+ this.hurt_nextthink = time + 1;
+ // 1998-07-03 trigger_hurt_touch fix by Robert Field end
+ }

-/*QUAKED trigger_hurt (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Any object touching this will be hurt
-set dmg to damage amount
-defalt dmg = 5
-*/
-void() trigger_hurt =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
return;
+ };

- InitTrigger ();
- self.touch = hurt_touch;
- if (!self.dmg)
- self.dmg = 5;
-
- SUB_CheckWaiting ();
+ //--------------------------------------------------------------
+ void() trigger_hurt =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_hurt";
+ this.classtype = CT_TRIGGER_HURT;
+ this.touch = this.hurt_touch;
+ init_trigger ();
+ if (!this.dmg)
+ this.dmg = 5;
+
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/ladder.qc

diff --git a/qc/triggers/ladder.qc b/qc/triggers/ladder.qc
index fa397be..af190e2 100644
--- a/qc/triggers/ladder.qc
+++ b/qc/triggers/ladder.qc
@@ -1,41 +1,7 @@
//==============================================================================
-// LADDERS (from rubicon2.qc)
+// trigger_ladder -- selections from Rubicon 2 qc by john fitzgibbons
//==============================================================================

-// selections from Rubicon 2 qc by john fitzgibbons
-
-//======================================================================
-// ladder_touch
-//----------------------------------------------------------------------
-void() ladder_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- // prevent the player "sticking" to a ladder if they are standing on
- // the platform at the top of the ladder with the bottom of their
- // bounding box flush with the top of the trigger -- iw
- if (other.absmin_z + 1 >= self.absmax_z - 1)
- return;
-
- // if the trigger has an angles field, check player's facing direction
- if (self.movedir != '0 0 0')
- {
- makevectors (other.angles);
- if (v_forward * self.movedir < 0)
- // not facing the right way
- return;
- }
-
- // changed to PMFLAGS -- CEV
- other.pmove_flags |= PMF_ONLADDER;
-}
-
-//======================================================================
-// trigger_ladder
-//----------------------------------------------------------------------
-
/*QUAKED trigger_ladder (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
invisible ladder entity. when player is touching this entity, he can climb by pushing 'jump'

@@ -43,25 +9,61 @@ Keys:

"angle" the direction player must be facing to climb ladder
*/
-void() trigger_ladder =
+class trigger_ladder: base_trigger
{
- if (SUB_Inhibit())
- // new spawnflags for all entities -- iw
- return;
+ //--------------------------------------------------------------
+ // trigger_ladder_touch
+ //--------------------------------------------------------------
+ virtual void() ladder_touch =
+ {
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;
+
+ // prevent the player "sticking" to a ladder if they are
+ // standing on the platform at the top of the ladder with
+ // the bottom of their bounding box flush with the top of
+ // the trigger -- iw
+ if (other.absmin_z + 1 >= this.absmax_z - 1)
+ return;

- // ignore an "up" or "down" angle (doesn't make sense for a ladder)
- if (self.angles_y == -1 || self.angles_y == -2)
+ // if the trigger has an angles field, check player's
+ // facing direction
+ if (this.movedir != '0 0 0')
+ {
+ makevectors (other.angles);
+ if (v_forward * this.movedir < 0)
+ // not facing the right way
+ return;
+ }
+
+ // changed to PMFLAGS -- CEV
+ other.pmove_flags |= PMF_ONLADDER;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_ladder =
{
- dprint ("WARNING: trigger_ladder ignored bad 'angle' value: ");
- dprint (ftos (self.angles_y));
- dprint ("\n");
+ if (SUB_Inhibit())
+ // new spawnflags for all entities -- iw
+ return;

- self.angles_y = 0;
- }
+ // ignore an "up" or "down" angle (doesn't make sense
+ // for a ladder)
+ if (this.angles_y == -1 || this.angles_y == -2)
+ {
+ dprint ("WARNING: trigger_ladder ignored bad "
+ "'angle' value: ");
+ dprint (ftos (this.angles_y));
+ dprint ("\n");

- InitTrigger ();
- self.touch = ladder_touch;
+ this.angles_y = 0;
+ }

- SUB_CheckWaiting ();
+ this.classname = "trigger_ladder";
+ this.classtype = CT_TRIGGER_LADDER;
+ this.touch = this.ladder_touch;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};
-

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

Diff qc/triggers/look.qc

diff --git a/qc/triggers/look.qc b/qc/triggers/look.qc
index 73a94f7..64840ef 100644
--- a/qc/triggers/look.qc
+++ b/qc/triggers/look.qc
@@ -1,67 +1,6 @@
-//==============================================================================
-// trigger_look
-//==============================================================================
-
-///////////////////////////////////////////////////////////////
-//trigger_look (a.k.a. trigger_onlookat from NullPointPaladin!)
-///////////////////////////////////////////////////////////////
-void() onlookat_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- if (self.nextthink > time)
- // allready been triggered
- return;
-
- // added player view offset to make this more accurate
- // to the player crosshairs
- local vector player_offset;
- player_offset = other.origin + other.view_ofs;
-
- makevectors (other.v_angle);
-
- // using speed to determine the reach of the trace
- if (!self.speed)
- self.speed = 500;
-
- traceline (player_offset, (player_offset + (v_forward * self.speed)),
- FALSE, other);
-
- if (trace_ent.targetname == self.target)
- {
- // Play message if available
- if (self.message != "")
- centerprint (other, self.message);
-
- self.use = multi_trigger;
- SUB_UseTargets ();
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1,
- ATTN_NORM);
- else
- sound (self, CHAN_VOICE, self.noise1, 1,
- ATTN_NORM);
-
- // added wait
- if (self.wait > 0)
- {
- self.think = multi_wait;
- self.nextthink = time + self.wait;
- }
- else
- {
- // we can't just remove (self) here, because this
- // is a touch function called wheil C code is looping
- // through area links...
- self.touch = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- }
- }
-};
+////////////////////////////////////////////////////////////////////////////////
+// trigger_look (a.k.a. trigger_onlookat from NullPointPaladin!)
+////////////////////////////////////////////////////////////////////////////////

/*QUAKED trigger_look (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
This will trigger when a player is within the brush trigger and looks directly at a target entity.
@@ -74,51 +13,115 @@ noise1 = Path to custom sound. Use with sounds key set to 4 (e.g. fish/bite.wav

See manual for complete details. See pd_cutscenes sample map for example
*/
-void() trigger_look =
+class trigger_look: base_multiple
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // play all the sounds available for a normal trigger
- if (self.sounds == 0)
- {
- precache_sound ("misc/null.wav");
- self.noise = "misc/null.wav";
- }
- else if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
- else if (self.sounds == 4)
+ //--------------------------------------------------------------
+ virtual void() look_touch =
{
- if (!self.noise1)
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;
+
+ if (this.nextthink > time)
+ // already been triggered
+ return;
+
+ // added player view offset to make this more accurate
+ // to the player crosshairs
+ local vector player_offset = other.origin + other.view_ofs;
+
+ makevectors (other.v_angle);
+
+ // using speed to determine the reach of the trace
+ if (!this.speed)
+ this.speed = 500;
+
+ traceline (player_offset,
+ (player_offset + (v_forward * this.speed)),
+ FALSE, other);
+
+ if (trace_ent.targetname == this.target)
{
- // dumptruck_ds
- objerror ("no soundfile set in noise1!\n");
- remove (self);
+ // Play message if available
+ if (this.message != "")
+ centerprint (other, this.message);
+
+ this.use = this.multi_trigger;
+ SUB_UseTargets ();
+
+ if (this.noise != "")
+ sound (this, CHAN_VOICE, this.noise, 1,
+ ATTN_NORM);
+ else
+ sound (this, CHAN_VOICE, this.noise1, 1,
+ ATTN_NORM);
+
+ // added wait
+ if (this.wait > 0)
+ {
+ this.think = this.multi_wait;
+ this.nextthink = time + this.wait;
+ }
+ else
+ {
+ // we can't just remove (this) here, because
+ // this is a touch function called while C
+ // code is looping through area links...
+ this.touch = SUB_Null;
+ this.nextthink = time + 0.1;
+ this.think = SUB_Remove;
+ }
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_look =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
return;
+
+ // play all the sounds available for a normal trigger
+ if (this.sounds == 0)
+ {
+ precache_sound ("misc/null.wav");
+ this.noise = "misc/null.wav";
}
- else
+ else if (this.sounds == 1)
{
- precache_sound (self.noise1);
+ precache_sound ("misc/secret.wav");
+ this.noise = "misc/secret.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ this.noise = "misc/talk.wav";
+ }
+ else if (this.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ this.noise = "misc/trigger1.wav";
+ }
+ else if (this.sounds == 4)
+ {
+ if (!this.noise1)
+ {
+ // dumptruck_ds
+ objerror ("no soundfile set in noise1!\n");
+ remove (this);
+ return;
+ }
+ else
+ {
+ precache_sound (this.noise1);
+ }
+ this.noise = this.noise1;
}
- self.noise = self.noise1;
- }
-
- InitTrigger ();
- self.touch = onlookat_touch;

- SUB_CheckWaiting ();
+ this.classname = "trigger_look";
+ this.classtype = CT_TRIGGER_LOOK;
+ this.touch = this.look_touch;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/misc.qc

diff --git a/qc/triggers/misc.qc b/qc/triggers/misc.qc
deleted file mode 100644
index 7f89031..0000000
--- a/qc/triggers/misc.qc
+++ /dev/null
@@ -1,506 +0,0 @@
-//==============================================================================
-// TRIGGERS.QC
-//==============================================================================
-
-//----------------------------------------------------------------------
-void() trigger_reactivate =
-{
- self.solid = SOLID_TRIGGER;
-};
-
-float SPAWNFLAG_NOMESSAGE = 1;
-float SPAWNFLAG_NOTOUCH = 1;
-float SPAWNFLAG_TURNS_OFF = 2; // used for Wait for retrigger spawnflag
-
-//----------------------------------------------------------------------
-// the wait time has passed, so set back up for another activation
-//----------------------------------------------------------------------
-void() multi_wait =
-{
- if (self.max_health)
- {
- self.health = self.max_health;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
- }
-};
-
-//----------------------------------------------------------------------
-// the trigger was just touched/killed/used
-// self.enemy should be set to the activator so it can be held through a
-// delay so wait for the delay time before firing
-//----------------------------------------------------------------------
-void() multi_trigger =
-{
- if (self.nextthink > time)
- {
- // allready been triggered
- return;
- }
-
- if (self.classname == "trigger_secret")
- {
- if (self.enemy.classname != "player")
- return;
- if (cutscene)
- // Don't activate in cutscene mode
- return;
- found_secrets = found_secrets + 1;
- WriteByte (MSG_ALL, SVC_FOUNDSECRET);
- }
-
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- // don't trigger again until reset
- self.takedamage = DAMAGE_NO;
-
- activator = self.enemy;
-
- SUB_UseTargets ();
-
- if (self.wait > 0)
- {
- self.think = multi_wait;
- self.nextthink = time + self.wait;
- if (self.spawnflags & SPAWNFLAG_TURNS_OFF)
- {
- self.is_waiting = 1;
- SUB_CheckWaiting ();
- }
- }
- else
- {
- // we can't just remove (self) here, because this is a touch
- // function called wheil C code is looping through area links...
- self.touch = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- }
-};
-
-//----------------------------------------------------------------------
-// dumptruck_ds
-//----------------------------------------------------------------------
-void() multi_killed =
-{
- // Supa, restore health and do nothing if we're still waiting to
- // be activated
- if (self.estate != STATE_ACTIVE)
- {
- self.health = self.max_health; // nyah nyah~!
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
-
- return;
- }
-
- self.enemy = damage_attacker;
- multi_trigger ();
-};
-
-//----------------------------------------------------------------------
-// dumptruck_ds
-//----------------------------------------------------------------------
-void() multi_use =
-{
- self.enemy = activator;
- multi_trigger ();
-};
-
-//----------------------------------------------------------------------
-// dumptruck_ds
-//----------------------------------------------------------------------
-void() multi_touch =
-{
-
- if (other.classname != "player")
- return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- // if the trigger has an angles field, check player's facing direction
- if (self.movedir != '0 0 0')
- {
- makevectors (other.angles);
- if (v_forward * self.movedir < 0)
- // not facing the right way
- return;
- }
-
- self.enemy = other;
- multi_trigger ();
-};
-
-/*QUAKED trigger_multiple (.5 .5 .5) ? notouch WAIT_FOR_RETRIGGER 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
-
-Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
-If "WAIT_FOR_RETRIGGER" is set, it must be triggered by another entity before it can trigger again.
-If "delay" is set, the trigger waits some time after activating before firing.
-"wait" : Seconds between triggerings. (.2 default)
-If notouch is set, the trigger is only fired by other entities, not by touching.
-NOTOUCH has been obsoleted by trigger_relay!
-sounds
-1) secret
-2) beep beep
-3) large switch
-set "message" to text string
-"is_waiting" : If set to 1, this trigger will do nothing until another trigger activates it
-*/
-void() trigger_multiple =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
- else if (self.sounds == 3)
- {
- precache_sound ("misc/trigger1.wav");
- self.noise = "misc/trigger1.wav";
- }
-
- if (!self.wait)
- {
- self.wait = 0.2;
- }
- else if (self.wait < 0 && (self.spawnflags & SPAWNFLAG_TURNS_OFF))
- {
- objerror("Wait for retrigger and negative wait don't"
- " make sense");
- }
-
- self.use = multi_use;
-
- InitTrigger ();
-
- if (self.health)
- {
- if (self.spawnflags & SPAWNFLAG_NOTOUCH)
- objerror ("health and notouch don't make sense\n");
- self.max_health = self.health;
- self.th_die = multi_killed;
- self.takedamage = DAMAGE_YES;
- self.solid = SOLID_BBOX;
- // make sure it links into the world
- setorigin (self, self.origin);
- }
- else
- {
- if (!(self.spawnflags & SPAWNFLAG_NOTOUCH))
- {
- self.touch = multi_touch;
- }
- }
-
- SUB_CheckWaiting ();
-};
-
-/*QUAKED trigger_once (.5 .5 .5) ? notouch 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
-
-Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
-"targetname". If "health" is set, the trigger must be killed to activate.
-If notouch is set, the trigger is only fired by other entities, not by touching.
-if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
-if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
-sounds
-1) secret
-2) beep beep
-3) large switch
-set "message" to text string
-*/
-void() trigger_once =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.wait = -1;
- trigger_multiple ();
-};
-
-//=============================================================================
-
-/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
-*/
-void() trigger_relay =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.use = SUB_UseTargets;
-};
-
-//----------------------------------------------------------------------
-// target_setstate
-//----------------------------------------------------------------------
-float SETSTATE_STARTOFF = 1;
-float SETSTATE_CLOSEALLDOORS = 2;
-float SETSTATE_DONTRESETBUTTON = 4;
-
-//----------------------------------------------------------------------
-float(entity e) entity_get_state =
-{
- if (e.classname == "func_door")
- return e.owner.estate;
- else
- return e.estate;
-};
-
-//----------------------------------------------------------------------
-void(entity e, float state, float flags) entity_set_state =
-{
- float closealldoors = 0;
-
- if (e.classname == "func_button")
- {
- if (state == STATE_ACTIVE)
- button_unlock (e, flags & SETSTATE_DONTRESETBUTTON);
- else
- button_lock (e);
- }
- else if (e.classname == "func_door")
- {
- if (flags & SETSTATE_CLOSEALLDOORS)
- closealldoors = 1;
-
- if (state == STATE_ACTIVE)
- door_estate_unlock (e, closealldoors);
- else
- door_estate_lock (e, closealldoors);
- }
- else
- {
- e.estate = state;
- }
-
- if (e.is_waiting > 0 && state == STATE_ACTIVE)
- {
- SUB_CallAsSelf (SUB_EndWaiting, e);
- }
-
- // if (e.touch && e.touch != SUB_Null)
- // {
- // force_retouch = 2;
- // }
-};
-
-//----------------------------------------------------------------------
-void(string matchstring, .string matchfield, float state, float flags)
- target_setstate_set_target =
-{
- local entity t;
-
- t = find (world, matchfield, matchstring);
- while (t != world)
- {
- if (state == -1)
- {
- if (entity_get_state(t) == STATE_ACTIVE)
- entity_set_state (t, STATE_INACTIVE, flags);
- else
- entity_set_state (t, STATE_ACTIVE, flags);
- }
- else
- {
- entity_set_state (t, state, flags);
- }
-
- t = find (t, matchfield, matchstring);
- }
-};
-
-//----------------------------------------------------------------------
-void(float state) target_setstate_set_alltargets =
-{
- if (self.target && self.target != "")
- {
- target_setstate_set_target(self.target, targetname,
- state, self.spawnflags);
- target_setstate_set_target(self.target, targetname2,
- state, self.spawnflags);
- target_setstate_set_target(self.target, targetname3,
- state, self.spawnflags);
- target_setstate_set_target(self.target, targetname4,
- state, self.spawnflags);
- }
- if (self.target2 && self.target2 != "")
- {
- target_setstate_set_target(self.target2, targetname,
- state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname2,
- state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname3,
- state, self.spawnflags);
- target_setstate_set_target(self.target2, targetname4,
- state, self.spawnflags);
- }
- if (self.target3 && self.target3 != "")
- {
- target_setstate_set_target(self.target3, targetname,
- state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname2,
- state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname3,
- state, self.spawnflags);
- target_setstate_set_target(self.target3, targetname4,
- state, self.spawnflags);
- }
- if (self.target4 && self.target4 != "")
- {
- target_setstate_set_target(self.target4, targetname,
- state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname2,
- state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname3,
- state, self.spawnflags);
- target_setstate_set_target(self.target4, targetname4,
- state, self.spawnflags);
- }
-};
-
-//----------------------------------------------------------------------
-void() target_setstate_use =
-{
- local float state;
-
- if (self.style == 1)
- state = STATE_ACTIVE;
- else if (self.style == 2)
- state = STATE_INACTIVE;
- else
- state = -1;
-
- target_setstate_set_alltargets (state);
-};
-
-//----------------------------------------------------------------------
-void() target_setstate_startoff_think =
-{
- target_setstate_set_alltargets (STATE_INACTIVE);
-};
-
-//----------------------------------------------------------------------
-void() target_setstate =
-{
- self.use = target_setstate_use;
-
- if (self.spawnflags & SETSTATE_STARTOFF)
- {
- // wait a bit while doors finish being set up
- self.think = target_setstate_startoff_think;
- self.nextthink = time + 0.2;
- }
-};
-
-//----------------------------------------------------------------------
-// trigger_everything
-//----------------------------------------------------------------------
-void() trigger_everything_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- if (time < self.attack_finished)
- return;
-
- activator = other;
-
- SUB_UseSpecificTarget (self.target, targetname);
-
- if (self.wait)
- if (!(self.spawnflags & 1))
- self.attack_finished = time + self.wait;
-};
-
-//----------------------------------------------------------------------
-void() trigger_everything = {
- InitTrigger ();
-
- self.touch = trigger_everything_touch;
- SUB_CheckWaiting ();
-};
-
-//----------------------------------------------------------------------
-// target_setcount
-//----------------------------------------------------------------------
-void(string name, .string fld) target_setcount_set =
-{
- local entity t;
-
- t = find (world, fld, name);
-
- while (t)
- {
- if (self.style == 1)
- t.count += self.count;
- else
- t.count = self.count;
-
- t = find (t, fld, name);
- }
-};
-
-//----------------------------------------------------------------------
-void() target_setcount_use =
-{
- if (self.target && self.target != "")
- {
- target_setcount_set (self.target, targetname);
- target_setcount_set (self.target, targetname2);
- target_setcount_set (self.target, targetname3);
- target_setcount_set (self.target, targetname4);
- }
- if (self.target2 && self.target2 != "")
- {
- target_setcount_set (self.target2, targetname);
- target_setcount_set (self.target2, targetname2);
- target_setcount_set (self.target2, targetname3);
- target_setcount_set (self.target2, targetname4);
- }
- if (self.target3 && self.target3 != "")
- {
- target_setcount_set (self.target3, targetname);
- target_setcount_set (self.target3, targetname2);
- target_setcount_set (self.target3, targetname3);
- target_setcount_set (self.target3, targetname4);
- }
- if (self.target4 && self.target4 != "")
- {
- target_setcount_set (self.target4, targetname);
- target_setcount_set (self.target4, targetname2);
- target_setcount_set (self.target4, targetname3);
- target_setcount_set (self.target4, targetname4);
- }
-
- if (self.spawnflags & 1)
- {
- if (self.style == 1)
- activator.count += activator.count;
- else
- activator.count = activator.count;
- }
-};
-
-//----------------------------------------------------------------------
-void() target_setcount =
-{
- self.use = target_setcount_use;
-
-};

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

Diff qc/triggers/monsterface.qc

diff --git a/qc/triggers/monsterface.qc b/qc/triggers/monsterface.qc
index 5aa56a4..d1c8960 100644
--- a/qc/triggers/monsterface.qc
+++ b/qc/triggers/monsterface.qc
@@ -2,37 +2,6 @@
// trigger_monsterface
//==============================================================================

-void() trigger_monsterface_touch =
-{
- // only affect ground monsters
- if (other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
- return;
-
- if (!visibleToOther(other.enemy))
- {
- // enemy is hidden
- // don't dodge around, just go straight
- other.t_length = time + self.wait + 0.2;
- // face where I want
- other.ideal_yaw = self.angles_y;
- }
-};
-
-void() trigger_monsterface_init =
-{
- self.solid = SOLID_TRIGGER;
- // set size and link into world
- setmodel (self, self.model);
- self.movetype = MOVETYPE_NONE;
- self.modelindex = 0;
- self.model = "";
-
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
-
- self.touch = trigger_monsterface_touch;
-};
-
/*QUAKED trigger_monsterface (.5 .0 .5)
Running monsters that do not see their target and touch this will face in the direction of the trigger's angle instead of the unseen target.
Use this trigger to make monsters leave their sniping spot and execute complex maneuvers.
@@ -42,12 +11,49 @@ Keys:
"targetname" entity name
"wait" time to wait between retriggers
*/
-void() trigger_monsterface =
+class trigger_monsterface: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- trigger_monsterface_init();
- // InitTrigger ();
+ //--------------------------------------------------------------
+ virtual void() monsterface_touch =
+ {
+ // only affect ground monsters
+ if (other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
+ return;
+
+ if (!visibleToOther(other.enemy))
+ {
+ // enemy is hidden
+ // don't dodge around, just go straight
+ other.t_length = time + this.wait + 0.2;
+ // face where I want
+ other.ideal_yaw = this.angles_y;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init =
+ {
+ this.solid = SOLID_TRIGGER;
+ // set size and link into world
+ setmodel (this, this.model);
+ this.movetype = MOVETYPE_NONE;
+ this.modelindex = 0;
+ this.model = "";
+
+ if (this.angles == '0 0 0')
+ this.angles = '0 360 0';
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_monsterface =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_monsterface";
+ this.classtype = CT_TRIGGER_MONSTERFACE;
+ this.touch = this.monsterface_touch;
+ this.init ();
+ };
};

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

Diff qc/triggers/monsterjump.qc

diff --git a/qc/triggers/monsterjump.qc b/qc/triggers/monsterjump.qc
index 02f817f..acd510d 100644
--- a/qc/triggers/monsterjump.qc
+++ b/qc/triggers/monsterjump.qc
@@ -1,61 +1,81 @@
//==============================================================================
-// trigger_monsterjump
+// trigger_monsterjump -- id1 monsterjump with additions from progs_dump 3
//==============================================================================

-//----------------------------------------------------------------------
-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;
-};
+// constants
+const float TRIGGER_MONSTERJUMP_STARTOFF = 8;

-/*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
+/*QUAKED trigger_monsterjump (.5 .5 .5) ? X X X TRIGGER_MONSTERJUMP_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
+If TRIGGER_MONSTERJUMP_STARTOFF flag is set, this makes the trigger inactive. This can
be targeted and toggled off and on.
*/
-void() trigger_monsterjump =
+class trigger_monsterjump: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() monsterjump_touch =
+ {
+ if (this.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 = this.movedir_x * this.speed;
+ other.velocity_y = this.movedir_y * this.speed;
+
+ if (!(other.flags & FL_ONGROUND))
+ return;

- self.use = push_toggle;
+ other.flags = other.flags - FL_ONGROUND;
+
+ other.velocity_z = this.height;
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds was based on hipnotic blocker_use now Alkaline estate
+ //--------------------------------------------------------------
+ virtual void() monsterjump_use =
+ {
+ // TODO CEV duplicating some code here between this and
+ // trigger_push_custom
+ if (this.estate != STATE_ACTIVE)
+ this.estate = STATE_ACTIVE;
+ else
+ this.estate = STATE_INACTIVE;
+ };

- // dumptruck_ds
- if (self.spawnflags & DT_STARTOFF)
+ //--------------------------------------------------------------
+ void() trigger_monsterjump =
{
- self.estate = STATE_INACTIVE;
- }
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- if (!self.speed)
- self.speed = 200;
- if (!self.height)
- self.height = 200;
- if (self.angles == '0 0 0')
- self.angles = '0 360 0';
+ // dumptruck_ds
+ if (this.spawnflags & TRIGGER_MONSTERJUMP_STARTOFF)
+ {
+ this.estate = STATE_INACTIVE;
+ }

- InitTrigger ();
- self.touch = trigger_monsterjump_touch;
+ if (!this.speed)
+ this.speed = 200;
+ if (!this.height)
+ this.height = 200;
+ if (this.angles == '0 0 0')
+ this.angles = '0 360 0';

- SUB_CheckWaiting ();
+ this.classname = "trigger_monsterjump";
+ this.classtype = CT_TRIGGER_MONSTERJUMP;
+ this.touch = this.monsterjump_touch;
+ this.use = this.monsterjump_use;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/multiple.qc

diff --git a/qc/triggers/multiple.qc b/qc/triggers/multiple.qc
new file mode 100644
index 0000000..6299e19
--- /dev/null
+++ b/qc/triggers/multiple.qc
@@ -0,0 +1,255 @@
+//==============================================================================
+// trigger_multiple, trigger_once
+//==============================================================================
+
+// constants
+const float TRIGGER_MULTIPLE_NOTOUCH = 1;
+// used for Wait for retrigger spawnflag
+const float TRIGGER_MULTIPLE_TURNS_OFF = 2;
+
+//------------------------------------------------------------------------------
+// generic multiple class
+//------------------------------------------------------------------------------
+class base_multiple: base_trigger
+{
+ //--------------------------------------------------------------
+ // the wait time has passed, so set back up for another activation
+ //--------------------------------------------------------------
+ virtual void() multi_wait =
+ {
+ if (this.max_health)
+ {
+ this.health = this.max_health;
+ this.takedamage = DAMAGE_YES;
+ this.solid = SOLID_BBOX;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // the trigger was just touched/killed/used
+ // this.enemy should be set to the activator so it can be held
+ // through a delay so wait for the delay time before firing
+ //--------------------------------------------------------------
+ virtual void() multi_trigger =
+ {
+ if (this.nextthink > time)
+ {
+ // already been triggered
+ return;
+ }
+
+ if (this.classtype == CT_TRIGGER_SECRET)
+ {
+ if (this.enemy.classtype != CT_PLAYER)
+ return;
+ if (cutscene)
+ // Don't activate in cutscene mode
+ return;
+ found_secrets = found_secrets + 1;
+ WriteByte (MSG_ALL, SVC_FOUNDSECRET);
+ }
+
+ if (this.noise != "")
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+
+ // don't trigger again until reset
+ this.takedamage = DAMAGE_NO;
+
+ activator = this.enemy;
+
+ SUB_UseTargets ();
+
+ if (this.wait > 0)
+ {
+ this.think = this.multi_wait;
+ this.nextthink = time + this.wait;
+ if (this.spawnflags & TRIGGER_MULTIPLE_TURNS_OFF)
+ {
+ this.is_waiting = 1;
+ SUB_CheckWaiting ();
+ }
+ }
+ else
+ {
+ // we can't just remove (self) here, because this
+ // is a touch function called while C code is looping
+ // through area links...
+ this.touch = SUB_Null;
+ this.nextthink = time + 0.1;
+ this.think = SUB_Remove;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void() multi_killed =
+ {
+ // Supa, restore health and do nothing if we're still
+ // waiting to be activated
+ if (this.estate != STATE_ACTIVE)
+ {
+ this.health = this.max_health; // nyah nyah~!
+ this.takedamage = DAMAGE_YES;
+ this.solid = SOLID_BBOX;
+
+ return;
+ }
+
+ this.enemy = damage_attacker;
+ this.multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void() multi_use =
+ {
+ this.enemy = activator;
+ this.multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void() multi_touch =
+ {
+ if (other.classtype != CT_PLAYER)
+ return;
+
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;
+
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ // if the trigger has an angles field, check player's
+ // facing direction
+ if (this.movedir != '0 0 0')
+ {
+ makevectors (other.angles);
+ if (v_forward * this.movedir < 0)
+ // not facing the right way
+ return;
+ }
+
+ this.enemy = other;
+ this.multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() multi_init =
+ {
+ if (this.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ this.noise = "misc/secret.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ this.noise = "misc/talk.wav";
+ }
+ else if (this.sounds == 3)
+ {
+ precache_sound ("misc/trigger1.wav");
+ this.noise = "misc/trigger1.wav";
+ }
+
+ if (!this.wait)
+ {
+ this.wait = 0.2;
+ }
+ else if (this.wait < 0 &&
+ (this.spawnflags & TRIGGER_MULTIPLE_TURNS_OFF))
+ {
+ objerror ("Wait for retrigger and negative wait don't"
+ " make sense");
+ }
+
+ this.use = this.multi_use;
+ init_trigger ();
+
+ if (this.health)
+ {
+ if (this.spawnflags & TRIGGER_MULTIPLE_NOTOUCH)
+ objerror ("health and notouch don't make "
+ "sense\n");
+ this.max_health = this.health;
+ this.th_die = this.multi_killed;
+ this.takedamage = DAMAGE_YES;
+ this.solid = SOLID_BBOX;
+ // make sure it links into the world
+ setorigin (this, this.origin);
+ }
+ else
+ {
+ if (!(this.spawnflags & TRIGGER_MULTIPLE_NOTOUCH))
+ {
+ this.touch = this.multi_touch;
+ }
+ }
+
+ SUB_CheckWaiting ();
+ };
+};
+
+/*QUAKED trigger_multiple (.5 .5 .5) ? notouch WAIT_FOR_RETRIGGER 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
+
+Variable sized repeatable trigger. Must be targeted at one or more entities. If "health" is set, the trigger must be killed to activate each time.
+If "WAIT_FOR_RETRIGGER" is set, it must be triggered by another entity before it can trigger again.
+If "delay" is set, the trigger waits some time after activating before firing.
+"wait" : Seconds between triggerings. (.2 default)
+If notouch is set, the trigger is only fired by other entities, not by touching.
+NOTOUCH has been obsoleted by trigger_relay!
+sounds
+1) secret
+2) beep beep
+3) large switch
+set "message" to text string
+"is_waiting" : If set to 1, this trigger will do nothing until another trigger activates it
+*/
+class trigger_multiple: base_multiple
+{
+ //--------------------------------------------------------------
+ void() trigger_multiple =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_multiple";
+ this.classtype = CT_TRIGGER_MULTIPLE;
+
+ this.multi_init ();
+ };
+};
+
+/*QUAKED trigger_once (.5 .5 .5) ? notouch 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
+
+Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching
+"targetname". If "health" is set, the trigger must be killed to activate.
+If notouch is set, the trigger is only fired by other entities, not by touching.
+if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired.
+if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0.
+sounds
+1) secret
+2) beep beep
+3) large switch
+set "message" to text string
+*/
+class trigger_once: base_multiple
+{
+ void() trigger_once =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.wait = -1;
+ this.multi_init ();
+ this.classname = "trigger_once";
+ this.classtype = CT_TRIGGER_ONCE;
+ };
+};

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

Diff qc/triggers/onlyregistered.qc

diff --git a/qc/triggers/onlyregistered.qc b/qc/triggers/onlyregistered.qc
index 710fc6a..8a0452b 100644
--- a/qc/triggers/onlyregistered.qc
+++ b/qc/triggers/onlyregistered.qc
@@ -1,49 +1,53 @@
//==============================================================================
-// trigger_onlyregistered
+// trigger_onlyregistered -- ONLY REGISTERED TRIGGERS
//==============================================================================

-// ONLY REGISTERED TRIGGERS
-void() trigger_onlyregistered_touch =
+/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
+Only fires if playing the registered version, otherwise prints the message
+*/
+class trigger_onlyregistered: base_trigger
{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;

- if (self.attack_finished > time)
- return;
+ if (this.attack_finished > time)
+ return;

- self.attack_finished = time + 2;
+ this.attack_finished = time + 2;

- if (cvar("registered"))
- {
- self.message = "";
- SUB_UseTargets ();
- remove (self);
- }
- else
- {
- if (self.message != "")
+ if (cvar("registered"))
{
- centerprint (other, self.message);
- sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
+ this.message = "";
+ SUB_UseTargets ();
+ remove (this);
}
- }
-};
+ else
+ {
+ if (this.message != "")
+ {
+ centerprint (other, this.message);
+ sound (other, CHAN_BODY, "misc/talk.wav",
+ 1, ATTN_NORM);
+ }
+ }
+ };

-/*QUAKED trigger_onlyregistered (.5 .5 .5) ?
-Only fires if playing the registered version, otherwise prints the message
-*/
-void() trigger_onlyregistered =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ void() trigger_onlyregistered =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- precache_sound ("misc/talk.wav");
- InitTrigger ();
- self.touch = trigger_onlyregistered_touch;
+ precache_sound ("misc/talk.wav");

- SUB_CheckWaiting ();
+ this.classname = "trigger_onlyregistered";
+ this.classtype = CT_TRIGGER_ONLYREGISTERED;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};
-
-

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
index 674a59b..4258df1 100644
--- a/qc/triggers/push.qc
+++ b/qc/triggers/push.qc
@@ -1,32 +1,22 @@
-//==============================================================================
-// 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 ///////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-
-//======================================================================
-// solve_quadratic
-//
-// from Nexuiz source code; copied from
+////////////////////////////////////////////////////////////////////////////////
+// trigger_push -- id1 with additions by dumptruck_ds & CEV
+////////////////////////////////////////////////////////////////////////////////
+
+// constants
+const float TRIGGER_PUSH_ONCE = 1; // only trigger once
+const float TRIGGER_PUSH_STARTOFF = 8; // trigger will start off
+const float TRIGGER_PUSH_SILENT = 16; // push silently
+const float TRIGGER_PUSH_NOISE = 32; // use custom sound via noise key/value
+
+//----------------------------------------------------------------------
+// solve_quadratic -- from Nexuiz source code; original can be found at
// 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;
+ // ax^2 + bx + c = 0
+ vector v = '0 0 0';
float D;
- v = '0 0 0';
if (a == 0)
{
if (b != 0)
@@ -77,44 +67,46 @@ vector(float a, float b, float c) solve_quadratic =
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 =
+class base_trigger_push: base_trigger
{
- local float grav, sdist, zdist, vs, vz, jumpheight;
- local vector sdir, torg;
- vector solution;
- float trigger_push_calculatevelocity_flighttime;
+ //--------------------------------------------------------------
+ // 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
+ //
+ // copied from Nexuiz source code; original can be found here:
+ // github.com/smlinux/nexuiz/blob/master/data/qcsrc/server/t_jumppads.qc
+ //--------------------------------------------------------------
+ nonvirtual vector(vector org, entity tgt, float ht) calculatevelocity =
+ {
+ local float grav, sdist, zdist, vs, vz, jumpheight;
+ local vector sdir, torg;
+ local vector solution;
+ local float flighttime;

- torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
+ torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;

- grav = autocvar (sv_gravity, PM_GRAVITY);
+ grav = autocvar (sv_gravity, PM_GRAVITY);

- zdist = torg_z - org_z;
- sdist = vlen (torg - org - zdist * '0 0 1');
- sdir = normalize (torg - org - zdist * '0 0 1');
+ 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;
+ // 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...
@@ -133,131 +125,127 @@ vector(vector org, entity tgt, float ht) trigger_push_calculatevelocity =

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);
+ // 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
+ // 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)
{
- // almost straight line type
- // jump apex is before the jump
- // we must take the larger one
- trigger_push_calculatevelocity_flighttime = solution_y;
+ // down-jump
+ if (ht < 0)
+ {
+ // almost straight line type
+ // jump apex is before the jump
+ // we must take the larger one
+ flighttime = solution_y;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one too
+ 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;
+ // up-jump
+ if (ht < 0)
+ {
+ // almost straight line type
+ // jump apex is after the jump
+ // we must take the smaller one
+ flighttime = solution_x;
+ }
+ else
+ {
+ // regular jump
+ // jump apex is during the jump
+ // we must take the larger one
+ flighttime = solution_y;
+ }
}
- }
- else
+ vs = sdist / flighttime;
+
+ // finally calculate the velocity
+ return sdir * vs + '0 0 1' * vz;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() findtarget =
{
- // 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
+ this.enemy = find (world, ::targetname, this.target);
+ if (this.enemy)
{
- // regular jump
- // jump apex is during the jump
- // we must take the larger one
- trigger_push_calculatevelocity_flighttime = solution_y;
+ local vector org;
+ org = (this.absmin + this.absmax) * 0.5;
+ org_z = this.absmax_z - -24; // - PL_MIN_z;
+ this.movedir = this.calculatevelocity (org,
+ this.enemy, this.height);
}
- }
- 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)
+ //--------------------------------------------------------------
+ virtual void() push_touch =
{
- 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 /////////////////////////////////////
-////////////////////////////////////////////////////////////////////////
+ if (this.estate != STATE_ACTIVE)
+ return;

-//----------------------------------------------------------------------
-void() trigger_push_touch =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- 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 ();
+ // try to find target again if necessary
+ if (this.target && (!this.enemy))
+ this.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;
+ // we have a target, set movedir accordingly
+ if (this.target && this.enemy)
+ this.movedir = this.calculatevelocity (other.origin,
+ this.enemy, this.height);

- if (other.classname == "player")
+ if (other.classname == "grenade")
{
- if (!(self.spawnflags & DT_SILENT))
+ if (this.target && this.enemy)
+ other.velocity = this.movedir;
+ else
+ other.velocity = this.speed * this.movedir * 10;
+ }
+ else if (other.health > 0)
+ {
+ if (this.target && this.enemy)
+ other.velocity = this.movedir;
+ else
+ other.velocity = this.speed * this.movedir * 10;
+
+ if (other.classtype == CT_PLAYER &&
+ !(this.spawnflags & TRIGGER_PUSH_SILENT))
{
if (other.fly_sound < time)
{
- if (!(self.spawnflags & DT_NOISE))
+ if (!(this.spawnflags &
+ TRIGGER_PUSH_NOISE))
{
other.fly_sound = time + 1.5;
sound (other, CHAN_AUTO,
@@ -268,66 +256,67 @@ void() trigger_push_touch =
{
other.fly_sound = time + 1.5;
sound (other, CHAN_AUTO,
- self.noise,
+ this.noise,
1, ATTN_NORM);
}
}
}
}
- }

- if (self.spawnflags & PUSH_ONCE)
- remove (self);
-};
+ if (this.spawnflags & TRIGGER_PUSH_ONCE)
+ remove (this);
+ };

-// // 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
+/*QUAKED trigger_push (.5 .5 .5) ? TRIGGER_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 =
+class trigger_push: base_trigger_push
{
+ //--------------------------------------------------------------
// dumptruck_ds
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ /*
+ virtual void() push_use =
+ {
+ this.is_waiting = !this.is_waiting;
+ }
+ */

- InitTrigger ();
- precache_sound ("ambience/windfly.wav");
- self.touch = trigger_push_touch;
+ //--------------------------------------------------------------
+ // dumptruck_ds
+ //--------------------------------------------------------------
+ void() trigger_push =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- if (!self.speed)
- self.speed = 1000;
+ this.classname = "trigger_push";
+ this.classtype = CT_TRIGGER_PUSH;
+ this.touch = push_touch;
+ init_trigger ();
+ precache_sound ("ambience/windfly.wav");

- if (self.target != __NULL__ && 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';
- }
+ if (!this.speed)
+ this.speed = 1000;

- SUB_CheckWaiting ();
-};
+ if (this.target != __NULL__ && this.target != "")
+ {
+ // attempt to find the target
+ this.findtarget ();
+ if (!this.enemy)
+ if (!this.movedir)
+ // TODO CEV is this up? I don't remember
+ this.movedir = '0 0 180';
+ }

-//======================================================================
-// 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;
+ SUB_CheckWaiting ();
+ };
};

-/*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
+/*QUAKED trigger_push_custom (.5 .5 .5) ? TRIGGER_PUSH_ONCE TRIGGER_PUSH_STARTOFF TRIGGER_PUSH_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
@@ -335,35 +324,50 @@ 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.
+If TRIGGER_PUSH_STARTOFF flag is set, this disables the trigger. This can
+be targeted and toggled off and on. If the TRIGGER_PUSH_SILENT flag is set
+it won't make the windfly sound. Use TRIGGER_PUSH_NOISE 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 =
+Adapted from Hipnotic's func_togglewall
+*/
+class trigger_push_custom: base_trigger_push
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
+ //--------------------------------------------------------------
+ // dumptruck_ds was based on hipnotic blocker_use now Alkaline estate
+ //--------------------------------------------------------------
+ virtual void() push_custom_use =
+ {
+ if (this.estate != STATE_ACTIVE)
+ this.estate = STATE_ACTIVE;
+ else
+ this.estate = STATE_INACTIVE;
+ };
+
+ //--------------------------------------------------------------
+ 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;
+ this.classname = "trigger_push_custom";
+ this.classtype = CT_TRIGGER_PUSH_CUSTOM;
+ this.touch = push_touch;
+ this.use = push_custom_use;
+ init_trigger ();
+ precache_sound ("ambience/windfly.wav");

- if (self.spawnflags & DT_STARTOFF)
- self.estate = STATE_INACTIVE;
+ if (this.spawnflags & TRIGGER_PUSH_STARTOFF)
+ this.estate = STATE_INACTIVE;

- if (self.noise != "")
- precache_sound(self.noise);
+ if (this.noise != "")
+ precache_sound (this.noise);

- if (!self.speed)
- self.speed = 1000;
+ if (!this.speed)
+ this.speed = 1000;

- SUB_CheckWaiting ();
+ SUB_CheckWaiting ();
+ };
};
-
-////////////////////////////////////////////////////////////////////////
-// end dumptruck_ds additions //////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////

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

Diff qc/triggers/relay.qc

diff --git a/qc/triggers/relay.qc b/qc/triggers/relay.qc
new file mode 100644
index 0000000..bb3aaf1
--- /dev/null
+++ b/qc/triggers/relay.qc
@@ -0,0 +1,21 @@
+//==============================================================================
+// trigger_relay
+//==============================================================================
+
+/*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This fixed size trigger cannot be touched, it can only be fired by other events. It can contain killtargets, targets, delays, and messages.
+*/
+class trigger_relay: base_trigger
+{
+ //-------------------------------------------------------------
+ void() trigger_relay =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_relay";
+ this.classtype = CT_TRIGGER_RELAY;
+ this.use = SUB_UseTargets;
+ };
+};

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

Diff qc/triggers/remove.qc

diff --git a/qc/triggers/remove.qc b/qc/triggers/remove.qc
index 2a85640..b2fbab0 100644
--- a/qc/triggers/remove.qc
+++ b/qc/triggers/remove.qc
@@ -4,14 +4,15 @@

// Selections from hiptrig.qc NOT the entire file

-/* Trigger QuickC program
+/*
+ Trigger QuickC program
By Jim Dose' 12/2/96
Copyright (c)1996 Hipnotic Interactive, Inc.
All rights reserved.
Distributed (unsupported) on 3.12.97
*/

-// void() remove_touch =
+// void() trigger_remove_touch =
// {
// if (other.flags & self.cnt)
// return;
@@ -39,5 +40,5 @@
// self.cnt = self.cnt - FL_CLIENT;
//
// InitTrigger ();
-// self.touch = remove_touch;
+// self.touch = trigger_remove_touch;
// };

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

Diff qc/triggers/secret.qc

diff --git a/qc/triggers/secret.qc b/qc/triggers/secret.qc
index a0cbc0b..965a737 100644
--- a/qc/triggers/secret.qc
+++ b/qc/triggers/secret.qc
@@ -9,31 +9,36 @@ sounds
2) beep beep
set "message" to text string
*/
-void() trigger_secret =
+class trigger_secret: base_multiple
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ void() trigger_secret =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- total_secrets = total_secrets + 1;
- self.wait = -1;
+ total_secrets = total_secrets + 1;
+ this.wait = -1;

- if (!self.message)
- self.message = "You found a secret area!";
+ if (!this.message)
+ this.message = "You found a secret area!";

- if (!self.sounds)
- self.sounds = 1;
+ if (!this.sounds)
+ this.sounds = 1;

- if (self.sounds == 1)
- {
- precache_sound ("misc/secret.wav");
- self.noise = "misc/secret.wav";
- }
- else if (self.sounds == 2)
- {
- precache_sound ("misc/talk.wav");
- self.noise = "misc/talk.wav";
- }
+ if (this.sounds == 1)
+ {
+ precache_sound ("misc/secret.wav");
+ this.noise = "misc/secret.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ precache_sound ("misc/talk.wav");
+ this.noise = "misc/talk.wav";
+ }

- trigger_multiple ();
+ this.multi_init ();
+ this.classname = "trigger_secret";
+ this.classtype = CT_TRIGGER_SECRET;
+ };
};

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

Diff qc/triggers/setcount.qc

diff --git a/qc/triggers/setcount.qc b/qc/triggers/setcount.qc
new file mode 100644
index 0000000..519cb9c
--- /dev/null
+++ b/qc/triggers/setcount.qc
@@ -0,0 +1,76 @@
+//==============================================================================
+// target_setcount
+//==============================================================================
+
+//------------------------------------------------------------------------------
+// target_setcount
+//------------------------------------------------------------------------------
+class target_setcount: base_trigger
+{
+ //--------------------------------------------------------------
+ virtual void(string name, .string fld) setcount_set =
+ {
+ local entity t;
+
+ t = find (world, ::fld, name);
+
+ while (t)
+ {
+ if (this.style == 1)
+ t.count += this.count;
+ else
+ t.count = this.count;
+
+ t = find (t, ::fld, name);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() setcount_use =
+ {
+ if (this.target && this.target != "")
+ {
+ this.setcount_set (this.target, ::targetname);
+ this.setcount_set (this.target, ::targetname2);
+ this.setcount_set (this.target, ::targetname3);
+ this.setcount_set (this.target, ::targetname4);
+ }
+ if (this.target2 && this.target2 != "")
+ {
+ this.setcount_set (this.target2, ::targetname);
+ this.setcount_set (this.target2, ::targetname2);
+ this.setcount_set (this.target2, ::targetname3);
+ this.setcount_set (this.target2, ::targetname4);
+ }
+ if (this.target3 && this.target3 != "")
+ {
+ this.setcount_set (this.target3, ::targetname);
+ this.setcount_set (this.target3, ::targetname2);
+ this.setcount_set (this.target3, ::targetname3);
+ this.setcount_set (this.target3, ::targetname4);
+ }
+ if (this.target4 && this.target4 != "")
+ {
+ this.setcount_set (this.target4, ::targetname);
+ this.setcount_set (this.target4, ::targetname2);
+ this.setcount_set (this.target4, ::targetname3);
+ this.setcount_set (this.target4, ::targetname4);
+ }
+
+ if (this.spawnflags & 1)
+ {
+ if (this.style == 1)
+ activator.count += activator.count;
+ else
+ activator.count = activator.count;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() target_setcount =
+ {
+ this.classname = "target_setcount";
+ this.classtype = CT_TARGET_SETCOUNT;
+ this.use = this.setcount_use;
+ };
+};

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

Diff qc/triggers/setgravity.qc

diff --git a/qc/triggers/setgravity.qc b/qc/triggers/setgravity.qc
index 48a2b65..f34b494 100644
--- a/qc/triggers/setgravity.qc
+++ b/qc/triggers/setgravity.qc
@@ -2,58 +2,16 @@
// trigger_setgravity; was in hip_trig.qc
//==============================================================================

-/* Trigger QuickC program
+/*
+ Trigger QuickC program
By Jim Dose' 12/2/96
Copyright (c)1996 Hipnotic Interactive, Inc.
All rights reserved.
- Do not distribute.
+ Distributed (unsupported) on 3.12.97
*/

-float DT_GRAVTOFF = 8; // trigger will start off
-
-//----------------------------------------------------------------------
-// dumptruck_ds based on hipnotic blocker_use
-//----------------------------------------------------------------------
-void() grav_toggle =
-{
- if (self.estate != STATE_ACTIVE)
- self.estate = STATE_ACTIVE;
- else
- self.estate = STATE_INACTIVE;
-
-};
-
-//----------------------------------------------------------------------
-// from Copper -- dumptruck_ds
-//----------------------------------------------------------------------
-void() trigger_gravity_touch =
-{
- // if (!CheckValidTouch()) return;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- local float grav;
-
- // This is commented out so that the changing gravity will
- // affect everything, if you don't want to use all affecting
- // gravity changes, then uncomment these two lines.
- // if (other.classname != "player")
- // return;
-
- if (self.gravity == -1)
- grav = 1;
- else
- grav = self.gravity;
-
- // the player's gravity is now managed in PlayerPreThink(), however
- // other entities don't have special gravity management, so their
- // gravity is still set directly -- iw
- if (other.classname == "player")
- other.wantedgravity = grav;
- else
- other.gravity = grav;
-};
+// constants
+const float TRIGGER_SETGRAVITY_STARTOFF = 8; // trigger will start off

/*QUAKED trigger_setgravity (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
set the gravity of a player
@@ -78,26 +36,73 @@ set the gravity of a player
triggers not to work properly.

*/
-void() trigger_setgravity =
+class trigger_setgravity: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- InitTrigger ();
-
- // dumptruck_ds
- self.use = grav_toggle;
- self.touch = trigger_gravity_touch;
-
- // dumptruck_ds
- if (self.spawnflags & DT_GRAVTOFF)
- self.estate = STATE_INACTIVE;
-
- if (!self.gravity)
- self.gravity = -1;
- else
- self.gravity = ((self.gravity - 1) / 100);
-
- SUB_CheckWaiting ();
+ //--------------------------------------------------------------
+ // from Copper -- dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void() setgravity_touch =
+ {
+ // if (!CheckValidTouch()) return;
+
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ local float grav;
+
+ // This is commented out so that the changing gravity will
+ // affect everything, if you don't want to use all affecting
+ // gravity changes, then uncomment these two lines.
+ // if (other.classtype != CT_PLAYER)
+ // return;
+
+ if (this.gravity == -1)
+ grav = 1;
+ else
+ grav = this.gravity;
+
+ // the player's gravity is now managed in PlayerPreThink(),
+ // however other entities don't have special gravity
+ // management, so their gravity is still set directly -- iw
+ if (other.classtype == CT_PLAYER)
+ other.wantedgravity = grav;
+ else
+ other.gravity = grav;
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds based on hipnotic blocker_use
+ //--------------------------------------------------------------
+ virtual void() setgravity_use =
+ {
+ if (this.estate != STATE_ACTIVE)
+ this.estate = STATE_ACTIVE;
+ else
+ this.estate = STATE_INACTIVE;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_setgravity =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_setgravity";
+ this.classtype = CT_TRIGGER_SETGRAVITY;
+ this.touch = this.setgravity_touch;
+ this.use = this.setgravity_use;
+ init_trigger ();
+
+ // dumptruck_ds
+ if (this.spawnflags & TRIGGER_SETGRAVITY_STARTOFF)
+ this.estate = STATE_INACTIVE;
+
+ if (!this.gravity)
+ this.gravity = -1;
+ else
+ this.gravity = ((this.gravity - 1) / 100);
+
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/setskill.qc

diff --git a/qc/triggers/setskill.qc b/qc/triggers/setskill.qc
index 3dc48a0..a23e1d4 100644
--- a/qc/triggers/setskill.qc
+++ b/qc/triggers/setskill.qc
@@ -1,27 +1,34 @@
//==============================================================================
// trigger_setskill
//==============================================================================
-void() trigger_skill_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- cvar_set ("skill", self.message);
-};

/*QUAKED trigger_setskill (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
sets skill level to the value of "message".
Only used on start map.
*/
-void() trigger_setskill =
+class trigger_setskill: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() skill_touch =
+ {
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;
+
+ cvar_set ("skill", this.message);
+ };

- InitTrigger ();
- self.touch = trigger_skill_touch;
+ //--------------------------------------------------------------
+ void() trigger_setskill =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- SUB_CheckWaiting ();
+ this.classname = "trigger_setskill";
+ this.classtype = CT_TRIGGER_SETSKILL;
+ this.touch = this.skill_touch;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/setstate.qc

diff --git a/qc/triggers/setstate.qc b/qc/triggers/setstate.qc
new file mode 100644
index 0000000..4144c94
--- /dev/null
+++ b/qc/triggers/setstate.qc
@@ -0,0 +1,177 @@
+//==============================================================================
+// target_setstate
+//==============================================================================
+
+// constants for setstate
+const float SETSTATE_STARTOFF = 1;
+const float SETSTATE_CLOSEALLDOORS = 2;
+const float SETSTATE_DONTRESETBUTTON = 4;
+
+//------------------------------------------------------------------------------
+// target_setstate
+//------------------------------------------------------------------------------
+class target_setstate: entity
+{
+ //--------------------------------------------------------------
+ virtual float(entity e) entity_get_state =
+ {
+ if (e.classname == "func_door")
+ return e.owner.estate;
+ else
+ return e.estate;
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity e, float state, float flags) entity_set_state =
+ {
+ float closealldoors = 0;
+
+ if (e.classname == "func_button")
+ {
+ if (state == STATE_ACTIVE)
+ button_unlock (e, flags &
+ SETSTATE_DONTRESETBUTTON);
+ else
+ button_lock (e);
+ }
+ else if (e.classname == "func_door")
+ {
+ if (flags & SETSTATE_CLOSEALLDOORS)
+ closealldoors = 1;
+
+ if (state == STATE_ACTIVE)
+ door_estate_unlock (e, closealldoors);
+ else
+ door_estate_lock (e, closealldoors);
+ }
+ else
+ {
+ e.estate = state;
+ }
+
+ if (e.is_waiting > 0 && state == STATE_ACTIVE)
+ {
+ SUB_CallAsSelf (SUB_EndWaiting, e);
+ }
+
+ /*
+ if (e.touch && e.touch != SUB_Null)
+ {
+ force_retouch = 2;
+ }
+ */
+ };
+
+ //--------------------------------------------------------------
+ virtual void(string matchstring, .string matchfield, float state,
+ float flags) set_target =
+ {
+ local entity t;
+
+ t = find (world, ::matchfield, matchstring);
+ while (t != world)
+ {
+ if (state == -1)
+ {
+ if (this.entity_get_state(t) == STATE_ACTIVE)
+ this.entity_set_state (t,
+ STATE_INACTIVE, flags);
+ else
+ this.entity_set_state (t,
+ STATE_ACTIVE, flags);
+ }
+ else
+ {
+ this.entity_set_state (t, state, flags);
+ }
+
+ t = find (t, ::matchfield, matchstring);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(float state) set_alltargets =
+ {
+ if (this.target && this.target != "")
+ {
+ this.set_target (this.target, ::targetname,
+ state, this.spawnflags);
+ this.set_target (this.target, ::targetname2,
+ state, this.spawnflags);
+ this.set_target (this.target, ::targetname3,
+ state, this.spawnflags);
+ this.set_target (this.target, ::targetname4,
+ state, this.spawnflags);
+ }
+ if (this.target2 && this.target2 != "")
+ {
+ this.set_target (this.target2, ::targetname,
+ state, this.spawnflags);
+ this.set_target (this.target2, ::targetname2,
+ state, this.spawnflags);
+ this.set_target (this.target2, ::targetname3,
+ state, this.spawnflags);
+ this.set_target (this.target2, ::targetname4,
+ state, this.spawnflags);
+ }
+ if (this.target3 && this.target3 != "")
+ {
+ this.set_target (this.target3, ::targetname,
+ state, this.spawnflags);
+ this.set_target (this.target3, ::targetname2,
+ state, this.spawnflags);
+ this.set_target (this.target3, ::targetname3,
+ state, this.spawnflags);
+ this.set_target (this.target3, ::targetname4,
+ state, this.spawnflags);
+ }
+ if (this.target4 && this.target4 != "")
+ {
+ this.set_target (this.target4, ::targetname,
+ state, this.spawnflags);
+ this.set_target (this.target4, ::targetname2,
+ state, this.spawnflags);
+ this.set_target (this.target4, ::targetname3,
+ state, this.spawnflags);
+ this.set_target (this.target4, ::targetname4,
+ state, this.spawnflags);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() setstate_use =
+ {
+ local float state;
+
+ if (this.style == 1)
+ state = STATE_ACTIVE;
+ else if (this.style == 2)
+ state = STATE_INACTIVE;
+ else
+ state = -1;
+
+ this.set_alltargets (state);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() setstate_startoff_think =
+ {
+ this.set_alltargets (STATE_INACTIVE);
+ };
+
+
+ //--------------------------------------------------------------
+ void() target_setstate =
+ {
+ this.classname = "target_setstate";
+ this.classtype = CT_TARGET_SETSTATE;
+ this.use = this.setstate_use;
+
+ if (this.spawnflags & SETSTATE_STARTOFF)
+ {
+ // wait a bit while doors finish being set up
+ this.think = this.setstate_startoff_think;
+ this.nextthink = time + 0.2;
+ }
+ };
+};

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

Diff qc/triggers/shake.qc

diff --git a/qc/triggers/shake.qc b/qc/triggers/shake.qc
index b6b1675..fc759c4 100644
--- a/qc/triggers/shake.qc
+++ b/qc/triggers/shake.qc
@@ -1,122 +1,126 @@
//==============================================================================
-// TRIGGER_SHAKE
+// trigger_shake -- point entity from Rubicon Rumble Pack; requires TARGETNAME
//==============================================================================

-// this is a point entity from Rubicon Rumble Pack Devkit
-// REQUIRES A TARGETNAME
-
// constants
-float VIEWONLY = 1;
+const float TRIGGER_SHAKE_VIEWONLY = 1;
+
+/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) TRIGGER_SHAKE_VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

-//----------------------------------------------------------------------
-void() shake_think =
+Earthquake trigger - shakes players in it's radius when active.
+Strength of tremor is greatest at the centre.
+dmg Strength at center (default is 120)
+wait Duration of shake (default is 1)
+count Affect radius (defalt is 200)
+noise Noise to play when starting to shake
+noise1 Noise to play when stopping
+targetname Must be triggered
+Spawnflags
+TRIGGER_SHAKE_VIEWONLY Shakes the view, but player movement is not affected
+*/
+class trigger_shake: base_trigger
{
- if (self.attack_finished < time)
+ //--------------------------------------------------------------
+ virtual void() shake_think =
{
- // Done
- self.nextthink = -1;
-
- if (self.noise1 != "")
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ if (this.attack_finished < time)
+ {
+ // Done
+ this.nextthink = -1;

- return;
- }
+ if (this.noise1 != "")
+ sound (this, CHAN_VOICE, this.noise1,
+ 1, ATTN_NORM);

- // Shake all players in the effect radius...
+ return;
+ }

- local entity plyr;
- plyr = findradius (self.origin, self.count);
+ // Shake all players in the effect radius...
+ local entity p;
+ p = findradius (this.origin, this.count);

- while (plyr)
- {
- if (plyr.flags & FL_CLIENT)
+ while (p)
{
- local float d;
-
- // Scale effect by distance
- d = vlen (self.origin - plyr.origin);
- d = (self.count - d) / self.count;
-
- if (d > 0)
+ if (p.flags & FL_CLIENT)
{
- // shake up the view
- plyr.punchangle_x = -1 *
- (random() + (0.025 * self.dmg * d));
+ local float d;

- // push the player around
- if (plyr.flags & FL_ONGROUND
- && !(self.spawnflags & VIEWONLY))
+ // Scale effect by distance
+ d = vlen (this.origin - p.origin);
+ d = (this.count - d) / this.count;
+
+ if (d > 0)
{
- d = self.dmg * d;
- plyr.velocity_x = plyr.velocity_x +
- (random() * d * 2 - d);
- plyr.velocity_y = plyr.velocity_y +
- (random() * d * 2 - d);
- // always push up
- plyr.velocity_z = plyr.velocity_z +
- (random() * d);
+ // shake up the view
+ p.punchangle_x = -1 * (random() +
+ (0.025 * this.dmg * d));
+
+ // push the player around
+ if (p.flags & FL_ONGROUND
+ && !(this.spawnflags &
+ TRIGGER_SHAKE_VIEWONLY))
+ {
+ d = this.dmg * d;
+ p.velocity_x = p.velocity_x +
+ (random() * d * 2 - d);
+ p.velocity_y = p.velocity_y +
+ (random() * d * 2 - d);
+ // always push up
+ p.velocity_z = p.velocity_z +
+ (random() * d);
+ }
}
}
+ p = p.chain;
}
- plyr = plyr.chain;
- }

- // keep going
- self.nextthink = time + 0.1;
-};
+ // keep going
+ this.nextthink = time + 0.1;
+ };

-//----------------------------------------------------------------------
-void() shake_use =
-{
- // already active
- if (self.attack_finished > time)
- return;
+ //--------------------------------------------------------------
+ virtual void() shake_use =
+ {
+ // already active
+ if (this.attack_finished > time)
+ return;

- // Start...
- if (self.noise != "")
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ // Start...
+ if (this.noise != "")
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);

- self.attack_finished = time + self.wait;
- self.nextthink = time + 0.1;
-};
+ this.attack_finished = time + this.wait;
+ this.nextthink = time + 0.1;
+ };

-/*QUAKED trigger_shake (.5 0 .5) (-8 -8 -8) (8 8 8) VIEWONLY X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Earthquake trigger - shakes players in it's radius when active.
-Strength of tremor is greatest at the centre.
-dmg Strength at center (default is 120)
-wait Duration of shake (default is 1)
-count Affect radius (defalt is 200)
-noise Noise to play when starting to shake
-noise1 Noise to play when stopping
-targetname Must be triggered
-Spawnflags
-VIEWONL Shakes the view, but player movement is not affected
-*/
-void() trigger_shake =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
-
- if (!self.targetname)
- objerror("trigger_shake without name");
-
- if (self.noise != "")
- precache_sound (self.noise);
- if (self.noise1 != "")
- precache_sound (self.noise1);
-
- if (!self.dmg)
- self.dmg = 120;
- if (self.count <= 0)
- self.count = 200;
- if (self.wait <= 0)
- self.wait = 1.0;
-
- setorigin (self, self.origin);
-
- self.nextthink = -1;
- self.think = shake_think;
- self.use = shake_use;
+ //--------------------------------------------------------------
+ void() trigger_shake =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.classname = "trigger_shake";
+ this.classtype = CT_TRIGGER_SHAKE;
+ this.think = this.shake_think;
+ this.use = this.shake_use;
+
+ if (!this.targetname)
+ objerror ("trigger_shake without name");
+
+ if (this.noise != "")
+ precache_sound (this.noise);
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+
+ if (!this.dmg)
+ this.dmg = 120;
+ if (this.count <= 0)
+ this.count = 200;
+ if (this.wait <= 0)
+ this.wait = 1.0;
+
+ setorigin (this, this.origin);
+ this.nextthink = -1;
+ };
};

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

Diff qc/triggers/take_weapon.qc

diff --git a/qc/triggers/take_weapon.qc b/qc/triggers/take_weapon.qc
index 6812939..e8bc499 100644
--- a/qc/triggers/take_weapon.qc
+++ b/qc/triggers/take_weapon.qc
@@ -5,40 +5,51 @@
//======================================================================
// GIVE AND TAKE STUFF (WIP)
// This is Axe only at the moment. Need to research removing all weapons.
-//----------------------------------------------------------------------
-
-// thanks to ShanJaq and Spike for their help on this.
-void() take_weapon_use =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- if (!(other.flags & FL_CLIENT))
- return;
-
- multi_trigger ();
- other.items &= ~IT_SHOTGUN;
- other.currentammo = !other.ammo_shells;
- other.ammo_shells = !other.ammo_shells;
- other.items = other.items - (other.items & IT_SHELLS);
- W_SetCurrentAmmo ();
- W_BestWeapon ();
-};
+//======================================================================

/*QUAKED trigger_take_weapon (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

Removes shotgun upon touch. You can also set "reset_items" in the worldspawn entity to accomplish an axe only start.
*/
-void() trigger_take_weapon =
+class trigger_take_weapon: base_multiple
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.wait = -1;
- trigger_multiple ();
- self.touch = take_weapon_use;
-
- SUB_CheckWaiting ();
+ //--------------------------------------------------------------
+ // trigger_take_weapon_use
+ // thanks to ShanJaq and Spike for their help on this.
+ //--------------------------------------------------------------
+ virtual void() take_weapon =
+ {
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;
+
+ if (!(other.flags & FL_CLIENT))
+ return;
+
+ this.multi_trigger ();
+ other.items &= ~IT_SHOTGUN;
+ other.currentammo = !other.ammo_shells;
+ other.ammo_shells = !other.ammo_shells;
+ other.items = other.items - (other.items & IT_SHELLS);
+ if (other.classtype == CT_PLAYER)
+ {
+ PlayerSetCurrentAmmo ();
+ PlayerBestWeapon ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_take_weapon =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ this.wait = -1;
+ this.multi_init ();
+ this.classname = "trigger_take_weapon";
+ this.classtype = CT_TRIGGER_TAKE_WEAPON;
+ this.touch = this.take_weapon;
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/teleport.qc

diff --git a/qc/triggers/teleport.qc b/qc/triggers/teleport.qc
index 303aa2b..3599d80 100644
--- a/qc/triggers/teleport.qc
+++ b/qc/triggers/teleport.qc
@@ -1,25 +1,27 @@
//==============================================================================
-// TRIGGER_TELEPORT
-//==============================================================================
-
// TELEPORT TRIGGERS with added functions from Zerstrorer and Qmaster
// -- dumptruck_ds
+//==============================================================================

// constants
-float PLAYER_ONLY = 1;
-float SILENT = 2;
-float RANDOM = 4;
-float TELE_STEALTH = 8;
-float MONSTER_ONLY = 16;
-float TELE_DD = 32;
+const float TRIGGER_TELEPORT_ONLYPLAYER = 1;
+const float TRIGGER_TELEPORT_SILENT = 2;
+const float TRIGGER_TELEPORT_RANDOM = 4;
+const float TRIGGER_TELEPORT_STEALTH = 8;
+const float TRIGGER_TELEPORT_ONLYMONSTER = 16;
+const float TRIGGER_TELEPORT_DD = 32;
+
+//======================================================================
+// teleporter fog & teleporter death
+//======================================================================

//----------------------------------------------------------------------
-void() play_teleport =
+void() spawn_tfog_think =
{
local float v;
local string tmpstr;

- v = random () * 5;
+ v = random() * 5;
if (v < 1)
tmpstr = "misc/r_tele1.wav";
else if (v < 2)
@@ -44,7 +46,7 @@ void(vector org) spawn_tfog =
s.origin = org;
s.spawnflags = self.spawnflags; // dumptruck_ds
s.nextthink = time + 0.2;
- s.think = play_teleport;
+ s.think = spawn_tfog_think;

WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TELEPORT);
@@ -54,16 +56,16 @@ void(vector org) spawn_tfog =
};

//----------------------------------------------------------------------
-void() tdeath_touch =
+void() spawn_tdeath_touch =
{
if (other == self.owner)
return;

// frag anyone who teleports in on top of an invincible player
- if (other.classname == "player")
+ if (other.classtype == CT_PLAYER)
{
// 1998-07-26 Pentagram telefrag fix by Zoid/Maddes start
- if (self.owner.classname != "player")
+ if (self.owner.classtype != CT_PLAYER)
{
// other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
@@ -109,7 +111,7 @@ void() tdeath_touch =
}

/*
- if (self.owner.classname != "player")
+ if (self.owner.classtype != CT_PLAYER)
{ // other monsters explode themselves
T_Damage (self.owner, self, self, 50000);
return;
@@ -134,7 +136,7 @@ void(vector org, entity death_owner) spawn_tdeath =
death.angles = '0 0 0';
setsize (death, death_owner.mins - '1 1 1', death_owner.maxs + '1 1 1');
setorigin (death, org);
- death.touch = tdeath_touch;
+ death.touch = spawn_tdeath_touch;
death.nextthink = time + 0.2;
death.think = SUB_Remove;
death.owner = death_owner;
@@ -144,350 +146,229 @@ void(vector org, entity death_owner) spawn_tdeath =
};

//======================================================================
-// teleport_randomspot
-//
-// more Zerstrorer -- dumptruck_ds
-// teleport_randomspot - returns a random spot to teleport to among all
-// of the "info_teleport_random" entities in the level. self.count is
-// the number of spots
-//----------------------------------------------------------------------
-entity() teleport_randomspot =
-{
- local float rndm;
- // local float rndm, num1;
- local entity spot,first;
+// trigger_teleport
+//======================================================================

- rndm = rint (random() * (self.count - 1));
- spot = find (world, classname, "info_teleport_random");
- if (!spot)
- dprint ("No random teleport points found!\n");
- first = spot;
+/*QUAKED trigger_teleport (.5 .5 .5) ? TRIGGER_TELEPORT_ONLYPLAYER TRIGGER_TELEPORT_SILENT TRIGGER_TELEPORT_RANDOM TRIGGER_TELEPORT_STEALTH 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

- while (rndm > 0)
- {
- rndm = rndm - 1;
- spot = find (spot, classname, "info_teleport_random");
- }
+Any object touching this will be transported to the corresponding
+info_teleport_destination entity. You must set the "target" field,
+and create an object with a "targetname" field that matches.

- if (spot == world)
- {
- dprint ("Random spot found world!!\n");
- spot = first;
- }
+If the trigger_teleport has a targetname, it will only teleport entities
+when it has been fired.

- return spot;
-};
-// end dumptruck_ds
+TRIGGER_TELEPORT_SILENT(2) eliminates the teleporter ambient noise (good
+for hidden monster teleporters.

-//----------------------------------------------------------------------
-void() teleport_touch =
+TRIGGER_TELEPORT_RANDOM(4) causes the teleporter to send the player to a
+random destination among the info_teleport_random markers in the level.
+You MUST place a "count" field that is the number of info_teleport_random
+entities you placed.
+
+TRIGGER_TELEPORT_STEALTH(8) eliminates the particle flash and noise when
+an entity is teleported.
+
+TRIGGER_TELEPORT_ONLYMONSTER(16) will only teleport monsters
+*/
+class trigger_teleport: base_trigger
{
- local entity t;
- local vector org;
+ //--------------------------------------------------------------
+ // trigger_teleport_randomspot -- more Zerstrorer -- dumptruck_ds
+ // teleport_randomspot - returns a random spot to teleport to
+ // among all of the "info_teleport_random" entities in the level.
+ // self.count is the number of spots
+ //--------------------------------------------------------------
+ nonvirtual entity() randomspot =
+ {
+ local float rndm;
+ // local float rndm, num1;
+ local entity spot,first;

- if (self.estate != STATE_ACTIVE)
- return;
+ rndm = rint (random() * (this.count - 1));
+ spot = findfloat (world, ::classtype, CT_INFO_TELEPORT_RANDOM);
+ if (!spot)
+ dprint ("No random teleport points found!\n");
+ first = spot;

- if (self.targetname != "")
- if (self.nextthink < time)
- // not fired yet
- return;
+ while (rndm > 0)
+ {
+ rndm = rndm - 1;
+ spot = findfloat (spot, ::classtype,
+ CT_INFO_TELEPORT_RANDOM);
+ }

- if (self.spawnflags & PLAYER_ONLY)
- if (other.classname != "player")
- return;
+ if (spot == world)
+ {
+ dprint ("Random spot found world!!\n");
+ spot = first;
+ }

- // is this going to work? dumptruck_ds
- if (self.spawnflags & MONSTER_ONLY)
- if (other.classname == "player")
- return;
+ return spot;
+ };
+ // end dumptruck_ds

- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
+ //--------------------------------------------------------------
+ virtual void() teleport_touch =
+ {
+ local entity t;
+ local vector org;

- // Supa, is this trigger waiting to be activated?
- if (self.is_waiting == TRUE)
- return;
+ if (this.estate != STATE_ACTIVE)
+ return;

- // Special case
- if (self.is_waiting != -1)
- if (self.targetname != "")
- if (self.nextthink < time)
+ if (this.targetname != "")
+ if (this.nextthink < time)
// not fired yet
return;

- // only teleport living creatures
- if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
- return;
-
- SUB_UseTargets ();
-
- // put a tfog where the player was
- // ### dhm - if stealth, don't spawn a fog
- if (!(self.spawnflags & TELE_STEALTH))
- spawn_tfog (other.origin);
-
- // dhm - if this is a random teleporter, pick a random spot!
- if (self.spawnflags & RANDOM)
- t = teleport_randomspot ();
- else if ((self.spawnflags & TELE_DD) && other.classname == "player")
- t = find (world, targetname, self.noise);
- else
- t = find (world, targetname, self.target);
-
- if (!t)
- objerror ("couldn't find target");
-
- // put a tfog where the player was
- /*
- spawn_tfog (other.origin);
-
- t = find (world, targetname, self.target);
- if (!t)
- objerror ("couldn't find target");
- */
-
- // spawn a tfog flash in front of the destination
- makevectors (t.mangle);
- org = t.origin + 32 * v_forward;
-
- // ### dhm - if stealth, don't spawn a fog
- if (!(self.spawnflags & TELE_STEALTH))
- spawn_tfog (org);
-
- spawn_tdeath (t.origin, other);
-
- // move the player and lock him down for a little while
- if (!other.health)
- {
- other.origin = t.origin;
- other.velocity = (v_forward * other.velocity_x) +
- (v_forward * other.velocity_y);
- return;
- }
-
- setorigin (other, t.origin);
- other.angles = t.mangle;
+ if (this.spawnflags & TRIGGER_TELEPORT_ONLYPLAYER)
+ if (other.classtype != CT_PLAYER)
+ return;

- if (other.classname == "player")
- {
- // retrieves fog values from teleport destination, if any
- fog_setFromEnt (other, t);
-
- // turn this way immediately
- other.fixangle = 1;
- other.teleport_time = time + 0.7;
- // push player out at PM_TELEEXITSPEED -- CEV
- other.velocity = v_forward * PM_TELEEXITSPEED;
- // TODO CEV commented out the next line
- // other.flags = other.flags - other.flags & FL_ONGROUND;
- }
+ // is this going to work? dumptruck_ds
+ if (this.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER)
+ if (other.classtype == CT_PLAYER)
+ return;

- if ((self.spawnflags & MONSTER_ONLY) && other.classname != "player")
- {
- // turn this way immediately
- other.fixangle = 1;
- other.teleport_time = time + 0.7;
- if (other.flags & FL_ONGROUND)
- other.flags = other.flags - FL_ONGROUND;
- other.velocity = v_forward * PM_TELEEXITSPEED;
- other.flags = other.flags - other.flags & FL_ONGROUND;
- }
-};
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return;

-// this is from Qmaster:
+ // Supa, is this trigger waiting to be activated?
+ if (this.is_waiting == TRUE)
+ return;

-// "I created an info_teleport_changedest
-// target = targetname of trigger_teleport to affect
-// message = targetname of new info_teleport_destination (or whatever entity
-// really) to now teleport to
+ // Special case
+ if (this.is_waiting != -1)
+ if (this.targetname != "")
+ if (this.nextthink < time)
+ // not fired yet
+ return;

-// So that I can automatically update the teleporter under my coagula map as you
-// progress rather than have a bunch of triggers that I need to killtarget.
-// Falling is not fatal then, but it does put you back some. Works as a sorta
-// checkpoint system but also builds on my older idea for saving time in coop
-// implemented in my Terracity map eons ago.
+ // only teleport living creatures
+ if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
+ return;

-// looking at vanilla, you would only need to change trig.target to match
-// self.message if you were to add this."
+ SUB_UseTargets ();

-//----------------------------------------------------------------------
-void() teleport_destchange =
-{
- local entity trig;
+ // put a tfog where the player was
+ // ### dhm - if stealth, don't spawn a fog
+ if (!(this.spawnflags & TRIGGER_TELEPORT_STEALTH))
+ spawn_tfog (other.origin);

- trig = find(world,targetname,self.target);
- if (!trig || trig.classname != "trigger_teleport")
- {
- dprint ("\b[TELEPORT_DESTCHANGE]\b ");
- dprint ("Cannot find trigger_teleport\n");
- return;
- }
+ // dhm - if this is a random teleporter, pick a random spot!
+ if (this.spawnflags & TRIGGER_TELEPORT_RANDOM)
+ {
+ t = randomspot ();
+ }
+ else if ((this.spawnflags & TRIGGER_TELEPORT_DD) &&
+ other.classtype == CT_PLAYER)
+ {
+ t = find (world, ::targetname, this.noise);
+ }
+ else
+ {
+ t = find (world, ::targetname, this.target);
+ }

- trig.goalentity = find (world, targetname, self.message);
- if (!trig.goalentity)
- {
- dprint ("\b[TELEPORT_DESTCHANGE]\b ");
- dprint ("Cannot find teleport destination\n");
- return;
- }
+ if (!t)
+ objerror ("couldn't find target");

- makevectors (trig.goalentity.mangle);
- trig.goalentity.movedir = v_forward;
- trig.goalentity.pos1 = trig.goalentity.origin + 32 *
- trig.goalentity.movedir;
+ // put a tfog where the player was
+ /*
+ spawn_tfog (other.origin);

- // dumptruck_ds see comment above
- trig.target = self.message;
-};
+ t = find (world, ::targetname, this.target);
+ if (!t)
+ objerror ("couldn't find target");
+ */

-/*QUAKED info_teleport_changedest (0 0.5 0) (-4 -4 -4) (4 4 4) 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
-Allows a mapper to change the target of a teleport_trigger. Useful in maps where
-the player may fall into a void and the mapper wants to update where they "respawn"
-as they progress through the level. Could also be used for teleport puzzles and more.
-target = trigger_teleport to change
-message = new info_teleport_destination's targetname to switch to
-targetname = name of this entity so we can use it
-*/
-void() info_teleport_changedest =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
+ // spawn a tfog flash in front of the destination
+ makevectors (t.mangle);
+ org = t.origin + 32 * v_forward;

- self.use = teleport_destchange;
- if (self.targetname == "")
- {
- dprint ("\b[ERROR]\b info_teleport_changedest ");
- dprint ("with no targetname\n");
- remove (self);
- }
+ // ### dhm - if stealth, don't spawn a fog
+ if (!(this.spawnflags & TRIGGER_TELEPORT_STEALTH))
+ spawn_tfog (org);

- if (self.target == "")
- {
- dprint ("\b[ERROR]\b info_teleport_changedest ");
- dprint ("with no target\n");
- remove(self);
- }
+ spawn_tdeath (t.origin, other);

- if (self.message == "")
- {
- dprint ("\b[ERROR]\b info_teleport_changedest ");
- dprint ("with no message set for new destination\n");
- remove (self);
- }
-};
+ // move the player and lock him down for a little while
+ if (!other.health)
+ {
+ other.origin = t.origin;
+ other.velocity = (v_forward * other.velocity_x) +
+ (v_forward * other.velocity_y);
+ return;
+ }

-/*QUAKED info_teleport_destination (.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");
-}
-This is the destination marker for a teleporter. It should have a "targetname"
-field with the same value as a teleporter's "target" field.
-*/
-void() info_teleport_destination =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
+ setorigin (other, t.origin);
+ other.angles = t.mangle;

- local vector end;
+ if (other.classtype == CT_PLAYER)
+ {
+ // retrieves fog values from teleport destination,
+ // if any
+ fog_setFromEnt (other, t);
+
+ // turn this way immediately
+ other.fixangle = 1;
+ other.teleport_time = time + 0.7;
+ // push player out at PM_TELEEXITSPEED -- CEV
+ other.velocity = v_forward * PM_TELEEXITSPEED;
+ // TODO CEV commented out the next line
+ //other.flags = other.flags - other.flags & FL_ONGROUND;
+ }

- // this does nothing, just serves as a target spot
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.model = "";
+ if ((this.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER) &&
+ other.classtype != CT_PLAYER)
+ {
+ // turn this way immediately
+ other.fixangle = 1;
+ other.teleport_time = time + 0.7;
+ if (other.flags & FL_ONGROUND)
+ other.flags = other.flags - FL_ONGROUND;
+ other.velocity = v_forward * PM_TELEEXITSPEED;
+ other.flags = other.flags - other.flags & FL_ONGROUND;
+ }
+ };

- // drop teleporter exit to the floor if it's PM_TELEDROP units
- // away -- CEV
- end = self.origin + PM_TELEDROP;
- tracebox (self.origin, self.mins, self.maxs, end, FALSE, self);
- if (trace_allsolid || trace_startsolid || trace_fraction < 1)
+ //--------------------------------------------------------------
+ virtual void() teleport_use =
{
- droptofloor ();
- // bump origin up so player won't exit into the floor -- CEV
- // This was '0 0 24' but that was causing issues -- CEV
- self.origin = self.origin + '0 0 27';
- }
- else
+ this.nextthink = time + 0.2;
+ // make sure even still objects get hit
+ force_retouch = 2;
+ this.think = SUB_Null;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_teleport =
{
- // instead apply the standard fixed Z offset -- CEV
- self.origin = self.origin + '0 0 27';
- }
-
- if (!self.targetname)
- if (self.target != __NULL__ && self.target != "")
- // quake 3 compat -- CEV
- self.targetname = self.target;
- else
- objerror ("no targetname");
-};
-
-/*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");
-}
-This is a random destination marker for a teleporter.
-*/
-void() info_teleport_random =
-{
- // this does nothing, just serves as a target spot
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.model = "";
- self.origin = self.origin + '0 0 27';
-};
-
-//----------------------------------------------------------------------
-void() teleport_use =
-{
- self.nextthink = time + 0.2;
- // make sure even still objects get hit
- force_retouch = 2;
- self.think = SUB_Null;
-};
-
-/*QUAKED trigger_teleport (.5 .5 .5) ? PLAYER_ONLY SILENT RANDOM STEALTH X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-Any object touching this will be transported to the corresponding
-info_teleport_destination entity. You must set the "target" field,
-and create an object with a "targetname" field that matches.
-
-If the trigger_teleport has a targetname, it will only teleport entities
-when it has been fired.
-
-SILENT(2) eliminates the teleporter ambient noise (good for hidden monster teleporters.
-RANDOM(4) causes the teleporter to send the player to a random destination
- among the info_teleport_random markers in the level. You MUST place a
- "count" field that is the number of info_teleport_random entities you
- placed.
-STEALTH(8) eliminates the particle flash and noise when an entity is teleported.
-MONSTER_ONLY(16) will only teleport monsters
-*/
-void() trigger_teleport =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
-
- local vector o;
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- InitTrigger ();
- self.touch = teleport_touch;
+ local vector o;

- // find the destination
- if (!self.target)
- objerror ("no target");
+ this.classname = "trigger_teleport";
+ this.classtype = CT_TRIGGER_TELEPORT;
+ this.touch = this.teleport_touch;
+ this.use = this.teleport_use;
+ init_trigger ();

- self.use = teleport_use;
+ // find the destination
+ if (!this.target)
+ objerror ("no target");

- if (!(self.spawnflags & SILENT))
- {
- precache_sound ("ambience/hum1.wav");
- o = (self.mins + self.maxs) * 0.5;
- ambientsound (o, "ambience/hum1.wav", 0.5, ATTN_STATIC);
- }
+ if (!(this.spawnflags & TRIGGER_TELEPORT_SILENT))
+ {
+ precache_sound ("ambience/hum1.wav");
+ o = (this.mins + this.maxs) * 0.5;
+ ambientsound (o, "ambience/hum1.wav", 0.5, ATTN_STATIC);
+ }

- SUB_CheckWaiting ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/textstory.qc

diff --git a/qc/triggers/textstory.qc b/qc/triggers/textstory.qc
index 5156eec..e1d4183 100644
--- a/qc/triggers/textstory.qc
+++ b/qc/triggers/textstory.qc
@@ -1,225 +1,270 @@
//==============================================================================
-// TRIGGER_TEXTSTORY
+// trigger_textstory
//==============================================================================

// constants
-float TEXTSTORY_SILENT = 1;
-float TEXTSTORY_NOFADE = 2;
+const float TEXTSTORY_SILENT = 1;
+const float TEXTSTORY_NOFADE = 2;

-//----------------------------------------------------------------------
-void(entity controller) textstory_hide =
+//------------------------------------------------------------------------------
+// base textstory class
+//------------------------------------------------------------------------------
+class base_textstory: base_trigger
{
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT))
- return;
-
- self.enemy.suppressCenterPrint = FALSE;
- centerprint (self.enemy, "");
+ //--------------------------------------------------------------
+ // hide a textstory
+ //--------------------------------------------------------------
+ virtual void(entity controller) hide =
+ {
+ if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
+ return;

- if (controller.noise2 != __NULL__ && controller.noise2 != "")
- sound (self.enemy, CHAN_BODY, controller.noise2, 1, ATTN_NORM);
+ this.enemy.suppressCenterPrint = FALSE;
+ centerprint (this.enemy, "");

- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- csf_fade (self.enemy, 0, '0 0 0', 0.5);
+ if (controller.noise2 != __NULL__ && controller.noise2 != "")
+ sound (this.enemy, CHAN_BODY, controller.noise2, 1,
+ ATTN_NORM);

-};
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ csf_fade (this.enemy, 0, '0 0 0', 0.5);
+ };

-//----------------------------------------------------------------------
-void(entity controller) textstory_show =
-{
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT))
- return;
+ //--------------------------------------------------------------
+ // show a textstory
+ //--------------------------------------------------------------
+ virtual void(entity controller) show =
+ {
+ if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
+ return;

- self.enemy.suppressCenterPrint = TRUE;
+ this.enemy.suppressCenterPrint = TRUE;

- centerprint_builtin (self.enemy, controller.message);
+ centerprint_builtin (this.enemy, controller.message);

- if (!self.state)
- {
- if (controller.noise1 != __NULL__ && controller.noise1 != "")
+ if (!this.state)
{
- sound (self.enemy, CHAN_BODY, controller.noise1,
- 1, ATTN_NORM);
+ if (controller.noise1 != __NULL__ &&
+ controller.noise1 != "")
+ {
+ sound (this.enemy, CHAN_BODY, controller.noise1,
+ 1, ATTN_NORM);
+ }
+
+ if (!(controller.spawnflags & TEXTSTORY_NOFADE))
+ {
+ //custom fade amount --dumptruck_ds
+ if (!this.fade_amt)
+ csf_fade (this.enemy, 160, '0 0 0', 1);
+ else
+ csf_fade (this.enemy, this.fade_amt,
+ '0 0 0', 1);
+ }
}

- if (!(controller.spawnflags & TEXTSTORY_NOFADE))
- {
- //custom fade amount --dumptruck_ds
- if (!self.fade_amt)
- csf_fade (self.enemy, 160, '0 0 0', 1);
- else
- csf_fade (self.enemy, self.fade_amt,
- '0 0 0', 1);
- }
- }
-
- self.state = 1;
-};
-
-//----------------------------------------------------------------------
-void() trigger_textstory_hide =
-{
- textstory_hide (self);
-
- self.enemy = world;
- self.state = 0;
-};
-
-//----------------------------------------------------------------------
-void() trigger_textstory_show =
-{
- textstory_show (self);
-
- self.think = trigger_textstory_hide;
- self.nextthink = time + 0.2;
-
+ this.state = 1;
+ };
};

-//----------------------------------------------------------------------
-void() trigger_textstory_touch =
+//------------------------------------------------------------------------------
+// trigger_textstory -- centerprint text when inside this trigger
+//------------------------------------------------------------------------------
+class trigger_textstory: base_textstory
{
+ //--------------------------------------------------------------
+ // hide text
+ //--------------------------------------------------------------
+ virtual void() text_hide =
+ {
+ super::hide (this);

- if (!(other.flags & FL_CLIENT))
- return;
- if (self.estate != STATE_ACTIVE)
- return;
+ this.enemy = world;
+ this.state = 0;
+ };

- // don't show message if another player is already triggering it
- if (other != self.enemy && self.state == 1)
- return;
+ //--------------------------------------------------------------
+ // show text
+ //--------------------------------------------------------------
+ virtual void() text_show =
+ {
+ super::show (this);

- if (self.mangle &&
- !isInAngle (other.v_angle, self.mangle, self.view_ofs))
- return;
+ this.think = this.text_hide;
+ this.nextthink = time + 0.2;
+ };

- if (self.attack_finished < time)
+ //--------------------------------------------------------------
+ virtual void() story_touch =
{
+ if (!(other.flags & FL_CLIENT))
+ return;
+ if (this.estate != STATE_ACTIVE)
+ return;

- self.attack_finished = time + 0.1;
- self.enemy = other;
+ // don't show message if another player is already triggering it
+ if (other != this.enemy && this.state == 1)
+ return;

- trigger_textstory_show ();
- }
-};
+ if (this.mangle && !isInAngle (other.v_angle, this.mangle,
+ this.view_ofs))
+ {
+ return;
+ }

-//----------------------------------------------------------------------
-void() trigger_textstory =
-{
- InitTrigger ();
- self.touch = trigger_textstory_touch;
+ if (this.attack_finished < time)
+ {
+ this.attack_finished = time + 0.1;
+ this.enemy = other;

- if (self.view_ofs == '0 0 0')
- self.view_ofs = '90 90 0';
+ this.text_show ();
+ }
+ };

- if (self.mangle)
- self.mangle = normalizeAngles180(self.mangle);
+ //--------------------------------------------------------------
+ void() trigger_textstory =
+ {
+ this.classname = "trigger_textstory";
+ this.classtype = CT_TRIGGER_TEXTSTORY;
+ this.touch = this.story_touch;
+ init_trigger ();

- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
+ if (this.view_ofs == '0 0 0')
+ this.view_ofs = '90 90 0';

- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
+ if (this.mangle)
+ this.mangle = normalizeAngles180 (this.mangle);

- if (self.spawnflags & TEXTSTORY_SILENT)
- {
- self.noise1 = "";
- self.noise2 = "";
- }
+ if (this.noise1 == "")
+ this.noise1 = "misc/talk.wav";

+ if (this.noise2 == "")
+ this.noise2 = "misc/null.wav";

- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
+ if (this.spawnflags & TEXTSTORY_SILENT)
+ {
+ this.noise1 = "";
+ this.noise2 = "";
+ }

- SUB_CheckWaiting ();
-};

-//----------------------------------------------------------------------
-void() target_textstory_helper_hide =
-{
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+ if (this.noise2 != "")
+ precache_sound (this.noise2);

- textstory_hide (self.owner);
- remove (self);
+ SUB_CheckWaiting ();
+ };
};

-//----------------------------------------------------------------------
-void() target_textstory_helper_show =
+//------------------------------------------------------------------------------
+// helper class spawned by target_textstory below
+//------------------------------------------------------------------------------
+class target_textstory_helper: base_textstory
{
- if (!self.enemy || !(self.enemy.flags & FL_CLIENT))
+ //--------------------------------------------------------------
+ // hide text
+ //--------------------------------------------------------------
+ virtual void() helper_text_hide =
+ {
+ this.hide (this.owner);
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ // show text
+ //--------------------------------------------------------------
+ virtual void() helper_text_show =
{
- remove (self);
- return;
- }
+ if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
+ {
+ remove (this);
+ return;
+ }

- textstory_show (self.owner);
+ this.show (this.owner);

- if (self.attack_finished < time)
- self.think = target_textstory_helper_hide;
+ if (this.attack_finished < time)
+ this.think = this.helper_text_hide;

- self.nextthink = time + 0.1;
-};
+ this.nextthink = time + 0.1;
+ };

-//----------------------------------------------------------------------
-void(entity tgt) target_textstory_spawn_helper =
-{
- entity e;
-
- e = spawn();
- e.classname = "target_textstory_helper";
- e.owner = self;
- e.think = target_textstory_helper_show;
- e.nextthink = time + 0.1;
- e.attack_finished = time + self.wait;
- e.enemy = tgt;
+ //--------------------------------------------------------------
+ void() target_textstory_helper =
+ {
+ this.classname = "target_textstory_helper";
+ this.classtype = CT_TARGET_TEXTSTORY_HELPER;
+ this.think = this.helper_text_show;
+ };
};

-//----------------------------------------------------------------------
-void() target_textstory_use =
+//------------------------------------------------------------------------------
+// target_textstory: centerprint a message for an amount of time when used
+//------------------------------------------------------------------------------
+class target_textstory: base_textstory
{
+ //--------------------------------------------------------------
+ // create the hidden object that'll show the actual message
+ //--------------------------------------------------------------
+ virtual void(entity tgt) spawn_helper =
+ {
+ target_textstory_helper helper;
+ helper = spawn (target_textstory_helper,
+ owner:this,
+ nextthink:time + 0.1,
+ attack_finished:time + this.wait,
+ enemy:tgt);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() story_use =
+ {
+ if (!(activator.flags & FL_CLIENT))
+ return;
+ if (this.estate != STATE_ACTIVE)
+ return;

- if (!(activator.flags & FL_CLIENT))
- return;
- if (self.estate != STATE_ACTIVE)
- return;
-
- entity t;
+ local entity t;

- if (self.spawnflags & TRIGGER_CENTERPRINTALL)
- {
- t = find (world, classname, "player");
- while (t)
+ if (this.spawnflags & TRIGGER_CENTERPRINTALL)
{
- target_textstory_spawn_helper (t);
- t = find (t, classname, "player");
+ t = findfloat (world, ::classtype, CT_PLAYER);
+ while (t)
+ {
+ this.spawn_helper (t);
+ t = findfloat (t, ::classtype, CT_PLAYER);
+ }
}
- }
- else
- {
- target_textstory_spawn_helper (activator);
- }
-};
+ else
+ {
+ this.spawn_helper (activator);
+ }
+ };

-//----------------------------------------------------------------------
-void() target_textstory =
-{
- if (self.noise1 == "")
- self.noise1 = "misc/talk.wav";
+ //--------------------------------------------------------------
+ void() target_textstory =
+ {
+ this.classname = "target_textstory";
+ this.classtype = CT_TARGET_TEXTSTORY;
+ this.use = this.story_use;

- if (self.noise2 == "")
- self.noise2 = "misc/null.wav";
+ if (this.noise1 == "")
+ this.noise1 = "misc/talk.wav";

- if (self.spawnflags & TEXTSTORY_SILENT) {
- self.noise1 = "";
- self.noise2 = "";
- }
+ if (this.noise2 == "")
+ this.noise2 = "misc/null.wav";

- if (self.noise1 != "")
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
+ if (this.spawnflags & TEXTSTORY_SILENT) {
+ this.noise1 = "";
+ this.noise2 = "";
+ }

- if (!self.wait)
- self.wait = 5;
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+ if (this.noise2 != "")
+ precache_sound (this.noise2);

- self.use = target_textstory_use;
+ if (!this.wait)
+ this.wait = 5;
+ };
};

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

Diff qc/triggers/usekey.qc

diff --git a/qc/triggers/usekey.qc b/qc/triggers/usekey.qc
index eea8980..33696e9 100644
--- a/qc/triggers/usekey.qc
+++ b/qc/triggers/usekey.qc
@@ -2,129 +2,146 @@
// trigger_usekey
//==============================================================================

-/* Trigger QuickC program
+/*
+ Trigger QuickC program
By Jim Dose' 12/2/96
Copyright (c)1996 Hipnotic Interactive, Inc.
All rights reserved.
Distributed (unsupported) on 3.12.97
*/

-float USE_SILV_KEY = 8;
-float USE_GOLD_KEY = 16;
-
-//======================================================================
-// keytrigger_unlock
-//
-// Perform the actions which should be performed when self is successfully
-// unlocked with a key.
-//
-// This function exists so that it can be passed as an argument to the new
-// keylock_try_to_unlock function. This code was previously part of the
-// keytrigger_use function. -- iw
-//----------------------------------------------------------------------
-void() keytrigger_unlock =
-{
- // we can't just remove (self) here, because this is a touch
- // function called while C code is looping through area links...
- self.touch = SUB_Null;
- self.use = SUB_Null;
- self.nextthink = time + 0.1;
- self.think = SUB_Remove;
- self.message = "";
-
- SUB_UseTargets ();
-};
+// constants
+const float TRIGGER_USEKEY_SILV_KEY = 8;
+const float TRIGGER_USEKEY_GOLD_KEY = 16;

-//----------------------------------------------------------------------
-void() keytrigger_use =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+/*
+QUAKED trigger_usekey (0 .5 0) ? X X X
+TRIGGER_USEKEY_SILV_KEY TRIGGER_USEKEY_GOLD_KEY 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

- if (self.attack_finished > time)
- return;
-
- self.attack_finished = time + 2;
- keylock_try_to_unlock (activator, self.message, keytrigger_unlock);
-};
-
-//----------------------------------------------------------------------
-void() keytrigger_touch =
-{
- activator = other;
- keytrigger_use ();
-};
-
-/*QUAKED trigger_usekey (0 .5 0) ? X X X USE_SILV_KEY USE_GOLD_KEY 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
-
-Variable sized single use trigger that requires a key to trigger targets. Must be targeted at one or more entities.
+Variable sized single use trigger that requires a key to trigger
+targets. Must be targeted at one or more entities.

"cnt" if 1, leave a used key in the player's inventory (0 default).
-"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity.
+"keyname" if set, this is the keyname of the item_key_custom which unlocks
+ this entity.
"message" is printed when the trigger is touched without having the right key.
"noise1" sound file for the "key required" sound (default is per worldtype).
"noise2" sound file for the "key used" sound (default is per worldtype).
*/
-void() trigger_usekey =
+class trigger_usekey: base_trigger
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // the keylock_* functions use self.noise3 and self.noise4 internally,
- // but trigger_usekey doesn't use the self.noise1 or self.noise2 fields
- // for anything, so we allow the mapper to specify custom sound files by
- // setting self.noise1 and self.noise2, but we move those values into
- // self.noise3 and self.noise4 -- iw
- self.noise3 = self.noise1;
- self.noise4 = self.noise2;
- self.noise1 = "";
- self.noise2 = "";
-
- keylock_init ();
-
- if (self.spawnflags & USE_SILV_KEY)
+
+ //--------------------------------------------------------------
+ // trigger_usekey_unlock
+ //
+ // Perform the actions which should be performed when self is
+ // successfully unlocked with a key.
+ //
+ // This function exists so that it can be passed as an argument
+ // to the new keylock_try_to_unlock function. This code was
+ // previously part of the trigger_usekey_use function. -- iw
+ //--------------------------------------------------------------
+ virtual void() unlock =
+ {
+ // we can't just remove (self) here, because this is a
+ // touch function called while C code is looping through
+ // area links...
+ this.touch = SUB_Null;
+ this.use = SUB_Null;
+ this.nextthink = time + 0.1;
+ this.think = SUB_Remove;
+ this.message = "";
+
+ SUB_UseTargets ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() usekey_use =
{
- //dumptruck_ds
- keylock_set_silver_key ();
+ // from Copper -- dumptruck_ds
+ if (!CheckValidTouch())
+ return;

- if (self.keyname != "")
- {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
+ if (this.attack_finished > time)
+ return;
+
+ this.attack_finished = time + 2;
+ keylock_try_to_unlock (activator, this.message,
+ this.unlock);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() usekey_touch =
+ {
+ activator = other;
+ this.usekey_use ();
+ };

- if (self.spawnflags & USE_GOLD_KEY)
+ //--------------------------------------------------------------
+ void() trigger_usekey =
{
- //dumptruck_ds
- keylock_set_gold_key ();
-
- if (self.keyname != "")
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;
+
+ // the keylock_* functions use self.noise3 and self.noise4
+ // internally, but trigger_usekey doesn't use the self.noise1
+ // or self.noise2 fields for anything, so we allow the mapper
+ // to specify custom sound files by setting self.noise1 and
+ // self.noise2, but we move those values into self.noise3 and
+ // self.noise4 -- iw
+ this.noise3 = this.noise1;
+ this.noise4 = this.noise2;
+ this.noise1 = "";
+ this.noise2 = "";
+
+ keylock_init ();
+
+ if (this.spawnflags & TRIGGER_USEKEY_SILV_KEY)
{
- self.netname = self.keyname;
- self.keyname = "";
+ //dumptruck_ds
+ keylock_set_silver_key ();
+
+ if (this.keyname != "")
+ {
+ this.netname = this.keyname;
+ this.keyname = "";
+ }
}
- }

- // support for item_key_custom -- iw
- if (self.keyname != "")
- {
- keylock_set_custom_key (self.keyname);
- // this should not be referenced again
- self.keyname = "";
- }
+ if (this.spawnflags & TRIGGER_USEKEY_GOLD_KEY)
+ {
+ //dumptruck_ds
+ keylock_set_gold_key ();
+
+ if (this.keyname != "")
+ {
+ this.netname = this.keyname;
+ this.keyname = "";
+ }
+ }

- if (!keylock_has_key_set())
- {
- objerror ("no key specified!");
- return;
- }
+ // support for item_key_custom -- iw
+ if (this.keyname != "")
+ {
+ keylock_set_custom_key (this.keyname);
+ // this should not be referenced again
+ this.keyname = "";
+ }

- self.use = keytrigger_use;
- self.touch = keytrigger_touch;
+ if (!keylock_has_key_set())
+ {
+ objerror ("no key specified!");
+ return;
+ }

- InitTrigger ();
- SUB_CheckWaiting ();
+ this.classname = "trigger_usekey";
+ this.classtype = CT_TRIGGER_USEKEY;
+ this.touch = this.usekey_touch;
+ this.use = this.usekey_use;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/triggers/void.qc

diff --git a/qc/triggers/void.qc b/qc/triggers/void.qc
index 9ab4f4d..118b47f 100644
--- a/qc/triggers/void.qc
+++ b/qc/triggers/void.qc
@@ -2,63 +2,84 @@
// trigger_void
//==============================================================================

-//This is necros' trigger_void from Lost Chapters pack, modified by dumptruck_ds
+//======================================================================
+// This is necros' trigger_void from Lost Chapters pack, modified
+// by dumptruck_ds, modified again by CEV
+//======================================================================

// constants
-const float MONSTER_SAFE = 1;
-const float PLAYER_SAFE = 2;
+const float TRIGGER_VOID_MONSTER_SAFE = 1;
+const float TRIGGER_VOID_PLAYER_SAFE = 2;

-//----------------------------------------------------------------------
-void() trigger_void_touch =
+/*
+QUAKED trigger_void (.5 .5 .5) ? X X X X X X X X
+NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH
+NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+Use this for a 'void' area.
+Removes monsters, gibs, ammo, etc... also kills player.
+*/
+class trigger_void: base_trigger
{
- if (self.estate != STATE_ACTIVE)
- return;
-
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return FALSE;
+ //--------------------------------------------------------------
+ virtual void() void_touch =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

- if (self.spawnflags & MONSTER_SAFE && other.flags & FL_MONSTER)
- // ignore monsters
- return;
- if (self.spawnflags & PLAYER_SAFE && other.flags & FL_CLIENT)
- // ignore players
- return;
+ // from Copper -- dumptruck_ds
+ if (other.movetype == MOVETYPE_NOCLIP)
+ return FALSE;

- if (other.takedamage)
- {
- // kills even with Pentagram, this took forever to figure
- // out!! -- dumptruck_ds
- other.invincible_finished = 0;
- T_Damage (other, self, self, other.health + 1000);
+ if (this.spawnflags & TRIGGER_VOID_MONSTER_SAFE &&
+ other.flags & FL_MONSTER)
+ {
+ // ignore monsters
+ return;
+ }

- if (other.flags & FL_MONSTER)
- remove (other);
- }
+ if (this.spawnflags & TRIGGER_VOID_PLAYER_SAFE &&
+ other.flags & FL_CLIENT)
+ {
+ // ignore players
+ return;
+ }

- if (other.classname == "gib" || other.classname == "grenade" ||
- other.classname == "spike" || other.classname == "missile")
- {
- remove (other);
- }
+ if (other.takedamage)
+ {
+ // kills even with Pentagram, this took forever to
+ // figure out!! -- dumptruck_ds
+ other.invincible_finished = 0;
+ T_Damage (other, this, this, other.health + 1000);
+
+ if (other.flags & FL_MONSTER)
+ remove (other);
+ }

- if (other.flags & FL_ITEM)
- remove (other);
+ if (other.classname == "gib" ||
+ other.classname == "grenade" ||
+ other.classname == "spike" ||
+ other.classname == "missile")
+ {
+ remove (other);
+ }

- force_retouch = 2;
-};
+ if (other.flags & FL_ITEM)
+ remove (other);

-/*QUAKED trigger_void (.5 .5 .5) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-Use this for a 'void' area. removes monsters, gibs, ammo, etc... also kills player.
-*/
-void() trigger_void =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ force_retouch = 2;
+ };

- InitTrigger ();
- self.touch = trigger_void_touch;
+ //--------------------------------------------------------------
+ void() trigger_void =
+ {
+ // new spawnflags for all entities -- iw
+ if (SUB_Inhibit())
+ return;

- SUB_CheckWaiting ();
+ this.classname = "trigger_void";
+ this.classtype = CT_TRIGGER_VOID;
+ this.touch = this.void_touch;
+ init_trigger ();
+ SUB_CheckWaiting ();
+ };
};

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

Diff qc/weapons.qc

diff --git a/qc/weapons.qc b/qc/weapons.qc
index 3cbb724..071b761 100644
--- a/qc/weapons.qc
+++ b/qc/weapons.qc
@@ -1,14 +1,6 @@
-/*==============================================================================
- WEAPONS.QC
-==============================================================================*/
-
-void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
-void() player_run;
-void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
-void(vector org, vector vel, float damage) SpawnBlood;
-void() SuperDamageSound;
-void() create_mobot; // dumptruck_ds mobot.qc
-void(entity mis, float speed) SetupHoming;
+//==============================================================================
+// WEAPONS.QC
+//==============================================================================

void(entity mis, vector dir, float speed) SetSpeed =
{
@@ -22,211 +14,11 @@ void(entity mis, vector dir, float speed) SetSpeed =
}
};

-//======================================================================
-// W_Precache called by worldspawn
-//----------------------------------------------------------------------
-void() W_Precache =
-{
- precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
- precache_sound ("weapons/rocket1i.wav");// spike gun
- precache_sound ("weapons/sgun1.wav");
- precache_sound ("weapons/guncock.wav"); // player shotgun
- precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
- precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
- precache_sound ("weapons/spike2.wav"); // super spikes
- precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
- precache_sound ("weapons/grenade.wav"); // grenade launcher
- precache_sound ("weapons/bounce.wav"); // grenade bounce
- precache_sound ("weapons/shotgn2.wav"); // super shotgun
-
- // dumptruck_ds mobot.qc precaches START
- precache_model ("progs/ogre.mdl");
- precache_model ("progs/h_ogre.mdl");
- precache_model ("progs/grenade.mdl");
- precache_sound ("ogre/ogdrag.wav");
- precache_sound ("ogre/ogdth.wav");
- precache_sound ("ogre/ogidle.wav");
- precache_sound ("ogre/ogidle2.wav");
- precache_sound ("ogre/ogpain1.wav");
- precache_sound ("ogre/ogsawatk.wav");
- precache_sound ("ogre/ogwake.wav");
-
- precache_model ("progs/demon.mdl");
- precache_model ("progs/h_demon.mdl");
-
- precache_sound ("demon/ddeath.wav");
- precache_sound ("demon/dhit2.wav");
- precache_sound ("demon/djump.wav");
- precache_sound ("demon/dpain1.wav");
- precache_sound ("demon/idle1.wav");
- precache_sound ("demon/sight2.wav");
-
- precache_model2 ("progs/enforcer.mdl");
- precache_model2 ("progs/h_mega.mdl");
- precache_model2 ("progs/laser.mdl");
- precache_model2 ("progs/s_spike.mdl");
-
- precache_sound2 ("enforcer/death1.wav");
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- precache_sound2 ("enforcer/idle1.wav");
- precache_sound2 ("enforcer/pain1.wav");
- precache_sound2 ("enforcer/pain2.wav");
- precache_sound2 ("enforcer/sight1.wav");
- precache_sound2 ("enforcer/sight2.wav");
- precache_sound2 ("enforcer/sight3.wav");
- precache_sound2 ("enforcer/sight4.wav");
-
- precache_model ("progs/soldier.mdl");
- precache_model ("progs/h_guard.mdl");
-
- precache_model ("progs/gib1.mdl");
- precache_model ("progs/gib2.mdl");
- precache_model ("progs/gib3.mdl");
-
- precache_sound ("soldier/death1.wav");
- precache_sound ("soldier/idle.wav");
- precache_sound ("soldier/pain1.wav");
- precache_sound ("soldier/pain2.wav");
- precache_sound ("soldier/sattck1.wav");
- precache_sound ("soldier/sight1.wav");
- precache_sound ("player/udeath.wav"); // gib death
-
- precache_model ("progs/h_dog.mdl");
- precache_model ("progs/dog.mdl");
- precache_sound ("dog/dattack1.wav");
- precache_sound ("dog/ddeath.wav");
- precache_sound ("dog/dpain1.wav");
- precache_sound ("dog/dsight.wav");
- precache_sound ("dog/idle.wav");
-
- precache_model ("progs/wizard.mdl");
- precache_model ("progs/h_wizard.mdl");
- precache_model ("progs/w_spike.mdl");
-
- precache_sound ("wizard/hit.wav"); // used by c code
- precache_sound ("wizard/wattack.wav");
- precache_sound ("wizard/wdeath.wav");
- precache_sound ("wizard/widle1.wav");
- precache_sound ("wizard/widle2.wav");
- precache_sound ("wizard/wpain.wav");
- precache_sound ("wizard/wsight.wav");
-
- precache_model2 ("progs/shalrath.mdl");
- precache_model2 ("progs/h_shal.mdl");
- precache_model2 ("progs/v_spike.mdl");
-
- precache_sound2 ("shalrath/attack.wav");
- precache_sound2 ("shalrath/attack2.wav");
- precache_sound2 ("shalrath/death.wav");
- precache_sound2 ("shalrath/idle.wav");
- precache_sound2 ("shalrath/pain.wav");
- precache_sound2 ("shalrath/sight.wav");
-
- precache_model ("progs/knight.mdl");
- precache_model ("progs/h_knight.mdl");
-
- precache_sound ("knight/kdeath.wav");
- precache_sound ("knight/khurt.wav");
- precache_sound ("knight/ksight.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
- precache_sound ("knight/idle.wav");
-
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/k_spike.mdl");
- precache_model2 ("progs/k_spike2.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/hknight.mdl");
- precache_model2 ("progs/h_hellkn.mdl");
- precache_model2 ("progs/k_spike.mdl");
-
- precache_sound2 ("hknight/attack1.wav");
- precache_sound2 ("hknight/death1.wav");
- precache_sound2 ("hknight/pain1.wav");
- precache_sound2 ("hknight/sight1.wav");
- precache_sound ("hknight/hit.wav"); // used by C code; don't sound2
- precache_sound2 ("hknight/slash1.wav");
- precache_sound2 ("hknight/idle.wav");
- precache_sound2 ("hknight/grunt.wav");
- precache_sound ("knight/sword1.wav");
- precache_sound ("knight/sword2.wav");
-
- precache_sound2 ("blob/death1.wav");
- precache_sound2 ("blob/hit1.wav");
- precache_sound2 ("blob/land1.wav");
- precache_sound2 ("blob/sight1.wav");
-
- precache_model ("progs/zombie.mdl");
- precache_model ("progs/h_zombie.mdl");
- precache_model ("progs/zom_gib.mdl");
-
- precache_sound ("zombie/z_idle.wav");
- precache_sound ("zombie/z_idle1.wav");
- precache_sound ("zombie/z_shot1.wav");
- precache_sound ("zombie/z_gib.wav");
- precache_sound ("zombie/z_pain.wav");
- precache_sound ("zombie/z_pain1.wav");
- precache_sound ("zombie/z_fall.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- precache_sound ("zombie/idle_w2.wav");
-
- precache_model ("progs/shambler.mdl");
- precache_model ("progs/s_light.mdl");
- precache_model ("progs/h_shams.mdl");
- precache_model ("progs/bolt.mdl");
-
- precache_sound ("shambler/sattck1.wav");
- precache_sound ("shambler/sboom.wav");
- precache_sound ("shambler/sdeath.wav");
- precache_sound ("shambler/shurt2.wav");
- precache_sound ("shambler/sidle.wav");
- precache_sound ("shambler/ssight.wav");
- precache_sound ("shambler/melee1.wav");
- precache_sound ("shambler/melee2.wav");
- precache_sound ("shambler/smack.wav");
- // dumptruck_ds mobot.qc END
-};
-
float() crandom =
{
return 2 * (random () - 0.5);
};

-//======================================================================
-// W_FireAxe
-//----------------------------------------------------------------------
-void() W_FireAxe =
-{
- local vector source;
- local vector org;
-
- makevectors (self.v_angle);
- source = self.origin + '0 0 16';
- traceline (source, source + v_forward * 64, FALSE, self);
- if (trace_fraction == 1.0)
- return;
- org = trace_endpos - v_forward * 4;
-
- if (trace_ent.takedamage)
- {
- trace_ent.axhitme = 1;
- SpawnBlood (org, '0 0 0', 20);
- T_Damage (trace_ent, self, self, 20);
- }
- else
- { // hit wall
- sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_GUNSHOT);
- WriteCoord (MSG_BROADCAST, org_x);
- WriteCoord (MSG_BROADCAST, org_y);
- WriteCoord (MSG_BROADCAST, org_z);
- }
-};
-
//----------------------------------------------------------------------
vector() wall_velocity =
{
@@ -241,7 +33,7 @@ vector() wall_velocity =
};


-//======================================================================
+//----------------------------------------------------------------------
// SpawnMeatSpray
//----------------------------------------------------------------------
void(vector org, vector vel) SpawnMeatSpray =
@@ -269,7 +61,7 @@ void(vector org, vector vel) SpawnMeatSpray =
setorigin (missile, org);
};

-//======================================================================
+//----------------------------------------------------------------------
// SpawnBlood
//----------------------------------------------------------------------
void(vector org, vector vel, float damage) SpawnBlood =
@@ -277,7 +69,7 @@ void(vector org, vector vel, float damage) SpawnBlood =
particle (org, vel * 0.1, 73, damage * 2);
};

-//======================================================================
+//----------------------------------------------------------------------
// spawn_touchblood
//----------------------------------------------------------------------
void(float damage) spawn_touchblood =
@@ -288,7 +80,7 @@ void(float damage) spawn_touchblood =
SpawnBlood (self.origin + vel* 0.01, vel, damage);
};

-//======================================================================
+//----------------------------------------------------------------------
// SpawnChunk
//----------------------------------------------------------------------
void(vector org, vector vel) SpawnChunk =
@@ -335,13 +127,9 @@ void(entity hit, float damage) AddMultiDamage =

// TODO CEV

-/*
-==============================================================================
-
-BULLETS
-
-==============================================================================
-*/
+//======================================================================
+// Shotguns
+//======================================================================

/*
================
@@ -373,9 +161,8 @@ void(float damage, vector dir) TraceAttack =
}
};

-//======================================================================
+//----------------------------------------------------------------------
// FireBullets
-//
// Used by shotgun, super shotgun, and enemy soldier firing. Go to the
// trouble of combining multiple pellets into a single damage call.
//----------------------------------------------------------------------
@@ -405,7 +192,7 @@ void(float shotcount, vector dir, vector spread) FireBullets =
ApplyMultiDamage ();
};

-//======================================================================
+//----------------------------------------------------------------------
// W_FireShotgun
//----------------------------------------------------------------------
void() W_FireShotgun =
@@ -447,21 +234,16 @@ void() W_FireSuperShotgun =
FireBullets (14, dir, '0.14 0.08 0');
};

+//======================================================================
+// Rockets
+//======================================================================

-/*
-==============================================================================
-
-ROCKETS
-
-==============================================================================
-*/
-
-void() s_explode1 = [0, s_explode2] {};
-void() s_explode2 = [1, s_explode3] {};
-void() s_explode3 = [2, s_explode4] {};
-void() s_explode4 = [3, s_explode5] {};
-void() s_explode5 = [4, s_explode6] {};
-void() s_explode6 = [5, SUB_Remove] {};
+void() s_explode1 = [0, s_explode2] { };
+void() s_explode2 = [1, s_explode3] { };
+void() s_explode3 = [2, s_explode4] { };
+void() s_explode4 = [3, s_explode5] { };
+void() s_explode5 = [4, s_explode6] { };
+void() s_explode6 = [5, SUB_Remove] { };

void() BecomeExplosion =
{
@@ -681,13 +463,9 @@ void() W_GruntRocket =

//end dumptruck_ds grunt missle end

-/*
-===============================================================================
-
-LIGHTNING
-
-===============================================================================
-*/
+//======================================================================
+// Lightning
+//======================================================================

/*
=================
@@ -745,17 +523,21 @@ void() W_FireLightning =

if (self.ammo_cells < 1)
{
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
+ if (self.classname == "player")
+ {
+ self.weapon = PlayerBestWeapon ();
+ PlayerSetCurrentAmmo ();
+ }
return;
}

-// explode if under water
- if (self.waterlevel > 1)
+ // explode if under water
+ if (self.waterlevel > WATERLEVEL_FEET)
{
cells = self.ammo_cells;
self.ammo_cells = 0;
- W_SetCurrentAmmo ();
+ if (self.classname == "player")
+ PlayerSetCurrentAmmo ();
T_RadiusDamage (self, self, 35*cells, world);
return;
}
@@ -791,6 +573,9 @@ void() W_FireLightning =

//=============================================================================

+//======================================================================
+// Grenades
+//======================================================================

/*
================
@@ -942,10 +727,13 @@ void() W_FireGrenade =

//=============================================================================

+//======================================================================
+// Nails
+//======================================================================
+
void() spike_touch;
void() superspike_touch;

-
/*
===============
launch_spike
@@ -1012,8 +800,11 @@ void(float ox) W_FireSpikes =

if (self.ammo_nails < 1)
{
- self.weapon = W_BestWeapon ();
- W_SetCurrentAmmo ();
+ if (self.classname == "player")
+ {
+ self.weapon = PlayerBestWeapon ();
+ PlayerSetCurrentAmmo ();
+ }
return;
}

@@ -1025,10 +816,7 @@ void(float ox) W_FireSpikes =
launch_spike (self.origin + self.view_ofs + v_up * -8 + v_right*ox, dir); //seven Nailgun position fix - thanks to Greenwood -- dumptruck_ds

self.punchangle_x = -2;
-
- };
-
-
+};

void() spike_touch =
{
@@ -1159,449 +947,6 @@ PLAYER WEAPON USE
===============================================================================
*/

-void() W_SetCurrentAmmo =
-{
- player_run (); // get out of any weapon firing states
-
- self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
-
- if (self.weapon == IT_AXE)
- {
- self.currentammo = 0;
- self.weaponmodel = "progs/v_axe.mdl";
- self.weaponframe = 0;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.currentammo = self.ammo_shells;
- self.weaponmodel = "progs/v_shot2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_SHELLS;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.currentammo = self.ammo_nails;
- self.weaponmodel = "progs/v_nail2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_NAILS;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.currentammo = self.ammo_rockets;
- self.weaponmodel = "progs/v_rock2.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_ROCKETS;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- self.currentammo = self.ammo_cells;
- self.weaponmodel = "progs/v_light.mdl";
- self.weaponframe = 0;
- self.items = self.items | IT_CELLS;
- }
- else
- {
- self.currentammo = 0;
- self.weaponmodel = "";
- self.weaponframe = 0;
- }
-};
-
-float() W_BestWeapon =
-{
- local float it;
-
- it = self.items;
-
- if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
- return IT_LIGHTNING;
- if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
- return IT_SUPER_NAILGUN;
- if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
- return IT_SUPER_SHOTGUN;
- if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
- return IT_NAILGUN;
- if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
- return IT_SHOTGUN;
- return IT_AXE;
-};
-
-float() W_CheckNoAmmo =
-{
- if (self.currentammo > 0)
- return TRUE;
-
- if (self.weapon == IT_AXE)
- return TRUE;
-
- self.weapon = W_BestWeapon ();
-
- W_SetCurrentAmmo ();
-
-// drop the weapon down
- return FALSE;
-};
-
-/*
-============
-W_Attack
-
-An attack impulse can be triggered now
-============
-*/
-void() player_axe1;
-void() player_axeb1;
-void() player_axec1;
-void() player_axed1;
-void() player_shot1;
-void() player_nail1;
-void() player_light1;
-void() player_rocket1;
-
-void() W_Attack =
-{
- local float r;
-
- if (!W_CheckNoAmmo ())
- return;
-
- makevectors (self.v_angle); // calculate forward angle for velocity
- self.show_hostile = time + 1; // wake monsters up
-
- if (self.weapon == IT_AXE)
- {
- sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
- r = random();
- if (r < 0.25)
- player_axe1 ();
- else if (r<0.5)
- player_axeb1 ();
- else if (r<0.75)
- player_axec1 ();
- else
- player_axed1 ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- player_shot1 ();
- W_FireShotgun ();
- self.attack_finished = time + 0.5;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- player_shot1 ();
- W_FireSuperShotgun ();
- self.attack_finished = time + 0.7;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- player_nail1 ();
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- player_rocket1();
- W_FireGrenade();
- self.attack_finished = time + 0.6;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- player_rocket1();
- W_FireRocket();
- self.attack_finished = time + 0.8;
- }
- else if (self.weapon == IT_LIGHTNING)
- {
- player_light1();
- self.attack_finished = time + 0.1;
- sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
- }
-};
-
-/*
-============
-W_ChangeWeapon
-
-============
-*/
-void() W_ChangeWeapon =
-{
- local float it, am, fl;
-
- it = self.items;
- am = 0;
-
- if (self.impulse == 1)
- {
- fl = IT_AXE;
- }
- else if (self.impulse == 2)
- {
- fl = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.impulse == 3)
- {
- fl = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.impulse == 4)
- {
- fl = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.impulse == 5)
- {
- fl = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.impulse == 6)
- {
- fl = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 7)
- {
- fl = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.impulse == 8)
- {
- fl = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
- else
- {
- dprint ("WARNING: W_ChangeWeapon: bad impulse: ");
- dprint (ftos (self.impulse));
- dprint ("\n");
- return;
- }
-
- self.impulse = 0;
-
- if (!(self.items & fl))
- { // don't have the weapon or the ammo
- sprint (self, "no weapon.\n");
- return;
- }
-
- if (am)
- { // don't have the ammo
- sprint (self, "not enough ammo.\n");
- return;
- }
-
-//
-// set weapon, set ammo
-//
- self.weapon = fl;
- W_SetCurrentAmmo ();
-};
-
-/*
-============
-CycleWeaponCommand
-
-Go to the next weapon with ammo
-============
-*/
-void() CycleWeaponCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-CycleWeaponReverseCommand
-
-Go to the prev weapon with ammo
-============
-*/
-void() CycleWeaponReverseCommand =
-{
- local float it, am;
-
- it = self.items;
- self.impulse = 0;
-
- while (1)
- {
- am = 0;
-
- if (self.weapon == IT_LIGHTNING)
- {
- self.weapon = IT_ROCKET_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_ROCKET_LAUNCHER)
- {
- self.weapon = IT_GRENADE_LAUNCHER;
- if (self.ammo_rockets < 1)
- am = 1;
- }
- else if (self.weapon == IT_GRENADE_LAUNCHER)
- {
- self.weapon = IT_SUPER_NAILGUN;
- if (self.ammo_nails < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_NAILGUN)
- {
- self.weapon = IT_NAILGUN;
- if (self.ammo_nails < 1)
- am = 1;
- }
- else if (self.weapon == IT_NAILGUN)
- {
- self.weapon = IT_SUPER_SHOTGUN;
- if (self.ammo_shells < 2)
- am = 1;
- }
- else if (self.weapon == IT_SUPER_SHOTGUN)
- {
- self.weapon = IT_SHOTGUN;
- if (self.ammo_shells < 1)
- am = 1;
- }
- else if (self.weapon == IT_SHOTGUN)
- {
- self.weapon = IT_AXE;
- }
- else if (self.weapon == IT_AXE)
- {
- self.weapon = IT_LIGHTNING;
- if (self.ammo_cells < 1)
- am = 1;
- }
-
- if ( (it & self.weapon) && am == 0)
- {
- W_SetCurrentAmmo ();
- return;
- }
- }
-
-};
-
-/*
-============
-W_WeaponFrame
-
-Called every frame so impulse events can be handled as well as possible
-============
-*/
-void() W_WeaponFrame =
-{
- if (time < self.attack_finished)
- return;
-
-if (self.impulse) // 1998-08-14 Constantly checking all impulses fix by Perged
- ImpulseCommands ();
-
-// check for attack
- if (self.button0)
- {
- SuperDamageSound ();
- W_Attack ();
- }
-};
-
/*
========
SuperDamageSound

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

Diff qc/world.qc

diff --git a/qc/world.qc b/qc/world.qc
index c349420..7160f97 100644
--- a/qc/world.qc
+++ b/qc/world.qc
@@ -2,6 +2,10 @@
// WORLD
//==============================================================================

+// globals
+entity bodyque_head;
+entity lastspawn;
+
// prototypes
void() InitBodyQue;

@@ -155,7 +159,175 @@ void() main =
precache_file2 ("maps/dm6.bsp");
};

-//======================================================================
+//----------------------------------------------------------------------
+// WeaponPrecache -- was W_Precache; called by worldspawn
+//----------------------------------------------------------------------
+void() WeaponPrecache =
+{
+ precache_sound ("weapons/r_exp3.wav"); // new rocket explosion
+ precache_sound ("weapons/rocket1i.wav");// spike gun
+ precache_sound ("weapons/sgun1.wav");
+ precache_sound ("weapons/guncock.wav"); // player shotgun
+ precache_sound ("weapons/ric1.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric2.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/ric3.wav"); // ricochet (used in c code)
+ precache_sound ("weapons/spike2.wav"); // super spikes
+ precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code)
+ precache_sound ("weapons/grenade.wav"); // grenade launcher
+ precache_sound ("weapons/bounce.wav"); // grenade bounce
+ precache_sound ("weapons/shotgn2.wav"); // super shotgun
+
+ // dumptruck_ds mobot.qc precaches START
+ precache_model ("progs/ogre.mdl");
+ precache_model ("progs/h_ogre.mdl");
+ precache_model ("progs/grenade.mdl");
+ precache_sound ("ogre/ogdrag.wav");
+ precache_sound ("ogre/ogdth.wav");
+ precache_sound ("ogre/ogidle.wav");
+ precache_sound ("ogre/ogidle2.wav");
+ precache_sound ("ogre/ogpain1.wav");
+ precache_sound ("ogre/ogsawatk.wav");
+ precache_sound ("ogre/ogwake.wav");
+
+ precache_model ("progs/demon.mdl");
+ precache_model ("progs/h_demon.mdl");
+
+ precache_sound ("demon/ddeath.wav");
+ precache_sound ("demon/dhit2.wav");
+ precache_sound ("demon/djump.wav");
+ precache_sound ("demon/dpain1.wav");
+ precache_sound ("demon/idle1.wav");
+ precache_sound ("demon/sight2.wav");
+
+ precache_model2 ("progs/enforcer.mdl");
+ precache_model2 ("progs/h_mega.mdl");
+ precache_model2 ("progs/laser.mdl");
+ precache_model2 ("progs/s_spike.mdl");
+
+ precache_sound2 ("enforcer/death1.wav");
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ precache_sound2 ("enforcer/idle1.wav");
+ precache_sound2 ("enforcer/pain1.wav");
+ precache_sound2 ("enforcer/pain2.wav");
+ precache_sound2 ("enforcer/sight1.wav");
+ precache_sound2 ("enforcer/sight2.wav");
+ precache_sound2 ("enforcer/sight3.wav");
+ precache_sound2 ("enforcer/sight4.wav");
+
+ precache_model ("progs/soldier.mdl");
+ precache_model ("progs/h_guard.mdl");
+
+ precache_model ("progs/gib1.mdl");
+ precache_model ("progs/gib2.mdl");
+ precache_model ("progs/gib3.mdl");
+
+ precache_sound ("soldier/death1.wav");
+ precache_sound ("soldier/idle.wav");
+ precache_sound ("soldier/pain1.wav");
+ precache_sound ("soldier/pain2.wav");
+ precache_sound ("soldier/sattck1.wav");
+ precache_sound ("soldier/sight1.wav");
+ precache_sound ("player/udeath.wav"); // gib death
+
+ precache_model ("progs/h_dog.mdl");
+ precache_model ("progs/dog.mdl");
+ precache_sound ("dog/dattack1.wav");
+ precache_sound ("dog/ddeath.wav");
+ precache_sound ("dog/dpain1.wav");
+ precache_sound ("dog/dsight.wav");
+ precache_sound ("dog/idle.wav");
+
+ precache_model ("progs/wizard.mdl");
+ precache_model ("progs/h_wizard.mdl");
+ precache_model ("progs/w_spike.mdl");
+
+ precache_sound ("wizard/hit.wav"); // used by c code
+ precache_sound ("wizard/wattack.wav");
+ precache_sound ("wizard/wdeath.wav");
+ precache_sound ("wizard/widle1.wav");
+ precache_sound ("wizard/widle2.wav");
+ precache_sound ("wizard/wpain.wav");
+ precache_sound ("wizard/wsight.wav");
+
+ precache_model2 ("progs/shalrath.mdl");
+ precache_model2 ("progs/h_shal.mdl");
+ precache_model2 ("progs/v_spike.mdl");
+
+ precache_sound2 ("shalrath/attack.wav");
+ precache_sound2 ("shalrath/attack2.wav");
+ precache_sound2 ("shalrath/death.wav");
+ precache_sound2 ("shalrath/idle.wav");
+ precache_sound2 ("shalrath/pain.wav");
+ precache_sound2 ("shalrath/sight.wav");
+
+ precache_model ("progs/knight.mdl");
+ precache_model ("progs/h_knight.mdl");
+
+ precache_sound ("knight/kdeath.wav");
+ precache_sound ("knight/khurt.wav");
+ precache_sound ("knight/ksight.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+ precache_sound ("knight/idle.wav");
+
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+ precache_model2 ("progs/k_spike2.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/hknight.mdl");
+ precache_model2 ("progs/h_hellkn.mdl");
+ precache_model2 ("progs/k_spike.mdl");
+
+ precache_sound2 ("hknight/attack1.wav");
+ precache_sound2 ("hknight/death1.wav");
+ precache_sound2 ("hknight/pain1.wav");
+ precache_sound2 ("hknight/sight1.wav");
+ precache_sound ("hknight/hit.wav"); // used by C code; don't sound2
+ precache_sound2 ("hknight/slash1.wav");
+ precache_sound2 ("hknight/idle.wav");
+ precache_sound2 ("hknight/grunt.wav");
+ precache_sound ("knight/sword1.wav");
+ precache_sound ("knight/sword2.wav");
+
+ precache_sound2 ("blob/death1.wav");
+ precache_sound2 ("blob/hit1.wav");
+ precache_sound2 ("blob/land1.wav");
+ precache_sound2 ("blob/sight1.wav");
+
+ precache_model ("progs/zombie.mdl");
+ precache_model ("progs/h_zombie.mdl");
+ precache_model ("progs/zom_gib.mdl");
+
+ precache_sound ("zombie/z_idle.wav");
+ precache_sound ("zombie/z_idle1.wav");
+ precache_sound ("zombie/z_shot1.wav");
+ precache_sound ("zombie/z_gib.wav");
+ precache_sound ("zombie/z_pain.wav");
+ precache_sound ("zombie/z_pain1.wav");
+ precache_sound ("zombie/z_fall.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ precache_sound ("zombie/idle_w2.wav");
+
+ precache_model ("progs/shambler.mdl");
+ precache_model ("progs/s_light.mdl");
+ precache_model ("progs/h_shams.mdl");
+ precache_model ("progs/bolt.mdl");
+
+ precache_sound ("shambler/sattck1.wav");
+ precache_sound ("shambler/sboom.wav");
+ precache_sound ("shambler/sdeath.wav");
+ precache_sound ("shambler/shurt2.wav");
+ precache_sound ("shambler/sidle.wav");
+ precache_sound ("shambler/ssight.wav");
+ precache_sound ("shambler/melee1.wav");
+ precache_sound ("shambler/melee2.wav");
+ precache_sound ("shambler/smack.wav");
+ // dumptruck_ds mobot.qc END
+};
+
+//----------------------------------------------------------------------
// DetectKnownRelease
// This detects whether the current map is from a known release for which
// a backwards-compatibility hack should be applied, and sets the
@@ -168,42 +340,20 @@ void() DetectKnownRelease =
known_release = KNOWN_RELEASE_NOT;
release_name = "";

- if (mapname == "dm1" ||
- mapname == "dm2" ||
- mapname == "dm3" ||
- mapname == "dm4" ||
- mapname == "dm5" ||
- mapname == "dm6" ||
- mapname == "e1m1" ||
- mapname == "e1m2" ||
- mapname == "e1m3" ||
- mapname == "e1m4" ||
- mapname == "e1m5" ||
- mapname == "e1m6" ||
- mapname == "e1m7" ||
- mapname == "e1m8" ||
- mapname == "e2m1" ||
- mapname == "e2m2" ||
- mapname == "e2m3" ||
- mapname == "e2m4" ||
- mapname == "e2m5" ||
- mapname == "e2m6" ||
+ if (mapname == "dm1" || mapname == "dm2" || mapname == "dm3" ||
+ mapname == "dm4" || mapname == "dm5" || mapname == "dm6" ||
+ mapname == "e1m1" || mapname == "e1m2" || mapname == "e1m3" ||
+ mapname == "e1m4" || mapname == "e1m5" || mapname == "e1m6" ||
+ mapname == "e1m7" || mapname == "e1m8" ||
+ mapname == "e2m1" || mapname == "e2m2" || mapname == "e2m3" ||
+ mapname == "e2m4" || mapname == "e2m5" || mapname == "e2m6" ||
mapname == "e2m7" ||
- mapname == "e3m1" ||
- mapname == "e3m2" ||
- mapname == "e3m3" ||
- mapname == "e3m4" ||
- mapname == "e3m5" ||
- mapname == "e3m6" ||
+ mapname == "e3m1" || mapname == "e3m2" || mapname == "e3m3" ||
+ mapname == "e3m4" || mapname == "e3m5" || mapname == "e3m6" ||
mapname == "e3m7" ||
- mapname == "e4m1" ||
- mapname == "e4m2" ||
- mapname == "e4m3" ||
- mapname == "e4m4" ||
- mapname == "e4m5" ||
- mapname == "e4m6" ||
- mapname == "e4m7" ||
- mapname == "e4m8" ||
+ mapname == "e4m1" || mapname == "e4m2" || mapname == "e4m3" ||
+ mapname == "e4m4" || mapname == "e4m5" || mapname == "e4m6" ||
+ mapname == "e4m7" || mapname == "e4m8" ||
mapname == "end" ||
(mapname == "start" && world.message == "Introduction"))
{
@@ -211,21 +361,14 @@ void() DetectKnownRelease =
release_name = "id1";
}

- if (mapname == "jamx_artistical" ||
- mapname == "jamx_bloodshot" ||
- mapname == "jamx_fw" ||
- mapname == "jamx_hcm" ||
- mapname == "jamx_ionous" ||
- mapname == "jamx_jcr" ||
- mapname == "jamx_kalebclark" ||
- mapname == "jamx_mafon" ||
- //mapname == "jamx_mugwump" || // dummy map
- mapname == "jamx_naitelveni" ||
- mapname == "jamx_newhouse" ||
- mapname == "jamx_pinchy" ||
- mapname == "jamx_strwrk" ||
- mapname == "jamx_ukko" ||
- mapname == "jamx_yoder" ||
+ if (mapname == "jamx_artistical" || mapname == "jamx_bloodshot" ||
+ mapname == "jamx_fw" || mapname == "jamx_hcm" ||
+ mapname == "jamx_ionous" || mapname == "jamx_jcr" ||
+ mapname == "jamx_kalebclark" || mapname == "jamx_mafon" ||
+ // mapname == "jamx_mugwump" || // dummy map
+ mapname == "jamx_naitelveni" || mapname == "jamx_newhouse" ||
+ mapname == "jamx_pinchy" || mapname == "jamx_strwrk" ||
+ mapname == "jamx_ukko" || mapname == "jamx_yoder" ||
(mapname == "start" && world.message == "An Unending Dusk"))
{
known_release = KNOWN_RELEASE_FUNC_MAPJAMX;
@@ -240,8 +383,6 @@ void() DetectKnownRelease =
}
};

-entity lastspawn;
-
/*QUAKED worldspawn (0 0 0) ?
Only used for the world entity.

@@ -322,8 +463,9 @@ void() worldspawn =
InitNewSpawnflags ();

lastspawn = world;
-
InitBodyQue ();
+ self.classname = "world";
+ self.classtype = CT_WORLD;

// custom map attributes
if (self.model == "maps/e1m8.bsp" && self.skip_id1_overrides == 0)
@@ -339,9 +481,8 @@ void() worldspawn =

// the area based ambient sounds MUST be the first precache_sounds

- // player precaches
- // get weapon precaches
- W_Precache ();
+ // player precaches; get weapon precaches
+ WeaponPrecache ();

// sounds used from C physics code
precache_sound_land ("demon/dland2.wav"); // landing thud
@@ -476,7 +617,8 @@ void() worldspawn =
precache_model2 ("progs/b_g_key.mdl");
precache_model ("progs/health/pd_vial.mdl"); // DropVial -- dumptruck_ds
precache_sound ("items/r_item1.wav");
- precache_sound ("dump/armsh1.wav"); // DropShard -- dumptruck_ds
+ precache_sound ("items/armor_shard_q3.wav"); // DropShard - dumptruck_ds
+ precache_sound ("items/item_respawn_q3.wav"); // CEV
precache_model ("progs/armshr.mdl");

// Setup light anim tables. 'a' is total darkness, 'z' is maxbright.
@@ -571,11 +713,9 @@ void() StartFrame =
}
};

-/*==============================================================================
- BODY QUE
-==============================================================================*/
-
-entity bodyque_head;
+//======================================================================
+// BODY QUE
+//======================================================================

//----------------------------------------------------------------------
void() bodyque =
@@ -598,11 +738,9 @@ void() InitBodyQue =
bodyque_head.owner.owner.owner.owner = bodyque_head;
};

-//======================================================================
-// CopyToBodyQue
-//
-// make a body que entry for the given ent so the ent can be
-// respawned elsewhere
+//----------------------------------------------------------------------
+// CopyToBodyQue -- make a body que entry for the given ent so the ent
+// can be respawned elsewhere
//----------------------------------------------------------------------
void(entity ent) CopyToBodyQue =
{

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

Diff sound/items/armor_shard_q3.wav

diff --git a/sound/items/armor_shard_q3.wav b/sound/items/armor_shard_q3.wav
new file mode 100644
index 0000000..fa6da69
Binary files /dev/null and b/sound/items/armor_shard_q3.wav differ

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

Diff sound/items/item_respawn_q3.wav

diff --git a/sound/items/item_respawn_q3.wav b/sound/items/item_respawn_q3.wav
new file mode 100644
index 0000000..03cf43b
Binary files /dev/null and b/sound/items/item_respawn_q3.wav differ

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