// Generates a dungeon with rooms.
// Worthless Bums 2012.


// Generates a dungeon with rectangular rooms connected by corridors.
function generateRoomAndCorridorDungeon (%size)
{//echo("generateRoomAndCorridorDungeon()");
	$mazeDimension = %size;
	$mazeLength = %size * %size;
	destroyMazeRoom();
	$mazeRoom[%size, %size] = null;
	$baseTile = "Obsidian_Tile_32x32ImageMap";
	PreloadedTilemap.setImagemap("Preloaded_Obsidian_Tile_Background_2048x2048Imagemap");
	PreloadedTilemap.setPosition("128 128");
	PreloadedTilemap.setSize("128 128");
	PreloadedTilemap.setLayer($PreloadedTilemapLayer);		// Layer 26, not 25 like the rest of the tile Sprites!
	for (%i = 0; %i < %size; %i++)
	{
		for (%j = 0; %j < %size; %j++)
		{
			$mazeRoom[%i, %j] = new Sprite("Wall")
			{
				status = -2;				// By default make the room tile unwalkable and unsmashable.
				SceneLayer = 25;
				position = %i * 4 + 2 SPC %j * 4 + 2;
				scenegraph = levelSceneGraph;
				imagemap = "Wall_Tile_32x32ImageMap";
				visible = true;
				size = "4 4";
			};
			addObjectToScene($mazeRoom[%i, %j]);
		}
	}
	// Cell data.
	$roomSize = 8;// Room size 6 & 7makes some funny maps!					// Rather arbitrary - just have rooms large enough for a full squad to squeeze inside! That's a design decision...
	$cellSize = %size / $roomSize;	// Scale %size and $roomSize or trim off fractions!
	%numberOfCells = $cellSize * $cellSize;
	$cellArray[%numberOfCells] = 0;		// Since the maze room is square, $cellSize is also the number of cells on the entire map.
	// Loop through cell array.
	for (%i = 0; %i < $cellSize; %i++)			// Columns.
	{
		for (%j = 0; %j < $cellSize; %j++)		// Rows.
		{
			// Fill each cell index with the four corners of that cell.
			$cellArray[%i * $roomSize + %j] = new ScriptObject()
			{	
				// Corner	// x-coordinate				// y-coordinate					// Example coordinates for $roomSize = 8
				nwCorner = 	%j * $roomSize 				SPC	%i * $roomSize;				// 0 0		 8 0
				neCorner = 	(%j + 1) * $roomSize - 1	SPC	%i * $roomSize;				// 7 0		15 0
				swCorner = 	%j * $roomSize 				SPC	(%i + 1) * $roomSize - 1;	// 0 7		`8 7
				seCorner = 	(%j + 1) * $roomSize - 1	SPC	(%i + 1) * $roomSize - 1;	// 7 7		15 7
				free = true;
			};
			//echo(%i * $roomSize + %j SPC "$cellArray[%i + %j].free =" SPC $cellArray[%i + %j].free);
		}
	}
	%randomCellIndex = getRandom(0, %numberOfCells - 1);
	%randomCellIndex = 0;
	createRoomAtCell($cellArray[%randomCellIndex]);
	$cellArray[%randomCellIndex].free = false;
	%roomCount = 1;
	%cellPicked = false;
	%cellAttempts = 0;
	%maxRooms = 64;		// Somewhat arbitrary.
	for (%numRooms = 1; %numRooms < %maxRooms; %numRooms++)
	{
		%cellPicked = false;
		%directionZero = false;
		%directionOne = false;
		%directionTwo = false;
		%directionThree = false;
		do {
			%cellDirection = getRandom(0, 3);
			switch (%cellDirection)
			{
				case 0:	// Up.
					if (%randomCellIndex - 8 > 0	&&		// Up is -8 cells.
						getWord($cellArray[%randomCellIndex - 1].nwCorner, 1) != 0)
					{
						if ($cellArray[%randomCellIndex - 8].free)
						{
							createRoomAtCell($cellArray[%randomCellIndex - 8]);
							$cellArray[%randomCellIndex - 8].free = false;
							%roomCount++;
							%cellPicked = true;
							%randomCellIndex = %randomCellIndex - 8;
							%cellAttempts = 8;
						}
					}
					else
					{//echo("%cellAttempts =" SPC %cellAttempts);
						%cellAttempts++;
					}
					%directionZero = true;
					
				case 1:	// Down.
					if (%randomCellIndex + 8 < %numberOfCells	&&		// Down is +8 cells.
						getWord($cellArray[%randomCellIndex - 1].swCorner, 1) != $mazeDimension - 1)
					{
						if ($cellArray[%randomCellIndex + 8].free)
						{
							createRoomAtCell($cellArray[%randomCellIndex + 8]);
							$cellArray[%randomCellIndex + 8].free = false;
							%roomCount++;
							%cellPicked = true;
							%randomCellIndex = %randomCellIndex + 8;
							%cellAttempts = 8;
						}
					}
					else
					{//echo("%cellAttempts =" SPC %cellAttempts);
						%cellAttempts++;
					}
					%directionOne = true;
					
				case 2:	// Left.
					if (%randomCellIndex - 1 > 0	&&			// Left is -1 cell.
						getWord($cellArray[%randomCellIndex - 1].nwCorner, 0) != 0)//(%randomCellX + %randomCellY) % $roomSize != 0)	// Multiple of $roomSize means the room is on the left hand edge of the map.
					{
						if ($cellArray[%randomCellIndex - 1].free)
						{
							createRoomAtCell($cellArray[%randomCellIndex - 1]);
							$cellArray[%randomCellIndex - 1].free = false;
							%roomCount++;
							%cellPicked = true;
							%randomCellIndex = %randomCellIndex - 1;
							%cellAttempts = 8;
						}
					}
					else
					{//echo("%cellAttempts =" SPC %cellAttempts);
						%cellAttempts++;
					}
					%directionTwo = true;
					
				case 3:	// Right.
					if (%randomCellIndex + 1 < %numberOfCells	&&		// Right is +1 cells.
						getWord($cellArray[%randomCellIndex + 1].neCorner, 0) != $mazeDimension - 1)
					{
						if ($cellArray[%randomCellIndex + 1].free)
						{
							createRoomAtCell($cellArray[%randomCellIndex + 1]);
							$cellArray[%randomCellIndex + 1].free = false;
							%roomCount++;
							%cellPicked = true;
							%randomCellIndexs = %randomCellIndex + 1;
							%cellAttempts = 8;
						}
					}
					else
					{//echo("%cellAttempts =" SPC %cellAttempts);
						%cellAttempts++;
					}
					%directionThree = true;
				
			}
		} while (!%cellPicked	&&		// Keep trying if we don't have a free cell...
				 !(%directionZero && %directionOne && %directionTwo && %directionThree))		// Make sure we have checked all directions to walk in!
	}
	connectCellRooms();
	addStairsToDungeon();
}
function createRoomAtCell (%randomCell)
{//echo("createRoomAtCell()");
	for (%i = getWord(%randomCell.nwCorner, 0) + 1; %i < getWord(%randomCell.neCorner, 0) - 1; %i++)		// Columns.
	{
		for (%j = getWord(%randomCell.nwCorner, 1) + 1; %j < getWord(%randomCell.swCorner, 1) - 1; %j++)	// Rows.
		{
			$mazeRoom[%i, %j].safeDelete();
			$mazeRoom[%i, %j] = null;
		}
	}
}
function connectCellRooms ()
{//echo("connectCellRooms()");
	for (%i = 0; %i < $cellSize; %i++)
	{
		for (%j = 0; %j < $cellSize; %j++)
		{
			if (!$cellArray[%i * $roomSize + %j].free)
			{
				%cellArrayIndex = %i * $roomSize + %j;
				%xIndex = getWord($cellArray[%cellArrayIndex].nwCorner, 0);
				%yIndex = getWord($cellArray[%cellArrayIndex].nwCorner, 1);
				if (%cellArrayIndex - 8 >= 0)						// Up is -8.
				{
					if (!$cellArray[%cellArrayIndex - 8].free)
					{
						makeFloorTile(%xIndex + 3, %yIndex);
						makeFloorTile(%xIndex + 3, %yIndex - 1);
						makeFloorTile(%xIndex + 3, %yIndex - 2);
					}
				}
				if (%cellArrayIndex + 8 < %numberOfCells)			// Down is +8.
				{
					if (!$cellArray[%cellArrayIndex + 8].free)
					{
						makeFloorTile(%xIndex + 3, %yIndex + 6);
						makeFloorTile(%xIndex + 3, %yIndex + 7);
						makeFloorTile(%xIndex + 3, %yIndex + 8);
					}
				}
				if (%cellArrayIndex - 1 >= 0	&&					// Left is -1.
					getWord($cellArray[%cellArrayIndex].nwCorner, 0) != 0)
				{
					if (!$cellArray[%cellArrayIndex - 1].free)
					{
						makeFloorTile(%xIndex, %yIndex + 3);
						makeFloorTile(%xIndex - 1, %yIndex + 3);
						makeFloorTile(%xIndex - 2, %yIndex + 3);
					}
				}
				if (%cellArrayIndex + 1 < %numberOfCells	&&		// Right is +1.
					getWord($cellArray[%cellArrayIndex].nwCorner, 0) != $mazeDimension - 1)
				{
					if (!$cellArray[%cellArrayIndex + 1].free)
					{
						makeFloorTile(%xIndex + 6, %yIndex + 3);
						makeFloorTile(%xIndex + 7, %yIndex + 3);
						makeFloorTile(%xIndex + 8, %yIndex + 3);
					}
				}
			}
		}
	}
}
function makeFloorTile (%xIndex, %yIndex)
{//echo("makeFloorTile()");
	$mazeRoom[%xIndex, %yIndex].safeDelete();
	$mazeRoom[%xIndex, %yIndex] = null;
}