예제 #1
0
bool CGrayInstall::ReadMulData(CGFile &file, const CUOIndexRec &Index, void * pData)
{
	if ( file.Seek(Index.GetFileOffset(), SEEK_SET) != Index.GetFileOffset() )
		return false;

	DWORD dwLength = Index.GetBlockLength();
	if ( file.Read(pData, dwLength) != dwLength )
		return false;

	return true;
}
예제 #2
0
CSphereTerrainInfo::CSphereTerrainInfo( TERRAIN_TYPE id )
{
    ASSERT( id < TERRAIN_QTY );

    VERFILE_TYPE filedata;
    size_t offset;
    CUOIndexRec Index;
    VERFILE_FORMAT format;
    if ( g_VerData.FindVerDataBlock( VERFILE_TILEDATA, id/UOTILE_BLOCK_QTY, Index ))
    {
        filedata = VERFILE_VERDATA;
        format = VERFORMAT_ORIGINAL;
        offset = Index.GetFileOffset() + 4 + (sizeof(CUOTerrainTypeRec)*(id%UOTILE_BLOCK_QTY));
        ASSERT( Index.GetBlockLength() >= sizeof( CUOTerrainTypeRec ));
    }
    else
    {
        filedata = VERFILE_TILEDATA;
        format = g_Install.GetMulFormat(filedata);

        switch (format)
        {
            case VERFORMAT_HIGHSEAS: // high seas format (CUOTerrainTypeRec_HS)
                offset = (id == 0? 0 : 4) + (( id / UOTILE_BLOCK_QTY ) * 4 ) + ( id * sizeof( CUOTerrainTypeRec_HS ));
                break;

            case VERFORMAT_ORIGINAL: // original format (CUOTerrainTypeRec)
            default:
                offset = 4 + (( id / UOTILE_BLOCK_QTY ) * 4 ) + ( id * sizeof( CUOTerrainTypeRec ));
                break;
        }
    }

    if ( g_Install.m_File[filedata].Seek( offset, SEEK_SET ) != offset )
    {
        throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Seek");
    }

    switch (format)
    {
        case VERFORMAT_HIGHSEAS: // high seas format (CUOTerrainTypeRec_HS)
            if ( g_Install.m_File[filedata].Read(static_cast <CUOTerrainTypeRec_HS *>(this), sizeof(CUOTerrainTypeRec_HS)) <= 0 )
                throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Read");
            break;

        case VERFORMAT_ORIGINAL: // old format (CUOTerrainTypeRec)
        default:
        {
            CUOTerrainTypeRec record;
            if ( g_Install.m_File[filedata].Read(static_cast <CUOTerrainTypeRec *>(&record), sizeof(CUOTerrainTypeRec)) <= 0 )
                throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Read");

            m_flags = record.m_flags;
            m_unknown = 0;
            m_index = record.m_index;
            strcpylen(m_name, record.m_name, CountOf(m_name));
            break;
        }
    }
}
예제 #3
0
void CGrayMapBlock::Load( int bx, int by )
{
	ADDTOCALLSTACK("CGrayMapBlock::Load");
	// Read in all the statics data for this block.
	m_CacheTime.InitCacheTime();		// This is invalid !

	ASSERT( bx < (g_MapList.GetX(m_map)/UO_BLOCK_SIZE) );
	ASSERT( by < (g_MapList.GetY(m_map)/UO_BLOCK_SIZE) );

	if (( m_map < 0 ) || ( m_map >= 255 ))
	{
		g_Log.EventError("Unsupported map #%d specified. Auto-fixing that to 0.\n", m_map);
		m_map = 0;
	}

	unsigned long ulBlockIndex = (bx*(g_MapList.GetY(m_map)/UO_BLOCK_SIZE) + by);

	if ( !g_MapList.m_maps[m_map] )
	{
		memset( &m_Terrain, 0, sizeof( m_Terrain ));
		throw CGrayError(LOGL_CRIT, 0, "CGrayMapBlock: Map is not supported since MUL files for it not available.");
	}

	bool bPatchedTerrain = false, bPatchedStatics = false;

	if ( g_Cfg.m_fUseMapDiffs && g_MapList.m_pMapDiffCollection )
	{
		// Check to see if the terrain or statics in this block is patched
		CMapDiffBlock * pDiffBlock = g_MapList.m_pMapDiffCollection->GetAtBlock( ulBlockIndex, g_MapList.m_mapid[m_map] );
		if ( pDiffBlock )
		{
			if ( pDiffBlock->m_pTerrainBlock )
			{
				memcpy( &m_Terrain, pDiffBlock->m_pTerrainBlock, sizeof(CUOMapBlock) );
				bPatchedTerrain = true;
			}

			if ( pDiffBlock->m_iStaticsCount >= 0 )
			{
				m_Statics.LoadStatics( pDiffBlock->m_iStaticsCount, pDiffBlock->m_pStaticsBlock );
				bPatchedStatics = true;
			}
		}
	}

	// Only load terrain if it wasn't patched
	if ( ! bPatchedTerrain )
	{
		int mapNumber = g_MapList.m_mapnum[m_map];
		CGFile * pFile = &(g_Install.m_Maps[mapNumber]);
		ASSERT(pFile != NULL);
		ASSERT(pFile->IsFileOpen());
		
		// determine the location in the file where the data needs to be read from
		CUOIndexRec index;
		index.SetupIndex( ulBlockIndex * sizeof(CUOMapBlock), sizeof(CUOMapBlock));

		unsigned long fileOffset = index.GetFileOffset();
		if (g_Install.m_IsMapUopFormat[mapNumber])
		{
			for ( int i = 0; i < 256; i++ )
			{
				MapAddress pMapAddress = g_Install.m_UopMapAddress[mapNumber][i];
				if (( ulBlockIndex <= pMapAddress.dwLastBlock ) && ( ulBlockIndex >= pMapAddress.dwFirstBlock ))
				{
					fileOffset = static_cast<unsigned long>(pMapAddress.qwAdress + ((ulBlockIndex - pMapAddress.dwFirstBlock)*196));
					break;
				}
			}


		/*	// when the map is in a UOP container we need to modify the file offset to account for the block header
			// data. the uop file format splits the map data into smaller 'blocks', each of which has its on header (as
			// well as an overall file header)
			//
			// we must therefore determine which block of data contains the map information we need, and then add
			// the extra number of bytes to our file offset
			const unsigned long fileHeaderLength = 40; // length of overall file header
			const unsigned long blockHeaderLength = 12; // length of the block header
			const unsigned long firstDataEntryOffset = 3412; // offset of first actual data byte within a block
			const unsigned long firstBlockDataEntryOffset = fileHeaderLength + blockHeaderLength + firstDataEntryOffset; // offset of first actual data byte for the first entry in the file
			const unsigned long mapBlockLength = 802816; // maximum size of a block

			// note: to avoid writing code that parse the UOP format properly we are calculating a new offset based on the
			// sizes of the blocks as-of client 7.0.24.0. the nature of the UOP format allows the block lengths to differ
			// and for the data to be compressed, so we should watch out for this in the future (and if this happens we'll
			// have to handle UOP data properly)

			unsigned long block = fileOffset / mapBlockLength;
			fileOffset += firstBlockDataEntryOffset + ((firstDataEntryOffset) * (block / 100)) + (blockHeaderLength * block);*/
		}

		// seek to position in file
		if ( pFile->Seek( fileOffset, SEEK_SET ) != fileOffset )
		{
			memset( &m_Terrain, 0, sizeof(m_Terrain));
			throw CGrayError(LOGL_CRIT, CGFile::GetLastError(), "CGrayMapBlock: Seek Ver");
		}

		// read terrain data
		if ( pFile->Read( &m_Terrain, sizeof(CUOMapBlock)) <= 0 )
		{
			memset( &m_Terrain, 0, sizeof( m_Terrain ));
			throw CGrayError(LOGL_CRIT, CGFile::GetLastError(), "CGrayMapBlock: Read");
		}
	}

	// Only load statics if they weren't patched
	if ( ! bPatchedStatics )
	{
		m_Statics.LoadStatics( ulBlockIndex, m_map );
	}

	m_CacheTime.HitCacheTime();		// validate.
}