00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "q_shared.h"
00013 #include "bg_saga.h"
00014 #include "bg_weapons.h"
00015 #include "bg_public.h"
00016
00017 #define SIEGECHAR_TAB 9 //perhaps a bit hacky, but I don't think there's any define existing for "tab"
00018
00019
00020 #include "../namespace_begin.h"
00021
00022 extern int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
00023 extern void trap_FS_Read( void *buffer, int len, fileHandle_t f );
00024 extern void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
00025 extern void trap_FS_FCloseFile( fileHandle_t f );
00026 extern int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
00027
00028 #ifndef QAGAME //cgame, ui
00029 qhandle_t trap_R_RegisterShaderNoMip( const char *name );
00030 #endif
00031
00032 char siege_info[MAX_SIEGE_INFO_SIZE];
00033 int siege_valid = 0;
00034
00035 siegeTeam_t *team1Theme = NULL;
00036 siegeTeam_t *team2Theme = NULL;
00037
00038 siegeClass_t bgSiegeClasses[MAX_SIEGE_CLASSES];
00039 int bgNumSiegeClasses = 0;
00040
00041 siegeTeam_t bgSiegeTeams[MAX_SIEGE_TEAMS];
00042 int bgNumSiegeTeams = 0;
00043
00044
00045 stringID_table_t bgSiegeClassFlagNames[] =
00046 {
00047 ENUM2STRING(CFL_MORESABERDMG),
00048 ENUM2STRING(CFL_STRONGAGAINSTPHYSICAL),
00049 ENUM2STRING(CFL_FASTFORCEREGEN),
00050 ENUM2STRING(CFL_STATVIEWER),
00051 ENUM2STRING(CFL_HEAVYMELEE),
00052 ENUM2STRING(CFL_SINGLE_ROCKET),
00053 ENUM2STRING(CFL_CUSTOMSKEL),
00054 ENUM2STRING(CFL_EXTRA_AMMO),
00055 "", -1
00056 };
00057
00058
00059 stringID_table_t StanceTable[] =
00060 {
00061 ENUM2STRING(SS_NONE),
00062 ENUM2STRING(SS_FAST),
00063 ENUM2STRING(SS_MEDIUM),
00064 ENUM2STRING(SS_STRONG),
00065 ENUM2STRING(SS_DESANN),
00066 ENUM2STRING(SS_TAVION),
00067 ENUM2STRING(SS_DUAL),
00068 ENUM2STRING(SS_STAFF),
00069 "", 0
00070 };
00071
00072
00073 stringID_table_t WPTable[] =
00074 {
00075 "NULL",WP_NONE,
00076 ENUM2STRING(WP_NONE),
00077
00078 ENUM2STRING(WP_STUN_BATON),
00079 ENUM2STRING(WP_MELEE),
00080 ENUM2STRING(WP_SABER),
00081 ENUM2STRING(WP_BRYAR_PISTOL),
00082 "WP_BLASTER_PISTOL", WP_BRYAR_PISTOL,
00083 ENUM2STRING(WP_BLASTER),
00084 ENUM2STRING(WP_DISRUPTOR),
00085 ENUM2STRING(WP_BOWCASTER),
00086 ENUM2STRING(WP_REPEATER),
00087 ENUM2STRING(WP_DEMP2),
00088 ENUM2STRING(WP_FLECHETTE),
00089 ENUM2STRING(WP_ROCKET_LAUNCHER),
00090 ENUM2STRING(WP_THERMAL),
00091 ENUM2STRING(WP_TRIP_MINE),
00092 ENUM2STRING(WP_DET_PACK),
00093 ENUM2STRING(WP_CONCUSSION),
00094 ENUM2STRING(WP_BRYAR_OLD),
00095 ENUM2STRING(WP_EMPLACED_GUN),
00096 ENUM2STRING(WP_TURRET),
00097 "", 0
00098 };
00099
00100 stringID_table_t FPTable[] =
00101 {
00102 ENUM2STRING(FP_HEAL),
00103 ENUM2STRING(FP_LEVITATION),
00104 ENUM2STRING(FP_SPEED),
00105 ENUM2STRING(FP_PUSH),
00106 ENUM2STRING(FP_PULL),
00107 ENUM2STRING(FP_TELEPATHY),
00108 ENUM2STRING(FP_GRIP),
00109 ENUM2STRING(FP_LIGHTNING),
00110 ENUM2STRING(FP_RAGE),
00111 ENUM2STRING(FP_PROTECT),
00112 ENUM2STRING(FP_ABSORB),
00113 ENUM2STRING(FP_TEAM_HEAL),
00114 ENUM2STRING(FP_TEAM_FORCE),
00115 ENUM2STRING(FP_DRAIN),
00116 ENUM2STRING(FP_SEE),
00117 ENUM2STRING(FP_SABER_OFFENSE),
00118 ENUM2STRING(FP_SABER_DEFENSE),
00119 ENUM2STRING(FP_SABERTHROW),
00120 "", -1
00121 };
00122
00123 stringID_table_t HoldableTable[] =
00124 {
00125 ENUM2STRING(HI_NONE),
00126
00127 ENUM2STRING(HI_SEEKER),
00128 ENUM2STRING(HI_SHIELD),
00129 ENUM2STRING(HI_MEDPAC),
00130 ENUM2STRING(HI_MEDPAC_BIG),
00131 ENUM2STRING(HI_BINOCULARS),
00132 ENUM2STRING(HI_SENTRY_GUN),
00133 ENUM2STRING(HI_JETPACK),
00134 ENUM2STRING(HI_HEALTHDISP),
00135 ENUM2STRING(HI_AMMODISP),
00136 ENUM2STRING(HI_EWEB),
00137 ENUM2STRING(HI_CLOAK),
00138
00139 "", -1
00140 };
00141
00142 stringID_table_t PowerupTable[] =
00143 {
00144 ENUM2STRING(PW_NONE),
00145 ENUM2STRING(PW_QUAD),
00146 ENUM2STRING(PW_BATTLESUIT),
00147 ENUM2STRING(PW_PULL),
00148 ENUM2STRING(PW_REDFLAG),
00149 ENUM2STRING(PW_BLUEFLAG),
00150 ENUM2STRING(PW_NEUTRALFLAG),
00151 ENUM2STRING(PW_SHIELDHIT),
00152 ENUM2STRING(PW_SPEEDBURST),
00153 ENUM2STRING(PW_DISINT_4),
00154 ENUM2STRING(PW_SPEED),
00155 ENUM2STRING(PW_CLOAKED),
00156 ENUM2STRING(PW_FORCE_ENLIGHTENED_LIGHT),
00157 ENUM2STRING(PW_FORCE_ENLIGHTENED_DARK),
00158 ENUM2STRING(PW_FORCE_BOON),
00159 ENUM2STRING(PW_YSALAMIRI),
00160
00161 "", -1
00162 };
00163
00164
00165
00166
00167
00168 void BG_SiegeStripTabs(char *buf)
00169 {
00170 int i = 0;
00171 int i_r = 0;
00172
00173 while (buf[i])
00174 {
00175 if (buf[i] != SIEGECHAR_TAB)
00176 {
00177 buf[i_r] = buf[i];
00178 }
00179 else
00180 {
00181 buf[i_r] = ' ';
00182 }
00183
00184 i_r++;
00185 i++;
00186 }
00187
00188 buf[i_r] = '\0';
00189 }
00190
00191 int BG_SiegeGetValueGroup(char *buf, char *group, char *outbuf)
00192 {
00193 int i = 0;
00194 int j;
00195 char checkGroup[4096];
00196 qboolean isGroup;
00197 int parseGroups = 0;
00198
00199 while (buf[i])
00200 {
00201 if (buf[i] != ' ' && buf[i] != '{' && buf[i] != '}' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB)
00202 {
00203 if (buf[i] == '/' &&
00204 buf[i+1] == '/')
00205 {
00206 while (buf[i] && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB)
00207 {
00208 i++;
00209 }
00210 }
00211 else
00212 {
00213 j = 0;
00214
00215 while (buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB && buf[i] != '{' && buf[i])
00216 {
00217 if (buf[i] == '/' && buf[i+1] == '/')
00218 {
00219 break;
00220 }
00221
00222 checkGroup[j] = buf[i];
00223 j++;
00224 i++;
00225 }
00226 checkGroup[j] = 0;
00227
00228
00229 if (buf[i] == '/' && buf[i+1] == '/')
00230 {
00231 while (buf[i] && buf[i] != '\n' && buf[i] != '\r')
00232 {
00233 i++;
00234 }
00235 while (buf[i] == '\n' || buf[i] == '\r')
00236 {
00237 i++;
00238 }
00239 }
00240
00241 if (!buf[i])
00242 {
00243 Com_Error(ERR_DROP, "Unexpected EOF while looking for group '%s'", group);
00244 }
00245
00246 isGroup = qfalse;
00247
00248 while (buf[i] && buf[i] == ' ' || buf[i] == SIEGECHAR_TAB || buf[i] == '\n' || buf[i] == '\r')
00249 {
00250 i++;
00251 }
00252
00253 if (buf[i] == '{')
00254 {
00255 isGroup = qtrue;
00256 }
00257
00258
00259 if (isGroup && !Q_stricmp(checkGroup, group))
00260 {
00261 while (buf[i] != '{' && buf[i])
00262 {
00263 i++;
00264 }
00265
00266 if (buf[i])
00267 {
00268 j = 0;
00269
00270 parseGroups = 0;
00271
00272 while ((buf[i] != '}' || parseGroups) && buf[i])
00273 {
00274 if (buf[i] == '{')
00275 {
00276 parseGroups++;
00277 }
00278 else if (buf[i] == '}')
00279 {
00280 parseGroups--;
00281 }
00282
00283 if (parseGroups < 0)
00284 {
00285 Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group);
00286 }
00287
00288 if ((buf[i] != '{' || parseGroups > 1) &&
00289 (buf[i] != '}' || parseGroups > 0))
00290 {
00291 outbuf[j] = buf[i];
00292 j++;
00293 }
00294
00295 if (buf[i] == '}' && !parseGroups)
00296 {
00297 break;
00298 }
00299
00300 i++;
00301 }
00302 outbuf[j] = 0;
00303
00304
00305 if (buf[i] != '}')
00306 {
00307 Com_Error(ERR_DROP, "Group '%s' is missing a closing bracket", group);
00308 }
00309
00310
00311 BG_SiegeStripTabs(outbuf);
00312
00313 return 1;
00314 }
00315 else
00316 {
00317 Com_Error(ERR_DROP, "Error parsing group in file, unexpected EOF before opening bracket while looking for group '%s'", group);
00318 }
00319 }
00320 else if (!isGroup)
00321 {
00322 while (buf[i] && buf[i] != '\n' && buf[i] != '\r')
00323 {
00324 i++;
00325 }
00326 }
00327 else
00328 {
00329 parseGroups = 0;
00330
00331 while (buf[i] && (buf[i] != '}' || parseGroups))
00332 {
00333 if (buf[i] == '{')
00334 {
00335 parseGroups++;
00336 }
00337 else if (buf[i] == '}')
00338 {
00339 parseGroups--;
00340 }
00341
00342 if (parseGroups < 0)
00343 {
00344 Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group);
00345 }
00346
00347 if (buf[i] == '}' && !parseGroups)
00348 {
00349 break;
00350 }
00351
00352 i++;
00353 }
00354
00355 if (buf[i] != '}')
00356 {
00357 Com_Error(ERR_DROP, "Found an opening bracket without a matching closing bracket while looking for group '%s'", group);
00358 }
00359
00360 i++;
00361 }
00362 }
00363 }
00364 else if (buf[i] == '{')
00365 {
00366 parseGroups = 0;
00367
00368 while (buf[i] && (buf[i] != '}' || parseGroups))
00369 {
00370 if (buf[i] == '{')
00371 {
00372 parseGroups++;
00373 }
00374 else if (buf[i] == '}')
00375 {
00376 parseGroups--;
00377 }
00378
00379 if (parseGroups < 0)
00380 {
00381 Com_Error(ERR_DROP, "Found a closing bracket without an opening bracket while looking for group '%s'", group);
00382 }
00383
00384 if (buf[i] == '}' && !parseGroups)
00385 {
00386 break;
00387 }
00388
00389 i++;
00390 }
00391
00392 if (buf[i] != '}')
00393 {
00394 Com_Error(ERR_DROP, "Found an opening bracket without a matching closing bracket while looking for group '%s'", group);
00395 }
00396 }
00397
00398 if (!buf[i])
00399 {
00400 break;
00401 }
00402 i++;
00403 }
00404
00405 return 0;
00406 }
00407
00408 int BG_SiegeGetPairedValue(char *buf, char *key, char *outbuf)
00409 {
00410 int i = 0;
00411 int j;
00412 int k;
00413 char checkKey[4096];
00414
00415 while (buf[i])
00416 {
00417 if (buf[i] != ' ' && buf[i] != '{' && buf[i] != '}' && buf[i] != '\n' && buf[i] != '\r')
00418 {
00419 if (buf[i] == '/' &&
00420 buf[i+1] == '/')
00421 {
00422 while (buf[i] && buf[i] != '\n' && buf[i] != '\r')
00423 {
00424 i++;
00425 }
00426 }
00427 else
00428 {
00429 j = 0;
00430
00431 while (buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r' && buf[i] != SIEGECHAR_TAB && buf[i])
00432 {
00433 if (buf[i] == '/' && buf[i+1] == '/')
00434 {
00435 break;
00436 }
00437
00438 checkKey[j] = buf[i];
00439 j++;
00440 i++;
00441 }
00442 checkKey[j] = 0;
00443
00444 k = i;
00445
00446 while (buf[k] && (buf[k] == ' ' || buf[k] == '\n' || buf[k] == '\r'))
00447 {
00448 k++;
00449 }
00450
00451 if (buf[k] == '{')
00452 {
00453 int openB = 0;
00454
00455 while (buf[i] && (buf[i] != '}' || openB))
00456 {
00457 if (buf[i] == '{')
00458 {
00459 openB++;
00460 }
00461 else if (buf[i] == '}')
00462 {
00463 openB--;
00464 }
00465
00466 if (openB < 0)
00467 {
00468 Com_Error(ERR_DROP, "Unexpected closing bracket (too many) while parsing to end of group '%s'", checkKey);
00469 }
00470
00471 if (buf[i] == '}' && !openB)
00472 {
00473 break;
00474 }
00475 i++;
00476 }
00477
00478 if (buf[i] == '}')
00479 {
00480 i++;
00481 }
00482 }
00483 else
00484 {
00485
00486 if (buf[i] != '/' || buf[i+1] != '/')
00487 {
00488 if (!Q_stricmp(checkKey, key))
00489 {
00490 while ((buf[i] == ' ' || buf[i] == '\n' || buf[i] == '\r' || buf[i] == SIEGECHAR_TAB) && buf[i])
00491 {
00492 i++;
00493 }
00494
00495 if (buf[i])
00496 {
00497 qboolean parseToQuote = qfalse;
00498
00499 if (buf[i] == '\"')
00500 {
00501 i++;
00502 parseToQuote = qtrue;
00503 }
00504
00505 j = 0;
00506 while ( ((!parseToQuote && buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r') || (parseToQuote && buf[i] != '\"')) )
00507 {
00508 if (buf[i] == '/' &&
00509 buf[i+1] == '/')
00510 {
00511 break;
00512 }
00513 outbuf[j] = buf[i];
00514 j++;
00515 i++;
00516
00517 if (!buf[i])
00518 {
00519 if (parseToQuote)
00520 {
00521 Com_Error(ERR_DROP, "Unexpected EOF while looking for endquote, error finding paired value for '%s'", key);
00522 }
00523 else
00524 {
00525 Com_Error(ERR_DROP, "Unexpected EOF while looking for space or endline, error finding paired value for '%s'", key);
00526 }
00527 }
00528 }
00529 outbuf[j] = 0;
00530
00531 return 1;
00532 }
00533 else
00534 {
00535 Com_Error(ERR_DROP, "Error parsing file, unexpected EOF while looking for valud '%s'", key);
00536 }
00537 }
00538 else
00539 {
00540 while (buf[i] && buf[i] != '\n')
00541 {
00542 i++;
00543 }
00544 }
00545 }
00546 else
00547 {
00548 Com_Error(ERR_DROP, "Error parsing file, found comment, expected value for '%s'", key);
00549 }
00550 }
00551 }
00552 }
00553
00554 if (!buf[i])
00555 {
00556 break;
00557 }
00558 i++;
00559 }
00560
00561 return 0;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571 void BG_SiegeTranslateForcePowers(char *buf, siegeClass_t *siegeClass)
00572 {
00573 char checkPower[1024];
00574 char checkLevel[256];
00575 int l = 0;
00576 int k = 0;
00577 int j = 0;
00578 int i = 0;
00579 int parsedLevel = 0;
00580 qboolean allPowers = qfalse;
00581 qboolean noPowers = qfalse;
00582
00583 if (!Q_stricmp(buf, "FP_ALL"))
00584 {
00585 allPowers = qtrue;
00586 }
00587
00588 if (buf[0] == '0' && !buf[1])
00589 {
00590 noPowers = qtrue;
00591 }
00592
00593
00594 while (i < NUM_FORCE_POWERS)
00595 {
00596 if (allPowers)
00597 {
00598 siegeClass->forcePowerLevels[i] = FORCE_LEVEL_3;
00599 }
00600 else
00601 {
00602 siegeClass->forcePowerLevels[i] = 0;
00603 }
00604 i++;
00605 }
00606
00607 if (allPowers || noPowers)
00608 {
00609 return;
00610 }
00611
00612 i = 0;
00613 while (buf[i])
00614 {
00615 if (buf[i] != ' ' && buf[i] != '|')
00616 {
00617 j = 0;
00618
00619 while (buf[i] && buf[i] != ' ' && buf[i] != '|' && buf[i] != ',')
00620 {
00621 checkPower[j] = buf[i];
00622 j++;
00623 i++;
00624 }
00625 checkPower[j] = 0;
00626
00627 if (buf[i] == ',')
00628 {
00629 i++;
00630 l = 0;
00631 while (buf[i] && buf[i] != ' ' && buf[i] != '|')
00632 {
00633 checkLevel[l] = buf[i];
00634 l++;
00635 i++;
00636 }
00637 checkLevel[l] = 0;
00638 parsedLevel = atoi(checkLevel);
00639
00640
00641 if (parsedLevel < 0)
00642 {
00643 parsedLevel = 0;
00644 }
00645 if (parsedLevel > FORCE_LEVEL_5)
00646 {
00647 parsedLevel = FORCE_LEVEL_5;
00648 }
00649 }
00650 else
00651 {
00652 parsedLevel = 3;
00653 }
00654
00655 if (checkPower[0])
00656 {
00657 k = 0;
00658
00659 if (!Q_stricmp(checkPower, "FP_JUMP"))
00660 {
00661 strcpy(checkPower, "FP_LEVITATION");
00662 }
00663
00664 while (FPTable[k].id != -1 && FPTable[k].name[0])
00665 {
00666 if (!Q_stricmp(checkPower, FPTable[k].name))
00667 {
00668 siegeClass->forcePowerLevels[k] = parsedLevel;
00669 break;
00670 }
00671 k++;
00672 }
00673 }
00674 }
00675
00676 if (!buf[i])
00677 {
00678 break;
00679 }
00680 i++;
00681 }
00682 }
00683
00684
00685
00686
00687
00688 int BG_SiegeTranslateGenericTable(char *buf, stringID_table_t *table, qboolean bitflag)
00689 {
00690 int items = 0;
00691 char checkItem[1024];
00692 int i = 0;
00693 int j = 0;
00694 int k = 0;
00695
00696 if (buf[0] == '0' && !buf[1])
00697 {
00698 return 0;
00699 }
00700
00701 while (buf[i])
00702 {
00703 if (buf[i] != ' ' && buf[i] != '|')
00704 {
00705 j = 0;
00706
00707 while (buf[i] && buf[i] != ' ' && buf[i] != '|')
00708 {
00709 checkItem[j] = buf[i];
00710 j++;
00711 i++;
00712 }
00713 checkItem[j] = 0;
00714
00715 if (checkItem[0])
00716 {
00717 k = 0;
00718
00719 while (table[k].name && table[k].name[0])
00720 {
00721 if (!Q_stricmp(checkItem, table[k].name))
00722 {
00723 if (bitflag)
00724 {
00725 items |= (1 << table[k].id);
00726 }
00727 else
00728 {
00729 return table[k].id;
00730 }
00731 break;
00732 }
00733 k++;
00734 }
00735 }
00736 }
00737
00738 if (!buf[i])
00739 {
00740 break;
00741 }
00742
00743 i++;
00744 }
00745 return items;
00746 }
00747
00748 char *classTitles[SPC_MAX] =
00749 {
00750 "infantry",
00751 "vanguard",
00752 "support",
00753 "jedi_general",
00754 "demolitionist",
00755 "heavy_weapons",
00756 };
00757
00758
00759 void BG_SiegeParseClassFile(const char *filename, siegeClassDesc_t *descBuffer)
00760 {
00761 fileHandle_t f;
00762 int len;
00763 int i;
00764 char classInfo[4096];
00765 char parseBuf[4096];
00766
00767 len = trap_FS_FOpenFile(filename, &f, FS_READ);
00768
00769 if (!f || len >= 4096)
00770 {
00771 return;
00772 }
00773
00774 trap_FS_Read(classInfo, len, f);
00775
00776 trap_FS_FCloseFile(f);
00777
00778 classInfo[len] = 0;
00779
00780
00781 if (descBuffer)
00782 {
00783 if (!BG_SiegeGetPairedValue(classInfo, "description", descBuffer->desc))
00784 {
00785 strcpy(descBuffer->desc, "DESCRIPTION UNAVAILABLE");
00786 }
00787
00788
00789
00790 assert(strlen(descBuffer->desc) < SIEGE_CLASS_DESC_LEN);
00791 }
00792
00793 BG_SiegeGetValueGroup(classInfo, "ClassInfo", classInfo);
00794
00795
00796 if (BG_SiegeGetPairedValue(classInfo, "name", parseBuf))
00797 {
00798 strcpy(bgSiegeClasses[bgNumSiegeClasses].name, parseBuf);
00799 }
00800 else
00801 {
00802 Com_Error(ERR_DROP, "Siege class without name entry");
00803 }
00804
00805
00806 if (BG_SiegeGetPairedValue(classInfo, "model", parseBuf))
00807 {
00808 strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf);
00809 }
00810 else
00811 {
00812 bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0;
00813 }
00814
00815
00816 if (BG_SiegeGetPairedValue(classInfo, "skin", parseBuf))
00817 {
00818 strcpy(bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf);
00819 }
00820 else
00821 {
00822 bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0;
00823 }
00824
00825
00826 if (BG_SiegeGetPairedValue(classInfo, "saber1", parseBuf))
00827 {
00828 strcpy(bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf);
00829 }
00830 else
00831 {
00832 bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0;
00833 }
00834
00835
00836 if (BG_SiegeGetPairedValue(classInfo, "saber2", parseBuf))
00837 {
00838 strcpy(bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf);
00839 }
00840 else
00841 {
00842 bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0;
00843 }
00844
00845
00846 if (BG_SiegeGetPairedValue(classInfo, "saberstyle", parseBuf))
00847 {
00848 bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable(parseBuf, StanceTable, qtrue);
00849 }
00850 else
00851 {
00852 bgSiegeClasses[bgNumSiegeClasses].saberStance = 0;
00853 }
00854
00855
00856 if (BG_SiegeGetPairedValue(classInfo, "sabercolor", parseBuf))
00857 {
00858 bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi(parseBuf);
00859 bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue;
00860 }
00861 else
00862 {
00863 bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse;
00864 }
00865
00866
00867 if (BG_SiegeGetPairedValue(classInfo, "saber2color", parseBuf))
00868 {
00869 bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi(parseBuf);
00870 bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue;
00871 }
00872 else
00873 {
00874 bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse;
00875 }
00876
00877
00878 if (BG_SiegeGetPairedValue(classInfo, "weapons", parseBuf))
00879 {
00880 bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable(parseBuf, WPTable, qtrue);
00881 }
00882 else
00883 {
00884 Com_Error(ERR_DROP, "Siege class without weapons entry");
00885 }
00886
00887 if (!(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER)))
00888 {
00889 bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE);
00890
00891
00892
00893 }
00894
00895
00896 if (BG_SiegeGetPairedValue(classInfo, "forcepowers", parseBuf))
00897 {
00898 BG_SiegeTranslateForcePowers(parseBuf, &bgSiegeClasses[bgNumSiegeClasses]);
00899 }
00900 else
00901 {
00902 i = 0;
00903 while (i < NUM_FORCE_POWERS)
00904 {
00905 bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0;
00906 i++;
00907 }
00908 }
00909
00910
00911 if (BG_SiegeGetPairedValue(classInfo, "classflags", parseBuf))
00912 {
00913 bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable(parseBuf, bgSiegeClassFlagNames, qtrue);
00914 }
00915 else
00916 {
00917 bgSiegeClasses[bgNumSiegeClasses].classflags = 0;
00918 }
00919
00920
00921 if (BG_SiegeGetPairedValue(classInfo, "maxhealth", parseBuf))
00922 {
00923 bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi(parseBuf);
00924 }
00925 else
00926 {
00927 bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100;
00928 }
00929
00930
00931 if (BG_SiegeGetPairedValue(classInfo, "starthealth", parseBuf))
00932 {
00933 bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi(parseBuf);
00934 }
00935 else
00936 {
00937 bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth;
00938 }
00939
00940
00941
00942 if (BG_SiegeGetPairedValue(classInfo, "maxarmor", parseBuf))
00943 {
00944 bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi(parseBuf);
00945 }
00946 else
00947 {
00948 bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0;
00949 }
00950
00951
00952 if (BG_SiegeGetPairedValue(classInfo, "startarmor", parseBuf))
00953 {
00954 bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi(parseBuf);
00955 if (!bgSiegeClasses[bgNumSiegeClasses].maxarmor)
00956 {
00957 bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor;
00958 }
00959 }
00960 else
00961 {
00962 bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor;
00963 }
00964
00965
00966 if (BG_SiegeGetPairedValue(classInfo, "speed", parseBuf))
00967 {
00968 bgSiegeClasses[bgNumSiegeClasses].speed = atof(parseBuf);
00969 }
00970 else
00971 {
00972 bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f;
00973 }
00974
00975
00976 if (BG_SiegeGetPairedValue(classInfo, "uishader", parseBuf))
00977 {
00978 #ifdef QAGAME
00979 bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
00980 memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
00981 #elif defined CGAME
00982 bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
00983 memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
00984 #else //ui
00985 bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap_R_RegisterShaderNoMip(parseBuf);
00986 memcpy(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,parseBuf,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
00987 #endif
00988 }
00989 else
00990 {
00991 Com_Error(ERR_DROP, "Siege class without uishader entry");
00992 }
00993
00994
00995 if (BG_SiegeGetPairedValue(classInfo, "class_shader", parseBuf))
00996 {
00997 #ifdef QAGAME
00998 bgSiegeClasses[bgNumSiegeClasses].classShader = 0;
00999 #else //cgame, ui
01000 bgSiegeClasses[bgNumSiegeClasses].classShader = trap_R_RegisterShaderNoMip(parseBuf);
01001 assert( bgSiegeClasses[bgNumSiegeClasses].classShader );
01002 if ( !bgSiegeClasses[bgNumSiegeClasses].classShader )
01003 {
01004
01005 Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name );
01006 }
01007
01008 else
01009 #endif
01010 {
01011
01012 int titleLength,i,arrayTitleLength;
01013 char *holdBuf;
01014
01015 titleLength = strlen(parseBuf);
01016 for (i=0;i<SPC_MAX;i++)
01017 {
01018
01019 arrayTitleLength = strlen(classTitles[i]);
01020 if (arrayTitleLength>titleLength)
01021 {
01022 break;
01023 }
01024
01025 holdBuf = parseBuf + ( titleLength - arrayTitleLength);
01026 if (!strcmp(holdBuf,classTitles[i]))
01027 {
01028 bgSiegeClasses[bgNumSiegeClasses].playerClass = i;
01029 break;
01030 }
01031 }
01032
01033
01034 if (i>=SPC_MAX)
01035 {
01036 bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY;
01037 }
01038 }
01039 }
01040 else
01041 {
01042
01043 Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name );
01044 }
01045
01046
01047 if (BG_SiegeGetPairedValue(classInfo, "holdables", parseBuf))
01048 {
01049 bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable(parseBuf, HoldableTable, qtrue);
01050 }
01051 else
01052 {
01053 bgSiegeClasses[bgNumSiegeClasses].invenItems = 0;
01054 }
01055
01056
01057 if (BG_SiegeGetPairedValue(classInfo, "powerups", parseBuf))
01058 {
01059 bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable(parseBuf, PowerupTable, qtrue);
01060 }
01061 else
01062 {
01063 bgSiegeClasses[bgNumSiegeClasses].powerups = 0;
01064 }
01065
01066
01067 bgNumSiegeClasses++;
01068 }
01069
01070
01071 int BG_SiegeCountBaseClass(const int team, const short classIndex)
01072 {
01073 int count = 0,i;
01074 siegeTeam_t *stm;
01075
01076 stm = BG_SiegeFindThemeForTeam(team);
01077 if (!stm)
01078 {
01079 return(0);
01080
01081 }
01082
01083 for (i=0;i<stm->numClasses;i++)
01084 {
01085
01086 if (stm->classes[i]->playerClass == classIndex)
01087 {
01088 count++;
01089 }
01090 }
01091 return(count);
01092 }
01093
01094 char *BG_GetUIPortraitFile(const int team, const short classIndex, const short cntIndex)
01095 {
01096 int count = 0,i;
01097 siegeTeam_t *stm;
01098
01099 stm = BG_SiegeFindThemeForTeam(team);
01100 if (!stm)
01101 {
01102 return(0);
01103
01104 }
01105
01106
01107 for (i=0;i<stm->numClasses;i++)
01108 {
01109
01110 if (stm->classes[i]->playerClass == classIndex)
01111 {
01112 if (count==cntIndex)
01113 {
01114 return(stm->classes[i]->uiPortrait);
01115 }
01116 ++count;
01117 }
01118 }
01119
01120 return(0);
01121 }
01122
01123 int BG_GetUIPortrait(const int team, const short classIndex, const short cntIndex)
01124 {
01125 int count = 0,i;
01126 siegeTeam_t *stm;
01127
01128 stm = BG_SiegeFindThemeForTeam(team);
01129 if (!stm)
01130 {
01131 return(0);
01132
01133 }
01134
01135
01136 for (i=0;i<stm->numClasses;i++)
01137 {
01138
01139 if (stm->classes[i]->playerClass == classIndex)
01140 {
01141 if (count==cntIndex)
01142 {
01143 return(stm->classes[i]->uiPortraitShader);
01144 }
01145 ++count;
01146 }
01147 }
01148
01149 return(0);
01150 }
01151
01152
01153 siegeClass_t *BG_GetClassOnBaseClass(const int team, const short classIndex, const short cntIndex)
01154 {
01155 int count = 0,i;
01156 siegeTeam_t *stm;
01157
01158 stm = BG_SiegeFindThemeForTeam(team);
01159 if (!stm)
01160 {
01161 return(0);
01162 }
01163
01164
01165 for (i=0;i<stm->numClasses;i++)
01166 {
01167
01168 if (stm->classes[i]->playerClass == classIndex)
01169 {
01170 if (count==cntIndex)
01171 {
01172 return(stm->classes[i]);
01173 }
01174 ++count;
01175 }
01176 }
01177
01178 return(0);
01179 }
01180
01181 void BG_SiegeLoadClasses(siegeClassDesc_t *descBuffer)
01182 {
01183 int numFiles;
01184 int filelen;
01185 char filelist[4096];
01186 char filename[MAX_QPATH];
01187 char* fileptr;
01188 int i;
01189
01190 bgNumSiegeClasses = 0;
01191
01192 numFiles = trap_FS_GetFileList("ext_data/Siege/Classes", ".scl", filelist, 4096 );
01193 fileptr = filelist;
01194
01195 for (i = 0; i < numFiles; i++, fileptr += filelen+1)
01196 {
01197 filelen = strlen(fileptr);
01198 strcpy(filename, "ext_data/Siege/Classes/");
01199 strcat(filename, fileptr);
01200
01201 if (descBuffer)
01202 {
01203 BG_SiegeParseClassFile(filename, &descBuffer[i]);
01204 }
01205 else
01206 {
01207 BG_SiegeParseClassFile(filename, NULL);
01208 }
01209 }
01210 }
01211
01212
01213
01214
01215
01216
01217
01218
01219 siegeClass_t *BG_SiegeFindClassByName(const char *classname)
01220 {
01221 int i = 0;
01222
01223 while (i < bgNumSiegeClasses)
01224 {
01225 if (!Q_stricmp(bgSiegeClasses[i].name, classname))
01226 {
01227 return &bgSiegeClasses[i];
01228 }
01229 i++;
01230 }
01231
01232 return NULL;
01233 }
01234
01235 void BG_SiegeParseTeamFile(const char *filename)
01236 {
01237 fileHandle_t f;
01238 int len;
01239 char teamInfo[2048];
01240 char parseBuf[1024];
01241 char lookString[256];
01242 int i = 1;
01243 qboolean success = qtrue;
01244
01245 len = trap_FS_FOpenFile(filename, &f, FS_READ);
01246
01247 if (!f || len >= 2048)
01248 {
01249 return;
01250 }
01251
01252 trap_FS_Read(teamInfo, len, f);
01253
01254 trap_FS_FCloseFile(f);
01255
01256 teamInfo[len] = 0;
01257
01258 if (BG_SiegeGetPairedValue(teamInfo, "name", parseBuf))
01259 {
01260 strcpy(bgSiegeTeams[bgNumSiegeTeams].name, parseBuf);
01261 }
01262 else
01263 {
01264 Com_Error(ERR_DROP, "Siege team with no name definition");
01265 }
01266
01267
01268 #ifdef CGAME
01269 if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", parseBuf))
01270 {
01271 bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap_R_RegisterShaderNoMip(parseBuf);
01272 }
01273 #else
01274 bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0;
01275 #endif
01276
01277 bgSiegeTeams[bgNumSiegeTeams].numClasses = 0;
01278
01279 if (BG_SiegeGetValueGroup(teamInfo, "Classes", teamInfo))
01280 {
01281 while (success && i < MAX_SIEGE_CLASSES)
01282 {
01283 strcpy(lookString, va("class%i", i));
01284
01285 success = BG_SiegeGetPairedValue(teamInfo, lookString, parseBuf);
01286
01287 if (!success)
01288 {
01289 break;
01290 }
01291
01292 bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName(parseBuf);
01293
01294 if (!bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses])
01295 {
01296 Com_Error(ERR_DROP, "Invalid class specified: '%s'", parseBuf);
01297 }
01298
01299 bgSiegeTeams[bgNumSiegeTeams].numClasses++;
01300
01301 i++;
01302 }
01303 }
01304
01305 if (!bgSiegeTeams[bgNumSiegeTeams].numClasses)
01306 {
01307 Com_Error(ERR_DROP, "Team defined with no allowable classes\n");
01308 }
01309
01310
01311 bgNumSiegeTeams++;
01312 }
01313
01314 void BG_SiegeLoadTeams(void)
01315 {
01316 int numFiles;
01317 int filelen;
01318 char filelist[4096];
01319 char filename[MAX_QPATH];
01320 char* fileptr;
01321 int i;
01322
01323 bgNumSiegeTeams = 0;
01324
01325 numFiles = trap_FS_GetFileList("ext_data/Siege/Teams", ".team", filelist, 4096 );
01326 fileptr = filelist;
01327
01328 for (i = 0; i < numFiles; i++, fileptr += filelen+1)
01329 {
01330 filelen = strlen(fileptr);
01331 strcpy(filename, "ext_data/Siege/Teams/");
01332 strcat(filename, fileptr);
01333 BG_SiegeParseTeamFile(filename);
01334 }
01335 }
01336
01337
01338
01339
01340
01341
01342
01343
01344 siegeTeam_t *BG_SiegeFindThemeForTeam(int team)
01345 {
01346 if (team == SIEGETEAM_TEAM1)
01347 {
01348 return team1Theme;
01349 }
01350 else if (team == SIEGETEAM_TEAM2)
01351 {
01352 return team2Theme;
01353 }
01354
01355 return NULL;
01356 }
01357
01358 #ifndef UI_EXPORTS //only for game/cgame
01359
01360 extern qboolean WP_SaberParseParms( const char *SaberName, saberInfo_t *saber );
01361 extern int BG_ModelCache(const char *modelName, const char *skinName);
01362
01363 void BG_PrecacheSabersForSiegeTeam(int team)
01364 {
01365 siegeTeam_t *t;
01366 saberInfo_t saber;
01367 char *saberName;
01368 int sNum;
01369
01370 t = BG_SiegeFindThemeForTeam(team);
01371
01372 if (t)
01373 {
01374 int i = 0;
01375
01376 while (i < t->numClasses)
01377 {
01378 sNum = 0;
01379
01380 while (sNum < MAX_SABERS)
01381 {
01382 switch (sNum)
01383 {
01384 case 0:
01385 saberName = &t->classes[i]->saber1[0];
01386 break;
01387 case 1:
01388 saberName = &t->classes[i]->saber2[0];
01389 break;
01390 default:
01391 saberName = NULL;
01392 break;
01393 }
01394
01395 if (saberName && saberName[0])
01396 {
01397 WP_SaberParseParms(saberName, &saber);
01398 if (!Q_stricmp(saberName, saber.name))
01399 {
01400 if (saber.model[0])
01401 {
01402 BG_ModelCache(saber.model, NULL);
01403 }
01404 }
01405 }
01406
01407 sNum++;
01408 }
01409
01410 i++;
01411 }
01412 }
01413 }
01414 #endif
01415
01416 qboolean BG_SiegeCheckClassLegality(int team, char *classname)
01417 {
01418 siegeTeam_t **teamPtr = NULL;
01419 int i = 0;
01420
01421 if (team == SIEGETEAM_TEAM1)
01422 {
01423 teamPtr = &team1Theme;
01424 }
01425 else if (team == SIEGETEAM_TEAM2)
01426 {
01427 teamPtr = &team2Theme;
01428 }
01429 else
01430 {
01431 return qtrue;
01432 }
01433
01434 if (!teamPtr || !(*teamPtr))
01435 {
01436 return qtrue;
01437 }
01438
01439
01440 while (i < (*teamPtr)->numClasses)
01441 {
01442 if (!Q_stricmp(classname, (*teamPtr)->classes[i]->name))
01443 {
01444 return qtrue;
01445 }
01446 i++;
01447 }
01448
01449
01450 strcpy(classname, (*teamPtr)->classes[0]->name);
01451
01452 return qfalse;
01453 }
01454
01455 siegeTeam_t *BG_SiegeFindTeamForTheme(char *themeName)
01456 {
01457 int i = 0;
01458
01459 while (i < bgNumSiegeTeams)
01460 {
01461 if (bgSiegeTeams[i].name &&
01462 !Q_stricmp(bgSiegeTeams[i].name, themeName))
01463 {
01464 return &bgSiegeTeams[i];
01465 }
01466
01467 i++;
01468 }
01469
01470 return NULL;
01471 }
01472
01473 void BG_SiegeSetTeamTheme(int team, char *themeName)
01474 {
01475 siegeTeam_t **teamPtr = NULL;
01476
01477 if (team == SIEGETEAM_TEAM1)
01478 {
01479 teamPtr = &team1Theme;
01480 }
01481 else
01482 {
01483 teamPtr = &team2Theme;
01484 }
01485
01486 (*teamPtr) = BG_SiegeFindTeamForTheme(themeName);
01487 }
01488
01489 int BG_SiegeFindClassIndexByName(const char *classname)
01490 {
01491 int i = 0;
01492
01493 while (i < bgNumSiegeClasses)
01494 {
01495 if (!Q_stricmp(bgSiegeClasses[i].name, classname))
01496 {
01497 return i;
01498 }
01499 i++;
01500 }
01501
01502 return -1;
01503 }
01504
01505
01506
01507
01508 #include "../namespace_end.h"