/* ==================== CM_AdjustAreaPortalState ==================== */ void CM_AdjustAreaPortalState(int area1, int area2, qboolean open) { if (area1 < 0 || area2 < 0) { return; } if (area1 >= cm.numAreas || area2 >= cm.numAreas) { Com_Error(ERR_DROP, "CM_ChangeAreaPortalState: bad area number"); } if (open) { cm.areaPortals[area1 * cm.numAreas + area2]++; cm.areaPortals[area2 * cm.numAreas + area1]++; } else if (cm.areaPortals[area2 * cm.numAreas + area1]) // Ridah, fixes loadgame issue { cm.areaPortals[area1 * cm.numAreas + area2]--; cm.areaPortals[area2 * cm.numAreas + area1]--; if (cm.areaPortals[area2 * cm.numAreas + area1] < 0) { Com_Error(ERR_DROP, "CM_AdjustAreaPortalState: negative reference count"); } } CM_FloodAreaConnections(); }
/* * CM_ReadPortalState * Reads the portal state from a savegame file * and recalculates the area connections */ void CM_ReadPortalState( cmodel_state_t *cms, int file ) { int i; FS_Read( &cms->map_areaportals, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ), file ); for( i = 0; i < cms->numareas * cms->numareas; i++ ) cms->map_areaportals[i] = LittleLong( cms->map_areaportals[i] ); CM_FloodAreaConnections( cms ); }
/* * CM_ReadAreaBits */ void CM_ReadAreaBits( cmodel_state_t *cms, qbyte *buffer ) { int i, j; int rowsize; memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); rowsize = CM_AreaRowSize( cms ); for( i = 0; i < cms->numareas; i++ ) { qbyte *row; row = buffer + i * rowsize; for( j = 0; j < cms->numareas; j++ ) { if( row[j>>3] & (1<<(j&7)) ) cms->map_areaportals[i * cms->numareas + j] = 1; } } CM_FloodAreaConnections( cms ); }
/* * CM_SetAreaPortalState */ void CM_SetAreaPortalState( cmodel_state_t *cms, int area1, int area2, qboolean open ) { int row1, row2; if( area1 == area2 ) return; if( area1 < 0 || area2 < 0 ) return; row1 = area1 * cms->numareas + area2; row2 = area2 * cms->numareas + area1; if( open ) { cms->map_areaportals[row1]++; cms->map_areaportals[row2]++; } else { if( cms->map_areaportals[row1] > 0 ) cms->map_areaportals[row1]--; if( cms->map_areaportals[row2] > 0 ) cms->map_areaportals[row2]--; } CM_FloodAreaConnections( cms ); }
/* * CM_LoadMap * Loads in the map and all submodels * * for spawning a server with no map at all, call like this: * CM_LoadMap( "", qfalse, &checksum ); // no real map */ cmodel_t *CM_LoadMap( cmodel_state_t *cms, const char *name, qboolean clientload, unsigned *checksum ) { int length; unsigned *buf; char *header; const modelFormatDescr_t *descr; bspFormatDesc_t *bspFormat = NULL; assert( cms ); assert( name && strlen( name ) < MAX_CONFIGSTRING_CHARS ); assert( checksum ); cms->map_clientload = clientload; if( !strcmp( cms->map_name, name ) && ( clientload || !Cvar_Value( "flushmap" ) ) ) { *checksum = cms->checksum; if( !clientload ) { memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); CM_FloodAreaConnections( cms ); } return cms->map_cmodels; // still have the right version } CM_Clear( cms ); if( !name || !name[0] ) { cms->numleafs = 1; cms->numcmodels = 2; *checksum = 0; return cms->map_cmodels; // cinematic servers won't have anything at all } // // load the file // length = FS_LoadFile( name, ( void ** )&buf, NULL, 0 ); if( !buf ) Com_Error( ERR_DROP, "Couldn't load %s", name ); cms->checksum = Com_MD5Digest32( ( const qbyte * )buf, length ); *checksum = cms->checksum; // call the apropriate loader descr = Q_FindFormatDescriptor( cm_supportedformats, ( const qbyte * )buf, (const bspFormatDesc_t **)&bspFormat ); if( !descr ) Com_Error( ERR_DROP, "CM_LoadMap: unknown fileid for %s", name ); if( !bspFormat ) Com_Error( ERR_DROP, "CM_LoadMap: %s: unknown bsp format" ); // copy header into temp variable to be saveed in a cvar header = Mem_TempMalloc( descr->headerLen + 1 ); memcpy( header, buf, descr->headerLen ); header[descr->headerLen] = '\0'; // store map format description in cvars Cvar_ForceSet( "cm_mapHeader", header ); Cvar_ForceSet( "cm_mapVersion", va( "%i", LittleLong( *((int *)((qbyte *)buf + descr->headerLen)) ) ) ); Mem_TempFree( header ); descr->loader( cms, NULL, buf, bspFormat ); CM_InitBoxHull( cms ); CM_InitOctagonHull( cms ); if( cms->numareas ) { cms->map_areas = Mem_Alloc( cms->mempool, cms->numareas * sizeof( *cms->map_areas ) ); cms->map_areaportals = Mem_Alloc( cms->mempool, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); memset( cms->map_areaportals, 0, cms->numareas * cms->numareas * sizeof( *cms->map_areaportals ) ); CM_FloodAreaConnections( cms ); } memset( cms->nullrow, 255, MAX_CM_LEAFS / 8 ); Q_strncpyz( cms->map_name, name, sizeof( cms->map_name ) ); return cms->map_cmodels; }