예제 #1
0
void cEnchantments::ParseFromNBT(const cParsedNBT & a_NBT, int a_EnchListTagIdx)
{
	// Read the enchantments from the specified NBT list tag (ench or StoredEnchantments)

	// Verify that the tag is a list:
	if (a_NBT.GetType(a_EnchListTagIdx) != TAG_List)
	{
		LOGWARNING("%s: Invalid EnchListTag type: exp %d, got %d. Enchantments not parsed",
			__FUNCTION__, TAG_List, a_NBT.GetType(a_EnchListTagIdx)
		);
		ASSERT(!"Bad EnchListTag type");
		return;
	}
	
	// Verify that the list is of Compounds:
	if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound)
	{
		LOGWARNING("%s: Invalid NBT list children type: exp %d, got %d. Enchantments not parsed",
			__FUNCTION__, TAG_Compound, a_NBT.GetChildrenType(a_EnchListTagIdx)
		);
		ASSERT(!"Bad EnchListTag children type");
		return;
	}
	
	Clear();
	
	// Iterate over all the compound children, parse an enchantment from each:
	for (int tag = a_NBT.GetFirstChild(a_EnchListTagIdx); tag >= 0; tag = a_NBT.GetNextSibling(tag))
	{
		// tag is the compound inside the "ench" list tag
		ASSERT(a_NBT.GetType(tag) == TAG_Compound);
		
		// Search for the id and lvl tags' values:
		int id = -1, lvl = -1;
		for (int ch = a_NBT.GetFirstChild(tag); ch >= 0; ch = a_NBT.GetNextSibling(ch))
		{
			if (a_NBT.GetType(ch) != TAG_Short)
			{
				continue;
			}
			if (a_NBT.GetName(ch) == "id")
			{
				id = a_NBT.GetShort(ch);
			}
			else if (a_NBT.GetName(ch) == "lvl")
			{
				lvl = a_NBT.GetShort(ch);
			}
		}  // for ch - children of the compound tag
		
		if ((id == -1) || (lvl <= 0))
		{
			// Failed to parse either the id or the lvl, skip this compound
			continue;
		}
		
		// Store the enchantment:
		m_Enchantments[id] = lvl;
	}  // for tag - children of the ench list tag
}
예제 #2
0
bool cWSSAnvil::LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx)
{
    if ((a_TagIdx < 0) || (a_NBT.GetType(a_TagIdx) != TAG_List) || (a_NBT.GetChildrenType(a_TagIdx) != TAG_Double))
    {
        return false;
    }
    int idx = 0;
    for (int Tag = a_NBT.GetFirstChild(a_TagIdx); (Tag > 0) && (idx < a_NumDoubles); Tag = a_NBT.GetNextSibling(Tag), ++idx)
    {
        a_Doubles[idx] = a_NBT.GetDouble(Tag);
    }  // for Tag - PosTag[]
    return (idx == a_NumDoubles);  // Did we read enough doubles?
}
예제 #3
0
bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT)
{
    // The data arrays, in MCA-native y/z/x ordering (will be reordered for the final chunk data)
    cChunkDef::BlockTypes   BlockTypes;
    cChunkDef::BlockNibbles MetaData;
    cChunkDef::BlockNibbles BlockLight;
    cChunkDef::BlockNibbles SkyLight;

    memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes));
    memset(MetaData,   0,           sizeof(MetaData));
    memset(SkyLight,   0xff,        sizeof(SkyLight));  // By default, data not present in the NBT means air, which means full skylight
    memset(BlockLight, 0x00,        sizeof(BlockLight));

    // Load the blockdata, blocklight and skylight:
    int Level = a_NBT.FindChildByName(0, "Level");
    if (Level < 0)
    {
        return false;
    }
    int Sections = a_NBT.FindChildByName(Level, "Sections");
    if ((Sections < 0) || (a_NBT.GetType(Sections) != TAG_List) || (a_NBT.GetChildrenType(Sections) != TAG_Compound))
    {
        return false;
    }
    for (int Child = a_NBT.GetFirstChild(Sections); Child >= 0; Child = a_NBT.GetNextSibling(Child))
    {
        int y = 0;
        int SectionY = a_NBT.FindChildByName(Child, "Y");
        if ((SectionY < 0) || (a_NBT.GetType(SectionY) != TAG_Byte))
        {
            continue;
        }
        y = a_NBT.GetByte(SectionY);
        if ((y < 0) || (y > 15))
        {
            continue;
        }
        CopyNBTData(a_NBT, Child, "Blocks",     (char *)&(BlockTypes[y * 4096]), 4096);
        CopyNBTData(a_NBT, Child, "Data",       (char *)&(MetaData[y   * 2048]), 2048);
        CopyNBTData(a_NBT, Child, "SkyLight",   (char *)&(SkyLight[y   * 2048]), 2048);
        CopyNBTData(a_NBT, Child, "BlockLight", (char *)&(BlockLight[y * 2048]), 2048);
    }  // for itr - LevelSections[]

    // Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style:
    cChunkDef::BiomeMap BiomeMap;
    cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes"));
    if (Biomes == NULL)
    {
        // MCS-style biomes not available, load vanilla-style:
        Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes"));
    }

    // Load the entities from NBT:
    cEntityList      Entities;
    cBlockEntityList BlockEntities;
    LoadEntitiesFromNBT     (Entities,      a_NBT, a_NBT.FindChildByName(Level, "Entities"));
    LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities"), BlockTypes, MetaData);

    bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0);

    /*
    // Uncomment this block for really cool stuff :)
    // DEBUG magic: Invert the underground, so that we can see the MC generator in action :)
    bool ShouldInvert[cChunkDef::Width * cChunkDef::Width];
    memset(ShouldInvert, 0, sizeof(ShouldInvert));
    for (int y = cChunkDef::Height - 1; y >= 0; y--)
    {
    	for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
    	{
    		int Index = cChunkDef::MakeIndexNoCheck(x, y, z);
    		if (ShouldInvert[x + cChunkDef::Width * z])
    		{
    			BlockTypes[Index] = (BlockTypes[Index] == E_BLOCK_AIR) ? E_BLOCK_STONE : E_BLOCK_AIR;
    		}
    		else
    		{
    			switch (BlockTypes[Index])
    			{
    				case E_BLOCK_AIR:
    				case E_BLOCK_LEAVES:
    				{
    					// nothing needed
    					break;
    				}
    				default:
    				{
    					ShouldInvert[x + cChunkDef::Width * z] = true;
    				}
    			}
    			BlockTypes[Index] = E_BLOCK_AIR;
    		}
    	}
    }  // for y
    //*/

    m_World->SetChunkData(
        a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ,
        BlockTypes, MetaData,
        IsLightValid ? BlockLight : NULL,
        IsLightValid ? SkyLight : NULL,
        NULL, Biomes,
        Entities, BlockEntities,
        false
    );
    return true;
}