Guest User

AnvilChunk.cpo

a guest
Apr 13th, 2012
46
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "Chunk.hpp"
  2. #include "AnvilChunk.hpp"
  3. #include "nbt.hpp"
  4.  
  5. Section::Section()
  6. {
  7.     y = -1;
  8.  
  9.     blocks = new BYTE[SECTIONBLOCKS];
  10.     blockData = new BYTE[SECTIONBLOCKS / 2];
  11.     skyLight = new BYTE[SECTIONBLOCKS / 2];
  12.     blockLight = new BYTE[SECTIONBLOCKS / 2];
  13.  
  14.     memset(blocks, 0, sizeof(BYTE) * SECTIONBLOCKS);
  15.     memset(blockData, 0, sizeof(BYTE) * SECTIONBLOCKS / 2);
  16.     memset(skyLight, 0, sizeof(BYTE) * SECTIONBLOCKS / 2);
  17.     memset(blockLight, 0, sizeof(BYTE) * SECTIONBLOCKS / 2);
  18. }
  19.  
  20. Section::~Section()
  21. {
  22.     delete [] blocks;
  23.     delete [] blockData;
  24.     delete [] skyLight;
  25.     delete [] blockLight;
  26. }
  27.  
  28. AnvilChunk::AnvilChunk() : Chunk()
  29. {
  30.     anvilHeightMap = 0;
  31.     sections = 0;
  32. }
  33.  
  34. AnvilChunk::~AnvilChunk()
  35. {
  36. }
  37.  
  38. void AnvilChunk::Allocate()
  39. {
  40.     if (!anvilHeightMap)
  41.         anvilHeightMap = new int[MAPX * MAPY];
  42.     if(!sections)
  43.         sections = new Section*[MAXSECTIONS];
  44.  
  45.     memset(anvilHeightMap, 0, sizeof(int) * MAPX * MAPY);
  46.     memset(sections, 0, sizeof(Section*) * MAXSECTIONS);
  47. }
  48.  
  49. void AnvilChunk::Deallocate()
  50. {
  51.     if (anvilHeightMap)
  52.     {
  53.         delete[] anvilHeightMap;
  54.         anvilHeightMap = 0;
  55.     }
  56.  
  57.     if(sections)
  58.     {
  59.         for(int i = 0; i < MAXSECTIONS; i++)
  60.         {
  61.             if(sections[i])
  62.             {
  63.                 delete sections[i];
  64.                 sections[i] = 0;
  65.             }
  66.         }
  67.  
  68.         delete[] sections;
  69.         sections = 0;
  70.     }
  71. }
  72.  
  73. bool AnvilChunk::ParseNBT(void * p)
  74. {
  75.     if (!p)
  76.         return false;
  77.     NBT_Reader * read = (NBT_Reader *)p;
  78.  
  79.     Section* section = 0;
  80.  
  81.     NBTTag tag = read->ReadData(); // Read first compound
  82.     while ((tag = read->ReadData()) != TAG_Unknown)
  83.     {
  84.         const NBTData * data = read->GetData();
  85.         if (!data)
  86.             continue;
  87.         if (!valid)
  88.         {
  89.             if (data->tag != TAG_Compound)
  90.                 continue;
  91.             if (!data->name)
  92.                 continue;
  93.             if (!StringCheck(data->name, "Level"))
  94.                 continue;
  95.             valid = true;
  96.         }
  97.         switch (data->tag)
  98.         {
  99.             case TAG_Int:
  100.                 if (StringCheck(data->name, "xPos"))
  101.                 {
  102.                     chunkX = data->i;
  103.                 }
  104.                 else if (StringCheck(data->name, "zPos"))
  105.                 {
  106.                     chunkY = data->i;
  107.                 }
  108.                 else if(StringCheck(data->name, "Y") && section != 0)
  109.                 {
  110.                     section->y = data->i;
  111.                 }
  112.                 break;
  113.             case TAG_Long:
  114.                 if (StringCheck(data->name, "LastUpdate"))
  115.                 {
  116.                     lastUpdate = data->l;
  117.                 }
  118.                 break;
  119.             case TAG_IntArray:
  120.                 if(StringCheck(data->name, "HeightMap"))
  121.                 {
  122.                     if (data->size < MAPX * MAPY * sizeof(int))
  123.                         continue;
  124.                     memcpy(anvilHeightMap, data->ias, MAPX * MAPY * sizeof(int));
  125.                 }
  126.                 break;
  127.             case TAG_List:
  128.                 if(StringCheck(data->name, "Sections"))
  129.                 {
  130.                     if(section != 0)
  131.                     {
  132.                         if(section->y >= 0 && section->y < MAXSECTIONS)
  133.                             this->sections[section->y] = section;
  134.                         else // shouldn't happen;
  135.                             delete section;
  136.                     }
  137.  
  138.                     section = new Section();
  139.                 }
  140.                 break;
  141.             case TAG_ByteArray:
  142.                 // Blocks
  143.                 if (StringCheck(data->name, "Blocks") && section != 0)
  144.                 {
  145.                     if (data->size < SECTIONBLOCKS)
  146.                         continue;
  147.                     // Get blocks
  148.                     if (pref.logging)
  149.                     {
  150.                         for (int i = 0; i < SECTIONBLOCKS; ++i)
  151.                         {
  152.                             ++amount.block[section->blocks[i] = data->bas[i]];
  153.                         }
  154.                     }
  155.                     else
  156.                     {
  157.                         memcpy(section->blocks, data->bas, SECTIONBLOCKS);
  158.                     }
  159.                     continue;
  160.                 }
  161.                 // Data
  162.                 if (StringCheck(data->name, "Data")  && section != 0)
  163.                 {
  164.                     if (data->size < SECTIONBLOCKS / 2)
  165.                         continue;
  166.  
  167.                     memcpy(section->blockData, data->bas, SECTIONBLOCKS / 2);
  168.                     continue;
  169.                 }
  170.                 // Skylight
  171.                 if (StringCheck(data->name, "SkyLight")  && section != 0)
  172.                 {
  173.                     if (data->size < SECTIONBLOCKS / 2)
  174.                         continue;
  175.                     memcpy(section->skyLight, data->bas, SECTIONBLOCKS / 2);
  176.                     continue;
  177.                 }
  178.                 // Blocklight
  179.                 if (StringCheck(data->name, "BlockLight")  && section != 0)
  180.                 {
  181.                     if (data->size < SECTIONBLOCKS / 2)
  182.                         continue;
  183.                     memcpy(section->blockLight, data->bas, SECTIONBLOCKS / 2);
  184.                     continue;
  185.                 }
  186.                 break;
  187.         }
  188.     }
  189.  
  190.     if(section != 0)
  191.     {
  192.         if(section->y >= 0 && section->y < MAXSECTIONS)
  193.             this->sections[section->y] = section;
  194.         else // shouldn't happen;
  195.             delete section;
  196.     }
  197.  
  198.     // Invalid
  199.     if (!valid)
  200.     {
  201.         amount.filesize = 0;
  202.         return false;
  203.     }
  204.    
  205.     // 10 000 000
  206.     if (abs(chunkX) > MAPCOORD || abs(chunkY) > MAPCOORD)
  207.     {
  208.         amount.filesize = 0;
  209.         valid = false;
  210.         return false;
  211.     }
  212.  
  213.     return true;
  214. }
  215.  
  216. int AnvilChunk::GetHeight(int x, int y, int Z, int minZ)
  217. {
  218.     if (x < 0 || x >= MAPX) return 0;
  219.     if (y < 0 || y >= MAPY) return 0;
  220.     if ((pref.flags & CHUNKP_NOHEIGHTMAP) == 0 && Z > (anvilHeightMap[y * MAPY + x]))
  221.         Z = (anvilHeightMap[y * MAPY + x]);
  222.     for (int z = Z; z >= minZ; --z)
  223.         if (ReadBlock(x, y, z) != AIR || z <= minZ)
  224.             return z;
  225.     return minZ;
  226. }
  227.  
  228. Color AnvilChunk::GetColor(int x, int y, int z, bool side)
  229. {
  230.     unsigned short n = ReadBlock(x, y, z);
  231.     switch (n)
  232.     {
  233.         case WOOL:
  234.             n = WOOLCOLOR + ReadBlockData(x, y, z);
  235.             break;
  236.         case LOG:
  237.             n = LOGCOLOR + ReadBlockData(x, y, z) % 3;
  238.             break;
  239.         case LEAVES:
  240.             n = LEAFCOLOR + ReadBlockData(x, y, z) % 3;
  241.             break;
  242.         case SLAB_STONE:
  243.             n = SLABCOLOR + ReadBlockData(x, y, z) % 4;
  244.             break;
  245.         case GRASS:
  246.             if (side)
  247.                 n = DIRT;
  248.             break;
  249.     }
  250.     return DataValues::GetColor(n);
  251. }
  252.  
  253. BYTE AnvilChunk::ReadBlock(int x, int z, int y)
  254. {
  255.     int section = y / 16;
  256.     if(y < 0 || y > MAXSECTIONS || sections == 0 || sections[y] == 0)
  257.         return 0;
  258.  
  259.     if(x < 0 || x > MAPX)
  260.         return 0;
  261.     if(z < 0 || z > MAPY)
  262.         return 0;
  263.  
  264.     return sections[section]->blocks[((y % 16) * 16 + z) * 16 + x];
  265. }
  266.  
  267. BYTE AnvilChunk::ReadBlockData(int x, int z, int y)
  268. {
  269.     int section = y / 16;
  270.     if(y < 0 || y > MAXSECTIONS || sections == 0 || sections[y] == 0)
  271.         return 0;
  272.  
  273.     if(x < 0 || x > MAPX)
  274.         return 0;
  275.     if(z < 0 || z > MAPY)
  276.         return 0;
  277.  
  278.     int i = (((y % 16) * 16 + z) * 16 + x) / 2;
  279.     if(i % 2 == 0)
  280.         return (sections[section]->blockData[i] >> 4) & 0x0F;
  281.     else
  282.         return sections[section]->blockData[i] & 0x0F;
  283. }
  284.  
  285. BYTE AnvilChunk::ReadBlockLight(int x, int z, int y)
  286. {
  287.     int section = y / 16;
  288.     if(y < 0 || y > MAXSECTIONS || sections == 0 || sections[y] == 0)
  289.         return 0;
  290.  
  291.     if(x < 0 || x > MAPX)
  292.         return 0;
  293.     if(z < 0 || z > MAPY)
  294.         return 0;
  295.  
  296.     int i = (((y % 16) * 16 + z) * 16 + x) / 2;
  297.     if(i % 2 == 0)
  298.         return (sections[section]->blockLight[i] >> 4) & 0x0F;
  299.     else
  300.         return sections[section]->blockLight[i] & 0x0F;
  301. }
  302.  
  303. void AnvilChunk::PassExclude(int & x, int & y, int & z, Color & color)
  304. {
  305.     if (z < 0)
  306.         return;
  307.     BYTE n = 0;
  308.     do
  309.     {
  310.         n = ReadBlock(x, y, z);
  311.     }
  312.     while (!pref.block[n] && --z >= 0);
  313.     color = (z < 0) ? 0 : GetColor(x, y, z);
  314. }
  315.  
  316. #include <math.h>
  317.  
  318. void AnvilChunk::PassNight(int & x, int & y, int & z, Color & color)
  319. {
  320.     if (z < 0)
  321.         return;
  322.     BYTE bLight = ReadBlockLight(x, y, z);
  323.     float light = pow(0.9f, 15 - bLight);
  324.     color.Interpolate(Color(0, 0, 0), 1 - light);
  325. }
RAW Paste Data