예제 #1
0
        public static bool Paste(RegionFile region, int offsetX, int offsetZ)
        {
            if (currentPaste == null)
                return false;

            for (int x = 0; x < currentPaste.Width; x++)
            {
                for (int z = 0; z < currentPaste.Height; z++)
                {
                    if (currentPaste.Biomes[x, z] == (byte)Biome.Unspecified)
                        continue;

                    Coord chunkOffset = new Coord(offsetX + x, offsetZ + z);
                    chunkOffset.AbsolutetoChunk();
                    if (chunkOffset.X < 0 || chunkOffset.X >= 32 || chunkOffset.Z < 0 || chunkOffset.Z >= 32)
                        continue;
                    Chunk c = region.Chunks[chunkOffset.X, chunkOffset.Z];
                    if (c == null || c.Root == null)
                        continue;

                    int pasteX = (offsetX + x) % 16;
                    int pasteZ = (offsetZ + z) % 16;

                    ((TAG_Byte_Array)c.Root["Level"]["Biomes"]).Payload[pasteX + pasteZ * 16] = currentPaste.Biomes[x, z];
                }
            }

            return true;
        }
예제 #2
0
        public static void AddorRemoveBlocksSelection(RegionFile region, Bitmap b, Color selectionColor, int[] blockIds, bool add)
        {
            if (blockIds == null || blockIds.Length == 0)
                return;

            List<int> ids = new List<int>(blockIds);

            foreach (Chunk c in region.Chunks)
            {
                if (c.Root == null)
                    continue;
                Coord chunkOffset = new Coord(region.Coords);
                chunkOffset.RegiontoChunk();
                chunkOffset = new Coord(c.Coords.X - chunkOffset.X, c.Coords.Z - chunkOffset.Z);
                chunkOffset.ChunktoAbsolute();

                TAG_Compound[] sections = new TAG_Compound[16];
                int highest = -1;
                foreach (TAG t in (TAG[])c.Root["Level"]["Sections"])
                {
                    byte index = (byte)t["Y"];
                    if (index > highest)
                        highest = index;
                    sections[index] = (TAG_Compound)t;
                }

                //chunk exists but all blocks are air
                if (highest < 0)
                    return;

                highest = ((highest + 1) * 16) - 1;

                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        int y;
                        if (c.ManualHeightmap[x + z * 16] >= 0)
                            y = c.ManualHeightmap[x + z * 16];
                        else
                        {
                            y = GetHeight(sections, x, z, highest);
                            c.ManualHeightmap[x + z * 16] = y;
                        }
                        if (y < 0)
                            continue;

                        if (ids.Contains(GetBlock(sections, x, y, z)))
                        {
                            b.SetPixel(OFFSETX + chunkOffset.X + x, OFFSETY + chunkOffset.Z + z, add ? selectionColor : Color.Transparent);
                        }
                    }
                }
            }
        }
예제 #3
0
        public static void AddorRemoveBiomesSelection(RegionFile region, Bitmap b, Color selectionColor, byte biome, bool add)
        {
            foreach (Chunk c in region.Chunks)
            {
                if (c.Root == null)
                    continue;
                Coord chunkOffset = new Coord(region.Coords);
                chunkOffset.RegiontoChunk();
                chunkOffset = new Coord(c.Coords.X - chunkOffset.X, c.Coords.Z - chunkOffset.Z);
                chunkOffset.ChunktoAbsolute();

                byte[] biomes = (byte[])c.Root["Level"]["Biomes"];

                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        if(biome == biomes[x + z * 16])
                            b.SetPixel(OFFSETX + chunkOffset.X + x, OFFSETY + chunkOffset.Z + z, add ? selectionColor : Color.Transparent);
                    }
                }
            }
        }
