aboutsummaryrefslogtreecommitdiffstats
path: root/qw-qc/subs.qc
diff options
context:
space:
mode:
authorTravis Bradshaw <travis.bradshaw@idsoftware.com>2012-01-31 16:03:17 -0600
committerTravis Bradshaw <travis.bradshaw@idsoftware.com>2012-01-31 16:03:17 -0600
commitbf4ac424ce754894ac8f1dae6a3981954bc9852d (patch)
treeff4a31bc2a3ae18eb8fa5bbca9a9bab90f0d11ab /qw-qc/subs.qc
parent0023db327bc1db00068284b70e1db45857aeee35 (diff)
downloadquake-pum-bf4ac424ce754894ac8f1dae6a3981954bc9852d.tar.gz
Just kind of shoving the QuakeWorld QuakeC source in here.
Diffstat (limited to 'qw-qc/subs.qc')
-rw-r--r--qw-qc/subs.qc310
1 files changed, 310 insertions, 0 deletions
diff --git a/qw-qc/subs.qc b/qw-qc/subs.qc
new file mode 100644
index 0000000..43e4f76
--- /dev/null
+++ b/qw-qc/subs.qc
@@ -0,0 +1,310 @@
+/*
+ subs.qc
+
+ sub-functions, mostly movement related
+
+ Copyright (C) 1996-1997 Id Software, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to:
+
+ Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330
+ Boston, MA 02111-1307, USA
+
+*/
+
+
+void() SUB_Null = {};
+
+void() SUB_Remove = {remove(self);};
+
+
+/*
+QuakeEd only writes a single float for angles (bad idea), so up and down are
+just constant angles.
+*/
+vector() 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';
+};
+
+/*
+================
+InitTrigger
+================
+*/
+void() InitTrigger =
+{
+// trigger angles are used for one-way touches. An angle of 0 is assumed
+// to mean no restrictions, so use a yaw of 360 instead.
+ if (self.angles != '0 0 0')
+ SetMovedir ();
+ self.solid = SOLID_TRIGGER;
+ setmodel (self, self.model); // set size and link into world
+ self.movetype = MOVETYPE_NONE;
+ self.modelindex = 0;
+ self.model = "";
+};
+
+/*
+=============
+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;
+ 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;
+
+ if (!tspeed)
+ objerror("No speed is defined!");
+
+ self.think1 = func;
+ self.finaldest = tdest;
+ self.think = SUB_CalcMoveDone;
+
+ if (tdest == self.origin)
+ {
+ self.velocity = '0 0 0';
+ self.nextthink = self.ltime + 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.03)
+ traveltime = 0.03;
+
+// 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.velocity = vdestdelta * (1/traveltime); // qcc won't take vec/float
+};
+
+/*
+============
+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;
+};
+
+/*
+============
+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();
+};
+
+
+//=============================================================================
+
+void() DelayThink =
+{
+ activator = self.enemy;
+ SUB_UseTargets ();
+ remove(self);
+};
+
+/*
+==============================
+SUB_UseTargets
+
+the global "activator" should be set to the entity that initiated the firing.
+
+If self.delay is set, a DelayedUse entity will be created that will actually
+do the SUB_UseTargets after that many seconds have passed.
+
+Centerprints any self.message to the activator.
+
+Removes all entities with a targetname that match self.killtarget,
+and removes them, so some events can remove other triggers.
+
+Search for (string)targetname in all entities that
+match (string)self.target and call their .use function
+
+==============================
+*/
+void() SUB_UseTargets =
+{
+ local entity t, stemp, otemp, act;
+
+//
+// check for a delay
+//
+ if (self.delay)
+ {
+ // create a temp object to fire at a later time
+ t = spawn();
+ t.classname = "DelayedUse";
+ t.nextthink = time + self.delay;
+ t.think = DelayThink;
+ t.enemy = activator;
+ t.message = self.message;
+ t.killtarget = self.killtarget;
+ t.target = self.target;
+ return;
+ }
+
+
+//
+// print the message
+//
+ if (activator.classname == "player" && self.message != "")
+ {
+ centerprint (activator, self.message);
+ if (!self.noise)
+ sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
+ }
+
+//
+// kill the killtagets
+//
+ if (self.killtarget)
+ {
+ t = world;
+ do
+ {
+ t = find (t, targetname, self.killtarget);
+ if (!t)
+ return;
+ remove (t);
+ } while ( 1 );
+ }
+
+//
+// fire targets
+//
+ if (self.target)
+ {
+ act = activator;
+ t = world;
+ do
+ {
+ t = find (t, targetname, self.target);
+ if (!t)
+ {
+ return;
+ }
+ stemp = self;
+ otemp = other;
+ self = t;
+ other = stemp;
+ if (self.use != SUB_Null)
+ {
+ if (self.use)
+ self.use ();
+ }
+ self = stemp;
+ other = otemp;
+ activator = act;
+ } while ( 1 );
+ }
+
+
+};
+