Beispiel #1
0
 ///<summary>Reads all Entities and TileEntities from the given chunk NBT</summary>
 public void ReadEntitiesAndTileEntitiesFromNBT(CompoundContainer chunkLevelCompound)
 {
     if (chunkLevelCompound.Contains("Entities"))
     {
         var entList = chunkLevelCompound.GetAsList("Entities");
         if (entList != null && entList.contentsType == NBTTag.TAG_Compound)
         {
             for (int i = 0; i < entList.Length; i++)
             {
                 entities.Add(new Entity(entList.Get <CompoundContainer>(i)));
             }
         }
     }
     if (chunkLevelCompound.Contains("TileEntities"))
     {
         var tileEntList = chunkLevelCompound.GetAsList("TileEntities");
         if (tileEntList != null && tileEntList.contentsType == NBTTag.TAG_Compound)
         {
             for (int i = 0; i < tileEntList.Length; i++)
             {
                 var te = new TileEntity(tileEntList.Get <CompoundContainer>(i));
                 tileEntities.Add(new BlockCoord(te.BlockPosX, te.BlockPosY, te.BlockPosZ), te);
             }
         }
     }
 }
Beispiel #2
0
 public TileEntity(CompoundContainer compound)
 {
     NBTCompound = compound;
     BlockPosX   = compound.Get <int>("x");
     BlockPosY   = compound.Get <int>("y");
     BlockPosZ   = compound.Get <int>("z");
 }
Beispiel #3
0
 static void LoadBlocksMCRFormat(ChunkData chunk, CompoundContainer nbtCompound)
 {
     byte[] blocks = nbtCompound.Get <byte[]>("Blocks");
     byte[] add;             //TODO: include "Add" bits in ID (from modded worlds)
     if (nbtCompound.Contains("Add"))
     {
         add = nbtCompound.Get <byte[]>("Add");
     }
     byte[] meta = nbtCompound.Get <byte[]>("Data");            //TODO: also include meta in block lookup
     for (int x = 0; x < 16; x++)
     {
         for (int z = 0; z < 16; z++)
         {
             for (int y = 0; y < 128; y++)
             {
                 byte id    = blocks[(x * 16 + z) * 128 + y];
                 var  block = BlockList.FindByNumeric(new NumericID(id, 0));
                 if (block != null)
                 {
                     chunk.SetBlockAt(x, y, z, new BlockState(block));
                 }
             }
         }
     }
 }
Beispiel #4
0
        public Entity(CompoundContainer compound)
        {
            NBTCompound = compound;
            ListContainer pos = compound.GetAsList("Pos");

            BlockPosX = (int)Math.Floor(pos.Get <double>(0));
            BlockPosY = (int)Math.Floor(pos.Get <double>(1));
            BlockPosZ = (int)Math.Floor(pos.Get <double>(2));
        }
Beispiel #5
0
 public bool Compare(BlockState other, bool compareProperties = true)
 {
     if (compareProperties)
     {
         if (!CompoundContainer.AreEqual(properties, other.properties))
         {
             return(false);
         }
     }
     return(block == other.block);
 }
