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