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" "lab.zaar.be/thefish/alchemyst-go/util/appctx" ) //fixme move to config var minRoomSize = 8 var maxRoomSize = 22 var maxrooms = 100 var fges = map[int]types.RectFill{ 1: { Top: gamemap.NewWall, Bottom: gamemap.NewWall, Left: gamemap.NewWall, Right: gamemap.NewWall, BottomLeft: gamemap.NewWall, BottomRight: gamemap.NewWall, TopLeft: gamemap.NewWall, TopRight: gamemap.NewWall, Body: gamemap.NewFloor, }, 2: { Top: gamemap.NewWaterTile, Bottom: gamemap.NewWaterTile, Left: gamemap.NewWaterTile, Right: gamemap.NewWaterTile, BottomLeft: gamemap.NewWaterTile, BottomRight: gamemap.NewWaterTile, TopLeft: gamemap.NewWaterTile, TopRight: gamemap.NewWaterTile, Body: gamemap.NewDeepWaterTile, }, } func GetRandomRoomList(rng *util.RNG, l *gamemap.Level, maxRooms, minRoomSize, maxRoomSize int, ) []gamemap.Room{ rooms := make([]gamemap.Room, 0) pfLoader := gamemap.NewPrefabLoader() pfRooms := pfLoader.PrefabRoomsList() var fillage types.RectFill prefabUsed := false for i := 0; i < maxRooms; i++ { failed := false fillage = fges[rng.GetWeightedEntity(map[int]int{1: 10, 2: 1})] var newRoom = gamemap.Room{} if prefabUsed && rng.Range(0, 5) <= 3 { newRoom = gamemap.NewRandomRectRoom( rng, rng.Range(minRoomSize, maxRoomSize), rng.Range(minRoomSize, maxRoomSize), fillage, ) } else { //if prefabUsed { //prefab prefabUsed = true r := pfRooms[rng.Range(0, len(pfRooms))] //copy to local scope newRoom = gamemap.Room{ Rect: r.Rect, Center: r.Center, Geometry: r.Geometry, Items: r.Items, Mobs: r.Mobs, Connectors: make([]types.Coords,0), } newRoom.Connectors = append(newRoom.Connectors, r.Connectors...) // for _, coord := range r.Connectors { // newRoom.Connectors = append(newRoom.Connectors, coord) // } } where := types.Coords{ X: rng.Range(1, l.W-2-newRoom.W), Y: rng.Range(1, l.H-2-newRoom.H), } newRoom.MoveToCoords(where) for _, otherRoom := range rooms { if otherRoom.Intersects(newRoom.Rect) { failed = true break } } if failed { continue } if len(newRoom.Connectors) > 0 { rooms = append(rooms, newRoom) } } return rooms } //fixme overlapping rooms func BlitToLevel (l *gamemap.Level, rooms[]gamemap.Room) { for _, room := range rooms { err := room.BlitToLevel(l) if err != nil { appctx.Logger().Err(err) } } } //delaunay helper funcs func MedianStraight(rng *util.RNG, l *gamemap.Level, rooms []gamemap.Room, centers []types.Coords, edge types.Edge) { //find connected rooms var fromRoom, toRoom gamemap.Room for _, room := range rooms { if room.Center == edge.From { fromRoom = room continue } if room.Center == edge.To { toRoom = room continue } if len(fromRoom.Connectors) > 0 && len(toRoom.Connectors) > 0 { break } } midpoint := edge.Midpoint() fromConnector := FindNearestConnector(midpoint, fromRoom) toConnector := FindNearestConnector(midpoint, toRoom) ConnectStraight(rng, l, fromConnector, toConnector, midpoint) } func FindNearestConnector(midpoint types.Coords, room gamemap.Room) types.Coords { var nearest types.Coords for _, con := range room.Connectors { if nearest.X == 0 { nearest = con continue } if midpoint.DistanceTo(con) < midpoint.DistanceTo(nearest) { nearest = con } } return nearest } func ConnectStraight(rng *util.RNG, l *gamemap.Level, from, to, midpoint types.Coords) { toss := rng.Range(1, 2) if toss > 1 { DigHTunnel(l, from.X, midpoint.X, from.Y) DigVTunnel(l, from.Y, to.Y, midpoint.X) DigHTunnel(l, midpoint.X, to.X, to.Y) } else { DigVTunnel(l, from.Y, midpoint.Y, from.X) DigHTunnel(l, from.X, to.X, midpoint.Y) DigVTunnel(l, midpoint.Y, to.Y, to.X) } } func DigHTunnel(l *gamemap.Level, x1, x2, y int) { 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{X: i, Y: y}) { l.MakePassByXY(i, y, gamemap.NewFloor()) //l.Tiles[i][y] = gamemap.NewFloor() } } } func DigVTunnel(l *gamemap.Level, y1, y2, x int) { 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: x, Y: i}) { l.MakePassByXY(x, i, gamemap.NewFloor()) } } } //default helper func ConnectRoomCenters(l *gamemap.Level, room, otherRoom gamemap.Room, toss int) { if toss == 0 { DigHTunnel(l, room.Center.X, otherRoom.Center.X, room.Center.Y) DigVTunnel(l, room.Center.Y, otherRoom.Center.Y, otherRoom.Center.X) } else { DigVTunnel(l, room.Center.Y, otherRoom.Center.Y, room.Center.Y) DigHTunnel(l, room.Center.X, otherRoom.Center.X, otherRoom.Center.Y) } }