예제 #4
0
        public static void Copy(RegionFile region, Bitmap selection, Color selectionColor)
        {
            BiomeCopy biomeData = new BiomeCopy();
            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null || c.Root == null)
                        continue;

                    byte[] biomes = (byte[])c.Root["Level"]["Biomes"];
                    for (int x = 0; x < 16; x++)
                    {
                        for (int z = 0; z < 16; z++)
                        {
                            if (selection.GetPixel(RegionUtil.OFFSETX + chunkX * 16 + x, RegionUtil.OFFSETY + chunkZ * 16 + z).ToArgb() == selectionColor.ToArgb())
                            {
                                biomeData.Biomes[chunkX * 16 + x, chunkZ * 16 + z] = biomes[x + z * 16];
                                biomeData.Empty = false;
                                if (biomeData.Left > chunkX * 16 + x)
                                    biomeData.Left = chunkX * 16 + x;
                                if (biomeData.Right < chunkX * 16 + x)
                                    biomeData.Right = chunkX * 16 + x;
                                if (biomeData.Top > chunkZ * 16 + z)
                                    biomeData.Top = chunkZ * 16 + z;
                                if (biomeData.Bottom < chunkZ * 16 + z)
                                    biomeData.Bottom = chunkZ * 16 + z;
                            }
                        }
                    }
                }
            }
            biomeData.Crop();
            System.Windows.Forms.Clipboard.SetData("BiomeCopy", biomeData);
        }
예제 #5
0
        public static void RenderRegionChunkstobePopulated(RegionFile region, Bitmap b, bool clip = true)
        {
            using (Graphics g = Graphics.FromImage(b))
            {
                if (clip)
                    g.SetClip(CLIP);
                g.Clear(Color.Transparent);
            }

            RenderRegionChunkstobePopulated(region, 0, 31, 0, 31, OFFSETX, OFFSETY, b);
        }
예제 #6
0
 private void Run()
 {
     String[] paths = Directory.GetFiles(regionDir, "*.mca", SearchOption.TopDirectoryOnly);
     String format = String.Format("{{0}} region {{1}} of {0}", paths.Length);
     int count = 0;
     foreach (String path in paths)
     {
         UpdateStatus(String.Format(format, "Reading", count));
         UpdateProgress(count, paths.Length);
         RegionFile region = new RegionFile(path);
         UpdateStatus(String.Format(format, replace ? "Replacing" : "Filling", count));
         if (!replace)
         {
             RegionUtil.Fill(region, null, Color.Black, biome1, worldSeed);
         }
         else
         {
             RegionUtil.Replace(region, null, Color.Black, ((BiomeType)biome1).ID, biome2, worldSeed);
         }
         UpdateStatus(String.Format(format, "Saving", count));
         mutex.WaitOne();
         region.Write(true);
         mutex.ReleaseMutex();
         count++;
     }
     UpdateProgress(paths.Length, paths.Length);
     UpdateStatus("Done");
 }
예제 #7
0
        private Bitmap RenderRegionBiomes(RegionFile region, Bitmap b, int offsetX, int offsetY)
        {
            foreach (Chunk c in region.Chunks)
            {
                if (c == null || c.Root == null)
                    continue;
                Coord chunkOffset = new Coord(c.Coords);
                chunkOffset.ChunktoRegionRelative();
                chunkOffset.ChunktoAbsolute();
                RenderChunkBiomes(c, b, offsetX + chunkOffset.X, offsetY + chunkOffset.Z);
            }

            return b;
        }
예제 #8
0
        public static void RenderRegionBiomes(RegionFile region, Bitmap b, String[,] toolTips, bool clip = true)
        {
            using (Graphics g = Graphics.FromImage(b))
            {
                if(clip)
                    g.SetClip(CLIP);
                g.Clear(Color.Black);
            }

            RenderRegionBiomes(region, 0, 31, 0, 31, OFFSETX, OFFSETY, b, toolTips);
        }
예제 #9
0
        public void SetDirtyFlags(RegionFile region)
        {
            if (lastBiomeAction == null || lastPopulateAction == null)
                throw new Exception("No record of last region save state.");

            region.Dirty = false;
            foreach (ChunkState state in lastBiomeAction.Chunks)
            {
                Chunk c = region.Chunks[state.Coords.X, state.Coords.Z];
                if (c == null)
                    continue;
                else if (c.Root == null)
                {
                    c.Dirty = false;
                    continue;
                }

                if (ByteArraysEqual((byte[])c.Root["Level"]["Biomes"], state.Biomes))
                {
                    c.Dirty = false;
                }
                else
                {
                    c.Dirty = true;
                    region.Dirty = true;
                }
            }

            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null)
                        continue;
                    else if (c.Root == null)
                    {
                        c.Dirty = false;
                        continue;
                    }

                    if (((byte)c.Root["Level"]["TerrainPopulated"]) != lastPopulateAction.PopulatedFlags[chunkX, chunkZ])
                    {
                        c.Dirty = true;
                        region.Dirty = true;
                    }
                }
            }
        }
