summaryrefslogtreecommitdiff
path: root/tools.go
blob: ffb763af622f773255c6856d4b54ed877e293bab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package main

import (
	"github.com/kch42/gomcmap/mcmap"
)

type BiomeGetter interface {
	GetBiome(x, z int) (mcmap.Biome, bool)
}

type XZPos struct {
	X, Z int
}

type Change map[XZPos]mcmap.Biome

type Tool interface {
	SingleClick() bool // Whether only one click should be performed (true) or the action should be repeated, if the mouse is dragged
	Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change
}

type drawTool struct {
	radGetter func() int
}

func (d *drawTool) SingleClick() bool { return false }

func (d *drawTool) Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change {
	rad := d.radGetter()
	if rad <= 0 {
		return nil
	}

	change := make(Change)
	for xp := x - (rad - 1); xp < x+rad; xp++ {
		for zp := z - (rad - 1); zp < z+rad; zp++ {
			change[XZPos{xp, zp}] = bio
		}
	}

	return change
}

func NewDrawTool(radGetter func() int) *drawTool {
	return &drawTool{radGetter}
}

type fillTool struct{}

func (f *fillTool) SingleClick() bool { return true }

func (f *fillTool) Do(bio mcmap.Biome, bioget BiomeGetter, x, z int) Change {
	oldbio, ok := bioget.GetBiome(x, z)
	if !ok {
		return nil
	}

	change := make(Change)
	floodfill(oldbio, bio, bioget, x, z, change)
	return change
}

func floodfill(oldbio, newbio mcmap.Biome, bioget BiomeGetter, x, z int, change Change) {
	pos := XZPos{x, z}
	if _, ok := change[pos]; ok {
		return
	}

	if bio, ok := bioget.GetBiome(x, z); ok && (bio == oldbio) {
		change[pos] = newbio

		floodfill(oldbio, newbio, bioget, x-1, z, change)
		floodfill(oldbio, newbio, bioget, x+1, z, change)
		floodfill(oldbio, newbio, bioget, x, z-1, change)
		floodfill(oldbio, newbio, bioget, x, z+1, change)
	}
}

func NewFillTool() *fillTool {
	return new(fillTool)
}