Beispiel #6
0
        ///<summary>Generates the full NBT data of a chunk</summary>
        public void WriteToNBT(CompoundContainer level, Version version)
        {
            ListContainer sectionsList = level.GetAsList("Sections");

            foreach (sbyte secY in sections.Keys)
            {
                var section = sections[secY];
                //if(IsSectionEmpty(secY)) continue;
                var comp = GetSectionCompound(sectionsList, secY);
                if (comp == null)
                {
                    bool use_1_16_format = version >= Version.Release_1(16);
                    comp = section.CreateCompound(secY, use_1_16_format);
                }
                sectionsList.Add(null, comp);
            }
            //Make the biomes
            var        finalBiomeArray = MakeBiomeArray();
            List <int> biomes          = new List <int>();

            for (int y = 0; y < 64; y++)
            {
                for (int z = 0; z < 4; z++)
                {
                    for (int x = 0; x < 4; x++)
                    {
                        var b = finalBiomeArray != null ? finalBiomeArray[x, y, z] : 1;
                        biomes.Add(b);
                    }
                }
            }
            level.Add("Biomes", biomes.ToArray());

            //Add TileEntities
            var teList = level.GetAsList("TileEntities");

            foreach (var te in tileEntities)
            {
                teList.Add(te.Value.NBTCompound);
            }

            //Add Entities
            var entitiyList = level.GetAsList("Entities");

            foreach (var e in entities)
            {
                entitiyList.Add(e.NBTCompound);
            }

            //Add "post processing" positions (i.e. block positions that need an update)
            var ppList = level.GetAsList("PostProcessing");

            foreach (var t in blockTicks)
            {
                //TODO: section index and coordinate packing is being guessed, trying to find out how to do it.
                int   listIndex = t.y / 16;
                var   x         = t.x % 16;
                var   y         = t.y % 16;
                var   z         = t.z % 16;
                var   list      = ppList.Get <ListContainer>(listIndex);
                short packed    = (short)((z << 8) + (y << 4) + x);
                list.Add(packed);
            }

            //Add liquid / tile ticks

            /*
             * var tileTickList = level.GetAsList("TileTicks");
             * var liquidTickList = level.GetAsList("LiquidTicks");
             * foreach (var t in blockTicks)
             * {
             *      var block = GetBlockAt(t.x, t.y, t.z).block;
             *      bool isLiquid = block.IsLiquid;
             *      var comp = new CompoundContainer();
             *      string i;
             *      if(isLiquid)
             *      {
             *              //i = block.IsWater ? "minecraft:flowing_water" : "minecraft:flowing_lava";
             *              //flowing_water and flowing_lava only applies to non-source blocks.
             *              i = block.ID;
             *      }
             *      else
             *      {
             *              i = block.ID;
             *      }
             *      var worldCoord = coords.BlockCoord + t;
             *      comp.Add("i", i);
             *      comp.Add("t", 20);
             *      comp.Add("p", 0);
             *      comp.Add("x", worldCoord.x);
             *      comp.Add("y", worldCoord.y);
             *      comp.Add("z", worldCoord.z);
             *      if(isLiquid)
             *      {
             *              liquidTickList.Add(comp);
             *      }
             *      else
             *      {
             *              tileTickList.Add(comp);
             *      }
             * }*/
        }
Beispiel #7
0
        private CompoundContainer CreatePlayerCompound(int posX, int posY, int posZ, bool creativeModeWithCheats)
        {
            var player = new CompoundContainer();

            var abilities = player.AddCompound("abilities");

            abilities.Add <byte>("flying", 0);
            abilities.Add <float>("flySpeed", 0.05f);
            abilities.Add <byte>("instabuild", (byte)(creativeModeWithCheats ? 1 : 0));
            abilities.Add <byte>("invulnerable", (byte)(creativeModeWithCheats ? 1 : 0));
            abilities.Add <byte>("mayBuild", 0);
            abilities.Add <byte>("mayfly", (byte)(creativeModeWithCheats ? 1 : 0));
            abilities.Add <float>("walkSpeed", 0.1f);

            player.AddCompound("Brain").AddCompound("memories");
            player.AddCompound("recipeBook");
            player.Add("Attributes", new ListContainer(NBTTag.TAG_Compound));
            player.Add("EnderItems", new ListContainer(NBTTag.TAG_Compound));
            player.Add("Inventory", new ListContainer(NBTTag.TAG_Compound));
            player.AddList("Motion", NBTTag.TAG_Double).AddRange(0d, 0d, 0d);

            var pos = player.AddList("Pos", NBTTag.TAG_Double);

            pos.Add <double>(posX);
            pos.Add <double>(posY);
            pos.Add <double>(posZ);
            player.AddList("Rotation", NBTTag.TAG_Float).AddRange(0f, 0f);

            player.Add("AbsorptionAmount", 0f);
            player.Add <short>("Air", 300);
            player.Add <short>("DeathTime", 0);
            player.Add <string>("Dimension", "minecraft:overworld");
            player.Add <float>("FallDistance", 0);
            player.Add <byte>("FallFlying", 0);
            player.Add <short>("Fire", -20);
            player.Add <float>("foodExhaustionLevel", 0);
            player.Add <int>("foodLevel", 20);
            player.Add <float>("foodSaturationLevel", 5);
            player.Add <int>("foodTickTimer", 0);
            player.Add <float>("Health", 20);
            player.Add <int>("HurtByTimestamp", 0);
            player.Add <short>("HurtTime", 0);
            player.Add <byte>("Invulnerable", 0);
            player.Add <byte>("OnGround", 0);
            player.Add <int>("playerGameType", creativeModeWithCheats ? 1 : 0);
            player.Add <int>("Score", 0);
            player.Add <byte>("seenCredits", 0);
            player.Add <int>("SelectedItemSlot", 0);
            player.Add <short>("SleepTimer", 0);
            player.Add <int>("XpLevel", 0);
            player.Add <float>("XpP", 0);
            player.Add <int>("XpSeed", 0);
            player.Add <int>("XpTotal", 0);

            player.Add <int>("DataVersion", 2504);

            //UUID?
            player.Add <int[]>("UUID", new int[] { 0, 0, 0, 0 });

            return(player);
        }
