Home | History | Annotate | Download | only in progs
      1 
      2 
      3 void() SUB_Null = {};
      4 
      5 void() SUB_Remove = {remove(self);};
      6 
      7 
      8 /*
      9 QuakeEd only writes a single float for angles (bad idea), so up and down are
     10 just constant angles.
     11 */
     12 vector() SetMovedir =
     13 {
     14 	if (self.angles == '0 -1 0')
     15 		self.movedir = '0 0 1';
     16 	else if (self.angles == '0 -2 0')
     17 		self.movedir = '0 0 -1';
     18 	else
     19 	{
     20 		makevectors (self.angles);
     21 		self.movedir = v_forward;
     22 	}
     23 	
     24 	self.angles = '0 0 0';
     25 };
     26 
     27 /*
     28 ================
     29 InitTrigger
     30 ================
     31 */
     32 void() InitTrigger =
     33 {
     34 // trigger angles are used for one-way touches.  An angle of 0 is assumed
     35 // to mean no restrictions, so use a yaw of 360 instead.
     36 	if (self.angles != '0 0 0')
     37 		SetMovedir ();
     38 	self.solid = SOLID_TRIGGER;
     39 	setmodel (self, self.model);	// set size and link into world
     40 	self.movetype = MOVETYPE_NONE;
     41 	self.modelindex = 0;
     42 	self.model = "";
     43 };
     44 
     45 /*
     46 =============
     47 SUB_CalcMove
     48 
     49 calculate self.velocity and self.nextthink to reach dest from
     50 self.origin traveling at speed
     51 ===============
     52 */
     53 void(entity ent, vector tdest, float tspeed, void() func) SUB_CalcMoveEnt =
     54 {
     55 local entity	stemp;
     56 	stemp = self;
     57 	self = ent;
     58 
     59 	SUB_CalcMove (tdest, tspeed, func);
     60 	self = stemp;
     61 };
     62 
     63 void(vector tdest, float tspeed, void() func) SUB_CalcMove =
     64 {
     65 local vector	vdestdelta;
     66 local float		len, traveltime;
     67 
     68 	if (!tspeed)
     69 		objerror("No speed is defined!");
     70 
     71 	self.think1 = func;
     72 	self.finaldest = tdest;
     73 	self.think = SUB_CalcMoveDone;
     74 
     75 	if (tdest == self.origin)
     76 	{
     77 		self.velocity = '0 0 0';
     78 		self.nextthink = self.ltime + 0.1;
     79 		return;
     80 	}
     81 		
     82 // set destdelta to the vector needed to move
     83 	vdestdelta = tdest - self.origin;
     84 	
     85 // calculate length of vector
     86 	len = vlen (vdestdelta);
     87 	
     88 // divide by speed to get time to reach dest
     89 	traveltime = len / tspeed;
     90 
     91 	if (traveltime < 0.03)
     92 		traveltime = 0.03;
     93 	
     94 // set nextthink to trigger a think when dest is reached
     95 	self.nextthink = self.ltime + traveltime;
     96 
     97 // scale the destdelta vector by the time spent traveling to get velocity
     98 	self.velocity = vdestdelta * (1/traveltime);	// qcc won't take vec/float	
     99 };
    100 
    101 /*
    102 ============
    103 After moving, set origin to exact final destination
    104 ============
    105 */
    106 void()  SUB_CalcMoveDone =
    107 {
    108 	setorigin(self, self.finaldest);
    109 	self.velocity = '0 0 0';
    110 	self.nextthink = -1;
    111 	if (self.think1)
    112 		self.think1();
    113 };
    114 
    115 
    116 /*
    117 =============
    118 SUB_CalcAngleMove
    119 
    120 calculate self.avelocity and self.nextthink to reach destangle from
    121 self.angles rotating 
    122 
    123 The calling function should make sure self.think is valid
    124 ===============
    125 */
    126 void(entity ent, vector destangle, float tspeed, void() func) SUB_CalcAngleMoveEnt =
    127 {
    128 local entity		stemp;
    129 	stemp = self;
    130 	self = ent;
    131 	SUB_CalcAngleMove (destangle, tspeed, func);
    132 	self = stemp;
    133 };
    134 
    135 void(vector destangle, float tspeed, void() func) SUB_CalcAngleMove =
    136 {
    137 local vector	destdelta;
    138 local float		len, traveltime;
    139 
    140 	if (!tspeed)
    141 		objerror("No speed is defined!");
    142 		
    143 // set destdelta to the vector needed to move
    144 	destdelta = destangle - self.angles;
    145 	
    146 // calculate length of vector
    147 	len = vlen (destdelta);
    148 	
    149 // divide by speed to get time to reach dest
    150 	traveltime = len / tspeed;
    151 
    152 // set nextthink to trigger a think when dest is reached
    153 	self.nextthink = self.ltime + traveltime;
    154 
    155 // scale the destdelta vector by the time spent traveling to get velocity
    156 	self.avelocity = destdelta * (1 / traveltime);
    157 	
    158 	self.think1 = func;
    159 	self.finalangle = destangle;
    160 	self.think = SUB_CalcAngleMoveDone;
    161 };
    162 
    163 /*
    164 ============
    165 After rotating, set angle to exact final angle
    166 ============
    167 */
    168 void() SUB_CalcAngleMoveDone =
    169 {
    170 	self.angles = self.finalangle;
    171 	self.avelocity = '0 0 0';
    172 	self.nextthink = -1;
    173 	if (self.think1)
    174 		self.think1();
    175 };
    176 
    177 
    178 //=============================================================================
    179 
    180 void() DelayThink =
    181 {
    182 	activator = self.enemy;
    183 	SUB_UseTargets ();
    184 	remove(self);
    185 };
    186 
    187 /*
    188 ==============================
    189 SUB_UseTargets
    190 
    191 the global "activator" should be set to the entity that initiated the firing.
    192 
    193 If self.delay is set, a DelayedUse entity will be created that will actually
    194 do the SUB_UseTargets after that many seconds have passed.
    195 
    196 Centerprints any self.message to the activator.
    197 
    198 Removes all entities with a targetname that match self.killtarget,
    199 and removes them, so some events can remove other triggers.
    200 
    201 Search for (string)targetname in all entities that
    202 match (string)self.target and call their .use function
    203 
    204 ==============================
    205 */
    206 void() SUB_UseTargets =
    207 {
    208 	local entity t, stemp, otemp, act;
    209 
    210 //
    211 // check for a delay
    212 //
    213 	if (self.delay)
    214 	{
    215 	// create a temp object to fire at a later time
    216 		t = spawn();
    217 		t.classname = "DelayedUse";
    218 		t.nextthink = time + self.delay;
    219 		t.think = DelayThink;
    220 		t.enemy = activator;
    221 		t.message = self.message;
    222 		t.killtarget = self.killtarget;
    223 		t.target = self.target;
    224 		return;
    225 	}
    226 	
    227 	
    228 //
    229 // print the message
    230 //
    231 	if (activator.classname == "player" && self.message != "")
    232 	{
    233 		centerprint (activator, self.message);
    234 		if (!self.noise)
    235 			sound (activator, CHAN_VOICE, "misc/talk.wav", 1, ATTN_NORM);
    236 	}
    237 
    238 //
    239 // kill the killtagets
    240 //
    241 	if (self.killtarget)
    242 	{
    243 		t = world;
    244 		do
    245 		{
    246 			t = find (t, targetname, self.killtarget);
    247 			if (!t)
    248 				return;
    249 			remove (t);
    250 		} while ( 1 );
    251 	}
    252 	
    253 //
    254 // fire targets
    255 //
    256 	if (self.target)
    257 	{
    258 		act = activator;
    259 		t = world;
    260 		do
    261 		{
    262 			t = find (t, targetname, self.target);
    263 			if (!t)
    264 			{
    265 				return;
    266 			}
    267 			stemp = self;
    268 			otemp = other;
    269 			self = t;
    270 			other = stemp;
    271 			if (self.use != SUB_Null)
    272 			{
    273 				if (self.use)
    274 					self.use ();
    275 			}
    276 			self = stemp;
    277 			other = otemp;
    278 			activator = act;
    279 		} while ( 1 );
    280 	}
    281 	
    282 
    283 };
    284 
    285