123 lines
4.5 KiB
Plaintext
123 lines
4.5 KiB
Plaintext
extends Node3D
|
|
class_name LevelGenerator
|
|
|
|
var levelGrid: Array[Array]
|
|
@export var gridSize: int = 250
|
|
|
|
var spawnableRooms: Array[RoomData]
|
|
var biomes: Array[Biome]
|
|
var rng := RandomNumberGenerator.new()
|
|
|
|
func _ready() -> void:
|
|
initGrid()
|
|
|
|
var spaceshipRoomList := RoomListSpaceship.new() # Have something choose the map in this part later
|
|
spawnableRooms = spaceshipRoomList.rooms
|
|
|
|
|
|
var temp: Array[DoorPosition]
|
|
|
|
# Generate the level
|
|
temp = spawnRoom(spawnableRooms[0],Vector2i(40,40),0,true)
|
|
for x in temp:
|
|
spawnRoomAtDoor(spawnableRooms[0],x)
|
|
printLevelGrid()
|
|
|
|
func initGrid() -> void:
|
|
for x in gridSize:
|
|
var newRow: Array
|
|
levelGrid.push_back(newRow)
|
|
for y in gridSize:
|
|
var newCell := GridCell.new()
|
|
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 = cell2.door
|
|
returnCell.doorOrientation = cell2.doorOrientation
|
|
returnCell.biome = cell1.biome
|
|
return returnCell
|
|
func addArrays2D(array1: Array[Array], array2: Array[Array], arr2pos: Vector2i = Vector2i(0,0)) -> void:
|
|
if array1.size() < (arr2pos.x - 1) + array2.size(): return
|
|
if array1[arr2pos.y].size() < (arr2pos.y - 1) + 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 rotateArray2D(array: Array[Array], numberOfRotationsBy90Degrees: int = 1) -> 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)):
|
|
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 rotateRoom(roomData: RoomData, numberOfRotationsBy90Degrees: int) -> void:
|
|
rotateArray2D(roomData.roomGrid,numberOfRotationsBy90Degrees)
|
|
for door in roomData.doorPositions:
|
|
door.rotatePosRight(roomData.roomGrid.size(),numberOfRotationsBy90Degrees)
|
|
door.orientation += numberOfRotationsBy90Degrees % 4
|
|
func spawnRoom(roomData: RoomData,pos: Vector2i,numberOfRotationsBy90Degrees: int = 0, centered: bool = false) -> Array[DoorPosition]: #Pos corresponds to the upper left corner of the room immage
|
|
var roomScene: PackedScene = load(roomData.roomSceneRef)
|
|
|
|
rotateRoom(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)
|
|
addObject(roomScene,self,Vector3(pos.x+(roomGrid.size()/2),0,pos.y+(roomGrid[0].size()/2)),Vector3(0,(numberOfRotationsBy90Degrees%4)*PI/2,0))
|
|
for door in doorPositions:
|
|
door.pos += pos
|
|
|
|
return doorPositions
|
|
func spawnRoomAtDoor(roomData: RoomData, door: DoorPosition) -> void:
|
|
var spawnDoor: DoorPosition = roomData.doorPositions[rng.randi_range(0,roomData.doorPositions.size()-1)]
|
|
var doorOrientationDifference : int = spawnDoor.orientation - door.orientation
|
|
var numberOfRoomRotations: int = 0
|
|
if !abs(doorOrientationDifference) == 2:
|
|
if doorOrientationDifference > 0:
|
|
numberOfRoomRotations = 1
|
|
if doorOrientationDifference == 0:
|
|
numberOfRoomRotations = 2
|
|
if doorOrientationDifference < 0:
|
|
numberOfRoomRotations = 3
|
|
|
|
spawnRoom(roomData,door.pos,numberOfRoomRotations)
|
|
func printLevelGrid() -> void:
|
|
var debugCube: PackedScene = preload("res://test/debugCube.tscn")
|
|
for x in levelGrid.size():
|
|
for y in levelGrid[x].size():
|
|
if levelGrid[x][y].spaceTaken:
|
|
addObject(debugCube,self,Vector3(x+0.5,0,y+0.5))
|