Beispiel #8
0
        public CompoundContainer CreateCompound(sbyte secY, bool use_1_16_Format)
        {
            var comp = new CompoundContainer();

            comp.Add("Y", (byte)secY);
            ListContainer paletteContainer = new ListContainer(NBTTag.TAG_Compound);

            foreach (var block in palette)
            {
                CompoundContainer paletteBlock = new CompoundContainer();
                paletteBlock.Add("Name", block.block.ID);
                if (block.properties != null)
                {
                    CompoundContainer properties = new CompoundContainer();
                    foreach (var prop in block.properties.cont.Keys)
                    {
                        var value = block.properties.Get(prop);
                        if (value is bool b)
                        {
                            value = b.ToString().ToLower();
                        }
                        properties.Add(prop, value.ToString());
                    }
                    paletteBlock.Add("Properties", properties);
                }
                paletteContainer.Add("", paletteBlock);
            }
            comp.Add("Palette", paletteContainer);
            //Encode block indices to bits and longs, oof
            int indexLength = Math.Max(4, (int)Math.Log(palette.Count - 1, 2.0) + 1);
            //How many block indices fit inside a long?
            int indicesPerLong = (int)Math.Floor(64f / indexLength);

            long[]   longs       = new long[(int)Math.Ceiling(4096f / indicesPerLong)];
            string[] longsBinary = new string[longs.Length];
            for (int j = 0; j < longsBinary.Length; j++)
            {
                longsBinary[j] = "";
            }
            int i = 0;

            for (int y = 0; y < 16; y++)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        string bin = NumToBits(blocks[x, y, z], indexLength);
                        bin = Converter.ReverseString(bin);
                        if (use_1_16_Format)
                        {
                            if (longsBinary[i].Length + indexLength > 64)
                            {
                                //The full value doesn't fit, start on the next long
                                i++;
                                longsBinary[i] += bin;
                            }
                            else
                            {
                                for (int j = 0; j < indexLength; j++)
                                {
                                    if (longsBinary[i].Length >= 64)
                                    {
                                        i++;
                                    }
                                    longsBinary[i] += bin[j];
                                }
                            }
                        }
                    }
                }
            }
            for (int j = 0; j < longs.Length; j++)
            {
                string s = longsBinary[j];
                s        = s.PadRight(64, '0');
                s        = Converter.ReverseString(s);
                longs[j] = Convert.ToInt64(s, 2);
            }
            comp.Add("BlockStates", longs);
            return(comp);
        }
Beispiel #9
0
        static void LoadBlocksAnvilFormat(ChunkData chunk, CompoundContainer nbtCompound, Version?version)
        {
            var sectionsList = nbtCompound.GetAsList("Sections");

            foreach (var o in sectionsList.cont)
            {
                var section = new ChunkSection(null);

                var compound = (CompoundContainer)o;
                if (!compound.Contains("Y") || !compound.Contains("Palette"))
                {
                    continue;
                }
                sbyte secY;
                unchecked
                {
                    secY = Convert.ToSByte(compound.Get("Y"));
                }
                section.palette.Clear();
                foreach (var cont in compound.GetAsList("Palette").cont)
                {
                    CompoundContainer block = (CompoundContainer)cont;
                    var proto = BlockList.Find((string)block.Get("Name"));
                    var bs    = new BlockState(proto);
                    if (block.Contains("Properties"))
                    {
                        bs.properties = block.GetAsCompound("Properties");
                    }
                    section.palette.Add(bs);
                }

                //1.15 uses the full range of bits where 1.16 doesn't use the last bits if they can't contain a block index
                int    indexLength = Math.Max(4, (int)Math.Log(section.palette.Count - 1, 2.0) + 1);
                long[] longs       = (long[])compound.Get("BlockStates");
                string bits        = "";
                for (int i = 0; i < longs.Length; i++)
                {
                    string newBits = "";
                    byte[] bytes   = BitConverter.GetBytes(longs[i]);
                    for (int j = 0; j < 8; j++)
                    {
                        newBits += Converter.ByteToBinary(bytes[j], true);
                    }
                    if (version == null || version.Value < Version.Release_1(16, 0))
                    {
                        bits += newBits;
                    }
                    else
                    {
                        bits += newBits.Substring(0, (int)Math.Floor(newBits.Length / (double)indexLength) * indexLength);
                    }
                }
                //TODO: needs testing
                for (int y = 0; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int x = 0; x < 16; x++)
                        {
                            section.blocks[x, y, z] = Converter.BitsToValue(bits, y * 256 + z * 16 + x, indexLength);
                        }
                    }
                }
                chunk.sections.Add(secY, section);
            }
        }