00001
00002
00003
00004
00005 #include "q_shared.h"
00006 #include "bg_public.h"
00007 #include "bg_strap.h"
00008
00009 #ifdef QAGAME
00010 #include "g_local.h"
00011 #endif
00012
00013 #ifdef UI_EXPORTS
00014 #include "../ui/ui_local.h"
00015 #endif
00016
00017 #ifndef UI_EXPORTS
00018 #ifndef QAGAME
00019 #include "../cgame/cg_local.h"
00020 #endif
00021 #endif
00022
00023 #ifdef _XBOX
00024 extern void *Z_Malloc(int iSize, memtag_t eTag, qboolean bZeroit, int iAlign);
00025 extern void Z_Free(void *pvAddress);
00026 #endif
00027
00028 #ifdef QAGAME
00029 extern void Q3_SetParm (int entID, int parmNum, const char *parmValue);
00030 #endif
00031
00032 #include "../namespace_begin.h"
00033
00034 const char *bgToggleableSurfaces[BG_NUM_TOGGLEABLE_SURFACES] =
00035 {
00036 "l_arm_key",
00037 "torso_canister1",
00038 "torso_canister2",
00039 "torso_canister3",
00040 "torso_tube1",
00041 "torso_tube2",
00042 "torso_tube3",
00043 "torso_tube4",
00044 "torso_tube5",
00045 "torso_tube6",
00046 "r_arm",
00047 "l_arm",
00048 "torso_shield",
00049 "torso_galaktorso",
00050 "torso_collar",
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 "r_wing1",
00061 "r_wing2",
00062 "l_wing1",
00063 "l_wing2",
00064 "r_gear",
00065 "l_gear",
00066 "nose",
00067 "blah4",
00068 "blah5",
00069 "l_hand",
00070 "r_hand",
00071 "helmet",
00072 "head",
00073 "head_concussion_charger",
00074 "head_light_blaster_cann",
00075 NULL
00076 };
00077
00078 const int bgToggleableSurfaceDebris[BG_NUM_TOGGLEABLE_SURFACES] =
00079 {
00080 0,
00081 0,
00082 0,
00083 0,
00084 0,
00085 0,
00086 0,
00087 0,
00088 0,
00089 0,
00090 0,
00091 0,
00092 0,
00093 0,
00094 0,
00095 3,
00096 5,
00097 4,
00098 6,
00099 0,
00100 0,
00101 7,
00102 0,
00103 0,
00104 0,
00105 0,
00106 0,
00107 0,
00108 0,
00109 0,
00110 -1
00111 };
00112
00113 const char *bg_customSiegeSoundNames[MAX_CUSTOM_SIEGE_SOUNDS] =
00114 {
00115 "*att_attack",
00116 "*att_primary",
00117 "*att_second",
00118 "*def_guns",
00119 "*def_position",
00120 "*def_primary",
00121 "*def_second",
00122 "*reply_coming",
00123 "*reply_go",
00124 "*reply_no",
00125 "*reply_stay",
00126 "*reply_yes",
00127 "*req_assist",
00128 "*req_demo",
00129 "*req_hvy",
00130 "*req_medic",
00131 "*req_sup",
00132 "*req_tech",
00133 "*spot_air",
00134 "*spot_defenses",
00135 "*spot_emplaced",
00136 "*spot_sniper",
00137 "*spot_troops",
00138 "*tac_cover",
00139 "*tac_fallback",
00140 "*tac_follow",
00141 "*tac_hold",
00142 "*tac_split",
00143 "*tac_together",
00144 NULL
00145 };
00146
00147
00148
00149
00150 char *forceMasteryLevels[NUM_FORCE_MASTERY_LEVELS] =
00151 {
00152 "MASTERY0",
00153 "MASTERY1",
00154 "MASTERY2",
00155 "MASTERY3",
00156 "MASTERY4",
00157 "MASTERY5",
00158 "MASTERY6",
00159 "MASTERY7",
00160 };
00161
00162 int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS] =
00163 {
00164 0,
00165 5,
00166 10,
00167 20,
00168 30,
00169 50,
00170 75,
00171 100
00172 };
00173
00174 int bgForcePowerCost[NUM_FORCE_POWERS][NUM_FORCE_POWER_LEVELS] =
00175 {
00176 { 0, 2, 4, 6 },
00177 { 0, 0, 2, 6 },
00178 { 0, 2, 4, 6 },
00179 { 0, 1, 3, 6 },
00180 { 0, 1, 3, 6 },
00181 { 0, 4, 6, 8 },
00182 { 0, 1, 3, 6 },
00183 { 0, 2, 5, 8 },
00184 { 0, 4, 6, 8 },
00185 { 0, 2, 5, 8 },
00186 { 0, 1, 3, 6 },
00187 { 0, 1, 3, 6 },
00188 { 0, 1, 3, 6 },
00189 { 0, 2, 4, 6 },
00190 { 0, 2, 5, 8 },
00191 { 0, 1, 5, 8 },
00192 { 0, 1, 5, 8 },
00193 { 0, 4, 6, 8 }
00194
00195 };
00196
00197 int forcePowerSorted[NUM_FORCE_POWERS] =
00198 {
00199 FP_TELEPATHY,
00200 FP_HEAL,
00201 FP_ABSORB,
00202 FP_PROTECT,
00203 FP_TEAM_HEAL,
00204 FP_LEVITATION,
00205 FP_SPEED,
00206 FP_PUSH,
00207 FP_PULL,
00208 FP_SEE,
00209 FP_LIGHTNING,
00210 FP_DRAIN,
00211 FP_RAGE,
00212 FP_GRIP,
00213 FP_TEAM_FORCE,
00214 FP_SABER_OFFENSE,
00215 FP_SABER_DEFENSE,
00216 FP_SABERTHROW
00217 };
00218
00219 int forcePowerDarkLight[NUM_FORCE_POWERS] =
00220 {
00221 FORCE_LIGHTSIDE,
00222 0,
00223 0,
00224 0,
00225 0,
00226 FORCE_LIGHTSIDE,
00227 FORCE_DARKSIDE,
00228 FORCE_DARKSIDE,
00229 FORCE_DARKSIDE,
00230 FORCE_LIGHTSIDE,
00231 FORCE_LIGHTSIDE,
00232 FORCE_LIGHTSIDE,
00233 FORCE_DARKSIDE,
00234 FORCE_DARKSIDE,
00235 0,
00236 0,
00237 0,
00238 0
00239
00240 };
00241
00242 int WeaponReadyAnim[WP_NUM_WEAPONS] =
00243 {
00244 TORSO_DROPWEAP1,
00245
00246 TORSO_WEAPONREADY3,
00247 TORSO_WEAPONREADY3,
00248 BOTH_STAND2,
00249 TORSO_WEAPONREADY2,
00250 TORSO_WEAPONREADY3,
00251 TORSO_WEAPONREADY3,
00252 TORSO_WEAPONREADY3,
00253 TORSO_WEAPONREADY3,
00254 TORSO_WEAPONREADY3,
00255 TORSO_WEAPONREADY3,
00256 TORSO_WEAPONREADY3,
00257 TORSO_WEAPONREADY10,
00258 TORSO_WEAPONREADY10,
00259 TORSO_WEAPONREADY10,
00260 TORSO_WEAPONREADY3,
00261 TORSO_WEAPONREADY2,
00262
00263
00264 BOTH_STAND1,
00265 TORSO_WEAPONREADY1
00266 };
00267
00268 int WeaponReadyLegsAnim[WP_NUM_WEAPONS] =
00269 {
00270 BOTH_STAND1,
00271
00272 BOTH_STAND1,
00273 BOTH_STAND1,
00274 BOTH_STAND2,
00275 BOTH_STAND1,
00276 BOTH_STAND1,
00277 BOTH_STAND1,
00278 BOTH_STAND1,
00279 BOTH_STAND1,
00280 BOTH_STAND1,
00281 BOTH_STAND1,
00282 BOTH_STAND1,
00283 BOTH_STAND1,
00284 BOTH_STAND1,
00285 BOTH_STAND1,
00286 BOTH_STAND1,
00287 BOTH_STAND1,
00288
00289
00290 BOTH_STAND1,
00291 BOTH_STAND1
00292 };
00293
00294 int WeaponAttackAnim[WP_NUM_WEAPONS] =
00295 {
00296 BOTH_ATTACK1,
00297
00298 BOTH_ATTACK3,
00299 BOTH_ATTACK3,
00300 BOTH_STAND2,
00301 BOTH_ATTACK2,
00302 BOTH_ATTACK3,
00303 BOTH_ATTACK3,
00304 BOTH_ATTACK3,
00305 BOTH_ATTACK3,
00306 BOTH_ATTACK3,
00307 BOTH_ATTACK3,
00308 BOTH_ATTACK3,
00309 BOTH_THERMAL_THROW,
00310 BOTH_ATTACK3,
00311 BOTH_ATTACK3,
00312 BOTH_ATTACK2,
00313
00314
00315 BOTH_STAND1,
00316 BOTH_ATTACK1
00317 };
00318
00319 qboolean BG_FileExists(const char *fileName)
00320 {
00321 if (fileName && fileName[0])
00322 {
00323 int fh = 0;
00324 trap_FS_FOpenFile(fileName, &fh, FS_READ);
00325 if (fh > 0)
00326 {
00327 trap_FS_FCloseFile(fh);
00328 return qtrue;
00329 }
00330 }
00331
00332 return qfalse;
00333 }
00334
00335 #ifndef UI_EXPORTS //don't need this stuff in the ui
00336
00337
00338
00339 #include "../namespace_end.h"
00340
00341 #ifdef QAGAME
00342 char *G_NewString( const char *string );
00343 #else
00344 char *CG_NewString( const char *string );
00345 #endif
00346
00347 #include "../namespace_begin.h"
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 void BG_ParseField( BG_field_t *l_fields, const char *key, const char *value, byte *ent )
00359 {
00360 BG_field_t *f;
00361 byte *b;
00362 float v;
00363 vec3_t vec;
00364
00365 for ( f=l_fields ; f->name ; f++ ) {
00366 if ( !Q_stricmp(f->name, key) ) {
00367
00368 b = (byte *)ent;
00369
00370 switch( f->type ) {
00371 case F_LSTRING:
00372 #ifdef QAGAME
00373 *(char **)(b+f->ofs) = G_NewString (value);
00374 #else
00375 *(char **)(b+f->ofs) = CG_NewString (value);
00376 #endif
00377 break;
00378 case F_VECTOR:
00379 sscanf (value, "%f %f %f", &vec[0], &vec[1], &vec[2]);
00380 ((float *)(b+f->ofs))[0] = vec[0];
00381 ((float *)(b+f->ofs))[1] = vec[1];
00382 ((float *)(b+f->ofs))[2] = vec[2];
00383 break;
00384 case F_INT:
00385 *(int *)(b+f->ofs) = atoi(value);
00386 break;
00387 case F_FLOAT:
00388 *(float *)(b+f->ofs) = atof(value);
00389 break;
00390 case F_ANGLEHACK:
00391 v = atof(value);
00392 ((float *)(b+f->ofs))[0] = 0;
00393 ((float *)(b+f->ofs))[1] = v;
00394 ((float *)(b+f->ofs))[2] = 0;
00395 break;
00396 #ifdef QAGAME
00397 case F_PARM1:
00398 case F_PARM2:
00399 case F_PARM3:
00400 case F_PARM4:
00401 case F_PARM5:
00402 case F_PARM6:
00403 case F_PARM7:
00404 case F_PARM8:
00405 case F_PARM9:
00406 case F_PARM10:
00407 case F_PARM11:
00408 case F_PARM12:
00409 case F_PARM13:
00410 case F_PARM14:
00411 case F_PARM15:
00412 case F_PARM16:
00413 Q3_SetParm( ((gentity_t *)(ent))->s.number, (f->type - F_PARM1), (char *) value );
00414 break;
00415 #endif
00416 default:
00417 case F_IGNORE:
00418 break;
00419 }
00420 return;
00421 }
00422 }
00423 }
00424
00425 #endif
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber, int teamForce, int gametype, int fpDisabled)
00440 {
00441 char powerBuf[128];
00442 char readBuf[128];
00443 qboolean maintainsValidity = qtrue;
00444 int powerLen = strlen(powerOut);
00445 int i = 0;
00446 int c = 0;
00447 int allowedPoints = 0;
00448 int usedPoints = 0;
00449 int countDown = 0;
00450
00451 int final_Side;
00452 int final_Powers[NUM_FORCE_POWERS];
00453
00454 if (powerLen >= 128)
00455 {
00456
00457 strcpy(powerBuf, "7-1-032330000000001333");
00458 maintainsValidity = qfalse;
00459 }
00460 else
00461 {
00462 strcpy(powerBuf, powerOut);
00463 }
00464
00465
00466 strcpy(powerOut, va("%i-", maxRank));
00467
00468 while (i < 128 && powerBuf[i] && powerBuf[i] != '-')
00469 {
00470 i++;
00471 }
00472 i++;
00473 while (i < 128 && powerBuf[i] && powerBuf[i] != '-')
00474 {
00475 readBuf[c] = powerBuf[i];
00476 c++;
00477 i++;
00478 }
00479 readBuf[c] = 0;
00480 i++;
00481
00482 final_Side = atoi(readBuf);
00483
00484 if (final_Side != FORCE_LIGHTSIDE &&
00485 final_Side != FORCE_DARKSIDE)
00486 {
00487 final_Side = FORCE_DARKSIDE;
00488 maintainsValidity = qfalse;
00489 }
00490
00491 if (teamForce)
00492 {
00493 if (final_Side != teamForce)
00494 {
00495 final_Side = teamForce;
00496
00497
00498 }
00499 }
00500
00501
00502
00503 c = 0;
00504 while (i < 128 && powerBuf[i] && powerBuf[i] != '\n' && c < NUM_FORCE_POWERS)
00505 {
00506 readBuf[0] = powerBuf[i];
00507 readBuf[1] = 0;
00508 final_Powers[c] = atoi(readBuf);
00509 c++;
00510 i++;
00511 }
00512
00513
00514
00515 allowedPoints = forceMasteryPoints[maxRank];
00516
00517 i = 0;
00518 while (i < NUM_FORCE_POWERS)
00519 {
00520 if (final_Powers[i] &&
00521 forcePowerDarkLight[i] &&
00522 forcePowerDarkLight[i] != final_Side)
00523 {
00524 final_Powers[i] = 0;
00525
00526 }
00527
00528 if ( final_Powers[i] &&
00529 (fpDisabled & (1 << i)) )
00530 {
00531 final_Powers[i] = 0;
00532 }
00533
00534 i++;
00535 }
00536
00537 if (gametype < GT_TEAM)
00538 {
00539 final_Powers[FP_TEAM_HEAL] = 0;
00540 final_Powers[FP_TEAM_FORCE] = 0;
00541 }
00542
00543 usedPoints = 0;
00544 i = 0;
00545 while (i < NUM_FORCE_POWERS)
00546 {
00547 countDown = 0;
00548
00549 countDown = final_Powers[i];
00550
00551 while (countDown > 0)
00552 {
00553 usedPoints += bgForcePowerCost[i][countDown];
00554
00555 if ( countDown == 1 &&
00556 ((i == FP_LEVITATION) ||
00557 (i == FP_SABER_OFFENSE && freeSaber) ||
00558 (i == FP_SABER_DEFENSE && freeSaber)) )
00559 {
00560 usedPoints -= bgForcePowerCost[i][countDown];
00561 }
00562 countDown--;
00563 }
00564
00565 i++;
00566 }
00567
00568 if (usedPoints > allowedPoints)
00569 {
00570 int attemptedCycles = 0;
00571 int powerCycle = 2;
00572 int minPow = 0;
00573
00574 if (freeSaber)
00575 {
00576 minPow = 1;
00577 }
00578
00579 maintainsValidity = qfalse;
00580
00581 while (usedPoints > allowedPoints)
00582 {
00583 c = 0;
00584
00585 while (c < NUM_FORCE_POWERS && usedPoints > allowedPoints)
00586 {
00587 if (final_Powers[c] && final_Powers[c] < powerCycle)
00588 {
00589 if (c == FP_SABER_OFFENSE &&
00590 (final_Powers[FP_SABER_DEFENSE] > minPow || final_Powers[FP_SABERTHROW] > 0))
00591 {
00592 int whichOne = FP_SABERTHROW;
00593
00594 if (!final_Powers[whichOne])
00595 {
00596 whichOne = FP_SABER_DEFENSE;
00597 }
00598
00599 while (final_Powers[whichOne] > 0 && usedPoints > allowedPoints)
00600 {
00601 if ( final_Powers[whichOne] > 1 ||
00602 ( (whichOne != FP_SABER_OFFENSE || !freeSaber) &&
00603 (whichOne != FP_SABER_DEFENSE || !freeSaber) ) )
00604 {
00605 usedPoints -= bgForcePowerCost[whichOne][final_Powers[whichOne]];
00606 final_Powers[whichOne]--;
00607 }
00608 else
00609 {
00610 break;
00611 }
00612 }
00613 }
00614 else
00615 {
00616 while (final_Powers[c] > 0 && usedPoints > allowedPoints)
00617 {
00618 if ( final_Powers[c] > 1 ||
00619 ((c != FP_LEVITATION) &&
00620 (c != FP_SABER_OFFENSE || !freeSaber) &&
00621 (c != FP_SABER_DEFENSE || !freeSaber)) )
00622 {
00623 usedPoints -= bgForcePowerCost[c][final_Powers[c]];
00624 final_Powers[c]--;
00625 }
00626 else
00627 {
00628 break;
00629 }
00630 }
00631 }
00632 }
00633
00634 c++;
00635 }
00636
00637 powerCycle++;
00638 attemptedCycles++;
00639
00640 if (attemptedCycles > NUM_FORCE_POWERS)
00641 {
00642 break;
00643 }
00644 }
00645
00646 if (usedPoints > allowedPoints)
00647 {
00648 i = 0;
00649
00650 while (i < NUM_FORCE_POWERS)
00651 {
00652 final_Powers[i] = 0;
00653 if (i == FP_LEVITATION ||
00654 (i == FP_SABER_OFFENSE && freeSaber) ||
00655 (i == FP_SABER_DEFENSE && freeSaber))
00656 {
00657 final_Powers[i] = 1;
00658 }
00659 i++;
00660 }
00661 usedPoints = 0;
00662 }
00663 }
00664
00665 if (freeSaber)
00666 {
00667 if (final_Powers[FP_SABER_OFFENSE] < 1)
00668 {
00669 final_Powers[FP_SABER_OFFENSE] = 1;
00670 }
00671 if (final_Powers[FP_SABER_DEFENSE] < 1)
00672 {
00673 final_Powers[FP_SABER_DEFENSE] = 1;
00674 }
00675 }
00676 if (final_Powers[FP_LEVITATION] < 1)
00677 {
00678 final_Powers[FP_LEVITATION] = 1;
00679 }
00680
00681 i = 0;
00682 while (i < NUM_FORCE_POWERS)
00683 {
00684 if (final_Powers[i] > FORCE_LEVEL_3)
00685 {
00686 final_Powers[i] = FORCE_LEVEL_3;
00687 }
00688 i++;
00689 }
00690
00691 if (fpDisabled)
00692 {
00693
00694
00695 if (fpDisabled & (1 << FP_LEVITATION))
00696 {
00697 final_Powers[FP_LEVITATION] = 1;
00698 }
00699 if (fpDisabled & (1 << FP_SABER_OFFENSE))
00700 {
00701 final_Powers[FP_SABER_OFFENSE] = 3;
00702 }
00703 if (fpDisabled & (1 << FP_SABER_DEFENSE))
00704 {
00705 final_Powers[FP_SABER_DEFENSE] = 3;
00706 }
00707 }
00708
00709 if (final_Powers[FP_SABER_OFFENSE] < 1)
00710 {
00711 final_Powers[FP_SABER_DEFENSE] = 0;
00712 final_Powers[FP_SABERTHROW] = 0;
00713 }
00714
00715
00716
00717
00718 Q_strcat(powerOut, 128, va("%i-", final_Side));
00719
00720 i = strlen(powerOut);
00721 c = 0;
00722 while (c < NUM_FORCE_POWERS)
00723 {
00724 strcpy(readBuf, va("%i", final_Powers[c]));
00725 powerOut[i] = readBuf[0];
00726 c++;
00727 i++;
00728 }
00729 powerOut[i] = 0;
00730
00731 return maintainsValidity;
00732 }
00733
00734 #ifdef __LCC__
00735
00736 void BG_GiveMeVectorFromMatrix(mdxaBone_t *boltMatrix, int flags, vec3_t vec)
00737 {
00738 switch (flags)
00739 {
00740 case ORIGIN:
00741 vec[0] = boltMatrix->matrix[0][3];
00742 vec[1] = boltMatrix->matrix[1][3];
00743 vec[2] = boltMatrix->matrix[2][3];
00744 break;
00745 case POSITIVE_Y:
00746 vec[0] = boltMatrix->matrix[0][1];
00747 vec[1] = boltMatrix->matrix[1][1];
00748 vec[2] = boltMatrix->matrix[2][1];
00749 break;
00750 case POSITIVE_X:
00751 vec[0] = boltMatrix->matrix[0][0];
00752 vec[1] = boltMatrix->matrix[1][0];
00753 vec[2] = boltMatrix->matrix[2][0];
00754 break;
00755 case POSITIVE_Z:
00756 vec[0] = boltMatrix->matrix[0][2];
00757 vec[1] = boltMatrix->matrix[1][2];
00758 vec[2] = boltMatrix->matrix[2][2];
00759 break;
00760 case NEGATIVE_Y:
00761 vec[0] = -boltMatrix->matrix[0][1];
00762 vec[1] = -boltMatrix->matrix[1][1];
00763 vec[2] = -boltMatrix->matrix[2][1];
00764 break;
00765 case NEGATIVE_X:
00766 vec[0] = -boltMatrix->matrix[0][0];
00767 vec[1] = -boltMatrix->matrix[1][0];
00768 vec[2] = -boltMatrix->matrix[2][0];
00769 break;
00770 case NEGATIVE_Z:
00771 vec[0] = -boltMatrix->matrix[0][2];
00772 vec[1] = -boltMatrix->matrix[1][2];
00773 vec[2] = -boltMatrix->matrix[2][2];
00774 break;
00775 }
00776 }
00777 #endif
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 gitem_t bg_itemlist[] =
00796 {
00797 {
00798 NULL,
00799 NULL,
00800 { NULL,
00801 NULL,
00802 0, 0} ,
00803 NULL,
00804 NULL,
00805
00806 0,
00807 0,
00808 0,
00809 "",
00810 "",
00811 ""
00812 },
00813
00814
00815
00816
00817
00818
00819
00820
00821 {
00822 "item_shield_sm_instant",
00823 "sound/player/pickupshield.wav",
00824 { "models/map_objects/mp/psd_sm.md3",
00825 0, 0, 0},
00826 NULL,
00827 "gfx/mp/small_shield",
00828
00829 25,
00830 IT_ARMOR,
00831 1,
00832 "",
00833 ""
00834 ""
00835 },
00836
00837
00838
00839
00840 {
00841 "item_shield_lrg_instant",
00842 "sound/player/pickupshield.wav",
00843 { "models/map_objects/mp/psd.md3",
00844 0, 0, 0},
00845 NULL,
00846 "gfx/mp/large_shield",
00847
00848 100,
00849 IT_ARMOR,
00850 2,
00851 "",
00852 "",
00853 ""
00854 },
00855
00856
00857
00858
00859 {
00860 "item_medpak_instant",
00861 "sound/player/pickuphealth.wav",
00862 { "models/map_objects/mp/medpac.md3",
00863 0, 0, 0 },
00864 NULL,
00865 "gfx/hud/i_icon_medkit",
00866
00867 25,
00868 IT_HEALTH,
00869 0,
00870 "",
00871 "",
00872 ""
00873 },
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 {
00884 "item_seeker",
00885 "sound/weapons/w_pkup.wav",
00886 { "models/items/remote.md3",
00887 0, 0, 0} ,
00888 NULL,
00889 "gfx/hud/i_icon_seeker",
00890
00891 120,
00892 IT_HOLDABLE,
00893 HI_SEEKER,
00894 "",
00895 "",
00896 "@MENUS_AN_ATTACK_DRONE_SIMILAR"
00897 },
00898
00899
00900
00901
00902 {
00903 "item_shield",
00904 "sound/weapons/w_pkup.wav",
00905 { "models/map_objects/mp/shield.md3",
00906 0, 0, 0} ,
00907 NULL,
00908 "gfx/hud/i_icon_shieldwall",
00909
00910 120,
00911 IT_HOLDABLE,
00912 HI_SHIELD,
00913 "",
00914 "sound/weapons/detpack/stick.wav sound/movers/doors/forcefield_on.wav sound/movers/doors/forcefield_off.wav sound/movers/doors/forcefield_lp.wav sound/effects/bumpfield.wav",
00915 "@MENUS_THIS_STATIONARY_ENERGY"
00916 },
00917
00918
00919
00920
00921 {
00922 "item_medpac",
00923 "sound/weapons/w_pkup.wav",
00924 { "models/map_objects/mp/bacta.md3",
00925 0, 0, 0} ,
00926 NULL,
00927 "gfx/hud/i_icon_bacta",
00928
00929 25,
00930 IT_HOLDABLE,
00931 HI_MEDPAC,
00932 "",
00933 "",
00934 "@SP_INGAME_BACTA_DESC"
00935 },
00936
00937
00938
00939
00940 {
00941 "item_medpac_big",
00942 "sound/weapons/w_pkup.wav",
00943 { "models/items/big_bacta.md3",
00944 0, 0, 0} ,
00945 NULL,
00946 "gfx/hud/i_icon_big_bacta",
00947
00948 25,
00949 IT_HOLDABLE,
00950 HI_MEDPAC_BIG,
00951 "",
00952 "",
00953 "@SP_INGAME_BACTA_DESC"
00954 },
00955
00956
00957
00958
00959 {
00960 "item_binoculars",
00961 "sound/weapons/w_pkup.wav",
00962 { "models/items/binoculars.md3",
00963 0, 0, 0} ,
00964 NULL,
00965 "gfx/hud/i_icon_zoom",
00966
00967 60,
00968 IT_HOLDABLE,
00969 HI_BINOCULARS,
00970 "",
00971 "",
00972 "@SP_INGAME_LA_GOGGLES_DESC"
00973 },
00974
00975
00976
00977
00978 {
00979 "item_sentry_gun",
00980 "sound/weapons/w_pkup.wav",
00981 { "models/items/psgun.glm",
00982 0, 0, 0} ,
00983 NULL,
00984 "gfx/hud/i_icon_sentrygun",
00985
00986 120,
00987 IT_HOLDABLE,
00988 HI_SENTRY_GUN,
00989 "",
00990 "",
00991 "@MENUS_THIS_DEADLY_WEAPON_IS"
00992 },
00993
00994
00995
00996
00997 {
00998 "item_jetpack",
00999 "sound/weapons/w_pkup.wav",
01000 { "models/items/psgun.glm",
01001 0, 0, 0} ,
01002 NULL,
01003 "gfx/hud/i_icon_jetpack",
01004
01005 120,
01006 IT_HOLDABLE,
01007 HI_JETPACK,
01008 "effects/boba/jet.efx",
01009 "sound/chars/boba/JETON.wav sound/chars/boba/JETHOVER.wav sound/effects/fire_lp.wav",
01010 "@MENUS_JETPACK_DESC"
01011 },
01012
01013
01014
01015
01016 {
01017 "item_healthdisp",
01018 "sound/weapons/w_pkup.wav",
01019 { "models/map_objects/mp/bacta.md3",
01020 0, 0, 0} ,
01021 NULL,
01022 "gfx/hud/i_icon_healthdisp",
01023
01024 120,
01025 IT_HOLDABLE,
01026 HI_HEALTHDISP,
01027 "",
01028 "",
01029 ""
01030 },
01031
01032
01033
01034
01035 {
01036 "item_ammodisp",
01037 "sound/weapons/w_pkup.wav",
01038 { "models/map_objects/mp/bacta.md3",
01039 0, 0, 0} ,
01040 NULL,
01041 "gfx/hud/i_icon_ammodisp",
01042
01043 120,
01044 IT_HOLDABLE,
01045 HI_AMMODISP,
01046 "",
01047 "",
01048 ""
01049 },
01050
01051
01052
01053
01054 {
01055 "item_eweb_holdable",
01056 "sound/interface/shieldcon_empty",
01057 { "models/map_objects/hoth/eweb_model.glm",
01058 0, 0, 0} ,
01059 NULL,
01060 "gfx/hud/i_icon_eweb",
01061
01062 120,
01063 IT_HOLDABLE,
01064 HI_EWEB,
01065 "",
01066 "",
01067 "@MENUS_EWEB_DESC"
01068 },
01069
01070
01071
01072
01073 {
01074 "item_cloak",
01075 "sound/weapons/w_pkup.wav",
01076 { "models/items/psgun.glm",
01077 0, 0, 0} ,
01078 NULL,
01079 "gfx/hud/i_icon_cloak",
01080
01081 120,
01082 IT_HOLDABLE,
01083 HI_CLOAK,
01084 "",
01085 "",
01086 "@MENUS_CLOAK_DESC"
01087 },
01088
01089
01090
01091
01092 {
01093 "item_force_enlighten_light",
01094 "sound/player/enlightenment.wav",
01095 { "models/map_objects/mp/jedi_enlightenment.md3",
01096 0, 0, 0} ,
01097 NULL,
01098 "gfx/hud/mpi_jlight",
01099
01100 25,
01101 IT_POWERUP,
01102 PW_FORCE_ENLIGHTENED_LIGHT,
01103 "",
01104 "",
01105 ""
01106 },
01107
01108
01109
01110
01111 {
01112 "item_force_enlighten_dark",
01113 "sound/player/enlightenment.wav",
01114 { "models/map_objects/mp/dk_enlightenment.md3",
01115 0, 0, 0} ,
01116 NULL,
01117 "gfx/hud/mpi_dklight",
01118
01119 25,
01120 IT_POWERUP,
01121 PW_FORCE_ENLIGHTENED_DARK,
01122 "",
01123 "",
01124 ""
01125 },
01126
01127
01128
01129
01130 {
01131 "item_force_boon",
01132 "sound/player/boon.wav",
01133 { "models/map_objects/mp/force_boon.md3",
01134 0, 0, 0} ,
01135 NULL,
01136 "gfx/hud/mpi_fboon",
01137
01138 25,
01139 IT_POWERUP,
01140 PW_FORCE_BOON,
01141 "",
01142 "",
01143 ""
01144 },
01145
01146
01147
01148
01149 {
01150 "item_ysalimari",
01151 "sound/player/ysalimari.wav",
01152 { "models/map_objects/mp/ysalimari.md3",
01153 0, 0, 0} ,
01154 NULL,
01155 "gfx/hud/mpi_ysamari",
01156
01157 25,
01158 IT_POWERUP,
01159 PW_YSALAMIRI,
01160 "",
01161 "",
01162 ""
01163 },
01164
01165
01166
01167
01168
01169
01170
01171
01172 {
01173 "weapon_stun_baton",
01174 "sound/weapons/w_pkup.wav",
01175 { "models/weapons2/stun_baton/baton_w.glm",
01176 0, 0, 0},
01177 "models/weapons2/stun_baton/baton.md3",
01178 "gfx/hud/w_icon_stunbaton",
01179
01180 100,
01181 IT_WEAPON,
01182 WP_STUN_BATON,
01183 "",
01184 "",
01185 ""
01186 },
01187
01188
01189
01190
01191 {
01192 "weapon_melee",
01193 "sound/weapons/w_pkup.wav",
01194 { "models/weapons2/stun_baton/baton_w.glm",
01195 0, 0, 0},
01196 "models/weapons2/stun_baton/baton.md3",
01197 "gfx/hud/w_icon_melee",
01198
01199 100,
01200 IT_WEAPON,
01201 WP_MELEE,
01202 "",
01203 "",
01204 "@MENUS_MELEE_DESC"
01205 },
01206
01207
01208
01209
01210 {
01211 "weapon_saber",
01212 "sound/weapons/w_pkup.wav",
01213 { "models/weapons2/saber/saber_w.glm",
01214 0, 0, 0},
01215 "models/weapons2/saber/saber_w.md3",
01216 "gfx/hud/w_icon_lightsaber",
01217
01218 100,
01219 IT_WEAPON,
01220 WP_SABER,
01221 "",
01222 "",
01223 "@MENUS_AN_ELEGANT_WEAPON_FOR"
01224 },
01225
01226
01227
01228
01229 {
01230
01231 "weapon_blaster_pistol",
01232 "sound/weapons/w_pkup.wav",
01233 { "models/weapons2/blaster_pistol/blaster_pistol_w.glm",
01234 0, 0, 0},
01235 "models/weapons2/blaster_pistol/blaster_pistol.md3",
01236 "gfx/hud/w_icon_blaster_pistol",
01237
01238 100,
01239 IT_WEAPON,
01240 WP_BRYAR_PISTOL,
01241 "",
01242 "",
01243 "@MENUS_BLASTER_PISTOL_DESC"
01244 },
01245
01246
01247
01248 {
01249 "weapon_concussion_rifle",
01250 "sound/weapons/w_pkup.wav",
01251 { "models/weapons2/concussion/c_rifle_w.glm",
01252 0, 0, 0},
01253 "models/weapons2/concussion/c_rifle.md3",
01254 "gfx/hud/w_icon_c_rifle",
01255
01256 50,
01257 IT_WEAPON,
01258 WP_CONCUSSION,
01259 "",
01260 "",
01261 "@MENUS_CONC_RIFLE_DESC"
01262 },
01263
01264
01265
01266
01267 {
01268 "weapon_bryar_pistol",
01269 "sound/weapons/w_pkup.wav",
01270 { "models/weapons2/briar_pistol/briar_pistol_w.glm",
01271 0, 0, 0},
01272 "models/weapons2/briar_pistol/briar_pistol.md3",
01273 "gfx/hud/w_icon_briar",
01274
01275 100,
01276 IT_WEAPON,
01277 WP_BRYAR_OLD,
01278 "",
01279 "",
01280 "@SP_INGAME_BLASTER_PISTOL"
01281 },
01282
01283
01284
01285 {
01286 "weapon_blaster",
01287 "sound/weapons/w_pkup.wav",
01288 { "models/weapons2/blaster_r/blaster_w.glm",
01289 0, 0, 0},
01290 "models/weapons2/blaster_r/blaster.md3",
01291 "gfx/hud/w_icon_blaster",
01292
01293 100,
01294 IT_WEAPON,
01295 WP_BLASTER,
01296 "",
01297 "",
01298 "@MENUS_THE_PRIMARY_WEAPON_OF"
01299 },
01300
01301
01302
01303 {
01304 "weapon_disruptor",
01305 "sound/weapons/w_pkup.wav",
01306 { "models/weapons2/disruptor/disruptor_w.glm",
01307 0, 0, 0},
01308 "models/weapons2/disruptor/disruptor.md3",
01309 "gfx/hud/w_icon_disruptor",
01310
01311 100,
01312 IT_WEAPON,
01313 WP_DISRUPTOR,
01314 "",
01315 "",
01316 "@MENUS_THIS_NEFARIOUS_WEAPON"
01317 },
01318
01319
01320
01321 {
01322 "weapon_bowcaster",
01323 "sound/weapons/w_pkup.wav",
01324 { "models/weapons2/bowcaster/bowcaster_w.glm",
01325 0, 0, 0},
01326 "models/weapons2/bowcaster/bowcaster.md3",
01327 "gfx/hud/w_icon_bowcaster",
01328
01329 100,
01330 IT_WEAPON,
01331 WP_BOWCASTER,
01332 "",
01333 "",
01334 "@MENUS_THIS_ARCHAIC_LOOKING"
01335 },
01336
01337
01338
01339 {
01340 "weapon_repeater",
01341 "sound/weapons/w_pkup.wav",
01342 { "models/weapons2/heavy_repeater/heavy_repeater_w.glm",
01343 0, 0, 0},
01344 "models/weapons2/heavy_repeater/heavy_repeater.md3",
01345 "gfx/hud/w_icon_repeater",
01346
01347 100,
01348 IT_WEAPON,
01349 WP_REPEATER,
01350 "",
01351 "",
01352 "@MENUS_THIS_DESTRUCTIVE_PROJECTILE"
01353 },
01354
01355
01356
01357
01358 {
01359 "weapon_demp2",
01360 "sound/weapons/w_pkup.wav",
01361 { "models/weapons2/demp2/demp2_w.glm",
01362 0, 0, 0},
01363 "models/weapons2/demp2/demp2.md3",
01364 "gfx/hud/w_icon_demp2",
01365
01366 100,
01367 IT_WEAPON,
01368 WP_DEMP2,
01369 "",
01370 "",
01371 "@MENUS_COMMONLY_REFERRED_TO"
01372 },
01373
01374
01375
01376 {
01377 "weapon_flechette",
01378 "sound/weapons/w_pkup.wav",
01379 { "models/weapons2/golan_arms/golan_arms_w.glm",
01380 0, 0, 0},
01381 "models/weapons2/golan_arms/golan_arms.md3",
01382 "gfx/hud/w_icon_flechette",
01383
01384 100,
01385 IT_WEAPON,
01386 WP_FLECHETTE,
01387 "",
01388 "",
01389 "@MENUS_WIDELY_USED_BY_THE_CORPORATE"
01390 },
01391
01392
01393
01394 {
01395 "weapon_rocket_launcher",
01396 "sound/weapons/w_pkup.wav",
01397 { "models/weapons2/merr_sonn/merr_sonn_w.glm",
01398 0, 0, 0},
01399 "models/weapons2/merr_sonn/merr_sonn.md3",
01400 "gfx/hud/w_icon_merrsonn",
01401
01402 3,
01403 IT_WEAPON,
01404 WP_ROCKET_LAUNCHER,
01405 "",
01406 "",
01407 "@MENUS_THE_PLX_2M_IS_AN_EXTREMELY"
01408 },
01409
01410
01411
01412 {
01413 "ammo_thermal",
01414 "sound/weapons/w_pkup.wav",
01415 { "models/weapons2/thermal/thermal_pu.md3",
01416 "models/weapons2/thermal/thermal_w.glm", 0, 0},
01417 "models/weapons2/thermal/thermal.md3",
01418 "gfx/hud/w_icon_thermal",
01419
01420 4,
01421 IT_AMMO,
01422 AMMO_THERMAL,
01423 "",
01424 "",
01425 "@MENUS_THE_THERMAL_DETONATOR"
01426 },
01427
01428
01429
01430 {
01431 "ammo_tripmine",
01432 "sound/weapons/w_pkup.wav",
01433 { "models/weapons2/laser_trap/laser_trap_pu.md3",
01434 "models/weapons2/laser_trap/laser_trap_w.glm", 0, 0},
01435 "models/weapons2/laser_trap/laser_trap.md3",
01436 "gfx/hud/w_icon_tripmine",
01437
01438 3,
01439 IT_AMMO,
01440 AMMO_TRIPMINE,
01441 "",
01442 "",
01443 "@MENUS_TRIP_MINES_CONSIST_OF"
01444 },
01445
01446
01447
01448 {
01449 "ammo_detpack",
01450 "sound/weapons/w_pkup.wav",
01451 { "models/weapons2/detpack/det_pack_pu.md3", "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_w.glm", 0},
01452 "models/weapons2/detpack/det_pack.md3",
01453 "gfx/hud/w_icon_detpack",
01454
01455 3,
01456 IT_AMMO,
01457 AMMO_DETPACK,
01458 "",
01459 "",
01460 "@MENUS_A_DETONATION_PACK_IS"
01461 },
01462
01463
01464
01465 {
01466 "weapon_thermal",
01467 "sound/weapons/w_pkup.wav",
01468 { "models/weapons2/thermal/thermal_w.glm", "models/weapons2/thermal/thermal_pu.md3",
01469 0, 0 },
01470 "models/weapons2/thermal/thermal.md3",
01471 "gfx/hud/w_icon_thermal",
01472
01473 4,
01474 IT_WEAPON,
01475 WP_THERMAL,
01476 "",
01477 "",
01478 "@MENUS_THE_THERMAL_DETONATOR"
01479 },
01480
01481
01482
01483 {
01484 "weapon_trip_mine",
01485 "sound/weapons/w_pkup.wav",
01486 { "models/weapons2/laser_trap/laser_trap_w.glm", "models/weapons2/laser_trap/laser_trap_pu.md3",
01487 0, 0},
01488 "models/weapons2/laser_trap/laser_trap.md3",
01489 "gfx/hud/w_icon_tripmine",
01490
01491 3,
01492 IT_WEAPON,
01493 WP_TRIP_MINE,
01494 "",
01495 "",
01496 "@MENUS_TRIP_MINES_CONSIST_OF"
01497 },
01498
01499
01500
01501 {
01502 "weapon_det_pack",
01503 "sound/weapons/w_pkup.wav",
01504 { "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_pu.md3", "models/weapons2/detpack/det_pack_w.glm", 0},
01505 "models/weapons2/detpack/det_pack.md3",
01506 "gfx/hud/w_icon_detpack",
01507
01508 3,
01509 IT_WEAPON,
01510 WP_DET_PACK,
01511 "",
01512 "",
01513 "@MENUS_A_DETONATION_PACK_IS"
01514 },
01515
01516
01517
01518 {
01519 "weapon_emplaced",
01520 "sound/weapons/w_pkup.wav",
01521 { "models/weapons2/blaster_r/blaster_w.glm",
01522 0, 0, 0},
01523 "models/weapons2/blaster_r/blaster.md3",
01524 "gfx/hud/w_icon_blaster",
01525
01526 50,
01527 IT_WEAPON,
01528 WP_EMPLACED_GUN,
01529 "",
01530 "",
01531 ""
01532 },
01533
01534
01535
01536 {
01537 "weapon_turretwp",
01538 "sound/weapons/w_pkup.wav",
01539 { "models/weapons2/blaster_r/blaster_w.glm",
01540 0, 0, 0},
01541 "models/weapons2/blaster_r/blaster.md3",
01542 "gfx/hud/w_icon_blaster",
01543
01544 50,
01545 IT_WEAPON,
01546 WP_TURRET,
01547 "",
01548 "",
01549 ""
01550 },
01551
01552
01553
01554
01555
01556
01557
01558
01559 {
01560 "ammo_force",
01561 "sound/player/pickupenergy.wav",
01562 { "models/items/energy_cell.md3",
01563 0, 0, 0},
01564 NULL,
01565 "gfx/hud/w_icon_blaster",
01566
01567 100,
01568 IT_AMMO,
01569 AMMO_FORCE,
01570 "",
01571 "",
01572 ""
01573 },
01574
01575
01576
01577
01578 {
01579 "ammo_blaster",
01580 "sound/player/pickupenergy.wav",
01581 { "models/items/energy_cell.md3",
01582 0, 0, 0},
01583 NULL,
01584 "gfx/hud/i_icon_battery",
01585
01586 100,
01587 IT_AMMO,
01588 AMMO_BLASTER,
01589 "",
01590 "",
01591 ""
01592 },
01593
01594
01595
01596
01597 {
01598 "ammo_powercell",
01599 "sound/player/pickupenergy.wav",
01600 { "models/items/power_cell.md3",
01601 0, 0, 0},
01602 NULL,
01603 "gfx/mp/ammo_power_cell",
01604
01605 100,
01606 IT_AMMO,
01607 AMMO_POWERCELL,
01608 "",
01609 "",
01610 ""
01611 },
01612
01613
01614
01615
01616 {
01617 "ammo_metallic_bolts",
01618 "sound/player/pickupenergy.wav",
01619 { "models/items/metallic_bolts.md3",
01620 0, 0, 0},
01621 NULL,
01622 "gfx/mp/ammo_metallic_bolts",
01623
01624 100,
01625 IT_AMMO,
01626 AMMO_METAL_BOLTS,
01627 "",
01628 "",
01629 ""
01630 },
01631
01632
01633
01634
01635 {
01636 "ammo_rockets",
01637 "sound/player/pickupenergy.wav",
01638 { "models/items/rockets.md3",
01639 0, 0, 0},
01640 NULL,
01641 "gfx/mp/ammo_rockets",
01642
01643 3,
01644 IT_AMMO,
01645 AMMO_ROCKETS,
01646 "",
01647 "",
01648 ""
01649 },
01650
01651
01652
01653
01654
01655 {
01656 "ammo_all",
01657 "sound/player/pickupenergy.wav",
01658 { "models/items/battery.md3",
01659 0, 0, 0},
01660 NULL,
01661 "gfx/mp/ammo_rockets",
01662
01663 0,
01664 IT_AMMO,
01665 -1,
01666 "",
01667 "",
01668 ""
01669 },
01670
01671
01672
01673
01674
01675
01676
01677 {
01678 "team_CTF_redflag",
01679 NULL,
01680 { "models/flags/r_flag.md3",
01681 "models/flags/r_flag_ysal.md3", 0, 0 },
01682 NULL,
01683 "gfx/hud/mpi_rflag",
01684
01685 0,
01686 IT_TEAM,
01687 PW_REDFLAG,
01688 "",
01689 "",
01690 ""
01691 },
01692
01693
01694
01695
01696 {
01697 "team_CTF_blueflag",
01698 NULL,
01699 { "models/flags/b_flag.md3",
01700 "models/flags/b_flag_ysal.md3", 0, 0 },
01701 NULL,
01702 "gfx/hud/mpi_bflag",
01703
01704 0,
01705 IT_TEAM,
01706 PW_BLUEFLAG,
01707 "",
01708 "",
01709 ""
01710 },
01711
01712
01713
01714
01715
01716
01717
01718
01719 {
01720 "team_CTF_neutralflag",
01721 NULL,
01722 { "models/flags/n_flag.md3",
01723 0, 0, 0 },
01724 NULL,
01725 "icons/iconf_neutral1",
01726
01727 0,
01728 IT_TEAM,
01729 PW_NEUTRALFLAG,
01730 "",
01731 "",
01732 ""
01733 },
01734
01735 {
01736 "item_redcube",
01737 "sound/player/pickupenergy.wav",
01738 { "models/powerups/orb/r_orb.md3",
01739 0, 0, 0 },
01740 NULL,
01741 "icons/iconh_rorb",
01742
01743 0,
01744 IT_TEAM,
01745 0,
01746 "",
01747 "",
01748 ""
01749 },
01750
01751 {
01752 "item_bluecube",
01753 "sound/player/pickupenergy.wav",
01754 { "models/powerups/orb/b_orb.md3",
01755 0, 0, 0 },
01756 NULL,
01757 "icons/iconh_borb",
01758
01759 0,
01760 IT_TEAM,
01761 0,
01762 "",
01763 "",
01764 ""
01765 },
01766
01767
01768 {NULL}
01769 };
01770
01771 int bg_numItems = sizeof(bg_itemlist) / sizeof(bg_itemlist[0]) - 1;
01772
01773 float vectoyaw( const vec3_t vec ) {
01774 float yaw;
01775
01776 if (vec[YAW] == 0 && vec[PITCH] == 0) {
01777 yaw = 0;
01778 } else {
01779 if (vec[PITCH]) {
01780 yaw = ( atan2( vec[YAW], vec[PITCH]) * 180 / M_PI );
01781 } else if (vec[YAW] > 0) {
01782 yaw = 90;
01783 } else {
01784 yaw = 270;
01785 }
01786 if (yaw < 0) {
01787 yaw += 360;
01788 }
01789 }
01790
01791 return yaw;
01792 }
01793
01794 qboolean BG_HasYsalamiri(int gametype, playerState_t *ps)
01795 {
01796 if (gametype == GT_CTY &&
01797 (ps->powerups[PW_REDFLAG] || ps->powerups[PW_BLUEFLAG]))
01798 {
01799 return qtrue;
01800 }
01801
01802 if (ps->powerups[PW_YSALAMIRI])
01803 {
01804 return qtrue;
01805 }
01806
01807 return qfalse;
01808 }
01809
01810 qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t power)
01811 {
01812 if (BG_HasYsalamiri(gametype, ps))
01813 {
01814 return qfalse;
01815 }
01816
01817 if ( ps->forceRestricted || ps->trueNonJedi )
01818 {
01819 return qfalse;
01820 }
01821
01822 if (ps->weapon == WP_EMPLACED_GUN)
01823 {
01824 return qfalse;
01825 }
01826
01827 if (ps->m_iVehicleNum)
01828 {
01829 return qfalse;
01830 }
01831
01832 if (ps->duelInProgress)
01833 {
01834 if (power != FP_SABER_OFFENSE && power != FP_SABER_DEFENSE &&
01835 power != FP_LEVITATION)
01836 {
01837 if (!ps->saberLockFrame || power != FP_PUSH)
01838 {
01839 return qfalse;
01840 }
01841 }
01842 }
01843
01844 if (ps->saberLockFrame || ps->saberLockTime > time)
01845 {
01846 if (power != FP_PUSH)
01847 {
01848 return qfalse;
01849 }
01850 }
01851
01852 if (ps->fallingToDeath)
01853 {
01854 return qfalse;
01855 }
01856
01857 if ((ps->brokenLimbs & (1 << BROKENLIMB_RARM)) ||
01858 (ps->brokenLimbs & (1 << BROKENLIMB_LARM)))
01859 {
01860 switch (power)
01861 {
01862 case FP_PUSH:
01863 case FP_PULL:
01864 case FP_GRIP:
01865 case FP_LIGHTNING:
01866 case FP_DRAIN:
01867 return qfalse;
01868 default:
01869 break;
01870 }
01871 }
01872
01873 return qtrue;
01874 }
01875
01876
01877
01878
01879
01880
01881 gitem_t *BG_FindItemForPowerup( powerup_t pw ) {
01882 int i;
01883
01884 for ( i = 0 ; i < bg_numItems ; i++ ) {
01885 if ( (bg_itemlist[i].giType == IT_POWERUP ||
01886 bg_itemlist[i].giType == IT_TEAM) &&
01887 bg_itemlist[i].giTag == pw ) {
01888 return &bg_itemlist[i];
01889 }
01890 }
01891
01892 return NULL;
01893 }
01894
01895
01896
01897
01898
01899
01900
01901 gitem_t *BG_FindItemForHoldable( holdable_t pw ) {
01902 int i;
01903
01904 for ( i = 0 ; i < bg_numItems ; i++ ) {
01905 if ( bg_itemlist[i].giType == IT_HOLDABLE && bg_itemlist[i].giTag == pw ) {
01906 return &bg_itemlist[i];
01907 }
01908 }
01909
01910 Com_Error( ERR_DROP, "HoldableItem not found" );
01911
01912 return NULL;
01913 }
01914
01915
01916
01917
01918
01919
01920
01921
01922 gitem_t *BG_FindItemForWeapon( weapon_t weapon ) {
01923 gitem_t *it;
01924
01925 for ( it = bg_itemlist + 1 ; it->classname ; it++) {
01926 if ( it->giType == IT_WEAPON && it->giTag == weapon ) {
01927 return it;
01928 }
01929 }
01930
01931 Com_Error( ERR_DROP, "Couldn't find item for weapon %i", weapon);
01932 return NULL;
01933 }
01934
01935
01936
01937
01938
01939
01940
01941 gitem_t *BG_FindItemForAmmo( ammo_t ammo ) {
01942 gitem_t *it;
01943
01944 for ( it = bg_itemlist + 1 ; it->classname ; it++) {
01945 if ( it->giType == IT_AMMO && it->giTag == ammo ) {
01946 return it;
01947 }
01948 }
01949
01950 Com_Error( ERR_DROP, "Couldn't find item for ammo %i", ammo);
01951 return NULL;
01952 }
01953
01954
01955
01956
01957
01958
01959
01960 gitem_t *BG_FindItem( const char *classname ) {
01961 gitem_t *it;
01962
01963 for ( it = bg_itemlist + 1 ; it->classname ; it++ ) {
01964 if ( !Q_stricmp( it->classname, classname) )
01965 return it;
01966 }
01967
01968 return NULL;
01969 }
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979 qboolean BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTime ) {
01980 vec3_t origin;
01981
01982 BG_EvaluateTrajectory( &item->pos, atTime, origin );
01983
01984
01985 if ( ps->origin[0] - origin[0] > 44
01986 || ps->origin[0] - origin[0] < -50
01987 || ps->origin[1] - origin[1] > 36
01988 || ps->origin[1] - origin[1] < -36
01989 || ps->origin[2] - origin[2] > 36
01990 || ps->origin[2] - origin[2] < -36 ) {
01991 return qfalse;
01992 }
01993
01994 return qtrue;
01995 }
01996
01997 int BG_ProperForceIndex(int power)
01998 {
01999 int i = 0;
02000
02001 while (i < NUM_FORCE_POWERS)
02002 {
02003 if (forcePowerSorted[i] == power)
02004 {
02005 return i;
02006 }
02007
02008 i++;
02009 }
02010
02011 return -1;
02012 }
02013
02014 void BG_CycleForce(playerState_t *ps, int direction)
02015 {
02016 int i = ps->fd.forcePowerSelected;
02017 int x = i;
02018 int presel = i;
02019 int foundnext = -1;
02020
02021 if (!ps->fd.forcePowersKnown & (1 << x) ||
02022 x >= NUM_FORCE_POWERS ||
02023 x == -1)
02024 {
02025 return;
02026 }
02027
02028 x = BG_ProperForceIndex(x);
02029 presel = x;
02030
02031 if (direction == 1)
02032 {
02033 x++;
02034 }
02035 else
02036 {
02037 x--;
02038 }
02039
02040 if (x >= NUM_FORCE_POWERS)
02041 {
02042 x = 0;
02043 }
02044 if (x < 0)
02045 {
02046 x = NUM_FORCE_POWERS-1;
02047 }
02048
02049 i = forcePowerSorted[x];
02050
02051 while (x != presel)
02052 {
02053 if (ps->fd.forcePowersKnown & (1 << i) && i != ps->fd.forcePowerSelected)
02054 {
02055 if (i != FP_LEVITATION &&
02056 i != FP_SABER_OFFENSE &&
02057 i != FP_SABER_DEFENSE &&
02058 i != FP_SABERTHROW)
02059 {
02060 foundnext = i;
02061 break;
02062 }
02063 }
02064
02065 if (direction == 1)
02066 {
02067 x++;
02068 }
02069 else
02070 {
02071 x--;
02072 }
02073
02074 if (x >= NUM_FORCE_POWERS)
02075 {
02076 x = 0;
02077 }
02078 if (x < 0)
02079 {
02080 x = NUM_FORCE_POWERS-1;
02081 }
02082
02083 i = forcePowerSorted[x];
02084 }
02085
02086 if (foundnext != -1)
02087 {
02088 ps->fd.forcePowerSelected = foundnext;
02089 }
02090 }
02091
02092 int BG_GetItemIndexByTag(int tag, int type)
02093 {
02094 int i = 0;
02095
02096 while (i < bg_numItems)
02097 {
02098 if (bg_itemlist[i].giTag == tag &&
02099 bg_itemlist[i].giType == type)
02100 {
02101 return i;
02102 }
02103
02104 i++;
02105 }
02106
02107 return 0;
02108 }
02109
02110
02111 qboolean BG_IsItemSelectable(playerState_t *ps, int item)
02112 {
02113 if (item == HI_HEALTHDISP || item == HI_AMMODISP ||
02114 item == HI_JETPACK)
02115 {
02116 return qfalse;
02117 }
02118 return qtrue;
02119 }
02120
02121 void BG_CycleInven(playerState_t *ps, int direction)
02122 {
02123 int i;
02124 int dontFreeze = 0;
02125 int original;
02126
02127 i = bg_itemlist[ps->stats[STAT_HOLDABLE_ITEM]].giTag;
02128 original = i;
02129
02130 if (direction == 1)
02131 {
02132 i++;
02133 if (i == HI_NUM_HOLDABLE)
02134 {
02135 i = 1;
02136 }
02137 }
02138 else
02139 {
02140 i--;
02141 if (i == 0)
02142 {
02143 i = HI_NUM_HOLDABLE-1;
02144 }
02145 }
02146
02147 while (i != original)
02148 {
02149 if (ps->stats[STAT_HOLDABLE_ITEMS] & (1 << i))
02150 {
02151 if (BG_IsItemSelectable(ps, i))
02152 {
02153 ps->stats[STAT_HOLDABLE_ITEM] = BG_GetItemIndexByTag(i, IT_HOLDABLE);
02154 break;
02155 }
02156 }
02157
02158 if (direction == 1)
02159 {
02160 i++;
02161 }
02162 else
02163 {
02164 i--;
02165 }
02166
02167 if (i <= 0)
02168 {
02169 i = HI_NUM_HOLDABLE-1;
02170 }
02171 else if (i >= HI_NUM_HOLDABLE)
02172 {
02173 i = 1;
02174 }
02175
02176 dontFreeze++;
02177 if (dontFreeze >= 32)
02178 {
02179 break;
02180 }
02181 }
02182 }
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192 qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const playerState_t *ps ) {
02193 gitem_t *item;
02194
02195 if ( ent->modelindex < 1 || ent->modelindex >= bg_numItems ) {
02196 Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: index out of range" );
02197 }
02198
02199 item = &bg_itemlist[ent->modelindex];
02200
02201 if ( ps )
02202 {
02203 if ( ps->trueJedi )
02204 {
02205 if ( item->giType != IT_TEAM
02206 && item->giType != IT_ARMOR
02207 && (item->giType != IT_WEAPON || item->giTag != WP_SABER)
02208 && (item->giType != IT_HOLDABLE || item->giTag != HI_SEEKER)
02209 && (item->giType != IT_POWERUP || item->giTag == PW_YSALAMIRI) )
02210 {
02211 return qfalse;
02212 }
02213 }
02214 else if ( ps->trueNonJedi )
02215 {
02216 if ( (item->giType == IT_POWERUP && item->giTag != PW_YSALAMIRI)
02217 || (item->giType == IT_HOLDABLE && item->giTag == HI_SEEKER)
02218 || (item->giType == IT_WEAPON && item->giTag == WP_SABER ) )
02219 {
02220 return qfalse;
02221 }
02222 }
02223 if ( ps->isJediMaster && item && (item->giType == IT_WEAPON || item->giType == IT_AMMO))
02224 {
02225 return qfalse;
02226 }
02227 if ( ps->duelInProgress )
02228 {
02229 return qfalse;
02230 }
02231 }
02232 else
02233 {
02234 return qfalse;
02235 }
02236
02237 switch( item->giType ) {
02238 case IT_WEAPON:
02239 if (ent->generic1 == ps->clientNum && ent->powerups)
02240 {
02241 return qfalse;
02242 }
02243 if (!(ent->eFlags & EF_DROPPEDWEAPON) && (ps->stats[STAT_WEAPONS] & (1 << item->giTag)) &&
02244 item->giTag != WP_THERMAL && item->giTag != WP_TRIP_MINE && item->giTag != WP_DET_PACK)
02245 {
02246 return qfalse;
02247 }
02248 if (item->giTag == WP_THERMAL || item->giTag == WP_TRIP_MINE || item->giTag == WP_DET_PACK)
02249 {
02250 int ammoIndex = weaponData[item->giTag].ammoIndex;
02251 if (ps->ammo[ammoIndex] >= ammoData[ammoIndex].max)
02252 {
02253 return qfalse;
02254 }
02255 }
02256 return qtrue;
02257
02258 case IT_AMMO:
02259 if (item->giTag == -1)
02260 {
02261 return qtrue;
02262 }
02263 if ( ps->ammo[item->giTag] >= ammoData[item->giTag].max) {
02264 return qfalse;
02265 }
02266 return qtrue;
02267
02268 case IT_ARMOR:
02269 if ( ps->stats[STAT_ARMOR] >= ps->stats[STAT_MAX_HEALTH] ) {
02270 return qfalse;
02271 }
02272 return qtrue;
02273
02274 case IT_HEALTH:
02275
02276
02277 if ((ps->fd.forcePowersActive & (1 << FP_RAGE)))
02278 {
02279 return qfalse;
02280 }
02281
02282 if ( item->quantity == 5 || item->quantity == 100 ) {
02283 if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
02284 return qfalse;
02285 }
02286 return qtrue;
02287 }
02288
02289 if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] ) {
02290 return qfalse;
02291 }
02292 return qtrue;
02293
02294 case IT_POWERUP:
02295 if (ps && (ps->powerups[PW_YSALAMIRI]))
02296 {
02297 if (item->giTag != PW_YSALAMIRI)
02298 {
02299 return qfalse;
02300 }
02301 }
02302 return qtrue;
02303
02304 case IT_TEAM:
02305 if( gametype == GT_CTF || gametype == GT_CTY ) {
02306
02307
02308
02309 if (ps->persistant[PERS_TEAM] == TEAM_RED) {
02310 if (item->giTag == PW_BLUEFLAG ||
02311 (item->giTag == PW_REDFLAG && ent->modelindex2) ||
02312 (item->giTag == PW_REDFLAG && ps->powerups[PW_BLUEFLAG]) )
02313 return qtrue;
02314 } else if (ps->persistant[PERS_TEAM] == TEAM_BLUE) {
02315 if (item->giTag == PW_REDFLAG ||
02316 (item->giTag == PW_BLUEFLAG && ent->modelindex2) ||
02317 (item->giTag == PW_BLUEFLAG && ps->powerups[PW_REDFLAG]) )
02318 return qtrue;
02319 }
02320 }
02321
02322 return qfalse;
02323
02324 case IT_HOLDABLE:
02325 if ( ps->stats[STAT_HOLDABLE_ITEMS] & (1 << item->giTag))
02326 {
02327 return qfalse;
02328 }
02329 return qtrue;
02330
02331 case IT_BAD:
02332 Com_Error( ERR_DROP, "BG_CanItemBeGrabbed: IT_BAD" );
02333 default:
02334 #ifndef Q3_VM
02335 #ifndef NDEBUG // bk0001204
02336 Com_Printf("BG_CanItemBeGrabbed: unknown enum %d\n", item->giType );
02337 #endif
02338 #endif
02339 break;
02340 }
02341
02342 return qfalse;
02343 }
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353 void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result ) {
02354 float deltaTime;
02355 float phase;
02356
02357 switch( tr->trType ) {
02358 case TR_STATIONARY:
02359 case TR_INTERPOLATE:
02360 VectorCopy( tr->trBase, result );
02361 break;
02362 case TR_LINEAR:
02363 deltaTime = ( atTime - tr->trTime ) * 0.001;
02364 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
02365 break;
02366 case TR_SINE:
02367 deltaTime = ( atTime - tr->trTime ) / (float) tr->trDuration;
02368 phase = sin( deltaTime * M_PI * 2 );
02369 VectorMA( tr->trBase, phase, tr->trDelta, result );
02370 break;
02371 case TR_LINEAR_STOP:
02372 if ( atTime > tr->trTime + tr->trDuration ) {
02373 atTime = tr->trTime + tr->trDuration;
02374 }
02375 deltaTime = ( atTime - tr->trTime ) * 0.001;
02376 if ( deltaTime < 0 ) {
02377 deltaTime = 0;
02378 }
02379 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
02380 break;
02381 case TR_NONLINEAR_STOP:
02382 if ( atTime > tr->trTime + tr->trDuration )
02383 {
02384 atTime = tr->trTime + tr->trDuration;
02385 }
02386
02387 if ( atTime - tr->trTime > tr->trDuration || atTime - tr->trTime <= 0 )
02388 {
02389 deltaTime = 0;
02390 }
02391 else
02392 {
02393 deltaTime = tr->trDuration*0.001f*((float)cos( DEG2RAD(90.0f - (90.0f*((float)atTime-tr->trTime)/(float)tr->trDuration)) ));
02394 }
02395 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
02396 break;
02397 case TR_GRAVITY:
02398 deltaTime = ( atTime - tr->trTime ) * 0.001;
02399 VectorMA( tr->trBase, deltaTime, tr->trDelta, result );
02400 result[2] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime;
02401 break;
02402 default:
02403 #ifdef QAGAME
02404 Com_Error( ERR_DROP, "BG_EvaluateTrajectory: [GAME SIDE] unknown trType: %i", tr->trType );
02405 #else
02406 Com_Error( ERR_DROP, "BG_EvaluateTrajectory: [CLIENTGAME SIDE] unknown trType: %i", tr->trType );
02407 #endif
02408 break;
02409 }
02410 }
02411
02412
02413
02414
02415
02416
02417
02418
02419 void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result ) {
02420 float deltaTime;
02421 float phase;
02422
02423 switch( tr->trType ) {
02424 case TR_STATIONARY:
02425 case TR_INTERPOLATE:
02426 VectorClear( result );
02427 break;
02428 case TR_LINEAR:
02429 VectorCopy( tr->trDelta, result );
02430 break;
02431 case TR_SINE:
02432 deltaTime = ( atTime - tr->trTime ) / (float) tr->trDuration;
02433 phase = cos( deltaTime * M_PI * 2 );
02434 phase *= 0.5;
02435 VectorScale( tr->trDelta, phase, result );
02436 break;
02437 case TR_LINEAR_STOP:
02438 if ( atTime > tr->trTime + tr->trDuration ) {
02439 VectorClear( result );
02440 return;
02441 }
02442 VectorCopy( tr->trDelta, result );
02443 break;
02444 case TR_NONLINEAR_STOP:
02445 if ( atTime - tr->trTime > tr->trDuration || atTime - tr->trTime <= 0 )
02446 {
02447 VectorClear( result );
02448 return;
02449 }
02450 deltaTime = tr->trDuration*0.001f*((float)cos( DEG2RAD(90.0f - (90.0f*((float)atTime-tr->trTime)/(float)tr->trDuration)) ));
02451 VectorScale( tr->trDelta, deltaTime, result );
02452 break;
02453 case TR_GRAVITY:
02454 deltaTime = ( atTime - tr->trTime ) * 0.001;
02455 VectorCopy( tr->trDelta, result );
02456 result[2] -= DEFAULT_GRAVITY * deltaTime;
02457 break;
02458 default:
02459 Com_Error( ERR_DROP, "BG_EvaluateTrajectoryDelta: unknown trType: %i", tr->trTime );
02460 break;
02461 }
02462 }
02463
02464 char *eventnames[] = {
02465 "EV_NONE",
02466
02467 "EV_CLIENTJOIN",
02468
02469 "EV_FOOTSTEP",
02470 "EV_FOOTSTEP_METAL",
02471 "EV_FOOTSPLASH",
02472 "EV_FOOTWADE",
02473 "EV_SWIM",
02474
02475 "EV_STEP_4",
02476 "EV_STEP_8",
02477 "EV_STEP_12",
02478 "EV_STEP_16",
02479
02480 "EV_FALL",
02481
02482 "EV_JUMP_PAD",
02483
02484 "EV_GHOUL2_MARK",
02485
02486 "EV_GLOBAL_DUEL",
02487 "EV_PRIVATE_DUEL",
02488
02489 "EV_JUMP",
02490 "EV_ROLL",
02491 "EV_WATER_TOUCH",
02492 "EV_WATER_LEAVE",
02493 "EV_WATER_UNDER",
02494 "EV_WATER_CLEAR",
02495
02496 "EV_ITEM_PICKUP",
02497 "EV_GLOBAL_ITEM_PICKUP",
02498
02499 "EV_VEH_FIRE",
02500
02501 "EV_NOAMMO",
02502 "EV_CHANGE_WEAPON",
02503 "EV_FIRE_WEAPON",
02504 "EV_ALT_FIRE",
02505 "EV_SABER_ATTACK",
02506 "EV_SABER_HIT",
02507 "EV_SABER_BLOCK",
02508 "EV_SABER_CLASHFLARE",
02509 "EV_SABER_UNHOLSTER",
02510 "EV_BECOME_JEDIMASTER",
02511 "EV_DISRUPTOR_MAIN_SHOT",
02512 "EV_DISRUPTOR_SNIPER_SHOT",
02513 "EV_DISRUPTOR_SNIPER_MISS",
02514 "EV_DISRUPTOR_HIT",
02515 "EV_DISRUPTOR_ZOOMSOUND",
02516
02517 "EV_PREDEFSOUND",
02518
02519 "EV_TEAM_POWER",
02520
02521 "EV_SCREENSHAKE",
02522
02523 "EV_LOCALTIMER",
02524
02525 "EV_USE",
02526
02527 "EV_USE_ITEM0",
02528 "EV_USE_ITEM1",
02529 "EV_USE_ITEM2",
02530 "EV_USE_ITEM3",
02531 "EV_USE_ITEM4",
02532 "EV_USE_ITEM5",
02533 "EV_USE_ITEM6",
02534 "EV_USE_ITEM7",
02535 "EV_USE_ITEM8",
02536 "EV_USE_ITEM9",
02537 "EV_USE_ITEM10",
02538 "EV_USE_ITEM11",
02539 "EV_USE_ITEM12",
02540 "EV_USE_ITEM13",
02541 "EV_USE_ITEM14",
02542 "EV_USE_ITEM15",
02543
02544 "EV_ITEMUSEFAIL",
02545
02546 "EV_ITEM_RESPAWN",
02547 "EV_ITEM_POP",
02548 "EV_PLAYER_TELEPORT_IN",
02549 "EV_PLAYER_TELEPORT_OUT",
02550
02551 "EV_GRENADE_BOUNCE",
02552 "EV_MISSILE_STICK",
02553
02554 "EV_PLAY_EFFECT",
02555 "EV_PLAY_EFFECT_ID",
02556 "EV_PLAY_PORTAL_EFFECT_ID",
02557
02558 "EV_PLAYDOORSOUND",
02559 "EV_PLAYDOORLOOPSOUND",
02560 "EV_BMODEL_SOUND",
02561
02562 "EV_MUTE_SOUND",
02563 "EV_VOICECMD_SOUND",
02564 "EV_GENERAL_SOUND",
02565 "EV_GLOBAL_SOUND",
02566 "EV_GLOBAL_TEAM_SOUND",
02567 "EV_ENTITY_SOUND",
02568
02569 "EV_PLAY_ROFF",
02570
02571 "EV_GLASS_SHATTER",
02572 "EV_DEBRIS",
02573 "EV_MISC_MODEL_EXP",
02574
02575 "EV_CONC_ALT_IMPACT",
02576
02577 "EV_MISSILE_HIT",
02578 "EV_MISSILE_MISS",
02579 "EV_MISSILE_MISS_METAL",
02580 "EV_BULLET",
02581
02582 "EV_PAIN",
02583 "EV_DEATH1",
02584 "EV_DEATH2",
02585 "EV_DEATH3",
02586 "EV_OBITUARY",
02587
02588 "EV_POWERUP_QUAD",
02589 "EV_POWERUP_BATTLESUIT",
02590
02591
02592 "EV_FORCE_DRAINED",
02593
02594 "EV_GIB_PLAYER",
02595 "EV_SCOREPLUM",
02596
02597 "EV_CTFMESSAGE",
02598
02599 "EV_BODYFADE",
02600
02601 "EV_SIEGE_ROUNDOVER",
02602 "EV_SIEGE_OBJECTIVECOMPLETE",
02603
02604 "EV_DESTROY_GHOUL2_INSTANCE",
02605
02606 "EV_DESTROY_WEAPON_MODEL",
02607
02608 "EV_GIVE_NEW_RANK",
02609 "EV_SET_FREE_SABER",
02610 "EV_SET_FORCE_DISABLE",
02611
02612 "EV_WEAPON_CHARGE",
02613 "EV_WEAPON_CHARGE_ALT",
02614
02615 "EV_SHIELD_HIT",
02616
02617 "EV_DEBUG_LINE",
02618 "EV_TESTLINE",
02619 "EV_STOPLOOPINGSOUND",
02620 "EV_STARTLOOPINGSOUND",
02621 "EV_TAUNT",
02622
02623 };
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635 void BG_AddPredictableEventToPlayerstate( int newEvent, int eventParm, playerState_t *ps ) {
02636
02637 #ifdef _DEBUG
02638 {
02639 static vmCvar_t showEvents;
02640 static qboolean isRegistered = qfalse;
02641
02642 if (!isRegistered)
02643 {
02644 trap_Cvar_Register(&showEvents, "showevents", "0", 0);
02645 isRegistered = qtrue;
02646 }
02647
02648 if ( showEvents.integer != 0 ) {
02649 #ifdef QAGAME
02650 Com_Printf(" game event svt %5d -> %5d: num = %20s parm %d\n", ps->pmove_framecount, ps->eventSequence, eventnames[newEvent], eventParm);
02651 #else
02652 Com_Printf("Cgame event svt %5d -> %5d: num = %20s parm %d\n", ps->pmove_framecount, ps->eventSequence, eventnames[newEvent], eventParm);
02653 #endif
02654 }
02655 }
02656 #endif
02657 ps->events[ps->eventSequence & (MAX_PS_EVENTS-1)] = newEvent;
02658 ps->eventParms[ps->eventSequence & (MAX_PS_EVENTS-1)] = eventParm;
02659 ps->eventSequence++;
02660 }
02661
02662
02663
02664
02665
02666
02667 void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
02668 vec3_t angles;
02669 float p;
02670 int effectNum;
02671
02672
02673 if ( ps->pm_type != PM_NORMAL && ps->pm_type != PM_JETPACK && ps->pm_type != PM_FLOAT ) {
02674 return;
02675 }
02676
02677
02678
02679 if ( ps->jumppad_ent != jumppad->number ) {
02680
02681 vectoangles( jumppad->origin2, angles);
02682 p = fabs( AngleNormalize180( angles[PITCH] ) );
02683 if( p < 45 ) {
02684 effectNum = 0;
02685 } else {
02686 effectNum = 1;
02687 }
02688 }
02689
02690 ps->jumppad_ent = jumppad->number;
02691 ps->jumppad_frame = ps->pmove_framecount;
02692
02693 VectorCopy( jumppad->origin2, ps->velocity );
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703 int BG_EmplacedView(vec3_t baseAngles, vec3_t angles, float *newYaw, float constraint)
02704 {
02705 float dif = AngleSubtract(baseAngles[YAW], angles[YAW]);
02706
02707 if (dif > constraint ||
02708 dif < -constraint)
02709 {
02710 float amt;
02711
02712 if (dif > constraint)
02713 {
02714 amt = (dif-constraint);
02715 dif = constraint;
02716 }
02717 else if (dif < -constraint)
02718 {
02719 amt = (dif+constraint);
02720 dif = -constraint;
02721 }
02722 else
02723 {
02724 amt = 0.0f;
02725 }
02726
02727 *newYaw = AngleSubtract(angles[YAW], -dif);
02728
02729 if (amt > 1.0f || amt < -1.0f)
02730 {
02731 return 2;
02732 }
02733 else
02734 {
02735 return 1;
02736 }
02737 }
02738
02739 return 0;
02740 }
02741
02742
02743
02744 qboolean BG_IsValidCharacterModel(const char *modelName, const char *skinName)
02745 {
02746 if (!Q_stricmp(skinName, "menu"))
02747 {
02748 return qfalse;
02749 }
02750 else if (!Q_stricmp(modelName, "kyle"))
02751 {
02752 if (!Q_stricmp(skinName, "fpls"))
02753 {
02754 return qfalse;
02755 }
02756 else if (!Q_stricmp(skinName, "fpls2"))
02757 {
02758 return qfalse;
02759 }
02760 else if (!Q_stricmp(skinName, "fpls3"))
02761 {
02762 return qfalse;
02763 }
02764 }
02765 return qtrue;
02766 }
02767
02768 qboolean BG_ValidateSkinForTeam( const char *modelName, char *skinName, int team, float *colors )
02769 {
02770 if (!Q_stricmpn(modelName, "jedi_",5))
02771 {
02772 if (team == TEAM_RED && colors)
02773 {
02774 colors[0] = 1.0f;
02775 colors[1] = 0.0f;
02776 colors[2] = 0.0f;
02777 }
02778 else if (team == TEAM_BLUE && colors)
02779 {
02780 colors[0] = 0.0f;
02781 colors[1] = 0.0f;
02782 colors[2] = 1.0f;
02783 }
02784 return qtrue;
02785 }
02786
02787 if (team == TEAM_RED)
02788 {
02789 if ( Q_stricmp( "red", skinName ) != 0 )
02790 {
02791 if ( Q_stricmp( "blue", skinName ) == 0
02792 || Q_stricmp( "default", skinName ) == 0
02793 || strchr(skinName, '|')
02794 || !BG_IsValidCharacterModel(modelName, skinName) )
02795 {
02796 Q_strncpyz(skinName, "red", MAX_QPATH);
02797 return qfalse;
02798 }
02799 else
02800 {
02801 int len = strlen( skinName );
02802 if ( len < 3 )
02803 {
02804 Q_strcat(skinName, MAX_QPATH, "_red");
02805 }
02806 else
02807 {
02808 char *start = &skinName[len-3];
02809 if ( Q_strncmp( "red", start, 3 ) != 0 )
02810 {
02811 if ( len+4 >= MAX_QPATH )
02812 {
02813 Q_strncpyz(skinName, "red", MAX_QPATH);
02814 return qfalse;
02815 }
02816 else
02817 {
02818 Q_strcat(skinName, MAX_QPATH, "_red");
02819 }
02820 }
02821 }
02822
02823 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02824 {
02825 Q_strncpyz(skinName, "red", MAX_QPATH);
02826 }
02827 return qfalse;
02828 }
02829 }
02830
02831 }
02832 else if (team == TEAM_BLUE)
02833 {
02834 if ( Q_stricmp( "blue", skinName ) != 0 )
02835 {
02836 if ( Q_stricmp( "red", skinName ) == 0
02837 || Q_stricmp( "default", skinName ) == 0
02838 || strchr(skinName, '|')
02839 || !BG_IsValidCharacterModel(modelName, skinName) )
02840 {
02841 Q_strncpyz(skinName, "blue", MAX_QPATH);
02842 return qfalse;
02843 }
02844 else
02845 {
02846 int len = strlen( skinName );
02847 if ( len < 4 )
02848 {
02849 Q_strcat(skinName, MAX_QPATH, "_blue");
02850 }
02851 else
02852 {
02853 char *start = &skinName[len-4];
02854 if ( Q_strncmp( "blue", start, 4 ) != 0 )
02855 {
02856 if ( len+5 >= MAX_QPATH )
02857 {
02858 Q_strncpyz(skinName, "blue", MAX_QPATH);
02859 return qfalse;
02860 }
02861 else
02862 {
02863 Q_strcat(skinName, MAX_QPATH, "_blue");
02864 }
02865 }
02866 }
02867
02868 if ( !BG_FileExists( va( "models/players/%s/model_%s.skin", modelName, skinName ) ) )
02869 {
02870 Q_strncpyz(skinName, "blue", MAX_QPATH);
02871 }
02872 return qfalse;
02873 }
02874 }
02875 }
02876 return qtrue;
02877 }
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887 void BG_PlayerStateToEntityState( playerState_t *ps, entityState_t *s, qboolean snap ) {
02888 int i;
02889
02890 if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR ) {
02891 s->eType = ET_INVISIBLE;
02892 } else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH ) {
02893 s->eType = ET_INVISIBLE;
02894 } else {
02895 s->eType = ET_PLAYER;
02896 }
02897
02898 s->number = ps->clientNum;
02899
02900 s->pos.trType = TR_INTERPOLATE;
02901 VectorCopy( ps->origin, s->pos.trBase );
02902 if ( snap ) {
02903 SnapVector( s->pos.trBase );
02904 }
02905
02906 VectorCopy( ps->velocity, s->pos.trDelta );
02907
02908 s->apos.trType = TR_INTERPOLATE;
02909 VectorCopy( ps->viewangles, s->apos.trBase );
02910 if ( snap ) {
02911 SnapVector( s->apos.trBase );
02912 }
02913
02914 s->trickedentindex = ps->fd.forceMindtrickTargetIndex;
02915 s->trickedentindex2 = ps->fd.forceMindtrickTargetIndex2;
02916 s->trickedentindex3 = ps->fd.forceMindtrickTargetIndex3;
02917 s->trickedentindex4 = ps->fd.forceMindtrickTargetIndex4;
02918
02919 s->forceFrame = ps->saberLockFrame;
02920
02921 s->emplacedOwner = ps->electrifyTime;
02922
02923 s->speed = ps->speed;
02924
02925 s->genericenemyindex = ps->genericEnemyIndex;
02926
02927 s->activeForcePass = ps->activeForcePass;
02928
02929 s->angles2[YAW] = ps->movementDir;
02930 s->legsAnim = ps->legsAnim;
02931 s->torsoAnim = ps->torsoAnim;
02932
02933 s->legsFlip = ps->legsFlip;
02934 s->torsoFlip = ps->torsoFlip;
02935
02936 s->clientNum = ps->clientNum;
02937
02938 s->eFlags = ps->eFlags;
02939 s->eFlags2 = ps->eFlags2;
02940
02941 s->saberInFlight = ps->saberInFlight;
02942 s->saberEntityNum = ps->saberEntityNum;
02943 s->saberMove = ps->saberMove;
02944 s->forcePowersActive = ps->fd.forcePowersActive;
02945
02946 if (ps->duelInProgress)
02947 {
02948 s->bolt1 = 1;
02949 }
02950 else
02951 {
02952 s->bolt1 = 0;
02953 }
02954
02955 s->otherEntityNum2 = ps->emplacedIndex;
02956
02957 s->saberHolstered = ps->saberHolstered;
02958
02959 if (ps->genericEnemyIndex != -1)
02960 {
02961 s->eFlags |= EF_SEEKERDRONE;
02962 }
02963
02964 if ( ps->stats[STAT_HEALTH] <= 0 ) {
02965 s->eFlags |= EF_DEAD;
02966 } else {
02967 s->eFlags &= ~EF_DEAD;
02968 }
02969
02970 if ( ps->externalEvent ) {
02971 s->event = ps->externalEvent;
02972 s->eventParm = ps->externalEventParm;
02973 } else if ( ps->entityEventSequence < ps->eventSequence ) {
02974 int seq;
02975
02976 if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
02977 ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
02978 }
02979 seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
02980 s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
02981 s->eventParm = ps->eventParms[ seq ];
02982 ps->entityEventSequence++;
02983 }
02984
02985
02986 s->weapon = ps->weapon;
02987 s->groundEntityNum = ps->groundEntityNum;
02988
02989 s->powerups = 0;
02990 for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
02991 if ( ps->powerups[ i ] ) {
02992 s->powerups |= 1 << i;
02993 }
02994 }
02995
02996 s->loopSound = ps->loopSound;
02997 s->generic1 = ps->generic1;
02998
02999
03000 s->modelindex2 = ps->weaponstate;
03001 s->constantLight = ps->weaponChargeTime;
03002
03003 VectorCopy(ps->lastHitLoc, s->origin2);
03004
03005 s->isJediMaster = ps->isJediMaster;
03006
03007 s->time2 = ps->holocronBits;
03008
03009 s->fireflag = ps->fd.saberAnimLevel;
03010
03011 s->heldByClient = ps->heldByClient;
03012 s->ragAttach = ps->ragAttach;
03013
03014 s->iModelScale = ps->iModelScale;
03015
03016 s->brokenLimbs = ps->brokenLimbs;
03017
03018 s->hasLookTarget = ps->hasLookTarget;
03019 s->lookTarget = ps->lookTarget;
03020
03021 s->customRGBA[0] = ps->customRGBA[0];
03022 s->customRGBA[1] = ps->customRGBA[1];
03023 s->customRGBA[2] = ps->customRGBA[2];
03024 s->customRGBA[3] = ps->customRGBA[3];
03025
03026 s->m_iVehicleNum = ps->m_iVehicleNum;
03027 }
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037 void BG_PlayerStateToEntityStateExtraPolate( playerState_t *ps, entityState_t *s, int time, qboolean snap ) {
03038 int i;
03039
03040 if ( ps->pm_type == PM_INTERMISSION || ps->pm_type == PM_SPECTATOR ) {
03041 s->eType = ET_INVISIBLE;
03042 } else if ( ps->stats[STAT_HEALTH] <= GIB_HEALTH ) {
03043 s->eType = ET_INVISIBLE;
03044 } else {
03045 s->eType = ET_PLAYER;
03046 }
03047
03048 s->number = ps->clientNum;
03049
03050 s->pos.trType = TR_LINEAR_STOP;
03051 VectorCopy( ps->origin, s->pos.trBase );
03052 if ( snap ) {
03053 SnapVector( s->pos.trBase );
03054 }
03055
03056 VectorCopy( ps->velocity, s->pos.trDelta );
03057
03058 s->pos.trTime = time;
03059
03060 s->pos.trDuration = 50;
03061
03062 s->apos.trType = TR_INTERPOLATE;
03063 VectorCopy( ps->viewangles, s->apos.trBase );
03064 if ( snap ) {
03065 SnapVector( s->apos.trBase );
03066 }
03067
03068 s->trickedentindex = ps->fd.forceMindtrickTargetIndex;
03069 s->trickedentindex2 = ps->fd.forceMindtrickTargetIndex2;
03070 s->trickedentindex3 = ps->fd.forceMindtrickTargetIndex3;
03071 s->trickedentindex4 = ps->fd.forceMindtrickTargetIndex4;
03072
03073 s->forceFrame = ps->saberLockFrame;
03074
03075 s->emplacedOwner = ps->electrifyTime;
03076
03077 s->speed = ps->speed;
03078
03079 s->genericenemyindex = ps->genericEnemyIndex;
03080
03081 s->activeForcePass = ps->activeForcePass;
03082
03083 s->angles2[YAW] = ps->movementDir;
03084 s->legsAnim = ps->legsAnim;
03085 s->torsoAnim = ps->torsoAnim;
03086
03087 s->legsFlip = ps->legsFlip;
03088 s->torsoFlip = ps->torsoFlip;
03089
03090 s->clientNum = ps->clientNum;
03091
03092 s->eFlags = ps->eFlags;
03093 s->eFlags2 = ps->eFlags2;
03094
03095 s->saberInFlight = ps->saberInFlight;
03096 s->saberEntityNum = ps->saberEntityNum;
03097 s->saberMove = ps->saberMove;
03098 s->forcePowersActive = ps->fd.forcePowersActive;
03099
03100 if (ps->duelInProgress)
03101 {
03102 s->bolt1 = 1;
03103 }
03104 else
03105 {
03106 s->bolt1 = 0;
03107 }
03108
03109 s->otherEntityNum2 = ps->emplacedIndex;
03110
03111 s->saberHolstered = ps->saberHolstered;
03112
03113 if (ps->genericEnemyIndex != -1)
03114 {
03115 s->eFlags |= EF_SEEKERDRONE;
03116 }
03117
03118 if ( ps->stats[STAT_HEALTH] <= 0 ) {
03119 s->eFlags |= EF_DEAD;
03120 } else {
03121 s->eFlags &= ~EF_DEAD;
03122 }
03123
03124 if ( ps->externalEvent ) {
03125 s->event = ps->externalEvent;
03126 s->eventParm = ps->externalEventParm;
03127 } else if ( ps->entityEventSequence < ps->eventSequence ) {
03128 int seq;
03129
03130 if ( ps->entityEventSequence < ps->eventSequence - MAX_PS_EVENTS) {
03131 ps->entityEventSequence = ps->eventSequence - MAX_PS_EVENTS;
03132 }
03133 seq = ps->entityEventSequence & (MAX_PS_EVENTS-1);
03134 s->event = ps->events[ seq ] | ( ( ps->entityEventSequence & 3 ) << 8 );
03135 s->eventParm = ps->eventParms[ seq ];
03136 ps->entityEventSequence++;
03137 }
03138 s->weapon = ps->weapon;
03139 s->groundEntityNum = ps->groundEntityNum;
03140
03141 s->powerups = 0;
03142 for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
03143 if ( ps->powerups[ i ] ) {
03144 s->powerups |= 1 << i;
03145 }
03146 }
03147
03148 s->loopSound = ps->loopSound;
03149 s->generic1 = ps->generic1;
03150
03151
03152 s->modelindex2 = ps->weaponstate;
03153 s->constantLight = ps->weaponChargeTime;
03154
03155 VectorCopy(ps->lastHitLoc, s->origin2);
03156
03157 s->isJediMaster = ps->isJediMaster;
03158
03159 s->time2 = ps->holocronBits;
03160
03161 s->fireflag = ps->fd.saberAnimLevel;
03162
03163 s->heldByClient = ps->heldByClient;
03164 s->ragAttach = ps->ragAttach;
03165
03166 s->iModelScale = ps->iModelScale;
03167
03168 s->brokenLimbs = ps->brokenLimbs;
03169
03170 s->hasLookTarget = ps->hasLookTarget;
03171 s->lookTarget = ps->lookTarget;
03172
03173 s->customRGBA[0] = ps->customRGBA[0];
03174 s->customRGBA[1] = ps->customRGBA[1];
03175 s->customRGBA[2] = ps->customRGBA[2];
03176 s->customRGBA[3] = ps->customRGBA[3];
03177
03178 s->m_iVehicleNum = ps->m_iVehicleNum;
03179 }
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190 #ifdef QAGAME //game
03191 extern int trap_G2API_InitGhoul2Model(void **ghoul2Ptr, const char *fileName, int modelIndex, qhandle_t customSkin,
03192 qhandle_t customShader, int modelFlags, int lodBias);
03193 extern void trap_G2API_CleanGhoul2Models(void **ghoul2Ptr);
03194 #else //cgame/ui
03195 extern qhandle_t trap_R_RegisterModel( const char *name );
03196 #endif
03197
03198 extern qhandle_t trap_R_RegisterSkin( const char *name );
03199
03200 int BG_ModelCache(const char *modelName, const char *skinName)
03201 {
03202 #ifdef QAGAME
03203 void *g2 = NULL;
03204
03205 if (skinName && skinName[0])
03206 {
03207 trap_R_RegisterSkin(skinName);
03208 }
03209
03210
03211 trap_G2API_InitGhoul2Model(&g2, modelName, 0, 0, 0, 0, 0);
03212 if (g2)
03213 {
03214 trap_G2API_CleanGhoul2Models(&g2);
03215 }
03216 return 0;
03217 #else
03218 if (skinName && skinName[0])
03219 {
03220 trap_R_RegisterSkin(skinName);
03221 }
03222 return trap_R_RegisterModel(modelName);
03223 #endif
03224 }
03225
03226 #ifdef _XBOX // Hacky BG_Alloc replacement
03227
03228
03229
03230
03231
03232
03233
03234 void *BG_Alloc ( int size )
03235 {
03236 return Z_Malloc(size, TAG_BG_ALLOC, qfalse, 4);
03237 }
03238
03239 void *BG_AllocUnaligned ( int size )
03240 {
03241
03242 return Z_Malloc(size, TAG_BG_ALLOC, qfalse, 4);
03243 }
03244
03245
03246
03247 #define MAX_TEMP_ALLOCS 3
03248 static void *tempAllocPointers[MAX_TEMP_ALLOCS] = { 0 };
03249 static int tempAllocSizes[MAX_TEMP_ALLOCS] = { 0 };
03250
03251 void *BG_TempAlloc( int size )
03252 {
03253 int i;
03254
03255
03256 for (i = 0; i < MAX_TEMP_ALLOCS; ++i)
03257 if (!tempAllocPointers[i])
03258 break;
03259
03260 if (i == MAX_TEMP_ALLOCS)
03261 {
03262 assert(!"No space for TempAlloc -> Increase MAX_TEMP_ALLOCS");
03263 return NULL;
03264 }
03265
03266 tempAllocPointers[i] = Z_Malloc(size, TAG_TEMP_WORKSPACE, qfalse, 4);
03267 tempAllocSizes[i] = size;
03268
03269 return tempAllocPointers[i];
03270 }
03271
03272 void BG_TempFree( int size )
03273 {
03274 int i;
03275
03276
03277 for (i = MAX_TEMP_ALLOCS - 1; i >= 0; --i)
03278 if (tempAllocPointers[i] && (tempAllocSizes[i] == size))
03279 break;
03280
03281 if (i < 0)
03282 {
03283 assert(!"BG_TempFree doesn't match a call to BG_TempAlloc");
03284 return;
03285 }
03286
03287 Z_Free(tempAllocPointers[i]);
03288 tempAllocPointers[i] = 0;
03289 tempAllocSizes[i] = 0;
03290
03291 return;
03292 }
03293
03294 char *BG_StringAlloc ( const char *source )
03295 {
03296 char *dest;
03297
03298 dest = (char *) BG_Alloc ( strlen ( source ) + 1 );
03299 strcpy ( dest, source );
03300 return dest;
03301 }
03302
03303 qboolean BG_OutOfMemory ( void )
03304 {
03305
03306 return qfalse;
03307 }
03308
03309 #else // _XBOX
03310
03311 #ifdef QAGAME
03312 #define MAX_POOL_SIZE 3000000 //1024000
03313 #elif defined CGAME //don't need as much for cgame stuff. 2mb will be fine.
03314 #define MAX_POOL_SIZE 2048000
03315 #else //And for the ui the only thing we'll be using this for anyway is allocating anim data for g2 menu models
03316 #define MAX_POOL_SIZE 512000
03317 #endif
03318
03319
03320
03321
03322
03323
03324 static char bg_pool[MAX_POOL_SIZE];
03325 static int bg_poolSize = 0;
03326 static int bg_poolTail = MAX_POOL_SIZE;
03327
03328 void *BG_Alloc ( int size )
03329 {
03330 bg_poolSize = ((bg_poolSize + 0x00000003) & 0xfffffffc);
03331
03332 if (bg_poolSize + size > bg_poolTail)
03333 {
03334 Com_Error( ERR_DROP, "BG_Alloc: buffer exceeded tail (%d > %d)", bg_poolSize + size, bg_poolTail);
03335 return 0;
03336 }
03337
03338 bg_poolSize += size;
03339
03340 return &bg_pool[bg_poolSize-size];
03341 }
03342
03343 void *BG_AllocUnaligned ( int size )
03344 {
03345 if (bg_poolSize + size > bg_poolTail)
03346 {
03347 Com_Error( ERR_DROP, "BG_AllocUnaligned: buffer exceeded tail (%d > %d)", bg_poolSize + size, bg_poolTail);
03348 return 0;
03349 }
03350
03351 bg_poolSize += size;
03352
03353 return &bg_pool[bg_poolSize-size];
03354 }
03355
03356 void *BG_TempAlloc( int size )
03357 {
03358 size = ((size + 0x00000003) & 0xfffffffc);
03359
03360 if (bg_poolTail - size < bg_poolSize)
03361 {
03362 Com_Error( ERR_DROP, "BG_TempAlloc: buffer exceeded head (%d > %d)", bg_poolTail - size, bg_poolSize);
03363 return 0;
03364 }
03365
03366 bg_poolTail -= size;
03367
03368 return &bg_pool[bg_poolTail];
03369 }
03370
03371 void BG_TempFree( int size )
03372 {
03373 size = ((size + 0x00000003) & 0xfffffffc);
03374
03375 if (bg_poolTail+size > MAX_POOL_SIZE)
03376 {
03377 Com_Error( ERR_DROP, "BG_TempFree: tail greater than size (%d > %d)", bg_poolTail+size, MAX_POOL_SIZE );
03378 }
03379
03380 bg_poolTail += size;
03381 }
03382
03383 char *BG_StringAlloc ( const char *source )
03384 {
03385 char *dest;
03386
03387 dest = BG_Alloc ( strlen ( source ) + 1 );
03388 strcpy ( dest, source );
03389 return dest;
03390 }
03391
03392 qboolean BG_OutOfMemory ( void )
03393 {
03394 return bg_poolSize >= MAX_POOL_SIZE;
03395 }
03396
03397 #endif // _XBOX && QAGAME
03398
03399 #include "../namespace_end.h"