package mapgens import ( "lab.zaar.be/thefish/alchemyst-go/engine/gamemap" "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 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() //fill with walls for i := 0; i < l.W; i ++ { for j := 0; j < l.H; j++ { l.SetTileByXY(i, j, gamemap.NewWall()) } } rooms := make([]*gamemap.Room, 0) for i := 0; i < maxrooms; i++ { 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), } for _, otherRoom := range rooms { if otherRoom.Intersects(newRoom.Rect) { failed = true break } } if !failed { rooms = append(rooms, newRoom) } newRoom.BlitToLevel(l, where) //addStairs(rooms) //itemize(rooms) } for idx, room := range rooms { if idx > 0 { 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) { 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) } 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) { var start, finish int if x1 < x2 { start = x1 finish = x2 } else { start = x2 finish = x1 } for i := start; i <= finish; i++ { if l.InBounds(types.Coords{i, y}) { l.SetTileByXY(i, y, fillage.Body.(func() *gamemap.Tile)()) //l.Tiles[i][y] = gamemap.NewFloor() } } } func digVTunnel(l *gamemap.Level, y1, y2, x int, fillage types.RectFill) { var start, finish int if y1 < y2 { start = y1 finish = y2 } else { start = y2 finish = y1 } for i := start; i <= finish; i++ { if l.InBounds(types.Coords{x, i}) { l.SetTileByXY(x, i, fillage.Body.(func() *gamemap.Tile)()) } } }