예제 #10
0
 private void ApplyBiomeState(BiomeAction action, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, UpdateStatus updateStatus)
 {
     foreach (ChunkState state in action.Chunks)
     {
         Chunk c = region.Chunks[state.Coords.X, state.Coords.Z];
         if (c == null || c.Root == null)
             continue;
         ((TAG_Byte_Array)c.Root["Level"]["Biomes"]).Payload = (byte[])state.Biomes.Clone();
     }
     tooltips = new String[biomeOverlay.Width, biomeOverlay.Height];
     if (terrainOverlay != null)
     {
         updateStatus("Generating terrain map");
         RegionUtil.RenderRegionTerrain(region, terrainOverlay);
     }
     updateStatus("Generating biome map");
     RegionUtil.RenderRegionBiomes(region, biomeOverlay, tooltips);
     updateStatus("");
 }
예제 #11
0
 private void ResetControls()
 {
     lstRegions.Items.Clear();
     lastSelectedRegionIndex = -1;
     trackMagnification.Value = 1;
     lblMagnification.Text = "Magnification: 1x";
     imgRegion.Reset();
     region = null;
     dim = Dimension.Overworld;
     overworldToolStripMenuItem.Checked = true;
     netherToolStripMenuItem.Checked = false;
     endToolStripMenuItem.Checked = false;
     if (history != null)
         history.Dispose();
     history = new HistoryManager(HistoryChange);
     history.RecordSelectionState(imgRegion.Layers[SELECTIONLAYER].Image, "Initial State");
 }
예제 #12
0
        public void RecordPopulateState(RegionFile region, String description)
        {
            PopulateAction action = new PopulateAction(description);
            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null || c.Root == null)
                        continue;

                    action.PopulatedFlags[chunkX, chunkZ] = (byte)c.Root["Level"]["TerrainPopulated"];
                }
            }
            Add(action);
            OnChange();
        }
예제 #13
0
        private void lstRegions_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (world == null || lstRegions.SelectedIndex == lastSelectedRegionIndex)
                return;

            if (!SaveIfNecessary())
            {
                lstRegions.SelectedIndex = lastSelectedRegionIndex;
                return;
            }

            history.FilterOutType(typeof(BiomeAction));
            history.FilterOutType(typeof(PopulateAction));

            Match m = Regex.Match(lstRegions.SelectedItem.ToString(), @"Region (-?\d+), (-?\d+)");
            int x = int.Parse(m.Groups[1].Value);
            int z = int.Parse(m.Groups[2].Value);
            String pathFormat = String.Format("{0}{1}r.{{0}}.{{1}}.mca", world.GetRegionDirectory(dim), Path.DirectorySeparatorChar);

            UpdateStatus("Reading region file");
            region = new RegionFile(String.Format(pathFormat, x, z));
            history.RecordBiomeState(region, "Initial Biomes");
            history.RecordPopulateState(region, "Initial Populate Flags");
            history.SetLastSaveActions();
            imgRegion.Reset();
            UpdateStatus("Generating terrain map");
            RegionUtil.RenderRegionTerrain(region, imgRegion.Layers[MAPLAYER].Image, false);
            UpdateStatus("Generating biome map");
            RegionUtil.RenderRegionBiomes(region, imgRegion.Layers[BIOMELAYER].Image, imgRegion.ToolTips, false);
            UpdateStatus("");
            RegionUtil.RenderRegionChunkstobePopulated(region, imgRegion.Layers[POPULATELAYER].Image, false);
            imgRegion.Redraw();

            RegionFile[,] surrounding = new RegionFile[3, 3];
            UpdateStatus("Reading surrounding chunks");
            surrounding[0, 0] = new RegionFile(String.Format(pathFormat, x - 1, z - 1), 30, 31, 30, 31);
            surrounding[1, 0] = new RegionFile(String.Format(pathFormat, x, z - 1), 0, 31, 30, 31);
            surrounding[2, 0] = new RegionFile(String.Format(pathFormat, x + 1, z - 1), 0, 1, 30, 31);
            surrounding[0, 1] = new RegionFile(String.Format(pathFormat, x - 1, z), 30, 31, 0, 31);
            surrounding[1, 1] = null;
            surrounding[2, 1] = new RegionFile(String.Format(pathFormat, x + 1, z, 0, 1, 0, 31));
            surrounding[0, 2] = new RegionFile(String.Format(pathFormat, x - 1, z + 1), 30, 31, 0, 1);
            surrounding[1, 2] = new RegionFile(String.Format(pathFormat, x, z + 1), 0, 31, 0, 1);
            surrounding[2, 2] = new RegionFile(String.Format(pathFormat, x + 1, z + 1), 0, 1, 0, 1);
            UpdateStatus("Generating map for surrounding chunks");
            RegionUtil.RenderSurroundingRegions(surrounding, imgRegion.Layers[MAPLAYER].Image, imgRegion.Layers[BIOMELAYER].Image, imgRegion.ToolTips, imgRegion.Layers[POPULATELAYER].Image);
            UpdateStatus("");
            imgRegion.Redraw();

            lastSelectedRegionIndex = lstRegions.SelectedIndex;
        }
