Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nyzul] Random layout generation implementation #6995

Draft
wants to merge 1 commit into
base: base
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
287 changes: 287 additions & 0 deletions scripts/globals/nyzul/floor_layout.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
-----------------------------------
-- Nyzul Isle: Floor generation methods and data.
-----------------------------------
local ID = zones[xi.zone.NYZUL_ISLE]
-----------------------------------
xi = xi or {}
xi.nyzul = xi.nyzul or {}

local room =
{
-- Rooms located in South-East block.
SE_EXT_N = 101,
SE_EXT_E = 102,
SE_EXT_S = 103,
SE_EXT_W_LOWER = 104,
SE_EXT_W_UPPER = 105,
SE_INT_N = 106,
SE_INT_NE = 107,
SE_INT_E = 108,
SE_INT_SE = 109,
SE_INT_S = 110,
SE_INT_SW = 111,
SE_INT_W = 112,
SE_INT_NW = 113,
}

local group =
{
-- Room groups located in South-East block.
SE_1 = 1001,
SE_2 = 1002,
SE_3 = 1003,
SE_4 = 1004,
SE_5 = 1005,
SE_6 = 1006,
SE_7 = 1007,
}

local block =
{
NORTH_EAST = 1,
CENTRAL = 2,
EAST = 3,
SOUTH_WEST = 4,
SOUTH = 5,
SOUTH_EAST = 6,
}

-- Information of all individual rooms.
local roomInfoTable =
{
-- South-East block (7 groups, 13 rooms).
[room.SE_EXT_N] = -- In group SE 1.
{
mobSpawnPoints = { { 460, 0, -446.5 }, { 460, 0, -433.5 }, { 433.5, 0, -433.5 }, { 486.5, 0, -433.5 }, { 460, 0, -429 } },
lampSpawnPoints = { { 480, 0, -440 }, { 460, 0, -440 }, { 440, 0, -440 } }
},
[room.SE_EXT_E] = -- In group SE 2.
{
mobSpawnPoints = { { 553, 0, -560 }, { 560, 0, -552.5 }, { 560, 0, -527.5 }, { 553.5, 0, -513.5 }, { 553.5, 0, -540 } },
lampSpawnPoints = { { 560, 0, -540 }, { 560, 0, -520 }, { 560, 0, -560 } }
},
[room.SE_EXT_S] = -- In group SE 3.
{
mobSpawnPoints = { { 460, 0, -640 }, { 486.5, 0, -646.5 }, { 433.5, 0, -646.5 }, { 486.5, 0, -633.5 }, { 433.5, 0, -633.5 } },
lampSpawnPoints = { { 460, 0, -646.5 }, { 460, 0, -633.5 } }
},
[room.SE_EXT_W_LOWER] = -- In group SE 6.
{
mobSpawnPoints = { { 366.5, 0, -535.5 }, { 375.5, 0, -535.5 }, { 384.5, 0, -540 }, { 375.5, 0, -544.5 }, { 366.5, 0, -549 } },
lampSpawnPoints = { { 366.5, 0, -535.5 }, { 366.5, 0, -535.5 } }
},
[room.SE_EXT_W_UPPER] = -- In group SE 7.
{
mobSpawnPoints = { { 366.5, 0, -526.5 }, { 393.5, 0, -553.5 }, { 393.5, 0, -526.5 }, { 380, 0, -526.5 }, { 393.5, 0, -540 } },
lampSpawnPoints = { { 366.5, 0, -526.5 }, { 393.5, 0, -553.5 } }
},
[room.SE_INT_N] = -- In group SE 4.
{
mobSpawnPoints = { { 473.5, 0, -486.5 }, { 446.5, 0, -486.5 }, { 455.5, 0, -495.5 }, { 464.5, 0, -500 }, { 455.5, 0, -513.5 } },
lampSpawnPoints = { { 451, 0, -486.5 }, { 469, 0, -486.5 } }
},
[room.SE_INT_NE] = -- In group SE 4.
{
mobSpawnPoints = { { 509, 0, -500 }, { 491, 0, -500 }, { 491, 0, -509 }, { 486.5, 0, -513.5 }, { 500, 0, -486.5 } },
lampSpawnPoints = { { 491, 0, -500 }, { 500, 0, -509 } }
},
[room.SE_INT_E] = -- In group SE 5.
{
mobSpawnPoints = { { 500, 0, -540 }, { 509, 0, -531 }, { 491, 0, -549 }, { 491, 0, -531 }, { 509, 0, -549 } },
lampSpawnPoints = { { 491, 0, -540 }, { 509, 0, -540 } }
},
[room.SE_INT_SE] = -- In group SE 5.
{
mobSpawnPoints = { { 513.5, 0, -593.5 }, { 505.5, 0, -585.5 }, { 491, 0, -571 }, { 486.5, 0, -566.5 }, { 486.5, 0, -593.5 } },
lampSpawnPoints = { { 509, 0, -589 }, { 491, 0, -580 } }
},
[room.SE_INT_S] = -- In group SE 6.
{
mobSpawnPoints = { { 464.5, 0, -566.5 }, { 464.5, 0, -580 }, { 455.5, 0, -584.5 }, { 455.5, 0, -566.5 }, { 446.5, 0, -571 } },
lampSpawnPoints = { { 446.5, 0, -566.5 }, { 473.5, 0, -566.5 } }
},
[room.SE_INT_SW] = -- In group SE 6.
{
mobSpawnPoints = { { 424.5, 0, -575.5 }, { 415.5, 0, -580 }, { 411, 0, -593.5 }, { 406.5, 0, -566.5 }, { 429, 0, -566.5 } },
lampSpawnPoints = { { 424.5, 0, -580 }, { 420, 0, -575.5 } }
},
[room.SE_INT_W] = -- In group SE 7.
{
mobSpawnPoints = { { 433.5, 0, -553.5 }, { 415.5, 0, -535.5 }, { 429, 0, -531 }, { 411, 0, -549 }, { 420, 0, -540 } },
lampSpawnPoints = { { 420, 0, -540 }, { 429, 0, -549 } }
},
[room.SE_INT_NW] = -- In group SE 7.
{
mobSpawnPoints = { { 406.5, 0, -513.5 }, { 433.5, 0, -509 }, { 433.5, 0, -486.5 }, { 424.5, 0, -495.5 }, { 415.5, 0, -495.5 } },
lampSpawnPoints = { { 420, 0, -504.5 }, { 411, 0, -513.5 } }
},
}

