1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 //====================================================================================
24 //
25 //rww - ICARUS callback file, all that can be handled within vm's is handled in here.
26 //
27 //====================================================================================
28 
29 #include "qcommon/q_shared.h"
30 #include "bg_public.h"
31 #include "b_local.h"
32 #include "icarus/Q3_Interface.h"
33 #include "icarus/Q3_Registers.h"
34 #include "g_nav.h"
35 
36 qboolean BG_SabersOff( playerState_t *ps );
37 extern stringID_table_t WPTable[];
38 extern stringID_table_t BSTable[];
39 
40 
41 //This is a hack I guess. It's because we can't include the file this enum is in
42 //unless we're using cpp. But we need it for the interpreter stuff.
43 //In any case, DO NOT modify this enum.
44 
45 // Hack++
46 // This code is compiled as C++ on Xbox. We could try and rig something above
47 // so that we only get the C version of the includes (no full Icarus) in that
48 // scenario, but I think we'll just try to leave this out instead.
49 //#if defined(__linux__) && defined(__GCC__) || !defined(__linux__)
50 enum
51 {
52 	TK_EOF = -1,
53 	TK_UNDEFINED,
54 	TK_COMMENT,
55 	TK_EOL,
56 	TK_CHAR,
57 	TK_STRING,
58 	TK_INT,
59 	TK_INTEGER = TK_INT,
60 	TK_FLOAT,
61 	TK_IDENTIFIER,
62 	TK_USERDEF,
63 };
64 //#endif
65 
66 #include "icarus/interpreter.h"
67 
68 extern stringID_table_t animTable [MAX_ANIMATIONS+1];
69 
70 stringID_table_t setTable[] =
71 {
72 	ENUM2STRING(SET_SPAWNSCRIPT),//0
73 	ENUM2STRING(SET_USESCRIPT),
74 	ENUM2STRING(SET_AWAKESCRIPT),
75 	ENUM2STRING(SET_ANGERSCRIPT),
76 	ENUM2STRING(SET_ATTACKSCRIPT),
77 	ENUM2STRING(SET_VICTORYSCRIPT),
78 	ENUM2STRING(SET_PAINSCRIPT),
79 	ENUM2STRING(SET_FLEESCRIPT),
80 	ENUM2STRING(SET_DEATHSCRIPT),
81 	ENUM2STRING(SET_DELAYEDSCRIPT),
82 	ENUM2STRING(SET_BLOCKEDSCRIPT),
83 	ENUM2STRING(SET_FFIRESCRIPT),
84 	ENUM2STRING(SET_FFDEATHSCRIPT),
85 	ENUM2STRING(SET_MINDTRICKSCRIPT),
86 	ENUM2STRING(SET_NO_MINDTRICK),
87 	ENUM2STRING(SET_ORIGIN),
88 	ENUM2STRING(SET_TELEPORT_DEST),
89 	ENUM2STRING(SET_ANGLES),
90 	ENUM2STRING(SET_XVELOCITY),
91 	ENUM2STRING(SET_YVELOCITY),
92 	ENUM2STRING(SET_ZVELOCITY),
93 	ENUM2STRING(SET_Z_OFFSET),
94 	ENUM2STRING(SET_ENEMY),
95 	ENUM2STRING(SET_LEADER),
96 	ENUM2STRING(SET_NAVGOAL),
97 	ENUM2STRING(SET_ANIM_UPPER),
98 	ENUM2STRING(SET_ANIM_LOWER),
99 	ENUM2STRING(SET_ANIM_BOTH),
100 	ENUM2STRING(SET_ANIM_HOLDTIME_LOWER),
101 	ENUM2STRING(SET_ANIM_HOLDTIME_UPPER),
102 	ENUM2STRING(SET_ANIM_HOLDTIME_BOTH),
103 	ENUM2STRING(SET_PLAYER_TEAM),
104 	ENUM2STRING(SET_ENEMY_TEAM),
105 	ENUM2STRING(SET_BEHAVIOR_STATE),
106 	ENUM2STRING(SET_BEHAVIOR_STATE),
107 	ENUM2STRING(SET_HEALTH),
108 	ENUM2STRING(SET_ARMOR),
109 	ENUM2STRING(SET_DEFAULT_BSTATE),
110 	ENUM2STRING(SET_CAPTURE),
111 	ENUM2STRING(SET_DPITCH),
112 	ENUM2STRING(SET_DYAW),
113 	ENUM2STRING(SET_EVENT),
114 	ENUM2STRING(SET_TEMP_BSTATE),
115 	ENUM2STRING(SET_COPY_ORIGIN),
116 	ENUM2STRING(SET_VIEWTARGET),
117 	ENUM2STRING(SET_WEAPON),
118 	ENUM2STRING(SET_ITEM),
119 	ENUM2STRING(SET_WALKSPEED),
120 	ENUM2STRING(SET_RUNSPEED),
121 	ENUM2STRING(SET_YAWSPEED),
122 	ENUM2STRING(SET_AGGRESSION),
123 	ENUM2STRING(SET_AIM),
124 	ENUM2STRING(SET_FRICTION),
125 	ENUM2STRING(SET_GRAVITY),
126 	ENUM2STRING(SET_IGNOREPAIN),
127 	ENUM2STRING(SET_IGNOREENEMIES),
128 	ENUM2STRING(SET_IGNOREALERTS),
129 	ENUM2STRING(SET_DONTSHOOT),
130 	ENUM2STRING(SET_DONTFIRE),
131 	ENUM2STRING(SET_LOCKED_ENEMY),
132 	ENUM2STRING(SET_NOTARGET),
133 	ENUM2STRING(SET_LEAN),
134 	ENUM2STRING(SET_CROUCHED),
135 	ENUM2STRING(SET_WALKING),
136 	ENUM2STRING(SET_RUNNING),
137 	ENUM2STRING(SET_CHASE_ENEMIES),
138 	ENUM2STRING(SET_LOOK_FOR_ENEMIES),
139 	ENUM2STRING(SET_FACE_MOVE_DIR),
140 	ENUM2STRING(SET_ALT_FIRE),
141 	ENUM2STRING(SET_DONT_FLEE),
142 	ENUM2STRING(SET_FORCED_MARCH),
143 	ENUM2STRING(SET_NO_RESPONSE),
144 	ENUM2STRING(SET_NO_COMBAT_TALK),
145 	ENUM2STRING(SET_NO_ALERT_TALK),
146 	ENUM2STRING(SET_UNDYING),
147 	ENUM2STRING(SET_TREASONED),
148 	ENUM2STRING(SET_DISABLE_SHADER_ANIM),
149 	ENUM2STRING(SET_SHADER_ANIM),
150 	ENUM2STRING(SET_INVINCIBLE),
151 	ENUM2STRING(SET_NOAVOID),
152 	ENUM2STRING(SET_SHOOTDIST),
153 	ENUM2STRING(SET_TARGETNAME),
154 	ENUM2STRING(SET_TARGET),
155 	ENUM2STRING(SET_TARGET2),
156 	ENUM2STRING(SET_LOCATION),
157 	ENUM2STRING(SET_PAINTARGET),
158 	ENUM2STRING(SET_TIMESCALE),
159 	ENUM2STRING(SET_VISRANGE),
160 	ENUM2STRING(SET_EARSHOT),
161 	ENUM2STRING(SET_VIGILANCE),
162 	ENUM2STRING(SET_HFOV),
163 	ENUM2STRING(SET_VFOV),
164 	ENUM2STRING(SET_DELAYSCRIPTTIME),
165 	ENUM2STRING(SET_FORWARDMOVE),
166 	ENUM2STRING(SET_RIGHTMOVE),
167 	ENUM2STRING(SET_LOCKYAW),
168 	ENUM2STRING(SET_SOLID),
169 	ENUM2STRING(SET_CAMERA_GROUP),
170 	ENUM2STRING(SET_CAMERA_GROUP_Z_OFS),
171 	ENUM2STRING(SET_CAMERA_GROUP_TAG),
172 	ENUM2STRING(SET_LOOK_TARGET),
173 	ENUM2STRING(SET_ADDRHANDBOLT_MODEL),
174 	ENUM2STRING(SET_REMOVERHANDBOLT_MODEL),
175 	ENUM2STRING(SET_ADDLHANDBOLT_MODEL),
176 	ENUM2STRING(SET_REMOVELHANDBOLT_MODEL),
177 	ENUM2STRING(SET_FACEAUX),
178 	ENUM2STRING(SET_FACEBLINK),
179 	ENUM2STRING(SET_FACEBLINKFROWN),
180 	ENUM2STRING(SET_FACEFROWN),
181 	ENUM2STRING(SET_FACENORMAL),
182 	ENUM2STRING(SET_FACEEYESCLOSED),
183 	ENUM2STRING(SET_FACEEYESOPENED),
184 	ENUM2STRING(SET_SCROLLTEXT),
185 	ENUM2STRING(SET_LCARSTEXT),
186 	ENUM2STRING(SET_SCROLLTEXTCOLOR),
187 	ENUM2STRING(SET_CAPTIONTEXTCOLOR),
188 	ENUM2STRING(SET_CENTERTEXTCOLOR),
189 	ENUM2STRING(SET_PLAYER_USABLE),
190 	ENUM2STRING(SET_STARTFRAME),
191 	ENUM2STRING(SET_ENDFRAME),
192 	ENUM2STRING(SET_ANIMFRAME),
193 	ENUM2STRING(SET_LOOP_ANIM),
194 	ENUM2STRING(SET_INTERFACE),
195 	ENUM2STRING(SET_SHIELDS),
196 	ENUM2STRING(SET_NO_KNOCKBACK),
197 	ENUM2STRING(SET_INVISIBLE),
198 	ENUM2STRING(SET_VAMPIRE),
199 	ENUM2STRING(SET_FORCE_INVINCIBLE),
200 	ENUM2STRING(SET_GREET_ALLIES),
201 	ENUM2STRING(SET_PLAYER_LOCKED),
202 	ENUM2STRING(SET_LOCK_PLAYER_WEAPONS),
203 	ENUM2STRING(SET_NO_IMPACT_DAMAGE),
204 	ENUM2STRING(SET_PARM1),
205 	ENUM2STRING(SET_PARM2),
206 	ENUM2STRING(SET_PARM3),
207 	ENUM2STRING(SET_PARM4),
208 	ENUM2STRING(SET_PARM5),
209 	ENUM2STRING(SET_PARM6),
210 	ENUM2STRING(SET_PARM7),
211 	ENUM2STRING(SET_PARM8),
212 	ENUM2STRING(SET_PARM9),
213 	ENUM2STRING(SET_PARM10),
214 	ENUM2STRING(SET_PARM11),
215 	ENUM2STRING(SET_PARM12),
216 	ENUM2STRING(SET_PARM13),
217 	ENUM2STRING(SET_PARM14),
218 	ENUM2STRING(SET_PARM15),
219 	ENUM2STRING(SET_PARM16),
220 	ENUM2STRING(SET_DEFEND_TARGET),
221 	ENUM2STRING(SET_WAIT),
222 	ENUM2STRING(SET_COUNT),
223 	ENUM2STRING(SET_SHOT_SPACING),
224 	ENUM2STRING(SET_VIDEO_PLAY),
225 	ENUM2STRING(SET_VIDEO_FADE_IN),
226 	ENUM2STRING(SET_VIDEO_FADE_OUT),
227 	ENUM2STRING(SET_REMOVE_TARGET),
228 	ENUM2STRING(SET_LOADGAME),
229 	ENUM2STRING(SET_MENU_SCREEN),
230 	ENUM2STRING(SET_OBJECTIVE_SHOW),
231 	ENUM2STRING(SET_OBJECTIVE_HIDE),
232 	ENUM2STRING(SET_OBJECTIVE_SUCCEEDED),
233 	ENUM2STRING(SET_OBJECTIVE_FAILED),
234 	ENUM2STRING(SET_MISSIONFAILED),
235 	ENUM2STRING(SET_TACTICAL_SHOW),
236 	ENUM2STRING(SET_TACTICAL_HIDE),
237 	ENUM2STRING(SET_FOLLOWDIST),
238 	ENUM2STRING(SET_SCALE),
239 	ENUM2STRING(SET_OBJECTIVE_CLEARALL),
240 	ENUM2STRING(SET_MISSIONSTATUSTEXT),
241 	ENUM2STRING(SET_WIDTH),
242 	ENUM2STRING(SET_CLOSINGCREDITS),
243 	ENUM2STRING(SET_SKILL),
244 	ENUM2STRING(SET_MISSIONSTATUSTIME),
245 	ENUM2STRING(SET_FULLNAME),
246 	ENUM2STRING(SET_FORCE_HEAL_LEVEL),
247 	ENUM2STRING(SET_FORCE_JUMP_LEVEL),
248 	ENUM2STRING(SET_FORCE_SPEED_LEVEL),
249 	ENUM2STRING(SET_FORCE_PUSH_LEVEL),
250 	ENUM2STRING(SET_FORCE_PULL_LEVEL),
251 	ENUM2STRING(SET_FORCE_MINDTRICK_LEVEL),
252 	ENUM2STRING(SET_FORCE_GRIP_LEVEL),
253 	ENUM2STRING(SET_FORCE_LIGHTNING_LEVEL),
254 	ENUM2STRING(SET_SABER_THROW),
255 	ENUM2STRING(SET_SABER_DEFENSE),
256 	ENUM2STRING(SET_SABER_OFFENSE),
257 	ENUM2STRING(SET_VIEWENTITY),
258 	ENUM2STRING(SET_WATCHTARGET),
259 	ENUM2STRING(SET_SABERACTIVE),
260 	ENUM2STRING(SET_ADJUST_AREA_PORTALS),
261 	ENUM2STRING(SET_DMG_BY_HEAVY_WEAP_ONLY),
262 	ENUM2STRING(SET_SHIELDED),
263 	ENUM2STRING(SET_NO_GROUPS),
264 	ENUM2STRING(SET_FIRE_WEAPON),
265 	ENUM2STRING(SET_INACTIVE),
266 	ENUM2STRING(SET_FUNC_USABLE_VISIBLE),
267 	ENUM2STRING(SET_MISSION_STATUS_SCREEN),
268 	ENUM2STRING(SET_END_SCREENDISSOLVE),
269 	ENUM2STRING(SET_LOOPSOUND),
270 	ENUM2STRING(SET_ICARUS_FREEZE),
271 	ENUM2STRING(SET_ICARUS_UNFREEZE),
272 	ENUM2STRING(SET_USE_CP_NEAREST),
273 	ENUM2STRING(SET_MORELIGHT),
274 	ENUM2STRING(SET_CINEMATIC_SKIPSCRIPT),
275 	ENUM2STRING(SET_NO_FORCE),
276 	ENUM2STRING(SET_NO_FALLTODEATH),
277 	ENUM2STRING(SET_DISMEMBERABLE),
278 	ENUM2STRING(SET_NO_ACROBATICS),
279 	ENUM2STRING(SET_MUSIC_STATE),
280 	ENUM2STRING(SET_USE_SUBTITLES),
281 	ENUM2STRING(SET_CLEAN_DAMAGING_ENTS),
282 	ENUM2STRING(SET_HUD),
283 
284 //FIXME: add BOTH_ attributes here too
285 	{"",	SET_},
286 };
287 
Q3_TaskIDClear(int * taskID)288 void Q3_TaskIDClear( int *taskID )
289 {
290 	*taskID = -1;
291 }
292 
G_DebugPrint(int printLevel,const char * format,...)293 void G_DebugPrint( int printLevel, const char *format, ... )
294 {
295 	va_list		argptr;
296 	char		text[1024] = {0};
297 
298 	//Don't print messages they don't want to see
299 	//if ( g_ICARUSDebug->integer < level )
300 	if (developer.integer != 2)
301 		return;
302 
303 	va_start( argptr, format );
304 	Q_vsnprintf(text, sizeof( text ), format, argptr );
305 	va_end( argptr );
306 
307 	//Add the color formatting
308 	switch ( printLevel )
309 	{
310 		case WL_ERROR:
311 			Com_Printf ( S_COLOR_RED"ERROR: %s", text );
312 			break;
313 
314 		case WL_WARNING:
315 			Com_Printf ( S_COLOR_YELLOW"WARNING: %s", text );
316 			break;
317 
318 		case WL_DEBUG:
319 			{
320 				int		entNum;
321 				char	*buffer;
322 
323 				entNum = atoi( text );
324 
325 				//if ( ( ICARUS_entFilter >= 0 ) && ( ICARUS_entFilter != entNum ) )
326 				//	return;
327 
328 				buffer = (char *) text;
329 				buffer += 5;
330 
331 				if ( ( entNum < 0 ) || ( entNum >= MAX_GENTITIES ) )
332 					entNum = 0;
333 
334 				Com_Printf ( S_COLOR_BLUE"DEBUG: %s(%d): %s\n", g_entities[entNum].script_targetname, entNum, buffer );
335 				break;
336 			}
337 		default:
338 		case WL_VERBOSE:
339 			Com_Printf ( S_COLOR_GREEN"INFO: %s", text );
340 			break;
341 	}
342 }
343 
344 /*
345 -------------------------
346 Q3_GetAnimLower
347 -------------------------
348 */
Q3_GetAnimLower(gentity_t * ent)349 static char *Q3_GetAnimLower( gentity_t *ent )
350 {
351 	int anim = 0;
352 
353 	if ( ent->client == NULL )
354 	{
355 		G_DebugPrint( WL_WARNING, "Q3_GetAnimLower: attempted to read animation state off non-client!\n" );
356 		return NULL;
357 	}
358 
359 	anim = ent->client->ps.legsAnim;
360 
361 	return (char *)animTable[anim].name;
362 }
363 
364 /*
365 -------------------------
366 Q3_GetAnimUpper
367 -------------------------
368 */
Q3_GetAnimUpper(gentity_t * ent)369 static char *Q3_GetAnimUpper( gentity_t *ent )
370 {
371 	int anim = 0;
372 
373 	if ( ent->client == NULL )
374 	{
375 		G_DebugPrint( WL_WARNING, "Q3_GetAnimUpper: attempted to read animation state off non-client!\n" );
376 		return NULL;
377 	}
378 
379 	anim = ent->client->ps.torsoAnim;
380 
381 	return (char *)animTable[anim].name;
382 }
383 
384 /*
385 -------------------------
386 Q3_GetAnimBoth
387 -------------------------
388 */
Q3_GetAnimBoth(gentity_t * ent)389 static char *Q3_GetAnimBoth( gentity_t *ent )
390 {
391  	char	*lowerName, *upperName;
392 
393 	lowerName = Q3_GetAnimLower( ent );
394 	upperName = Q3_GetAnimUpper( ent );
395 
396 	if ( !lowerName || !lowerName[0] )
397 	{
398 		G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: NULL legs animation string found!\n" );
399 		return NULL;
400 	}
401 
402 	if ( !upperName || !upperName[0] )
403 	{
404 		G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: NULL torso animation string found!\n" );
405 		return NULL;
406 	}
407 
408 	if ( Q_stricmp( lowerName, upperName ) )
409 	{
410 #ifdef _DEBUG	// sigh, cut down on tester reports that aren't important
411 		G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: legs and torso animations did not match : returning legs\n" );
412 #endif
413 	}
414 
415 	return lowerName;
416 }
417 
Q3_PlaySound(int taskID,int entID,const char * name,const char * channel)418 int Q3_PlaySound( int taskID, int entID, const char *name, const char *channel )
419 {
420 	gentity_t		*ent = &g_entities[entID];
421 	char			finalName[MAX_QPATH];
422 	soundChannel_t	voice_chan = CHAN_VOICE; // set a default so the compiler doesn't bitch
423 	qboolean		type_voice = qfalse;
424 	int				soundHandle;
425 	qboolean		bBroadcast;
426 
427 	Q_strncpyz( finalName, name, MAX_QPATH );
428 	Q_strupr(finalName);
429 	//G_AddSexToMunroString( finalName, qtrue );
430 
431 	COM_StripExtension( (const char *)finalName, finalName, sizeof( finalName ) );
432 
433 	soundHandle = G_SoundIndex( (char *) finalName );
434 	bBroadcast = qfalse;
435 
436 	if ( ( Q_stricmp( channel, "CHAN_ANNOUNCER" ) == 0 ) || (ent->classname && Q_stricmp("target_scriptrunner", ent->classname ) == 0) ) {
437 		bBroadcast = qtrue;
438 	}
439 
440 
441 	// moved here from further down so I can easily check channel-type without code dup...
442 	//
443 	if ( Q_stricmp( channel, "CHAN_VOICE" ) == 0 )
444 	{
445 		voice_chan = CHAN_VOICE;
446 		type_voice = qtrue;
447 	}
448 	else if ( Q_stricmp( channel, "CHAN_VOICE_ATTEN" ) == 0 )
449 	{
450 		voice_chan = CHAN_AUTO;//CHAN_VOICE_ATTEN;
451 		type_voice = qtrue;
452 	}
453 	else if ( Q_stricmp( channel, "CHAN_VOICE_GLOBAL" ) == 0 ) // this should broadcast to everyone, put only casue animation on G_SoundOnEnt...
454 	{
455 		voice_chan = CHAN_AUTO;//CHAN_VOICE_GLOBAL;
456 		type_voice = qtrue;
457 		bBroadcast = qtrue;
458 	}
459 
460 	// if we're in-camera, check for skipping cinematic and ifso, no subtitle print (since screen is not being
461 	//	updated anyway during skipping). This stops leftover subtitles being left onscreen after unskipping.
462 	//
463 	/*
464 	if (!in_camera ||
465 		(!g_skippingcin || !g_skippingcin->integer)
466 		)	// paranoia towards project end <g>
467 	{
468 		// Text on
469 		// certain NPC's we always want to use subtitles regardless of subtitle setting
470 		if (g_subtitles->integer == 1 || (ent->NPC && (ent->NPC->scriptFlags & SCF_USE_SUBTITLES) ) ) // Show all text
471 		{
472 			if ( in_camera)	// Cinematic
473 			{
474 				trap->SendServerCommand( -1, va("ct \"%s\" %i", finalName, soundHandle) );
475 			}
476 			else //if (precacheWav[i].speaker==SP_NONE)	//  lower screen text
477 			{
478 				sharedEntity_t		*ent2 = SV_GentityNum(0);
479 				// the numbers in here were either the original ones Bob entered (350), or one arrived at from checking the distance Chell stands at in stasis2 by the computer core that was submitted as a bug report...
480 				//
481 				if (bBroadcast || (DistanceSquared(ent->currentOrigin, ent2->currentOrigin) < ((voice_chan == CHAN_VOICE_ATTEN)?(350 * 350):(1200 * 1200)) ) )
482 				{
483 					trap->SendServerCommand( -1, va("ct \"%s\" %i", finalName, soundHandle) );
484 				}
485 			}
486 		}
487 		// Cinematic only
488 		else if (g_subtitles->integer == 2) // Show only talking head text and CINEMATIC
489 		{
490 			if ( in_camera)	// Cinematic text
491 			{
492 				trap->SendServerCommand( -1, va("ct \"%s\" %i", finalName, soundHandle));
493 			}
494 		}
495 
496 	}
497 	*/
498 
499 	if ( type_voice )
500 	{
501 		char buf[128];
502 		float tFVal = 0;
503 
504 		trap->Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
505 
506 		tFVal = atof(buf);
507 
508 
509 		if ( tFVal > 1.0f )
510 		{//Skip the damn sound!
511 			return qtrue;
512 		}
513 		else
514 		{
515 			//This the voice channel
516 			G_Sound( ent, voice_chan, G_SoundIndex((char *) finalName) );
517 		}
518 		//Remember we're waiting for this
519 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_CHAN_VOICE, taskID );
520 
521 		return qfalse;
522 	}
523 
524 	if ( bBroadcast )
525 	{//Broadcast the sound
526 		gentity_t	*te;
527 
528 		te = G_TempEntity( ent->r.currentOrigin, EV_GLOBAL_SOUND );
529 		te->s.eventParm = soundHandle;
530 		te->r.svFlags |= SVF_BROADCAST;
531 	}
532 	else
533 	{
534 		G_Sound( ent, CHAN_AUTO, soundHandle );
535 	}
536 
537 	return qtrue;
538 }
539 
540 /*
541 -------------------------
542 Q3_Play
543 -------------------------
544 */
Q3_Play(int taskID,int entID,const char * type,const char * name)545 void Q3_Play( int taskID, int entID, const char *type, const char *name )
546 {
547 	gentity_t *ent = &g_entities[entID];
548 
549 	if ( !Q_stricmp( type, "PLAY_ROFF" ) )
550 	{
551 		// Try to load the requested ROFF
552 		ent->roffid = trap->ROFF_Cache((char*)name);
553 		if ( ent->roffid )
554 		{
555 			ent->roffname = G_NewString( name );
556 
557 			// Start the roff from the beginning
558 			//ent->roff_ctr = 0;
559 
560 			//Save this off for later
561 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
562 
563 			// Let the ROFF playing start.
564 			//ent->next_roff_time = level.time;
565 
566 			//rww - Maybe use pos1 and pos2? I don't think we need to care if these values are sent across the net.
567 			// These need to be initialised up front...
568 			//VectorCopy( ent->r.currentOrigin, ent->pos1 );
569 			//VectorCopy( ent->r.currentAngles, ent->pos2 );
570 			VectorCopy( ent->r.currentOrigin, ent->s.origin2 );
571 			VectorCopy( ent->r.currentAngles, ent->s.angles2 );
572 
573 			trap->LinkEntity( (sharedEntity_t *)ent );
574 
575 			trap->ROFF_Play(ent->s.number, ent->roffid, qtrue);
576 		}
577 	}
578 }
579 
580 /*
581 =============
582 anglerCallback
583 
584 Utility function
585 =============
586 */
anglerCallback(gentity_t * ent)587 void anglerCallback( gentity_t *ent )
588 {
589 	//Complete the task
590 	trap->ICARUS_TaskIDComplete( (sharedEntity_t *)ent, TID_ANGLE_FACE );
591 
592 	//Set the currentAngles, clear all movement
593 	VectorMA( ent->s.apos.trBase, (ent->s.apos.trDuration*0.001f), ent->s.apos.trDelta, ent->r.currentAngles );
594 	VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
595 	VectorClear( ent->s.apos.trDelta );
596 	ent->s.apos.trDuration = 1;
597 	ent->s.apos.trType = TR_STATIONARY;
598 	ent->s.apos.trTime = level.time;
599 
600 	//Stop thinking
601 	ent->reached = 0;
602 	if ( ent->think == anglerCallback )
603 	{
604 		ent->think = 0;
605 	}
606 
607 	//link
608 	trap->LinkEntity( (sharedEntity_t *)ent );
609 }
610 
611 void MatchTeam( gentity_t *teamLeader, int moverState, int time );
612 void Blocked_Mover( gentity_t *ent, gentity_t *other );
613 
614 /*
615 =============
616 moverCallback
617 
618 Utility function
619 =============
620 */
moverCallback(gentity_t * ent)621 void moverCallback( gentity_t *ent )
622 {	//complete the task
623 	trap->ICARUS_TaskIDComplete( (sharedEntity_t *)ent, TID_MOVE_NAV );
624 
625 	// play sound
626 	ent->s.loopSound = 0;//stop looping sound
627 	ent->s.loopIsSoundset = qfalse;
628 	G_PlayDoorSound( ent, BMS_END );//play end sound
629 
630 	if ( ent->moverState == MOVER_1TO2 )
631 	{//reached open
632 		// reached pos2
633 		MatchTeam( ent, MOVER_POS2, level.time );
634 		//SetMoverState( ent, MOVER_POS2, level.time );
635 	}
636 	else if ( ent->moverState == MOVER_2TO1 )
637 	{//reached closed
638 		MatchTeam( ent, MOVER_POS1, level.time );
639 		//SetMoverState( ent, MOVER_POS1, level.time );
640 	}
641 
642 	if ( ent->blocked == Blocked_Mover )
643 	{
644 		ent->blocked = 0;
645 	}
646 
647 //	if ( !Q_stricmp( "misc_model_breakable", ent->classname ) && ent->physicsBounce )
648 //	{//a gravity-affected model
649 //		misc_model_breakable_gravity_init( ent, qfalse );
650 //	}
651 }
652 
Blocked_Mover(gentity_t * ent,gentity_t * other)653 void Blocked_Mover( gentity_t *ent, gentity_t *other )
654 {
655 	// remove anything other than a client -- no longer the case
656 
657 	// don't remove security keys or goodie keys
658 	if ( other->s.eType == ET_ITEM)
659 	{
660 		// should we be doing anything special if a key blocks it... move it somehow..?
661 	}
662 	// if your not a client, or your a dead client remove yourself...
663 	else if ( other->s.number && (!other->client || (other->client && other->health <= 0 && other->r.contents == CONTENTS_CORPSE && !other->message)) )
664 	{
665 		//if ( !other->taskManager || !other->taskManager->IsRunning() )
666 		{
667 			// if an item or weapon can we do a little explosion..?
668 			G_FreeEntity( other );
669 			return;
670 		}
671 	}
672 
673 	if ( ent->damage ) {
674 		G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
675 	}
676 }
677 
678 /*
679 =============
680 moveAndRotateCallback
681 
682 Utility function
683 =============
684 */
moveAndRotateCallback(gentity_t * ent)685 void moveAndRotateCallback( gentity_t *ent )
686 {
687 	//stop turning
688 	anglerCallback( ent );
689 	//stop moving
690 	moverCallback( ent );
691 }
692 
693 /*
694 =============
695 Q3_Lerp2Start
696 
697 Lerps the origin of an entity to its starting position
698 =============
699 */
Q3_Lerp2Start(int entID,int taskID,float duration)700 void Q3_Lerp2Start( int entID, int taskID, float duration )
701 {
702 	gentity_t	*ent = &g_entities[entID];
703 
704 	if(!ent)
705 	{
706 		G_DebugPrint( WL_WARNING, "Q3_Lerp2Start: invalid entID %d\n", entID);
707 		return;
708 	}
709 
710 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
711 	{
712 		G_DebugPrint( WL_ERROR, "Q3_Lerp2Start: ent %d is NOT a mover!\n", entID);
713 		return;
714 	}
715 
716 	if ( ent->s.eType != ET_MOVER )
717 	{
718 		ent->s.eType = ET_MOVER;
719 	}
720 
721 	//FIXME: set up correctly!!!
722 	ent->moverState = MOVER_2TO1;
723 	ent->s.eType = ET_MOVER;
724 	ent->reached = moverCallback;		//Callsback the the completion of the move
725 	if ( ent->damage )
726 	{
727 		ent->blocked = Blocked_Mover;
728 	}
729 
730 	ent->s.pos.trDuration = duration * 10;	//In seconds
731 	ent->s.pos.trTime = level.time;
732 
733 	trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
734 	// starting sound
735 	G_PlayDoorLoopSound( ent );
736 	G_PlayDoorSound( ent, BMS_START );	//??
737 
738 	trap->LinkEntity( (sharedEntity_t *)ent );
739 }
740 
741 /*
742 =============
743 Q3_Lerp2End
744 
745 Lerps the origin of an entity to its ending position
746 =============
747 */
Q3_Lerp2End(int entID,int taskID,float duration)748 void Q3_Lerp2End( int entID, int taskID, float duration )
749 {
750 	gentity_t	*ent = &g_entities[entID];
751 
752 	if(!ent)
753 	{
754 		G_DebugPrint( WL_WARNING, "Q3_Lerp2End: invalid entID %d\n", entID);
755 		return;
756 	}
757 
758 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
759 	{
760 		G_DebugPrint( WL_ERROR, "Q3_Lerp2End: ent %d is NOT a mover!\n", entID);
761 		return;
762 	}
763 
764 	if ( ent->s.eType != ET_MOVER )
765 	{
766 		ent->s.eType = ET_MOVER;
767 	}
768 
769 	//FIXME: set up correctly!!!
770 	ent->moverState = MOVER_1TO2;
771 	ent->s.eType = ET_MOVER;
772 	ent->reached = moverCallback;		//Callsback the the completion of the move
773 	if ( ent->damage )
774 	{
775 		ent->blocked = Blocked_Mover;
776 	}
777 
778 	ent->s.pos.trDuration = duration * 10;	//In seconds
779 	ent->s.time = level.time;
780 
781 	trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
782 	// starting sound
783 	G_PlayDoorLoopSound( ent );
784 	G_PlayDoorSound( ent, BMS_START );	//??
785 
786 	trap->LinkEntity( (sharedEntity_t *)ent );
787 }
788 
789 void InitMoverTrData( gentity_t *ent );
790 
791 /*
792 =============
793 Q3_Lerp2Pos
794 
795 Lerps the origin and angles of an entity to the destination values
796 
797 =============
798 */
Q3_Lerp2Pos(int taskID,int entID,vec3_t origin,vec3_t angles,float duration)799 void Q3_Lerp2Pos( int taskID, int entID, vec3_t origin, vec3_t angles, float duration )
800 {
801 	gentity_t	*ent = &g_entities[entID];
802 	vec3_t		ang;
803 	int			i;
804 	moverState_t moverState;
805 
806 	if(!ent)
807 	{
808 		G_DebugPrint( WL_WARNING, "Q3_Lerp2Pos: invalid entID %d\n", entID);
809 		return;
810 	}
811 
812 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
813 	{
814 		G_DebugPrint( WL_ERROR, "Q3_Lerp2Pos: ent %d is NOT a mover!\n", entID);
815 		return;
816 	}
817 
818 	if ( ent->s.eType != ET_MOVER )
819 	{
820 		ent->s.eType = ET_MOVER;
821 	}
822 
823 	//Don't allow a zero duration
824 	if ( duration == 0 )
825 		duration = 1;
826 
827 	//
828 	// Movement
829 
830 	moverState = ent->moverState;
831 
832 	if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
833 	{
834 		VectorCopy( ent->r.currentOrigin, ent->pos1 );
835 		VectorCopy( origin, ent->pos2 );
836 
837 		moverState = MOVER_1TO2;
838 	}
839 	else
840 	{
841 		VectorCopy( ent->r.currentOrigin, ent->pos2 );
842 		VectorCopy( origin, ent->pos1 );
843 
844 		moverState = MOVER_2TO1;
845 	}
846 
847 	InitMoverTrData( ent );
848 
849 	ent->s.pos.trDuration = duration;
850 
851 	// start it going
852 	MatchTeam( ent, moverState, level.time );
853 	//SetMoverState( ent, moverState, level.time );
854 
855 	//Only do the angles if specified
856 	if ( angles != NULL )
857 	{
858 		//
859 		// Rotation
860 
861 		for ( i = 0; i < 3; i++ )
862 		{
863 			ang[i] = AngleDelta( angles[i], ent->r.currentAngles[i] );
864 			ent->s.apos.trDelta[i] = ( ang[i] / ( duration * 0.001f ) );
865 		}
866 
867 		VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
868 
869 		if ( ent->alt_fire )
870 		{
871 			ent->s.apos.trType = TR_LINEAR_STOP;
872 		}
873 		else
874 		{
875 			ent->s.apos.trType = TR_NONLINEAR_STOP;
876 		}
877 		ent->s.apos.trDuration = duration;
878 
879 		ent->s.apos.trTime = level.time;
880 
881 		ent->reached = moveAndRotateCallback;
882 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANGLE_FACE, taskID );
883 	}
884 	else
885 	{
886 		//Setup the last bits of information
887 		ent->reached = moverCallback;
888 	}
889 
890 	if ( ent->damage )
891 	{
892 		ent->blocked = Blocked_Mover;
893 	}
894 
895 	trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
896 	// starting sound
897 	G_PlayDoorLoopSound( ent );
898 	G_PlayDoorSound( ent, BMS_START );	//??
899 
900 	trap->LinkEntity( (sharedEntity_t *)ent );
901 }
902 
903 /*
904 =============
905 Q3_LerpAngles
906 
907 Lerps the angles to the destination value
908 =============
909 */
Q3_Lerp2Angles(int taskID,int entID,vec3_t angles,float duration)910 void Q3_Lerp2Angles( int taskID, int entID, vec3_t angles, float duration )
911 {
912 	gentity_t	*ent = &g_entities[entID];
913 	vec3_t		ang;
914 	int			i;
915 
916 	if(!ent)
917 	{
918 		G_DebugPrint( WL_WARNING, "Q3_Lerp2Angles: invalid entID %d\n", entID);
919 		return;
920 	}
921 
922 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
923 	{
924 		G_DebugPrint( WL_ERROR, "Q3_Lerp2Angles: ent %d is NOT a mover!\n", entID);
925 		return;
926 	}
927 
928 	//If we want an instant move, don't send 0...
929 	ent->s.apos.trDuration = (duration>0) ? duration : 1;
930 
931 	for ( i = 0; i < 3; i++ )
932 	{
933 		ang [i] = AngleSubtract( angles[i], ent->r.currentAngles[i]);
934 		ent->s.apos.trDelta[i] = ( ang[i] / ( ent->s.apos.trDuration * 0.001f ) );
935 	}
936 
937 	VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
938 
939 	if ( ent->alt_fire )
940 	{
941 		ent->s.apos.trType = TR_LINEAR_STOP;
942 	}
943 	else
944 	{
945 		ent->s.apos.trType = TR_NONLINEAR_STOP;
946 	}
947 
948 	ent->s.apos.trTime = level.time;
949 
950 	trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANGLE_FACE, taskID );
951 
952 	//ent->e_ReachedFunc = reachedF_NULL;
953 	ent->think = anglerCallback;
954 	ent->nextthink = level.time + duration;
955 
956 	trap->LinkEntity( (sharedEntity_t *)ent );
957 }
958 
959 /*
960 =============
961 Q3_GetTag
962 
963 Gets the value of a tag by the give name
964 =============
965 */
Q3_GetTag(int entID,const char * name,int lookup,vec3_t info)966 int	Q3_GetTag( int entID, const char *name, int lookup, vec3_t info )
967 {
968 	gentity_t	*ent = &g_entities[entID];
969 
970 	if (!ent->inuse)
971 	{
972 		assert(0);
973 		return 0;
974 	}
975 
976 	switch ( lookup )
977 	{
978 	case TYPE_ORIGIN:
979 		return TAG_GetOrigin( ent->ownername, name, info );
980 		break;
981 
982 	case TYPE_ANGLES:
983 		return TAG_GetAngles( ent->ownername, name, info );
984 		break;
985 	}
986 
987 	return 0;
988 }
989 
990 //-----------------------------------------------
991 
992 /*
993 ============
994 Q3_Use
995 
996 Uses an entity
997 ============
998 */
Q3_Use(int entID,const char * target)999 void Q3_Use( int entID, const char *target )
1000 {
1001 	gentity_t	*ent  = &g_entities[entID];
1002 
1003 	if ( !ent )
1004 	{
1005 		G_DebugPrint( WL_WARNING, "Q3_Use: invalid entID %d\n", entID);
1006 		return;
1007 	}
1008 
1009 	if( !target || !target[0] )
1010 	{
1011 		G_DebugPrint( WL_WARNING, "Q3_Use: string is NULL!\n" );
1012 		return;
1013 	}
1014 
1015 	G_UseTargets2(ent, ent, target);
1016 }
1017 
1018 /*
1019 ============
1020 Q3_Kill
1021   Description	:
1022   Return type	: void
1023   Argument		:  int entID
1024   Argument		: const char *name
1025 ============
1026 */
Q3_Kill(int entID,const char * name)1027 void Q3_Kill( int entID, const char *name )
1028 {
1029 	gentity_t	*ent = &g_entities[entID];
1030 	gentity_t	*victim = NULL;
1031 	int			o_health;
1032 
1033 	if( !Q_stricmp( name, "self") )
1034 	{
1035 		victim = ent;
1036 	}
1037 	else if( !Q_stricmp( name, "enemy" ) )
1038 	{
1039 		victim = ent->enemy;
1040 	}
1041 	else
1042 	{
1043 		victim = G_Find (NULL, FOFS(targetname), (char *) name );
1044 	}
1045 
1046 	if ( !victim )
1047 	{
1048 		G_DebugPrint( WL_WARNING, "Q3_Kill: can't find %s\n", name);
1049 		return;
1050 	}
1051 
1052 	//rww - I guess this would only apply to NPCs anyway. I'm not going to bother.
1053 	//if ( victim == ent )
1054 	//{//don't ICARUS_FreeEnt me, I'm in the middle of a script!  (FIXME: shouldn't ICARUS handle this internally?)
1055 	//	victim->svFlags |= SVF_KILLED_SELF;
1056 	//}
1057 
1058 	o_health = victim->health;
1059 	victim->health = 0;
1060 	if ( victim->client )
1061 	{
1062 		victim->flags |= FL_NO_KNOCKBACK;
1063 	}
1064 	//G_SetEnemy(victim, ent);
1065 	if( victim->die != NULL )	// check can be omitted
1066 	{
1067 		//GEntity_DieFunc( victim, NULL, NULL, o_health, MOD_UNKNOWN );
1068 		victim->die(victim, victim, victim, o_health, MOD_UNKNOWN);
1069 	}
1070 }
1071 
1072 /*
1073 ============
1074 Q3_RemoveEnt
1075   Description	:
1076   Return type	: void
1077   Argument		: sharedEntity_t *victim
1078 ============
1079 */
Q3_RemoveEnt(gentity_t * victim)1080 void Q3_RemoveEnt( gentity_t *victim )
1081 {
1082 	if( victim->client )
1083 	{
1084 		if ( victim->s.eType != ET_NPC )
1085 		{
1086 			G_DebugPrint( WL_WARNING, "Q3_RemoveEnt: You can't remove clients in MP!\n" );
1087 			assert(0); //can't remove clients in MP
1088 		}
1089 		else
1090 		{//remove the NPC
1091 			if ( victim->client->NPC_class == CLASS_VEHICLE )
1092 			{//eject everyone out of a vehicle that's about to remove itself
1093 				Vehicle_t *pVeh = victim->m_pVehicle;
1094 				if ( pVeh && pVeh->m_pVehicleInfo )
1095 				{
1096 					pVeh->m_pVehicleInfo->EjectAll( pVeh );
1097 				}
1098 			}
1099 			victim->think = G_FreeEntity;
1100 			victim->nextthink = level.time + 100;
1101 		}
1102 		/*
1103 		//ClientDisconnect(ent);
1104 		victim->s.eFlags |= EF_NODRAW;
1105 		victim->s.eType = ET_INVISIBLE;
1106 		victim->contents = 0;
1107 		victim->health = 0;
1108 		victim->targetname = NULL;
1109 
1110 		if ( victim->NPC && victim->NPC->tempGoal != NULL )
1111 		{
1112 			G_FreeEntity( victim->NPC->tempGoal );
1113 			victim->NPC->tempGoal = NULL;
1114 		}
1115 		if ( victim->client->ps.saberEntityNum != ENTITYNUM_NONE && victim->client->ps.saberEntityNum > 0 )
1116 		{
1117 			if ( g_entities[victim->client->ps.saberEntityNum].inuse )
1118 			{
1119 				G_FreeEntity( &g_entities[victim->client->ps.saberEntityNum] );
1120 			}
1121 			victim->client->ps.saberEntityNum = ENTITYNUM_NONE;
1122 		}
1123 		//Disappear in half a second
1124 		victim->e_ThinkFunc = thinkF_G_FreeEntity;
1125 		victim->nextthink = level.time + 500;
1126 		return;
1127 		*/
1128 	}
1129 	else
1130 	{
1131 		victim->think = G_FreeEntity;
1132 		victim->nextthink = level.time + 100;
1133 	}
1134 }
1135 
1136 
1137 /*
1138 ============
1139 Q3_Remove
1140   Description	:
1141   Return type	: void
1142   Argument		:  int entID
1143   Argument		: const char *name
1144 ============
1145 */
Q3_Remove(int entID,const char * name)1146 void Q3_Remove( int entID, const char *name )
1147 {
1148 	gentity_t *ent = &g_entities[entID];
1149 	gentity_t	*victim = NULL;
1150 
1151 	if( !Q_stricmp( "self", name ) )
1152 	{
1153 		victim = ent;
1154 		if ( !victim )
1155 		{
1156 			G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
1157 			return;
1158 		}
1159 		Q3_RemoveEnt( victim );
1160 	}
1161 	else if( !Q_stricmp( "enemy", name ) )
1162 	{
1163 		victim = ent->enemy;
1164 		if ( !victim )
1165 		{
1166 			G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
1167 			return;
1168 		}
1169 		Q3_RemoveEnt( victim );
1170 	}
1171 	else
1172 	{
1173 		victim = G_Find( NULL, FOFS(targetname), (char *) name );
1174 		if ( !victim )
1175 		{
1176 			G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
1177 			return;
1178 		}
1179 
1180 		while ( victim )
1181 		{
1182 			Q3_RemoveEnt( victim );
1183 			victim = G_Find( victim, FOFS(targetname), (char *) name );
1184 		}
1185 	}
1186 }
1187 
1188 /*
1189 =================================================
1190 
1191   Get / Set Functions
1192 
1193 =================================================
1194 */
1195 
1196 /*
1197 ============
1198 Q3_GetFloat
1199   Description	:
1200   Return type	: int
1201   Argument		:  int entID
1202   Argument		: int type
1203   Argument		: const char *name
1204   Argument		: float *value
1205 ============
1206 */
Q3_GetFloat(int entID,int type,const char * name,float * value)1207 int Q3_GetFloat( int entID, int type, const char *name, float *value )
1208 {
1209 	gentity_t	*ent = &g_entities[entID];
1210 	int toGet = 0;
1211 
1212 	if ( !ent )
1213 	{
1214 		return 0;
1215 	}
1216 
1217 	toGet = GetIDForString( setTable, name );	//FIXME: May want to make a "getTable" as well
1218 	//FIXME: I'm getting really sick of these huge switch statements!
1219 
1220 	//NOTENOTE: return true if the value was correctly obtained
1221 	switch ( toGet )
1222 	{
1223 	case SET_PARM1:
1224 	case SET_PARM2:
1225 	case SET_PARM3:
1226 	case SET_PARM4:
1227 	case SET_PARM5:
1228 	case SET_PARM6:
1229 	case SET_PARM7:
1230 	case SET_PARM8:
1231 	case SET_PARM9:
1232 	case SET_PARM10:
1233 	case SET_PARM11:
1234 	case SET_PARM12:
1235 	case SET_PARM13:
1236 	case SET_PARM14:
1237 	case SET_PARM15:
1238 	case SET_PARM16:
1239 		if (ent->parms == NULL)
1240 		{
1241 			G_DebugPrint( WL_ERROR, "GET_PARM: %s %s did not have any parms set!\n", ent->classname, ent->targetname );
1242 			return 0;	// would prefer qfalse, but I'm fitting in with what's here <sigh>
1243 		}
1244 		*value = atof( ent->parms->parm[toGet - SET_PARM1] );
1245 		break;
1246 
1247 	case SET_COUNT:
1248 		*value = ent->count;
1249 		break;
1250 
1251 	case SET_HEALTH:
1252 		*value = ent->health;
1253 		break;
1254 
1255 	case SET_SKILL:
1256 		return 0;
1257 		break;
1258 
1259 	case SET_XVELOCITY://## %f="0.0" # Velocity along X axis
1260 		if ( ent->client == NULL )
1261 		{
1262 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_XVELOCITY, %s not a client\n", ent->targetname );
1263 			return 0;
1264 		}
1265 		*value = ent->client->ps.velocity[0];
1266 		break;
1267 
1268 	case SET_YVELOCITY://## %f="0.0" # Velocity along Y axis
1269 		if ( ent->client == NULL )
1270 		{
1271 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_YVELOCITY, %s not a client\n", ent->targetname );
1272 			return 0;
1273 		}
1274 		*value = ent->client->ps.velocity[1];
1275 		break;
1276 
1277 	case SET_ZVELOCITY://## %f="0.0" # Velocity along Z axis
1278 		if ( ent->client == NULL )
1279 		{
1280 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ZVELOCITY, %s not a client\n", ent->targetname );
1281 			return 0;
1282 		}
1283 		*value = ent->client->ps.velocity[2];
1284 		break;
1285 
1286 	case SET_Z_OFFSET:
1287 		*value = ent->r.currentOrigin[2] - ent->s.origin[2];
1288 		break;
1289 
1290 	case SET_DPITCH://## %f="0.0" # Pitch for NPC to turn to
1291 		return 0;
1292 		break;
1293 
1294 	case SET_DYAW://## %f="0.0" # Yaw for NPC to turn to
1295 		return 0;
1296 		break;
1297 
1298 	case SET_WIDTH://## %f="0.0" # Width of NPC bounding box
1299 		*value = ent->r.mins[0];
1300 		break;
1301 	case SET_TIMESCALE://## %f="0.0" # Speed-up slow down game (0 - 1.0)
1302 		return 0;
1303 		break;
1304 	case SET_CAMERA_GROUP_Z_OFS://## %s="NULL" # all ents with this cameraGroup will be focused on
1305 		return 0;
1306 		break;
1307 
1308 	case SET_VISRANGE://## %f="0.0" # How far away NPC can see
1309 		return 0;
1310 		break;
1311 
1312 	case SET_EARSHOT://## %f="0.0" # How far an NPC can hear
1313 		return 0;
1314 		break;
1315 
1316 	case SET_VIGILANCE://## %f="0.0" # How often to look for enemies (0 - 1.0)
1317 		return 0;
1318 		break;
1319 
1320 	case SET_GRAVITY://## %f="0.0" # Change this ent's gravity - 800 default
1321 		*value = g_gravity.value;
1322 		break;
1323 
1324 	case SET_FACEEYESCLOSED:
1325 	case SET_FACEEYESOPENED:
1326 	case SET_FACEAUX:		//## %f="0.0" # Set face to Aux expression for number of seconds
1327 	case SET_FACEBLINK:		//## %f="0.0" # Set face to Blink expression for number of seconds
1328 	case SET_FACEBLINKFROWN:	//## %f="0.0" # Set face to Blinkfrown expression for number of seconds
1329 	case SET_FACEFROWN:		//## %f="0.0" # Set face to Frown expression for number of seconds
1330 	case SET_FACENORMAL:		//## %f="0.0" # Set face to Normal expression for number of seconds
1331 		G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_FACE___ not implemented\n" );
1332 		return 0;
1333 		break;
1334 	case SET_WAIT:		//## %f="0.0" # Change an entity's wait field
1335 		*value = ent->wait;
1336 		break;
1337 	case SET_FOLLOWDIST:		//## %f="0.0" # How far away to stay from leader in BS_FOLLOW_LEADER
1338 		return 0;
1339 		break;
1340 	//# #sep ints
1341 	case SET_ANIM_HOLDTIME_LOWER://## %d="0" # Hold lower anim for number of milliseconds
1342 		if ( ent->client == NULL )
1343 		{
1344 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ANIM_HOLDTIME_LOWER, %s not a client\n", ent->targetname );
1345 			return 0;
1346 		}
1347 		*value = ent->client->ps.legsTimer;
1348 		break;
1349 	case SET_ANIM_HOLDTIME_UPPER://## %d="0" # Hold upper anim for number of milliseconds
1350 		if ( ent->client == NULL )
1351 		{
1352 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ANIM_HOLDTIME_UPPER, %s not a client\n", ent->targetname );
1353 			return 0;
1354 		}
1355 		*value = ent->client->ps.torsoTimer;
1356 		break;
1357 	case SET_ANIM_HOLDTIME_BOTH://## %d="0" # Hold lower and upper anims for number of milliseconds
1358 		G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ANIM_HOLDTIME_BOTH not implemented\n" );
1359 		return 0;
1360 		break;
1361 	case SET_ARMOR://## %d="0" # Change armor
1362 		if ( ent->client == NULL )
1363 		{
1364 			G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ARMOR, %s not a client\n", ent->targetname );
1365 			return 0;
1366 		}
1367 		*value = ent->client->ps.stats[STAT_ARMOR];
1368 		break;
1369 	case SET_WALKSPEED://## %d="0" # Change walkSpeed
1370 		return 0;
1371 		break;
1372 	case SET_RUNSPEED://## %d="0" # Change runSpeed
1373 		return 0;
1374 		break;
1375 	case SET_YAWSPEED://## %d="0" # Change yawSpeed
1376 		return 0;
1377 		break;
1378 	case SET_AGGRESSION://## %d="0" # Change aggression 1-5
1379 		return 0;
1380 		break;
1381 	case SET_AIM://## %d="0" # Change aim 1-5
1382 		return 0;
1383 		break;
1384 	case SET_FRICTION://## %d="0" # Change ent's friction - 6 default
1385 		return 0;
1386 		break;
1387 	case SET_SHOOTDIST://## %d="0" # How far the ent can shoot - 0 uses weapon
1388 		return 0;
1389 		break;
1390 	case SET_HFOV://## %d="0" # Horizontal field of view
1391 		return 0;
1392 		break;
1393 	case SET_VFOV://## %d="0" # Vertical field of view
1394 		return 0;
1395 		break;
1396 	case SET_DELAYSCRIPTTIME://## %d="0" # How many seconds to wait before running delayscript
1397 		return 0;
1398 		break;
1399 	case SET_FORWARDMOVE://## %d="0" # NPC move forward -127(back) to 127
1400 		return 0;
1401 		break;
1402 	case SET_RIGHTMOVE://## %d="0" # NPC move right -127(left) to 127
1403 		return 0;
1404 		break;
1405 	case SET_STARTFRAME:	//## %d="0" # frame to start animation sequence on
1406 		return 0;
1407 		break;
1408 	case SET_ENDFRAME:	//## %d="0" # frame to end animation sequence on
1409 		return 0;
1410 		break;
1411 	case SET_ANIMFRAME:	//## %d="0" # of current frame
1412 		return 0;
1413 		break;
1414 
1415 	case SET_SHOT_SPACING://## %d="1000" # Time between shots for an NPC - reset to defaults when changes weapon
1416 		return 0;
1417 		break;
1418 	case SET_MISSIONSTATUSTIME://## %d="0" # Amount of time until Mission Status should be shown after death
1419 		return 0;
1420 		break;
1421 	//# #sep booleans
1422 	case SET_IGNOREPAIN://## %t="BOOL_TYPES" # Do not react to pain
1423 		return 0;
1424 		break;
1425 	case SET_IGNOREENEMIES://## %t="BOOL_TYPES" # Do not acquire enemies
1426 		return 0;
1427 		break;
1428 	case SET_IGNOREALERTS://## Do not get enemy set by allies in area(ambush)
1429 		return 0;
1430 		break;
1431 	case SET_DONTSHOOT://## %t="BOOL_TYPES" # Others won't shoot you
1432 		return 0;
1433 		break;
1434 	case SET_NOTARGET://## %t="BOOL_TYPES" # Others won't pick you as enemy
1435 		*value = (ent->flags&FL_NOTARGET);
1436 		break;
1437 	case SET_DONTFIRE://## %t="BOOL_TYPES" # Don't fire your weapon
1438 		return 0;
1439 		break;
1440 
1441 	case SET_LOCKED_ENEMY://## %t="BOOL_TYPES" # Keep current enemy until dead
1442 		return 0;
1443 		break;
1444 	case SET_CROUCHED://## %t="BOOL_TYPES" # Force NPC to crouch
1445 		return 0;
1446 		break;
1447 	case SET_WALKING://## %t="BOOL_TYPES" # Force NPC to move at walkSpeed
1448 		return 0;
1449 		break;
1450 	case SET_RUNNING://## %t="BOOL_TYPES" # Force NPC to move at runSpeed
1451 		return 0;
1452 		break;
1453 	case SET_CHASE_ENEMIES://## %t="BOOL_TYPES" # NPC will chase after enemies
1454 		return 0;
1455 		break;
1456 	case SET_LOOK_FOR_ENEMIES://## %t="BOOL_TYPES" # NPC will be on the lookout for enemies
1457 		return 0;
1458 		break;
1459 	case SET_FACE_MOVE_DIR://## %t="BOOL_TYPES" # NPC will face in the direction it's moving
1460 		return 0;
1461 		break;
1462 	case SET_FORCED_MARCH://## %t="BOOL_TYPES" # Force NPC to move at runSpeed
1463 		return 0;
1464 		break;
1465 	case SET_UNDYING://## %t="BOOL_TYPES" # Can take damage down to 1 but not die
1466 		return 0;
1467 		break;
1468 	case SET_NOAVOID://## %t="BOOL_TYPES" # Will not avoid other NPCs or architecture
1469 		return 0;
1470 		break;
1471 
1472 	case SET_SOLID://## %t="BOOL_TYPES" # Make yourself notsolid or solid
1473 		*value = ent->r.contents;
1474 		break;
1475 	case SET_PLAYER_USABLE://## %t="BOOL_TYPES" # Can be activateby the player's "use" button
1476 		*value = (ent->r.svFlags&SVF_PLAYER_USABLE);
1477 		break;
1478 	case SET_LOOP_ANIM://## %t="BOOL_TYPES" # For non-NPCs: loop your animation sequence
1479 		return 0;
1480 		break;
1481 	case SET_INTERFACE://## %t="BOOL_TYPES" # Player interface on/off
1482 		G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_INTERFACE not implemented\n" );
1483 		return 0;
1484 		break;
1485 	case SET_SHIELDS://## %t="BOOL_TYPES" # NPC has no shields (Borg do not adapt)
1486 		return 0;
1487 		break;
1488 	case SET_INVISIBLE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
1489 		*value = (ent->s.eFlags&EF_NODRAW);
1490 		break;
1491 	case SET_VAMPIRE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
1492 		return 0;
1493 		break;
1494 	case SET_FORCE_INVINCIBLE://## %t="BOOL_TYPES" # Makes an NPC not solid and not visible
1495 		return 0;
1496 		break;
1497 	case SET_GREET_ALLIES://## %t="BOOL_TYPES" # Makes an NPC greet teammates
1498 		return 0;
1499 		break;
1500 	case SET_VIDEO_FADE_IN://## %t="BOOL_TYPES" # Makes video playback fade in
1501 		G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_VIDEO_FADE_IN not implemented\n" );
1502 		return 0;
1503 		break;
1504 	case SET_VIDEO_FADE_OUT://## %t="BOOL_TYPES" # Makes video playback fade out
1505 		G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_VIDEO_FADE_OUT not implemented\n" );
1506 		return 0;
1507 		break;
1508 	case SET_PLAYER_LOCKED://## %t="BOOL_TYPES" # Makes it so player cannot move
1509 		return 0;
1510 		break;
1511 	case SET_LOCK_PLAYER_WEAPONS://## %t="BOOL_TYPES" # Makes it so player cannot switch weapons
1512 		return 0;
1513 		break;
1514 	case SET_NO_IMPACT_DAMAGE://## %t="BOOL_TYPES" # Makes it so player cannot switch weapons
1515 		return 0;
1516 		break;
1517 	case SET_NO_KNOCKBACK://## %t="BOOL_TYPES" # Stops this ent from taking knockback from weapons
1518 		*value = (ent->flags&FL_NO_KNOCKBACK);
1519 		break;
1520 	case SET_ALT_FIRE://## %t="BOOL_TYPES" # Force NPC to use altfire when shooting
1521 		return 0;
1522 		break;
1523 	case SET_NO_RESPONSE://## %t="BOOL_TYPES" # NPCs will do generic responses when this is on (usescripts override generic responses as well)
1524 		return 0;
1525 		break;
1526 	case SET_INVINCIBLE://## %t="BOOL_TYPES" # Completely unkillable
1527 		*value = (ent->flags&FL_GODMODE);
1528 		break;
1529 	case SET_MISSIONSTATUSACTIVE:	//# Turns on Mission Status Screen
1530 		return 0;
1531 		break;
1532 	case SET_NO_COMBAT_TALK://## %t="BOOL_TYPES" # NPCs will not do their combat talking noises when this is on
1533 		return 0;
1534 		break;
1535 	case SET_NO_ALERT_TALK://## %t="BOOL_TYPES" # NPCs will not do their combat talking noises when this is on
1536 		return 0;
1537 		break;
1538 	case SET_USE_CP_NEAREST://## %t="BOOL_TYPES" # NPCs will use their closest combat points, not try and find ones next to the player, or flank player
1539 		return 0;
1540 		break;
1541 	case SET_DISMEMBERABLE://## %t="BOOL_TYPES" # NPC will not be affected by force powers
1542 		return 0;
1543 		break;
1544 	case SET_NO_FORCE:
1545 		return 0;
1546 		break;
1547 	case SET_NO_ACROBATICS:
1548 		return 0;
1549 		break;
1550 	case SET_USE_SUBTITLES:
1551 		return 0;
1552 		break;
1553 	case SET_NO_FALLTODEATH://## %t="BOOL_TYPES" # NPC will not be affected by force powers
1554 		return 0;
1555 		break;
1556 	case SET_MORELIGHT://## %t="BOOL_TYPES" # NPCs will use their closest combat points, not try and find ones next to the player, or flank player
1557 		return 0;
1558 		break;
1559 	case SET_TREASONED://## %t="BOOL_TYPES" # Player has turned on his own- scripts will stop: NPCs will turn on him and level changes load the brig
1560 		return 0;
1561 		break;
1562 	case SET_DISABLE_SHADER_ANIM:	//## %t="BOOL_TYPES" # Shaders won't animate
1563 		return 0;
1564 		break;
1565 	case SET_SHADER_ANIM:	//## %t="BOOL_TYPES" # Shader will be under frame control
1566 		return 0;
1567 		break;
1568 
1569 	default:
1570 		if ( trap->ICARUS_VariableDeclared( name ) != VTYPE_FLOAT )
1571 			return 0;
1572 
1573 		return trap->ICARUS_GetFloatVariable( name, value );
1574 	}
1575 
1576 	return 1;
1577 }
1578 
1579 
1580 /*
1581 ============
1582 Q3_GetVector
1583   Description	:
1584   Return type	: int
1585   Argument		:  int entID
1586   Argument		: int type
1587   Argument		: const char *name
1588   Argument		: vec3_t value
1589 ============
1590 */
Q3_GetVector(int entID,int type,const char * name,vec3_t value)1591 int Q3_GetVector( int entID, int type, const char *name, vec3_t value )
1592 {
1593 	gentity_t	*ent = &g_entities[entID];
1594 	int toGet = 0;
1595 	if ( !ent )
1596 	{
1597 		return 0;
1598 	}
1599 
1600 	toGet = GetIDForString( setTable, name );	//FIXME: May want to make a "getTable" as well
1601 	//FIXME: I'm getting really sick of these huge switch statements!
1602 
1603 	//NOTENOTE: return true if the value was correctly obtained
1604 	switch ( toGet )
1605 	{
1606 	case SET_PARM1:
1607 	case SET_PARM2:
1608 	case SET_PARM3:
1609 	case SET_PARM4:
1610 	case SET_PARM5:
1611 	case SET_PARM6:
1612 	case SET_PARM7:
1613 	case SET_PARM8:
1614 	case SET_PARM9:
1615 	case SET_PARM10:
1616 	case SET_PARM11:
1617 	case SET_PARM12:
1618 	case SET_PARM13:
1619 	case SET_PARM14:
1620 	case SET_PARM15:
1621 	case SET_PARM16:
1622 		if ( sscanf( ent->parms->parm[toGet - SET_PARM1], "%f %f %f", &value[0], &value[1], &value[2] ) != 3 ) {
1623 			G_DebugPrint( WL_WARNING, "Q3_GetVector: failed sscanf on SET_PARM%d (%s)\n", toGet, name );
1624 			VectorClear( value );
1625 		}
1626 		break;
1627 
1628 	case SET_ORIGIN:
1629 		VectorCopy(ent->r.currentOrigin, value);
1630 		break;
1631 
1632 	case SET_ANGLES:
1633 		VectorCopy(ent->r.currentAngles, value);
1634 		break;
1635 
1636 	case SET_TELEPORT_DEST://## %v="0.0 0.0 0.0" # Set origin here as soon as the area is clear
1637 		G_DebugPrint( WL_WARNING, "Q3_GetVector: SET_TELEPORT_DEST not implemented\n" );
1638 		return 0;
1639 		break;
1640 
1641 	default:
1642 
1643 		if ( trap->ICARUS_VariableDeclared( name ) != VTYPE_VECTOR )
1644 			return 0;
1645 
1646 		return trap->ICARUS_GetVectorVariable( name, value );
1647 	}
1648 
1649 	return 1;
1650 }
1651 
1652 /*
1653 ============
1654 Q3_GetString
1655   Description	:
1656   Return type	: int
1657   Argument		:  int entID
1658   Argument		: int type
1659   Argument		: const char *name
1660   Argument		: char **value
1661 ============
1662 */
Q3_GetString(int entID,int type,const char * name,char ** value)1663 int Q3_GetString( int entID, int type, const char *name, char **value )
1664 {
1665 	gentity_t	*ent = &g_entities[entID];
1666 	int toGet = 0;
1667 	if ( !ent )
1668 	{
1669 		return 0;
1670 	}
1671 
1672 	toGet = GetIDForString( setTable, name );	//FIXME: May want to make a "getTable" as well
1673 
1674 	switch ( toGet )
1675 	{
1676 	case SET_ANIM_BOTH:
1677 		*value = (char *) Q3_GetAnimBoth( ent );
1678 
1679 		if ( !value || !value[0] )
1680 			return 0;
1681 
1682 		break;
1683 
1684 	case SET_PARM1:
1685 	case SET_PARM2:
1686 	case SET_PARM3:
1687 	case SET_PARM4:
1688 	case SET_PARM5:
1689 	case SET_PARM6:
1690 	case SET_PARM7:
1691 	case SET_PARM8:
1692 	case SET_PARM9:
1693 	case SET_PARM10:
1694 	case SET_PARM11:
1695 	case SET_PARM12:
1696 	case SET_PARM13:
1697 	case SET_PARM14:
1698 	case SET_PARM15:
1699 	case SET_PARM16:
1700 		if ( ent->parms )
1701 		{
1702 			*value = (char *) ent->parms->parm[toGet - SET_PARM1];
1703 		}
1704 		else
1705 		{
1706 			G_DebugPrint( WL_WARNING, "Q3_GetString: invalid ent %s has no parms!\n", ent->targetname );
1707 			return 0;
1708 		}
1709 		break;
1710 
1711 	case SET_TARGET:
1712 		*value = (char *) ent->target;
1713 		break;
1714 
1715 	case SET_LOCATION:
1716 		return 0;
1717 		break;
1718 
1719 	//# #sep Scripts and other file paths
1720 	case SET_SPAWNSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when spawned //0 - do not change these, these are equal to BSET_SPAWN, etc
1721 		*value = ent->behaviorSet[BSET_SPAWN];
1722 		break;
1723 	case SET_USESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when used
1724 		*value = ent->behaviorSet[BSET_USE];
1725 		break;
1726 	case SET_AWAKESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when startled
1727 		*value = ent->behaviorSet[BSET_AWAKE];
1728 		break;
1729 	case SET_ANGERSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script run when find an enemy for the first time
1730 		*value = ent->behaviorSet[BSET_ANGER];
1731 		break;
1732 	case SET_ATTACKSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when you shoot
1733 		*value = ent->behaviorSet[BSET_ATTACK];
1734 		break;
1735 	case SET_VICTORYSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when killed someone
1736 		*value = ent->behaviorSet[BSET_VICTORY];
1737 		break;
1738 	case SET_LOSTENEMYSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when you can't find your enemy
1739 		*value = ent->behaviorSet[BSET_LOSTENEMY];
1740 		break;
1741 	case SET_PAINSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when hit
1742 		*value = ent->behaviorSet[BSET_PAIN];
1743 		break;
1744 	case SET_FLEESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when hit and low health
1745 		*value = ent->behaviorSet[BSET_FLEE];
1746 		break;
1747 	case SET_DEATHSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when killed
1748 		*value = ent->behaviorSet[BSET_DEATH];
1749 		break;
1750 	case SET_DELAYEDSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run after a delay
1751 		*value = ent->behaviorSet[BSET_DELAYED];
1752 		break;
1753 	case SET_BLOCKEDSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when blocked by teammate
1754 		*value = ent->behaviorSet[BSET_BLOCKED];
1755 		break;
1756 	case SET_FFIRESCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when player has shot own team repeatedly
1757 		*value = ent->behaviorSet[BSET_FFIRE];
1758 		break;
1759 	case SET_FFDEATHSCRIPT://## %s="NULL" !!"W:\game\base\scripts\!!#*.txt" # Script to run when player kills a teammate
1760 		*value = ent->behaviorSet[BSET_FFDEATH];
1761 		break;
1762 
1763 	//# #sep Standard strings
1764 	case SET_ENEMY://## %s="NULL" # Set enemy by targetname
1765 		return 0;
1766 		break;
1767 	case SET_LEADER://## %s="NULL" # Set for BS_FOLLOW_LEADER
1768 		return 0;
1769 		break;
1770 	case SET_CAPTURE://## %s="NULL" # Set captureGoal by targetname
1771 		return 0;
1772 		break;
1773 
1774 	case SET_TARGETNAME://## %s="NULL" # Set/change your targetname
1775 		*value = ent->targetname;
1776 		break;
1777 	case SET_PAINTARGET://## %s="NULL" # Set/change what to use when hit
1778 		return 0;
1779 		break;
1780 	case SET_CAMERA_GROUP://## %s="NULL" # all ents with this cameraGroup will be focused on
1781 		return 0;
1782 		break;
1783 	case SET_CAMERA_GROUP_TAG://## %s="NULL" # all ents with this cameraGroup will be focused on
1784 		return 0;
1785 		break;
1786 	case SET_LOOK_TARGET://## %s="NULL" # object for NPC to look at
1787 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_LOOK_TARGET, NOT SUPPORTED IN MULTIPLAYER\n" );
1788 		break;
1789 	case SET_TARGET2://## %s="NULL" # Set/change your target2: on NPC's: this fires when they're knocked out by the red hypo
1790 		return 0;
1791 		break;
1792 
1793 	case SET_REMOVE_TARGET://## %s="NULL" # Target that is fired when someone completes the BS_REMOVE behaviorState
1794 		return 0;
1795 		break;
1796 	case SET_WEAPON:
1797 		return 0;
1798 		break;
1799 
1800 	case SET_ITEM:
1801 		return 0;
1802 		break;
1803 	case SET_MUSIC_STATE:
1804 		return 0;
1805 		break;
1806 	//The below cannot be gotten
1807 	case SET_NAVGOAL://## %s="NULL" # *Move to this navgoal then continue script
1808 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_NAVGOAL not implemented\n" );
1809 		return 0;
1810 		break;
1811 	case SET_VIEWTARGET://## %s="NULL" # Set angles toward ent by targetname
1812 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_VIEWTARGET not implemented\n" );
1813 		return 0;
1814 		break;
1815 	case SET_WATCHTARGET://## %s="NULL" # Set angles toward ent by targetname
1816 		return 0;
1817 		break;
1818 	case SET_VIEWENTITY:
1819 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_VIEWENTITY not implemented\n" );
1820 		return 0;
1821 		break;
1822 	case SET_CAPTIONTEXTCOLOR:	//## %s=""  # Color of text RED:WHITE:BLUE: YELLOW
1823 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_CAPTIONTEXTCOLOR not implemented\n" );
1824 		return 0;
1825 		break;
1826 	case SET_CENTERTEXTCOLOR:	//## %s=""  # Color of text RED:WHITE:BLUE: YELLOW
1827 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_CENTERTEXTCOLOR not implemented\n" );
1828 		return 0;
1829 		break;
1830 	case SET_SCROLLTEXTCOLOR:	//## %s=""  # Color of text RED:WHITE:BLUE: YELLOW
1831 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_SCROLLTEXTCOLOR not implemented\n" );
1832 		return 0;
1833 		break;
1834 	case SET_COPY_ORIGIN://## %s="targetname"  # Copy the origin of the ent with targetname to your origin
1835 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_COPY_ORIGIN not implemented\n" );
1836 		return 0;
1837 		break;
1838 	case SET_DEFEND_TARGET://## %s="targetname"  # This NPC will attack the target NPC's enemies
1839 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_COPY_ORIGIN not implemented\n" );
1840 		return 0;
1841 		break;
1842 	case SET_VIDEO_PLAY://## %s="filename" !!"W:\game\base\video\!!#*.roq" # Play a Video (inGame)
1843 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_VIDEO_PLAY not implemented\n" );
1844 		return 0;
1845 		break;
1846 	case SET_LOADGAME://## %s="exitholodeck" # Load the savegame that was auto-saved when you started the holodeck
1847 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_LOADGAME not implemented\n" );
1848 		return 0;
1849 		break;
1850 	case SET_LOCKYAW://## %s="off"  # Lock legs to a certain yaw angle (or "off" or "auto" uses current)
1851 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_LOCKYAW not implemented\n" );
1852 		return 0;
1853 		break;
1854 	case SET_SCROLLTEXT:	//## %s="" # key of text string to print
1855 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_SCROLLTEXT not implemented\n" );
1856 		return 0;
1857 		break;
1858 	case SET_LCARSTEXT:	//## %s="" # key of text string to print in LCARS frame
1859 		G_DebugPrint( WL_WARNING, "Q3_GetString: SET_LCARSTEXT not implemented\n" );
1860 		return 0;
1861 		break;
1862 
1863 	case SET_FULLNAME://## %s="NULL" # Set/change your targetname
1864 		*value = ent->fullName;
1865 		break;
1866 	default:
1867 
1868 		if ( trap->ICARUS_VariableDeclared( name ) != VTYPE_STRING )
1869 			return 0;
1870 
1871 		return trap->ICARUS_GetStringVariable( name, (const char *) *value );
1872 	}
1873 
1874 	return 1;
1875 }
1876 
1877 /*
1878 ============
1879 MoveOwner
1880   Description	:
1881   Return type	: void
1882   Argument		: sharedEntity_t *self
1883 ============
1884 */
1885 qboolean SpotWouldTelefrag2( gentity_t *mover, vec3_t dest );
MoveOwner(gentity_t * self)1886 void MoveOwner( gentity_t *self )
1887 {
1888 	gentity_t *owner = &g_entities[self->r.ownerNum];
1889 
1890 	self->nextthink = level.time + FRAMETIME;
1891 	self->think = G_FreeEntity;
1892 
1893 	if ( !owner || !owner->inuse )
1894 	{
1895 		return;
1896 	}
1897 
1898 	if ( SpotWouldTelefrag2( owner, self->r.currentOrigin ) )
1899 	{
1900 		self->think = MoveOwner;
1901 	}
1902 	else
1903 	{
1904 		G_SetOrigin( owner, self->r.currentOrigin );
1905 		trap->ICARUS_TaskIDComplete( (sharedEntity_t *)owner, TID_MOVE_NAV );
1906 	}
1907 }
1908 
1909 /*
1910 =============
1911 Q3_SetTeleportDest
1912 
1913 Copies passed origin to ent running script once there is nothing there blocking the spot
1914 =============
1915 */
Q3_SetTeleportDest(int entID,vec3_t org)1916 static qboolean Q3_SetTeleportDest( int entID, vec3_t org )
1917 {
1918 	gentity_t	*teleEnt = &g_entities[entID];
1919 
1920 	if ( teleEnt )
1921 	{
1922 		if ( SpotWouldTelefrag2( teleEnt, org ) )
1923 		{
1924 			gentity_t *teleporter = G_Spawn();
1925 
1926 			G_SetOrigin( teleporter, org );
1927 			teleporter->r.ownerNum = teleEnt->s.number;
1928 
1929 			teleporter->think = MoveOwner;
1930 			teleporter->nextthink = level.time + FRAMETIME;
1931 
1932 			return qfalse;
1933 		}
1934 		else
1935 		{
1936 			G_SetOrigin( teleEnt, org );
1937 		}
1938 	}
1939 
1940 	return qtrue;
1941 }
1942 
1943 /*
1944 =============
1945 Q3_SetOrigin
1946 
1947 Sets the origin of an entity directly
1948 =============
1949 */
Q3_SetOrigin(int entID,vec3_t origin)1950 static void Q3_SetOrigin( int entID, vec3_t origin )
1951 {
1952 	gentity_t	*ent = &g_entities[entID];
1953 
1954 	if ( !ent )
1955 	{
1956 		G_DebugPrint( WL_WARNING, "Q3_SetOrigin: bad ent %d\n", entID);
1957 		return;
1958 	}
1959 
1960 	trap->UnlinkEntity ((sharedEntity_t *)ent);
1961 
1962 	if(ent->client)
1963 	{
1964 		VectorCopy(origin, ent->client->ps.origin);
1965 		VectorCopy(origin, ent->r.currentOrigin);
1966 		ent->client->ps.origin[2] += 1;
1967 
1968 		VectorClear (ent->client->ps.velocity);
1969 		ent->client->ps.pm_time = 160;		// hold time
1970 		ent->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
1971 
1972 		ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
1973 
1974 //		G_KillBox (ent);
1975 	}
1976 	else
1977 	{
1978 		G_SetOrigin( ent, origin );
1979 	}
1980 
1981 	trap->LinkEntity( (sharedEntity_t *)ent );
1982 }
1983 
1984 /*
1985 =============
1986 Q3_SetCopyOrigin
1987 
1988 Copies origin of found ent into ent running script
1989 =============`
1990 */
Q3_SetCopyOrigin(int entID,const char * name)1991 static void Q3_SetCopyOrigin( int entID, const char *name )
1992 {
1993 	gentity_t	*found = G_Find( NULL, FOFS(targetname), (char *) name);
1994 
1995 	if(found)
1996 	{
1997 		Q3_SetOrigin( entID, found->r.currentOrigin );
1998 		SetClientViewAngle( &g_entities[entID], found->s.angles );
1999 	}
2000 	else
2001 	{
2002 		G_DebugPrint( WL_WARNING, "Q3_SetCopyOrigin: ent %s not found!\n", name);
2003 	}
2004 }
2005 
2006 /*
2007 =============
2008 Q3_SetVelocity
2009 
2010 Set the velocity of an entity directly
2011 =============
2012 */
Q3_SetVelocity(int entID,int axis,float speed)2013 static void Q3_SetVelocity( int entID, int axis, float speed )
2014 {
2015 	gentity_t	*found = &g_entities[entID];
2016 	//FIXME: Not supported
2017 	if(!found)
2018 	{
2019 		G_DebugPrint( WL_WARNING, "Q3_SetVelocity invalid entID %d\n", entID);
2020 		return;
2021 	}
2022 
2023 	if(!found->client)
2024 	{
2025 		G_DebugPrint( WL_WARNING, "Q3_SetVelocity: not a client %d\n", entID);
2026 		return;
2027 	}
2028 
2029 	//FIXME: add or set?
2030 	found->client->ps.velocity[axis] += speed;
2031 
2032 	found->client->ps.pm_time = 500;
2033 	found->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
2034 }
2035 
2036 /*
2037 =============
2038 Q3_SetAngles
2039 
2040 Sets the angles of an entity directly
2041 =============
2042 */
Q3_SetAngles(int entID,vec3_t angles)2043 static void Q3_SetAngles( int entID, vec3_t angles )
2044 {
2045 	gentity_t	*ent = &g_entities[entID];
2046 
2047 
2048 	if ( !ent )
2049 	{
2050 		G_DebugPrint( WL_WARNING, "Q3_SetAngles: bad ent %d\n", entID);
2051 		return;
2052 	}
2053 
2054 	if (ent->client)
2055 	{
2056 		SetClientViewAngle( ent, angles );
2057 	}
2058 	else
2059 	{
2060 		VectorCopy( angles, ent->s.angles );
2061 	}
2062 	trap->LinkEntity( (sharedEntity_t *)ent );
2063 }
2064 
2065 /*
2066 =============
2067 Q3_Lerp2Origin
2068 
2069 Lerps the origin to the destination value
2070 =============
2071 */
Q3_Lerp2Origin(int taskID,int entID,vec3_t origin,float duration)2072 void Q3_Lerp2Origin( int taskID, int entID, vec3_t origin, float duration )
2073 {
2074 	gentity_t	*ent = &g_entities[entID];
2075 	moverState_t moverState;
2076 
2077 	if(!ent)
2078 	{
2079 		G_DebugPrint( WL_WARNING, "Q3_Lerp2Origin: invalid entID %d\n", entID);
2080 		return;
2081 	}
2082 
2083 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
2084 	{
2085 		G_DebugPrint( WL_ERROR, "Q3_Lerp2Origin: ent %d is NOT a mover!\n", entID);
2086 		return;
2087 	}
2088 
2089 	if ( ent->s.eType != ET_MOVER )
2090 	{
2091 		ent->s.eType = ET_MOVER;
2092 	}
2093 
2094 	moverState = ent->moverState;
2095 
2096 	if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
2097 	{
2098 		VectorCopy( ent->r.currentOrigin, ent->pos1 );
2099 		VectorCopy( origin, ent->pos2 );
2100 
2101 		moverState = MOVER_1TO2;
2102 	}
2103 	else if ( moverState == MOVER_POS2 || moverState == MOVER_1TO2 )
2104 	{
2105 		VectorCopy( ent->r.currentOrigin, ent->pos2 );
2106 		VectorCopy( origin, ent->pos1 );
2107 
2108 		moverState = MOVER_2TO1;
2109 	}
2110 
2111 	InitMoverTrData( ent );	//FIXME: This will probably break normal things that are being moved...
2112 
2113 	ent->s.pos.trDuration = duration;
2114 
2115 	// start it going
2116 	MatchTeam( ent, moverState, level.time );
2117 	//SetMoverState( ent, moverState, level.time );
2118 
2119 	ent->reached = moverCallback;
2120 	if ( ent->damage )
2121 	{
2122 		ent->blocked = Blocked_Mover;
2123 	}
2124 	if ( taskID != -1 )
2125 	{
2126 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
2127 	}
2128 	// starting sound
2129 	G_PlayDoorLoopSound( ent );//start looping sound
2130 	G_PlayDoorSound( ent, BMS_START );	//play start sound
2131 
2132 	trap->LinkEntity( (sharedEntity_t *)ent );
2133 }
2134 
Q3_SetOriginOffset(int entID,int axis,float offset)2135 static void Q3_SetOriginOffset( int entID, int axis, float offset )
2136 {
2137 	gentity_t	*ent = &g_entities[entID];
2138 	vec3_t origin;
2139 	float duration;
2140 
2141 	if(!ent)
2142 	{
2143 		G_DebugPrint( WL_WARNING, "Q3_SetOriginOffset: invalid entID %d\n", entID);
2144 		return;
2145 	}
2146 
2147 	if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
2148 	{
2149 		G_DebugPrint( WL_ERROR, "Q3_SetOriginOffset: ent %d is NOT a mover!\n", entID);
2150 		return;
2151 	}
2152 
2153 	VectorCopy( ent->s.origin, origin );
2154 	origin[axis] += offset;
2155 	duration = 0;
2156 	if ( ent->speed )
2157 	{
2158 		duration = fabs(offset)/fabs(ent->speed)*1000.0f;
2159 	}
2160 	Q3_Lerp2Origin( -1, entID, origin, duration );
2161 }
2162 
2163 /*
2164 =============
2165 Q3_SetEnemy
2166 
2167 Sets the enemy of an entity
2168 =============
2169 */
Q3_SetEnemy(int entID,const char * name)2170 static void Q3_SetEnemy( int entID, const char *name )
2171 {
2172 	gentity_t	*ent  = &g_entities[entID];
2173 
2174 	if ( !ent )
2175 	{
2176 		G_DebugPrint( WL_WARNING, "Q3_SetEnemy: invalid entID %d\n", entID);
2177 		return;
2178 	}
2179 
2180 	if( !Q_stricmp("NONE", name) || !Q_stricmp("NULL", name))
2181 	{
2182 		if(ent->NPC)
2183 		{
2184 			G_ClearEnemy(ent);
2185 		}
2186 		else
2187 		{
2188 			ent->enemy = NULL;
2189 		}
2190 	}
2191 	else
2192 	{
2193 		gentity_t	*enemy = G_Find( NULL, FOFS(targetname), (char *) name);
2194 
2195 		if(enemy == NULL)
2196 		{
2197 			G_DebugPrint( WL_ERROR, "Q3_SetEnemy: no such enemy: '%s'\n", name );
2198 			return;
2199 		}
2200 		/*else if(enemy->health <= 0)
2201 		{
2202 			//G_DebugPrint( WL_ERROR, "Q3_SetEnemy: ERROR - desired enemy has health %d\n", enemy->health );
2203 			return;
2204 		}*/
2205 		else
2206 		{
2207 			if(ent->NPC)
2208 			{
2209 				G_SetEnemy( ent, enemy );
2210 				ent->cantHitEnemyCounter = 0;
2211 			}
2212 			else
2213 			{
2214 				G_SetEnemy(ent, enemy);
2215 			}
2216 		}
2217 	}
2218 }
2219 
2220 
2221 /*
2222 =============
2223 Q3_SetLeader
2224 
2225 Sets the leader of an NPC
2226 =============
2227 */
Q3_SetLeader(int entID,const char * name)2228 static void Q3_SetLeader( int entID, const char *name )
2229 {
2230 	gentity_t	*ent  = &g_entities[entID];
2231 
2232 	if ( !ent )
2233 	{
2234 		G_DebugPrint( WL_WARNING, "Q3_SetLeader: invalid entID %d\n", entID);
2235 		return;
2236 	}
2237 
2238 	if ( !ent->client )
2239 	{
2240 		G_DebugPrint( WL_ERROR, "Q3_SetLeader: ent %d is NOT a player or NPC!\n", entID);
2241 		return;
2242 	}
2243 
2244 	if( !Q_stricmp("NONE", name) || !Q_stricmp("NULL", name))
2245 	{
2246 		ent->client->leader = NULL;
2247 	}
2248 	else
2249 	{
2250 		gentity_t	*leader = G_Find( NULL, FOFS(targetname), (char *) name);
2251 
2252 		if(leader == NULL)
2253 		{
2254 			//G_DebugPrint( WL_ERROR,"Q3_SetEnemy: unable to locate enemy: '%s'\n", name );
2255 			return;
2256 		}
2257 		else if(leader->health <= 0)
2258 		{
2259 			//G_DebugPrint( WL_ERROR,"Q3_SetEnemy: ERROR - desired enemy has health %d\n", enemy->health );
2260 			return;
2261 		}
2262 		else
2263 		{
2264 			ent->client->leader = leader;
2265 		}
2266 	}
2267 }
2268 
2269 /*
2270 =============
2271 Q3_SetNavGoal
2272 
2273 Sets the navigational goal of an entity
2274 =============
2275 */
Q3_SetNavGoal(int entID,const char * name)2276 static qboolean Q3_SetNavGoal( int entID, const char *name )
2277 {
2278 	gentity_t	*ent  = &g_entities[ entID ];
2279 	vec3_t		goalPos;
2280 
2281 	if ( !ent->health )
2282 	{
2283 		G_DebugPrint( WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a corpse! \"%s\"\n", name, ent->script_targetname );
2284 		return qfalse;
2285 	}
2286 	if ( !ent->NPC )
2287 	{
2288 		G_DebugPrint( WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a non-NPC: \"%s\"\n", name, ent->script_targetname );
2289 		return qfalse;
2290 	}
2291 	if ( !ent->NPC->tempGoal )
2292 	{
2293 		G_DebugPrint( WL_ERROR, "Q3_SetNavGoal: tried to set a navgoal (\"%s\") on a dead NPC: \"%s\"\n", name, ent->script_targetname );
2294 		return qfalse;
2295 	}
2296 	if ( !ent->NPC->tempGoal->inuse )
2297 	{
2298 		G_DebugPrint( WL_ERROR, "Q3_SetNavGoal: NPC's (\"%s\") navgoal is freed: \"%s\"\n", name, ent->script_targetname );
2299 		return qfalse;
2300 	}
2301 	if( Q_stricmp( "null", name) == 0
2302 		|| Q_stricmp( "NULL", name) == 0 )
2303 	{
2304 		ent->NPC->goalEntity = NULL;
2305 		trap->ICARUS_TaskIDComplete( (sharedEntity_t *)ent, TID_MOVE_NAV );
2306 		return qfalse;
2307 	}
2308 	else
2309 	{
2310 		//Get the position of the goal
2311 		if ( TAG_GetOrigin2( NULL, name, goalPos ) == qfalse )
2312 		{
2313 			gentity_t	*targ = G_Find(NULL, FOFS(targetname), (char*)name);
2314 			if ( !targ )
2315 			{
2316 				G_DebugPrint( WL_ERROR, "Q3_SetNavGoal: can't find NAVGOAL \"%s\"\n", name );
2317 				return qfalse;
2318 			}
2319 			else
2320 			{
2321 				ent->NPC->goalEntity = targ;
2322 				ent->NPC->goalRadius = sqrt(ent->r.maxs[0]+ent->r.maxs[0]) + sqrt(targ->r.maxs[0]+targ->r.maxs[0]);
2323 				ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
2324 			}
2325 		}
2326 		else
2327 		{
2328 			int	goalRadius = TAG_GetRadius( NULL, name );
2329 			NPC_SetMoveGoal( ent, goalPos, goalRadius, qtrue, -1, NULL );
2330 			//We know we want to clear the lastWaypoint here
2331 			ent->NPC->goalEntity->lastWaypoint = WAYPOINT_NONE;
2332 			ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
2333 	#ifdef _DEBUG
2334 			//this is *only* for debugging navigation
2335 			ent->NPC->tempGoal->target = G_NewString( name );
2336 	#endif// _DEBUG
2337 		return qtrue;
2338 		}
2339 	}
2340 	return qfalse;
2341 }
2342 /*
2343 ============
2344 SetLowerAnim
2345   Description	:
2346   Return type	: static void
2347   Argument		:  int entID
2348   Argument		: int animID
2349 ============
2350 */
SetLowerAnim(int entID,int animID)2351 static void SetLowerAnim( int entID, int animID)
2352 {
2353 	gentity_t	*ent  = &g_entities[entID];
2354 
2355 	if ( !ent )
2356 	{
2357 		G_DebugPrint( WL_WARNING, "SetLowerAnim: invalid entID %d\n", entID);
2358 		return;
2359 	}
2360 
2361 	if ( !ent->client )
2362 	{
2363 		G_DebugPrint( WL_ERROR, "SetLowerAnim: ent %d is NOT a player or NPC!\n", entID);
2364 		return;
2365 	}
2366 
2367 	G_SetAnim(ent,NULL,SETANIM_LEGS,animID,SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD|SETANIM_FLAG_OVERRIDE,0);
2368 }
2369 
2370 /*
2371 ============
2372 SetUpperAnim
2373   Description	:
2374   Return type	: static void
2375   Argument		:  int entID
2376   Argument		: int animID
2377 ============
2378 */
SetUpperAnim(int entID,int animID)2379 static void SetUpperAnim ( int entID, int animID)
2380 {
2381 	gentity_t	*ent  = &g_entities[entID];
2382 
2383 	if ( !ent )
2384 	{
2385 		G_DebugPrint( WL_WARNING, "SetUpperAnim: invalid entID %d\n", entID);
2386 		return;
2387 	}
2388 
2389 	if ( !ent->client )
2390 	{
2391 		G_DebugPrint( WL_ERROR, "SetLowerAnim: ent %d is NOT a player or NPC!\n", entID);
2392 		return;
2393 	}
2394 
2395 	G_SetAnim(ent,NULL,SETANIM_TORSO,animID,SETANIM_FLAG_RESTART|SETANIM_FLAG_HOLD|SETANIM_FLAG_OVERRIDE,0);
2396 }
2397 
2398 /*
2399 =============
2400 Q3_SetAnimUpper
2401 
2402 Sets the upper animation of an entity
2403 =============
2404 */
Q3_SetAnimUpper(int entID,const char * anim_name)2405 static qboolean Q3_SetAnimUpper( int entID, const char *anim_name )
2406 {
2407 	int			animID = 0;
2408 
2409 	animID = GetIDForString( animTable, anim_name );
2410 
2411 	if( animID == -1 )
2412 	{
2413 		G_DebugPrint( WL_WARNING, "Q3_SetAnimUpper: unknown animation sequence '%s'\n", anim_name );
2414 		return qfalse;
2415 	}
2416 
2417 	/*
2418 	if ( !PM_HasAnimation( SV_GentityNum(entID), animID ) )
2419 	{
2420 		return qfalse;
2421 	}
2422 	*/
2423 
2424 	SetUpperAnim( entID, animID );
2425 	return qtrue;
2426 }
2427 
2428 /*
2429 =============
2430 Q3_SetAnimLower
2431 
2432 Sets the lower animation of an entity
2433 =============
2434 */
Q3_SetAnimLower(int entID,const char * anim_name)2435 static qboolean Q3_SetAnimLower( int entID, const char *anim_name )
2436 {
2437 	int			animID = 0;
2438 
2439 	//FIXME: Setting duck anim does not actually duck!
2440 
2441 	animID = GetIDForString( animTable, anim_name );
2442 
2443 	if( animID == -1 )
2444 	{
2445 		G_DebugPrint( WL_WARNING, "Q3_SetAnimLower: unknown animation sequence '%s'\n", anim_name );
2446 		return qfalse;
2447 	}
2448 
2449 	/*
2450 	if ( !PM_HasAnimation( SV_GentityNum(entID), animID ) )
2451 	{
2452 		return qfalse;
2453 	}
2454 	*/
2455 
2456 	SetLowerAnim( entID, animID );
2457 	return qtrue;
2458 }
2459 
2460 /*
2461 ============
2462 Q3_SetAnimHoldTime
2463   Description	:
2464   Return type	: static void
2465   Argument		:  int entID
2466   Argument		: int int_data
2467   Argument		: qboolean lower
2468 ============
2469 */
Q3_SetAnimHoldTime(int entID,int int_data,qboolean lower)2470 static void Q3_SetAnimHoldTime( int entID, int int_data, qboolean lower )
2471 {
2472 	G_DebugPrint( WL_WARNING, "Q3_SetAnimHoldTime is not currently supported in MP\n");
2473 	/*
2474 	gentity_t	*ent  = &g_entities[entID];
2475 
2476 	if ( !ent )
2477 	{
2478 		G_DebugPrint( WL_WARNING, "Q3_SetAnimHoldTime: invalid entID %d\n", entID);
2479 		return;
2480 	}
2481 
2482 	if ( !ent->client )
2483 	{
2484 		G_DebugPrint( WL_ERROR, "Q3_SetAnimHoldTime: ent %d is NOT a player or NPC!\n", entID);
2485 		return;
2486 	}
2487 
2488 	if(lower)
2489 	{
2490 		PM_SetLegsAnimTimer( ent, &ent->client->ps.legsAnimTimer, int_data );
2491 	}
2492 	else
2493 	{
2494 		PM_SetTorsoAnimTimer( ent, &ent->client->ps.torsoAnimTimer, int_data );
2495 	}
2496 	*/
2497 }
2498 
2499 /*
2500 ============
2501 Q3_SetHealth
2502   Description	:
2503   Return type	: static void
2504   Argument		:  int entID
2505   Argument		: int data
2506 ============
2507 */
Q3_SetHealth(int entID,int data)2508 static void Q3_SetHealth( int entID, int data )
2509 {
2510 	gentity_t	*ent  = &g_entities[entID];
2511 
2512 	if ( !ent )
2513 	{
2514 		G_DebugPrint( WL_WARNING, "Q3_SetHealth: invalid entID %d\n", entID);
2515 		return;
2516 	}
2517 
2518 	if ( data < 0 )
2519 	{
2520 		data = 0;
2521 	}
2522 
2523 	ent->health = data;
2524 
2525 	if(!ent->client)
2526 	{
2527 		return;
2528 	}
2529 
2530 	ent->client->ps.stats[STAT_HEALTH] = data;
2531 
2532 	if ( ent->client->ps.stats[STAT_HEALTH] > ent->client->ps.stats[STAT_MAX_HEALTH] )
2533 	{
2534 		ent->health = ent->client->ps.stats[STAT_HEALTH] = ent->client->ps.stats[STAT_MAX_HEALTH];
2535 	}
2536 	if ( data == 0 )
2537 	{
2538 		ent->health = 1;
2539 		if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR )
2540 		{ //this would be silly
2541 			return;
2542 		}
2543 
2544 		if ( ent->client->tempSpectate >= level.time )
2545 		{ //this would also be silly
2546 			return;
2547 		}
2548 
2549 		ent->flags &= ~FL_GODMODE;
2550 		ent->client->ps.stats[STAT_HEALTH] = ent->health = -999;
2551 		player_die (ent, ent, ent, 100000, MOD_FALLING);
2552 	}
2553 }
2554 
2555 
2556 /*
2557 ============
2558 Q3_SetArmor
2559   Description	:
2560   Return type	: static void
2561   Argument		:  int entID
2562   Argument		: int data
2563 ============
2564 */
Q3_SetArmor(int entID,int data)2565 static void Q3_SetArmor( int entID, int data )
2566 {
2567 	gentity_t	*ent  = &g_entities[entID];
2568 
2569 	if ( !ent )
2570 	{
2571 		G_DebugPrint( WL_WARNING, "Q3_SetArmor: invalid entID %d\n", entID);
2572 		return;
2573 	}
2574 
2575 	if(!ent->client)
2576 	{
2577 		return;
2578 	}
2579 
2580 	ent->client->ps.stats[STAT_ARMOR] = data;
2581 	if ( ent->client->ps.stats[STAT_ARMOR] > ent->client->ps.stats[STAT_MAX_HEALTH] )
2582 	{
2583 		ent->client->ps.stats[STAT_ARMOR] = ent->client->ps.stats[STAT_MAX_HEALTH];
2584 	}
2585 }
2586 
2587 
2588 /*
2589 ============
2590 Q3_SetBState
2591   Description	:
2592   Return type	: static qboolean
2593   Argument		:  int entID
2594   Argument		: const char *bs_name
2595 FIXME: this should be a general NPC wrapper function
2596 	that is called ANY time	a bState is changed...
2597 ============
2598 */
Q3_SetBState(int entID,const char * bs_name)2599 static qboolean Q3_SetBState( int entID, const char *bs_name )
2600 {
2601 	gentity_t	*ent  = &g_entities[entID];
2602 	bState_t	bSID;
2603 
2604 	if ( !ent )
2605 	{
2606 		G_DebugPrint( WL_WARNING, "Q3_SetBState: invalid entID %d\n", entID);
2607 		return qtrue;
2608 	}
2609 
2610 	if ( !ent->NPC )
2611 	{
2612 		G_DebugPrint( WL_ERROR, "Q3_SetBState: '%s' is not an NPC\n", ent->targetname );
2613 		return qtrue;//ok to complete
2614 	}
2615 
2616 	bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
2617 	if ( bSID != (bState_t)-1 )
2618 	{
2619 		if ( bSID == BS_SEARCH || bSID == BS_WANDER )
2620 		{
2621 			//FIXME: Reimplement
2622 
2623 			if( ent->waypoint != WAYPOINT_NONE )
2624 			{
2625 				NPC_BSSearchStart( ent->waypoint, bSID );
2626 			}
2627 			else
2628 			{
2629 				ent->waypoint = NAV_FindClosestWaypointForEnt( ent, WAYPOINT_NONE );
2630 
2631 				if( ent->waypoint != WAYPOINT_NONE )
2632 				{
2633 					NPC_BSSearchStart( ent->waypoint, bSID );
2634 				}
2635 				/*else if( ent->lastWaypoint >=0 && ent->lastWaypoint < num_waypoints )
2636 				{
2637 					NPC_BSSearchStart( ent->lastWaypoint, bSID );
2638 				}
2639 				else if( ent->lastValidWaypoint >=0 && ent->lastValidWaypoint < num_waypoints )
2640 				{
2641 					NPC_BSSearchStart( ent->lastValidWaypoint, bSID );
2642 				}*/
2643 				else
2644 				{
2645 					G_DebugPrint( WL_ERROR, "Q3_SetBState: '%s' is not in a valid waypoint to search from!\n", ent->targetname );
2646 					return qtrue;
2647 				}
2648 			}
2649 		}
2650 
2651 
2652 		ent->NPC->tempBehavior = BS_DEFAULT;//need to clear any temp behaviour
2653 		if ( ent->NPC->behaviorState == BS_NOCLIP && bSID != BS_NOCLIP )
2654 		{//need to rise up out of the floor after noclipping
2655 			ent->r.currentOrigin[2] += 0.125;
2656 			G_SetOrigin( ent, ent->r.currentOrigin );
2657 		}
2658 		ent->NPC->behaviorState = bSID;
2659 		if ( bSID == BS_DEFAULT )
2660 		{
2661 			ent->NPC->defaultBehavior = bSID;
2662 		}
2663 	}
2664 
2665 	ent->NPC->aiFlags &= ~NPCAI_TOUCHED_GOAL;
2666 
2667 //	if ( bSID == BS_FLY )
2668 //	{//FIXME: need a set bState wrapper
2669 //		ent->client->moveType = MT_FLYSWIM;
2670 //	}
2671 //	else
2672 	{
2673 		//FIXME: these are presumptions!
2674 		//Q3_SetGravity( entID, g_gravity->value );
2675 		//ent->client->moveType = MT_RUNJUMP;
2676 	}
2677 
2678 	if ( bSID == BS_NOCLIP )
2679 	{
2680 		ent->client->noclip = qtrue;
2681 	}
2682 	else
2683 	{
2684 		ent->client->noclip = qfalse;
2685 	}
2686 
2687 /*
2688 	if ( bSID == BS_FACE || bSID == BS_POINT_AND_SHOOT || bSID == BS_FACE_ENEMY )
2689 	{
2690 		ent->NPC->aimTime = level.time + 5 * 1000;//try for 5 seconds
2691 		return qfalse;//need to wait for task complete message
2692 	}
2693 */
2694 
2695 //	if ( bSID == BS_SNIPER || bSID == BS_ADVANCE_FIGHT )
2696 	if ( bSID == BS_ADVANCE_FIGHT )
2697 	{
2698 		return qfalse;//need to wait for task complete message
2699 	}
2700 
2701 /*
2702 	if ( bSID == BS_SHOOT || bSID == BS_POINT_AND_SHOOT )
2703 	{//Let them shoot right NOW
2704 		ent->NPC->shotTime = ent->attackDebounceTime = level.time;
2705 	}
2706 */
2707 	if ( bSID == BS_JUMP )
2708 	{
2709 		ent->NPC->jumpState = JS_FACING;
2710 	}
2711 
2712 	return qtrue;//ok to complete
2713 }
2714 
2715 
2716 /*
2717 ============
2718 Q3_SetTempBState
2719   Description	:
2720   Return type	: static qboolean
2721   Argument		:  int entID
2722   Argument		: const char *bs_name
2723 ============
2724 */
Q3_SetTempBState(int entID,const char * bs_name)2725 static qboolean Q3_SetTempBState( int entID, const char *bs_name )
2726 {
2727 	gentity_t	*ent  = &g_entities[entID];
2728 	bState_t	bSID;
2729 
2730 	if ( !ent )
2731 	{
2732 		G_DebugPrint( WL_WARNING, "Q3_SetTempBState: invalid entID %d\n", entID);
2733 		return qtrue;
2734 	}
2735 
2736 	if ( !ent->NPC )
2737 	{
2738 		G_DebugPrint( WL_ERROR, "Q3_SetTempBState: '%s' is not an NPC\n", ent->targetname );
2739 		return qtrue;//ok to complete
2740 	}
2741 
2742 	bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
2743 	if ( bSID != (bState_t)-1 )
2744 	{
2745 		ent->NPC->tempBehavior = bSID;
2746 	}
2747 
2748 /*
2749 	if ( bSID == BS_FACE || bSID == BS_POINT_AND_SHOOT || bSID == BS_FACE_ENEMY )
2750 	{
2751 		ent->NPC->aimTime = level.time + 5 * 1000;//try for 5 seconds
2752 		return qfalse;//need to wait for task complete message
2753 	}
2754 */
2755 
2756 /*
2757 	if ( bSID == BS_SHOOT || bSID == BS_POINT_AND_SHOOT )
2758 	{//Let them shoot right NOW
2759 		ent->NPC->shotTime = ent->attackDebounceTime = level.time;
2760 	}
2761 */
2762 	return qtrue;//ok to complete
2763 }
2764 
2765 
2766 /*
2767 ============
2768 Q3_SetDefaultBState
2769   Description	:
2770   Return type	: static void
2771   Argument		:  int entID
2772   Argument		: const char *bs_name
2773 ============
2774 */
Q3_SetDefaultBState(int entID,const char * bs_name)2775 static void Q3_SetDefaultBState( int entID, const char *bs_name )
2776 {
2777 	gentity_t	*ent  = &g_entities[entID];
2778 	bState_t	bSID;
2779 
2780 	if ( !ent )
2781 	{
2782 		G_DebugPrint( WL_WARNING, "Q3_SetDefaultBState: invalid entID %d\n", entID);
2783 		return;
2784 	}
2785 
2786 	if ( !ent->NPC )
2787 	{
2788 		G_DebugPrint( WL_ERROR, "Q3_SetDefaultBState: '%s' is not an NPC\n", ent->targetname );
2789 		return;
2790 	}
2791 
2792 	bSID = (bState_t)(GetIDForString( BSTable, bs_name ));
2793 	if ( bSID != (bState_t)-1 )
2794 	{
2795 		ent->NPC->defaultBehavior = bSID;
2796 	}
2797 }
2798 
2799 
2800 /*
2801 ============
2802 Q3_SetDPitch
2803   Description	:
2804   Return type	: static void
2805   Argument		:  int entID
2806   Argument		: float data
2807 ============
2808 */
Q3_SetDPitch(int entID,float data)2809 static void Q3_SetDPitch( int entID, float data )
2810 {
2811 	gentity_t	*ent  = &g_entities[entID];
2812 	int pitchMin;
2813 	int pitchMax;
2814 
2815 	if ( !ent )
2816 	{
2817 		G_DebugPrint( WL_WARNING, "Q3_SetDPitch: invalid entID %d\n", entID);
2818 		return;
2819 	}
2820 
2821 	if ( !ent->NPC || !ent->client )
2822 	{
2823 		G_DebugPrint( WL_ERROR, "Q3_SetDPitch: '%s' is not an NPC\n", ent->targetname );
2824 		return;
2825 	}
2826 
2827 	pitchMin = -ent->client->renderInfo.headPitchRangeUp + 1;
2828 	pitchMax = ent->client->renderInfo.headPitchRangeDown - 1;
2829 
2830 	//clamp angle to -180 -> 180
2831 	data = AngleNormalize180( data );
2832 
2833 	//Clamp it to my valid range
2834 	if ( data < -1 )
2835 	{
2836 		if ( data < pitchMin )
2837 		{
2838 			data = pitchMin;
2839 		}
2840 	}
2841 	else if ( data > 1 )
2842 	{
2843 		if ( data > pitchMax )
2844 		{
2845 			data = pitchMax;
2846 		}
2847 	}
2848 
2849 	ent->NPC->lockedDesiredPitch = ent->NPC->desiredPitch = data;
2850 }
2851 
2852 
2853 /*
2854 ============
2855 Q3_SetDYaw
2856   Description	:
2857   Return type	: static void
2858   Argument		:  int entID
2859   Argument		: float data
2860 ============
2861 */
Q3_SetDYaw(int entID,float data)2862 static void Q3_SetDYaw( int entID, float data )
2863 {
2864 	gentity_t	*ent  = &g_entities[entID];
2865 
2866 	if ( !ent )
2867 	{
2868 		G_DebugPrint( WL_WARNING, "Q3_SetDYaw: invalid entID %d\n", entID);
2869 		return;
2870 	}
2871 
2872 	if ( !ent->NPC )
2873 	{
2874 		G_DebugPrint( WL_ERROR, "Q3_SetDYaw: '%s' is not an NPC\n", ent->targetname );
2875 		return;
2876 	}
2877 
2878 	if(!ent->enemy)
2879 	{//don't mess with this if they're aiming at someone
2880 		ent->NPC->lockedDesiredYaw = ent->NPC->desiredYaw = ent->s.angles[1] = data;
2881 	}
2882 	else
2883 	{
2884 		G_DebugPrint( WL_WARNING, "Could not set DYAW: '%s' has an enemy (%s)!\n", ent->targetname, ent->enemy->targetname );
2885 	}
2886 }
2887 
2888 
2889 /*
2890 ============
2891 Q3_SetShootDist
2892   Description	:
2893   Return type	: static void
2894   Argument		:  int entID
2895   Argument		: float data
2896 ============
2897 */
Q3_SetShootDist(int entID,float data)2898 static void Q3_SetShootDist( int entID, float data )
2899 {
2900 	gentity_t	*ent  = &g_entities[entID];
2901 
2902 	if ( !ent )
2903 	{
2904 		G_DebugPrint( WL_WARNING, "Q3_SetShootDist: invalid entID %d\n", entID);
2905 		return;
2906 	}
2907 
2908 	if ( !ent->NPC )
2909 	{
2910 		G_DebugPrint( WL_ERROR, "Q3_SetShootDist: '%s' is not an NPC\n", ent->targetname );
2911 		return;
2912 	}
2913 
2914 	ent->NPC->stats.shootDistance = data;
2915 }
2916 
2917 
2918 /*
2919 ============
2920 Q3_SetVisrange
2921   Description	:
2922   Return type	: static void
2923   Argument		:  int entID
2924   Argument		: float data
2925 ============
2926 */
Q3_SetVisrange(int entID,float data)2927 static void Q3_SetVisrange( int entID, float data )
2928 {
2929 	gentity_t	*ent  = &g_entities[entID];
2930 
2931 	if ( !ent )
2932 	{
2933 		G_DebugPrint( WL_WARNING, "Q3_SetVisrange: invalid entID %d\n", entID);
2934 		return;
2935 	}
2936 
2937 	if ( !ent->NPC )
2938 	{
2939 		G_DebugPrint( WL_ERROR, "Q3_SetVisrange: '%s' is not an NPC\n", ent->targetname );
2940 		return;
2941 	}
2942 
2943 	ent->NPC->stats.visrange = data;
2944 }
2945 
2946 
2947 /*
2948 ============
2949 Q3_SetEarshot
2950   Description	:
2951   Return type	: static void
2952   Argument		:  int entID
2953   Argument		: float data
2954 ============
2955 */
Q3_SetEarshot(int entID,float data)2956 static void Q3_SetEarshot( int entID, float data )
2957 {
2958 	gentity_t	*ent  = &g_entities[entID];
2959 
2960 	if ( !ent )
2961 	{
2962 		G_DebugPrint( WL_WARNING, "Q3_SetEarshot: invalid entID %d\n", entID);
2963 		return;
2964 	}
2965 
2966 	if ( !ent->NPC )
2967 	{
2968 		G_DebugPrint( WL_ERROR, "Q3_SetEarshot: '%s' is not an NPC\n", ent->targetname );
2969 		return;
2970 	}
2971 
2972 	ent->NPC->stats.earshot = data;
2973 }
2974 
2975 
2976 /*
2977 ============
2978 Q3_SetVigilance
2979   Description	:
2980   Return type	: static void
2981   Argument		:  int entID
2982   Argument		: float data
2983 ============
2984 */
Q3_SetVigilance(int entID,float data)2985 static void Q3_SetVigilance( int entID, float data )
2986 {
2987 	gentity_t	*ent  = &g_entities[entID];
2988 
2989 	if ( !ent )
2990 	{
2991 		G_DebugPrint( WL_WARNING, "Q3_SetVigilance: invalid entID %d\n", entID);
2992 		return;
2993 	}
2994 
2995 	if ( !ent->NPC )
2996 	{
2997 		G_DebugPrint( WL_ERROR, "Q3_SetVigilance: '%s' is not an NPC\n", ent->targetname );
2998 		return;
2999 	}
3000 
3001 	ent->NPC->stats.vigilance = data;
3002 }
3003 
3004 
3005 /*
3006 ============
3007 Q3_SetVFOV
3008   Description	:
3009   Return type	: static void
3010   Argument		:  int entID
3011   Argument		: int data
3012 ============
3013 */
Q3_SetVFOV(int entID,int data)3014 static void Q3_SetVFOV( int entID, int data )
3015 {
3016 	gentity_t	*ent  = &g_entities[entID];
3017 
3018 	if ( !ent )
3019 	{
3020 		G_DebugPrint( WL_WARNING, "Q3_SetVFOV: invalid entID %d\n", entID);
3021 		return;
3022 	}
3023 
3024 	if ( !ent->NPC )
3025 	{
3026 		G_DebugPrint( WL_ERROR, "Q3_SetVFOV: '%s' is not an NPC\n", ent->targetname );
3027 		return;
3028 	}
3029 
3030 	ent->NPC->stats.vfov = data;
3031 }
3032 
3033 
3034 /*
3035 ============
3036 Q3_SetHFOV
3037   Description	:
3038   Return type	: static void
3039   Argument		:  int entID
3040   Argument		: int data
3041 ============
3042 */
Q3_SetHFOV(int entID,int data)3043 static void Q3_SetHFOV( int entID, int data )
3044 {
3045 	gentity_t	*ent  = &g_entities[entID];
3046 
3047 	if ( !ent )
3048 	{
3049 		G_DebugPrint( WL_WARNING, "Q3_SetHFOV: invalid entID %d\n", entID);
3050 		return;
3051 	}
3052 
3053 	if ( !ent->NPC )
3054 	{
3055 		G_DebugPrint( WL_ERROR, "Q3_SetHFOV: '%s' is not an NPC\n", ent->targetname );
3056 		return;
3057 	}
3058 
3059 	ent->NPC->stats.hfov = data;
3060 }
3061 
3062 
3063 /*
3064 ============
3065 Q3_SetWidth
3066   Description	:
3067   Return type	: static void
3068   Argument		:  int entID
3069   Argument		: float data
3070 ============
3071 */
Q3_SetWidth(int entID,int data)3072 static void Q3_SetWidth( int entID, int data )
3073 {
3074 	G_DebugPrint( WL_WARNING, "Q3_SetWidth: NOT SUPPORTED IN MP\n");
3075 	return;
3076 }
3077 
3078 /*
3079 ============
3080 Q3_SetTimeScale
3081   Description	:
3082   Return type	: static void
3083   Argument		:  int entID
3084   Argument		: const char *data
3085 ============
3086 */
Q3_SetTimeScale(int entID,const char * data)3087 static void Q3_SetTimeScale( int entID, const char *data )
3088 {
3089 	trap->Cvar_Set("timescale", data);
3090 }
3091 
3092 
3093 /*
3094 ============
3095 Q3_SetInvisible
3096   Description	:
3097   Return type	: static void
3098   Argument		:  int entID
3099   Argument		: qboolean invisible
3100 ============
3101 */
Q3_SetInvisible(int entID,qboolean invisible)3102 static void Q3_SetInvisible( int entID, qboolean invisible )
3103 {
3104 	gentity_t	*self  = &g_entities[entID];
3105 
3106 	if ( !self )
3107 	{
3108 		G_DebugPrint( WL_WARNING, "Q3_SetInvisible: invalid entID %d\n", entID);
3109 		return;
3110 	}
3111 
3112 	if ( invisible )
3113 	{
3114 		self->s.eFlags |= EF_NODRAW;
3115 		if ( self->client )
3116 		{
3117 			self->client->ps.eFlags |= EF_NODRAW;
3118 		}
3119 		self->r.contents = 0;
3120 	}
3121 	else
3122 	{
3123 		self->s.eFlags &= ~EF_NODRAW;
3124 		if ( self->client )
3125 		{
3126 			self->client->ps.eFlags &= ~EF_NODRAW;
3127 		}
3128 	}
3129 }
3130 
3131 /*
3132 ============
3133 Q3_SetVampire
3134   Description	:
3135   Return type	: static void
3136   Argument		:  int entID
3137   Argument		: qboolean vampire
3138 ============
3139 */
Q3_SetVampire(int entID,qboolean vampire)3140 static void Q3_SetVampire( int entID, qboolean vampire )
3141 {
3142 	G_DebugPrint( WL_WARNING, "Q3_SetVampire: NOT SUPPORTED IN MP\n");
3143 	return;
3144 }
3145 /*
3146 ============
3147 Q3_SetGreetAllies
3148   Description	:
3149   Return type	: static void
3150   Argument		:  int entID
3151   Argument		: qboolean greet
3152 ============
3153 */
Q3_SetGreetAllies(int entID,qboolean greet)3154 static void Q3_SetGreetAllies( int entID, qboolean greet )
3155 {
3156 	gentity_t	*self  = &g_entities[entID];
3157 
3158 	if ( !self )
3159 	{
3160 		G_DebugPrint( WL_WARNING, "Q3_SetGreetAllies: invalid entID %d\n", entID);
3161 		return;
3162 	}
3163 
3164 	if ( !self->NPC )
3165 	{
3166 		G_DebugPrint( WL_WARNING, "Q3_SetGreetAllies: ent %s is not an NPC!\n", self->targetname );
3167 		return;
3168 	}
3169 
3170 	if ( greet )
3171 	{
3172 		self->NPC->aiFlags |= NPCAI_GREET_ALLIES;
3173 	}
3174 	else
3175 	{
3176 		self->NPC->aiFlags &= ~NPCAI_GREET_ALLIES;
3177 	}
3178 }
3179 
3180 
3181 /*
3182 ============
3183 Q3_SetViewTarget
3184   Description	:
3185   Return type	: static void
3186   Argument		: int entID
3187   Argument		: const char *name
3188 ============
3189 */
Q3_SetViewTarget(int entID,const char * name)3190 static void Q3_SetViewTarget (int entID, const char *name)
3191 {
3192 	gentity_t	*self  = &g_entities[entID];
3193 	gentity_t	*viewtarget = G_Find( NULL, FOFS(targetname), (char *) name);
3194 	vec3_t		viewspot, selfspot, viewvec, viewangles;
3195 
3196 	if ( !self )
3197 	{
3198 		G_DebugPrint( WL_WARNING, "Q3_SetViewTarget: invalid entID %d\n", entID);
3199 		return;
3200 	}
3201 
3202 	if ( !self->client )
3203 	{
3204 		G_DebugPrint( WL_ERROR, "Q3_SetViewTarget: '%s' is not a player/NPC!\n", self->targetname );
3205 		return;
3206 	}
3207 
3208 	//FIXME: Exception handle here
3209 	if (viewtarget == NULL)
3210 	{
3211 		G_DebugPrint( WL_WARNING, "Q3_SetViewTarget: can't find ViewTarget: '%s'\n", name );
3212 		return;
3213 	}
3214 
3215 	//FIXME: should we set behavior to BS_FACE and keep facing this ent as it moves
3216 	//around for a script-specified length of time...?
3217 	VectorCopy ( self->s.origin, selfspot );
3218 	selfspot[2] += self->client->ps.viewheight;
3219 
3220 	if ( viewtarget->client )
3221 	{
3222 		VectorCopy ( viewtarget->client->renderInfo.eyePoint, viewspot );
3223 	}
3224 	else
3225 	{
3226 		VectorCopy ( viewtarget->s.origin, viewspot );
3227 	}
3228 
3229 	VectorSubtract( viewspot, selfspot, viewvec );
3230 
3231 	vectoangles( viewvec, viewangles );
3232 
3233 	Q3_SetDYaw( entID, viewangles[YAW] );
3234 	Q3_SetDPitch( entID, viewangles[PITCH] );
3235 }
3236 
3237 
3238 /*
3239 ============
3240 Q3_SetWatchTarget
3241   Description	:
3242   Return type	: static void
3243   Argument		: int entID
3244   Argument		: const char *name
3245 ============
3246 */
Q3_SetWatchTarget(int entID,const char * name)3247 static void Q3_SetWatchTarget (int entID, const char *name)
3248 {
3249 	gentity_t	*self  = &g_entities[entID];
3250 	gentity_t	*watchTarget = NULL;
3251 
3252 	if ( !self )
3253 	{
3254 		G_DebugPrint( WL_WARNING, "Q3_SetWatchTarget: invalid entID %d\n", entID);
3255 		return;
3256 	}
3257 
3258 	if ( !self->NPC )
3259 	{
3260 		G_DebugPrint( WL_ERROR, "Q3_SetWatchTarget: '%s' is not an NPC!\n", self->targetname );
3261 		return;
3262 	}
3263 
3264 	if ( Q_stricmp( "NULL", name ) == 0 || Q_stricmp( "NONE", name ) == 0 || ( self->targetname && (Q_stricmp( self->targetname, name ) == 0) ) )
3265 	{//clearing watchTarget
3266 		self->NPC->watchTarget = NULL;
3267 	}
3268 
3269 	watchTarget = G_Find( NULL, FOFS(targetname), (char *) name);
3270 	if ( watchTarget == NULL )
3271 	{
3272 		G_DebugPrint( WL_WARNING, "Q3_SetWatchTarget: can't find WatchTarget: '%s'\n", name );
3273 		return;
3274 	}
3275 
3276 	self->NPC->watchTarget = watchTarget;
3277 }
3278 
Q3_SetLoopSound(int entID,const char * name)3279 void Q3_SetLoopSound(int entID, const char *name)
3280 {
3281 	sfxHandle_t	index;
3282 	gentity_t	*self  = &g_entities[entID];
3283 
3284 	if ( Q_stricmp( "NULL", name ) == 0 || Q_stricmp( "NONE", name )==0)
3285 	{
3286 		self->s.loopSound = 0;
3287 		self->s.loopIsSoundset = qfalse;
3288 		return;
3289 	}
3290 
3291 	index = G_SoundIndex( (char*)name );
3292 
3293 	if (index)
3294 	{
3295 		self->s.loopSound = index;
3296 		self->s.loopIsSoundset = qfalse;
3297 	}
3298 	else
3299 	{
3300 		G_DebugPrint( WL_WARNING, "Q3_SetLoopSound: can't find sound file: '%s'\n", name );
3301 	}
3302 }
3303 
Q3_SetICARUSFreeze(int entID,const char * name,qboolean freeze)3304 void Q3_SetICARUSFreeze( int entID, const char *name, qboolean freeze )
3305 {
3306 	gentity_t	*self  = G_Find( NULL, FOFS(targetname), name );
3307 	if ( !self )
3308 	{//hmm, targetname failed, try script_targetname?
3309 		self = G_Find( NULL, FOFS(script_targetname), name );
3310 	}
3311 
3312 	if ( !self )
3313 	{
3314 		G_DebugPrint( WL_WARNING, "Q3_SetICARUSFreeze: invalid ent %s\n", name);
3315 		return;
3316 	}
3317 
3318 	if ( freeze )
3319 	{
3320 		self->r.svFlags |= SVF_ICARUS_FREEZE;
3321 	}
3322 	else
3323 	{
3324 		self->r.svFlags &= ~SVF_ICARUS_FREEZE;
3325 	}
3326 }
3327 
3328 /*
3329 ============
3330 Q3_SetViewEntity
3331   Description	:
3332   Return type	: static void
3333   Argument		: int entID
3334   Argument		: const char *name
3335 ============
3336 */
Q3_SetViewEntity(int entID,const char * name)3337 void Q3_SetViewEntity(int entID, const char *name)
3338 {
3339 	G_DebugPrint( WL_WARNING, "Q3_SetViewEntity currently unsupported in MP, ask if you need it.\n");
3340 }
3341 
3342 /*
3343 ============
3344 Q3_SetWeapon
3345   Description	:
3346   Return type	: static void
3347   Argument		: int entID
3348   Argument		: const char *wp_name
3349 ============
3350 */
3351 extern void ChangeWeapon( gentity_t *ent, int newWeapon );
Q3_SetWeapon(int entID,const char * wp_name)3352 static void Q3_SetWeapon (int entID, const char *wp_name)
3353 {
3354 	gentity_t	*ent  = &g_entities[entID];
3355 	int		wp = GetIDForString( WPTable, wp_name );
3356 
3357 	ent->client->ps.stats[STAT_WEAPONS] = (1<<wp);
3358 	ChangeWeapon( ent, wp );
3359 }
3360 
3361 /*
3362 ============
3363 Q3_SetItem
3364   Description	:
3365   Return type	: static void
3366   Argument		: int entID
3367   Argument		: const char *wp_name
3368 ============
3369 */
Q3_SetItem(int entID,const char * item_name)3370 static void Q3_SetItem (int entID, const char *item_name)
3371 { //rww - unused in mp
3372 	G_DebugPrint( WL_WARNING, "Q3_SetItem: NOT SUPPORTED IN MP\n");
3373 	return;
3374 }
3375 
3376 
3377 
3378 /*
3379 ============
3380 Q3_SetWalkSpeed
3381   Description	:
3382   Return type	: static void
3383   Argument		: int entID
3384   Argument		: int int_data
3385 ============
3386 */
Q3_SetWalkSpeed(int entID,int int_data)3387 static void Q3_SetWalkSpeed (int entID, int int_data)
3388 {
3389 	gentity_t	*self  = &g_entities[entID];
3390 
3391 	if ( !self )
3392 	{
3393 		G_DebugPrint( WL_WARNING, "Q3_SetWalkSpeed: invalid entID %d\n", entID);
3394 		return;
3395 	}
3396 
3397 	if ( !self->NPC )
3398 	{
3399 		G_DebugPrint( WL_ERROR, "Q3_SetWalkSpeed: '%s' is not an NPC!\n", self->targetname );
3400 		return;
3401 	}
3402 
3403 	if(int_data == 0)
3404 	{
3405 		self->NPC->stats.walkSpeed = self->client->ps.speed = 1;
3406 	}
3407 
3408 	self->NPC->stats.walkSpeed = self->client->ps.speed = int_data;
3409 }
3410 
3411 
3412 /*
3413 ============
3414 Q3_SetRunSpeed
3415   Description	:
3416   Return type	: static void
3417   Argument		: int entID
3418   Argument		: int int_data
3419 ============
3420 */
Q3_SetRunSpeed(int entID,int int_data)3421 static void Q3_SetRunSpeed (int entID, int int_data)
3422 {
3423 	gentity_t	*self  = &g_entities[entID];
3424 
3425 	if ( !self )
3426 	{
3427 		G_DebugPrint( WL_WARNING, "Q3_SetRunSpeed: invalid entID %d\n", entID);
3428 		return;
3429 	}
3430 
3431 	if ( !self->NPC )
3432 	{
3433 		G_DebugPrint( WL_ERROR, "Q3_SetRunSpeed: '%s' is not an NPC!\n", self->targetname );
3434 		return;
3435 	}
3436 
3437 	if(int_data == 0)
3438 	{
3439 		self->NPC->stats.runSpeed = self->client->ps.speed = 1;
3440 	}
3441 
3442 	self->NPC->stats.runSpeed = self->client->ps.speed = int_data;
3443 }
3444 
3445 
3446 /*
3447 ============
3448 Q3_SetYawSpeed
3449   Description	:
3450   Return type	: static void
3451   Argument		: int entID
3452   Argument		: float float_data
3453 ============
3454 */
Q3_SetYawSpeed(int entID,float float_data)3455 static void Q3_SetYawSpeed (int entID, float float_data)
3456 {
3457 	gentity_t	*self  = &g_entities[entID];
3458 
3459 	if ( !self )
3460 	{
3461 		G_DebugPrint( WL_WARNING, "Q3_SetYawSpeed: invalid entID %d\n", entID);
3462 		return;
3463 	}
3464 
3465 	if ( !self->NPC )
3466 	{
3467 		G_DebugPrint( WL_ERROR, "Q3_SetYawSpeed: '%s' is not an NPC!\n", self->targetname );
3468 		return;
3469 	}
3470 
3471 	self->NPC->stats.yawSpeed = float_data;
3472 }
3473 
3474 
3475 /*
3476 ============
3477 Q3_SetAggression
3478   Description	:
3479   Return type	: static void
3480   Argument		: int entID
3481   Argument		: int int_data
3482 ============
3483 */
Q3_SetAggression(int entID,int int_data)3484 static void Q3_SetAggression(int entID, int int_data)
3485 {
3486 	gentity_t	*self  = &g_entities[entID];
3487 
3488 
3489 	if ( !self )
3490 	{
3491 		G_DebugPrint( WL_WARNING, "Q3_SetAggression: invalid entID %d\n", entID);
3492 		return;
3493 	}
3494 
3495 	if ( !self->NPC )
3496 	{
3497 		G_DebugPrint( WL_ERROR, "Q3_SetAggression: '%s' is not an NPC!\n", self->targetname );
3498 		return;
3499 	}
3500 
3501 	if(int_data < 1 || int_data > 5)
3502 		return;
3503 
3504 	self->NPC->stats.aggression = int_data;
3505 }
3506 
3507 
3508 /*
3509 ============
3510 Q3_SetAim
3511   Description	:
3512   Return type	: static void
3513   Argument		: int entID
3514   Argument		: int int_data
3515 ============
3516 */
Q3_SetAim(int entID,int int_data)3517 static void Q3_SetAim(int entID, int int_data)
3518 {
3519 	gentity_t	*self  = &g_entities[entID];
3520 
3521 	if ( !self )
3522 	{
3523 		G_DebugPrint( WL_WARNING, "Q3_SetAim: invalid entID %d\n", entID);
3524 		return;
3525 	}
3526 
3527 	if ( !self->NPC )
3528 	{
3529 		G_DebugPrint( WL_ERROR, "Q3_SetAim: '%s' is not an NPC!\n", self->targetname );
3530 		return;
3531 	}
3532 
3533 	if(int_data < 1 || int_data > 5)
3534 		return;
3535 
3536 	self->NPC->stats.aim = int_data;
3537 }
3538 
3539 
3540 /*
3541 ============
3542 Q3_SetFriction
3543   Description	:
3544   Return type	: static void
3545   Argument		: int entID
3546   Argument		: int int_data
3547 ============
3548 */
Q3_SetFriction(int entID,int int_data)3549 static void Q3_SetFriction(int entID, int int_data)
3550 {
3551 	gentity_t	*self  = &g_entities[entID];
3552 
3553 	if ( !self )
3554 	{
3555 		G_DebugPrint( WL_WARNING, "Q3_SetFriction: invalid entID %d\n", entID);
3556 		return;
3557 	}
3558 
3559 	if ( !self->client )
3560 	{
3561 		G_DebugPrint( WL_ERROR, "Q3_SetFriction: '%s' is not an NPC/player!\n", self->targetname );
3562 		return;
3563 	}
3564 
3565 	G_DebugPrint( WL_WARNING, "Q3_SetFriction currently unsupported in MP\n");
3566 	//	self->client->ps.friction = int_data;
3567 }
3568 
3569 
3570 /*
3571 ============
3572 Q3_SetGravity
3573   Description	:
3574   Return type	: static void
3575   Argument		: int entID
3576   Argument		: float float_data
3577 ============
3578 */
Q3_SetGravity(int entID,float float_data)3579 static void Q3_SetGravity(int entID, float float_data)
3580 {
3581 	gentity_t	*self  = &g_entities[entID];
3582 
3583 	if ( !self )
3584 	{
3585 		G_DebugPrint( WL_WARNING, "Q3_SetGravity: invalid entID %d\n", entID);
3586 		return;
3587 	}
3588 
3589 	if ( !self->client )
3590 	{
3591 		G_DebugPrint( WL_ERROR, "Q3_SetGravity: '%s' is not an NPC/player!\n", self->targetname );
3592 		return;
3593 	}
3594 
3595 	//FIXME: what if we want to return them to normal global gravity?
3596 	if ( self->NPC )
3597 	{
3598 		self->NPC->aiFlags |= NPCAI_CUSTOM_GRAVITY;
3599 	}
3600 	self->client->ps.gravity = float_data;
3601 }
3602 
3603 
3604 /*
3605 ============
3606 Q3_SetWait
3607   Description	:
3608   Return type	: static void
3609   Argument		: int entID
3610   Argument		: float float_data
3611 ============
3612 */
Q3_SetWait(int entID,float float_data)3613 static void Q3_SetWait(int entID, float float_data)
3614 {
3615 	gentity_t	*self  = &g_entities[entID];
3616 
3617 	if ( !self )
3618 	{
3619 		G_DebugPrint( WL_WARNING, "Q3_SetWait: invalid entID %d\n", entID);
3620 		return;
3621 	}
3622 
3623 	self->wait = float_data;
3624 }
3625 
3626 
Q3_SetShotSpacing(int entID,int int_data)3627 static void Q3_SetShotSpacing(int entID, int int_data)
3628 {
3629 	gentity_t	*self  = &g_entities[entID];
3630 
3631 	if ( !self )
3632 	{
3633 		G_DebugPrint( WL_WARNING, "Q3_SetShotSpacing: invalid entID %d\n", entID);
3634 		return;
3635 	}
3636 
3637 	if ( !self->NPC )
3638 	{
3639 		G_DebugPrint( WL_ERROR, "Q3_SetShotSpacing: '%s' is not an NPC!\n", self->targetname );
3640 		return;
3641 	}
3642 
3643 	self->NPC->aiFlags &= ~NPCAI_BURST_WEAPON;
3644 	self->NPC->burstSpacing = int_data;
3645 }
3646 
3647 /*
3648 ============
3649 Q3_SetFollowDist
3650   Description	:
3651   Return type	: static void
3652   Argument		: int entID
3653   Argument		: float float_data
3654 ============
3655 */
Q3_SetFollowDist(int entID,float float_data)3656 static void Q3_SetFollowDist(int entID, float float_data)
3657 {
3658 	gentity_t	*self  = &g_entities[entID];
3659 
3660 	if ( !self )
3661 	{
3662 		G_DebugPrint( WL_WARNING, "Q3_SetFollowDist: invalid entID %d\n", entID);
3663 		return;
3664 	}
3665 
3666 	if ( !self->client || !self->NPC )
3667 	{
3668 		G_DebugPrint( WL_ERROR, "Q3_SetFollowDist: '%s' is not an NPC!\n", self->targetname );
3669 		return;
3670 	}
3671 
3672 	self->NPC->followDist = float_data;
3673 }
3674 
3675 
3676 /*
3677 ============
3678 Q3_SetScale
3679   Description	:
3680   Return type	: static void
3681   Argument		: int entID
3682   Argument		: float float_data
3683 ============
3684 */
Q3_SetScale(int entID,float float_data)3685 static void Q3_SetScale(int entID, float float_data)
3686 {
3687 	gentity_t	*self  = &g_entities[entID];
3688 
3689 	if ( !self )
3690 	{
3691 		G_DebugPrint( WL_WARNING, "Q3_SetScale: invalid entID %d\n", entID);
3692 		return;
3693 	}
3694 
3695 	if (self->client)
3696 	{
3697 		self->client->ps.iModelScale = float_data*100.0f;
3698 	}
3699 	else
3700 	{
3701 		self->s.iModelScale = float_data*100.0f;
3702 	}
3703 }
3704 
3705 /*
3706 ============
3707 Q3_GameSideCheckStringCounterIncrement
3708   Description	:
3709   Return type	: static float
3710   Argument		: const char *string
3711 ============
3712 */
Q3_GameSideCheckStringCounterIncrement(const char * string)3713 static float Q3_GameSideCheckStringCounterIncrement( const char *string )
3714 {
3715 	char	*numString;
3716 	float	val = 0.0f;
3717 
3718 	if ( string[0] == '+' )
3719 	{//We want to increment whatever the value is by whatever follows the +
3720 		if ( string[1] )
3721 		{
3722 			numString = (char *)&string[1];
3723 			val = atof( numString );
3724 		}
3725 	}
3726 	else if ( string[0] == '-' )
3727 	{//we want to decrement
3728 		if ( string[1] )
3729 		{
3730 			numString = (char *)&string[1];
3731 			val = atof( numString ) * -1;
3732 		}
3733 	}
3734 
3735 	return val;
3736 }
3737 
3738 /*
3739 ============
3740 Q3_SetCount
3741   Description	:
3742   Return type	: static void
3743   Argument		: int entID
3744   Argument		: const char *data
3745 ============
3746 */
Q3_SetCount(int entID,const char * data)3747 static void Q3_SetCount(int entID, const char *data)
3748 {
3749 	gentity_t	*self  = &g_entities[entID];
3750 	float		val = 0.0f;
3751 
3752 	//FIXME: use FOFS() stuff here to make a generic entity field setting?
3753 	if ( !self )
3754 	{
3755 		G_DebugPrint( WL_WARNING, "Q3_SetCount: invalid entID %d\n", entID);
3756 		return;
3757 	}
3758 
3759 	if ( (val = Q3_GameSideCheckStringCounterIncrement( data )) )
3760 	{
3761 		self->count += (int)(val);
3762 	}
3763 	else
3764 	{
3765 		self->count = atoi((char *) data);
3766 	}
3767 }
3768 
3769 
3770 /*
3771 ============
3772 Q3_SetTargetName
3773   Description	:
3774   Return type	: static void
3775   Argument		: int entID
3776   Argument		: const char *targetname
3777 ============
3778 */
Q3_SetTargetName(int entID,const char * targetname)3779 static void Q3_SetTargetName (int entID, const char *targetname)
3780 {
3781 	gentity_t	*self  = &g_entities[entID];
3782 
3783 	if ( !self )
3784 	{
3785 		G_DebugPrint( WL_WARNING, "Q3_SetTargetName: invalid entID %d\n", entID);
3786 		return;
3787 	}
3788 
3789 	if(!Q_stricmp("NULL", ((char *)targetname)))
3790 	{
3791 		self->targetname = NULL;
3792 	}
3793 	else
3794 	{
3795 		self->targetname = G_NewString( targetname );
3796 	}
3797 }
3798 
3799 
3800 /*
3801 ============
3802 Q3_SetTarget
3803   Description	:
3804   Return type	: static void
3805   Argument		: int entID
3806   Argument		: const char *target
3807 ============
3808 */
Q3_SetTarget(int entID,const char * target)3809 static void Q3_SetTarget (int entID, const char *target)
3810 {
3811 	gentity_t	*self  = &g_entities[entID];
3812 
3813 	if ( !self )
3814 	{
3815 		G_DebugPrint( WL_WARNING, "Q3_SetTarget: invalid entID %d\n", entID);
3816 		return;
3817 	}
3818 
3819 	if(!Q_stricmp("NULL", ((char *)target)))
3820 	{
3821 		self->target = NULL;
3822 	}
3823 	else
3824 	{
3825 		self->target = G_NewString( target );
3826 	}
3827 }
3828 
3829 /*
3830 ============
3831 Q3_SetTarget2
3832   Description	:
3833   Return type	: static void
3834   Argument		: int entID
3835   Argument		: const char *target
3836 ============
3837 */
Q3_SetTarget2(int entID,const char * target2)3838 static void Q3_SetTarget2 (int entID, const char *target2)
3839 {
3840 	G_DebugPrint( WL_WARNING, "Q3_SetTarget2 does not exist in MP\n");
3841 	/*
3842 	sharedEntity_t	*self  = SV_GentityNum(entID);
3843 
3844 	if ( !self )
3845 	{
3846 		G_DebugPrint( WL_WARNING, "Q3_SetTarget2: invalid entID %d\n", entID);
3847 		return;
3848 	}
3849 
3850 	if(!Q_stricmp("NULL", ((char *)target2)))
3851 	{
3852 		self->target2 = NULL;
3853 	}
3854 	else
3855 	{
3856 		self->target2 = G_NewString( target2 );
3857 	}
3858 	*/
3859 }
3860 /*
3861 ============
3862 Q3_SetRemoveTarget
3863   Description	:
3864   Return type	: static void
3865   Argument		: int entID
3866   Argument		: const char *target
3867 ============
3868 */
Q3_SetRemoveTarget(int entID,const char * target)3869 static void Q3_SetRemoveTarget (int entID, const char *target)
3870 {
3871 	gentity_t	*self  = &g_entities[entID];
3872 
3873 	if ( !self )
3874 	{
3875 		G_DebugPrint( WL_WARNING, "Q3_SetRemoveTarget: invalid entID %d\n", entID);
3876 		return;
3877 	}
3878 
3879 	if ( !self->NPC )
3880 	{
3881 		G_DebugPrint( WL_ERROR, "Q3_SetRemoveTarget: '%s' is not an NPC!\n", self->targetname );
3882 		return;
3883 	}
3884 
3885 	if( !Q_stricmp("NULL", ((char *)target)) )
3886 	{
3887 		self->target3 = NULL;
3888 	}
3889 	else
3890 	{
3891 		self->target3 = G_NewString( target );
3892 	}
3893 }
3894 
3895 
3896 /*
3897 ============
3898 Q3_SetPainTarget
3899   Description	:
3900   Return type	: void
3901   Argument		: int entID
3902   Argument		: const char *targetname
3903 ============
3904 */
Q3_SetPainTarget(int entID,const char * targetname)3905 static void Q3_SetPainTarget (int entID, const char *targetname)
3906 {
3907 	G_DebugPrint( WL_WARNING, "Q3_SetPainTarget: NOT SUPPORTED IN MP\n");
3908 	/*
3909 	sharedEntity_t	*self  = SV_GentityNum(entID);
3910 
3911 	if ( !self )
3912 	{
3913 		G_DebugPrint( WL_WARNING, "Q3_SetPainTarget: invalid entID %d\n", entID);
3914 		return;
3915 	}
3916 
3917 	if(Q_stricmp("NULL", ((char *)targetname)) == 0)
3918 	{
3919 		self->paintarget = NULL;
3920 	}
3921 	else
3922 	{
3923 		self->paintarget = G_NewString((char *)targetname);
3924 	}
3925 	*/
3926 }
3927 
3928 /*
3929 ============
3930 Q3_SetFullName
3931   Description	:
3932   Return type	: static void
3933   Argument		: int entID
3934   Argument		: const char *fullName
3935 ============
3936 */
Q3_SetFullName(int entID,const char * fullName)3937 static void Q3_SetFullName (int entID, const char *fullName)
3938 {
3939 	gentity_t	*self  = &g_entities[entID];
3940 
3941 	if ( !self )
3942 	{
3943 		G_DebugPrint( WL_WARNING, "Q3_SetFullName: invalid entID %d\n", entID);
3944 		return;
3945 	}
3946 
3947 	if(!Q_stricmp("NULL", ((char *)fullName)))
3948 	{
3949 		self->fullName = NULL;
3950 	}
3951 	else
3952 	{
3953 		self->fullName = G_NewString( fullName );
3954 	}
3955 }
3956 
Q3_SetMusicState(const char * dms)3957 static void Q3_SetMusicState( const char *dms )
3958 {
3959 	G_DebugPrint( WL_WARNING, "Q3_SetMusicState: NOT SUPPORTED IN MP\n");
3960 	return;
3961 }
3962 
Q3_SetForcePowerLevel(int entID,int forcePower,int forceLevel)3963 static void Q3_SetForcePowerLevel ( int entID, int forcePower, int forceLevel )
3964 {
3965 	gentity_t	*self  = &g_entities[entID];
3966 
3967 	if ( forcePower < FP_FIRST || forceLevel >= NUM_FORCE_POWERS )
3968 	{
3969 		G_DebugPrint( WL_ERROR, "Q3_SetForcePowerLevel: Force Power index %d out of range (%d-%d)\n", forcePower, FP_FIRST, (NUM_FORCE_POWERS-1) );
3970 		return;
3971 	}
3972 
3973 	if ( forceLevel < 0 || forceLevel >= NUM_FORCE_POWER_LEVELS )
3974 	{
3975 		if ( forcePower != FP_SABER_OFFENSE || forceLevel >= SS_NUM_SABER_STYLES )
3976 		{
3977 			G_DebugPrint( WL_ERROR, "Q3_SetForcePowerLevel: Force power setting %d out of range (0-3)\n", forceLevel );
3978 			return;
3979 		}
3980 	}
3981 
3982 	if ( !self )
3983 	{
3984 		G_DebugPrint( WL_ERROR, "Q3_SetForcePowerLevel: invalid entID %d\n", entID);
3985 		return;
3986 	}
3987 
3988 	if ( !self->client )
3989 	{
3990 		G_DebugPrint( WL_ERROR, "Q3_SetForcePowerLevel: ent %s is not a player or NPC\n", self->targetname );
3991 		return;
3992 	}
3993 
3994 	self->client->ps.fd.forcePowerLevel[forcePower] = forceLevel;
3995 	if ( forceLevel )
3996 	{
3997 		self->client->ps.fd.forcePowersKnown |= ( 1 << forcePower );
3998 	}
3999 	else
4000 	{
4001 		self->client->ps.fd.forcePowersKnown &= ~( 1 << forcePower );
4002 	}
4003 }
4004 /*
4005 ============
4006 Q3_SetParm
4007   Description	:
4008   Return type	: void
4009   Argument		: int entID
4010   Argument		: int parmNum
4011   Argument		: const char *parmValue
4012 ============
4013 */
Q3_SetParm(int entID,int parmNum,const char * parmValue)4014 void Q3_SetParm (int entID, int parmNum, const char *parmValue)
4015 {
4016 	gentity_t	*ent = &g_entities[entID];
4017 	float		val;
4018 
4019 	if ( !ent )
4020 	{
4021 		G_DebugPrint( WL_WARNING, "Q3_SetParm: invalid entID %d\n", entID);
4022 		return;
4023 	}
4024 
4025 	if ( parmNum < 0 || parmNum >= MAX_PARMS )
4026 	{
4027 		G_DebugPrint( WL_WARNING, "SET_PARM: parmNum %d out of range!\n", parmNum );
4028 		return;
4029 	}
4030 
4031 	if( !ent->parms )
4032 	{
4033 		ent->parms = (parms_t *)G_Alloc( sizeof(parms_t) );
4034 		memset( ent->parms, 0, sizeof(parms_t) );
4035 	}
4036 
4037 	if ( (val = Q3_GameSideCheckStringCounterIncrement( parmValue )) )
4038 	{
4039 		val += atof( ent->parms->parm[parmNum] );
4040 		Com_sprintf( ent->parms->parm[parmNum], sizeof(ent->parms->parm[parmNum]), "%f", val );
4041 	}
4042 	else
4043 	{//Just copy the string
4044 		//copy only 16 characters
4045 		strncpy( ent->parms->parm[parmNum], parmValue, sizeof(ent->parms->parm[parmNum]) );
4046 		//set the last character to null in case we had to truncate their passed string
4047 		if ( ent->parms->parm[parmNum][sizeof(ent->parms->parm[parmNum]) - 1] != 0 )
4048 		{//Tried to set a string that is too long
4049 			ent->parms->parm[parmNum][sizeof(ent->parms->parm[parmNum]) - 1] = 0;
4050 			G_DebugPrint( WL_WARNING, "SET_PARM: parm%d string too long, truncated to '%s'!\n", parmNum, ent->parms->parm[parmNum] );
4051 		}
4052 	}
4053 }
4054 
4055 
4056 
4057 /*
4058 =============
4059 Q3_SetCaptureGoal
4060 
4061 Sets the capture spot goal of an entity
4062 =============
4063 */
Q3_SetCaptureGoal(int entID,const char * name)4064 static void Q3_SetCaptureGoal( int entID, const char *name )
4065 {
4066 	gentity_t	*ent  = &g_entities[entID];
4067 	gentity_t	*goal = G_Find( NULL, FOFS(targetname), (char *) name);
4068 
4069 	if ( !ent )
4070 	{
4071 		G_DebugPrint( WL_WARNING, "Q3_SetCaptureGoal: invalid entID %d\n", entID);
4072 		return;
4073 	}
4074 
4075 	if ( !ent->NPC )
4076 	{
4077 		G_DebugPrint( WL_ERROR, "Q3_SetCaptureGoal: '%s' is not an NPC!\n", ent->targetname );
4078 		return;
4079 	}
4080 
4081 	//FIXME: Exception handle here
4082 	if (goal == NULL)
4083 	{
4084 		G_DebugPrint( WL_ERROR, "Q3_SetCaptureGoal: can't find CaptureGoal target: '%s'\n", name );
4085 		return;
4086 	}
4087 
4088 	if(ent->NPC)
4089 	{
4090 		ent->NPC->captureGoal = goal;
4091 		ent->NPC->goalEntity = goal;
4092 		ent->NPC->goalTime = level.time + 100000;
4093 	}
4094 }
4095 
4096 /*
4097 =============
4098 Q3_SetEvent
4099 
4100 ?
4101 =============
4102 */
Q3_SetEvent(int entID,const char * event_name)4103 static void Q3_SetEvent( int entID, const char *event_name )
4104 { //rwwFIXMEFIXME: Use in MP?
4105 	G_DebugPrint( WL_WARNING, "Q3_SetEvent: NOT SUPPORTED IN MP (may be in future, ask if needed)\n");
4106 	return;
4107 }
4108 
4109 /*
4110 ============
4111 Q3_SetIgnorePain
4112 
4113 ?
4114 ============
4115 */
Q3_SetIgnorePain(int entID,qboolean data)4116 static void Q3_SetIgnorePain( int entID, qboolean data)
4117 {
4118 	gentity_t	*ent  = &g_entities[entID];
4119 
4120 	if ( !ent )
4121 	{
4122 		G_DebugPrint( WL_WARNING, "Q3_SetIgnorePain: invalid entID %d\n", entID);
4123 		return;
4124 	}
4125 
4126 	if ( !ent->NPC )
4127 	{
4128 		G_DebugPrint( WL_ERROR, "Q3_SetIgnorePain: '%s' is not an NPC!\n", ent->targetname );
4129 		return;
4130 	}
4131 
4132 	ent->NPC->ignorePain = data;
4133 }
4134 
4135 /*
4136 ============
4137 Q3_SetIgnoreEnemies
4138 
4139 ?
4140 ============
4141 */
Q3_SetIgnoreEnemies(int entID,qboolean data)4142 static void Q3_SetIgnoreEnemies( int entID, qboolean data)
4143 {
4144 
4145 	G_DebugPrint( WL_WARNING, "Q3_SetIgnoreEnemies: NOT SUPPORTED IN MP");
4146 	return;
4147 }
4148 
4149 /*
4150 ============
4151 Q3_SetIgnoreAlerts
4152 
4153 ?
4154 ============
4155 */
Q3_SetIgnoreAlerts(int entID,qboolean data)4156 static void Q3_SetIgnoreAlerts( int entID, qboolean data)
4157 {
4158 	gentity_t	*ent  = &g_entities[entID];
4159 
4160 	if ( !ent )
4161 	{
4162 		G_DebugPrint( WL_WARNING, "Q3_SetIgnoreAlerts: invalid entID %d\n", entID);
4163 		return;
4164 	}
4165 
4166 	if ( !ent->NPC )
4167 	{
4168 		G_DebugPrint( WL_ERROR, "Q3_SetIgnoreAlerts: '%s' is not an NPC!\n", ent->targetname );
4169 		return;
4170 	}
4171 
4172 	if(data)
4173 	{
4174 		ent->NPC->scriptFlags |= SCF_IGNORE_ALERTS;
4175 	}
4176 	else
4177 	{
4178 		ent->NPC->scriptFlags &= ~SCF_IGNORE_ALERTS;
4179 	}
4180 }
4181 
4182 
4183 /*
4184 ============
4185 Q3_SetNoTarget
4186 
4187 ?
4188 ============
4189 */
Q3_SetNoTarget(int entID,qboolean data)4190 static void Q3_SetNoTarget( int entID, qboolean data)
4191 {
4192 	gentity_t	*ent  = &g_entities[entID];
4193 
4194 	if ( !ent )
4195 	{
4196 		G_DebugPrint( WL_WARNING, "Q3_SetNoTarget: invalid entID %d\n", entID);
4197 		return;
4198 	}
4199 
4200 	if(data)
4201 		ent->flags |= FL_NOTARGET;
4202 	else
4203 		ent->flags &= ~FL_NOTARGET;
4204 }
4205 
4206 /*
4207 ============
4208 Q3_SetDontShoot
4209 
4210 ?
4211 ============
4212 */
Q3_SetDontShoot(int entID,qboolean add)4213 static void Q3_SetDontShoot( int entID, qboolean add)
4214 {
4215 	gentity_t	*ent  = &g_entities[entID];
4216 
4217 	if ( !ent )
4218 	{
4219 		G_DebugPrint( WL_WARNING, "Q3_SetDontShoot: invalid entID %d\n", entID);
4220 		return;
4221 	}
4222 
4223 	if(add)
4224 	{
4225 		ent->flags |= FL_DONT_SHOOT;
4226 	}
4227 	else
4228 	{
4229 		ent->flags &= ~FL_DONT_SHOOT;
4230 	}
4231 }
4232 
4233 /*
4234 ============
4235 Q3_SetDontFire
4236 
4237 ?
4238 ============
4239 */
Q3_SetDontFire(int entID,qboolean add)4240 static void Q3_SetDontFire( int entID, qboolean add)
4241 {
4242 	gentity_t	*ent  = &g_entities[entID];
4243 
4244 	if ( !ent )
4245 	{
4246 		G_DebugPrint( WL_WARNING, "Q3_SetDontFire: invalid entID %d\n", entID);
4247 		return;
4248 	}
4249 
4250 	if ( !ent->NPC )
4251 	{
4252 		G_DebugPrint( WL_ERROR, "Q3_SetDontFire: '%s' is not an NPC!\n", ent->targetname );
4253 		return;
4254 	}
4255 
4256 	if(add)
4257 	{
4258 		ent->NPC->scriptFlags |= SCF_DONT_FIRE;
4259 	}
4260 	else
4261 	{
4262 		ent->NPC->scriptFlags &= ~SCF_DONT_FIRE;
4263 	}
4264 }
4265 
4266 /*
4267 ============
4268 Q3_SetFireWeapon
4269 
4270 ?
4271 ============
4272 */
Q3_SetFireWeapon(int entID,qboolean add)4273 static void Q3_SetFireWeapon(int entID, qboolean add)
4274 {
4275 	gentity_t	*ent  = &g_entities[entID];
4276 
4277 	if ( !ent )
4278 	{
4279 		G_DebugPrint( WL_WARNING, "Q3_FireWeapon: invalid entID %d\n", entID);
4280 		return;
4281 	}
4282 
4283 	if ( !ent->NPC )
4284 	{
4285 		G_DebugPrint( WL_ERROR, "Q3_SetFireWeapon: '%s' is not an NPC!\n", ent->targetname );
4286 		return;
4287 	}
4288 
4289 	if(add)
4290 	{
4291 		ent->NPC->scriptFlags |= SCF_FIRE_WEAPON;
4292 	}
4293 	else
4294 	{
4295 		ent->NPC->scriptFlags &= ~SCF_FIRE_WEAPON;
4296 	}
4297 }
4298 
4299 
4300 /*
4301 ============
4302 Q3_SetInactive
4303 
4304 ?
4305 ============
4306 */
Q3_SetInactive(int entID,qboolean add)4307 static void Q3_SetInactive(int entID, qboolean add)
4308 {
4309 	gentity_t	*ent  = &g_entities[entID];
4310 
4311 	if ( !ent )
4312 	{
4313 		G_DebugPrint( WL_WARNING, "Q3_SetInactive: invalid entID %d\n", entID);
4314 		return;
4315 	}
4316 
4317 	if(add)
4318 	{
4319 		ent->flags |= FL_INACTIVE;
4320 	}
4321 	else
4322 	{
4323 		ent->flags &= ~FL_INACTIVE;
4324 	}
4325 }
4326 
4327 /*
4328 ============
4329 Q3_SetFuncUsableVisible
4330 
4331 ?
4332 ============
4333 */
Q3_SetFuncUsableVisible(int entID,qboolean visible)4334 static void Q3_SetFuncUsableVisible(int entID, qboolean visible )
4335 {
4336 	gentity_t	*ent  = &g_entities[entID];
4337 
4338 	if ( !ent )
4339 	{
4340 		G_DebugPrint( WL_WARNING, "Q3_SetFuncUsableVisible: invalid entID %d\n", entID);
4341 		return;
4342 	}
4343 
4344 	// Yeah, I know that this doesn't even do half of what the func_usable use code does, but if I've got two things on top of each other...and only
4345 	//	one is visible at a time....and neither can ever be used......and finally, the shader on it has the shader_anim stuff going on....It doesn't seem
4346 	//	like I can easily use the other version without nasty side effects.
4347 	if( visible )
4348 	{
4349 		ent->r.svFlags &= ~SVF_NOCLIENT;
4350 		ent->s.eFlags &= ~EF_NODRAW;
4351 	}
4352 	else
4353 	{
4354 		ent->r.svFlags |= SVF_NOCLIENT;
4355 		ent->s.eFlags |= EF_NODRAW;
4356 	}
4357 }
4358 
4359 /*
4360 ============
4361 Q3_SetLockedEnemy
4362 
4363 ?
4364 ============
4365 */
Q3_SetLockedEnemy(int entID,qboolean locked)4366 static void Q3_SetLockedEnemy ( int entID, qboolean locked)
4367 {
4368 	G_DebugPrint( WL_WARNING, "Q3_SetLockedEnemy: NOT SUPPORTED IN MP\n");
4369 	return;
4370 }
4371 
4372 char cinematicSkipScript[1024];
4373 
4374 /*
4375 ============
4376 Q3_SetCinematicSkipScript
4377 
4378 ============
4379 */
Q3_SetCinematicSkipScript(char * scriptname)4380 static void Q3_SetCinematicSkipScript( char *scriptname )
4381 {
4382 	G_DebugPrint( WL_WARNING, "Q3_SetCinematicSkipScript: NOT SUPPORTED IN MP\n");
4383 	return;
4384 }
4385 
4386 /*
4387 ============
4388 Q3_SetNoMindTrick
4389 
4390 ?
4391 ============
4392 */
Q3_SetNoMindTrick(int entID,qboolean add)4393 static void Q3_SetNoMindTrick( int entID, qboolean add)
4394 {
4395 	G_DebugPrint( WL_WARNING, "Q3_SetNoMindTrick: NOT SUPPORTED IN MP\n");
4396 	return;
4397 }
4398 
4399 /*
4400 ============
4401 Q3_SetCrouched
4402 
4403 ?
4404 ============
4405 */
Q3_SetCrouched(int entID,qboolean add)4406 static void Q3_SetCrouched( int entID, qboolean add)
4407 {
4408 	gentity_t	*ent  = &g_entities[entID];
4409 
4410 	if ( !ent )
4411 	{
4412 		G_DebugPrint( WL_WARNING, "Q3_SetCrouched: invalid entID %d\n", entID);
4413 		return;
4414 	}
4415 
4416 	if ( !ent->NPC )
4417 	{
4418 		G_DebugPrint( WL_ERROR, "Q3_SetCrouched: '%s' is not an NPC!\n", ent->targetname );
4419 		return;
4420 	}
4421 
4422 	if(add)
4423 	{
4424 		ent->NPC->scriptFlags |= SCF_CROUCHED;
4425 	}
4426 	else
4427 	{
4428 		ent->NPC->scriptFlags &= ~SCF_CROUCHED;
4429 	}
4430 }
4431 
4432 /*
4433 ============
4434 Q3_SetWalking
4435 
4436 ?
4437 ============
4438 */
Q3_SetWalking(int entID,qboolean add)4439 static void Q3_SetWalking( int entID, qboolean add)
4440 {
4441 	gentity_t	*ent  = &g_entities[entID];
4442 
4443 	if ( !ent )
4444 	{
4445 		G_DebugPrint( WL_WARNING, "Q3_SetWalking: invalid entID %d\n", entID);
4446 		return;
4447 	}
4448 
4449 	if ( !ent->NPC )
4450 	{
4451 		G_DebugPrint( WL_ERROR, "Q3_SetWalking: '%s' is not an NPC!\n", ent->targetname );
4452 		return;
4453 	}
4454 
4455 	if(add)
4456 	{
4457 		ent->NPC->scriptFlags |= SCF_WALKING;
4458 	}
4459 	else
4460 	{
4461 		ent->NPC->scriptFlags &= ~SCF_WALKING;
4462 	}
4463 	return;
4464 }
4465 
4466 /*
4467 ============
4468 Q3_SetRunning
4469 
4470 ?
4471 ============
4472 */
Q3_SetRunning(int entID,qboolean add)4473 static void Q3_SetRunning( int entID, qboolean add)
4474 {
4475 	gentity_t	*ent  = &g_entities[entID];
4476 
4477 	if ( !ent )
4478 	{
4479 		G_DebugPrint( WL_WARNING, "Q3_SetRunning: invalid entID %d\n", entID);
4480 		return;
4481 	}
4482 
4483 	if ( !ent->NPC )
4484 	{
4485 		G_DebugPrint( WL_ERROR, "Q3_SetRunning: '%s' is not an NPC!\n", ent->targetname );
4486 		return;
4487 	}
4488 
4489 	if(add)
4490 	{
4491 		ent->NPC->scriptFlags |= SCF_RUNNING;
4492 	}
4493 	else
4494 	{
4495 		ent->NPC->scriptFlags &= ~SCF_RUNNING;
4496 	}
4497 }
4498 
4499 /*
4500 ============
4501 Q3_SetForcedMarch
4502 
4503 ?
4504 ============
4505 */
Q3_SetForcedMarch(int entID,qboolean add)4506 static void Q3_SetForcedMarch( int entID, qboolean add)
4507 {
4508 	gentity_t	*ent  = &g_entities[entID];
4509 
4510 	if ( !ent )
4511 	{
4512 		G_DebugPrint( WL_WARNING, "Q3_SetForcedMarch: invalid entID %d\n", entID);
4513 		return;
4514 	}
4515 
4516 	if ( !ent->NPC )
4517 	{
4518 		G_DebugPrint( WL_ERROR, "Q3_SetForcedMarch: '%s' is not an NPC!\n", ent->targetname );
4519 		return;
4520 	}
4521 
4522 	if(add)
4523 	{
4524 		ent->NPC->scriptFlags |= SCF_FORCED_MARCH;
4525 	}
4526 	else
4527 	{
4528 		ent->NPC->scriptFlags &= ~SCF_FORCED_MARCH;
4529 	}
4530 }
4531 /*
4532 ============
4533 Q3_SetChaseEnemies
4534 
4535 indicates whether the npc should chase after an enemy
4536 ============
4537 */
Q3_SetChaseEnemies(int entID,qboolean add)4538 static void Q3_SetChaseEnemies( int entID, qboolean add)
4539 {
4540 	gentity_t	*ent  = &g_entities[entID];
4541 
4542 	if ( !ent )
4543 	{
4544 		G_DebugPrint( WL_WARNING, "Q3_SetChaseEnemies: invalid entID %d\n", entID);
4545 		return;
4546 	}
4547 
4548 	if ( !ent->NPC )
4549 	{
4550 		G_DebugPrint( WL_ERROR, "Q3_SetChaseEnemies: '%s' is not an NPC!\n", ent->targetname );
4551 		return;
4552 	}
4553 
4554 	if(add)
4555 	{
4556 		ent->NPC->scriptFlags |= SCF_CHASE_ENEMIES;
4557 	}
4558 	else
4559 	{
4560 		ent->NPC->scriptFlags &= ~SCF_CHASE_ENEMIES;
4561 	}
4562 }
4563 
4564 /*
4565 ============
4566 Q3_SetLookForEnemies
4567 
4568 if set npc will be on the look out for potential enemies
4569 if not set, npc will ignore enemies
4570 ============
4571 */
Q3_SetLookForEnemies(int entID,qboolean add)4572 static void Q3_SetLookForEnemies( int entID, qboolean add)
4573 {
4574 	gentity_t	*ent  = &g_entities[entID];
4575 
4576 	if ( !ent )
4577 	{
4578 		G_DebugPrint( WL_WARNING, "Q3_SetLookForEnemies: invalid entID %d\n", entID);
4579 		return;
4580 	}
4581 
4582 	if ( !ent->NPC )
4583 	{
4584 		G_DebugPrint( WL_ERROR, "Q3_SetLookForEnemies: '%s' is not an NPC!\n", ent->targetname );
4585 		return;
4586 	}
4587 
4588 	if(add)
4589 	{
4590 		ent->NPC->scriptFlags |= SCF_LOOK_FOR_ENEMIES;
4591 	}
4592 	else
4593 	{
4594 		ent->NPC->scriptFlags &= ~SCF_LOOK_FOR_ENEMIES;
4595 	}
4596 }
4597 
4598 /*
4599 ============
4600 Q3_SetFaceMoveDir
4601 
4602 ============
4603 */
Q3_SetFaceMoveDir(int entID,qboolean add)4604 static void Q3_SetFaceMoveDir( int entID, qboolean add)
4605 {
4606 	gentity_t	*ent  = &g_entities[entID];
4607 
4608 	if ( !ent )
4609 	{
4610 		G_DebugPrint( WL_WARNING, "Q3_SetFaceMoveDir: invalid entID %d\n", entID);
4611 		return;
4612 	}
4613 
4614 	if ( !ent->NPC )
4615 	{
4616 		G_DebugPrint( WL_ERROR, "Q3_SetFaceMoveDir: '%s' is not an NPC!\n", ent->targetname );
4617 		return;
4618 	}
4619 
4620 	if(add)
4621 	{
4622 		ent->NPC->scriptFlags |= SCF_FACE_MOVE_DIR;
4623 	}
4624 	else
4625 	{
4626 		ent->NPC->scriptFlags &= ~SCF_FACE_MOVE_DIR;
4627 	}
4628 }
4629 
4630 /*
4631 ============
4632 Q3_SetAltFire
4633 
4634 ?
4635 ============
4636 */
Q3_SetAltFire(int entID,qboolean add)4637 static void Q3_SetAltFire( int entID, qboolean add)
4638 {
4639 	gentity_t	*ent  = &g_entities[entID];
4640 
4641 	if ( !ent )
4642 	{
4643 		G_DebugPrint( WL_WARNING, "Q3_SetAltFire: invalid entID %d\n", entID);
4644 		return;
4645 	}
4646 
4647 	if ( !ent->NPC )
4648 	{
4649 		G_DebugPrint( WL_ERROR, "Q3_SetAltFire: '%s' is not an NPC!\n", ent->targetname );
4650 		return;
4651 	}
4652 
4653 	if(add)
4654 	{
4655 		ent->NPC->scriptFlags |= SCF_ALT_FIRE;
4656 	}
4657 	else
4658 	{
4659 		ent->NPC->scriptFlags &= ~SCF_ALT_FIRE;
4660 	}
4661 
4662 	ChangeWeapon( ent, 	ent->client->ps.weapon );
4663 }
4664 
4665 /*
4666 ============
4667 Q3_SetDontFlee
4668 
4669 ?
4670 ============
4671 */
Q3_SetDontFlee(int entID,qboolean add)4672 static void Q3_SetDontFlee( int entID, qboolean add)
4673 {
4674 	gentity_t	*ent  = &g_entities[entID];
4675 
4676 	if ( !ent )
4677 	{
4678 		G_DebugPrint( WL_WARNING, "Q3_SetDontFlee: invalid entID %d\n", entID);
4679 		return;
4680 	}
4681 
4682 	if ( !ent->NPC )
4683 	{
4684 		G_DebugPrint( WL_ERROR, "Q3_SetDontFlee: '%s' is not an NPC!\n", ent->targetname );
4685 		return;
4686 	}
4687 
4688 	if(add)
4689 	{
4690 		ent->NPC->scriptFlags |= SCF_DONT_FLEE;
4691 	}
4692 	else
4693 	{
4694 		ent->NPC->scriptFlags &= ~SCF_DONT_FLEE;
4695 	}
4696 }
4697 
4698 /*
4699 ============
4700 Q3_SetNoResponse
4701 
4702 ?
4703 ============
4704 */
Q3_SetNoResponse(int entID,qboolean add)4705 static void Q3_SetNoResponse( int entID, qboolean add)
4706 {
4707 	gentity_t	*ent  = &g_entities[entID];
4708 
4709 	if ( !ent )
4710 	{
4711 		G_DebugPrint( WL_WARNING, "Q3_SetNoResponse: invalid entID %d\n", entID);
4712 		return;
4713 	}
4714 
4715 	if ( !ent->NPC )
4716 	{
4717 		G_DebugPrint( WL_ERROR, "Q3_SetNoResponse: '%s' is not an NPC!\n", ent->targetname );
4718 		return;
4719 	}
4720 
4721 	if(add)
4722 	{
4723 		ent->NPC->scriptFlags |= SCF_NO_RESPONSE;
4724 	}
4725 	else
4726 	{
4727 		ent->NPC->scriptFlags &= ~SCF_NO_RESPONSE;
4728 	}
4729 }
4730 
4731 /*
4732 ============
4733 Q3_SetCombatTalk
4734 
4735 ?
4736 ============
4737 */
Q3_SetCombatTalk(int entID,qboolean add)4738 static void Q3_SetCombatTalk( int entID, qboolean add)
4739 {
4740 	gentity_t	*ent  = &g_entities[entID];
4741 
4742 	if ( !ent )
4743 	{
4744 		G_DebugPrint( WL_WARNING, "Q3_SetCombatTalk: invalid entID %d\n", entID);
4745 		return;
4746 	}
4747 
4748 	if ( !ent->NPC )
4749 	{
4750 		G_DebugPrint( WL_ERROR, "Q3_SetCombatTalk: '%s' is not an NPC!\n", ent->targetname );
4751 		return;
4752 	}
4753 
4754 	if ( add )
4755 	{
4756 		ent->NPC->scriptFlags |= SCF_NO_COMBAT_TALK;
4757 	}
4758 	else
4759 	{
4760 		ent->NPC->scriptFlags &= ~SCF_NO_COMBAT_TALK;
4761 	}
4762 }
4763 
4764 /*
4765 ============
4766 Q3_SetAlertTalk
4767 
4768 ?
4769 ============
4770 */
Q3_SetAlertTalk(int entID,qboolean add)4771 static void Q3_SetAlertTalk( int entID, qboolean add)
4772 {
4773 	gentity_t	*ent  = &g_entities[entID];
4774 
4775 	if ( !ent )
4776 	{
4777 		G_DebugPrint( WL_WARNING, "Q3_SetAlertTalk: invalid entID %d\n", entID);
4778 		return;
4779 	}
4780 
4781 	if ( !ent->NPC )
4782 	{
4783 		G_DebugPrint( WL_ERROR, "Q3_SetAlertTalk: '%s' is not an NPC!\n", ent->targetname );
4784 		return;
4785 	}
4786 
4787 	if ( add )
4788 	{
4789 		ent->NPC->scriptFlags |= SCF_NO_ALERT_TALK;
4790 	}
4791 	else
4792 	{
4793 		ent->NPC->scriptFlags &= ~SCF_NO_ALERT_TALK;
4794 	}
4795 }
4796 
4797 /*
4798 ============
4799 Q3_SetUseCpNearest
4800 
4801 ?
4802 ============
4803 */
Q3_SetUseCpNearest(int entID,qboolean add)4804 static void Q3_SetUseCpNearest( int entID, qboolean add)
4805 {
4806 	gentity_t	*ent  = &g_entities[entID];
4807 
4808 	if ( !ent )
4809 	{
4810 		G_DebugPrint( WL_WARNING, "Q3_SetUseCpNearest: invalid entID %d\n", entID);
4811 		return;
4812 	}
4813 
4814 	if ( !ent->NPC )
4815 	{
4816 		G_DebugPrint( WL_ERROR, "Q3_SetUseCpNearest: '%s' is not an NPC!\n", ent->targetname );
4817 		return;
4818 	}
4819 
4820 	if ( add )
4821 	{
4822 		ent->NPC->scriptFlags |= SCF_USE_CP_NEAREST;
4823 	}
4824 	else
4825 	{
4826 		ent->NPC->scriptFlags &= ~SCF_USE_CP_NEAREST;
4827 	}
4828 }
4829 
4830 /*
4831 ============
4832 Q3_SetNoForce
4833 
4834 ?
4835 ============
4836 */
Q3_SetNoForce(int entID,qboolean add)4837 static void Q3_SetNoForce( int entID, qboolean add)
4838 {
4839 	gentity_t	*ent  = &g_entities[entID];
4840 
4841 	if ( !ent )
4842 	{
4843 		G_DebugPrint( WL_WARNING, "Q3_SetNoForce: invalid entID %d\n", entID);
4844 		return;
4845 	}
4846 
4847 	if ( !ent->NPC )
4848 	{
4849 		G_DebugPrint( WL_ERROR, "Q3_SetNoForce: '%s' is not an NPC!\n", ent->targetname );
4850 		return;
4851 	}
4852 
4853 	if ( add )
4854 	{
4855 		ent->NPC->scriptFlags |= SCF_NO_FORCE;
4856 	}
4857 	else
4858 	{
4859 		ent->NPC->scriptFlags &= ~SCF_NO_FORCE;
4860 	}
4861 }
4862 
4863 /*
4864 ============
4865 Q3_SetNoAcrobatics
4866 
4867 ?
4868 ============
4869 */
Q3_SetNoAcrobatics(int entID,qboolean add)4870 static void Q3_SetNoAcrobatics( int entID, qboolean add)
4871 {
4872 	gentity_t	*ent  = &g_entities[entID];
4873 
4874 	if ( !ent )
4875 	{
4876 		G_DebugPrint( WL_WARNING, "Q3_SetNoAcrobatics: invalid entID %d\n", entID);
4877 		return;
4878 	}
4879 
4880 	if ( !ent->NPC )
4881 	{
4882 		G_DebugPrint( WL_ERROR, "Q3_SetNoAcrobatics: '%s' is not an NPC!\n", ent->targetname );
4883 		return;
4884 	}
4885 
4886 	if ( add )
4887 	{
4888 		ent->NPC->scriptFlags |= SCF_NO_ACROBATICS;
4889 	}
4890 	else
4891 	{
4892 		ent->NPC->scriptFlags &= ~SCF_NO_ACROBATICS;
4893 	}
4894 }
4895 
4896 /*
4897 ============
4898 Q3_SetUseSubtitles
4899 
4900 ?
4901 ============
4902 */
Q3_SetUseSubtitles(int entID,qboolean add)4903 static void Q3_SetUseSubtitles( int entID, qboolean add)
4904 {
4905 	G_DebugPrint( WL_WARNING, "Q3_SetUseSubtitles: NOT SUPPORTED IN MP\n");
4906 	return;
4907 }
4908 
4909 /*
4910 ============
4911 Q3_SetNoFallToDeath
4912 
4913 ?
4914 ============
4915 */
Q3_SetNoFallToDeath(int entID,qboolean add)4916 static void Q3_SetNoFallToDeath( int entID, qboolean add)
4917 {
4918 	gentity_t	*ent  = &g_entities[entID];
4919 
4920 	if ( !ent )
4921 	{
4922 		G_DebugPrint( WL_WARNING, "Q3_SetNoFallToDeath: invalid entID %d\n", entID);
4923 		return;
4924 	}
4925 
4926 	if ( !ent->NPC )
4927 	{
4928 		G_DebugPrint( WL_ERROR, "Q3_SetNoFallToDeath: '%s' is not an NPC!\n", ent->targetname );
4929 		return;
4930 	}
4931 
4932 	if ( add )
4933 	{
4934 		ent->NPC->scriptFlags |= SCF_NO_FALLTODEATH;
4935 	}
4936 	else
4937 	{
4938 		ent->NPC->scriptFlags &= ~SCF_NO_FALLTODEATH;
4939 	}
4940 }
4941 
4942 /*
4943 ============
4944 Q3_SetDismemberable
4945 
4946 ?
4947 ============
4948 */
Q3_SetDismemberable(int entID,qboolean dismemberable)4949 static void Q3_SetDismemberable( int entID, qboolean dismemberable)
4950 {
4951 	G_DebugPrint( WL_WARNING, "Q3_SetDismemberable: NOT SUPPORTED IN MP\n");
4952 	return;
4953 }
4954 
4955 
4956 /*
4957 ============
4958 Q3_SetMoreLight
4959 
4960 ?
4961 ============
4962 */
Q3_SetMoreLight(int entID,qboolean add)4963 static void Q3_SetMoreLight( int entID, qboolean add )
4964 {
4965 	G_DebugPrint( WL_WARNING, "Q3_SetMoreLight: NOT SUPPORTED IN MP\n");
4966 	return;
4967 }
4968 
4969 /*
4970 ============
4971 Q3_SetUndying
4972 
4973 ?
4974 ============
4975 */
Q3_SetUndying(int entID,qboolean undying)4976 static void Q3_SetUndying( int entID, qboolean undying)
4977 {
4978 	gentity_t	*ent  = &g_entities[entID];
4979 
4980 	if ( !ent )
4981 	{
4982 		G_DebugPrint( WL_WARNING, "Q3_SetUndying: invalid entID %d\n", entID);
4983 		return;
4984 	}
4985 
4986 	if(undying)
4987 	{
4988 		ent->flags |= FL_UNDYING;
4989 	}
4990 	else
4991 	{
4992 		ent->flags &= ~FL_UNDYING;
4993 	}
4994 }
4995 
4996 /*
4997 ============
4998 Q3_SetInvincible
4999 
5000 ?
5001 ============
5002 */
Q3_SetInvincible(int entID,qboolean invincible)5003 static void Q3_SetInvincible( int entID, qboolean invincible)
5004 {
5005 	gentity_t	*ent  = &g_entities[entID];
5006 
5007 	if ( !ent )
5008 	{
5009 		G_DebugPrint( WL_WARNING, "Q3_SetInvincible: invalid entID %d\n", entID);
5010 		return;
5011 	}
5012 
5013 	if ( !Q_stricmp( "func_breakable", ent->classname ) )
5014 	{
5015 		if ( invincible )
5016 		{
5017 			ent->spawnflags |= 1;
5018 		}
5019 		else
5020 		{
5021 			ent->spawnflags &= ~1;
5022 		}
5023 		return;
5024 	}
5025 
5026 	if ( invincible )
5027 	{
5028 		ent->flags |= FL_GODMODE;
5029 	}
5030 	else
5031 	{
5032 		ent->flags &= ~FL_GODMODE;
5033 	}
5034 }
5035 /*
5036 ============
5037 Q3_SetForceInvincible
5038   Description	:
5039   Return type	: static void
5040   Argument		:  int entID
5041   Argument		: qboolean forceInv
5042 ============
5043 */
Q3_SetForceInvincible(int entID,qboolean forceInv)5044 static void Q3_SetForceInvincible( int entID, qboolean forceInv )
5045 {
5046 	G_DebugPrint( WL_WARNING, "Q3_SetForceInvicible: NOT SUPPORTED IN MP\n");
5047 	return;
5048 }
5049 
5050 /*
5051 ============
5052 Q3_SetNoAvoid
5053 
5054 ?
5055 ============
5056 */
Q3_SetNoAvoid(int entID,qboolean noAvoid)5057 static void Q3_SetNoAvoid( int entID, qboolean noAvoid)
5058 {
5059 	gentity_t	*ent  = &g_entities[entID];
5060 
5061 	if ( !ent )
5062 	{
5063 		G_DebugPrint( WL_WARNING, "Q3_SetNoAvoid: invalid entID %d\n", entID);
5064 		return;
5065 	}
5066 
5067 	if ( !ent->NPC )
5068 	{
5069 		G_DebugPrint( WL_ERROR, "Q3_SetNoAvoid: '%s' is not an NPC!\n", ent->targetname );
5070 		return;
5071 	}
5072 
5073 	if(noAvoid)
5074 	{
5075 		ent->NPC->aiFlags |= NPCAI_NO_COLL_AVOID;
5076 	}
5077 	else
5078 	{
5079 		ent->NPC->aiFlags &= ~NPCAI_NO_COLL_AVOID;
5080 	}
5081 }
5082 
5083 /*
5084 ============
5085 SolidifyOwner
5086   Description	:
5087   Return type	: void
5088   Argument		: sharedEntity_t *self
5089 ============
5090 */
SolidifyOwner(gentity_t * self)5091 void SolidifyOwner( gentity_t *self )
5092 {
5093 	int oldContents;
5094 	gentity_t *owner = &g_entities[self->r.ownerNum];
5095 
5096 	self->nextthink = level.time + FRAMETIME;
5097 	self->think = G_FreeEntity;
5098 
5099 	if ( !owner || !owner->inuse )
5100 	{
5101 		return;
5102 	}
5103 
5104 	oldContents = owner->r.contents;
5105 	owner->r.contents = CONTENTS_BODY;
5106 	if ( SpotWouldTelefrag2( owner, owner->r.currentOrigin ) )
5107 	{
5108 		owner->r.contents = oldContents;
5109 		self->think = SolidifyOwner;
5110 	}
5111 	else
5112 	{
5113 		trap->ICARUS_TaskIDComplete( (sharedEntity_t *)owner, TID_RESIZE );
5114 	}
5115 }
5116 
5117 
5118 /*
5119 ============
5120 Q3_SetSolid
5121 
5122 ?
5123 ============
5124 */
Q3_SetSolid(int entID,qboolean solid)5125 static qboolean Q3_SetSolid( int entID, qboolean solid)
5126 {
5127 	gentity_t	*ent  = &g_entities[entID];
5128 
5129 	if ( !ent || !ent->inuse )
5130 	{
5131 		G_DebugPrint( WL_WARNING, "Q3_SetSolid: invalid entID %d\n", entID);
5132 		return qtrue;
5133 	}
5134 
5135 	if ( solid )
5136 	{//FIXME: Presumption
5137 		int oldContents = ent->r.contents;
5138 		ent->r.contents = CONTENTS_BODY;
5139 		if ( SpotWouldTelefrag2( ent, ent->r.currentOrigin ) )
5140 		{
5141 			gentity_t *solidifier = G_Spawn();
5142 
5143 			solidifier->r.ownerNum = ent->s.number;
5144 
5145 			solidifier->think = SolidifyOwner;
5146 			solidifier->nextthink = level.time + FRAMETIME;
5147 
5148 			ent->r.contents = oldContents;
5149 			return qfalse;
5150 		}
5151 		ent->clipmask |= CONTENTS_BODY;
5152 	}
5153 	else
5154 	{//FIXME: Presumption
5155 		if ( ent->s.eFlags & EF_NODRAW )
5156 		{//We're invisible too, so set contents to none
5157 			ent->r.contents = 0;
5158 		}
5159 		else
5160 		{
5161 			ent->r.contents = CONTENTS_CORPSE;
5162 		}
5163 	}
5164 	return qtrue;
5165 }
5166 
5167 /*
5168 ============
5169 Q3_SetForwardMove
5170 
5171 ?
5172 ============
5173 */
Q3_SetForwardMove(int entID,int fmoveVal)5174 static void Q3_SetForwardMove( int entID, int fmoveVal)
5175 {
5176 	gentity_t	*ent  = &g_entities[entID];
5177 
5178 	if ( !ent )
5179 	{
5180 		G_DebugPrint( WL_WARNING, "Q3_SetForwardMove: invalid entID %d\n", entID);
5181 		return;
5182 	}
5183 
5184 	if ( !ent->client )
5185 	{
5186 		G_DebugPrint( WL_ERROR, "Q3_SetForwardMove: '%s' is not an NPC/player!\n", ent->targetname );
5187 		return;
5188 	}
5189 
5190 	G_DebugPrint( WL_WARNING, "Q3_SetForwardMove: NOT SUPPORTED IN MP\n");
5191 	//ent->client->forced_forwardmove = fmoveVal;
5192 }
5193 
5194 /*
5195 ============
5196 Q3_SetRightMove
5197 
5198 ?
5199 ============
5200 */
Q3_SetRightMove(int entID,int rmoveVal)5201 static void Q3_SetRightMove( int entID, int rmoveVal)
5202 {
5203 	gentity_t	*ent  = &g_entities[entID];
5204 
5205 	if ( !ent )
5206 	{
5207 		G_DebugPrint( WL_WARNING, "Q3_SetRightMove: invalid entID %d\n", entID);
5208 		return;
5209 	}
5210 
5211 	if ( !ent->client )
5212 	{
5213 		G_DebugPrint( WL_ERROR, "Q3_SetRightMove: '%s' is not an NPC/player!\n", ent->targetname );
5214 		return;
5215 	}
5216 
5217 	G_DebugPrint( WL_WARNING, "Q3_SetRightMove: NOT SUPPORTED IN MP\n");
5218 	//ent->client->forced_rightmove = rmoveVal;
5219 }
5220 
5221 /*
5222 ============
5223 Q3_SetLockAngle
5224 
5225 ?
5226 ============
5227 */
Q3_SetLockAngle(int entID,const char * lockAngle)5228 static void Q3_SetLockAngle( int entID, const char *lockAngle)
5229 {
5230 	gentity_t	*ent  = &g_entities[entID];
5231 
5232 	if ( !ent )
5233 	{
5234 		G_DebugPrint( WL_WARNING, "Q3_SetLockAngle: invalid entID %d\n", entID);
5235 		return;
5236 	}
5237 
5238 	if ( !ent->client )
5239 	{
5240 		G_DebugPrint( WL_ERROR, "Q3_SetLockAngle: '%s' is not an NPC/player!\n", ent->targetname );
5241 		return;
5242 	}
5243 
5244 	G_DebugPrint( WL_WARNING, "Q3_SetLockAngle is not currently available. Ask if you really need it.\n");
5245 	/*
5246 	if(Q_stricmp("off", lockAngle) == 0)
5247 	{//free it
5248 		ent->client->renderInfo.renderFlags &= ~RF_LOCKEDANGLE;
5249 	}
5250 	else
5251 	{
5252 		ent->client->renderInfo.renderFlags |= RF_LOCKEDANGLE;
5253 
5254 
5255 		if(Q_stricmp("auto", lockAngle) == 0)
5256 		{//use current yaw
5257 			ent->client->renderInfo.lockYaw = ent->client->ps.viewangles[YAW];
5258 		}
5259 		else
5260 		{//specified yaw
5261 			ent->client->renderInfo.lockYaw = atof((char *)lockAngle);
5262 		}
5263 	}
5264 	*/
5265 }
5266 
5267 
5268 /*
5269 ============
5270 Q3_CameraGroup
5271 
5272 ?
5273 ============
5274 */
Q3_CameraGroup(int entID,char * camG)5275 static void Q3_CameraGroup( int entID, char *camG)
5276 {
5277 	G_DebugPrint( WL_WARNING, "Q3_CameraGroup: NOT SUPPORTED IN MP\n");
5278 	return;
5279 }
5280 
5281 /*
5282 ============
5283 Q3_CameraGroupZOfs
5284 
5285 ?
5286 ============
5287 */
Q3_CameraGroupZOfs(float camGZOfs)5288 static void Q3_CameraGroupZOfs( float camGZOfs )
5289 {
5290 	G_DebugPrint( WL_WARNING, "Q3_CameraGroupZOfs: NOT SUPPORTED IN MP\n");
5291 	return;
5292 }
5293 /*
5294 ============
5295 Q3_CameraGroup
5296 
5297 ?
5298 ============
5299 */
Q3_CameraGroupTag(char * camGTag)5300 static void Q3_CameraGroupTag( char *camGTag )
5301 {
5302 	G_DebugPrint( WL_WARNING, "Q3_CameraGroupTag: NOT SUPPORTED IN MP\n");
5303 	return;
5304 }
5305 
5306 /*
5307 ============
5308 Q3_RemoveRHandModel
5309 ============
5310 */
Q3_RemoveRHandModel(int entID,char * addModel)5311 static void Q3_RemoveRHandModel( int entID, char *addModel)
5312 {
5313 	G_DebugPrint( WL_WARNING, "Q3_RemoveRHandModel: NOT SUPPORTED IN MP\n");
5314 }
5315 
5316 /*
5317 ============
5318 Q3_AddRHandModel
5319 ============
5320 */
Q3_AddRHandModel(int entID,char * addModel)5321 static void Q3_AddRHandModel( int entID, char *addModel)
5322 {
5323 	G_DebugPrint( WL_WARNING, "Q3_AddRHandModel: NOT SUPPORTED IN MP\n");
5324 }
5325 
5326 /*
5327 ============
5328 Q3_AddLHandModel
5329 ============
5330 */
Q3_AddLHandModel(int entID,char * addModel)5331 static void Q3_AddLHandModel( int entID, char *addModel)
5332 {
5333 	G_DebugPrint( WL_WARNING, "Q3_AddLHandModel: NOT SUPPORTED IN MP\n");
5334 }
5335 
5336 /*
5337 ============
5338 Q3_RemoveLHandModel
5339 ============
5340 */
Q3_RemoveLHandModel(int entID,char * addModel)5341 static void Q3_RemoveLHandModel( int entID, char *addModel)
5342 {
5343 	G_DebugPrint( WL_WARNING, "Q3_RemoveLHandModel: NOT SUPPORTED IN MP\n");
5344 }
5345 
5346 /*
5347 ============
5348 Q3_LookTarget
5349 
5350 ?
5351 ============
5352 */
Q3_LookTarget(int entID,char * targetName)5353 static void Q3_LookTarget( int entID, char *targetName)
5354 {
5355 	gentity_t	*ent  = &g_entities[entID];
5356 	gentity_t	*targ = NULL;
5357 
5358 	if ( !ent )
5359 	{
5360 		G_DebugPrint( WL_WARNING, "Q3_LookTarget: invalid entID %d\n", entID);
5361 		return;
5362 	}
5363 
5364 	if ( !ent->client )
5365 	{
5366 		G_DebugPrint( WL_ERROR, "Q3_LookTarget: '%s' is not an NPC/player!\n", ent->targetname );
5367 		return;
5368 	}
5369 
5370 	if(Q_stricmp("none", targetName) == 0 || Q_stricmp("NULL", targetName) == 0)
5371 	{//clearing look target
5372 		NPC_ClearLookTarget( ent );
5373 		return;
5374 	}
5375 
5376 	targ = G_Find(NULL, FOFS(targetname), targetName);
5377 	if(!targ)
5378 	{
5379 		targ  = G_Find(NULL, FOFS(script_targetname), targetName);
5380 		if (!targ)
5381 		{
5382 			targ  = G_Find(NULL, FOFS(NPC_targetname), targetName);
5383 			if (!targ)
5384 			{
5385 				G_DebugPrint( WL_ERROR, "Q3_LookTarget: Can't find ent %s\n", targetName );
5386 				return;
5387 			}
5388 		}
5389 	}
5390 
5391 	NPC_SetLookTarget( ent, targ->s.number, 0 );
5392 }
5393 
5394 /*
5395 ============
5396 Q3_Face
5397 
5398 ?
5399 ============
5400 */
Q3_Face(int entID,int expression,float holdtime)5401 static void Q3_Face( int entID,int expression, float holdtime)
5402 {
5403 	G_DebugPrint( WL_WARNING, "Q3_Face: NOT SUPPORTED IN MP\n");
5404 }
5405 
5406 /*
5407 ============
5408 Q3_SetLocation
5409   Description	:
5410   Return type	: qboolean
5411   Argument		:  int entID
5412   Argument		: const char *location
5413 ============
5414 */
Q3_SetLocation(int entID,const char * location)5415 static qboolean Q3_SetLocation( int entID, const char *location )
5416 {
5417 	G_DebugPrint( WL_WARNING, "Q3_SetLocation: NOT SUPPORTED IN MP\n");
5418 	return qtrue;
5419 }
5420 
5421 /*
5422 ============
5423 Q3_SetPlayerLocked
5424   Description	:
5425   Return type	: void
5426   Argument		:  int entID
5427   Argument		: qboolean locked
5428 ============
5429 */
5430 qboolean	player_locked = qfalse;
Q3_SetPlayerLocked(int entID,qboolean locked)5431 static void Q3_SetPlayerLocked( int entID, qboolean locked )
5432 {
5433 	G_DebugPrint( WL_WARNING, "Q3_SetPlayerLocked: NOT SUPPORTED IN MP\n");
5434 }
5435 
5436 /*
5437 ============
5438 Q3_SetLockPlayerWeapons
5439   Description	:
5440   Return type	: void
5441   Argument		:  int entID
5442   Argument		: qboolean locked
5443 ============
5444 */
Q3_SetLockPlayerWeapons(int entID,qboolean locked)5445 static void Q3_SetLockPlayerWeapons( int entID, qboolean locked )
5446 {
5447 	G_DebugPrint( WL_WARNING, "Q3_SetLockPlayerWeapons: NOT SUPPORTED IN MP\n");
5448 }
5449 
5450 
5451 /*
5452 ============
5453 Q3_SetNoImpactDamage
5454   Description	:
5455   Return type	: void
5456   Argument		:  int entID
5457   Argument		: qboolean locked
5458 ============
5459 */
Q3_SetNoImpactDamage(int entID,qboolean noImp)5460 static void Q3_SetNoImpactDamage( int entID, qboolean noImp )
5461 {
5462 	G_DebugPrint( WL_WARNING, "Q3_SetNoImpactDamage: NOT SUPPORTED IN MP\n");
5463 }
5464 
5465 /*
5466 ============
5467 Q3_SetBehaviorSet
5468 
5469 ?
5470 ============
5471 */
Q3_SetBehaviorSet(int entID,int toSet,const char * scriptname)5472 static qboolean Q3_SetBehaviorSet( int entID, int toSet, const char *scriptname)
5473 {
5474 	gentity_t	*ent  = &g_entities[entID];
5475 	bSet_t		bSet = BSET_INVALID;
5476 
5477 	if ( !ent )
5478 	{
5479 		G_DebugPrint( WL_WARNING, "Q3_SetBehaviorSet: invalid entID %d\n", entID);
5480 		return qfalse;
5481 	}
5482 
5483 	switch(toSet)
5484 	{
5485 	case SET_SPAWNSCRIPT:
5486 		bSet = BSET_SPAWN;
5487 		break;
5488 	case SET_USESCRIPT:
5489 		bSet = BSET_USE;
5490 		break;
5491 	case SET_AWAKESCRIPT:
5492 		bSet = BSET_AWAKE;
5493 		break;
5494 	case SET_ANGERSCRIPT:
5495 		bSet = BSET_ANGER;
5496 		break;
5497 	case SET_ATTACKSCRIPT:
5498 		bSet = BSET_ATTACK;
5499 		break;
5500 	case SET_VICTORYSCRIPT:
5501 		bSet = BSET_VICTORY;
5502 		break;
5503 	case SET_LOSTENEMYSCRIPT:
5504 		bSet = BSET_LOSTENEMY;
5505 		break;
5506 	case SET_PAINSCRIPT:
5507 		bSet = BSET_PAIN;
5508 		break;
5509 	case SET_FLEESCRIPT:
5510 		bSet = BSET_FLEE;
5511 		break;
5512 	case SET_DEATHSCRIPT:
5513 		bSet = BSET_DEATH;
5514 		break;
5515 	case SET_DELAYEDSCRIPT:
5516 		bSet = BSET_DELAYED;
5517 		break;
5518 	case SET_BLOCKEDSCRIPT:
5519 		bSet = BSET_BLOCKED;
5520 		break;
5521 	case SET_FFIRESCRIPT:
5522 		bSet = BSET_FFIRE;
5523 		break;
5524 	case SET_FFDEATHSCRIPT:
5525 		bSet = BSET_FFDEATH;
5526 		break;
5527 	case SET_MINDTRICKSCRIPT:
5528 		bSet = BSET_MINDTRICK;
5529 		break;
5530 	}
5531 
5532 	if(bSet < BSET_SPAWN || bSet >= NUM_BSETS)
5533 	{
5534 		return qfalse;
5535 	}
5536 
5537 	if(!Q_stricmp("NULL", scriptname))
5538 	{
5539 		if ( ent->behaviorSet[bSet] != NULL )
5540 		{
5541 //			trap->TagFree( ent->behaviorSet[bSet] );
5542 		}
5543 
5544 		ent->behaviorSet[bSet] = NULL;
5545 		//memset( &ent->behaviorSet[bSet], 0, sizeof(ent->behaviorSet[bSet]) );
5546 	}
5547 	else
5548 	{
5549 		if ( scriptname )
5550 		{
5551 			if ( ent->behaviorSet[bSet] != NULL )
5552 			{
5553 //				trap->TagFree( ent->behaviorSet[bSet] );
5554 			}
5555 
5556 			ent->behaviorSet[bSet] = G_NewString( (char *) scriptname );	//FIXME: This really isn't good...
5557 		}
5558 
5559 		//ent->behaviorSet[bSet] = scriptname;
5560 		//strncpy( (char *) &ent->behaviorSet[bSet], scriptname, MAX_BSET_LENGTH );
5561 	}
5562 	return qtrue;
5563 }
5564 
5565 /*
5566 ============
5567 Q3_SetDelayScriptTime
5568 
5569 ?
5570 ============
5571 */
Q3_SetDelayScriptTime(int entID,int delayTime)5572 static void Q3_SetDelayScriptTime(int entID, int delayTime)
5573 {
5574 	G_DebugPrint( WL_WARNING, "Q3_SetDelayScriptTime: NOT SUPPORTED IN MP\n");
5575 }
5576 
5577 
5578 
5579 
5580 /*
5581 ============
5582 Q3_SetPlayerUsable
5583   Description	:
5584   Return type	: void
5585   Argument		:  int entID
5586   Argument		: qboolean usable
5587 ============
5588 */
Q3_SetPlayerUsable(int entID,qboolean usable)5589 static void Q3_SetPlayerUsable( int entID, qboolean usable )
5590 {
5591 	gentity_t	*ent  = &g_entities[entID];
5592 
5593 	if ( !ent )
5594 	{
5595 		G_DebugPrint( WL_WARNING, "Q3_SetPlayerUsable: invalid entID %d\n", entID);
5596 		return;
5597 	}
5598 
5599 	if(usable)
5600 	{
5601 		ent->r.svFlags |= SVF_PLAYER_USABLE;
5602 	}
5603 	else
5604 	{
5605 		ent->r.svFlags &= ~SVF_PLAYER_USABLE;
5606 	}
5607 }
5608 
5609 /*
5610 ============
5611 Q3_SetDisableShaderAnims
5612   Description	:
5613   Return type	: static void
5614   Argument		:  int entID
5615   Argument		: int disabled
5616 ============
5617 */
Q3_SetDisableShaderAnims(int entID,int disabled)5618 static void Q3_SetDisableShaderAnims( int entID, int disabled )
5619 {
5620 	G_DebugPrint( WL_WARNING, "Q3_SetDisableShaderAnims: NOT SUPPORTED IN MP\n");
5621 	return;
5622 }
5623 
5624 /*
5625 ============
5626 Q3_SetShaderAnim
5627   Description	:
5628   Return type	: static void
5629   Argument		:  int entID
5630   Argument		: int disabled
5631 ============
5632 */
Q3_SetShaderAnim(int entID,int disabled)5633 static void Q3_SetShaderAnim( int entID, int disabled )
5634 {
5635 	G_DebugPrint( WL_WARNING, "Q3_SetShaderAnim: NOT SUPPORTED IN MP\n");
5636 	return;
5637 }
5638 
5639 /*
5640 ============
5641 Q3_SetStartFrame
5642   Description	:
5643   Return type	: static void
5644   Argument		:  int entID
5645   Argument		: int startFrame
5646 ============
5647 */
Q3_SetStartFrame(int entID,int startFrame)5648 static void Q3_SetStartFrame( int entID, int startFrame )
5649 {
5650 	G_DebugPrint( WL_WARNING, "Q3_SetStartFrame: NOT SUPPORTED IN MP\n");
5651 }
5652 
5653 
5654 /*
5655 ============
5656 Q3_SetEndFrame
5657   Description	:
5658   Return type	: static void
5659   Argument		:  int entID
5660   Argument		: int endFrame
5661 ============
5662 */
Q3_SetEndFrame(int entID,int endFrame)5663 static void Q3_SetEndFrame( int entID, int endFrame )
5664 {
5665 	G_DebugPrint( WL_WARNING, "Q3_SetEndFrame: NOT SUPPORTED IN MP\n");
5666 }
5667 
5668 /*
5669 ============
5670 Q3_SetAnimFrame
5671   Description	:
5672   Return type	: static void
5673   Argument		:  int entID
5674   Argument		: int startFrame
5675 ============
5676 */
Q3_SetAnimFrame(int entID,int animFrame)5677 static void Q3_SetAnimFrame( int entID, int animFrame )
5678 {
5679 	G_DebugPrint( WL_WARNING, "Q3_SetAnimFrame: NOT SUPPORTED IN MP\n");
5680 }
5681 
5682 /*
5683 ============
5684 Q3_SetLoopAnim
5685   Description	:
5686   Return type	: void
5687   Argument		:  int entID
5688   Argument		: qboolean loopAnim
5689 ============
5690 */
Q3_SetLoopAnim(int entID,qboolean loopAnim)5691 static void Q3_SetLoopAnim( int entID, qboolean loopAnim )
5692 {
5693 	G_DebugPrint( WL_WARNING, "Q3_SetLoopAnim: NOT SUPPORTED IN MP\n");
5694 }
5695 
5696 
5697 /*
5698 ============
5699 Q3_SetShields
5700   Description	:
5701   Return type	: void
5702   Argument		:  int entID
5703   Argument		: qboolean shields
5704 ============
5705 */
Q3_SetShields(int entID,qboolean shields)5706 static void Q3_SetShields( int entID, qboolean shields )
5707 {
5708 	G_DebugPrint( WL_WARNING, "Q3_SetShields: NOT SUPPORTED IN MP\n");
5709 	return;
5710 }
5711 
5712 /*
5713 ============
5714 Q3_SetSaberActive
5715   Description	:
5716   Return type	: void
5717   Argument		:  int entID
5718   Argument		: qboolean shields
5719 ============
5720 */
Q3_SetSaberActive(int entID,qboolean active)5721 static void Q3_SetSaberActive( int entID, qboolean active )
5722 {
5723 	gentity_t *ent = &g_entities[entID];
5724 
5725 	if (!ent || !ent->inuse)
5726 	{
5727 		return;
5728 	}
5729 
5730 	if (!ent->client)
5731 	{
5732 		G_DebugPrint( WL_WARNING, "Q3_SetSaberActive: %d is not a client\n", entID);
5733 	}
5734 
5735 	//fixme: Take into account player being in state where saber won't toggle? For now we simply won't care.
5736 	if (!ent->client->ps.saberHolstered && active)
5737 	{
5738 		Cmd_ToggleSaber_f(ent);
5739 	}
5740 	else if (BG_SabersOff( &ent->client->ps ) && !active)
5741 	{
5742 		Cmd_ToggleSaber_f(ent);
5743 	}
5744 }
5745 
5746 /*
5747 ============
5748 Q3_SetNoKnockback
5749   Description	:
5750   Return type	: void
5751   Argument		:  int entID
5752   Argument		: qboolean noKnockback
5753 ============
5754 */
Q3_SetNoKnockback(int entID,qboolean noKnockback)5755 static void Q3_SetNoKnockback( int entID, qboolean noKnockback )
5756 {
5757 	gentity_t	*ent  = &g_entities[entID];
5758 
5759 	if ( !ent )
5760 	{
5761 		G_DebugPrint( WL_WARNING, "Q3_SetNoKnockback: invalid entID %d\n", entID);
5762 		return;
5763 	}
5764 
5765 	if ( noKnockback )
5766 	{
5767 		ent->flags |= FL_NO_KNOCKBACK;
5768 	}
5769 	else
5770 	{
5771 		ent->flags &= ~FL_NO_KNOCKBACK;
5772 	}
5773 }
5774 
5775 /*
5776 ============
5777 Q3_SetCleanDamagingEnts
5778   Description	:
5779   Return type	: void
5780 ============
5781 */
Q3_SetCleanDamagingEnts(void)5782 static void Q3_SetCleanDamagingEnts( void )
5783 {
5784 	G_DebugPrint( WL_WARNING, "Q3_SetCleanDamagingEnts: NOT SUPPORTED IN MP\n");
5785 	return;
5786 }
5787 
5788 vec4_t textcolor_caption;
5789 vec4_t textcolor_center;
5790 vec4_t textcolor_scroll;
5791 
5792 /*
5793 -------------------------
5794 Q3_SetTextColor
5795 -------------------------
5796 */
Q3_SetTextColor(vec4_t textcolor,const char * color)5797 static void Q3_SetTextColor ( vec4_t textcolor,const char *color)
5798 {
5799 	G_DebugPrint( WL_WARNING, "Q3_SetTextColor: NOT SUPPORTED IN MP\n");
5800 	return;
5801 }
5802 
5803 /*
5804 =============
5805 Q3_SetCaptionTextColor
5806 
5807 Change color text prints in
5808 =============
5809 */
Q3_SetCaptionTextColor(const char * color)5810 static void Q3_SetCaptionTextColor ( const char *color)
5811 {
5812 	Q3_SetTextColor(textcolor_caption,color);
5813 }
5814 
5815 /*
5816 =============
5817 Q3_SetCenterTextColor
5818 
5819 Change color text prints in
5820 =============
5821 */
Q3_SetCenterTextColor(const char * color)5822 static void Q3_SetCenterTextColor ( const char *color)
5823 {
5824 	Q3_SetTextColor(textcolor_center,color);
5825 }
5826 
5827 /*
5828 =============
5829 Q3_SetScrollTextColor
5830 
5831 Change color text prints in
5832 =============
5833 */
Q3_SetScrollTextColor(const char * color)5834 static void Q3_SetScrollTextColor ( const char *color)
5835 {
5836 	Q3_SetTextColor(textcolor_scroll,color);
5837 }
5838 
5839 /*
5840 =============
5841 Q3_ScrollText
5842 
5843 Prints a message in the center of the screen
5844 =============
5845 */
Q3_ScrollText(const char * id)5846 static void Q3_ScrollText ( const char *id)
5847 {
5848 	G_DebugPrint( WL_WARNING, "Q3_ScrollText: NOT SUPPORTED IN MP\n");
5849 	//trap->SendServerCommand( -1, va("st \"%s\"", id));
5850 
5851 	return;
5852 }
5853 
5854 /*
5855 =============
5856 Q3_LCARSText
5857 
5858 Prints a message in the center of the screen giving it an LCARS frame around it
5859 =============
5860 */
Q3_LCARSText(const char * id)5861 static void Q3_LCARSText ( const char *id)
5862 {
5863 	G_DebugPrint( WL_WARNING, "Q3_ScrollText: NOT SUPPORTED IN MP\n");
5864 	//trap->SendServerCommand( -1, va("lt \"%s\"", id));
5865 
5866 	return;
5867 }
5868 
5869 void UnLockDoors(gentity_t *const ent);
5870 void LockDoors(gentity_t *const ent);
5871 
5872 //returns qtrue if it got to the end, otherwise qfalse.
Q3_Set(int taskID,int entID,const char * type_name,const char * data)5873 qboolean Q3_Set( int taskID, int entID, const char *type_name, const char *data )
5874 {
5875 	gentity_t	*ent = &g_entities[entID];
5876 	float		float_data;
5877 	int			int_data, toSet;
5878 	vec3_t		vector_data;
5879 
5880 	//Set this for callbacks
5881 	toSet = GetIDForString( setTable, type_name );
5882 
5883 	//TODO: Throw in a showscript command that will list each command and what they're doing...
5884 	//		maybe as simple as printing that line of the script to the console preceeded by the person's name?
5885 	//		showscript can take any number of targetnames or "all"?  Groupname?
5886 	switch ( toSet )
5887 	{
5888 	case SET_ORIGIN:
5889 		if ( sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] ) != 3 ) {
5890 			G_DebugPrint( WL_WARNING, "Q3_Set: failed sscanf on SET_ORIGIN (%s)\n", type_name );
5891 			VectorClear( vector_data );
5892 		}
5893 		G_SetOrigin( ent, vector_data );
5894 		if ( Q_strncmp( "NPC_", ent->classname, 4 ) == 0 )
5895 		{//hack for moving spawners
5896 			VectorCopy( vector_data, ent->s.origin);
5897 		}
5898 		break;
5899 
5900 	case SET_TELEPORT_DEST:
5901 		if ( sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] ) != 3 ) {
5902 			G_DebugPrint( WL_WARNING, "Q3_Set: failed sscanf on SET_TELEPORT_DEST (%s)\n", type_name );
5903 			VectorClear( vector_data );
5904 		}
5905 		if ( !Q3_SetTeleportDest( entID, vector_data ) )
5906 		{
5907 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
5908 			return qfalse;
5909 		}
5910 		break;
5911 
5912 	case SET_COPY_ORIGIN:
5913 		Q3_SetCopyOrigin( entID, (char *) data );
5914 		break;
5915 
5916 	case SET_ANGLES:
5917 		//Q3_SetAngles( entID, *(vec3_t *) data);
5918 		if ( sscanf( data, "%f %f %f", &vector_data[0], &vector_data[1], &vector_data[2] ) != 3 ) {
5919 			G_DebugPrint( WL_WARNING, "Q3_Set: failed sscanf on SET_ANGLES (%s)\n", type_name );
5920 			VectorClear( vector_data );
5921 		}
5922 		Q3_SetAngles( entID, vector_data);
5923 		break;
5924 
5925 	case SET_XVELOCITY:
5926 		float_data = atof((char *) data);
5927 		Q3_SetVelocity( entID, 0, float_data);
5928 		break;
5929 
5930 	case SET_YVELOCITY:
5931 		float_data = atof((char *) data);
5932 		Q3_SetVelocity( entID, 1, float_data);
5933 		break;
5934 
5935 	case SET_ZVELOCITY:
5936 		float_data = atof((char *) data);
5937 		Q3_SetVelocity( entID, 2, float_data);
5938 		break;
5939 
5940 	case SET_Z_OFFSET:
5941 		float_data = atof((char *) data);
5942 		Q3_SetOriginOffset( entID, 2, float_data);
5943 		break;
5944 
5945 	case SET_ENEMY:
5946 		Q3_SetEnemy( entID, (char *) data );
5947 		break;
5948 
5949 	case SET_LEADER:
5950 		Q3_SetLeader( entID, (char *) data );
5951 		break;
5952 
5953 	case SET_NAVGOAL:
5954 		if ( Q3_SetNavGoal( entID, (char *) data ) )
5955 		{
5956 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_MOVE_NAV, taskID );
5957 			return qfalse;	//Don't call it back
5958 		}
5959 		break;
5960 
5961 	case SET_ANIM_UPPER:
5962 		if ( Q3_SetAnimUpper( entID, (char *) data ) )
5963 		{
5964 			Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the top
5965 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_UPPER, taskID );
5966 			return qfalse;	//Don't call it back
5967 		}
5968 		break;
5969 
5970 	case SET_ANIM_LOWER:
5971 		if ( Q3_SetAnimLower( entID, (char *) data ) )
5972 		{
5973 			Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the bottom
5974 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_LOWER, taskID );
5975 			return qfalse;	//Don't call it back
5976 		}
5977 		break;
5978 
5979 	case SET_ANIM_BOTH:
5980 		{
5981 			int	both = 0;
5982 			if ( Q3_SetAnimUpper( entID, (char *) data ) )
5983 			{
5984 				trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_UPPER, taskID );
5985 				both++;
5986 			}
5987 			else
5988 			{
5989 				G_DebugPrint( WL_ERROR, "Q3_SetAnimUpper: %s does not have anim %s!\n", ent->targetname, (char *)data );
5990 			}
5991 			if ( Q3_SetAnimLower( entID, (char *) data ) )
5992 			{
5993 				trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_LOWER, taskID );
5994 				both++;
5995 			}
5996 			else
5997 			{
5998 				G_DebugPrint( WL_ERROR, "Q3_SetAnimLower: %s does not have anim %s!\n", ent->targetname, (char *)data );
5999 			}
6000 			if ( both >= 2 )
6001 			{
6002 				trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_BOTH, taskID );
6003 			}
6004 			if ( both )
6005 			{
6006 				return qfalse;	//Don't call it back
6007 			}
6008 		}
6009 		break;
6010 
6011 	case SET_ANIM_HOLDTIME_LOWER:
6012 		int_data = atoi((char *) data);
6013 		Q3_SetAnimHoldTime( entID, int_data, qtrue );
6014 		Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the bottom
6015 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_LOWER, taskID );
6016 		return qfalse;	//Don't call it back
6017 		break;
6018 
6019 	case SET_ANIM_HOLDTIME_UPPER:
6020 		int_data = atoi((char *) data);
6021 		Q3_SetAnimHoldTime( entID, int_data, qfalse );
6022 		Q3_TaskIDClear( &ent->taskID[TID_ANIM_BOTH] );//We only want to wait for the top
6023 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_UPPER, taskID );
6024 		return qfalse;	//Don't call it back
6025 		break;
6026 
6027 	case SET_ANIM_HOLDTIME_BOTH:
6028 		int_data = atoi((char *) data);
6029 		Q3_SetAnimHoldTime( entID, int_data, qfalse );
6030 		Q3_SetAnimHoldTime( entID, int_data, qtrue );
6031 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_BOTH, taskID );
6032 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_UPPER, taskID );
6033 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_LOWER, taskID );
6034 		return qfalse;	//Don't call it back
6035 		break;
6036 
6037 	case SET_PLAYER_TEAM:
6038 		G_DebugPrint( WL_WARNING, "Q3_SetPlayerTeam: Not in MP ATM, let a programmer (ideally Rich) know if you need it\n");
6039 		break;
6040 
6041 	case SET_ENEMY_TEAM:
6042 		G_DebugPrint( WL_WARNING, "Q3_SetEnemyTeam: NOT SUPPORTED IN MP\n");
6043 		break;
6044 
6045 	case SET_HEALTH:
6046 		int_data = atoi((char *) data);
6047 		Q3_SetHealth( entID, int_data );
6048 		break;
6049 
6050 	case SET_ARMOR:
6051 		int_data = atoi((char *) data);
6052 		Q3_SetArmor( entID, int_data );
6053 		break;
6054 
6055 	case SET_BEHAVIOR_STATE:
6056 		if( !Q3_SetBState( entID, (char *) data ) )
6057 		{
6058 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_BSTATE, taskID );
6059 			return qfalse;//don't complete
6060 		}
6061 		break;
6062 
6063 	case SET_DEFAULT_BSTATE:
6064 		Q3_SetDefaultBState( entID, (char *) data );
6065 		break;
6066 
6067 	case SET_TEMP_BSTATE:
6068 		if( !Q3_SetTempBState( entID, (char *) data ) )
6069 		{
6070 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_BSTATE, taskID );
6071 			return qfalse;//don't complete
6072 		}
6073 		break;
6074 
6075 	case SET_CAPTURE:
6076 		Q3_SetCaptureGoal( entID, (char *) data );
6077 		break;
6078 
6079 	case SET_DPITCH://FIXME: make these set tempBehavior to BS_FACE and await completion?  Or set lockedDesiredPitch/Yaw and aimTime?
6080 		float_data = atof((char *) data);
6081 		Q3_SetDPitch( entID, float_data );
6082 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANGLE_FACE, taskID );
6083 		return qfalse;
6084 		break;
6085 
6086 	case SET_DYAW:
6087 		float_data = atof((char *) data);
6088 		Q3_SetDYaw( entID, float_data );
6089 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANGLE_FACE, taskID );
6090 		return qfalse;
6091 		break;
6092 
6093 	case SET_EVENT:
6094 		Q3_SetEvent( entID, (char *) data );
6095 		break;
6096 
6097 	case SET_VIEWTARGET:
6098 		Q3_SetViewTarget( entID, (char *) data );
6099 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANGLE_FACE, taskID );
6100 		return qfalse;
6101 		break;
6102 
6103 	case SET_WATCHTARGET:
6104 		Q3_SetWatchTarget( entID, (char *) data );
6105 		break;
6106 
6107 	case SET_VIEWENTITY:
6108 		Q3_SetViewEntity( entID, (char *) data );
6109 		break;
6110 
6111 	case SET_LOOPSOUND:
6112 		Q3_SetLoopSound( entID, (char *) data );
6113 		break;
6114 
6115 	case SET_ICARUS_FREEZE:
6116 	case SET_ICARUS_UNFREEZE:
6117 		Q3_SetICARUSFreeze( entID, (char *) data, (qboolean)(toSet==SET_ICARUS_FREEZE) );
6118 		break;
6119 
6120 	case SET_WEAPON:
6121 		Q3_SetWeapon ( entID, (char *) data);
6122 		break;
6123 
6124 	case SET_ITEM:
6125 		Q3_SetItem ( entID, (char *) data);
6126 		break;
6127 
6128 	case SET_WALKSPEED:
6129 		int_data = atoi((char *) data);
6130 		Q3_SetWalkSpeed ( entID, int_data);
6131 		break;
6132 
6133 	case SET_RUNSPEED:
6134 		int_data = atoi((char *) data);
6135 		Q3_SetRunSpeed ( entID, int_data);
6136 		break;
6137 
6138 	case SET_WIDTH:
6139 		int_data = atoi((char *) data);
6140 		Q3_SetWidth( entID, int_data );
6141 		return qfalse;
6142 		break;
6143 
6144 	case SET_YAWSPEED:
6145 		float_data = atof((char *) data);
6146 		Q3_SetYawSpeed ( entID, float_data);
6147 		break;
6148 
6149 	case SET_AGGRESSION:
6150 		int_data = atoi((char *) data);
6151 		Q3_SetAggression ( entID, int_data);
6152 		break;
6153 
6154 	case SET_AIM:
6155 		int_data = atoi((char *) data);
6156 		Q3_SetAim ( entID, int_data);
6157 		break;
6158 
6159 	case SET_FRICTION:
6160 		int_data = atoi((char *) data);
6161 		Q3_SetFriction ( entID, int_data);
6162 		break;
6163 
6164 	case SET_GRAVITY:
6165 		float_data = atof((char *) data);
6166 		Q3_SetGravity ( entID, float_data);
6167 		break;
6168 
6169 	case SET_WAIT:
6170 		float_data = atof((char *) data);
6171 		Q3_SetWait( entID, float_data);
6172 		break;
6173 
6174 	case SET_FOLLOWDIST:
6175 		float_data = atof((char *) data);
6176 		Q3_SetFollowDist( entID, float_data);
6177 		break;
6178 
6179 	case SET_SCALE:
6180 		float_data = atof((char *) data);
6181 		Q3_SetScale( entID, float_data);
6182 		break;
6183 
6184 	case SET_COUNT:
6185 		Q3_SetCount( entID, (char *) data);
6186 		break;
6187 
6188 	case SET_SHOT_SPACING:
6189 		int_data = atoi((char *) data);
6190 		Q3_SetShotSpacing( entID, int_data );
6191 		break;
6192 
6193 	case SET_IGNOREPAIN:
6194 		if(!Q_stricmp("true", ((char *)data)))
6195 			Q3_SetIgnorePain( entID, qtrue);
6196 		else if(!Q_stricmp("false", ((char *)data)))
6197 			Q3_SetIgnorePain( entID, qfalse);
6198 		break;
6199 
6200 	case SET_IGNOREENEMIES:
6201 		if(!Q_stricmp("true", ((char *)data)))
6202 			Q3_SetIgnoreEnemies( entID, qtrue);
6203 		else if(!Q_stricmp("false", ((char *)data)))
6204 			Q3_SetIgnoreEnemies( entID, qfalse);
6205 		break;
6206 
6207 	case SET_IGNOREALERTS:
6208 		if(!Q_stricmp("true", ((char *)data)))
6209 			Q3_SetIgnoreAlerts( entID, qtrue);
6210 		else if(!Q_stricmp("false", ((char *)data)))
6211 			Q3_SetIgnoreAlerts( entID, qfalse);
6212 		break;
6213 
6214 	case SET_DONTSHOOT:
6215 		if(!Q_stricmp("true", ((char *)data)))
6216 			Q3_SetDontShoot( entID, qtrue);
6217 		else if(!Q_stricmp("false", ((char *)data)))
6218 			Q3_SetDontShoot( entID, qfalse);
6219 		break;
6220 
6221 	case SET_DONTFIRE:
6222 		if(!Q_stricmp("true", ((char *)data)))
6223 			Q3_SetDontFire( entID, qtrue);
6224 		else if(!Q_stricmp("false", ((char *)data)))
6225 			Q3_SetDontFire( entID, qfalse);
6226 		break;
6227 
6228 	case SET_LOCKED_ENEMY:
6229 		if(!Q_stricmp("true", ((char *)data)))
6230 			Q3_SetLockedEnemy( entID, qtrue);
6231 		else if(!Q_stricmp("false", ((char *)data)))
6232 			Q3_SetLockedEnemy( entID, qfalse);
6233 		break;
6234 
6235 	case SET_NOTARGET:
6236 		if(!Q_stricmp("true", ((char *)data)))
6237 			Q3_SetNoTarget( entID, qtrue);
6238 		else if(!Q_stricmp("false", ((char *)data)))
6239 			Q3_SetNoTarget( entID, qfalse);
6240 		break;
6241 
6242 	case SET_LEAN:
6243 		G_DebugPrint( WL_WARNING, "SET_LEAN NOT SUPPORTED IN MP\n" );
6244 		break;
6245 
6246 	case SET_SHOOTDIST:
6247 		float_data = atof((char *) data);
6248 		Q3_SetShootDist( entID, float_data );
6249 		break;
6250 
6251 	case SET_TIMESCALE:
6252 		Q3_SetTimeScale( entID, (char *) data );
6253 		break;
6254 
6255 	case SET_VISRANGE:
6256 		float_data = atof((char *) data);
6257 		Q3_SetVisrange( entID, float_data );
6258 		break;
6259 
6260 	case SET_EARSHOT:
6261 		float_data = atof((char *) data);
6262 		Q3_SetEarshot( entID, float_data );
6263 		break;
6264 
6265 	case SET_VIGILANCE:
6266 		float_data = atof((char *) data);
6267 		Q3_SetVigilance( entID, float_data );
6268 		break;
6269 
6270 	case SET_VFOV:
6271 		int_data = atoi((char *) data);
6272 		Q3_SetVFOV( entID, int_data );
6273 		break;
6274 
6275 	case SET_HFOV:
6276 		int_data = atoi((char *) data);
6277 		Q3_SetHFOV( entID, int_data );
6278 		break;
6279 
6280 	case SET_TARGETNAME:
6281 		Q3_SetTargetName( entID, (char *) data );
6282 		break;
6283 
6284 	case SET_TARGET:
6285 		Q3_SetTarget( entID, (char *) data );
6286 		break;
6287 
6288 	case SET_TARGET2:
6289 		Q3_SetTarget2( entID, (char *) data );
6290 		break;
6291 
6292 	case SET_LOCATION:
6293 		if ( !Q3_SetLocation( entID, (char *) data ) )
6294 		{
6295 			trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_LOCATION, taskID );
6296 			return qfalse;
6297 		}
6298 		break;
6299 
6300 	case SET_PAINTARGET:
6301 		Q3_SetPainTarget( entID, (char *) data );
6302 		break;
6303 
6304 	case SET_DEFEND_TARGET:
6305 		G_DebugPrint( WL_WARNING, "Q3_SetDefendTarget unimplemented\n", entID );
6306 		//Q3_SetEnemy( entID, (char *) data);
6307 		break;
6308 
6309 	case SET_PARM1:
6310 	case SET_PARM2:
6311 	case SET_PARM3:
6312 	case SET_PARM4:
6313 	case SET_PARM5:
6314 	case SET_PARM6:
6315 	case SET_PARM7:
6316 	case SET_PARM8:
6317 	case SET_PARM9:
6318 	case SET_PARM10:
6319 	case SET_PARM11:
6320 	case SET_PARM12:
6321 	case SET_PARM13:
6322 	case SET_PARM14:
6323 	case SET_PARM15:
6324 	case SET_PARM16:
6325 		Q3_SetParm( entID, (toSet-SET_PARM1), (char *) data );
6326 		break;
6327 
6328 	case SET_SPAWNSCRIPT:
6329 	case SET_USESCRIPT:
6330 	case SET_AWAKESCRIPT:
6331 	case SET_ANGERSCRIPT:
6332 	case SET_ATTACKSCRIPT:
6333 	case SET_VICTORYSCRIPT:
6334 	case SET_PAINSCRIPT:
6335 	case SET_FLEESCRIPT:
6336 	case SET_DEATHSCRIPT:
6337 	case SET_DELAYEDSCRIPT:
6338 	case SET_BLOCKEDSCRIPT:
6339 	case SET_FFIRESCRIPT:
6340 	case SET_FFDEATHSCRIPT:
6341 	case SET_MINDTRICKSCRIPT:
6342 		if( !Q3_SetBehaviorSet(entID, toSet, (char *) data) )
6343 			G_DebugPrint( WL_ERROR, "Q3_SetBehaviorSet: Invalid bSet %s\n", type_name );
6344 		break;
6345 
6346 	case SET_NO_MINDTRICK:
6347 		if(!Q_stricmp("true", ((char *)data)))
6348 			Q3_SetNoMindTrick( entID, qtrue);
6349 		else
6350 			Q3_SetNoMindTrick( entID, qfalse);
6351 		break;
6352 
6353 	case SET_CINEMATIC_SKIPSCRIPT :
6354 		Q3_SetCinematicSkipScript((char *) data);
6355 		break;
6356 
6357 
6358 	case SET_DELAYSCRIPTTIME:
6359 		int_data = atoi((char *) data);
6360 		Q3_SetDelayScriptTime( entID, int_data );
6361 		break;
6362 
6363 	case SET_CROUCHED:
6364 		if(!Q_stricmp("true", ((char *)data)))
6365 			Q3_SetCrouched( entID, qtrue);
6366 		else
6367 			Q3_SetCrouched( entID, qfalse);
6368 		break;
6369 
6370 	case SET_WALKING:
6371 		if(!Q_stricmp("true", ((char *)data)))
6372 			Q3_SetWalking( entID, qtrue);
6373 		else
6374 			Q3_SetWalking( entID, qfalse);
6375 		break;
6376 
6377 	case SET_RUNNING:
6378 		if(!Q_stricmp("true", ((char *)data)))
6379 			Q3_SetRunning( entID, qtrue);
6380 		else
6381 			Q3_SetRunning( entID, qfalse);
6382 		break;
6383 
6384 	case SET_CHASE_ENEMIES:
6385 		if(!Q_stricmp("true", ((char *)data)))
6386 			Q3_SetChaseEnemies( entID, qtrue);
6387 		else
6388 			Q3_SetChaseEnemies( entID, qfalse);
6389 		break;
6390 
6391 	case SET_LOOK_FOR_ENEMIES:
6392 		if(!Q_stricmp("true", ((char *)data)))
6393 			Q3_SetLookForEnemies( entID, qtrue);
6394 		else
6395 			Q3_SetLookForEnemies( entID, qfalse);
6396 		break;
6397 
6398 	case SET_FACE_MOVE_DIR:
6399 		if(!Q_stricmp("true", ((char *)data)))
6400 			Q3_SetFaceMoveDir( entID, qtrue);
6401 		else
6402 			Q3_SetFaceMoveDir( entID, qfalse);
6403 		break;
6404 
6405 	case SET_ALT_FIRE:
6406 		if(!Q_stricmp("true", ((char *)data)))
6407 			Q3_SetAltFire( entID, qtrue);
6408 		else
6409 			Q3_SetAltFire( entID, qfalse);
6410 		break;
6411 
6412 	case SET_DONT_FLEE:
6413 		if(!Q_stricmp("true", ((char *)data)))
6414 			Q3_SetDontFlee( entID, qtrue);
6415 		else
6416 			Q3_SetDontFlee( entID, qfalse);
6417 		break;
6418 
6419 	case SET_FORCED_MARCH:
6420 		if(!Q_stricmp("true", ((char *)data)))
6421 			Q3_SetForcedMarch( entID, qtrue);
6422 		else
6423 			Q3_SetForcedMarch( entID, qfalse);
6424 		break;
6425 
6426 	case SET_NO_RESPONSE:
6427 		if(!Q_stricmp("true", ((char *)data)))
6428 			Q3_SetNoResponse( entID, qtrue);
6429 		else
6430 			Q3_SetNoResponse( entID, qfalse);
6431 		break;
6432 
6433 	case SET_NO_COMBAT_TALK:
6434 		if(!Q_stricmp("true", ((char *)data)))
6435 			Q3_SetCombatTalk( entID, qtrue);
6436 		else
6437 			Q3_SetCombatTalk( entID, qfalse);
6438 		break;
6439 
6440 	case SET_NO_ALERT_TALK:
6441 		if(!Q_stricmp("true", ((char *)data)))
6442 			Q3_SetAlertTalk( entID, qtrue);
6443 		else
6444 			Q3_SetAlertTalk( entID, qfalse);
6445 		break;
6446 
6447 	case SET_USE_CP_NEAREST:
6448 		if(!Q_stricmp("true", ((char *)data)))
6449 			Q3_SetUseCpNearest( entID, qtrue);
6450 		else
6451 			Q3_SetUseCpNearest( entID, qfalse);
6452 		break;
6453 
6454 	case SET_NO_FORCE:
6455 		if(!Q_stricmp("true", ((char *)data)))
6456 			Q3_SetNoForce( entID, qtrue);
6457 		else
6458 			Q3_SetNoForce( entID, qfalse);
6459 		break;
6460 
6461 	case SET_NO_ACROBATICS:
6462 		if(!Q_stricmp("true", ((char *)data)))
6463 			Q3_SetNoAcrobatics( entID, qtrue);
6464 		else
6465 			Q3_SetNoAcrobatics( entID, qfalse);
6466 		break;
6467 
6468 	case SET_USE_SUBTITLES:
6469 		if(!Q_stricmp("true", ((char *)data)))
6470 			Q3_SetUseSubtitles( entID, qtrue);
6471 		else
6472 			Q3_SetUseSubtitles( entID, qfalse);
6473 		break;
6474 
6475 	case SET_NO_FALLTODEATH:
6476 		if(!Q_stricmp("true", ((char *)data)))
6477 			Q3_SetNoFallToDeath( entID, qtrue);
6478 		else
6479 			Q3_SetNoFallToDeath( entID, qfalse);
6480 		break;
6481 
6482 	case SET_DISMEMBERABLE:
6483 		if(!Q_stricmp("true", ((char *)data)))
6484 			Q3_SetDismemberable( entID, qtrue);
6485 		else
6486 			Q3_SetDismemberable( entID, qfalse);
6487 		break;
6488 
6489 	case SET_MORELIGHT:
6490 		if(!Q_stricmp("true", ((char *)data)))
6491 			Q3_SetMoreLight( entID, qtrue);
6492 		else
6493 			Q3_SetMoreLight( entID, qfalse);
6494 		break;
6495 
6496 
6497 	case SET_TREASONED:
6498 		G_DebugPrint( WL_VERBOSE, "SET_TREASONED is disabled, do not use\n" );
6499 		/*
6500 		G_TeamRetaliation( NULL, SV_GentityNum(0), qfalse );
6501 		ffireLevel = FFIRE_LEVEL_RETALIATION;
6502 		*/
6503 		break;
6504 
6505 	case SET_UNDYING:
6506 		if(!Q_stricmp("true", ((char *)data)))
6507 			Q3_SetUndying( entID, qtrue);
6508 		else
6509 			Q3_SetUndying( entID, qfalse);
6510 		break;
6511 
6512 	case SET_INVINCIBLE:
6513 		if(!Q_stricmp("true", ((char *)data)))
6514 			Q3_SetInvincible( entID, qtrue);
6515 		else
6516 			Q3_SetInvincible( entID, qfalse);
6517 		break;
6518 
6519 	case SET_NOAVOID:
6520 		if(!Q_stricmp("true", ((char *)data)))
6521 			Q3_SetNoAvoid( entID, qtrue);
6522 		else
6523 			Q3_SetNoAvoid( entID, qfalse);
6524 		break;
6525 
6526 	case SET_SOLID:
6527 		if(!Q_stricmp("true", ((char *)data)))
6528 		{
6529 			if ( !Q3_SetSolid( entID, qtrue) )
6530 			{
6531 				trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_RESIZE, taskID );
6532 				return qfalse;
6533 			}
6534 		}
6535 		else
6536 		{
6537 			Q3_SetSolid( entID, qfalse);
6538 		}
6539 		break;
6540 
6541 	case SET_INVISIBLE:
6542 		if( !Q_stricmp("true", ((char *)data)) )
6543 			Q3_SetInvisible( entID, qtrue );
6544 		else
6545 			Q3_SetInvisible( entID, qfalse );
6546 		break;
6547 
6548 	case SET_VAMPIRE:
6549 		if( !Q_stricmp("true", ((char *)data)) )
6550 			Q3_SetVampire( entID, qtrue );
6551 		else
6552 			Q3_SetVampire( entID, qfalse );
6553 		break;
6554 
6555 	case SET_FORCE_INVINCIBLE:
6556 		if( !Q_stricmp("true", ((char *)data)) )
6557 			Q3_SetForceInvincible( entID, qtrue );
6558 		else
6559 			Q3_SetForceInvincible( entID, qfalse );
6560 		break;
6561 
6562 	case SET_GREET_ALLIES:
6563 		if( !Q_stricmp("true", ((char *)data)) )
6564 			Q3_SetGreetAllies( entID, qtrue );
6565 		else
6566 			Q3_SetGreetAllies( entID, qfalse );
6567 		break;
6568 
6569 	case SET_PLAYER_LOCKED:
6570 		if( !Q_stricmp("true", ((char *)data)) )
6571 			Q3_SetPlayerLocked( entID, qtrue );
6572 		else
6573 			Q3_SetPlayerLocked( entID, qfalse );
6574 		break;
6575 
6576 	case SET_LOCK_PLAYER_WEAPONS:
6577 		if( !Q_stricmp("true", ((char *)data)) )
6578 			Q3_SetLockPlayerWeapons( entID, qtrue );
6579 		else
6580 			Q3_SetLockPlayerWeapons( entID, qfalse );
6581 		break;
6582 
6583 	case SET_NO_IMPACT_DAMAGE:
6584 		if( !Q_stricmp("true", ((char *)data)) )
6585 			Q3_SetNoImpactDamage( entID, qtrue );
6586 		else
6587 			Q3_SetNoImpactDamage( entID, qfalse );
6588 		break;
6589 
6590 	case SET_FORWARDMOVE:
6591 		int_data = atoi((char *) data);
6592 		Q3_SetForwardMove( entID, int_data);
6593 		break;
6594 
6595 	case SET_RIGHTMOVE:
6596 		int_data = atoi((char *) data);
6597 		Q3_SetRightMove( entID, int_data);
6598 		break;
6599 
6600 	case SET_LOCKYAW:
6601 		Q3_SetLockAngle( entID, data);
6602 		break;
6603 
6604 	case SET_CAMERA_GROUP:
6605 		Q3_CameraGroup(entID, (char *)data);
6606 		break;
6607 	case SET_CAMERA_GROUP_Z_OFS:
6608 		float_data = atof((char *) data);
6609 		Q3_CameraGroupZOfs( float_data );
6610 		break;
6611 	case SET_CAMERA_GROUP_TAG:
6612 		Q3_CameraGroupTag( (char *)data );
6613 		break;
6614 
6615 	//FIXME: put these into camera commands
6616 	case SET_LOOK_TARGET:
6617 		Q3_LookTarget(entID, (char *)data);
6618 		break;
6619 
6620 	case SET_ADDRHANDBOLT_MODEL:
6621 		Q3_AddRHandModel(entID, (char *)data);
6622 		break;
6623 
6624 	case SET_REMOVERHANDBOLT_MODEL:
6625 		Q3_RemoveRHandModel(entID, (char *)data);
6626 		break;
6627 
6628 	case SET_ADDLHANDBOLT_MODEL:
6629 		Q3_AddLHandModel(entID, (char *)data);
6630 		break;
6631 
6632 	case SET_REMOVELHANDBOLT_MODEL:
6633 		Q3_RemoveLHandModel(entID, (char *)data);
6634 		break;
6635 
6636 	case SET_FACEEYESCLOSED:
6637 	case SET_FACEEYESOPENED:
6638 	case SET_FACEAUX:
6639 	case SET_FACEBLINK:
6640 	case SET_FACEBLINKFROWN:
6641 	case SET_FACEFROWN:
6642 	case SET_FACENORMAL:
6643 		float_data = atof((char *) data);
6644 		Q3_Face(entID, toSet, float_data);
6645 		break;
6646 
6647 	case SET_SCROLLTEXT:
6648 		Q3_ScrollText( (char *)data );
6649 		break;
6650 
6651 	case SET_LCARSTEXT:
6652 		Q3_LCARSText( (char *)data );
6653 		break;
6654 
6655 	case SET_CAPTIONTEXTCOLOR:
6656 		Q3_SetCaptionTextColor ( (char *)data );
6657 		break;
6658 	case SET_CENTERTEXTCOLOR:
6659 		Q3_SetCenterTextColor ( (char *)data );
6660 		break;
6661 	case SET_SCROLLTEXTCOLOR:
6662 		Q3_SetScrollTextColor ( (char *)data );
6663 		break;
6664 
6665 	case SET_PLAYER_USABLE:
6666 		if(!Q_stricmp("true", ((char *)data)))
6667 		{
6668 			Q3_SetPlayerUsable(entID, qtrue);
6669 		}
6670 		else
6671 		{
6672 			Q3_SetPlayerUsable(entID, qfalse);
6673 		}
6674 		break;
6675 
6676 	case SET_STARTFRAME:
6677 		int_data = atoi((char *) data);
6678 		Q3_SetStartFrame(entID, int_data);
6679 		break;
6680 
6681 	case SET_ENDFRAME:
6682 		int_data = atoi((char *) data);
6683 		Q3_SetEndFrame(entID, int_data);
6684 
6685 		trap->ICARUS_TaskIDSet( (sharedEntity_t *)ent, TID_ANIM_BOTH, taskID );
6686 		return qfalse;
6687 		break;
6688 
6689 	case SET_ANIMFRAME:
6690 		int_data = atoi((char *) data);
6691 		Q3_SetAnimFrame(entID, int_data);
6692 		return qfalse;
6693 		break;
6694 
6695 	case SET_LOOP_ANIM:
6696 		if(!Q_stricmp("true", ((char *)data)))
6697 		{
6698 			Q3_SetLoopAnim(entID, qtrue);
6699 		}
6700 		else
6701 		{
6702 			Q3_SetLoopAnim(entID, qfalse);
6703 		}
6704 		break;
6705 
6706 	case SET_INTERFACE:
6707 		G_DebugPrint( WL_WARNING, "Q3_SetInterface: NOT SUPPORTED IN MP\n");
6708 
6709 		break;
6710 
6711 	case SET_SHIELDS:
6712 		if(!Q_stricmp("true", ((char *)data)))
6713 		{
6714 			Q3_SetShields(entID, qtrue);
6715 		}
6716 		else
6717 		{
6718 			Q3_SetShields(entID, qfalse);
6719 		}
6720 		break;
6721 
6722 	case SET_SABERACTIVE:
6723 		if(!Q_stricmp("true", ((char *)data)))
6724 		{
6725 			Q3_SetSaberActive( entID, qtrue );
6726 		}
6727 		else
6728 		{
6729 			Q3_SetSaberActive( entID, qfalse );
6730 		}
6731 		break;
6732 
6733 	case SET_ADJUST_AREA_PORTALS:
6734 		G_DebugPrint( WL_WARNING, "Q3_SetAdjustAreaPortals: NOT SUPPORTED IN MP\n");
6735 		break;
6736 
6737 	case SET_DMG_BY_HEAVY_WEAP_ONLY:
6738 		G_DebugPrint( WL_WARNING, "Q3_SetDmgByHeavyWeapOnly: NOT SUPPORTED IN MP\n");
6739 		break;
6740 
6741 	case SET_SHIELDED:
6742 		G_DebugPrint( WL_WARNING, "Q3_SetShielded: NOT SUPPORTED IN MP\n");
6743 		break;
6744 
6745 	case SET_NO_GROUPS:
6746 		G_DebugPrint( WL_WARNING, "Q3_SetNoGroups: NOT SUPPORTED IN MP\n");
6747 		break;
6748 
6749 	case SET_FIRE_WEAPON:
6750 		if(!Q_stricmp("true", ((char *)data)))
6751 		{
6752 			Q3_SetFireWeapon( entID, qtrue);
6753 		}
6754 		else if(!Q_stricmp("false", ((char *)data)))
6755 		{
6756 			Q3_SetFireWeapon( entID, qfalse);
6757 		}
6758 		break;
6759 
6760 	case SET_INACTIVE:
6761 		if(!Q_stricmp("true", ((char *)data)))
6762 		{
6763 			Q3_SetInactive( entID, qtrue);
6764 		}
6765 		else if(!Q_stricmp("false", ((char *)data)))
6766 		{
6767 			Q3_SetInactive( entID, qfalse);
6768 		}
6769 		else if(!Q_stricmp("unlocked", ((char *)data)))
6770 		{
6771 			UnLockDoors(&g_entities[entID]);
6772 		}
6773 		else if(!Q_stricmp("locked", ((char *)data)))
6774 		{
6775 			LockDoors(&g_entities[entID]);
6776 		}
6777 		break;
6778 	case SET_END_SCREENDISSOLVE:
6779 		G_DebugPrint( WL_WARNING, "SET_END_SCREENDISSOLVE: NOT SUPPORTED IN MP\n");
6780 		break;
6781 
6782 	case SET_MISSION_STATUS_SCREEN:
6783 		//Cvar_Set("cg_missionstatusscreen", "1");
6784 		G_DebugPrint( WL_WARNING, "SET_MISSION_STATUS_SCREEN: NOT SUPPORTED IN MP\n");
6785 		break;
6786 
6787 	case SET_FUNC_USABLE_VISIBLE:
6788 		if(!Q_stricmp("true", ((char *)data)))
6789 		{
6790 			Q3_SetFuncUsableVisible( entID, qtrue);
6791 		}
6792 		else if(!Q_stricmp("false", ((char *)data)))
6793 		{
6794 			Q3_SetFuncUsableVisible( entID, qfalse);
6795 		}
6796 		break;
6797 
6798 	case SET_NO_KNOCKBACK:
6799 		if(!Q_stricmp("true", ((char *)data)))
6800 		{
6801 			Q3_SetNoKnockback(entID, qtrue);
6802 		}
6803 		else
6804 		{
6805 			Q3_SetNoKnockback(entID, qfalse);
6806 		}
6807 		break;
6808 
6809 	case SET_VIDEO_PLAY:
6810 		// don't do this check now, James doesn't want a scripted cinematic to also skip any Video cinematics as well,
6811 		//	the "timescale" and "skippingCinematic" cvars will be set back to normal in the Video code, so doing a
6812 		//	skip will now only skip one section of a multiple-part story (eg VOY1 bridge sequence)
6813 		//
6814 //		if ( g_timescale->value <= 1.0f )
6815 		{
6816 			G_DebugPrint( WL_WARNING, "SET_VIDEO_PLAY: NOT SUPPORTED IN MP\n");
6817 			//SV_SendConsoleCommand( va("inGameCinematic %s\n", (char *)data) );
6818 		}
6819 		break;
6820 
6821 	case SET_VIDEO_FADE_IN:
6822 		G_DebugPrint( WL_WARNING, "SET_VIDEO_FADE_IN: NOT SUPPORTED IN MP\n");
6823 		break;
6824 
6825 	case SET_VIDEO_FADE_OUT:
6826 		G_DebugPrint( WL_WARNING, "SET_VIDEO_FADE_OUT: NOT SUPPORTED IN MP\n");
6827 		break;
6828 	case SET_REMOVE_TARGET:
6829 		Q3_SetRemoveTarget( entID, (const char *) data );
6830 		break;
6831 
6832 	case SET_LOADGAME:
6833 		//trap->SendConsoleCommand( va("load %s\n", (const char *) data ) );
6834 		G_DebugPrint( WL_WARNING, "SET_LOADGAME: NOT SUPPORTED IN MP\n");
6835 		break;
6836 
6837 	case SET_MENU_SCREEN:
6838 		//UI_SetActiveMenu( (const char *) data );
6839 		break;
6840 
6841 	case SET_OBJECTIVE_SHOW:
6842 		G_DebugPrint( WL_WARNING, "SET_OBJECTIVE_SHOW: NOT SUPPORTED IN MP\n");
6843 		break;
6844 	case SET_OBJECTIVE_HIDE:
6845 		G_DebugPrint( WL_WARNING, "SET_OBJECTIVE_HIDE: NOT SUPPORTED IN MP\n");
6846 		break;
6847 	case SET_OBJECTIVE_SUCCEEDED:
6848 		G_DebugPrint( WL_WARNING, "SET_OBJECTIVE_SUCCEEDED: NOT SUPPORTED IN MP\n");
6849 		break;
6850 	case SET_OBJECTIVE_FAILED:
6851 		G_DebugPrint( WL_WARNING, "SET_OBJECTIVE_FAILED: NOT SUPPORTED IN MP\n");
6852 		break;
6853 
6854 	case SET_OBJECTIVE_CLEARALL:
6855 		G_DebugPrint( WL_WARNING, "SET_OBJECTIVE_CLEARALL: NOT SUPPORTED IN MP\n");
6856 		break;
6857 
6858 	case SET_MISSIONFAILED:
6859 		G_DebugPrint( WL_WARNING, "SET_MISSIONFAILED: NOT SUPPORTED IN MP\n");
6860 		break;
6861 
6862 	case SET_MISSIONSTATUSTEXT:
6863 		G_DebugPrint( WL_WARNING, "SET_MISSIONSTATUSTEXT: NOT SUPPORTED IN MP\n");
6864 		break;
6865 
6866 	case SET_MISSIONSTATUSTIME:
6867 		G_DebugPrint( WL_WARNING, "SET_MISSIONSTATUSTIME: NOT SUPPORTED IN MP\n");
6868 		break;
6869 
6870 	case SET_CLOSINGCREDITS:
6871 		G_DebugPrint( WL_WARNING, "SET_CLOSINGCREDITS: NOT SUPPORTED IN MP\n");
6872 		break;
6873 
6874 	case SET_SKILL:
6875 //		//can never be set
6876 		break;
6877 
6878 	case SET_FULLNAME:
6879 		Q3_SetFullName( entID, (char *) data );
6880 		break;
6881 
6882 	case SET_DISABLE_SHADER_ANIM:
6883 		if(!Q_stricmp("true", ((char *)data)))
6884 		{
6885 			Q3_SetDisableShaderAnims( entID, qtrue);
6886 		}
6887 		else
6888 		{
6889 			Q3_SetDisableShaderAnims( entID, qfalse);
6890 		}
6891 		break;
6892 
6893 	case SET_SHADER_ANIM:
6894 		if(!Q_stricmp("true", ((char *)data)))
6895 		{
6896 			Q3_SetShaderAnim( entID, qtrue);
6897 		}
6898 		else
6899 		{
6900 			Q3_SetShaderAnim( entID, qfalse);
6901 		}
6902 		break;
6903 
6904 	case SET_MUSIC_STATE:
6905 		Q3_SetMusicState( (char *) data );
6906 		break;
6907 
6908 	case SET_CLEAN_DAMAGING_ENTS:
6909 		Q3_SetCleanDamagingEnts();
6910 		break;
6911 
6912 	case SET_HUD:
6913 		G_DebugPrint( WL_WARNING, "SET_HUD: NOT SUPPORTED IN MP\n");
6914 		break;
6915 
6916 	case SET_FORCE_HEAL_LEVEL:
6917 	case SET_FORCE_JUMP_LEVEL:
6918 	case SET_FORCE_SPEED_LEVEL:
6919 	case SET_FORCE_PUSH_LEVEL:
6920 	case SET_FORCE_PULL_LEVEL:
6921 	case SET_FORCE_MINDTRICK_LEVEL:
6922 	case SET_FORCE_GRIP_LEVEL:
6923 	case SET_FORCE_LIGHTNING_LEVEL:
6924 	case SET_SABER_THROW:
6925 	case SET_SABER_DEFENSE:
6926 	case SET_SABER_OFFENSE:
6927 		int_data = atoi((char *) data);
6928 		Q3_SetForcePowerLevel( entID, (toSet-SET_FORCE_HEAL_LEVEL), int_data );
6929 		break;
6930 
6931 	default:
6932 		//G_DebugPrint( WL_ERROR, "Q3_Set: '%s' is not a valid set field\n", type_name );
6933 		trap->ICARUS_SetVar( taskID, entID, type_name, data );
6934 		break;
6935 	}
6936 
6937 	return qtrue;
6938 }
6939