summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Chabowski <kevin@kch42.de>2013-09-21 00:48:59 +0200
committerKevin Chabowski <kevin@kch42.de>2013-09-21 00:48:59 +0200
commitf051ce2392bc0bfae52945e8f53fe38f2d095637 (patch)
tree9cf7e28b009757747d12c5d4ac3e36a6469d4295
parentfc3743db98c3cc9f800cd50ae087e505ff260c0c (diff)
downloadgomcmap-f051ce2392bc0bfae52945e8f53fe38f2d095637.tar.gz
gomcmap-f051ce2392bc0bfae52945e8f53fe38f2d095637.tar.bz2
gomcmap-f051ce2392bc0bfae52945e8f53fe38f2d095637.zip
Deleting chunks implemented.
-rw-r--r--README.markdown1
-rw-r--r--mcmap/chunk.go5
-rw-r--r--mcmap/examples/delchunk/.gitignore1
-rw-r--r--mcmap/examples/delchunk/main.go41
-rw-r--r--mcmap/region.go27
5 files changed, 66 insertions, 9 deletions
diff --git a/README.markdown b/README.markdown
index 3a06e1f..3e493b7 100644
--- a/README.markdown
+++ b/README.markdown
@@ -20,7 +20,6 @@ Although I tested the library with some maps, I can't guarantee that everything
## Wishlist / TODO
-* Removing chunks.
* Recalculating light data.
* Reading and modifying level.dat and other files (currently only the region files are used).
* Test compatibility with older versions of Minecraft.
diff --git a/mcmap/chunk.go b/mcmap/chunk.go
index 9196776..dfac5a7 100644
--- a/mcmap/chunk.go
+++ b/mcmap/chunk.go
@@ -54,6 +54,8 @@ type Chunk struct {
blocks []Block // Ordered YZX
biomes []Biome // Ordered ZX
+ deleted bool
+
reg *Region
}
@@ -132,6 +134,9 @@ func (c *Chunk) SetBiome(x, z int, bio Biome) { c.biomes[z*ChunkSizeXZ+x] = bio
// If the chunk was modified, call MarkModified BEFORE.
func (c *Chunk) MarkUnused() error { return c.reg.unloadChunk(int(c.x), int(c.z)) }
+// MarkDeleted marks this chunk as deleted. After marking it as unused, it will be deleted and can no longer be used.
+func (c *Chunk) MarkDeleted() { c.deleted = true }
+
// RecalcHeightMap recalculates the internal height map.
//
// You should use this function before marking the chunk as unused, if you modified the chunk
diff --git a/mcmap/examples/delchunk/.gitignore b/mcmap/examples/delchunk/.gitignore
new file mode 100644
index 0000000..732afb9
--- /dev/null
+++ b/mcmap/examples/delchunk/.gitignore
@@ -0,0 +1 @@
+delchunk
diff --git a/mcmap/examples/delchunk/main.go b/mcmap/examples/delchunk/main.go
new file mode 100644
index 0000000..c8996a5
--- /dev/null
+++ b/mcmap/examples/delchunk/main.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "github.com/kch42/gomcmap/mcmap"
+ "os"
+)
+
+func main() {
+ path := flag.String("path", "", "Path to region directory")
+ flag.Parse()
+
+ if *path == "" {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ region, err := mcmap.OpenRegion(*path, false)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Could not open region: %s\n", err)
+ os.Exit(1)
+ }
+
+ chunk, err := region.Chunk(200, 200)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error getting chunk 200,200: %s\n", err)
+ os.Exit(1)
+ }
+
+ chunk.MarkDeleted()
+ if err := chunk.MarkUnused(); err != nil {
+ fmt.Fprintf(os.Stderr, "Could not mark chunk as unused: %s\n", err)
+ os.Exit(1)
+ }
+
+ if err := region.Save(); err != nil {
+ fmt.Fprintf(os.Stderr, "Could not save region: %s\n", err)
+ os.Exit(1)
+ }
+}
diff --git a/mcmap/region.go b/mcmap/region.go
index 34b3334..93c8693 100644
--- a/mcmap/region.go
+++ b/mcmap/region.go
@@ -157,15 +157,23 @@ func (reg *Region) cleanSuperchunks(forceSave bool) error {
if !(reg.autosave || forceSave) {
continue
}
+
fn := fmt.Sprintf("%s%cr.%d.%d.mca", reg.path, os.PathSeparator, scPos.X, scPos.Z)
- f, err := os.Create(fn)
- if err != nil {
- return err
- }
- defer f.Close()
- if err := writeRegionFile(f, sc.preChunks); err != nil {
- return err
+ if len(sc.preChunks) == 0 {
+ if err := os.Remove(fn); err != nil {
+ return err
+ }
+ } else {
+ f, err := os.Create(fn)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ if err := writeRegionFile(f, sc.preChunks); err != nil {
+ return err
+ }
}
}
@@ -239,7 +247,10 @@ func (reg *Region) unloadChunk(x, z int) error {
return nil
}
- if chunk.modified {
+ if chunk.deleted {
+ delete(sc.preChunks, cPos)
+ sc.modified = true
+ } else if chunk.modified {
pc, err := chunk.toPreChunk()
if err != nil {
return err