00001
00002
00003
00004
00005
00006
00007 #include "q_shared.h"
00008 #include "bg_public.h"
00009 #include "b_local.h"
00010 #include "../icarus/Q3_Interface.h"
00011 #include "../icarus/Q3_Registers.h"
00012 #include "g_nav.h"
00013
00014 #include "../namespace_begin.h"
00015 qboolean BG_SabersOff( playerState_t *ps );
00016 extern stringID_table_t WPTable[];
00017 extern stringID_table_t BSTable[];
00018 #include "../namespace_end.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _XBOX
00030 #ifndef __linux__
00031 enum
00032 {
00033 TK_EOF = -1,
00034 TK_UNDEFINED,
00035 TK_COMMENT,
00036 TK_EOL,
00037 TK_CHAR,
00038 TK_STRING,
00039 TK_INT,
00040 TK_INTEGER = TK_INT,
00041 TK_FLOAT,
00042 TK_IDENTIFIER,
00043 TK_USERDEF,
00044 };
00045 #endif
00046 #endif
00047
00048 #include "../icarus/interpreter.h"
00049
00050 extern stringID_table_t animTable [MAX_ANIMATIONS+1];
00051
00052 stringID_table_t setTable[] =
00053 {
00054 ENUM2STRING(SET_SPAWNSCRIPT),
00055 ENUM2STRING(SET_USESCRIPT),
00056 ENUM2STRING(SET_AWAKESCRIPT),
00057 ENUM2STRING(SET_ANGERSCRIPT),
00058 ENUM2STRING(SET_ATTACKSCRIPT),
00059 ENUM2STRING(SET_VICTORYSCRIPT),
00060 ENUM2STRING(SET_PAINSCRIPT),
00061 ENUM2STRING(SET_FLEESCRIPT),
00062 ENUM2STRING(SET_DEATHSCRIPT),
00063 ENUM2STRING(SET_DELAYEDSCRIPT),
00064 ENUM2STRING(SET_BLOCKEDSCRIPT),
00065 ENUM2STRING(SET_FFIRESCRIPT),
00066 ENUM2STRING(SET_FFDEATHSCRIPT),
00067 ENUM2STRING(SET_MINDTRICKSCRIPT),
00068 ENUM2STRING(SET_NO_MINDTRICK),
00069 ENUM2STRING(SET_ORIGIN),
00070 ENUM2STRING(SET_TELEPORT_DEST),
00071 ENUM2STRING(SET_ANGLES),
00072 ENUM2STRING(SET_XVELOCITY),
00073 ENUM2STRING(SET_YVELOCITY),
00074 ENUM2STRING(SET_ZVELOCITY),
00075 ENUM2STRING(SET_Z_OFFSET),
00076 ENUM2STRING(SET_ENEMY),
00077 ENUM2STRING(SET_LEADER),
00078 ENUM2STRING(SET_NAVGOAL),
00079 ENUM2STRING(SET_ANIM_UPPER),
00080 ENUM2STRING(SET_ANIM_LOWER),
00081 ENUM2STRING(SET_ANIM_BOTH),
00082 ENUM2STRING(SET_ANIM_HOLDTIME_LOWER),
00083 ENUM2STRING(SET_ANIM_HOLDTIME_UPPER),
00084 ENUM2STRING(SET_ANIM_HOLDTIME_BOTH),
00085 ENUM2STRING(SET_PLAYER_TEAM),
00086 ENUM2STRING(SET_ENEMY_TEAM),
00087 ENUM2STRING(SET_BEHAVIOR_STATE),
00088 ENUM2STRING(SET_BEHAVIOR_STATE),
00089 ENUM2STRING(SET_HEALTH),
00090 ENUM2STRING(SET_ARMOR),
00091 ENUM2STRING(SET_DEFAULT_BSTATE),
00092 ENUM2STRING(SET_CAPTURE),
00093 ENUM2STRING(SET_DPITCH),
00094 ENUM2STRING(SET_DYAW),
00095 ENUM2STRING(SET_EVENT),
00096 ENUM2STRING(SET_TEMP_BSTATE),
00097 ENUM2STRING(SET_COPY_ORIGIN),
00098 ENUM2STRING(SET_VIEWTARGET),
00099 ENUM2STRING(SET_WEAPON),
00100 ENUM2STRING(SET_ITEM),
00101 ENUM2STRING(SET_WALKSPEED),
00102 ENUM2STRING(SET_RUNSPEED),
00103 ENUM2STRING(SET_YAWSPEED),
00104 ENUM2STRING(SET_AGGRESSION),
00105 ENUM2STRING(SET_AIM),
00106 ENUM2STRING(SET_FRICTION),
00107 ENUM2STRING(SET_GRAVITY),
00108 ENUM2STRING(SET_IGNOREPAIN),
00109 ENUM2STRING(SET_IGNOREENEMIES),
00110 ENUM2STRING(SET_IGNOREALERTS),
00111 ENUM2STRING(SET_DONTSHOOT),
00112 ENUM2STRING(SET_DONTFIRE),
00113 ENUM2STRING(SET_LOCKED_ENEMY),
00114 ENUM2STRING(SET_NOTARGET),
00115 ENUM2STRING(SET_LEAN),
00116 ENUM2STRING(SET_CROUCHED),
00117 ENUM2STRING(SET_WALKING),
00118 ENUM2STRING(SET_RUNNING),
00119 ENUM2STRING(SET_CHASE_ENEMIES),
00120 ENUM2STRING(SET_LOOK_FOR_ENEMIES),
00121 ENUM2STRING(SET_FACE_MOVE_DIR),
00122 ENUM2STRING(SET_ALT_FIRE),
00123 ENUM2STRING(SET_DONT_FLEE),
00124 ENUM2STRING(SET_FORCED_MARCH),
00125 ENUM2STRING(SET_NO_RESPONSE),
00126 ENUM2STRING(SET_NO_COMBAT_TALK),
00127 ENUM2STRING(SET_NO_ALERT_TALK),
00128 ENUM2STRING(SET_UNDYING),
00129 ENUM2STRING(SET_TREASONED),
00130 ENUM2STRING(SET_DISABLE_SHADER_ANIM),
00131 ENUM2STRING(SET_SHADER_ANIM),
00132 ENUM2STRING(SET_INVINCIBLE),
00133 ENUM2STRING(SET_NOAVOID),
00134 ENUM2STRING(SET_SHOOTDIST),
00135 ENUM2STRING(SET_TARGETNAME),
00136 ENUM2STRING(SET_TARGET),
00137 ENUM2STRING(SET_TARGET2),
00138 ENUM2STRING(SET_LOCATION),
00139 ENUM2STRING(SET_PAINTARGET),
00140 ENUM2STRING(SET_TIMESCALE),
00141 ENUM2STRING(SET_VISRANGE),
00142 ENUM2STRING(SET_EARSHOT),
00143 ENUM2STRING(SET_VIGILANCE),
00144 ENUM2STRING(SET_HFOV),
00145 ENUM2STRING(SET_VFOV),
00146 ENUM2STRING(SET_DELAYSCRIPTTIME),
00147 ENUM2STRING(SET_FORWARDMOVE),
00148 ENUM2STRING(SET_RIGHTMOVE),
00149 ENUM2STRING(SET_LOCKYAW),
00150 ENUM2STRING(SET_SOLID),
00151 ENUM2STRING(SET_CAMERA_GROUP),
00152 ENUM2STRING(SET_CAMERA_GROUP_Z_OFS),
00153 ENUM2STRING(SET_CAMERA_GROUP_TAG),
00154 ENUM2STRING(SET_LOOK_TARGET),
00155 ENUM2STRING(SET_ADDRHANDBOLT_MODEL),
00156 ENUM2STRING(SET_REMOVERHANDBOLT_MODEL),
00157 ENUM2STRING(SET_ADDLHANDBOLT_MODEL),
00158 ENUM2STRING(SET_REMOVELHANDBOLT_MODEL),
00159 ENUM2STRING(SET_FACEAUX),
00160 ENUM2STRING(SET_FACEBLINK),
00161 ENUM2STRING(SET_FACEBLINKFROWN),
00162 ENUM2STRING(SET_FACEFROWN),
00163 ENUM2STRING(SET_FACENORMAL),
00164 ENUM2STRING(SET_FACEEYESCLOSED),
00165 ENUM2STRING(SET_FACEEYESOPENED),
00166 ENUM2STRING(SET_SCROLLTEXT),
00167 ENUM2STRING(SET_LCARSTEXT),
00168 ENUM2STRING(SET_SCROLLTEXTCOLOR),
00169 ENUM2STRING(SET_CAPTIONTEXTCOLOR),
00170 ENUM2STRING(SET_CENTERTEXTCOLOR),
00171 ENUM2STRING(SET_PLAYER_USABLE),
00172 ENUM2STRING(SET_STARTFRAME),
00173 ENUM2STRING(SET_ENDFRAME),
00174 ENUM2STRING(SET_ANIMFRAME),
00175 ENUM2STRING(SET_LOOP_ANIM),
00176 ENUM2STRING(SET_INTERFACE),
00177 ENUM2STRING(SET_SHIELDS),
00178 ENUM2STRING(SET_NO_KNOCKBACK),
00179 ENUM2STRING(SET_INVISIBLE),
00180 ENUM2STRING(SET_VAMPIRE),
00181 ENUM2STRING(SET_FORCE_INVINCIBLE),
00182 ENUM2STRING(SET_GREET_ALLIES),
00183 ENUM2STRING(SET_PLAYER_LOCKED),
00184 ENUM2STRING(SET_LOCK_PLAYER_WEAPONS),
00185 ENUM2STRING(SET_NO_IMPACT_DAMAGE),
00186 ENUM2STRING(SET_PARM1),
00187 ENUM2STRING(SET_PARM2),
00188 ENUM2STRING(SET_PARM3),
00189 ENUM2STRING(SET_PARM4),
00190 ENUM2STRING(SET_PARM5),
00191 ENUM2STRING(SET_PARM6),
00192 ENUM2STRING(SET_PARM7),
00193 ENUM2STRING(SET_PARM8),
00194 ENUM2STRING(SET_PARM9),
00195 ENUM2STRING(SET_PARM10),
00196 ENUM2STRING(SET_PARM11),
00197 ENUM2STRING(SET_PARM12),
00198 ENUM2STRING(SET_PARM13),
00199 ENUM2STRING(SET_PARM14),
00200 ENUM2STRING(SET_PARM15),
00201 ENUM2STRING(SET_PARM16),
00202 ENUM2STRING(SET_DEFEND_TARGET),
00203 ENUM2STRING(SET_WAIT),
00204 ENUM2STRING(SET_COUNT),
00205 ENUM2STRING(SET_SHOT_SPACING),
00206 ENUM2STRING(SET_VIDEO_PLAY),
00207 ENUM2STRING(SET_VIDEO_FADE_IN),
00208 ENUM2STRING(SET_VIDEO_FADE_OUT),
00209 ENUM2STRING(SET_REMOVE_TARGET),
00210 ENUM2STRING(SET_LOADGAME),
00211 ENUM2STRING(SET_MENU_SCREEN),
00212 ENUM2STRING(SET_OBJECTIVE_SHOW),
00213 ENUM2STRING(SET_OBJECTIVE_HIDE),
00214 ENUM2STRING(SET_OBJECTIVE_SUCCEEDED),
00215 ENUM2STRING(SET_OBJECTIVE_FAILED),
00216 ENUM2STRING(SET_MISSIONFAILED),
00217 ENUM2STRING(SET_TACTICAL_SHOW),
00218 ENUM2STRING(SET_TACTICAL_HIDE),
00219 ENUM2STRING(SET_FOLLOWDIST),
00220 ENUM2STRING(SET_SCALE),
00221 ENUM2STRING(SET_OBJECTIVE_CLEARALL),
00222 ENUM2STRING(SET_MISSIONSTATUSTEXT),
00223 ENUM2STRING(SET_WIDTH),
00224 ENUM2STRING(SET_CLOSINGCREDITS),
00225 ENUM2STRING(SET_SKILL),
00226 ENUM2STRING(SET_MISSIONSTATUSTIME),
00227 ENUM2STRING(SET_FULLNAME),
00228 ENUM2STRING(SET_FORCE_HEAL_LEVEL),
00229 ENUM2STRING(SET_FORCE_JUMP_LEVEL),
00230 ENUM2STRING(SET_FORCE_SPEED_LEVEL),
00231 ENUM2STRING(SET_FORCE_PUSH_LEVEL),
00232 ENUM2STRING(SET_FORCE_PULL_LEVEL),
00233 ENUM2STRING(SET_FORCE_MINDTRICK_LEVEL),
00234 ENUM2STRING(SET_FORCE_GRIP_LEVEL),
00235 ENUM2STRING(SET_FORCE_LIGHTNING_LEVEL),
00236 ENUM2STRING(SET_SABER_THROW),
00237 ENUM2STRING(SET_SABER_DEFENSE),
00238 ENUM2STRING(SET_SABER_OFFENSE),
00239 ENUM2STRING(SET_VIEWENTITY),
00240 ENUM2STRING(SET_WATCHTARGET),
00241 ENUM2STRING(SET_SABERACTIVE),
00242 ENUM2STRING(SET_ADJUST_AREA_PORTALS),
00243 ENUM2STRING(SET_DMG_BY_HEAVY_WEAP_ONLY),
00244 ENUM2STRING(SET_SHIELDED),
00245 ENUM2STRING(SET_NO_GROUPS),
00246 ENUM2STRING(SET_FIRE_WEAPON),
00247 ENUM2STRING(SET_INACTIVE),
00248 ENUM2STRING(SET_FUNC_USABLE_VISIBLE),
00249 ENUM2STRING(SET_MISSION_STATUS_SCREEN),
00250 ENUM2STRING(SET_END_SCREENDISSOLVE),
00251 ENUM2STRING(SET_LOOPSOUND),
00252 ENUM2STRING(SET_ICARUS_FREEZE),
00253 ENUM2STRING(SET_ICARUS_UNFREEZE),
00254 ENUM2STRING(SET_USE_CP_NEAREST),
00255 ENUM2STRING(SET_MORELIGHT),
00256 ENUM2STRING(SET_CINEMATIC_SKIPSCRIPT),
00257 ENUM2STRING(SET_NO_FORCE),
00258 ENUM2STRING(SET_NO_FALLTODEATH),
00259 ENUM2STRING(SET_DISMEMBERABLE),
00260 ENUM2STRING(SET_NO_ACROBATICS),
00261 ENUM2STRING(SET_MUSIC_STATE),
00262 ENUM2STRING(SET_USE_SUBTITLES),
00263 ENUM2STRING(SET_CLEAN_DAMAGING_ENTS),
00264 ENUM2STRING(SET_HUD),
00265
00266
00267 "", SET_,
00268 };
00269
00270 void Q3_TaskIDClear( int *taskID )
00271 {
00272 *taskID = -1;
00273 }
00274
00275 void G_DebugPrint( int level, const char *format, ... )
00276 {
00277 va_list argptr;
00278 char text[1024];
00279
00280
00281
00282 if (g_developer.integer != 2)
00283 return;
00284
00285 va_start (argptr, format);
00286 vsprintf (text, format, argptr);
00287 va_end (argptr);
00288
00289
00290 switch ( level )
00291 {
00292 case WL_ERROR:
00293 Com_Printf ( S_COLOR_RED"ERROR: %s", text );
00294 break;
00295
00296 case WL_WARNING:
00297 Com_Printf ( S_COLOR_YELLOW"WARNING: %s", text );
00298 break;
00299
00300 case WL_DEBUG:
00301 {
00302 int entNum;
00303 char *buffer;
00304
00305 sscanf( text, "%d", &entNum );
00306
00307
00308
00309
00310 buffer = (char *) text;
00311 buffer += 5;
00312
00313 if ( ( entNum < 0 ) || ( entNum > MAX_GENTITIES ) )
00314 entNum = 0;
00315
00316 Com_Printf ( S_COLOR_BLUE"DEBUG: %s(%d): %s\n", g_entities[entNum].script_targetname, entNum, buffer );
00317 break;
00318 }
00319 default:
00320 case WL_VERBOSE:
00321 Com_Printf ( S_COLOR_GREEN"INFO: %s", text );
00322 break;
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331 static char *Q3_GetAnimLower( gentity_t *ent )
00332 {
00333 int anim = 0;
00334
00335 if ( ent->client == NULL )
00336 {
00337 G_DebugPrint( WL_WARNING, "Q3_GetAnimLower: attempted to read animation state off non-client!\n" );
00338 return NULL;
00339 }
00340
00341 anim = ent->client->ps.legsAnim;
00342
00343 return (char *)animTable[anim].name;
00344 }
00345
00346
00347
00348
00349
00350
00351 static char *Q3_GetAnimUpper( gentity_t *ent )
00352 {
00353 int anim = 0;
00354
00355 if ( ent->client == NULL )
00356 {
00357 G_DebugPrint( WL_WARNING, "Q3_GetAnimUpper: attempted to read animation state off non-client!\n" );
00358 return NULL;
00359 }
00360
00361 anim = ent->client->ps.torsoAnim;
00362
00363 return (char *)animTable[anim].name;
00364 }
00365
00366
00367
00368
00369
00370
00371 static char *Q3_GetAnimBoth( gentity_t *ent )
00372 {
00373 char *lowerName, *upperName;
00374
00375 lowerName = Q3_GetAnimLower( ent );
00376 upperName = Q3_GetAnimUpper( ent );
00377
00378 if ( !lowerName || !lowerName[0] )
00379 {
00380 G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: NULL legs animation string found!\n" );
00381 return NULL;
00382 }
00383
00384 if ( !upperName || !upperName[0] )
00385 {
00386 G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: NULL torso animation string found!\n" );
00387 return NULL;
00388 }
00389
00390 if ( Q_stricmp( lowerName, upperName ) )
00391 {
00392 #ifdef _DEBUG // sigh, cut down on tester reports that aren't important
00393 G_DebugPrint( WL_WARNING, "Q3_GetAnimBoth: legs and torso animations did not match : returning legs\n" );
00394 #endif
00395 }
00396
00397 return lowerName;
00398 }
00399
00400 int Q3_PlaySound( int taskID, int entID, const char *name, const char *channel )
00401 {
00402 gentity_t *ent = &g_entities[entID];
00403 char finalName[MAX_QPATH];
00404 soundChannel_t voice_chan = CHAN_VOICE;
00405 qboolean type_voice = qfalse;
00406 int soundHandle;
00407 qboolean bBroadcast;
00408
00409 Q_strncpyz( finalName, name, MAX_QPATH );
00410 Q_strupr(finalName);
00411
00412
00413 COM_StripExtension( (const char *)finalName, finalName );
00414
00415 soundHandle = G_SoundIndex( (char *) finalName );
00416 bBroadcast = qfalse;
00417
00418 if ( ( Q_stricmp( channel, "CHAN_ANNOUNCER" ) == 0 ) || (ent->classname && Q_stricmp("target_scriptrunner", ent->classname ) == 0) ) {
00419 bBroadcast = qtrue;
00420 }
00421
00422
00423
00424
00425 if ( Q_stricmp( channel, "CHAN_VOICE" ) == 0 )
00426 {
00427 voice_chan = CHAN_VOICE;
00428 type_voice = qtrue;
00429 }
00430 else if ( Q_stricmp( channel, "CHAN_VOICE_ATTEN" ) == 0 )
00431 {
00432 voice_chan = CHAN_AUTO;
00433 type_voice = qtrue;
00434 }
00435 else if ( Q_stricmp( channel, "CHAN_VOICE_GLOBAL" ) == 0 )
00436 {
00437 voice_chan = CHAN_AUTO;
00438 type_voice = qtrue;
00439 bBroadcast = qtrue;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481 if ( type_voice )
00482 {
00483 char buf[128];
00484 float tFVal = 0;
00485
00486 trap_Cvar_VariableStringBuffer("timescale", buf, sizeof(buf));
00487
00488 tFVal = atof(buf);
00489
00490
00491 if ( tFVal > 1.0f )
00492 {
00493 return qtrue;
00494 }
00495 else
00496 {
00497
00498 G_Sound( ent, voice_chan, G_SoundIndex((char *) finalName) );
00499 }
00500
00501 trap_ICARUS_TaskIDSet( ent, TID_CHAN_VOICE, taskID );
00502
00503 return qfalse;
00504 }
00505
00506 if ( bBroadcast )
00507 {
00508 gentity_t *te;
00509
00510 te = G_TempEntity( ent->r.currentOrigin, EV_GLOBAL_SOUND );
00511 te->s.eventParm = soundHandle;
00512 te->r.svFlags |= SVF_BROADCAST;
00513 }
00514 else
00515 {
00516 G_Sound( ent, CHAN_AUTO, soundHandle );
00517 }
00518
00519 return qtrue;
00520 }
00521
00522
00523
00524
00525
00526
00527 void Q3_Play( int taskID, int entID, const char *type, const char *name )
00528 {
00529 gentity_t *ent = &g_entities[entID];
00530
00531 if ( !Q_stricmp( type, "PLAY_ROFF" ) )
00532 {
00533
00534 ent->roffid = trap_ROFF_Cache((char*)name);
00535 if ( ent->roffid )
00536 {
00537 ent->roffname = G_NewString( name );
00538
00539
00540
00541
00542
00543 trap_ICARUS_TaskIDSet( ent, TID_MOVE_NAV, taskID );
00544
00545
00546
00547
00548
00549
00550
00551
00552 VectorCopy( ent->r.currentOrigin, ent->s.origin2 );
00553 VectorCopy( ent->r.currentAngles, ent->s.angles2 );
00554
00555 trap_LinkEntity( ent );
00556
00557 trap_ROFF_Play(ent->s.number, ent->roffid, qtrue);
00558 }
00559 }
00560 }
00561
00562
00563
00564
00565
00566
00567
00568
00569 void anglerCallback( gentity_t *ent )
00570 {
00571
00572 trap_ICARUS_TaskIDComplete( ent, TID_ANGLE_FACE );
00573
00574
00575 VectorMA( ent->s.apos.trBase, (ent->s.apos.trDuration*0.001f), ent->s.apos.trDelta, ent->r.currentAngles );
00576 VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00577 VectorClear( ent->s.apos.trDelta );
00578 ent->s.apos.trDuration = 1;
00579 ent->s.apos.trType = TR_STATIONARY;
00580 ent->s.apos.trTime = level.time;
00581
00582
00583 ent->reached = 0;
00584 if ( ent->think == anglerCallback )
00585 {
00586 ent->think = 0;
00587 }
00588
00589
00590 trap_LinkEntity( ent );
00591 }
00592
00593 void MatchTeam( gentity_t *teamLeader, int moverState, int time );
00594 void Blocked_Mover( gentity_t *ent, gentity_t *other );
00595
00596
00597
00598
00599
00600
00601
00602
00603 void moverCallback( gentity_t *ent )
00604 {
00605 trap_ICARUS_TaskIDComplete( ent, TID_MOVE_NAV );
00606
00607
00608 ent->s.loopSound = 0;
00609 ent->s.loopIsSoundset = qfalse;
00610 G_PlayDoorSound( ent, BMS_END );
00611
00612 if ( ent->moverState == MOVER_1TO2 )
00613 {
00614
00615 MatchTeam( ent, MOVER_POS2, level.time );
00616
00617 }
00618 else if ( ent->moverState == MOVER_2TO1 )
00619 {
00620 MatchTeam( ent, MOVER_POS1, level.time );
00621
00622 }
00623
00624 if ( ent->blocked == Blocked_Mover )
00625 {
00626 ent->blocked = 0;
00627 }
00628
00629
00630
00631
00632
00633 }
00634
00635 void Blocked_Mover( gentity_t *ent, gentity_t *other )
00636 {
00637
00638
00639
00640 if ( (other->s.eType == ET_ITEM) )
00641 {
00642
00643 }
00644
00645 else if ( other->s.number && (!other->client || (other->client && other->health <= 0 && other->r.contents == CONTENTS_CORPSE && !other->message)) )
00646 {
00647
00648 {
00649
00650 G_FreeEntity( other );
00651 return;
00652 }
00653 }
00654
00655 if ( ent->damage ) {
00656 G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
00657 }
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667 void moveAndRotateCallback( gentity_t *ent )
00668 {
00669
00670 anglerCallback( ent );
00671
00672 moverCallback( ent );
00673 }
00674
00675
00676
00677
00678
00679
00680
00681
00682 void Q3_Lerp2Start( int entID, int taskID, float duration )
00683 {
00684 gentity_t *ent = &g_entities[entID];
00685
00686 if(!ent)
00687 {
00688 G_DebugPrint( WL_WARNING, "Q3_Lerp2Start: invalid entID %d\n", entID);
00689 return;
00690 }
00691
00692 if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
00693 {
00694 G_DebugPrint( WL_ERROR, "Q3_Lerp2Start: ent %d is NOT a mover!\n", entID);
00695 return;
00696 }
00697
00698 if ( ent->s.eType != ET_MOVER )
00699 {
00700 ent->s.eType = ET_MOVER;
00701 }
00702
00703
00704 ent->moverState = MOVER_2TO1;
00705 ent->s.eType = ET_MOVER;
00706 ent->reached = moverCallback;
00707 if ( ent->damage )
00708 {
00709 ent->blocked = Blocked_Mover;
00710 }
00711
00712 ent->s.pos.trDuration = duration * 10;
00713 ent->s.pos.trTime = level.time;
00714
00715 trap_ICARUS_TaskIDSet( ent, TID_MOVE_NAV, taskID );
00716
00717 G_PlayDoorLoopSound( ent );
00718 G_PlayDoorSound( ent, BMS_START );
00719
00720 trap_LinkEntity( ent );
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730 void Q3_Lerp2End( int entID, int taskID, float duration )
00731 {
00732 gentity_t *ent = &g_entities[entID];
00733
00734 if(!ent)
00735 {
00736 G_DebugPrint( WL_WARNING, "Q3_Lerp2End: invalid entID %d\n", entID);
00737 return;
00738 }
00739
00740 if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
00741 {
00742 G_DebugPrint( WL_ERROR, "Q3_Lerp2End: ent %d is NOT a mover!\n", entID);
00743 return;
00744 }
00745
00746 if ( ent->s.eType != ET_MOVER )
00747 {
00748 ent->s.eType = ET_MOVER;
00749 }
00750
00751
00752 ent->moverState = MOVER_1TO2;
00753 ent->s.eType = ET_MOVER;
00754 ent->reached = moverCallback;
00755 if ( ent->damage )
00756 {
00757 ent->blocked = Blocked_Mover;
00758 }
00759
00760 ent->s.pos.trDuration = duration * 10;
00761 ent->s.time = level.time;
00762
00763 trap_ICARUS_TaskIDSet( ent, TID_MOVE_NAV, taskID );
00764
00765 G_PlayDoorLoopSound( ent );
00766 G_PlayDoorSound( ent, BMS_START );
00767
00768 trap_LinkEntity( ent );
00769 }
00770
00771 void InitMoverTrData( gentity_t *ent );
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 void Q3_Lerp2Pos( int taskID, int entID, vec3_t origin, vec3_t angles, float duration )
00782 {
00783 gentity_t *ent = &g_entities[entID];
00784 vec3_t ang;
00785 int i;
00786 moverState_t moverState;
00787
00788 if(!ent)
00789 {
00790 G_DebugPrint( WL_WARNING, "Q3_Lerp2Pos: invalid entID %d\n", entID);
00791 return;
00792 }
00793
00794 if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
00795 {
00796 G_DebugPrint( WL_ERROR, "Q3_Lerp2Pos: ent %d is NOT a mover!\n", entID);
00797 return;
00798 }
00799
00800 if ( ent->s.eType != ET_MOVER )
00801 {
00802 ent->s.eType = ET_MOVER;
00803 }
00804
00805
00806 if ( duration == 0 )
00807 duration = 1;
00808
00809
00810
00811
00812 moverState = ent->moverState;
00813
00814 if ( moverState == MOVER_POS1 || moverState == MOVER_2TO1 )
00815 {
00816 VectorCopy( ent->r.currentOrigin, ent->pos1 );
00817 VectorCopy( origin, ent->pos2 );
00818
00819 moverState = MOVER_1TO2;
00820 }
00821 else
00822 {
00823 VectorCopy( ent->r.currentOrigin, ent->pos2 );
00824 VectorCopy( origin, ent->pos1 );
00825
00826 moverState = MOVER_2TO1;
00827 }
00828
00829 InitMoverTrData( ent );
00830
00831 ent->s.pos.trDuration = duration;
00832
00833
00834 MatchTeam( ent, moverState, level.time );
00835
00836
00837
00838 if ( angles != NULL )
00839 {
00840
00841
00842
00843 for ( i = 0; i < 3; i++ )
00844 {
00845 ang[i] = AngleDelta( angles[i], ent->r.currentAngles[i] );
00846 ent->s.apos.trDelta[i] = ( ang[i] / ( duration * 0.001f ) );
00847 }
00848
00849 VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00850
00851 if ( ent->alt_fire )
00852 {
00853 ent->s.apos.trType = TR_LINEAR_STOP;
00854 }
00855 else
00856 {
00857 ent->s.apos.trType = TR_NONLINEAR_STOP;
00858 }
00859 ent->s.apos.trDuration = duration;
00860
00861 ent->s.apos.trTime = level.time;
00862
00863 ent->reached = moveAndRotateCallback;
00864 trap_ICARUS_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
00865 }
00866 else
00867 {
00868
00869 ent->reached = moverCallback;
00870 }
00871
00872 if ( ent->damage )
00873 {
00874 ent->blocked = Blocked_Mover;
00875 }
00876
00877 trap_ICARUS_TaskIDSet( ent, TID_MOVE_NAV, taskID );
00878
00879 G_PlayDoorLoopSound( ent );
00880 G_PlayDoorSound( ent, BMS_START );
00881
00882 trap_LinkEntity( ent );
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892 void Q3_Lerp2Angles( int taskID, int entID, vec3_t angles, float duration )
00893 {
00894 gentity_t *ent = &g_entities[entID];
00895 vec3_t ang;
00896 int i;
00897
00898 if(!ent)
00899 {
00900 G_DebugPrint( WL_WARNING, "Q3_Lerp2Angles: invalid entID %d\n", entID);
00901 return;
00902 }
00903
00904 if ( ent->client || Q_stricmp(ent->classname, "target_scriptrunner") == 0 )
00905 {
00906 G_DebugPrint( WL_ERROR, "Q3_Lerp2Angles: ent %d is NOT a mover!\n", entID);
00907 return;
00908 }
00909
00910
00911 ent->s.apos.trDuration = (duration>0) ? duration : 1;
00912
00913 for ( i = 0; i < 3; i++ )
00914 {
00915 ang [i] = AngleSubtract( angles[i], ent->r.currentAngles[i]);
00916 ent->s.apos.trDelta[i] = ( ang[i] / ( ent->s.apos.trDuration * 0.001f ) );
00917 }
00918
00919 VectorCopy( ent->r.currentAngles, ent->s.apos.trBase );
00920
00921 if ( ent->alt_fire )
00922 {
00923 ent->s.apos.trType = TR_LINEAR_STOP;
00924 }
00925 else
00926 {
00927 ent->s.apos.trType = TR_NONLINEAR_STOP;
00928 }
00929
00930 ent->s.apos.trTime = level.time;
00931
00932 trap_ICARUS_TaskIDSet( ent, TID_ANGLE_FACE, taskID );
00933
00934
00935 ent->think = anglerCallback;
00936 ent->nextthink = level.time + duration;
00937
00938 trap_LinkEntity( ent );
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948 int Q3_GetTag( int entID, const char *name, int lookup, vec3_t info )
00949 {
00950 gentity_t *ent = &g_entities[entID];
00951
00952 if (!ent->inuse)
00953 {
00954 assert(0);
00955 return 0;
00956 }
00957
00958 switch ( lookup )
00959 {
00960 case TYPE_ORIGIN:
00961 return TAG_GetOrigin( ent->ownername, name, info );
00962 break;
00963
00964 case TYPE_ANGLES:
00965 return TAG_GetAngles( ent->ownername, name, info );
00966 break;
00967 }
00968
00969 return 0;
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981 void Q3_Use( int entID, const char *target )
00982 {
00983 gentity_t *ent = &g_entities[entID];
00984
00985 if ( !ent )
00986 {
00987 G_DebugPrint( WL_WARNING, "Q3_Use: invalid entID %d\n", entID);
00988 return;
00989 }
00990
00991 if( !target || !target[0] )
00992 {
00993 G_DebugPrint( WL_WARNING, "Q3_Use: string is NULL!\n" );
00994 return;
00995 }
00996
00997 G_UseTargets2(ent, ent, target);
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 void Q3_Kill( int entID, const char *name )
01010 {
01011 gentity_t *ent = &g_entities[entID];
01012 gentity_t *victim = NULL;
01013 int o_health;
01014
01015 if( !Q_stricmp( name, "self") )
01016 {
01017 victim = ent;
01018 }
01019 else if( !Q_stricmp( name, "enemy" ) )
01020 {
01021 victim = ent->enemy;
01022 }
01023 else
01024 {
01025 victim = G_Find (NULL, FOFS(targetname), (char *) name );
01026 }
01027
01028 if ( !victim )
01029 {
01030 G_DebugPrint( WL_WARNING, "Q3_Kill: can't find %s\n", name);
01031 return;
01032 }
01033
01034
01035
01036
01037
01038
01039
01040 o_health = victim->health;
01041 victim->health = 0;
01042 if ( victim->client )
01043 {
01044 victim->flags |= FL_NO_KNOCKBACK;
01045 }
01046
01047 if( victim->die != NULL )
01048 {
01049
01050 victim->die(victim, victim, victim, o_health, MOD_UNKNOWN);
01051 }
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 void Q3_RemoveEnt( gentity_t *victim )
01063 {
01064 if( victim->client )
01065 {
01066 if ( victim->s.eType != ET_NPC )
01067 {
01068 G_DebugPrint( WL_WARNING, "Q3_RemoveEnt: You can't remove clients in MP!\n" );
01069 assert(0);
01070 }
01071 else
01072 {
01073 if ( victim->client->NPC_class == CLASS_VEHICLE )
01074 {
01075 Vehicle_t *pVeh = victim->m_pVehicle;
01076 if ( pVeh && pVeh->m_pVehicleInfo )
01077 {
01078 pVeh->m_pVehicleInfo->EjectAll( pVeh );
01079 }
01080 }
01081 victim->think = G_FreeEntity;
01082 victim->nextthink = level.time + 100;
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110 }
01111 else
01112 {
01113 victim->think = G_FreeEntity;
01114 victim->nextthink = level.time + 100;
01115 }
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 void Q3_Remove( int entID, const char *name )
01129 {
01130 gentity_t *ent = &g_entities[entID];
01131 gentity_t *victim = NULL;
01132
01133 if( !Q_stricmp( "self", name ) )
01134 {
01135 victim = ent;
01136 if ( !victim )
01137 {
01138 G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
01139 return;
01140 }
01141 Q3_RemoveEnt( victim );
01142 }
01143 else if( !Q_stricmp( "enemy", name ) )
01144 {
01145 victim = ent->enemy;
01146 if ( !victim )
01147 {
01148 G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
01149 return;
01150 }
01151 Q3_RemoveEnt( victim );
01152 }
01153 else
01154 {
01155 victim = G_Find( NULL, FOFS(targetname), (char *) name );
01156 if ( !victim )
01157 {
01158 G_DebugPrint( WL_WARNING, "Q3_Remove: can't find %s\n", name );
01159 return;
01160 }
01161
01162 while ( victim )
01163 {
01164 Q3_RemoveEnt( victim );
01165 victim = G_Find( victim, FOFS(targetname), (char *) name );
01166 }
01167 }
01168 }
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 int Q3_GetFloat( int entID, int type, const char *name, float *value )
01190 {
01191 gentity_t *ent = &g_entities[entID];
01192 int toGet = 0;
01193
01194 if ( !ent )
01195 {
01196 return 0;
01197 }
01198
01199 toGet = GetIDForString( setTable, name );
01200
01201
01202
01203 switch ( toGet )
01204 {
01205 case SET_PARM1:
01206 case SET_PARM2:
01207 case SET_PARM3:
01208 case SET_PARM4:
01209 case SET_PARM5:
01210 case SET_PARM6:
01211 case SET_PARM7:
01212 case SET_PARM8:
01213 case SET_PARM9:
01214 case SET_PARM10:
01215 case SET_PARM11:
01216 case SET_PARM12:
01217 case SET_PARM13:
01218 case SET_PARM14:
01219 case SET_PARM15:
01220 case SET_PARM16:
01221 if (ent->parms == NULL)
01222 {
01223 G_DebugPrint( WL_ERROR, "GET_PARM: %s %s did not have any parms set!\n", ent->classname, ent->targetname );
01224 return 0;
01225 }
01226 *value = atof( ent->parms->parm[toGet - SET_PARM1] );
01227 break;
01228
01229 case SET_COUNT:
01230 *value = ent->count;
01231 break;
01232
01233 case SET_HEALTH:
01234 *value = ent->health;
01235 break;
01236
01237 case SET_SKILL:
01238 return 0;
01239 break;
01240
01241 case SET_XVELOCITY:
01242 if ( ent->client == NULL )
01243 {
01244 G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_XVELOCITY, %s not a client\n", ent->targetname );
01245 return 0;
01246 }
01247 *value = ent->client->ps.velocity[0];
01248 break;
01249
01250 case SET_YVELOCITY:
01251 if ( ent->client == NULL )
01252 {
01253 G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_YVELOCITY, %s not a client\n", ent->targetname );
01254 return 0;
01255 }
01256 *value = ent->client->ps.velocity[1];
01257 break;
01258
01259 case SET_ZVELOCITY:
01260 if ( ent->client == NULL )
01261 {
01262 G_DebugPrint( WL_WARNING, "Q3_GetFloat: SET_ZVELOCITY, %s not a client\n", ent->targetname );
01263 return 0;
01264 }
01265 *value = ent->client->ps.velocity[2];
01266 break;
01267
01268 case SET_Z_OFFSET:
01269 *value = ent->r.currentOrigin[2] - ent->s.origin[2];
01270 break;
01271
01272 case SET_DPITCH:
01273 return 0;
01274 break;
01275
01276 case SET_DYAW:
01277 return 0;
01278 break;
01279
01280 case SET_WIDTH:
01281 *value = ent->r.mins[0];
01282 break;
01283 case SET_TIMESCALE:
01284 return 0;
01285 break;
01286 case SET_CAMERA_GROUP_Z_OFS:
01287 return 0;
01288 break;
01289
01290 case SET_VISRANGE:
01291 return 0;
01292 break;
01293
01294 case SET_EARSHOT:
01295 return 0;
01296 break;
01297
01298 case SET_VIGILANCE:
01299 return 0;
01300 break;
01301
01302 case SET_GRAVITY:
01303 *value = g_gravity.value;
01304 break;
01305
01306 case SET_FACEEYESCLOSED:
01307 case SET_FACEEYESOPENED:
01308 case