예제 #14
0
        public static void RenderRegionTerrain(RegionFile region, Bitmap b, bool clip = true)
        {
            using (Graphics g = Graphics.FromImage(b))
            {
                if(clip)
                    g.SetClip(CLIP);
                g.Clear(Color.Black);
            }

            RenderRegionTerrain(region, 0, 31, 0, 31, OFFSETX, OFFSETY, b);
        }
예제 #15
0
        public static void SetChunkstobePopulated(RegionFile region, Bitmap selection, Color selectionColor, byte value)
        {
            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null || c.Root == null)
                        continue;

                    bool done = false;
                    for (int z = 0; z < 16; z++)
                    {
                        for (int x = 0; x < 16; x++)
                        {
                            if (selection.GetPixel(OFFSETX + chunkX * 16 + x, OFFSETY + chunkZ * 16 + z).ToArgb() == selectionColor.ToArgb())
                            {
                                ((TAG_Byte)c.Root["Level"]["TerrainPopulated"]).Payload = value;
                                done = true;
                                break;
                            }
                        }
                        if (done)
                            break;
                    }
                }
            }
        }
예제 #16
0
 public static void Replace(RegionFile region, Bitmap selection, Color selectionColor, byte biome1, Object biome2, long worldSeed)
 {
     byte? biomeId;
     BiomeUtil util;
     GetBiome(biome2, worldSeed, out biomeId, out util);
     if (biomeId != null)
         Replace(region, selection, selectionColor, biome1, (byte)biomeId);
     else
         Replace(region, selection, selectionColor, biome1, util);
 }
예제 #17
0
        public static void RenderSurroundingRegions(RegionFile[,] regions, Bitmap terrain, Bitmap biomes, String[,] toolTips, Bitmap populate)
        {
            RenderSurroundingRegion(regions[0, 0], 30, 31, 30, 31, 0, 0, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[1, 0], 0, 31, 30, 31, OFFSETX, 0, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[2, 0], 0, 1, 30, 31, OFFSETX + WIDTH, 0, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[0, 1], 30, 31, 0, 31, 0, OFFSETY, terrain, biomes, toolTips, populate);

            RenderSurroundingRegion(regions[2, 1], 0, 1, 0, 31, OFFSETX + WIDTH, OFFSETY, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[0, 2], 30, 31, 0, 1, 0, OFFSETY + HEIGHT, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[1, 2], 0, 31, 0, 1, OFFSETX, OFFSETY + HEIGHT, terrain, biomes, toolTips, populate);
            RenderSurroundingRegion(regions[2, 2], 0, 1, 0, 1, OFFSETX + WIDTH, OFFSETY + HEIGHT, terrain, biomes, toolTips, populate);
        }
예제 #18
0
        private void reloadCurrentRegionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (world == null || region == null)
                return;

            UpdateStatus("Reading region file");
            region = new RegionFile(region.Path);
            history.RecordBiomeState(region, "Reload Biomes");
            history.RecordPopulateState(region, "Reload Populate Flags");
            history.SetLastSaveActions();
            UpdateStatus("Generating terrain map");
            RegionUtil.RenderRegionTerrain(region, imgRegion.Layers[MAPLAYER].Image);
            UpdateStatus("Generating biome map");
            RegionUtil.RenderRegionBiomes(region, imgRegion.Layers[BIOMELAYER].Image, imgRegion.ToolTips);
            UpdateStatus("");
            RegionUtil.RenderRegionChunkstobePopulated(region, imgRegion.Layers[POPULATELAYER].Image);
            imgRegion.Redraw();
        }
