/** * @brief Sets the @c cls.state to @c ca_disconnected and informs the server * @sa CL_Drop * @note Goes from a connected state to disconnected state * Sends a disconnect message to the server * This is also called on @c Com_Error, so it shouldn't cause any errors */ void CL_Disconnect (void) { if (cls.state < ca_connecting) return; Com_Printf("Disconnecting...\n"); /* send a disconnect message to the server */ if (!Com_ServerState()) { dbuffer msg; NET_WriteByte(&msg, clc_stringcmd); NET_WriteString(&msg, NET_STATE_DISCONNECT "\n"); NET_WriteMsg(cls.netStream, msg); /* make sure, that this is send */ NET_Wait(0); } NET_StreamFinished(cls.netStream); cls.netStream = nullptr; CL_ClearState(); S_Stop(); R_ShutdownModels(false); R_FreeWorldImages(); CL_SetClientState(ca_disconnected); CL_ClearBattlescapeEvents(); GAME_EndBattlescape(); }
/** * @brief Specifies the model that will be used as the world * @param[in] tiles The tiles string can be only one map or a list of space * seperated map tiles for random assembly. In case of random assembly we also * need the @c pos string. Every tile needs an entry in the @c pos string, too. * @param[in] day Load the day lightmap * @param[in] pos In case of a random map assembly this is the string that holds * the world grid positions of the tiles. The positions are x, y and z values. * They are just written one after another for every tile in the @c tiles string * and every of the three components must exists for every tile. * @param[in] mapName The mapname that the get from the server (used to identify * the correct name for the materials in case of a random assembly). * @sa R_ModAddMapTile * @sa CM_LoadMap * @note This function is called for listen servers, too. This loads the bsp * struct for rendering it. The @c CM_LoadMap code only loads the collision * and pathfinding stuff. * @sa UI_BuildRadarImageList */ void R_ModBeginLoading (const char *tiles, qboolean day, const char *pos, const char *mapName) { char name[MAX_VAR]; char base[MAX_QPATH]; ipos3_t sh; int i; assert(mapName); R_FreeWorldImages(); /* clear any lights leftover in the active list from previous maps */ R_ClearActiveLights(); /* init */ R_BeginBuildingLightmaps(); r_numModelsInline = 0; r_numMapTiles = 0; /* load tiles */ while (tiles) { /* get tile name */ const char *token = Com_Parse(&tiles); if (!tiles) { /* finish */ R_ModEndLoading(mapName); return; } /* get base path */ if (token[0] == '-') { Q_strncpyz(base, token + 1, sizeof(base)); continue; } /* get tile name */ if (token[0] == '+') Com_sprintf(name, sizeof(name), "%s%s", base, token + 1); else Q_strncpyz(name, token, sizeof(name)); if (pos && pos[0]) { /* get grid position and add a tile */ for (i = 0; i < 3; i++) { token = Com_Parse(&pos); if (!pos) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid positions\n"); sh[i] = atoi(token); } if (sh[0] <= -(PATHFINDING_WIDTH / 2) || sh[0] >= PATHFINDING_WIDTH / 2) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid x position given: %i\n", sh[0]); if (sh[1] <= -(PATHFINDING_WIDTH / 2) || sh[1] >= PATHFINDING_WIDTH / 2) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid y position given: %i\n", sh[1]); if (sh[2] >= PATHFINDING_HEIGHT) Com_Error(ERR_DROP, "R_ModBeginLoading: invalid z position given: %i\n", sh[2]); R_ModAddMapTile(name, day, sh[0], sh[1], sh[2]); } else { /* load only a single tile, if no positions are specified */ R_ModAddMapTile(name, day, 0, 0, 0); R_ModEndLoading(mapName); return; } } Com_Error(ERR_DROP, "R_ModBeginLoading: invalid tile names\n"); }