1 package maps 2 3 import ( 4 "image" 5 "image/color" 6 7 "vimagination.zapto.org/minecraft" 8 ) 9 10 // Image represents a Minecraft Map 11 type Image struct { 12 level *minecraft.Level 13 bounds image.Rectangle 14 scale uint8 15 y int32 16 width, height int 17 colour func(minecraft.Block) color.Color 18 } 19 20 // ColorModel returns the palette for the map 21 func (Image) ColorModel() color.Model { 22 return palette 23 } 24 25 // Bounds returns the dimensions of the map 26 func (i Image) Bounds() image.Rectangle { 27 return image.Rectangle{ 28 Min: image.Point{}, 29 Max: image.Point{i.width, i.height}, 30 } 31 } 32 33 // At returns the colour at the specified coords 34 func (i Image) At(x, z int) color.Color { 35 var y int32 36 if i.y < 0 { 37 var err error 38 y, err = i.level.GetHeight(int32(x), int32(z)) 39 if err != nil { 40 return color.Transparent 41 } 42 } else { 43 y = i.y 44 } 45 b, err := i.level.GetBlock(int32(x), y, int32(z)) 46 if err != nil { 47 return color.Transparent 48 } 49 return i.colour(b) 50 } 51 52 // BlockColor is the standard block-to-colour func 53 func BlockColor(b minecraft.Block) color.Color { 54 if c, ok := colours[uint32(b.ID)<<16|uint32(b.Data)]; ok { 55 return palette[c] 56 } 57 if c, ok := colours[uint32(b.ID)]; ok { 58 return palette[c] 59 } 60 return color.Transparent 61 } 62 63 // Option represents a optional parameter for a map type 64 type Option func(*Image) 65 66 // FixedY is an options to fix the Y-coord of the blocks to be read. By default 67 // the highest, non-transparent block is usedd. 68 func FixedY(y int32) Option { 69 return func(i *Image) { 70 i.y = y 71 } 72 } 73 74 // Scale sets the scale the map is to be rendered at. 75 func Scale(s uint8) Option { 76 return func(i *Image) { 77 i.scale = s 78 } 79 } 80 81 // ColorFunc is an option for NewMap that specifies what colour blocks are 82 // painted as. 83 func ColorFunc(c func(minecraft.Block) color.Color) Option { 84 return func(i *Image) { 85 i.colour = c 86 } 87 } 88 89 // NewMap creates an image from a Minecraft level. 90 func NewMap(l *minecraft.Level, bounds image.Rectangle, options ...Option) Image { 91 i := Image{ 92 level: l, 93 bounds: bounds, 94 scale: 3, 95 y: -1, 96 colour: BlockColor, 97 } 98 for _, o := range options { 99 o(&i) 100 } 101 i.width = bounds.Dx() >> i.scale 102 i.height = bounds.Dy() >> i.scale 103 return i 104 } 105 106 var colours = map[uint32]uint8{} 107