예제 #19
0
        private static void RenderRegionBiomes(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap biomes, String[,] toolTips)
        {
            for (int x = chunkStartX; x <= chunkEndX; x++)
            {
                for (int z = chunkStartZ; z <= chunkEndZ; z++)
                {
                    Chunk c = region.Chunks[x, z];
                    if (c == null || c.Root == null)
                        continue;
                    Coord chunkOffset = new Coord(c.Coords);
                    chunkOffset.ChunktoRegionRelative();
                    chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ);
                    chunkOffset.ChunktoAbsolute();
                    chunkOffset.Add(offsetX, offsetY);

                    RenderChunkBiomes(c, biomes, toolTips, chunkOffset.X, chunkOffset.Z);
                }
            }
        }
예제 #20
0
        public void RecordBiomeState(RegionFile region, String description)
        {
            BiomeAction action = new BiomeAction(description);
            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for(int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null || c.Root == null)
                        continue;

                    //first point of accessing chunk's biomes, make sure it exists
                    TAG_Compound level = (TAG_Compound)c.Root["Level"];
                    byte[] biomes;
                    if (level.Payload.ContainsKey("Biomes"))
                        biomes = (byte[])level["Biomes"];
                    else
                    {
                        biomes = new byte[256];
                        for (int i = 0; i < biomes.Length; i++)
                            biomes[i] = (byte)Biome.Unspecified;
                        level.Payload.Add("Biomes", new TAG_Byte_Array(biomes, "Biomes"));
                    }

                    action.Chunks.Add(new ChunkState(chunkX, chunkZ, (byte[])biomes.Clone()));
                }
            }
            Add(action);
            OnChange();
        }
예제 #21
0
        private static void RenderRegionChunkstobePopulated(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap populate)
        {
            using (Graphics g = Graphics.FromImage(populate))
            {
                Brush brush = new SolidBrush(Color.Yellow);
                for (int x = chunkStartX; x <= chunkEndX; x++)
                {
                    for (int z = chunkStartZ; z <= chunkEndZ; z++)
                    {
                        Chunk c = region.Chunks[x, z];
                        if (c == null || c.Root == null)
                            continue;
                        Coord chunkOffset = new Coord(c.Coords);
                        chunkOffset.ChunktoRegionRelative();
                        chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ);
                        chunkOffset.ChunktoAbsolute();
                        chunkOffset.Add(offsetX, offsetY);

                        RenderChunktobePopulated(c, g, brush, chunkOffset.X, chunkOffset.Z);
                    }
                }
                brush.Dispose();
            }
        }
예제 #22
0
        public void Redo(Bitmap selection, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, Bitmap populateOverlay, UpdateStatus updateStatus)
        {
            if (!MoveNext())
                return;

            if (undoStack.Last.Value.PreviousAction == null)
            {
                throw new Exception("Redo sanity check failed.");
            }

            if (undoStack.Last.Value is SelectionAction)
            {
                ApplySelectionState((SelectionAction)undoStack.Last.Value, selection);
            }
            else if (undoStack.Last.Value is BiomeAction)
            {
                ApplyBiomeState((BiomeAction)undoStack.Last.Value, region, terrainOverlay, biomeOverlay, ref tooltips, updateStatus);
            }
            else if (undoStack.Last.Value is PopulateAction)
            {
                ApplyPopulateState((PopulateAction)undoStack.Last.Value, region, populateOverlay);
            }

            OnChange();
        }
예제 #23
0
        private static void RenderRegionTerrain(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap map)
        {
            if (signal != null || mutex != null || taskCount > 0)
                throw new Exception("RenderRegionTerrain re-entered, shouldn't be possible.");

            signal = new ManualResetEvent(false);
            taskCount = (chunkEndX - chunkStartX + 1) * (chunkEndZ - chunkStartZ + 1);
            mutex = new Mutex();

            for (int x = chunkStartX; x <= chunkEndX; x++)
            {
                for (int z = chunkStartZ; z <= chunkEndZ; z++)
                {
                    Chunk c = region.Chunks[x, z];
                    if (c == null || c.Root == null)
                    {
                        if (Interlocked.Decrement(ref taskCount) == 0)
                            signal.Set();
                        continue;
                    }
                    Coord chunkOffset = new Coord(c.Coords);
                    chunkOffset.ChunktoRegionRelative();
                    chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ);
                    chunkOffset.ChunktoAbsolute();
                    chunkOffset.Add(offsetX, offsetY);

                    ThreadPool.QueueUserWorkItem(RenderChunkTerrain, new Object[]{c, map, chunkOffset.X, chunkOffset.Z});
                }
            }

            signal.WaitOne();
            signal.Dispose();
            signal = null;
            mutex.WaitOne();
            mutex.ReleaseMutex();
            mutex.Dispose();
            mutex = null;
        }
