djcev.com

//

Git Repos / fte_dogmode / commit bbf96f9

Commit: bbf96f9961a27e963287adaab8306c9b87de20c3
Parent: 9ed77a98ac7b77f00bb9316145097040cb0e17e3
Author: Cameron Vanderzanden, 2024-01-09 11:09
Committer: Cameron Vanderzanden, 2024-01-09 11:09

Commit Message

Continue OO / Class-based refactor

Another big commit that's been a long time coming. Again this is
incomplete, in-process; there are a number of known bugs.

I've further refactored entities (func/ & misc/ & trigger/ mainly)
into object-oriented QuakeC for use with FTEQW. blocked(), think(),
touch(), and use() are no longer assigned & re-assigned during
execution. Many SUB_ functions and other helper functions have
been moved into relevant base classes (SUB_UseTargets in base_entity
for example). This work is ongoing as I get to more entity types
(items are next, then monsters).

Current significant bugs include: the camera and cutscene system
still needs to be refactored, modeltrain has odd bugs (and should
be reworked), monster oldone causes crash when loading end.bsp,
misc_teleporttrain causes crash when loading dmd8.bsp .

I've also messed around with some of the movement constants (trying
to scale back on the speed a bit).

Change List

?File Add Del
M qc/ai.qc -17
A qc/base_entities.qc +484
A qc/base_func.qc +133
A qc/base_item.qc +64
A qc/base_monster.qc +12
A qc/base_trigger.qc +118
D qc/classes/base_trigger.qc -46
M qc/client/intermission.qc +5 -16
M qc/client/maprules.qc +2 -1
M qc/combat.qc +121 -81
M qc/csqc/csqc_hudvanilla.qc +1 -1
M qc/csqc/csqc_progs.src +2 -2
M qc/cutscene.qc +4 -4
M qc/defs_builtins.qc +11
M qc/defs_classtype.qc +79 -6
M qc/defs_misc.qc +31 -98
M qc/func/bob.qc +189 -144
M qc/func/bossgate.qc +25 -21
M qc/func/breakable.qc +374 -431
M qc/func/brush.qc +15 -13
M qc/func/button.qc +172 -193
M qc/func/counter.qc +166 -162
M qc/func/door.qc +627 -592
M qc/func/door_secret.qc +225 -231
M qc/func/elvtr_button.qc +137 -136
M qc/func/episodegate.qc +28 -23
M qc/func/explobox.qc +48 -46
M qc/func/fall.qc +90 -86
M qc/func/fall2.qc +320 -296
M qc/func/illusionary.qc +13 -9
M qc/func/laser.qc +133 -108
M qc/func/monster_spawner.qc +514 -503
M qc/func/new_plat.qc +650 -564
M qc/func/particlefield.qc +199 -196
M qc/func/plat.qc +212 -186
M qc/func/rotate.qc +1099 -939
M qc/func/shadow.qc +209 -150
M qc/func/togglevisiblewall.qc +43 -40
M qc/func/togglewall.qc +64 -62
M qc/func/train.qc +365 -344
M qc/func/wall.qc +22 -14
M qc/hazards/ltrail.qc +181 -124
M qc/hazards/shooter.qc +251 -235
M qc/info/camera.qc +18 -12
A qc/info/intermission.qc +18
M qc/info/notnull.qc +1 -6
M qc/info/null.qc +1 -6
A qc/info/path_corner.qc +78
A qc/info/rotate.qc +37
M qc/info/teleport_changedest.qc +9 -11
M qc/info/teleport_destination.qc +17 -12
M qc/items/armor.qc -4
M qc/items/backpacks.qc +1 -1
M qc/items/misc.qc +1 -1
M qc/keylock.qc +3 -3
M qc/misc/air_bubbles.qc +35 -22
M qc/misc/ambient_sound.qc +89 -93
M qc/misc/deadstuff.qc +114 -112
M qc/misc/explobox.qc +18 -22
M qc/misc/fireball.qc +48 -33
M qc/misc/infight.qc +5 -8
M qc/misc/light_candle.qc +25 -19
M qc/misc/lights.qc +111 -93
M qc/misc/model.qc +45 -31
M qc/misc/modeltrain.qc +332 -123
M qc/misc/noisemaker.qc +9 -10
M qc/misc/particle_stream.qc +21 -21
M qc/misc/particles.qc +33 -31
M qc/misc/particlespray.qc +29 -15
M qc/misc/play.qc +105 -123
M qc/misc/sparks.qc +132 -103
M qc/misc/target_autosave.qc +62 -45
M qc/misc/teleporttrain.qc +62 -35
M qc/misc/viewthing.qc +9 -8
M qc/monsters.qc +167 -134
M qc/monsters/boss.qc +5 -7
M qc/monsters/boss2.qc +2 -2
M qc/monsters/demon.qc +3 -3
M qc/monsters/dog.qc +3 -3
M qc/monsters/enforcer.qc +4 -4
M qc/monsters/fish.qc +2 -2
M qc/monsters/hknight.qc +1 -1
M qc/monsters/knight.qc +1 -1
M qc/monsters/ogre.qc +6 -6
M qc/monsters/oldone.qc +7 -1
M qc/monsters/shalrath.qc +2 -2
M qc/monsters/shambler.qc +2 -2
M qc/monsters/soldier.qc +1 -1
M qc/monsters/wizard.qc +2 -2
M qc/monsters/zombie.qc +2 -2
M qc/player/player.qc +1 -13
M qc/player/pmove.qc +26 -12
M qc/progs.src +21 -14
M qc/subs.qc +62 -352
M qc/triggers/camera.qc +20 -8
M qc/triggers/changelevel.qc +19 -18
M qc/triggers/changemusic.qc +25 -28
M qc/triggers/changetarget.qc +4 -7
M qc/triggers/counter.qc +8 -9
M qc/triggers/cvarset.qc +25 -11
M qc/triggers/everything.qc +9 -7
M qc/triggers/filter.qc +11 -10
M qc/triggers/fog.qc +68 -60
M qc/triggers/heal.qc +60 -41
M qc/triggers/hurt.qc +13 -14
M qc/triggers/ladder.qc +13 -14
M qc/triggers/look.qc +28 -19
M qc/triggers/monsterface.qc +8 -13
M qc/triggers/monsterjump.qc +17 -18
M qc/triggers/multiple.qc +58 -38
M qc/triggers/onlyregistered.qc +12 -13
M qc/triggers/push.qc +32 -37
M qc/triggers/relay.qc +9 -6
M qc/triggers/remove.qc +1 -1
M qc/triggers/secret.qc +7 -6
M qc/triggers/setcount.qc +5 -4
M qc/triggers/setgravity.qc +19 -17
M qc/triggers/setskill.qc +9 -10
M qc/triggers/setstate.qc +44 -26
M qc/triggers/shake.qc +12 -12
M qc/triggers/take_weapon.qc +15 -16
M qc/triggers/teleport.qc +41 -44
M qc/triggers/textstory.qc +69 -32
M qc/triggers/usekey.qc +31 -24
M qc/triggers/void.qc +23 -24
M qc/weapons.qc +6 -6
M qc/world.qc +19

Diff qc/ai.qc

diff --git a/qc/ai.qc b/qc/ai.qc
index 24a28a8..73ee26d 100644
--- a/qc/ai.qc
+++ b/qc/ai.qc
@@ -86,23 +86,6 @@ void() movetarget_f =

};

-/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
-Monsters will continue walking towards the next target corner.
-*/
-void() path_corner =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.noise != __NULL__ && self.noise != "")
- precache_sound (self.noise);
- if (self.noise2 != __NULL__ && self.noise2 != "")
- precache_sound (self.noise2);
-
- movetarget_f ();
-};
-
/*
=============
t_movetarget

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

Diff qc/base_entities.qc

diff --git a/qc/base_entities.qc b/qc/base_entities.qc
new file mode 100644
index 0000000..e64fa31
--- /dev/null
+++ b/qc/base_entities.qc
@@ -0,0 +1,484 @@
+//==============================================================================
+// base_entities.qc -- top-level entities (entity, tempentity, mapentity)
+//==============================================================================
+
+// constants
+enumflags
+{
+ DISABLE_BLOCKED,
+ DISABLE_THINK,
+ DISABLE_TOUCH,
+ DISABLE_USE
+};
+
+//------------------------------------------------------------------------------
+class base_entity: entity
+{
+ // class fields
+ float interaction_flags;
+
+ //==============================================================
+ // Subs
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // was CheckValidTouch(); needed for both spawnable map entities
+ // and temporary entities -- CEV
+ //--------------------------------------------------------------
+ nonvirtual float(entity toucher) sub_checkvalidtouch =
+ {
+ if (toucher.classtype != CT_PLAYER)
+ return FALSE;
+ if (toucher.health <= 0)
+ return FALSE;
+ if (toucher.movetype == MOVETYPE_NOCLIP)
+ return FALSE;
+ if (this.estate != STATE_ACTIVE)
+ return FALSE;
+ return TRUE;
+ };
+
+ //==============================================================
+ // Interfacing
+ //==============================================================
+
+ // blocked() seems to only be used by func_ entities so it's
+ // undefined here & defined later in the base_func class -- CEV
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think = { };
+
+ //--------------------------------------------------------------
+ virtual void() think =
+ {
+ // has think been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_THINK)
+ return;
+
+ do_think (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch = { };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) handle_touch =
+ {
+ // has touch been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_TOUCH)
+ return;
+
+ do_touch (toucher);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() touch =
+ {
+ handle_touch (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use = { };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) handle_use =
+ {
+ // has use been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_USE)
+ return;
+
+ do_use (caller);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() use =
+ {
+ handle_use (other);
+ };
+
+ //==============================================================
+ // Constructor & Spawn Functions
+ //==============================================================
+
+ //--------------------------------------------------------------
+ void() base_entity =
+ {
+ this.classgroup |= CG_ENTITY;
+ };
+};
+
+//------------------------------------------------------------------------------
+// base_tempentity -- QC generated temporary entities
+//------------------------------------------------------------------------------
+class base_tempentity: base_entity
+{
+ //--------------------------------------------------------------
+ void() base_tempentity =
+ {
+ this.classgroup |= CG_TEMPENTITY;
+ };
+};
+
+//------------------------------------------------------------------------------
+// temp_delayed_use -- to facilitate delayed SUB_UseTargets
+//------------------------------------------------------------------------------
+class temp_delayed_use: base_tempentity
+{
+ //--------------------------------------------------------------
+ virtual void() delayed_think =
+ {
+ activator = this.enemy;
+ base_mapentity::sub_usetargets ();
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ void() temp_delayed_use =
+ {
+ this.classname = "DelayedUse";
+ this.classtype = CT_TEMP_DELAYEDUSE;
+ this.classgroup = CG_TEMPENTITY;
+ this.think = this.delayed_think;
+ };
+};
+
+//------------------------------------------------------------------------------
+// base_mapentity -- spawnable mapper-placeable entities
+//------------------------------------------------------------------------------
+class base_mapentity: base_entity
+{
+ //==============================================================
+ // Subs
+ //==============================================================
+
+ //--------------------------------------------------------------
+ nonvirtual void() sub_usetargets =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ local entity t;
+ local string match = "";
+
+ if (this.delay)
+ {
+ // create a temp object to fire at a later time
+ t = spawn (temp_delayed_use,
+ enemy: activator,
+ nextthink: time + this.delay,
+ message: this.message,
+ killtarget: this.killtarget,
+ killtarget2: this.killtarget2,
+ target: this.target,
+ target2: this.target2,
+ target3: this.target3,
+ target4: this.target4);
+ return;
+ }
+
+ // print the message
+ if (this.message != "" && !(flags & FL_NOCENTERPRINT))
+ {
+ if (this.spawnflags & TRIGGER_CENTERPRINTALL)
+ {
+ t = findfloat (world, ::classtype, CT_PLAYER);
+ while (t)
+ {
+ centerprint (t, this.message);
+ if (!this.noise)
+ sound (t, CHAN_VOICE,
+ "misc/talk.wav",
+ 1, ATTN_NORM);
+ t = findfloat (t, ::classtype,
+ CT_PLAYER);
+ }
+ }
+
+ else if (activator.classtype == CT_PLAYER)
+ {
+ centerprint (activator, this.message);
+ if (!this.noise)
+ sound (activator, CHAN_VOICE,
+ "misc/talk.wav", 1, ATTN_NORM);
+ }
+ }
+
+ // killtargets
+ for (float i = 0; i < 2; i++)
+ {
+ if (i == 0)
+ match = this.killtarget;
+ else if (i == 1)
+ match = this.killtarget2;
+
+ if (match == __NULL__ || match == "")
+ continue;
+
+ // copy-and-pasting a little code here -- CEV
+ t = find (world, ::targetname, match);
+ while (t != world)
+ {
+ if (t.switchshadstyle)
+ lightstyle (t.switchshadstyle, "m");
+ remove (t);
+ t = find (t, ::targetname, match);
+ }
+
+ t = find (world, ::targetname2, match);
+ while (t != world)
+ {
+ if (t.switchshadstyle)
+ lightstyle (t.switchshadstyle, "m");
+ remove (t);
+ t = find (t, ::targetname2, match);
+ }
+
+ t = find (world, ::targetname3, match);
+ while (t != world)
+ {
+ if (t.switchshadstyle)
+ lightstyle (t.switchshadstyle, "m");
+ remove (t);
+ t = find (t, ::targetname3, match);
+ }
+
+ t = find (world, ::targetname4, match);
+ while (t != world)
+ {
+ if (t.switchshadstyle)
+ lightstyle (t.switchshadstyle, "m");
+ remove (t);
+ t = find (t, ::targetname4, match);
+ }
+ match = "";
+ }
+
+ // regular targets
+ for (float i = 0; i < 4; i++)
+ {
+ switch (i)
+ {
+ case 3:
+ match = this.target4;
+ break;
+ case 2:
+ match = this.target3;
+ break;
+ case 1:
+ match = this.target2;
+ break;
+ default:
+ match = this.target;
+ }
+
+ if (match == __NULL__ || match == "")
+ continue;
+
+ // copy-and-pasting again -- CEV
+ t = find (world, ::targetname, match);
+ while (t != world)
+ {
+ if (t.classgroup & CG_MAPENTITY)
+ ((base_mapentity)t).handle_use (this);
+ else
+ // TODO CEV
+ SUB_UseAsSelf (t, match);
+ t = find (t, ::targetname, match);
+ }
+
+ t = find (world, ::targetname2, match);
+ while (t != world)
+ {
+ if (t.classgroup & CG_MAPENTITY)
+ ((base_mapentity)t).handle_use (this);
+ else
+ // TODO CEV
+ SUB_UseAsSelf (t, match);
+ t = find (t, ::targetname2, match);
+ }
+
+ t = find (world, ::targetname3, match);
+ while (t != world)
+ {
+ if (t.classgroup & CG_MAPENTITY)
+ ((base_mapentity)t).handle_use (this);
+ else
+ // TODO CEV
+ SUB_UseAsSelf (t, match);
+ t = find (t, ::targetname3, match);
+ }
+
+ t = find (world, ::targetname4, match);
+ while (t != world)
+ {
+ if (t.classgroup & CG_MAPENTITY)
+ ((base_mapentity)t).handle_use (this);
+ else
+ // TODO CEV
+ SUB_UseAsSelf (t, match);
+ t = find (t, ::targetname4, match);
+ }
+ }
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(string matchstring, .string matchfield) sub_usetarget =
+ {
+ if (matchstring == __NULL__ || matchstring == "")
+ return;
+
+ local entity t;
+
+ t = find (world, ::matchfield, matchstring);
+ while (t != world)
+ {
+ if (t.classgroup & CG_MAPENTITY)
+ ((base_mapentity)t).handle_use (this);
+ else
+ // TODO CEV
+ SUB_UseAsSelf (t, matchstring);
+ t = find (t, ::matchfield, matchstring);
+ }
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() sub_setmovedir =
+ {
+ // QuakeEd only writes a single float for angles (bad idea),
+ // so up and down are just constant angles.
+ if (this.angles == '0 -1 0')
+ {
+ this.movedir = '0 0 1';
+ }
+ else if (this.angles == '0 -2 0')
+ {
+ this.movedir = '0 0 -1';
+ }
+ else
+ {
+ makevectors (this.angles);
+ this.movedir = v_forward;
+ }
+
+ this.angles = '0 0 0';
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() sub_useandforgettargets =
+ {
+ sub_usetargets ();
+
+ this.delay = 0;
+ this.killtarget = "";
+ this.killtarget2 = "";
+ this.message = "";
+ this.target = "";
+ this.target2 = "";
+ this.target3 = "";
+ this.target4 = "";
+ };
+
+ //==============================================================
+ // Constructor & Spawn Functions
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // Ian "iw" Walshaw's new spawnflags for entities, created for
+ // progs_dump August 2019.
+ //
+ // The SPAWNFLAG constants & setup functions are defined elsewhere;
+ // see newflags.qc for documentation.
+ //--------------------------------------------------------------
+ virtual float() inhibit =
+ {
+ if (coop && (this.spawnflags & SPAWNFLAG_NOT_IN_COOP))
+ {
+ total_not_in_coop = total_not_in_coop + 1;
+ remove (this);
+ return TRUE;
+ }
+
+ if (!coop && !deathmatch &&
+ (this.spawnflags & SPAWNFLAG_NOT_IN_SP))
+ {
+ total_not_in_sp = total_not_in_sp + 1;
+ remove (this);
+ return TRUE;
+ }
+
+ // The built-in skill level spawnflags are ignored in
+ // Deathmatch, so we ignore the new ones in Deathmatch, too.
+ // -- iw
+ if (!deathmatch)
+ {
+ if (skill == 2 &&
+ (this.spawnflags & SPAWNFLAG_NOT_ON_SKILL2))
+ {
+ total_not_on_skill2 = total_not_on_skill2 + 1;
+ remove (this);
+ return TRUE;
+ }
+
+ if (skill == 3 &&
+ (this.spawnflags & SPAWNFLAG_NOT_ON_SKILL3))
+ {
+ total_not_on_skill3 = total_not_on_skill3 + 1;
+ remove (this);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+ };
+
+ //--------------------------------------------------------------
+ // class fields are set _after_ the individual class constructors
+ // are run -- CEV
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field = { };
+
+ //--------------------------------------------------------------
+ // because the constructor doesn't have reliable access to class
+ // fields, do any field handling in init_spawned -- CEV
+ //--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
+ void() base_mapentity =
+ {
+ // new spawnflags for all entities -- iw
+ // "all entities", well, all base_mapentities anyway -- CEV
+ if (inhibit())
+ return;
+
+ // this is from Nuclide -- CEV
+ if (__fullspawndata != __NULL__ && __fullspawndata != "")
+ {
+ // __fullspawndata contains an entity's fields as
+ // set in the map file in a format suitable for
+ // reading with tokenize () -- CEV
+#ifdef SSQC
+ // according to Nuclide start offsets differ between
+ // client and server Quake C
+ for (int i = 1; i < (tokenize(__fullspawndata) - 1);
+ i += 2)
+#else
+ // client starts at 0
+ for (int i = 0; i < (tokenize(__fullspawndata) - 1);
+ i += 2)
+#endif
+ {
+ /*
+ dprint (sprintf("base_mapentity::base_mapentity"
+ ": classname %s, fieldname %s\n",
+ this.classname, argv(i)));
+ */
+ init_field (argv(i), argv(i + 1));
+ }
+ __fullspawndata = "";
+ }
+
+ classgroup |= CG_MAPENTITY;
+ init_spawned ();
+ };
+};

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

Diff qc/base_func.qc

diff --git a/qc/base_func.qc b/qc/base_func.qc
new file mode 100644
index 0000000..20ae4e0
--- /dev/null
+++ b/qc/base_func.qc
@@ -0,0 +1,133 @@
+//==============================================================================
+// base_func.qc -- func base class
+//==============================================================================
+
+//======================================================================
+// Constants
+//======================================================================
+
+// button, door, elevator states -- CEV
+const float FUNC_STATE_TOP = 0;
+const float FUNC_STATE_BOTTOM = 1;
+const float FUNC_STATE_UP = 2;
+const float FUNC_STATE_DOWN = 3;
+
+//------------------------------------------------------------------------------
+class base_func: base_mapentity
+{
+ float calc_move_done;
+
+ //==============================================================
+ // Interfacing
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked = { };
+
+ //--------------------------------------------------------------
+ virtual void() blocked =
+ {
+ // has think been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_BLOCKED)
+ return;
+
+ do_blocked (other);
+ };
+
+ //==============================================================
+ // Subs
+ //==============================================================
+
+ //--------------------------------------------------------------
+ // SUB_CalcMove
+ //--------------------------------------------------------------
+ nonvirtual void(vector tdest, float tspeed, void() newthink) calc_move =
+ {
+ local vector vdestdelta;
+ local float len, traveltime, localtime;
+
+ if (!tspeed)
+ objerror ("mapentity::calc_move: No speed is defined!");
+
+ if (this.movetype == MOVETYPE_PUSH)
+ localtime = this.ltime;
+ else
+ localtime = time;
+
+ this.think1 = newthink;
+ this.finaldest = tdest;
+ this.calc_move_done = TRUE;
+
+ if (tdest == this.origin)
+ {
+ this.velocity = '0 0 0';
+ this.nextthink = localtime + 0.1;
+ return;
+ }
+
+ // set destdelta to the vector needed to move
+ vdestdelta = tdest - this.origin;
+
+ // calculate length of vector
+ len = vlen (vdestdelta);
+
+ // divide by speed to get time to reach tdest
+ traveltime = len / tspeed;
+
+ if (traveltime < 0.1)
+ {
+ this.velocity = '0 0 0';
+ this.nextthink = localtime + 0.1;
+ return;
+ }
+
+ // set nextthink to trigger a think when d is reached
+ this.nextthink = localtime + traveltime;
+
+ // scale the destdelta vector by the time spent traveling
+ // to get velocity
+ // qcc won't take vec/float
+ this.velocity = vdestdelta * (1 / traveltime);
+ };
+
+ //==============================================================
+ // Interfacing
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void() think =
+ {
+ // has think been disabled? -- CEV
+ if (this.interaction_flags & DISABLE_THINK)
+ return;
+
+ if (this.calc_move_done == TRUE)
+ {
+ setorigin (this, this.finaldest);
+ this.velocity = '0 0 0';
+ this.nextthink = -1;
+
+ // clear calc_move_done before calling think1 -- CEV
+ if (this.calc_move_done == TRUE)
+ this.calc_move_done = FALSE;
+
+ if (this.think1)
+ this.think1 ();
+ }
+ else
+ {
+ do_think (other);
+ }
+ };
+
+ //==============================================================
+ // Constructor & Spawn Functions
+ //==============================================================
+
+ //--------------------------------------------------------------
+ void() base_func =
+ {
+ this.classgroup |= CG_FUNC;
+ this.calc_move_done = FALSE;
+ };
+};

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

Diff qc/base_item.qc

diff --git a/qc/base_item.qc b/qc/base_item.qc
new file mode 100644
index 0000000..c8257f5
--- /dev/null
+++ b/qc/base_item.qc
@@ -0,0 +1,64 @@
+//==============================================================================
+// base_item.qc -- top-level item pickups
+//==============================================================================
+
+// constants - spawnflags
+const float ITEM_SPAWNSILENT = 32;
+const float ITEM_SPAWNED = 64;
+const float ITEM_SUSPENDED = 128;
+const float ITEM_RESPAWNDM = 16384;
+const float ITEM_DONTDROP = 8388608;
+
+// constants - internal flags
+enumflags
+{
+ ITEM_FLAG_RESPAWN
+};
+
+//------------------------------------------------------------------------------
+class base_item: base_mapentity
+{
+ float item_flags;
+
+ float ritem;
+ float respawndelay;
+ float respawncount;
+
+ //==============================================================
+ // Subs
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) check_touch =
+ {
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity item, float defaultdelay) check_respawn =
+ {
+ };
+
+ //--------------------------------------------------------------
+ // SUB_Regen -- was in items.qc
+ //--------------------------------------------------------------
+ nonvirtual void() sub_regen =
+ {
+ // restore original model
+ this.model = this.mdl;
+
+ // allow it to be touched again
+ this.solid = SOLID_TRIGGER;
+
+ // TODO CEV
+ // Respawn with DM effects
+ // if (deathmatch || (this.spawnflags & ITEM_RESPAWNDM))
+ // play respawn sound
+ sound (this, CHAN_VOICE, "items/item_respawn_q3.wav",
+ 1, ATTN_NORM);
+ // else
+ // play teleport sound and display particles
+ // spawn_tfog (this.origin + this.particles_offset);
+
+ setorigin (this, this.origin);
+ };
+};

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

Diff qc/base_monster.qc

diff --git a/qc/base_monster.qc b/qc/base_monster.qc
new file mode 100644
index 0000000..9521644
--- /dev/null
+++ b/qc/base_monster.qc
@@ -0,0 +1,12 @@
+//==============================================================================
+// base_monster.qc -- base monster class, monster logic
+//==============================================================================
+
+//------------------------------------------------------------------------------
+class base_monster: base_mapentity
+{
+ //--------------------------------------------------------------
+ virtual void() customphysics =
+ {
+ };
+};

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

Diff qc/base_trigger.qc

diff --git a/qc/base_trigger.qc b/qc/base_trigger.qc
new file mode 100644
index 0000000..4b50ecb
--- /dev/null
+++ b/qc/base_trigger.qc
@@ -0,0 +1,118 @@
+//==============================================================================
+// base_trigger.qc -- trigger base class
+//==============================================================================
+
+//------------------------------------------------------------------------------
+class base_trigger: base_mapentity
+{
+ // Supa, triggers, wait until activated before we can trigger?
+ float is_waiting;
+ float endwaiting;
+
+ //==============================================================
+ // Subs
+ //==============================================================
+
+ //--------------------------------------------------------------
+ nonvirtual void() sub_checkwaiting =
+ {
+ if (this.is_waiting <= 0)
+ return;
+
+ this.estate = STATE_INACTIVE;
+ this.endwaiting = TRUE;
+
+ dprint (sprintf("base_mapentity::sub_checkwaiting: spawned "
+ "a waiting %s with targetname %s and target %s\n",
+ this.classname, this.targetname, this.target));
+ };
+
+ static void(base_trigger bt) sub_endwaiting =
+ {
+ bt.endwaiting = FALSE;
+ bt.is_waiting = FALSE;
+ bt.estate = STATE_ACTIVE;
+
+ // special case for teleports, makes it ignore the
+ // fact that it has a targetname when touched
+ if (bt.classtype == CT_TRIGGER_TELEPORT)
+ bt.is_waiting = -1;
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) handle_use =
+ {
+ // SUB_EndWaiting -- CEV
+ if (this.is_waiting == TRUE && this.endwaiting == TRUE)
+ {
+ sub_endwaiting (this);
+ }
+ else
+ {
+ super::handle_use (caller);
+ }
+ };
+
+ //==============================================================
+ // Constructor & Spawn Functions
+ //==============================================================
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "is_waiting":
+ is_waiting = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ // 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')
+ sub_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);
+ };
+
+ //--------------------------------------------------------------
+ void() base_trigger =
+ {
+ this.classgroup |= CG_TRIGGER;
+ this.endwaiting = FALSE;
+ };
+};

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
deleted file mode 100644
index 957cfc5..0000000
--- a/qc/classes/base_trigger.qc
+++ /dev/null
@@ -1,46 +0,0 @@
-//==============================================================================
-// 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/intermission.qc

diff --git a/qc/client/intermission.qc b/qc/client/intermission.qc
index e376539..ece0575 100644
--- a/qc/client/intermission.qc
+++ b/qc/client/intermission.qc
@@ -8,18 +8,6 @@ float intermission_exittime;
entity used_exit;
string nextmap;

-/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-
-This is the camera point for the intermission.
-Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw'
-*/
-void() info_intermission =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-};
-
//----------------------------------------------------------------------
void() info_intermissiontext =
{
@@ -178,16 +166,17 @@ entity() FindIntermission =
local float cyc;

// look for info_intermission first
- spot = find (world, classname, "info_intermission");
+ spot = findfloat (world, classtype, CT_INFO_INTERMISSION);
if (spot)
{ // pick a random one
cyc = random() * 4;
while (cyc > 1)
{
- spot = find (spot, classname, "info_intermission");
+ spot = findfloat (spot, classtype,
+ CT_INFO_INTERMISSION);
if (!spot)
- spot = find (spot, classname,
- "info_intermission");
+ spot = findfloat (spot, classtype,
+ CT_INFO_INTERMISSION);
cyc = cyc - 1;
}
return spot;

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
index 40d3005..8391093 100644
--- a/qc/client/maprules.qc
+++ b/qc/client/maprules.qc
@@ -56,7 +56,8 @@ void() NextLevel =

if (t_level.nextthink < time)
{
- t_level.think = trigger_changelevel::changelevel_execute;
+ // TODO CEV
+ // t_level.think = trigger_changelevel::changelevel_execute;
t_level.nextthink = time + 0.1;
}
};

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

Diff qc/combat.qc

diff --git a/qc/combat.qc b/qc/combat.qc
index ad32c61..9606069 100644
--- a/qc/combat.qc
+++ b/qc/combat.qc
@@ -1,11 +1,4 @@
-
-void() T_MissileTouch;
-void() info_player_start;
-void(entity targ, entity inflictor, entity attacker) ClientObituary;
-
-void() monster_death_use;
-
-//============================================================================
+//==============================================================================

/*
============
@@ -17,10 +10,11 @@ explosions and melee attacks.
*/
float(entity targ, entity inflictor) CanDamage =
{
-// bmodels need special checking because their origin is 0,0,0
+ // bmodels need special checking because their origin is 0,0,0
if (targ.movetype == MOVETYPE_PUSH)
{
- traceline(inflictor.origin, 0.5 * (targ.absmin + targ.absmax), TRUE, self);
+ traceline (inflictor.origin,
+ 0.5 * (targ.absmin + targ.absmax), TRUE, self);
if (trace_fraction == 1)
return TRUE;
if (trace_ent == targ)
@@ -28,26 +22,25 @@ float(entity targ, entity inflictor) CanDamage =
return FALSE;
}

- traceline(inflictor.origin, targ.origin, TRUE, self);
+ traceline (inflictor.origin, targ.origin, TRUE, self);
if (trace_fraction == 1)
return TRUE;
- traceline(inflictor.origin, targ.origin + '15 15 0', TRUE, self);
+ traceline (inflictor.origin, targ.origin + '15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
+ traceline (inflictor.origin, targ.origin + '-15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
- traceline(inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
+ traceline (inflictor.origin, targ.origin + '-15 15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;
- traceline(inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
+ traceline (inflictor.origin, targ.origin + '15 -15 0', TRUE, self);
if (trace_fraction == 1)
return TRUE;

return FALSE;
};

-
/*
============
Killed
@@ -61,18 +54,29 @@ void(entity targ, entity inflictor, entity attacker) Killed =
self = targ;

if (self.health < -99)
- self.health = -99; // don't let sbar look bad if a player
+ // don't let sbar look bad if a player
+ self.health = -99;

if (self.movetype == MOVETYPE_PUSH || self.movetype == MOVETYPE_NONE)
- { // doors, triggers, etc
- self.th_die ();
+ {
+ // doors, triggers, etc
+ if (targ.classtype == CT_FUNC_BREAKABLE)
+ {
+ local func_breakable fb = (func_breakable)targ;
+ if (fb.th_die)
+ fb.th_die ();
+ }
+ else
+ {
+ self.th_die ();
+ }
self = oself;
return;
}

self.enemy = attacker;

-// bump the monster counter
+ // bump the monster counter
if (self.flags & FL_MONSTER)
{
killed_monsters = killed_monsters + 1;
@@ -82,15 +86,14 @@ void(entity targ, entity inflictor, entity attacker) Killed =
ClientObituary (self, inflictor, attacker);

self.takedamage = DAMAGE_NO;
- self.touch = SUB_Null;
+ self.touch = sub_null;

- monster_death_use();
+ monster_death_use ();
self.th_die ();

self = oself;
};

-
/*
============
T_Damage
@@ -110,67 +113,89 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=

// don't try to damage the world. Not healthy - bmFbr
if (!targ)
+ {
return;
+ }

- //johnfitz -- make sure targ.deathtype doesn't keep stale info after this function is done
+ // make sure targ.deathtype doesn't keep stale info after
+ // this function is done -- johnfitz
death_type = targ.deathtype;
targ.deathtype = "";
- //johnfitz
+ // johnfitz

if (!targ.takedamage)
+ {
return;
+ }

- //johnfitz -- some func_breakables ignore monster damage //added from Rubicon2 combat.qc dumptruck_ds
- if (targ.classname == "func_breakable")
+ // some func_breakables ignore monster damage -- johnfitz
+ // added from Rubicon2 combat.qc -- dumptruck_ds
+ if (targ.classtype == CT_FUNC_BREAKABLE)
{
- if (targ.spawnflags & BREAKABLE_NO_MONSTERS && attacker.flags & FL_MONSTER)
+ if (targ.spawnflags & BREAKABLE_NO_MONSTERS &&
+ attacker.flags & FL_MONSTER)
+ {
return;
+ }
}
- //johnfitz
+ // johnfitz

-// used by buttons and triggers to set activator for target firing
+ // used by buttons and triggers to set activator for target firing
damage_attacker = attacker;

-// check for quad damage powerup on the attacker
+ // check for quad damage powerup on the attacker
if (attacker.super_damage_finished > time)
damage = damage * 4;

// damage mod for monsters -- dumptruck_ds
if (attacker.damage_mod)
- damage = damage * attacker.damage_mod;
+ damage = damage * attacker.damage_mod;

- //don't deplete armor if drowning/burning, or protected by biosuit/pentagram/godmode (note: in ID1 pentagram/godmode doesn't actually protect your armor)
- if (death_type == "burning" || death_type == "drowning" || targ.invincible_finished >= time || targ.flags & FL_GODMODE)
+ // don't deplete armor if drowning/burning, or protected by
+ // biosuit/pentagram/godmode (note: in ID1 pentagram/godmode
+ // doesn't actually protect your armor)
+ if (death_type == "burning" || death_type == "drowning" ||
+ targ.invincible_finished >= time || targ.flags & FL_GODMODE)
+ {
ignore_armor = TRUE;
+ }
else
+ {
ignore_armor = FALSE;
-//johnfitz
-// save damage based on the target's armor level
- if (ignore_armor) //johnfitz -- some damage doesn't deplete armor
+ }
+
+ // johnfitz
+ // save damage based on the target's armor level
+ if (ignore_armor)
{
+ // johnfitz -- some damage doesn't deplete armor
save = 0;
}
else
{
- save = ceil(targ.armortype*damage);
- if (save >= targ.armorvalue)
- {
- save = targ.armorvalue;
- targ.armortype = 0; // lost all armor
- targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
+ save = ceil (targ.armortype * damage);
+ if (save >= targ.armorvalue)
+ {
+ save = targ.armorvalue;
+ // lost all armor
+ targ.armortype = 0;
+ targ.items = targ.items - (targ.items &
+ (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3));
+ }
}
-}
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
-// }
-// else
-// save = 0;
-// // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
+
+ // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos start
+ // }
+ // else
+ // save = 0;
+ // 1998-08-12 Drowning doesn't hurt armor by Maddes/Athos end
+
targ.armorvalue = targ.armorvalue - save;
- take = ceil(damage-save);
+ take = ceil (damage - save);

-// add to the damage total for clients, which will be sent as a single
-// message at the end of the frame
-// FIXME: remove after combining shotgun blasts?
+ // add to the damage total for clients, which will be sent as a
+ // single message at the end of the frame
+ // FIXME: remove after combining shotgun blasts?
if (targ.flags & FL_CLIENT)
{
targ.dmg_take = targ.dmg_take + take;
@@ -178,40 +203,46 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
targ.dmg_inflictor = inflictor;
}

-// figure momentum add
- if ( (inflictor != world) && (targ.movetype == MOVETYPE_WALK) )
+ // figure momentum add
+ if ((inflictor != world) && (targ.movetype == MOVETYPE_WALK))
{
dir = targ.origin - (inflictor.absmin + inflictor.absmax) * 0.5;
- dir = normalize(dir);
- targ.velocity = targ.velocity + dir*damage*8;
+ dir = normalize (dir);
+ targ.velocity = targ.velocity + dir * damage * 8;
}

-// check for godmode or invincibility
+ // check for godmode or invincibility
if (targ.flags & FL_GODMODE)
return;
+
if (targ.invincible_finished >= time)
{
if (self.invincible_sound < time)
{
- sound (targ, CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM);
+ sound (targ, CHAN_ITEM, "items/protect3.wav",
+ 1, ATTN_NORM);
self.invincible_sound = time + 2;
}
+
return;
}

-// team play damage avoidance
-// 1998-07-29 Teamplay 1 fix by Maddes start
- if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team)
- && (targ != attacker)
- && (attacker.classname == "player")
- && (inflictor.classname != "door") ) // because squishing a teammate is still possible
-// 1998-07-29 Teamplay 1 fix by Maddes end
- return;
+ // team play damage avoidance
+ // 1998-07-29 Teamplay 1 fix by Maddes start
+ if ((teamplay == 1) && (targ.team > 0) &&
+ (targ.team == attacker.team) && (targ != attacker) &&
+ (attacker.classname == "player") &&
+ (inflictor.classname != "door"))
+ {
+ // because squishing a teammate is still possible
+ // 1998-07-29 Teamplay 1 fix by Maddes end
+ return;
+ }

-// do the damage
+ // do the damage
targ.health = targ.health - take;

-// fire pain_target if appropriate
+ // fire pain_target if appropriate
if ((targ.flags & FL_MONSTER) &&
targ.pain_target != "" &&
targ.health <= targ.pain_threshold)
@@ -228,27 +259,32 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
return;
}

-// react to the damage
+ // react to the damage
oldself = self;
self = targ;

- if ( (self.flags & FL_MONSTER) && attacker != world)
+ if ((self.flags & FL_MONSTER) && attacker != world)
{
- // get mad unless of the same class (except for soldiers)
+ // get mad unless of the same class (except for soldiers)
if (self != attacker && attacker != self.enemy)
{
local float mode;
mode = 0;
+
// take highest mode so infighting happens consistently
if (self.infight_mode == -1 || self.infight_mode > mode)
{
mode = self.infight_mode;
}
+
if (mode != -1 && attacker.infight_mode > mode)
{
mode = attacker.infight_mode;
}
- //soldiers of the same style will infight -- dumptruck_ds - thanks for c0burn and Shamblernaut for your help!
+
+ // soldiers of the same style will infight
+ // -- dumptruck_ds
+ //thanks for c0burn and Shamblernaut for your help!
if (mode == -1)
{
if (attacker.classname == "player")
@@ -259,13 +295,17 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
FoundTarget ();
}
}
- else if (
- (self.classname != attacker.classname) ||
- ((self.classname == "monster_army") && (self.style == attacker.style)) ||
- (mode > 0 && self.mdl_body != attacker.mdl_body) || // infight if different models
- (mode > 1 && self.skin != attacker.skin) || // infight if different skin
- (mode > 2) // always infight
- )
+ else if ((self.classname != attacker.classname) ||
+ ((self.classname == "monster_army") &&
+ (self.style == attacker.style)) ||
+ // infight if different models
+ (mode > 0 &&
+ self.mdl_body != attacker.mdl_body) ||
+ // infight if different skin
+ (mode > 1 &&
+ self.skin != attacker.skin) ||
+ // always infight
+ (mode > 2))
{
if (self.enemy.classname == "player")
self.oldenemy = self.enemy;
@@ -278,7 +318,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage=
if (self.th_pain)
{
self.th_pain (attacker, take);
- // nightmare mode monsters don't go into pain frames often
+ // nightmare mode monsters don't go into pain frames often
if (skill == 3)
self.pain_finished = time + 5;
}

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

Diff qc/csqc/csqc_hudvanilla.qc

diff --git a/qc/csqc/csqc_hudvanilla.qc b/qc/csqc/csqc_hudvanilla.qc
index 3ececaf..aea1207 100644
--- a/qc/csqc/csqc_hudvanilla.qc
+++ b/qc/csqc/csqc_hudvanilla.qc
@@ -826,7 +826,7 @@ void(vector pos) Hud_Speedometer =
// fancy -- CEV
v = [player_local.velocity_x, player_local.velocity_y, 0];

- Hud_DrawNoFont8 (pos, vlen(v), 3, FALSE, HUDFONT_WHITE);
+ Hud_DrawNoFont8 (pos, rint(vlen(v)), 3, FALSE, HUDFONT_WHITE);
};

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

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 395faf9..9417653 100644
--- a/qc/csqc/csqc_progs.src
+++ b/qc/csqc/csqc_progs.src
@@ -1,8 +1,8 @@
+#pragma target fte
#pragma progs_dat "../../csprogs.dat"
+#pragma noref 1

#define FTE
-#pragma target fte
-#pragma noref 1
#define CSQC

#includelist

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 fbecb3b..998fedc 100644
--- a/qc/cutscene.qc
+++ b/qc/cutscene.qc
@@ -331,7 +331,7 @@ void() go_back =
// stuffcmd (c, "sizedown\nsizeup\n");

t.nextthink = time + 0.1;
- t.think = SUB_Remove;
+ t.think = sub_remove;
remove (self);
};

@@ -471,7 +471,7 @@ void() move_camera =
cpt = find (world, targetname, self.target);
if (!cpt.target)
{
- self.think = SUB_Null;
+ self.think = sub_null;
self.enemy.velocity = '0 0 0';
// mangle == velocity in cut-scene
self.enemy.mangle = '0 0 0';
@@ -664,7 +664,7 @@ void() gocam_use =
DHM_CalcMoveDone ();
self = temp;
self.nextthink = time + 0.1;
- self.think = SUB_Remove;
+ self.think = sub_remove;
};

//----------------------------------------------------------------------
@@ -702,7 +702,7 @@ void() Script_play =
temp = self;
self = scrpt;
SUB_UseTargets ();
- self.target = world.null_string;
+ self.target = __NULL__;
self = temp;
}

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 0546a71..9b00489 100644
--- a/qc/defs_builtins.qc
+++ b/qc/defs_builtins.qc
@@ -169,6 +169,9 @@ string(string s) precache_file2 = #77; // registered version only
void(entity e) setspawnparms = #78; // set parm1... to the values at
// level start for coop respawn

+// Part of FRIK_FILE, FTE_QC_INFOKEY, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS
+float(string) stof = #81;
+
// 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.
@@ -192,6 +195,9 @@ float(float value, float exp) pow = #97;
// value. world is returned when there are no more entities.
entity(entity start, .__variant fld, __variant match) findfloat = #98;

+// Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS
+vector(string s) stov = #117;
+
// for CSQC interaction -- CEV
void(float num, float type, .__variant fld) clientstat = #232;

@@ -215,6 +221,11 @@ void(entity ent) runstandardplayerphysics = #347;
// Look up a key in the server's public serverinfo string
string(string key) serverkey = #354;

+// from fteextensions.qc; Part of KRIMZON_SV_PARSECLIENTCOMMAND
+float(string s) tokenize = #441;
+// from fteextensions.qc; Part of KRIMZON_SV_PARSECLIENTCOMMAND
+string(float n) argv = #442;
+
// from fteextensions.qc, all part of DP_QC_ASINACOSATANATAN2TAN -- CEV
float(float s) asin = #471;
float(float c) acos = #472;

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
index 53134ac..176e378 100644
--- a/qc/defs_classtype.qc
+++ b/qc/defs_classtype.qc
@@ -3,10 +3,11 @@
//=============================================================================

// fields
+.float classgroup; // used to identify some base classes
.float classtype; // used to identify an entity's type

//----------------------------------------------------------------------
-// global classtype list; shared by client & server
+// classtype list; shared by client & server
//----------------------------------------------------------------------
enum
{
@@ -19,14 +20,44 @@ enum

// info
CT_INFO_FOCAL_POINT, // cutscenes
+ CT_INFO_INTERMISSION, // id1, end-of-map camera position
CT_INFO_MOVIE_CAMERA, // cutscenes
- CT_INFO_NOTNULL, //
- CT_INFO_NULL, //
- CT_INFO_TELEPORT_CHANGEDEST, // teleporters
- CT_INFO_TELEPORT_DESTINATION, // teleporters
+ CT_INFO_NOTNULL, // id1?
+ CT_INFO_NULL, // id1?
+ CT_INFO_ROTATE, // Hipnotic info_rotate
+ CT_INFO_TELEPORT_CHANGEDEST, // Qmaster teleporter changedest
+ CT_INFO_TELEPORT_DESTINATION, // id1 teleporters
CT_INFO_TELEPORT_RANDOM, // teleporters

// func
+ CT_FUNC_BOB, // RennyC func_bob
+ CT_FUNC_BOSSGATE, // id1 func_bossgate
+ CT_FUNC_BREAKABLE, // AD with mod. by Qmaster, iw, and d_ds
+ CT_FUNC_BUTTON, // id1 / pd3 func_button
+ CT_FUNC_COUNTER, // Hipnotic func_counter
+ CT_FUNC_DOOR, // id1 doors
+ CT_FUNC_DOOR_SECRET, // id1 secret door
+ CT_FUNC_ELVTR_BUTTON, // Rogue elevator buttons
+ CT_FUNC_EPISODEGATE, // id1 func_episodegate
+ CT_FUNC_EXPLOBOX, // id1 func_explobox
+ CT_FUNC_FALL, // RennyC func_fall
+ CT_FUNC_FALL2, // RennyC & whirledtsar func_fall2
+ CT_FUNC_ILLUSIONARY, // id1 func_illusionary
+ CT_FUNC_LASER, // Rubicon2 func_laser
+ CT_FUNC_MONSTER_SPAWNER, // progs_dump monster spawner
+ CT_FUNC_MOVEWALL, // Hipnotic rotation
+ CT_FUNC_NEW_PLAT, // Rogue / PD3 new_plat
+ CT_FUNC_ONCOUNT, // Hipnotic func_oncount
+ CT_FUNC_PARTICLEFIELD, // Hipnotic particle field
+ CT_FUNC_PLAT, // id1 plats / lifts
+ CT_FUNC_ROTATE_DOOR, // Hipnotic rotation
+ CT_FUNC_ROTATE_ENTITY, // Hipnotic rotation
+ CT_FUNC_ROTATE_TRAIN, // Hipnotic rotation
+ CT_FUNC_SHADOW, // pd3 func_shadow
+ CT_FUNC_TOGGLEVISIBLEWALL, // pd3(?) togglevisiblewall
+ CT_FUNC_TOGGLEWALL, // Hipnotic func_togglewall
+ CT_FUNC_TRAIN, // id1 train
+ CT_FUNC_WALL, // func_wall

// gibs
CT_GIB_HEAD_ARMY, // deadstuff
@@ -44,6 +75,14 @@ enum
CT_GIB_MISC_2, //
CT_GIB_MISC_3, //

+ // hazards
+ CT_HAZARD_LTRAIL_START, // DOE lightning trail
+ CT_HAZARD_LTRAIL_RELAY, // DOE lightning trail
+ CT_HAZARD_LTRAIL_END, // DOE lightning trail
+ CT_HAZARD_SHOOTER, // trap_shooter
+ CT_HAZARD_SPIKESHOOTER, // trap_spikeshooter
+ CT_HAZARD_SWITCHED_SHOOTER, // trap_switched_shooter
+
// lights
CT_LIGHT, // id1 light
CT_LIGHT_CANDLE, // light_candle
@@ -52,6 +91,7 @@ enum
CT_LIGHT_FLUORO, // id1 light_fluoro
CT_LIGHT_FLUOROSPARK, // id1 light_fluorospark
CT_LIGHT_GLOBE, // id1 light_globe
+ CT_LIGHT_SPRITE_FLAME, // pd3 sprite flame
CT_LIGHT_TORCH_SMALL_WALLTORCH, // id1

// misc
@@ -69,11 +109,14 @@ enum
CT_MISC_AMBIENT_THUNDER, // Zerstorer ambient thunder
CT_MISC_AMBIENT_WATER1, // ambient water 1
CT_MISC_AMBIENT_WIND2, // ambient wind 2
+ CT_MISC_BOB, // RennyC func_bob
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_MODELCANDLE, // model_candle
+ CT_MISC_MODELTRAIN, //
CT_MISC_NOISEMAKER, // pd3 some kind of testing ent?
CT_MISC_PARTICLES, // Rubicon2 misc_splash
CT_MISC_PARTICLESPRAY, // custents misc_particlespray
@@ -87,11 +130,17 @@ enum
CT_MISC_PLAY_MFLASH, // pd3 play muzzleflash
CT_MISC_PLAY_SOUND, // pd3 play_sound
CT_MISC_PLAY_SOUND_TRIGGERED, // pd3 play_sound
+ CT_MISC_ROTATE_OBJECT, // Hipnotic rotation
+ CT_MISC_SHADOWCONTROLLER, // pd3 shadows
CT_MISC_SPARKS, // misc_sparks
CT_MISC_VIEWTHING, // id1?
CT_MISC_TELE_FOG, // pd3 play
CT_MISC_TELEPORTTRAIN, // id1 teleport train

+ // paths
+ CT_PATH_CORNER, // id1 path_corner
+ CT_PATH_ROTATE, // Hipnotic rotation
+
// targets
CT_TARGET_AUTOSAVE, // target_autosave from copper
CT_TARGET_FOGBLEND, // fog
@@ -136,6 +185,30 @@ enum
CT_TRIGGER_VOID, // necros' trigger_void, modified

// temp entities
+ CT_TEMP_ANIM_CONTROLLER, // animation controller
CT_TEMP_BUBBLES, // air bubble
- CT_TEMP_FOG_CONTROLLER // fog
+ CT_TEMP_DELAYEDUSE, // delayed sub_usetargets
+ CT_TEMP_DOOR_TRIGGER, // id1 doors
+ CT_TEMP_FALL2_HELPER, // RennyC & whirledtsar fall2
+ CT_TEMP_FIREBALL, // created by misc_fireball
+ CT_TEMP_FOG_CONTROLLER, // fog
+ CT_TEMP_LASER_HELPER, // Rubicon2 func_laser
+ CT_TEMP_NEWPLAT_TRIGGER, // pd3 newplats
+ CT_TEMP_PLAT_TRIGGER, // id1 plats
+ CT_TEMP_ROTATE_CONTROLLER, // rotation controller
+ CT_TEMP_SPARK // misc_sparks
+};
+
+//----------------------------------------------------------------------
+// classgroups, defined as needed; I did not want to do this -- CEV
+//----------------------------------------------------------------------
+enumflags
+{
+ CG_ENTITY, // base entity
+ CG_TEMPENTITY, // temporary entities
+ CG_MAPENTITY, // entities with spawn functions
+ CG_FUNC, // func_*
+ CG_TRIGGER, // trigger_*
+ CG_ROTATE, // rotation objects
+ CG_HAZARD_LTRAIL // DOE lightning trail
};

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 de12145..606974b 100644
--- a/qc/defs_misc.qc
+++ b/qc/defs_misc.qc
@@ -1,6 +1,10 @@
-/*==============================================================================
- VARS NOT REFERENCED BY C CODE
-==============================================================================*/
+//==============================================================================
+// VARS NOT REFERENCED BY C CODE
+//==============================================================================
+
+//======================================================================
+// Constants
+//======================================================================

// inspired by Copper
const string version = "\n\"Dog\" mode for FTE\nversion 0.1a";
@@ -105,11 +109,6 @@ 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
const vector VEC_HULL_MIN = '-16 -16 -24';
@@ -191,10 +190,10 @@ const float MSG_MULTICAST = 4;
// value used only inside 'SendEntity' functions.
const float MSG_ENTITY = 5;

-// spawnflags for func_movewall
-const float MOVEWALL_VISIBLE = 1;
-const float MOVEWALL_TOUCH = 2;
-const float MOVEWALL_NONBLOCKING = 4;
+// entity state
+const float STATE_ACTIVE = 0;
+const float STATE_INACTIVE = 1;
+const float STATE_INVISIBLE = 8;

// known_release values -- iw
const float KNOWN_RELEASE_NOT = 0;
@@ -308,14 +307,12 @@ float AS_TURRET = 5;
//======================================================================
.string mdl;
.vector mangle; // angle at start
-.vector oldorigin; // only used by secret door
.string origmodel; // switchables brushes (added by bmFbr)
.float t_length, t_width;

//======================================================================
// doors, etc
//======================================================================
-.vector /*dest,*/ dest1, dest2;
.float wait; // time from firing to restarting
.float delay; // time from activation to firing
.entity trigger_field; // door's trigger entity
@@ -356,23 +353,9 @@ float AS_TURRET = 5;
.float lip;
.float state;
.vector pos1, pos2; // top and bottom positions
-.float height;
-
-//======================================================================
-// plat2 fields // progs_dump
-//======================================================================
-.float plat2Called;
-.float plat2LastMove;
-.float plat2GoTime;
-.float plat2GoTo;

-//======================================================================
-// elevator fields // progs_dump
-//======================================================================
-.float elevatorLastUse;
-.float elevatorOnFloor;
-.float elevatorToFloor;
-.vector elevatorDestination;
+// TODO CEV
+.float height;

//======================================================================
// fog // progs_dump
@@ -410,18 +393,6 @@ string lastnameused; // the targetname that was last used
// to trigger somthing

//======================================================================
-// switchable shadow
-//======================================================================
-.float switchshadstyle;
-.float shadowoff;
-.entity shadowcontroller;
-
-void() misc_shadowcontroller;
-void() misc_shadowcontroller_use;
-void() shadow_fade_in;
-void() shadow_fade_out;
-
-//======================================================================
// misc pd_additions
//======================================================================
.float reset_items; // dumptruck_ds
@@ -435,18 +406,7 @@ void() shadow_fade_out;
/*==============================================================================
combat.qc
==============================================================================*/
-void(entity targ, entity inflictor, entity attacker, float damage) T_Damage;
-float (entity e, float healamount, float ignore) T_Heal; // health function
-float(entity targ, entity inflictor) CanDamage;
-void() DummyFunction =
-{
- // gets rid of the last compiler warnings ; - )
- local string w;
- local float l;
- w = self.wad;
- l = self.light_lev;
-}
-.float is_waiting; // Supa, triggers, wait until activated
+// .float is_waiting; // Supa, triggers, wait until activated
// before we can trigger?
.float gravity; // from custdefs.qc by way of Hipnotic
float STAT_TOTALMONSTERS = 12; // required by Hipnotic code
@@ -461,21 +421,8 @@ float BREAKABLE_NO_MONSTERS = 1;
.float wantedgravity; // thanks Spike!
// .float ladder_step_finished; // footsteps on ladder -- dumptruck_ds

-// dumptruck_ds defs for breakables in rubcon2.qc
-// -- thanks to Qmaster and the Arcane Dimensions team
-/*
-.string break_template1_e;
-.string break_template2_e;
-.string break_template3_e;
-.string break_template4_e;
-.string break_template5_e;
-.string find_brk_template_model;
-*/
-
// from remakequake -- dumptruck_ds

-.vector dest, dest1, dest2;
-
void(string type, string text) print_self =
{
dprint (type);
@@ -488,13 +435,14 @@ void(string type, string text) print_self =
dprint ("\n");
};

-// TODO CEV
+// TODO CEV keep these
+.float alpha; // translucency in supported engines
+
+// TODO CEV check these
.float pain_threshold; // dumptruck_ds
.string pain_target; // dumptruck_ds
.float color; // Hipnotic
.float megahealth_rottime; // dumptruck_ds
-.float alpha; // from RennyC func_fall in dtmisc.qc
-.float ltrailLastUsed; // from DOE lighnin
.float style2; // c0burn's switchable lights
.float sight_trigger; // dumptruck_ds
.float keep_ammo; // dumptruck_ds
@@ -514,7 +462,7 @@ nosave float *world_sounds; // via Spike fun times! nosave=noclobber
void() Cutscene_Think;
float cutscene; // Set to TRUE during a cutscene.
float mindex_inviso; // Invisible (null sprite)
-.string null_string; // Replace 'string_null' with
+// .string null_string; // Replace 'string_null' with
// 'world.null_string'. null string,
// nothing should be held here.

@@ -548,8 +496,6 @@ float mindex_inviso; // Invisible (null sprite)
.vector mdlsz, centeroffset;
// Custom Model End -- dumptruck_ds

-.float shardvalue; // ammo shard value
-
.float drop_item; // key DropStuff

float SPAWN_SILENTLY = 2097152;
@@ -557,19 +503,8 @@ float TRIGGER_CENTERPRINTALL = 1048576;

// entity state
.float estate;
-.void() dormant_use;
-float STATE_ACTIVE = 0;
-float STATE_INACTIVE = 1;
-float STATE_INVISIBLE = 8;
-
.float prevstate;

-void(entity client, float density, vector color) fog_save;
-void(entity client, float density) skyfog_save;
-void(entity client, entity fogger) fog_setFromEnt;
-void(entity client, float density, vector color) fog_set;
-void(entity client, float density) skyfog_set;
-
nosave float cleanUpClientStuff;
nosave float gamestarted;

@@ -582,17 +517,7 @@ nosave float gamestarted;
float I_AM_TURRET = 262144; // dumptruck_ds
.void() th_turret;

-.entity animcontroller;
-.entity rotatecontroller;
-.float multiplier;
-
-
// TODO CEV
-.float first_frame, last_frame;
-.float first_frame2, last_frame2;
-.float frtime, frtime2;
-.float animtype, animtype2;
-.vector cmins, cmaxs;
.vector cust_avelocity;
.float touch_time;

@@ -602,12 +527,13 @@ float I_AM_TURRET = 262144; // dumptruck_ds
.vector csf_color;
.float csf_density;

-void(entity client) csf_apply;
-void(entity client, float density, vector color, float spd) csf_fade;
-void(entity client, float density, vector color) csf_set;
-
.float fade_amt;

+// TODO CEV shadows
+.float switchshadstyle;
+.float shadowoff;
+.entity shadowcontroller;
+
// worldspawn default mdls
.string h_vial_mdl;
.string h_25_mdl;
@@ -646,3 +572,10 @@ void(entity client, float density, vector color) csf_set;
// of the SendEntity method.
.float SendFlags;
#endif
+
+#ifdef SSQC
+// Set by the engine before calls to spawn functions, and is most easily
+// parsed with the tokenize builtin. This allows you to handle halflife's
+// multiple-fields-with-the-same-name (or target-specific fields).
+__unused var string __fullspawndata;
+#endif

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

Diff qc/func/bob.qc

diff --git a/qc/func/bob.qc b/qc/func/bob.qc
index 57b83c7..c9ccb3f 100644
--- a/qc/func/bob.qc
+++ b/qc/func/bob.qc
@@ -2,119 +2,195 @@
// func_bob -- code attributed to RennyC
//==============================================================================

-// fields
-.float attack_timer;
-.float bsporigin; // All bmodel origins are 0,0,0 check this first
-.float distance;
-.float waitmin2;
-
// constants
+const float BOB_STYLE_START_OFF = 1; // start off
const float BOB_COLLISION = 2; // Collision for misc_bob
const float BOB_NONSOLID = 4; // Non solid for func_bob

-//----------------------------------------------------------------------
-void() func_bob_timer =
+//------------------------------------------------------------------------------
+class base_func_bob: base_func
{
- // Keep ticking in background, use local timer (faster)
- self.think = func_bob_timer;
-
- if (self.bsporigin)
- self.nextthink = self.ltime + 0.1;
- else
- self.nextthink = time + 0.1;
+ // class fields
+ float attack_timer;
+ float bsporigin; // All bmodel origins are 0,0,0 check this first
+ float distance;
+ float waitmin2;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "attack_timer":
+ attack_timer = stof (fieldvalue);
+ break;
+ case "bsporigin":
+ bsporigin = stof (fieldvalue);
+ break;
+ case "distance":
+ distance = stof (fieldvalue);
+ break;
+ case "waitmin2":
+ waitmin2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };

- // Has the cycle completed?
- if (self.attack_timer < time)
+ //--------------------------------------------------------------
+ nonvirtual void() bob_on =
{
- // Setup bob cycle and half way point for slowdown
- self.attack_timer = time + self.count;
- self.distance = time + (self.count * 0.5);
- // Flip direction of bmodel bob
- self.lefty = 1 - self.lefty;
- if (self.lefty < 1)
- self.t_length = self.height;
+ // This may have been called by a "use" function, so don't
+ // allow it to be called repeatedly -- iw
+ this.interaction_flags |= DISABLE_USE;
+
+ if (this.bsporigin)
+ {
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ }
else
- self.t_length = -self.height;
+ {
+ this.movetype = MOVETYPE_FLY;
+ this.solid = SOLID_BBOX;
+ // Reset any onground flags
+ this.flags = 0;
+ }

- // Always reset velocity and flags
- self.velocity = '0 0 0';
- self.flags = 0;
- }
+ if (this.spawnflags & BOB_NONSOLID)
+ this.solid = SOLID_NOT;

- // Is the direction set?
- // This is a block condition to prevent the bmodel moving
- if (self.lefty != -1)
+ setmodel (this, this.mdl);
+ setsize (this, this.mins , this.maxs);
+
+ if (this.bsporigin)
+ this.nextthink = this.ltime + 0.1 + this.delay;
+ else
+ this.nextthink = time + 0.1 + this.delay;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() bob_off =
{
- // Slow down velocity (gradually)
- if (self.distance < time)
+ if (this.bsporigin)
{
- self.velocity = self.velocity * self.waitmin2;
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
}
else
{
- // Speed up velocity (linear/exponentially)
- self.t_length = self.t_length * self.waitmin;
- self.velocity += self.movedir * self.t_length;
+ this.movetype = MOVETYPE_FLY;
+ this.solid = SOLID_BBOX;
}
- }
-};

-//----------------------------------------------------------------------
-void() func_bob_on =
-{
- // This may have been called as a "use" function, so don't allow it
- // to be called repeatedly -- iw
- self.use = SUB_Null;
+ if (this.spawnflags & BOB_NONSOLID)
+ this.solid = SOLID_NOT;

- if (self.bsporigin)
- {
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- }
- else
- {
- self.movetype = MOVETYPE_FLY;
- self.solid = SOLID_BBOX;
- // Reset any onground flags
- self.flags = 0;
- }
-
- if (self.spawnflags & BOB_NONSOLID)
- self.solid = SOLID_NOT;
-
- setmodel (self, self.mdl);
- setsize (self, self.mins , self.maxs);
-
- self.think = func_bob_timer;
- if (self.bsporigin)
- self.nextthink = self.ltime + 0.1 + self.delay;
- else
- self.nextthink = time + 0.1 + self.delay;
-};
+ setmodel (this, this.mdl);
+ setsize (this, this.mins , this.maxs);
+ this.velocity = '0 0 0';
+ };

-//----------------------------------------------------------------------
-void() func_bob_off =
-{
- if (self.bsporigin)
+ //--------------------------------------------------------------
+ // was bob_timer -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- }
- else
+ if (this.bsporigin)
+ this.nextthink = this.ltime + 0.1;
+ else
+ this.nextthink = time + 0.1;
+
+ // Has the cycle completed?
+ if (this.attack_timer < time)
+ {
+ // Setup bob cycle and half way point for slowdown
+ this.attack_timer = time + this.count;
+ this.distance = time + (this.count * 0.5);
+ // Flip direction of bmodel bob
+ this.lefty = 1 - this.lefty;
+ if (this.lefty < 1)
+ this.t_length = this.height;
+ else
+ this.t_length = -this.height;
+
+ // Always reset velocity and flags
+ this.velocity = '0 0 0';
+ this.flags = 0;
+ }
+
+ // Is the direction set?
+ // This is a block condition to prevent the bmodel moving
+ if (this.lefty != -1)
+ {
+ // Slow down velocity (gradually)
+ if (this.distance < time)
+ {
+ this.velocity = this.velocity * this.waitmin2;
+ }
+ else
+ {
+ // Speed up velocity (linear/exponentially)
+ this.t_length = this.t_length * this.waitmin;
+ this.velocity += this.movedir * this.t_length;
+ }
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- self.movetype = MOVETYPE_FLY;
- self.solid = SOLID_BBOX;
- }
+ if (this.style & BOB_STYLE_START_OFF)
+ this.bob_on ();
+ };

- if (self.spawnflags & BOB_NONSOLID)
- self.solid = SOLID_NOT;
+ //--------------------------------------------------------------
+ nonvirtual void() bob_init =
+ {
+ this.spawnflags |= BOB_COLLISION;
+ if (this.spawnflags & BOB_NONSOLID)
+ this.spawnflags &= ~BOB_COLLISION;

- setmodel (self, self.mdl);
- setsize (self, self.mins , self.maxs);
- self.velocity = '0 0 0';
+ // Using a custom model?
+ if (this.mdl == "")
+ {
+ this.bsporigin = TRUE;
+ this.mdl = this.model;
+ }
+ else
+ {
+ this.bsporigin = FALSE;
+ this.modelindex = 0;
+ this.model = "";
+ }

- if (self.style & 1)
- self.use = func_bob_on;
+ sub_setmovedir ();
+ this.movedir = normalize (this.movedir);
+
+ if (this.height <= 0)
+ // Direction intensity
+ this.height = 8;
+ if (this.count < 1)
+ // Direction switch timer
+ this.count = 2;
+ if (this.waitmin <= 0)
+ // Speed up
+ this.waitmin = 1;
+ if (this.waitmin2 <= 0)
+ // Slow down
+ this.waitmin2 = 0.75;
+ if (this.delay < 0)
+ this.delay = random() + random() + random();
+
+ this.interaction_flags &= ~DISABLE_USE;
+
+ // added style key 1 for start off -- dumptruck_ds
+ if (this.style & BOB_STYLE_START_OFF)
+ bob_off ();
+ else
+ bob_on ();
+ };
};

/*QUAKED func_bob (0 .5 .8) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -138,56 +214,19 @@ STARTOFF : Starts off and waits for trigger - DISABLED, Ripped out ESTATE System
-------- NOTES --------
A SOLID bmodel that gently moves back and forth
*/
-void() func_bob =
+class func_bob: base_func_bob
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.spawnflags |= BOB_COLLISION;
- if (self.spawnflags & BOB_NONSOLID)
- self.spawnflags &= ~BOB_COLLISION;
-
- // Using a custom model?
- if (self.mdl == "")
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.bsporigin = TRUE;
- self.mdl = self.model;
- }
- else
+ bob_init ();
+ };
+
+ //--------------------------------------------------------------
+ void() func_bob =
{
- self.bsporigin = FALSE;
- self.modelindex = 0;
- self.model = "";
- }
-
- SetMovedir ();
- self.movedir = normalize (self.movedir);
-
- if (self.height <= 0)
- // Direction intensity
- self.height = 8;
- if (self.count < 1)
- // Direction switch timer
- self.count = 2;
- if (self.waitmin <= 0)
- // Speed up
- self.waitmin = 1;
- if (self.waitmin2 <= 0)
- // Slow down
- self.waitmin2 = 0.75;
- if (self.delay < 0)
- self.delay = random() + random() + random();
-
- // Setup Entity State functionality - Nope! (RennyC)
- // if (self.targetname != "")
- // self.use = func_bob_on;
-
- // added style key 1 for start off -- dumptruck_ds
- if (!self.style)
- func_bob_on ();
- else
- func_bob_off ();
+ this.classtype = CT_FUNC_BOB;
+ };
};

/*QUAKED misc_bob (0 0.5 0.8) (-8 -8 -8) (8 8 8) X BOB_COLLISION BOB_NONSOLID X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -196,15 +235,21 @@ void() func_bob =
}
Same as func_bob but uses a custom model instead of a brush. Use the mdl key to set the path of the model.
*/
-void() misc_bob =
+class misc_bob: base_func_bob
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.mdl == "")
+ this.mdl = string_null;
+ precache_model (this.mdl);

- if (self.mdl == "")
- self.mdl = string_null;
- precache_model (self.mdl);
+ bob_init ();
+ };

- func_bob ();
+ //--------------------------------------------------------------
+ void() misc_bob =
+ {
+ this.classtype = CT_MISC_BOB;
+ };
};

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

Diff qc/func/bossgate.qc

diff --git a/qc/func/bossgate.qc b/qc/func/bossgate.qc
index 07f519a..2161c1c 100644
--- a/qc/func/bossgate.qc
+++ b/qc/func/bossgate.qc
@@ -9,30 +9,34 @@ const float BOSSGATE_REVERSE = 16;
/*QUAKED func_bossgate (0 .5 .8) ? X X X X REVERSE_FUNCTIONALITY
This bmodel appears unless players have all of the episode sigils.
*/
-void() func_bossgate =
+class func_bossgate: base_func_wall
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.spawnflags & BOSSGATE_REVERSE)
+ virtual void() init_spawned =
{
- if (!((serverflags & 15) == 15))
+ if (this.spawnflags & BOSSGATE_REVERSE)
+ {
+ if (!((serverflags & 15) == 15))
+ {
+ // not all complete
+ return;
+ }
+ }
+ else
{
- // not all complete
- return;
+ if ((serverflags & 15) == 15)
+ // all episodes completed
+ return;
}
- }
- else
+ this.angles = '0 0 0';
+ // so it doesn't get pushed by anything
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ setmodel (this, this.model);
+ };
+
+ //--------------------------------------------------------------
+ void() func_bossgate =
{
- if ( (serverflags & 15) == 15 )
- // all episodes completed
- return;
- }
- self.angles = '0 0 0';
- // so it doesn't get pushed by anything
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
+ this.classtype = CT_FUNC_BOSSGATE;
+ };
};

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 40f83d4..df73fa4 100644
--- a/qc/func/breakable.qc
+++ b/qc/func/breakable.qc
@@ -7,217 +7,142 @@ const float BREAKABLE_NO_MONSTERS = 1;
const float BREAK_EXPLODE = 2;
const float BREAK_CUSTOM = 4;

-// prototypes
-void() make_breakable_debris;
-
-// fields
-.string break_template1;
-.string break_template2;
-.string break_template3;
-.string break_template4;
-.string break_template5;
-.float brk_obj_count1;
-.float brk_obj_count2;
-.float brk_obj_count3;
-.float brk_obj_count4;
-.float brk_obj_count5;
-
-//----------------------------------------------------------------------
-// template system from Qmaster -- dumptruck_ds
-//----------------------------------------------------------------------
-void() make_breakable_templates_debris =
+//------------------------------------------------------------------------------
+// base breakable class; used by func_breakable (below), func_fall2
+//------------------------------------------------------------------------------
+class base_breakable: base_func
{
- local float i;
- local entity new;
-
- i = 0;
- if (self.break_template1 != "")
- {
- while (i < self.brk_obj_count1)
- {
- new = spawn ();
- new.model = self.break_template1;
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
- // dumptruck_ds
- setmodel (new, new.model);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random() * 600;
- new.avelocity_y = random() * 600;
- new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random() * 10;
- new.flags = 0;
- i++;
- }
- }
-
- i = 0;
- if (self.break_template2 != "")
+ // class fields
+ string break_template1;
+ string break_template2;
+ string break_template3;
+ string break_template4;
+ string break_template5;
+ float brk_obj_count1;
+ float brk_obj_count2;
+ float brk_obj_count3;
+ float brk_obj_count4;
+ float brk_obj_count5;
+
+ //--------------------------------------------------------------
+ // SUB_DislodgeRestingEntities
+ // This clears the FL_ONGROUND flag from any entities that are on
+ // top of self. The engine does not update the FL_ONGROUND flag
+ // automatically in some cases, with the result that certain types
+ // of entities can be left floating in mid-air if the entity they
+ // are resting on is removed from under them. This function is
+ // intended to be called in the case where self is going to be
+ // removed, to ensure that other entities are not left floating. -- iw
+ //--------------------------------------------------------------
+ virtual void() sub_dislodgerestingentities =
{
- while (i < self.brk_obj_count2)
- {
- new = spawn ();
- new.model = self.break_template2;
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
- // dumptruck_ds
- setmodel (new, new.model);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random() * 600;
- new.avelocity_y = random() * 600;
- new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random() * 10;
- new.flags = 0;
- i++;
- }
- }
+ local entity e;

- i = 0;
- if (self.break_template3 != "")
- {
- while (i < self.brk_obj_count3)
+ e = nextent (world);
+ while (e && e != world)
{
- new = spawn ();
- new.model = self.break_template3;
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
- // dumptruck_ds
- setmodel (new, new.model);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random() * 600;
- new.avelocity_y = random() * 600;
- new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random() * 10;
- new.flags = 0;
- i++;
+ if ((e.flags & FL_ONGROUND) && e.groundentity == this)
+ e.flags = e.flags - (e.flags & FL_ONGROUND);
+ e = nextent (e);
}
- }
+ };

- i = 0;
- if (self.break_template4 != "")
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
{
- while (i < self.brk_obj_count4)
+ switch (fieldname)
{
- new = spawn ();
- new.model = self.break_template4;
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
- // dumptruck_ds
- setmodel (new, new.model);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random() * 600;
- new.avelocity_y = random() * 600;
- new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random() * 10;
- new.flags = 0;
- i++;
+ case "break_template1":
+ this.break_template1 = fieldvalue;
+ break;
+ case "break_template2":
+ this.break_template2 = fieldvalue;
+ break;
+ case "break_template3":
+ this.break_template3 = fieldvalue;
+ break;
+ case "break_template4":
+ this.break_template4 = fieldvalue;
+ break;
+ case "break_template5":
+ this.break_template5 = fieldvalue;
+ break;
+ case "brk_obj_count1":
+ this.brk_obj_count1 = stof (fieldvalue);
+ break;
+ case "brk_obj_count2":
+ this.brk_obj_count2 = stof (fieldvalue);
+ break;
+ case "brk_obj_count3":
+ this.brk_obj_count3 = stof (fieldvalue);
+ break;
+ case "brk_obj_count4":
+ this.brk_obj_count4 = stof (fieldvalue);
+ break;
+ case "brk_obj_count5":
+ this.brk_obj_count5 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
}
- }
+ };

- i = 0;
- if (self.break_template5 != "")
+ //--------------------------------------------------------------
+ virtual void(string templatename) template_single_debris =
{
- while (i < self.brk_obj_count5)
- {
- new = spawn ();
- new.model = self.break_template5;
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
- // dumptruck_ds
- setmodel (new, new.model);
- setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
- new.movetype = MOVETYPE_BOUNCE;
- new.solid = SOLID_NOT;
- new.avelocity_x = random() * 600;
- new.avelocity_y = random() * 600;
- new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
- new.ltime = time;
- new.nextthink = time + 10 + random() * 10;
- new.flags = 0;
- i++;
- }
- }
-};
-
-
-//======================================================================
-// Below this is from Rubicon2 -- dumptruck_ds
-//======================================================================
+ local entity new;

-//----------------------------------------------------------------------
-void() make_breakable_debris =
-{
- local float i = 0;
+ new = spawn ();
+ new.model = templatename;
+ new.origin_x = (this.maxs_x - this.mins_x) *
+ random() + this.mins_x;
+ new.origin_y = (this.maxs_y - this.mins_y) *
+ random() + this.mins_y;
+ new.origin_z = (this.maxs_z - this.mins_z) *
+ random() + this.mins_z;
+ // dumptruck_ds
+ setmodel (new, new.model);
+ setsize (new, '0 0 0', '0 0 0');
+ new.velocity = VelocityForDamage (this.health * 2);
+ new.movetype = MOVETYPE_BOUNCE;
+ new.solid = SOLID_NOT;
+ new.avelocity_x = random() * 600;
+ new.avelocity_y = random() * 600;
+ new.avelocity_z = random() * 600;
+ new.think = sub_remove;
+ new.ltime = time;
+ new.nextthink = time + 10 + random() * 10;
+ new.flags = 0;
+ };

- while (i < self.cnt)
+ //--------------------------------------------------------------
+ virtual void() single_debris =
{
local entity new;

new = spawn ();
- new.origin_x = (self.maxs_x - self.mins_x) *
- random() + self.mins_x;
- new.origin_y = (self.maxs_y - self.mins_y) *
- random() + self.mins_y;
- new.origin_z = (self.maxs_z - self.mins_z) *
- random() + self.mins_z;
-
- // this was originally just an mdl from Rubicon2, now you
- // set custom model via spawnflag or use the builtin from
+ new.origin_x = (this.maxs_x - this.mins_x) *
+ random() + this.mins_x;
+ new.origin_y = (this.maxs_y - this.mins_y) *
+ random() + this.mins_y;
+ new.origin_z = (this.maxs_z - this.mins_z) *
+ random() + this.mins_z;
+
+ // this was originally just an mdl from Rubicon2, now you set
+ // custom model via spawnflag or use the builtin from
// Rubicon2 -- dumptruck_ds
// setmodel (new, "progs/debris.mdl");

// dumptruck_ds
- setmodel (new, self.mdl_debris);
+ setmodel (new, this.mdl_debris);
setsize (new, '0 0 0', '0 0 0');
- new.velocity = VelocityForDamage (self.health * 2);
+ new.velocity = VelocityForDamage (this.health * 2);
new.movetype = MOVETYPE_BOUNCE;
new.solid = SOLID_NOT;
new.avelocity_x = random() * 600;
new.avelocity_y = random() * 600;
new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
+ new.think = sub_remove;
new.ltime = time;
new.nextthink = time + 10 + random() * 10;
new.flags = 0;
@@ -231,172 +156,185 @@ void() make_breakable_debris =
new.frame = 2;

// choose skin based on "style" key
- if (self.style == 1)
- new.skin = 1;
- if (self.style == 2)
- new.skin = 2;
- if (self.style == 3)
- // new debris skins start here - dumptruck_ds
- new.skin = 3;
- if (self.style == 4)
- new.skin = 4;
- if (self.style == 5)
- new.skin = 5;
- if (self.style == 6)
- new.skin = 6;
- if (self.style == 7)
- new.skin = 7;
- if (self.style == 8)
- new.skin = 8;
- if (self.style == 9)
- new.skin = 9;
- if (self.style == 10)
- new.skin = 10;
- if (self.style == 11)
- new.skin = 11;
- if (self.style == 12)
- new.skin = 12;
- if (self.style == 13)
- new.skin = 13;
- if (self.style == 14)
- new.skin = 14;
- if (self.style == 15)
- new.skin = 15;
- if (self.style == 16)
- new.skin = 16;
- if (self.style == 17)
- new.skin = 17;
- if (self.style == 18)
- new.skin = 18;
- if (self.style == 19)
- new.skin = 19;
- if (self.style == 20)
- new.skin = 20;
- if (self.style == 21)
- new.skin = 21;
- if (self.style == 22)
- new.skin = 22;
- if (self.style == 23)
- new.skin = 23;
- if (self.style == 24)
- new.skin = 24;
- if (self.style == 25)
- new.skin = 25;
- if (self.style == 26)
- new.skin = 26;
- if (self.style == 27)
- new.skin = 27;
- if (self.style == 28)
- new.skin = 28;
- if (self.style == 29)
- new.skin = 29;
- if (self.style == 30)
- new.skin = 30;
- if (self.style == 31)
- // new debris skins end here - dumptruck_ds
- new.skin = 31;
-
- i = i + 1;
- }
-};
+ //
+ // this was originally a large block of individual if
+ // statements in the form of:
+ // if (this.style == 1)
+ // new.skin = 1;
+ // if (this.style == 2)
+ // new.skin = 2;
+ // and so on, up until 31. As far as I can tell new.skin
+ // was always set to the same value as this.style. So I've
+ // simplified the block into the code below.
+ // New debris skins start at 3 and continue through 31
+ // according to comments left by dumptruck_ds -- CEV
+
+ if (this.style > 0 && this.style <= 31)
+ {
+ new.skin = this.style;
+ }
+ };

-//----------------------------------------------------------------------
-// dumptruck_ds -- set the spawnflag for cosmetic explosion effect;
-// use "dmg" value to hurt the player
-//----------------------------------------------------------------------
-void() func_breakable_die =
-{
- {
- // thanks to Qmaster!!! He helped me sort out noise1
- // playing from 0 0 0 with this temp entity - dumptruck_ds
- local entity ent;
-
- ent = spawn ();
- ent.origin = ((self.absmin + self.absmax) * 0.5);
- setsize (ent, '0 0 0', '0 0 0');
- ent.solid = SOLID_NOT;
- ent.think = SUB_Remove;
- // ent.ltime = time;
- ent.nextthink = time + 60;
-
- sound (ent, CHAN_AUTO, self.noise1, 1, ATTN_NORM);
- // remove (self);
- }
-
- // this is to ensure that any debris from another func_breakable
- // which is resting on top of this func_breakable is not left
- // floating in mid-air after this entity is removed -- iw
- SUB_DislodgeRestingEntities ();
-
- if (self.spawnflags & BREAK_EXPLODE)
+ //--------------------------------------------------------------
+ // template system from Qmaster -- dumptruck_ds
+ //--------------------------------------------------------------
+ nonvirtual void() make_breakable_templates_debris =
{
- if (self.spawnflags & BREAK_CUSTOM)
+ local float count = 0;
+ local string break_template = "";
+
+ for (int i = 1; i < 6; i++)
{
- make_breakable_templates_debris ();
+ switch (i)
+ {
+ case 1:
+ break_template = this.break_template1;
+ count = this.brk_obj_count1;
+ break;
+ case 2:
+ break_template = this.break_template2;
+ count = this.brk_obj_count2;
+ break;
+ case 3:
+ break_template = this.break_template3;
+ count = this.brk_obj_count3;
+ break;
+ case 4:
+ break_template = this.break_template4;
+ count = this.brk_obj_count4;
+ break;
+ case 5:
+ break_template = this.break_template5;
+ count = this.brk_obj_count5;
+ break;
+ }
+
+ if (break_template != __NULL__ && break_template != "")
+ {
+ for (int j = 0; j < count; j++)
+ {
+ template_single_debris (break_template);
+ }
+ }
+
+ break_template = "";
+ count = 0;
}
- else
+ };
+
+ //==============================================================
+ // Below this is from Rubicon2 -- dumptruck_ds
+ //==============================================================
+
+ //--------------------------------------------------------------
+ nonvirtual void() make_breakable_debris =
+ {
+ for (int i = 0; i < this.cnt; i++)
+ single_debris ();
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds -- set the spawnflag for cosmetic explosion
+ // effect; use "dmg" value to hurt the player
+ //--------------------------------------------------------------
+ virtual void() breakable_die =
+ {
+ // what is this brace doing here? -- TODO CEV
{
- make_breakable_debris ();
+ // thanks to Qmaster!!! He helped me sort out
+ // noise1 playing from 0 0 0 with this temp
+ // entity - dumptruck_ds
+ local entity ent;
+
+ ent = spawn ();
+ ent.origin = ((this.absmin + this.absmax) * 0.5);
+ setsize (ent, '0 0 0', '0 0 0');
+ ent.solid = SOLID_NOT;
+ ent.think = sub_remove;
+ // ent.ltime = time;
+ ent.nextthink = time + 60;
+
+ sound (ent, CHAN_AUTO, this.noise1, 1, ATTN_NORM);
+ // remove (this);
}
- // to let us use noise2
- func_explobox_explode_silent ();
-
- // this is broken as of 1.1.0 no custom explosion sound
- // for now -- dumptruck_ds
- // sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- remove (self);
- }
- else
- {
- self.origin = ((self.absmin + self.absmax) * 0.5);
- setorigin (self, self.origin);
- DropStuff ();
- if (self.spawnflags & BREAK_CUSTOM)
+
+ // this is to ensure that any debris from another
+ // func_breakable which is resting on top of this
+ // func_breakable is not left floating in mid-air
+ // after this entity is removed -- iw
+ sub_dislodgerestingentities ();
+
+ if (this.spawnflags & BREAK_EXPLODE)
{
- if (self.switchshadstyle)
- lightstyle(self.switchshadstyle, "m");
- make_breakable_templates_debris ();
- remove (self);
+ if (this.spawnflags & BREAK_CUSTOM)
+ make_breakable_templates_debris ();
+ else
+ make_breakable_debris ();
+
+ // to let us use noise2
+ // TODO CEV
+ func_explobox::explode_silent ();
+
+ // this is broken as of 1.1.0 no custom explosion
+ // sound for now -- dumptruck_ds
+ // sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);
+ remove (this);
}
else
{
- if (self.switchshadstyle)
- lightstyle(self.switchshadstyle, "m");
- make_breakable_debris ();
- remove (self);
+ this.origin = ((this.absmin + this.absmax) * 0.5);
+ setorigin (this, this.origin);
+ DropStuff ();
+ if (this.spawnflags & BREAK_CUSTOM)
+ {
+ if (this.switchshadstyle)
+ lightstyle(this.switchshadstyle, "m");
+ make_breakable_templates_debris ();
+ remove (this);
+ }
+ else
+ {
+ if (this.switchshadstyle)
+ lightstyle(this.switchshadstyle, "m");
+ make_breakable_debris ();
+ remove (this);
+ }
}
- }
-};
+ };

-//----------------------------------------------------------------------
-void() func_breakable_killed =
-{
- activator = damage_attacker;
- SUB_UseTargets ();
- func_breakable_die ();
-};
+ //--------------------------------------------------------------
+ virtual void() breakable_killed =
+ {
+ activator = damage_attacker;
+ sub_usetargets ();
+ breakable_die ();
+ };

-//----------------------------------------------------------------------
-void() func_breakable_use =
-{
- activator = other;
- SUB_UseTargets ();
- func_breakable_die ();
-};
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.targetname == __NULL__ || this.targetname == "")
+ return;

-//----------------------------------------------------------------------
-void() break_template_setup =
-{
- if (self.break_template1 != "")
- precache_model (self.break_template1);
- if (self.break_template2 != "")
- precache_model (self.break_template2);
- if (self.break_template3 != "")
- precache_model (self.break_template3);
- if (self.break_template4 != "")
- precache_model (self.break_template4);
- if (self.break_template5 != "")
- precache_model (self.break_template5);
+ activator = caller;
+ sub_usetargets ();
+ breakable_die ();
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() break_template_setup =
+ {
+ if (this.break_template1 != "")
+ precache_model (this.break_template1);
+ if (this.break_template2 != "")
+ precache_model (this.break_template2);
+ if (this.break_template3 != "")
+ precache_model (this.break_template3);
+ if (this.break_template4 != "")
+ precache_model (this.break_template4);
+ if (this.break_template5 != "")
+ precache_model (this.break_template5);
+ };
};

/*QUAKED func_breakable (0 .5 .8) ? NO_MONSTERS X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -463,116 +401,121 @@ brk_obj_count3(integer) : "Template 3 spawn count"
brk_obj_count4(integer) : "Template 4 spawn count"
brk_obj_count5(integer) : "Template 5 spawn count"
*/
-void() func_breakable =
+class func_breakable: base_breakable
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- break_template_setup ();
-
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- self.mdl_debris = "progs/debris.mdl";
- precache_model (self.mdl_debris);
- precache_sound ("blob/hit1.wav");
-
- if (self.noise1 != "")
- precache_sound(self.noise1);
-
- // adding new default sounds for "simple" breakables in 1.2.0
- // -- dumptruck_ds
-
- // here's genreic metal breaking
- if (self.style == 0 || self.style == 11 || self.style == 12 ||
- self.style == 17 || self.style == 18 || self.style == 19 ||
- self.style == 24 || self.style == 31)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- if !(self.noise1)
+ break_template_setup ();
+
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setmodel (this, this.model);
+ this.mdl_debris = "progs/debris.mdl";
+ precache_model (this.mdl_debris);
+ precache_sound ("blob/hit1.wav");
+
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+
+ // adding new default sounds for "simple" breakables in 1.2.0
+ // -- dumptruck_ds
+
+ // here's genreic metal breaking
+ if (this.style == 0 || this.style == 11 ||
+ this.style == 12 || this.style == 17 ||
+ this.style == 18 || this.style == 19 ||
+ this.style == 24 || this.style == 31)
{
- precache_sound ("break/metal2.wav");
- self.noise1 = "break/metal2.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/metal2.wav");
+ this.noise1 = "break/metal2.wav";
+ }
}
- }

- if (self.style == 3 || self.style == 4 || self.style == 5)
- {
- if !(self.noise1)
+ if (this.style == 3 || this.style == 4 || this.style == 5)
{
- precache_sound ("break/wood1.wav");
- precache_sound ("break/wood2.wav");
- // wood only randomized
- if (random() > 0.6)
- self.noise1 = "break/wood1.wav";
- else
- self.noise1 = "break/wood2.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/wood1.wav");
+ precache_sound ("break/wood2.wav");
+ // wood only randomized
+ if (random() > 0.6)
+ this.noise1 = "break/wood1.wav";
+ else
+ this.noise1 = "break/wood2.wav";
+ }
}
- }

- // glass sounds -- this is more of a shattering sound anyway
- if (self.style == 6 || self.style == 7 || self.style == 8 ||
- self.style == 9 || self.style == 10)
- {
- if !(self.noise1)
+ // glass sounds -- this is more of a shattering sound anyway
+ if (this.style == 6 || this.style == 7 || this.style == 8 ||
+ this.style == 9 || this.style == 10)
{
- precache_sound ("break/metal1.wav");
- self.noise1 = "break/metal1.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/metal1.wav");
+ this.noise1 = "break/metal1.wav";
+ }
}
- }

- if (self.style == 1 || self.style == 2 || self.style == 13 ||
- self.style == 14 || self.style == 15 || self.style == 16 ||
- self.style == 20 || self.style == 21 || self.style == 22 ||
- self.style == 23)
- {
- if !(self.noise1)
+ if (this.style == 1 || this.style == 2 ||
+ this.style == 13 || this.style == 14 ||
+ this.style == 15 || this.style == 16 ||
+ this.style == 20 || this.style == 21 ||
+ this.style == 22 || this.style == 23)
{
- precache_sound ("break/stones1.wav");
- precache_sound ("break/bricks1.wav");
- // wood only randomized
- if (random() > 0.6)
- self.noise1 = "break/bricks1.wav";
- else
- self.noise1 = "break/stones1.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/stones1.wav");
+ precache_sound ("break/bricks1.wav");
+ // wood only randomized
+ if (random() > 0.6)
+ this.noise1 = "break/bricks1.wav";
+ else
+ this.noise1 = "break/stones1.wav";
+ }
}
- }

- if (self.style == 25 || self.style == 26 || self.style == 27 ||
- self.style == 28 || self.style == 29 || self.style == 30)
- {
- if !(self.noise1)
+ if (this.style == 25 || this.style == 26 ||
+ this.style == 27 || this.style == 28 ||
+ this.style == 29 || this.style == 30)
{
- precache_sound ("break/stones1.wav");
- precache_sound ("break/bricks1.wav");
- // wood only randomized
- if (random() > 0.6)
- self.noise1 = "break/stones1.wav";
- else
- self.noise1 = "break/bricks1.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/stones1.wav");
+ precache_sound ("break/bricks1.wav");
+ // wood only randomized
+ if (random() > 0.6)
+ this.noise1 = "break/stones1.wav";
+ else
+ this.noise1 = "break/bricks1.wav";
+ }
+ // else
+ // {
+ // (this.noise1 = "blob/hit1.wav");
+ // }
}
- // else
- // {
- // (self.noise1 = "blob/hit1.wav");
- // }
- }
-
- if (!self.health)
- self.health = 20;
- if (!self.cnt)
- // was 6 dumptruck_ds
- self.cnt = 5;
-
- if (self.targetname != "")
- {
- self.use = func_breakable_use;
- }
- else
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = func_breakable_killed;
- }

- if (self.switchshadstyle)
- lightstyle (self.switchshadstyle, "a");
+ if (!this.health)
+ this.health = 20;
+ if (!this.cnt)
+ // was 6 dumptruck_ds
+ this.cnt = 5;
+
+ if (this.targetname == __NULL__ || this.targetname == "")
+ {
+ this.takedamage = DAMAGE_YES;
+ this.th_die = breakable_killed;
+ }
+
+ if (this.switchshadstyle)
+ lightstyle (this.switchshadstyle, "a");
+ };
+
+ //--------------------------------------------------------------
+ void() func_breakable =
+ {
+ this.classtype = CT_FUNC_BREAKABLE;
+ };
};

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

Diff qc/func/brush.qc

diff --git a/qc/func/brush.qc b/qc/func/brush.qc
index db7fc5c..208f115 100644
--- a/qc/func/brush.qc
+++ b/qc/func/brush.qc
@@ -2,25 +2,27 @@
// func_brush
//==============================================================================

-//this is on hold and not in progs.src
+// this is on hold and not in progs.src
// crashes in QS at the moment Jaycie is looking into it

// fields
+/*
.float solidstate;
.float visiblestate;
+*/

// constants
-const float START_INVISIBLE = 1;
-const float START_NONSOLID = 2;
-const float START_ALTFRAMES = 4;
-const float TOGGLE_VISIBILITY = 8;
-const float TOGGLE_SOLIDITY = 16;
-const float TOGGLE_FRAMES = 32;
+const float BRUSH_START_INVISIBLE = 1;
+const float BRUSH_START_NONSOLID = 2;
+const float BRUSH_START_ALTFRAMES = 4;
+const float BRUSH_TOGGLE_VISIBILITY = 8;
+const float BRUSH_TOGGLE_SOLIDITY = 16;
+const float BRUSH_TOGGLE_FRAMES = 32;

//----------------------------------------------------------------------
void() func_brush_use =
{
- if (self.spawnflags & TOGGLE_VISIBILITY)
+ if (self.spawnflags & BRUSH_TOGGLE_VISIBILITY)
{
if (self.visiblestate == 1)
{
@@ -33,7 +35,7 @@ void() func_brush_use =
self.visiblestate = 1;
}
}
- if (self.spawnflags & TOGGLE_SOLIDITY)
+ if (self.spawnflags & BRUSH_TOGGLE_SOLIDITY)
{
if (self.solidstate == 1)
{
@@ -47,7 +49,7 @@ void() func_brush_use =
self.solidstate = 1;
}
}
- if (self.spawnflags & TOGGLE_FRAMES)
+ if (self.spawnflags & BRUSH_TOGGLE_FRAMES)
self.frame = 1 - self.frame;
};

@@ -61,7 +63,7 @@ void() func_brush =
self.mdl = self.model;
setorigin (self, self.origin);

- if (self.spawnflags & START_INVISIBLE)
+ if (self.spawnflags & BRUSH_START_INVISIBLE)
{
self.visiblestate = 0;
self.model = "";
@@ -71,7 +73,7 @@ void() func_brush =
self.visiblestate = 1;
}

- if (self.spawnflags & START_NONSOLID)
+ if (self.spawnflags & BRUSH_START_NONSOLID)
{
self.solidstate = 0;
self.solid = SOLID_NOT;
@@ -82,7 +84,7 @@ void() func_brush =
self.solid = SOLID_BSP;
}

- if (self.spawnflags & START_ALTFRAMES)
+ if (self.spawnflags & BRUSH_START_ALTFRAMES)
self.frame = 1;
else
self.frame = 0;

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

Diff qc/func/button.qc

diff --git a/qc/func/button.qc b/qc/func/button.qc
index 36ac256..c2a8829 100644
--- a/qc/func/button.qc
+++ b/qc/func/button.qc
@@ -2,234 +2,213 @@
// func_button -- button and multiple button
//==============================================================================

-// prototypes
-void() button_wait;
-void() button_return;
-
-//----------------------------------------------------------------------
-void() button_wait =
-{
- self.state = STATE_TOP;
- self.nextthink = self.ltime + self.wait;
- self.think = button_return;
- activator = self.enemy;
- // use alternate textures
- self.frame = 1;
-
- if (self.estate != STATE_ACTIVE)
- return;
-
- SUB_UseTargets ();
-};
-
-//----------------------------------------------------------------------
-void() button_done =
-{
- self.state = STATE_BOTTOM;
-};
-
-//----------------------------------------------------------------------
-void() button_return =
-{
- if (self.estate != STATE_ACTIVE)
- return;
-
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, button_done);
- // use normal textures
- self.frame = 0;
-
- if (self.health)
- // can be shot again
- self.takedamage = DAMAGE_YES;
-};
+/*QUAKED func_button (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.

-//----------------------------------------------------------------------
-void() button_blocked =
+"angle" determines the opening direction
+"target" all entities with a matching targetname will be used
+"speed" override the default 40 speed
+"wait" override the default 1 second wait (-1 = never return)
+"lip" override the default 4 pixel lip remaining at end of move
+"health" if set, the button must be killed instead of touched
+"sounds"
+0) steam metal
+1) wooden clunk
+2) metallic click
+3) in-out
+*/
+class func_button: base_func
{
- // do nothing, just don't ome all the way back out
-};
+ //--------------------------------------------------------------
+ nonvirtual void() button_wait =
+ {
+ this.state = FUNC_STATE_TOP;
+ this.nextthink = this.ltime + this.wait;
+ activator = this.enemy;
+ // use alternate textures
+ this.frame = 1;

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

- if (self.state == STATE_UP || self.state == STATE_TOP)
- return;
+ sub_usetargets ();
+ };

- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ //--------------------------------------------------------------
+ nonvirtual void() button_done =
+ {
+ this.state = FUNC_STATE_BOTTOM;
+ };

- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, button_wait);
-};
+ //--------------------------------------------------------------
+ nonvirtual void() button_fire =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

-//----------------------------------------------------------------------
-void() button_use =
-{
- self.enemy = activator;
- button_fire ();
-};
+ if (this.state == FUNC_STATE_UP || this.state == FUNC_STATE_TOP)
+ return;

-//----------------------------------------------------------------------
-void() button_touch =
-{
- if (other.classname != "player")
- return;
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);

- self.enemy = other;
- button_fire ();
-};
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos2, this.speed, button_wait);
+ };

-//----------------------------------------------------------------------
-void() button_killed =
-{
- if (self.estate != STATE_ACTIVE)
- return;
+ //--------------------------------------------------------------
+ // was button_return -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

- self.enemy = damage_attacker;
- self.health = self.max_health;
- // wil be reset upon return
- self.takedamage = DAMAGE_NO;
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos1, this.speed, this.button_done);
+ // use normal textures
+ this.frame = 0;

- button_fire ();
-};
+ if (this.health)
+ // can be shot again
+ this.takedamage = DAMAGE_YES;
+ };

-//----------------------------------------------------------------------
-// adapted from Copper, thanks Lunaran
-//----------------------------------------------------------------------
-void(entity b) button_lock =
-{
- entity oself;
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ this.enemy = activator;
+ button_fire ();
+ };

- if (b.estate == STATE_INACTIVE)
- return;
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ if (this.health)
+ return;

- oself = self;
- self = b;
+ if (toucher.classtype != CT_PLAYER)
+ return;

- if (self.state == STATE_UP || self.state == STATE_TOP)
- self.prevstate = STATE_TOP;
- else
- self.prevstate = STATE_BOTTOM;
+ this.enemy = toucher;
+ button_fire ();
+ };

- if (self.max_health)
- self.takedamage = DAMAGE_NO;
+ //--------------------------------------------------------------
+ nonvirtual void() button_killed =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;

- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, button_wait);
- self.estate = STATE_INACTIVE;
+ this.enemy = damage_attacker;
+ this.health = this.max_health;
+ // wil be reset upon return
+ this.takedamage = DAMAGE_NO;

- self = oself;
-};
+ button_fire ();
+ };

-//----------------------------------------------------------------------
-void(entity b, float dontresetstate) button_unlock =
-{
- entity oself;
+ //--------------------------------------------------------------
+ // adapted from Copper, thanks Lunaran -- modified again by CEV
+ //--------------------------------------------------------------
+ nonvirtual void(func_button b) button_lock =
+ {
+ if (b.estate == STATE_INACTIVE)
+ return;
+
+ if (b.state == FUNC_STATE_UP || b.state == FUNC_STATE_TOP)
+ b.prevstate = FUNC_STATE_TOP;
+ else
+ b.prevstate = FUNC_STATE_BOTTOM;
+
+ if (b.max_health)
+ b.takedamage = DAMAGE_NO;
+
+ b.state = FUNC_STATE_UP;
+ b.calc_move (b.pos2, b.speed, b.button_wait);
+ b.estate = STATE_INACTIVE;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(func_button b, float dontresetstate) button_unlock =
+ {
+ if (b.estate == STATE_ACTIVE)
+ return;

- if (b.estate == STATE_ACTIVE)
- return;
+ if (!dontresetstate || b.wait != -1 ||
+ b.prevstate == FUNC_STATE_BOTTOM)
+ {
+ if (b.max_health)
+ {
+ b.takedamage = DAMAGE_YES;
+ b.health = b.max_health;
+ }
+
+ // use normal textures
+ b.frame = 0;
+ b.state = FUNC_STATE_DOWN;
+ b.calc_move (b.pos1, b.speed, b.button_done);
+ }

- oself = self;
- self = b;
+ b.estate = STATE_ACTIVE;
+ };

- if (!dontresetstate || self.wait != -1 ||
- self.prevstate == STATE_BOTTOM)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- if (self.max_health)
+ if (this.sounds == 0)
{
- self.takedamage = DAMAGE_YES;
- self.health = self.max_health;
+ precache_sound ("buttons/airbut1.wav");
+ this.noise = "buttons/airbut1.wav";
}

- // use normal textures
- self.frame = 0;
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, button_done);
- }
-
- self.estate = STATE_ACTIVE;
-
- self = oself;
-};
-
-/*QUAKED func_button (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
+ if (this.sounds == 1)
+ {
+ precache_sound ("buttons/switch21.wav");
+ this.noise = "buttons/switch21.wav";
+ }

-"angle" determines the opening direction
-"target" all entities with a matching targetname will be used
-"speed" override the default 40 speed
-"wait" override the default 1 second wait (-1 = never return)
-"lip" override the default 4 pixel lip remaining at end of move
-"health" if set, the button must be killed instead of touched
-"sounds"
-0) steam metal
-1) wooden clunk
-2) metallic click
-3) in-out
-*/
-void() func_button =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ if (this.sounds == 2)
+ {
+ precache_sound ("buttons/switch02.wav");
+ this.noise = "buttons/switch02.wav";
+ }

- if (self.sounds == 0)
- {
- precache_sound ("buttons/airbut1.wav");
- self.noise = "buttons/airbut1.wav";
- }
+ if (this.sounds == 3)
+ {
+ precache_sound ("buttons/switch04.wav");
+ this.noise = "buttons/switch04.wav";
+ }

- if (self.sounds == 1)
- {
- precache_sound ("buttons/switch21.wav");
- self.noise = "buttons/switch21.wav";
- }
+ sub_setmovedir ();

- if (self.sounds == 2)
- {
- precache_sound ("buttons/switch02.wav");
- self.noise = "buttons/switch02.wav";
- }
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ setmodel (this, this.model);

- if (self.sounds == 3)
- {
- precache_sound ("buttons/switch04.wav");
- self.noise = "buttons/switch04.wav";
- }
+ if (this.health)
+ {
+ this.max_health = this.health;
+ this.th_die = button_killed;
+ this.takedamage = DAMAGE_YES;
+ }

- SetMovedir ();
+ if (!this.speed)
+ this.speed = 40;
+ if (!this.wait)
+ this.wait = 1;
+ if (!this.lip)
+ this.lip = 4;

- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- setmodel (self, self.model);
+ this.state = FUNC_STATE_BOTTOM;

- self.blocked = button_blocked;
- self.use = button_use;
+ this.pos1 = this.origin;
+ this.pos2 = this.pos1 + this.movedir *
+ (fabs(this.movedir * this.size) - this.lip);
+ };

- if (self.health)
- {
- self.max_health = self.health;
- self.th_die = button_killed;
- self.takedamage = DAMAGE_YES;
- }
- else
+ //--------------------------------------------------------------
+ void() func_button =
{
- self.touch = button_touch;
- }
-
- if (!self.speed)
- self.speed = 40;
- if (!self.wait)
- self.wait = 1;
- if (!self.lip)
- self.lip = 4;
-
- self.state = STATE_BOTTOM;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir *
- (fabs(self.movedir * self.size) - self.lip);
+ this.classtype = CT_FUNC_BUTTON;
+ };
};

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

Diff qc/func/counter.qc

diff --git a/qc/func/counter.qc b/qc/func/counter.qc
index 209c801..6fcafa1 100644
--- a/qc/func/counter.qc
+++ b/qc/func/counter.qc
@@ -17,125 +17,6 @@ const float COUNTER_RANDOM = 16;
const float COUNTER_FINISHCOUNT = 32;
const float COUNTER_START_ON = 64;

-// prototypes
-void() counter_on_use;
-void() counter_off_use;
-
-//----------------------------------------------------------------------
-void() counter_think =
-{
- self.cnt = self.cnt + 1;
- if (self.spawnflags & COUNTER_RANDOM)
- {
- self.state = random() * self.count;
- self.state = floor(self.state) + 1;
- }
- else
- {
- self.state = self.cnt;
- }
-
- // fix func_counter and func_oncount handling of activator -- iw
- // activator = other;
- activator = self.enemy;
- SUB_UseTargets ();
- self.nextthink = time + self.wait;
-
- if (self.spawnflags & COUNTER_STEP)
- {
- counter_on_use ();
- }
-
- if (self.cnt >= self.count)
- {
- self.cnt = 0;
- if ((self.aflag) || !(self.spawnflags & COUNTER_LOOP))
- {
- if (self.spawnflags & COUNTER_TOGGLE)
- {
- counter_on_use ();
- }
- else
- {
- remove (self);
- }
- }
- }
-};
-
-//----------------------------------------------------------------------
-// counter_start_on_think
-// fix func_counter and func_oncount handling of activator -- iw
-//----------------------------------------------------------------------
-void() counter_start_on_think =
-{
- // to ensure it's not a random entity -- iw
- activator = world;
- counter_off_use ();
-};
-
-//----------------------------------------------------------------------
-void() counter_on_use =
-{
- if (( self.cnt != 0) && (self.spawnflags & COUNTER_FINISHCOUNT))
- {
- self.aflag = TRUE;
- return;
- }
-
- self.use = counter_off_use;
- self.think = SUB_Null;
- self.aflag = FALSE;
-};
-
-//----------------------------------------------------------------------
-void() counter_off_use =
-{
- self.aflag = FALSE;
- if (self.spawnflags & COUNTER_TOGGLE)
- {
- self.use = counter_on_use;
- }
- else
- {
- self.use = SUB_Null;
- }
-
- if (self.spawnflags & COUNTER_RESET)
- {
- self.cnt = 0;
- self.state = 0;
- }
-
- // fix func_counter and func_oncount handling of activator -- iw
- self.enemy = activator;
- self.think = counter_think;
-
- // fix "delay" making func_counter not work -- iw
- // if (self.delay)
- if (self.pausetime)
- {
- // fix "delay" making func_counter not work -- iw
- // self.nextthink = time + self.delay;
- self.nextthink = time + self.pausetime;
- }
- else
- {
- counter_think ();
- }
-};
-
-//----------------------------------------------------------------------
-float(entity counter) counter_GetCount =
-{
- if (counter.classname == "counter")
- {
- return counter.state;
- }
-
- return 0;
-};
-
/*QUAKED func_counter (0 0 0.5) (0 0 0) (32 32 32) TOGGLE LOOP STEP RESET RANDOM FINISHCOUNT START_ON X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
TOGGLE causes the counter to switch between an on and off state
each time the counter is triggered.
@@ -163,48 +44,158 @@ it specifies how high to count before reseting to zero. Default is 10.

"delay" how much time to wait before firing after being switched on.
*/
-void() func_counter =
+class func_counter: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ float counter_on;

- if (!self.wait)
- self.wait = 1;
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.spawnflags & COUNTER_START_ON && caller != this)
+ {
+ // was counter_start_on_think -- CEV
+ // fix func_counter and func_oncount handling of
+ // activator -- iw
+ // to ensure it's not a random entity -- iw
+ activator = world;
+ counter_off_use ();
+ }
+ else
+ {
+ // was counter_think -- CEV
+ this.cnt = this.cnt + 1;
+ if (this.spawnflags & COUNTER_RANDOM)
+ {
+ this.state = random() * this.count;
+ this.state = floor(this.state) + 1;
+ }
+ else
+ {
+ this.state = this.cnt;
+ }

- self.count = floor (self.count);
- if (self.count <= 0)
- self.count = 10;
+ // fix func_counter and func_oncount handling of
+ // activator -- iw
+ // activator = other;
+ activator = this.enemy;
+ sub_usetargets ();
+ this.nextthink = time + this.wait;

- // fix "delay" making func_counter not work -- iw
- self.pausetime = self.delay;
- self.delay = 0;
+ if (this.spawnflags & COUNTER_STEP)
+ {
+ counter_on_use ();
+ }

- self.cnt = 0;
- self.state = 0;
+ if (this.cnt >= this.count)
+ {
+ this.cnt = 0;
+ if ((aflag) || !(spawnflags & COUNTER_LOOP))
+ if (this.spawnflags & COUNTER_TOGGLE)
+ counter_on_use ();
+ else
+ remove (this);
+ }
+ }
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() counter_on_use =
+ {
+ if ((this.cnt != 0) && (this.spawnflags & COUNTER_FINISHCOUNT))
+ {
+ this.aflag = TRUE;
+ return;
+ }

- self.classname = "counter";
- self.use = counter_off_use;
- self.think = SUB_Null;
+ this.counter_on = TRUE;
+ this.interaction_flags |= DISABLE_THINK;
+ this.aflag = FALSE;
+ };

- if (self.spawnflags & COUNTER_START_ON)
+ //--------------------------------------------------------------
+ nonvirtual void() counter_off_use =
{
+ this.aflag = FALSE;
+ if (this.spawnflags & COUNTER_TOGGLE)
+ {
+ this.counter_on = FALSE;
+ }
+
+ if (this.spawnflags & COUNTER_RESET)
+ {
+ this.cnt = 0;
+ this.state = 0;
+ }
+
// fix func_counter and func_oncount handling of activator -- iw
- // self.think = counter_off_use;
- self.think = counter_start_on_think;
- self.nextthink = time + 0.1;
- }
-};
+ this.enemy = activator;
+ this.interaction_flags &= ~DISABLE_THINK;

-//----------------------------------------------------------------------
-void() oncount_use =
-{
- if (counter_GetCount(other) == self.count)
+ // fix "delay" making func_counter not work -- iw
+ // if (this.delay)
+ if (this.pausetime)
+ {
+ // fix "delay" making func_counter not work -- iw
+ // this.nextthink = time + this.delay;
+ this.nextthink = time + this.pausetime;
+ }
+ else
+ {
+ this.do_think (this);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- // fix func_counter and func_oncount handling of activator -- iw
- // activator = other;
- SUB_UseTargets ();
- }
+ if (counter_on)
+ counter_off_use ();
+ else
+ if (this.spawnflags & COUNTER_TOGGLE)
+ counter_on_use ();
+ };
+
+ //--------------------------------------------------------------
+ static float(entity ent) getcount =
+ {
+ if (ent.classtype == CT_FUNC_COUNTER)
+ return ent.state;
+
+ return 0;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (!this.wait)
+ this.wait = 1;
+
+ this.count = floor (this.count);
+ if (this.count <= 0)
+ this.count = 10;
+
+ // fix "delay" making func_counter not work -- iw
+ this.pausetime = this.delay;
+ this.delay = 0;
+ this.cnt = 0;
+ this.state = 0;
+
+ this.counter_on = TRUE;
+ this.interaction_flags |= DISABLE_THINK;
+
+ if (this.spawnflags & COUNTER_START_ON)
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.nextthink = time + 0.1;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() func_counter =
+ {
+ this.classname = "counter";
+ this.classtype = CT_FUNC_COUNTER;
+ };
};

/*QUAKED func_oncount (0 0 0.5) (0 0 0) (16 16 16)
@@ -215,20 +206,33 @@ reaches the value set by count, func_oncount triggers its targets.

"delay" how much time to wait before firing after being triggered.
*/
-void() func_oncount =
+class func_oncount: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.count = floor (self.count);
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (func_counter::getcount(caller) == this.count)
+ {
+ // fix func_counter and func_oncount handling
+ // of activator -- iw
+ // activator = other;
+ sub_usetargets ();
+ }
+ };

- if (self.count <= 0)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.count = 1;
- }
+ this.count = floor (this.count);
+
+ if (this.count <= 0)
+ this.count = 1;
+ };

- self.classname = "oncount";
- self.use = oncount_use;
- self.think = SUB_Null;
+ //--------------------------------------------------------------
+ void() func_oncount =
+ {
+ this.classname = "oncount";
+ this.classtype = CT_FUNC_ONCOUNT;
+ };
};

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

Diff qc/func/door.qc

diff --git a/qc/func/door.qc b/qc/func/door.qc
index 45600a2..d0d6d73 100644
--- a/qc/func/door.qc
+++ b/qc/func/door.qc
@@ -4,13 +4,12 @@

//----------------------------------------------------------------------
// Doors are similar to buttons, but can spawn a fat trigger field around
-// them to open without a touch, and they link together to form simultanious
+// them to open without a touch, and they link together to form simultaneous
// double/quad doors.
//
-// Door.owner is the master door. If there is only one door, it points to
-// itself. If multiple doors, all will point to a single one.
-//
-// Door.enemy chains from the master door through all doors linked in the chain.
+// Linked doors are a chain with prev_door and next_door being the previous
+// and next links in that chain respectively. The chain is terminated when
+// prev/next link connects to __NULL__ or back to self/this.
//----------------------------------------------------------------------

// constants
@@ -21,717 +20,753 @@ const float DOOR_SILVER_KEY = 16;
const float DOOR_TOGGLE = 32;
const float DOOR_DOOM_STYLE_UNLOCK = 64;

-// prototypes
-void() door_go_down;
-void() door_go_up;
-
-//----------------------------------------------------------------------
-// THINK FUNCTIONS
-//----------------------------------------------------------------------
-
-//----------------------------------------------------------------------
-void() door_blocked =
+//------------------------------------------------------------------------------
+class temp_door_trigger: base_tempentity
{
- T_Damage (other, self, self, self.dmg);
+ base_mapentity primary_door;

- // if a door has a negative wait, it would never come back if blocked,
- // so let it just squash the object to death real fast
- if (self.wait >= 0)
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- if (self.state == STATE_DOWN)
- door_go_up ();
- else
- door_go_down ();
- }
-};
-
-//----------------------------------------------------------------------
-void() door_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- if (self.spawnflags & DOOR_TOGGLE)
- // don't come down automatically
- return;
- self.think = door_go_down;
- self.nextthink = self.ltime + self.wait;
-};
+ if (toucher.health <= 0)
+ return;

-//----------------------------------------------------------------------
-void() door_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
+ if (toucher.movetype == MOVETYPE_NOCLIP)
+ // from copper -- dumptruck_ds
+ return;

-//----------------------------------------------------------------------
-void() door_go_down =
-{
- local entity oldself, shadow;
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- if (self.max_health)
- {
- self.takedamage = DAMAGE_YES;
- self.health = self.max_health;
- }
+ if (time < this.attack_finished)
+ return;

- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, door_hit_bottom);
-
- if (self.switchshadstyle)
- {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if (oldself.spawnflags & DOOR_START_OPEN)
- {
- shadow_fade_out ();
- shadow.shadowoff = 1;
- }
- else
- {
- shadow_fade_in ();
- shadow.shadowoff = 0;
- }
-
- self = oldself;
- }
-};
+ this.attack_finished = time + 1;

-//----------------------------------------------------------------------
-void() door_go_up =
-{
- local entity oldself, shadow;
-
- if (self.state == STATE_UP)
- // allready going up
- return;
+ if (this.primary_door)
+ primary_door.do_use (toucher);
+ };

- if (self.state == STATE_TOP)
+ //--------------------------------------------------------------
+ void() temp_door_trigger =
{
- // reset top wait time
- self.nextthink = self.ltime + self.wait;
- return;
- }
+ this.classtype = CT_TEMP_DOOR_TRIGGER;
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_TRIGGER;
+ };
+};

- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, door_hit_top);
+/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

- SUB_UseTargets ();
-
- if (self.switchshadstyle)
- {
- shadow = self.shadowcontroller;
- oldself = self;
- self = shadow;
-
- if (oldself.spawnflags & DOOR_START_OPEN)
- {
- shadow_fade_in ();
- shadow.shadowoff = 0;
- }
- else
- {
- shadow_fade_out ();
- shadow.shadowoff = 1;
- }
-
- self = oldself;
- }
-};
+if two doors touch, they are assumed to be connected and operate as a unit.

-//----------------------------------------------------------------------
-void() door_group_go_down =
-{
- local entity oself, starte;
-
- oself = self;
- starte = self;
+TOGGLE causes the door to wait in both the start and end states for a trigger event.

- do
- {
- door_go_down ();
- self = self.enemy;
- }
- while ((self != starte) && (self != world));
+START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).

- self = oself;
-};
+Key doors are always wait -1.

-//----------------------------------------------------------------------
-void() door_group_go_up =
+"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
+"angle" determines the opening direction
+"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
+"health" if set, door must be shot open
+"speed" movement speed (100 default)
+"wait" wait before returning (3 default, -1 = never return)
+"lip" lip remaining at end of move (8 default)
+"dmg" damage to inflict when blocked (2 default)
+"cnt" if 1, leave a used key in the player's inventory (0 default)
+"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
+"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
+"noise2" sound file for the "move" sound (if set, overrides "sounds")
+"noise3" sound file for the "key required" sound (default is per worldtype)
+"noise4" sound file for the "key used" sound (default is per worldtype)
+"sounds"
+0) no sound
+1) stone
+2) base
+3) stone chain
+4) screechy metal
+*/
+class func_door: base_func
{
- local entity oself, starte;
-
- oself = self;
- starte = self;
-
- do
+ float is_primary;
+ float need_link;
+ temp_door_trigger area_trig;
+ func_door prev_door;
+ func_door next_door;
+ misc_shadowcontroller shadow;
+
+ //--------------------------------------------------------------
+ static float (entity e1, entity e2) entities_touching =
{
- door_go_up ();
- self = self.enemy;
- }
- while ((self != starte) && (self != world));
+ if (e1.mins_x > e2.maxs_x)
+ return FALSE;
+ if (e1.mins_y > e2.maxs_y)
+ return FALSE;
+ if (e1.mins_z > e2.maxs_z)
+ return FALSE;
+ if (e1.maxs_x < e2.mins_x)
+ return FALSE;
+ if (e1.maxs_y < e2.mins_y)
+ return FALSE;
+ if (e1.maxs_z < e2.mins_z)
+ return FALSE;
+ return TRUE;
+ };
+
+ //--------------------------------------------------------------
+ // THINK FUNCTIONS
+ //--------------------------------------------------------------
+
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
+ {
+ T_Damage (blocker, this, this, this.dmg);

- self = oself;
-};
+ // if a door has a negative wait, it would never come back
+ // if blocked, so let it just squash the object to death
+ // real fast
+ if (this.wait >= 0)
+ {
+ if (this.state == FUNC_STATE_DOWN)
+ door_go_up ();
+ else
+ door_go_down ();
+ }
+ };

-//----------------------------------------------------------------------
-// ACTIVATION FUNCTIONS
-//----------------------------------------------------------------------
+ //--------------------------------------------------------------
+ nonvirtual void() door_hit_top =
+ {
+ sound (this, CHAN_VOICE, noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_TOP;
+ if (this.spawnflags & DOOR_TOGGLE)
+ // don't come down automatically
+ return;

-//----------------------------------------------------------------------
-void() door_fire =
-{
- if (self.owner != self)
- objerror ("door_fire: self.owner != self");
+ this.nextthink = this.ltime + this.wait;
+ };

- if (self.estate != STATE_ACTIVE)
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() door_hit_bottom =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;
+ };

- // self.noise4 is now played in keylock_try_to_unlock -- iw
+ //--------------------------------------------------------------
+ nonvirtual void() door_go_down =
+ {
+ sound (this, CHAN_VOICE, noise2, 1, ATTN_NORM);
+ if (this.max_health)
+ {
+ this.takedamage = DAMAGE_YES;
+ this.health = this.max_health;
+ }

- // no more message
- self.message = string_null;
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos1, this.speed, door_hit_bottom);

+ if (this.switchshadstyle && this.shadow)
+ {
+ if (this.spawnflags & DOOR_START_OPEN)
+ {
+ shadow.fade_out ();
+ shadow.shadowoff = 1;
+ }
+ else
+ {
+ shadow.fade_in ();
+ shadow.shadowoff = 0;
+ }
+ }
+ };

- if (self.spawnflags & DOOR_TOGGLE)
+ //--------------------------------------------------------------
+ nonvirtual void() door_go_up =
{
- if (self.state == STATE_UP || self.state == STATE_TOP)
+ if (this.state == FUNC_STATE_UP)
+ // allready going up
+ return;
+
+ if (this.state == FUNC_STATE_TOP)
{
- door_group_go_down ();
+ // reset top wait time
+ this.nextthink = this.ltime + this.wait;
return;
}
- }
-
- // trigger all paired doors
- door_group_go_up ();
-};
-
-//----------------------------------------------------------------------
-void() door_use =
-{
- local entity oself;
-
- // door message are for touch only
- self.message = "";
-
- self.owner.message = "";
- self.enemy.message = "";
- oself = self;
- self = self.owner;
- door_fire ();
- self = oself;
-};

-//----------------------------------------------------------------------
-void() door_trigger_touch =
-{
- if (other.health <= 0)
- return;
-
- if (other.movetype == MOVETYPE_NOCLIP)
- // from copper -- dumptruck_ds
- return;
-
- if (time < self.attack_finished)
- return;
-
- self.attack_finished = time + 1;
+ sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos2, this.speed, door_hit_top);

- activator = other;
- self = self.owner;
- door_use ();
-};
-
-//----------------------------------------------------------------------
-void() door_killed =
-{
- local entity oself;
-
- oself = self;
- self = self.owner;
- self.health = self.max_health;
- // wil be reset upon return
- self.takedamage = DAMAGE_NO;
- door_use ();
- self = oself;
-};
+ sub_usetargets ();
+
+ if (this.switchshadstyle && this.shadow)
+ {
+ if (this.spawnflags & DOOR_START_OPEN)
+ {
+ shadow.fade_in ();
+ shadow.shadowoff = 0;
+ }
+ else
+ {
+ shadow.fade_out ();
+ shadow.shadowoff = 1;
+ }
+ }
+ };

-//----------------------------------------------------------------------
-// door_unlock
-//
-// Perform the actions which should be performed when self is successfully
-// unlocked with a key.
-//
-// This function exists so that it can be passed as an argument to the new
-// keylock_try_to_unlock function. This code was previously part of the
-// door_touch function. -- iw
-//----------------------------------------------------------------------
-void() door_unlock =
-{
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ //--------------------------------------------------------------
+ nonvirtual void() door_group_go_down =
{
- self.touch = SUB_Null;
- if (self.enemy)
- self.enemy.touch = SUB_Null; // get paired door
- }
- door_use ();
-};
+ door_go_down ();

+ if (next_door && next_door != this && next_door != world)
+ next_door.door_group_go_down ();
+ };

-//----------------------------------------------------------------------
-// door_touch -- Prints messages and opens key doors
-//----------------------------------------------------------------------
-void() door_touch =
-{
- // if (other.classname != "player")
- // return;
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() door_group_go_up =
+ {
+ door_go_up ();

- if (self.owner.attack_finished > time)
- return;
+ if (next_door && next_door != this && next_door != world)
+ next_door.door_group_go_up ();
+ };

- self.owner.attack_finished = time + 2;
+ //--------------------------------------------------------------
+ // ACTIVATION FUNCTIONS
+ //--------------------------------------------------------------

- if (self.owner.message != "")
+ //--------------------------------------------------------------
+ // door_fire gets very confused if it's not static -- CEV
+ //--------------------------------------------------------------
+ static void(func_door d) door_fire =
{
- centerprint (other, self.owner.message);
- sound (other, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
- }
+ if (d.is_primary == FALSE)
+ objerror ("door_fire: called on non-primary door\n");

- // key door stuff
- if (!keylock_has_key_set())
- return;
+ if (d.estate != STATE_ACTIVE)
+ return;

- keylock_try_to_unlock (other, "", door_unlock);
-};
+ // noise4 is now played in keylock_try_to_unlock -- iw

-//----------------------------------------------------------------------
-// ENTITY STATE FUNCTIONS
-//----------------------------------------------------------------------
+ // no more message
+ d.message = "";

-//----------------------------------------------------------------------
-void(entity e, float closealldoors) door_estate_lock =
-{
- local entity oself, next;
+ if (d.spawnflags & DOOR_TOGGLE)
+ {
+ if (d.state == FUNC_STATE_UP ||
+ d.state == FUNC_STATE_TOP)
+ {
+ d.door_group_go_down ();
+ return;
+ }
+ }

- if (e.owner.estate == STATE_INACTIVE)
- return;
+ // trigger all paired doors
+ d.door_group_go_up ();
+ };

- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self &&
- e.owner.last_setstate_frame == framecount)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- return;
- }
-
- oself = self;
- self = e.owner;
-
- self.estate = STATE_INACTIVE;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
+ if (this.need_link == TRUE)
+ this.link_doors ();
+ else
+ this.door_go_down ();
+ };

- self.prevstate = self.state;
-
- if (self.state == STATE_UP || self.state == STATE_TOP)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- // don't close wait -1 nor toggleable doors...
- // ...unless the trigger_setstate has a "Close all doors"
- // spawnflag on
- if (!(self.wait == -1 || (self.spawnflags & DOOR_TOGGLE)) ||
- closealldoors)
- {
- door_group_go_down ();
+ if (this.is_primary == FALSE)
+ {
+ /*
+ dprint ("func_door::do_use: called use on a "
+ "non-primary door\n");
+ */
+ if (prev_door && prev_door != this)
+ prev_door.do_use (caller);
+ return;
}
- }

- if (self.max_health)
- {
- next = self;
+ // door message are for touch only
+ local func_door next = this;
do
{
- // e.health = 0;
- next.takedamage = DAMAGE_NO;
- next = next.enemy;
+ next.message = "";
+ next = next.next_door;
}
- while ((next != self) && (next != world));
- }
-
- self = oself;
-};
+ while (next && next != this && next != world);

-//----------------------------------------------------------------------
-void(entity e, float openalldoors) door_estate_unlock =
-{
- local entity oself, next;
-
- if (e.owner.estate == STATE_ACTIVE)
- return;
+ door_fire (this);
+ };

- // blocks linked doors from updating the same owner repeatedly
- if (e.owner.last_setstate == self &&
- e.owner.last_setstate_frame == framecount)
+ //--------------------------------------------------------------
+ virtual void() door_killed =
{
- return;
- }
-
- oself = self;
- self = e.owner;
-
- self.last_setstate = oself;
- self.last_setstate_frame = framecount;
+ if (this.is_primary == FALSE)
+ {
+ if (prev_door && prev_door != this)
+ prev_door.door_killed ();
+ return;
+ }

- if (self.prevstate == STATE_UP || self.prevstate == STATE_TOP)
+ this.health = this.max_health;
+ // will be reset upon return
+ this.takedamage = DAMAGE_NO;
+ do_use (other);
+ };
+
+ //--------------------------------------------------------------
+ // door_unlock
+ //
+ // Perform the actions which should be performed when this is
+ // successfully unlocked with a key.
+ //
+ // This function exists so that it can be passed as an argument
+ // to the new keylock_try_to_unlock function. This code was
+ // previously part of the door_touch function. -- iw
+ //--------------------------------------------------------------
+ nonvirtual void() door_unlock =
{
- if ((self.wait == -1 || (self.spawnflags & DOOR_TOGGLE)) &&
- openalldoors)
+ if (!(this.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
{
- door_group_go_up ();
+ // door has been unlocked, don't allow player to
+ // touch / activate it again
+ local func_door next = this;
+ do
+ {
+ next.interaction_flags |= DISABLE_TOUCH;
+ next = next.next_door;
+ }
+ while (next && next != this && next != world);
}
- }
+ do_use (other);
+ };

- if (self.max_health)
+ //--------------------------------------------------------------
+ // door_touch -- Prints messages and opens key doors
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- next = self;
- do
+ // find the primary door -- CEV
+ if (this.is_primary == FALSE)
{
- next.health = next.max_health;
- next.takedamage = DAMAGE_YES;
- next = next.enemy;
+ if (prev_door && prev_door != this)
+ prev_door.do_touch (toucher);
+ return;
}
- while ((next != self) && (next != world));
- }

- self.estate = STATE_ACTIVE;
- self = oself;
-};
+ // from Copper -- dumptruck_ds
+ if (sub_checkvalidtouch(toucher) == FALSE)
+ return;

-//----------------------------------------------------------------------
-// SPAWNING FUNCTIONS
-//----------------------------------------------------------------------
+ if (this.attack_finished > time)
+ return;

-//----------------------------------------------------------------------
-entity(vector fmins, vector fmaxs) spawn_field =
-{
- local entity trigger;
- local vector t1, t2;
-
- trigger = spawn ();
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.owner = self;
- trigger.touch = door_trigger_touch;
-
- t1 = fmins;
- t2 = fmaxs;
- setsize (trigger, t1 - '60 60 8', t2 + '60 60 8');
- return (trigger);
-};
+ this.attack_finished = time + 2;

-//----------------------------------------------------------------------
-float (entity e1, entity e2) EntitiesTouching =
-{
- if (e1.mins_x > e2.maxs_x)
- return FALSE;
- if (e1.mins_y > e2.maxs_y)
- return FALSE;
- if (e1.mins_z > e2.maxs_z)
- return FALSE;
- if (e1.maxs_x < e2.mins_x)
- return FALSE;
- if (e1.maxs_y < e2.mins_y)
- return FALSE;
- if (e1.maxs_z < e2.mins_z)
- return FALSE;
- return TRUE;
-};
+ if (this.message != __NULL__ && this.message != "")
+ {
+ centerprint (toucher, this.message);
+ sound (toucher, CHAN_VOICE, "misc/talk.wav",
+ 1, ATTN_NORM);
+ }

-//----------------------------------------------------------------------
-// LinkDoors
-//----------------------------------------------------------------------
-void() LinkDoors =
-{
- local entity t, starte;
- local vector cmins, cmaxs;
+ // key door stuff
+ if (!keylock_has_key_set(this))
+ return;
+
+ keylock_try_to_unlock (toucher, "", door_unlock);
+ };

- if (self.enemy)
- // already linked by another door
- return;
+ //--------------------------------------------------------------
+ // ENTITY STATE FUNCTIONS
+ //--------------------------------------------------------------

- if (self.spawnflags & 4)
+ //--------------------------------------------------------------
+ nonvirtual void(func_door d, float closealldoors) estate_lock =
{
- // don't want to link this door
- self.owner = self.enemy = self;
- return;
- }
+ if (d.is_primary == FALSE)
+ {
+ d.prev_door.estate_lock (d.prev_door, closealldoors);
+ return;
+ }

- cmins = self.mins;
- cmaxs = self.maxs;
+ local func_door next;

- starte = self;
- t = self;
+ if (d.estate == STATE_INACTIVE)
+ return;

- do
- {
- // master door
- self.owner = starte;
+ // blocks linked doors from updating the same owner repeatedly
+ if (d.last_setstate == this &&
+ d.last_setstate_frame == framecount)
+ {
+ return;
+ }

- if (self.health)
- starte.health = self.health;
- if (self.targetname != "")
- starte.targetname = self.targetname;
- if (self.message != "")
- starte.message = self.message;
+ d.estate = STATE_INACTIVE;
+ d.last_setstate = this;
+ d.last_setstate_frame = framecount;
+ d.prevstate = d.state;

- t = find (t, classname, self.classname);
- if (!t)
+ next = d.next_door;
+ do
{
- // make the chain a loop
- self.enemy = starte;
+ next.estate = STATE_INACTIVE;
+ next = next.next_door;
+ }
+ while (next && next != d && next != world);

- // shootable, fired, or key doors just needed the
- // owner/enemy links, they don't spawn a field
+ if (d.state == FUNC_STATE_UP || d.state == FUNC_STATE_TOP)
+ {
+ // don't close wait -1 nor toggleable doors...
+ // ...unless the trigger_setstate has a "Close all"
+ // spawnflag on
+ if (!(d.wait == -1 ||
+ (d.spawnflags & DOOR_TOGGLE)) || closealldoors)
+ {
+ d.door_group_go_down ();
+ }
+ }

- self = self.owner;
+ if (d.max_health)
+ {
+ next = d;
+ do
+ {
+ next.takedamage = DAMAGE_NO;
+ next = next.next_door;
+ }
+ while (next && next != d && next != world);
+ }
+ };

- if (self.health)
- return;
- if (self.targetname != "")
- return;
- if (keylock_has_key_set())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void(func_door d, float openalldoors) estate_unlock =
+ {
+ if (d.is_primary == FALSE)
+ {
+ d.prev_door.estate_unlock (d.prev_door, openalldoors);
+ return;
+ }

- self.owner.trigger_field = spawn_field (cmins, cmaxs);
+ local func_door next;
+
+ if (d.estate == STATE_ACTIVE)
+ return;

+ // blocks linked doors from updating the same owner repeatedly
+ if (d.last_setstate == this &&
+ d.last_setstate_frame == framecount)
+ {
return;
}

- if (EntitiesTouching(self,t))
- {
- if (t.enemy)
- objerror ("cross connected doors");
+ d.last_setstate = this;
+ d.last_setstate_frame = framecount;

- self.enemy = t;
- self = t;
+ if (d.prevstate == FUNC_STATE_UP ||
+ d.prevstate == FUNC_STATE_TOP)
+ {
+ if ((d.wait == -1 || (d.spawnflags & DOOR_TOGGLE)) &&
+ openalldoors)
+ {
+ d.door_group_go_up ();
+ }
+ }

- if (t.mins_x < cmins_x)
- cmins_x = t.mins_x;
- if (t.mins_y < cmins_y)
- cmins_y = t.mins_y;
- if (t.mins_z < cmins_z)
- cmins_z = t.mins_z;
- if (t.maxs_x > cmaxs_x)
- cmaxs_x = t.maxs_x;
- if (t.maxs_y > cmaxs_y)
- cmaxs_y = t.maxs_y;
- if (t.maxs_z > cmaxs_z)
- cmaxs_z = t.maxs_z;
+ if (d.max_health)
+ {
+ next = d;
+ do
+ {
+ next.health = next.max_health;
+ next.takedamage = DAMAGE_YES;
+ next = next.next_door;
+ }
+ while (next && next != d && next != world);
}
- }
- while (1);
-};

-/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK GOLD_KEY SILVER_KEY TOGGLE X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ d.estate = STATE_ACTIVE;

-if two doors touch, they are assumed to be connected and operate as a unit.
+ next = d.next_door;
+ do
+ {
+ next.estate = STATE_ACTIVE;
+ next = next.next_door;
+ }
+ while (next && next != d && next != world);
+ };

-TOGGLE causes the door to wait in both the start and end states for a trigger event.
+ //--------------------------------------------------------------
+ // SPAWNING FUNCTIONS
+ //--------------------------------------------------------------

-START_OPEN causes the door to move to its destination when spawned, and operate in reverse. It is used to temporarily or permanently close off an area when triggered (not useful for touch or takedamage doors).
+ //--------------------------------------------------------------
+ static temp_door_trigger(func_door d, vector fmins, vector fmaxs)
+ spawn_field =
+ {
+ local temp_door_trigger trigger;

-Key doors are always wait -1.
+ trigger = spawn (temp_door_trigger, primary_door: d);
+ setsize (trigger, fmins - '60 60 8', fmaxs + '60 60 8');
+ return trigger;
+ };

-"message" is printed when the door is touched if it is a trigger door and it hasn't been fired yet
-"angle" determines the opening direction
-"targetname" if set, no touch field will be spawned and a remote button or trigger field activates the door.
-"health" if set, door must be shot open
-"speed" movement speed (100 default)
-"wait" wait before returning (3 default, -1 = never return)
-"lip" lip remaining at end of move (8 default)
-"dmg" damage to inflict when blocked (2 default)
-"cnt" if 1, leave a used key in the player's inventory (0 default)
-"keyname" if set, this is the keyname of the item_key_custom which unlocks this entity
-"noise1" sound file for the "stop moving" sound (if set, overrides "sounds")
-"noise2" sound file for the "move" sound (if set, overrides "sounds")
-"noise3" sound file for the "key required" sound (default is per worldtype)
-"noise4" sound file for the "key used" sound (default is per worldtype)
-"sounds"
-0) no sound
-1) stone
-2) base
-3) stone chain
-4) screechy metal
-*/
-void() func_door =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ // LinkDoors
+ //--------------------------------------------------------------
+ nonvirtual void() link_doors =
+ {
+ // current, next, previous
+ local func_door cur, n, p;
+ local vector cmins, cmaxs;

- local string default_noise1;
- local string default_noise2;
- entity shadow;
- entity oldself;
+ if (this.is_primary == -1)
+ {
+ this.is_primary = TRUE;
+ this.need_link = FALSE;
+ }
+ else
+ {
+ // we've already been initialized by a previous
+ // link_doors pass
+ this.need_link = FALSE;
+ return;
+ }

- // self.noise3 and self.noise4 can now be overridden by the mapper, but
- // will be set to default values in keylock_init if necessary -- iw
- keylock_init ();
+ if (this.spawnflags & DOOR_DONT_LINK)
+ {
+ // don't want to link this door
+ next_door = prev_door = this;
+ return;
+ }

- // self.noise1 and self.noise2 can now be overridden by the mapper -- iw
- default_noise1 = "misc/null.wav";
- default_noise2 = "misc/null.wav";
+ cmins = this.mins;
+ cmaxs = this.maxs;
+ cur = n = p = this;

- if (self.sounds == 1)
- {
- default_noise1 = "doors/drclos4.wav";
- default_noise2 = "doors/doormv1.wav";
- }
+ while (1)
+ {
+ // overwrite primary door parameters
+ if (cur && cur != this && cur != world)
+ {
+ if (cur.health)
+ this.health = cur.health;
+
+ if (cur.targetname && cur.targetname != "")
+ this.targetname = cur.targetname;
+
+ if (cur.message && cur.message != "")
+ this.message = cur.message;
+ }
+
+ // cast to func_door -- CEV
+ n = (func_door)findfloat (n, ::classtype, CT_FUNC_DOOR);
+
+ if (n == __NULL__ || n == this || n == world)
+ {
+ // terminate the chain
+ cur.prev_door = p;
+ cur.next_door = __NULL__;
+
+ // shootable, fired, or key doors just
+ // needed the prev/next links, they
+ // don't spawn a field
+ if (this.health)
+ break;
+ if (this.targetname && this.targetname != "")
+ break;
+ if (keylock_has_key_set(this))
+ break;
+
+ // create area trigger
+ area_trig = spawn_field (this, cmins, cmaxs);
+ break;
+ }
+
+ if (entities_touching(cur, n))
+ {
+ if (n.next_door)
+ objerror ("func_door::link_doors: "
+ "cross connected doors\n");
+
+ n.is_primary = FALSE;
+ cur.need_link = FALSE;
+ cur.prev_door = p;
+ cur.next_door = n;
+
+ p = cur;
+ cur = n;
+
+ if (n.mins_x < cmins_x)
+ cmins_x = n.mins_x;
+ if (n.mins_y < cmins_y)
+ cmins_y = n.mins_y;
+ if (n.mins_z < cmins_z)
+ cmins_z = n.mins_z;
+ if (n.maxs_x > cmaxs_x)
+ cmaxs_x = n.maxs_x;
+ if (n.maxs_y > cmaxs_y)
+ cmaxs_y = n.maxs_y;
+ if (n.maxs_z > cmaxs_z)
+ cmaxs_z = n.maxs_z;
+ }
+ }
+ };

- if (self.sounds == 2)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- default_noise1 = "doors/hydro2.wav";
- default_noise2 = "doors/hydro1.wav";
- }
+ local string default_noise1;
+ local string default_noise2;

- if (self.sounds == 3)
- {
- default_noise1 = "doors/stndr2.wav";
- default_noise2 = "doors/stndr1.wav";
- }
+ // start by declaring is_primary to be uninitialized;
+ // it'll be set later for real during link_doors -- CEV
+ this.is_primary = -1;

- if (self.sounds == 4)
- {
- default_noise1 = "doors/ddoor2.wav";
- default_noise2 = "doors/ddoor1.wav";
- }
+ // instead of setting touch to sub_null -- CEV
+ this.interaction_flags &= ~DISABLE_TOUCH;

- if (self.noise1 == "")
- self.noise1 = default_noise1;
- if (self.noise2 == "")
- self.noise2 = default_noise2;
+ // this.noise3 and this.noise4 can now be overridden by
+ // the mapper, but will be set to default values in
+ // keylock_init if necessary -- iw
+ keylock_init ();

- precache_sound (self.noise1);
- precache_sound (self.noise2);
+ // this.noise1 and this.noise2 can now be overridden by
+ // the mapper -- iw
+ default_noise1 = "misc/null.wav";
+ default_noise2 = "misc/null.wav";

- SetMovedir ();
+ if (this.sounds == 1)
+ {
+ default_noise1 = "doors/drclos4.wav";
+ default_noise2 = "doors/doormv1.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ default_noise1 = "doors/hydro2.wav";
+ default_noise2 = "doors/hydro1.wav";
+ }
+ else if (this.sounds == 3)
+ {
+ default_noise1 = "doors/stndr2.wav";
+ default_noise2 = "doors/stndr1.wav";
+ }
+ else if (this.sounds == 4)
+ {
+ default_noise1 = "doors/ddoor2.wav";
+ default_noise2 = "doors/ddoor1.wav";
+ }

- self.max_health = self.health;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- // self.classname = "door";
+ if (this.noise1 == __NULL__ || this.noise1 == "")
+ this.noise1 = default_noise1;
+ if (this.noise1 == __NULL__ || this.noise2 == "")
+ this.noise2 = default_noise2;

- self.blocked = door_blocked;
- self.use = door_use;
+ precache_sound (this.noise1);
+ precache_sound (this.noise2);

- if (self.spawnflags & DOOR_SILVER_KEY)
- {
- keylock_set_silver_key ();
-
- if (self.keyname != "")
- {
- self.netname = self.keyname;
- self.keyname = "";
- }
- }
+ sub_setmovedir ();

- if (self.spawnflags & DOOR_GOLD_KEY)
- {
- keylock_set_gold_key ();
+ this.max_health = this.health;
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setorigin (this, this.origin);
+ setmodel (this, this.model);

- if (self.keyname != "")
+ if (this.spawnflags & DOOR_SILVER_KEY)
{
- self.netname = self.keyname;
- self.keyname = "";
+ 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 (!self.speed)
- self.speed = 100;
- if (!self.wait)
- self.wait = 3;
- if (!self.lip)
- self.lip = 8;
- if (!self.dmg)
- self.dmg = 2;
-
- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir *
- (fabs(self.movedir * self.size) - self.lip);
-
- // DOOR_START_OPEN is to allow an entity to be lighted in the
- // closed position but spawn in the open position
- if (self.spawnflags & DOOR_START_OPEN)
- {
- setorigin (self, self.pos2);
- self.pos2 = self.pos1;
- self.pos1 = self.origin;
- }
-
- self.state = STATE_BOTTOM;

- if (self.health)
- {
- self.takedamage = DAMAGE_YES;
- self.th_die = door_killed;
- }
+ if (this.spawnflags & DOOR_GOLD_KEY)
+ {
+ keylock_set_gold_key ();

- if (self.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
- self.cnt = 1;
+ if (this.keyname != "")
+ {
+ this.netname = this.keyname;
+ this.keyname = "";
+ }
+ }

- if (keylock_has_key_set())
- {
- if (!(self.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ // support for item_key_custom -- iw
+ if (this.keyname != "")
{
- self.wait = -1;
+ keylock_set_custom_key (this.keyname);
+ // this should not be referenced again
+ this.keyname = "";
}
- }
- self.touch = door_touch;

- // LinkDoors can't be done until all of the doors have been spawned,
- // so the sizes can be detected properly.
- self.think = LinkDoors;
- self.nextthink = self.ltime + 0.1;
+ if (!this.speed)
+ this.speed = 100;
+ if (!this.wait)
+ this.wait = 3;
+ if (!this.lip)
+ this.lip = 8;
+ if (!this.dmg)
+ this.dmg = 2;
+
+ this.pos1 = this.origin;
+ this.pos2 = this.pos1 + this.movedir *
+ (fabs(this.movedir * this.size) - this.lip);
+
+ // DOOR_START_OPEN is to allow an entity to be lighted in
+ // the closed position but spawn in the open position
+ if (this.spawnflags & DOOR_START_OPEN)
+ {
+ setorigin (this, this.pos2);
+ this.pos2 = this.pos1;
+ this.pos1 = this.origin;
+ }

- // creates a shadow controller entity for the door if it has
- // switchable shadows
- if (self.switchshadstyle)
- {
- shadow = spawn ();
+ this.state = FUNC_STATE_BOTTOM;

- self.shadowcontroller = shadow;
+ if (this.health)
+ {
+ this.takedamage = DAMAGE_YES;
+ this.th_die = this.door_killed;
+ }

- shadow.classname = "misc_shadowcontroller";
- shadow.switchshadstyle = self.switchshadstyle;
- shadow.speed = vlen (self.pos2 - self.pos1) / self.speed;
+ if (this.spawnflags & DOOR_DOOM_STYLE_UNLOCK)
+ this.cnt = 1;

- if (self.spawnflags & DOOR_START_OPEN)
- shadow.spawnflags = 1;
- else
- shadow.spawnflags = 0;
+ if (keylock_has_key_set(this))
+ {
+ if (!(this.spawnflags & DOOR_DOOM_STYLE_UNLOCK))
+ {
+ this.wait = -1;
+ }
+ }

- oldself = self;
+ // LinkDoors can't be done until all of the doors have
+ // been spawned, so the sizes can be detected properly.
+ this.need_link = TRUE;
+ this.nextthink = this.ltime + 0.1;

- self = shadow;
- misc_shadowcontroller ();
+ // creates a shadow controller entity for the door if it
+ // has switchable shadows
+ if (this.switchshadstyle)
+ {
+ // forgive me for using the ternary operator -- CEV
+ this.shadow = spawn (misc_shadowcontroller,
+ switchshadstyle: this.switchshadstyle,
+ speed: vlen (this.pos2 - this.pos1) / this.speed,
+ spawnflags: spawnflags & DOOR_START_OPEN ? 1:0);
+ }
+ };

- self = oldself;
- }
+ //--------------------------------------------------------------
+ void() func_door =
+ {
+ this.classtype = CT_FUNC_DOOR;
+ };
};

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

Diff qc/func/door_secret.qc

diff --git a/qc/func/door_secret.qc b/qc/func/door_secret.qc
index c84d176..3f517a6 100644
--- a/qc/func/door_secret.qc
+++ b/qc/func/door_secret.qc
@@ -9,263 +9,257 @@ const float SECRET_1ST_DOWN = 4; // 1st move is down from arrow
const float SECRET_NO_SHOOT = 8; // only opened by trigger
const float SECRET_YES_SHOOT = 16; // shootable even if targeted

-// prototypes
-void() fd_secret_move1;
-void() fd_secret_move2;
-void() fd_secret_move3;
-void() fd_secret_move4;
-void() fd_secret_move5;
-void() fd_secret_move6;
-void() fd_secret_done;
-
-//----------------------------------------------------------------------
-void() fd_secret_use =
-{
- local float temp;
-
- self.health = 10000;
-
- // exit if still moving around...
- if (self.origin != self.oldorigin)
- return;
+/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

- // no more message
- self.message = string_null;
+Basic secret door. Slides back, then to the side. Angle determines direction.
+wait = # of seconds before coming back
+1st_left = 1st move is left of arrow
+1st_down = 1st move is down from arrow
+always_shoot = even if targeted, keep shootable
+t_width = override WIDTH to move back (or height if going down)
+t_length = override LENGTH to move sideways
+"dmg" damage to inflict when blocked (2 default)

- // fire all targets / killtargets
- SUB_UseTargets ();
+If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
+"sounds"
+1) medieval
+2) metal
+3) base
+*/
+class func_door_secret: base_func
+{
+ float door_state;
+ vector dest1;
+ vector dest2;

- if (!(self.spawnflags & SECRET_NO_SHOOT))
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
{
- self.th_pain = SUB_NullPain;
- self.takedamage = DAMAGE_NO;
- }
+ if (time < this.attack_finished)
+ return;

- self.velocity = '0 0 0';
+ this.attack_finished = time + 0.5;
+ T_Damage (blocker, this, this, this.dmg);
+ };

- // Make a sound, wait a little...
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.nextthink = self.ltime + 0.1;
-
- // 1 or -1
- temp = 1 - (self.spawnflags & SECRET_1ST_LEFT);
- makevectors (self.mangle);
-
- if (!self.t_width)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (self.spawnflags & SECRET_1ST_DOWN)
- self.t_width = fabs (v_up * self.size);
- else
- self.t_width = fabs (v_right * self.size);
- }
-
- if (!self.t_length)
- self.t_length = fabs (v_forward * self.size);
-
- if (self.spawnflags & SECRET_1ST_DOWN)
- self.dest1 = self.origin - v_up * self.t_width;
- else
- self.dest1 = self.origin + v_right * (self.t_width * temp);
-
- self.dest2 = self.dest1 + v_forward * self.t_length;
- SUB_CalcMove (self.dest1, self.speed, fd_secret_move1);
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-};
-
-//----------------------------------------------------------------------
-void(entity attacker, float damage) fd_secret_pain =
-{
- fd_secret_use ();
-};
-
-//----------------------------------------------------------------------
-// fd_secret_move1 -- Wait after first movement...
-//----------------------------------------------------------------------
-void() fd_secret_move1 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move2;
- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
-
-//----------------------------------------------------------------------
-// fd_secret_move2 -- Start moving sideways w/sound...
-//----------------------------------------------------------------------
-void() fd_secret_move2 =
-{
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove (self.dest2, self.speed, fd_secret_move3);
-};
-
-//----------------------------------------------------------------------
-// fd_secret_move3 -- Wait here until time to go back...
-//----------------------------------------------------------------------
-void() fd_secret_move3 =
-{
- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- if (!(self.spawnflags & SECRET_OPEN_ONCE))
+ switch (this.door_state)
+ {
+ case 1:
+ // fd_secret_move1: Wait after first movement
+ this.nextthink = this.ltime + 1.0;
+ sound (this, CHAN_VOICE, this.noise3,
+ 1, ATTN_NORM);
+ break;
+ case 2:
+ // fd_secret_move2: move sideways w/sound
+ sound (this, CHAN_VOICE, this.noise2,
+ 1, ATTN_NORM);
+ calc_move (this.dest2, this.speed, this.think);
+ break;
+ case 3:
+ // fd_secret_move3: wait until time to go back
+ sound (this, CHAN_VOICE, this.noise3,
+ 1, ATTN_NORM);
+ if (!(this.spawnflags & SECRET_OPEN_ONCE))
+ this.nextthink = this.ltime + this.wait;
+ break;
+ case 4:
+ // fd_secret_move4: move backward...
+ sound (this, CHAN_VOICE, this.noise2,
+ 1, ATTN_NORM);
+ calc_move (this.dest1, this.speed, this.think);
+ break;
+ case 5:
+ // fd_secret_move5: wait 1 second...
+ this.nextthink = this.ltime + 1.0;
+ sound (this, CHAN_VOICE, this.noise3,
+ 1, ATTN_NORM);
+ break;
+ case 6:
+ // fd_secret_move6
+ sound (this, CHAN_VOICE, this.noise2,
+ 1, ATTN_NORM);
+ calc_move (this.oldorigin, this.speed,
+ this.think);
+ break;
+ case 7:
+ // fd_secret_done
+ if (!this.targetname ||
+ this.spawnflags & SECRET_YES_SHOOT)
+ {
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
+ this.th_pain = fd_secret_pain;
+ }
+
+ sound (this, CHAN_VOICE, this.noise3,
+ 1, ATTN_NORM);
+ break;
+ default:
+ dprint (sprintf("func_door_secret::do_think: "
+ "unhandled door_state %f!\n",
+ this.door_state));
+ }
+
+ if (this.door_state < 4 ||
+ !(this.spawnflags & SECRET_OPEN_ONCE))
+ {
+ this.door_state++;
+ }
+ };
+
+ //--------------------------------------------------------------
+ // secret_touch - ouch; Prints messages
+ //--------------------------------------------------------------
+ virtual void(entity t) do_touch =
{
- self.nextthink = self.ltime + self.wait;
- self.think = fd_secret_move4;
- }
-};
+ // from Copper -- dumptruck_ds
+ if (sub_checkvalidtouch(t) == FALSE)
+ return;

-//----------------------------------------------------------------------
-// fd_secret_move4 -- Move backward...
-//----------------------------------------------------------------------
-void() fd_secret_move4 =
-{
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove (self.dest1, self.speed, fd_secret_move5);
-};
+ if (this.attack_finished > time)
+ return;

-//----------------------------------------------------------------------
-// fd_secret_move5 -- Wait 1 second...
-//----------------------------------------------------------------------
-void() fd_secret_move5 =
-{
- self.nextthink = self.ltime + 1.0;
- self.think = fd_secret_move6;
- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
+ this.attack_finished = time + 2;

-//----------------------------------------------------------------------
-// fd_secret_move6
-//----------------------------------------------------------------------
-void() fd_secret_move6 =
-{
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
- SUB_CalcMove (self.oldorigin, self.speed, fd_secret_done);
-};
+ if (this.message != "")
+ {
+ centerprint (t, this.message);
+ sound (t, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
+ }
+ };

-//----------------------------------------------------------------------
-// fd_secret_done
-//----------------------------------------------------------------------
-void() fd_secret_done =
-{
- if (!self.targetname || self.spawnflags & SECRET_YES_SHOOT)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- }
+ local float temp;

- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
-};
+ this.health = 10000;

-//----------------------------------------------------------------------
-void() secret_blocked =
-{
- if (time < self.attack_finished)
- return;
+ // exit if still moving around...
+ if (this.origin != this.oldorigin)
+ return;

- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
+ // no more message
+ this.message = string_null;

-//----------------------------------------------------------------------
-// secret_touch - ouch; Prints messages
-//----------------------------------------------------------------------
-void() secret_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+ // fire all targets / killtargets
+ sub_usetargets ();

- if (self.attack_finished > time)
- return;
+ if (!(this.spawnflags & SECRET_NO_SHOOT))
+ {
+ this.th_pain = sub_nullpain;
+ this.takedamage = DAMAGE_NO;
+ }

- self.attack_finished = time + 2;
+ this.velocity = '0 0 0';

- if (self.message != "")
- {
- centerprint (other, self.message);
- sound (other, CHAN_BODY, "misc/talk.wav", 1, ATTN_NORM);
- }
-};
+ // Make a sound, wait a little...
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.nextthink = this.ltime + 0.1;

-/*QUAKED func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ // 1 or -1
+ temp = 1 - (this.spawnflags & SECRET_1ST_LEFT);
+ makevectors (this.mangle);

-Basic secret door. Slides back, then to the side. Angle determines direction.
-wait = # of seconds before coming back
-1st_left = 1st move is left of arrow
-1st_down = 1st move is down from arrow
-always_shoot = even if targeted, keep shootable
-t_width = override WIDTH to move back (or height if going down)
-t_length = override LENGTH to move sideways
-"dmg" damage to inflict when blocked (2 default)
+ if (!this.t_width)
+ {
+ if (this.spawnflags & SECRET_1ST_DOWN)
+ this.t_width = fabs (v_up * this.size);
+ else
+ this.t_width = fabs (v_right * this.size);
+ }

-If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
-"sounds"
-1) medieval
-2) metal
-3) base
-*/
-void() func_door_secret =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ if (!this.t_length)
+ this.t_length = fabs (v_forward * this.size);

- if (self.sounds == 0)
- self.sounds = 3;
+ if (this.spawnflags & SECRET_1ST_DOWN)
+ this.dest1 = this.origin - v_up * this.t_width;
+ else
+ this.dest1 = this.origin + v_right *
+ (this.t_width * temp);

- if (self.sounds == 1)
- {
- precache_sound ("doors/latch2.wav");
- precache_sound ("doors/winch2.wav");
- precache_sound ("doors/drclos4.wav");
- self.noise1 = "doors/latch2.wav";
- self.noise2 = "doors/winch2.wav";
- self.noise3 = "doors/drclos4.wav";
- }
-
- if (self.sounds == 2)
+ this.dest2 = this.dest1 + v_forward * this.t_length;
+ this.door_state = 1;
+ calc_move (this.dest1, this.speed, this.think);
+ sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(entity attacker, float damage) fd_secret_pain =
{
- precache_sound ("doors/airdoor1.wav");
- precache_sound ("doors/airdoor2.wav");
- self.noise2 = "doors/airdoor1.wav";
- self.noise1 = "doors/airdoor2.wav";
- self.noise3 = "doors/airdoor2.wav";
- }
-
- if (self.sounds == 3)
+ this.do_use (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- precache_sound ("doors/basesec1.wav");
- precache_sound ("doors/basesec2.wav");
- self.noise2 = "doors/basesec1.wav";
- self.noise1 = "doors/basesec2.wav";
- self.noise3 = "doors/basesec2.wav";
- }
-
- if (!self.dmg)
- self.dmg = 2;
-
- // Magic formula...
- self.mangle = self.angles;
- self.angles = '0 0 0';
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- // self.classname = "door";
- setmodel (self, self.model);
- setorigin (self, self.origin);
-
- self.touch = secret_touch;
- self.blocked = secret_blocked;
- self.speed = 50;
- self.use = fd_secret_use;
-
- if (!self.targetname || self.spawnflags & SECRET_YES_SHOOT)
+ if (this.sounds == 0)
+ this.sounds = 3;
+
+ if (this.sounds == 1)
+ {
+ precache_sound ("doors/latch2.wav");
+ precache_sound ("doors/winch2.wav");
+ precache_sound ("doors/drclos4.wav");
+ this.noise1 = "doors/latch2.wav";
+ this.noise2 = "doors/winch2.wav";
+ this.noise3 = "doors/drclos4.wav";
+ }
+
+ if (this.sounds == 2)
+ {
+ precache_sound ("doors/airdoor1.wav");
+ precache_sound ("doors/airdoor2.wav");
+ this.noise2 = "doors/airdoor1.wav";
+ this.noise1 = "doors/airdoor2.wav";
+ this.noise3 = "doors/airdoor2.wav";
+ }
+
+ if (this.sounds == 3)
+ {
+ precache_sound ("doors/basesec1.wav");
+ precache_sound ("doors/basesec2.wav");
+ this.noise2 = "doors/basesec1.wav";
+ this.noise1 = "doors/basesec2.wav";
+ this.noise3 = "doors/basesec2.wav";
+ }
+
+ if (!this.dmg)
+ this.dmg = 2;
+
+ // Magic formula...
+ this.speed = 50;
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setmodel (this, this.model);
+ setorigin (this, this.origin);
+
+ if (!this.targetname || this.spawnflags & SECRET_YES_SHOOT)
+ {
+ this.health = 10000;
+ this.takedamage = DAMAGE_YES;
+ // TODO CEV
+ this.th_pain = fd_secret_pain;
+ this.th_die = this.use;
+ }
+
+ this.oldorigin = this.origin;
+
+ if (!this.wait)
+ // 5 seconds before closing
+ this.wait = 5;
+ };
+
+ //--------------------------------------------------------------
+ void() func_door_secret =
{
- self.health = 10000;
- self.takedamage = DAMAGE_YES;
- self.th_pain = fd_secret_pain;
- self.th_die = fd_secret_use;
- }
-
- self.oldorigin = self.origin;
-
- if (!self.wait)
- // 5 seconds before closing
- self.wait = 5;
+ // this.classname = "door";
+ this.classtype = CT_FUNC_DOOR_SECRET;
+ };
};

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

Diff qc/func/elvtr_button.qc

diff --git a/qc/func/elvtr_button.qc b/qc/func/elvtr_button.qc
index 243f898..ef8e3d5 100644
--- a/qc/func/elvtr_button.qc
+++ b/qc/func/elvtr_button.qc
@@ -6,95 +6,11 @@
// pmack
// sept 96

-// constants
-const float ELVTR_DOWN = 1;
-
-// prototypes
-void() elvtr_button_wait;
-void() elvtr_button_return;
-
-//----------------------------------------------------------------------
-void() elvtr_button_wait =
-{
- elv_butn_dir = 0;
- if (self.spawnflags & ELVTR_DOWN)
- elv_butn_dir = -1;
- else
- elv_butn_dir = 1;
-
- self.state = STATE_TOP;
- self.nextthink = self.ltime + self.wait;
- self.think = elvtr_button_return;
- activator = self.enemy;
- SUB_UseTargets ();
- // use alternate textures
- self.frame = 1;
-};
-
-//----------------------------------------------------------------------
-void() elvtr_button_done =
-{
- self.state = STATE_BOTTOM;
-};
-
-//----------------------------------------------------------------------
-void() elvtr_button_return =
-{
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos1, self.speed, elvtr_button_done);
- // use normal textures
- self.frame = 0;
- if (self.health)
- // can be shot again
- self.takedamage = DAMAGE_YES;
-};
-
-
-//----------------------------------------------------------------------
-void() elvtr_button_blocked =
-{
- // do nothing, just don't ome all the way back out
-};
-
-
-//----------------------------------------------------------------------
-void() elvtr_button_fire =
-{
- if (self.state == STATE_UP || self.state == STATE_TOP)
- return;
-
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- self.state = STATE_UP;
- SUB_CalcMove (self.pos2, self.speed, elvtr_button_wait);
-};
+// globals
+float elv_butn_dir;

-//----------------------------------------------------------------------
-void() elvtr_button_use =
-{
- self.enemy = activator;
- elvtr_button_fire ();
-};
-
-//----------------------------------------------------------------------
-void() elvtr_button_touch =
-{
- if (other.classname != "player")
- return;
-
- self.enemy = other;
- elvtr_button_fire ();
-};
-
-//----------------------------------------------------------------------
-void() elvtr_button_killed =
-{
- self.enemy = damage_attacker;
- self.health = self.max_health;
- // wil be reset upon return
- self.takedamage = DAMAGE_NO;
- elvtr_button_fire ();
-};
+// constants
+const float BUTTON_ELVTR_DOWN = 1;

/*QUAKED func_elvtr_button (0 .5 .8) ? ELVTR_DOWN X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

@@ -117,66 +33,151 @@ When a button is touched, it moves some distance in the direction of it's angle,
2) metallic click
3) in-out
*/
-void() func_elvtr_button =
+class func_elvtr_button: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.sounds == 0)
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_button_wait =
{
- precache_sound ("buttons/airbut1.wav");
- self.noise = "buttons/airbut1.wav";
- }
-
- if (self.sounds == 1)
+ elv_butn_dir = 0;
+ if (this.spawnflags & BUTTON_ELVTR_DOWN)
+ elv_butn_dir = -1;
+ else
+ elv_butn_dir = 1;
+
+ this.state = FUNC_STATE_TOP;
+ this.nextthink = this.ltime + this.wait;
+ activator = this.enemy;
+ sub_usetargets ();
+ // use alternate textures
+ this.frame = 1;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_button_done =
{
- precache_sound ("buttons/switch21.wav");
- self.noise = "buttons/switch21.wav";
- }
+ this.state = FUNC_STATE_BOTTOM;
+ };

- if (self.sounds == 2)
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_button_fire =
{
- precache_sound ("buttons/switch02.wav");
- self.noise = "buttons/switch02.wav";
- }
+ if (this.state == FUNC_STATE_UP || this.state == FUNC_STATE_TOP)
+ return;

- if (self.sounds == 3)
- {
- precache_sound ("buttons/switch04.wav");
- self.noise = "buttons/switch04.wav";
- }
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);

- SetMovedir ();
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos2, this.speed, elvtr_button_wait);
+ };

- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- setmodel (self, self.model);
-
- self.blocked = elvtr_button_blocked;
- self.use = elvtr_button_use;
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
+ {
+ // do nothing, just don't ome all the way back out
+ };

- if (self.health)
+ //--------------------------------------------------------------
+ // was elvtr_button_return -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.max_health = self.health;
- self.th_die = elvtr_button_killed;
- self.takedamage = DAMAGE_YES;
- }
- else
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos1, this.speed, elvtr_button_done);
+ // use normal textures
+ this.frame = 0;
+ if (this.health)
+ // can be shot again
+ this.takedamage = DAMAGE_YES;
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- self.touch = elvtr_button_touch;
- }
+ if (this.health > 0)
+ return;

- if (!self.speed)
- self.speed = 40;
- if (!self.wait)
- self.wait = 1;
- if (!self.lip)
- self.lip = 4;
+ if (toucher.classtype != CT_PLAYER)
+ return;

- self.state = STATE_BOTTOM;
+ this.enemy = toucher;
+ elvtr_button_fire ();
+ };

- self.pos1 = self.origin;
- self.pos2 = self.pos1 + self.movedir *
- (fabs(self.movedir * self.size) - self.lip);
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ this.enemy = activator;
+ elvtr_button_fire ();
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_button_killed =
+ {
+ this.enemy = damage_attacker;
+ this.health = this.max_health;
+ // wil be reset upon return
+ this.takedamage = DAMAGE_NO;
+ elvtr_button_fire ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.sounds == 0)
+ {
+ precache_sound ("buttons/airbut1.wav");
+ this.noise = "buttons/airbut1.wav";
+ }
+
+ if (this.sounds == 1)
+ {
+ precache_sound ("buttons/switch21.wav");
+ this.noise = "buttons/switch21.wav";
+ }
+
+ if (this.sounds == 2)
+ {
+ precache_sound ("buttons/switch02.wav");
+ this.noise = "buttons/switch02.wav";
+ }
+
+ if (this.sounds == 3)
+ {
+ precache_sound ("buttons/switch04.wav");
+ this.noise = "buttons/switch04.wav";
+ }
+
+ sub_setmovedir ();
+
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ setmodel (this, this.model);
+
+ if (this.health)
+ {
+ this.max_health = this.health;
+ // TODO CEV
+ this.th_die = elvtr_button_killed;
+ this.takedamage = DAMAGE_YES;
+ }
+
+ if (!this.speed)
+ this.speed = 40;
+ if (!this.wait)
+ this.wait = 1;
+ if (!this.lip)
+ this.lip = 4;
+
+ this.state = FUNC_STATE_BOTTOM;
+
+ this.pos1 = this.origin;
+ this.pos2 = this.pos1 + this.movedir *
+ (fabs(this.movedir * this.size) - this.lip);
+ };
+
+ //--------------------------------------------------------------
+ void() func_elvtr_button =
+ {
+ this.classtype = CT_FUNC_ELVTR_BUTTON;
+ };
};

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

Diff qc/func/episodegate.qc

diff --git a/qc/func/episodegate.qc b/qc/func/episodegate.qc
index c238462..a785374 100644
--- a/qc/func/episodegate.qc
+++ b/qc/func/episodegate.qc
@@ -9,30 +9,35 @@ const float EPISODEGATE_REVERSE = 16;
/*QUAKED func_episodegate (0 .5 .8) ? E1 E2 E3 E4 REVERSE_FUNCTIONALITY
This bmodel will appear if the episode has allready been completed, so players can't reenter it.
*/
-void() func_episodegate =
+class func_episodegate: base_func_wall
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.spawnflags & EPISODEGATE_REVERSE)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // this is to avoid a possible issue with sigil_touch2
- self.spawnflags = self.spawnflags - EPISODEGATE_REVERSE;
- if (serverflags & self.spawnflags)
- // Haven't gotten rune yet
- return;
- }
- else
+ if (this.spawnflags & EPISODEGATE_REVERSE)
+ {
+ // this is to avoid a possible issue with sigil_touch2
+ this.spawnflags = this.spawnflags - EPISODEGATE_REVERSE;
+ if (serverflags & this.spawnflags)
+ // Haven't gotten rune yet
+ return;
+ }
+ else
+ {
+ if (!(serverflags & this.spawnflags))
+ // can still enter episode
+ return;
+ }
+ this.angles = '0 0 0';
+ // so it doesn't get pushed by anything
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ setmodel (this, this.model);
+ };
+
+ //--------------------------------------------------------------
+ void() func_episodegate =
{
- if (!(serverflags & self.spawnflags))
- // can still enter episode
- return;
- }
- self.angles = '0 0 0';
- // so it doesn't get pushed by anything
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
+ this.classtype = CT_FUNC_EPISODEGATE;
+ };
};

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

Diff qc/func/explobox.qc

diff --git a/qc/func/explobox.qc b/qc/func/explobox.qc
index 81ec694..85d2e75 100644
--- a/qc/func/explobox.qc
+++ b/qc/func/explobox.qc
@@ -2,36 +2,6 @@
// func_explobox -- selections from Rubicon 2 qc by john fitzgibbons
//==============================================================================

-//----------------------------------------------------------------------
-void() func_explobox_explode_silent =
-{
- self.takedamage = DAMAGE_NO;
- self.origin = ((self.absmin + self.absmax) * 0.5);
- self.classname = "explo_box";
- T_RadiusDamage (self, self, self.dmg, world);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_EXPLOSION);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- BecomeExplosion ();
-};
-
-//----------------------------------------------------------------------
-void() func_explobox_explode =
-{
- // sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
- func_explobox_explode_silent ();
-};
-
-//----------------------------------------------------------------------
-void() func_explobox_die =
-{
- // for some reason, time + 0.2 doesn't work
- self.nextthink = 0.2;
- self.think = func_explobox_explode;
-};
-
/*QUAKED func_explobox (0 .5 .8) ? START_OFF X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

An exploding brush entity. Works just like misc_explobox.
@@ -43,27 +13,59 @@ Keys:
"dmg" default 100

*/
-void() func_explobox =
+class func_explobox: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() explode_silent =
+ {
+ this.takedamage = DAMAGE_NO;
+ this.origin = ((this.absmin + this.absmax) * 0.5);
+ this.classname = "explo_box";
+ T_RadiusDamage (this, this, this.dmg, world);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_EXPLOSION);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ BecomeExplosion ();
+ };

- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setmodel (self, self.model);
- precache_sound ("weapons/r_exp3.wav");
+ //--------------------------------------------------------------
+ nonvirtual void() explobox_die =
+ {
+ // for some reason, time + 0.2 doesn't work
+ this.nextthink = 0.2;
+ };

- if (!self.health)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.health = 20;
- }
+ // sound (this, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM);
+ this.explode_silent ();
+ };

- if (!self.dmg)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.dmg = 100;
- }
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setmodel (this, this.model);
+ precache_sound ("weapons/r_exp3.wav");
+
+ if (!this.health)
+ this.health = 20;

- self.th_die = func_explobox_die;
- self.takedamage = DAMAGE_AIM;
+ if (!this.dmg)
+ this.dmg = 100;
+
+ // TODO CEV
+ this.th_die = explobox_die;
+ this.takedamage = DAMAGE_AIM;
+ };
+
+ //--------------------------------------------------------------
+ void() func_explobox =
+ {
+ this.classtype = CT_FUNC_EXPLOBOX;
+ };
};

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

Diff qc/func/fall.qc

diff --git a/qc/func/fall.qc b/qc/func/fall.qc
index 33c6af0..d924511 100644
--- a/qc/func/fall.qc
+++ b/qc/func/fall.qc
@@ -9,109 +9,113 @@
//==============================================================================

// constants
-const float DONT_FADE = 1;
-const float SILENT = 2;
+const float FUNCFADE_DONT_FADE = 1;
+const float FUNCFADE_SILENT = 2;

-//----------------------------------------------------------------------
-void() func_fall_think =
+/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+A brush that drops and fades away when touched and/or triggered.
+Add some spice to your jumping puzzles or other scripted sequences!
+Monsters will not trigger func_fall but will be gibbed if one falls on them.
+NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
+noise = sound to play when triggered, the default is a switch sound.
+wait = wait this long before falling.
+Use the DONT_FADE spawnflag if desired.
+
+Falling brush upon touch
+*/
+class func_fall: base_func
{
- if (self.cnt == TRUE && self.attack_finished < time)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.solid = SOLID_BBOX;
- // self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_TOSS;
-
- if (!(self.spawnflags & DONT_FADE))
+ if (this.cnt == TRUE && this.attack_finished < time)
{
+ this.solid = SOLID_BBOX;
+ // this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_TOSS;

- if (self.alpha > 0.1)
+ if (!(this.spawnflags & FUNCFADE_DONT_FADE))
{
- self.alpha = self.alpha - 0.03;
- }
- else
- {
- remove (self);
- return;
+ if (this.alpha > 0.1)
+ {
+ this.alpha = this.alpha - 0.03;
+ }
+ else
+ {
+ remove (this);
+ return;
+ }
}
}
- }
- self.nextthink = time + 0.1;
-};
+ this.nextthink = time + 0.1;
+ };

-//----------------------------------------------------------------------
-void() fall_touch =
-{
- if (other.classname == "player")
- {
- if (!(other.flags & FL_ONGROUND))
- other.flags = other.flags | FL_ONGROUND;
- }
- else if (other.flags & FL_MONSTER)
- {
- T_Damage (other, self, other, 50000);
- }
- else
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- return;
- }
+ if (toucher.classtype == CT_PLAYER)
+ {
+ if (!(toucher.flags & FL_ONGROUND))
+ toucher.flags = toucher.flags | FL_ONGROUND;
+ }
+ else if (toucher.flags & FL_MONSTER)
+ {
+ T_Damage (toucher, this, toucher, 50000);
+ }
+ else
+ {
+ return;
+ }

- if (self.cnt == TRUE)
- return;
+ if (this.cnt == TRUE)
+ return;

- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
+ this.attack_finished = time + this.wait;
+ this.cnt = TRUE;

- if (!(self.spawnflags & SILENT))
+ if (!(this.spawnflags & FUNCFADE_SILENT))
+ {
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise,
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_AUTO, "buttons/switch21.wav",
+ 1, ATTN_NORM);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
+ // thanks again RennyC for help on revisions --dumptruck_ds
+ this.attack_finished = time + this.wait;
+ this.cnt = TRUE;
+
+ if (this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
else
- sound (self, CHAN_AUTO, "buttons/switch21.wav",
+ sound (this, CHAN_AUTO, "buttons/switch21.wav",
1, ATTN_NORM);
- }
-};
+ };

-//----------------------------------------------------------------------
-void() fall_use =
-{
- // thanks again RennyC for help on revisions --dumptruck_ds
- self.attack_finished = time + self.wait;
- self.cnt = TRUE;
-
- if (self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
- else
- sound (self, CHAN_AUTO, "buttons/switch21.wav", 1, ATTN_NORM);
-};
-
-/*QUAKED func_fall (0 .5 .8) ? DONT_FADE X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-A brush that drops and fades away when touched and/or triggered.
-Add some spice to your jumping puzzles or other scripted sequences!
-Monsters will not trigger func_fall but will be gibbed if one falls on them.
-NOTE: When a func_fall brush touches another brush or entity it will stop, which can look odd in certain situations.
-noise = sound to play when triggered, the default is a switch sound.
-wait = wait this long before falling.
-Use the DONT_FADE spawnflag if desired.
-
-Falling brush upon touch
-*/
-void() func_fall =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ precache_sound ("buttons/switch21.wav");
+ if (this.noise != "")
+ precache_sound (this.noise);

- precache_sound ("buttons/switch21.wav");
- if (self.noise != "")
- precache_sound (self.noise);
+ this.alpha = 1;
+ this.cnt = FALSE;
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ this.nextthink = time;
+ setmodel (this, this.model);
+ };

- self.alpha = 1;
- self.cnt = FALSE;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- self.think = func_fall_think;
- self.nextthink = time;
- self.touch = fall_touch;
- self.use = fall_use;
- setmodel (self, self.model);
+ //--------------------------------------------------------------
+ void() func_fall =
+ {
+ this.classtype = CT_FUNC_FALL;
+ };
};

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

Diff qc/func/fall2.qc

diff --git a/qc/func/fall2.qc b/qc/func/fall2.qc
index 95e6a1e..17d8be0 100644
--- a/qc/func/fall2.qc
+++ b/qc/func/fall2.qc
@@ -2,196 +2,40 @@
// func_fall2 -- code attributed to RennyC & whirledtsar
//==============================================================================

-// fields
-.float alpha; // translucency in supported engines
-.entity char; // linker entity
-
// constants
-const float PLAYER_TRIGGERED = 1;
-const float MONSTER_TRIGGERED = 2;
-const float FALL_BREAKABLE = 8; // VR
-// const float FALL_SOLID = 16; // VR
-
-// prototypes
-void() fall_break_fields;
+const float FALL2_PLAYER_TRIGGERED = 1;
+const float FALL2_MONSTER_TRIGGERED = 2;
+const float FALL2_BREAKABLE = 8; // VR
+// const float FALL2_SOLID = 16; // VR

-//----------------------------------------------------------------------
-void() func_fall2_think =
+//------------------------------------------------------------------------------
+class temp_fall2_helper: base_tempentity
{
- // turn off quake engine splash sound
- self.waterlevel = self.watertype = 0;
-
- if (self.attack_finished < time)
+ //--------------------------------------------------------------
+ virtual void(entity e) do_touch =
{
- if (self.target != __NULL__ && self.target != "")
- // fire other targets; was SUB_UseTargets ()
- SUB_UseAndForgetTargets ();
-
-
- // removed FALL_SOLID behavior -- dumptruck_ds
- self.solid = SOLID_NOT;
-
- if (self.pos1 != '0 0 0')
- // apply stored avelocity vector values
- self.avelocity = self.pos1;
-
- if (self.pos2 && !self.velocity)
- // Add velocity movement
- self.velocity = self.pos2;
-
- if (self.cnt > 0)
- {
- // cnt over 0
- if (self.cnt >= 2)
- {
- self.movetype = MOVETYPE_BOUNCE;
- if (self.velocity_z < self.lip)
- self.velocity_z = self.lip;
- }
- else
- {
- // cnt is 1
- self.movetype = MOVETYPE_NOCLIP;
- if (self.velocity_z > self.lip)
- self.velocity_z -= self.speed *
- (frametime * 100);
- else
- self.velocity_z = self.lip;
- }
- }
- else
- {
- // default behavior (cnt is 0)
- self.movetype = MOVETYPE_TOSS;
- if (self.velocity_z < self.lip)
- self.velocity_z = self.lip;
- }
-
- if (self.pain_finished != -1)
- {
- if (self.alpha > 0.1)
- self.alpha = self.alpha - self.pain_finished;
- else
- {
- if (self.noise2 != __NULL__ &&self.noise2 != "")
- sound (self, CHAN_AUTO, self.noise2,
- 1, ATTN_NORM);
- remove (self);
- return;
- }
- }
+ if (e.flags & FL_FLY)
+ // flying monsters shouldn't trigger falling platforms
+ return;

- if (self.flags & FL_ONGROUND &&
- self.spawnflags & FALL_BREAKABLE)
+ if (e.flags & FL_MONSTER && owner.classtype == CT_FUNC_FALL2)
{
- // VR
-
- // aka BREAKABLE_NO_MONSTERS
- self.spawnflags(-)1;
- // aka BREAK_EXPLODE
- self.spawnflags(-)2;
- // because of how debris origin is calculated
- self.mins = self.absmin;
- self.maxs = self.absmax;
- // debris gets velocity from health
- self.health = self.lip * 0.1;
- // func_breakable uses cnt for quantity of debris
- // to spawn
- self.cnt = self.count;
- // removes self
- func_breakable_die ();
- return;
+ dprint ("temp_fall2_helper: inside field_touch\n");
+ local func_fall2 ff2;
+ ff2 = (func_fall2)owner;
+ ff2.thinkuse = TRUE;
+ ff2.nextthink = ff2.ltime + 0.1;
+ // TODO CEV
+ // ff2.nextthink = ff2.owner.ltime + 0.1;
+ remove (this);
}
- }
-
- self.nextthink = self.ltime + 0.1;
-};
-
-//----------------------------------------------------------------------
-void() fall2_touch =
-{
- if (!other.takedamage)
- return;
-
- if (other.classname != "player")
- // player activated only
- return;
-
- if (self.spawnflags & MONSTER_TRIGGERED)
- // disable on monster only, also fixes weird issue
- return;
-
- self.think = func_fall2_think;
- self.nextthink = self.ltime + 0.1;
-
- self.attack_finished = time + self.wait;
-
- // if (self.spawnflags & FALL_SOLID)
- // {
- // // VR
- // setsize (self, self.mins, self.maxs);
- // self.solid = SOLID_BBOX;
- // }
- // else
- // {
- // self.solid = SOLID_NOT;
- // }
-
- if (self.noise != __NULL__ && self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-
- // disable touch, only do this once!
- self.touch = SUB_Null;
-
- if (self.char)
- remove (self.char);
-};
-
-//----------------------------------------------------------------------
-void() func_fall2_use =
-{
- self.think = func_fall2_think;
- self.nextthink = self.ltime + 0.1;
- // disable touch when used
- self.touch = SUB_Null;
-
- // if (self.spawnflags&FALL_SOLID)
- // {
- // // VR
- // setsize (self, self.mins, self.maxs);
- // self.solid = SOLID_BBOX;
- // }
- // else
- // {
- // self.solid = SOLID_NOT;
- // }
-
- self.attack_finished = time + self.wait;
- if (self.noise != __NULL__ && self.noise != "")
- sound (self, CHAN_AUTO, self.noise, 1, ATTN_NORM);
-};
+ };

-//----------------------------------------------------------------------
-void() func_fall2_field_touch =
-{
- if (other.flags & FL_FLY)
- // flying monsters shouldn't trigger falling platforms
- return;
-
- if (other.flags & FL_MONSTER)
+ void() temp_fall2_helper =
{
- local entity oself;
-
- oself = self;
-
- self = self.owner;
- self.think = func_fall2_use;
- self.nextthink = self.owner.ltime + 0.1;
-
- self = oself;
-
- remove (self);
- }
+ this.classtype = CT_TEMP_FALL2_HELPER;
+ this.solid = SOLID_TRIGGER;
+ };
};

/*QUAKED func_fall2 (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -216,147 +60,327 @@ Default behavior allows anyone to activate func_fall2 on touch ONLY

Able to .target other entities, including other func_fall2s
*/
-void() func_fall2 =
+class func_fall2: base_breakable
{
- // This is a hack to have monsters be able to trigger it
- // by fake touch - Thanks to Nahuel
+ // class fields: linker entity
+ temp_fall2_helper fall2_helper;
+ float thinkuse;

- // Don't spawn on player only or if I'm a targetable
- if (!(self.spawnflags & PLAYER_TRIGGERED) && !(self.targetname))
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- local entity func_fall2_field;
-
- func_fall2_field = spawn ();
- func_fall2_field.owner = self;
- // Link 'em
- self.char = func_fall2_field;
- func_fall2_field.solid = SOLID_TRIGGER;
- setsize (func_fall2_field, self.absmin, self.absmax + '0 0 8');
- setorigin (func_fall2_field, self.origin);
- setmodel (func_fall2_field, self.model);
- func_fall2_field.touch = func_fall2_field_touch;
- }
-
- if (self.noise != __NULL__ && self.noise != "")
- precache_sound (self.noise);
- if (self.noise2 != __NULL__ && self.noise2 != "")
- precache_sound (self.noise2);
-
- self.alpha = 1;
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
-
- if (!self.pain_finished)
- self.pain_finished = 0.01;
- if (!self.targetname)
- // .touch in this instance is for players only
- self.touch = fall2_touch;
-
- if (!self.speed)
- self.speed = 10;
- if (!self.lip)
- self.lip = -800;
-
- if (self.avelocity != '0 0 0')
+ if (this.thinkuse == TRUE)
+ {
+ this.do_use (caller);
+ return;
+ }
+ // turn off quake engine splash sound
+ this.waterlevel = this.watertype = 0;
+
+ if (this.attack_finished < time)
+ {
+ if (this.target != __NULL__ && this.target != "")
+ sub_useandforgettargets ();
+
+
+ // removed FALL_SOLID behavior -- dumptruck_ds
+ this.solid = SOLID_NOT;
+
+ if (this.pos1 != '0 0 0')
+ // apply stored avelocity vector values
+ this.avelocity = this.pos1;
+
+ if (this.pos2 && !this.velocity)
+ // Add velocity movement
+ this.velocity = this.pos2;
+
+ if (this.cnt > 0)
+ {
+ // cnt over 0
+ if (this.cnt >= 2)
+ {
+ this.movetype = MOVETYPE_BOUNCE;
+ if (this.velocity_z < this.lip)
+ this.velocity_z = this.lip;
+ }
+ else
+ {
+ // cnt is 1
+ this.movetype = MOVETYPE_NOCLIP;
+ if (this.velocity_z > this.lip)
+ this.velocity_z -= this.speed *
+ (frametime * 100);
+ else
+ this.velocity_z = this.lip;
+ }
+ }
+ else
+ {
+ // default behavior (cnt is 0)
+ this.movetype = MOVETYPE_TOSS;
+ if (this.velocity_z < this.lip)
+ this.velocity_z = this.lip;
+ }
+
+ if (this.pain_finished != -1)
+ {
+ if (this.alpha > 0.1)
+ // TODO CEV fall2 was fading too fast
+ // so I've doubled the time; thinking
+ // too often?
+ this.alpha -= this.pain_finished * 0.5;
+ else
+ {
+ if (this.noise2 != __NULL__ &&
+ this.noise2 != "")
+ {
+ sound (this, CHAN_AUTO,
+ this.noise2,
+ 1, ATTN_NORM);
+ }
+ remove (this);
+ return;
+ }
+ }
+
+ if (this.flags & FL_ONGROUND &&
+ this.spawnflags & FALL2_BREAKABLE)
+ {
+ // VR
+ // aka BREAKABLE_NO_MONSTERS
+ this.spawnflags(-)1;
+ // aka BREAK_EXPLODE
+ this.spawnflags(-)2;
+ // because of how debris origin is calculated
+ this.mins = this.absmin;
+ this.maxs = this.absmax;
+ // debris gets velocity from health
+ this.health = this.lip * 0.1;
+ // func_breakable uses cnt for quantity of
+ // debris to spawn
+ this.cnt = this.count;
+ // removes this
+ breakable_die ();
+ return;
+ }
+ }
+
+ this.nextthink = this.ltime + 0.1;
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- // store it
- self.pos1 = self.avelocity;
- self.avelocity = '0 0 0';
- }
+ if (this.targetname != __NULL__ && this.targetname != "")
+ return;
+
+ if (!toucher.takedamage)
+ return;
+
+ if (toucher.classtype != CT_PLAYER)
+ // player activated only
+ return;

- if (self.spawnflags & FALL_BREAKABLE)
+ if (this.spawnflags & FALL2_MONSTER_TRIGGERED)
+ // disable on monster only, also fixes weird issue
+ return;
+
+ this.thinkuse = FALSE;
+ this.nextthink = this.ltime + 0.1;
+ this.attack_finished = time + this.wait;
+
+ // if (this.spawnflags & FALL_SOLID)
+ // {
+ // // VR
+ // setsize (this, this.mins, this.maxs);
+ // this.solid = SOLID_BBOX;
+ // }
+ // else
+ // {
+ // this.solid = SOLID_NOT;
+ // }
+
+ if (this.noise != __NULL__ && this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+
+ // disable touch, only do this once!
+ this.interaction_flags |= DISABLE_TOUCH;
+
+ if (this.fall2_helper)
+ remove (this.fall2_helper);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- // VR
- // dont fade if set to break
- self.pain_finished = -1;
- fall_break_fields ();
- }
- self.use = func_fall2_use;
-
- setmodel (self, self.model);
-};
+ this.thinkuse = FALSE;
+ this.nextthink = this.ltime + 0.1;
+ // disable touch when used
+ this.interaction_flags |= DISABLE_TOUCH;
+
+ // if (this.spawnflags & FALL_SOLID)
+ // {
+ // // VR
+ // setsize (this, this.mins, this.maxs);
+ // this.solid = SOLID_BBOX;
+ // }
+ // else
+ // {
+ // this.solid = SOLID_NOT;
+ // }
+
+ this.attack_finished = time + this.wait;
+ if (this.noise != __NULL__ && this.noise != "")
+ sound (this, CHAN_AUTO, this.noise, 1, ATTN_NORM);
+ };
+
+ // You may have to modify your multi_touch(); command in triggers.qc
+ // to allow both monsters & players to activate trigger_once/multiple.
+ // I recommend allowing the mapper themselves to select how that
+ // occurs. Default behavior is player only.
+
+ //--------------------------------------------------------------
+ nonvirtual void fall_break_fields ()
+ {
+ break_template_setup ();

-// You may have to modify your multi_touch(); command in triggers.qc to allow
-// both monsters & players to activate trigger_once/multiple. I recommend
-// allowing the mapper themselves to select how that occurs.
-// Default behavior is player only.
+ this.mdl_debris = "progs/debris.mdl";
+ precache_model (this.mdl_debris);

-//----------------------------------------------------------------------
-void fall_break_fields ()
-{
- break_template_setup ();
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+
+ // adding new default sounds for "simple" breakables in 1.2.0
+ // -- dumptruck_ds

- self.mdl_debris = "progs/debris.mdl";
- precache_model (self.mdl_debris);
+ // here's generic metal breaking
+ if (this.style == 0 || this.style == 11 ||
+ this.style == 12 || this.style == 17 ||
+ this.style == 18 || this.style == 19 ||
+ this.style == 24 || this.style == 31)
+ {
+ if !(this.noise1)
+ {
+ precache_sound ("break/metal2.wav");
+ this.noise1 = "break/metal2.wav";
+ }
+ }

- if (self.noise1 != "")
- precache_sound (self.noise1);
+ if (this.style == 3 || this.style == 4 || this.style == 5)
+ {
+ if !(this.noise1)
+ {
+ precache_sound ("break/wood1.wav");
+ precache_sound ("break/wood2.wav");
+ // wood only randomized
+ if (random() > 0.6)
+ this.noise1 = "break/wood1.wav";
+ else
+ this.noise1 = "break/wood2.wav";
+ }
+ }

- // adding new default sounds for "simple" breakables in 1.2.0
- // -- dumptruck_ds
+ // glass sounds -- this is more of a shattering sound anyway
+ if (this.style == 6 || this.style == 7 || this.style == 8 ||
+ this.style == 9 || this.style == 10)
+ {
+ if !(this.noise1)
+ {
+ precache_sound ("break/metal1.wav");
+ this.noise1 = "break/metal1.wav";
+ }
+ }

- // here's generic metal breaking
- if (self.style == 0 || self.style == 11 || self.style == 12 ||
- self.style == 17 || self.style == 18 || self.style == 19
- || self.style == 24 || self.style == 31)
- {
- if !(self.noise1)
+ if (this.style == 1 || this.style == 2 ||
+ this.style == 13 || this.style == 14 ||
+ this.style == 15 || this.style == 16 ||
+ this.style == 20 || this.style == 21 ||
+ this.style == 22 || this.style == 23)
{
- precache_sound ("break/metal2.wav");
- self.noise1 = "break/metal2.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/bricks1.wav");
+ this.noise1 = "break/bricks1.wav";
+ }
}
- }

- if (self.style == 3 || self.style == 4 || self.style == 5)
- {
- if !(self.noise1)
+ if (this.style == 25 || this.style == 26 ||
+ this.style == 27 || this.style == 28 ||
+ this.style == 29 || this.style == 30)
{
- precache_sound ("break/wood1.wav");
- precache_sound ("break/wood2.wav");
- // wood only randomized
- if (random() > 0.6)
- self.noise1 = "break/wood1.wav";
- else
- self.noise1 = "break/wood2.wav";
+ if !(this.noise1)
+ {
+ precache_sound ("break/stones1.wav");
+ this.noise1 = "break/stones1.wav";
+ }
}
- }

- // glass sounds -- this is more of a shattering sound anyway
- if (self.style == 6 || self.style == 7 || self.style == 8 ||
- self.style == 9 || self.style == 10)
+ if (!this.health)
+ this.health = 20;
+ if (!this.count)
+ // was 6 dumptruck_ds
+ this.count = 5;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- if !(self.noise1)
+ // This is a hack to have monsters be able to trigger it
+ // by fake touch - Thanks to Nahuel
+
+ // Don't spawn on player only or if I'm a targetable
+ if (!(this.spawnflags & FALL2_PLAYER_TRIGGERED) &&
+ !(this.targetname))
{
- precache_sound ("break/metal1.wav");
- self.noise1 = "break/metal1.wav";
+ // Link 'em
+ // modified to use a helper class -- CEV
+ this.fall2_helper = spawn (temp_fall2_helper,
+ owner: this);
+ setsize (this.fall2_helper, this.absmin,
+ this.absmax + '0 0 8');
+ setorigin (this.fall2_helper, this.origin);
+ setmodel (this.fall2_helper, this.model);
}
- }

- if (self.style == 1 || self.style == 2 || self.style == 13 ||
- self.style == 14 || self.style == 15 || self.style == 16 ||
- self.style == 20 || self.style == 21 || self.style == 22 ||
- self.style == 23)
- {
- if !(self.noise1)
+ if (this.noise != __NULL__ && this.noise != "")
+ precache_sound (this.noise);
+ if (this.noise2 != __NULL__ && this.noise2 != "")
+ precache_sound (this.noise2);
+
+ this.interaction_flags &= ~DISABLE_TOUCH;
+ this.alpha = 1.0;
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+
+ if (!this.pain_finished)
+ this.pain_finished = 0.01;
+
+ if (!this.speed)
+ this.speed = 10;
+ if (!this.lip)
+ this.lip = -800;
+
+ if (this.avelocity != '0 0 0')
{
- precache_sound ("break/bricks1.wav");
- self.noise1 = "break/bricks1.wav";
+ // store it
+ this.pos1 = this.avelocity;
+ this.avelocity = '0 0 0';
}
- }

- if (self.style == 25 || self.style == 26 || self.style == 27 ||
- self.style == 28 || self.style == 29 || self.style == 30)
- {
- if !(self.noise1)
+ if (this.spawnflags & FALL2_BREAKABLE)
{
- precache_sound ("break/stones1.wav");
- self.noise1 = "break/stones1.wav";
+ // VR
+ // dont fade if set to break
+ this.pain_finished = -1;
+ fall_break_fields ();
}
- }

- if (!self.health)
- self.health = 20;
- if (!self.count)
- // was 6 dumptruck_ds
- self.count = 5;
+ setmodel (this, this.model);
+ };
+
+ //--------------------------------------------------------------
+ void() func_fall2 =
+ {
+ this.classtype = CT_FUNC_FALL2;
+ };
};

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

Diff qc/func/illusionary.qc

diff --git a/qc/func/illusionary.qc b/qc/func/illusionary.qc
index faaad6f..edff2f4 100644
--- a/qc/func/illusionary.qc
+++ b/qc/func/illusionary.qc
@@ -5,15 +5,19 @@
/*QUAKED func_illusionary (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
A simple entity that looks solid but lets you walk through it.
*/
-void() func_illusionary =
+class func_illusionary: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ virtual void() init_spawned =
+ {
+ this.angles = '0 0 0';
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;
+ setmodel (this, this.model);
+ makestatic (this);
+ };

- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
- setmodel (self, self.model);
- makestatic (self);
+ void() func_illusionary =
+ {
+ this.classtype = CT_FUNC_ILLUSIONARY;
+ };
};

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 63967d8..325c169 100644
--- a/qc/func/laser.qc
+++ b/qc/func/laser.qc
@@ -2,76 +2,34 @@
// func_laser -- selections from Rubicon 2 qc by john fitzgibbons
//==============================================================================

-// fields
-.float alpha;
-.string message2;
-
// constants
const float LASER_START_OFF = 1;
const float LASER_SOLID = 2;

-//----------------------------------------------------------------------
-void() laser_helper_think =
-{
- if (!self.owner || self.owner.classname != "func_laser")
- {
- remove (self);
- return;
- }
-
- if (!(self.owner.spawnflags & LASER_START_OFF))
- self.owner.alpha = self.alpha * 0.8 +
- self.alpha * random() * 0.4;
-
- self.nextthink = time + 0.05;
-};
-
-//----------------------------------------------------------------------
-void() func_laser_touch =
-{
- // from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
- return;
-
- if (other.takedamage && self.attack_finished < time)
- {
- T_Damage (other, self, self, self.dmg);
- self.attack_finished = time + 0.1;
- }
-
-};
-
-//----------------------------------------------------------------------
-void() func_laser_use =
+//------------------------------------------------------------------------------
+class temp_laser_helper: base_tempentity
{
- if (self.spawnflags & LASER_START_OFF)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- setorigin (self, '0 0 0');
- 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
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
-
- if (activator.classname == "player" && self.message != "")
+ if (!this.owner || this.owner.classtype != CT_FUNC_LASER)
{
- centerprint (activator, self.message);
+ remove (this);
+ return;
}
- }
- else
- {
- // changed for progs_dump: the laser sound is now emitted from
- // the func_laser itself instead of from the activator -- iw
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);

- setorigin (self, '0 0 9000');
- self.spawnflags = self.spawnflags + LASER_START_OFF;
+ if (!(this.owner.spawnflags & LASER_START_OFF))
+ this.owner.alpha = this.alpha * 0.8 +
+ this.alpha * random() * 0.4;

- if (activator.classname == "player" && self.message2 != "")
- {
- centerprint (activator, self.message2);
- }
- }
+ this.nextthink = time + 0.05;
+ };
+
+ void() temp_laser_helper =
+ {
+ this.classtype = CT_TEMP_LASER_HELPER;
+ this.nextthink = 0.05;
+ };
};

/*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
@@ -93,59 +51,126 @@ Keys:
"message2" message to display when deactivated

*/
-void () func_laser =
+class func_laser: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ string message2;

- local entity helper;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "message2":
+ message2 = fieldvalue;
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };

- setmodel (self, self.model);
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ // from Copper -- dumptruck_ds
+ if (toucher.movetype == MOVETYPE_NOCLIP)
+ return;

- precache_sound ("buttons/switch02.wav");
- precache_sound ("buttons/switch04.wav");
+ if (toucher.takedamage && this.attack_finished < time)
+ {
+ T_Damage (toucher, this, this, this.dmg);
+ this.attack_finished = time + 0.1;
+ }
+
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.spawnflags & LASER_START_OFF)
+ {
+ setorigin (this, '0 0 0');
+ this.spawnflags = this.spawnflags - LASER_START_OFF;
+
+ // changed for progs_dump: the laser sound is now
+ // emitted from the func_laser itthis instead of
+ // from the activator -- iw
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+
+ if (activator.classtype == CT_PLAYER &&
+ this.message != "")
+ {
+ centerprint (activator, this.message);
+ }
+ }
+ else
+ {
+ // changed for progs_dump: the laser sound is now
+ // emitted from the func_laser itthis instead of
+ // from the activator -- iw
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+
+ setorigin (this, '0 0 9000');
+ this.spawnflags = this.spawnflags + LASER_START_OFF;
+
+ if (activator.classtype == CT_PLAYER &&
+ this.message2 != "")
+ {
+ centerprint (activator, this.message2);
+ }
+ }
+ };

- if (self.spawnflags & LASER_SOLID)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // so you can shoot between lasers in a single bmodel
- self.solid = SOLID_BSP;
- // required becuase of SOLID_BSP
- self.movetype = MOVETYPE_PUSH;
- }
- else
+ local entity helper;
+
+ setmodel (this, this.model);
+
+ precache_sound ("buttons/switch02.wav");
+ precache_sound ("buttons/switch04.wav");
+
+ if (this.spawnflags & LASER_SOLID)
+ {
+ // so you can shoot between lasers in a single bmodel
+ this.solid = SOLID_BSP;
+ // required becuase of SOLID_BSP
+ this.movetype = MOVETYPE_PUSH;
+ }
+ else
+ {
+ this.solid = SOLID_TRIGGER;
+ this.movetype = MOVETYPE_NONE;
+ }
+
+ if (!this.alpha)
+ this.alpha = 0.5;
+
+ if (!this.dmg)
+ this.dmg = 1;
+
+ if (this.spawnflags & LASER_START_OFF)
+ setorigin (this, '0 0 9000');
+
+ if (this.noise != "")
+ precache_sound (this.noise);
+ else
+ this.noise = "buttons/switch02.wav";
+
+ if (this.noise1 != "")
+ precache_sound (this.noise1);
+ else
+ this.noise1 = "buttons/switch04.wav";
+
+ // spawn a second entity to handle alpha changes, since
+ // MOVETYPE_PUSH doesn't support think functions
+ helper = spawn (temp_laser_helper, alpha: this.alpha,
+ owner: this);
+ };
+
+ //--------------------------------------------------------------
+ void() func_laser =
{
- self.solid = SOLID_TRIGGER;
- self.movetype = MOVETYPE_NONE;
- }
-
- if (!self.alpha)
- self.alpha = 0.5;
-
- if (!self.dmg)
- self.dmg = 1;
-
- self.use = func_laser_use;
- self.touch = func_laser_touch;
-
- if (self.spawnflags & LASER_START_OFF)
- setorigin (self, '0 0 9000');
-
- if (self.noise != "")
- precache_sound (self.noise);
- else
- self.noise = "buttons/switch02.wav";
-
- if (self.noise1 != "")
- precache_sound (self.noise1);
- else
- self.noise1 = "buttons/switch04.wav";
-
- // spawn a second entity to handle alpha changes, since
- // MOVETYPE_PUSH doesn't support think functions
- helper = spawn ();
- helper.alpha = self.alpha;
- helper.owner = self;
- helper.nextthink = 0.05;
- helper.think = laser_helper_think;
+ this.classtype = CT_FUNC_LASER;
+ };
};

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

Diff qc/func/monster_spawner.qc

diff --git a/qc/func/monster_spawner.qc b/qc/func/monster_spawner.qc
index 4a4958a..2e48b52 100644
--- a/qc/func/monster_spawner.qc
+++ b/qc/func/monster_spawner.qc
@@ -17,549 +17,560 @@ const float MOBOT_DONT_SPAWN_ANGRY = 2;
const float MOBOT_DONT_ADD_KILL_COUNT = 4;
const float MOBOT_SILENT_SPAWN = 32;

-//----------------------------------------------------------------------
-// MobotSpawnPoint -- Returns the entity to spawn at
-//----------------------------------------------------------------------
-entity() MobotSpawnPoint =
-{
- local entity spot;
+/*QUAKED func_monster_spawner (.75 0 .75) (-8 -8 -8) (8 8 8) REUSABLE 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
+Spawns monsters to targeted info_monster_spawnpoint
+bot
+Choose Style
+• 1 (Dog (Default)
+• 2 (Grunt)
+• 3 (Enforcer)
+• 4 (Ogre)
+• 5 (Fiend)
+• 6 (Wizard)
+• 7 (Shambler)
+• 8 (Knight)
+• 9 (HellKnight)
+• 10 (Spawn)
+• 11 (Zombie)
+• 12 (Shalrath)

- // spot = find (world, classname, "info_monster_spawnpoint");
- spot = find (world, targetname, self.target);
+Style 2 set to 1 overrides Style and chooses a random monster (excluding Zombies and Vores)

- if (!spot)
- objerror ("couldn't find target");
+Default time between spawns is 5 seconds; 12 for Zombies and Vores to reduce telefrags

- return spot;
-};
+Can set Berserk to 1 to skip most pain animations.

-//----------------------------------------------------------------------
-void() create_mobot =
+Can only use default health, models and sounds.
+*/
+class func_monster_spawner: base_func
{
- local entity bot, spawn_spot;
-
- // start entity and place it in world
- bot = spawn ();
- spawn_spot = MobotSpawnPoint ();
- // let's not use deathmatch points for this -- dumptruck_ds
- // spawn_spot = SelectSpawnPoint ();
- bot.origin = spawn_spot.origin + '0 0 1';
- bot.angles = spawn_spot.angles;
- bot.fixangle = TRUE;
- bot.proj_speed_mod = 1;
-
- if (!(self.spawnflags & MOBOT_SILENT_SPAWN))
- // SILENT
- spawn_tfog (bot.origin);
- spawn_tdeath (bot.origin, bot);
-
- if (self.style == 1)
+
+ //--------------------------------------------------------------
+ // find_spawnpoint -- Returns the entity to spawn at; was named
+ // MobotSpawnPoint
+ //--------------------------------------------------------------
+ nonvirtual entity() find_spawnpoint =
{
- // spawn a Doggo
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/dog.mdl");
- setsize (bot, '-32 -32 -24', '32 32 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = dog_stand1;
- bot.th_walk = dog_walk1;
- bot.th_run = dog_run1;
- bot.th_die = dog_die;
- bot.th_melee = dog_atta1;
- bot.th_missile = dog_leap1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = dog_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 25;
+ local entity spot;

- // polish him up
- bot.classname = "monster_dog";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ // spot = find (world, ::classname, "info_monster_spawnpoint");
+ spot = find (world, ::targetname, this.target);

- if (self.style == 2)
- {
- // spawn a Grunt
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/soldier.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = army_stand1;
- bot.th_walk = army_walk1;
- bot.th_run = army_run1;
- bot.th_die = army_die;
- // bot.th_melee = ogre_melee;
- bot.th_missile = army_atk1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = army_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
+ if (!spot)
+ objerror ("func_monster_spawner::find_spawnpoint: "
+ "couldn't find target!\n");

- // polish him up
- bot.classname = "monster_army";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ return spot;
+ };

- if (self.style == 3)
+ //--------------------------------------------------------------
+ nonvirtual void() create_mobot =
{
- // spawn an Enforcer
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/enforcer.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = enf_stand1;
- bot.th_walk = enf_walk1;
- bot.th_run = enf_run1;
- bot.th_die = enf_die;
- // bot.th_melee = ogre_melee;
- bot.th_missile = enf_atk1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = enf_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
+ local entity bot, spawn_spot;
+
+ // start entity and place it in world
+ bot = spawn ();
+ spawn_spot = find_spawnpoint ();
+ // let's not use deathmatch points for this -- dumptruck_ds
+ // spawn_spot = SelectSpawnPoint ();
+ bot.origin = spawn_spot.origin + '0 0 1';
+ bot.angles = spawn_spot.angles;
+ bot.fixangle = TRUE;
+ bot.proj_speed_mod = 1;
+
+ if (!(this.spawnflags & MOBOT_SILENT_SPAWN))
+ // SILENT
+ spawn_tfog (bot.origin);
+ spawn_tdeath (bot.origin, bot);
+
+ if (this.style == 1)
+ {
+ // spawn a Doggo
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/dog.mdl");
+ setsize (bot, '-32 -32 -24', '32 32 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = dog_stand1;
+ bot.th_walk = dog_walk1;
+ bot.th_run = dog_run1;
+ bot.th_die = dog_die;
+ bot.th_melee = dog_atta1;
+ bot.th_missile = dog_leap1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = dog_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 25;
+
+ // polish him up
+ bot.classname = "monster_dog";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- // polish him up
- bot.classname = "monster_enforcer";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ if (this.style == 2)
+ {
+ // spawn a Grunt
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/soldier.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = army_stand1;
+ bot.th_walk = army_walk1;
+ bot.th_run = army_run1;
+ bot.th_die = army_die;
+ // bot.th_melee = ogre_melee;
+ bot.th_missile = army_atk1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = army_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_army";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- if (self.style == 4)
- {
- // spawn an Ogre
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/ogre.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = ogre_stand1;
- bot.th_walk = ogre_walk1;
- bot.th_run = ogre_run1;
- bot.th_die = ogre_die;
- bot.th_melee = ogre_melee;
- bot.th_missile = ogre_nail1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = ogre_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 200;
+ if (this.style == 3)
+ {
+ // spawn an Enforcer
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/enforcer.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = enf_stand1;
+ bot.th_walk = enf_walk1;
+ bot.th_run = enf_run1;
+ bot.th_die = enf_die;
+ // bot.th_melee = ogre_melee;
+ bot.th_missile = enf_atk1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = enf_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_enforcer";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- // polish him up
- bot.classname = "monster_ogre";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ if (this.style == 4)
+ {
+ // spawn an Ogre
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/ogre.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = ogre_stand1;
+ bot.th_walk = ogre_walk1;
+ bot.th_run = ogre_run1;
+ bot.th_die = ogre_die;
+ bot.th_melee = ogre_melee;
+ bot.th_missile = ogre_nail1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = ogre_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 200;
+
+ // polish him up
+ bot.classname = "monster_ogre";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- if (self.style == 5)
- {
- // spawn an Fiend
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/demon.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = demon1_stand1;
- bot.th_walk = demon1_walk1;
- bot.th_run = demon1_run1;
- bot.th_die = demon_die;
- // one of two attacks
- bot.th_melee = Demon_MeleeAttack;
- // jump attack
- bot.th_missile = demon1_jump1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = demon1_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 300;
+ if (this.style == 5)
+ {
+ // spawn an Fiend
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/demon.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = demon1_stand1;
+ bot.th_walk = demon1_walk1;
+ bot.th_run = demon1_run1;
+ bot.th_die = demon_die;
+ // one of two attacks
+ bot.th_melee = Demon_MeleeAttack;
+ // jump attack
+ bot.th_missile = demon1_jump1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = demon1_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 300;
+
+ // polish him up
+ bot.classname = "monster_demon1";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- // polish him up
- bot.classname = "monster_demon1";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ if (this.style == 6)
+ {
+ // spawn a Wizard / Scrag
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/wizard.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_FLY;
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = wiz_stand1;
+ bot.th_walk = wiz_walk1;
+ bot.th_run = wiz_run1;
+ bot.th_die = wiz_die;
+ bot.th_missile = Wiz_Missile;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = Wiz_Pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 80;
+
+ // polish him up
+ bot.classname = "monster_wizard";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ bot.mdl_proj = "progs/w_spike.mdl";
+ }

- if (self.style == 6)
- {
- // spawn a Wizard / Scrag
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/wizard.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_FLY;
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = wiz_stand1;
- bot.th_walk = wiz_walk1;
- bot.th_run = wiz_run1;
- bot.th_die = wiz_die;
- bot.th_missile = Wiz_Missile;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = Wiz_Pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 80;
-
- // polish him up
- bot.classname = "monster_wizard";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- bot.mdl_proj = "progs/w_spike.mdl";
- }
-
- if (self.style == 7)
- {
- // spawn a Shambler
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/shambler.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = sham_stand1;
- bot.th_walk = sham_walk1;
- bot.th_run = sham_run1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = sham_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.th_die = sham_die;
- bot.th_missile = sham_magic1;
- bot.th_melee = sham_melee;
- bot.health = 600;
-
- // polish him up
- bot.classname = "monster_shambler";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 2';
- // bot.view_ofs = '0 0 22';
- }
-
- if (self.style == 8)
- {
- // spawn a Knight
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/knight.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = knight_stand1;
- bot.th_walk = knight_walk1;
- bot.th_run = knight_run1;
- bot.th_die = knight_die;
- bot.th_melee = knight_atk1;
- // bot.th_missile = knight_atk1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = knight_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 75;
+ if (this.style == 7)
+ {
+ // spawn a Shambler
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/shambler.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = sham_stand1;
+ bot.th_walk = sham_walk1;
+ bot.th_run = sham_run1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = sham_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.th_die = sham_die;
+ bot.th_missile = sham_magic1;
+ bot.th_melee = sham_melee;
+ bot.health = 600;
+
+ // polish him up
+ bot.classname = "monster_shambler";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 2';
+ // bot.view_ofs = '0 0 22';
+ }
+
+ if (this.style == 8)
+ {
+ // spawn a Knight
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/knight.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = knight_stand1;
+ bot.th_walk = knight_walk1;
+ bot.th_run = knight_run1;
+ bot.th_die = knight_die;
+ bot.th_melee = knight_atk1;
+ // bot.th_missile = knight_atk1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = knight_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 75;
+
+ // polish him up
+ bot.classname = "monster_knight";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- // polish him up
- bot.classname = "monster_knight";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ if (this.style == 9)
+ {
+ // spawn a HellKnight
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/hknight.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = hknight_stand1;
+ bot.th_walk = hknight_walk1;
+ bot.th_run = hknight_run1;
+ bot.th_melee = hknight_melee;
+ bot.th_die = hknight_die;
+ bot.th_missile = hknight_magicc1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = hknight_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 250;
+
+ // polish him up
+ bot.classname = "monster_hell_knight";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- if (self.style == 9)
- {
- // spawn a HellKnight
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/hknight.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = hknight_stand1;
- bot.th_walk = hknight_walk1;
- bot.th_run = hknight_run1;
- bot.th_melee = hknight_melee;
- bot.th_die = hknight_die;
- bot.th_missile = hknight_magicc1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = hknight_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 250;
+ if (this.style == 11)
+ {
+ // spawn a Zombie
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/zombie.mdl");
+ setsize (bot, '-16 -16 -24', '16 16 40');
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = zombie_start;
+ bot.th_walk = zombie_walk1;
+ bot.th_run = zombie_decide;
+ bot.th_pain = zombie_pain;
+ bot.th_die = zombie_die;
+ bot.th_missile = zombie_missile;
+ bot.health = 61;
+
+ // polish him up
+ bot.classname = "monster_zombie";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 2';
+ // bot.view_ofs = '0 0 22';
+ }

- // polish him up
- bot.classname = "monster_hell_knight";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
+ if (this.style == 12)
+ {
+ // spawn a Shalrath
+ // set size and shape
+ bot.solid = SOLID_SLIDEBOX;
+ bot.movetype = MOVETYPE_STEP;
+ setmodel (bot, "progs/shalrath.mdl");
+ setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
+ bot.flags = bot.flags | FL_MONSTER;
+ bot.takedamage = DAMAGE_AIM;
+
+ // define his animation
+ bot.th_stand = shal_stand;
+ bot.th_walk = shal_walk1;
+ bot.th_run = shal_run1;
+ bot.th_die = shalrath_die;
+ bot.th_missile = shal_attack1;
+ // fix for func_monster_spawner setting Voreballs
+ // to non-homing
+ bot.homing = 1;
+ // Berserk test from
+ // celephais.net/board/view_thread.php?id=4&start=3465
+ // -- dumptruck_ds
+ if !(this.berserk)
+ bot.th_pain = shalrath_pain;
+ else
+ bot.th_pain = sub_nullpain;
+ bot.health = 400;
+
+ // polish him up
+ bot.classname = "monster_shalrath";
+ bot.ideal_yaw = bot.angles * '0 1 0';
+ bot.yaw_speed = 120;
+ bot.view_ofs = '0 0 22';
+ }

- if (self.style == 11)
- {
- // spawn a Zombie
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/zombie.mdl");
- setsize (bot, '-16 -16 -24', '16 16 40');
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = zombie_start;
- bot.th_walk = zombie_walk1;
- bot.th_run = zombie_decide;
- bot.th_pain = zombie_pain;
- bot.th_die = zombie_die;
- bot.th_missile = zombie_missile;
- bot.health = 61;
-
- // polish him up
- bot.classname = "monster_zombie";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 2';
- // bot.view_ofs = '0 0 22';
- }
-
- if (self.style == 12)
- {
- // spawn a Shalrath
- // set size and shape
- bot.solid = SOLID_SLIDEBOX;
- bot.movetype = MOVETYPE_STEP;
- setmodel (bot, "progs/shalrath.mdl");
- setsize (bot, VEC_HULL2_MIN, VEC_HULL2_MAX);
- bot.flags = bot.flags | FL_MONSTER;
- bot.takedamage = DAMAGE_AIM;
-
- // define his animation
- bot.th_stand = shal_stand;
- bot.th_walk = shal_walk1;
- bot.th_run = shal_run1;
- bot.th_die = shalrath_die;
- bot.th_missile = shal_attack1;
- // fix for func_monster_spawner setting Voreballs to non-homing
- bot.homing = 1;
- // Berserk test from
- // http://celephais.net/board/view_thread.php?id=4&start=3465
- // -- dumptruck_ds
- if !(self.berserk)
- bot.th_pain = shalrath_pain;
- else
- bot.th_pain = SUB_NullPain;
- bot.health = 400;
-
- // polish him up
- bot.classname = "monster_shalrath";
- bot.ideal_yaw = bot.angles * '0 1 0';
- bot.yaw_speed = 120;
- bot.view_ofs = '0 0 22';
- }
-
- // begin his thinking
- // this seems better with monster_use -- dumptruck_ds
- bot.nextthink = time + 0.2;
- // bot.nextthink = time + 0.1 + random();
- if (!(self.spawnflags & MOBOT_DONT_SPAWN_ANGRY))
- {
- // required to avoid animation issues -- dumptruck_ds
- if (bot.classname != "monster_zombie")
- bot.think = monster_use;
+ // begin his thinking
+ // this seems better with monster_use -- dumptruck_ds
+ bot.nextthink = time + 0.2;
+ // bot.nextthink = time + 0.1 + random();
+ if (!(this.spawnflags & MOBOT_DONT_SPAWN_ANGRY))
+ {
+ // required to avoid animation issues -- dumptruck_ds
+ if (bot.classname != "monster_zombie")
+ bot.think = monster_use;
+ else
+ bot.think = bot.th_walk;
+ }
else
- bot.think = bot.th_walk;
- }
- else
- {
- bot.think = walkmonster_start_go;
- }
+ {
+ bot.think = walkmonster_start_go;
+ }

- if (!(self.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
- {
- // repacement function from iw -- dumptruck_ds
- monster_update_total (1);
- }
-};
+ if (!(this.spawnflags & MOBOT_DONT_ADD_KILL_COUNT))
+ {
+ // repacement function from iw -- dumptruck_ds
+ monster_update_total (1);
+ }
+ };

-//----------------------------------------------------------------------
-void() think_mobot =
-{
- dprint ("mobot thinking\n");
- // telefrag check thanks to ryanscissorhands for this code!
- // -- dumptruck_ds
- local entity nearby;
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ dprint ("mobot thinking\n");
+ // telefrag check thanks to ryanscissorhands for this code!
+ // -- dumptruck_ds
+ local entity nearby;

- // findradius (vector origin, float radius in Quake units)
- nearby = findradius (self.origin, 128);
+ // findradius (vector origin, float radius in Quake units)
+ nearby = findradius (this.origin, 128);

- while (nearby)
- {
- if (nearby.takedamage)
+ while (nearby)
{
- dprint ("monster waiting to spawn\n");
- // qss crash fix from paavohuhtala -- dumptruck_ds
- self.think = think_mobot;
- // delay the spawn by some amount;
- self.nextthink = time + 1;
- return;
+ if (nearby.takedamage)
+ {
+ dprint ("monster waiting to spawn\n");
+ // qss crash fix from paavohuhtala
+ // -- dumptruck_ds
+ // delay the spawn by some amount;
+ this.nextthink = time + 1;
+ return;
+ }
+ nearby = nearby.chain;
}
- nearby = nearby.chain;
- }
-
- self.count = self.count - 1;

- if (self.count < 0)
- return;
+ this.count = this.count - 1;

- if (self.count!=0)
- {
- if !(self.wait)
- self.nextthink = time + 5;
- else
- self.nextthink = time + self.wait;
+ if (this.count < 0)
+ return;

- if (self.style2 == 1)
+ if (this.count != 0)
{
- // random monster!! -- dumptruck_ds
- self.style = floor (random() * 12) + 1;
- // thanks whirledtsar for your help on this
- // -- dumptruck_ds
- create_mobot ();
+ if !(this.wait)
+ this.nextthink = time + 5;
+ else
+ this.nextthink = time + this.wait;
+
+ if (this.style2 == 1)
+ {
+ // random monster!! -- dumptruck_ds
+ this.style = floor (random() * 12) + 1;
+ // thanks whirledtsar for your help on this
+ // -- dumptruck_ds
+ create_mobot ();
+ }
+ else
+ {
+ create_mobot ();
+ }
}
else
{
- create_mobot ();
- }
- }
- else
- {
- if (self.spawnflags & MOBOT_SPAWNER_RESET)
- {
- self.count = self.cnt;
- self.think = SUB_Null;
+ if (this.spawnflags & MOBOT_SPAWNER_RESET)
+ {
+ this.count = this.cnt;
+ this.interaction_flags |= DISABLE_THINK;
+ }
}
- }
-
- // qthink I didn't realize I could do this! -- dumptruck_ds
- self.think = think_mobot;
-};
-
-/*QUAKED func_monster_spawner (.75 0 .75) (-8 -8 -8) (8 8 8) REUSABLE 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
-Spawns monsters to targeted info_monster_spawnpoint
-bot
-Choose Style
-• 1 (Dog (Default)
-• 2 (Grunt)
-• 3 (Enforcer)
-• 4 (Ogre)
-• 5 (Fiend)
-• 6 (Wizard)
-• 7 (Shambler)
-• 8 (Knight)
-• 9 (HellKnight)
-• 10 (Spawn)
-• 11 (Zombie)
-• 12 (Shalrath)
+ };

-Style 2 set to 1 overrides Style and chooses a random monster (excluding Zombies and Vores)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ this.do_think (caller);
+ };

-Default time between spawns is 5 seconds; 12 for Zombies and Vores to reduce telefrags
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if !(this.target)
+ {
+ objerror ("func_monster_spawner needs a target");
+ remove (this);
+ return;
+ }

-Can set Berserk to 1 to skip most pain animations.
+ if !(this.style)
+ this.style = 1;

-Can only use default health, models and sounds.
-*/
-void() func_monster_spawner =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ if (!this.count)
+ this.count = 5;
+ // fixes count display
+ this.count = this.count + 1;
+ // hold original count
+ this.cnt = this.count;
+ };

- if !(self.target)
+ //--------------------------------------------------------------
+ void() func_monster_spawner =
{
- objerror ("func_monster_spawner needs a target");
- remove (self);
- return;
- }
-
- if !(self.style)
- self.style = 1;
-
- if (!self.count)
- self.count = 5;
- // fixes count display
- self.count = self.count + 1;
- // hold original count
- self.cnt = self.count;
-
- self.use = think_mobot;
+ this.classtype = CT_FUNC_MONSTER_SPAWNER;
+ };
};

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

Diff qc/func/new_plat.qc

diff --git a/qc/func/new_plat.qc b/qc/func/new_plat.qc
index 31b817d..4974ad6 100644
--- a/qc/func/new_plat.qc
+++ b/qc/func/new_plat.qc
@@ -7,679 +7,765 @@
// september 1996

// constants / TYPES
-const float DN_N_WAIT = 1;
-const float PLT_TOGGLE = 2;
-const float ELEVATOR = 4;
-const float START_AT_TOP = 8;
-const float PLAT2 = 16;
-const float PLAT2_BOTTOM = 32;
-
-// globals
-float elv_butn_dir;
-
-//======================================================================
-// down N and wait code
-//======================================================================
-
-// prototypes
-void() dn_and_wait_go_up;
-void() dn_and_wait_go_down;
-void() dn_and_wait_crush;
-
-//----------------------------------------------------------------------
-void() dn_and_wait_hit_top =
+const float NEWPLAT_DN_N_WAIT = 1;
+const float NEWPLAT_PLT_TOGGLE = 2;
+const float NEWPLAT_ELEVATOR = 4;
+const float NEWPLAT_START_AT_TOP = 8;
+const float NEWPLAT_PLAT2 = 16;
+const float NEWPLAT_PLAT2_BOTTOM = 32;
+
+//------------------------------------------------------------------------------
+class temp_newplat_trigger: base_tempentity
{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
-};
-
-//----------------------------------------------------------------------
-void() dn_and_wait_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
- self.think = dn_and_wait_go_up;
- self.nextthink = self.ltime + self.health;
-};
-
-//----------------------------------------------------------------------
-void() dn_and_wait_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, dn_and_wait_hit_bottom);
-};
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ local float otherState;
+ local vector platPosition;

-//----------------------------------------------------------------------
-void() dn_and_wait_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, dn_and_wait_hit_top);
-};
+ // from Copper -- dumptruck_ds
+ if (sub_checkvalidtouch(toucher) == FALSE)
+ return;

-//----------------------------------------------------------------------
-void() dn_and_wait_crush =
-{
- T_Damage (other, self, self, 1);
+ if (this.enemy.classtype != CT_FUNC_NEW_PLAT)
+ return;
+
+ // at this point "this" is the trigger, "this.enemy" is
+ // the plat, and "toucher" is the player.

- if (self.state == STATE_UP)
- dn_and_wait_go_down ();
- else if (self.state == STATE_DOWN)
- dn_and_wait_go_up ();
- else
- objerror ("plat_new_crush: bad self.state\n");
-};
+ // cast enemy to func_new_plat -- CEV
+ local func_new_plat fp = (func_new_plat)this.enemy;

-//----------------------------------------------------------------------
-void() dn_and_wait_use =
-{
- if (self.state != STATE_TOP)
- return;
-
- dn_and_wait_go_down ();
-};
+ if ((fp.plat2LastMove + 2) > time)
+ return;

-//======================================================================
-// toggle type code
-//======================================================================
+ if (fp.state > 4)
+ // disabled.
+ return;

-// prototypes
-void() toggle_go_up;
-void() toggle_go_down;
-void() toggle_crush;
+ if (fp.plat2GoTo > FUNC_STATE_BOTTOM)
+ {
+ if (fp.plat2GoTime < time)
+ {
+ if (fp.plat2GoTo == FUNC_STATE_UP)
+ fp.plat2_go_up ();
+ else
+ fp.plat2_go_down ();
+
+ fp.plat2GoTo = 0;
+ }
+ return;
+ }

-//----------------------------------------------------------------------
-void() toggle_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
-};
+ if (fp.state > FUNC_STATE_BOTTOM)
+ // STATE_UP or STATE_DOWN
+ return;

-//----------------------------------------------------------------------
-void() toggle_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
+ platPosition = (fp.absmax + fp.absmin) * 0.5;

-//----------------------------------------------------------------------
-void() toggle_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, toggle_hit_bottom);
-};
+ if (fp.state == FUNC_STATE_TOP)
+ {
+ otherState = FUNC_STATE_TOP;
+ if (platPosition_z > toucher.origin_z)
+ otherState = FUNC_STATE_BOTTOM;
+ }
+ else
+ {
+ otherState = FUNC_STATE_BOTTOM;
+ if ((toucher.origin_z - platPosition_z) > fp.height)
+ otherState = FUNC_STATE_TOP;
+ }

-//----------------------------------------------------------------------
-void() toggle_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, toggle_hit_top);
-};
+ if (fp.state == otherState)
+ {
+ fp.plat2Called = 0;
+ fp.plat2GoTime = time + 0.5;
+ }
+ else
+ {
+ fp.plat2GoTime = time + 0.1;
+ fp.plat2Called = 1;
+ }

-//----------------------------------------------------------------------
-void() toggle_crush =
-{
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- toggle_go_down ();
- else if (self.state == STATE_DOWN)
- toggle_go_up ();
- else
- objerror ("plat_new_crush: bad self.state\n");
-};
+ if (fp.state == FUNC_STATE_BOTTOM)
+ fp.plat2GoTo = FUNC_STATE_UP;
+ else if (fp.state == FUNC_STATE_TOP)
+ fp.plat2GoTo = FUNC_STATE_DOWN;
+ };

-//----------------------------------------------------------------------
-void() toggle_use =
-{
- if (self.state == STATE_TOP)
- toggle_go_down ();
- else if (self.state == STATE_BOTTOM)
- toggle_go_up ();
+ //--------------------------------------------------------------
+ void() temp_newplat_trigger =
+ {
+ this.classtype = CT_TEMP_NEWPLAT_TRIGGER;
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_TRIGGER;
+ };
};

-//======================================================================
-// elvtr type code
-//======================================================================
-
-// prototypes
-void() elvtr_crush;
+/*QUAKED func_new_plat (0 .5 .8) ? DN_N_WAIT PLT_TOGGLE ELEVATOR START_AT_TOP PLAT2 P2_BOTTOM X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY

-//----------------------------------------------------------------------
-void() elvtr_stop =
-{
- self.elevatorOnFloor = self.elevatorToFloor;
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
- self.elevatorLastUse = time;
-};
+--------------
+DN_N_WAIT is a plat that starts at the top and when triggered, goes down, waits, then comes back up.
+health - number of seconds to wait (default 5)
+--------------
+PLT_TOGGLE is a plat that will change between the top and bottom each time it is triggered.
+--------------
+ELEVATOR is an elevator plat. You can have as many levels as you want but they must be all the same distance away. Use elevator button entity as the trigger.
+cnt is the number of floors
+height is the distance between floors
+wait is the number of seconds before the elevator can be activated again after starting or stopping (default 0)

-//----------------------------------------------------------------------
-void() elvtr_go =
-{
- self.elevatorDestination = self.pos2;
- self.elevatorDestination_z = self.pos2_z +
- (self.height * self.elevatorToFloor);
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.elevatorDestination, self.speed, elvtr_stop);
- self.elevatorLastUse = time;
-};
+START_AT_TOP is an optional flag for elevators. It just tells the elevator that it's position is the top floor. (Default is the bottom floor) USE THIS ONLY WITH ELEVATORS!
+-------------
+PLAT2 is a fixed version of the original plat. If you want the plat to start at the bottom and move to the top on demand, use a negative height. That will tell Quake to lower the plat at spawn time. Always place this plat type in the top position when making the map. This will ensure correct lighting, hopefully. If a plat2 is the target of a trigger, it will be disabled until it has been triggered. Delay is the wait before the plat returns to original position.

-//----------------------------------------------------------------------
-void() elvtr_crush =
-{
- local float tmp;
+If you don't want to bother figuring out the height, don't put a
+value in the height

- // T_Damage (other, self, self, 1);
+delay default 3
+speed default 150
+cnt default 2

- // the elevator is changing direction, so swap the floor it's coming
- // from and the floor it's going to -- iw
- tmp = self.elevatorOnFloor;
- self.elevatorOnFloor = self.elevatorToFloor;
- self.elevatorToFloor = tmp;
+P2_BOTTOM is an optional switch to have an auto-sized plat2 start at the bottom.
+--------------
+Plats are always drawn in the extended position, so they will light correctly.

- elvtr_go ();
-};
+If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.

-//----------------------------------------------------------------------
-// elvtr_use -- elevator use function
-// self = plat, other = elevator button, other.enemy = player
-//----------------------------------------------------------------------
-void() elvtr_use =
+If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
+Set "sounds" to one of the following:
+1) base fast
+2) chain slow
+*/
+class func_new_plat: base_func
{
- local float tempDist, elvPos, btnPos;
-
- // the original DoE code allowed an elevator to be activated again
- // when it was in the process of moving between floors (assuming the
- // wait period was over); this resulted in sometimes unintuitive
- // behavior, so, the following test prevents this -- iw
- if (self.elevatorToFloor != self.elevatorOnFloor)
- return;
-
- // the original DoE code had a hard-coded two second wait period;
- // this has been changed for progs_dump so that self.wait is used
- // instead -- iw
- if ((self.elevatorLastUse + self.wait) > time)
- return;
-
- self.elevatorLastUse = time;
+ // class fields for progs_dump plat2 (& Rogue multifloor elevator)
+ float plat2Called;
+ float plat2LastMove;
+ float plat2GoTime;
+ float plat2GoTo;
+ float elevatorLastUse;
+ float elevatorOnFloor;
+ float elevatorToFloor;
+
+ vector pos_top;
+ vector pos_bottom;
+
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };

- if (elv_butn_dir == 0)
- return;
+ //==============================================================
+ // down N and wait code
+ //==============================================================

- elvPos = (self.absmin_z + self.absmax_z) * 0.5;
- btnPos = (other.absmin_z + other.absmax_z) * 0.5;
+ //--------------------------------------------------------------
+ nonvirtual void() dn_and_wait_hit_top =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_TOP;
+ };

- if (elvPos > btnPos)
+ //--------------------------------------------------------------
+ nonvirtual void() dn_and_wait_hit_bottom =
{
- tempDist = (elvPos - btnPos) / self.height;
- tempDist = ceil (tempDist);
- self.elevatorToFloor = self.elevatorOnFloor - tempDist;
- elvtr_go ();
- return;
- }
- else
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;
+ this.nextthink = this.ltime + this.health;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() dn_and_wait_go_down =
{
- tempDist = btnPos - elvPos;
- if (tempDist > self.height)
- {
- tempDist = tempDist / self.height;
- tempDist = floor (tempDist);
- self.elevatorToFloor = self.elevatorOnFloor + tempDist;
- elvtr_go ();
- return;
- }
- }
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos2, this.speed, dn_and_wait_hit_bottom);
+ };

- if (elv_butn_dir == -1)
+ //--------------------------------------------------------------
+ nonvirtual void() dn_and_wait_go_up =
{
- if (self.elevatorOnFloor > 0)
- {
- self.elevatorToFloor = self.elevatorOnFloor - 1;
- elvtr_go ();
- }
- }
- else if (elv_butn_dir == 1)
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos1, this.speed, dn_and_wait_hit_top);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(entity blocker) dn_and_wait_crush =
{
- if (self.elevatorOnFloor < (self.cnt - 1))
- {
- self.elevatorToFloor = self.elevatorOnFloor + 1;
- elvtr_go ();
- }
- }
-};
+ T_Damage (blocker, this, this, 1);

-//======================================================================
-// PLAT2 type code
-//======================================================================
+ if (this.state == FUNC_STATE_UP)
+ dn_and_wait_go_down ();
+ else if (this.state == FUNC_STATE_DOWN)
+ dn_and_wait_go_up ();
+ else
+ objerror ("plat_new_crush: bad this.state\n");
+ };

-// prototypes
-void() plat2_center_touch;
-void() plat2_go_up;
-void() plat2_go_down;
-void() plat2_crush;
+ //--------------------------------------------------------------
+ nonvirtual void() dn_and_wait_use =
+ {
+ if (this.state != FUNC_STATE_TOP)
+ return;

-//----------------------------------------------------------------------
-void() plat2_spawn_inside_trigger =
-{
- local entity trigger;
- local vector tmin, tmax;
+ dn_and_wait_go_down ();
+ };

- // middle trigger
- trigger = spawn ();
- trigger.touch = plat2_center_touch;
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.enemy = self;
+ //==============================================================
+ // toggle type code
+ //==============================================================

- tmin = self.mins + '25 25 0';
- tmax = self.maxs - '25 25 -8';
- tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
+ //--------------------------------------------------------------
+ nonvirtual void() toggle_hit_top =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_TOP;
+ };

- if (self.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
+ //--------------------------------------------------------------
+ nonvirtual void() toggle_hit_bottom =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;
+ };

- if (self.size_x <= 50)
+ //--------------------------------------------------------------
+ nonvirtual void() toggle_go_down =
{
- tmin_x = (self.mins_x + self.maxs_x) / 2;
- tmax_x = tmin_x + 1;
- }
- if (self.size_y <= 50)
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos2, this.speed, toggle_hit_bottom);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() toggle_go_up =
{
- tmin_y = (self.mins_y + self.maxs_y) / 2;
- tmax_y = tmin_y + 1;
- }
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos1, this.speed, toggle_hit_top);
+ };

- setsize (trigger, tmin, tmax);
-};
+ //--------------------------------------------------------------
+ nonvirtual void(entity blocker) toggle_crush =
+ {
+ T_Damage (blocker, this, this, 1);

-//----------------------------------------------------------------------
-void() plat2_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
+ if (this.state == FUNC_STATE_UP)
+ toggle_go_down ();
+ else if (this.state == FUNC_STATE_DOWN)
+ toggle_go_up ();
+ else
+ objerror ("plat_new_crush: bad this.state\n");
+ };

- self.plat2LastMove = time;
- if (self.plat2Called == 1)
+ //--------------------------------------------------------------
+ nonvirtual void() toggle_use =
{
- self.think = plat2_go_down;
- self.nextthink = self.ltime + 1.5;
- self.plat2Called = 0;
- // allow immediate move
- self.plat2LastMove = 0;
- }
- else if (!(self.spawnflags & START_AT_TOP))
+ if (this.state == FUNC_STATE_TOP)
+ toggle_go_down ();
+ else if (this.state == FUNC_STATE_BOTTOM)
+ toggle_go_up ();
+ };
+
+ //==============================================================
+ // elvtr type code
+ //==============================================================
+
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_stop =
{
- self.think = plat2_go_down;
- self.nextthink = self.ltime + self.delay;
- self.plat2Called = 0;
- }
-};
-
-//----------------------------------------------------------------------
-void() plat2_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-
- self.plat2LastMove = time;
- if (self.plat2Called == 1)
+ this.elevatorOnFloor = this.elevatorToFloor;
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;
+ this.elevatorLastUse = time;
+ /*
+ // a messy testing print -- CEV
+ dprint (sprintf("func_new_plat: elvtr_stop, origin: %v\n",
+ this.origin));
+ */
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() elvtr_go =
{
- self.think = plat2_go_up;
- self.nextthink = self.ltime + 1.5;
- self.plat2Called = 0;
- // allow immediate move
- self.plat2LastMove = 0;
- }
- else if (self.spawnflags & START_AT_TOP)
+ // another messy testing dprint -- CEV
+ /*
+ dprint (sprintf("elvtr_go: pos_bottom %v, pos_bottom_z %g, "
+ "origin %v, on floor %g, to floor %g\n",
+ this.pos_bottom,
+ this.pos_bottom_z,
+ this.origin,
+ this.elevatorOnFloor,
+ this.elevatorToFloor));
+ */
+
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+
+ // TODO CEV for some reason vector class fields are behaving
+ // weirdly here. Addressing x y and z directly works but
+ // reading from or assigning a whole vector doesn't. I'm
+ // using an in-place vector created from parts of pos_bottom
+ // below in place of the previous elevatorDestination vector
+ // for this reason. This is incredibly annoying. -- CEV
+ this.calc_move ([this.pos_bottom_x, this.pos_bottom_y,
+ this.pos_bottom_z +
+ (this.height * this.elevatorToFloor)],
+ this.speed, this.elvtr_stop);
+ this.elevatorLastUse = time;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(entity blocker) elvtr_crush =
{
- self.think = plat2_go_up;
- self.nextthink = self.ltime + self.delay;
- self.plat2Called = 0;
- }
-};
+ local float tmp;

-//----------------------------------------------------------------------
-void() plat2_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, plat2_hit_bottom);
-};
+ // T_Damage (other, this, this, 1);

-//----------------------------------------------------------------------
-void() plat2_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, plat2_hit_top);
-};
+ // the elevator is changing direction, so swap the floor
+ // it's coming from and the floor it's going to -- iw
+ tmp = this.elevatorOnFloor;
+ this.elevatorOnFloor = this.elevatorToFloor;
+ this.elevatorToFloor = tmp;

-//----------------------------------------------------------------------
-void() plat2_use =
-{
- if(self.state > 4)
- self.state = self.state - 10;
+ elvtr_go ();
+ };

- self.use = SUB_Null;
-};
+ //--------------------------------------------------------------
+ // elvtr_use -- elevator use function
+ // this = plat, other = elevator button, other.enemy = player
+ //--------------------------------------------------------------
+ nonvirtual void(entity button) elvtr_use =
+ {
+ // the original DoE code allowed an elevator to be activated
+ // again when it was in the process of moving between floors
+ // (assuming the wait period was over); this resulted in
+ // sometimes unintuitive behavior, so, the following test
+ // prevents this -- iw
+ if (this.elevatorToFloor != this.elevatorOnFloor)
+ return;

-//----------------------------------------------------------------------
-void() plat2_center_touch =
-{
- local float otherState;
- local vector platPosition;
+ // the original DoE code had a hard-coded two second wait
+ // period; this has been changed for progs_dump so that
+ // this.wait is used instead -- iw
+ if ((this.elevatorLastUse + this.wait) > time)
+ return;

- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
+ local float tempDist, elvPos, btnPos;

- // at this point, self is the trigger. self.enemy is the plat.
- // this changes self to be the plat, other is the player.
- self = self.enemy;
+ this.elevatorLastUse = time;

- if ((self.plat2LastMove + 2) > time)
- return;
+ if (elv_butn_dir == 0)
+ return;

- if (self.state > 4)
- // disabled.
- return;
+ elvPos = (this.absmin_z + this.absmax_z) * 0.5;
+ btnPos = (button.absmin_z + button.absmax_z) * 0.5;

- if (self.plat2GoTo > STATE_BOTTOM)
- {
- if (self.plat2GoTime < time)
+ if (elvPos > btnPos)
{
- if (self.plat2GoTo == STATE_UP)
- plat2_go_up ();
- else
- plat2_go_down ();
-
- self.plat2GoTo = 0;
+ tempDist = (elvPos - btnPos) / this.height;
+ tempDist = ceil (tempDist);
+ this.elevatorToFloor = this.elevatorOnFloor - tempDist;
+ elvtr_go ();
+ return;
+ }
+ else
+ {
+ tempDist = btnPos - elvPos;
+ if (tempDist > this.height)
+ {
+ tempDist = tempDist / this.height;
+ tempDist = floor (tempDist);
+ this.elevatorToFloor = this.elevatorOnFloor +
+ tempDist;
+ elvtr_go ();
+ return;
+ }
}
- return;
- }
-
- if (self.state > STATE_BOTTOM)
- // STATE_UP or STATE_DOWN
- return;

- platPosition = (self.absmax + self.absmin) * 0.5;
+ if (elv_butn_dir == -1)
+ {
+ if (this.elevatorOnFloor > 0)
+ {
+ this.elevatorToFloor = this.elevatorOnFloor - 1;
+ elvtr_go ();
+ }
+ }
+ else if (elv_butn_dir == 1)
+ {
+ if (this.elevatorOnFloor < (this.cnt - 1))
+ {
+ this.elevatorToFloor = this.elevatorOnFloor + 1;
+ elvtr_go ();
+ }
+ }
+ };

- if (self.state == STATE_TOP)
- {
- otherState = STATE_TOP;
- if (platPosition_z > other.origin_z)
- otherState = STATE_BOTTOM;
- }
- else
- {
- otherState = STATE_BOTTOM;
- if ((other.origin_z - platPosition_z) > self.height)
- otherState = STATE_TOP;
- }
+ //==============================================================
+ // PLAT2 type code
+ //==============================================================

- if (self.state == otherState)
- {
- self.plat2Called = 0;
- self.plat2GoTime = time + 0.5;
- }
- else
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_spawn_inside_trigger =
{
- self.plat2GoTime = time + 0.1;
- self.plat2Called = 1;
- }
-
- if (self.state == STATE_BOTTOM)
- self.plat2GoTo = STATE_UP;
- else if (self.state == STATE_TOP)
- self.plat2GoTo = STATE_DOWN;
-};
+ local temp_newplat_trigger trigger;
+ local vector tmin, tmax;

-//----------------------------------------------------------------------
-void() plat2_crush =
-{
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- plat2_go_down ();
- else if (self.state == STATE_DOWN)
- plat2_go_up ();
- else
- objerror ("plat2_crush: bad self.state\n");
-};
+ // middle trigger
+ trigger = spawn (temp_newplat_trigger, enemy: this);

-//======================================================================
-// Common Plat Code
-//======================================================================
+ tmin = this.mins + '25 25 0';
+ tmax = this.maxs - '25 25 -8';
+ tmin_z = tmax_z - (this.pos1_z - this.pos2_z + 8);

-/*QUAKED func_new_plat (0 .5 .8) ? DN_N_WAIT PLT_TOGGLE ELEVATOR START_AT_TOP PLAT2 P2_BOTTOM X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+ if (this.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;

+ if (this.size_x <= 50)
+ {
+ tmin_x = (this.mins_x + this.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+ if (this.size_y <= 50)
+ {
+ tmin_y = (this.mins_y + this.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }

---------------
-DN_N_WAIT is a plat that starts at the top and when triggered, goes down, waits, then comes back up.
-health - number of seconds to wait (default 5)
---------------
-PLT_TOGGLE is a plat that will change between the top and bottom each time it is triggered.
---------------
-ELEVATOR is an elevator plat. You can have as many levels as you want but they must be all the same distance away. Use elevator button entity as the trigger.
-cnt is the number of floors
-height is the distance between floors
-wait is the number of seconds before the elevator can be activated again after starting or stopping (default 0)
+ setsize (trigger, tmin, tmax);
+ };

-START_AT_TOP is an optional flag for elevators. It just tells the elevator that it's position is the top floor. (Default is the bottom floor) USE THIS ONLY WITH ELEVATORS!
--------------
-PLAT2 is a fixed version of the original plat. If you want the plat to start at the bottom and move to the top on demand, use a negative height. That will tell Quake to lower the plat at spawn time. Always place this plat type in the top position when making the map. This will ensure correct lighting, hopefully. If a plat2 is the target of a trigger, it will be disabled until it has been triggered. Delay is the wait before the plat returns to original position.
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_hit_top =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_TOP;

-If you don't want to bother figuring out the height, don't put a
-value in the height
+ this.plat2LastMove = time;
+ if (this.plat2Called == 1)
+ {
+ // allow immediate move
+ this.plat2LastMove = 0;
+ this.plat2Called = 0;
+ this.nextthink = this.ltime + 1.5;
+ }
+ else if (!(this.spawnflags & NEWPLAT_START_AT_TOP))
+ {
+ this.plat2Called = 0;
+ this.nextthink = this.ltime + this.delay;
+ }
+ };

-delay default 3
-speed default 150
-cnt default 2
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_hit_bottom =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;

-P2_BOTTOM is an optional switch to have an auto-sized plat2 start at the bottom.
---------------
-Plats are always drawn in the extended position, so they will light correctly.
+ this.plat2LastMove = time;
+ if (this.plat2Called == 1)
+ {
+ // allow immediate move
+ this.plat2LastMove = 0;
+ this.plat2Called = 0;
+ this.nextthink = this.ltime + 1.5;
+ }
+ else if (this.spawnflags & NEWPLAT_START_AT_TOP)
+ {
+ this.plat2Called = 0;
+ this.nextthink = this.ltime + this.delay;
+ }
+ };

-If the plat is the target of another trigger or button, it will start out disabled in the extended position until it is trigger, when it will lower and become a normal plat.
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_go_down =
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos2, this.speed, this.plat2_hit_bottom);
+ };

-If the "height" key is set, that will determine the amount the plat moves, instead of being implicitly determined by the model's height.
-Set "sounds" to one of the following:
-1) base fast
-2) chain slow
-*/
-void() func_new_plat =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_go_up =
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos1, this.speed, this.plat2_hit_top);
+ };

- //local entity t;
- local float negativeHeight;
+ //--------------------------------------------------------------
+ nonvirtual void() plat2_use =
+ {
+ if (this.state > 4)
+ this.state = this.state - 10;

- negativeHeight = 0;
+ this.interaction_flags |= DISABLE_USE;
+ };

- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
+ //--------------------------------------------------------------
+ nonvirtual void(entity blocker) plat2_crush =
+ {
+ T_Damage (blocker, this, this, 1);

- if (self.sounds == 0)
- self.sounds = 2;
+ if (this.state == FUNC_STATE_UP)
+ plat2_go_down ();
+ else if (this.state == FUNC_STATE_DOWN)
+ plat2_go_up ();
+ else
+ objerror ("plat2_crush: bad this.state\n");
+ };

- // FIX THIS TO LOAD A GENERIC PLAT SOUND
+ //==============================================================
+ // Common Plat Code
+ //==============================================================

- if (self.sounds == 1)
- {
- if (!self.noise || self.noise == "")
- self.noise = "plats/plat1.wav";
- if (!self.noise1 || self.noise1 == "")
- self.noise1 = "plats/plat2.wav";
- }
- else if (self.sounds == 2)
- {
- if (!self.noise || self.noise == "")
- self.noise = "plats/medplat1.wav";
- if (!self.noise1 || self.noise1 == "")
- self.noise1 = "plats/medplat2.wav";
- }
- else if (self.sounds == 3)
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
{
- // base door sound
- if (!self.noise || self.noise == "")
- self.noise = "doors/hydro1.wav";
- if (!self.noise1 || self.noise1 == "")
- self.noise1 = "doors/hydro2.wav";
- }
- else if (self.sounds == 4)
+ if (this.spawnflags & NEWPLAT_DN_N_WAIT)
+ this.dn_and_wait_crush (blocker);
+ else if (this.spawnflags & NEWPLAT_PLT_TOGGLE)
+ this.toggle_crush (blocker);
+ else if (this.spawnflags & NEWPLAT_ELEVATOR)
+ this.elvtr_crush (blocker);
+ else if (this.spawnflags & NEWPLAT_PLAT2)
+ this.plat2_crush (blocker);
+ else
+ dprint ("func_new_plat::do_blocked - check flags\n");
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- // func_train sounds
- if (!self.noise || self.noise == "")
- self.noise = "plats/train1.wav";
- if (!self.noise1 || self.noise1 == "")
- self.noise1 = "plats/train2.wav";
- }
- else
+ if (this.spawnflags & NEWPLAT_DN_N_WAIT)
+ {
+ if (this.state == FUNC_STATE_BOTTOM)
+ this.dn_and_wait_go_up ();
+ }
+ else if (this.spawnflags & NEWPLAT_PLAT2)
+ {
+ if (this.state == FUNC_STATE_TOP)
+ this.plat2_go_down ();
+ else if (this.state == FUNC_STATE_BOTTOM)
+ this.plat2_go_up ();
+ }
+ else
+ {
+ dprint ("func_new_plat::do_think: unhandled spawnflag "
+ "in think function!\n");
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- if (!self.noise || self.noise == "")
- self.noise = "misc/null.wav";
- if (!self.noise1 || self.noise1 == "")
- self.noise1 = "misc/null.wav";
- }
+ if (this.spawnflags & NEWPLAT_DN_N_WAIT)
+ this.dn_and_wait_use ();
+ else if (this.spawnflags & NEWPLAT_PLT_TOGGLE)
+ this.toggle_use ();
+ else if (this.spawnflags & NEWPLAT_ELEVATOR)
+ this.elvtr_use (caller);
+ else if (this.spawnflags & NEWPLAT_PLAT2)
+ if (this.targetname != "")
+ this.plat2_use ();
+ else
+ dprint ("func_new_plat::do_use: invalid spawnflags\n");
+ };

- precache_sound (self.noise);
- precache_sound (self.noise1);
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ // local entity t;
+ local float negativeHeight;

- self.mangle = self.angles;
- self.angles = '0 0 0';
+ negativeHeight = 0;

- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
+ this.pos_top = '0 0 0';
+ this.pos_bottom = '0 0 0';

- if (!self.speed)
- self.speed = 150;
+ if (!this.t_length)
+ this.t_length = 80;
+ if (!this.t_width)
+ this.t_width = 10;

- // pos1 is the top position, pos2 is the bottom
- self.pos1 = self.origin;
- self.pos2 = self.origin;
+ if (this.sounds == 0)
+ this.sounds = 2;

- if (self.height < 0)
- {
- negativeHeight = 1;
- self.height = 0 - self.height;
- }
+ // FIX THIS TO LOAD A GENERIC PLAT SOUND

- if (self.height)
- {
- self.pos2_z = self.origin_z - self.height;
- }
- else
- {
- negativeHeight = 1;
- self.height = self.size_z - 8;
- self.pos2_z = self.origin_z - self.height;
- }
-
- if (self.spawnflags & DN_N_WAIT)
- {
- self.use = dn_and_wait_use;
- self.blocked = dn_and_wait_crush;
-
- if (negativeHeight == 1)
+ if (this.sounds == 1)
{
- self.state = STATE_BOTTOM;
- setorigin (self, self.pos2);
+ if (!this.noise || this.noise == "")
+ this.noise = "plats/plat1.wav";
+ if (!this.noise1 || this.noise1 == "")
+ this.noise1 = "plats/plat2.wav";
}
- else
- self.state = STATE_TOP;
-
- if (!self.health)
- self.health = 5;
- }
- else if (self.spawnflags & PLT_TOGGLE)
- {
- self.use = toggle_use;
- self.blocked = toggle_crush;
- if (negativeHeight == 1)
+ else if (this.sounds == 2)
+ {
+ if (!this.noise || this.noise == "")
+ this.noise = "plats/medplat1.wav";
+ if (!this.noise1 || this.noise1 == "")
+ this.noise1 = "plats/medplat2.wav";
+ }
+ else if (this.sounds == 3)
{
- setorigin (self, self.pos2);
- self.state = STATE_BOTTOM;
+ // base door sound
+ if (!this.noise || this.noise == "")
+ this.noise = "doors/hydro1.wav";
+ if (!this.noise1 || this.noise1 == "")
+ this.noise1 = "doors/hydro2.wav";
+ }
+ else if (this.sounds == 4)
+ {
+ // func_train sounds
+ if (!this.noise || this.noise == "")
+ this.noise = "plats/train1.wav";
+ if (!this.noise1 || this.noise1 == "")
+ this.noise1 = "plats/train2.wav";
}
else
{
- self.state = STATE_TOP;
+ if (!this.noise || this.noise == "")
+ this.noise = "misc/null.wav";
+ if (!this.noise1 || this.noise1 == "")
+ this.noise1 = "misc/null.wav";
}
- }
- else if (self.spawnflags & ELEVATOR)
- {
- self.elevatorLastUse = 0;

- // allow the mapper to set self.wait, but don't allow a negative
- // wait period -- iw
- if (self.wait < 0)
- self.wait = 0;
+ precache_sound (this.noise);
+ precache_sound (this.noise1);
+
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+
+ // commented out the classname assignment -- CEV
+ // this.classname = "plat";
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setorigin (this, this.origin);
+ setmodel (this, this.model);
+ setsize (this, this.mins , this.maxs);
+
+ if (!this.speed)
+ this.speed = 150;
+
+ // pos1 is the top position, pos2 is the bottom
+ pos1 = this.origin;
+ pos2 = this.origin;

- if (self.spawnflags & START_AT_TOP)
+ if (this.height < 0)
{
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos2_z = self.origin_z -
- (self.height * (self.cnt - 1));
- self.elevatorOnFloor = self.cnt - 1;
- self.elevatorToFloor = self.elevatorOnFloor;
+ negativeHeight = 1;
+ this.height = 0 - this.height;
+ }
+
+ if (this.height)
+ {
+ pos2_z = this.origin_z - this.height;
}
else
{
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- self.pos1_z = self.origin_z +
- (self.height * (self.cnt - 1));
- self.elevatorOnFloor = 0;
- self.elevatorToFloor = self.elevatorOnFloor;
+ negativeHeight = 1;
+ height = this.size_z - 8;
+ pos2_z = this.origin_z - this.height;
}

- self.use = elvtr_use;
- self.blocked = elvtr_crush;
- }
- else if (self.spawnflags & PLAT2)
- {
- // the "start moving" trigger
- plat2_spawn_inside_trigger ();
- self.plat2Called = 0;
- self.plat2LastMove = 0;
- self.plat2GoTo = 0;
- self.plat2GoTime = 0;
- self.blocked = plat2_crush;
-
- if (!self.delay)
- self.delay = 3;
-
- if (negativeHeight == 1)
+ if (this.spawnflags & NEWPLAT_DN_N_WAIT)
{
- self.state = STATE_BOTTOM;
- // make sure START_AT_TOP isn't set. We need that...
- self.spawnflags = PLAT2;
- setorigin (self, self.pos2);
+ if (negativeHeight == 1)
+ {
+ this.state = FUNC_STATE_BOTTOM;
+ setorigin (this, pos2);
+ }
+ else
+ {
+ this.state = FUNC_STATE_TOP;
+ }
+
+ if (!this.health)
+ this.health = 5;
}
- else
+ else if (this.spawnflags & NEWPLAT_PLT_TOGGLE)
{
- // default position is top.
- self.spawnflags = self.spawnflags | START_AT_TOP;
- self.state = STATE_TOP;
+ if (negativeHeight == 1)
+ {
+ setorigin (this, pos2);
+ this.state = FUNC_STATE_BOTTOM;
+ }
+ else
+ {
+ this.state = FUNC_STATE_TOP;
+ }
}
-
- if (self.targetname != "")
+ else if (this.spawnflags & NEWPLAT_ELEVATOR)
{
- self.use = plat2_use;
- self.state = self.state + 10;
+ this.elevatorLastUse = 0;
+
+ // allow the mapper to set this.wait, but don't
+ // allow a negative wait period -- iw
+ if (this.wait < 0)
+ this.wait = 0;
+
+ if (this.spawnflags & NEWPLAT_START_AT_TOP)
+ {
+ this.pos_top = this.origin;
+ this.pos_bottom = this.origin;
+ this.pos_bottom_z = this.origin_z -
+ (this.height * (this.cnt - 1));
+ this.elevatorOnFloor = this.cnt - 1;
+ this.elevatorToFloor = this.elevatorOnFloor;
+ }
+ else
+ {
+ this.pos_top = this.origin;
+ this.pos_bottom = this.origin;
+ this.pos_top_z = this.origin_z +
+ (this.height * (this.cnt - 1));
+ this.elevatorOnFloor = 0;
+ this.elevatorToFloor = this.elevatorOnFloor;
+ }
}
- }
+ else if (this.spawnflags & NEWPLAT_PLAT2)
+ {
+ // the "start moving" trigger
+ plat2_spawn_inside_trigger ();
+ this.plat2Called = 0;
+ this.plat2LastMove = 0;
+ this.plat2GoTo = 0;
+ this.plat2GoTime = 0;
+
+ if (!this.delay)
+ this.delay = 3;
+
+ if (negativeHeight == 1)
+ {
+ this.state = FUNC_STATE_BOTTOM;
+ // make sure START_AT_TOP isn't set.
+ // We need that...
+ this.spawnflags = NEWPLAT_PLAT2;
+ setorigin (this, this.pos2);
+ }
+ else
+ {
+ // default position is top.
+ this.spawnflags = this.spawnflags |
+ NEWPLAT_START_AT_TOP;
+ this.state = FUNC_STATE_TOP;
+ }
+
+ if (this.targetname != "")
+ this.state = this.state + 10;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() func_new_plat =
+ {
+ this.classtype = CT_FUNC_NEW_PLAT;
+ };
};

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

Diff qc/func/particlefield.qc

diff --git a/qc/func/particlefield.qc b/qc/func/particlefield.qc
index e2fb276..3b64cba 100644
--- a/qc/func/particlefield.qc
+++ b/qc/func/particlefield.qc
@@ -9,250 +9,253 @@
// Distributed (unsupported) on 3.12.97

// constants
-// float START_OFF = 1;
-const float USE_COUNT = 1;
+// float PARTICLEFIELD_START_OFF = 1;
+const float PARTICLEFIELD_USE_COUNT = 1;

-//----------------------------------------------------------------------
-void() particlefield_XZ =
-{
- local vector pos;
- local vector start;
- local vector end;
+/*QUAKED func_particlefield (0 .5 .8) ? USE_COUNT 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

- if ((self.spawnflags & USE_COUNT) &&
- (counter_GetCount(other) != self.cnt))
- {
- return;
- }
+Creates a brief particle flash roughly the size of the defining
+brush each time it is triggered.
+
+USE_COUNT when the activator is a func_counter, the field will only
+activate when count is equal to "cnt". Same as using a func_oncount
+to trigger.

- // dprint( "XZ\n" );
- self.ltime = time + 0.25;
+"cnt" is the count to activate on when USE_COUNT is set.
+"color" is the color of the particles. Default is 192 (yellow).
+"count" is the density of the particles. Default is 2.
+"noise" is the sound to play when triggered. Do not use a looping sound here.
+"dmg" is the amount of damage to cause when touched.
+*/
+class func_particlefield: base_func
+{
+ vector dest;
+ vector dest1;
+ vector dest2;

- if (self.noise != "")
+ float field_direction;
+
+ //--------------------------------------------------------------
+ nonvirtual void() particlefield_xz =
{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
+ local vector pos = '0 0 0';
+ local vector start;
+ local vector end;

- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient())
- return;
+ /*
+ dprint ("func_particlefield::particlefield_xz: entering\n");
+ */

- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_y = start_y;
- pos_z = start_z;
+ this.ltime = time + 0.25;

- while (pos_z <= end_z)
- {
- pos_x = start_x;
- while (pos_x <= end_x)
+ if (this.noise != "")
{
- particle (pos, '0 0 0', self.color, self.count);
- pos_x = pos_x + 16;
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
}
- pos_z = pos_z + 16;
- }
-};

-//----------------------------------------------------------------------
-void() particlefield_YZ =
-{
- local vector pos;
- local vector start;
- local vector end;
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient())
+ return;

- if ((self.spawnflags & USE_COUNT) &&
- (counter_GetCount(other) != self.cnt))
- {
- return;
- }
-
- // dprint( "YZ: " );
- // dprint( vtos( self.dest1 ) );
- // dprint( " - " );
- // dprint( vtos( self.dest2 ) );
- // dprint( "\n" );
+ start = this.dest1 + this.origin;
+ end = this.dest2 + this.origin;
+ pos_y = start_y;
+ pos_z = start_z;

- self.ltime = time + 0.25;
+ while (pos_z <= end_z)
+ {
+ pos_x = start_x;
+ while (pos_x <= end_x)
+ {
+ particle (pos, '0 0 0', this.color, this.count);
+ pos_x = pos_x + 16;
+ }
+ pos_z = pos_z + 16;
+ }
+ };

- if (self.noise != "")
+ //--------------------------------------------------------------
+ nonvirtual void() particlefield_yz =
{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
+ local vector pos = '0 0 0';
+ local vector start;
+ local vector end;

- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient())
- return;
+ /*
+ dprint (sprintf("func_particlefield::particlefield_yz: "
+ "entering, dest1 %v, dest2 %v\n", dest1, dest2));
+ */

- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_x = start_x;
- pos_z = start_z;
+ this.ltime = time + 0.25;

- while (pos_z < end_z)
- {
- pos_y = start_y;
- while (pos_y < end_y)
+ if (this.noise != "")
{
- particle (pos, '0 0 0', self.color, self.count);
- pos_y = pos_y + 16;
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
}
- pos_z = pos_z + 16;
- }
-};
-
-//----------------------------------------------------------------------
-void() particlefield_XY =
-{
- local vector pos;
- local vector start;
- local vector end;

- if (( self.spawnflags & USE_COUNT) &&
- (counter_GetCount( other ) != self.cnt ))
- {
- return;
- }
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient())
+ return;

- // dprint( "XY\n" );
+ start = this.dest1 + this.origin;
+ end = this.dest2 + this.origin;
+ pos_x = start_x;
+ pos_z = start_z;

- self.ltime = time + 0.25;
+ while (pos_z < end_z)
+ {
+ pos_y = start_y;
+ while (pos_y < end_y)
+ {
+ particle (pos, '0 0 0', this.color, this.count);
+ pos_y = pos_y + 16;
+ }
+ pos_z = pos_z + 16;
+ }
+ };

- if (self.noise != "")
+ //--------------------------------------------------------------
+ nonvirtual void() particlefield_xy =
{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
+ local vector pos;
+ local vector start;
+ local vector end;

- // Only show particles if client is visible.
- // This helps to keep network traffic down to a minimum.
- if (!checkclient())
- return;
+ /*
+ dprint ("func_particlefield::particlefield_xy: entering\n");
+ */

- start = self.dest1 + self.origin;
- end = self.dest2 + self.origin;
- pos_x = start_x;
- pos_z = start_z;
+ this.ltime = time + 0.25;

- while (pos_x < end_x)
- {
- pos_y = start_y;
- while (pos_y < end_y)
+ if (this.noise != "")
{
- particle (pos, '0 0 0', self.color, self.count);
- pos_y = pos_y + 16;
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
}
- pos_x = pos_x + 16;
- }
-};

-//----------------------------------------------------------------------
-void() particlefield_touch =
-{
- if (!self.dmg)
- return;
+ // Only show particles if client is visible.
+ // This helps to keep network traffic down to a minimum.
+ if (!checkclient())
+ return;

- if (time > self.ltime)
- return;
+ start = this.dest1 + this.origin;
+ end = this.dest2 + this.origin;
+ pos_x = start_x;
+ pos_z = start_z;

- if (time < self.attack_finished)
- return;
+ while (pos_x < end_x)
+ {
+ pos_y = start_y;
+ while (pos_y < end_y)
+ {
+ particle (pos, '0 0 0', this.color, this.count);
+ pos_y = pos_y + 16;
+ }
+ pos_x = pos_x + 16;
+ }
+ };

- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ if (!this.dmg)
+ return;

-/*QUAKED func_particlefield (0 .5 .8) ? USE_COUNT 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
+ if (time > this.ltime)
+ return;

-Creates a brief particle flash roughly the size of the defining
-brush each time it is triggered.
+ if (time < this.attack_finished)
+ return;

-USE_COUNT when the activator is a func_counter, the field will only
-activate when count is equal to "cnt". Same as using a func_oncount
-to trigger.
+ this.attack_finished = time + 0.5;
+ T_Damage (toucher, this, this, this.dmg);
+ };

-"cnt" is the count to activate on when USE_COUNT is set.
-"color" is the color of the particles. Default is 192 (yellow).
-"count" is the density of the particles. Default is 2.
-"noise" is the sound to play when triggered. Do not use a looping sound here.
-"dmg" is the amount of damage to cause when touched.
-*/
-void() func_particlefield =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.color)
- {
- self.color = 192;
- }
-
- if (self.count == 0)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- self.count = 2;
- }
-
- self.classname = "particlefield";
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, self.model);
- self.model = string_null;
-
- self.origin = (self.mins + self.maxs) * 0.5;
- setorigin (self, self.origin);
- self.dest = self.maxs - self.mins - '16 16 16';
- self.dest1 = self.mins + '8 8 8' - self.origin;
- self.dest2 = self.maxs + '7.9 7.9 7.9' - self.origin;
- setsize (self, self.mins, self.maxs);
- self.touch = particlefield_touch;
- // dprint (vtos(self.dest));
- // dprint (" ");
-
- if (self.dest_x > self.dest_z)
- {
- if (self.dest_y > self.dest_z)
+ if ((this.spawnflags & PARTICLEFIELD_USE_COUNT) &&
+ func_counter::getcount(caller) != this.cnt)
{
- // dprint ("XY1 - ");
- // dprint (ftos(self.cnt));
- // dprint ("\n");
-
- self.use = particlefield_XY;
- self.dest1_z = (self.dest1_z + self.dest2_z) / 2;
+ /*
+ dprint (sprintf("func_particlefield::do_use: "
+ "returning early, getcount(other) %s, "
+ "this.cnt %s\n", func_counter::getcount(other),
+ this.cnt));
+ */
+ return;
}
+
+ if (this.field_direction == 1)
+ this.particlefield_xy ();
+ else if (this.field_direction == 2)
+ this.particlefield_yz ();
+ else if (this.field_direction == 3)
+ this.particlefield_xz ();
else
- {
- // dprint ("XZ1 - ");
- // dprint (ftos(self.cnt));
- // dprint ("\n");
- self.use = particlefield_XZ;
- self.dest1_y = (self.dest1_y + self.dest2_y) / 2;
- }
- }
- else
+ dprint ("func_particlefield::do_use: invalid field "
+ "direction!\n");
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- if (self.dest_y > self.dest_x)
+ if (!this.color)
+ this.color = 192;
+
+ if (this.count == 0)
+ this.count = 2;
+
+ this.classname = "particlefield";
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+ setmodel (this, this.model);
+ this.model = string_null;
+
+ this.origin = (this.mins + this.maxs) * 0.5;
+ setorigin (this, this.origin);
+ this.dest = this.maxs - this.mins - '16 16 16';
+ this.dest1 = this.mins + '8 8 8' - this.origin;
+ this.dest2 = this.maxs + '7.9 7.9 7.9' - this.origin;
+ setsize (this, this.mins, this.maxs);
+
+ if (dest_x > dest_z)
{
- // dprint ("YZ2 - ");
- // dprint (ftos(self.cnt));
- // dprint ("\n");
- self.use = particlefield_YZ;
- self.dest1_x = (self.dest1_x + self.dest2_x) / 2;
+ if (dest_y > dest_z)
+ {
+ field_direction = 1;
+ dest1_z = (dest1_z + dest2_z) / 2;
+ }
+ else
+ {
+ field_direction = 3;
+ dest1_y = (dest1_y + dest2_y) / 2;
+ }
}
else
{
- // dprint ("XZ2 - ");
- // dprint (ftos(self.cnt));
- // dprint ("\n");
- self.use = particlefield_XZ;
- self.dest1_y = (self.dest1_y + self.dest2_y) / 2;
+ if (dest_y > dest_x)
+ {
+ field_direction = 2;
+ dest1_x = (dest1_x + dest2_x) / 2;
+ }
+ else
+ {
+ field_direction = 3;
+ dest1_y = (dest1_y + dest2_y) / 2;
+ }
}
- }

- if (self.noise != "")
+ if (this.noise != "")
+ precache_sound (this.noise);
+
+ this.ltime = time;
+ };
+
+ //--------------------------------------------------------------
+ void() func_particlefield =
{
- precache_sound (self.noise);
- }
- self.ltime = time;
+ this.classtype = CT_FUNC_PARTICLEFIELD;
+ };
};

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

Diff qc/func/plat.qc

diff --git a/qc/func/plat.qc b/qc/func/plat.qc
index 85e309c..6866717 100644
--- a/qc/func/plat.qc
+++ b/qc/func/plat.qc
@@ -5,141 +5,59 @@
// constants
const float PLAT_LOW_TRIGGER = 1;

-// prototypes
-void() plat_center_touch;
-void() plat_outside_touch;
-void() plat_trigger_use;
-void() plat_go_up;
-void() plat_go_down;
-void() plat_crush;
-
-//----------------------------------------------------------------------
-void() plat_spawn_inside_trigger =
+//------------------------------------------------------------------------------
+class temp_plat_trigger: base_tempentity
{
- local entity trigger;
- local vector tmin, tmax;
-
- // middle trigger
- trigger = spawn ();
- trigger.touch = plat_center_touch;
- trigger.movetype = MOVETYPE_NONE;
- trigger.solid = SOLID_TRIGGER;
- trigger.enemy = self;
-
- tmin = self.mins + '25 25 0';
- tmax = self.maxs - '25 25 -8';
- tmin_z = tmax_z - (self.pos1_z - self.pos2_z + 8);
- if (self.spawnflags & PLAT_LOW_TRIGGER)
- tmax_z = tmin_z + 8;
-
- if (self.size_x <= 50)
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- tmin_x = (self.mins_x + self.maxs_x) / 2;
- tmax_x = tmin_x + 1;
- }
-
- if (self.size_y <= 50)
+ // from Copper -- dumptruck_ds
+ if (sub_checkvalidtouch(toucher) == FALSE)
+ return;
+
+ if (this.enemy.classtype != CT_FUNC_PLAT)
+ return;
+
+ // cast to func_plat -- CEV
+ local func_plat fp = (func_plat)this.enemy;
+
+ if (fp.state == FUNC_STATE_BOTTOM)
+ fp.plat_go_up ();
+ else if (fp.state == FUNC_STATE_TOP)
+ // delay going down
+ fp.nextthink = fp.ltime + 1;
+ };
+
+ /*
+ //--------------------------------------------------------------
+ // this doesn't seem to be called from anywhere -- CEV
+ //--------------------------------------------------------------
+ nonvirtual void(entity toucher) plat_outside_touch =
{
- tmin_y = (self.mins_y + self.maxs_y) / 2;
- tmax_y = tmin_y + 1;
- }
-
- setsize (trigger, tmin, tmax);
-};
+ // from Copper -- dumptruck_ds
+ if (sub_checkvalidtouch(toucher) == FALSE)
+ return;

-//----------------------------------------------------------------------
-void() plat_hit_top =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_TOP;
- self.think = plat_go_down;
- self.nextthink = self.ltime + 3;
-};
+ if (this.enemy.classtype != CT_FUNC_PLAT)
+ return;

-//----------------------------------------------------------------------
-void() plat_hit_bottom =
-{
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- self.state = STATE_BOTTOM;
-};
+ // dprint ("plat_outside_touch\n");

-//----------------------------------------------------------------------
-void() plat_go_down =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_DOWN;
- SUB_CalcMove (self.pos2, self.speed, plat_hit_bottom);
-};
+ // cast to func_plat -- CEV
+ local func_plat fp = (func_plat)this.enemy;

-//----------------------------------------------------------------------
-void() plat_go_up =
-{
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- self.state = STATE_UP;
- SUB_CalcMove (self.pos1, self.speed, plat_hit_top);
-};
-
-//----------------------------------------------------------------------
-void() plat_center_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- self = self.enemy;
-
- if (self.state == STATE_BOTTOM)
- plat_go_up ();
- else if (self.state == STATE_TOP)
- // delay going down
- self.nextthink = self.ltime + 1;
-};
-
-//----------------------------------------------------------------------
-void() plat_outside_touch =
-{
- // from Copper -- dumptruck_ds
- if (!CheckValidTouch())
- return;
-
- // dprint ("plat_outside_touch\n");
- self = self.enemy;
- if (self.state == STATE_TOP)
- plat_go_down ();
-};
+ if (fp.state == FUNC_STATE_TOP)
+ fp.plat_go_down ();
+ };
+ */

-//----------------------------------------------------------------------
-void() plat_trigger_use =
-{
- if (self.think)
- // allready activated
- return;
-
- plat_go_down ();
-};
-
-//----------------------------------------------------------------------
-void() plat_crush =
-{
- // dprint ("plat_crush\n");
-
- T_Damage (other, self, self, 1);
-
- if (self.state == STATE_UP)
- plat_go_down ();
- else if (self.state == STATE_DOWN)
- plat_go_up ();
- else
- objerror ("plat_crush: bad self.state\n");
-};
-
-//----------------------------------------------------------------------
-void() plat_use =
-{
- self.use = SUB_Null;
- if (self.state != STATE_UP)
- objerror ("plat_use: not in up state");
- plat_go_down ();
+ //--------------------------------------------------------------
+ void() temp_plat_trigger =
+ {
+ this.classtype = CT_TEMP_PLAT_TRIGGER;
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_TRIGGER;
+ };
};

/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -155,72 +73,180 @@ Set "sounds" to one of the following:
1) base fast
2) chain slow
*/
-void() func_plat =
+class func_plat: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ nonvirtual void() plat_spawn_inside_trigger =
+ {
+ local entity trigger;
+ local vector tmin, tmax;
+
+ // middle trigger
+ trigger = spawn (temp_plat_trigger, enemy: this);
+
+ tmin = this.mins + '25 25 0';
+ tmax = this.maxs - '25 25 -8';
+ tmin_z = tmax_z - (this.pos1_z - this.pos2_z + 8);
+ if (this.spawnflags & PLAT_LOW_TRIGGER)
+ tmax_z = tmin_z + 8;
+
+ if (this.size_x <= 50)
+ {
+ tmin_x = (this.mins_x + this.maxs_x) / 2;
+ tmax_x = tmin_x + 1;
+ }
+
+ if (this.size_y <= 50)
+ {
+ tmin_y = (this.mins_y + this.maxs_y) / 2;
+ tmax_y = tmin_y + 1;
+ }
+
+ setsize (trigger, tmin, tmax);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() plat_hit_top =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_TOP;
+ this.nextthink = this.ltime + 3;
+ };

- if (!self.t_length)
- self.t_length = 80;
- if (!self.t_width)
- self.t_width = 10;
+ //--------------------------------------------------------------
+ nonvirtual void() plat_hit_bottom =
+ {
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ this.state = FUNC_STATE_BOTTOM;
+ };

- if (self.sounds == 0)
- self.sounds = 2;
- // FIX THIS TO LOAD A GENERIC PLAT SOUND
+ //--------------------------------------------------------------
+ nonvirtual void() plat_go_down =
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_DOWN;
+ calc_move (this.pos2, this.speed, plat_hit_bottom);
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() plat_go_up =
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ this.state = FUNC_STATE_UP;
+ calc_move (this.pos1, this.speed, plat_hit_top);
+ };

- if (self.sounds == 1)
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
+ {
+ T_Damage (blocker, this, this, 1);
+
+ if (this.state == FUNC_STATE_UP)
+ plat_go_down ();
+ else if (this.state == FUNC_STATE_DOWN)
+ plat_go_up ();
+ else
+ objerror ("plat_crush: bad this.state\n");
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- precache_sound ("plats/plat1.wav");
- precache_sound ("plats/plat2.wav");
- self.noise = "plats/plat1.wav";
- self.noise1 = "plats/plat2.wav";
- }
+ if (this.state == FUNC_STATE_TOP)
+ this.plat_go_down ();
+ };

- if (self.sounds == 2)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- precache_sound ("plats/medplat1.wav");
- precache_sound ("plats/medplat2.wav");
- self.noise = "plats/medplat1.wav";
- self.noise1 = "plats/medplat2.wav";
- }
-
- self.mangle = self.angles;
- self.angles = '0 0 0';
-
- self.classname = "plat";
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- setorigin (self, self.origin);
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
-
- self.blocked = plat_crush;
- if (!self.speed)
- self.speed = 150;
-
- // pos1 is the top position, pos2 is the bottom
- self.pos1 = self.origin;
- self.pos2 = self.origin;
- if (self.height)
- self.pos2_z = self.origin_z - self.height;
- else
- self.pos2_z = self.origin_z - self.size_z + 8;
-
- self.use = plat_trigger_use;
-
- // the "start moving" trigger
- plat_spawn_inside_trigger ();
-
- if (self.targetname != "")
+ if (this.interaction_flags & DISABLE_USE)
+ return;
+
+ if (this.targetname != "")
+ {
+ this.interaction_flags |= DISABLE_USE;
+ if (this.state != FUNC_STATE_UP)
+ objerror ("plat_use: not in up state");
+ plat_go_down ();
+ }
+ else
+ {
+ if (this.think)
+ // allready activated
+ return;
+
+ plat_go_down ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.state = STATE_UP;
- self.use = plat_use;
- }
- else
+ this.interaction_flags = 0;
+
+ if (!this.t_length)
+ this.t_length = 80;
+ if (!this.t_width)
+ this.t_width = 10;
+
+ if (this.sounds == 0)
+ this.sounds = 2;
+ // FIX THIS TO LOAD A GENERIC PLAT SOUND
+
+ if (this.sounds == 1)
+ {
+ precache_sound ("plats/plat1.wav");
+ precache_sound ("plats/plat2.wav");
+ this.noise = "plats/plat1.wav";
+ this.noise1 = "plats/plat2.wav";
+ }
+
+ if (this.sounds == 2)
+ {
+ precache_sound ("plats/medplat1.wav");
+ precache_sound ("plats/medplat2.wav");
+ this.noise = "plats/medplat1.wav";
+ this.noise1 = "plats/medplat2.wav";
+ }
+
+ this.mangle = this.angles;
+ this.angles = '0 0 0';
+
+ this.classname = "plat";
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ setorigin (this, this.origin);
+ setmodel (this, this.model);
+ setsize (this, this.mins , this.maxs);
+
+ if (!this.speed)
+ this.speed = 150;
+
+ // pos1 is the top position, pos2 is the bottom
+ this.pos1 = this.origin;
+ this.pos2 = this.origin;
+ if (this.height)
+ this.pos2_z = this.origin_z - this.height;
+ else
+ this.pos2_z = this.origin_z - this.size_z + 8;
+
+ // the "start moving" trigger
+ plat_spawn_inside_trigger ();
+
+ if (this.targetname != "")
+ {
+ this.state = FUNC_STATE_UP;
+ }
+ else
+ {
+ setorigin (this, this.pos2);
+ this.state = FUNC_STATE_BOTTOM;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() func_plat =
{
- setorigin (self, self.pos2);
- self.state = STATE_BOTTOM;
- }
+ this.classtype = CT_FUNC_PLAT;
+ };
};

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 5ba211c..76dab78 100644
--- a/qc/func/rotate.qc
+++ b/qc/func/rotate.qc
@@ -10,37 +10,26 @@
// Distributed (unsupported) on 3.12.97
//======================================================================

-// fields
-.float rotate_type;
-.vector neworigin;
-.vector rotate;
-.float endtime;
-.float duration;
-.vector finalangle;
-.string path;
-.string group;
-.string event;
-
// constants
-const float STATE_ACTIVE = 0;
-const float STATE_INACTIVE = 1;
-const float STATE_SPEEDINGUP = 2;
-const float STATE_SLOWINGDOWN = 3;
-
-const float STATE_CLOSED = 4;
-const float STATE_OPEN = 5;
-const float STATE_OPENING = 6;
-const float STATE_CLOSING = 7;
-
-const float STATE_WAIT = 0;
-const float STATE_MOVE = 1;
-const float STATE_STOP = 2;
-const float STATE_FIND = 3;
-const float STATE_NEXT = 4;
-
-const float OBJECT_ROTATE = 0;
-const float OBJECT_MOVEWALL = 1;
-const float OBJECT_SETORIGIN = 2;
+const float ROTATE_STATE_ACTIVE = 0;
+const float ROTATE_STATE_INACTIVE = 1;
+const float ROTATE_STATE_SPEEDINGUP = 2;
+const float ROTATE_STATE_SLOWINGDOWN = 3;
+
+const float ROTATE_STATE_CLOSED = 4;
+const float ROTATE_STATE_OPEN = 5;
+const float ROTATE_STATE_OPENING = 6;
+const float ROTATE_STATE_CLOSING = 7;
+
+const float ROTATE_STATE_WAIT = 0;
+const float ROTATE_STATE_MOVE = 1;
+const float ROTATE_STATE_STOP = 2;
+const float ROTATE_STATE_FIND = 3;
+const float ROTATE_STATE_NEXT = 4;
+
+const float ROTATE_OBJECT_ROTATE = 0;
+const float ROTATE_OBJECT_MOVEWALL = 1;
+const float ROTATE_OBJECT_SETORIGIN = 2;

const float ROTATE_ENTITY_TOGGLE = 1; // spawnflags for func_rotate_entity
const float ROTATE_ENTITY_START_ON = 2;
@@ -55,303 +44,325 @@ const float PATH_ROTATE_SET_DAMAGE = 64;

const float ROTATE_DOOR_STAYOPEN = 1; // spawnflags for func_rotate_door

-//----------------------------------------------------------------------
-// SUB_NormalizeAngles
-//----------------------------------------------------------------------
-vector(vector ang) SUB_NormalizeAngles =
-{
- while (ang_x > 360)
- ang_x = ang_x - 360;
- while (ang_x < 0)
- ang_x = ang_x + 360;
- while (ang_y > 360)
- ang_y = ang_y - 360;
- while (ang_y < 0)
- ang_y = ang_y + 360;
- while (ang_z > 360)
- ang_z = ang_z - 360;
- while (ang_z < 0)
- ang_z = ang_z + 360;
-
- return ang;
-};
+const float MOVEWALL_VISIBLE = 1; // spawnflags for func_movewall
+const float MOVEWALL_TOUCH = 2;
+const float MOVEWALL_NONBLOCKING = 4;

-/*QUAKED info_rotate (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 the point of rotation for rotatable objects.
-*/
-void() info_rotate =
+//------------------------------------------------------------------------------
+class base_rotate: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- // remove self after a little while, to make sure that entities that
- // have targeted it have had a chance to spawn
- self.nextthink = time + 2;
- self.think = SUB_Remove;
-};
+ // class fields
+ float duration;
+ float endtime;
+ float rotate_type;

-//----------------------------------------------------------------------
-void() RotateTargets =
-{
- local vector org, vx, vy, vz;
- local entity ent;
+ vector finalangle;
+ vector neworigin;
+ vector rotate;

- makevectors (self.angles);
+ vector dest;
+ vector dest1;
+ vector dest2;

- ent = find (world, targetname, self.target);
+ string event;
+ string group;
+ string path;

- while (ent)
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
{
- if (ent.rotate_type == OBJECT_SETORIGIN)
- {
- org = ent.oldorigin;
- vx = (v_forward * org_x);
- vy = (v_right * org_y);
- vy = vy * -1;
- vz = (v_up * org_z);
- ent.neworigin = vx + vy + vz;
- setorigin (ent, ent.neworigin + self.origin);
- }
- else if (ent.rotate_type == OBJECT_ROTATE)
- {
- ent.angles = self.angles;
- org = ent.oldorigin;
- vx = (v_forward * org_x);
- vy = (v_right * org_y);
- vy = vy * -1;
- vz = (v_up * org_z);
- ent.neworigin = vx + vy + vz;
- setorigin (ent, ent.neworigin + self.origin);
- }
- else
+ switch (fieldname)
{
- org = ent.oldorigin;
- vx = (v_forward * org_x);
- vy = (v_right * org_y);
- vy = vy * -1;
- vz = (v_up * org_z);
- ent.neworigin = vx + vy + vz;
- ent.neworigin = self.origin - self.oldorigin +
- (ent.neworigin - ent.oldorigin);
- ent.velocity = (ent.neworigin - ent.origin) * 25;
- }
- ent = find (ent, targetname, self.target);
- }
-};
+ case "duration":
+ duration = stof (fieldvalue);
+ break;
+ case "endtime":
+ endtime = stof (fieldvalue);
+ break;
+ case "rotate_type":
+ rotate_type = stof (fieldvalue);
+ break;
+ case "finalangle":
+ finalangle = stov (fieldvalue);
+ break;
+ case "neworigin":
+ neworigin = stov (fieldvalue);
+ break;
+ case "rotate":
+ rotate = stov (fieldvalue);
+ break;
+ case "event":
+ event = fieldvalue;
+ break;
+ case "group":
+ group = fieldvalue;
+ break;
+ case "path":
+ path = fieldvalue;
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };

-//----------------------------------------------------------------------
-void() RotateTargetsFinal =
-{
- local entity ent;
+ //--------------------------------------------------------------
+ // SUB_NormalizeAngles
+ //--------------------------------------------------------------
+ static vector(vector ang) normalizeangles =
+ {
+ while (ang_x > 360)
+ ang_x = ang_x - 360;
+ while (ang_x < 0)
+ ang_x = ang_x + 360;
+ while (ang_y > 360)
+ ang_y = ang_y - 360;
+ while (ang_y < 0)
+ ang_y = ang_y + 360;
+ while (ang_z > 360)
+ ang_z = ang_z - 360;
+ while (ang_z < 0)
+ ang_z = ang_z + 360;

- ent = find (world, targetname, self.target);
+ return ang;
+ };

- while (ent)
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_targets =
{
- ent.velocity = '0 0 0';
- if (ent.rotate_type == OBJECT_ROTATE)
- {
- ent.angles = self.angles;
- }
- ent = find (ent, targetname, self.target);
- }
-};
+ local vector org, vx, vy, vz;
+ local entity ent;
+ local base_rotate rot;

-//----------------------------------------------------------------------
-void() SetTargetOrigin =
-{
- local entity ent;
+ makevectors (this.angles);

- ent = find (world, targetname, self.target);
+ ent = find (world, ::targetname, this.target);

- while (ent)
- {
- if (ent.rotate_type == OBJECT_MOVEWALL)
- {
- setorigin (ent, self.origin - self.oldorigin +
- (ent.neworigin - ent.oldorigin) );
- }
- else
+ while (ent)
{
- setorigin (ent, ent.neworigin + self.origin);
- }
- ent = find (ent, targetname, self.target);
- }
-};
-
-//----------------------------------------------------------------------
-void() LinkRotateTargets =
-{
- local entity ent;
- local vector tempvec;
+ if (!(ent.classgroup & CG_ROTATE))
+ {
+ dprint (sprintf("rotate_targets: found "
+ "unhandled class %s, targetname %s\n",
+ ent.classname, ent.targetname));
+ ent = find (ent, ::targetname, this.target);
+ continue;
+ }

- self.oldorigin = self.origin;
- ent = find (world, targetname, self.target);
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;

- while (ent)
- {
- if (ent.classname == "rotate_object")
- {
- ent.rotate_type = OBJECT_ROTATE;
- ent.oldorigin = ent.origin - self.oldorigin;
- ent.neworigin = ent.origin - self.oldorigin;
- ent.owner = self;
- }
- else if (ent.classname == "func_movewall")
- {
- ent.rotate_type = OBJECT_MOVEWALL;
- tempvec = (ent.absmin + ent.absmax) * 0.5;
- ent.oldorigin = tempvec - self.oldorigin;
- ent.neworigin = ent.oldorigin;
- ent.owner = self;
- }
- else
- {
- ent.rotate_type = OBJECT_SETORIGIN;
- ent.oldorigin = ent.origin - self.oldorigin;
- ent.neworigin = ent.origin - self.oldorigin;
+ if (rot.rotate_type == ROTATE_OBJECT_SETORIGIN)
+ {
+ org = rot.oldorigin;
+ vx = (v_forward * org_x);
+ vy = (v_right * org_y);
+ vy = vy * -1;
+ vz = (v_up * org_z);
+ rot.neworigin = vx + vy + vz;
+ setorigin (rot, rot.neworigin + this.origin);
+ }
+ else if (rot.rotate_type == ROTATE_OBJECT_ROTATE)
+ {
+ rot.angles = this.angles;
+ org = rot.oldorigin;
+ vx = (v_forward * org_x);
+ vy = (v_right * org_y);
+ vy = vy * -1;
+ vz = (v_up * org_z);
+ rot.neworigin = vx + vy + vz;
+ setorigin (rot, rot.neworigin + this.origin);
+ }
+ else
+ {
+ org = rot.oldorigin;
+ vx = (v_forward * org_x);
+ vy = (v_right * org_y);
+ vy = vy * -1;
+ vz = (v_up * org_z);
+ rot.neworigin = vx + vy + vz;
+ rot.neworigin = this.origin - this.oldorigin +
+ (rot.neworigin - rot.oldorigin);
+ rot.velocity = (rot.neworigin - rot.origin) * 25;
+ }
+ ent = find (ent, ::targetname, this.target);
}
- ent = find (ent, targetname, self.target);
- }
-};
+ };

-//----------------------------------------------------------------------
-void(float amount) SetDamageOnTargets =
-{
- local entity ent;
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_targets_final =
+ {
+ local entity ent;
+ local base_rotate rot;

- ent = find (world, targetname, self.target);
+ ent = find (world, ::targetname, this.target);

- while (ent)
- {
- if (ent.classtype == CT_TRIGGER_HURT)
- {
- // cast to trigger_hurt -- CEV
- local trigger_hurt t = (trigger_hurt)ent;
- t.setdamage (ent, amount);
- }
- else if (ent.classname == "func_movewall")
+ while (ent)
{
- ent.dmg = amount;
- }
- ent = find (ent, targetname, self.target);
- }
-};
-
-//======================================================================
-// Simple continual rotatation
-//======================================================================
+ if (!(ent.classgroup & CG_ROTATE))
+ {
+ dprint (sprintf("rotate_targets_final: found "
+ "unhandled class %s, targetname %s\n",
+ ent.classname, ent.targetname));
+ ent = find (ent, ::targetname, this.target);
+ continue;
+ }

-//----------------------------------------------------------------------
-void() rotate_entity_think =
-{
- local float t;
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;

- t = time - self.ltime;
- self.ltime = time;
+ rot.velocity = '0 0 0';
+ if (rot.rotate_type == ROTATE_OBJECT_ROTATE)
+ {
+ rot.angles = this.angles;
+ }

- if (self.state == STATE_SPEEDINGUP)
- {
- self.count = self.count + self.cnt * t;
- if (self.count > 1)
- {
- self.count = 1;
+ ent = find (ent, ::targetname, this.target);
}
+ };

- // get rate of rotation
- t = t * self.count;
- }
- else if (self.state == STATE_SLOWINGDOWN)
+ //--------------------------------------------------------------
+ nonvirtual void() set_target_origin =
{
- self.count = self.count - self.cnt * t;
- if (self.count < 0)
- {
- RotateTargetsFinal ();
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
- return;
- }
+ local entity ent;
+ local base_rotate rot;

- // get rate of rotation
- t = t * self.count;
- }
+ ent = find (world, ::targetname, this.target);

- self.angles = self.angles + (self.rotate * t);
- self.angles = SUB_NormalizeAngles (self.angles);
- RotateTargets ();
- self.nextthink = time + 0.02;
-};
+ while (ent)
+ {
+ if (!(ent.classgroup & CG_ROTATE))
+ {
+ dprint (sprintf("rotate_targets_final: found "
+ "unhandled class %s, targetname %s\n",
+ ent.classname, ent.targetname));
+ ent = find (ent, ::targetname, this.target);
+ continue;
+ }

-//----------------------------------------------------------------------
-void() rotate_entity_use =
-{
- // change to alternate textures
- self.frame = 1 - self.frame;
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;

- if (self.state == STATE_ACTIVE)
- {
- if (self.spawnflags & ROTATE_ENTITY_TOGGLE)
- {
- if (self.speed)
+ if (rot.rotate_type == ROTATE_OBJECT_MOVEWALL)
{
- self.count = 1;
- self.state = STATE_SLOWINGDOWN;
+ setorigin (rot, this.origin - this.oldorigin +
+ (rot.neworigin - rot.oldorigin));
}
else
{
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
+ setorigin (rot, rot.neworigin + this.origin);
}
+
+ ent = find (ent, ::targetname, this.target);
}
- }
- else if (self.state == STATE_INACTIVE)
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() link_rotate_targets =
{
- self.think = rotate_entity_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
- if (self.speed)
- {
- self.count = 0;
- self.state = STATE_SPEEDINGUP;
- }
- else
+ local base_rotate rot;
+ local entity ent;
+ local vector tempvec;
+
+ this.oldorigin = this.origin;
+ ent = find (world, ::targetname, this.target);
+
+ while (ent)
{
- self.state = STATE_ACTIVE;
+ if (ent.classtype == CT_MISC_ROTATE_OBJECT)
+ {
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;
+ rot.rotate_type = ROTATE_OBJECT_ROTATE;
+ rot.oldorigin = rot.origin - this.oldorigin;
+ rot.neworigin = rot.origin - this.oldorigin;
+ rot.owner = this;
+ }
+ else if (ent.classtype == CT_FUNC_MOVEWALL)
+ {
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;
+ rot.rotate_type = ROTATE_OBJECT_MOVEWALL;
+ tempvec = (rot.absmin + rot.absmax) * 0.5;
+ rot.oldorigin = tempvec - this.oldorigin;
+ rot.neworigin = rot.oldorigin;
+ rot.owner = this;
+ }
+ else if (ent.classgroup & CG_ROTATE)
+ {
+ // cast to base_rotate -- CEV
+ rot = (base_rotate)ent;
+ rot.rotate_type = ROTATE_OBJECT_SETORIGIN;
+ rot.oldorigin = rot.origin - this.oldorigin;
+ rot.neworigin = rot.origin - this.oldorigin;
+ }
+ else
+ {
+ dprint (sprintf("link_rotate_targets: found an "
+ "unsupported class %s, targetname %s\n",
+ ent.classname, ent.targetname));
+ }
+ ent = find (ent, ::targetname, this.target);
}
- }
- else if (self.state == STATE_SPEEDINGUP)
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void(float amount) set_damage_on_targets =
{
- if (self.spawnflags & ROTATE_ENTITY_TOGGLE)
+ local entity ent;
+
+ ent = find (world, ::targetname, this.target);
+
+ while (ent)
{
- self.state = STATE_SLOWINGDOWN;
+ if (ent.classtype == CT_TRIGGER_HURT)
+ {
+ // cast to trigger_hurt -- CEV
+ local trigger_hurt t = (trigger_hurt)ent;
+ t.setdamage (t, amount);
+ }
+ else if (ent.classtype == CT_FUNC_MOVEWALL)
+ {
+ ent.dmg = amount;
+ }
+ ent = find (ent, ::targetname, this.target);
}
- }
- else
+ };
+
+ //--------------------------------------------------------------
+ void() base_rotate =
{
- self.state = STATE_SPEEDINGUP;
- }
+ this.classgroup |= CG_ROTATE;
+ };
};

-//----------------------------------------------------------------------
-void() rotate_entity_firstthink =
+/*QUAKED rotate_object (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+This defines an object to be rotated. Used as the target of func_rotate_door.
+*/
+class rotate_object: base_rotate
{
- LinkRotateTargets ();
- if (self.spawnflags & ROTATE_ENTITY_START_ON)
- {
- self.state = STATE_ACTIVE;
- self.think = rotate_entity_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
- }
- else
- {
- self.state = STATE_INACTIVE;
- self.think = SUB_Null;
- }
- self.use = rotate_entity_use;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+ setmodel (this, this.model);
+ setsize (this, this.mins, this.maxs);
+ this.interaction_flags |= DISABLE_THINK;
+ };
+
+ //--------------------------------------------------------------
+ void() rotate_object =
+ {
+ this.classname = "rotate_object";
+ this.classtype = CT_MISC_ROTATE_OBJECT;
+ };
};

+
+//------------------------------------------------------------------------------
+// Simple continual rotatation
+//------------------------------------------------------------------------------
+
/*QUAKED func_rotate_entity (0 .5 .8) (-8 -8 -8) (8 8 8) TOGGLE START_ON 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 an entity that continually rotates. Can be toggled on and
@@ -367,31 +378,147 @@ If "deathtype" is set with a string, this is the message that will appear when a
"target" is the center of rotation.
"speed" is how long the entity takes to go from standing still to full speed and vice-versa.
*/
-void() func_rotate_entity =
+class func_rotate_entity: base_rotate
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ float firstthink;
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.firstthink)
+ {
+ // was rotate_entity_firstthink
+ this.firstthink = FALSE;
+ link_rotate_targets ();
+ if (this.spawnflags & ROTATE_ENTITY_START_ON)
+ {
+ this.state = ROTATE_STATE_ACTIVE;
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.nextthink = time + 0.02;
+ this.ltime = time;
+ }
+ else
+ {
+ this.state = ROTATE_STATE_INACTIVE;
+ this.interaction_flags |= DISABLE_THINK;
+ }
+ }
+ else
+ {
+ // was rotate_entity_think -- CEV
+ local float t;

- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
+ t = time - this.ltime;
+ this.ltime = time;

- setmodel (self, self.model);
- setsize (self, self.mins, self.maxs);
+ if (this.state == ROTATE_STATE_SPEEDINGUP)
+ {
+ this.count = this.count + this.cnt * t;
+ if (this.count > 1)
+ this.count = 1;
+
+ // get rate of rotation
+ t = t * this.count;
+ }
+ else if (this.state == ROTATE_STATE_SLOWINGDOWN)
+ {
+ this.count = this.count - this.cnt * t;
+ if (this.count < 0)
+ {
+ rotate_targets_final ();
+ this.state = ROTATE_STATE_INACTIVE;
+ this.interaction_flags |= DISABLE_THINK;
+ return;
+ }
+
+ // get rate of rotation
+ t = t * this.count;
+ }
+
+ this.angles = this.angles + (this.rotate * t);
+ this.angles = normalizeangles (this.angles);
+ rotate_targets ();
+ this.nextthink = time + 0.02;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ // change to alternate textures
+ this.frame = 1 - this.frame;
+
+ if (this.state == ROTATE_STATE_ACTIVE)
+ {
+ if (this.spawnflags & ROTATE_ENTITY_TOGGLE)
+ {
+ if (this.speed)
+ {
+ this.count = 1;
+ this.state = ROTATE_STATE_SLOWINGDOWN;
+ }
+ else
+ {
+ this.state = ROTATE_STATE_INACTIVE;
+ this.interaction_flags |= DISABLE_THINK;
+ }
+ }
+ }
+ else if (this.state == ROTATE_STATE_INACTIVE)
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.firstthink = FALSE;
+ this.nextthink = time + 0.02;
+ this.ltime = time;
+ if (this.speed)
+ {
+ this.count = 0;
+ this.state = ROTATE_STATE_SPEEDINGUP;
+ }
+ else
+ {
+ this.state = ROTATE_STATE_ACTIVE;
+ }
+ }
+ else if (this.state == ROTATE_STATE_SPEEDINGUP)
+ {
+ if (this.spawnflags & ROTATE_ENTITY_TOGGLE)
+ {
+ this.state = ROTATE_STATE_SLOWINGDOWN;
+ }
+ }
+ else
+ {
+ this.state = ROTATE_STATE_SPEEDINGUP;
+ }
+ };

- if (self.speed != 0)
+ virtual void() init_spawned =
{
- self.cnt = 1 / self.speed;
- }
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+
+ setmodel (this, this.model);
+ setsize (this, this.mins, this.maxs);
+
+ if (this.speed != 0)
+ this.cnt = 1 / this.speed;
+
+ this.firstthink = TRUE;
+ this.nextthink = time + 0.1;
+ this.ltime = time;
+ };

- self.think = rotate_entity_firstthink;
- self.nextthink = time + 0.1;
- self.ltime = time;
+ //--------------------------------------------------------------
+ void() func_rotate_entity =
+ {
+ this.classtype = CT_FUNC_ROTATE_ENTITY;
+ };
};

-//======================================================================
+//------------------------------------------------------------------------------
// Train with rotation functionality
-//======================================================================
+//------------------------------------------------------------------------------

/*QUAKED path_rotate (0.5 0.3 0) (-8 -8 -8) (8 8 8) ROTATION ANGLES STOP NO_ROTATE DAMAGE MOVETIME SET_DAMAGE
Path for rotate_train.
@@ -414,507 +541,482 @@ void() func_rotate_entity =
"noise1" contains the name of the sound to play when train moves.
"event" is a target to trigger when train arrives at path_rotate.
*/
-void() path_rotate =
+class path_rotate: base_rotate
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.noise != "")
- {
- precache_sound (self.noise);
- }
- if ( self.noise1 != "" )
- {
- precache_sound (self.noise1);
- }
-};
-
-// prototypes
-void() rotate_train;
-void() rotate_train_next;
-void() rotate_train_find;
-
-//----------------------------------------------------------------------
-void() rotate_train_think =
-{
- local float t, timeelapsed;
-
- t = time - self.ltime;
- self.ltime = time;
-
- if ((self.endtime) && (time >= self.endtime))
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.endtime = 0;
- if (self.state == STATE_MOVE)
+ if (this.noise != "")
{
- setorigin (self, self.finaldest);
- self.velocity = '0 0 0';
+ precache_sound (this.noise);
}
- if (self.think1)
- self.think1 ();
- }
- else
- {
- timeelapsed = (time - self.cnt) * self.duration;
- if (timeelapsed > 1)
- timeelapsed = 1;
- setorigin (self, self.dest1 + (self.dest2 * timeelapsed));
- }
-
- self.angles = self.angles + (self.rotate * t);
- self.angles = SUB_NormalizeAngles (self.angles);
- RotateTargets ();
-
- self.nextthink = time + 0.02;
-};
-
-//----------------------------------------------------------------------
-void() rotate_train_use =
-{
- if (self.think1 != rotate_train_find)
- {
- if (self.velocity != '0 0 0')
- // already activated
- return;
- if (self.think1)
+ if (this.noise1 != "")
{
- self.think1 ();
+ precache_sound (this.noise1);
}
- }
-};
-
-//----------------------------------------------------------------------
-void() rotate_train_wait =
-{
- self.state = STATE_WAIT;
+ };

- if (self.goalentity.noise != "")
+ //--------------------------------------------------------------
+ void() path_rotate =
{
- sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
+ this.classtype = CT_PATH_ROTATE;
+ };
+};

- if (self.goalentity.spawnflags & PATH_ROTATE_ANGLES)
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
+/*QUAKED func_rotate_train (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

- if (self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE)
- {
- self.rotate = '0 0 0';
- }
+In path_rotate, set speed to be the new speed of the train after it reaches
+the path change. If speed is -1, the train will warp directly to the next
+path change after the specified wait time. If MOVETIME is set on the
+path_rotate, the train to interprets "speed" as the length of time to
+take moving from one corner to another.

- self.endtime = self.ltime + self.goalentity.wait;
- self.think1 = rotate_train_next;
-};
+"noise" contains the name of the sound to play when train stops.
+"noise1" contains the name of the sound to play when train moves.
+Both "noise" and "noise1" defaults depend upon "sounds" variable and
+can be overridden by the "noise" and "noise1" variable in path_rotate.

-//----------------------------------------------------------------------
-void() rotate_train_stop =
-{
- self.state = STATE_STOP;
+Also in path_rotate, if STOP is set, the train will wait until it is
+retriggered before moving on to the next goal.

- if (self.goalentity.noise != "")
- {
- sound (self, CHAN_VOICE, self.goalentity.noise, 1, ATTN_NORM);
- }
- else
- {
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
+Trains are moving platforms that players can ride.
+"path" specifies the first path_rotate and is the starting position.
+If the train is the target of a button or trigger, it will not begin moving until activated.
+The func_rotate_train entity is the center of rotation of all objects targeted by it.

- if (self.goalentity.spawnflags & PATH_ROTATE_ANGLES)
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
+If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
+
+speed default 100
+dmg default 0
+sounds
+1) ratchet metal
+*/
+class func_rotate_train: base_rotate
+{
+ base_rotate goal_rotate;

- if (self.goalentity.spawnflags & PATH_ROTATE_NO_ROTATE)
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_train_wait =
{
- self.rotate = '0 0 0';
- }
+ this.state = ROTATE_STATE_WAIT;

- self.dmg = 0;
- self.think1 = rotate_train_next;
-};
+ if (this.goal_rotate.noise != "")
+ {
+ sound (this, CHAN_VOICE, this.goal_rotate.noise,
+ 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ }

-//----------------------------------------------------------------------
-void() rotate_train_next =
-{
- local entity current, targ;
- local vector vdestdelta;
- local float len, traveltime, div;
- local string temp;
+ if (this.goal_rotate.spawnflags & PATH_ROTATE_ANGLES)
+ {
+ this.rotate = '0 0 0';
+ this.angles = this.finalangle;
+ }

- self.state = STATE_NEXT;
+ if (this.goal_rotate.spawnflags & PATH_ROTATE_NO_ROTATE)
+ {
+ this.rotate = '0 0 0';
+ }

- current = self.goalentity;
- targ = find (world, targetname, self.path);
- if (targ.classname != "path_rotate")
- objerror ("Next target is not path_rotate");
+ this.endtime = this.ltime + this.goal_rotate.wait;
+ // TODO CEV
+ this.think1 = rotate_train_next;
+ };

- if (self.goalentity.noise1 != "")
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_train_stop =
{
- self.noise1 = self.goalentity.noise1;
- }
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ this.state = ROTATE_STATE_STOP;

- self.goalentity = targ;
- self.path = targ.target;
- if (!self.path )
- objerror ("rotate_train_next: no next target");
+ if (this.goal_rotate.noise != "")
+ {
+ sound (this, CHAN_VOICE, this.goal_rotate.noise,
+ 1, ATTN_NORM);
+ }
+ else
+ {
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ }

- if (targ.spawnflags & PATH_ROTATE_STOP)
- {
- self.think1 = rotate_train_stop;
- }
- else if (targ.wait)
- {
- self.think1 = rotate_train_wait;
- }
- else
- {
- self.think1 = rotate_train_next;
- }
+ if (this.goal_rotate.spawnflags & PATH_ROTATE_ANGLES)
+ {
+ this.rotate = '0 0 0';
+ this.angles = this.finalangle;
+ }

- if (current.event != "")
- {
- // Trigger any events that should happen at the corner.
- temp = self.target;
- self.target = current.event;
- self.message = current.message;
- SUB_UseTargets ();
- self.target = temp;
- self.message = string_null;
- }
-
- if (current.spawnflags & PATH_ROTATE_ANGLES)
- {
- self.rotate = '0 0 0';
- self.angles = self.finalangle;
- }
+ if (this.goal_rotate.spawnflags & PATH_ROTATE_NO_ROTATE)
+ {
+ this.rotate = '0 0 0';
+ }

- if (current.spawnflags & PATH_ROTATE_ROTATION)
- {
- self.rotate = current.rotate;
- }
+ this.dmg = 0;
+ // TODO CEV
+ this.think1 = rotate_train_next;
+ };

- if (current.spawnflags & PATH_ROTATE_DAMAGE)
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_train_next =
{
- self.dmg = current.dmg;
- }
+ local base_rotate current;
+ local base_rotate targ_rotate;
+ local entity targ;
+ local vector vdestdelta;
+ local float len, traveltime, div;
+ local string temp;

- if (current.spawnflags & PATH_ROTATE_SET_DAMAGE)
- {
- SetDamageOnTargets (current.dmg);
- }
+ this.state = ROTATE_STATE_NEXT;

- if (current.speed == -1)
- {
- // Warp to the next path_corner
- setorigin (self, targ.origin);
- self.endtime = self.ltime + 0.01;
- SetTargetOrigin ();
+ current = this.goal_rotate;
+ targ = find (world, ::targetname, this.path);
+ if (targ.classtype != CT_PATH_ROTATE)
+ objerror ("Next target is not path_rotate");
+
+ // cast to path_rotate -- CEV
+ targ_rotate = (path_rotate)targ;

- if (targ.spawnflags & PATH_ROTATE_ANGLES)
+ if (this.goal_rotate.noise1 != "")
{
- self.angles = targ.angles;
+ this.noise1 = this.goal_rotate.noise1;
}
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);

- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
- self.finaldest = self.origin;
- }
- else
- {
- self.state = STATE_MOVE;
+ this.goal_rotate = targ_rotate;
+ this.path = targ.target;
+ if (!this.path )
+ objerror ("rotate_train_next: no next target");

- self.finaldest = targ.origin;
- if (self.finaldest == self.origin)
+ if (targ_rotate.spawnflags & PATH_ROTATE_STOP)
{
- self.velocity = '0 0 0';
- self.endtime = self.ltime + 0.1;
-
- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
- self.finaldest = self.origin;
- return;
+ // TODO CEV
+ this.think1 = rotate_train_stop;
}
- // set destdelta to the vector needed to move
- vdestdelta = self.finaldest - self.origin;
-
- // calculate length of vector
- len = vlen (vdestdelta);
-
- if (current.spawnflags & PATH_ROTATE_MOVETIME)
+ else if (targ_rotate.wait)
{
- traveltime = current.speed;
+ // TODO CEV
+ this.think1 = rotate_train_wait;
}
else
{
- // check if there's a speed change
- if (current.speed > 0)
- self.speed = current.speed;
-
- if (!self.speed)
- objerror ("No speed is defined!");
+ // TODO CEV
+ this.think1 = rotate_train_next;
+ }

- // divide by speed to get time to reach dest
- traveltime = len / self.speed;
+ if (current.event != "")
+ {
+ // Trigger any events that should happen at the corner.
+ temp = this.target;
+ this.target = current.event;
+ this.message = current.message;
+ sub_usetargets ();
+ this.target = temp;
+ this.message = string_null;
}

- if (traveltime < 0.1)
+ if (current.spawnflags & PATH_ROTATE_ANGLES)
{
- self.velocity = '0 0 0';
- self.endtime = self.ltime + 0.1;
- if (targ.spawnflags & PATH_ROTATE_ANGLES)
- {
- self.angles = targ.angles;
- }
- return;
+ this.rotate = '0 0 0';
+ this.angles = this.finalangle;
}

- // qcc won't take vec/float
- div = 1 / traveltime;
+ if (current.spawnflags & PATH_ROTATE_ROTATION)
+ {
+ this.rotate = current.rotate;
+ }

- if (targ.spawnflags & PATH_ROTATE_ANGLES)
+ if (current.spawnflags & PATH_ROTATE_DAMAGE)
{
- self.finalangle = SUB_NormalizeAngles (targ.angles);
- self.rotate = (targ.angles - self.angles) * div;
+ this.dmg = current.dmg;
}

- // set endtime to trigger a think when dest is reached
- self.endtime = self.ltime + traveltime;
+ if (current.spawnflags & PATH_ROTATE_SET_DAMAGE)
+ {
+ set_damage_on_targets (current.dmg);
+ }

- // scale the destdelta vector by the time spent
- // traveling to get velocity
- self.velocity = vdestdelta * div;
+ if (current.speed == -1)
+ {
+ // Warp to the next path_corner
+ setorigin (this, targ_rotate.origin);
+ this.endtime = this.ltime + 0.01;
+ set_target_origin ();

- self.duration = div; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = vdestdelta; // delta
- self.dest1 = self.origin; // original position
- }
-};
+ if (targ_rotate.spawnflags & PATH_ROTATE_ANGLES)
+ {
+ this.angles = targ_rotate.angles;
+ }

-//----------------------------------------------------------------------
-void() rotate_train_find =
-{
- local entity targ;
+ this.duration = 1; // 1 / duration
+ this.cnt = time; // start time
+ this.dest2 = '0 0 0'; // delta
+ this.dest1 = this.origin; // original position
+ this.finaldest = this.origin;
+ }
+ else
+ {
+ this.state = ROTATE_STATE_MOVE;

- self.state = STATE_FIND;
+ this.finaldest = targ_rotate.origin;
+ if (this.finaldest == this.origin)
+ {
+ this.velocity = '0 0 0';
+ this.endtime = this.ltime + 0.1;
+
+ this.duration = 1; // 1 / duration
+ this.cnt = time; // start time
+ this.dest2 = '0 0 0'; // delta
+ this.dest1 = this.origin; // original position
+ this.finaldest = this.origin;
+ return;
+ }
+ // set destdelta to the vector needed to move
+ vdestdelta = this.finaldest - this.origin;

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

- // the first target is the point of rotation.
- // the second target is the path.
- targ = find (world, targetname, self.path);
- if (targ.classname != "path_rotate")
- objerror ("Next target is not path_rotate");
+ if (current.spawnflags & PATH_ROTATE_MOVETIME)
+ {
+ traveltime = current.speed;
+ }
+ else
+ {
+ // check if there's a speed change
+ if (current.speed > 0)
+ this.speed = current.speed;

- // Save the current entity
- self.goalentity = targ;
+ if (!this.speed)
+ objerror ("No speed is defined!");

- if (targ.spawnflags & PATH_ROTATE_ANGLES)
- {
- self.angles = targ.angles;
- self.finalangle = SUB_NormalizeAngles (targ.angles);
- }
+ // divide by speed to get time to reach dest
+ traveltime = len / this.speed;
+ }

- self.path = targ.target;
- setorigin (self, targ.origin);
- SetTargetOrigin ();
- RotateTargetsFinal ();
- self.think1 = rotate_train_next;
+ if (traveltime < 0.1)
+ {
+ this.velocity = '0 0 0';
+ this.endtime = this.ltime + 0.1;
+ if (targ_rotate.spawnflags & PATH_ROTATE_ANGLES)
+ {
+ this.angles = targ_rotate.angles;
+ }
+ return;
+ }

- if (!self.targetname)
- {
- // not triggered, so start immediately
- self.endtime = self.ltime + 0.1;
- }
- else
- {
- self.endtime = 0;
- }
+ // qcc won't take vec/float
+ div = 1 / traveltime;

- self.duration = 1; // 1 / duration
- self.cnt = time; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
-};
+ if (targ_rotate.spawnflags & PATH_ROTATE_ANGLES)
+ {
+ finalangle = normalizeangles
+ (targ_rotate.angles);
+ rotate = (targ_rotate.angles - this.angles) *
+ div;
+ }

-//----------------------------------------------------------------------
-void() rotate_train =
-{
- objerror ("rotate_train entities should be changed to "
- "rotate_object with\nfunc_rotate_train controllers\n");
-};
+ // set endtime to trigger a think when dest is reached
+ this.endtime = this.ltime + traveltime;

-/*QUAKED func_rotate_train (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
+ // scale the destdelta vector by the time spent
+ // traveling to get velocity
+ this.velocity = vdestdelta * div;

-In path_rotate, set speed to be the new speed of the train after it reaches
-the path change. If speed is -1, the train will warp directly to the next
-path change after the specified wait time. If MOVETIME is set on the
-path_rotate, the train to interprets "speed" as the length of time to
-take moving from one corner to another.
+ this.duration = div; // 1 / duration
+ this.cnt = time; // start time
+ this.dest2 = vdestdelta; // delta
+ this.dest1 = this.origin; // original position
+ }
+ };

-"noise" contains the name of the sound to play when train stops.
-"noise1" contains the name of the sound to play when train moves.
-Both "noise" and "noise1" defaults depend upon "sounds" variable and
-can be overridden by the "noise" and "noise1" variable in path_rotate.
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_train_find =
+ {
+ local entity targ;
+ local base_rotate targ_rotate;

-Also in path_rotate, if STOP is set, the train will wait until it is
-retriggered before moving on to the next goal.
+ this.state = ROTATE_STATE_FIND;

-Trains are moving platforms that players can ride.
-"path" specifies the first path_rotate and is the starting position.
-If the train is the target of a button or trigger, it will not begin moving until activated.
-The func_rotate_train entity is the center of rotation of all objects targeted by it.
+ link_rotate_targets ();

-If "deathtype" is set with a string, this is the message that will appear when a player is killed by the train.
+ // the first target is the point of rotation.
+ // the second target is the path.
+ targ = find (world, ::targetname, this.path);
+ if (targ.classtype != CT_PATH_ROTATE)
+ objerror ("Next target is not path_rotate");

-speed default 100
-dmg default 0
-sounds
-1) ratchet metal
-*/
-void() func_rotate_train =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ // cast to base_rotate -- CEV
+ targ_rotate = (base_rotate)targ;

- if (!self.speed)
- self.speed = 100;
- if (!self.target)
- objerror ("rotate_train without a target");
+ // Save the current entity
+ this.goal_rotate = targ_rotate;

- if (!self.noise)
- {
- if (self.sounds == 0)
+ if (targ_rotate.spawnflags & PATH_ROTATE_ANGLES)
{
- self.noise = "misc/null.wav";
+ this.angles = targ_rotate.angles;
+ this.finalangle = normalizeangles (targ_rotate.angles);
}

- if (self.sounds == 1)
+ this.path = targ_rotate.target;
+ setorigin (this, targ_rotate.origin);
+ set_target_origin ();
+ rotate_targets_final ();
+ this.think1 = rotate_train_next;
+
+ if (!this.targetname)
+ {
+ // not triggered, so start immediately
+ this.endtime = this.ltime + 0.1;
+ }
+ else
{
- self.noise = "plats/train2.wav";
+ this.endtime = 0;
}
- }

- if (!self.noise1)
+ this.duration = 1; // 1 / duration
+ this.cnt = time; // start time
+ this.dest2 = '0 0 0'; // delta
+ this.dest1 = this.origin; // original position
+ };
+
+ //--------------------------------------------------------------
+ // was rotate_train_think
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (self.sounds == 0)
+ local float t, timeelapsed;
+
+ t = time - this.ltime;
+ this.ltime = time;
+
+ if ((this.endtime) && (time >= this.endtime))
{
- self.noise1 = "misc/null.wav";
- }
+ this.endtime = 0;
+ if (this.state == ROTATE_STATE_MOVE)
+ {
+ setorigin (this, this.finaldest);
+ this.velocity = '0 0 0';
+ }

- if (self.sounds == 1)
+ if (this.think1)
+ {
+ this.think1 ();
+ }
+ }
+ else
{
- self.noise1 = "plats/train1.wav";
+ timeelapsed = (time - this.cnt) * this.duration;
+ if (timeelapsed > 1)
+ timeelapsed = 1;
+ setorigin (this,
+ this.dest1 + (this.dest2 * timeelapsed));
}
- }

- precache_sound (self.noise);
- precache_sound (self.noise1);
+ this.angles = this.angles + (this.rotate * t);
+ this.angles = normalizeangles (this.angles);
+ rotate_targets ();

- self.cnt = 1;
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_STEP;
- self.use = rotate_train_use;
+ this.nextthink = time + 0.02;
+ };

- setmodel (self, self.model);
- setsize (self, self.mins, self.maxs);
- setorigin (self, self.origin);
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.think1 != rotate_train_find)
+ {
+ if (this.velocity != '0 0 0')
+ // already activated
+ return;
+ if (this.think1)
+ {
+ this.think1 ();
+ }
+ }
+ };

- // start trains on the second frame, to make sure their targets
- // have had a chance to spawn
- self.ltime = time;
- self.nextthink = self.ltime + 0.1;
- self.endtime = self.ltime + 0.1;
- self.think = rotate_train_think;
- self.think1 = rotate_train_find;
- self.state = STATE_FIND;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (!this.speed)
+ this.speed = 100;
+ if (!this.target)
+ objerror ("rotate_train without a target");

- self.duration = 1; // 1 / duration
- self.cnt = 0.1; // start time
- self.dest2 = '0 0 0'; // delta
- self.dest1 = self.origin; // original position
+ if (!this.noise)
+ {
+ if (this.sounds == 0)
+ {
+ this.noise = "misc/null.wav";
+ }

- self.flags = self.flags | FL_ONGROUND;
-};
+ if (this.sounds == 1)
+ {
+ this.noise = "plats/train2.wav";
+ }
+ }

-//======================================================================
-// Moving clip walls
-//======================================================================
+ if (!this.noise1)
+ {
+ if (this.sounds == 0)
+ {
+ this.noise1 = "misc/null.wav";
+ }

-// prototypes
-void() rotate_door_reversedirection;
-void() rotate_door_group_reversedirection;
+ if (this.sounds == 1)
+ {
+ this.noise1 = "plats/train1.wav";
+ }
+ }

-//----------------------------------------------------------------------
-void() movewall_touch =
-{
- if (time < self.owner.attack_finished)
- return;
+ precache_sound (this.noise);
+ precache_sound (this.noise1);

- if (self.dmg)
- {
- T_Damage (other, self, self.owner, self.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- else if (self.owner.dmg)
- {
- T_Damage (other, self, self.owner, self.owner.dmg);
- self.owner.attack_finished = time + 0.5;
- }
-};
+ this.cnt = 1;
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_STEP;

-//----------------------------------------------------------------------
-void() movewall_blocked =
-{
- local entity temp;
+ setmodel (this, this.model);
+ setsize (this, this.mins, this.maxs);
+ setorigin (this, this.origin);

- if (time < self.owner.attack_finished)
- return;
+ // start trains on the second frame, to make sure their
+ // targets have had a chance to spawn
+ this.ltime = time;
+ this.nextthink = this.ltime + 0.1;
+ this.endtime = this.ltime + 0.1;
+ // TODO CEV
+ // this.think = rotate_train_think;
+ this.think1 = rotate_train_find;
+ this.state = ROTATE_STATE_FIND;

- self.owner.attack_finished = time + 0.5;
+ this.duration = 1; // 1 / duration
+ this.cnt = 0.1; // start time
+ this.dest2 = '0 0 0'; // delta
+ this.dest1 = this.origin; // original position

- if (self.owner.classname == "func_rotate_door")
- {
- temp = self;
- self = self.owner;
- rotate_door_group_reversedirection ();
- self = temp;
- }
+ this.flags = this.flags | FL_ONGROUND;
+ };

- if (self.dmg)
+ //--------------------------------------------------------------
+ void() func_rotate_train =
{
- T_Damage (other, self, self.owner, self.dmg);
- self.owner.attack_finished = time + 0.5;
- }
- else if (self.owner.dmg)
- {
- T_Damage (other, self, self.owner, self.owner.dmg);
- self.owner.attack_finished = time + 0.5;
- }
+ this.classtype = CT_FUNC_ROTATE_TRAIN;
+ };
};

-//----------------------------------------------------------------------
-void() movewall_think =
+//------------------------------------------------------------------------------
+void() rotate_train =
{
- self.ltime = time;
- self.nextthink = time + 0.02;
+ objerror ("rotate_train entities should be changed to "
+ "rotate_object with\nfunc_rotate_train controllers\n");
};

+
+//------------------------------------------------------------------------------
+// Moving clip walls
+//------------------------------------------------------------------------------
+
/*QUAKED func_movewall (0 .5 .8) ? VISIBLE TOUCH NONBLOCKING X X X X X NOT_ON_EASY NOT_ON_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 to emulate collision on rotating objects.
@@ -927,210 +1029,97 @@ NONBLOCKING makes the brush non-solid. This is useless if VISIBLE is set.

"dmg" specifies the damage to cause when touched or blocked.
*/
-void() func_movewall =
+class func_movewall: base_rotate
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.angles = '0 0 0';
- self.movetype = MOVETYPE_PUSH;
-
- if (self.spawnflags & MOVEWALL_NONBLOCKING)
- {
- self.solid = SOLID_NOT;
- }
- else
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- self.solid = SOLID_BSP;
- self.blocked = movewall_blocked;
- }
+ if (!(this.spawnflags & MOVEWALL_TOUCH))
+ return;

- if (self.spawnflags & MOVEWALL_TOUCH)
- {
- self.touch = movewall_touch;
- }
+ if (time < this.owner.attack_finished)
+ return;

- setmodel (self,self.model);
+ if (this.dmg)
+ {
+ T_Damage (toucher, this, this.owner, this.dmg);
+ this.owner.attack_finished = time + 0.5;
+ }
+ else if (this.owner.dmg)
+ {
+ T_Damage (toucher, this, this.owner, this.owner.dmg);
+ this.owner.attack_finished = time + 0.5;
+ }
+ };

- if (!(self.spawnflags & MOVEWALL_VISIBLE))
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
{
- self.model = string_null;
- }
-
- self.think = movewall_think;
- self.nextthink = time + 0.02;
- self.ltime = time;
-};
-
-/*QUAKED rotate_object (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
-This defines an object to be rotated. Used as the target of func_rotate_door.
-*/
-void() rotate_object =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.classname = "rotate_object";
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self,self.model);
- setsize (self, self.mins, self.maxs);
- self.think = SUB_Null;
-};
-
-//======================================================================
-// Rotating doors
-//======================================================================
-
-//----------------------------------------------------------------------
-void() rotate_door_think2 =
-{
- local float t;
-
- t = time - self.ltime;
- self.ltime = time;
+ if (this.solid == SOLID_NOT)
+ return;

- // change to alternate textures
- self.frame = 1 - self.frame;
+ if (time < this.owner.attack_finished)
+ return;

- self.angles = self.dest;
+ this.owner.attack_finished = time + 0.5;

- if (self.state == STATE_OPENING)
- {
- self.state = STATE_OPEN;
- }
- else
- {
- if (self.spawnflags & ROTATE_DOOR_STAYOPEN)
+ if (this.owner.classtype == CT_FUNC_ROTATE_DOOR)
{
- rotate_door_group_reversedirection ();
- return;
+ local func_rotate_door fdr;
+ fdr = (func_rotate_door)this.owner;
+ fdr.rotate_door_group_reversedirection ();
}
- self.state = STATE_CLOSED;
- }
-
- sound (self, CHAN_VOICE, self.noise3, 1, ATTN_NORM);
- self.think = SUB_Null;

- RotateTargetsFinal ();
-};
-
-//----------------------------------------------------------------------
-void() rotate_door_think =
-{
- local float t;
-
- t = time - self.ltime;
- self.ltime = time;
+ if (this.dmg)
+ {
+ T_Damage (blocker, this, this.owner, this.dmg);
+ this.owner.attack_finished = time + 0.5;
+ }
+ else if (this.owner.dmg)
+ {
+ T_Damage (blocker, this, this.owner, this.owner.dmg);
+ this.owner.attack_finished = time + 0.5;
+ }
+ };

- if (time < self.endtime)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.angles = self.angles + (self.rotate * t);
- RotateTargets ();
- }
- else
- {
- self.angles = self.dest;
- RotateTargets ();
- self.think = rotate_door_think2;
- }
-
- self.nextthink = time + 0.01;
-};
-
-//----------------------------------------------------------------------
-void() rotate_door_reversedirection =
-{
- local vector start;
-
- // change to alternate textures
- self.frame = 1 - self.frame;
+ this.ltime = time;
+ this.nextthink = time + 0.02;
+ };

- if (self.state == STATE_CLOSING)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- start = self.dest1;
- self.dest = self.dest2;
- self.state = STATE_OPENING;
- }
- else
- {
- start = self.dest2;
- self.dest = self.dest1;
- self.state = STATE_CLOSING;
- }
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-
- self.rotate = (self.dest - start) * (1 / self.speed);
- self.think = rotate_door_think;
- self.nextthink = time + 0.02;
- self.endtime = time + self.speed - (self.endtime - time);
- self.ltime = time;
-};
+ this.angles = '0 0 0';
+ this.movetype = MOVETYPE_PUSH;

-//----------------------------------------------------------------------
-void() rotate_door_group_reversedirection =
-{
- local string name;
-
- // tell all associated rotaters to reverse direction
- if (self.group != "")
- {
- name = self.group;
- self = find (world, group, name);
- while (self)
- {
- rotate_door_reversedirection ();
- self = find (self, group, name);
- }
- }
- else
- {
- rotate_door_reversedirection ();
- }
-};
-
-//----------------------------------------------------------------------
-void() rotate_door_use =
-{
- local vector start;
+ if (this.spawnflags & MOVEWALL_NONBLOCKING)
+ this.solid = SOLID_NOT;
+ else
+ this.solid = SOLID_BSP;

- if ((self.state != STATE_OPEN) && (self.state != STATE_CLOSED))
- return;
+ setmodel (this,this.model);

- if (!self.cnt)
- {
- self.cnt = 1;
- LinkRotateTargets ();
- }
+ if (!(this.spawnflags & MOVEWALL_VISIBLE))
+ this.model = string_null;

- // change to alternate textures
- self.frame = 1 - self.frame;
+ this.nextthink = time + 0.02;
+ this.ltime = time;
+ };

- if (self.state == STATE_CLOSED)
- {
- start = self.dest1;
- self.dest = self.dest2;
- self.state = STATE_OPENING;
- }
- else
+ //--------------------------------------------------------------
+ void() func_movewall =
{
- start = self.dest2;
- self.dest = self.dest1;
- self.state = STATE_CLOSING;
- }
-
- sound (self, CHAN_VOICE, self.noise2, 1, ATTN_NORM);
-
- self.rotate = (self.dest - start) * (1 / self.speed);
- self.think = rotate_door_think;
- self.nextthink = time + 0.01;
- self.endtime = time + self.speed;
- self.ltime = time;
+ this.classtype = CT_FUNC_MOVEWALL;
+ };
};

+//------------------------------------------------------------------------------
+// Rotating doors
+//------------------------------------------------------------------------------
+
/*QUAKED func_rotate_door (0 .5 .8) (-8 -8 -8) (8 8 8) STAYOPEN 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 door that rotates between two positions around a point of
@@ -1147,92 +1136,263 @@ once door from closing again when it's blocked.
2) metal
3) base
*/
-void() func_rotate_door =
+class func_rotate_door: base_rotate
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ float second_think;

- if (!self.target)
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_door_reversedirection =
{
- objerror ("rotate_door without target.");
- }
+ local vector start;

- self.dest1 = '0 0 0';
- self.dest2 = self.angles;
- self.angles = self.dest1;
+ // change to alternate textures
+ this.frame = 1 - this.frame;

- // default to 2 seconds
- if (!self.speed)
- {
- self.speed = 2;
- }
+ if (this.state == ROTATE_STATE_CLOSING)
+ {
+ start = this.dest1;
+ this.dest = this.dest2;
+ this.state = ROTATE_STATE_OPENING;
+ }
+ else
+ {
+ start = this.dest2;
+ this.dest = this.dest1;
+ this.state = ROTATE_STATE_CLOSING;
+ }

- self.cnt = 0;
+ sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);

- if (!self.dmg)
- {
- self.dmg = 2;
- }
- else if (self.dmg < 0)
- {
- self.dmg = 0;
- }
+ this.rotate = (this.dest - start) * (1 / this.speed);
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.second_think = FALSE;
+ this.nextthink = time + 0.02;
+ this.endtime = time + this.speed - (this.endtime - time);
+ this.ltime = time;
+ };

- if (self.sounds == 0)
+ //--------------------------------------------------------------
+ nonvirtual void() rotate_door_group_reversedirection =
{
- // If at least one custom sound is defined, then let's
- // ignore the presets and go for the custom sounds,
- // otherwise let's use preset #1 by default
- if (self.noise1=="" && self.noise2=="" && self.noise3=="")
+ local string name;
+ local entity g_ent;
+ local func_rotate_door g_rot;
+
+ // tell all associated rotaters to reverse direction
+ if (this.group != __NULL__ && this.group != "")
{
- self.sounds = 1;
+ name = this.group;
+ g_ent = find (world, func_rotate_door::group, name);
+ while (g_ent)
+ {
+ if (g_ent.classgroup & CT_FUNC_ROTATE_DOOR)
+ {
+ // cast to func_rotate_door -- CEV
+ g_rot = (func_rotate_door)g_ent;
+ g_rot.rotate_door_reversedirection ();
+ }
+ g_ent = find (this, func_rotate_door::group,
+ name);
+ }
}
else
{
- if (self.noise1=="")
- self.noise1 = "misc/null.wav";
- if (self.noise2=="")
- self.noise2 = "misc/null.wav";
- if (self.noise3=="")
- self.noise3 = "misc/null.wav";
+ rotate_door_reversedirection ();
}
- }
+ };

- if (self.sounds == 1)
- {
- self.noise1 = "doors/latch2.wav";
- self.noise2 = "doors/winch2.wav";
- self.noise3 = "doors/drclos4.wav";
- }
- else if (self.sounds == 2)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.noise2 = "doors/airdoor1.wav";
- self.noise1 = "doors/airdoor2.wav";
- self.noise3 = self.noise1;
- }
- else if (self.sounds == 3)
+ local float t;
+
+ if (!this.second_think)
+ {
+ // was rotate_door_think -- CEV
+ t = time - this.ltime;
+ this.ltime = time;
+
+ if (time < this.endtime)
+ {
+ this.angles = this.angles + (this.rotate * t);
+ rotate_targets ();
+ }
+ else
+ {
+ this.angles = this.dest;
+ rotate_targets ();
+ this.second_think = TRUE;
+ this.interaction_flags &= ~DISABLE_THINK;
+ }
+
+ this.nextthink = time + 0.01;
+ }
+ else
+ {
+ // was rotate_door_think2 -- CEV
+ t = time - this.ltime;
+ this.ltime = time;
+
+ // change to alternate textures
+ this.frame = 1 - this.frame;
+ this.angles = this.dest;
+
+ if (this.state == ROTATE_STATE_OPENING)
+ {
+ this.state = ROTATE_STATE_OPEN;
+ }
+ else
+ {
+ if (this.spawnflags & ROTATE_DOOR_STAYOPEN)
+ {
+ rotate_door_group_reversedirection ();
+ return;
+ }
+ this.state = ROTATE_STATE_CLOSED;
+ }
+
+ sound (this, CHAN_VOICE, this.noise3, 1, ATTN_NORM);
+ this.interaction_flags |= DISABLE_THINK;
+
+ rotate_targets_final ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- self.noise2 = "doors/basesec1.wav";
- self.noise1 = "doors/basesec2.wav";
- self.noise3 = self.noise1;
- }
- else if (self.sounds == 4)
+ local vector start;
+
+ if ((this.state != ROTATE_STATE_OPEN) &&
+ (this.state != ROTATE_STATE_CLOSED))
+ {
+ return;
+ }
+
+ if (!this.cnt)
+ {
+ this.cnt = 1;
+ link_rotate_targets ();
+ }
+
+ // change to alternate textures
+ this.frame = 1 - this.frame;
+
+ if (this.state == ROTATE_STATE_CLOSED)
+ {
+ start = this.dest1;
+ this.dest = this.dest2;
+ this.state = ROTATE_STATE_OPENING;
+ }
+ else
+ {
+ start = this.dest2;
+ this.dest = this.dest1;
+ this.state = ROTATE_STATE_CLOSING;
+ }
+
+ sound (this, CHAN_VOICE, this.noise2, 1, ATTN_NORM);
+
+ this.rotate = (this.dest - start) * (1 / this.speed);
+ this.second_think = FALSE;
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.nextthink = time + 0.01;
+ this.endtime = time + this.speed;
+ this.ltime = time;
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // added slinet option - sounds 4 -- dumptruck_ds
- self.noise1 = self.noise2 = self.noise3 = "misc/null.wav";
- }
-
- precache_sound (self.noise1);
- precache_sound (self.noise2);
- precache_sound (self.noise3);
-
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, self.model);
- setorigin (self, self.origin);
- setsize (self, self.mins, self.maxs);
- self.state = STATE_CLOSED;
- self.use = rotate_door_use;
- self.think = SUB_Null;
+ if (!this.target)
+ {
+ objerror ("rotate_door without target.");
+ }
+
+ this.dest1 = '0 0 0';
+ this.dest2 = this.angles;
+ this.angles = this.dest1;
+
+ // default to 2 seconds
+ if (!this.speed)
+ {
+ this.speed = 2;
+ }
+
+ this.cnt = 0;
+
+ if (!this.dmg)
+ {
+ this.dmg = 2;
+ }
+ else if (this.dmg < 0)
+ {
+ this.dmg = 0;
+ }
+
+ if (this.sounds == 0)
+ {
+ // If at least one custom sound is defined, then let's
+ // ignore the presets and go for the custom sounds,
+ // otherwise let's use preset #1 by default
+ if (this.noise1 == "" && this.noise2 == "" &&
+ this.noise3 == "")
+ {
+ this.sounds = 1;
+ }
+ else
+ {
+ if (this.noise1 == "")
+ this.noise1 = "misc/null.wav";
+ if (this.noise2 == "")
+ this.noise2 = "misc/null.wav";
+ if (this.noise3 == "")
+ this.noise3 = "misc/null.wav";
+ }
+ }
+
+ if (this.sounds == 1)
+ {
+ this.noise1 = "doors/latch2.wav";
+ this.noise2 = "doors/winch2.wav";
+ this.noise3 = "doors/drclos4.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ this.noise2 = "doors/airdoor1.wav";
+ this.noise1 = "doors/airdoor2.wav";
+ this.noise3 = this.noise1;
+ }
+ else if (this.sounds == 3)
+ {
+ this.noise2 = "doors/basesec1.wav";
+ this.noise1 = "doors/basesec2.wav";
+ this.noise3 = this.noise1;
+ }
+ else if (this.sounds == 4)
+ {
+ // added silent option - sounds 4 -- dumptruck_ds
+ this.noise1 = this.noise2 = "misc/null.wav";
+ this.noise3 = "misc/null.wav";
+ }
+
+ precache_sound (this.noise1);
+ precache_sound (this.noise2);
+ precache_sound (this.noise3);
+
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+ setmodel (this, this.model);
+ setorigin (this, this.origin);
+ setsize (this, this.mins, this.maxs);
+ this.state = ROTATE_STATE_CLOSED;
+ this.interaction_flags |= DISABLE_THINK;
+ this.second_think = FALSE;
+ };
+
+ //--------------------------------------------------------------
+ void() func_rotate_door =
+ {
+ this.classtype = CT_FUNC_ROTATE_DOOR;
+ };
};

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 daa936e..e3028f2 100644
--- a/qc/func/shadow.qc
+++ b/qc/func/shadow.qc
@@ -2,103 +2,19 @@
// func_shadow -- An invisible bmodel that can be used to only cast shadows.
//==============================================================================

-.float speed2;
+//======================================================================
+// switchable shadow fields
+//======================================================================
+/*
+.float switchshadstyle;
+.float shadowoff;
+.entity shadowcontroller;
+*/

// constants
const float SHADOWCONTROLLER_STARTOFF = 1;

-//----------------------------------------------------------------------
-void() shadow_fade_out =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint (ftos(self.count));
- dprint ("\n");
-
- lightstyle (self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count + self.dmg;
- if (self.count > 12)
- return;
-
- self.think = shadow_fade_out;
- self.nextthink = time + self.delay;
-};
-
-//----------------------------------------------------------------------
-void() shadow_fade_in =
-{
- if (self.count < 0)
- self.count = 0;
- if (self.count > 12)
- self.count = 12;
-
- dprint (ftos(self.count));
- dprint ("\n");
-
- lightstyle (self.switchshadstyle, lightstyle_fade_lookup(self.count));
- self.count = self.count - self.dmg;
- if (self.count < 0)
- return;
-
- self.think = shadow_fade_in;
- self.nextthink = time + self.delay;
-};
-
-//----------------------------------------------------------------------
-void(float speed) misc_shadowcontroller_setsteps =
-{
- // self.delay -> time between steps
- // self.dmg -> step size
- if (speed >= 0.24)
- {
- self.delay = (speed / 12);
- self.dmg = 1;
- }
- else if (speed >= 0.12)
- {
- self.delay = (speed / 6);
- self.dmg = 2;
- }
- else if (speed >= 0.06)
- {
- self.delay = (speed / 3);
- self.dmg = 4;
- }
- else if (speed >= 0.04)
- {
- self.delay = (speed / 2);
- self.dmg = 6;
- }
- else
- {
- self.delay = 0;
- self.dmg = 12;
- }
-};
-
-//----------------------------------------------------------------------
-void() misc_shadowcontroller_use =
-{
- if (self.shadowoff)
- {
- dprint ("Fade in:\n");
- misc_shadowcontroller_setsteps (self.speed);
- shadow_fade_in ();
- self.shadowoff = 0;
- }
- else
- {
- dprint ("Fade out:\n");
- misc_shadowcontroller_setsteps (self.speed2);
- shadow_fade_out ();
- self.shadowoff = 1;
- }
-};
-
-//----------------------------------------------------------------------
+//------------------------------------------------------------------------------
// misc_shadowcontroller
//
// Controls switchable shadows on any bmodel entity (except doors).
@@ -109,88 +25,231 @@ void() misc_shadowcontroller_use =
// speed2: Same as 'speed' but for the fade out animation. If unset it's
// the same value as 'speed'.
// spawnflag 1: target shadow starts as disabled
-//----------------------------------------------------------------------
-void() misc_shadowcontroller =
+//------------------------------------------------------------------------------
+class misc_shadowcontroller: base_mapentity
{
- entity t1;
+ float fading;
+ float speed2;

- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "speed2":
+ speed2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() fade_out =
+ {
+ if (this.count < 0)
+ this.count = 0;
+ if (this.count > 12)
+ this.count = 12;
+
+ if (this.fading >= 0)
+ this.fading = -1;
+
+ /*
+ dprint (ftos(this.count));
+ dprint ("\n");
+ */
+
+ lightstyle (this.switchshadstyle,
+ lightstyle_fade_lookup(this.count));
+ this.count = this.count + this.dmg;
+ if (this.count > 12)
+ return;
+
+ this.nextthink = time + this.delay;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() fade_in =
+ {
+ if (this.count < 0)
+ this.count = 0;
+ if (this.count > 12)
+ this.count = 12;
+
+ if (this.fading <= 0)
+ this.fading = 1;
+
+ /*
+ dprint (ftos(this.count));
+ dprint ("\n");
+ */
+
+ lightstyle (this.switchshadstyle,
+ lightstyle_fade_lookup(this.count));
+ this.count = this.count - this.dmg;
+ if (this.count < 0)
+ return;

+ this.nextthink = time + this.delay;
+ };

- // doesn't search for a target if switchshadstyle is already set
- // used for built-in shadow controllers
- if (!self.switchshadstyle)
+ //--------------------------------------------------------------
+ nonvirtual void(float speed) setsteps =
{
- // we need to find only the first target entity with
- // switchable shadows set, since shadow lightstyles
- // are bound by targetname
- t1 = find (world, targetname2, self.target);
+ // this.delay -> time between steps
+ // this.dmg -> step size
+ if (speed >= 0.24)
+ {
+ this.delay = (speed / 12);
+ this.dmg = 1;
+ }
+ else if (speed >= 0.12)
+ {
+ this.delay = (speed / 6);
+ this.dmg = 2;
+ }
+ else if (speed >= 0.06)
+ {
+ this.delay = (speed / 3);
+ this.dmg = 4;
+ }
+ else if (speed >= 0.04)
+ {
+ this.delay = (speed / 2);
+ this.dmg = 6;
+ }
+ else
+ {
+ this.delay = 0;
+ this.dmg = 12;
+ }
+ };

- while (t1 != world && !t1.switchshadstyle)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.fading < 0)
+ this.fade_out ();
+ else if (this.fading > 0)
+ this.fade_in ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.shadowoff)
+ {
+ /*
+ dprint ("Fade in:\n");
+ */
+ setsteps (this.speed);
+ fade_in ();
+ this.shadowoff = 0;
+ }
+ else
{
- t1 = find (t1, targetname2, self.target);
+ /*
+ dprint ("Fade out:\n");
+ */
+ setsteps (this.speed2);
+ fade_out ();
+ this.shadowoff = 1;
}
+ };

- if (t1 == world)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ entity t1;
+
+ // doesn't search for a target if switchshadstyle is already set
+ // used for built-in shadow controllers
+ if (!this.switchshadstyle)
{
- t1 = find (world, targetname, self.target);
+ // we need to find only the first target entity with
+ // switchable shadows set, since shadow lightstyles
+ // are bound by targetname
+ t1 = find (world, ::targetname2, this.target);

while (t1 != world && !t1.switchshadstyle)
{
- t1 = find (t1, targetname, self.target);
+ t1 = find (t1, ::targetname2, this.target);
}
- }

- if (t1 == world)
- {
- dprint ("\b[misc_shadowcontroller]\b "
- "_switchableshadow not set in target ");
- dprint (self.target);
- dprint ("\n");
- return;
+ if (t1 == world)
+ {
+ t1 = find (world, ::targetname, this.target);
+
+ while (t1 != world && !t1.switchshadstyle)
+ {
+ t1 = find (t1, ::targetname,
+ this.target);
+ }
+ }
+
+ if (t1 == world)
+ {
+ dprint ("\b[misc_shadowcontroller]\b "
+ "_switchableshadow not set in target ");
+ dprint (this.target);
+ dprint ("\n");
+ return;
+ }
+
+ this.switchshadstyle = t1.switchshadstyle;
}

- self.switchshadstyle = t1.switchshadstyle;
- }
+ this.fading = 0;

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

- if (self.spawnflags & SHADOWCONTROLLER_STARTOFF)
- {
- lightstyle (self.switchshadstyle, "m");
+ if (this.spawnflags & SHADOWCONTROLLER_STARTOFF)
+ {
+ lightstyle (this.switchshadstyle, "m");

- self.shadowoff = 1;
- self.count = 12;
+ this.shadowoff = 1;
+ this.count = 12;

- misc_shadowcontroller_setsteps (self.speed2);
- }
- else
- {
- lightstyle (self.switchshadstyle, "a");
- self.shadowoff = 0;
- self.count = 0;
- misc_shadowcontroller_setsteps (self.speed);
- }
+ setsteps (this.speed2);
+ }
+ else
+ {
+ lightstyle (this.switchshadstyle, "a");
+ this.shadowoff = 0;
+ this.count = 0;
+ setsteps (this.speed);
+ }
+ };

- self.use = misc_shadowcontroller_use;
+ //--------------------------------------------------------------
+ void() misc_shadowcontroller =
+ {
+ this.classname = "misc_shadowcontroller";
+ this.classtype = CT_MISC_SHADOWCONTROLLER;
+ };
};

-//----------------------------------------------------------------------
-void() func_shadow =
+//------------------------------------------------------------------------------
+class func_shadow: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.angles = '0 0 0';
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_NOT;

- self.angles = '0 0 0';
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_NOT;
+ this.modelindex = 0;
+ this.model = "";
+ };

- self.modelindex = 0;
- self.model = "";
+ //--------------------------------------------------------------
+ void() func_shadow =
+ {
+ this.classtype = CT_FUNC_SHADOW;
+ };
};

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

Diff qc/func/togglevisiblewall.qc

diff --git a/qc/func/togglevisiblewall.qc b/qc/func/togglevisiblewall.qc
index 6afd14f..d483970 100644
--- a/qc/func/togglevisiblewall.qc
+++ b/qc/func/togglevisiblewall.qc
@@ -14,55 +14,58 @@
const float TOGGLEVISWALL_STARTOFF = 1;
const float TOGGLEVISWALL_NOTSOLID = 2;

-//----------------------------------------------------------------------
-void() func_togglevisiblewall_use =
+class func_togglevisiblewall: base_func
{
- if (!self.state)
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- if (!(self.spawnflags & TOGGLEVISWALL_NOTSOLID))
+ if (!this.state)
{
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
+ if (!(this.spawnflags & TOGGLEVISWALL_NOTSOLID))
+ {
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ }
+ setmodel (this, this.origmodel);
+ if (this.switchshadstyle)
+ lightstyle (this.switchshadstyle, "a");
+ this.state = 1;
}
- setmodel (self, self.origmodel);
- if (self.switchshadstyle)
- lightstyle (self.switchshadstyle, "a");
- self.state = 1;
- }
- else
+ else
+ {
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+ setmodel (this, "");
+ if (this.switchshadstyle)
+ lightstyle (this.switchshadstyle, "m");
+ this.state = 0;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
+ this.angles = '0 0 0';

- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- setmodel (self, "");
- if (self.switchshadstyle)
- lightstyle (self.switchshadstyle, "m");
- self.state = 0;
- }
-};
+ this.origmodel = this.model;

-//----------------------------------------------------------------------
-void() func_togglevisiblewall =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ if (this.spawnflags & TOGGLEVISWALL_STARTOFF)
+ this.state = 1;
+ else
+ this.state = 0;

- self.angles = '0 0 0';
- self.use = func_togglevisiblewall_use;
-
- self.origmodel = self.model;
+ if (this.spawnflags & TOGGLEVISWALL_NOTSOLID)
+ {
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NONE;
+ }

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

- if (self.spawnflags & TOGGLEVISWALL_NOTSOLID)
+ //--------------------------------------------------------------
+ void() func_togglevisiblewall =
{
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NONE;
- }
-
- func_togglevisiblewall_use ();
+ this.classtype = CT_FUNC_TOGGLEVISIBLEWALL;
+ };
};

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 88df402..b604e53 100644
--- a/qc/func/togglewall.qc
+++ b/qc/func/togglewall.qc
@@ -11,36 +11,6 @@
// constants
const float TOGGLEWALL_START_OFF = 1;

-//----------------------------------------------------------------------
-void() blocker_touch =
-{
- if (!self.dmg)
- return;
-
- if (time < self.attack_finished)
- return;
- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
-};
-
-//----------------------------------------------------------------------
-void() blocker_use =
-{
- if (!self.state)
- {
- self.state = 1;
- setorigin (self, self.origin - '8000 8000 8000');
- // sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- }
- else
- {
- self.state = 0;
- setorigin (self, self.origin + '8000 8000 8000');
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
-};
-
/*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.
@@ -51,44 +21,76 @@ TOGGLEWALL_START_OFF wall doesn't block until triggered.
"noise1" is the sound to play when wall is blocking.
"dmg" is the amount of damage to cause when touched.
*/
-void() func_togglewall =
+class func_togglewall: base_func
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- self.classname = "togglewall";
- self.movetype = MOVETYPE_PUSH;
- self.mdl = self.model;
- setmodel (self, self.model);
- setsize (self, self.mins, self.maxs);
- setorigin (self, self.origin);
- self.touch = blocker_touch;
- self.use = blocker_use;
- if (!self.noise)
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
- self.noise = "misc/null.wav";
- }
+ if (!this.dmg)
+ return;

- if ( !self.noise1 )
- {
- self.noise1 = "misc/null.wav";
- }
+ if (time < this.attack_finished)
+ return;

- precache_sound (self.noise);
- precache_sound (self.noise1);
+ this.attack_finished = time + 0.5;
+ T_Damage (toucher, this, this, this.dmg);
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ };

- self.solid = SOLID_BSP;
- self.model = string_null;
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (!this.state)
+ {
+ this.state = 1;
+ setorigin (this, this.origin - '8000 8000 8000');
+ // sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ }
+ else
+ {
+ this.state = 0;
+ setorigin (this, this.origin + '8000 8000 8000');
+ sound (this, CHAN_VOICE, this.noise, 1, ATTN_NORM);
+ }
+ };

- if (self.spawnflags & TOGGLEWALL_START_OFF)
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- self.state = 0;
- setorigin (self, self.origin + '8000 8000 8000');
- }
- else
+ this.movetype = MOVETYPE_PUSH;
+ this.mdl = this.model;
+ setmodel (this, this.model);
+ setsize (this, this.mins, this.maxs);
+ setorigin (this, this.origin);
+
+ if (!this.noise)
+ this.noise = "misc/null.wav";
+
+ if (!this.noise1)
+ this.noise1 = "misc/null.wav";
+
+ precache_sound (this.noise);
+ precache_sound (this.noise1);
+
+ this.solid = SOLID_BSP;
+ this.model = string_null;
+
+ if (this.spawnflags & TOGGLEWALL_START_OFF)
+ {
+ this.state = 0;
+ setorigin (this, this.origin + '8000 8000 8000');
+ }
+ else
+ {
+ this.state = 1;
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() func_togglewall =
{
- self.state = 1;
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
- }
+ this.classname = "togglewall";
+ this.classtype = CT_FUNC_TOGGLEWALL;
+ };
};

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 4e28eb3..81fb00b 100644
--- a/qc/func/train.qc
+++ b/qc/func/train.qc
@@ -2,8 +2,6 @@
// func_train
//==============================================================================

-.float speed2;
-
// constants
const float TRAIN_RETRIGGER = 1;
const float TRAIN_MOVEONTRIGGER = 2;
@@ -17,312 +15,409 @@ const float TRAIN_NEXT_WAIT = 0; // normal movement
const float TRAIN_NEXT_STOP = 1; // force a stop on the next path_corner
const float TRAIN_NEXT_CONTINUE = 2; // force continue on the next
// path_corner (ignores wait time)
-const float TRAIN_STYLE_SINGLEANIM = 1;
-
-const float TRAIN_ANIMTYPE_FORWARD = 1;
-const float TRAIN_ANIMTYPE_BACKFORTH = 2;

-// prototypes
-void() train_next;
-void() func_train_find;
-
-//----------------------------------------------------------------------
-void() train_blocked =
+//------------------------------------------------------------------------------
+class base_func_train: base_func
{
- if (time < self.attack_finished)
- return;
+ float find_think;
+ float moving_use;
+ float speed2;

- self.attack_finished = time + 0.5;
- T_Damage (other, self, self, self.dmg);
-};
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "speed2":
+ speed2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };

-//----------------------------------------------------------------------
-// Use function for when the train is stopped.
-// Makes the train continue on path_corners with wait -1,
-// or forces a continue if the "move on trigger" spawnflag is set.
-//----------------------------------------------------------------------
-void() train_use =
-{
+ //--------------------------------------------------------------
+ virtual void(entity blocker) do_blocked =
+ {
+ if (time < this.attack_finished)
+ return;

- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
+ this.attack_finished = time + 0.5;
+ T_Damage (blocker, this, this, this.dmg);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- train_next ();
- return;
- }
+ if (find_think == TRUE)
+ {
+ this.train_find ();
+ }
+ else
+ {
+ this.train_next ();
+ }
+ };
+
+ //--------------------------------------------------------------
+ // Use function for when the train is stopped.
+ // Makes the train continue on path_corners with wait -1,
+ // or forces a continue if the "move on trigger" spawnflag is set.
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.moving_use)
+ {
+ //----------------------------------------------
+ // Use function for when the train is moving.
+ // Forces a stop or an instant continue on the
+ // next path_corner depending on the spawnflag set
+ //----------------------------------------------
+ if (spawnflags & TRAIN_MOVEONTRIGGER || this.wait < 0)
+ this.cnt = TRAIN_NEXT_CONTINUE;
+ else if (this.spawnflags & TRAIN_STOPONTRIGGER)
+ this.cnt = TRAIN_NEXT_STOP;
+ return;
+ }
+
+ if (this.spawnflags & TRAIN_MOVEONTRIGGER || this.wait < 0)
+ {
+ this.train_next ();
+ return;
+ }

- // Train has already moved after startup, and has no
- // "stop on trigger" flag, so ignore activation.
- if (self.think != func_train_find && self.cnt != TRAIN_NEXT_STOP)
- return;
+ // Train has already moved after startup, and has no
+ // "stop on trigger" flag, so ignore activation.
+ if (!this.find_think && this.cnt != TRAIN_NEXT_STOP)
+ {
+ return;
+ }

- train_next ();
-};
+ train_next ();
+ };

-//----------------------------------------------------------------------
-// Use function for when the train is moving.
-// Forces a stop or an instant continue on the next path_corner depending
-// on the spawnflag set
-//----------------------------------------------------------------------
-void() train_moving_use =
-{
- if (self.spawnflags & TRAIN_MOVEONTRIGGER || self.wait < 0)
- self.cnt = TRAIN_NEXT_CONTINUE;
- else if (self.spawnflags & TRAIN_STOPONTRIGGER)
- self.cnt = TRAIN_NEXT_STOP;
-};
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlepath = { };

-//----------------------------------------------------------------------
-// path_corner has been reached, so decide what to do next
-//----------------------------------------------------------------------
-void() train_wait =
-{
- local float localtime;
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlepause = { };

- if (self.movetype == MOVETYPE_PUSH)
- localtime = self.ltime;
- else
- localtime = time;
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlestop = { };

- // ready to be re-triggered
- self.use = train_use;
+ //--------------------------------------------------------------
+ // path_corner has been reached, so decide what to do next
+ //--------------------------------------------------------------
+ nonvirtual void() train_wait =
+ {
+ local float localtime;

- // from Copper
- // Trains now fire their path_corners' targets on arrival.
- // If a player is riding the train, treat them as activator.
- activator = nextent (world);
+ if (this.movetype == MOVETYPE_PUSH)
+ localtime = this.ltime;
+ else
+ localtime = time;

- while (!EntitiesTouching(self,activator) &&
- activator.classname == "player")
- {
- activator = nextent (activator);
- }
+ // ready to be re-triggered
+ this.moving_use = FALSE;

- if (activator.classname != "player")
- // default to player1 wherever they are
+ // from Copper
+ // Trains now fire their path_corners' targets on arrival.
+ // If a player is riding the train, treat them as activator.
activator = nextent (world);

- SUB_UseEntTargets (self.enemy);
+ while (!func_door::entities_touching(this, activator) &&
+ activator.classtype == CT_PLAYER)
+ {
+ activator = nextent (activator);
+ }

- if (self.enemy.speed)
- // sets the speed from the current path_corner
- self.speed2 = self.enemy.speed;
+ if (activator.classtype != CT_PLAYER)
+ // default to player1 wherever they are
+ activator = nextent (world);

- // copies the modeltrain animation parameters set in the
- // path_corner, if any
- if (self.classname == "misc_modeltrain")
- {
- if (self.enemy.first_frame)
- self.first_frame = self.enemy.first_frame;
- if (self.enemy.last_frame)
- self.last_frame = self.enemy.last_frame;
- if (self.enemy.first_frame2)
- self.first_frame2 = self.enemy.first_frame2;
- if (self.enemy.last_frame2)
- self.last_frame2 = self.enemy.last_frame2;
- if (self.enemy.frtime)
- self.frtime = self.enemy.frtime;
- if (self.enemy.frtime2)
- self.frtime2 = self.enemy.frtime2;
- if (self.enemy.animtype)
- self.animtype = self.enemy.animtype;
- if (self.enemy.animtype2)
- self.animtype2 = self.enemy.animtype2;
- if (self.enemy.multiplier)
- self.multiplier = self.enemy.multiplier;
- }
-
- self.think = train_next;
-
- // train is moving normally and path_corner has a wait set,
- // so pause for that time.
- if (self.wait > 0 && self.cnt == TRAIN_NEXT_WAIT &&
- !(self.spawnflags & TRAIN_RETRIGGER))
- {
- // state: stopped
- self.state = 0;
- if (self.classname == "misc_modeltrain")
- SUB_CallAsSelf (self.animcontroller.think,
- self.animcontroller);
- self.nextthink = localtime + self.wait;
-
- // play stopping sound. If path_corner has a custom
- // sound, play that instead
- if (self.enemy.noise != "")
- sound (self, CHAN_WEAPON, self.enemy.noise,
- 1, ATTN_NORM);
- else
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
- }
- // train is moving normally and path_corner has no wait time,
- // or has been forced to move instantly through a triggering.
- else if (self.cnt != TRAIN_NEXT_STOP && !self.wait &&
- !(self.spawnflags & TRAIN_RETRIGGER))
- {
+ if (this.enemy.classgroup & CG_MAPENTITY)
+ {
+ // was SUB_UseEntTargets -- CEV
+ ((base_mapentity)this.enemy).sub_usetargets ();
+ }

- // play "passing by" sound, if any. If path_corner has
- // a custom one, play that instead
- if (self.enemy.noise2 != "")
- sound (self, CHAN_WEAPON, self.enemy.noise2,
- 1, ATTN_NORM);
- else if (self.noise2 != "")
- sound (self, CHAN_WEAPON, self.noise2, 1, ATTN_NORM);
+ if (this.enemy.speed)
+ // sets the speed from the current path_corner
+ this.speed2 = this.enemy.speed;

- // move instantly
- self.nextthink = -1;
- train_next ();
- }
- // path_corner has wait -1, or train has been forced to stop
- // through a triggering. Also catches the backwards compatible
- // case for the original rubicon2 "retrigger" flag.
- else
- {
- // play stopping sound. If path_corner has a custom
- // sound, play that instead
- if (self.enemy.noise != "")
- sound (self, CHAN_WEAPON, self.enemy.noise,
- 1, ATTN_NORM);
+ // hook for misc_modeltrain -- CEV
+ train_wait_handlepath ();
+ this.find_think = FALSE;
+
+ // train is moving normally and path_corner has a wait set,
+ // so pause for that time.
+ if (this.wait > 0 && this.cnt == TRAIN_NEXT_WAIT &&
+ !(this.spawnflags & TRAIN_RETRIGGER))
+ {
+ dprint (sprintf("train_wait: pause position, this "
+ "wait %g, classname %s, this.noise %s\n",
+ this.wait, this.classname, this.noise));
+
+ // state: stopped
+ this.state = 0;
+
+ // hook for misc_modeltrain -- CEV
+ train_wait_handlepause ();
+
+ // TODO CEV: there's a problem here where modeltrains
+ // aren't waiting when they should
+ this.nextthink = localtime + this.wait;
+
+ // play stopping sound. If path_corner has a custom
+ // sound, play that instead
+ if (this.enemy.noise != "")
+ sound (this, CHAN_WEAPON, this.enemy.noise,
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_VOICE, this.noise,
+ 1, ATTN_NORM);
+ }
+ // train is moving normally and path_corner has no wait time,
+ // or has been forced to move instantly through a triggering.
+ else if (this.cnt != TRAIN_NEXT_STOP && !this.wait &&
+ !(this.spawnflags & TRAIN_RETRIGGER))
+ {
+ /*
+ // testing dprint -- CEV
+ dprint ("train_wait: no wait time\n");
+ */
+ // play "passing by" sound, if any. If path_corner has
+ // a custom one, play that instead
+ if (this.enemy.noise2 != "")
+ sound (this, CHAN_WEAPON, this.enemy.noise2,
+ 1, ATTN_NORM);
+ else if (this.noise2 != "")
+ sound (this, CHAN_WEAPON, this.noise2,
+ 1, ATTN_NORM);
+
+ // move instantly
+ this.nextthink = -1;
+ train_next ();
+ }
+ // path_corner has wait -1, or train has been forced to stop
+ // through a triggering. Also catches the backwards compatible
+ // case for the original rubicon2 "retrigger" flag.
else
- sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM);
+ {
+ // testing dprint -- CEV
+ dprint ("train_wait: end position\n");
+
+ // play stopping sound. If path_corner has a custom
+ // sound, play that instead
+ if (this.enemy.noise != "")
+ sound (this, CHAN_WEAPON, this.enemy.noise,
+ 1, ATTN_NORM);
+ else
+ sound (this, CHAN_VOICE, this.noise,
+ 1, ATTN_NORM);
+
+ // state: stopped
+ this.state = 0;
+ // hook for misc_modeltrain -- CEV
+ train_wait_handlestop ();
+ this.nextthink = -1;
+ }
+ };

- // state: stopped
- self.state = 0;
+ //--------------------------------------------------------------
+ virtual void(entity targ) train_next_custom = { };

- if (self.classname == "misc_modeltrain")
- SUB_CallAsSelf (self.animcontroller.think,
- self.animcontroller);
- self.nextthink = -1;
- }
-};
+ //--------------------------------------------------------------
+ virtual void() train_next_custom2 = { };

-//----------------------------------------------------------------------
-// searches for the next path_corner and sends the train on its way
-//----------------------------------------------------------------------
-void() train_next =
-{
- local entity targ;
- vector destang, displ;
+ //--------------------------------------------------------------
+ // searches for the next path_corner and sends the train on its way
+ //--------------------------------------------------------------
+ nonvirtual void() train_next =
+ {
+ local entity targ;
+ vector displ = '0 0 0';

- destang = displ = '0 0 0';
+ targ = find (world, ::targetname, this.target);

- targ = find (world, targetname, self.target);
+ if (!targ || this.target == "")
+ objerror ("train_next: no next target");

- if (!targ || self.target == "")
- objerror ("train_next: no next target");
+ this.target = targ.target;
+
+ if (targ.wait)
+ {
+ // get the wait time from the upcoming path_corner
+
+ // wait -2 on the path_corner forces it to continue
+ // moving (no wait), even if the train has a default
+ // wait time
+ if (targ.wait == -2)
+ this.wait = 0;
+ else
+ this.wait = targ.wait;
+ }
+ else
+ {
+ // use train's current wait time otherwise
+ this.wait = this.pausetime;
+ }

- self.target = targ.target;
+ this.enemy = targ;

- // gets the wait time from the upcoming path_corner if set
- if (targ.wait)
- {
- // wait -2 on the path_corner forces it to continue moving
- // (no wait), even if the train has a default wait time
- if (targ.wait == -2)
- self.wait = 0;
+ sound (this, CHAN_VOICE, this.noise1, 1, ATTN_NORM);
+
+ if (!(!this.wait && this.cnt == TRAIN_NEXT_CONTINUE))
+ this.cnt = TRAIN_NEXT_WAIT;
+
+ // store up any premature triggerings until current
+ // movement is finished
+ this.moving_use = TRUE;
+
+ // hook for modeltrain -- CEV
+ train_next_custom (targ);
+
+ if (!this.state)
+ this.state = 1;
+
+ // if the TRAIN_CUSTOMALIGN flag is checked then the train
+ // should align with its path_corners based on the location
+ // of an "origin" brush added to the train by the mapper
+ // instead of the mins corner -therektafire
+ local float doDisplace;
+ if (this.spawnflags & TRAIN_CUSTOMALIGN)
+ doDisplace = 0.0;
else
- self.wait = targ.wait;
- }
- // uses train's current wait time otherwise
- else
+ doDisplace = 1.0;
+
+ if (this.classtype != CT_MISC_MODELTRAIN)
+ displ = this.mins;
+
+ calc_move (targ.origin - (displ * doDisplace),
+ this.speed2, train_wait);
+ };
+
+ //--------------------------------------------------------------
+ // searches for the first path_corner after the train entity is
+ // initialized
+ //--------------------------------------------------------------
+ nonvirtual void() train_find =
{
- self.wait = self.pausetime;
- }
+ local entity targ;
+ local float localtime;
+ local vector displ = '0 0 0';

- self.enemy = targ;
-
- sound (self, CHAN_VOICE, self.noise1, 1, ATTN_NORM);
+ if (this.movetype == MOVETYPE_PUSH)
+ localtime = this.ltime;
+ else
+ localtime = time;
+
+ targ = find (world, ::targetname, this.target);
+ this.target = targ.target;
+
+ local float doDisplace;
+ if (this.spawnflags & TRAIN_CUSTOMALIGN)
+ doDisplace = 0.0;
+ else
+ doDisplace = 1.0;

- if (!(!self.wait && self.cnt == TRAIN_NEXT_CONTINUE))
- self.cnt = TRAIN_NEXT_WAIT;
+ if (this.classtype != CT_MISC_MODELTRAIN)
+ displ = this.mins;

- // store up any premature triggerings until current
- // movement is finished
- self.use = train_moving_use;
+ this.enemy = targ;
+ setorigin (this, targ.origin - (displ * doDisplace));
+ if (targ.speed)
+ // uses speed from the 1st path corner if set
+ this.speed2 = targ.speed;

- if (self.classname == "misc_modeltrain")
- {
- if (!(self.spawnflags & TRAIN_NOROTATE))
+ if (!this.targetname)
{
- destang = vectoangles (targ.origin - self.origin);
- if (self.spawnflags & TRAIN_ROTATEY)
- {
- destang_x = self.angles_x;
- destang_z = self.angles_z;
- }
- if (self.multiplier > 0)
- SUB_CalcAngleMoveController (destang,
- self.speed2 * self.multiplier,
- SUB_Null, self.rotatecontroller);
- else
- self.angles = destang;
+ // not triggered, so start immediately
+ this.nextthink = localtime + 0.1;
+ this.find_think = FALSE;
}
- }
+ };

- if (!self.state)
+ //--------------------------------------------------------------
+ nonvirtual void() train_init =
{
- self.state = 1;
- if (self.classname == "misc_modeltrain" &&
- self.style != TRAIN_STYLE_SINGLEANIM)
+ if (!this.speed)
+ this.speed = 100;
+ if (!this.target)
+ objerror ("func_train without a target");
+ if (!this.dmg)
+ this.dmg = 2;
+
+ if (this.spawnflags & TRAIN_STOPONTRIGGER &&
+ this.spawnflags & TRAIN_MOVEONTRIGGER)
{
- SUB_CallAsSelf (self.animcontroller.think,
- self.animcontroller);
+ objerror ("func_train: Stop and move on trigger "
+ "set at the same time");
}
- }
-
- // if the TRAIN_CUSTOMALIGN flag is checked then the train should
- // align with its path_corners based on the location of an "origin"
- // brush added to the train by the mapper instead of the mins corner
- // -therektafire
- local float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN)
- doDisplace = 0.0;
- else
- doDisplace = 1.0;
-
- if (self.classname != "misc_modeltrain")
- displ = self.mins;
-
- SUB_CalcMove (targ.origin - (displ * doDisplace), self.speed2,
- train_wait);
-};

-//----------------------------------------------------------------------
-// searches for the first path_corner after the train entity is initialized
-//----------------------------------------------------------------------
-void() func_train_find =
-{
- local entity targ;
- local float localtime;
- local vector displ = '0 0 0';
-
- if (self.movetype == MOVETYPE_PUSH)
- localtime = self.ltime;
- else
- localtime = time;
-
- targ = find (world, targetname, self.target);
- self.target = targ.target;
-
- local float doDisplace;
- if (self.spawnflags & TRAIN_CUSTOMALIGN)
- doDisplace = 0.0;
- else
- doDisplace = 1.0;
+ if (this.sounds == 1)
+ {
+ if (this.noise == "")
+ this.noise = "plats/train2.wav";
+ if (this.noise1 == "")
+ this.noise1 = "plats/train1.wav";
+ }
+ else if (this.sounds == 2)
+ {
+ // base door sound
+ if (this.noise == "")
+ this.noise = "doors/hydro2.wav";
+ if (this.noise1 == "")
+ this.noise1 = "doors/hydro1.wav";
+ }
+ else
+ {
+ if (this.noise == "")
+ this.noise = "misc/null.wav";
+ if (this.noise1 == "")
+ this.noise1 = "misc/null.wav";
+ }
+
+ // backwards compatibility with previous version
+ if (this.noise3 != "")
+ this.noise = this.noise3;
+ if (this.noise4 != "")
+ this.noise1 = this.noise4;
+
+ precache_sound (this.noise);
+ precache_sound (this.noise1);
+ if (this.noise2 != "")
+ precache_sound (this.noise2);
+
+ this.cnt = TRAIN_NEXT_WAIT;

- if (self.classname != "misc_modeltrain")
- displ = self.mins;
+ if (this.spawnflags & TRAIN_NONSOLID)
+ {
+ this.solid = SOLID_NOT;
+ this.movetype = MOVETYPE_NOCLIP;
+ }
+ else
+ {
+ this.solid = SOLID_BSP;
+ this.movetype = MOVETYPE_PUSH;
+ }

- self.enemy = targ;
- setorigin (self, targ.origin - (displ * doDisplace));
- if (targ.speed)
- // uses speed from the 1st path corner if set
- self.speed2 = targ.speed;
+ setmodel (this, this.model);
+ setsize (this, this.mins , this.maxs);
+ setorigin (this, this.origin);

- if (!self.targetname)
- {
- // not triggered, so start immediately
- self.nextthink = localtime + 0.1;
- self.think = train_next;
- }
+ // start trains on the second frame, to make sure their
+ // targets have had a chance to spawn
+
+ if (this.movetype == MOVETYPE_PUSH)
+ this.nextthink = this.ltime + 0.1;
+ else
+ this.nextthink = time + 0.1;
+
+ this.moving_use = FALSE;
+ this.find_think = TRUE;
+ this.speed2 = this.speed;
+ };
};

/*QUAKED func_train (0 .5 .8) ? RETRIGGER
@@ -340,89 +435,15 @@ sounds
2) base

*/
-void() func_train =
-{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (!self.speed)
- self.speed = 100;
- if (!self.target)
- objerror ("func_train without a target");
- if (!self.dmg)
- self.dmg = 2;
-
- if(self.spawnflags & TRAIN_STOPONTRIGGER &&
- self.spawnflags & TRAIN_MOVEONTRIGGER)
+class func_train: base_func_train
+{
+ virtual void() init_spawned =
{
- objerror ("func_train: Stop and move on trigger "
- "set at the same time");
- }
+ train_init ();
+ };

- if (self.sounds == 1)
- {
- if (self.noise == "")
- self.noise = "plats/train2.wav";
- if (self.noise1 == "")
- self.noise1 = "plats/train1.wav";
- }
- else if (self.sounds == 2)
- {
- // base door sound
- if (self.noise == "")
- self.noise = "doors/hydro2.wav";
- if (self.noise1 == "")
- self.noise1 = "doors/hydro1.wav";
- }
- else
- {
- if (self.noise == "")
- self.noise = "misc/null.wav";
- if (self.noise1 == "")
- self.noise1 = "misc/null.wav";
- }
-
- // backwards compatibility with previous version
- if (self.noise3 != "")
- self.noise = self.noise3;
- if (self.noise4 != "")
- self.noise1 = self.noise4;
-
- precache_sound (self.noise);
- precache_sound (self.noise1);
- if (self.noise2 != "")
- precache_sound (self.noise2);
-
- self.cnt = TRAIN_NEXT_WAIT;
-
- if (self.spawnflags & TRAIN_NONSOLID)
+ void() func_train =
{
- self.solid = SOLID_NOT;
- self.movetype = MOVETYPE_NOCLIP;
- }
- else
- {
- self.solid = SOLID_BSP;
- self.movetype = MOVETYPE_PUSH;
- }
-
- self.blocked = train_blocked;
- self.use = train_use;
- // self.classname = "train";
-
- setmodel (self, self.model);
- setsize (self, self.mins , self.maxs);
- setorigin (self, self.origin);
-
- // start trains on the second frame, to make sure their targets
- // have had a chance to spawn
-
- if (self.movetype == MOVETYPE_PUSH)
- self.nextthink = self.ltime + 0.1;
- else
- self.nextthink = time + 0.1;
-
- self.think = func_train_find;
- self.speed2 = self.speed;
+ this.classtype = CT_FUNC_TRAIN;
+ };
};

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

Diff qc/func/wall.qc

diff --git a/qc/func/wall.qc b/qc/func/wall.qc
index 7e7b251..62d85f5 100644
--- a/qc/func/wall.qc
+++ b/qc/func/wall.qc
@@ -2,26 +2,34 @@
// func_wall
//==============================================================================

-//----------------------------------------------------------------------
-void() func_wall_use =
+class base_func_wall: base_func
{
- // change to alternate textures
- self.frame = 1 - self.frame;
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ // change to alternate textures
+ this.frame = 1 - this.frame;
+ };
};

/*QUAKED func_wall (0 .5 .8) ? X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
This is just a solid wall if not inhibitted
*/
-void() func_wall =
+class func_wall: base_func_wall
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.angles = '0 0 0';
+ // so it doesn't get pushed by anything
+ this.movetype = MOVETYPE_PUSH;
+ this.solid = SOLID_BSP;
+ setmodel (this, this.model);
+ };

- self.angles = '0 0 0';
- // so it doesn't get pushed by anything
- self.movetype = MOVETYPE_PUSH;
- self.solid = SOLID_BSP;
- self.use = func_wall_use;
- setmodel (self, self.model);
+ //--------------------------------------------------------------
+ void() func_wall =
+ {
+ this.classtype = CT_FUNC_WALL;
+ };
};

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

Diff qc/hazards/ltrail.qc

diff --git a/qc/hazards/ltrail.qc b/qc/hazards/ltrail.qc
index 9e450c3..80d0355 100644
--- a/qc/hazards/ltrail.qc
+++ b/qc/hazards/ltrail.qc
@@ -8,99 +8,138 @@
// sept 96
//======================================================================

-// float ltrailLastUsed; -- now an entity field.
-
// constants
-const float LT_TOGGLE = 1;
-const float LT_ACTIVE = 2;
+const float LTRAIL_TOGGLE = 1;
+const float LTRAIL_ACTIVE = 2;
+const float LTRAIL_THINK_CHAIN = 1;
+const float LTRAIL_THINK_FIRE = 2;

-//----------------------------------------------------------------------
-void() ltrail_chain =
+//------------------------------------------------------------------------------
+class base_hazard_ltrail: base_mapentity
{
- SUB_UseTargets ();
- self.think = SUB_Null;
-};
+ float ltrail_last_used;
+ float think_state;

-//----------------------------------------------------------------------
-void() ltrail_fire =
-{
- local entity myTarget;
-
- if (self.classname != "ltrail_end")
+ //--------------------------------------------------------------
+ nonvirtual void() ltrail_chain =
{
- if (!self.sounds)
- sound (self, CHAN_VOICE, "weapons/lhit.wav",
- 1, ATTN_NORM);
- myTarget = find (world, targetname, self.target);
- WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
- WriteEntity (MSG_BROADCAST, self);
- WriteCoord (MSG_BROADCAST, self.origin_x);
- WriteCoord (MSG_BROADCAST, self.origin_y);
- WriteCoord (MSG_BROADCAST, self.origin_z);
- WriteCoord (MSG_BROADCAST, myTarget.origin_x);
- WriteCoord (MSG_BROADCAST, myTarget.origin_y);
- WriteCoord (MSG_BROADCAST, myTarget.origin_z);
- LightningDamage (self.origin, myTarget.origin,
- self, self.currentammo);
- }
-
- if ( self.items < time)
+ sub_usetargets ();
+ this.interaction_flags |= DISABLE_THINK;
+ };
+
+ //--------------------------------------------------------------
+ nonvirtual void() ltrail_fire =
{
- self.think = ltrail_chain;
- self.nextthink = time + self.frags;
- }
- else
+
+ if (this.classtype != CT_HAZARD_LTRAIL_END)
+ {
+ local entity targent;
+
+ if (!this.sounds)
+ sound (this, CHAN_VOICE, "weapons/lhit.wav",
+ 1, ATTN_NORM);
+
+ targent = find (world, ::targetname, this.target);
+ WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
+ WriteEntity (MSG_BROADCAST, this);
+ WriteCoord (MSG_BROADCAST, this.origin_x);
+ WriteCoord (MSG_BROADCAST, this.origin_y);
+ WriteCoord (MSG_BROADCAST, this.origin_z);
+ WriteCoord (MSG_BROADCAST, targent.origin_x);
+ WriteCoord (MSG_BROADCAST, targent.origin_y);
+ WriteCoord (MSG_BROADCAST, targent.origin_z);
+ LightningDamage (this.origin, targent.origin,
+ this, this.currentammo);
+ }
+
+ if (this.items < time)
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.think_state = LTRAIL_THINK_CHAIN;
+ this.nextthink = time + this.frags;
+ }
+ else
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.think_state = LTRAIL_THINK_FIRE;
+ this.nextthink = time + 0.05;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- self.think = ltrail_fire;
- self.nextthink = time + 0.05;
- }
-};
+ switch (this.think_state)
+ {
+ case LTRAIL_THINK_CHAIN:
+ ltrail_chain ();
+ break;
+ case LTRAIL_THINK_FIRE:
+ ltrail_fire ();
+ break;
+ default:
+ dprint ("base_hazard_ltrail::do_think: "
+ "unhandled think state!\n");
+ }
+ };

-//----------------------------------------------------------------------
-void() ltrail_start_fire =
-{
- // if it's a toggle ltrail, we ignore triggers from ltrail_end's
- // when toggled off.
- if (self.spawnflags & LT_TOGGLE)
+ //--------------------------------------------------------------
+ // was ltrail_start_fire
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- // user is not a lightning trail - change activity state.
- if ( other.classname != "ltrail_end" )
+ // if it's a toggle ltrail, we ignore triggers from
+ // ltrail_end's when toggled off.
+ if (this.spawnflags & LTRAIL_TOGGLE)
{
- if (self.spawnflags & LT_ACTIVE)
+ // user is not a lightning trail; change activity state.
+ if (caller.classtype != CT_HAZARD_LTRAIL_END)
{
- // currently active
- self.spawnflags = self.spawnflags - LT_ACTIVE;
- return;
+ if (this.spawnflags & LTRAIL_ACTIVE)
+ {
+ // currently active
+ this.spawnflags -= LTRAIL_ACTIVE;
+ return;
+ }
+ else
+ {
+ // not active
+ this.spawnflags += LTRAIL_ACTIVE;
+ }
}
- else
+ else if (!(this.spawnflags & LTRAIL_ACTIVE))
{
- // not active
- self.spawnflags = self.spawnflags + LT_ACTIVE;
+ // user is lightning trail, but trail has
+ // been turned off. ignore the message.
+ return;
}
}
- // user is lightning trail, but trail has been turned off.
- // ignore the message.
- else if (!(self.spawnflags & LT_ACTIVE))
- return;
- }

- if (self.classname == "ltrail_start")
- {
- self.items = time + self.weapon;
- ltrail_fire ();
- self.ltrailLastUsed = time;
- }
- else if (self.classname == "ltrail_relay")
- {
- self.items = time + self.weapon;
- ltrail_fire ();
- }
- else
+ if (this.classtype == CT_HAZARD_LTRAIL_START)
+ {
+ this.items = time + this.weapon;
+ ltrail_fire ();
+ this.ltrail_last_used = time;
+ }
+ else if (this.classtype == CT_HAZARD_LTRAIL_START)
+ {
+ this.items = time + this.weapon;
+ ltrail_fire ();
+ }
+ else
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.think_state = LTRAIL_THINK_CHAIN;
+ this.nextthink = time + this.frags;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() base_hazard_ltrail =
{
- self.think = ltrail_chain;
- self.nextthink = time + self.frags;
- }
+ this.classgroup |= CG_HAZARD_LTRAIL;
+ };
};

/*QUAKED ltrail_start (0 1 0) (-8 -8 -8) (8 8 8) LT_TOGGLE START_ON 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
@@ -117,34 +156,40 @@ Default is 0.3 seconds.

Set the LT_TOGGLE checkbox if you want the lightning shooter to continuously fire until triggered again.
*/
-void() ltrail_start =
+class ltrail_start: base_hazard_ltrail
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.ltrail_last_used = time;

- self.ltrailLastUsed = time;
+ precache_sound ("weapons/lhit.wav");
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_BBOX;
+ this.interaction_flags |= DISABLE_THINK;

- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
+ if (this.currentammo == 0)
+ this.currentammo = 25;

- if (self.currentammo == 0)
- self.currentammo = 25;
+ if (this.weapon == 0)
+ this.weapon = 0.3;

- if (self.weapon == 0)
- self.weapon = 0.3;
+ if (this.frags == 0)
+ this.frags = 0.3;

- if (self.frags == 0)
- self.frags = 0.3;
+ if (this.spawnflags & LTRAIL_ACTIVE)
+ {
+ this.items = time + 99999999;
+ this.think_state = LTRAIL_THINK_FIRE;
+ this.nextthink = time + 0.1;
+ }
+ };

- if (self.spawnflags & LT_ACTIVE)
+ //--------------------------------------------------------------
+ void() ltrail_start =
{
- self.items = time + 99999999;
- self.think = ltrail_fire;
- self.nextthink = time + 0.1;
- }
+ this.classtype = CT_HAZARD_LTRAIL_START;
+ };
};

/*QUAKED ltrail_relay (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
@@ -158,25 +203,31 @@ Default is 0.3 seconds.
Set weapon to amount of time to be firing the lightning.
Default is 0.3 seconds.
*/
-void() ltrail_relay =
+class ltrail_relay: base_hazard_ltrail
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ precache_sound ("weapons/lhit.wav");
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_BBOX;
+ this.interaction_flags |= DISABLE_THINK;

- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
+ if (this.currentammo == 0)
+ this.currentammo = 25;

- if (self.currentammo == 0)
- self.currentammo = 25;
+ if (this.weapon == 0)
+ this.weapon = 0.3;

- if (self.weapon == 0)
- self.weapon = 0.3;
+ if (this.frags == 0)
+ this.frags = 0.3;
+ };

- if (self.frags == 0)
- self.frags = 0.3;
+ //--------------------------------------------------------------
+ void() ltrail_relay =
+ {
+ this.classtype = CT_HAZARD_LTRAIL_RELAY;
+ };
};

/*QUAKED ltrail_end (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
@@ -186,23 +237,29 @@ Does not fire any lightning.
Set frags to amount of time before next item is triggered.
Default is 0.3 seconds.
*/
-void() ltrail_end =
+class ltrail_end: base_hazard_ltrail
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ precache_sound ("weapons/lhit.wav");
+ this.movetype = MOVETYPE_NONE;
+ this.solid = SOLID_BBOX;
+ this.interaction_flags |= DISABLE_THINK;

- precache_sound ("weapons/lhit.wav");
- self.movetype = MOVETYPE_NONE;
- self.solid = SOLID_BBOX;
- self.use = ltrail_start_fire;
+ if (this.currentammo == 0)
+ this.currentammo = 25;

- if (self.currentammo == 0)
- self.currentammo = 25;
+ if (this.weapon == 0)
+ this.weapon = 0.3;

- if (self.weapon == 0)
- self.weapon = 0.3;
+ if (this.frags == 0)
+ this.frags = 0.3;
+ };

- if (self.frags == 0)
- self.frags = 0.3;
+ //--------------------------------------------------------------
+ void() ltrail_end =
+ {
+ this.classtype = CT_HAZARD_LTRAIL_END;
+ };
};

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

Diff qc/hazards/shooter.qc

diff --git a/qc/hazards/shooter.qc b/qc/hazards/shooter.qc
index 6a72583..4e709c5 100644
--- a/qc/hazards/shooter.qc
+++ b/qc/hazards/shooter.qc
@@ -5,17 +5,18 @@
// MED 11/09/96 added new spawnflags -- taken from hipdefs.qc - dumptruck_ds

// constants
-float SPAWNFLAG_SUPERSPIKE = 1;
-float SPAWNFLAG_LASER = 2;
-float SPAWNFLAG_LAVABALL = 4;
-float SPAWNFLAG_ROCKET = 8;
-float SPAWNFLAG_VOREBALL = 16;
-float SPAWNFLAG_GRENADE = 32;
-float SPAWNFLAG_GIBS = 64;
-float SPAWNFLAG_SILENT = 128;
+const float SHOOTER_SPAWNFLAG_SUPERSPIKE = 1;
+const float SHOOTER_SPAWNFLAG_LASER = 2;
+const float SHOOTER_SPAWNFLAG_LAVABALL = 4;
+const float SHOOTER_SPAWNFLAG_ROCKET = 8;
+const float SHOOTER_SPAWNFLAG_VOREBALL = 16;
+const float SHOOTER_SPAWNFLAG_GRENADE = 32;
+const float SHOOTER_SPAWNFLAG_GIBS = 64;
+const float SHOOTER_SPAWNFLAG_SILENT = 128;

-// prototypes
-void(vector org, vector vec) LaunchLaser;
+//======================================================================
+// stray functions that need to be reworked -- TODO CEV
+//======================================================================

//----------------------------------------------------------------------
// ShalMissileTouch -- moved from Shalrath to enable shooter version
@@ -41,7 +42,7 @@ void() ShalMissileTouch =
BecomeExplosion ();

// self.velocity = '0 0 0';
- // self.touch = SUB_Null;
+ // self.touch = sub_null;
// setmodel (self, "progs/s_explod.spr");
// self.solid = SOLID_NOT;
// s_explode1 ();
@@ -68,157 +69,210 @@ void() ZombieGrenadeTouch =
sound (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM);
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
- self.touch = SUB_Remove;
+ self.touch = sub_remove;
};

-//----------------------------------------------------------------------
-// spikeshooter_use
-// MED 11/09/96 added lava ball and rocket
-// dumptruck_ds added voreball and grenades
-//----------------------------------------------------------------------
-void() spikeshooter_use =
+//------------------------------------------------------------------------------
+class base_hazard_shooter: base_mapentity
{
- local entity gnade, lavaball, rockettrap, voreball, zgibs;
-
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "enforcer/enfire.wav",
- 1, ATTN_NORM);
- LaunchLaser (self.origin, self.movedir);
- newmis.spawnflags = self.spawnflags;
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- // dms
- sound (self, CHAN_VOICE, "boss1/throw.wav",
- 1, ATTN_NORM);
- lavaball = spawn ();
- lavaball.movetype = MOVETYPE_FLYMISSILE;
- lavaball.solid = SOLID_BBOX;
- lavaball.classname = "lavaball";
- // set lavaball speed
- lavaball.velocity = self.movedir * 600; // was 300 dms
- lavaball.angles = vectoangles (lavaball.velocity);
- lavaball.owner = self;
- lavaball.touch = ShalMissileTouch;
- setmodel (lavaball, "progs/lavaball.mdl"); // dms
- setsize (lavaball, '0 0 0', '0 0 0');
- setorigin (lavaball, self.origin);
- lavaball.avelocity = '0 0 400';
- lavaball.nextthink = time + 5;
- lavaball.think = SUB_Remove;
- }
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
+ //--------------------------------------------------------------
+ // shooter_think -- MED 11/01/96 added state capability
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/sgun1.wav",
- 1, ATTN_NORM);
- rockettrap = spawn ();
- rockettrap.movetype = MOVETYPE_FLYMISSILE;
- rockettrap.solid = SOLID_BBOX;
- rockettrap.classname = "rockettrap";
- // set rocket speed
- rockettrap.velocity = self.movedir * 1000;
- rockettrap.angles = vectoangles (rockettrap.velocity);
- rockettrap.owner = self;
- rockettrap.touch = T_MissileTouch;
- setmodel (rockettrap, "progs/missile.mdl"); // dms
- setsize (rockettrap, '0 0 0', '0 0 0');
- setorigin (rockettrap, self.origin);
- // rockettrap.avelocity = '0 0 400';
- rockettrap.nextthink = time + 5;
- rockettrap.think = SUB_Remove;
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "shalrath/attack2.wav",
- 1, ATTN_NORM);
- voreball = spawn ();
- voreball.movetype = MOVETYPE_FLYMISSILE;
- voreball.solid = SOLID_BBOX;
- voreball.classname = "voreball";
- // set voreball speed
- voreball.velocity = self.movedir * 600; // was 300 dms
- voreball.angles = vectoangles (voreball.velocity);
- voreball.owner = self;
- voreball.touch = ShalMissileTouch;
- setmodel (voreball, "progs/v_spike.mdl"); // dms
- setsize (voreball, '0 0 0', '0 0 0');
- setorigin (voreball, self.origin);
- voreball.avelocity = '0 0 400';
- voreball.nextthink = time + 5;
- voreball.think = SUB_Remove;
- }
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/grenade.wav",
- 1, ATTN_NORM);
- gnade = spawn ();
- gnade.movetype = MOVETYPE_BOUNCE;
- // gnade.movetype = MOVETYPE_FLYMISSILE;
- gnade.solid = SOLID_BBOX;
- gnade.classname = "gnade";
- // set grenade speed
- // gnade.velocity = self.movedir * 600; // was 300 dms
- gnade.velocity = self.movedir * 600 + v_up * 200 +
- crandom() * v_right * 10 + crandom() * v_up * 10;
- gnade.angles = vectoangles (gnade.velocity);
- gnade.owner = self;
- gnade.touch = GrenadeTouch;
- setmodel (gnade, "progs/grenade.mdl"); // dms
- setsize (gnade, '0 0 0', '0 0 0');
- setorigin (gnade, self.origin);
- gnade.avelocity = '300 300 300';
- gnade.nextthink = time + 2.5;
- gnade.think = GrenadeExplode;
- }
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "zombie/z_shot1.wav",
- 1, ATTN_NORM);
- zgibs = spawn ();
- zgibs.owner = self;
- zgibs.movetype = MOVETYPE_BOUNCE;
- zgibs.solid = SOLID_BBOX;
- zgibs.classname = "zgibs";
- setmodel (zgibs, "progs/zom_gib.mdl");
- setsize (zgibs, '0 0 0', '0 0 0');
- setorigin (zgibs, self.origin);
- zgibs.velocity = self.movedir * 600 + v_up * 200 +
- crandom() * v_right * 10 + crandom() * v_up * 10;
- zgibs.avelocity = '3000 1000 2000';
- zgibs.touch = ZombieGrenadeTouch;
- // set missile duration
- zgibs.nextthink = time + 2.5;
- zgibs.think = SUB_Remove;
- }
- else
+ if (this.state)
+ this.do_use (other);
+
+ this.nextthink = time + this.wait;
+ };
+
+ //--------------------------------------------------------------
+ // spikeshooter_use
+ // MED 11/09/96 added lava ball and rocket
+ // dumptruck_ds added voreball and grenades
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- if (!(self.spawnflags & SPAWNFLAG_SILENT))
- sound (self, CHAN_VOICE, "weapons/spike2.wav",
- 1, ATTN_NORM);
- launch_spike (self.origin, self.movedir);
- newmis.velocity = self.movedir * 500;
- if (self.spawnflags & SPAWNFLAG_SUPERSPIKE)
- newmis.touch = superspike_touch;
- }
-};
+ local entity gnade, lavaball, rockettrap, voreball, zgibs;

-//----------------------------------------------------------------------
-// shooter_think -- MED 11/01/96 added state capability
-//----------------------------------------------------------------------
-void() shooter_think =
-{
- if (self.state)
+ if (this.spawnflags & SHOOTER_SPAWNFLAG_LASER)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "enforcer/enfire.wav",
+ 1, ATTN_NORM);
+ LaunchLaser (this.origin, this.movedir);
+ newmis.spawnflags = this.spawnflags;
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_LAVABALL)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ // dms
+ sound (this, CHAN_VOICE, "boss1/throw.wav",
+ 1, ATTN_NORM);
+ lavaball = spawn ();
+ lavaball.movetype = MOVETYPE_FLYMISSILE;
+ lavaball.solid = SOLID_BBOX;
+ lavaball.classname = "lavaball";
+ // set lavaball speed
+ lavaball.velocity = this.movedir * 600; // was 300 dms
+ lavaball.angles = vectoangles (lavaball.velocity);
+ lavaball.owner = this;
+ lavaball.touch = ShalMissileTouch;
+ setmodel (lavaball, "progs/lavaball.mdl"); // dms
+ setsize (lavaball, '0 0 0', '0 0 0');
+ setorigin (lavaball, this.origin);
+ lavaball.avelocity = '0 0 400';
+ lavaball.nextthink = time + 5;
+ lavaball.think = sub_remove;
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_ROCKET)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "weapons/sgun1.wav",
+ 1, ATTN_NORM);
+ rockettrap = spawn ();
+ rockettrap.movetype = MOVETYPE_FLYMISSILE;
+ rockettrap.solid = SOLID_BBOX;
+ rockettrap.classname = "rockettrap";
+ // set rocket speed
+ rockettrap.velocity = this.movedir * 1000;
+ rockettrap.angles = vectoangles (rockettrap.velocity);
+ rockettrap.owner = this;
+ rockettrap.touch = T_MissileTouch;
+ setmodel (rockettrap, "progs/missile.mdl"); // dms
+ setsize (rockettrap, '0 0 0', '0 0 0');
+ setorigin (rockettrap, this.origin);
+ // rockettrap.avelocity = '0 0 400';
+ rockettrap.nextthink = time + 5;
+ rockettrap.think = sub_remove;
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_VOREBALL)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "shalrath/attack2.wav",
+ 1, ATTN_NORM);
+ voreball = spawn ();
+ voreball.movetype = MOVETYPE_FLYMISSILE;
+ voreball.solid = SOLID_BBOX;
+ voreball.classname = "voreball";
+ // set voreball speed
+ voreball.velocity = this.movedir * 600; // was 300 dms
+ voreball.angles = vectoangles (voreball.velocity);
+ voreball.owner = this;
+ voreball.touch = ShalMissileTouch;
+ setmodel (voreball, "progs/v_spike.mdl"); // dms
+ setsize (voreball, '0 0 0', '0 0 0');
+ setorigin (voreball, this.origin);
+ voreball.avelocity = '0 0 400';
+ voreball.nextthink = time + 5;
+ voreball.think = sub_remove;
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_GRENADE)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "weapons/grenade.wav",
+ 1, ATTN_NORM);
+ gnade = spawn ();
+ gnade.movetype = MOVETYPE_BOUNCE;
+ // gnade.movetype = MOVETYPE_FLYMISSILE;
+ gnade.solid = SOLID_BBOX;
+ gnade.classname = "gnade";
+ // set grenade speed
+ // gnade.velocity = this.movedir * 600; // was 300 dms
+ gnade.velocity = this.movedir * 600 + v_up * 200 +
+ crandom() * v_right * 10 + crandom() * v_up * 10;
+ gnade.angles = vectoangles (gnade.velocity);
+ gnade.owner = this;
+ gnade.touch = GrenadeTouch;
+ setmodel (gnade, "progs/grenade.mdl"); // dms
+ setsize (gnade, '0 0 0', '0 0 0');
+ setorigin (gnade, this.origin);
+ gnade.avelocity = '300 300 300';
+ gnade.nextthink = time + 2.5;
+ gnade.think = GrenadeExplode;
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_GIBS)
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "zombie/z_shot1.wav",
+ 1, ATTN_NORM);
+ zgibs = spawn ();
+ zgibs.owner = this;
+ zgibs.movetype = MOVETYPE_BOUNCE;
+ zgibs.solid = SOLID_BBOX;
+ zgibs.classname = "zgibs";
+ setmodel (zgibs, "progs/zom_gib.mdl");
+ setsize (zgibs, '0 0 0', '0 0 0');
+ setorigin (zgibs, this.origin);
+ zgibs.velocity = this.movedir * 600 + v_up * 200 +
+ crandom() * v_right * 10 + crandom() * v_up * 10;
+ zgibs.avelocity = '3000 1000 2000';
+ zgibs.touch = ZombieGrenadeTouch;
+ // set missile duration
+ zgibs.nextthink = time + 2.5;
+ zgibs.think = sub_remove;
+ }
+ else
+ {
+ if (!(this.spawnflags & SHOOTER_SPAWNFLAG_SILENT))
+ sound (this, CHAN_VOICE, "weapons/spike2.wav",
+ 1, ATTN_NORM);
+ launch_spike (this.origin, this.movedir);
+ newmis.velocity = this.movedir * 500;
+ if (this.spawnflags & SHOOTER_SPAWNFLAG_SUPERSPIKE)
+ newmis.touch = superspike_touch;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- spikeshooter_use ();
- }
- self.nextthink = time + self.wait;
+ if (this.proj_speed_mod <= 0)
+ this.proj_speed_mod = 1;
+
+ sub_setmovedir ();
+
+ if (this.spawnflags & SHOOTER_SPAWNFLAG_LASER)
+ {
+ precache_model2 ("progs/laser.mdl");
+ precache_sound2 ("enforcer/enfire.wav");
+ precache_sound2 ("enforcer/enfstop.wav");
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_LAVABALL)
+ {
+ precache_model ("progs/lavaball.mdl");
+ // precache_sound2 ("knight/sword2.wav"); // dms
+ precache_sound2 ("boss1/throw.wav"); // dms
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_ROCKET)
+ {
+ precache_model ("progs/missile.mdl");
+ precache_sound ("weapons/sgun1.wav");
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_VOREBALL)
+ {
+ precache_model ("progs/v_spike.mdl");
+ precache_sound ("shalrath/attack2.wav");
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_GRENADE)
+ {
+ precache_model ("progs/grenade.mdl");
+ // grenade launcher
+ precache_sound ("weapons/grenade.wav");
+ }
+ else if (this.spawnflags & SHOOTER_SPAWNFLAG_GIBS)
+ {
+ precache_model ("progs/zom_gib.mdl");
+ // Zombie gibs
+ precache_sound ("zombie/z_shot1.wav");
+ precache_sound ("zombie/z_miss.wav");
+ precache_sound ("zombie/z_hit.wav");
+ }
+ else
+ {
+ precache_sound ("weapons/spike2.wav");
+ }
+ };
};

/*QUAKED trap_spikeshooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -226,58 +280,13 @@ void() shooter_think =
When triggered, fires a spike in the direction set in QuakeEd.
Laser is only for REGISTERED.
*/
-void() trap_spikeshooter =
+class trap_spikeshooter: base_hazard_shooter
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- if (self.proj_speed_mod <= 0)
- self.proj_speed_mod = 1;
-
- // MED 11/01/96 commented out setmovedir
- SetMovedir ();
- self.use = spikeshooter_use;
- if (self.spawnflags & SPAWNFLAG_LASER)
- {
- precache_model2 ("progs/laser.mdl");
- precache_sound2 ("enforcer/enfire.wav");
- precache_sound2 ("enforcer/enfstop.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_LAVABALL)
- {
- precache_model ("progs/lavaball.mdl");
- // precache_sound2 ("knight/sword2.wav"); // dms
- precache_sound2 ("boss1/throw.wav"); // dms
- }
- else if (self.spawnflags & SPAWNFLAG_ROCKET)
- {
- precache_model ("progs/missile.mdl");
- precache_sound ("weapons/sgun1.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_VOREBALL)
- {
- precache_model ("progs/v_spike.mdl");
- precache_sound ("shalrath/attack2.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_GRENADE)
- {
- precache_model ("progs/grenade.mdl");
- // grenade launcher
- precache_sound ("weapons/grenade.wav");
- }
- else if (self.spawnflags & SPAWNFLAG_GIBS)
- {
- precache_model ("progs/zom_gib.mdl");
- // Zombie gibs
- precache_sound ("zombie/z_shot1.wav");
- precache_sound ("zombie/z_miss.wav");
- precache_sound ("zombie/z_hit.wav");
- }
- else
+ //--------------------------------------------------------------
+ void() trap_spikeshooter =
{
- precache_sound ("weapons/spike2.wav");
- }
+ this.classtype = CT_HAZARD_SPIKESHOOTER;
+ };
};

/*QUAKED trap_shooter (0 .5 .8) (-8 -8 -8) (8 8 8) superspike laser lavaball rocket silent X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -285,29 +294,26 @@ Continuously fires spikes.
"wait" time between spike (1.0 default)
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
*/
-void() trap_shooter =
+class trap_shooter: base_hazard_shooter
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ super::init_spawned ();

- trap_spikeshooter ();
+ if (this.wait == 0)
+ this.wait = 1;

- if (self.wait == 0)
- self.wait = 1;
+ // MED 11/01/96 added state capability
+ this.state = 1;
+ this.nextthink = this.nextthink + this.wait + this.ltime;
+ };

- // MED 11/01/96 added state capability
- self.state = 1;
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
-};
-
-//----------------------------------------------------------------------
-// trap_shooter_use -- MED 11/01/96 added new use function
-//----------------------------------------------------------------------
-void() trap_shooter_use =
-{
- self.state = 1 - self.state;
+ //--------------------------------------------------------------
+ void() trap_shooter =
+ {
+ this.classtype = CT_HAZARD_SHOOTER;
+ };
};

//MED 11/01/96 added new function
@@ -317,19 +323,29 @@ Continuously fires spikes.
"nextthink" delay before firing first spike, so multiple shooters can be stagered.
"state" 0 initially off, 1 initially on. (0 default)
*/
-void() trap_switched_shooter =
+class trap_switched_shooter: base_hazard_shooter
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ //--------------------------------------------------------------
+ // trap_shooter_use -- MED 11/01/96 added new use function
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ this.state = 1 - this.state;
+ };

- trap_spikeshooter ();
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ super::init_spawned ();
+ if (this.wait == 0)
+ this.wait = 1;

- if (self.wait == 0)
- self.wait = 1;
+ // MED 11/01/96 added state capability
+ this.nextthink = this.nextthink + this.wait + this.ltime;
+ };

- // MED 11/01/96 added state capability
- self.nextthink = self.nextthink + self.wait + self.ltime;
- self.think = shooter_think;
- self.use = trap_shooter_use;
+ void() trap_switched_shooter =
+ {
+ this.classtype = CT_HAZARD_SWITCHED_SHOOTER;
+ };
};

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
index b2fb64a..a612f12 100644
--- a/qc/info/camera.qc
+++ b/qc/info/camera.qc
@@ -6,10 +6,16 @@
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
+class info_movie_camera: base_mapentity
{
//--------------------------------------------------------------
- virtual void() imc_touch =
+ virtual void(entity caller) do_think =
+ {
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity e) do_touch =
{
local string temps;

@@ -18,33 +24,34 @@ class info_movie_camera: entity

temps = this.target;
this.target = this.message;
- SUB_UseTargets ();
+ 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 =
+ virtual void() init_spawned =
{
// this does nothing, just serves as a target spot
/*
if (vision)
return;
*/
-
// ...more than a spot in Zer mode.
- // this.use = SUB_Null;
+ // 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;
+ };
+
+ //--------------------------------------------------------------
+ void() info_movie_camera =
+ {
+ this.classtype = CT_INFO_MOVIE_CAMERA;
};
};

@@ -52,7 +59,7 @@ class info_movie_camera: entity
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
+class info_focal_point: base_mapentity
{
//--------------------------------------------------------------
void() info_focal_point =
@@ -62,7 +69,6 @@ class info_focal_point: entity
// 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/intermission.qc

diff --git a/qc/info/intermission.qc b/qc/info/intermission.qc
new file mode 100644
index 0000000..45de93b
--- /dev/null
+++ b/qc/info/intermission.qc
@@ -0,0 +1,18 @@
+//==============================================================================
+// info_intermission
+//==============================================================================
+
+/*QUAKED info_intermission (1 0.5 0.5) (-16 -16 -16) (16 16 16) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
+
+This is the camera point for the intermission.
+Use mangle instead of angle, so you can set pitch or roll as well as yaw. 'pitch roll yaw'
+*/
+class info_intermission: base_mapentity
+{
+ //--------------------------------------------------------------
+ void() info_intermission =
+ {
+ this.classtype = CT_INFO_INTERMISSION;
+ };
+};
+

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
index 6d4dbd6..89a165f 100644
--- a/qc/info/notnull.qc
+++ b/qc/info/notnull.qc
@@ -6,16 +6,11 @@

Never used in the or
*/
-class info_notnull: entity
+class info_notnull: base_mapentity
{
//--------------------------------------------------------------
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
index 42bff05..f3f3efa 100644
--- a/qc/info/null.qc
+++ b/qc/info/null.qc
@@ -6,16 +6,11 @@

Used as a positional target for spotlights, etc.
*/
-class info_null: entity
+class info_null: base_mapentity
{
//--------------------------------------------------------------
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/path_corner.qc

diff --git a/qc/info/path_corner.qc b/qc/info/path_corner.qc
new file mode 100644
index 0000000..4534386
--- /dev/null
+++ b/qc/info/path_corner.qc
@@ -0,0 +1,78 @@
+//==============================================================================
+// path_corner
+//==============================================================================
+
+/*QUAKED path_corner (0.5 0.3 0) (-8 -8 -8) (8 8 8)
+Monsters will continue walking towards the next target corner.
+*/
+class path_corner: base_mapentity
+{
+ // support for modeltrain -- CEV
+ float first_frame;
+ float first_frame2;
+ float last_frame;
+ float last_frame2;
+ float frtime;
+ float frtime2;
+ float animtype;
+ float animtype2;
+ float multiplier;
+ float speed2;
+
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "first_frame":
+ first_frame = stof (fieldvalue);
+ break;
+ case "first_frame2":
+ first_frame2 = stof (fieldvalue);
+ break;
+ case "last_frame":
+ last_frame = stof (fieldvalue);
+ break;
+ case "last_frame2":
+ last_frame2 = stof (fieldvalue);
+ break;
+ case "frtime":
+ frtime = stof (fieldvalue);
+ break;
+ case "frtime2":
+ frtime2 = stof (fieldvalue);
+ break;
+ case "animtype":
+ animtype = stof (fieldvalue);
+ break;
+ case "animtype2":
+ animtype2 = stof (fieldvalue);
+ break;
+ case "multiplier":
+ multiplier = stof (fieldvalue);
+ break;
+ case "speed2":
+ speed2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ if (this.noise != __NULL__ && this.noise != "")
+ precache_sound (this.noise);
+ if (this.noise2 != __NULL__ && this.noise2 != "")
+ precache_sound (this.noise2);
+
+ movetarget_f ();
+ };
+
+ //--------------------------------------------------------------
+ void() path_corner =
+ {
+ this.classtype = CT_PATH_CORNER;
+ };
+};

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

Diff qc/info/rotate.qc

diff --git a/qc/info/rotate.qc b/qc/info/rotate.qc
new file mode 100644
index 0000000..227709b
--- /dev/null
+++ b/qc/info/rotate.qc
@@ -0,0 +1,37 @@
+//==============================================================================
+// info_rotate
+//==============================================================================
+
+//======================================================================
+// Rotate QuickC program
+// By Jim Dose' 10/17/96
+// Copyright (c)1996 Hipnotic Interactive, Inc.
+// All rights reserved.
+// Distributed (unsupported) on 3.12.97
+//======================================================================
+
+/*QUAKED info_rotate (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 the point of rotation for rotatable objects.
+*/
+class info_rotate: base_mapentity
+{
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ virtual void() info_spawned =
+ {
+ // remove self after a little while, to make sure that
+ // entities that have targeted it have had a chance to spawn
+ this.nextthink = time + 2;
+ };
+
+ //--------------------------------------------------------------
+ void() info_rotate =
+ {
+ this.classtype = CT_INFO_ROTATE;
+ };
+};

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
index 2e1a6fc..01852d2 100644
--- a/qc/info/teleport_changedest.qc
+++ b/qc/info/teleport_changedest.qc
@@ -10,7 +10,7 @@ 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
+class info_teleport_changedest: base_mapentity
{
// this is from Qmaster:
//
@@ -30,7 +30,7 @@ class info_teleport_changedest: entity
// match self.message if you were to add this."

//--------------------------------------------------------------
- virtual void() changedest_use =
+ virtual void(entity e) do_use =
{
local entity trig;

@@ -60,16 +60,8 @@ class info_teleport_changedest: entity
};

//--------------------------------------------------------------
- void() info_teleport_changedest =
+ virtual void() init_spawned =
{
- // 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 ");
@@ -91,6 +83,12 @@ class info_teleport_changedest: entity
remove (this);
}
};
+
+ //--------------------------------------------------------------
+ void() info_teleport_changedest =
+ {
+ this.classtype = CT_INFO_TELEPORT_CHANGEDEST;
+ };
};


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
index d4c09fb..57e63b5 100644
--- a/qc/info/teleport_destination.qc
+++ b/qc/info/teleport_destination.qc
@@ -13,20 +13,14 @@ 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
+class info_teleport_destination: base_mapentity
{
//--------------------------------------------------------------
- void() info_teleport_destination =
+ virtual void() init_spawned =
{
- // 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 = "";
@@ -55,6 +49,13 @@ class info_teleport_destination: entity
else
objerror ("no targetname");
};
+
+ //--------------------------------------------------------------
+ void() info_teleport_destination =
+ {
+ this.classtype = CT_INFO_TELEPORT_DESTINATION;
+ };
+
};

/*QUAKED info_teleport_random (.5 .5 .5) (-8 -8 -8) (8 8 32) X X X X X X X X NOT_ON_EASY NOT_ON_NORMAL NOT_ON_HARD_OR_NIGHTMARE NOT_IN_DEATHMATCH NOT_IN_COOP NOT_IN_SINGLEPLAYER X NOT_ON_HARD_ONLY NOT_ON_NIGHTMARE_ONLY
@@ -63,17 +64,21 @@ model ("progs/player.mdl");
}
This is a random destination marker for a teleporter.
*/
-class info_teleport_random: entity
+class info_teleport_random: base_mapentity
{
//--------------------------------------------------------------
- void() info_teleport_random =
+ virtual void() init_spawned =
{
// 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';
};
+
+ //--------------------------------------------------------------
+ void() info_teleport_random =
+ {
+ this.classtype = CT_INFO_TELEPORT_RANDOM;
+ };
};

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 7470e1e..f21e130 100644
--- a/qc/items/armor.qc
+++ b/qc/items/armor.qc
@@ -20,10 +20,6 @@ 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;
-
//----------------------------------------------------------------------
// shard_touch -- this is from RMQ shard_touch
//----------------------------------------------------------------------

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 415bcc1..b5fed74 100644
--- a/qc/items/backpacks.qc
+++ b/qc/items/backpacks.qc
@@ -379,7 +379,7 @@ void() DropBackpack =

// remove after 2 minutes
item.nextthink = time + 120;
- item.think = SUB_Remove;
+ item.think = sub_remove;
};

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

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 952722f..ad16b36 100644
--- a/qc/items/misc.qc
+++ b/qc/items/misc.qc
@@ -52,7 +52,7 @@ void() DelaySpawnItem =
else
self.movetype = MOVETYPE_TOSS;

- self.use = SUB_Null;
+ self.use = sub_null;
};

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

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

Diff qc/keylock.qc

diff --git a/qc/keylock.qc b/qc/keylock.qc
index ccc619b..3fc2f53 100644
--- a/qc/keylock.qc
+++ b/qc/keylock.qc
@@ -128,12 +128,12 @@ void(string key_name) keylock_set_custom_key =
// keylock_has_key_set
//
// Return TRUE if one of the keylock_set_*_key functions has been called
-// for self, otherwise return FALSE. -- iw
+// for entity e, otherwise return FALSE. -- iw
//----------------------------------------------------------------------
-float() keylock_has_key_set =
+float(entity e) keylock_has_key_set =
{
// support for item_key_custom -- iw
- return self.items != 0 || self.customkeys != 0;
+ return e.items != 0 || e.customkeys != 0;
};

/*

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 1358c53..94eb74f 100644
--- a/qc/misc/air_bubbles.qc
+++ b/qc/misc/air_bubbles.qc
@@ -2,18 +2,36 @@
// air_bubbles
//==============================================================================

-class temp_bubbles: entity
+class temp_bubbles: base_tempentity
{
+ float in_water;
+
+ //--------------------------------------------------------------
+ // was bubble_bob -- CEV
//--------------------------------------------------------------
- virtual void() bubble_bob =
+ virtual void(entity caller) do_think =
{
local float rnd1, rnd2, rnd3;

+ // waterlevel isn't being updated now for whatever reason,
+ // so do a pointcontents check manually here -- CEV
+ if (pointcontents(this.origin) >= CONTENT_SOLID)
+ {
+ // remove if in open air or a solid -- CEV
+ remove (this);
+ return;
+ }
+
this.cnt = this.cnt + 1;
+
if (this.cnt == 4)
bubble_split ();
+
if (this.cnt == 20)
+ {
remove (this);
+ return;
+ }

rnd1 = this.velocity_x + (-10 + (random() * 20));
rnd2 = this.velocity_y + (-10 + (random() * 20));
@@ -39,17 +57,15 @@ class temp_bubbles: entity
this.velocity_z = rnd3;

this.nextthink = time + 0.5;
- this.think = bubble_bob;
};

//--------------------------------------------------------------
- virtual void() bubble_remove =
+ virtual void(entity toucher) do_touch =
{
- if (other.classtype == this.classtype)
- {
+ if (toucher.classtype == this.classtype)
// dprint ("bump");
return;
- }
+
remove (this);
};

@@ -61,10 +77,9 @@ class temp_bubbles: entity
origin: this.origin);
this.frame = 1;
this.cnt = 10;
- if (this.waterlevel != WATERLEVEL_EYES)
- remove (this);
};

+ //--------------------------------------------------------------
void() temp_bubbles =
{
// make bubbles
@@ -74,9 +89,7 @@ class temp_bubbles: entity
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;
@@ -90,35 +103,35 @@ class temp_bubbles: entity
air bubbles entity

*/
-class air_bubbles: entity
+class air_bubbles: base_mapentity
{
//--------------------------------------------------------------
- virtual void() make_bubbles =
+ // was make_bubbles -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
local temp_bubbles bubble;

bubble = spawn (temp_bubbles, origin: this.origin);
this.nextthink = time + random() + 0.5;
- this.think = make_bubbles;
};

//--------------------------------------------------------------
- void() air_bubbles =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ precache_model ("progs/s_bubble.spr");
+ this.nextthink = time + 1;
+ };

+ //--------------------------------------------------------------
+ void() air_bubbles =
+ {
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 9e7ebb2..b42706f 100644
--- a/qc/misc/ambient_sound.qc
+++ b/qc/misc/ambient_sound.qc
@@ -16,7 +16,7 @@ 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
+class base_ambient_sound: base_mapentity
{
//--------------------------------------------------------------
static void(vector source) ambient_sound_fire =
@@ -112,18 +112,11 @@ Keys:

"speed" attenuation, default 3
*/
-class ambient_general: entity
+class ambient_general: base_mapentity
{
//--------------------------------------------------------------
- void() ambient_general =
+ virtual void() init_spawned =
{
- // 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)
{
@@ -148,6 +141,12 @@ class ambient_general: entity
ambientsound (this.origin, this.noise, this.volume, this.speed);
remove (this);
};
+
+ //--------------------------------------------------------------
+ void() ambient_general =
+ {
+ this.classtype = CT_MISC_AMBIENT_GENERAL;
+ };
};

//======================================================================
@@ -157,15 +156,15 @@ class ambient_general: entity
class FireAmbient: base_ambient_sound
{
//--------------------------------------------------------------
- void() FireAmbient =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_fire (this.origin);
+ };

- this.classname = "FireAmbient";
+ //--------------------------------------------------------------
+ void() FireAmbient =
+ {
this.classtype = CT_MISC_AMBIENT_FIRE;
- ambient_sound_fire (this.origin);
};
};

@@ -176,15 +175,15 @@ same as FireAmbient
class ambient_fire: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_fire =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_fire (this.origin);
+ };

- this.classname = "ambient_fire";
+ //--------------------------------------------------------------
+ void() ambient_fire =
+ {
this.classtype = CT_MISC_AMBIENT_FIRE;
- ambient_sound_fire (this.origin);
};
};

@@ -196,15 +195,15 @@ class ambient_fire: base_ambient_sound
class ambient_comp_hum: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_comp_hum =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_comphum (this.origin);
+ };

- this.classname = "ambient_comp_hum";
+ //--------------------------------------------------------------
+ void() ambient_comp_hum =
+ {
this.classtype = CT_MISC_AMBIENT_COMPHUM;
- ambient_sound_comphum (this.origin);
};
};

@@ -213,15 +212,15 @@ class ambient_comp_hum: base_ambient_sound
class ambient_drip: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_drip =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_drip (this.origin);
+ };

- this.classname = "ambient_drip";
+ //--------------------------------------------------------------
+ void() ambient_drip =
+ {
this.classtype = CT_MISC_AMBIENT_DRIP;
- ambient_sound_drip (this.origin);
};
};

@@ -230,15 +229,15 @@ class ambient_drip: base_ambient_sound
class ambient_drone: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_drone =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_drone (this.origin);
+ };

- this.classname = "ambient_drone";
+ //--------------------------------------------------------------
+ void() ambient_drone =
+ {
this.classtype = CT_MISC_AMBIENT_DRONE;
- ambient_sound_drone (this.origin);
};
};

@@ -247,15 +246,15 @@ class ambient_drone: base_ambient_sound
class ambient_flouro_buzz: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_flouro_buzz =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_fbuzz (this.origin);
+ };

- this.classname = "ambient_fluoro_buzz";
+ //--------------------------------------------------------------
+ void() ambient_flouro_buzz =
+ {
this.classtype = CT_MISC_AMBIENT_FBUZZ;
- ambient_sound_fbuzz (this.origin);
};
};

@@ -264,15 +263,15 @@ class ambient_flouro_buzz: base_ambient_sound
class ambient_light_buzz: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_light_buzz =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_lbuzz (this.origin);
+ };

- this.classname = "ambient_light_buzz";
+ //--------------------------------------------------------------
+ void() ambient_light_buzz =
+ {
this.classtype = CT_MISC_AMBIENT_LBUZZ;
- ambient_sound_lbuzz (this.origin);
};
};

@@ -281,15 +280,15 @@ class ambient_light_buzz: base_ambient_sound
class ambient_suck_wind: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_suck_wind =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_suckwind (this.origin);
+ };

- this.classname = "ambient_suck_wind";
+ //--------------------------------------------------------------
+ void() ambient_suck_wind =
+ {
this.classtype = CT_MISC_AMBIENT_SUCKWIND;
- ambient_sound_suckwind (this.origin);
};
};

@@ -298,15 +297,15 @@ class ambient_suck_wind: base_ambient_sound
class ambient_swamp1: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_swamp1 =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_swamp1 (this.origin);
+ };

- this.classname = "ambient_swamp1";
+ //--------------------------------------------------------------
+ void() ambient_swamp1 =
+ {
this.classtype = CT_MISC_AMBIENT_SWAMP1;
- ambient_sound_swamp1 (this.origin);
};
};

@@ -315,15 +314,15 @@ class ambient_swamp1: base_ambient_sound
class ambient_swamp2: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_swamp2 =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_swamp2 (this.origin);
+ };

- this.classname = "ambient_swamp2";
+ //--------------------------------------------------------------
+ void() ambient_swamp2 =
+ {
this.classtype = CT_MISC_AMBIENT_SWAMP2;
- ambient_sound_swamp2 (this.origin);
};
};

@@ -343,15 +342,15 @@ class ambient_swamp2: base_ambient_sound
class ambient_water1: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_water1 =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_water1 (this.origin);
+ };

- this.classname = "ambient_water1";
+ //--------------------------------------------------------------
+ void() ambient_water1 =
+ {
this.classtype = CT_MISC_AMBIENT_WATER1;
- ambient_sound_water1 (this.origin);
};
};

@@ -360,15 +359,15 @@ class ambient_water1: base_ambient_sound
class ambient_wind2: base_ambient_sound
{
//--------------------------------------------------------------
- void() ambient_wind2 =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ ambient_sound_wind2 (this.origin);
+ };

- this.classname = "ambient_wind2";
+ //--------------------------------------------------------------
+ void() ambient_wind2 =
+ {
this.classtype = CT_MISC_AMBIENT_WIND2;
- ambient_sound_wind2 (this.origin);
};
};

@@ -392,7 +391,7 @@ only need one of these in your level. It will play everywhere.
class ambient_thunder: base_ambient_sound
{
//--------------------------------------------------------------
- virtual void() thunder_go_boom =
+ virtual void(entity caller) do_think =
{
if (random() < 0.5)
sound (this, CHAN_AUTO, SND_AMBIENTHUNDER,
@@ -401,25 +400,22 @@ class ambient_thunder: base_ambient_sound
sound (this, CHAN_AUTO, SND_AMBIENTHUNDER,
1, ATTN_NONE);

- this.think = thunder_go_boom;
this.nextthink = time + 40 * random ();
};

//--------------------------------------------------------------
- void() ambient_thunder =
+ virtual void() init_spawned =
{
- // 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 ();
};
+
+ //--------------------------------------------------------------
+ void() ambient_thunder =
+ {
+ this.classtype = CT_MISC_AMBIENT_THUNDER;
+ };
};

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 d91fd69..a261637 100644
--- a/qc/misc/deadstuff.qc
+++ b/qc/misc/deadstuff.qc
@@ -11,17 +11,11 @@
model ("progs/h_demon.mdl");
}
*/
-class gib_head_demon: entity
+class gib_head_demon: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_demon =
+ virtual void() init_spawned =
{
- // 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;
@@ -36,6 +30,12 @@ class gib_head_demon: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_demon =
+ {
+ this.classtype = CT_GIB_HEAD_DEMON;
+ };
};

/*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
@@ -43,17 +43,11 @@ class gib_head_demon: entity
model ("progs/h_dog.mdl");
}
*/
-class gib_head_dog: entity
+class gib_head_dog: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_dog =
+ virtual void() init_spawned =
{
- // 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
@@ -68,6 +62,12 @@ class gib_head_dog: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_dog =
+ {
+ this.classtype = CT_GIB_HEAD_DOG;
+ };
};

/*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
@@ -75,15 +75,11 @@ class gib_head_dog: entity
model ("progs/h_guard.mdl");
}
*/
-class gib_head_army: entity
+class gib_head_army: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_army =
+ virtual void() init_spawned =
{
- // 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;
@@ -98,23 +94,23 @@ class gib_head_army: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_army =
+ {
+ this.classtype = CT_GIB_HEAD_ARMY;
+ };
};

/*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");
}*/
-class gib_head_hell_knight: entity
+class gib_head_hell_knight: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_hell_knight =
+ virtual void() init_spawned =
{
- // 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;
@@ -129,23 +125,23 @@ class gib_head_hell_knight: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_hell_knight =
+ {
+ this.classtype = CT_GIB_HEAD_HELL_KNIGHT;
+ };
};

/*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");
}*/
-class gib_head_knight: entity
+class gib_head_knight: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_knight =
+ virtual void() init_spawned =
{
- // 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;
@@ -160,6 +156,12 @@ class gib_head_knight: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_knight =
+ {
+ this.classtype = CT_GIB_HEAD_KNIGHT;
+ };
};

/*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
@@ -167,17 +169,11 @@ class gib_head_knight: entity
model ("progs/h_mega.mdl");
}
*/
-class gib_head_enforcer: entity
+class gib_head_enforcer: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_enforcer =
+ virtual void() init_spawned =
{
- // 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;
@@ -192,54 +188,54 @@ class gib_head_enforcer: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_enforcer =
+ {
+ this.classtype = CT_GIB_HEAD_ENFORCER;
+ };
};

/*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");
}*/
-class gib_head_ogre: entity
+class gib_head_ogre: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_ogre =
+ virtual void() init_spawned =
{
- // 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');
+ this.solid = SOLID_BBOX;
+ setsize (this,'-12.35 -15.7 -0.17','10.67 13.88 30');
}
else
{
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_ogre =
+ {
+ this.classtype = CT_GIB_HEAD_OGRE;
+ };
};

/*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");
}*/
-class gib_head_player: entity
+class gib_head_player: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_player =
+ virtual void() init_spawned =
{
- // 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;
@@ -254,23 +250,23 @@ class gib_head_player: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_player =
+ {
+ this.classtype = CT_GIB_HEAD_PLAYER;
+ };
};

/*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");
}*/
-class gib_head_shalrath: entity
+class gib_head_shalrath: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_shalrath =
+ virtual void() init_spawned =
{
- // 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;
@@ -285,23 +281,23 @@ class gib_head_shalrath: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_shalrath =
+ {
+ this.classtype = CT_GIB_HEAD_SHALRATH;
+ };
};

/*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");
}*/
-class gib_head_shambler: entity
+class gib_head_shambler: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_shambler =
+ virtual void() init_spawned =
{
- // 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
@@ -316,23 +312,23 @@ class gib_head_shambler: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_shambler =
+ {
+ this.classtype = CT_GIB_HEAD_SHAMBLER;
+ };
};

/*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");
}*/
-class gib_head_wizard: entity
+class gib_head_wizard: base_mapentity
{
//--------------------------------------------------------------
- void() gib_head_wizard =
+ virtual void() init_spawned =
{
- // 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;
@@ -347,23 +343,23 @@ class gib_head_wizard: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_head_wizard =
+ {
+ this.classtype = CT_GIB_HEAD_WIZARD;
+ };
};

/*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");
}*/
-class gib_misc_1: entity
+class gib_misc_1: base_mapentity
{
//--------------------------------------------------------------
- void() gib_misc_1 =
+ virtual void() init_spawned =
{
- // 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;
@@ -378,23 +374,23 @@ class gib_misc_1: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_misc_1 =
+ {
+ this.classtype = CT_GIB_MISC_1;
+ };
};

/*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");
}*/
-class gib_misc_2: entity
+class gib_misc_2: base_mapentity
{
//--------------------------------------------------------------
- void() gib_misc_2 =
+ virtual void() init_spawned =
{
- // 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;
@@ -409,23 +405,23 @@ class gib_misc_2: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_misc_2 =
+ {
+ this.classtype = CT_GIB_MISC_2;
+ };
};

/*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");
}*/
-class gib_misc_3: entity
+class gib_misc_3: base_mapentity
{
//--------------------------------------------------------------
- void() gib_misc_3 =
+ virtual void() init_spawned =
{
- // 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;
@@ -440,4 +436,10 @@ class gib_misc_3: entity
this.solid = SOLID_NOT;
}
};
+
+ //--------------------------------------------------------------
+ void() gib_misc_3 =
+ {
+ this.classtype = CT_GIB_MISC_3;
+ };
};

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 dd3f8c5..b643d39 100644
--- a/qc/misc/explobox.qc
+++ b/qc/misc/explobox.qc
@@ -3,9 +3,9 @@
//==============================================================================

//----------------------------------------------------------------------
-class base_explobox: entity
+class base_explobox: base_mapentity
{
- virtual void() barrel_explode =
+ nonvirtual void() barrel_explode =
{
this.takedamage = DAMAGE_NO;
this.classname = "explo_box";
@@ -28,16 +28,8 @@ Explosive box
class misc_explobox: base_explobox
{
//--------------------------------------------------------------
- void() misc_explobox =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- local float oldz;
-
- this.classname = "misc_explobox";
- this.classtype = CT_MISC_EXPLOBOX;
this.solid = SOLID_BBOX;
this.movetype = MOVETYPE_NONE;
precache_model ("maps/b_explob.bsp");
@@ -51,7 +43,7 @@ class misc_explobox: base_explobox
this.touch = monster_touch;

this.origin_z = this.origin_z + 2;
- oldz = this.origin_z;
+ local float oldz = this.origin_z;
droptofloor ();
if (oldz - this.origin_z > 250)
{
@@ -61,6 +53,12 @@ class misc_explobox: base_explobox
remove (this);
}
};
+
+ //--------------------------------------------------------------
+ void() misc_explobox =
+ {
+ this.classtype = CT_MISC_EXPLOBOX;
+ };
};

/*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
@@ -72,16 +70,8 @@ Smaller explosive box
class misc_explobox2: base_explobox
{
//--------------------------------------------------------------
- void() misc_explobox2 =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- local float oldz;
-
- this.classname = "misc_explobox2";
- this.classtype = CT_MISC_EXPLOBOX2;
this.solid = SOLID_BBOX;
this.movetype = MOVETYPE_NONE;
precache_model2 ("maps/b_exbox2.bsp");
@@ -95,7 +85,7 @@ class misc_explobox2: base_explobox
this.touch = monster_touch;

this.origin_z = this.origin_z + 2;
- oldz = this.origin_z;
+ local float oldz = this.origin_z;
droptofloor ();
if (oldz - this.origin_z > 250)
{
@@ -105,4 +95,10 @@ class misc_explobox2: base_explobox
remove (this);
}
};
+
+ //--------------------------------------------------------------
+ void() misc_explobox2 =
+ {
+ this.classtype = CT_MISC_EXPLOBOX2;
+ };
};

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 52de1b6..e892288 100644
--- a/qc/misc/fireball.qc
+++ b/qc/misc/fireball.qc
@@ -2,53 +2,63 @@
// misc_fireball
//==============================================================================

+//------------------------------------------------------------------------------
+class temp_fireball: base_tempentity
+{
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ T_Damage (toucher, this, this, 20);
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ void() temp_fireball =
+ {
+ this.classname = "fireball";
+ this.classtype = CT_TEMP_FIREBALL;
+ this.solid = SOLID_TRIGGER;
+ this.movetype = MOVETYPE_TOSS;
+ setmodel (this, "progs/lavaball.mdl");
+ setsize (this, '0 0 0', '0 0 0');
+ setorigin (this, this.origin);
+ this.nextthink = time + 5;
+ };
+};
+
/*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
+Flying lava balls spawner
speed - set vertical speed of fireballs. default 1000.
*/
-class misc_fireball: entity
+class misc_fireball: base_mapentity
{
//--------------------------------------------------------------
- virtual void() fire_touch =
- {
- T_Damage (other, this, this, 20);
- remove (this);
- };
+ // was fire_fly -- CEV
//--------------------------------------------------------------
- nonvirtual void() fire_fly =
+ virtual void(entity caller) do_think =
{
- local entity fireball;
+ local temp_fireball fireball;

- fireball = spawn ();
- fireball.solid = SOLID_TRIGGER;
- fireball.movetype = MOVETYPE_TOSS;
- fireball.velocity = '0 0 1000';
- fireball.velocity_x = (random() * 100) - 50;
- fireball.velocity_y = (random() * 100) - 50;
- fireball.velocity_z = 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;
+ fireball = spawn (temp_fireball,
+ velocity: [
+ (random() * 100) - 50,
+ (random() * 100) - 50,
+ this.speed + (random() * 200)],
+ origin: this.origin);

this.nextthink = time + (random() * 5) + 3;
- this.think = fire_fly;
};

//--------------------------------------------------------------
- void() misc_fireball =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- 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
@@ -56,10 +66,15 @@ class misc_fireball: entity
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() misc_fireball =
+ {
+ this.classname = "fireball";
+ this.classtype = CT_MISC_FIREBALL;
+ };
};

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 bac87ad..07c4978 100644
--- a/qc/misc/infight.qc
+++ b/qc/misc/infight.qc
@@ -17,7 +17,7 @@
const float INFIGHT_MUTUAL = 1;
const float INFIGHT_PLAYER_ACTIVATION = 2;

-class misc_infight: entity
+class misc_infight: base_mapentity
{
//--------------------------------------------------------------
nonvirtual void(entity t1, entity t2) make_angry_at =
@@ -36,7 +36,7 @@ class misc_infight: entity
};

//--------------------------------------------------------------
- virtual void() misc_infight_use =
+ virtual void(entity caller) do_use =
{
local entity t1, t2;

@@ -117,14 +117,11 @@ class misc_infight: entity
};

//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
void() misc_infight =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- 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 d7ee158..0e74565 100644
--- a/qc/misc/light_candle.qc
+++ b/qc/misc/light_candle.qc
@@ -114,12 +114,30 @@ _anglescale => _anglescale
//dumptruck_ds taken from honey (originally from Rogue)
White candle
*/
-class light_candle: entity
+class light_candle: base_mapentity
{
- // the following block of code doesn't seem to be used anywhere -- CEV
- /*
//--------------------------------------------------------------
- void() model_candle_think =
+ virtual void() init_spawned =
+ {
+ precache_model ("progs/candle.mdl");
+ setmodel (this, "progs/candle.mdl");
+ makestatic (this);
+ };
+
+ //--------------------------------------------------------------
+ void() light_candle =
+ {
+ this.classtype = CT_LIGHT_CANDLE;
+ };
+};
+
+//------------------------------------------------------------------------------
+class model_candle: base_mapentity
+{
+ //--------------------------------------------------------------
+ // was model_candle_think
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
this.frame = this.frame + 1;
if (this.frame > 3)
@@ -128,28 +146,16 @@ class light_candle: entity
};

//--------------------------------------------------------------
- void() model_candle =
+ virtual void() init_spawned =
{
precache_model ("progs/candle.mdl");
-
setmodel (this, "progs/candle.mdl");
-
- this.think = model_candle_think;
this.nextthink = time + 0.1;
};
- */

//--------------------------------------------------------------
- void() light_candle =
+ void() model_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);
+ this.classtype = CT_MISC_MODELCANDLE;
};
};

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 5f0ebe2..cf59cf2 100644
--- a/qc/misc/lights.qc
+++ b/qc/misc/lights.qc
@@ -7,6 +7,9 @@ const float LIGHT_START_OFF = 1;
const float LIGHT_FADE_IN_OUT = 2;
const float LIGHT_SILENT_TORCH = 4; // for silent torch -- dumptruck_ds

+const float LIGHT_THINK_FADE_IN = 1;
+const float LIGHT_THINK_FADE_OUT = 2;
+
//----------------------------------------------------------------------
// lightstyle_lookup
//----------------------------------------------------------------------
@@ -115,67 +118,85 @@ string(float num) lightstyle_fade_lookup =
}
};

-class base_light: entity
+//------------------------------------------------------------------------------
+class base_light: base_mapentity
{
- //--------------------------------------------------------------
- // light_fade_in
- //--------------------------------------------------------------
- nonvirtual void() light_fade_in =
+ float think_state;
+
+ virtual void(entity caller) do_think =
{
- if (this.count < 0)
- this.count = 0;
- if (this.count > 12)
- this.count = 12;
+ if (this.think_state == LIGHT_THINK_FADE_IN)
+ {
+ // 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;
+ lightstyle (this.style,
+ lightstyle_fade_lookup(this.count));

- this.think = light_fade_in;
- this.nextthink = time + this.speed;
- };
+ this.count = this.count + 1;
+ if (this.count > 12)
+ return;

- //--------------------------------------------------------------
- // light_fade_out
- //--------------------------------------------------------------
- nonvirtual void() light_fade_out =
- {
- if (this.count < 0)
- this.count = 0;
- if (this.count > 12)
- this.count = 12;
+ this.nextthink = time + this.speed;
+ }
+ else if (this.think_state == LIGHT_THINK_FADE_OUT)
+ {
+ // light_fade_out
+ 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;
+ lightstyle (this.style,
+ lightstyle_fade_lookup(this.count));

- this.think = light_fade_out;
- this.nextthink = time + this.speed;
+ this.count = this.count - 1;
+ if (this.count < 0)
+ return;
+
+ this.nextthink = time + this.speed;
+ }
+ else
+ {
+ dprint ("base_light::do_think: unhandled "
+ "think state!\n");
+ }
};

//--------------------------------------------------------------
// light_use -- using a light will turn it on and off
//--------------------------------------------------------------
- nonvirtual void() light_use =
+ virtual void(entity caller) do_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 ();
+ {
+ this.think_state = LIGHT_THINK_FADE_IN;
+ this.do_think (other);
+ }
else
+ {
lightstyle (this.style,
lightstyle_lookup(this.style2));
+ }
}
else
{
this.spawnflags = this.spawnflags + LIGHT_START_OFF;
if (this.spawnflags & LIGHT_FADE_IN_OUT && !this.style2)
- light_fade_out ();
+ {
+ this.think_state = LIGHT_THINK_FADE_OUT;
+ this.do_think (other);
+ }
else
+ {
lightstyle (this.style, "a");
+ }
}
};

@@ -199,7 +220,6 @@ class base_light: entity
return;

// switchable light
- this.use = light_use;
if (this.spawnflags & LIGHT_START_OFF)
{
this.count = 0;
@@ -328,16 +348,15 @@ _anglescale => _anglescale
class light: base_light
{
//--------------------------------------------------------------
- void() light =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ light_init ();
+ };

- this.classname = "light";
+ //--------------------------------------------------------------
+ void() light =
+ {
this.classtype = CT_LIGHT;
-
- light_init ();
};
};

@@ -350,19 +369,18 @@ See the "light" entity for a full description.
class light_fluoro: base_light
{
//--------------------------------------------------------------
- void() light_fluoro =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "light_fluoro";
- this.classtype = CT_LIGHT_FLUORO;
-
// TODO CEV calling lbuzz directly
base_ambient_sound::ambient_sound_lbuzz (this.origin);
light_init ();
};
+
+ //--------------------------------------------------------------
+ void() light_fluoro =
+ {
+ this.classtype = CT_LIGHT_FLUORO;
+ };
};

/*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
@@ -376,20 +394,19 @@ See the "light" entity for a full description.
class light_fluorospark: base_ambient_sound
{
//--------------------------------------------------------------
- void() light_fluorospark =
+ virtual void() init_spawned =
{
- // 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);
};
+
+ //--------------------------------------------------------------
+ void() light_fluorospark =
+ {
+ this.classtype = CT_LIGHT_FLUOROSPARK;
+ };
};

/*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
@@ -400,19 +417,18 @@ See the "light" entity for a full description.
class light_globe: base_light
{
//--------------------------------------------------------------
- void() light_globe =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "light_globe";
- this.classtype = CT_LIGHT_GLOBE;
-
precache_model ("progs/s_light.spr");
setmodel (this, "progs/s_light.spr");
makestatic (this);
};
+
+ //--------------------------------------------------------------
+ void() light_globe =
+ {
+ this.classtype = CT_LIGHT_GLOBE;
+ };
};

/*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
@@ -423,14 +439,8 @@ See the "light" entity for a full description.
class light_torch_small_walltorch: base_ambient_sound
{
//--------------------------------------------------------------
- void() light_torch_small_walltorch =
+ virtual void() init_spawned =
{
- // 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");
@@ -440,6 +450,12 @@ class light_torch_small_walltorch: base_ambient_sound
ambient_sound_fire (this.origin);
makestatic (this);
};
+
+ //--------------------------------------------------------------
+ void() light_torch_small_walltorch =
+ {
+ this.classtype = CT_LIGHT_TORCH_SMALL_WALLTORCH;
+ };
};

/*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
@@ -450,20 +466,20 @@ See the "light" entity for a full description.
class light_flame_large_yellow: base_ambient_sound
{
//--------------------------------------------------------------
- void() light_flame_large_yellow =
+ virtual void() init_spawned =
{
- // 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);
};
+
+ //--------------------------------------------------------------
+ void() light_flame_large_yellow =
+ {
+ this.classtype = CT_LIGHT_FLAME_LARGE_YELLOW;
+ };
};

/*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
@@ -473,19 +489,20 @@ See the "light" entity for a full description.
*/
class light_flame_small_yellow: base_ambient_sound
{
- void() light_flame_small_yellow =
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // 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);
};
+
+ void() light_flame_small_yellow =
+ {
+ this.classname = "light_flame_small_yellow";
+ this.classtype = CT_LIGHT_FLAME_SMALL_YELLOW;
+ };
};

/*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
@@ -501,12 +518,8 @@ Large flame spite*/
class light_sprite_flame: base_misc_model
{
//--------------------------------------------------------------
- void() light_sprite_flame =
+ virtual void() init_spawned =
{
- // 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
@@ -517,7 +530,12 @@ class light_sprite_flame: base_misc_model
this.first_frame = 0;
this.last_frame = 13;
this.speed = 0.05;
- this.think = misc_model_think;
this.nextthink = time + 0.1;
};
+
+ //--------------------------------------------------------------
+ void() light_sprite_flame =
+ {
+ this.classtype = CT_LIGHT_SPRITE_FLAME;
+ };
};

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 afefc39..975188f 100644
--- a/qc/misc/model.qc
+++ b/qc/misc/model.qc
@@ -15,39 +15,32 @@ const float MISC_MODEL_ONLY_ONCE = 8;
const float MISC_MODEL_PLAY_COUNT = 16;
const float MISC_MODEL_STARTOFF = 32;

-class base_misc_model: entity
+class base_misc_model: base_mapentity
{
// class fields
float first_frame; // The starting frame of the animation
float last_frame; // The ending frame of the animation

//--------------------------------------------------------------
- virtual void() misc_model_use =
+ virtual void(string fieldname, string fieldvalue) init_field =
{
- if (this.state == STATE_ACTIVE)
+ switch (fieldname)
{
- 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);
+ case "first_frame":
+ first_frame = stof (fieldvalue);
+ break;
+ case "last_frame":
+ last_frame = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
}
};

//--------------------------------------------------------------
// misc_model_think -- Handles animation for misc_model entity.
//--------------------------------------------------------------
- virtual void() misc_model_think =
+ virtual void(entity caller) do_think =
{
this.nextthink = time + fabs (this.speed);
if (this.estate != STATE_ACTIVE)
@@ -97,6 +90,28 @@ class base_misc_model: entity
}
};

+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ 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);
+ }
+ };
};

/*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
@@ -117,15 +132,8 @@ last_frame: The last frame of the animation.
class misc_model: base_misc_model
{
//--------------------------------------------------------------
- void() misc_model =
+ virtual void() init_spawned =
{
- // 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");

@@ -134,6 +142,8 @@ class misc_model: base_misc_model
if (!this.mdlsz)
this.mdlsz = '32 32 32';

+ this.interaction_flags |= DISABLE_THINK;
+
vector vmin, vmax;

vmin_x = this.centeroffset_x - (this.mdlsz_x / 2);
@@ -157,8 +167,6 @@ class misc_model: base_misc_model
this.movetype = MOVETYPE_TOSS;
else this.movetype = MOVETYPE_NONE;

- this.use = misc_model_use;
-
if (!this.frame)
this.frame = this.first_frame;

@@ -192,7 +200,7 @@ class misc_model: base_misc_model
if (!this.speed)
this.speed = 0.1;
this.nextthink = time + this.speed;
- this.think = misc_model_think;
+ this.interaction_flags &= ~DISABLE_THINK;
}

if (this.spawnflags & MISC_MODEL_STARTOFF)
@@ -200,6 +208,12 @@ class misc_model: base_misc_model
else
this.state = STATE_INVISIBLE;

- misc_model_use ();
+ do_use (other);
+ };
+
+ //--------------------------------------------------------------
+ void() misc_model =
+ {
+ this.classtype = CT_MISC_MODEL;
};
};

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 c8ff211..ff3cb10 100644
--- a/qc/misc/modeltrain.qc
+++ b/qc/misc/modeltrain.qc
@@ -2,161 +2,370 @@
// misc_modeltrain -- was plats.qc
//==============================================================================

- //--------------------------------------------------------------
-void() animcontroller_think =
+// constants
+const float TRAIN_STYLE_SINGLEANIM = 1; // modeltrain with one animation
+
+const float TRAIN_ANIMTYPE_FORWARD = 1;
+const float TRAIN_ANIMTYPE_BACKFORTH = 2;
+
+//------------------------------------------------------------------------------
+class base_misc_modeltrain: base_func_train
{
- local float first, last, step, atype, dir, nextframe;
- local entity tr;
+ // class fields
+ float first_frame;
+ float first_frame2;
+ float last_frame;
+ float last_frame2;
+ float frtime;
+ float frtime2;
+ float animtype;
+ float animtype2;
+ float multiplier;
+ float speed2;

- tr = self.owner;
+ vector cmins;
+ vector cmaxs;

- // train just went from stopped to moving or vice-versa,
- // and have both animations set
- if (self.state != tr.state && tr.style != TRAIN_STYLE_SINGLEANIM)
+ //--------------------------------------------------------------
+ virtual void(string fieldname, string fieldvalue) init_field =
{
- if (tr.state)
+ switch (fieldname)
{
- // just started moving
- tr.frame = zeroconvert (tr.first_frame2);
+ case "cmins":
+ cmins = stov (fieldvalue);
+ break;
+ case "cmaxs":
+ cmaxs = stov (fieldvalue);
+ break;
+ case "first_frame":
+ first_frame = stof (fieldvalue);
+ break;
+ case "first_frame2":
+ first_frame2 = stof (fieldvalue);
+ break;
+ case "last_frame":
+ last_frame = stof (fieldvalue);
+ break;
+ case "last_frame2":
+ last_frame2 = stof (fieldvalue);
+ break;
+ case "frtime":
+ frtime = stof (fieldvalue);
+ break;
+ case "frtime2":
+ frtime2 = stof (fieldvalue);
+ break;
+ case "animtype":
+ animtype = stof (fieldvalue);
+ break;
+ case "animtype2":
+ animtype2 = stof (fieldvalue);
+ break;
+ case "multiplier":
+ multiplier = stof (fieldvalue);
+ break;
+ case "speed2":
+ speed2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
}
- else
- {
- // just stopped
- tr.frame = zeroconvert (tr.first_frame);
- }
- // reset back/forth status
- tr.distance = 1;
- self.state = tr.state;
- }
- else
+ };
+};
+
+//------------------------------------------------------------------------------
+class temp_anim_controller: base_tempentity
+{
+ base_misc_modeltrain tr;
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (self.state && tr.style != TRAIN_STYLE_SINGLEANIM)
+ local float first, last, step, atype, dir, nextframe;
+
+ // train just went from stopped to moving or vice-versa,
+ // and have both animations set
+ if (this.state != tr.state &&
+ tr.style != TRAIN_STYLE_SINGLEANIM)
{
- // moving train animation, if set
- first = zeroconvert (tr.first_frame2);
- last = zeroconvert (tr.last_frame2);
- atype = tr.animtype2;
+ if (tr.state)
+ // just started moving
+ tr.frame = zeroconvert (tr.first_frame2);
+ else
+ // just stopped
+ tr.frame = zeroconvert (tr.first_frame);
+
+ // reset back/forth status
+ tr.distance = 1;
+ this.state = tr.state;
}
else
{
- // stopped/default train animation
- first = zeroconvert (tr.first_frame);
- last = zeroconvert (tr.last_frame);
- atype = tr.animtype;
- }
+ if (this.state && tr.style != TRAIN_STYLE_SINGLEANIM)
+ {
+ // moving train animation, if set
+ first = zeroconvert (tr.first_frame2);
+ last = zeroconvert (tr.last_frame2);
+ atype = tr.animtype2;
+ }
+ else
+ {
+ // stopped/default train animation
+ first = zeroconvert (tr.first_frame);
+ last = zeroconvert (tr.last_frame);
+ atype = tr.animtype;
+ }

- if (first > last)
- // reverse direction
- step = dir = -1;
- else
- step = dir = 1;
+ if (first > last)
+ // reverse direction
+ step = dir = -1;
+ else
+ step = dir = 1;

- // back-and-forth is going the other way, so invert
- // the step's signal
- if (tr.distance < 0)
- step = step * (-1);
+ // back-and-forth is going the other way, so invert
+ // the step's signal
+ if (tr.distance < 0)
+ step = step * (-1);

- nextframe = tr.frame + step;
+ nextframe = tr.frame + step;

- if (atype == TRAIN_ANIMTYPE_BACKFORTH)
- {
- if (dir > 0 && (nextframe > last ||
- nextframe < first) ||
- dir < 0 && (nextframe > first ||
- nextframe < last))
+ if (atype == TRAIN_ANIMTYPE_BACKFORTH)
{
- nextframe = tr.frame - step;
- tr.distance = tr.distance * (-1);
+ if (dir > 0 && (nextframe > last ||
+ nextframe < first) ||
+ dir < 0 && (nextframe > first ||
+ nextframe < last))
+ {
+ nextframe = tr.frame - step;
+ tr.distance = tr.distance * (-1);
+ }
}
+
+ if (dir > 0)
+ nextframe = wrap (nextframe, first, last);
+ else
+ nextframe = wrap (nextframe, last, first);
+
+ tr.frame = nextframe;
}

- if (dir > 0)
- nextframe = wrap (nextframe, first, last);
+ if (this.state || tr.style == TRAIN_STYLE_SINGLEANIM)
+ this.nextthink = time + tr.frtime;
else
- nextframe = wrap (nextframe, last, first);
+ this.nextthink = time + tr.frtime2;
+ };
+
+ //--------------------------------------------------------------
+ void() temp_anim_controller =
+ {
+ this.classname = "animcontroller";
+ this.classtype = CT_TEMP_ANIM_CONTROLLER;
+ this.state = 0;
+ };
+};
+
+//------------------------------------------------------------------------------
+class temp_rotate_controller: base_tempentity
+{
+ base_misc_modeltrain tr;
+
+ //--------------------------------------------------------------
+ // SUB_CalcAngleMoveDoneController
+ // After rotating, set angle to exact final angle
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ tr.angles = this.finalangle;
+ tr.avelocity = '0 0 0';
+ this.nextthink = -1;
+ };
+
+ //--------------------------------------------------------------
+ // SUB_CalcAngleMoveController -- Same as SUB_CalcAngleMove, but
+ // using a separate controller entity to not lose track of current
+ // think functions.
+ //--------------------------------------------------------------
+ nonvirtual void(vector destangle, float tspeed) sub_calcanglemove =
+ {
+ local vector destdelta;
+ local float len, traveltime;
+
+ if (!tspeed)
+ objerror("No speed is defined!");

- tr.frame = nextframe;
+ // set destdelta to the vector needed to move
+ destdelta = normalizeAngles180 (destangle - tr.angles);

- }
+ /*
+ dprint3 ("destangle: ", vtos(destangle), "\n");
+ dprint3 ("this.angles: ", vtos(this.angles), "\n");
+ dprint3 ("destdelta: ", vtos(destdelta), "\n");
+ */

- self.think = animcontroller_think;
- if (self.state || tr.style == TRAIN_STYLE_SINGLEANIM)
- self.nextthink = time + tr.frtime;
- else
- self.nextthink = time + tr.frtime2;
-};
+ // calculate length of vector
+ len = vlen (destdelta);
+
+ // divide by speed to get time to reach dest
+ traveltime = len / tspeed;
+
+ // set nextthink to trigger a think when dest is reached
+ this.nextthink = time + traveltime;
+
+ // scale the destdelta vector by the time spent traveling to
+ // get velocity
+ tr.avelocity = destdelta * (1 / traveltime);
+
+ // Makes sure controller.owner points to self so it can be
+ // referenced later in the think function
+ this.finalangle = destangle;
+ };

//--------------------------------------------------------------
-void() misc_modeltrain =
+ void() temp_rotate_controller =
+ {
+ this.classname = "rotatecontroller";
+ this.classtype = CT_TEMP_ROTATE_CONTROLLER;
+ };
+};
+
+//------------------------------------------------------------------------------
+class misc_modeltrain: base_misc_modeltrain
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ temp_anim_controller animcontroller;
+ temp_rotate_controller rotatecontroller;

- precache_model (self.mdl);
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlepath =
+ {
+ // copies the modeltrain animation parameters set in the
+ // path_corner, if any
+ if (this.enemy.classtype == CT_PATH_CORNER)
+ {
+ local path_corner path = (path_corner)this.enemy;
+ if (path.first_frame)
+ this.first_frame = path.first_frame;
+ if (path.last_frame)
+ this.last_frame = path.last_frame;
+ if (path.first_frame2)
+ this.first_frame2 = path.first_frame2;
+ if (path.last_frame2)
+ this.last_frame2 = path.last_frame2;
+ if (path.frtime)
+ this.frtime = path.frtime;
+ if (path.frtime2)
+ this.frtime2 = path.frtime2;
+ if (path.animtype)
+ this.animtype = path.animtype;
+ if (path.animtype2)
+ this.animtype2 = path.animtype2;
+ if (path.multiplier)
+ this.multiplier = path.multiplier;
+ }
+ };

- func_train ();
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlepause =
+ {
+ animcontroller.do_think (other);
+ };

- if (self.spawnflags & TRAIN_NONSOLID)
+ //--------------------------------------------------------------
+ virtual void() train_wait_handlestop =
{
- self.solid = SOLID_NOT;
- }
- else
- {
- self.solid = SOLID_BBOX;
- if (self.cmins == VEC_ORIGIN)
- self.cmins = '-8 -8 -8';
- if (self.cmaxs == VEC_ORIGIN)
- self.cmaxs = '8 8 8';
- }
-
- self.movetype = MOVETYPE_NOCLIP;
- setmodel (self, self.mdl);
- setsize (self, self.cmins , self.cmaxs);
- setorigin (self, self.origin);
-
- local entity rot, anim;
-
- rot = spawn ();
- self.rotatecontroller = rot;
- rot.classname = "rotatecontroller";
- rot.owner = self;
-
- anim = spawn ();
- self.animcontroller = anim;
- anim.classname = "animcontroller";
- anim.owner = self;
-
- anim.think = animcontroller_think;
- anim.nextthink = time + 0.2;
-
- self.distance = 1;
-
- if (!self.frtime)
- self.frtime = 0.1;
- if (!self.frtime2)
- self.frtime2 = self.frtime;
- if (!self.multiplier)
- self.multiplier = 1;
-
- // make sure all first and last frame fields are filled
- if (self.first_frame && !self.last_frame)
- self.last_frame = self.first_frame;
- else if (!self.first_frame && self.last_frame)
- self.first_frame = self.last_frame;
+ animcontroller.do_think (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity targ) train_next_custom =
+ {
+ vector destang = '0 0 0';
+
+ if (!(this.spawnflags & TRAIN_NOROTATE))
+ {
+ destang = vectoangles (targ.origin - this.origin);
+
+ if (this.spawnflags & TRAIN_ROTATEY)
+ {
+ destang_x = this.angles_x;
+ destang_z = this.angles_z;
+ }
+
+ if (this.multiplier > 0)
+ rotatecontroller.sub_calcanglemove (destang,
+ this.speed2 * this.multiplier);
+ else
+ this.angles = destang;
+ }
+
+ if (!this.state)
+ {
+ this.state = 1;
+ if (this.style != TRAIN_STYLE_SINGLEANIM)
+ animcontroller.do_think (other);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ precache_model (this.mdl);
+ train_init ();
+
+ if (this.spawnflags & TRAIN_NONSOLID)
+ {
+ this.solid = SOLID_NOT;
+ }
+ else
+ {
+ this.solid = SOLID_BBOX;
+ if (this.cmins == VEC_ORIGIN)
+ this.cmins = '-8 -8 -8';
+ if (this.cmaxs == VEC_ORIGIN)
+ this.cmaxs = '8 8 8';
+ }
+
+ this.movetype = MOVETYPE_NOCLIP;
+ setmodel (this, this.mdl);
+ setsize (this, this.cmins , this.cmaxs);
+ setorigin (this, this.origin);
+
+ rotatecontroller = spawn (temp_rotate_controller, tr: this);
+ animcontroller = spawn (temp_anim_controller, tr: this);
+ animcontroller.nextthink = time + 0.2;
+
+ if (!this.frtime)
+ this.frtime = 0.1;
+ if (!this.frtime2)
+ this.frtime2 = this.frtime;
+ if (!this.multiplier)
+ this.multiplier = 1;
+
+ // make sure all first and last frame fields are filled
+ if (this.first_frame && !this.last_frame)
+ this.last_frame = this.first_frame;
+ else if (!this.first_frame && this.last_frame)
+ this.first_frame = this.last_frame;

- if (self.first_frame2 && !self.last_frame2)
- self.last_frame2 = self.first_frame2;
- else if (!self.first_frame2 && self.last_frame2)
- self.first_frame2 = self.last_frame2;
+ if (this.first_frame2 && !this.last_frame2)
+ this.last_frame2 = this.first_frame2;
+ else if (!this.first_frame2 && this.last_frame2)
+ this.first_frame2 = this.last_frame2;
+
+ if (this.first_frame2 == 0)
+ this.style = TRAIN_STYLE_SINGLEANIM;

- if (!self.first_frame2)
- self.style = TRAIN_STYLE_SINGLEANIM;
+ if (!this.animtype)
+ this.animtype = TRAIN_ANIMTYPE_FORWARD;
+ if (!this.animtype2)
+ this.animtype2 = this.animtype;

- if (!self.animtype)
- self.animtype = TRAIN_ANIMTYPE_FORWARD;
- if (!self.animtype2)
- self.animtype2 = self.animtype;
+ this.distance = 1;
+ this.frame = this.first_frame;
+ };

- self.frame = self.first_frame;
+ //--------------------------------------------------------------
+ void() misc_modeltrain =
+ {
+ this.classtype = CT_MISC_MODELTRAIN;
+ };
};

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 32a0671..8f2660c 100644
--- a/qc/misc/noisemaker.qc
+++ b/qc/misc/noisemaker.qc
@@ -6,10 +6,10 @@

For optimzation testing, starts a lot of sounds.
*/
-class misc_noisemaker: entity
+class misc_noisemaker: base_mapentity
{
//--------------------------------------------------------------
- virtual void() noise_think =
+ virtual void(entity caller) do_think =
{
this.nextthink = time + 0.5;
sound (this, 1, "enforcer/enfire.wav", 1, ATTN_NORM);
@@ -22,12 +22,8 @@ class misc_noisemaker: entity
};

//--------------------------------------------------------------
- void() misc_noisemaker =
+ virtual void() init_spawned =
{
- // 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");
@@ -39,9 +35,12 @@ class misc_noisemaker: entity
precache_sound2 ("enforcer/death1.wav");
precache_sound2 ("enforcer/idle1.wav");

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

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 15a2e34..fb684bb 100644
--- a/qc/misc/particle_stream.qc
+++ b/qc/misc/particle_stream.qc
@@ -15,7 +15,7 @@ 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
*/
-class misc_particle_stream: entity
+class misc_particle_stream: base_mapentity
{
//--------------------------------------------------------------
nonvirtual void(vector start, vector end, float color1, float color2,
@@ -44,16 +44,9 @@ class misc_particle_stream: entity
};

//--------------------------------------------------------------
- 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);
- };
-
+ // was particle_stream_start -- CEV
//--------------------------------------------------------------
- virtual void() particle_stream_start =
+ virtual void(entity caller) do_think =
{
local entity pspot;

@@ -61,7 +54,8 @@ class misc_particle_stream: entity

if (!pspot)
{
- dprint ("Particle stream can't find target!");
+ dprint ("misc_particle_stream::do_think: "
+ "Particle stream can't find target!\n");
return;
}

@@ -69,15 +63,17 @@ class misc_particle_stream: entity
};

//--------------------------------------------------------------
- void() misc_particle_stream =
+ virtual void(entity caller) do_use =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "misc_particle_stream";
- this.classtype = CT_MISC_PARTICLE_STREAM;
+ 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() init_spawned =
+ {
if (!this.target)
objerror ("misc_particle_stream with not target!");

@@ -88,10 +84,14 @@ class misc_particle_stream: entity
if (!this.noise)
this.noise = "misc/null.wav";

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

- this.use = particle_use;
- this.think = particle_stream_start;
this.nextthink = time + 0.2;
};
+
+ //--------------------------------------------------------------
+ void() misc_particle_stream =
+ {
+ this.classtype = CT_MISC_PARTICLE_STREAM;
+ };
};

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 b9a6975..e888516 100644
--- a/qc/misc/particles.qc
+++ b/qc/misc/particles.qc
@@ -5,7 +5,7 @@
//==============================================================================

// constants
-const float PARTICLES_START_OFF;
+const float PARTICLES_START_OFF = 1;

/*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

@@ -19,51 +19,44 @@ Produces a continuous particle splash for waterfalls and other effects

"volume" density of particles. (default 10)
*/
-class misc_particles: entity
+class misc_particles: base_mapentity
{
//--------------------------------------------------------------
- virtual void() splash_use =
+ // was splash_think -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (this.spawnflags & PARTICLES_START_OFF)
- this.spawnflags = this.spawnflags - PARTICLES_START_OFF;
- else
- this.spawnflags = this.spawnflags + PARTICLES_START_OFF;
+ 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;
};

//--------------------------------------------------------------
- virtual void() splash_think =
+ virtual void(entity caller) do_use =
{
if (this.spawnflags & PARTICLES_START_OFF)
{
- this.nextthink = time + 0.1;
- this.think = splash_think;
+ this.spawnflags = this.spawnflags - PARTICLES_START_OFF;
+ this.interaction_flags |= DISABLE_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;
+ this.spawnflags = this.spawnflags + PARTICLES_START_OFF;
+ this.interaction_flags &= ~DISABLE_THINK;
}
};

//--------------------------------------------------------------
- void() misc_particles =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "misc_particles";
- this.classtype = CT_MISC_PARTICLES;
-
if (!this.wait)
this.wait = 0.1;

@@ -73,9 +66,18 @@ class misc_particles: entity
if (!this.volume)
this.volume = 10;

+ if (this.spawnflags & PARTICLES_START_OFF)
+ this.interaction_flags |= DISABLE_THINK;
+ else
+ this.interaction_flags &= ~DISABLE_THINK;
+
this.color = this.color * 16;
- this.use = splash_use;
this.nextthink = time + this.wait;
- this.think = splash_think;
+ };
+
+ //--------------------------------------------------------------
+ void() misc_particles =
+ {
+ this.classtype = CT_MISC_PARTICLES;
};
};

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 9e1826f..08bae28 100644
--- a/qc/misc/particlespray.qc
+++ b/qc/misc/particlespray.qc
@@ -18,14 +18,27 @@ 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.
*/
-class misc_particlespray: entity
+class misc_particlespray: base_mapentity
{
// class fields
float endtime;
float duration;

//--------------------------------------------------------------
- virtual void() particlespray_think =
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "duration":
+ duration = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
particle (this.origin, this.movedir, this.color, this.count);

@@ -39,18 +52,18 @@ class misc_particlespray: entity
};

//--------------------------------------------------------------
- virtual void() particlespray_use =
+ virtual void(entity caller) do_use =
{
+ if (this.targetname != __NULL__ && this.targetname != "")
+ return;
+
this.endtime = time + this.duration;
- particlespray_think ();
+ this.do_think (caller);
};

- void() misc_particlespray =
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
if (!this.color)
this.color = 47;

@@ -64,13 +77,14 @@ class misc_particlespray: entity
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;
+ };
+
+ //--------------------------------------------------------------
+ void() misc_particlespray =
+ {
+ this.classname = "particlespray";
+ this.classtype = CT_MISC_PARTICLESPRAY;
};
};

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 9ed77d9..919d729 100644
--- a/qc/misc/play.qc
+++ b/qc/misc/play.qc
@@ -9,10 +9,25 @@
// Distributed (unsupported) on 3.12.97
//======================================================================

-class base_play_sound: entity
+class base_play_sound: base_mapentity
{
//--------------------------------------------------------------
- virtual void() play_sound_use =
+ // was play_sound_think -- CEV
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ local float t;
+ t = this.wait * random ();
+
+ if (t < this.delay)
+ t = this.delay;
+
+ this.nextthink = time + t;
+ this.do_use (other);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
if (this.spawnflags & 1)
{
@@ -37,19 +52,6 @@ class base_play_sound: entity
};

//--------------------------------------------------------------
- virtual void() play_sound_think =
- {
- local float t;
- t = this.wait * random ();
-
- if (t < this.delay)
- t = this.delay;
-
- this.nextthink = time + t;
- play_sound_use ();
- };
-
- //--------------------------------------------------------------
nonvirtual void() play_sound_init =
{
precache_sound (this.noise);
@@ -64,7 +66,12 @@ class base_play_sound: entity
if (this.spawnflags & 1)
if (this.impulse == 0)
this.impulse = 7;
- this.use = play_sound_use;
+ };
+
+ //--------------------------------------------------------------
+ void() base_play_sound =
+ {
+ this.interaction_flags |= DISABLE_THINK;
};
};

@@ -83,12 +90,8 @@ play a sound when it is used
class play_sound_triggered: base_play_sound
{
//--------------------------------------------------------------
- virtual void() play_sound_triggered =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
// dumptruck_ds
if (!this.noise)
{
@@ -96,10 +99,13 @@ class play_sound_triggered: base_play_sound
remove (this);
return;
}
+ play_sound_init ();
+ };

- this.classname = "play_sound_triggered";
+ //--------------------------------------------------------------
+ void() play_sound_triggered =
+ {
this.classtype = CT_MISC_PLAY_SOUND_TRIGGERED;
- play_sound_init ();
};
};

@@ -119,14 +125,8 @@ play a sound on a periodic basis
class play_sound: base_play_sound
{
//--------------------------------------------------------------
- void() play_sound =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- local float t;
-
// dumptruck_ds
if (!this.noise)
{
@@ -135,8 +135,6 @@ class play_sound: base_play_sound
return;
}

- this.classname = "play_sound";
- this.classtype = CT_MISC_PLAY_SOUND;
play_sound_init ();

if (this.wait == 0)
@@ -144,20 +142,27 @@ class play_sound: base_play_sound
if (this.delay == 0)
this.delay = 2;

- this.think = play_sound_think;
+ // enable think function
+ this.interaction_flags &= ~DISABLE_THINK;

- t = this.wait * random ();
+ local float t = this.wait * random ();
if (t < this.delay)
t = this.delay;

this.nextthink = time + t;
};
+
+ //--------------------------------------------------------------
+ void() play_sound =
+ {
+ this.classtype = CT_MISC_PLAY_SOUND;
+ };
};

-class base_tele_fog: entity
+class base_tele_fog: base_mapentity
{
//--------------------------------------------------------------
- virtual void() play_tfog =
+ virtual void(entity caller) do_use =
{
// thanks Khreathor -- dumptruck_ds
spawn_tfog (this.origin);
@@ -175,15 +180,12 @@ Use this when killtageting an entity if the player can see.
class tele_fog: base_tele_fog
{
//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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;
};
};

@@ -199,17 +201,15 @@ Use this when killtageting an entity if the player can see.
class play_tele: base_tele_fog
{
//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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;
};
};

@@ -218,10 +218,10 @@ class play_tele: base_tele_fog
When triggered, creates a explosion at it's origin. Causes damage.

*/
-class play_explosion: entity
+class play_explosion: base_mapentity
{
//--------------------------------------------------------------
- virtual void() play_explosion_fx =
+ virtual void(entity caller) do_use =
{
// thanks Khreathor -- dumptruck_ds
// GrenadeExplode uses this.owner as the attacker -- iw
@@ -230,15 +230,12 @@ class play_explosion: entity
};

//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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;
};
};

@@ -249,10 +246,10 @@ When triggered, plays the lavasplash effect from E1M7.
Use noise key for a custom sound.

*/
-class play_lavasplash: entity
+class play_lavasplash: base_mapentity
{
//--------------------------------------------------------------
- virtual void() play_lavasplash_fx =
+ virtual void(entity caller) do_use =
{
// thanks Khreathor -- dumptruck_ds
if (this.noise != "")
@@ -268,26 +265,25 @@ class play_lavasplash: entity
};

//--------------------------------------------------------------
- void() play_lavasplash =
+ virtual void() init_spawned =
{
- // 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 =
+ {
+ this.classtype = CT_MISC_PLAY_LAVASPLASH;
};
};

-class base_meat_shower: entity
+class base_meat_shower: base_mapentity
{
//--------------------------------------------------------------
- virtual void() play_meatspray =
+ virtual void(entity caller) do_use =
{
// -- dumptruck_ds -- thanks to Spike for helping with errors
if (this.style == 1)
@@ -328,15 +324,12 @@ Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regul
class meat_shower: base_meat_shower
{
//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
void() meat_shower =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "meat_shower";
this.classtype = CT_MISC_PLAY_GIBS;
- this.use = play_meatspray;
};
};

@@ -350,26 +343,23 @@ Use style 0 for normal and 1 for extra large. fly_sound 0 is silent, 1 for regul
class play_gibs: base_meat_shower
{
//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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
*/
-class play_mflash: entity
+class play_mflash: base_mapentity
{
//--------------------------------------------------------------
- virtual void() mflash_use =
+ virtual void(entity caller) do_use =
{
this.effects = this.effects | EF_MUZZLEFLASH;

@@ -378,15 +368,8 @@ class play_mflash: entity
};

//--------------------------------------------------------------
- void() play_mflash =
+ virtual void() init_spawned =
{
- // 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);
@@ -396,7 +379,12 @@ class play_mflash: entity
this.movetype = MOVETYPE_NONE;
this.solid = SOLID_NOT;
setsize (this, '0 0 0', '0 0 0');
- this.use = mflash_use;
+ };
+
+ //--------------------------------------------------------------
+ void() play_mflash =
+ {
+ this.classtype = CT_MISC_PLAY_MFLASH;
};
};

@@ -404,10 +392,10 @@ class play_mflash: entity
a triggerable, spherical field of yellow particles
state 1 = start on
*/
-class play_bfield: entity
+class play_bfield: base_mapentity
{
//--------------------------------------------------------------
- virtual void() bfield_toggle =
+ virtual void(entity caller) do_use =
{
if (!this.state)
{
@@ -425,15 +413,8 @@ class play_bfield: entity
};

//--------------------------------------------------------------
- void() play_bfield =
+ virtual void() init_spawned =
{
- // 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);
@@ -445,7 +426,12 @@ class play_bfield: entity
setsize (this, '0 0 0', '0 0 0');
if (this.state)
this.effects = this.effects | EF_BRIGHTFIELD;
- this.use = bfield_toggle;
+ };
+
+ //--------------------------------------------------------------
+ void() play_bfield =
+ {
+ this.classtype = CT_MISC_PLAY_BFIELD;
};
};

@@ -453,10 +439,10 @@ class play_bfield: entity
a triggerable bright lighting effect
state 1 = start on
*/
-class play_brlight: entity
+class play_brlight: base_mapentity
{
//--------------------------------------------------------------
- virtual void() brlight_toggle =
+ virtual void(entity caller) do_use =
{
// dumptruck_ds -- thanks to c0burn
if (!this.state)
@@ -475,15 +461,8 @@ class play_brlight: entity
};

//--------------------------------------------------------------
- void() play_brlight =
+ virtual void() init_spawned =
{
- // 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);
@@ -495,7 +474,12 @@ class play_brlight: entity
setsize (this, '0 0 0', '0 0 0');
if (this.state)
this.effects = this.effects | EF_BRIGHTLIGHT;
- this.use = brlight_toggle;
+ };
+
+ //--------------------------------------------------------------
+ void() play_brlight =
+ {
+ this.classtype = CT_MISC_PLAY_BRLIGHT;
};
};

@@ -503,10 +487,10 @@ class play_brlight: entity
a triggerable lighting effect
state 1 = start on
*/
-class play_dimlight: entity
+class play_dimlight: base_mapentity
{
//--------------------------------------------------------------
- virtual void() dim_toggle =
+ virtual void(entity caller) do_use =
{
if (!this.state)
{
@@ -524,15 +508,8 @@ class play_dimlight: entity
};

//--------------------------------------------------------------
- void() play_dimlight =
+ virtual void() init_spawned =
{
- // 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);
@@ -545,6 +522,11 @@ class play_dimlight: entity
if (this.state)
this.effects = this.effects | EF_DIMLIGHT;
setorigin (this, this.origin);
- this.use = dim_toggle;
+ };
+
+ //--------------------------------------------------------------
+ void() play_dimlight =
+ {
+ this.classtype = CT_MISC_PLAY_DIMLIGHT;
};
};

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 58cdee6..2c49622 100644
--- a/qc/misc/sparks.qc
+++ b/qc/misc/sparks.qc
@@ -7,6 +7,74 @@ const float MISC_SPARKS_START_OFF = 1;
const float MISC_SPARKS_BLUE = 2;
const float MISC_SPARKS_PALE = 4;

+enum
+{
+ TEMP_SPARK_FADE1,
+ TEMP_SPARK_FADE2,
+ TEMP_SPARK_FADE3,
+ TEMP_SPARK_FADE4,
+ TEMP_SPARK_REMOVE,
+ MISC_SPARKS_OFFLIGHT,
+ MISC_SPARKS_MAKE
+};
+
+//------------------------------------------------------------------------------
+// temp_spark - an individual spark - from Rubicon2, refactored by CEV
+//------------------------------------------------------------------------------
+class temp_spark: base_tempentity
+{
+ float think_state;
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.think_state == TEMP_SPARK_REMOVE)
+ {
+ remove (this);
+ return;
+ }
+
+ this.alpha -= 0.2;
+ this.think_state += 1;
+ this.nextthink = time + 0.05;
+ };
+
+ //--------------------------------------------------------------
+ void() temp_spark =
+ {
+ this.classname = "spark";
+ this.classtype = CT_TEMP_SPARK;
+
+ this.movetype = MOVETYPE_BOUNCE;
+ this.solid = SOLID_TRIGGER;
+ this.alpha = 1.0;
+ this.gravity = 0.3;
+ this.velocity_x = -40 + random() * 80;
+ this.velocity_y = -40 + random() * 80;
+ this.velocity_z = -40 + random() * 80;
+ this.avelocity = '3000 3000 3000';
+
+ if (random() < 0.33)
+ this.skin = 0;
+ else if (random() < 0.5)
+ this.skin = 1;
+ else
+ this.skin = 2;
+
+ if (this.spawnflags & MISC_SPARKS_PALE)
+ this.skin = this.skin + 6;
+ else if (this.spawnflags & MISC_SPARKS_BLUE)
+ this.skin = this.skin + 3;
+
+ setmodel (this, "progs/spark.mdl");
+ setorigin (this, this.origin);
+ setsize (this, '0 0 0', '0 0 0');
+
+ this.think_state = TEMP_SPARK_FADE1;
+ this.nextthink = time + 0.5 + 1.5 * random();
+ };
+};
+
/*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

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.
@@ -25,127 +93,75 @@ Keys:
0) no sound
1) sparks
*/
-class misc_sparks: entity
+class misc_sparks: base_mapentity
{
- //--------------------------------------------------------------
- nonvirtual void() sparks_fade1 = [0, sparks_fade2]
- {
- this.alpha = 0.8; this.nextthink = time + 0.05;
- };
+ float think_state;

//--------------------------------------------------------------
- nonvirtual void() sparks_fade2 = [0, sparks_fade3]
+ virtual void(entity caller) do_think =
{
- this.alpha = 0.6; this.nextthink = time + 0.05;
- };
-
- //--------------------------------------------------------------
- nonvirtual void() sparks_fade3 = [0, sparks_fade4]
- {
- this.alpha = 0.4; this.nextthink = time + 0.05;
+ if (this.think_state == MISC_SPARKS_OFFLIGHT)
+ {
+ // was spark_turnofflight -- CEV
+ sub_usetargets ();
+ this.think_state = MISC_SPARKS_MAKE;
+ this.nextthink = time + (random() + 0.5) *
+ this.wait - 0.15;
+ }
+ else if (this.think_state == MISC_SPARKS_MAKE)
+ {
+ // was make_sparks -- CEV
+ this.make_sparks ();
+ }
};

//--------------------------------------------------------------
- nonvirtual void() sparks_fade4 = [0, SUB_Remove]
+ virtual void(entity caller) do_use =
{
- this.alpha = 0.2; this.nextthink = time + 0.05;
- };

- //--------------------------------------------------------------
- virtual void() sparks_use =
- {
if (this.spawnflags & MISC_SPARKS_START_OFF)
- this.spawnflags = this.spawnflags -
- MISC_SPARKS_START_OFF;
+ {
+ this.interaction_flags &= ~DISABLE_THINK;
+ this.nextthink = time + random() * 0.1;
+ }
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;
+ {
+ this.interaction_flags |= DISABLE_THINK;
+ }
};

//--------------------------------------------------------------
- virtual void() make_sparks =
+ nonvirtual void() make_sparks =
{
- if (this.spawnflags & MISC_SPARKS_START_OFF)
- {
- this.nextthink = time + 0.1;
- this.think = make_sparks;
- }
- else
+ local float i;
+ i = -0.25 * this.cnt + random() * 0.5 * this.cnt;
+ while (i < this.cnt)
{
- local float i;
- i = -0.25 * this.cnt + random() * 0.5 * this.cnt;
- while (i < this.cnt)
- {
- 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;
- }
-
- if (this.sounds == 1)
- {
- 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 ();
- this.nextthink = time + 0.1 + random() * 0.1;
- this.think = this.spark_turnofflight;
+ local temp_spark spark;
+ spark = spawn (temp_spark,
+ owner: this,
+ spawnflags: this.spawnflags,
+ origin: this.origin);
+
+ i = i + 1;
}
+
+ if (this.sounds == 1)
+ 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 ();
+ this.think_state = MISC_SPARKS_OFFLIGHT;
+ this.nextthink = time + 0.1 + random() * 0.1;
};

//--------------------------------------------------------------
- void() misc_sparks =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "misc_sparks";
- this.classtype = CT_MISC_SPARKS;
precache_model ("progs/spark.mdl");

if (!this.noise)
@@ -162,8 +178,21 @@ class misc_sparks: entity
if (!this.cnt)
this.cnt = 15;

- this.use = sparks_use;
- this.nextthink = time + random() * 0.1;
- this.think = make_sparks;
+ this.think_state = MISC_SPARKS_MAKE;
+
+ if (this.spawnflags & MISC_SPARKS_START_OFF)
+ {
+ this.interaction_flags |= DISABLE_THINK;
+ }
+ else
+ {
+ this.nextthink = time + random() * 0.1;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() misc_sparks =
+ {
+ this.classtype = CT_MISC_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 b192def..2dd841e 100644
--- a/qc/misc/target_autosave.qc
+++ b/qc/misc/target_autosave.qc
@@ -16,12 +16,12 @@ the bprint tends to stomp any other prints on screen in most quake clients, so u
message(string) : "Change save filename" : "auto"
]
*/
-class target_autosave: entity
+class target_autosave: base_mapentity
{
//--------------------------------------------------------------
// autosave -- was in client.qc
//--------------------------------------------------------------
- virtual void(entity client, string savename) autosave =
+ nonvirtual void(entity client, string savename) autosave =
{
// autosavename = savename;
stuffcmd (client, "echo Autosaving...; wait; save ");
@@ -30,51 +30,20 @@ class target_autosave: entity
};

//--------------------------------------------------------------
- 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 =
+ nonvirtual void() toggle_autosave =
{
local entity e = world;
local float printed = FALSE;

- do {
+ do
+ {
e = findfloat (e, ::classtype, CT_TARGET_AUTOSAVE);
if (!e)
break;

- if (e.use == target_autosave_use)
+ if (e.estate == STATE_ACTIVE)
{
- e.use = SUB_Null;
+ e.estate = STATE_INACTIVE;
if (!printed)
{
bprint ("Autosaves disabled\n");
@@ -83,7 +52,7 @@ class target_autosave: entity
}
else
{
- e.use = target_autosave_use;
+ e.estate = STATE_ACTIVE;
if (!printed)
{
bprint ("Autosaves reenabled\n");
@@ -95,20 +64,68 @@ class target_autosave: entity
};

//--------------------------------------------------------------
- void() target_autosave =
+ // was target_autosave_delaythink
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
- if (deathmatch || coop)
+ this.do_use (caller);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.estate != STATE_ACTIVE)
+ return;
+
+ if (this.enemy)
{
- remove (this);
+ activator = this.enemy;
+ this.enemy = world;
+ }
+
+ if (activator.classtype != CT_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.interaction_flags &= ~DISABLE_THINK;
+ this.nextthink = 2;
return;
}

- this.classname = "target_autosave";
- this.classtype = CT_TARGET_AUTOSAVE;
+ // sound(activator, CHAN_VOICE, "misc/sav.wav", 0.3, ATTN_NORM);
+ autosave (activator, this.message);
+ };

+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
if (this.message == string_null)
this.message = "auto";
// precache_sound2 ("misc/sav.wav");
- this.use = target_autosave_use;
+ this.interaction_flags |= DISABLE_THINK;
+ };
+
+ //--------------------------------------------------------------
+ void() target_autosave =
+ {
+ if (deathmatch || coop)
+ {
+ remove (this);
+ return;
+ }
+
+ this.classtype = CT_TARGET_AUTOSAVE;
};
};

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 56e6418..57f8dae 100644
--- a/qc/misc/teleporttrain.qc
+++ b/qc/misc/teleporttrain.qc
@@ -3,6 +3,14 @@
// Code for the fixed teleporttrain written by c0burn and modified by ZungryWare
//==============================================================================

+// constants
+enum
+{
+ TELEPORTTRAIN_NEXT,
+ TELEPORTTRAIN_WAIT,
+ TELEPORTTRAIN_FIND
+};
+
/*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!
@@ -22,10 +30,25 @@ 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.
*/
-class misc_teleporttrain: entity
+class misc_teleporttrain: base_mapentity
{
+ float think_state;
+
+ //--------------------------------------------------------------
+ nonvirtual 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.think_state = TELEPORTTRAIN_WAIT;
+ this.nextthink = time + (len / spd);
+ };
+
//--------------------------------------------------------------
- virtual void() teleporttrain_next =
+ nonvirtual void() teleporttrain_next =
{
local vector dir;

@@ -38,7 +61,7 @@ class misc_teleporttrain: entity
}

this.enemy = find (world, ::targetname, this.target);
- if (this.enemy.classname == "path_corner")
+ if (this.enemy.classtype == CT_PATH_CORNER)
{
dir = normalize ((this.enemy.origin + '16 16 16') -
this.origin);
@@ -55,7 +78,7 @@ class misc_teleporttrain: entity
};

//--------------------------------------------------------------
- virtual void() teleporttrain_wait =
+ nonvirtual void() teleporttrain_wait =
{
local float wait_time;

@@ -65,36 +88,16 @@ class misc_teleporttrain: entity
wait_time = 0.1;

this.velocity = '0 0 0';
+ this.think_state = TELEPORTTRAIN_NEXT;
this.nextthink = time + wait_time;
- this.think = teleporttrain_next;
- };
-
- //--------------------------------------------------------------
- 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 =
+ nonvirtual void() teleporttrain_find =
{
// always start positioned on the first path_corner
this.enemy = find (world, ::targetname, this.target);
- if (this.enemy.classname == "path_corner")
+ if (this.enemy.classtype == CT_PATH_CORNER)
{
setorigin (this, this.enemy.origin + '16 16 16');
this.target = this.enemy.target;
@@ -112,20 +115,38 @@ class misc_teleporttrain: entity
else if (!this.targetname)
// not triggered, so start immediately
teleporttrain_next ();
- else
- this.use = teleporttrain_use;
};

//--------------------------------------------------------------
- void() misc_teleporttrain =
+ virtual void(entity caller) do_think =
+ {
+ switch (this.think_state)
+ {
+ case TELEPORTTRAIN_NEXT:
+ this.teleporttrain_next ();
+ break;
+ case TELEPORTTRAIN_WAIT:
+ this.teleporttrain_wait ();
+ break;
+ case TELEPORTTRAIN_FIND:
+ this.teleporttrain_find ();
+ break;
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
+ if (this.spawnflags & 4 || !this.targetname)
return;

- this.classname = "misc_teleporttrain";
- this.classtype = CT_MISC_TELEPORTTRAIN;
+ if (this.velocity == '0 0 0')
+ teleporttrain_next ();
+ };

+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
if (!this.target)
{
objerror ("misc_teleporttrain has no target");
@@ -158,7 +179,13 @@ class misc_teleporttrain: entity
this.avelocity = '40 80 120';
// this.avelocity = '100 200 300';

- this.think = teleporttrain_find;
+ this.think_state = TELEPORTTRAIN_FIND;
this.nextthink = time + 0.1;
};
+
+ //--------------------------------------------------------------
+ void() misc_teleporttrain =
+ {
+ this.classtype = CT_MISC_TELEPORTTRAIN;
+ };
};

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 21ae6e4..34296a6 100644
--- a/qc/misc/viewthing.qc
+++ b/qc/misc/viewthing.qc
@@ -6,19 +6,20 @@

Just for the debugging level. Don't use
*/
-class viewthing: entity
+class viewthing: base_mapentity
{
- void() viewthing =
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- 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");
};
+
+ //--------------------------------------------------------------
+ void() viewthing =
+ {
+ this.classtype = CT_MISC_VIEWTHING;
+ };
};

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

Diff qc/monsters.qc

diff --git a/qc/monsters.qc b/qc/monsters.qc
index 0b9a16a..1576acf 100644
--- a/qc/monsters.qc
+++ b/qc/monsters.qc
@@ -38,41 +38,44 @@ void(float n) monster_update_total =
.float tele_solid;
.float tele_movetype;

-void(vector org) spawn_tfog;
-void(vector org, entity death_owner) spawn_tdeath;
-
void() monster_teleport_go =
{
-self.solid = self.tele_solid;
-self.movetype = self.tele_movetype;
-setmodel(self, self.tele_model);
-setsize (self, self.tele_mins, self.tele_maxs);
+ self.solid = self.tele_solid;
+ self.movetype = self.tele_movetype;
+ setmodel(self, self.tele_model);
+ setsize (self, self.tele_mins, self.tele_maxs);

-self.delay = 0; //fix for cumulative delays for counters etc. -- dumptruck_ds
+ // fix for cumulative delays for counters etc. -- dumptruck_ds
+ self.delay = 0;

-self.think1();
-//override the random delay some go functions apply
-self.nextthink = time + 0.1;
+ self.think1();
+ //override the random delay some go functions apply
+ self.nextthink = time + 0.1;
{
if !(self.spawnflags & SPAWN_SILENTLY)
{
- if (self.wait == 0) //dumptruck_ds: if wait value is > 0 spawn silently or use a spawnflag
- spawn_tfog (self.origin);
+ // dumptruck_ds: if wait value is > 0 spawn silently
+ // or use a spawnflag
+ if (self.wait == 0)
+ spawn_tfog (self.origin);
spawn_tdeath(self.origin, self);
}
}

}

-void() monster_teleport_delay = //new from Qmaster func coding help thread
+// new from Qmaster func coding help thread
+void() monster_teleport_delay =
{
-self.think = monster_teleport_go;
+ self.think = monster_teleport_go;
if (self.delay == -1)
- {
- self.nextthink = time + 0.1 + random(); //if delay is set to -1 random delay from 0.1 to 1 second - dumptruck_ds
- return;
- }
-self.nextthink = time + 0.1 + self.delay;
+ {
+ // if delay is set to -1 random delay from 0.1 to 1
+ // second - dumptruck_ds
+ self.nextthink = time + 0.1 + random();
+ return;
+ }
+ self.nextthink = time + 0.1 + self.delay;
};

/*
@@ -107,28 +110,28 @@ void() monster_teleport_check =

float (void() monster_start_fn) monster_teleport =
{
-if(!(self.spawnflags & 8))
- return FALSE;
-
-//PREACH: This monster is to be teleported in, so hide it
-self.tele_model= self.model;
-self.tele_mins = self.mins;
-self.tele_maxs = self.maxs;
-self.tele_solid = self.solid;
-self.tele_movetype = self.movetype;
-
-self.model = "";
-self.modelindex = 0;
-self.solid = SOLID_NOT;
-self.movetype = MOVETYPE_NONE;
-self.think1 = monster_start_fn;
-
-// wait for other entities to finish spawning, then check that
-// something targets this -- iw
-self.think = monster_teleport_check;
-self.nextthink = time + 0.1;
-
-return TRUE;
+ if(!(self.spawnflags & 8))
+ return FALSE;
+
+ // PREACH: This monster is to be teleported in, so hide it
+ self.tele_model= self.model;
+ self.tele_mins = self.mins;
+ self.tele_maxs = self.maxs;
+ self.tele_solid = self.solid;
+ self.tele_movetype = self.movetype;
+
+ self.model = "";
+ self.modelindex = 0;
+ self.solid = SOLID_NOT;
+ self.movetype = MOVETYPE_NONE;
+ self.think1 = monster_start_fn;
+
+ // wait for other entities to finish spawning, then check that
+ // something targets this -- iw
+ self.think = monster_teleport_check;
+ self.nextthink = time + 0.1;
+
+ return TRUE;
}

//end of Preach's new fields here
@@ -150,10 +153,13 @@ void() monster_touch =
if (other.health <= 0)
return;

- if ((!(other.flags & FL_ONGROUND)) && ((other.absmin_z >= self.absmax_z - 2)))
+ if ((!(other.flags & FL_ONGROUND)) &&
+ ((other.absmin_z >= self.absmax_z - 2)))
+ {
other.flags = other.flags + FL_ONGROUND;
+ }

- //you can add other stuff like pushable players/monsters here
+ // you can add other stuff like pushable players/monsters here
};
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end

@@ -174,14 +180,16 @@ void() monster_use =
return;
if (activator.flags & FL_NOTARGET)
return;
- if (activator.movetype == MOVETYPE_NOCLIP) // Copper -- dumptruck_ds
+ if (activator.movetype == MOVETYPE_NOCLIP)
+ // Copper -- dumptruck_ds
return FALSE;
- if (activator.classname != "player")
+
+ if (activator.classname != "player")
return;


-// delay reaction so if the monster is teleported, its sound is still
-// heard
+ // delay reaction so if the monster is teleported, its sound is still
+ // heard
self.enemy = activator;
self.nextthink = time + 0.1;
self.think = FoundTarget;
@@ -197,7 +205,7 @@ enemy as activator.
*/
void() monster_death_use =
{
-// fall to ground
+ // fall to ground
if (self.flags & FL_FLY)
self.flags = self.flags - FL_FLY;
if (self.flags & FL_SWIM)
@@ -238,17 +246,20 @@ void() monster_pain_use =

void() walkmonster_start_go =
{
- self.origin_z = self.origin_z + 1; // raise off floor a bit
-//Preach's "check" here
+ // raise off floor a bit
+ self.origin_z = self.origin_z + 1;

-// if(time <= 0.5)
-if(!(self.spawnflags & 8))
-{
- droptofloor();
+ // Preach's "check" here

- if !(self.spawnflags & I_AM_TURRET) // fixes an incorrect dprint -- dumptruck_ds
+ // if(time <= 0.5)
+ if(!(self.spawnflags & 8))
+ {
+ droptofloor();
+
+ if !(self.spawnflags & I_AM_TURRET)
{
- if (!walkmove(0,0))
+ // fixes an incorrect dprint -- dumptruck_ds
+ if (!walkmove(0,0))
{
dprint ("\n\n");
dprint (self.classname);
@@ -257,7 +268,7 @@ if(!(self.spawnflags & 8))
dprint ("\n\n");
}
}
-}
+ }

self.takedamage = DAMAGE_AIM;

@@ -271,7 +282,8 @@ if(!(self.spawnflags & 8))

if (self.target != "")
{
- self.goalentity = self.movetarget = find(world, targetname, self.target);
+ self.goalentity = self.movetarget = find (world,
+ targetname, self.target);
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
if (!self.movetarget)
{
@@ -279,7 +291,8 @@ if(!(self.spawnflags & 8))
dprint (vtos(self.origin));
dprint ("\n");
}
-// this used to be an objerror
+
+ // this used to be an objerror
if (self.movetarget.classname == "path_corner")
{
self.th_walk ();
@@ -296,55 +309,57 @@ if(!(self.spawnflags & 8))
self.th_stand ();
}

-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+ // self.nextthink = self.nextthink + random()*0.5;
self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
- // if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // dumptruck_ds -- using spawn_angry set to 1 in order to spawn
+ // in "angry" monsters
+ // if ((self.spawnflags & 8) && self.spawn_angry == 1)
// {
// monster_use();
// }
- local entity pl; //dumptruck_ds -- this is Shamblernaut's method
+
+ // dumptruck_ds -- this is Shamblernaut's method
+ local entity pl;

pl = find (world, classname, "player");

if (self.spawn_angry == 1)
{
- activator = pl;
- monster_use();
+ activator = pl;
+ monster_use();
}
};

-
+// Preach's tutorial
void() walkmonster_start =
-
- //Preach's tutorial
{
-
- if (cvar("nomonsters")) {
- remove(self);
+ if (cvar("nomonsters"))
+ {
+ remove (self);
return;
}

- if(monster_teleport(walkmonster_start_go))
- return;
+ if (monster_teleport(walkmonster_start_go))
+ return;
+
+ // delay drop to floor to make sure all doors have been spawned
+ // spread think times so they don't all happen at same time

-// delay drop to floor to make sure all doors have been spawned
-// spread think times so they don't all happen at same time
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix
+ // by Maddes/Kryten
+ self.touch = monster_touch;
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+ // self.nextthink = self.nextthink + random()*0.5;
self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
self.think = walkmonster_start_go;
total_monsters = total_monsters + 1;
- /// Trigger enemy after spawn (khreathor)
-
+ /// Trigger enemy after spawn (khreathor)
};

-
-
void() flymonster_start_go =
{
self.takedamage = DAMAGE_AIM;
@@ -367,14 +382,16 @@ void() flymonster_start_go =

if (self.target != "")
{
- self.goalentity = self.movetarget = find(world, targetname, self.target);
+ self.goalentity = self.movetarget = find (world,
+ targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
-// this used to be an objerror
+
+ // this used to be an objerror
if (self.movetarget.classname == "path_corner")
{
self.th_walk ();
@@ -391,55 +408,61 @@ void() flymonster_start_go =
self.th_stand ();
}

- self.nextthink = time + 0.1 + random()*0.5; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+ self.nextthink = time + 0.1 + random()*0.5;

-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
+ // dumptruck_ds -- using spawn_angry set to 1 in order to spawn
+ // in "angry" monsters
+ // if ((self.spawnflags & 8) && self.spawn_angry == 1)
+ // {
+ // monster_use();
+ // }
+
+ //dumptruck_ds -- this is Shamblernaut's method
local entity pl;

pl = find (world, classname, "player");

if (self.spawn_angry == 1)
{
- activator = pl;
- monster_use();
+ activator = pl;
+ monster_use();
}
-
};

void() flymonster_start =
{
- if (cvar("nomonsters")) {
- remove(self);
+ if (cvar("nomonsters"))
+ {
+ remove (self);
return;
}

- //Preach's tutorial
+ // Preach's tutorial

- if(monster_teleport(flymonster_start_go))
- return;
+ if (monster_teleport(flymonster_start_go))
+ return;

- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_FLY; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten
+ self.touch = monster_touch;
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+ self.flags = self.flags | FL_FLY;

-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+ // self.nextthink = self.nextthink + random()*0.5;
self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
self.think = flymonster_start_go;
total_monsters = total_monsters + 1;
};

-
void() swimmonster_start_go =
{
if (deathmatch)
{
- remove(self);
+ remove (self);
return;
}

@@ -456,14 +479,15 @@ void() swimmonster_start_go =

if (self.target != "")
{
- self.goalentity = self.movetarget = find(world, targetname, self.target);
+ self.goalentity = self.movetarget = find (world,
+ targetname, self.target);
if (!self.movetarget)
{
dprint ("Monster can't find target at ");
dprint (vtos(self.origin));
dprint ("\n");
}
-// this used to be an objerror
+ // this used to be an objerror
self.ideal_yaw = vectoyaw(self.goalentity.origin - self.origin);
self.th_walk ();
}
@@ -473,46 +497,55 @@ void() swimmonster_start_go =
self.th_stand ();
}

-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+ // self.nextthink = self.nextthink + random()*0.5;
self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
-// if ((self.spawnflags & 8) && self.spawn_angry == 1) //dumptruck_ds -- using spawn_angry set to 1 in order to spawn in "angry" monsters
-// {
-// monster_use();
-// }
-//dumptruck_ds -- this is Shamblernaut's method
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+
+ // dumptruck_ds -- using spawn_angry set to 1 in order to spawn
+ // in "angry" monsters
+ // if ((self.spawnflags & 8) && self.spawn_angry == 1)
+ // {
+ // monster_use();
+ // }
+
+ // dumptruck_ds -- this is Shamblernaut's method
local entity pl;

pl = find (world, classname, "player");

if (self.spawn_angry == 1)
{
- activator = pl;
- monster_use();
+ activator = pl;
+ monster_use();
}
};

void() swimmonster_start =
{
- if (cvar("nomonsters")) {
- remove(self);
+ if (cvar("nomonsters"))
+ {
+ remove (self);
return;
}
- self.touch = monster_touch; // 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten
- self.flags = self.flags | FL_SWIM; // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol

- //Preach's tutorial
+ // 1998-09-16 Sliding/not-jumping on monsters/boxes/players
+ // fix by Maddes/Kryten
+ self.touch = monster_touch;
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol
+ self.flags = self.flags | FL_SWIM;
+
+ // Preach's tutorial

- if(monster_teleport(swimmonster_start_go))
- return;
+ if (monster_teleport(swimmonster_start_go))
+ return;

-// spread think times so they don't all happen at same time
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
-// self.nextthink = self.nextthink + random()*0.5;
+ // spread think times so they don't all happen at same time
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol start
+ // self.nextthink = self.nextthink + random()*0.5;
self.nextthink = time + 0.1 + random()*0.5;
-// 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
+ // 1998-08-14 Monsters sometimes do not move fix by Lord Sméagol end
self.think = swimmonster_start_go;
total_monsters = total_monsters + 1;
};

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

Diff qc/monsters/boss.qc

diff --git a/qc/monsters/boss.qc b/qc/monsters/boss.qc
index 5d15386..5c49e77 100644
--- a/qc/monsters/boss.qc
+++ b/qc/monsters/boss.qc
@@ -324,10 +324,8 @@ void() lightning_fire =

if (time >= lightning_end)
{ // done here, put the terminals back up
- self = le1;
- door_go_down ();
- self = le2;
- door_go_down ();
+ ((func_door)le1).door_go_down ();
+ ((func_door)le2).door_go_down ();
return;
}

@@ -368,8 +366,8 @@ void() lightning_use =
}

if (
- (le1.state != STATE_TOP && le1.state != STATE_BOTTOM)
- || (le2.state != STATE_TOP && le2.state != STATE_BOTTOM)
+ (le1.state != FUNC_STATE_TOP && le1.state != FUNC_STATE_BOTTOM)
+ || (le2.state != FUNC_STATE_TOP && le2.state != FUNC_STATE_BOTTOM)
|| (le1.state != le2.state) )
{
// dprint ("not aligned\n");
@@ -389,7 +387,7 @@ void() lightning_use =
if (!self)
return;
self.enemy = activator;
- if (le1.state == STATE_TOP && self.health > 0)
+ if (le1.state == FUNC_STATE_TOP && self.health > 0)
{
sound_pain (self, CHAN_VOICE, "boss1/pain.wav", 1, ATTN_NORM);
self.health = self.health - 1;

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

Diff qc/monsters/boss2.qc

diff --git a/qc/monsters/boss2.qc b/qc/monsters/boss2.qc
index 295e03b..e58227b 100644
--- a/qc/monsters/boss2.qc
+++ b/qc/monsters/boss2.qc
@@ -274,8 +274,8 @@ void() GibBoss2 =
}
setsize (head, '-67 -60 -6', '62 52 88');
// setsize (head, '-16 -16 0', '16 16 56');
- head.touch = SUB_Null;
- head.think = SUB_Remove;
+ head.touch = sub_null;
+ head.think = sub_remove;
head.nextthink = time + 120;
if !(self.spawnflags & NO_LAVASPLASH)
{

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

Diff qc/monsters/demon.qc

diff --git a/qc/monsters/demon.qc b/qc/monsters/demon.qc
index 5d338c6..ac06fe8 100644
--- a/qc/monsters/demon.qc
+++ b/qc/monsters/demon.qc
@@ -312,7 +312,7 @@ void() monster_demon1 =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = demon1_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;

walkmonster_start();
};
@@ -453,7 +453,7 @@ void() Demon_JumpTouch =
{ // jump randomly to not get hung up
//dprint ("popjump\n");
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
+// self.touch = sub_null;
self.touch = monster_touch;
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
self.think = demon1_jump1;
@@ -468,7 +468,7 @@ void() Demon_JumpTouch =
}

// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
+ // self.touch = sub_null;
self.touch = monster_touch;
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
self.think = demon1_jump11;

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

Diff qc/monsters/dog.qc

diff --git a/qc/monsters/dog.qc b/qc/monsters/dog.qc
index 2ded26e..eb5b6b3 100644
--- a/qc/monsters/dog.qc
+++ b/qc/monsters/dog.qc
@@ -89,7 +89,7 @@ void() Dog_JumpTouch =
{ // jump randomly to not get hung up
//dprint ("popjump\n");
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
-// self.touch = SUB_Null;
+// self.touch = sub_null;
self.touch = monster_touch;
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
self.think = dog_leap1;
@@ -104,7 +104,7 @@ void() Dog_JumpTouch =
}

// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten start
- // self.touch = SUB_Null;
+ // self.touch = sub_null;
self.touch = monster_touch;
// 1998-09-16 Sliding/not-jumping on monsters/boxes/players fix by Maddes/Kryten end
self.think = dog_run1;
@@ -468,7 +468,7 @@ void() monster_dog =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = dog_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = dog_die;
self.th_melee = dog_atta1;
self.th_missile = dog_leap1;

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

Diff qc/monsters/enforcer.qc

diff --git a/qc/monsters/enforcer.qc b/qc/monsters/enforcer.qc
index 5460d7b..052b0d8 100644
--- a/qc/monsters/enforcer.qc
+++ b/qc/monsters/enforcer.qc
@@ -120,7 +120,7 @@ void(vector org, vector vec) LaunchLaser =
else
{
newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
+ newmis.think = sub_remove;
}
newmis.touch = Laser_Touch;
};
@@ -174,7 +174,7 @@ void(vector org, vector vec) EnfLaunchSpike =
else
{
newmis.nextthink = time + 5;
- newmis.think = SUB_Remove;
+ newmis.think = sub_remove;
}
newmis.touch = superspike_touch;
};
@@ -261,7 +261,7 @@ void() EnfRocket =
else
{
missile.nextthink = time + 5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
}
missile.skin = self.skin_proj; //dumptruck_ds

@@ -971,7 +971,7 @@ void() monster_enforcer =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = enf_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = enf_die;
if (self.style == 1 || self.style == 2 || self.style == 5) // new animation frame check -- dumptruck_ds
{

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

Diff qc/monsters/fish.qc

diff --git a/qc/monsters/fish.qc b/qc/monsters/fish.qc
index c5ac5c6..a4a3c54 100644
--- a/qc/monsters/fish.qc
+++ b/qc/monsters/fish.qc
@@ -175,7 +175,7 @@ void() fish_die =
ThrowHead ("progs/h_dog.mdl", self.health);
}
DropStuff();
- SUB_Remove();
+ sub_remove();
}
// regular death
else
@@ -299,7 +299,7 @@ void() monster_fish =
if !(self.berserk) //Berserk from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = fish_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_melee = f_attack1;

swimmonster_start ();

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

Diff qc/monsters/hknight.qc

diff --git a/qc/monsters/hknight.qc b/qc/monsters/hknight.qc
index f0942a4..9bfa7a5 100644
--- a/qc/monsters/hknight.qc
+++ b/qc/monsters/hknight.qc
@@ -705,7 +705,7 @@ void() monster_hell_knight =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = hknight_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = hknight_die;

walkmonster_start ();

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

Diff qc/monsters/knight.qc

diff --git a/qc/monsters/knight.qc b/qc/monsters/knight.qc
index c15368c..936322d 100644
--- a/qc/monsters/knight.qc
+++ b/qc/monsters/knight.qc
@@ -368,7 +368,7 @@ void() monster_knight =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = knight_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = knight_die;

walkmonster_start ();

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

Diff qc/monsters/ogre.qc

diff --git a/qc/monsters/ogre.qc b/qc/monsters/ogre.qc
index 66822b0..edd017e 100644
--- a/qc/monsters/ogre.qc
+++ b/qc/monsters/ogre.qc
@@ -66,7 +66,7 @@ void() OgreGrenadeExplode =
WriteCoord (MSG_BROADCAST, self.origin_z);

self.velocity = '0 0 0';
- self.touch = SUB_Null;
+ self.touch = sub_null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
@@ -131,7 +131,7 @@ void() FlakTouch =
// stick around for a little while...
self.velocity = '0 0 0';
self.solid = SOLID_NOT;
- self.touch = SUB_Null;
+ self.touch = sub_null;
self.model = string_null;
self.oldorigin = self.origin - other.origin; //displacement from enemy origin (its gonna move next frame)
self.oldenemy = other;
@@ -208,7 +208,7 @@ void() BDW_OgreFireFlak =
else
{
flak.nextthink = time + 6;
- flak.think = SUB_Remove;
+ flak.think = sub_remove;
}
flak.dmg = 4;

@@ -408,7 +408,7 @@ void(float elevation) PreachFireZombie =

// set missile duration
missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
// setmodel (missile, "progs/grenade.mdl");
if (self.mdl_proj != "") // dumptruck_ds
{
@@ -1390,7 +1390,7 @@ void() monster_ogre =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = ogre_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;

walkmonster_start();
};
@@ -1515,7 +1515,7 @@ void() monster_ogre_marksman =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = ogre_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;

walkmonster_start();
};

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

Diff qc/monsters/oldone.qc

diff --git a/qc/monsters/oldone.qc b/qc/monsters/oldone.qc
index 2e6ba03..116e9de 100644
--- a/qc/monsters/oldone.qc
+++ b/qc/monsters/oldone.qc
@@ -1,3 +1,5 @@
+// TODO CEV: this is causing FTEQW to hang for some reason
+
/*
==============================================================================

@@ -5,6 +7,7 @@ OLD ONE

==============================================================================
*/
+/*
$cd id1/models/old_one
$origin 0 0 24
$base base
@@ -251,9 +254,11 @@ void(entity attacker, float damage) nopain =

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

-
+*/
/*QUAKED monster_oldone (1 0 0) (-160 -128 -24) (160 128 256)
*/
+// TODO CEV
+/*
void() monster_oldone =
{
// new spawnflags for all entities -- iw
@@ -295,3 +300,4 @@ void() monster_oldone =

total_monsters = total_monsters + 1;
};
+*/

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

Diff qc/monsters/shalrath.qc

diff --git a/qc/monsters/shalrath.qc b/qc/monsters/shalrath.qc
index ee97ab0..a8c7603 100644
--- a/qc/monsters/shalrath.qc
+++ b/qc/monsters/shalrath.qc
@@ -262,7 +262,7 @@ void() ShalMissile =
// WriteCoord (MSG_BROADCAST, self.origin_z);
//
// self.velocity = '0 0 0';
-// self.touch = SUB_Null;
+// self.touch = sub_null;
// setmodel (self, "progs/s_explod.spr");
// self.solid = SOLID_NOT;
// s_explode1 ();
@@ -396,7 +396,7 @@ void() monster_shalrath =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = shalrath_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_missile = shal_attack1;
self.th_turret = shal_turret_attack1;
self.think = walkmonster_start;

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

Diff qc/monsters/shambler.qc

diff --git a/qc/monsters/shambler.qc b/qc/monsters/shambler.qc
index 9da3c81..24958e8 100644
--- a/qc/monsters/shambler.qc
+++ b/qc/monsters/shambler.qc
@@ -40,7 +40,7 @@ void() ShamRocket =
else
{
missile.nextthink = time + 5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
}
missile.skin = self.skin_proj; //dumptruck_ds

@@ -696,7 +696,7 @@ void() monster_shambler =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = sham_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;

walkmonster_start();
};

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

Diff qc/monsters/soldier.qc

diff --git a/qc/monsters/soldier.qc b/qc/monsters/soldier.qc
index 3a5034e..44f774c 100644
--- a/qc/monsters/soldier.qc
+++ b/qc/monsters/soldier.qc
@@ -659,7 +659,7 @@ void() monster_army =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = army_pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = army_die;

walkmonster_start ();

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

Diff qc/monsters/wizard.qc

diff --git a/qc/monsters/wizard.qc b/qc/monsters/wizard.qc
index 6c28995..672c939 100644
--- a/qc/monsters/wizard.qc
+++ b/qc/monsters/wizard.qc
@@ -79,7 +79,7 @@ void(entity missile, float mspeed, float accuracy) LaunchMissile =

// set missile duration
missile.nextthink = time + 5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
};


@@ -545,7 +545,7 @@ void() monster_wizard =
if !(self.berserk) //Berserk test from http://celephais.net/board/view_thread.php?id=4&start=3465 -- dumptruck_ds
self.th_pain = Wiz_Pain;
else
- self.th_pain = SUB_NullPain;
+ self.th_pain = sub_nullpain;
self.th_die = wiz_die;

flymonster_start ();

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 63cf23d..ba4022a 100644
--- a/qc/monsters/zombie.qc
+++ b/qc/monsters/zombie.qc
@@ -196,7 +196,7 @@ ATTACKS
// sound_land (self, CHAN_WEAPON, "zombie/z_miss.wav", 1, ATTN_NORM); // bounce sound
// self.velocity = '0 0 0';
// self.avelocity = '0 0 0';
-// self.touch = SUB_Remove;
+// self.touch = sub_remove;
// };

/*
@@ -233,7 +233,7 @@ void(vector st) ZombieFireGrenade =

// set missile duration
missile.nextthink = time + 2.5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
// setmodel (missile, "progs/zom_gib.mdl");
if (self.mdl_proj != "") // dumptruck_ds custom_mdls
{

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
index be90a5e..1e9d8ba 100644
--- a/qc/player/player.qc
+++ b/qc/player/player.qc
@@ -623,18 +623,6 @@ void() PlayerDeathBubblesSpawn =
}

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;
@@ -744,7 +732,7 @@ void(string gibname, float dm) ThrowGib =
new.avelocity_x = random() * 600;
new.avelocity_y = random() * 600;
new.avelocity_z = random() * 600;
- new.think = SUB_Remove;
+ new.think = sub_remove;
new.ltime = time;
new.nextthink = time + 10 + random() * 10;
new.frame = 0;

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
index 561f5d6..2207d49 100644
--- a/qc/player/pmove.qc
+++ b/qc/player/pmove.qc
@@ -18,7 +18,7 @@ vector input_movevalues;

// fields
// note: timers are expensive, require synch between server and client -- CEV
-.entity groundentity;
+// .entity groundentity;
.vector groundnormal;
.float pmove_flags; // custom movement flags -- CEV
.float doublejump_timer; // time in which a player can doublejump
@@ -27,12 +27,12 @@ vector input_movevalues;

// 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_AIRACCEL = 7.5f; // 10 in Q1; now 7.5 or 8.0
+const float PM_AIRACCELQ3 = 0.75f; // 1.0 in Q3 ?; now 0.75 or 0.8
+const float PM_AIRACCELFWD = 0.75f; // 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_BOOSTACCEL = 11.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
@@ -58,8 +58,8 @@ 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_WALLJUMPGROUND = 20.0f; // distance from ground to allow WJ (36)
+const float PM_WALLJUMPLIMIT = -225.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

@@ -142,6 +142,14 @@ void() SV_RunClientCommand =
//----------------------------------------------------------------------
static void(entity ent) PM_DoTouch =
{
+#ifdef SSQC
+ if (ent && (ent.classgroup & CG_MAPENTITY))
+ {
+ other = self;
+ ((base_mapentity)ent).handle_touch (self);
+ return;
+ }
+#endif
if (ent && ent.touch != __NULL__)
{
local entity orig_self;
@@ -453,6 +461,8 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
// touch the saved entity; inline PM_DoTouch -- CEV
if (touched_ent && touched_ent.touch != __NULL__)
{
+ PM_DoTouch (touched_ent);
+ /*
local entity orig_self;

orig_self = self;
@@ -460,6 +470,7 @@ void(float dogravity, float sticky, float dostep, float doskim) PM_DanceMove =
self = touched_ent;
self.touch ();
self = orig_self;
+ */
}

// clip velocity to the saved plane
@@ -840,8 +851,11 @@ void() PM_Jump =
msg = sprintf ("PM_Jump: jump %g, ", self.velocity_z);
#endif

- // do an additive jump -- CEV
- self.velocity_z += PM_JUMPSPEED;
+ // do an additive jump on non-flat ground -- CEV
+ if (self.groundnormal_z == 1)
+ self.velocity_z = PM_JUMPSPEED;
+ else
+ self.velocity_z += PM_JUMPSPEED;
}

// report new Z velocity
@@ -1122,11 +1136,11 @@ void(vector wishvel, float move_time) PM_WalkAccelerate =
if (input_movevalues_y == 0)
{
// Painkiller style air control
- if (input_movevalues_x < 0)
- // we're slowing down
+ if (wishvel * self.velocity < 0)
+ // against original velocity; we're slowing down
accel = PM_AIRACCELBACK;
else
- // we're gaining speed
+ // we're with original velocity - gaining speed
accel = PM_AIRACCELFWD;

// borrow the friction var to flag a conditional below

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 c9bedb7..64a2dc0 100644
--- a/qc/progs.src
+++ b/qc/progs.src
@@ -1,8 +1,8 @@
+#pragma target fte
#pragma progs_dat "../progs.dat"
+#pragma autoproto

#define FTE
-#pragma target fte
-#pragma autoproto
#define SSQC

#includelist
@@ -36,7 +36,23 @@ world.qc
//----------------------------------------------------------------------
// base classes
//----------------------------------------------------------------------
-classes/base_trigger.qc // methods & fields for trigger entities
+base_entities.qc // topmost entity classes
+base_func.qc // base func_ classes
+base_item.qc // ammo, armor, health, weapons, etc.
+base_monster.qc // base monster classes
+base_trigger.qc // methods & fields for trigger entities
+
+//----------------------------------------------------------------------
+// info entities -- destinations, targets, etc.
+//----------------------------------------------------------------------
+info/camera.qc // was in cutscene.qc
+info/intermission.qc //
+info/null.qc // info_null; was in lights.qc
+info/notnull.qc // info_notnull; was in lights.qc
+info/path_corner.qc // id1 path_corner
+info/rotate.qc // hipnotic info_rotate
+info/teleport_changedest.qc // Qmaster's info_teleport_changedest
+info/teleport_destination.qc // teleporter endpoints

//----------------------------------------------------------------------
// combat & monster AI -- TODO CEV need to reformat
@@ -63,15 +79,6 @@ player/pmove.qc // QC player movement code -- CEV
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
//----------------------------------------------------------------------
items/ammo.qc // ammo; was in items.qc
@@ -91,6 +98,8 @@ items/shotguns.qc //
//----------------------------------------------------------------------
// func entities
//----------------------------------------------------------------------
+func/shadow.qc //
+func/wall.qc // was misc.qc -- CEV
func/bob.qc // RennyC's stand alone version based on AD
func/bossgate.qc // was misc.qc -- CEV
func/breakable.qc // selections from Rubicon2 QC; was rubicon2.qc -- CEV
@@ -110,11 +119,9 @@ func/new_plat.qc // Rogue MP newplats.qc
func/plat.qc // was plats.qc -- CEV
func/particlefield.qc // Hipnotic particlefield and func_togglewall
func/rotate.qc // from Hipnotic thanks RennyC; was rotate.qc
-func/shadow.qc //
func/togglevisiblewall.qc // was misc.qc -- CEV
func/togglewall.qc // was hippart.qc -- CEV
func/train.qc // was plats.qc -- CEV
-func/wall.qc // was misc.qc -- CEV

//----------------------------------------------------------------------
// trigger & target entities

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 ca6a367..420c3b8 100644
--- a/qc/subs.qc
+++ b/qc/subs.qc
@@ -9,17 +9,28 @@
// need to do is give a nextthink time in order to trigger it
.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;
-void() SUB_Null;
-void() SUB_Remove;
-void() SUB_UseTargets;
-float(entity targ) visible;
+//----------------------------------------------------------------------
+void() sub_null =
+{
+ // no-op
+};
+
+//----------------------------------------------------------------------
+void(entity attacker, float damage) sub_nullpain =
+{
+ // no-op
+};
+
+//----------------------------------------------------------------------
+void() sub_remove =
+{
+ remove (self);
+};
+
+//==============================================================================
+//==============================================================================
+//==============================================================================
+//==============================================================================

//----------------------------------------------------------------------
// CheckItemRespawn -- was in items.qc
@@ -66,253 +77,31 @@ float() CheckValidTouch =
//----------------------------------------------------------------------
void() DelayThink =
{
+ dprint (sprintf("DelayThink: self classname %s\n", self.classname));
activator = self.enemy;
SUB_UseTargets ();
+ dprint (sprintf("DelayThink: removing classname %s\n", self.classname));
remove (self);
};

-/*
-QuakeEd only writes a single float for angles (bad idea), so up and down are
-just constant angles.
-*/
-void() SetMovedir =
-{
- if (self.angles == '0 -1 0')
- {
- self.movedir = '0 0 1';
- }
- else if (self.angles == '0 -2 0')
- {
- self.movedir = '0 0 -1';
- }
- else
- {
- makevectors (self.angles);
- self.movedir = v_forward;
- }
-
- self.angles = '0 0 0';
-};
-
-//----------------------------------------------------------------------
-void() SUB_Null =
-{
- // no-op
-};
-
-//----------------------------------------------------------------------
-void(entity attacker, float damage) SUB_NullPain =
-{
- // no-op
-};
-
-//----------------------------------------------------------------------
-void() SUB_Remove =
-{
- remove (self);
-};
-
-//----------------------------------------------------------------------
-// SUB_CallAsSelf -- wrap the self/oself shuffle for code cleanliness elsewhere
-//----------------------------------------------------------------------
-void(void() fun, entity newself) SUB_CallAsSelf =
+void(entity ent, string matchstring) SUB_UseAsSelf =
{
- local entity oself;
-
- oself = self;
- self = newself;
- fun();
- self = oself;
-};
+ local entity stemp, otemp;

-//----------------------------------------------------------------------
-// SUB_CalcMove -- calculate self.velocity and self.nextthink to reach
-// dest from self.origin traveling at speed
-//----------------------------------------------------------------------
-void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
-{
- local entity stemp;
stemp = self;
+ otemp = other;
self = ent;
-
- SUB_CalcMove (tdest, tspeed, func);
- self = stemp;
-};
-
-//----------------------------------------------------------------------
-void(vector tdest, float tspeed, void() func) SUB_CalcMove =
-{
- local vector vdestdelta;
- local float len, traveltime, localtime;
-
- if (!tspeed)
- objerror ("No speed is defined!");
-
- if (self.movetype == MOVETYPE_PUSH)
- localtime = self.ltime;
- else
- localtime = time;
-
- self.think1 = func;
- self.finaldest = tdest;
- self.think = SUB_CalcMoveDone;
-
- if (tdest == self.origin)
- {
- self.velocity = '0 0 0';
- self.nextthink = localtime + 0.1;
- return;
- }
-
- // set destdelta to the vector needed to move
- vdestdelta = tdest - self.origin;
-
- // calculate length of vector
- len = vlen (vdestdelta);
-
- // divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- if (traveltime < 0.1)
+ other = stemp;
+ if (self.use != sub_null)
{
- self.velocity = '0 0 0';
- self.nextthink = localtime + 0.1;
- return;
+ if (self.use)
+ {
+ lastnameused = matchstring;
+ self.use ();
+ }
}
-
- // set nextthink to trigger a think when dest is reached
- self.nextthink = localtime + traveltime;
-
- // scale the destdelta vector by the time spent traveling
- // to get velocity
- // qcc won't take vec/float
- self.velocity = vdestdelta * (1 / traveltime);
-};
-
-//----------------------------------------------------------------------
-// SUB_CalcMoveDone -- After moving, set origin to exact final destination
-//----------------------------------------------------------------------
-void() SUB_CalcMoveDone =
-{
- setorigin (self, self.finaldest);
- self.velocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- self.think1 ();
-};
-
-//----------------------------------------------------------------------
-// SUB_CalcAngleMove
-// calculate self.avelocity and self.nextthink to reach destangle from
-// self.angles rotating. The calling function should make sure self.think
-// is valid
-//----------------------------------------------------------------------
-void(entity ent, vector destangle, float tspeed, void() func)
- SUB_CalcAngleMoveEnt =
-{
- local entity stemp;
- stemp = self;
- self = ent;
- SUB_CalcAngleMove (destangle, tspeed, func);
self = stemp;
-};
-
-//----------------------------------------------------------------------
-void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
-{
- local vector destdelta;
- local float len, traveltime;
-
- if (!tspeed)
- objerror("No speed is defined!");
-
- // set destdelta to the vector needed to move
- destdelta = destangle - self.angles;
-
- // calculate length of vector
- len = vlen (destdelta);
-
- // divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- // set nextthink to trigger a think when dest is reached
- self.nextthink = self.ltime + traveltime;
-
- // scale the destdelta vector by the time spent traveling to
- // get velocity
- self.avelocity = destdelta * (1 / traveltime);
-
- self.think1 = func;
- self.finalangle = destangle;
- self.think = SUB_CalcAngleMoveDone;
-};
-
-//----------------------------------------------------------------------
-// SUB_CalcAngleMoveDone -- After rotating, set angle to exact final angle
-//----------------------------------------------------------------------
-void() SUB_CalcAngleMoveDone =
-{
- self.angles = self.finalangle;
- self.avelocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- self.think1 ();
-};
-
-//----------------------------------------------------------------------
-// SUB_CalcAngleMoveController -- Same as SUB_CalcAngleMove, but using a
-// separate controller entity to not lose track of current think functions.
-//----------------------------------------------------------------------
-void(vector destangle, float tspeed, void() func, entity controller)
- SUB_CalcAngleMoveController =
-{
- local vector destdelta;
- local float len, traveltime;
-
- if (!tspeed)
- objerror("No speed is defined!");
-
- // set destdelta to the vector needed to move
-
- destdelta = normalizeAngles180 (destangle - self.angles);
- /*
- dprint3 ("destangle: ", vtos(destangle), "\n");
- dprint3 ("self.angles: ", vtos( self.angles), "\n");
- dprint3 ("destdelta: ", vtos(destdelta), "\n");
- */
-
- // calculate length of vector
- len = vlen (destdelta);
-
- // divide by speed to get time to reach dest
- traveltime = len / tspeed;
-
- // set nextthink to trigger a think when dest is reached
- controller.nextthink = time + traveltime;
-
- // scale the destdelta vector by the time spent traveling to
- // get velocity
- self.avelocity = destdelta * (1 / traveltime);
-
- // Makes sure controller.owner points to self so it can be
- // referenced later in the think function
- controller.owner = self;
- controller.think1 = func;
- controller.finalangle = destangle;
- controller.think = SUB_CalcAngleMoveDoneController;
-};
-
-//----------------------------------------------------------------------
-// SUB_CalcAngleMoveDoneController
-// After rotating, set angle to exact final angle
-//----------------------------------------------------------------------
-void() SUB_CalcAngleMoveDoneController =
-{
- self.owner.angles = self.finalangle;
- self.owner.avelocity = '0 0 0';
- self.nextthink = -1;
- if (self.think1)
- SUB_CallAsSelf(self.think1, self.owner);
+ other = otemp;
};

/* ### (added targets, killtargets, and targetnames)
@@ -336,17 +125,18 @@ or self.target4 and use their .use function.
*/
void(string matchstring, .string matchfield) SUB_UseSpecificTarget =
{
- local entity t, stemp, otemp, act;
+ local entity t, act;

act = activator;
- t = find (world, matchfield, matchstring);
+ t = find (world, ::matchfield, matchstring);
while (t != world)
{
+ /*
stemp = self;
otemp = other;
self = t;
other = stemp;
- if (self.use != SUB_Null)
+ if (self.use != sub_null)
{
if (self.use)
{
@@ -356,8 +146,10 @@ void(string matchstring, .string matchfield) SUB_UseSpecificTarget =
}
self = stemp;
other = otemp;
+ */
+ SUB_UseAsSelf (t, matchstring);
activator = act;
- t = find (t, matchfield, matchstring);
+ t = find (t, ::matchfield, matchstring);
}
};

@@ -417,85 +209,85 @@ void() SUB_UseTargets =
// kill the killtarget entities
if (self.killtarget != "")
{
- t = find (world, targetname, self.killtarget);
+ t = find (world, ::targetname, self.killtarget);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname, self.killtarget);
+ t = find (t, ::targetname, self.killtarget);
}

- t = find (world, targetname2, self.killtarget);
+ t = find (world, ::targetname2, self.killtarget);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname2, self.killtarget);
+ t = find (t, ::targetname2, self.killtarget);
}

- t = find (world, targetname3, self.killtarget);
+ t = find (world, ::targetname3, self.killtarget);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname3, self.killtarget);
+ t = find (t, ::targetname3, self.killtarget);
}

- t = find (world, targetname4, self.killtarget);
+ t = find (world, ::targetname4, self.killtarget);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname4, self.killtarget);
+ t = find (t, ::targetname4, self.killtarget);
}
}

// kill the killtaget2 entities
if (self.killtarget2 != "")
{
- t = find (world, targetname, self.killtarget2);
+ t = find (world, ::targetname, self.killtarget2);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname, self.killtarget2);
+ t = find (t, ::targetname, self.killtarget2);
}

- t = find (world, targetname2, self.killtarget2);
+ t = find (world, ::targetname2, self.killtarget2);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname2, self.killtarget2);
+ t = find (t, ::targetname2, self.killtarget2);
}

- t = find (world, targetname3, self.killtarget2);
+ t = find (world, ::targetname3, self.killtarget2);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname3, self.killtarget2);
+ t = find (t, ::targetname3, self.killtarget2);
}

- t = find (world, targetname4, self.killtarget2);
+ t = find (world, ::targetname4, self.killtarget2);
while (t != world)
{
if (t.switchshadstyle)
lightstyle (t.switchshadstyle, "m");
remove (t);
- t = find (t, targetname4, self.killtarget2);
+ t = find (t, ::targetname4, self.killtarget2);
}
}

// fire targets; target 1
- if (self.target != "")
+ if (self.target && self.target != "")
{
SUB_UseSpecificTarget (self.target, targetname);
SUB_UseSpecificTarget (self.target, targetname2);
@@ -504,7 +296,7 @@ void() SUB_UseTargets =
}

// target 2
- if (self.target2 != "")
+ if (self.target2 && self.target2 != "")
{
SUB_UseSpecificTarget (self.target2, targetname);
SUB_UseSpecificTarget (self.target2, targetname2);
@@ -513,7 +305,7 @@ void() SUB_UseTargets =
}

// target 3
- if (self.target3 != "")
+ if (self.target3 && self.target3 != "")
{
SUB_UseSpecificTarget (self.target3, targetname);
SUB_UseSpecificTarget (self.target3, targetname2);
@@ -522,7 +314,7 @@ void() SUB_UseTargets =
}

// target 4
- if (self.target4 != "")
+ if (self.target4 && self.target4 != "")
{
SUB_UseSpecificTarget (self.target4, targetname);
SUB_UseSpecificTarget (self.target4, targetname2);
@@ -531,29 +323,6 @@ void() SUB_UseTargets =
}
};

-//----------------------------------------------------------------------
-void(string matchstring) SUB_UseName =
-{
- SUB_UseSpecificTarget (matchstring, targetname);
- SUB_UseSpecificTarget (matchstring, targetname2);
- SUB_UseSpecificTarget (matchstring, targetname3);
- SUB_UseSpecificTarget (matchstring, targetname4);
-};
-
-//----------------------------------------------------------------------
-// SUB_UseEntTargets
-//----------------------------------------------------------------------
-void(entity t) SUB_UseEntTargets =
-{
- if (t == world)
- return;
- activator = self;
- entity oself = self;
- self = t;
- SUB_UseTargets ();
- self = oself;
-};
-
/*
------------------------------------------------------------------------
SUB_UseAndForgetTargets
@@ -686,34 +455,6 @@ void (void() thinkst) SUB_CheckRefire =
self.think = thinkst;
};

-/*
-------------------------------------------------------------------------
-SUB_DislodgeRestingEntities
-
-This clears the FL_ONGROUND flag from any entities that are on top of
-self.
-
-The engine does not update the FL_ONGROUND flag automatically in some
-cases, with the result that certain types of entities can be left
-floating in mid-air if the entity they are resting on is removed from
-under them. This function is intended to be called in the case where
-self is going to be removed, to ensure that other entities are not left
-floating. -- iw
-------------------------------------------------------------------------
-*/
-void() SUB_DislodgeRestingEntities =
-{
- local entity e;
-
- e = nextent (world);
- while (e != world)
- {
- if ((e.flags & FL_ONGROUND) && e.groundentity == self)
- e.flags = e.flags - (e.flags & FL_ONGROUND);
- e = nextent (e);
- }
-};
-
//--------------------------------------------------------------------//
// SUB_Think -- Drake -- This makes an entity do a think function right now.
//--------------------------------------------------------------------//
@@ -728,37 +469,6 @@ void(entity ent, void() thinkst) SUB_Think =
};

//----------------------------------------------------------------------
-void() SUB_EndWaiting =
-{
- self.is_waiting = 0;
- self.estate = STATE_ACTIVE;
- if (self.use == SUB_EndWaiting)
- self.use = self.dormant_use;
-
- // special case for teleports, makes it ignore the fact that it
- // has a targetname when touched
- if (self.classname == "trigger_teleport")
- self.is_waiting = -1;
-};
-
-//----------------------------------------------------------------------
-void() SUB_CheckWaiting =
-{
- if (self.is_waiting > 0)
- {
- self.dormant_use = self.use;
- self.use = SUB_EndWaiting;
- self.estate = STATE_INACTIVE;
-
- dprint ("Spawned a waiting ");
- dprint (self.classname);
- dprint (" with targetname ");
- dprint (self.targetname);
- dprint (" and target ");
- dprint (self.target);
- dprint ("\n");
- }
-};

//----------------------------------------------------------------------
// SUB_Regen -- was in items.qc

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
index 2392678..25a4a8e 100644
--- a/qc/triggers/camera.qc
+++ b/qc/triggers/camera.qc
@@ -4,6 +4,8 @@

class base_trigger_camera: base_trigger
{
+ float is_removed;
+
//--------------------------------------------------------------
// camera_activate -- PM: Called from either touch or use.
//--------------------------------------------------------------
@@ -19,7 +21,7 @@ class base_trigger_camera: base_trigger
return;

// You can't touch/use this again.
- this.touch = this.use = SUB_Null;
+ this.is_removed = TRUE;

// If player is on ground, take him off ground so no one
// gets confused
@@ -91,11 +93,11 @@ class base_trigger_camera: base_trigger
*/

activator = this;
- SUB_UseTargets ();
+ sub_usetargets ();

// Remove the trigger_camera from level
this.nextthink = time + 0.1;
- this.think = SUB_Remove;
+ this.think = sub_remove;
};

//--------------------------------------------------------------
@@ -131,7 +133,7 @@ class base_trigger_camera: base_trigger
this.nextthink = time + 100000;
// make sure even still objects get hit
force_retouch = 2;
- this.think = SUB_Null;
+ this.think = __NULL__;
*/
};

@@ -146,6 +148,8 @@ class base_trigger_camera: base_trigger
return;
}

+ this.is_removed = FALSE;
+
if (pt)
{
// The new way, this is for you Tronyn.
@@ -182,11 +186,15 @@ after it has been fired.
class trigger_camera: base_trigger_camera
{
//--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ trigger_camera_spawn (FALSE);
+ };
+
+ //--------------------------------------------------------------
void() trigger_camera =
{
- this.classname = "trigger_camera";
this.classtype = CT_TRIGGER_CAMERA;
- this.trigger_camera_spawn (FALSE);
};
};

@@ -200,10 +208,14 @@ amount of time(seconds) to stay on the first script page.
class trigger_camera_point: base_trigger_camera
{
//--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.trigger_camera_spawn (TRUE);
+ };
+
+ //--------------------------------------------------------------
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 52b92be..d747548 100644
--- a/qc/triggers/changelevel.qc
+++ b/qc/triggers/changelevel.qc
@@ -12,7 +12,9 @@ When the player touches this, he gets sent to the map listed in the "map" variab
class trigger_changelevel: base_trigger
{
//--------------------------------------------------------------
- virtual void() changelevel_execute =
+ // was changelevel_execute
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
used_exit = this;
local entity pos;
@@ -66,19 +68,19 @@ class trigger_changelevel: base_trigger
};

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

// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

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

@@ -89,7 +91,7 @@ class trigger_changelevel: base_trigger
}

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

if ((this.spawnflags & 16) && (deathmatch == 0))
{
@@ -104,12 +106,12 @@ class trigger_changelevel: base_trigger
return;
}

- this.touch = SUB_Null;
+ this.interaction_flags |= DISABLE_TOUCH;
+ this.interaction_flags |= DISABLE_USE;

// 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;
};

@@ -117,7 +119,7 @@ class trigger_changelevel: base_trigger
// trigger_changelevel_use
// dumptruck_ds based on hipnotic blocker_use; was named dt_exit_toggle
//--------------------------------------------------------------
- virtual void() changelevel_use =
+ virtual void(entity caller) do_use =
{
if (this.estate != STATE_ACTIVE)
{
@@ -132,27 +134,26 @@ class trigger_changelevel: base_trigger
};

//--------------------------------------------------------------
- void() trigger_changelevel =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "trigger_changelevel";
- this.classtype = CT_TRIGGER_CHANGELEVEL;
+ this.interaction_flags = 0;

// dumptruck_ds
if (this.spawnflags & TRIGGER_CHANGELEVEL_EXITOFF)
this.is_waiting = 1;

- SUB_CheckWaiting ();
- this.use = this.changelevel_use;
+ sub_checkwaiting ();

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

init_trigger ();
this.flags = this.flags | FL_NOCENTERPRINT;
- this.touch = this.changelevel_touch;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_changelevel =
+ {
+ this.classtype = CT_TRIGGER_CHANGELEVEL;
};
};

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 561929d..0d9531c 100644
--- a/qc/triggers/changemusic.qc
+++ b/qc/triggers/changemusic.qc
@@ -5,7 +5,7 @@
class base_changemusic: base_trigger
{
//--------------------------------------------------------------
- virtual void(float newtrack) changemusic =
+ nonvirtual void(float newtrack) changemusic =
{
// changing the field via a pointer
*world_sounds = newtrack;
@@ -29,34 +29,31 @@ class base_changemusic: base_trigger
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). */
class trigger_changemusic: base_changemusic
{
+ virtual void(entity caller) do_think =
+ {
+ remove (this);
+ };
+
//--------------------------------------------------------------
// thanks to jleww via changemusic.rar --dumptruck_ds
//--------------------------------------------------------------
- virtual void() changemusic_touch =
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

- if (!(other.flags & FL_CLIENT))
+ if (!(toucher.flags & FL_CLIENT))
return;

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

//--------------------------------------------------------------
- void() trigger_changemusic =
+ virtual void() init_spawned =
{
- // 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
@@ -67,9 +64,13 @@ class trigger_changemusic: base_changemusic
}

init_trigger ();
- this.touch = this.changemusic_touch;
+ sub_checkwaiting ();
+ };

- SUB_CheckWaiting ();
+ //--------------------------------------------------------------
+ void() trigger_changemusic =
+ {
+ this.classtype = CT_TRIGGER_CHANGEMUSIC;
};
};

@@ -82,31 +83,27 @@ class trigger_cdtrack: base_changemusic
{
// point entity version uses count for music track number for
// backwards compatibly in Adoria mod -- dumptruck_ds
- virtual void() cdtrack_use =
+ virtual void(entity caller) do_use =
{
this.changemusic (this.count);
};

//--------------------------------------------------------------
- void() trigger_cdtrack =
+ virtual void() init_spawned =
{
- // 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;
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_cdtrack =
+ {
+ this.classtype = CT_TRIGGER_CDTRACK;
};
};

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 e3cbf30..d91f256 100644
--- a/qc/triggers/changetarget.qc
+++ b/qc/triggers/changetarget.qc
@@ -13,7 +13,7 @@ cnt = target field to change, null defaults to target
class trigger_changetarget: base_trigger
{
//--------------------------------------------------------------
- virtual void() changetarget_use =
+ virtual void(entity caller) do_use =
{
if (this.estate != STATE_ACTIVE)
return;
@@ -33,14 +33,11 @@ class trigger_changetarget: base_trigger
};

//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
void() trigger_changetarget =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- 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 17a72e4..85f0060 100644
--- a/qc/triggers/counter.qc
+++ b/qc/triggers/counter.qc
@@ -16,7 +16,7 @@ After the counter has been triggered "count" times (default 2), it will fire all
class trigger_counter: base_multiple
{
//--------------------------------------------------------------
- virtual void() counter_use =
+ virtual void(entity caller) do_use =
{
if (this.estate != STATE_ACTIVE)
return;
@@ -58,18 +58,17 @@ class trigger_counter: base_multiple
};

//--------------------------------------------------------------
- void() trigger_counter =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "trigger_counter";
- this.classtype = CT_TRIGGER_COUNTER;
- this.use = this.counter_use;
this.wait = -1;

if (!this.count)
this.count = 2;
};
+
+ //--------------------------------------------------------------
+ void() trigger_counter =
+ {
+ this.classtype = CT_TRIGGER_COUNTER;
+ };
};

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
index 69e4335..afb5e3c 100644
--- a/qc/triggers/cvarset.qc
+++ b/qc/triggers/cvarset.qc
@@ -10,7 +10,15 @@ sv_gravity, sv_friction, fov, and v_idlescale.
class trigger_cvarset: base_trigger
{
//--------------------------------------------------------------
- virtual void() change_cvar =
+ // was cvarset_delaythink
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ sub_usetargets ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
local entity check;

@@ -24,20 +32,31 @@ class trigger_cvarset: base_trigger

check.ideal_yaw = -1;

+ this.interaction_flags &= ~DISABLE_THINK;
this.nextthink = time + 0.02;
- this.think = SUB_UseTargets;
};

//--------------------------------------------------------------
- virtual void() cvarset_touch =
+ // touch wasn't enabled in the original trigger_cvarset -- CEV
+ //--------------------------------------------------------------
+ /*
+ virtual void(entity toucher) do_touch =
{
- if (this.cnt > time || other.health <= 0 ||
- other.classtype != CT_PLAYER)
+ if (this.cnt > time || toucher.health <= 0 ||
+ toucher.classtype != CT_PLAYER)
{
return;
}

- this.change_cvar ();
+ this.do_use (toucher);
+ };
+ */
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ init_trigger ();
+ this.interaction_flags |= DISABLE_THINK;
};

//--------------------------------------------------------------
@@ -46,11 +65,6 @@ class trigger_cvarset: base_trigger
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
index a8ed360..cfb09f9 100644
--- a/qc/triggers/everything.qc
+++ b/qc/triggers/everything.qc
@@ -8,7 +8,7 @@
class trigger_everything: base_trigger
{
//--------------------------------------------------------------
- virtual void() everything_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;
@@ -16,9 +16,9 @@ class trigger_everything: base_trigger
if (time < this.attack_finished)
return;

- activator = other;
+ activator = toucher;

- SUB_UseSpecificTarget (this.target, ::targetname);
+ sub_usetarget (this.target, ::targetname);

if (this.wait)
if (!(this.spawnflags & 1))
@@ -26,13 +26,15 @@ class trigger_everything: base_trigger
};

//--------------------------------------------------------------
- void() trigger_everything =
+ virtual void() init_spawned =
{
init_trigger ();
+ sub_checkwaiting ();
+ };

- this.classname = "trigger_everything";
+ //--------------------------------------------------------------
+ void() 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 0616af8..debcd82 100644
--- a/qc/triggers/filter.qc
+++ b/qc/triggers/filter.qc
@@ -34,16 +34,16 @@ const float FILTER_OP_BITMASK_OR = 6;
class trigger_filter: base_trigger
{
//--------------------------------------------------------------
- virtual void() filter_use =
+ virtual void(entity caller) do_use =
{
this.state = 0;

if (this.estate != STATE_ACTIVE)
return;

- entity targ;
- float fieldtype, op, result, targfloat;
- string targstring;
+ local entity targ;
+ local float fieldtype, op, result, targfloat;
+ local string targstring;

targfloat = fieldtype = op = result = 0;
targstring = "";
@@ -216,21 +216,22 @@ class trigger_filter: base_trigger
if (this.spawnflags & 2 && activator.owner)
activator = activator.owner;

- SUB_UseTargets ();
+ sub_usetargets ();

- if (other.classtype == CT_TRIGGER_EVERYTHING &&
- other.spawnflags & 1 && other.wait)
+ if (caller.classtype == CT_TRIGGER_EVERYTHING &&
+ caller.spawnflags & 1 && caller.wait)
{
- other.attack_finished = time + other.wait;
+ caller.attack_finished = time + caller.wait;
}
}
};

//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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 0fed77d..1ab18c8 100644
--- a/qc/triggers/fog.qc
+++ b/qc/triggers/fog.qc
@@ -139,12 +139,12 @@ void(entity client, float density) skyfog_set =
};

//------------------------------------------------------------------------------
-class base_fog_controller: entity
+class base_fog_controller: base_mapentity
{
float speed2;

//--------------------------------------------------------------
- virtual void(entity cl, float sTo, float f) skyfog_blendSetFraction =
+ nonvirtual void(entity cl, float sTo, float f) skyfog_blendSetFraction =
{
local float s;

@@ -157,7 +157,7 @@ class base_fog_controller: entity
};

//--------------------------------------------------------------
- virtual void(entity cl, vector cTo, float dTo, float f)
+ nonvirtual void(entity cl, vector cTo, float dTo, float f)
fog_blendSetFraction =
{
local float d;
@@ -177,9 +177,10 @@ class base_fog_controller: entity
};

//--------------------------------------------------------------
- // fog_blendTimeThink -- used by both trigger_fog and target_fogblend
+ // fog controller think -- used by both trigger_fog and
+ // target_fogblend; was fog_blendTimeThink
//--------------------------------------------------------------
- virtual void() fog_blendTimeThink =
+ virtual void(entity caller) do_think =
{
local float f;
local float dTo, sTo;
@@ -289,7 +290,6 @@ class temp_fog_controller: base_fog_controller
{
this.classname = "temp_fog_controller";
this.classtype = CT_TEMP_FOG_CONTROLLER;
- this.think = this.fog_blendTimeThink;
};
};

@@ -328,7 +328,20 @@ Activator's fog will be blended over time from start to end values.
class target_fogblend: base_fog_controller
{
//--------------------------------------------------------------
- virtual void() fogblend_use =
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "speed2":
+ this.speed2 = stof (fieldvalue);
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
this.enemy = activator;
if (this.enemy.classtype != CT_PLAYER)
@@ -372,23 +385,14 @@ class target_fogblend: base_fog_controller
};

//--------------------------------------------------------------
- void() target_fogblend =
+ virtual void() init_spawned =
{
- // 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;
}

- this.classname = "target_fogblend";
- this.classtype = CT_TARGET_FOGBLEND;
- this.use = this.fogblend_use;
- this.think = this.fog_blendTimeThink;
-
if (this.spawnflags & FOGBLEND_REVERSE)
this.state = 1;
else
@@ -407,6 +411,12 @@ class target_fogblend: base_fog_controller
if (this.speed2 == -1)
this.speed2 = 0;
};
+
+ //--------------------------------------------------------------
+ void() target_fogblend =
+ {
+ this.classtype = CT_TARGET_FOGBLEND;
+ };
};

/*QUAKED trigger_fogblend (.5 .5 .2) ?
@@ -437,12 +447,12 @@ class trigger_fogblend: base_trigger
//--------------------------------------------------------------
// fog_blendTouch
//--------------------------------------------------------------
- virtual void() fog_blendTouch =
+ virtual void(entity toucher) do_touch =
{
- if (other.classtype != CT_PLAYER)
+ if (toucher.classtype != CT_PLAYER)
return;

- if (other.health <= 0)
+ if (toucher.health <= 0)
return;

if (this.estate != STATE_ACTIVE)
@@ -471,19 +481,19 @@ class trigger_fogblend: base_trigger
// 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));
+ ovel = toucher.velocity * FOG_INTERVAL;
+ leaving = ((toucher.absmax_x + ovel_x < this.absmin_x) ||
+ (toucher.absmax_y + ovel_y < this.absmin_y) ||
+ (toucher.absmax_z + ovel_z < this.absmin_z) ||
+ (toucher.absmin_x + ovel_x > this.absmax_x) ||
+ (toucher.absmin_y + ovel_y > this.absmax_y) ||
+ (toucher.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;
+ leaving = toucher.velocity * this.movedir;
if (leaving > 0)
{
lerp_density = ent_density2;
@@ -502,7 +512,7 @@ class trigger_fogblend: base_trigger
// in transition, blend proportionally between
// the two fogs
mid = (this.mins + this.maxs) * 0.5;
- dorg = other.origin + other.view_ofs - mid;
+ dorg = toucher.origin + toucher.view_ofs - mid;

f = dorg * this.movedir;
f = (f / this.distance) + 0.5;
@@ -514,37 +524,36 @@ class trigger_fogblend: base_trigger
}

if (this.fog_density || this.fog_density2)
- fog_set (other, lerp_density, lerp_color);
+ fog_set (toucher, lerp_density, lerp_color);
if (this.skyfog_density || this.skyfog_density2)
- skyfog_set (other, lerp_sdensity);
+ skyfog_set (toucher, lerp_sdensity);

this.rad_time = time;
this.attack_finished = time + FOG_INTERVAL;

// reset client's fogblend_entity in case it's currently being
// transitioned by another entity
- other.fogblend_entity = world;
+ toucher.fogblend_entity = world;
};

//--------------------------------------------------------------
- void() trigger_fogblend =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
// InitTrigger (now init_trigger) assumes angle 0 means no angle
if (this.angles == '0 0 0')
this.angles = '0 360 0';

- 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));

- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_fogblend =
+ {
+ this.classtype = CT_TRIGGER_FOGBLEND;
};
};

@@ -561,35 +570,35 @@ CAVEATS:
class trigger_fog: base_trigger
{
//--------------------------------------------------------------
- virtual void() fog_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

- if (!(other.flags & FL_CLIENT))
+ if (!(toucher.flags & FL_CLIENT))
return;

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

// transition already occurring from this trigger
- if (other.fogblend_entity.owner == this)
+ if (toucher.fogblend_entity.owner == this)
return;

if (this.fog_density)
- fog_save_to_previous (other);
+ fog_save_to_previous (toucher);
if (this.skyfog_density)
- skyfog_save_to_previous (other);
+ skyfog_save_to_previous (toucher);

// 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,
+ owner: this,
+ enemy: toucher,
// speed2 is used when state is 0
speed2: this.speed,
fog_color: this.fog_color,
@@ -597,29 +606,28 @@ class trigger_fog: base_trigger
skyfog_density: this.skyfog_density,
pain_finished: time + this.delay + this.speed);
controller.nextthink = time + controller.delay;
- other.fogblend_entity = controller;
+ toucher.fogblend_entity = controller;
};

//--------------------------------------------------------------
- void() trigger_fog =
+ virtual void() init_spawned =
{
- // 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;
}

- 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 ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_fog =
+ {
+ this.classtype = CT_TRIGGER_FOG;
};
};

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 247be3e..bef2258 100644
--- a/qc/triggers/heal.qc
+++ b/qc/triggers/heal.qc
@@ -4,7 +4,7 @@
// was in dtmisc.qc -- CEV
//==============================================================================

-// entity fields
+// global entity fields
.float heal_timer;

// Constants for the healing trigger
@@ -31,14 +31,34 @@ class trigger_heal: base_trigger
// class fields
float heal_amount;
float health_max;
+ string message2;

//--------------------------------------------------------------
- virtual void() heal_think =
+ virtual void(string fieldname, string fieldvalue) init_field =
+ {
+ switch (fieldname)
+ {
+ case "heal_amount":
+ heal_amount = stof (fieldvalue);
+ break;
+ case "health_max":
+ health_max = stof (fieldvalue);
+ break;
+ case "message2":
+ message2 = fieldvalue;
+ break;
+ default:
+ super::init_field (fieldname, fieldvalue);
+ }
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
if (this.cnt == this.count)
{
dprint ("trigger_heal think: full\n");
- this.think = SUB_Null;
+ this.interaction_flags |= DISABLE_THINK;
return;
}

@@ -60,35 +80,36 @@ class trigger_heal: base_trigger
};

//--------------------------------------------------------------
- virtual void() heal_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
{
return;
}

if (this.spawnflags & TRIGGER_HEAL_PLAYER_ONLY &&
- other.classtype != CT_PLAYER)
+ toucher.classtype != CT_PLAYER)
{
return;
}

if (this.spawnflags & TRIGGER_HEAL_MONSTER_ONLY &&
- !(other.flags & FL_MONSTER))
+ !(toucher.flags & FL_MONSTER))
{
return;
}

- if (other.classtype != CT_PLAYER && !(other.flags & FL_MONSTER))
+ if (toucher.classtype != CT_PLAYER &&
+ !(toucher.flags & FL_MONSTER))
{
return;
}

- if (other.heal_timer > time)
+ if (toucher.heal_timer > time)
{
return;
}
@@ -96,11 +117,11 @@ class trigger_heal: base_trigger
if (this.count && this.cnt <= 0)
{
if (this.message2 != __NULL__ && this.message2 != "")
- centerprint (other, this.message2);
+ centerprint (toucher, this.message2);
return;
}

- if ((other.takedamage) && (other.health < this.health_max))
+ if ((toucher.takedamage) && (toucher.health < this.health_max))
{
if (this.noise != "")
sound (this, CHAN_AUTO, this.noise,
@@ -111,10 +132,10 @@ class trigger_heal: base_trigger

local float calc_healing;

- if ((other.health + this.heal_amount) > this.health_max)
- calc_healing = this.health_max - other.health;
+ if ((toucher.health + heal_amount) > health_max)
+ calc_healing = health_max - toucher.health;
else
- calc_healing = this.heal_amount;
+ calc_healing = heal_amount;

if (this.count)
{
@@ -125,50 +146,43 @@ class trigger_heal: base_trigger

if (this.delay)
{
- this.think = this.heal_think;
+ interaction_flags &= ~DISABLE_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");
+ dprint (sprintf("trigger_heal::do_touch: "
+ "used [max: %f, current: %f, "
+ "using: %f]\n",
+ this.count, this.cnt, calc_healing));
}

if (this.message != __NULL__ && this.message != "")
- centerprint (other, this.message);
+ centerprint (toucher, this.message);

- T_Heal (other, calc_healing, 1);
- other.heal_timer = time + this.wait;
+ T_Heal (toucher, calc_healing, 1);
+ toucher.heal_timer = time + this.wait;
}
};

//--------------------------------------------------------------
- virtual void() heal_toggle =
+ /*
+ nonvirtual void() heal_toggle =
{
- if (this.touch == SUB_Null)
- this.touch = this.heal_touch;
+ if (this.interaction_flags & DISABLE_TOUCH)
+ this.interaction_flags &= ~DISABLE_TOUCH;
else
- this.touch = SUB_Null;
+ this.interaction_flags |= DISABLE_TOUCH;
};
+ */

//--------------------------------------------------------------
- void() trigger_heal =
+ virtual void() init_spawned =
{
- // 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)
@@ -195,16 +209,21 @@ class trigger_heal: base_trigger
/*
if (this.targetname)
{
- this.use = this.heal_toggle;
+ this.interaction_flags &= ~DISABLE_USE;
if (this.spawnflags & TRIGGER_HEAL_START_ON)
- this.touch = this.heal_touch;
+ this.interaction_flags &= ~DISABLE_TOUCH;
else
- this.touch = SUB_Null;
+ this.interaction_flags |= DISABLE_TOUCH;
}
else
*/

- this.touch = this.heal_touch;
- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_heal =
+ {
+ this.classtype = CT_TRIGGER_HEAL;
};
};

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 da3e19d..9793bda 100644
--- a/qc/triggers/hurt.qc
+++ b/qc/triggers/hurt.qc
@@ -16,7 +16,7 @@ class trigger_hurt: base_trigger
// 1998-07-03 hurt_touch fix by Robert Field end

//--------------------------------------------------------------
- virtual void(entity ent, float amount) setdamage =
+ nonvirtual void(entity ent, float amount) setdamage =
{
ent.dmg = amount;

@@ -40,16 +40,16 @@ class trigger_hurt: base_trigger
// 1998-07-03 hurt_touch fix by Robert Field end

//--------------------------------------------------------------
- virtual void() hurt_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
return;

- if (other.takedamage && this.nextthink < time)
+ if (toucher.takedamage && this.nextthink < time)
{
// 1998-07-03 trigger_hurt_touch fix by Robert Field
// this.solid = SOLID_NOT;
@@ -57,7 +57,7 @@ class trigger_hurt: base_trigger
if (time < this.hurt_nextthink)
return;
// 1998-07-03 hurt_touch fix by Robert Field end
- T_Damage (other, this, this, this.dmg);
+ T_Damage (toucher, this, this, this.dmg);
// 1998-07-03 hurt_touch fix by Robert Field start
// this.think = hurt_on;
// this.nextthink = time + 1;
@@ -70,19 +70,18 @@ class trigger_hurt: base_trigger
};

//--------------------------------------------------------------
- void() trigger_hurt =
+ virtual void() init_spawned =
{
- // 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 ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_hurt =
+ {
+ this.classtype = CT_TRIGGER_HURT;
};
};

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 af190e2..6f548f5 100644
--- a/qc/triggers/ladder.qc
+++ b/qc/triggers/ladder.qc
@@ -14,40 +14,36 @@ class trigger_ladder: base_trigger
//--------------------------------------------------------------
// trigger_ladder_touch
//--------------------------------------------------------------
- virtual void() ladder_touch =
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
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)
+ if (toucher.absmin_z + 1 >= this.absmax_z - 1)
return;

// if the trigger has an angles field, check player's
// facing direction
if (this.movedir != '0 0 0')
{
- makevectors (other.angles);
+ makevectors (toucher.angles);
if (v_forward * this.movedir < 0)
// not facing the right way
return;
}

// changed to PMFLAGS -- CEV
- other.pmove_flags |= PMF_ONLADDER;
+ toucher.pmove_flags |= PMF_ONLADDER;
};

//--------------------------------------------------------------
- void() trigger_ladder =
+ virtual void() init_spawned =
{
- if (SUB_Inhibit())
- // new spawnflags for all entities -- iw
- return;
-
// ignore an "up" or "down" angle (doesn't make sense
// for a ladder)
if (this.angles_y == -1 || this.angles_y == -2)
@@ -60,10 +56,13 @@ class trigger_ladder: base_trigger
this.angles_y = 0;
}

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

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 64840ef..5402d58 100644
--- a/qc/triggers/look.qc
+++ b/qc/triggers/look.qc
@@ -16,10 +16,16 @@ See manual for complete details. See pd_cutscenes sample map for example
class trigger_look: base_multiple
{
//--------------------------------------------------------------
- virtual void() look_touch =
+ virtual void(entity caller) do_use =
+ {
+ multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

if (this.nextthink > time)
@@ -28,9 +34,9 @@ class trigger_look: base_multiple

// added player view offset to make this more accurate
// to the player crosshairs
- local vector player_offset = other.origin + other.view_ofs;
+ local vector player_offset = toucher.origin + toucher.view_ofs;

- makevectors (other.v_angle);
+ makevectors (toucher.v_angle);

// using speed to determine the reach of the trace
if (!this.speed)
@@ -38,16 +44,19 @@ class trigger_look: base_multiple

traceline (player_offset,
(player_offset + (v_forward * this.speed)),
- FALSE, other);
+ FALSE, other);

if (trace_ent.targetname == this.target)
{
// Play message if available
if (this.message != "")
- centerprint (other, this.message);
+ centerprint (toucher, this.message);

+ // TODO CEV
+ /*
this.use = this.multi_trigger;
- SUB_UseTargets ();
+ */
+ sub_usetargets ();

if (this.noise != "")
sound (this, CHAN_VOICE, this.noise, 1,
@@ -59,7 +68,6 @@ class trigger_look: base_multiple
// added wait
if (this.wait > 0)
{
- this.think = this.multi_wait;
this.nextthink = time + this.wait;
}
else
@@ -67,20 +75,17 @@ class trigger_look: base_multiple
// 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.interaction_flags |= DISABLE_TOUCH;
+ this.interaction_flags |= DISABLE_USE;
+ this.is_removed = TRUE;
this.nextthink = time + 0.1;
- this.think = SUB_Remove;
}
}
};

//--------------------------------------------------------------
- void() trigger_look =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
// play all the sounds available for a normal trigger
if (this.sounds == 0)
{
@@ -118,10 +123,14 @@ class trigger_look: base_multiple
this.noise = this.noise1;
}

- this.classname = "trigger_look";
- this.classtype = CT_TRIGGER_LOOK;
- this.touch = this.look_touch;
+ this.is_removed = FALSE;
init_trigger ();
- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_look =
+ {
+ this.classtype = CT_TRIGGER_LOOK;
};
};

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 d1c8960..c0bab33 100644
--- a/qc/triggers/monsterface.qc
+++ b/qc/triggers/monsterface.qc
@@ -14,25 +14,27 @@ Keys:
class trigger_monsterface: base_trigger
{
//--------------------------------------------------------------
- virtual void() monsterface_touch =
+ virtual void(entity toucher) do_touch =
{
// only affect ground monsters
- if (other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
+ if (toucher.flags &
+ (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
return;

- if (!visibleToOther(other.enemy))
+ if (!visibleToOther(toucher.enemy))
{
// enemy is hidden
// don't dodge around, just go straight
- other.t_length = time + this.wait + 0.2;
+ toucher.t_length = time + this.wait + 0.2;
// face where I want
- other.ideal_yaw = this.angles_y;
+ toucher.ideal_yaw = this.angles_y;
}
};

//--------------------------------------------------------------
- virtual void() init =
+ virtual void() init_spawned =
{
+ // a bit like InitTrigger below -- CEV
this.solid = SOLID_TRIGGER;
// set size and link into world
setmodel (this, this.model);
@@ -47,13 +49,6 @@ class trigger_monsterface: base_trigger
//--------------------------------------------------------------
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 acd510d..129e5d3 100644
--- a/qc/triggers/monsterjump.qc
+++ b/qc/triggers/monsterjump.qc
@@ -18,30 +18,31 @@ be targeted and toggled off and on.
class trigger_monsterjump: base_trigger
{
//--------------------------------------------------------------
- virtual void() monsterjump_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

- if (other.flags & (FL_MONSTER | FL_FLY | FL_SWIM) != FL_MONSTER)
+ if (toucher.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;
+ toucher.velocity_x = this.movedir_x * this.speed;
+ toucher.velocity_y = this.movedir_y * this.speed;

- if (!(other.flags & FL_ONGROUND))
+ if (!(toucher.flags & FL_ONGROUND))
return;

- other.flags = other.flags - FL_ONGROUND;
+ toucher.flags = toucher.flags - FL_ONGROUND;

- other.velocity_z = this.height;
+ toucher.velocity_z = this.height;
};

//--------------------------------------------------------------
// dumptruck_ds was based on hipnotic blocker_use now Alkaline estate
//--------------------------------------------------------------
- virtual void() monsterjump_use =
+ virtual void(entity caller) do_use =
{
// TODO CEV duplicating some code here between this and
// trigger_push_custom
@@ -52,12 +53,8 @@ class trigger_monsterjump: base_trigger
};

//--------------------------------------------------------------
- void() trigger_monsterjump =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
// dumptruck_ds
if (this.spawnflags & TRIGGER_MONSTERJUMP_STARTOFF)
{
@@ -71,11 +68,13 @@ class trigger_monsterjump: base_trigger
if (this.angles == '0 0 0')
this.angles = '0 360 0';

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

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
index 6299e19..f1866bb 100644
--- a/qc/triggers/multiple.qc
+++ b/qc/triggers/multiple.qc
@@ -12,6 +12,8 @@ const float TRIGGER_MULTIPLE_TURNS_OFF = 2;
//------------------------------------------------------------------------------
class base_multiple: base_trigger
{
+ float is_removed;
+
//--------------------------------------------------------------
// the wait time has passed, so set back up for another activation
//--------------------------------------------------------------
@@ -35,6 +37,10 @@ class base_multiple: base_trigger
if (this.nextthink > time)
{
// already been triggered
+ /*
+ dprint ("base_multiple::multi_trigger: already been "
+ "triggered\n");
+ */
return;
}

@@ -57,16 +63,16 @@ class base_multiple: base_trigger

activator = this.enemy;

- SUB_UseTargets ();
+ dprint ("base_multiple::multi_trigger: firing targets...\n");
+ 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 ();
+ sub_checkwaiting ();
}
}
else
@@ -74,9 +80,8 @@ class base_multiple: base_trigger
// 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.is_removed = TRUE;
this.nextthink = time + 0.1;
- this.think = SUB_Remove;
}
};

@@ -101,24 +106,34 @@ class base_multiple: base_trigger
};

//--------------------------------------------------------------
- // dumptruck_ds
- //--------------------------------------------------------------
- virtual void() multi_use =
+ virtual void(entity caller) do_think =
{
- this.enemy = activator;
- this.multi_trigger ();
+ if (this.is_removed == TRUE)
+ {
+ remove (this);
+ }
+ else
+ {
+ multi_wait ();
+ }
};

//--------------------------------------------------------------
// dumptruck_ds
//--------------------------------------------------------------
- virtual void() multi_touch =
+ virtual void(entity toucher) do_touch =
{
- if (other.classtype != CT_PLAYER)
+ if (this.is_removed == TRUE)
+ return;
+
+ if (this.spawnflags & TRIGGER_MULTIPLE_NOTOUCH)
+ return;
+
+ if (toucher.classtype != CT_PLAYER)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
return;

if (this.estate != STATE_ACTIVE)
@@ -128,19 +143,33 @@ class base_multiple: base_trigger
// facing direction
if (this.movedir != '0 0 0')
{
- makevectors (other.angles);
+ makevectors (toucher.angles);
if (v_forward * this.movedir < 0)
// not facing the right way
return;
}

- this.enemy = other;
+ this.enemy = toucher;
+ this.multi_trigger ();
+ };
+
+ //--------------------------------------------------------------
+ // dumptruck_ds
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ if (this.is_removed == TRUE)
+ return;
+
+ this.enemy = activator;
this.multi_trigger ();
};

//--------------------------------------------------------------
- virtual void() multi_init =
+ nonvirtual void() multi_init =
{
+ this.is_removed = FALSE;
+
if (this.sounds == 1)
{
precache_sound ("misc/secret.wav");
@@ -168,7 +197,6 @@ class base_multiple: base_trigger
" make sense");
}

- this.use = this.multi_use;
init_trigger ();

if (this.health)
@@ -183,15 +211,8 @@ class base_multiple: base_trigger
// 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 ();
+ sub_checkwaiting ();
};
};

@@ -213,16 +234,15 @@ set "message" to text string
class trigger_multiple: base_multiple
{
//--------------------------------------------------------------
- void() trigger_multiple =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ this.multi_init ();
+ };

- this.classname = "trigger_multiple";
+ //--------------------------------------------------------------
+ void() trigger_multiple =
+ {
this.classtype = CT_TRIGGER_MULTIPLE;
-
- this.multi_init ();
};
};

@@ -241,15 +261,15 @@ set "message" to text string
*/
class trigger_once: base_multiple
{
- void() trigger_once =
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
this.wait = -1;
this.multi_init ();
- this.classname = "trigger_once";
+ };
+
+ void() 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 8a0452b..60e6c36 100644
--- a/qc/triggers/onlyregistered.qc
+++ b/qc/triggers/onlyregistered.qc
@@ -8,10 +8,10 @@ Only fires if playing the registered version, otherwise prints the message
class trigger_onlyregistered: base_trigger
{
//--------------------------------------------------------------
- virtual void() touch =
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

if (this.attack_finished > time)
@@ -22,32 +22,31 @@ class trigger_onlyregistered: base_trigger
if (cvar("registered"))
{
this.message = "";
- SUB_UseTargets ();
+ sub_usetargets ();
remove (this);
}
else
{
if (this.message != "")
{
- centerprint (other, this.message);
- sound (other, CHAN_BODY, "misc/talk.wav",
+ centerprint (toucher, this.message);
+ sound (toucher, CHAN_BODY, "misc/talk.wav",
1, ATTN_NORM);
}
}
};

//--------------------------------------------------------------
- void() trigger_onlyregistered =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
precache_sound ("misc/talk.wav");
+ init_trigger ();
+ sub_checkwaiting ();
+ };

- this.classname = "trigger_onlyregistered";
+ //--------------------------------------------------------------
+ void() 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 4258df1..901df32 100644
--- a/qc/triggers/push.qc
+++ b/qc/triggers/push.qc
@@ -207,13 +207,13 @@ class base_trigger_push: base_trigger
};

//--------------------------------------------------------------
- virtual void() push_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
return;

// try to find target again if necessary
@@ -222,40 +222,40 @@ class base_trigger_push: base_trigger

// we have a target, set movedir accordingly
if (this.target && this.enemy)
- this.movedir = this.calculatevelocity (other.origin,
+ this.movedir = this.calculatevelocity (toucher.origin,
this.enemy, this.height);

- if (other.classname == "grenade")
+ if (toucher.classname == "grenade")
{
if (this.target && this.enemy)
- other.velocity = this.movedir;
+ toucher.velocity = this.movedir;
else
- other.velocity = this.speed * this.movedir * 10;
+ toucher.velocity = speed * movedir * 10;
}
- else if (other.health > 0)
+ else if (toucher.health > 0)
{
if (this.target && this.enemy)
- other.velocity = this.movedir;
+ toucher.velocity = movedir;
else
- other.velocity = this.speed * this.movedir * 10;
+ toucher.velocity = speed * movedir * 10;

- if (other.classtype == CT_PLAYER &&
+ if (toucher.classtype == CT_PLAYER &&
!(this.spawnflags & TRIGGER_PUSH_SILENT))
{
- if (other.fly_sound < time)
+ if (toucher.fly_sound < time)
{
if (!(this.spawnflags &
TRIGGER_PUSH_NOISE))
{
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO,
+ toucher.fly_sound = time + 1.5;
+ sound (toucher, CHAN_AUTO,
"ambience/windfly.wav",
1, ATTN_NORM);
}
else
{
- other.fly_sound = time + 1.5;
- sound (other, CHAN_AUTO,
+ toucher.fly_sound = time + 1.5;
+ sound (toucher, CHAN_AUTO,
this.noise,
1, ATTN_NORM);
}
@@ -285,17 +285,8 @@ class trigger_push: base_trigger_push
*/

//--------------------------------------------------------------
- // dumptruck_ds
- //--------------------------------------------------------------
- void() trigger_push =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- this.classname = "trigger_push";
- this.classtype = CT_TRIGGER_PUSH;
- this.touch = push_touch;
init_trigger ();
precache_sound ("ambience/windfly.wav");

@@ -312,7 +303,13 @@ class trigger_push: base_trigger_push
this.movedir = '0 0 180';
}

- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_push =
+ {
+ this.classtype = CT_TRIGGER_PUSH;
};
};

@@ -337,7 +334,7 @@ class trigger_push_custom: base_trigger_push
//--------------------------------------------------------------
// dumptruck_ds was based on hipnotic blocker_use now Alkaline estate
//--------------------------------------------------------------
- virtual void() push_custom_use =
+ virtual void(entity caller) do_use =
{
if (this.estate != STATE_ACTIVE)
this.estate = STATE_ACTIVE;
@@ -346,16 +343,8 @@ class trigger_push_custom: base_trigger_push
};

//--------------------------------------------------------------
- void() trigger_push_custom =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit ())
- return;
-
- 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");

@@ -368,6 +357,12 @@ class trigger_push_custom: base_trigger_push
if (!this.speed)
this.speed = 1000;

- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_push_custom =
+ {
+ this.classtype = CT_TRIGGER_PUSH_CUSTOM;
};
};

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
index bb3aaf1..61e6641 100644
--- a/qc/triggers/relay.qc
+++ b/qc/triggers/relay.qc
@@ -7,15 +7,18 @@ This fixed size trigger cannot be touched, it can only be fired by other events.
*/
class trigger_relay: base_trigger
{
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
+ {
+ sub_usetargets ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
//-------------------------------------------------------------
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 b2fbab0..6a21033 100644
--- a/qc/triggers/remove.qc
+++ b/qc/triggers/remove.qc
@@ -16,7 +16,7 @@
// {
// if (other.flags & self.cnt)
// return;
-// other.touch = SUB_Null;
+// other.touch = __NULL__;
// other.model = "";
// remove (self);
// };

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 965a737..83b5d6a 100644
--- a/qc/triggers/secret.qc
+++ b/qc/triggers/secret.qc
@@ -11,12 +11,9 @@ set "message" to text string
*/
class trigger_secret: base_multiple
{
- void() trigger_secret =
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
total_secrets = total_secrets + 1;
this.wait = -1;

@@ -38,7 +35,11 @@ class trigger_secret: base_multiple
}

this.multi_init ();
- this.classname = "trigger_secret";
+ };
+
+ //--------------------------------------------------------------
+ void() 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
index 519cb9c..8cb517d 100644
--- a/qc/triggers/setcount.qc
+++ b/qc/triggers/setcount.qc
@@ -8,7 +8,7 @@
class target_setcount: base_trigger
{
//--------------------------------------------------------------
- virtual void(string name, .string fld) setcount_set =
+ nonvirtual void(string name, .string fld) setcount_set =
{
local entity t;

@@ -26,7 +26,7 @@ class target_setcount: base_trigger
};

//--------------------------------------------------------------
- virtual void() setcount_use =
+ virtual void(entity caller) do_use =
{
if (this.target && this.target != "")
{
@@ -67,10 +67,11 @@ class target_setcount: base_trigger
};

//--------------------------------------------------------------
+ virtual void() init_spawned = { };
+
+ //--------------------------------------------------------------
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 f34b494..330abdd 100644
--- a/qc/triggers/setgravity.qc
+++ b/qc/triggers/setgravity.qc
@@ -41,9 +41,13 @@ class trigger_setgravity: base_trigger
//--------------------------------------------------------------
// from Copper -- dumptruck_ds
//--------------------------------------------------------------
- virtual void() setgravity_touch =
+ virtual void(entity toucher) do_touch =
{
- // if (!CheckValidTouch()) return;
+ // from Copper -- dumptruck_ds
+ /*
+ if (sub_checkvalidtouch(toucher) == FALSE)
+ return;
+ */

if (this.estate != STATE_ACTIVE)
return;
@@ -53,7 +57,7 @@ class trigger_setgravity: base_trigger
// 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)
+ // if (toucher.classtype != CT_PLAYER)
// return;

if (this.gravity == -1)
@@ -64,16 +68,16 @@ class trigger_setgravity: base_trigger
// 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;
+ if (toucher.classtype == CT_PLAYER)
+ toucher.wantedgravity = grav;
else
- other.gravity = grav;
+ toucher.gravity = grav;
};

//--------------------------------------------------------------
// dumptruck_ds based on hipnotic blocker_use
//--------------------------------------------------------------
- virtual void() setgravity_use =
+ virtual void(entity caller) do_use =
{
if (this.estate != STATE_ACTIVE)
this.estate = STATE_ACTIVE;
@@ -82,16 +86,8 @@ class trigger_setgravity: base_trigger
};

//--------------------------------------------------------------
- void() trigger_setgravity =
+ virtual void() init_spawned =
{
- // 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
@@ -103,6 +99,12 @@ class trigger_setgravity: base_trigger
else
this.gravity = ((this.gravity - 1) / 100);

- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_setgravity =
+ {
+ this.classtype = CT_TRIGGER_SETGRAVITY;
};
};

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 a23e1d4..0e32d91 100644
--- a/qc/triggers/setskill.qc
+++ b/qc/triggers/setskill.qc
@@ -9,26 +9,25 @@ Only used on start map.
class trigger_setskill: base_trigger
{
//--------------------------------------------------------------
- virtual void() skill_touch =
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

cvar_set ("skill", this.message);
};

//--------------------------------------------------------------
- void() trigger_setskill =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ init_trigger ();
+ sub_checkwaiting ();
+ };

- this.classname = "trigger_setskill";
+ //--------------------------------------------------------------
+ void() 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
index 4144c94..70b602a 100644
--- a/qc/triggers/setstate.qc
+++ b/qc/triggers/setstate.qc
@@ -10,52 +10,62 @@ const float SETSTATE_DONTRESETBUTTON = 4;
//------------------------------------------------------------------------------
// target_setstate
//------------------------------------------------------------------------------
-class target_setstate: entity
+class target_setstate: base_trigger
{
//--------------------------------------------------------------
- virtual float(entity e) entity_get_state =
+ nonvirtual float(entity e) entity_get_state =
{
- if (e.classname == "func_door")
- return e.owner.estate;
+ if (e.classtype == CT_FUNC_DOOR)
+ return e.estate;
else
return e.estate;
};

//--------------------------------------------------------------
- virtual void(entity e, float state, float flags) entity_set_state =
+ nonvirtual void(entity e, float state, float flags) entity_set_state =
{
float closealldoors = 0;

- if (e.classname == "func_button")
+ if (e.classtype == CT_FUNC_BUTTON)
{
+ // cast to func_button -- CEV
+ local func_button b = (func_button)e;
if (state == STATE_ACTIVE)
- button_unlock (e, flags &
+ b.button_unlock (b, flags &
SETSTATE_DONTRESETBUTTON);
else
- button_lock (e);
+ b.button_lock (b);
}
- else if (e.classname == "func_door")
+ else if (e.classtype == CT_FUNC_DOOR)
{
+ // cast to func_door -- CEV
+ local func_door d = (func_door)e;
+
if (flags & SETSTATE_CLOSEALLDOORS)
closealldoors = 1;

if (state == STATE_ACTIVE)
- door_estate_unlock (e, closealldoors);
+ d.estate_unlock (d, closealldoors);
else
- door_estate_lock (e, closealldoors);
+ d.estate_lock (d, closealldoors);
}
else
{
e.estate = state;
}

- if (e.is_waiting > 0 && state == STATE_ACTIVE)
+ if (e.classgroup & CG_TRIGGER)
{
- SUB_CallAsSelf (SUB_EndWaiting, e);
+ local base_trigger bt = (base_trigger)e;
+
+ if (bt.is_waiting > 0 && state == STATE_ACTIVE)
+ {
+ base_trigger::sub_endwaiting ((base_trigger)e);
+ }
}

/*
- if (e.touch && e.touch != SUB_Null)
+ if (e.touch && e.touch != __NULL__)
{
force_retouch = 2;
}
@@ -63,7 +73,7 @@ class target_setstate: entity
};

//--------------------------------------------------------------
- virtual void(string matchstring, .string matchfield, float state,
+ nonvirtual void(string matchstring, .string matchfield, float state,
float flags) set_target =
{
local entity t;
@@ -90,7 +100,7 @@ class target_setstate: entity
};

//--------------------------------------------------------------
- virtual void(float state) set_alltargets =
+ nonvirtual void(float state) set_alltargets =
{
if (this.target && this.target != "")
{
@@ -139,7 +149,7 @@ class target_setstate: entity
};

//--------------------------------------------------------------
- virtual void() setstate_use =
+ virtual void(entity caller) do_use =
{
local float state;

@@ -154,24 +164,32 @@ class target_setstate: entity
};

//--------------------------------------------------------------
- virtual void() setstate_startoff_think =
+ // was setstate_startoff_think
+ //--------------------------------------------------------------
+ virtual void(entity caller) setstate_startoff_think =
{
- this.set_alltargets (STATE_INACTIVE);
+ if (this.spawnflags & SETSTATE_STARTOFF)
+ this.set_alltargets (STATE_INACTIVE);
};

-
//--------------------------------------------------------------
- void() target_setstate =
+ virtual void() init_spawned =
{
- 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.interaction_flags &= ~DISABLE_THINK;
this.nextthink = time + 0.2;
}
+ else
+ {
+ this.interaction_flags |= DISABLE_THINK;
+ }
+ };
+
+ //--------------------------------------------------------------
+ void() target_setstate =
+ {
+ this.classtype = CT_TARGET_SETSTATE;
};
};

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 fc759c4..dad5789 100644
--- a/qc/triggers/shake.qc
+++ b/qc/triggers/shake.qc
@@ -21,7 +21,9 @@ TRIGGER_SHAKE_VIEWONLY Shakes the view, but player movement is not affected
class trigger_shake: base_trigger
{
//--------------------------------------------------------------
- virtual void() shake_think =
+ // was shake_think
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_think =
{
if (this.attack_finished < time)
{
@@ -79,7 +81,7 @@ class trigger_shake: base_trigger
};

//--------------------------------------------------------------
- virtual void() shake_use =
+ virtual void(entity caller) do_use =
{
// already active
if (this.attack_finished > time)
@@ -94,17 +96,8 @@ class trigger_shake: base_trigger
};

//--------------------------------------------------------------
- void() trigger_shake =
+ virtual void() init_spawned =
{
- // 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");

@@ -121,6 +114,13 @@ class trigger_shake: base_trigger
this.wait = 1.0;

setorigin (this, this.origin);
+ // this.interaction_flags &= ~DISABLE_THINK;
this.nextthink = -1;
};
+
+ //--------------------------------------------------------------
+ void() trigger_shake =
+ {
+ this.classtype = CT_TRIGGER_SHAKE;
+ };
};

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 e8bc499..9dfda6a 100644
--- a/qc/triggers/take_weapon.qc
+++ b/qc/triggers/take_weapon.qc
@@ -17,21 +17,21 @@ class trigger_take_weapon: base_multiple
// trigger_take_weapon_use
// thanks to ShanJaq and Spike for their help on this.
//--------------------------------------------------------------
- virtual void() take_weapon =
+ virtual void(entity toucher) do_touch =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(toucher) == FALSE)
return;

- if (!(other.flags & FL_CLIENT))
+ if (!(toucher.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)
+ toucher.items &= ~IT_SHOTGUN;
+ toucher.currentammo = !toucher.ammo_shells;
+ toucher.ammo_shells = !toucher.ammo_shells;
+ toucher.items = toucher.items - (toucher.items & IT_SHELLS);
+ if (toucher.classtype == CT_PLAYER)
{
PlayerSetCurrentAmmo ();
PlayerBestWeapon ();
@@ -39,17 +39,16 @@ class trigger_take_weapon: base_multiple
};

//--------------------------------------------------------------
- void() trigger_take_weapon =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
this.wait = -1;
this.multi_init ();
- this.classname = "trigger_take_weapon";
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() 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 3599d80..043c659 100644
--- a/qc/triggers/teleport.qc
+++ b/qc/triggers/teleport.qc
@@ -138,7 +138,7 @@ void(vector org, entity death_owner) spawn_tdeath =
setorigin (death, org);
death.touch = spawn_tdeath_touch;
death.nextthink = time + 0.2;
- death.think = SUB_Remove;
+ death.think = sub_remove;
death.owner = death_owner;

// make sure even still objects get hit
@@ -209,7 +209,7 @@ class trigger_teleport: base_trigger
// end dumptruck_ds

//--------------------------------------------------------------
- virtual void() teleport_touch =
+ virtual void(entity toucher) do_touch =
{
local entity t;
local vector org;
@@ -223,16 +223,16 @@ class trigger_teleport: base_trigger
return;

if (this.spawnflags & TRIGGER_TELEPORT_ONLYPLAYER)
- if (other.classtype != CT_PLAYER)
+ if (toucher.classtype != CT_PLAYER)
return;

// is this going to work? dumptruck_ds
if (this.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER)
- if (other.classtype == CT_PLAYER)
+ if (toucher.classtype == CT_PLAYER)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
return;

// Supa, is this trigger waiting to be activated?
@@ -247,15 +247,15 @@ class trigger_teleport: base_trigger
return;

// only teleport living creatures
- if (other.health <= 0 || other.solid != SOLID_SLIDEBOX)
+ if (toucher.health <= 0 || toucher.solid != SOLID_SLIDEBOX)
return;

- SUB_UseTargets ();
+ sub_usetargets ();

// 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);
+ spawn_tfog (toucher.origin);

// dhm - if this is a random teleporter, pick a random spot!
if (this.spawnflags & TRIGGER_TELEPORT_RANDOM)
@@ -263,7 +263,7 @@ class trigger_teleport: base_trigger
t = randomspot ();
}
else if ((this.spawnflags & TRIGGER_TELEPORT_DD) &&
- other.classtype == CT_PLAYER)
+ toucher.classtype == CT_PLAYER)
{
t = find (world, ::targetname, this.noise);
}
@@ -277,7 +277,7 @@ class trigger_teleport: base_trigger

// put a tfog where the player was
/*
- spawn_tfog (other.origin);
+ spawn_tfog (toucher.origin);

t = find (world, ::targetname, this.target);
if (!t)
@@ -292,70 +292,60 @@ class trigger_teleport: base_trigger
if (!(this.spawnflags & TRIGGER_TELEPORT_STEALTH))
spawn_tfog (org);

- spawn_tdeath (t.origin, other);
+ spawn_tdeath (t.origin, toucher);

// move the player and lock him down for a little while
- if (!other.health)
+ if (!toucher.health)
{
- other.origin = t.origin;
- other.velocity = (v_forward * other.velocity_x) +
- (v_forward * other.velocity_y);
+ toucher.origin = t.origin;
+ toucher.velocity = (v_forward * toucher.velocity_x) +
+ (v_forward * toucher.velocity_y);
return;
}

- setorigin (other, t.origin);
- other.angles = t.mangle;
+ setorigin (toucher, t.origin);
+ toucher.angles = t.mangle;

- if (other.classtype == CT_PLAYER)
+ if (toucher.classtype == CT_PLAYER)
{
// retrieves fog values from teleport destination,
// if any
- fog_setFromEnt (other, t);
+ fog_setFromEnt (toucher, t);

// turn this way immediately
- other.fixangle = 1;
- other.teleport_time = time + 0.7;
+ toucher.fixangle = 1;
+ toucher.teleport_time = time + 0.7;
// push player out at PM_TELEEXITSPEED -- CEV
- other.velocity = v_forward * PM_TELEEXITSPEED;
+ toucher.velocity = v_forward * PM_TELEEXITSPEED;
// TODO CEV commented out the next line
- //other.flags = other.flags - other.flags & FL_ONGROUND;
+ // toucher.flags -= toucher.flags & FL_ONGROUND;
}

if ((this.spawnflags & TRIGGER_TELEPORT_ONLYMONSTER) &&
- other.classtype != CT_PLAYER)
+ toucher.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;
+ toucher.fixangle = 1;
+ toucher.teleport_time = time + 0.7;
+ if (toucher.flags & FL_ONGROUND)
+ toucher.flags = toucher.flags - FL_ONGROUND;
+ toucher.velocity = v_forward * PM_TELEEXITSPEED;
+ toucher.flags -= toucher.flags & FL_ONGROUND;
}
};

//--------------------------------------------------------------
- virtual void() teleport_use =
+ virtual void(entity caller) do_use =
{
this.nextthink = time + 0.2;
// make sure even still objects get hit
force_retouch = 2;
- this.think = SUB_Null;
+ this.interaction_flags |= DISABLE_THINK;
};

//--------------------------------------------------------------
- void() trigger_teleport =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
-
- local vector o;
-
- this.classname = "trigger_teleport";
- this.classtype = CT_TRIGGER_TELEPORT;
- this.touch = this.teleport_touch;
- this.use = this.teleport_use;
init_trigger ();

// find the destination
@@ -364,11 +354,18 @@ class trigger_teleport: base_trigger

if (!(this.spawnflags & TRIGGER_TELEPORT_SILENT))
{
+ local vector o;
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 ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_teleport =
+ {
+ this.classtype = CT_TRIGGER_TELEPORT;
};
};

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 e1d4183..11dbd90 100644
--- a/qc/triggers/textstory.qc
+++ b/qc/triggers/textstory.qc
@@ -6,15 +6,25 @@
const float TEXTSTORY_SILENT = 1;
const float TEXTSTORY_NOFADE = 2;

+enum
+{
+ TEXTSTORY_THINK_HIDE,
+ TEXTSTORY_THINK_SHOW,
+ TEXTSTORY_THINK_HELPERHIDE,
+ TEXTSTORY_THINK_HELPERSHOW
+};
+
//------------------------------------------------------------------------------
// base textstory class
//------------------------------------------------------------------------------
class base_textstory: base_trigger
{
+ float think_state;
+
//--------------------------------------------------------------
// hide a textstory
//--------------------------------------------------------------
- virtual void(entity controller) hide =
+ nonvirtual void(entity controller) text_hide =
{
if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
return;
@@ -33,7 +43,7 @@ class base_textstory: base_trigger
//--------------------------------------------------------------
// show a textstory
//--------------------------------------------------------------
- virtual void(entity controller) show =
+ nonvirtual void(entity controller) text_show =
{
if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
return;
@@ -74,9 +84,9 @@ class trigger_textstory: base_textstory
//--------------------------------------------------------------
// hide text
//--------------------------------------------------------------
- virtual void() text_hide =
+ nonvirtual void() story_hide =
{
- super::hide (this);
+ text_hide (this);

this.enemy = world;
this.state = 0;
@@ -85,27 +95,36 @@ class trigger_textstory: base_textstory
//--------------------------------------------------------------
// show text
//--------------------------------------------------------------
- virtual void() text_show =
+ nonvirtual void() story_show =
{
- super::show (this);
+ text_show (this);

- this.think = this.text_hide;
+ this.think_state = TEXTSTORY_THINK_HIDE;
this.nextthink = time + 0.2;
};

//--------------------------------------------------------------
- virtual void() story_touch =
+ virtual void(entity caller) do_think =
{
- if (!(other.flags & FL_CLIENT))
+ if (this.think_state == TEXTSTORY_THINK_HIDE)
+ this.story_hide ();
+ else if (this.think_state == TEXTSTORY_THINK_SHOW)
+ this.story_show ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity toucher) do_touch =
+ {
+ if (!(toucher.flags & FL_CLIENT))
return;
if (this.estate != STATE_ACTIVE)
return;

// don't show message if another player is already triggering it
- if (other != this.enemy && this.state == 1)
+ if (toucher != this.enemy && this.state == 1)
return;

- if (this.mangle && !isInAngle (other.v_angle, this.mangle,
+ if (this.mangle && !isInAngle (toucher.v_angle, this.mangle,
this.view_ofs))
{
return;
@@ -114,18 +133,15 @@ class trigger_textstory: base_textstory
if (this.attack_finished < time)
{
this.attack_finished = time + 0.1;
- this.enemy = other;
+ this.enemy = toucher;

- this.text_show ();
+ this.story_show ();
}
};

//--------------------------------------------------------------
- void() trigger_textstory =
+ virtual void() init_spawned =
{
- this.classname = "trigger_textstory";
- this.classtype = CT_TRIGGER_TEXTSTORY;
- this.touch = this.story_touch;
init_trigger ();

if (this.view_ofs == '0 0 0')
@@ -152,7 +168,13 @@ class trigger_textstory: base_textstory
if (this.noise2 != "")
precache_sound (this.noise2);

- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_textstory =
+ {
+ this.classtype = CT_TRIGGER_TEXTSTORY;
};
};

@@ -164,16 +186,16 @@ class target_textstory_helper: base_textstory
//--------------------------------------------------------------
// hide text
//--------------------------------------------------------------
- virtual void() helper_text_hide =
+ nonvirtual void() helper_story_hide =
{
- this.hide (this.owner);
+ this.text_hide (this.owner);
remove (this);
};

//--------------------------------------------------------------
// show text
//--------------------------------------------------------------
- virtual void() helper_text_show =
+ nonvirtual void() helper_story_show =
{
if (!this.enemy || !(this.enemy.flags & FL_CLIENT))
{
@@ -181,20 +203,33 @@ class target_textstory_helper: base_textstory
return;
}

- this.show (this.owner);
+ this.text_show (this.owner);

if (this.attack_finished < time)
- this.think = this.helper_text_hide;
+ this.think_state = TEXTSTORY_THINK_HELPERHIDE;

this.nextthink = time + 0.1;
};

//--------------------------------------------------------------
+ virtual void(entity caller) do_think =
+ {
+ if (this.think_state == TEXTSTORY_THINK_HELPERHIDE)
+ this.helper_story_hide ();
+ else if (this.think_state == TEXTSTORY_THINK_HELPERSHOW)
+ this.helper_story_show ();
+ };
+
+ //--------------------------------------------------------------
+ virtual void() init_spawned =
+ {
+ this.think_state = TEXTSTORY_THINK_HELPERSHOW;
+ };
+
+ //--------------------------------------------------------------
void() target_textstory_helper =
{
- this.classname = "target_textstory_helper";
this.classtype = CT_TARGET_TEXTSTORY_HELPER;
- this.think = this.helper_text_show;
};
};

@@ -206,7 +241,7 @@ class target_textstory: base_textstory
//--------------------------------------------------------------
// create the hidden object that'll show the actual message
//--------------------------------------------------------------
- virtual void(entity tgt) spawn_helper =
+ nonvirtual void(entity tgt) spawn_helper =
{
target_textstory_helper helper;
helper = spawn (target_textstory_helper,
@@ -217,7 +252,7 @@ class target_textstory: base_textstory
};

//--------------------------------------------------------------
- virtual void() story_use =
+ virtual void(entity caller) do_use =
{
if (!(activator.flags & FL_CLIENT))
return;
@@ -242,12 +277,8 @@ class target_textstory: base_textstory
};

//--------------------------------------------------------------
- void() target_textstory =
+ virtual void() init_spawned =
{
- this.classname = "target_textstory";
- this.classtype = CT_TARGET_TEXTSTORY;
- this.use = this.story_use;
-
if (this.noise1 == "")
this.noise1 = "misc/talk.wav";

@@ -267,4 +298,10 @@ class target_textstory: base_textstory
if (!this.wait)
this.wait = 5;
};
+
+ //--------------------------------------------------------------
+ void() target_textstory =
+ {
+ this.classtype = CT_TARGET_TEXTSTORY;
+ };
};

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 33696e9..510951c 100644
--- a/qc/triggers/usekey.qc
+++ b/qc/triggers/usekey.qc
@@ -32,6 +32,8 @@ targets. Must be targeted at one or more entities.
*/
class trigger_usekey: base_trigger
{
+ // class fields
+ float is_removed;

//--------------------------------------------------------------
// trigger_usekey_unlock
@@ -43,49 +45,51 @@ class trigger_usekey: base_trigger
// to the new keylock_try_to_unlock function. This code was
// previously part of the trigger_usekey_use function. -- iw
//--------------------------------------------------------------
- virtual void() unlock =
+ nonvirtual 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 ();
+ sub_usetargets ();
+
+ this.interaction_flags |= DISABLE_TOUCH;
+ this.interaction_flags |= DISABLE_USE;
+ this.is_removed = TRUE;
+ this.nextthink = time + 0.1;
};

//--------------------------------------------------------------
- virtual void() usekey_use =
+ virtual void(entity caller) do_think =
+ {
+ if (this.is_removed == TRUE)
+ remove (this);
+ };
+
+ //--------------------------------------------------------------
+ virtual void(entity caller) do_use =
{
// from Copper -- dumptruck_ds
- if (!CheckValidTouch())
+ if (sub_checkvalidtouch(caller) == FALSE)
return;

if (this.attack_finished > time)
return;

this.attack_finished = time + 2;
- keylock_try_to_unlock (activator, this.message,
- this.unlock);
+ keylock_try_to_unlock (caller, this.message, this.unlock);
};

//--------------------------------------------------------------
- virtual void() usekey_touch =
+ virtual void(entity toucher) do_touch =
{
- activator = other;
- this.usekey_use ();
+ this.do_use (toucher);
};

//--------------------------------------------------------------
- void() trigger_usekey =
+ virtual void() init_spawned =
{
- // 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
@@ -131,17 +135,20 @@ class trigger_usekey: base_trigger
this.keyname = "";
}

- if (!keylock_has_key_set())
+ if (!keylock_has_key_set(this))
{
objerror ("no key specified!");
return;
}

- this.classname = "trigger_usekey";
- this.classtype = CT_TRIGGER_USEKEY;
- this.touch = this.usekey_touch;
- this.use = this.usekey_use;
+ this.is_removed = FALSE;
init_trigger ();
- SUB_CheckWaiting ();
+ sub_checkwaiting ();
+ };
+
+ //--------------------------------------------------------------
+ void() trigger_usekey =
+ {
+ this.classtype = CT_TRIGGER_USEKEY;
};
};

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 118b47f..3a356eb 100644
--- a/qc/triggers/void.qc
+++ b/qc/triggers/void.qc
@@ -21,65 +21,64 @@ Removes monsters, gibs, ammo, etc... also kills player.
class trigger_void: base_trigger
{
//--------------------------------------------------------------
- virtual void() void_touch =
+ virtual void(entity toucher) do_touch =
{
if (this.estate != STATE_ACTIVE)
return;

// from Copper -- dumptruck_ds
- if (other.movetype == MOVETYPE_NOCLIP)
+ if (toucher.movetype == MOVETYPE_NOCLIP)
return FALSE;

if (this.spawnflags & TRIGGER_VOID_MONSTER_SAFE &&
- other.flags & FL_MONSTER)
+ toucher.flags & FL_MONSTER)
{
// ignore monsters
return;
}

if (this.spawnflags & TRIGGER_VOID_PLAYER_SAFE &&
- other.flags & FL_CLIENT)
+ toucher.flags & FL_CLIENT)
{
// ignore players
return;
}

- if (other.takedamage)
+ if (toucher.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);
+ toucher.invincible_finished = 0;
+ T_Damage (toucher, this, this, toucher.health + 1000);

- if (other.flags & FL_MONSTER)
- remove (other);
+ if (toucher.flags & FL_MONSTER)
+ remove (toucher);
}

- if (other.classname == "gib" ||
- other.classname == "grenade" ||
- other.classname == "spike" ||
- other.classname == "missile")
+ if (toucher.classname == "gib" ||
+ toucher.classname == "grenade" ||
+ toucher.classname == "spike" ||
+ toucher.classname == "missile")
{
- remove (other);
+ remove (toucher);
}

- if (other.flags & FL_ITEM)
- remove (other);
+ if (toucher.flags & FL_ITEM)
+ remove (toucher);

force_retouch = 2;
};

//--------------------------------------------------------------
- void() trigger_void =
+ virtual void() init_spawned =
{
- // new spawnflags for all entities -- iw
- if (SUB_Inhibit())
- return;
+ init_trigger ();
+ sub_checkwaiting ();
+ };

- this.classname = "trigger_void";
+ //--------------------------------------------------------------
+ void() 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 071b761..eb0c8cd 100644
--- a/qc/weapons.qc
+++ b/qc/weapons.qc
@@ -54,7 +54,7 @@ void(vector org, vector vel) SpawnMeatSpray =

// set missile duration
missile.nextthink = time + 1;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;

setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
@@ -243,13 +243,13 @@ 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_explode6 = [5, sub_remove] { };

void() BecomeExplosion =
{
self.movetype = MOVETYPE_NONE;
self.velocity = '0 0 0';
- self.touch = SUB_Null;
+ self.touch = sub_null;
setmodel (self, "progs/s_explod.spr");
self.solid = SOLID_NOT;
s_explode1 ();
@@ -385,7 +385,7 @@ void() W_FireRocket =

// set missile duration
missile.nextthink = time + 5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;

setmodel (missile, "progs/missile.mdl");
setsize (missile, '0 0 0', '0 0 0');
@@ -433,7 +433,7 @@ void() W_GruntRocket =
}
else {
missile.nextthink = time + 5;
- missile.think = SUB_Remove;
+ missile.think = sub_remove;
}
if (self.mdl_proj != "") // dumptruck_ds
{
@@ -758,7 +758,7 @@ void(vector org, vector dir, float speed) launch_spike2 = {
}
else
{
- newmis.think = SUB_Remove;
+ newmis.think = sub_remove;
newmis.nextthink = time + 6;
}
setmodel (newmis, "progs/spike.mdl");

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 7160f97..a7e9dd9 100644
--- a/qc/world.qc
+++ b/qc/world.qc
@@ -756,3 +756,22 @@ void(entity ent) CopyToBodyQue =
setsize (bodyque_head, ent.mins, ent.maxs);
bodyque_head = bodyque_head.owner;
};
+
+// TODO CEV based on code from Nuclide SDK
+/*
+void(void() spawnfunc) CheckSpawn =
+{
+ if (spawnfunc)
+ {
+ // dprint (sprintf("CheckSpawn: creating %s\n",
+ // self.classname));
+ spawnfunc ();
+ }
+ else
+ {
+ // print (sprintf("CheckSpawn: cannot find entity class %s\n",
+ // self.classname));
+ remove (self);
+ }
+};
+*/

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