func (rw *RegionWrapper) GetBiomeAt(x, z int) (mcmap.Biome, bool) { cx, cz, bx, bz := mcmap.BlockToChunk(x, z) pos := XZPos{cx, cz} if bc, ok := rw.bioCache[pos]; ok { return bc[bz*mcmap.ChunkSizeXZ+bx], true } if !rw.RegionLoaded() { return mcmap.BioUncalculated, false } chunk, err := rw.region.Chunk(cx, cz) switch err { case nil: case mcmap.NotAvailable: return mcmap.BioUncalculated, false default: rw.guicbs.reportFail(fmt.Sprintf("Error while getting chunk %d, %d: %s", cx, cz, err)) return mcmap.BioUncalculated, false } bc := make([]mcmap.Biome, mcmap.ChunkRectXZ) i := 0 for z := 0; z < mcmap.ChunkSizeXZ; z++ { for x := 0; x < mcmap.ChunkSizeXZ; x++ { bc[i] = chunk.Biome(x, z) i++ } } rw.bioCache[pos] = bc return chunk.Biome(bx, bz), true }
func (rw *RegionWrapper) SetBiomeAt(x, z int, bio mcmap.Biome) { cx, cz, bx, bz := mcmap.BlockToChunk(x, z) pos := XZPos{cx, cz} chunk, err := rw.region.Chunk(cx, cz) switch err { case nil: case mcmap.NotAvailable: return default: rw.guicbs.reportFail(fmt.Sprintf("Error while getting chunk %d, %d: %s", cx, cz, err)) return } chunk.SetBiome(bx, bz, bio) var newcol *gdk.Color if rw.fixSnowIce { newcol = rw.fixWeather(bio, bx, bz, chunk) } chunk.MarkModified() // Update cache if bc, ok := rw.bioCache[pos]; ok { bc[bz*mcmap.ChunkSizeXZ+bx] = bio } // Update tile if biotile, ok := rw.Biotiles[pos]; ok { gdk.ThreadsEnter() drawable := biotile.GetDrawable() gc := gdk.NewGC(drawable) gc.SetRgbFgColor(rw.bioLookup.Color(bio)) drawable.DrawRectangle(gc, true, bx*zoom, bz*zoom, zoom, zoom) if newcol != nil { drawable = rw.Maptiles[pos].GetDrawable() gc = gdk.NewGC(drawable) gc.SetRgbFgColor(newcol) drawable.DrawRectangle(gc, true, bx*zoom, bz*zoom, zoom, zoom) } gdk.ThreadsLeave() } }
func (f *fillTool) Do(bio mcmap.Biome, biogs BiomeGetSetter, x, z int) { oldbio, ok := biogs.GetBiomeAt(x, z) if (!ok) || (oldbio == bio) { return } inChunkQueue := []XZPos{} outOfChunkQueue := []XZPos{{x, z}} for { oocqL := len(outOfChunkQueue) - 1 if oocqL < 0 { break } pos := outOfChunkQueue[oocqL] inChunkQueue = []XZPos{pos} outOfChunkQueue = outOfChunkQueue[:oocqL] cx, cz, _, _ := mcmap.BlockToChunk(pos.X, pos.Z) xStart := cx * mcmap.ChunkSizeXZ zStart := cz * mcmap.ChunkSizeXZ xEnd := xStart + mcmap.ChunkSizeXZ zEnd := zStart + mcmap.ChunkSizeXZ for { icqL := len(inChunkQueue) - 1 if icqL < 0 { break } pos := inChunkQueue[icqL] inChunkQueue = inChunkQueue[:icqL] px, pz := pos.X, pos.Z if haveBio, ok := biogs.GetBiomeAt(px, pz); ok && (haveBio == oldbio) { biogs.SetBiomeAt(px, pz, bio) nx, nz := px+1, pz if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) } else { outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) } nx, nz = px-1, pz if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) } else { outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) } nx, nz = px, pz+1 if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) } else { outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) } nx, nz = px, pz-1 if chkBounds(nx, nz, xStart, zStart, xEnd, zEnd) { inChunkQueue = append(inChunkQueue, XZPos{nx, nz}) } else { outOfChunkQueue = append(outOfChunkQueue, XZPos{nx, nz}) } } } } }