mapgen moving to delanay -> minimum spanning tree for rooms connection

This commit is contained in:
2019-11-11 01:47:16 +03:00
parent b734e538f4
commit e30aa33715
16 changed files with 380 additions and 73 deletions

View File

@ -5,12 +5,38 @@ import (
"lab.zaar.be/thefish/alchemyst-go/engine/types"
"lab.zaar.be/thefish/alchemyst-go/util"
)
//fixme move to config
var minRoomSize = 3
var maxRoomSize = 22
var maxrooms = 50
//fixme make closure to stack them
var fges = map[int]types.RectFill{
1: types.RectFill{
Top: func() *gamemap.Tile { return gamemap.NewWall() },
Bottom: func() *gamemap.Tile { return gamemap.NewWall() },
Left: func() *gamemap.Tile { return gamemap.NewWall() },
Right: func() *gamemap.Tile { return gamemap.NewWall() },
BottomLeft: func() *gamemap.Tile { return gamemap.NewWall() },
BottomRight: func() *gamemap.Tile { return gamemap.NewWall() },
TopLeft: func() *gamemap.Tile { return gamemap.NewWall() },
TopRight: func() *gamemap.Tile { return gamemap.NewWall() },
Body: func() *gamemap.Tile { return gamemap.NewFloor() },
},
2: types.RectFill{
Top: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Bottom: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Left: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Right: func() *gamemap.Tile { return gamemap.NewWaterTile() },
BottomLeft: func() *gamemap.Tile { return gamemap.NewWaterTile() },
BottomRight: func() *gamemap.Tile { return gamemap.NewWaterTile() },
TopLeft: func() *gamemap.Tile { return gamemap.NewWaterTile() },
TopRight: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Body: func() *gamemap.Tile { return gamemap.NewDeepWaterTile() },
},
}
func DefaultGen(l *gamemap.Level) (*gamemap.Level, []*gamemap.Room) {
rng := util.NewRNG()
@ -24,35 +50,26 @@ func DefaultGen(l *gamemap.Level) (*gamemap.Level, []*gamemap.Room) {
rooms := make([]*gamemap.Room, 0)
//one wall around whole level guaranteed
levelBoundary := types.NewRect(l.X + 1, l.Y + 1, l.W - 2, l.H - 2)
for i := 0; i < maxrooms; i++ {
newRoom := &gamemap.Room{
Rect: types.NewRect(
rng.Range(l.X, l.W),
rng.Range(l.Y, l.H),
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
)}
newRoom.Center = types.Coords{newRoom.X + newRoom.W / 2, newRoom.Y + newRoom.H / 2}
failed := false
if !levelBoundary.InBounds(types.Coords{newRoom.X, newRoom.Y}) {
failed = true
var failed = false
var fillage types.RectFill
fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})]
newRoom := gamemap.NewRandomRectRoom(
rng,
rng.Range(minRoomSize, maxRoomSize),
rng.Range(minRoomSize, maxRoomSize),
fillage,
)
where := types.Coords{
rng.Range(1, l.W -2 - newRoom.W),
rng.Range(1, l.H - 2 - newRoom.H),
}
if !failed && !l.InBounds(types.Coords{newRoom.X + newRoom.W, newRoom.Y + newRoom.H}) {
failed = true
}
if !failed {
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
for _, otherRoom := range rooms {
if otherRoom.Intersects(newRoom.Rect) {
failed = true
break
}
}
@ -60,61 +77,31 @@ func DefaultGen(l *gamemap.Level) (*gamemap.Level, []*gamemap.Room) {
rooms = append(rooms, newRoom)
}
newRoom.BlitToLevel(l, where)
//addStairs(rooms)
//itemize(rooms)
}
fges := map[int]types.RectFill{
1: types.RectFill{
Top: func() *gamemap.Tile { return gamemap.NewWall() },
Bottom: func() *gamemap.Tile { return gamemap.NewWall() },
Left: func() *gamemap.Tile { return gamemap.NewWall() },
Right: func() *gamemap.Tile { return gamemap.NewWall() },
BottomLeft: func() *gamemap.Tile { return gamemap.NewWall() },
BottomRight: func() *gamemap.Tile { return gamemap.NewWall() },
TopLeft: func() *gamemap.Tile { return gamemap.NewWall() },
TopRight: func() *gamemap.Tile { return gamemap.NewWall() },
Body: func() *gamemap.Tile { return gamemap.NewFloor() },
},
2: types.RectFill{
Top: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Bottom: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Left: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Right: func() *gamemap.Tile { return gamemap.NewWaterTile() },
BottomLeft: func() *gamemap.Tile { return gamemap.NewWaterTile() },
BottomRight: func() *gamemap.Tile { return gamemap.NewWaterTile() },
TopLeft: func() *gamemap.Tile { return gamemap.NewWaterTile() },
TopRight: func() *gamemap.Tile { return gamemap.NewWaterTile() },
Body: func() *gamemap.Tile { return gamemap.NewDeepWaterTile() },
},
}
var fillage types.RectFill
for _, room := range rooms {
fillage = fges[rng.GetWeightedEntity(map[int]int{1:10, 2:1})]
room.Blit(fillage, l)
}
for idx, room := range rooms {
if idx > 0 {
connectRooms(l, room, rooms[idx-1], fillage, rng.Range(0,1))
connectRooms(l, room, rooms[idx-1], fillage, rng.Range(0, 1))
}
}
return l, rooms
}
func connectRooms (l *gamemap.Level, room, otherRoom *gamemap.Room, fillage types.RectFill, toss int) {
func connectRooms(l *gamemap.Level, room, otherRoom *gamemap.Room, fillage types.RectFill, toss int) {
if toss == 0 {
digHTunnel(l, room.Center.X,otherRoom.Center.X,room.Center.Y, fillage)
digVTunnel(l, room.Center.Y,otherRoom.Center.Y,otherRoom.Center.X, fillage)
digHTunnel(l, room.Center.X, otherRoom.Center.X, room.Center.Y, fillage)
digVTunnel(l, room.Center.Y, otherRoom.Center.Y, otherRoom.Center.X, fillage)
} else {
digVTunnel(l, room.Center.Y, otherRoom.Center.Y, room.Center.Y, fillage)
digHTunnel(l, room.Center.X, otherRoom.Center.X, otherRoom.Center.Y, fillage)
}
}
func digHTunnel(l *gamemap.Level, x1,x2,y int, fillage types.RectFill) {
func digHTunnel(l *gamemap.Level, x1, x2, y int, fillage types.RectFill) {
var start, finish int
if x1 < x2 {
start = x1
@ -131,7 +118,7 @@ func digHTunnel(l *gamemap.Level, x1,x2,y int, fillage types.RectFill) {
}
}
func digVTunnel(l *gamemap.Level, y1,y2,x int, fillage types.RectFill) {
func digVTunnel(l *gamemap.Level, y1, y2, x int, fillage types.RectFill) {
var start, finish int
if y1 < y2 {
start = y1