00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "cl_game.h"
00027 #include "cgame.h"
00028 #include "battlescape/cl_localentity.h"
00029 #include "ui/ui_main.h"
00030 #include "ui/ui_nodes.h"
00031 #include "cl_team.h"
00032 #include "battlescape/events/e_main.h"
00033 #include "cl_inventory.h"
00034 #include "ui/node/ui_node_model.h"
00035
00036 static const cgame_export_t gameTypeList[] = {
00037 {"Multiplayer mode", "multiplayer", GAME_MULTIPLAYER, GAME_MP_InitStartup, GAME_MP_Shutdown, NULL, GAME_MP_GetTeam, GAME_MP_MapInfo, GAME_MP_Results, NULL, NULL, GAME_MP_GetEquipmentDefinition, NULL, NULL, NULL, NULL, NULL, NULL, GAME_MP_EndRoundAnnounce, GAME_MP_StartBattlescape},
00038 {"Campaign mode", "campaigns", GAME_CAMPAIGN, GAME_CP_InitStartup, GAME_CP_Shutdown, GAME_CP_Spawn, GAME_CP_GetTeam, GAME_CP_MapInfo, GAME_CP_Results, GAME_CP_ItemIsUseable, GAME_CP_DisplayItemInfo, GAME_CP_GetEquipmentDefinition, GAME_CP_CharacterCvars, GAME_CP_TeamIsKnown, GAME_CP_Drop, GAME_CP_InitializeBattlescape, GAME_CP_Frame, GAME_CP_GetModelForItem, NULL, NULL},
00039 {"Skirmish mode", "skirmish", GAME_SKIRMISH, GAME_SK_InitStartup, GAME_SK_Shutdown, NULL, GAME_SK_GetTeam, GAME_SK_MapInfo, GAME_SK_Results, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
00040
00041 {NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
00042 };
00043
00047 static character_t characters[MAX_ACTIVETEAM];
00048
00058 character_t* GAME_GetCharacter (int index)
00059 {
00060 if (index < 0 || index >= lengthof(characters))
00061 Com_Error(ERR_DROP, "Out of bounds character access");
00062
00063 return &characters[index];
00064 }
00065
00071 size_t GAME_GetCharacterArraySize (void)
00072 {
00073 return lengthof(characters);
00074 }
00075
00081 void GAME_ResetCharacters (void)
00082 {
00083 memset(&characters, 0, sizeof(characters));
00084 chrDisplayList.num = 0;
00085 }
00086
00087 void GAME_AppendTeamMember (int memberIndex, const char *teamDefID, const equipDef_t *ed)
00088 {
00089 character_t *chr;
00090
00091 if (ed == NULL)
00092 Com_Error(ERR_DROP, "No equipment definition given");
00093
00094 chr = GAME_GetCharacter(memberIndex);
00095
00096 CL_GenerateCharacter(chr, teamDefID);
00097
00098 cls.i.EquipActor(&cls.i, &chr->i, ed, chr->teamDef);
00099
00100 chrDisplayList.chr[memberIndex] = chr;
00101 chrDisplayList.num++;
00102 }
00103
00104 void GAME_GenerateTeam (const char *teamDefID, const equipDef_t *ed, int teamMembers)
00105 {
00106 int i;
00107
00108 if (teamMembers > GAME_GetCharacterArraySize())
00109 Com_Error(ERR_DROP, "More than the allowed amount of team members");
00110
00111 if (ed == NULL)
00112 Com_Error(ERR_DROP, "No equipment definition given");
00113
00114 GAME_ResetCharacters();
00115
00116 for (i = 0; i < teamMembers; i++)
00117 GAME_AppendTeamMember(i, teamDefID, ed);
00118 }
00119
00120 static const cgame_export_t *GAME_GetCurrentType (void)
00121 {
00122 const cgame_export_t *list = gameTypeList;
00123
00124 if (cls.gametype == GAME_NONE)
00125 return NULL;
00126
00127 while (list->name) {
00128 if (list->gametype == cls.gametype)
00129 return list;
00130 list++;
00131 }
00132
00133 return NULL;
00134 }
00135
00136 void GAME_ReloadMode (void)
00137 {
00138 const cgame_export_t *list = GAME_GetCurrentType();
00139 if (list != NULL) {
00140 const int gametype = list->gametype;
00141 GAME_SetMode(GAME_NONE);
00142 GAME_SetMode(gametype);
00143 }
00144 }
00145
00152 void GAME_StartBattlescape (qboolean isTeamPlay)
00153 {
00154 const cgame_export_t *list = GAME_GetCurrentType();
00155 if (list != NULL && list->StartBattlescape) {
00156 list->StartBattlescape(isTeamPlay);
00157 } else {
00158 UI_InitStack(mn_hud->string, NULL, qtrue, qtrue);
00159 }
00160 if (list != NULL)
00161 Com_Printf("Used inventory slots: %i\n", cls.i.GetUsedSlots(&cls.i));
00162 }
00163
00168 void GAME_EndBattlescape (void)
00169 {
00170 Com_Printf("Used inventory slots after battle: %i\n", cls.i.GetUsedSlots(&cls.i));
00171 }
00172
00178 void GAME_EndRoundAnnounce (int playerNum, int team)
00179 {
00181 const cgame_export_t *list = GAME_GetCurrentType();
00182 if (list != NULL && list->EndRoundAnnounce)
00183 list->EndRoundAnnounce(playerNum, team);
00184 }
00185
00191 void GAME_DisplayItemInfo (uiNode_t *node, const char *string)
00192 {
00193 const cgame_export_t *list = GAME_GetCurrentType();
00194 if (list != NULL && list->DisplayItemInfo)
00195 list->DisplayItemInfo(node, string);
00196 }
00197
00198 #if 0
00199
00202 static cgame_import_t* GAME_GetImportData (void)
00203 {
00204 static cgame_import_t gameImport;
00205 static cgame_import_t *cgi = NULL;
00206
00207 if (cgi == NULL) {
00208 memset(&gameImport, 0, sizeof(gameImport));
00209 cgi = &gameImport;
00210
00211 cgi->csi = &csi;
00212 cgi->cls = &cls;
00213 cgi->cl = &cl;
00214
00215 cgi->Cmd_AddCommand = Cmd_AddCommand;
00216 cgi->Cmd_Argc = Cmd_Argc;
00217 cgi->Cmd_Args = Cmd_Args;
00218 cgi->Cmd_Argv = Cmd_Argv;
00219 cgi->Cmd_ExecuteString = Cmd_ExecuteString;
00220 cgi->Cmd_RemoveCommand = Cmd_RemoveCommand;
00221 cgi->Cvar_Delete = Cvar_Delete;
00222 cgi->Cvar_Get = Cvar_Get;
00223 cgi->Cvar_Integer = Cvar_GetInteger;
00224 cgi->Cvar_Set = Cvar_Set;
00225 cgi->Cvar_SetValue = Cvar_SetValue;
00226 cgi->Cvar_String = Cvar_GetString;
00227 cgi->FS_FreeFile = FS_FreeFile;
00228 cgi->FS_LoadFile = FS_LoadFile;
00229 cgi->UI_AddOption = UI_AddOption;
00230 cgi->UI_ExecuteConfunc = UI_ExecuteConfunc;
00231 cgi->UI_InitStack = UI_InitStack;
00232 cgi->UI_Popup = UI_Popup;
00233 cgi->UI_PopupList = UI_PopupList;
00234 cgi->UI_PopWindow = UI_PopWindow;
00235 cgi->UI_PushWindow = UI_PushWindow;
00236 cgi->UI_RegisterLinkedListText = UI_RegisterLinkedListText;
00237 cgi->UI_RegisterOption = UI_RegisterOption;
00238 cgi->UI_RegisterText = UI_RegisterText;
00239 cgi->UI_ResetData = UI_ResetData;
00240 cgi->UI_TextNodeSelectLine = UI_TextNodeSelectLine;
00241 cgi->mxml_AddBool = mxml_AddBool;
00242 cgi->mxml_AddBoolValue = mxml_AddBoolValue;
00243 cgi->mxml_AddByte = mxml_AddByte;
00244 cgi->mxml_AddByteValue = mxml_AddByteValue;
00245 cgi->mxml_AddDate = mxml_AddDate;
00246 cgi->mxml_AddDouble = mxml_AddDouble;
00247 cgi->mxml_AddDoubleValue = mxml_AddDoubleValue;
00248 cgi->mxml_AddFloat = mxml_AddFloat;
00249 cgi->mxml_AddFloatValue = mxml_AddFloatValue;
00250 cgi->mxml_AddInt = mxml_AddInt;
00251 cgi->mxml_AddIntValue = mxml_AddIntValue;
00252 cgi->mxml_AddLong = mxml_AddLong;
00253 cgi->mxml_AddLongValue = mxml_AddLongValue;
00254 cgi->mxml_AddNode = mxml_AddNode;
00255 cgi->mxml_AddPos2 = mxml_AddPos2;
00256 cgi->mxml_AddPos3 = mxml_AddPos3;
00257 cgi->mxml_AddShort = mxml_AddShort;
00258 cgi->mxml_AddShortValue = mxml_AddShortValue;
00259 cgi->mxml_AddString = mxml_AddString;
00260 cgi->mxml_AddStringValue = mxml_AddStringValue;
00261 cgi->R_LoadImage = R_LoadImage;
00262 cgi->R_LoadImageData = R_LoadImageData;
00263 cgi->R_SoftenTexture = R_SoftenTexture;
00264 cgi->R_UploadAlpha = R_UploadAlpha;
00265 cgi->S_SetSampleRepeatRate = S_SetSampleRepeatRate;
00266 cgi->S_StartLocalSample = S_StartLocalSample;
00267 }
00268
00269 return cgi;
00270 }
00271 #endif
00272
00273 static const int TAG_INVENTORY = 17462;
00274
00275 static void GAME_FreeInventory (void *data)
00276 {
00277 Mem_Free(data);
00278 }
00279
00280 static void *GAME_AllocInventoryMemory (size_t size)
00281 {
00282 return Mem_PoolAlloc(size, cl_genericPool, TAG_INVENTORY);
00283 }
00284
00285
00286 static void GAME_FreeAllInventory (void)
00287 {
00288 Mem_FreeTag(cl_genericPool, TAG_INVENTORY);
00289 }
00290
00291 static const inventoryImport_t inventoryImport = { GAME_FreeInventory, GAME_FreeAllInventory, GAME_AllocInventoryMemory };
00292
00293 void GAME_SetMode (int gametype)
00294 {
00295 const cgame_export_t *list;
00296
00297 if (gametype < 0 || gametype > GAME_MAX) {
00298 Com_Printf("Invalid gametype %i given\n", gametype);
00299 return;
00300 }
00301
00302 if (cls.gametype == gametype)
00303 return;
00304
00305 list = GAME_GetCurrentType();
00306 if (list) {
00307 Com_Printf("Shutdown gametype '%s'\n", list->name);
00308 list->Shutdown();
00309
00310
00311 if (!UI_IsWindowOnStack("main"))
00312 UI_InitStack("main", "", qtrue, qtrue);
00313 }
00314
00315 cls.gametype = gametype;
00316
00317 CL_Disconnect();
00318
00319 list = GAME_GetCurrentType();
00320 if (list) {
00321 Com_Printf("Change gametype to '%s'\n", list->name);
00322
00323 INV_DestroyInventory(&cls.i);
00324 INV_InitInventory(list->name, &cls.i, &csi, &inventoryImport);
00325 list->Init();
00326 }
00327 }
00328
00329 static void UI_MapInfoGetNext (int step)
00330 {
00331 const mapDef_t *md;
00332
00333 cls.currentSelectedMap += step;
00334
00335 if (cls.currentSelectedMap < 0)
00336 cls.currentSelectedMap = cls.numMDs - 1;
00337
00338 cls.currentSelectedMap %= cls.numMDs;
00339
00340 md = Com_GetMapDefByIDX(cls.currentSelectedMap);
00341
00342
00343 if (md->map[0] == '.')
00344 UI_MapInfoGetNext(step);
00345 }
00346
00351 static void UI_MapInfo (int step)
00352 {
00353 const char *mapname;
00354 const mapDef_t *md;
00355 const cgame_export_t *list = GAME_GetCurrentType();
00356
00357 if (!list)
00358 return;
00359
00360 if (!cls.numMDs)
00361 return;
00362
00363 UI_MapInfoGetNext(step);
00364
00365 md = list->MapInfo(step);
00366 if (!md)
00367 return;
00368
00369 mapname = md->map;
00370
00371 if (mapname[0] == '+') {
00372 Cvar_Set("mn_svmapname", va("%s %s", md->map, md->param ? md->param : ""));
00373 mapname++;
00374 } else {
00375 Cvar_Set("mn_svmapname", md->map);
00376 }
00377
00378 if (FS_CheckFile("pics/maps/shots/%s.jpg", mapname) != -1)
00379 Cvar_Set("mn_mappic", va("maps/shots/%s", mapname));
00380 else
00381 Cvar_Set("mn_mappic", "maps/shots/default");
00382
00383 if (FS_CheckFile("pics/maps/shots/%s_2.jpg", mapname) != -1)
00384 Cvar_Set("mn_mappic2", va("maps/shots/%s_2", mapname));
00385 else
00386 Cvar_Set("mn_mappic2", "maps/shots/default");
00387
00388 if (FS_CheckFile("pics/maps/shots/%s_3.jpg", mapname) != -1)
00389 Cvar_Set("mn_mappic3", va("maps/shots/%s_3", mapname));
00390 else
00391 Cvar_Set("mn_mappic3", "maps/shots/default");
00392 }
00393
00394 static void UI_GetMaps_f (void)
00395 {
00396 UI_MapInfo(0);
00397 }
00398
00399 static void UI_ChangeMap_f (void)
00400 {
00401 if (!strcmp(Cmd_Argv(0), "mn_nextmap"))
00402 UI_MapInfo(1);
00403 else
00404 UI_MapInfo(-1);
00405 }
00406
00407 static void UI_SelectMap_f (void)
00408 {
00409 const char *mapname;
00410 int i;
00411
00412 if (Cmd_Argc() != 2) {
00413 Com_Printf("Usage: %s <mapname>\n", Cmd_Argv(0));
00414 return;
00415 }
00416
00417 if (!cls.numMDs)
00418 return;
00419
00420 mapname = Cmd_Argv(1);
00421
00422 for (i = 0; i < cls.numMDs; i++) {
00423 const mapDef_t *md = Com_GetMapDefByIDX(i);
00424 if (strcmp(md->map, mapname))
00425 continue;
00426 cls.currentSelectedMap = i;
00427 UI_MapInfo(0);
00428 return;
00429 }
00430
00431 for (i = 0; i < cls.numMDs; i++) {
00432 const mapDef_t *md = Com_GetMapDefByIDX(i);
00433 if (strcmp(md->id, mapname))
00434 continue;
00435 cls.currentSelectedMap = i;
00436 UI_MapInfo(0);
00437 return;
00438 }
00439
00440 Com_Printf("Could not find map %s\n", mapname);
00441 }
00442
00446 static void GAME_SetMode_f (void)
00447 {
00448 const char *modeName;
00449 const cgame_export_t *list = gameTypeList;
00450
00451 if (Cmd_Argc() == 2)
00452 modeName = Cmd_Argv(1);
00453 else
00454 modeName = UI_GetActiveWindowName();
00455
00456 if (modeName[0] == '\0')
00457 return;
00458
00459 while (list->name) {
00460 if (!strcmp(list->menu, modeName)) {
00461 GAME_SetMode(list->gametype);
00462 return;
00463 }
00464 list++;
00465 }
00466 Com_Printf("GAME_SetMode_f: Mode '%s' not found\n", modeName);
00467 }
00468
00469 static qboolean GAME_IsArmourUseableForTeam (const objDef_t *od, const teamDef_t *teamDef)
00470 {
00471 if (teamDef != NULL && teamDef->armour && INV_IsArmour(od)) {
00472 if (CHRSH_IsTeamDefAlien(teamDef))
00473 return od->useable == TEAM_ALIEN;
00474 else if (teamDef->race == RACE_PHALANX_HUMAN)
00475 return od->useable == TEAM_PHALANX;
00476 else if (teamDef->race == RACE_CIVILIAN)
00477 return od->useable == TEAM_CIVILIAN;
00478 else
00479 return qfalse;
00480 }
00481
00482 return qtrue;
00483 }
00484
00485 qboolean GAME_ItemIsUseable (const objDef_t *od)
00486 {
00487 const cgame_export_t *list = GAME_GetCurrentType();
00488 const char *teamDefID = GAME_GetTeamDef();
00489 const teamDef_t *teamDef = Com_GetTeamDefinitionByID((teamDefID));
00490
00491
00492 if (!GAME_IsArmourUseableForTeam(od, teamDef))
00493 return qfalse;
00494
00495 if (list && list->IsItemUseable)
00496 return list->IsItemUseable(od);
00497
00498 return qtrue;
00499 }
00500
00512 void GAME_HandleResults (struct dbuffer *msg, int winner, int *numSpawned, int *numAlive, int numKilled[][MAX_TEAMS], int numStunned[][MAX_TEAMS])
00513 {
00514 const cgame_export_t *list = GAME_GetCurrentType();
00515 if (list)
00516 list->Results(msg, winner, numSpawned, numAlive, numKilled, numStunned);
00517 else
00518 CL_Drop();
00519 }
00520
00527 static void CL_NetSendItem (struct dbuffer *buf, item_t item, containerIndex_t container, int x, int y)
00528 {
00529 const int ammoIdx = item.m ? item.m->idx : NONE;
00530 const eventRegister_t *eventData = CL_GetEvent(EV_INV_TRANSFER);
00531 assert(item.t);
00532 Com_DPrintf(DEBUG_CLIENT, "CL_NetSendItem: Add item %s to container %i (t=%i:a=%i:m=%i) (x=%i:y=%i)\n",
00533 item.t->id, container, item.t->idx, item.a, ammoIdx, x, y);
00534 NET_WriteFormat(buf, eventData->formatString, item.t->idx, item.a, ammoIdx, container, x, y, item.rotated, item.amount);
00535 }
00536
00540 static void CL_NetSendInventory (struct dbuffer *buf, const inventory_t *i)
00541 {
00542 containerIndex_t container;
00543 int nr = 0;
00544 const invList_t *ic;
00545
00546 for (container = 0; container < csi.numIDs; container++) {
00547 for (ic = i->c[container]; ic; ic = ic->next)
00548 nr++;
00549 }
00550
00551 NET_WriteShort(buf, nr * INV_INVENTORY_BYTES);
00552 for (container = 0; container < csi.numIDs; container++) {
00553 for (ic = i->c[container]; ic; ic = ic->next)
00554 CL_NetSendItem(buf, ic->item, container, ic->x, ic->y);
00555 }
00556 }
00557
00563 static void GAME_NetSendCharacter (struct dbuffer * buf, const character_t *chr)
00564 {
00565 int j;
00566
00567 if (!chr)
00568 Com_Error(ERR_DROP, "No character given");
00569 if (chr->fieldSize != ACTOR_SIZE_2x2 && chr->fieldSize != ACTOR_SIZE_NORMAL)
00570 Com_Error(ERR_DROP, "Invalid character size given for character '%s': %i",
00571 chr->name, chr->fieldSize);
00572 if (chr->teamDef == NULL)
00573 Com_Error(ERR_DROP, "Character with no teamdef set (%s)", chr->name);
00574
00575 NET_WriteByte(buf, chr->fieldSize);
00576 NET_WriteShort(buf, chr->ucn);
00577 NET_WriteString(buf, chr->name);
00578
00579
00580 NET_WriteString(buf, chr->path);
00581 NET_WriteString(buf, chr->body);
00582 NET_WriteString(buf, chr->head);
00583 NET_WriteByte(buf, chr->skin);
00584
00585 NET_WriteShort(buf, chr->HP);
00586 NET_WriteShort(buf, chr->maxHP);
00587 NET_WriteByte(buf, chr->teamDef->idx);
00588 NET_WriteByte(buf, chr->gender);
00589 NET_WriteByte(buf, chr->STUN);
00590 NET_WriteByte(buf, chr->morale);
00591
00592 for (j = 0; j < SKILL_NUM_TYPES + 1; j++)
00593 NET_WriteLong(buf, chr->score.experience[j]);
00594 for (j = 0; j < SKILL_NUM_TYPES; j++)
00595 NET_WriteByte(buf, chr->score.skills[j]);
00596 for (j = 0; j < SKILL_NUM_TYPES + 1; j++)
00597 NET_WriteByte(buf, chr->score.initialSkills[j]);
00598 for (j = 0; j < KILLED_NUM_TYPES; j++)
00599 NET_WriteShort(buf, chr->score.kills[j]);
00600 for (j = 0; j < KILLED_NUM_TYPES; j++)
00601 NET_WriteShort(buf, chr->score.stuns[j]);
00602 NET_WriteShort(buf, chr->score.assignedMissions);
00603 }
00604
00611 static void GAME_SendCurrentTeamSpawningInfo (struct dbuffer * buf, chrList_t *team)
00612 {
00613 int i;
00614
00615
00616 NET_WriteByte(buf, clc_teaminfo);
00617 NET_WriteByte(buf, team->num);
00618
00619 Com_DPrintf(DEBUG_CLIENT, "GAME_SendCurrentTeamSpawningInfo: Upload information about %i soldiers to server\n", team->num);
00620 for (i = 0; i < team->num; i++) {
00621 character_t *chr = team->chr[i];
00622
00623 GAME_NetSendCharacter(buf, chr);
00624
00625 CL_NetSendInventory(buf, &chr->i);
00626 }
00627 }
00628
00629 const char* GAME_GetTeamDef (void)
00630 {
00631 const char *teamDefID = Cvar_GetString("cl_teamdef");
00632 if (teamDefID[0] == '\0')
00633 teamDefID = "phalanx";
00634 return teamDefID;
00635 }
00636
00637 static qboolean GAME_Spawn (void)
00638 {
00639 const size_t size = GAME_GetCharacterArraySize();
00640 int i;
00641
00642
00643
00644 if (GAME_GetCurrentType() == NULL || chrDisplayList.num == 0) {
00645 const char *teamDefID = GAME_GetTeamDef();
00646 const equipDef_t *ed = INV_GetEquipmentDefinitionByID("multiplayer_initial");
00647
00648
00649 INV_DestroyInventory(&cls.i);
00650 INV_InitInventory("client", &cls.i, &csi, &inventoryImport);
00651 GAME_GenerateTeam(teamDefID, ed, size);
00652 }
00653
00654 for (i = 0; i < size; i++)
00655 cl.chrList.chr[i] = chrDisplayList.chr[i];
00656 cl.chrList.num = chrDisplayList.num;
00657
00658 return qtrue;
00659 }
00660
00666 static void GAME_InitializeBattlescape (chrList_t *team)
00667 {
00668 int i;
00669 const cgame_export_t *list = GAME_GetCurrentType();
00670
00671 for (i = 0; i < lengthof(cl.teamList); i++) {
00672 UI_ExecuteConfunc("huddisable %i", i);
00673 }
00674
00675 if (list && list->InitializeBattlescape)
00676 list->InitializeBattlescape(team);
00677 }
00678
00682 void GAME_SpawnSoldiers (void)
00683 {
00684 const cgame_export_t *list = GAME_GetCurrentType();
00685 qboolean spawnStatus;
00686
00687
00688 if (list && list->Spawn)
00689 spawnStatus = list->Spawn();
00690 else
00691 spawnStatus = GAME_Spawn();
00692
00693 if (spawnStatus && cl.chrList.num > 0) {
00694 struct dbuffer *msg;
00695
00696
00697 msg = new_dbuffer();
00698 GAME_SendCurrentTeamSpawningInfo(msg, &cl.chrList);
00699 NET_WriteMsg(cls.netStream, msg);
00700
00701 msg = new_dbuffer();
00702 NET_WriteByte(msg, clc_stringcmd);
00703 NET_WriteString(msg, "spawn\n");
00704 NET_WriteMsg(cls.netStream, msg);
00705
00706 GAME_InitializeBattlescape(&cl.chrList);
00707 }
00708 }
00709
00710 int GAME_GetCurrentTeam (void)
00711 {
00712 const cgame_export_t *list = GAME_GetCurrentType();
00713
00714 if (list && list->GetTeam != NULL)
00715 return list->GetTeam();
00716
00717 return TEAM_DEFAULT;
00718 }
00719
00720 equipDef_t *GAME_GetEquipmentDefinition (void)
00721 {
00722 const cgame_export_t *list = GAME_GetCurrentType();
00723
00724 if (list && list->GetEquipmentDefinition != NULL)
00725 return list->GetEquipmentDefinition();
00726 return NULL;
00727 }
00728
00729 qboolean GAME_TeamIsKnown (const teamDef_t *teamDef)
00730 {
00731 const cgame_export_t *list = GAME_GetCurrentType();
00732
00733 if (!teamDef)
00734 return qfalse;
00735
00736 if (list && list->IsTeamKnown != NULL)
00737 return list->IsTeamKnown(teamDef);
00738 return qtrue;
00739 }
00740
00741 void GAME_CharacterCvars (const character_t *chr)
00742 {
00743 const cgame_export_t *list = GAME_GetCurrentType();
00744 if (list && list->UpdateCharacterValues != NULL)
00745 list->UpdateCharacterValues(chr);
00746 }
00747
00751 static void GAME_Abort_f (void)
00752 {
00753
00754 Cbuf_AddText(va("sv win %i\n", TEAM_ALIEN));
00755 }
00756
00757 void GAME_Drop (void)
00758 {
00759 const cgame_export_t *list = GAME_GetCurrentType();
00760
00761 if (list && list->Drop) {
00762 list->Drop();
00763 } else {
00764 SV_Shutdown("Drop", qfalse);
00765 GAME_SetMode(GAME_NONE);
00766 UI_InitStack("main", NULL, qfalse, qtrue);
00767 }
00768 }
00769
00773 static void GAME_Exit_f (void)
00774 {
00775 GAME_SetMode(GAME_NONE);
00776 }
00777
00781 void GAME_Frame (void)
00782 {
00783 const cgame_export_t *list;
00784
00785 list = GAME_GetCurrentType();
00786 if (list && list->RunFrame != NULL)
00787 list->RunFrame();
00788 }
00789
00796 const char* GAME_GetModelForItem (const objDef_t *od, uiModel_t** uiModel)
00797 {
00798 const cgame_export_t *list = GAME_GetCurrentType();
00799 if (list && list->GetModelForItem != NULL) {
00800 const char *model = list->GetModelForItem(od);
00801 if (model != NULL) {
00802 if (uiModel != NULL)
00803 *uiModel = UI_GetUIModel(model);
00804 return model;
00805 }
00806 }
00807
00808 if (uiModel != NULL)
00809 *uiModel = NULL;
00810 return od->model;
00811 }
00812
00813 mapDef_t* Com_GetMapDefinitionByID (const char *mapDefID)
00814 {
00815 int i;
00816
00817 assert(mapDefID);
00818
00819 for (i = 0; i < cls.numMDs; i++) {
00820 mapDef_t *md = Com_GetMapDefByIDX(i);
00821 if (!strcmp(md->id, mapDefID))
00822 return md;
00823 }
00824
00825 Com_DPrintf(DEBUG_CLIENT, "Com_GetMapDefinition: Could not find mapdef with id: '%s'\n", mapDefID);
00826 return NULL;
00827 }
00828
00829 mapDef_t* Com_GetMapDefByIDX (int index)
00830 {
00831 return &cls.mds[index];
00832 }
00833
00834 void GAME_InitStartup (void)
00835 {
00836 Cmd_AddCommand("game_setmode", GAME_SetMode_f, "Decides with game mode should be set - takes the menu as reference");
00837 Cmd_AddCommand("game_exit", GAME_Exit_f, "Abort the game and let the aliens/opponents win");
00838 Cmd_AddCommand("game_abort", GAME_Abort_f, "Abort the game and let the aliens/opponents win");
00839 Cmd_AddCommand("mn_getmaps", UI_GetMaps_f, "The initial map to show");
00840 Cmd_AddCommand("mn_nextmap", UI_ChangeMap_f, "Switch to the next valid map for the selected gametype");
00841 Cmd_AddCommand("mn_prevmap", UI_ChangeMap_f, "Switch to the previous valid map for the selected gametype");
00842 Cmd_AddCommand("mn_selectmap", UI_SelectMap_f, "Switch to the map given by the parameter - may be invalid for the current gametype");
00843 }