721 lines
26 KiB
GDScript
721 lines
26 KiB
GDScript
extends Node3D
|
|
class_name LevelGenerator
|
|
|
|
var levelGrid: Array[Array]
|
|
@export var gridSizeX: int = 15
|
|
@export var gridSizeY: int = 3
|
|
@export var gridSizeZ: int = 15
|
|
|
|
@export var bufferSize: int = 5
|
|
|
|
@export var shipLogic: ShipLogic
|
|
|
|
@export var doorBlock: PackedScene # Temporary
|
|
@export var doorOBJ: PackedScene #Temporary
|
|
@export var tile: PackedScene # Temporary
|
|
@export var lamp: PackedScene # Temporary
|
|
@export var tileWall: PackedScene # Temporary
|
|
@export var tileCorner: PackedScene # Temporary
|
|
|
|
var levelGenSeed: int = 0
|
|
|
|
var globalParameters: ParamterList
|
|
|
|
var rng: RandomNumberGenerator = RandomNumberGenerator.new() #Get random values, usefull for random level generation huh
|
|
var currentMission: Mission
|
|
|
|
var doorSpawnPoints: Array[DoorPosition] #Where to put them doors
|
|
var doorBlockSpawnPoints: Array[DoorPosition] #Where to put them door blockers
|
|
|
|
var biomeExitPositions: Array[BiomeExit] #Points where you can leave a biome
|
|
var biomeExitChecker: RoomData = RoomData.new(preload("res://Maps/MapGenerator/BiomeExitChecker.png").get_image(),"") #Nonexisten Room used to check if a door is a valid Biome Exit
|
|
var connectPathPositions: PackedVector2Array #Where to place floor tiles of connecting paths
|
|
|
|
var astar: AStar2D = AStar2D.new()
|
|
|
|
func generate(usingSeed: int) -> void:
|
|
|
|
|
|
levelGenSeed = usingSeed
|
|
initRandom() # Set seed for level generation
|
|
initGrid() #Assign a new grid space object to each space of the 5x5x5m grid
|
|
##Center the world
|
|
position.x = -gridSizeX*2.5
|
|
position.z = -gridSizeZ*2.5
|
|
|
|
for x in gridSizeX:
|
|
for y in gridSizeY:
|
|
for z in gridSizeZ:
|
|
debugCubeAtPos(levelGrid[x][y][z].position*5)
|
|
|
|
|
|
func initRandom() -> void:
|
|
rng.set_seed(hash(levelGenSeed))
|
|
|
|
func initGrid() -> void:
|
|
for x in gridSizeX:
|
|
var newRow: Array
|
|
levelGrid.push_back(newRow)
|
|
for y in gridSizeY:
|
|
var newCol: Array
|
|
levelGrid[x].push_back(newCol)
|
|
for z in gridSizeZ:
|
|
var newCell := GridCell.new()
|
|
newCell.position = Vector3i(x,y,z)
|
|
levelGrid[x][y].push_back(newCell)
|
|
|
|
func debugCubeAtPos(pos: Vector3):
|
|
var debugCube: PackedScene = preload("res://Maps/Rooms/Generator/4Way/4WayRoomGenerator.tscn")
|
|
addObject(debugCube,self,pos+Vector3(2.5,0,2.5))
|
|
|
|
func addObject(AddedObject:PackedScene, Parent: Node3D, Position: Vector3, Rotation: Vector3= Vector3(0,0,0)) -> Node:
|
|
if !AddedObject:
|
|
print("tried to add object but packed scene is null")
|
|
return
|
|
var obj = AddedObject.instantiate()
|
|
Parent.add_child(obj)
|
|
obj.position = Position
|
|
obj.rotation = Rotation
|
|
return obj
|
|
|
|
## OLD LEVEL GEN CODE
|
|
|
|
#func generate(usingSeed: int) -> void:
|
|
|
|
#levelGenSeed = usingSeed
|
|
#
|
|
#initRandom() # Set seed for level generation
|
|
#initGrid() #Assign a new grid space object to each space of the 1x1m grid
|
|
#
|
|
##Center the world
|
|
#position.x = -gridSize/2
|
|
#position.z = -gridSize/2
|
|
#
|
|
#currentMission = RescueMission.new() #Have something choose the mission type in this part later
|
|
#
|
|
##Biomes
|
|
#generateBufferBiome(bufferSize)
|
|
#var doorList: Array[DoorPosition] #Seccond Array contains door positions
|
|
#for bPrio in currentMission.biomes.size():
|
|
#doorList = placeBiomes(currentMission.biomes[bPrio])
|
|
#spreadBiomes()
|
|
#
|
|
##Rooms into Biomes
|
|
#placeRooms(doorList)
|
|
#
|
|
##Doors
|
|
##chooseBiomeExits()
|
|
#doorsAtBiomeExits()
|
|
#findValidDoors()
|
|
#spawnDoors()
|
|
#
|
|
##Generate Astar setup for finding Paths between Biomes and Rooms
|
|
#generateAstarPoints()
|
|
#connectAstarPoints()
|
|
#weightAstarPoints()
|
|
#
|
|
##Connect Biomes
|
|
#connectPathPositions = generateConnectionPath()
|
|
#generateFloorPositions()
|
|
#placeFloorPositionTiles()
|
|
#placeWallsAlongTiles()
|
|
#
|
|
#
|
|
#
|
|
#
|
|
#
|
|
#shipLogic.onLevelGenFinished()
|
|
#shipLogic.main.mapScreen.generateMap(levelGrid)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
##Misc Utility
|
|
#func abandonSeed() -> void:
|
|
#print("SEED IS NOT VALID")
|
|
#
|
|
#func initRandom() -> void:
|
|
#rng.set_seed(hash(levelGenSeed))
|
|
#
|
|
#func initGrid() -> void:
|
|
#for x in gridSizeX:
|
|
#var newRow: Array
|
|
#levelGrid.push_back(newRow)
|
|
#for y in gridSizeY:
|
|
#var newCol: Array
|
|
#levelGrid[x].push_back(newCol)
|
|
#for z in gridSizeZ:
|
|
#var newCell := GridCell.new()
|
|
#newCell.position = Vector3i(x,y,z)
|
|
#levelGrid[x].push_back(newCell)
|
|
#
|
|
#func addGridCells(cell1: GridCell,cell2: GridCell) -> GridCell:
|
|
#var returnCell: GridCell = GridCell.new()
|
|
#returnCell.spaceTaken = cell1.spaceTaken or cell2.spaceTaken
|
|
#returnCell.door = cell1.door or cell2.door
|
|
#if cell1.door and !cell2.door:
|
|
#returnCell.doorOrientation = cell1.doorOrientation
|
|
#else:
|
|
#returnCell.doorOrientation = cell2.doorOrientation
|
|
#returnCell.position = cell1.position
|
|
#returnCell.biome = cell1.biome
|
|
#returnCell.biomeConnection = cell1.biomeConnection
|
|
#return returnCell
|
|
#
|
|
#func shuffleArray(array: Array) -> Array:
|
|
#for i in array.size()-1:
|
|
##Get Array indexes
|
|
#var iA: int = array.size()-1-i
|
|
#var iB: int = rng.randi_range(0,array.size()-2-i)
|
|
#
|
|
##Get two elements from the array
|
|
#var a = array[iA]
|
|
#var b = array[iB]
|
|
#
|
|
##Swap both elements
|
|
#array[iB] = a
|
|
#array[iA] = b
|
|
#
|
|
#return array
|
|
#
|
|
#func addArrays2D(array1: Array[Array], array2: Array[Array], arr2pos: Vector2i = Vector2i(0,0)) -> void:
|
|
#if array1.size() <= (arr2pos.x) + array2.size(): return
|
|
#if array1[arr2pos.y].size() <= (arr2pos.y) + array2[0].size(): return
|
|
#for x in array2.size():
|
|
#for y in array2[x].size():
|
|
#array1[x+arr2pos.x][y+arr2pos.y] = addGridCells(array1[x+arr2pos.x][y+arr2pos.y],array2[x][y])
|
|
#
|
|
#func checkOverlapArrays2D(array1: Array[Array], array2: Array[Array], arr2pos: Vector2i = Vector2i(0,0)) -> bool:
|
|
#if array1.size() <= arr2pos.x + array2.size() or arr2pos.x < 0: return true
|
|
#if array1[arr2pos.y].size() <= arr2pos.y + array2[0].size() or arr2pos.y < 0: return true
|
|
#for x in array2.size():
|
|
#for y in array2[x].size():
|
|
#if array1[x+arr2pos.x][y+arr2pos.y].spaceTaken and array2[x][y].spaceTaken: return true
|
|
#return false
|
|
#
|
|
#func checkBiomeOverlap(biome: String, pos: Vector2i, length: int, height: int) -> bool:
|
|
#if levelGrid.size() <= pos.x + length or pos.x < 0: return true
|
|
#if levelGrid[pos.y].size() <= pos.y + height or pos.y < 0: return true
|
|
#for x in length:
|
|
#for y in height:
|
|
#if levelGrid[x+pos.x][y+pos.y].biome: return true
|
|
#return false
|
|
#
|
|
#func rotateArray2D(array: Array[Array], numberOfRotationsBy90Degrees: int) -> void:
|
|
#var size: int = array.size()
|
|
#var layerCount: int = size/2
|
|
#
|
|
#for x in numberOfRotationsBy90Degrees%4:
|
|
#for layer in layerCount:
|
|
#var first: int = layer
|
|
#var last: int = size - first - 1
|
|
#
|
|
#for element in range(first, last):
|
|
#var offset = element - first
|
|
#
|
|
#var top = array[first][element]
|
|
#var right = array[element][last]
|
|
#var bot = array[last][last-offset]
|
|
#var left = array[last-offset][first]
|
|
#
|
|
#array[element][last] = top
|
|
#array[last][last-offset] = right
|
|
#array[last-offset][first] = bot
|
|
#array[first][element] = left
|
|
#
|
|
#func getDoorPosition(cell: GridCell, GridCellPosition: Vector2i) -> DoorPosition:
|
|
#if !cell.door:
|
|
#print("Tried to get door at cell that isnt a door")
|
|
#return null
|
|
#var returnDoorPosition := DoorPosition.new()
|
|
#returnDoorPosition.pos = GridCellPosition
|
|
#returnDoorPosition.orientation = cell.doorOrientation
|
|
#return returnDoorPosition
|
|
#
|
|
#func addObject(AddedObject:PackedScene, Parent: Node3D, Position: Vector3, Rotation: Vector3= Vector3(0,0,0)) -> Node:
|
|
#if !AddedObject:
|
|
#print("tried to add object but packed scene is null")
|
|
#return
|
|
#var obj = AddedObject.instantiate()
|
|
#Parent.add_child(obj)
|
|
#obj.position = Position
|
|
#obj.rotation = Rotation
|
|
#return obj
|
|
#
|
|
#func changeBiomeArea2D(biome: String,pos:Vector2i,length: int,height: int):
|
|
#for x in length:
|
|
#for y in height:
|
|
#levelGrid[pos.x+x][pos.y+y].biome = biome
|
|
#
|
|
##Spawning Rooms
|
|
#func rotateRoomData(roomData: RoomData, numberOfRotationsBy90Degrees: int) -> void:
|
|
#rotateArray2D(roomData.roomGrid,numberOfRotationsBy90Degrees)
|
|
#roomData.rotations = wrapi(roomData.rotations + numberOfRotationsBy90Degrees,0,4)
|
|
#for door in roomData.doorPositions:
|
|
#door.rotatePosRight(roomData.roomGrid.size(),numberOfRotationsBy90Degrees)
|
|
#roomData.roomGrid[door.pos.x][door.pos.y].doorOrientation = wrapi(door.orientation-2,0,4)
|
|
#
|
|
#func spawnRoom(roomDataInput: RoomData,pos: Vector2i,numberOfRotationsBy90Degrees: int = 0, centered: bool = false) -> Array[DoorPosition]: #Pos corresponds to the upper left corner of the room immage
|
|
#var roomData: RoomData = roomDataInput.duplicateRoom()
|
|
#var roomScene: PackedScene = roomDataInput.roomScene
|
|
#rotateRoomData(roomData,numberOfRotationsBy90Degrees)
|
|
#var roomGrid := roomData.roomGrid
|
|
#var doorPositions: Array[DoorPosition] = roomData.doorPositions
|
|
#if centered:
|
|
#pos = Vector2i(pos.x-(roomGrid.size()/2),pos.y-(roomGrid[0].size()/2))
|
|
#
|
|
#addArrays2D(levelGrid,roomGrid,pos)
|
|
#
|
|
##Make Room
|
|
#var room: BasicRoom = addObject(roomScene,self,Vector3(pos.x+(roomGrid.size()/2),0,pos.y+(roomGrid[0].size()/2)),Vector3(0,(roomData.rotations%4)*PI/2,0))
|
|
#room.biomeName = levelGrid[pos.x][pos.y].biome
|
|
#shipLogic.addRoomToRoomList(room)
|
|
#
|
|
#
|
|
#
|
|
#for door in doorPositions:
|
|
#door.pos = pos + door.pos
|
|
#
|
|
#
|
|
#
|
|
#return doorPositions
|
|
#
|
|
#func getDoorFromRoom(roomData: RoomData,index: int) -> DoorPosition:
|
|
#return roomData.doorPositions[index % roomData.doorPositions.size()]
|
|
#
|
|
#func putRoomAtDoor(roomData: RoomData, door: DoorPosition,spawnDoorIndex: int) -> Array: ##Return array contains roomData, spawn Pos in that order
|
|
##Init Values:
|
|
#var spawnDoor: DoorPosition = getDoorFromRoom(roomData,spawnDoorIndex) #Which door from the spawned room connects to the exiting room
|
|
#var doorOrientationDifference : int = wrapi(spawnDoor.orientation - door.orientation,0,4) #Difference in orinet. between spawned and existing room
|
|
#var numberOfRoomRotations: int = 0 #How many rotations are needed to make spawned rooms spawn door face the existing door
|
|
#var spawnPos: Vector2i
|
|
#var doorOffset: Vector2i #Offset by 1 space so the doors are next to eachother and not inside eachoter
|
|
#
|
|
##Find number of rotations and then rotate the room
|
|
#if !doorOrientationDifference == 2:
|
|
#if doorOrientationDifference == 1:
|
|
#numberOfRoomRotations = 3
|
|
#if doorOrientationDifference == 0:
|
|
#numberOfRoomRotations = 2
|
|
#if doorOrientationDifference == 3:
|
|
#numberOfRoomRotations = 1
|
|
#rotateRoomData(roomData,numberOfRoomRotations)
|
|
#
|
|
##Get new values for spawnDoor and set door offset
|
|
#spawnDoor = getDoorFromRoom(roomData,spawnDoorIndex)
|
|
#match spawnDoor.orientation:
|
|
#0: doorOffset = Vector2i(0,-1)
|
|
#1: doorOffset = Vector2i(1,0)
|
|
#2: doorOffset = Vector2i(0,1)
|
|
#3: doorOffset = Vector2i(-1,0)
|
|
#
|
|
##Set spawn pos and return values
|
|
#spawnPos = door.pos - spawnDoor.pos + doorOffset
|
|
#var returnArray: Array = [roomData,spawnPos]
|
|
#return returnArray
|
|
#
|
|
#func spawnRoomAtDoor(roomDataInput: Array[RoomData], door: DoorPosition, biome: String) -> Array[DoorPosition]:
|
|
#var returnArray: Array[DoorPosition]
|
|
#var roomData: RoomData = null
|
|
#var spawnDoorIndex: int = -1
|
|
##Choose the room to use
|
|
#var rooms: Array[RoomData] = roomDataInput.duplicate()
|
|
#
|
|
#shuffleArray(rooms)
|
|
#for r in floor(rooms.size()/2):
|
|
##Randomise door checking order
|
|
#var doorIndices: Array[int]
|
|
#for x in rooms[r].doorPositions.size():
|
|
#doorIndices.push_back(x)
|
|
#shuffleArray(doorIndices)
|
|
#
|
|
##Check if doorIndex fits and assign roomData and spawnDoorIndex if it does
|
|
#for doorIndex in doorIndices:
|
|
#if checkIfRoomFits(rooms[r],door,doorIndex, biome):
|
|
#roomData = rooms[r].duplicateRoom()
|
|
#spawnDoorIndex = doorIndex
|
|
#break
|
|
#
|
|
##Check if a room has been found
|
|
#if !roomData or spawnDoorIndex == -1:
|
|
#var checkPosition = door.pos
|
|
#match door.orientation:
|
|
#0: checkPosition += Vector2i(-1,-2)
|
|
#1: checkPosition += Vector2i(0,-1)
|
|
#2: checkPosition += Vector2i(-1,0)
|
|
#3: checkPosition += Vector2i(-2,-1)
|
|
#if !checkOverlapArrays2D(levelGrid,biomeExitChecker.roomGrid,checkPosition):
|
|
#biomeExitPositions.push_back(BiomeExit.new(door.pos,door.orientation,biome))
|
|
#return returnArray
|
|
#
|
|
##Get Spawn Info and spawn room
|
|
#var spawnInfo: Array = putRoomAtDoor(roomData,door,spawnDoorIndex)
|
|
#spawnRoom(spawnInfo[0],spawnInfo[1])
|
|
#returnArray = spawnInfo[0].doorPositions
|
|
#for x in returnArray.size():
|
|
#returnArray[x].pos = spawnInfo[1] + returnArray[x].pos
|
|
#return returnArray
|
|
#
|
|
#func checkIfBiomeFits(length: int, height: int, pos: Vector2i, biome: String) -> bool:
|
|
#if levelGrid.size() <= pos.x + length or pos.x < 0: return true
|
|
#if levelGrid[pos.y].size() <= pos.y + height or pos.y < 0: return true
|
|
#for x in length:
|
|
#for y in height:
|
|
#if levelGrid[x+pos.x][y+pos.y].biome != biome:
|
|
#return false
|
|
#return true
|
|
#
|
|
#func checkIfRoomFits(roomDataInput: RoomData,door: DoorPosition,spawnDoorIndex: int, biome: String) -> bool:
|
|
#var roomData: RoomData = roomDataInput.duplicateRoom()
|
|
#var spawnInfo: Array = putRoomAtDoor(roomData,door,spawnDoorIndex)
|
|
#
|
|
#if !checkOverlapArrays2D(levelGrid,spawnInfo[0].roomGrid,spawnInfo[1]) and checkIfBiomeFits(spawnInfo[0].roomGrid.size(),spawnInfo[0].roomGrid[0].size(),spawnInfo[1],biome):
|
|
#return true
|
|
#else:
|
|
#return false
|
|
#
|
|
#func isOutOfArray2DBounds(sizeX: int, sizeY: int, pos: Vector2i) -> bool:
|
|
#if pos.x >= sizeX or pos.x < 0 or pos.y >= sizeY or pos.y < 0:
|
|
#return true
|
|
#else:
|
|
#return false
|
|
#
|
|
#func isValidDoor(pos:Vector2i) -> bool: # Checks if the door connects to another door using its orientation,
|
|
##if this function finds a valid door, it removes the door status from the other door to avoid duplicated doors
|
|
#match levelGrid[pos.x][pos.y].doorOrientation:
|
|
#0:
|
|
#if isOutOfArray2DBounds(levelGrid.size(),levelGrid[0].size(),Vector2i(pos.x,pos.y-1)): return false
|
|
#if !levelGrid[pos.x][pos.y-1].door: return false
|
|
#else: levelGrid[pos.x][pos.y-1].door = false
|
|
#1:
|
|
#if isOutOfArray2DBounds(levelGrid.size(),levelGrid[0].size(),Vector2i(pos.x+1,pos.y)): return false
|
|
#if !levelGrid[pos.x+1][pos.y].door: return false
|
|
#else: levelGrid[pos.x+1][pos.y].door = false
|
|
#2:
|
|
#if isOutOfArray2DBounds(levelGrid.size(),levelGrid[0].size(),Vector2i(pos.x,pos.y+1)): return false
|
|
#if !levelGrid[pos.x][pos.y+1].door: return false
|
|
#else: levelGrid[pos.x][pos.y+1].door = false
|
|
#3:
|
|
#if isOutOfArray2DBounds(levelGrid.size(),levelGrid[0].size(),Vector2i(pos.x-1,pos.y)): return false
|
|
#if !levelGrid[pos.x-1][pos.y].door: return false
|
|
#else: levelGrid[pos.x-1][pos.y].door = false
|
|
#return true
|
|
#
|
|
#func findValidDoors() -> void:
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if levelGrid[x][y].door:
|
|
#var newDoorObject := DoorPosition.new()
|
|
#newDoorObject.pos = Vector2i(x,y)
|
|
#newDoorObject.orientation = levelGrid[x][y].doorOrientation
|
|
#if isValidDoor(Vector2i(x,y)):
|
|
#doorSpawnPoints.push_back(newDoorObject)
|
|
#else:
|
|
#doorBlockSpawnPoints.push_back(newDoorObject)
|
|
#
|
|
#func spawnDoors() -> void:
|
|
#for doorSpawn in doorSpawnPoints:
|
|
#addObject(doorOBJ,self,Vector3(doorSpawn.pos.x+0.5,0,doorSpawn.pos.y+0.5),Vector3(0,doorSpawn.orientation*-PI/2,0))
|
|
##debugCubeAtPos(doorSpawn.pos)
|
|
#for doorBlockSpawn in doorBlockSpawnPoints:
|
|
#addObject(doorBlock,self,Vector3(doorBlockSpawn.pos.x+0.5,0,doorBlockSpawn.pos.y+0.5),Vector3(0,doorBlockSpawn.orientation*-PI/2,0))
|
|
#
|
|
#func placeRooms(doorList: Array[DoorPosition]) -> void:
|
|
#var nextDoors: Array[DoorPosition] = []
|
|
#
|
|
##YES I KNOW A DO WHILE LOOP IS BETTER HERE BUT GODOT DOESNT HAVE IT
|
|
#for door in doorList:
|
|
#var doorBiome: Biome = getBiome(levelGrid[door.pos.x][door.pos.y].biome)
|
|
#nextDoors += spawnRoomAtDoor(doorBiome.roomList.rooms,door,doorBiome.name)
|
|
#doorList = nextDoors
|
|
#nextDoors = []
|
|
#
|
|
#while !doorList.is_empty():
|
|
#for door in doorList:
|
|
#var doorBiome: Biome = getBiome(levelGrid[door.pos.x][door.pos.y].biome)
|
|
#nextDoors += spawnRoomAtDoor(doorBiome.roomList.rooms,door,doorBiome.name)
|
|
#doorList = nextDoors
|
|
#nextDoors = []
|
|
#
|
|
##Generating Biomes
|
|
#func generateBufferBiome(bufferWidth: int) -> void:
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if (x < bufferWidth) or (y < bufferWidth) or (x > levelGrid.size() - bufferWidth) or (y > levelGrid.size() - bufferWidth):
|
|
#levelGrid[x][y].biome = "buffer"
|
|
#
|
|
#
|
|
#func getBiome(biomeName: String) -> Biome:
|
|
#for prio in currentMission.biomes.size():
|
|
#for biome in currentMission.biomes[prio]:
|
|
#if biome.name == biomeName:
|
|
#return biome
|
|
#return Biome.new("empty",RoomList.new(),RoomData.new(),0,0)
|
|
#
|
|
#func generateBiomePos(biome: String,starterRoomSize: Vector2i) -> Vector2i:
|
|
#var genPos: Vector2i
|
|
#var possiblePos: Array[Vector2i]
|
|
#
|
|
##Find all possible Pos without a biome
|
|
#for x in levelGrid.size() - starterRoomSize.x - 1:
|
|
#for y in levelGrid[x].size() - starterRoomSize.y - 1:
|
|
#if !levelGrid[x][y].biome:
|
|
#possiblePos.push_back(levelGrid[x][y].position)
|
|
#
|
|
##Go through all pos untill one works
|
|
#genPos = possiblePos[rng.randi_range(0,possiblePos.size()-1)]
|
|
#while checkBiomeOverlap(biome,genPos,starterRoomSize.x,starterRoomSize.y):
|
|
#possiblePos.erase(genPos)
|
|
#if possiblePos.size() == 0:
|
|
#abandonSeed()
|
|
#break
|
|
#genPos = possiblePos[rng.randi_range(0,possiblePos.size()-1)]
|
|
#
|
|
#return genPos
|
|
#
|
|
#func placeBiomes(biomes: Array[Biome]) -> Array[DoorPosition]:
|
|
#var returnDoorLists: Array[DoorPosition] = []
|
|
#
|
|
#for biome in biomes:
|
|
#var starterRoomSize: Vector2i = Vector2i(biome.starterRoom.roomGrid.size(),biome.starterRoom.roomGrid[0].size())
|
|
#var generatePos: Vector2i = generateBiomePos(biome.name,starterRoomSize)
|
|
#changeBiomeArea2D(biome.name,generatePos,starterRoomSize.x,starterRoomSize.y)
|
|
#
|
|
##Spawn Starter room and add doors to list
|
|
#var doorList: Array[DoorPosition]
|
|
#doorList = spawnRoom(biome.starterRoom,generatePos,rng.randi_range(0,3))
|
|
#returnDoorLists += doorList
|
|
#
|
|
##If first Biome, set Starting Position
|
|
#if shipLogic.playerStartPos == Vector3(0,0,0):
|
|
#shipLogic.playerStartPos = Vector3(generatePos.x + biome.starterRoom.roomGrid.size()/2,0,generatePos.y + biome.starterRoom.roomGrid[0].size()/2) + self.position
|
|
#
|
|
#return returnDoorLists
|
|
#
|
|
#func fillCell(cellBiome: String,pos: Vector2i) -> GridCell:
|
|
#if isOutOfArray2DBounds(levelGrid.size(),levelGrid[0].size(),pos): return
|
|
#if !levelGrid[pos.x][pos.y].biome:
|
|
#levelGrid[pos.x][pos.y].biome = cellBiome
|
|
#return levelGrid[pos.x][pos.y]
|
|
#return
|
|
#
|
|
#func spreadCell(cell: GridCell,pos: Vector2i) -> Array[GridCell]:
|
|
#var returnCells: Array[GridCell] = []
|
|
#returnCells.push_back(fillCell(cell.biome,pos + Vector2i(0,-1)))
|
|
#returnCells.push_back(fillCell(cell.biome,pos + Vector2i(1,0)))
|
|
#returnCells.push_back(fillCell(cell.biome,pos + Vector2i(0,1)))
|
|
#returnCells.push_back(fillCell(cell.biome,pos + Vector2i(-1,0)))
|
|
#while returnCells.has(null):
|
|
#returnCells.erase(null)
|
|
#return returnCells
|
|
#
|
|
#func allCellsHaveBiome() -> bool:
|
|
#for x in levelGrid.size():
|
|
#for cell in levelGrid[x]:
|
|
#if !cell.biome: return false
|
|
#return true
|
|
#
|
|
#func spreadBiomes() -> void:
|
|
##Get all current biome grid cells -> Put them in starterCells
|
|
#var startCells: Array[GridCell] = []
|
|
#var startProbabilities: PackedFloat32Array = []
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if levelGrid[x][y].biome:
|
|
#var cell: GridCell = levelGrid[x][y]
|
|
#startCells.push_back(cell)
|
|
#startProbabilities.push_back(getBiome(cell.biome).spread)
|
|
#
|
|
#
|
|
##Spread them by one -> put the new ones in a new array
|
|
#while !(startCells.is_empty() or startProbabilities.is_empty()):
|
|
#var newCells: Array[GridCell] = []
|
|
#var newProbabilities: PackedFloat32Array = []
|
|
#var randomCellIndex: int = rng.rand_weighted(startProbabilities)
|
|
#
|
|
#if randomCellIndex == -1:
|
|
#randomCellIndex = startProbabilities.size()-1
|
|
#
|
|
#var cell: GridCell = startCells[randomCellIndex]
|
|
#
|
|
#newCells += spreadCell(cell,cell.position)
|
|
#for newCell in newCells:
|
|
#newProbabilities.push_back(getBiome(newCell.biome).spread)
|
|
#
|
|
##New cells now contains all that were newly assigned a biome and the ones that didnt spread
|
|
#startCells.remove_at(randomCellIndex)
|
|
#startProbabilities.remove_at(randomCellIndex)
|
|
#
|
|
#startCells += newCells
|
|
#startProbabilities += newProbabilities
|
|
#
|
|
##Astar
|
|
#func generateAstarPoints(findAllSpaceTakenCells: bool = false) -> void:
|
|
#var currentID: int = 0
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if (levelGrid[x][y].spaceTaken == findAllSpaceTakenCells) and !(x == 0 or x == gridSize-1 or y == 0 or y == gridSize-1):
|
|
#astar.add_point(currentID,Vector2i(x,y))
|
|
#currentID += 1
|
|
#
|
|
#func connectAstarPoints() -> void:
|
|
#for point in astar.get_point_ids():
|
|
#var possibleNeighbors: Array[int] = [point+1,point-1,point-gridSize,point+gridSize]
|
|
#
|
|
#for posNeigh in possibleNeighbors:
|
|
#if astar.has_point(posNeigh):
|
|
#astar.connect_points(point,posNeigh,true)
|
|
#
|
|
#func weightAstarPoints() -> void:
|
|
#for point in astar.get_point_ids():
|
|
#if astar.get_point_connections(point).size() != 4:
|
|
#astar.set_point_weight_scale(point,10)
|
|
#
|
|
#func posToID(pos: Vector2i) -> int:
|
|
#return gridSize*pos.x + pos.y
|
|
#
|
|
##Generating Biome Connections
|
|
#func chooseBiomeExits() -> void:
|
|
#var existingBiomes: Array[String] = []
|
|
#var currentBiomeExits: Array[BiomeExit] = []
|
|
#var choosenBiomeExits: Array[BiomeExit] = []
|
|
## Find What Biomes are Present
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if !existingBiomes.has(levelGrid[x][y].biome) and levelGrid[x][y].biome != "buffer":
|
|
#existingBiomes.push_back(levelGrid[x][y].biome)
|
|
#
|
|
##For each biome choose a number of exit
|
|
#for i in existingBiomes.size():
|
|
##Look through all exits for exits belonging to this biome
|
|
#for exit in biomeExitPositions:
|
|
#if exit.biome == existingBiomes[i]:
|
|
#currentBiomeExits.push_back(exit)
|
|
#biomeExitPositions.erase(exit)
|
|
#
|
|
##For each other biome, choose an exit
|
|
#
|
|
#for n in existingBiomes.size()-1:
|
|
#if currentBiomeExits:
|
|
## Randomly determine an exit
|
|
#var exit: BiomeExit = currentBiomeExits[rng.randi_range(0,currentBiomeExits.size()-1)]
|
|
#
|
|
##Test if exit was already choosen
|
|
#if !choosenBiomeExits.has(exit):
|
|
#choosenBiomeExits.push_back(exit)
|
|
#
|
|
#currentBiomeExits.clear()
|
|
#
|
|
##Get rid of all other exits
|
|
#biomeExitPositions = choosenBiomeExits
|
|
#
|
|
#func doorsAtBiomeExits() -> void:
|
|
#for exit in biomeExitPositions:
|
|
#levelGrid[exit.pos.x][exit.pos.y].door = false
|
|
#
|
|
#func generateConnectionPath() -> PackedVector2Array:
|
|
#var returnArray: PackedVector2Array = []
|
|
#
|
|
##Look through all exits and find the closest other exit
|
|
#for exit in biomeExitPositions:
|
|
#var newPath: PackedVector2Array = []
|
|
#var closestPointPath: PackedVector2Array = []
|
|
#for otherExit in biomeExitPositions:
|
|
#newPath = astar.get_point_path(posToID(exit.pos),posToID(otherExit.pos))
|
|
#if exit.biome != otherExit.biome and newPath.size() < closestPointPath.size() or closestPointPath.size() == 0:
|
|
#closestPointPath = newPath
|
|
#
|
|
##Connect the exits
|
|
#if closestPointPath.size() == 0:
|
|
#levelGrid[exit.pos.x][exit.pos.y].door = true
|
|
#else:
|
|
#returnArray += closestPointPath
|
|
#
|
|
#return returnArray
|
|
#
|
|
#func addFloorPos(gridCell: GridCell) -> void:
|
|
#if !gridCell.biomeConnection and !gridCell.spaceTaken:
|
|
#connectPathPositions.push_back(gridCell.position)
|
|
#gridCell.biomeConnection = true
|
|
#gridCell.spaceTaken = true
|
|
#
|
|
#func generateFloorPositions(spread: int = 2) -> void:
|
|
#for x in spread:
|
|
#for y in connectPathPositions.size():
|
|
#var fPos: Vector2i = connectPathPositions[y]
|
|
#levelGrid[fPos.x][fPos.y].spaceTaken = true
|
|
#levelGrid[fPos.x][fPos.y].biomeConnection = true
|
|
#addFloorPos(levelGrid[clampi(fPos.x+1,0,gridSize-1)][fPos.y])
|
|
#addFloorPos(levelGrid[fPos.x][clampi(fPos.y+1,0,gridSize-1)])
|
|
#addFloorPos(levelGrid[clampi(fPos.x-1,0,gridSize-1)][fPos.y])
|
|
#addFloorPos(levelGrid[fPos.x][clampi(fPos.y-1,0,gridSize-1)])
|
|
#
|
|
#func placeFloorPositionTiles() -> void:
|
|
#for tilePos in connectPathPositions:
|
|
#addObject(tile,self,Vector3(tilePos.x+0.5,0,tilePos.y+0.5))
|
|
#
|
|
#if rng.randf_range(0,1) > 0.9:
|
|
#shipLogic.hallwayLights.push_back(addObject(lamp,self,Vector3(tilePos.x+0.5,2.5,tilePos.y+0.5)))
|
|
#
|
|
#func spawnWallSegment(pos: Vector2i,rot: int) -> void:
|
|
#addObject(tileWall,self,Vector3(pos.x+0.5,0,pos.y+0.5),Vector3(0,rot*PI/2,0))
|
|
#
|
|
#func spawnCornerSegment(pos: Vector2i,rot: int) -> void:
|
|
#addObject(tileCorner,self,Vector3(pos.x+0.5,0,pos.y+0.5),Vector3(0,rot*PI/2,0))
|
|
#
|
|
#func placeWallsAlongTiles() -> void:
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if !levelGrid[x][y].biomeConnection: continue
|
|
##Walls
|
|
#if x+1 != levelGrid.size():
|
|
#if !levelGrid[x+1][y].spaceTaken: spawnWallSegment(Vector2i(x,y),3)
|
|
#else: spawnWallSegment(Vector2i(x,y),3)
|
|
#if x != 0:
|
|
#if !levelGrid[x-1][y].spaceTaken: spawnWallSegment(Vector2i(x,y),1)
|
|
#else: spawnWallSegment(Vector2i(x,y),1)
|
|
#if y+1 != levelGrid.size():
|
|
#if !levelGrid[x][y+1].spaceTaken: spawnWallSegment(Vector2i(x,y),2)
|
|
#else: spawnWallSegment(Vector2i(x,y),2)
|
|
#if y != 0:
|
|
#if !levelGrid[x][y-1].spaceTaken: spawnWallSegment(Vector2i(x,y),0)
|
|
#else: spawnWallSegment(Vector2i(x,y),0)
|
|
##Corners
|
|
#if x+1 != levelGrid.size() and y+1 != levelGrid.size():
|
|
#if !levelGrid[x+1][y+1].spaceTaken: spawnCornerSegment(Vector2i(x,y),3)
|
|
#else: spawnCornerSegment(Vector2i(x,y),3)
|
|
#if x != 0 and y != 0:
|
|
#if !levelGrid[x-1][y-1].spaceTaken: spawnCornerSegment(Vector2i(x,y),1)
|
|
#else: spawnCornerSegment(Vector2i(x,y),1)
|
|
#if x+1 != levelGrid.size() and y != 0:
|
|
#if !levelGrid[x+1][y-1].spaceTaken: spawnCornerSegment(Vector2i(x,y),0)
|
|
#else: spawnCornerSegment(Vector2i(x,y),0)
|
|
#if y+1 != levelGrid.size() and x != 0:
|
|
#if !levelGrid[x-1][y+1].spaceTaken: spawnCornerSegment(Vector2i(x,y),2)
|
|
#else: spawnCornerSegment(Vector2i(x,y),2)
|
|
#
|
|
##Debug Functions
|
|
#func printLevelGrid() -> void:
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if levelGrid[x][y].biomeConnection:
|
|
#debugCubeAtPos(Vector2(x,y))
|
|
#
|
|
#func printBiomeGrid() -> void:
|
|
#for x in levelGrid.size():
|
|
#for y in levelGrid[x].size():
|
|
#if levelGrid[x][y].biome == "test":
|
|
#debugCubeAtPos(Vector2(x,y))
|
|
#
|
|
#func debugCubeAtPos(pos: Vector2):
|
|
#var debugCube: PackedScene = preload("res://test/debugCube.tscn")
|
|
#addObject(debugCube,self,Vector3(pos.x+0.5,0,pos.y+0.5))
|
|
#
|
|
#func showAstarPoints() -> void:
|
|
#for point in astar.get_point_ids():
|
|
#var point_pos: Vector2i = astar.get_point_position(point)
|
|
#debugCubeAtPos(point_pos)
|