Skip to content

Instantly share code, notes, and snippets.

@Jasoncrawforddesign
Created August 4, 2020 00:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Jasoncrawforddesign/79b41b6071d7c8a6ce7118c63db173d5 to your computer and use it in GitHub Desktop.
Save Jasoncrawforddesign/79b41b6071d7c8a6ce7118c63db173d5 to your computer and use it in GitHub Desktop.
-- Hey, I've created this Lua Script to allow quick creations of dungeon rooms.
-- WARNING|| if you havn't already I also highly recommend downloading my DungeonPrefabs collection or you'll run into issues with this script.
-- The script itself is fairly customizable. You can either leave all the code as is, add to it, or make changes. It's entirely up to you.
-- (however I do recommend checking out the lua scripts that are already included with Asset Forge to gain a little understanding of how this Lua script has been put together)
-- If you're new to coding or happy with how it functions already, just play around with the variables below by adding your own models/prefabs to the random generation, build amounts or leave as is.
-- I am aware this dungeon room generation isn't perfect but it quickly creates a dungeon room allowing you to tweak things as needed.
-- eg. occasionally models will overlap, such as ladders will be placed under a column or crate, either generate another room or move the individual models.
-- Make sure to check out the function calls at the end of the script, you can comment them out which could mean no walls generate for example.
-- Enjoy, I can't wait to see what you create!
--Feel free to adjust the random range of these two variables, these correlate to the size of the room-------------------------
sizeX = math.random(3, 8) -- Random size on X axis from 2 to 8, min can be 2 only
sizeZ = math.random(3, 8) -- Random size on Z axis from 2 to 8, min can be 2 only
--------------------------------------------------------------------------------------
--Can change these six variables below, for different results------
doorWaysToBuild = 0 --Amount of doorways to place in this room
ladderDownToBuild = 0 -- Amount of ladders to place going down
ladderUpToBuild = 0 --Amount of ladders to place going up
cratesToPlace = 0 --Amount of crates to place in this room
maxFloorDecalToPlace = 0 -- Max amount of floor decal to place in this room
minFloorDecalToPlace = 0 -- Min amount of floor decal to place in this room
stairsWaysUpToBuild = 1 -- Amount of staircases going up to place in room
stairWaysDownToBuild = 1 -- Amount of staircases going down to place in room
--------------------------------------------------------------------
-- no need to touch these 4 lines of code -----
local a,b,c
origZ = sizeZ
origX = sizeX
columnsToBuild = 2
-----------------------------------------
--Feel free to adjust the string paths in randomWallCorners, randomColumns and randomFloorDecals-----------------------------------------------------------------------------------------
randomWallCorners = { "Dungeons/wall_corner", "Dungeons/wall_corner_diagonal", "Dungeons/wall_corner_round"} --strings can be changed/added just ensure you declare the correct path.
randomWallCorner = randomWallCorners[math.random(#randomWallCorners)];
randomColumns = {"Dungeons/column", "Dungeons/column_round"} --strings can be changed/added just ensure you declare the correct path.
randomColumn = randomColumns[math.random(#randomColumns)];
randomFloorDecals = {"Dungeons/floor_detail"} --strings can be changed/added just ensure you declare the correct path.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function buildWalls() -- this function builds walls on x axis and z axis, it also adds corner pieces.
for x = 0, sizeX - 1 do -- Repeat size on X axis
buildWall = "Dungeons/wall"
--buildCorner = "Dungeons/wall_corner" --Remove randomWallCorner/Corners and use this variable for exact corner piece.
if(x == sizeX -1)
then
forge.build(randomWallCorner, {0, 0, 0}, {0, 0, 0}) -- Place corner
forge.build(randomWallCorner, {0, 0, sizeZ -1}, {0, 90, 0}) -- Place corner
elseif(x > 0)
then
forge.build(buildWall, {x, 0, 0}, {0, 90, 0}) -- Place wall
forge.build(buildWall, {x, 0, sizeZ -1}, {0, 90, 0}) -- Place wall
end
end
for z = 0, sizeZ - 2 do -- Repeat size on Z axis
buildWall = "Dungeons/wall"
--buildCorner = "Dungeons/wall_corner" --Remove randomWallCorner/Corners and use this variable for exact corner piece.
if(z == 0)
then
forge.build(randomWallCorner, {sizeX -1, 0,0}, {0, -90, 0}) -- Place corner
forge.build(randomWallCorner, {sizeX -1, 0, sizeZ-1}, {0, 180, 0}) -- Place corner
elseif(z > 0)
then
forge.build(buildWall, {0, 0, z}, {0, 0, 0}) -- Place wall
forge.build(buildWall, {sizeX -1, 0, z}, {0, 0, 0}) -- Place wall
end
end
end
function buildSecondFloorWalls()
if(stairsWaysUpToBuild >= 1)
then
for x = 0, sizeX - 1 do -- Repeat size on X axis
buildWall = "Dungeons/wall"
--buildCorner = "Dungeons/wall_corner" --Remove randomWallCorner/Corners and use this variable for exact corner piece.
if(x == sizeX -1)
then
forge.build(randomWallCorner, {0, 1, 0}, {0, 0, 0}) -- Place corner
forge.build(randomWallCorner, {0, 1, sizeZ -1}, {0, 90, 0}) -- Place corner
elseif(x > 0)
then
forge.build(buildWall, {x, 1, 0}, {0, 90, 0}) -- Place wall
forge.build(buildWall, {x, 1, sizeZ -1}, {0, 90, 0}) -- Place wall
end
end
for z = 0, sizeZ - 2 do -- Repeat size on Z axis
buildWall = "Dungeons/wall"
--buildCorner = "Dungeons/wall_corner" --Remove randomWallCorner/Corners and use this variable for exact corner piece.
if(z == 0)
then
forge.build(randomWallCorner, {sizeX -1, 1,0}, {0, -90, 0}) -- Place corner
forge.build(randomWallCorner, {sizeX -1, 1, sizeZ-1}, {0, 180, 0}) -- Place corner
elseif(z > 0)
then
forge.build(buildWall, {0, 1, z}, {0, 0, 0}) -- Place wall
forge.build(buildWall, {sizeX -1, 1, z}, {0, 0, 0}) -- Place wall
end
end
end
end
function buildFloor() -- this function is creating the floor
for x = 0, sizeX - 1 do
for z = 0, sizeZ - 1 do
forge.build("Dungeons/floor", {x,-1, z}, {0, 0, 0}) -- Place roof
end
end
end
function buildColumns() -- this if statement is placing Columns into the level if requirements are met.
tempColumns = 2
if(sizeX > 4 and sizeZ > 4) --if the size of the room is less then 4 on either X axis or Z axis, columns will not be created.
then
if(sizeX <= sizeZ)
then
for x = 0, columnsToBuild -1 do
if(x == 1)
then
forge.build(randomColumn, {(origX * 0.5)-.5,0, (origZ-1) * 0.25}, {0, 0, 0}) --place column detail
end
if(x == 0)
then
forge.build(randomColumn, {(origX * 0.5)-.5,0, (origZ-1) * 0.75}, {0, 0, 0}) --place column detail
end
end
else
for x = 0, columnsToBuild -1 do
if(x == 1)
then
forge.build(randomColumn, {(origX * .25)-.5,0, (origZ-1) * 0.5}, {0, 0, 0}) --place column detail
end
if(x == 0)
then
forge.build(randomColumn, {(origX * 0.75)-.5,0, (origZ-1) * 0.5}, {0, 0, 0}) --place column detail
end
end
end
if(stairsWaysUpToBuild > 0)
then
if(sizeX <= sizeZ)
then
for x = 0, tempColumns -1 do
if(x == 1)
then
forge.build(randomColumn, {(origX * 0.5)-.5,2, (origZ-1) * 0.25}, {0, 0, 180}) --place column detail
end
if(x == 0)
then
forge.build(randomColumn, {(origX * 0.5)-.5,2, (origZ-1) * 0.75}, {0, 0, 180}) --place column detail
end
end
else
for x = 0, tempColumns -1 do
if(x == 1)
then
forge.build(randomColumn, {(origX * .25)-.5,2, (origZ-1) * 0.5}, {0, 0, 180}) --place column detail
end
if(x == 0)
then
forge.build(randomColumn, {(origX * 0.75)-.5,2, (origZ-1) * 0.5}, {0, 0, 180}) --place column detail
end
end
end
end
end
end
function buildDoorWays() -- this for function is replacing walls with doorways
for x = 0, doorWaysToBuild -1 do --if no walls are built, eg. only corners no doorways will be present in generation of dungeon floor.
forge.selectRandom(buildWall)
a = forge.getSelectionX() -- temp holding X axis infomation, of random selected wall piece.
b = forge.getSelectionY() -- temp holding Y axis infomation, of random selected wall piece.
c = forge.getSelectionZ() -- temp holding Z axis infomation, of random selected wall piece.
if(c == 0 and a > 0) -- checking if it's on the zero of axisZ
then
forge.deleteSelection()
forge.build("DungeonPrefabs/doorway_openjoint", {a, b,-0.4}, {0,90,0})
elseif (a == sizeX-1 and c > 0) -- checking if it's max on the axisX
then
forge.deleteSelection()
forge.build("DungeonPrefabs/doorway_openjoint", {a+0.4, b, c}, {0,0,0})
else -- if above if statements aren't met then replace the wall that's been selected.
forge.replaceSelection("DungeonPrefabs/doorway_openjoint")
end
end
end
function buildStairwaysUp() -- this for function is replacing walls with staircases up
for x = 0, stairsWaysUpToBuild -1 do --if no walls are built, eg. only corners no doorways will be present in generation of dungeon floor.
forge.selectRandom(buildWall)
a = forge.getSelectionX() -- temp holding X axis infomation, of random selected wall piece.
b = forge.getSelectionY() -- temp holding Y axis infomation, of random selected wall piece.
c = forge.getSelectionZ() -- temp holding Z axis infomation, of random selected wall piece.
if(a > 0 and c == 0) -- checking if it's on the zero of axisZ
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_up", {a, b, c +.4}, {0,-90,0})
elseif (a == sizeX-1 and c > 0) -- checking if it's max on the axisX
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_up", {a - 0.4, b, c}, {0,180,0})
elseif (a == 0 and c >= 0)
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_up", {a + 0.4, b, c}, {0,0,0})
elseif(c == sizeZ -1)
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_up", {a, b, c - 0.4}, {0,90,0})
else -- a > c
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_up", {a, b, c + 0.4}, {0,0,0})
end
end
end
function buildStairwaysDown() -- this for function is replacing walls with staircases down
for x = 0, stairWaysDownToBuild -1 do --if no walls are built, eg. only corners no doorways will be present in generation of dungeon floor.
forge.selectRandom(buildWall)
a = forge.getSelectionX() -- temp holding X axis infomation, of random selected wall piece.
b = forge.getSelectionY() -- temp holding Y axis infomation, of random selected wall piece.
c = forge.getSelectionZ() -- temp holding Z axis infomation, of random selected wall piece.
if(a > 0 and c == 0) -- checking if it's on the zero of axisZ
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_down", {a, b, c -0.9}, {0,-90,0})
elseif (a == sizeX-1 and c > 0) -- checking if it's max on the axisX
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_down", {a + 0.9, b, c}, {0,180,0})
elseif (a == 0 and c >= 0)
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_down", {a - 0.9, b, c}, {0,0,0})
elseif(c == sizeZ -1)
then
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_down", {a, b, c + 0.9}, {0,90,0})
else -- a > c
forge.deleteSelection()
forge.build("DungeonPrefabs/staircase_down", {a, b, c - 0.0}, {0,0,0})
end
end
end
function buildLadderUp() -- this function is placing a ladder going up.
for x = 0, ladderUpToBuild - 1 do
randX = math.random(1.5, sizeX-1.5)
randZ = math.random(1.5, sizeZ-1.5)
rotY = math.random(0,1)
if(rotY == 1)
then
forge.build("Western/detail_ladder", {randX, 0, randZ}, {0,0,0})
else
forge.build("Western/detail_ladder", {randX, 0, randZ}, {0,90,0})
end
end
end
function buildLadderDown() -- this function is placing in a ladder going down, it will run this code until the it can find a spot not under a wall or doorway
if(ladderDownToBuild > 0)
then
repeat
forge.selectRandom ("Dungeons/floor")
a = forge.getSelectionX()
b = forge.getSelectionY()
c = forge.getSelectionZ()
if(a != sizeX -1)
then
if(c != sizeZ -1)
then
if(c != 0)
then
if(a != 0)
then
forge.deleteSelection()
forge.build("DungeonPrefabs/ladder_down", {a, b, c}, {0,0,0})
ladderDownToBuild = 0
end
end
end
end
forge.selectNone()
until(ladderDownToBuild == 0)
end
end
function buildCrates() -- this function is crates in the room
for x = 0, cratesToPlace - 1 do
randX = math.random(1.5, sizeX-1.5)
randZ = math.random(1.5, sizeZ-1.5)
rotY = math.random(0, 360)
forge.build("DungeonPrefabs/crates_test", {randX, 0, randZ}, {0,rotY,0})
end
end
function buildFloorDecal(numFloorDecal) -- this function is placing floor decal, the variable numFloorDecal is defined in buildHierachy() function.
for x = 0 , numFloorDecal - 1 do
randX = math.random(1.5, sizeX-1.5)
randZ = math.random(1.5, sizeZ-1.5)
rotY = math.random(0, 360)
forge.build("Dungeons/floor_detail", {randX,0, randZ}, {0, 0, 0}) --place floor detail)
end
end
function buildHierachy() -- This function checks size of room before deciding what to build.
--Comment out any functions within the if statments that you do or do not want to happen.
if(sizeX <= 3)
then
buildLadderDown()
--buildLadderUp() -- if ladder up is more important comment out buildLadderDown(), and uncomment this
buildFloorDecal(minFloorDecalToPlace)
elseif(sizeZ <= 3)
then
buildLadderDown()
--buildLadderUp() -- if ladder up is more important comment out buildLadderDown(), and uncomment this
buildFloorDecal(minFloorDecalToPlace)
elseif(sizeX >= 4 and sizeX <= 6)
then
buildLadderDown()
buildLadderUp()
--buildCrates()
buildFloorDecal(math.random(minFloorDecalToPlace, maxFloorDecalToPlace))
elseif(sizeZ >= 4 and sizeZ <= 6)
then
buildLadderDown()
buildLadderUp()
--buildCrates()
buildFloorDecal(math.random(minFloorDecalToPlace, maxFloorDecalToPlace))
elseif(sizeZ >= 7 and sizeX >= 7)
then
buildLadderDown()
buildLadderUp()
buildFloorDecal(math.random(minFloorDecalToPlace, maxFloorDecalToPlace))
end
end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Comment out any of the following function calls to disable there intended purpose.
forge.clear(); -- Clear previous model, if for whatever reason you don't want to remove models already currently in the scene comment this out.
buildWalls() -- builds walls/wall corners
buildFloor()-- builds floor/floor decal
buildDoorWays() -- replaces a random wall with a doorway, declare how many doors to create above in the variables.
buildColumns() --builds columns, if the room size requirement is met.
buildHierachy() -- checks room, then places remaining objects (Ladders up, down, floor decal and crates) in a set hierachy. The purpose is to deter objects from overlapping.
buildStairwaysDown()
buildStairwaysUp()
buildSecondFloorWalls()
--forge.selectAll()
--forge.groupSelection()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment