Ejemplo n.º 1
0
        private void FillWithLeaves(AlphaBlockCollection tree, int y)
        {
            int  distanceFromTop = tree.YDim - y;
            uint size            = 1u + (uint)distanceFromTop * 2u;

            tree.Fill(new BoundingBox(new Position((tree.XDim - (int)size) / 2, y, (tree.ZDim - (int)size) / 2), size, 1u, size), _leafId);
        }
Ejemplo n.º 2
0
        private int GetStartRenderYCave(AlphaBlockCollection Blocks, int X, int Z)
        {
            int Y = 255;

            if (Y > 255)
            {
                Y = 255;
            }

            while (Y >= 0 && _ColourPalette.FastPalette[0][Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)].A == 0)
            {
                Y--;
            }
            while (Y >= 0 && _ColourPalette.FastPalette[0][Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)].A != 0)
            {
                Y--;
            }
            while (Y >= 0 && _ColourPalette.FastPalette[0][Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)].A == 0)
            {
                Y--;
            }

            if (Y == 0)
            {
                return(_ColourPalette.DepthOpacities[Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)] == 0 ? -1 : 0);
            }
            return(Y);
        }
Ejemplo n.º 3
0
        private static void loadLayers()
        {
            AlphaBlockCollection blk = null;
            int x, z, cx, cz, mx, mz, id;

            if (needSave)
            {
                saveLayers();
            }

            reg = ((AnvilRegion)
                   lvl.GetRegionManager().GetRegion(region[0], region[1]));
            mnuStatus.Text = "Loading Block Data";

            needSave = false;
            y        = mnuHeight.SelectedIndex;

            for (cx = 0; cx < cxd; cx++)
            {
                for (cz = 0; cz < czd; cz++)
                {
                    if (reg.ChunkExists(cx, cz))
                    {
                        blk = reg.GetChunkRef(cx, cz).Blocks;
                    }

                    else
                    {
                        blk = null;
                    }

                    for (x = 0; x < xd; x++)
                    {
                        for (z = 0; z < zd; z++)
                        {
                            mx = cx * xd + x;
                            mz = cz * zd + z;
                            if (blk != null)
                            {
                                id = Tools.Tool.Map[mx][mz].ID = blk.GetID(x, y, z);
                                Tools.Tool.Map[mx][mz].Data = blk.GetData(x, y, z);
                                Tools.Tool.Map[mx][mz].ent  = blk.GetTileEntity(x, y, z);
                            }

                            else
                            {
                                id = Tools.Tool.Map[mx][mz].ID = -1;
                            }
                            Tools.Tool.Clr[mx][mz] = BlockColor.getBlockColor(id);
                        }
                    }

                    mnuLoad.Increment(xd * zd);
                }
            }
            mnuLoad.Increment(-hgt * wid);

            loadImage();
        }
Ejemplo n.º 4
0
 // *** If there is no tile entity, Substrate can throw an exception.  This utility function just handles that gracefully
 /// <summary>
 ///     Get the tile entity for a block, without throwing an exception if none exists
 /// </summary>
 /// <remarks>
 ///     Substrate's library throws an exception if you try to retrieve a tile entity that does not exist.  This utility function handles this, swallowing the error and merely returning null instead of crashing.
 /// </remarks>
 /// <param name="Blocks">
 ///     The block collection to get the tile entity from
 /// </param>
 /// <param name="X">
 ///     The X position of the block to get the tile entity for
 /// </param>
 /// <param name="Y">
 ///     The Y position of the block to get the tile entity for
 /// </param>
 /// <param name="Z">
 ///     The Z position of the block to get the tile entity for
 /// </param>
 /// <returns>
 ///     The tile entity for the block, or <see langword="null"/>
 /// </returns>
 /// <seealso cref=" Substrate.TileEntity"/>
 public static TileEntity SafeGetTileEntity(this AlphaBlockCollection Blocks, int X, int Y, int Z)
 {
     try
     {
         return Blocks.GetTileEntity(X, Y, Z);
     }
     catch
     {
         return null;
     }
 }
