Files
go-mc/bot/path/movement.go
2020-09-23 15:23:47 -07:00

180 lines
4.1 KiB
Go

package path
// Movement represents a single type of movement in a path.
type Movement uint8
var allMovements = []Movement{TraverseNorth, TraverseSouth, TraverseEast, TraverseWest,
TraverseNorthWest, TraverseNorthEast, TraverseSouthWest, TraverseSouthEast,
DropNorth, DropSouth, DropEast, DropWest,
AscendNorth, AscendSouth, AscendEast, AscendWest,
}
// Valid movement values.
const (
Waypoint Movement = iota
TraverseNorth
TraverseSouth
TraverseEast
TraverseWest
TraverseNorthEast
TraverseNorthWest
TraverseSouthEast
TraverseSouthWest
DropNorth
DropSouth
DropEast
DropWest
AscendNorth
AscendSouth
AscendEast
AscendWest
)
func (m Movement) Possible(nav *Nav, x, y, z int, from V3) bool {
// fmt.Printf("%s.Possible(%d,%d,%d)\n", m, x, y, z)
switch m {
case Waypoint, TraverseNorth, TraverseSouth, TraverseEast, TraverseWest:
if !SteppableBlock(nav.World.GetBlockStatus(x, y, z)) {
return false
}
return AirLikeBlock(nav.World.GetBlockStatus(x, y+1, z)) && AirLikeBlock(nav.World.GetBlockStatus(x, y+2, z))
case TraverseNorthWest, TraverseNorthEast, TraverseSouthWest, TraverseSouthEast:
if !SteppableBlock(nav.World.GetBlockStatus(x, y, z)) {
return false
}
if !AirLikeBlock(nav.World.GetBlockStatus(x, y+1, z)) || !AirLikeBlock(nav.World.GetBlockStatus(x, y+2, z)) {
return false
}
if !AirLikeBlock(nav.World.GetBlockStatus(from.X, y+1, z)) || !AirLikeBlock(nav.World.GetBlockStatus(from.X, y+2, z)) {
return false
}
return AirLikeBlock(nav.World.GetBlockStatus(x, y+1, from.Z)) && AirLikeBlock(nav.World.GetBlockStatus(x, y+2, from.Z))
case DropNorth, DropSouth, DropEast, DropWest:
for amt := 0; amt < 3; amt++ {
if !AirLikeBlock(nav.World.GetBlockStatus(x, y+amt+1, z)) {
return false
}
}
return SteppableBlock(nav.World.GetBlockStatus(x, y, z))
case AscendNorth, AscendSouth, AscendEast, AscendWest:
if !AirLikeBlock(nav.World.GetBlockStatus(x, y+1, z)) || !AirLikeBlock(nav.World.GetBlockStatus(x, y+2, z)) {
return false
}
return SteppableBlock(nav.World.GetBlockStatus(x, y, z)) &&
AirLikeBlock(nav.World.GetBlockStatus(from.X, from.Y+1, from.Z)) &&
AirLikeBlock(nav.World.GetBlockStatus(from.X, from.Y+2, from.Z))
default:
panic(m)
}
}
func (m Movement) Offset() (x, y, z int) {
switch m {
case Waypoint:
return 0, 0, 0
case TraverseNorth:
return 0, 0, -1
case TraverseSouth:
return 0, 0, 1
case TraverseEast:
return 1, 0, 0
case TraverseWest:
return -1, 0, 0
case DropNorth:
return 0, -1, -1
case DropSouth:
return 0, -1, 1
case DropEast:
return 1, -1, 0
case DropWest:
return -1, -1, 0
case AscendNorth:
return 0, 1, -1
case AscendSouth:
return 0, 1, 1
case AscendEast:
return 1, 1, 0
case AscendWest:
return -1, 1, 0
case TraverseNorthWest:
return -1, 0, -1
case TraverseNorthEast:
return 1, 0, -1
case TraverseSouthWest:
return -1, 0, 1
case TraverseSouthEast:
return 1, 0, 1
default:
panic(m)
}
}
func (m Movement) BaseCost() float64 {
switch m {
case Waypoint:
return 0
case TraverseNorth, TraverseSouth, TraverseEast, TraverseWest:
return 1
case TraverseNorthWest, TraverseNorthEast, TraverseSouthWest, TraverseSouthEast:
return 1.25
case DropNorth, DropSouth, DropEast, DropWest:
return 2
case AscendNorth, AscendSouth, AscendEast, AscendWest:
return 2.25
default:
panic(m)
}
}
func (m Movement) String() string {
switch m {
case Waypoint:
return "waypoint"
case TraverseNorth:
return "traverse-north"
case TraverseSouth:
return "traverse-south"
case TraverseEast:
return "traverse-east"
case TraverseWest:
return "traverse-west"
case DropNorth:
return "drop-north"
case DropSouth:
return "drop-south"
case DropEast:
return "drop-east"
case DropWest:
return "drop-west"
case AscendNorth:
return "jump-north"
case AscendSouth:
return "jump-south"
case AscendEast:
return "jump-east"
case AscendWest:
return "jump-west"
case TraverseNorthWest:
return "traverse-northwest"
case TraverseNorthEast:
return "traverse-northeast"
case TraverseSouthWest:
return "traverse-southwest"
case TraverseSouthEast:
return "traverse-southeast"
default:
panic(m)
}
}