예제 #24
0
        public void Undo(Bitmap selection, RegionFile region, Bitmap terrainOverlay, Bitmap biomeOverlay, ref String[,] tooltips, Bitmap populateOverlay, UpdateStatus updateStatus)
        {
            while (undoStack.Count > 0 && undoStack.Last.Value.PreviousAction == null)
            {
                redoStack.AddLast(undoStack.Last.Value);
                undoStack.RemoveLast();
            }

            if (undoStack.Count == 0)
                return;

            IAction previous = undoStack.Last.Value.PreviousAction;
            if (previous == null)
            {
                throw new Exception("Undo sanity check failed.");
            }

            if (previous is SelectionAction)
            {
                ApplySelectionState((SelectionAction)previous, selection);
            }
            else if (previous is BiomeAction)
            {
                ApplyBiomeState((BiomeAction)previous, region, terrainOverlay, biomeOverlay, ref tooltips, updateStatus);
            }
            else if (previous is PopulateAction)
            {
                ApplyPopulateState((PopulateAction)previous, region, populateOverlay);
            }

            MovePrevious();
            OnChange();
        }
예제 #25
0
 private static void RenderSurroundingRegion(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap terrain, Bitmap biomes, String[,] toolTips, Bitmap populate)
 {
     RenderRegionTerrain(region, chunkStartX, chunkEndX, chunkStartZ, chunkEndZ, offsetX, offsetY, terrain);
     RenderRegionBiomes(region, chunkStartX, chunkEndX, chunkStartZ, chunkEndZ, offsetX, offsetY, biomes, toolTips);
     RenderRegionChunkstobePopulated(region, chunkStartX, chunkEndX, chunkStartZ, chunkEndZ, offsetX, offsetY, populate);
 }
예제 #26
0
        private void ApplyPopulateState(PopulateAction action, RegionFile region, Bitmap populateOverlay)
        {
            for (int chunkX = 0; chunkX < 32; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < 32; chunkZ++)
                {
                    Chunk c = region.Chunks[chunkX, chunkZ];
                    if (c == null || c.Root == null)
                        continue;

                    ((TAG_Byte)c.Root["Level"]["TerrainPopulated"]).Payload = action.PopulatedFlags[chunkX, chunkZ];
                }
            }
            RegionUtil.RenderRegionChunkstobePopulated(region, populateOverlay);
        }
예제 #27
0
        private static void Replace(RegionFile region, Bitmap selection, Color selectionColor, byte search, BiomeUtil replace)
        {
            foreach (Chunk c in region.Chunks)
            {
                if (c.Root == null)
                    continue;
                Coord chunkOffset = new Coord(region.Coords);
                chunkOffset.RegiontoChunk();
                chunkOffset = new Coord(c.Coords.X - chunkOffset.X, c.Coords.Z - chunkOffset.Z);
                chunkOffset.ChunktoAbsolute();

                Coord chunkAbs = new Coord(c.Coords);
                chunkAbs.ChunktoAbsolute();

                byte[] biomes = (byte[])c.Root["Level"]["Biomes"];

                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        if (selection == null || (selection.GetPixel(OFFSETX + chunkOffset.X + x, OFFSETY + chunkOffset.Z + z).ToArgb() == selectionColor.ToArgb()))
                        {
                            if (biomes[x + z * 16] == search)
                            {
                                biomes[x + z * 16] = (byte)replace.GetBiome(chunkAbs.X + x, chunkAbs.Z + z);
                            }
                        }
                    }
                }
            }
        }
