cl_game.c

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018 See the GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     /* pack equipment */
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         /* we dont need to go back to "main" stack if we are already on this stack */
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         /* inventory structure switched/initialized */
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     /* special purpose maps are not startable without the specific context */
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     /* skip random map char */
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     /* Don't allow armour for other teams */
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     /* model */
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     /* header */
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     /* If there is no active gametype we create a team with default values.
00643      * This is e.g. the case when someone starts a map with the map command */
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         /* inventory structure switched/initialized */
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     /* this callback is responsible to set up the cl.chrList */
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         /* send team info */
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     /* aborting means letting the aliens win */
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 }

Generated by  doxygen 1.6.2