123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- function floorRef(currentFloor, type, row, col)
- if (type == "mob") then
- local mobTable = currentFloor["mobTable"]
- if (mobTable[row] == nil or mobTable[row][col] == nil) then
- return nil
- else
- return mobTable[row][col]
- end
- else
- local tileTable = currentFloor["tileTable"]
- if (tileTable[row] == nil or tileTable[row][col] == nil) then
- return nil
- else
- return tileTable[row][col]
- end
- end
- end
- function floorSet(currentFloor, type, row, col, newVal)
- if (type == "mob") then
- local mobTable = currentFloor["mobTable"]
- if (mobTable[row] == nil) then
- mobTable[row] = {}
- end
- mobTable[row][col] = newVal
- else
- local tileTable = currentFloor["tileTable"]
- if (tileTable[row] == nil) then
- tileTable[row] = {}
- end
- tileTable[row][col] = newVal
- end
- end
- function calculatePCStats(level, race, class)
- local statNames = {"maxHP", "maxMP", "melAtk", "rngAtk", "def", "splAtk", "splSup"}
- local result = {}
- for i, stat in pairs(statNames) do
- local levelFactor = level + 4
- local subtotalStat = levelFactor * raceStatFactors[race][stat] * classStatFactors[class][stat]
- local totalStat = math.min(100, math.floor(subtotalStat))
- result[stat] = totalStat
- end
- return result
- end
- function randInt(min, max)
- local scale = max - min + 1
- return math.floor(math.random() * scale) + min
- end
- function pickRandomTile(room)
- return randInt(room[1][1], room[2][1]), randInt(room[1][2], room[2][2])
- end
- function setSpecialRoom(c, stopAt, specialRooms, value)
- local j = 0
- for i=1,stopAt do
- if (specialRooms[i] == nil) then
- j = j + 1
- end
- if (j == c) then
- specialRooms[i] = { id = value }
- return i
- end
- end
- end
- function coordinatesWithinBoundary(xCheck, yCheck, x1, y1, x2, y2)
- return xCheck >= math.min(x1, x2)
- and xCheck <= math.max(x1, x2)
- and yCheck >= math.min(y1, y2)
- and yCheck <= math.max(y1, y2)
- end
- function coordinatesWithinRoom(xCheck, yCheck, room)
- for i, _ in pairs(room) do
- if (room[i+1] ~= nil) then
- if (coordinatesWithinBoundary(xCheck, yCheck, room[i][1], room[i][2], room[i+1][1], room[i+1][2])) then
- return true
- end
- end
- end
- return false
- end
- function calculateCenter(room)
- return math.floor((room[1][1] + room[2][1]) / 2.0), math.floor((room[1][2] + room[2][2]) / 2.0)
- end
- function calculateRoomDistance(room1, room2)
- local x1, y1 = calculateCenter(room1)
- local x2, y2 = calculateCenter(room2)
- local base = x2 - x1
- local height = y2 - y1
- return math.sqrt(base * base + height * height)
- end
- function findClosestRoom(room, listOfExistingRooms, skipRooms)
- local bestRoomIndex, bestRoomDistance
- bestRoomDistance = 10000000
- for i, checkRoom in pairs(listOfExistingRooms) do
- local distance = calculateRoomDistance(room, checkRoom)
- if (distance < bestRoomDistance and skipRooms[i] ~= nil) then
- bestRoomDistance = distance
- bestRoomIndex = i
- end
- end
- return bestRoomIndex
- end
- function calculateHallwayCoordinates(a1, b1, a4, b4, diffA)
- a2 = a1 + math.floor(diffA / 2)
- b2 = b1
- a3 = a2
- b3 = b4
- return a1, b1, a2, b2, a3, b3, a4, b4
- end
- function generateHallway(room1, room2)
- local room1CenterX, room1CenterY = calculateCenter(room1)
- local room2CenterX, room2CenterY = calculateCenter(room2)
- local xDiff = room2CenterX - room1CenterX
- local yDiff = room2CenterY - room1CenterY
- local isVertical = math.abs(xDiff) <= math.abs(xDiff)
- local x1, y1, x2, y2, x3, y3, x4, y4
- if (isVertical) then
- y1, x1, y2, x2, y3, x3, y4, x4 = calculateHallwayCoordinates(room1CenterY, room1CenterX, room2CenterY, room2CenterX, yDiff)
- else
- x1, y1, x2, y2, x3, y3, x4, y4 = calculateHallwayCoordinates(room1CenterX, room1CenterY, room2CenterX, room2CenterY, xDiff)
- end
- return { {x1, y1}, {x2, y2}, {x3, y3}, {x4, y4} }
- end
- function generateRoom(roomRange, listOfExistingRooms, minWidth, minHeight, maxWidth, maxHeight, xPadding, yPadding)
- local width = randInt(minWidth, maxWidth)
- local height = randInt(minHeight, maxHeight)
- local startX = randInt(roomRange[1], roomRange[3] - width)
- local startY = randInt(roomRange[2], roomRange[4] - height)
- for i, existingRoom in pairs(listOfExistingRooms) do
- local compareX = startX - existingRoom[2][1] + xPadding
- local compareY = startY - existingRoom[2][2] + yPadding
- if (compareX < 0 and compareY < 0) then
- if (compareX < compareY) then
- startX = existingRoom[2][1] + xPadding
- else
- startY = existingRoom[2][2] + yPadding
- end
- end
- end
- return {{startX, startY}, {startX + width, startY + height}}
- end
- function generateTown(worldSeed)
- local townGenSeed = worldSeed + 20152314
- math.randomseed(townGenSeed)
- local result = {}
- for i=1,9 do
- result[i] = {}
- for j=1,9 do
- if (i == 1 or i == 9 or j == 1 or j == 9) then
- result[i][j] = 1
- elseif (i == 5 and j == 5) then
- result[i][j] = 11
- else
- result[i][j] = 0
- end
- end
- end
- return result
- end
- function generateFloor(worldSeed, floorNum)
- local floorGenSeed = worldSeed + 612151518 + floorNum
- math.randomseed(floorGenSeed)
- local xRoomSpacing = 4
- local yRoomSpacing = 4
- local xFloorPadding = 2
- local yFloorPadding = 2
- local roomWidth = 10
- local roomHeight = 10
- local innerRoomWidthMin = 3
- local innerRoomHeightMin = 3
- local innerRoomWidthMax = 8
- local innerRoomHeightMax = 8
- local innerRoomPaddingX = 2
- local innerRoomPaddingY = 2
- local roomRows = 4
- local roomCols = 4
- local roomRanges = {}
- for i=1,roomRows do
- roomRanges[i] = {}
- for j=1,roomCols do
- local x1 = (roomWidth + xRoomSpacing) * (j - 1)
- local y1 = (roomHeight + yRoomSpacing) * (i - 1)
- local x2 = x1 + roomWidth
- local y2 = y1 + roomHeight
- roomRanges[i][j] = {x1, y1, x2, y2}
- end
- end
- local listOfExistingRooms = {}
- local floorWidth = 0
- local floorHeight = 0
- for i=1,roomRows do
- for j=1,roomCols do
- local newRoom = generateRoom(roomRanges[i][j], listOfExistingRooms, innerRoomWidthMin, innerRoomHeightMin, innerRoomWidthMax, innerRoomHeightMax, innerRoomPaddingX, innerRoomPaddingY)
- table.insert(listOfExistingRooms, newRoom)
- floorWidth = math.max(floorWidth, newRoom[2][1])
- floorHeight = math.max(floorHeight, newRoom[2][2])
- end
- end
- floorWidth = floorWidth + xFloorPadding * 2
- floorHeight = floorHeight + yFloorPadding * 2
- local skipRooms = {}
- skipRooms[1] = true
- local hallways = {}
- for i=2,roomRows*roomCols do
- local j = findClosestRoom(listOfExistingRooms[i], listOfExistingRooms, skipRooms)
- table.insert(hallways, generateHallway(listOfExistingRooms[i], listOfExistingRooms[j]))
- skipRooms[i] = true
- end
- local specialRooms = {}
- local specialRoomCount = 0
- local result = {}
- if (floorNum < 100) then
- local c = randInt(1, roomRows*roomCols - specialRoomCount)
- local i = setSpecialRoom(c, roomRows*roomCols, specialRooms, 11)
- local x, y = pickRandomTile(listOfExistingRooms[i])
- specialRooms[i]["x"] = x
- specialRooms[i]["y"] = y
- specialRoomCount = specialRoomCount + 1
- end
- if (floorNum > 0) then
- local c = randInt(1, roomRows*roomCols - specialRoomCount)
- local i = setSpecialRoom(c, roomRows*roomCols, specialRooms, 12)
- local x, y = pickRandomTile(listOfExistingRooms[i])
- specialRooms[i]["x"] = x
- specialRooms[i]["y"] = y
- specialRoomCount = specialRoomCount + 1
- end
- if (floorNum % 5 == 1) then
- local c = randInt(1, roomRows*roomCols - specialRoomCount)
- local i = setSpecialRoom(c, roomRows*roomCols, specialRooms, 13)
- local x, y = pickRandomTile(listOfExistingRooms[i])
- specialRooms[i]["x"] = x
- specialRooms[i]["y"] = y
- specialRoomCount = specialRoomCount + 1
- end
- if (floorNum % 5 == 0) then
- local c = randInt(1, roomRows*roomCols - specialRoomCount)
- local i = setSpecialRoom(c, roomRows*roomCols, specialRooms, 14)
- local x, y = pickRandomTile(listOfExistingRooms[i])
- specialRooms[i]["x"] = x
- specialRooms[i]["y"] = y
- specialRoomCount = specialRoomCount + 1
- end
- local specialTiles = {}
- for i, room in pairs(specialRooms) do
- if (specialTiles[room["x"]] == nil) then
- specialTiles[room["x"]] = {}
- end
- specialTiles[room["x"]][room["y"]] = room["id"]
- end
- for i=1,floorHeight do
- result[i] = {}
- for j=1,floorWidth do
- local insideRoom = false
- if (specialTiles[j - xFloorPadding] ~= nil and specialTiles[j - xFloorPadding][i - yFloorPadding] ~= nil) then
- result[i][j] = specialTiles[j - xFloorPadding][i - yFloorPadding]
- else
- for _, room in pairs(listOfExistingRooms) do
- if (coordinatesWithinRoom(j - xFloorPadding, i - yFloorPadding, room)) then
- insideRoom = true
- break
- end
- end
- if (not insideRoom) then
- for _, hallway in pairs(hallways) do
- if (coordinatesWithinRoom(j - xFloorPadding, i - yFloorPadding, hallway)) then
- insideRoom = true
- break
- end
- end
- end
- if (insideRoom) then
- result[i][j] = 0
- else
- result[i][j] = 1
- end
- end
- end
- end
- return result
- end
- function getSpecialTile(type, floor)
- local codeList = {stairsUp = 11, stairsDown = 12, save = 13, boss = 14}
- local code = codeList[type]
- for i, row in pairs(floor["tileTable"]) do
- for j, cell in pairs(row) do
- if (cell == code) then
- return i, j
- end
- end
- end
- end
- moveableMobValues = {}
- moveableMobValues[0] = true
- moveableTileValues = {}
- moveableTileValues[0] = true
- moveableTileValues[11] = true
- moveableTileValues[12] = true
- moveableTileValues[13] = true
- function changeFloors(globalState, changeType, targetFloor)
- local player = globalState["currentFloor"]["player"]
- local tileTable
- if (targetFloor == 0) then
- tileTable = generateTown(globalState["worldSeed"])
- else
- tileTable = generateFloor(globalState["worldSeed"], targetFloor)
- end
- local mobTable = {}
- local newFloor = {
- mobTable = mobTable,
- tileTable = tileTable,
- player = player,
- id = targetFloor
- }
- local playerRow, playerCol
- if (changeType == "up") then
- playerRow, playerCol = getSpecialTile("stairsDown", newFloor)
- elseif (changeType == "down") then
- playerRow, playerCol = getSpecialTile("stairsUp", newFloor)
- else
- playerRow, playerCol = getSpecialTile("save", newFloor)
- end
- player["row"] = playerRow
- player["col"] = playerCol
- floorSet(newFloor, "mob", player["row"], player["col"], 1)
- globalState["currentFloor"] = newFloor
- end
- function attemptToMove(globalState, direction)
- local currentFloor = globalState["currentFloor"]
- local mobTable = currentFloor["mobTable"]
- local tileTable = currentFloor["tileTable"]
- local player = currentFloor["player"]
- local playerRow, playerCol = player["row"], player["col"]
- local targetRow, targetCol
- if (direction == "up") then
- targetRow = playerRow - 1
- targetCol = playerCol
- elseif (direction == "down") then
- targetRow = playerRow + 1
- targetCol = playerCol
- elseif (direction == "left") then
- targetRow = playerRow
- targetCol = playerCol - 1
- else
- targetRow = playerRow
- targetCol = playerCol + 1
- end
- local targetMob = floorRef(currentFloor, "mob", targetRow, targetCol)
- local targetTile = floorRef(currentFloor, "tile", targetRow, targetCol)
- if ((targetMob == nil or moveableMobValues[targetMob]) and moveableTileValues[targetTile]) then
- executeRound(globalState, "move", targetRow, targetCol)
- elseif (targetMob ~= nil and targetMob > 0 and moveableTileValues[targetTile]) then
- executeRound(globalState, "attack", targetRow, targetCol)
- end
- end
- function executeTurn(globalState, mob, actionType, targetRow, targetCol)
- local currentFloor = globalState["currentFloor"]
- local mobTable = currentFloor["mobTable"]
- local mobRow = mob["row"]
- local mobCol = mob["col"]
- local id = mob["id"]
- if (actionType == "move") then
- floorSet(currentFloor, "mob", mobRow, mobCol, 0)
- floorSet(currentFloor, "mob", targetRow, targetCol, id)
- mob["row"] = targetRow
- mob["col"] = targetCol
- end
- end
- function executeRound(globalState, actionType, targetRow, targetCol)
- local currentFloor = globalState["currentFloor"]
- local mobTable = currentFloor["mobTable"]
- executeTurn(globalState, currentFloor["player"], actionType, targetRow, targetCol)
- for i, row in pairs(mobTable) do
- for j, cell in pairs(row) do
- if (cell > 1) then
- local mobLogic, targetRow, targetCol = getMobLogic(mob)
- executeTurn(globalState, cell, mobLogic, targetRow, targetCol)
- end
- end
- end
- if (actionType == "move") then
- local newTile = floorRef(currentFloor, "tile", targetRow, targetCol)
- if (newTile == 11) then
- changeFloors(globalState, "up", currentFloor["id"] + 1)
- elseif (newTile == 12) then
- changeFloors(globalState, "down", currentFloor["id"] - 1)
- end
- end
- end
- raceStatFactors = {
- human = { maxHP = 1.05, maxMP = 1.05, melAtk = 1.05, rngAtk = 1.05, def = 1.05, splAtk = 1.05, splSup = 1.05 }
- }
- classStatFactors = {
- warrior = { maxHP = 1.5, maxMP = 0.0, melAtk = 1.5, rngAtk = 1.25, def = 1.5, splAtk = 0.0, splSup = 0.0 }
- }
- myClass = "warrior"
- mySubclass = "knight"
- myRace = "human"
- mySubrace = "plains"
- myLevel = 5
- myExperience = 12
- myBossLevelCode = 0
- mySaveFloorCode = 1
- myWorldSeed = 12345
- myStats = calculatePCStats(myLevel, myRace, myClass)
- myStats["currentHP"] = myStats["maxHP"]
- myStats["currentMP"] = myStats["maxMP"]
- myPlayer = {
- stats = myStats,
- id = 1,
- row = 19,
- col = 19
- }
- myCurrentFloor = {
- player = myPlayer,
- id = 2
- }
- globalState = {
- worldSeed = myWorldSeed,
- currentFloor = myCurrentFloor
- }
- changeFloors(globalState, "up", 1)
|