예제 #28
0
        public void Render()
        {
            Point topLeft = new Point(int.MaxValue, int.MaxValue);
            Point bottomRight = new Point(int.MinValue, int.MinValue);

            if (LowerLimit > UpperLimit)
            {
                int temp = LowerLimit;
                LowerLimit = UpperLimit;
                UpperLimit = temp;
            }

            if (Only != null && Exclude != null)
            {
                foreach (byte b in Exclude)
                {
                    if (Only.Contains(b))
                        Only.Remove(b);
                }
                Exclude = null;
            }

            String[] paths = Directory.GetFiles(regionDir, "*.mca", SearchOption.TopDirectoryOnly);

            foreach (String path in paths)
            {
                Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mca");
                Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
                c.RegiontoAbsolute();
                if (c.X < topLeft.X)
                    topLeft.X = c.X;
                if (c.Z < topLeft.Y)
                    topLeft.Y = c.Z;
                c.Add(REGIONWIDTH, REGIONHEIGHT);
                if (c.X > bottomRight.X)
                    bottomRight.X = c.X;
                if (c.Z > bottomRight.Y)
                    bottomRight.Y = c.Z;
            }

            String format = String.Format("Reading region {{0}} of {0}", paths.Length);
            int count = 0;

            if (LessMemory)
            {
                int regionsWide = (bottomRight.X - topLeft.X) / REGIONWIDTH;
                int regionsTall = (bottomRight.Y - topLeft.Y) / REGIONHEIGHT;
                Point regionTopLeft = new Point(topLeft.X / REGIONWIDTH, topLeft.Y / REGIONHEIGHT);
                String[,] regions = new String[regionsWide, regionsTall];

                foreach (String path in paths)
                {
                    Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mc[ar]");
                    Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value));
                    c.Add(-regionTopLeft.X, -regionTopLeft.Y);
                    regions[c.X, c.Z] = path;
                }

                Bitmap strip = new Bitmap(bottomRight.X - topLeft.X, REGIONHEIGHT, PixelFormat.Format32bppArgb);
                PngWriter writer = new PngWriter(outPath, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);

                for (int y = 0; y < regionsTall; y++)
                {
                    using (Graphics g = Graphics.FromImage(strip))
                    {
                        g.Clear(Color.Transparent);
                    }

                    for (int x = 0; x < regionsWide; x++)
                    {
                        if (regions[x, y] != null)
                        {
                            count++;
                            if (updateStatus != null)
                                updateStatus(String.Format(format, count));
                            if (log != null)
                            {
                                log.Write(String.Format(format, count));
                                log.WriteLine(String.Format(" :: {0}", Path.GetFileName(regions[x, y])));
                            }

                            RegionFile region = new RegionFile(regions[x, y]);
                            Coord offset = new Coord(region.Coords);
                            offset.RegiontoAbsolute();
                            offset.X -= topLeft.X;

                            if (BiomeOverlay)
                                RenderRegionBiomes(region, strip, offset.X, 0);
                            else
                                RenderRegion(region, strip, offset.X, 0);
                        }
                    }
                    writer.WriteBitmap(strip);
                }

                writer.Close();
                strip.Dispose();
            }
            else
            {
                Bitmap map = new Bitmap(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
                foreach (String path in paths)
                {
                    count++;
                    if (updateStatus != null)
                        updateStatus(String.Format(format, count));
                    if (log != null)
                    {
                        log.Write(String.Format(format, count));
                        log.WriteLine(String.Format(" :: {0}", Path.GetFileName(path)));
                    }
                    RegionFile region = new RegionFile(path);
                    Coord offset = new Coord(region.Coords);
                    offset.RegiontoAbsolute();
                    offset.Add(-topLeft.X, -topLeft.Y);

                    if (BiomeOverlay)
                        RenderRegionBiomes(region, map, offset.X, offset.Z);
                    else
                        RenderRegion(region, map, offset.X, offset.Z);
                }

                if (CropMap)
                    map = Crop(map);
                Rotate = (Rotate % 360) / 90;
                if (Rotate == 1)
                    map.RotateFlip(RotateFlipType.Rotate90FlipNone);
                else if (Rotate == 2)
                    map.RotateFlip(RotateFlipType.Rotate180FlipNone);
                else if (Rotate == 3)
                    map.RotateFlip(RotateFlipType.Rotate270FlipNone);

                map.Save(outPath, ImageFormat.Png);
                map.Dispose();

            }

            if (updateStatus != null)
                updateStatus("Done");
            if (log != null)
                log.WriteLine("Done");
            if (callback != null)
                callback();
        }
예제 #29
0
 public static void Fill(RegionFile region, Bitmap selection, Color selectionColor, Object biome, long worldSeed)
 {
     byte? biomeId;
     BiomeUtil util;
     GetBiome(biome, worldSeed, out biomeId, out util);
     if (biomeId != null)
         Fill(region, selection, selectionColor, (byte)biomeId);
     else
         Fill(region, selection, selectionColor, util);
 }