180 lines
4.1 KiB
Go
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)
|
|
}
|
|
}
|