2019-11-14 21:14:52 +03:00

177 lines
4.1 KiB
Go

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 = 5
var maxRoomSize = 25
var maxrooms = 200
var fges = map[int]types.RectFill{
1: types.RectFill{
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: types.RectFill{
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(ctx appctx.ClientCtx, rng *util.RNG, l *gamemap.Level, maxRooms, minRoomSize, maxRoomSize int, ) []gamemap.Room{
rooms := make([]gamemap.Room, 0)
pfLoader := gamemap.NewPrefabLoader(ctx)
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 {
//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),
}
for _, coord := range r.Connectors {
newRoom.Connectors = append(newRoom.Connectors, coord)
}
} else {
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),
}
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
}
//delaunay helper funcs
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(0, 1)
if toss == 0 {
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{i, y}) {
l.SetTileByXY(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, i}) {
l.SetTileByXY(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)
}
}