Ejemplo n.º 5
0
        // *** Render start determiners
        private int GetStartRenderYNormal(AlphaBlockCollection Blocks, int X, int Z)
        {
            int Y = Blocks.GetHeight(X, Z);

            if (Y > 255)
            {
                Y = 255;
            }
            if (Y == 0)
            {
                return(_ColourPalette.DepthOpacities[Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)] == 0 ? -1 : 0);
            }
            return(Y);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Create an empty, exportable schematic of given dimensions.
        /// </summary>
        /// <param name="xdim">The length of the X-dimension in blocks.</param>
        /// <param name="ydim">The length of the Y-dimension in blocks.</param>
        /// <param name="zdim">The length of the Z-dimension in blocks.</param>
        public Schematic(int xdim, int ydim, int zdim)
        {
            _blocks = new XZYByteArray(xdim, ydim, zdim);
            _data = new XZYNibbleArray(xdim, ydim, zdim);
            _blockLight = new XZYNibbleArray(xdim, ydim, zdim);
            _skyLight = new XZYNibbleArray(xdim, ydim, zdim);
            _heightMap = new ZXByteArray(xdim, zdim);

            _entities = new TagNodeList(TagType.TAG_COMPOUND);
            _tileEntities = new TagNodeList(TagType.TAG_COMPOUND);

            _blockset = new AlphaBlockCollection(_blocks, _data, _blockLight, _skyLight, _heightMap, _tileEntities);
            _entityset = new EntityCollection(_entities);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Create an empty, exportable schematic of given dimensions.
        /// </summary>
        /// <param name="xdim">The length of the X-dimension in blocks.</param>
        /// <param name="ydim">The length of the Y-dimension in blocks.</param>
        /// <param name="zdim">The length of the Z-dimension in blocks.</param>
        public Schematic(int xdim, int ydim, int zdim)
        {
            _blocks     = new XZYByteArray(xdim, ydim, zdim);
            _data       = new XZYNibbleArray(xdim, ydim, zdim);
            _blockLight = new XZYNibbleArray(xdim, ydim, zdim);
            _skyLight   = new XZYNibbleArray(xdim, ydim, zdim);
            _heightMap  = new ZXByteArray(xdim, zdim);

            _entities     = new TagNodeList(TagType.TAG_COMPOUND);
            _tileEntities = new TagNodeList(TagType.TAG_COMPOUND);

            _blockset  = new AlphaBlockCollection(_blocks, _data, _blockLight, _skyLight, _heightMap, _tileEntities);
            _entityset = new EntityCollection(_entities);
        }
Ejemplo n.º 8
0
        /// <inheritdoc/>
        public override AlphaBlockCollection GenerateTree(Random rng)
        {
            int width, height, depth;
            int centerX, centerZ;

            if (_isLarge)
            {
                width  = 7;
                height = 7 + rng.Next(0, 3);
                depth  = 7;

                centerX = 3;
                centerZ = 3;
            }
            else
            {
                width  = 5;
                height = 5 + rng.Next(0, 2);
                depth  = 5;

                centerX = 2;
                centerZ = 2;
            }

            AlphaBlockCollection tree = new AlphaBlockCollection(width, height, depth);

            tree.AutoLight = false;


            int canopyHeight = 3;

            if (_isLarge)
            {
                canopyHeight = 4;
            }

            for (int i = 1; i < canopyHeight; i++)
            {
                FillWithLeaves(tree, height - i);
            }
            GenerateOuterShroomLeaves(tree, height - canopyHeight);
            for (int i = 0; i < (height - 1); i++)
            {
                tree.SetID(centerX, i, centerZ, _logId);
            }

            return(tree);
        }
Ejemplo n.º 9
0
        private void GenerateOuterShroomLeaves(AlphaBlockCollection tree, int y)
        {
            int width  = tree.XDim;
            int height = tree.YDim;
            int depth  = tree.ZDim;

            for (int i = 1; i < (width - 1); i++)
            {
                tree.SetID(i, y, 0, _leafId);
                tree.SetID(i, y, depth - 1, _leafId);
            }
            for (int i = 1; i < (depth - 1); i++)
            {
                tree.SetID(0, y, i, _leafId);
                tree.SetID(width - 1, y, i, _leafId);
            }
        }
Ejemplo n.º 10
0
        private static void saveLayers()
        {
            AlphaBlockCollection chk = null;
            int x, z, cx, cz, ax, az;

            mnuStatus.Text = "Saving Block Data";

            for (cx = 0; cx < cxd; cx++)
            {
                for (cz = 0; cz < czd; cz++)
                {
                    if (reg.ChunkExists(cx, cz))
                    {
                        chk = reg.GetChunkRef(cx, cz).Blocks;

                        for (x = 0; x < xd; x++)
                        {
                            for (z = 0; z < zd; z++)
                            {
                                ax = cx * xd + x;
                                az = cz * zd + z;
                                chk.SetBlock(x,
                                             y,
                                             z,
                                             new AlphaBlock(Tools.Tool.Map[ax][az].ID,
                                                            Tools.Tool.Map[ax][az].Data));
                                if (Tools.Tool.Map[ax][az].ent != null)
                                {
                                    chk.SetTileEntity(x, y, z, Tools.Tool.Map[ax][az].ent);
                                }
                            }
                        }

                        mnuLoad.Increment(xd * zd);
                        reg.Save();
                    }
                }
            }

            GC.Collect();

            mnuLoad.Increment(-hgt * wid);
            mnuStatus.Text = "Not Loading";
        }
Ejemplo n.º 11
0
        void ProcessChunk(ChunkRef Chunk)
        {
            AlphaBlockCollection Blocks = Chunk.Blocks;

            for (int ChunkX = 0; ChunkX < 16; ChunkX++)
            {
                for (int ChunkZ = 0; ChunkZ < 16; ChunkZ++)
                {
                    for (int ChunkY = 0; ChunkY < 128; ChunkY++)
                    {
                        TileEntity     Entity = Blocks.SafeGetTileEntity(ChunkX, ChunkY, ChunkZ);
                        TileEntitySign Sign   = Entity as TileEntitySign;
                        if (Sign != null)
                        {
                            ParseSignInfo(Sign, ChunkX, ChunkY, ChunkZ, Chunk);
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
 public static int GetBlockLight(this AlphaBlockCollection blocks, LocalBlockPosition position)
 {
     return(blocks.GetBlockLight(position.X, position.Y, position.Z));
 }
Ejemplo n.º 13
0
        public static void Generate(frmMace frmLogForm, string strUserCityName,
                                    bool booIncludeFarms, bool booIncludeMoat, bool booIncludeWalls,
                                    bool booIncludeDrawbridges, bool booIncludeGuardTowers, bool booIncludeBuildings,
                                    bool booIncludePaths, bool booIncludeMineshaft, bool booIncludeItemsInChests,
                                    bool booIncludeValuableBlocks, bool booIncludeGhostdancerSpawners,
                                    string strCitySize, string strMoatType, string strCityEmblem,
                                    string strOutsideLights, string strTowerAddition, string strWallMaterial,
                                    string strCitySeed, string strWorldSeed, bool booExportSchematic)
        {
            #region seed the random number generators
            int    intCitySeed, intWorldSeed;
            Random randSeeds = new Random();
            if (strCitySeed.Length == 0)
            {
                intCitySeed = randSeeds.Next();
                frmLogForm.UpdateLog("Random city seed: " + intCitySeed);
            }
            else
            {
                intCitySeed = JavaStringHashCode(strCitySeed);
                frmLogForm.UpdateLog("Random city seed: " + strCitySeed);
            }
            if (strWorldSeed.Length == 0)
            {
                intWorldSeed = randSeeds.Next();
                frmLogForm.UpdateLog("Random world seed: " + intWorldSeed);
            }
            else
            {
                intWorldSeed = JavaStringHashCode(strWorldSeed);
                frmLogForm.UpdateLog("Random world seed: " + strWorldSeed);
            }
            RandomHelper.SetSeed(intCitySeed);
            #endregion

            #region create minecraft world directory from a random unused city name
            string strFolder = String.Empty, strCityName = String.Empty;

            strUserCityName = SafeFilename(strUserCityName);
            if (strUserCityName.ToLower().Trim().Length == 0)
            {
                strUserCityName = "random";
            }

            if (strUserCityName.ToLower().Trim() != "random")
            {
                if (Directory.Exists(Utils.GetMinecraftSavesDirectory(strUserCityName)))
                {
                    if (MessageBox.Show("A world called \"" + strUserCityName + "\" already exists. " +
                                        "Would you like to use a random name instead?", "World already exists",
                                        MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                    {
                        frmLogForm.UpdateLog("Cancelled, because a world with this name already exists.");
                        return;
                    }
                }
                else
                {
                    strCityName = strUserCityName;
                    strFolder   = Utils.GetMinecraftSavesDirectory(strCityName);
                }
            }
            if (strCityName.Length == 0)
            {
                string strStart, strEnd;
                do
                {
                    strStart    = RandomHelper.RandomFileLine(Path.Combine("Resources", "CityAdj.txt"));
                    strEnd      = RandomHelper.RandomFileLine(Path.Combine("Resources", "CityNoun.txt"));
                    strCityName = "City of " + strStart + strEnd;
                    strFolder   = Utils.GetMinecraftSavesDirectory(strCityName);
                } while (strStart.ToLower().Trim() == strEnd.ToLower().Trim() || Directory.Exists(strFolder) || (strStart + strEnd).Length > 14);
            }
            Directory.CreateDirectory(strFolder);
            RandomHelper.SetSeed(intCitySeed);
            #endregion

            #region get handles to world, chunk manager and block manager
            BetaWorld        worldDest = BetaWorld.Create(@strFolder);
            BetaChunkManager cmDest    = worldDest.GetChunkManager();
            BlockManager     bmDest    = worldDest.GetBlockManager();
            bmDest.AutoLight = false;
            #endregion

            #region determine block sizes
            // first we set the city size by chunks
            int intCitySize = 12;
            switch (strCitySize)
            {
            case "Random":
                intCitySize = RandomHelper.Next(8, 16);
                break;

            case "Very small":
                intCitySize = 5;
                break;

            case "Small":
                intCitySize = 8;
                break;

            case "Medium":
                intCitySize = 12;
                break;

            case "Large":
                intCitySize = 16;
                break;

            case "Very large":
                intCitySize = 25;
                break;

            default:
                Debug.Fail("Invalid switch result");
                break;
            }
            // then we multiply by 16, because that's the x and z of a chunk
            intCitySize *= 16;
            int intFarmLength = booIncludeFarms ? 32 : 8;
            int intMapLength  = intCitySize + (intFarmLength * 2);
            #endregion

            #region setup classes
            BlockShapes.SetupClass(bmDest, intMapLength);
            BlockHelper.SetupClass(bmDest, intMapLength);
            if (!SourceWorld.SetupClass(worldDest, booIncludeItemsInChests, booIncludeGhostdancerSpawners))
            {
                return;
            }
            NoticeBoard.SetupClass(intCitySeed, intWorldSeed);
            #endregion

            #region determine random options
            // ensure selected options take priority, but don't set things on fire
            if (strTowerAddition == "Random")
            {
                strTowerAddition = RandomHelper.RandomString("Fire beacon", "Flag");
            }
            if (strWallMaterial.StartsWith("Wood"))
            {
                if (strMoatType == "Lava" || strMoatType == "Fire" || strMoatType == "Random")
                {
                    strMoatType = RandomHelper.RandomString("Drop to Bedrock", "Cactus", "Water");
                }
                strOutsideLights = "Torches";
            }
            if (strWallMaterial == "Random")
            {
                if (strMoatType == "Lava" || strMoatType == "Fire" || strOutsideLights == "Fire")
                {
                    strWallMaterial = RandomHelper.RandomString("Brick", "Cobblestone", "Sandstone", "Stone");
                }
                else
                {
                    strWallMaterial = RandomHelper.RandomString("Brick", "Cobblestone", "Sandstone",
                                                                "Stone", "Wood Planks");
                    if (strWallMaterial.StartsWith("Wood"))
                    {
                        if (strMoatType == "Random")
                        {
                            strMoatType = RandomHelper.RandomString("Drop to Bedrock", "Cactus", "Water");
                        }
                        strOutsideLights = "Torches";
                    }
                }
            }
            if (strOutsideLights == "Random")
            {
                strOutsideLights = RandomHelper.RandomString("Fire", "Torches");
            }
            if (strMoatType == "Random")
            {
                int intRand = RandomHelper.Next(100);
                if (intRand >= 90)
                {
                    strMoatType = "Drop to Bedrock";
                }
                else if (intRand >= 80)
                {
                    strMoatType = "Cactus";
                }
                else if (intRand >= 50)
                {
                    strMoatType = "Lava";
                }
                else if (intRand >= 40)
                {
                    strMoatType = "Fire";
                }
                else
                {
                    strMoatType = "Water";
                }
            }

            int intWallMaterial = BlockType.STONE;
            switch (strWallMaterial)
            {
            case "Brick":
                intWallMaterial = BlockType.BRICK_BLOCK;
                break;

            case "Cobblestone":
                intWallMaterial = BlockType.COBBLESTONE;
                break;

            case "Sandstone":
                intWallMaterial = BlockType.SANDSTONE;
                break;

            case "Stone":
                intWallMaterial = BlockType.STONE;
                break;

            case "Wood Planks":
                intWallMaterial = BlockType.WOOD_PLANK;
                break;

            case "Wood Logs":
                intWallMaterial = BlockType.WOOD;
                break;

            case "Bedrock":
                intWallMaterial = BlockType.BEDROCK;
                break;

            case "Mossy Cobblestone":
                intWallMaterial = BlockType.MOSS_STONE;
                break;

            case "Netherrack":
                intWallMaterial = BlockType.NETHERRACK;
                break;

            case "Glass":
                intWallMaterial = BlockType.GLASS;
                break;

            case "Ice":
                intWallMaterial = BlockType.ICE;
                break;

            case "Snow":
                intWallMaterial = BlockType.SNOW_BLOCK;
                break;

            case "Glowstone":
                intWallMaterial = BlockType.GLOWSTONE_BLOCK;
                break;

            case "Dirt":
                intWallMaterial = BlockType.DIRT;
                break;

            case "Obsidian":
                intWallMaterial = BlockType.OBSIDIAN;
                break;

            case "Jack-o-Lantern":
                intWallMaterial = BlockType.JACK_O_LANTERN;
                break;

            case "Soul sand":
                intWallMaterial = BlockType.SOUL_SAND;
                break;

            case "Gold":
                intWallMaterial = BlockType.GOLD_BLOCK;
                break;

            case "Diamond":
                intWallMaterial = BlockType.DIAMOND_BLOCK;
                break;

            default:
                Debug.Fail("Invalid switch result");
                break;
            }
            #endregion

            #region make the city
            frmLogForm.UpdateLog("Creating underground terrain");
            Chunks.CreateInitialChunks(cmDest, intMapLength / 16, frmLogForm);
            frmLogForm.UpdateProgress(25);

            Buildings.structPoint spMineshaftEntrance = new Buildings.structPoint();

            if (booIncludeWalls)
            {
                frmLogForm.UpdateLog("Creating walls");
                Walls.MakeWalls(worldDest, intFarmLength, intMapLength, strCityEmblem, strOutsideLights, intWallMaterial);
            }
            frmLogForm.UpdateProgress(34);
            if (booIncludeBuildings || booIncludePaths)
            {
                frmLogForm.UpdateLog("Creating paths");
                int[,] intArea = Paths.MakePaths(worldDest, bmDest, intFarmLength, intMapLength, strCitySize,
                                                 booIncludeMineshaft);
                frmLogForm.UpdateProgress(36);
                if (booIncludeBuildings)
                {
                    frmLogForm.UpdateLog("Creating buildings");
                    spMineshaftEntrance = Buildings.MakeInsideCity(bmDest, worldDest, intArea, intFarmLength, intMapLength, booIncludePaths);
                    frmLogForm.UpdateProgress(45);
                    if (booIncludeMineshaft)
                    {
                        frmLogForm.UpdateLog("Creating mineshaft");
                        Mineshaft.MakeMineshaft(worldDest, bmDest, intFarmLength, intMapLength, spMineshaftEntrance);
                    }
                }
            }
            frmLogForm.UpdateProgress(51);

            if (booIncludeMoat)
            {
                frmLogForm.UpdateLog("Creating moat");
                Moat.MakeMoat(intFarmLength, intMapLength, strMoatType, booIncludeGuardTowers);
            }
            frmLogForm.UpdateProgress(52);

            if (booIncludeDrawbridges)
            {
                frmLogForm.UpdateLog("Creating drawbridges");
                Drawbridge.MakeDrawbridges(bmDest, intFarmLength, intMapLength, booIncludeMoat,
                                           booIncludeWalls, booIncludeItemsInChests, intWallMaterial, strMoatType, strCityName);
            }
            frmLogForm.UpdateProgress(53);

            if (booIncludeGuardTowers)
            {
                frmLogForm.UpdateLog("Creating guard towers");
                GuardTowers.MakeGuardTowers(bmDest, intFarmLength, intMapLength, booIncludeWalls,
                                            strOutsideLights, strTowerAddition, booIncludeItemsInChests, intWallMaterial);
            }
            frmLogForm.UpdateProgress(54);

            if (booIncludeFarms)
            {
                frmLogForm.UpdateLog("Creating farms");
                Farms.MakeFarms(worldDest, bmDest, intFarmLength, intMapLength);
            }
            frmLogForm.UpdateProgress(58);

            if (!booIncludeValuableBlocks)
            {
                cmDest.Save();
                worldDest.Save();
                Chunks.ReplaceValuableBlocks(worldDest, bmDest, intMapLength, intWallMaterial);
            }
            frmLogForm.UpdateProgress(60);
            Chunks.PositionRails(worldDest, bmDest, intMapLength);
            frmLogForm.UpdateProgress(62);
            #endregion

            #region world settings
            // spawn looking at one of the city entrances
            if (booIncludeFarms)
            {
                SpawnPoint spLevel = new SpawnPoint(7, 11, 13);
                worldDest.Level.Spawn = spLevel;
                worldDest.Level.Spawn = new SpawnPoint(intMapLength / 2, 64, intMapLength - (intFarmLength - 10));
            }
            else
            {
                worldDest.Level.Spawn = new SpawnPoint(intMapLength / 2, 64, intMapLength - (intFarmLength - 7));
            }
            // spawn in the middle of the city
//#if DEBUG
            //worldDest.Level.Spawn = new SpawnPoint(intMapLength / 2, 64, intMapLength / 2);
//#endif
            if (strWorldSeed.Length > 0)
            {
                worldDest.Level.RandomSeed = intWorldSeed;
            }

#if RELEASE
            worldDest.Level.Time = RandomHelper.Next(24000);

            if (RandomHelper.NextDouble() < 0.15)
            {
                worldDest.Level.IsRaining = true;
                // one-quarter to three-quarters of a day
                worldDest.Level.RainTime = RandomHelper.Next(6000, 18000);
                if (RandomHelper.NextDouble() < 0.25)
                {
                    worldDest.Level.IsThundering = true;
                    worldDest.Level.ThunderTime  = worldDest.Level.RainTime;
                }
            }
#endif
            #endregion

#if DEBUG
            MakeHelperChest(bmDest, worldDest.Level.Spawn.X + 2, worldDest.Level.Spawn.Y, worldDest.Level.Spawn.Z + 2);
#endif

            frmLogForm.UpdateLog("Creating lighting data");
            Chunks.ResetLighting(worldDest, cmDest, frmLogForm, (int)Math.Pow(intMapLength / 16, 2));

            worldDest.Level.LevelName = strCityName;
            worldDest.Save();

            if (booExportSchematic)
            {
                frmLogForm.UpdateLog("Creating schematic");
                AlphaBlockCollection abcExport = new AlphaBlockCollection(intMapLength, 128, intMapLength);
                for (int x = 0; x < intMapLength; x++)
                {
                    for (int z = 0; z < intMapLength; z++)
                    {
                        for (int y = 0; y < 128; y++)
                        {
                            abcExport.SetBlock(x, y, z, bmDest.GetBlock(x, y, z));
                        }
                    }
                }
                Schematic CitySchematic = new Schematic(intMapLength, 128, intMapLength);
                CitySchematic.Blocks = abcExport;
                CitySchematic.Export(Utils.GetMinecraftSavesDirectory(strCityName) + "\\" + strCityName + ".schematic");
            }

            frmLogForm.UpdateLog("\r\nCreated the " + strCityName + "!");
            frmLogForm.UpdateLog("It'll be at the end of your MineCraft world list.");
        }
Ejemplo n.º 14
0
        public static void Generate(frmMace frmLogForm, BetaWorld worldDest, BetaChunkManager cmDest, BlockManager bmDest,
                                    int x, int z, bool booExportSchematics, string strUndergroundOres)
        {
            #region create a city name
            string strStart, strEnd;
            do
            {
                strStart  = RNG.RandomFileLine(Path.Combine("Resources", City.CityNamePrefixFilename));
                strEnd    = RNG.RandomFileLine(Path.Combine("Resources", City.CityNameSuffixFilename));
                City.Name = City.CityNamePrefix + strStart + strEnd;
            } while (GenerateWorld.lstCityNames.Contains(City.Name) ||
                     strStart.ToLower().Trim() == strEnd.ToLower().Trim() ||
                     (strStart + strEnd).Length > 14);
            GenerateWorld.lstCityNames.Add(City.Name);
            #endregion

            #region determine block sizes
            City.CityLength *= 16;
            City.FarmLength *= 16;
            City.EdgeLength  = 8;
            City.MapLength   = City.CityLength + (City.EdgeLength * 2);
            #endregion

            #region setup classes
            BlockShapes.SetupClass(bmDest);
            BlockHelper.SetupClass(bmDest);
            NoticeBoard.SetupClass();
            if (!SourceWorld.SetupClass(worldDest))
            {
                return;
            }
            #endregion

            #region determine random options
            switch (City.WallMaterialID)
            {
            case BlockType.WOOD_PLANK:
            case BlockType.WOOD:
            case BlockType.LEAVES:
            case BlockType.VINES:
            case BlockType.WOOL:
            case BlockType.BOOKSHELF:
                switch (City.OutsideLightType)
                {
                case "Fire":
                    frmLogForm.UpdateLog("Fixing fire-spreading combination", true, true);
                    City.OutsideLightType = "Torches";
                    break;
                }
                switch (City.MoatType)
                {
                case "Fire":
                case "Lava":
                    frmLogForm.UpdateLog("Fixing fire-spreading combination", true, true);
                    City.MoatType = "Water";
                    break;
                }
                break;
            }
            switch (City.PathType.ToLower().Trim())
            {
            case "stone_raised":
                City.PathBlockID              = BlockInfo.DoubleSlab.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 0;
                City.PathExtends              = 2;
                break;

            case "sandstone_raised":
                City.PathBlockID              = BlockInfo.Sandstone.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 1;
                City.PathExtends              = 2;
                break;

            case "woodplanks_raised":
                City.PathBlockID              = BlockInfo.WoodPlank.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 2;
                City.PathExtends              = 2;
                break;

            case "cobblestone_raised":
                City.PathBlockID              = BlockInfo.Cobblestone.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 3;
                City.PathExtends              = 2;
                break;

            case "brick_raised":
                City.PathBlockID              = BlockInfo.BrickBlock.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 4;
                City.PathExtends              = 2;
                break;

            case "stonebrick_raised":
                City.PathBlockID              = BlockInfo.StoneBrick.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = BlockInfo.Slab.ID;
                City.PathAlternativeBlockData = 5;
                City.PathExtends              = 2;
                break;

            case "stonebrick":
                City.PathBlockID              = BlockInfo.StoneBrick.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = 0;
                City.PathAlternativeBlockData = 0;
                City.PathExtends              = 1;
                break;

            case "sandstone":
                City.PathBlockID              = BlockInfo.Sandstone.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = 0;
                City.PathAlternativeBlockData = 0;
                City.PathExtends              = 1;
                break;

            case "stone":
                City.PathBlockID              = BlockInfo.Stone.ID;
                City.PathBlockData            = 0;
                City.PathAlternativeBlockID   = 0;
                City.PathAlternativeBlockData = 0;
                City.PathExtends              = 1;
                break;

            case "wood":
                City.PathBlockID              = BlockInfo.Wood.ID;
                City.PathBlockData            = RNG.Next(0, 2);
                City.PathAlternativeBlockID   = 0;
                City.PathAlternativeBlockData = 0;
                City.PathExtends              = 1;
                break;
            }
            #endregion

            #region make the city
            frmLogForm.UpdateLog("Creating the " + City.Name, false, false);
            frmLogForm.UpdateLog("City length in blocks: " + City.MapLength, true, true);
            frmLogForm.UpdateLog("Edge length in blocks: " + City.EdgeLength, true, true);
            frmLogForm.UpdateLog("Farm length in blocks: " + City.FarmLength, true, true);
            frmLogForm.UpdateLog("City position in blocks: " + ((x + Chunks.CITY_RELOCATION_CHUNKS) * 16) + "," +
                                 ((z + Chunks.CITY_RELOCATION_CHUNKS) * 16), true, true);
            frmLogForm.UpdateLog("Theme: " + City.ThemeName, true, true);
            frmLogForm.UpdateLog("Creating underground terrain", true, false);
            Chunks.CreateInitialChunks(cmDest, frmLogForm, strUndergroundOres);
            frmLogForm.UpdateProgress(0.21);

            Buildings.structPoint spMineshaftEntrance = new Buildings.structPoint();

            if (City.HasWalls)
            {
                frmLogForm.UpdateLog("Creating walls", true, false);
                Walls.MakeWalls(worldDest, frmLogForm);
            }
            frmLogForm.UpdateProgress(0.24);

            if (City.HasDrawbridges)
            {
                frmLogForm.UpdateLog("Creating entrances", true, false);
                Entrances.MakeEntrances(bmDest);
            }
            frmLogForm.UpdateProgress(0.27);

            if (City.HasMoat)
            {
                frmLogForm.UpdateLog("Creating moat", true, false);
                Moat.MakeMoat(frmLogForm, bmDest);
            }
            frmLogForm.UpdateProgress(0.30);

            if (City.HasBuildings || City.HasPaths)
            {
                frmLogForm.UpdateLog("Creating paths", true, false);
                frmLogForm.UpdateLog("Path type: " + City.PathType, true, true);
                int[,] intArea = Paths.MakePaths(worldDest, bmDest);
                frmLogForm.UpdateProgress(0.33);
                if (City.HasBuildings)
                {
                    frmLogForm.UpdateLog("Creating buildings", true, false);
                    spMineshaftEntrance = Buildings.MakeInsideCity(bmDest, worldDest, intArea, frmLogForm);
                    frmLogForm.UpdateProgress(0.36);
                    if (City.HasMineshaft)
                    {
                        frmLogForm.UpdateLog("Creating mineshaft", true, false);
                        Mineshaft.MakeMineshaft(worldDest, bmDest, spMineshaftEntrance, frmLogForm);
                    }
                }
            }
            frmLogForm.UpdateProgress(0.39);

            if (City.HasGuardTowers)
            {
                frmLogForm.UpdateLog("Creating guard towers", true, false);
                GuardTowers.MakeGuardTowers(bmDest, frmLogForm);
            }
            frmLogForm.UpdateProgress(0.42);

            if (City.HasFarms)
            {
                frmLogForm.UpdateLog("Creating farms", true, false);
                Farms2.MakeFarms(worldDest, bmDest);
            }
            frmLogForm.UpdateProgress(0.45);

            if (City.HasFlowers)
            {
                frmLogForm.UpdateLog("Creating flowers", true, false);
                Flowers.MakeFlowers(worldDest, bmDest);
            }
            frmLogForm.UpdateProgress(0.46);

            if (!City.HasValuableBlocks)
            {
                frmLogForm.UpdateLog("Replacing valuable blocks", true, true);
                cmDest.Save();
                worldDest.Save();
                Chunks.ReplaceValuableBlocks(worldDest, bmDest);
            }
            frmLogForm.UpdateProgress(0.48);

            frmLogForm.UpdateLog("Creating rail data", true, false);
            Chunks.PositionRails(worldDest, bmDest);
            frmLogForm.UpdateProgress(0.50);

            frmLogForm.UpdateLog("Creating lighting data", true, false);
            Chunks.ResetLighting(worldDest, cmDest, frmLogForm);
            frmLogForm.UpdateProgress(0.95);
            #endregion

            #region export schematic
            if (booExportSchematics)
            {
                frmLogForm.UpdateLog("Creating schematic in world folder", true, false);
                AlphaBlockCollection abcExport = new AlphaBlockCollection(City.MapLength, 128, City.MapLength + City.FarmLength);
                for (int xBlock = 0; xBlock < City.MapLength; xBlock++)
                {
                    for (int zBlock = -City.FarmLength; zBlock < City.MapLength; zBlock++)
                    {
                        for (int y = 0; y < 128; y++)
                        {
                            abcExport.SetBlock(xBlock, y, City.FarmLength + zBlock, bmDest.GetBlock(xBlock, y, zBlock));
                        }
                    }
                }
                Schematic CitySchematic = new Schematic(City.MapLength, 128, City.MapLength + City.FarmLength);
                CitySchematic.Blocks = abcExport;
                CitySchematic.Export(worldDest.Path + "\\" + City.Name + ".schematic");
            }
            #endregion

            #region positioning
            frmLogForm.UpdateLog("Creating position data", true, false);
            Chunks.MoveChunks(worldDest, cmDest, x, z);
            frmLogForm.UpdateProgress(1);
            #endregion
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Create an exportable schematic wrapper around existing blocks and entities.
 /// </summary>
 /// <param name="blocks">An existing <see cref="AlphaBlockCollection"/>.</param>
 /// <param name="entities">An existing <see cref="EntityCollection"/>.</param>
 public Schematic(AlphaBlockCollection blocks, EntityCollection entities)
 {
     _blockset  = blocks;
     _entityset = entities;
 }
Ejemplo n.º 16
0
		//------------------------------------------------------------
		//          GIGANTIC MAP CONVERSION FUNCTION!
		//------------------------------------------------------------
		///<summary>
		///		<para>This is the function that will be called when the big 'convert' button is pressed on the panel. 
		///     	Conversion is BIG. I have divided it into the following stages:</para>
        /// 		<para></para>
		/// 		<para>1) Open the Substrate directory, read it, and initialize cubiquity stuff </para>
		/// 
		/// 		<para>2) Handle file names. Handle closing existing files, deleting them, replacing them, relinking them, etc. Make sure everything lines up smoothly,  and
		/// 			minimize crashing as a result of overwriting things.</para>
		/// 		  
		/// 		<para>3) Translate the 3D Array of Voxels from Substrate to Cubiquity, minding things like Regions and dimensions.</para>
		/// 
		/// 		<para>4) Save all the materials we created and wish to keep. Again, ensure no naming conflict problems. </para>
		/// 
		/// 		<para>5) Refresh everything dependent on the newly saved materials</para>
		///			<para></para>
		/// 		<para> Although this function takes no parameters, it is reliant heavily on class members; such as toAsset, toVdb, _options, _saveName,  _toSubstrateMap, and in general
		/// 			pretty much every other part of SubstrateConverter. It also relies on Application., AssetDatabase., and File. calls.</para>
		/// </summary>
		public void ConvertMap()
		{
			//------------------------------------------------------------
			//------- STAGE 1: GET THE MAPS OPEN AND CREATE SOME HANDLERS!
			//------------------------------------------------------------

			//Load in the Substrate Map folder! (The three versions of map are 'Alpha, Beta, and Anvil.' Our 
			//maps are served in Anvil format. We don't have to errorcheck; substrate will pop an error if we failed.
			AnvilWorld leWorld = AnvilWorld.Create(_toSubstrateMap);

			//The region actually contains data about the chunks.
			AnvilRegionManager leRegions = leWorld.GetRegionManager();

			//I have no idea what a more clever way of getting the number of regions in leRegions might be, so let's do this for now
			int regionTotal = 0;
			foreach(AnvilRegion region in leRegions)
			{
				if(region != null) //I hate that warning in the editor that region is declared but never used...
					regionTotal++;
			}

			//debugging to make sure loops work and understand if any assets went mysteriously missing.
			Debug.Log ("Attempting to load " + regionTotal.ToString() + " regions");

			//this exists ENTIRELY as a set of helpers so that I can concatenate strings together and perform sexy operations on them :|
			String pathVDB = "";
			String pathAsset = "";

			//this has helped tremendously during the debug phase
			int failDetector = 0;

			//this needs to be rooted at the Assets directory, or there shall be chaos! CHAOS! 
			//(If improperly done it will result in 'unable to create asset' and DEATH!
			//Debug.Log ("Rooting _toAsset: " + _toAsset);
			String toAssetHelp = Paths.RootToDirectory(Application.dataPath, toAsset);
	
			//------------------------------------------------------------
			//------- PROCEED REGION BY REGION!
			//------------------------------------------------------------
			// I have added a wiki page on the evils of conversion. Right now, I am creating a VoxelData object per region
			//btw, we can use foreach on leRegions because leRegion is 'Enumerable'. Check out its inheritance. 
			int regionCount = 0;
			foreach(AnvilRegion region in leRegions)
			{
				//well, since I put it in the above foreach, I suddenly feel obligated to do it here, also... Don't judge me!
				if(region == null) continue;

				//Chunk Size * chunks in region.... map is automatically 256 deep
				int xSize = region.XDim * this.subChunkSize;
				int zSize = region.ZDim * this.subChunkSize;
				int ySize = this.subMapDepth - _clipFromAbove;


				//it appears that while minecraft prefers xzy, cubiquity prefers xyz (height compes second)
				//meh, I nabbed this from a little deeper in Cubiquity than its top-level menu selectors, cause I wanted to be able to specify my own vdb name
				//it creates both the asset (which we are going to have to save) and the .vdb

				//anyway, make sure we create the new data with the proper file name!!!
				ColoredCubesVolumeData data = null;

				//------------------------------------------------------------
				//------- STAGE 2: HANDLE NAMING CONFLICTS/REIMPORTING/ETC
				//------------------------------------------------------------

				//This handy-dandy notebook is going to record for us information we need to regenerate copies of the VolumeData .asset that used to link to the
				//vdb previous to import AND it holds onto the original data structures so we can ask ColoredCubesVolume if their data == data we replaced. 
				Dictionary<String, ColoredCubesVolumeData> relinker = new Dictionary<String, ColoredCubesVolumeData>();

				//use that nice helper variable with this nice helper function to ensure our path is prepped for either single or multiple saves...
				//all without cluttering our code with loads of if/thens
				pathVDB = Paths.HelpMakePath(toVDB, regionTotal, regionCount, ".vdb");
				pathAsset = Paths.HelpMakePath(toAssetHelp, regionTotal, regionCount, ".asset");

				//Debug.Log ("Created pathAsset: " + pathAsset);

				//Alrighty then. What we want to do is check and see if this VDB already exists.
				//if it exists, we want to try and delete it.
				//to delete it, we have to figure out if it's somehow locked and then attempt to unlock it.
				//then we have to try and delete it and we might get some errors (for which we should prep a try/catch)
				if(File.Exists (pathVDB))
				{

					Debug.Log ("A .vdb by this name already exists. Searching through .asset files to see if it is currently opened.");

					//Alright, so we're going to do some hacking and see if we can figure out how to delete the vdbs live.
					//this is gonna look for the .asset file that the vdb is attached to...

					//if we managed to find the .asset that links to this vdb, we must BURN IT MUAHAHAHAHHAHAA
					//I've changed if(oldData) to while(oldData) to account for the possibility that multiple Data .assets
					//might have the vdb open in read only mode 

					failDetector = 0;
					foreach(ColoredCubesVolumeData oldData in FindVolumeMatchingPath(pathVDB))
					{

						Debug.Log ("Successfully found an .asset reading from the .vdb. Attempting to shut it down to release the .vdb.");

						//I'm going out on a limb here to see if this works... If it doesn't, we can fudge around a little
						//more or just try to fail gracefully.
						oldData.ShutdownCubiquityVolume();

						//referencing this function (GetAssetPath) takes a million bajillion years.
						String oldDataPath = AssetDatabase.GetAssetPath (oldData);

						//write down in our handy-dandy notebook that this oldData once existed at some location
						if(!relinker.ContainsKey (oldDataPath))
						{
							relinker.Add (oldDataPath, oldData);
						}

						//now let's try and delete the asset itself so we get no linking errors...
						AssetDatabase.DeleteAsset(oldDataPath);

						failDetector++;
						if(failDetector >= 1000) break;
					}

					//this should no longer ever fire because olddata does a comparison now; but I'll leave it in place. 
					if(failDetector >= 1000)
					{
						throw new System.ArgumentException("I need to write better while loops", failDetector.ToString());
				
					}

					Debug.Log ("Attempting to delete the old .vdb under the assumption it is no longer open. If the deletion fails, the conversion will not proceed. The .vdb can be deleted manually with the Unity Editor closed, or you can specify a different save name for the .vdb.");

					//When this error is thrown, the entire conversion attempt stops; and we don't corrupt our existing data.
					File.Delete (pathVDB);
				
				} //checking for if VDB exists and deleting it/its .assets

				Debug.Log ("Creating new VDB");

				//CREATE LE NEW DATA with the path we just got :)
				data = VolumeData.CreateEmptyVolumeData<ColoredCubesVolumeData>(new Region(0, 0, 0, xSize-1, ySize-1-_clipFromBelow, zSize-1), pathVDB);

				//Mayday!
				if(data == null)
				{

					Debug.Log("Unable to initialize ColoredCubesVolumeData. Attempting to fail gracefully by abandoning conversion attempt.");
					return;
				}


				//------------------------------------------------------------
				//------- STAGE 3: TRANSFER THE 3D ARRAYS, BLOCK BY BLOCK
				//------------------------------------------------------------

				//declare the chunk-reference-thingy we'll be using to access Substrate blocks!
				ChunkRef chunk = null;
				AlphaBlockCollection blocks = null; //I get the impression Substrate once thought it needed Alpha, Beta, and Anvil Block Collections... and then ended up only needing 1 kind...


				//----- The array CONVERSION! -----//
				//And here is where we will actually go through the loop's 3 dimensions and attempt to change the blocks
				//Scroll down to the super-interior 'k' loop to find the block replacement code

				//iterate through the chunks and blocks on x axis 
				for(int iChunk = 0, iBlock = 0; iChunk < region.XDim;)
				{

					//iterate through the chunks and blocks on z axis (the odd initialization parameters will fire the blocks called 'ITERATION CODE' on the first run.)
					//(and the odd termination parameters should fire when jChunk = the last chunk and jBlock = the last block
					for(int jChunk = -1, jBlock = this.subChunkSize; jChunk < region.ZDim - 1 || jBlock < this.subChunkSize - 1; jBlock++)
					{	
						//ITERATION CODE FOR J/Z
						if(jBlock >= this.subChunkSize)
						{
							jBlock = 0;
							jChunk ++;

							//nab the new chunk
							chunk = region.GetChunkRef(iChunk, jChunk);
						
							//determine if it's valid
							if(chunk == null)
							{
								//hehe, I'm cheating, I'm cheating. this allows the ITERATION CODE block to handle loading the next chunk ;) 
								jBlock = this.subChunkSize;
								continue;
							}
							if(!chunk.IsTerrainPopulated)
							{
								jBlock = this.subChunkSize;
								continue;
							}

							//handily access its blocks
							blocks = chunk.Blocks;
						}
								
						//there is only 1 chunk on the y axis, so go straight through the blocks without worrking about kChunks or kBlocks
						for(int k = _clipFromBelow; k < ySize; k++)
						{
							//NAB THE ID! Using the Substrate block collections 'get id'
							int blockId = blocks.GetID (iBlock, k, jBlock);

							///Translate the ID using our personal 'ConvertBlock' and throw that quantizedColor variable into Cubiquity's voxeldata collection!
							data.SetVoxel(iBlock, k-_clipFromBelow, jBlock, ConvertBlock (blockId));
						}//K/Y loop
						
					}//J/Z loop
					
					//ITERATION CODE FOR I/X
					iBlock++;
					if(iBlock >= this.subChunkSize)
					{
						iBlock = 0;
						iChunk ++;
					}
				} //I/X loop


				//------------------------------------------------------------
				//------- STAGE 4: SAVE EVERYTHING WHERE IT NEEDS TO GO, AGAIN PREVENT NAMING CONFLICTS
				//------------------------------------------------------------

				//Now, data should be filled with all of the cubes we extracted from the chunks. We need to save the .asset files! We want to add on
				//the region number if we loaded more than one region, and leave the name the way it is if we didn't.
				//we just have to make the new asset(s) permenant

				//there is a possibility a nincompoop with good intentions somehow ended up with an .asset file that
				//has the name we're replacing, but a .vdb that's named something else entirely.
				//in this case we don't want to destroy that potentially valuable .vdb- but we've got to get rid of the 
				//asset. And since the .vdb might be locked, we have to shut it down to prevent strange deletion difficulties.

				if(File.Exists (pathAsset))
				{
					//check out if this is a ColoredCubesVolumeData or not
					ColoredCubesVolumeData oldData = AssetDatabase.LoadAssetAtPath(pathAsset, typeof(ColoredCubesVolumeData)) as ColoredCubesVolumeData;
					
					if(oldData != null)
					{
						Debug.Log ("A stray .asset file has been found with an identical name but with a .vdb at " + oldData.fullPathToVoxelDatabase + " Will attempt to shutdown and overwrite the .asset without harming the .vdb");
						
						//again, this little bugger is going to help me refresh all the ColoredCubesVolumes at the end
						//replacer.Add (pathVDB, oldData);
						
						//I'm going out on a limb here to see if this works... If it doesn't, we can fudge around a little
						//more or just try to fail gracefully.
						oldData.ShutdownCubiquityVolume();

						//I am on the fence about whether I want to relink this data. And I don't think I do. After all, our previous foreach iterator 
						//would have found this current oldData if there wasn't a mixmatch with vdbs. 
					}
					else
					{
						Debug.Log("An .asset of a different type (non ColoredCubesVolumeData) has been found at the save location. Attempting to overwrite it.");
					}
					
					
					//now let's try and delete the asset itself so we get no linking errors...
					AssetDatabase.DeleteAsset(pathAsset);
				}


				//Debug.Log ("The hell is pathAsset? " + pathAsset);

				//Create the asset
				AssetDatabase.CreateAsset(data, pathAsset);
				AssetDatabase.SaveAssets();

				//Do some selection/saving/cleanup
				EditorUtility.FocusProjectWindow ();
				Selection.activeObject = data;

				//------------------------------------------------------------
				//------- STAGE 5: REFRESH DEPENDENT COMPONENTS
				//------------------------------------------------------------

				//This nifty little loop is going to handle refreshing our ColoredCubesVolumes!
				//right off the bat I'm not going to have it create .asset files; especially cause I haven't shared
				
				//so, let's iterate through all of the oldDatas we destroyed
				foreach(KeyValuePair<String, ColoredCubesVolumeData> toDo in relinker)
				{

					foreach(ColoredCubesVolume toLink in FindObjectMatchingData(toDo.Value))
					{
						//update it
						toLink.data = data;

					}
				}

				AssetDatabase.SaveAssets();
			
				//iterate :3
				regionCount++;

			}//for each region

			AssetDatabase.Refresh ();

			Debug.Log ("Conversion attempt was successful");
		}
Ejemplo n.º 17
0
 public static int GetTileTickValue(this AlphaBlockCollection blocks, LocalBlockPosition position)
 {
     return(blocks.GetTileTickValue(position.X, position.Y, position.Z));
 }
Ejemplo n.º 18
0
 public static AlphaBlockRef GetBlockRef(this AlphaBlockCollection blocks, LocalBlockPosition position)
 {
     return(blocks.GetBlockRef(position.X, position.Y, position.Z));
 }
Ejemplo n.º 19
0
 public static BlockInfo GetInfo(this AlphaBlockCollection blocks, LocalBlockPosition position)
 {
     return(blocks.GetInfo(position.X, position.Y, position.Z));
 }
Ejemplo n.º 20
0
 public static TileEntity GetTileEntity(this AlphaBlockCollection blocks, LocalBlockPosition position)
 {
     return(blocks.GetTileEntity(position.X, position.Y, position.Z));
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Create an exportable schematic wrapper around existing blocks and entities.
 /// </summary>
 /// <param name="blocks">An existing <see cref="AlphaBlockCollection"/>.</param>
 /// <param name="entities">An existing <see cref="EntityCollection"/>.</param>
 public Schematic(AlphaBlockCollection blocks, EntityCollection entities)
 {
     _blockset = blocks;
     _entityset = entities;
 }
Ejemplo n.º 22
0
        // ReSharper disable once FunctionComplexityOverflow
        // *** I do ^ because this function is the 'hottest' block of code in the program, and saving cycles during execution is ridiculously important here.
        void RenderChunk(ChunkRef Chunk, ParallelLoopState LoopState)
        {
            // *** Track how many chunks have been processed, for user feedback
            Interlocked.Increment(ref _ProcessedChunks);
            Interlocked.Increment(ref _ActiveRenderThreads);
#if !DEBUG && !FAST
            // *** In release mode, gracefully handle bad chunks.  Explode in debug mode so I can track down the issue.
            try
            {
#endif

            int[][] DepthOpacities = _ColourPalette.DepthOpacities;

            // *** Cancellation logic for parallel processing
            if (LoopState != null && _Cancellation.IsCancellationRequested)
            {
                LoopState.Stop();
            }

            if (LoopState != null && LoopState.IsStopped)
            {
                Interlocked.Decrement(ref _ActiveRenderThreads);
                return;
            }

            // *** Hold off on rendering if the user needs to attend to an issue
            while (_PauseRendering > 0)
            {
                Thread.Sleep(50);
            }

            // *** Load the chunk from disk here
            AlphaBlockCollection Blocks = Chunk.Blocks;

            for (int X = 0; X < 16; X++)
            {
                for (int Z = 0; Z < 16; Z++)
                {
                    // *** Start by finding the topmost block to render
                    int EndY = _RenderStartY(Blocks, X, Z);
                    int Y    = EndY;

                    if (Y < 0)
                    {
                        continue; // *** No valid renderable blocks in this column, so continue with the next column
                    }
                    // *** Drill into the column to determine how many blocks down to render
                    int RenderVal = 255;
                    while (RenderVal > 0)
                    {
                        RenderVal -= DepthOpacities[Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)];
                        if (Y == 0) // *** If we've hit the bottom of the map, don't try and keep going.
                        {
                            break;  // *** It wouldn't end well.
                        }
                        Y--;
                    }

                    Colour SetColour = Colour.Transparent; // *** What colour to set the current column's pixel to.

                    // *** The Block-Metadata palette for this column's biome
                    Colour[][] BiomePalette = _ColourPalette.FastPalette[Chunk.Biomes.GetBiome(X, Z)];

                    for (; Y <= EndY; Y++) // *** Now render up from the lowest block to the starting block
                    {
                        // *** For each block we render, grab its palette entry.
                        Colour Entry = BiomePalette[Blocks.GetID(X, Y, Z)][Blocks.GetData(X, Y, Z)];

                        // *** If it has an associated entity colours list, then it needs special consideration to get its colour
                        if ((Entry.Color & 0xFFFF0000U) == 0x00FF0000U) // *** Check for the flag value (0 Alpha, 255 Red - Blue and Green form the 0-65535 index)
                        {
                            PaletteEntry Entry2 = _ColourPalette.GetPaletteEntry((int)(Entry.Color & 0x0000FFFFU)).First(e => e.IsMatch(Blocks.GetData(X, Y, Z), Blocks.SafeGetTileEntity(X, Y, Z)));
                            if (Entry2 != null)
                            {
                                Entry = Entry2.Color;
                            }
                        }

                        if (Entry.A == 0)
                        {
                            continue; // *** If we're trying to render air, let's not.
                        }
                        // *** Blend in our working colour to the column's pixel, after applying altitude and light-level blends.
                        SetColour.Blend(Entry.Copy().LightLevel((uint)Math.Max(_Config.MinLightLevel, Blocks.GetBlockLight(X, Math.Min(Y + 1, 255), Z))).Altitude(Y));
                    }

                    Marshal.WriteInt32(_RenderTarget.Scan0 + (_Stride * (((Chunk.Z - _Config.SubregionChunks.Y) << 4) + Z)) + ((((Chunk.X - _Config.SubregionChunks.X) << 4) + X) << 2), (int)SetColour.FullAlpha().Color);
                }
            }
#if !DEBUG && !FAST // *** When not running in debug mode, chunks that fail to render should NOT crash everything.
        }

        catch (Exception Ex)
        {
            Interlocked.Increment(ref _PauseRendering);

            _CorruptChunks = true;
            RenderingErrorEventArgs E = new RenderingErrorEventArgs
            {
                ErrorException   = Ex,
                IsFatal          = false,
                UserErrorMessage = "A chunk failed to render",
                ErrorCode        = ErrorBadChunk
            };

            if (RenderError != null)
            {
                RenderError.Invoke(this, E);
            }

            Interlocked.Decrement(ref _PauseRendering);
        }
#endif
            Interlocked.Decrement(ref _ActiveRenderThreads);
        }