-- Information of all rooms that form an indivisible group (No doors to separate them).
local groupInfoTable =
{
-- South-East block (7 groups, 13 rooms).
[group.SE_1] =
{
rooms = { room.SE_EXT_N },
connections =
{
{ group.SE_4, { ID.npc.DOOR_OFFSET + 8 } }
},
},
[group.SE_2] =
{
rooms = { room.SE_EXT_E },
connections =
{
{ group.SE_5, { ID.npc.DOOR_OFFSET + 5 } }
},
},
[group.SE_3] =
{
rooms = { room.SE_EXT_S },
connections =
{
{ group.SE_6, { ID.npc.DOOR_OFFSET + 2 } }
},
},
[group.SE_4] =
{
rooms = { room.SE_INT_N, room.SE_INT_NE },
connections =
{
{ group.SE_1, { ID.npc.DOOR_OFFSET + 8 } },
{ group.SE_5, { ID.npc.DOOR_OFFSET + 6 } },
{ group.SE_7, { ID.npc.DOOR_OFFSET + 7 } }
},
},
[group.SE_5] =
{
rooms = { room.SE_INT_E, room.SE_INT_SE },
connections =
{
{ group.SE_2, { ID.npc.DOOR_OFFSET + 5 } },
{ group.SE_4, { ID.npc.DOOR_OFFSET + 6 } },
{ group.SE_6, { ID.npc.DOOR_OFFSET + 3 } }
},
},
[group.SE_6] =
{
rooms = { room.SE_INT_S, room.SE_INT_SW, room.SE_EXT_W_LOWER },
connections =
{
{ group.SE_3, { ID.npc.DOOR_OFFSET + 2 } },
{ group.SE_5, { ID.npc.DOOR_OFFSET + 3 } },
{ group.SE_7, { ID.npc.DOOR_OFFSET, ID.npc.DOOR_OFFSET + 1, ID.npc.DOOR_OFFSET + 4 } }
},
},
[group.SE_7] =
{
rooms = { room.SE_INT_W, room.SE_INT_NW, room.SE_EXT_W_UPPER },
connections =
{
{ group.SE_4, { ID.npc.DOOR_OFFSET + 7 } },
{ group.SE_6, { ID.npc.DOOR_OFFSET, ID.npc.DOOR_OFFSET + 1, ID.npc.DOOR_OFFSET + 4 } }
},
},
}

