Beispiel #1
0
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
}
Beispiel #2
0
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()
	}
}
Beispiel #3
0
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})
				}
			}
		}
	}
}