-- Blocks are independent. Contain groups of rooms. The selection of those room groups define a layout.
local blockInfoTable =
{
[block.NORTH_EAST] = {},
[block.CENTRAL ] = {},
[block.EAST ] = {},
[block.SOUTH_WEST] = {},
[block.SOUTH ] = {},
[block.SOUTH_EAST] = { group.SE_1, group.SE_2, group.SE_3, group.SE_4, group.SE_5, group.SE_6, group.SE_7 },
}

xi.nyzul.generateRandomLayout = function()
local layout = {}
layout.mobSpwanPointTable = {}
layout.lampSpawnPointTable = {}
layout.doorsToOpenTable = {}
layout.runeSpawnPoint = {}

-- 1. Select one block (currently hardcoded to 6; later use math.random(1, 6))
local chosenBlockId = 6
local allowedGroupsTable = blockInfoTable[chosenBlockId]

-- 2: Select 1 (any) group from the block to start the layout.
local randomEntry = math.random(1, #allowedGroupsTable)
local initialGroupId = allowedGroupsTable[randomEntry]
table.remove(allowedGroupsTable, randomEntry)

-- 3: Create a list of rooms and track the amount we have.
local roomTable = {} -- We will store all individual room IDs from all groups used here.
local totalRooms = 0
local roomsNeeded = 6 + math.random(0, 2) -- We need 6 rooms at the bare minimum.

-- Repeat process until we ensure the amount of rooms we need is reached.
local groupTable = {}
table.insert(groupTable, { initialGroupId, { 0 } })

while totalRooms < roomsNeeded do
-- 4. Pick a random group.
randomEntry = math.random(1, #groupTable)

-- Unpack info and delete entry.
local groupId = groupTable[randomEntry][1]
local doorTable = groupTable[randomEntry][2]
table.remove(groupTable, randomEntry)

-- 5. Handle doors.
randomEntry = math.random(1, #doorTable) -- This will choose how many doors we open.
for i = 1, randomEntry do
local doorId = doorTable[i]
if doorId ~= 0 then
table.insert(layout.doorsToOpenTable, doorId)
end
end

-- Store room IDs contained in chosen group entry.
local groupInfo = groupInfoTable[groupId]
for i = 1, #groupInfo.rooms do
table.insert(roomTable, groupInfo.rooms[i])
end

-- 6. Prepare next loop with chosen group entry.
for i = 1, #groupInfo.connections do
-- Ensure entry can be chosen in the first place.
local connectedGroupId = groupInfo.connections[i][1]
for j = 1, #allowedGroupsTable do
if connectedGroupId == allowedGroupsTable[j] then
table.insert(groupTable, groupInfo.connections[i])
table.remove(allowedGroupsTable, j)

break
end
end
end

totalRooms = totalRooms + #groupInfo.rooms
end

-- 7. Choose one room from roomTable as the initial spawn for the rune.
local initialRoomIndex = math.random(1, #roomTable)
local runicPortalPosTable = roomInfoTable[roomTable[initialRoomIndex]].lampSpawnPoints

table.insert(layout.runeSpawnPoint, runicPortalPosTable[math.random(1, #runicPortalPosTable)])
table.remove(roomTable, initialRoomIndex)

-- 8. Populate the mob and lamp spawn point tables from the remaining rooms.
for _, roomId in ipairs(roomTable) do
local roomData = roomInfoTable[roomId]

for _, coordinates in ipairs(roomData.mobSpawnPoints) do
table.insert(layout.mobSpwanPointTable, coordinates)
end

for _, coordinates in ipairs(roomData.lampSpawnPoints) do
table.insert(layout.lampSpawnPointTable, coordinates)
end
end

return layout
end