// Handles Monster Spawning Holes.
// Worthless Bums 2012.


// Spawns a monster from a grating tile!
function spawnGratingMonster ()
{//echo("spawnGratingMonster()");
	// Loop through grating tiles.
	for (%i = 0; %i < $gratingList.getCount(); %i++)
	{
		// Grab grating.
		%grating = $gratingList.getObject(%i);
		
		// Pick a grating within sight of the squad.
		%fowTileImagemap = getWord($fogOfWar.getTileType(%grating.xIndex, %grating.yIndex), 1);
		if (%fowTileImagemap $= "Sprites:blank_1x1")
		{
			// Make sure tile is not covered by a squad member or other obstruction!
			if (tileIsClear(%grating.xIndex, %grating.yIndex))
			{
				// Burst grating!
				//%grating.imagemap = "Set1GratingFloorDestroyedImageMap";
				/*if ($overworldLocation $= "Command Deck")
				{
					%grating.imagemap = "Set1GratingFloorDestroyedImageMap";
				}
				else if ($overworldLocation $= "Engineering Deck")
				{
					%grating.imagemap = "EngineeringDeckSet2GratingFloorDestroyedImageMap";
				}*/
				%grating.imagemap = getImageFromOverworldLocation();
				%grating.frame = 50;
				// Spawn a monster!
				%monster = spawnRandomMonster(%grating.xIndex, %grating.yIndex);
				// Add shadow to monster.
				createUnitShadow(%monster);
				// Add monster to list.
				$monsterList.add(%monster);
				// Play monster discovery shriek!
				playRandomMetalWallCollapseSfx();
				// Play monster discovery shriek!
				playRobotShriekSfx();
				pushQuickInfoText("An enemy burst\nfrom the grating!", 4500);
				// Update event log.
				updateEventText($whiteColor @ "Grating bursts open" @ $defaultColor @ "!");
				return true;
			}
		}
	}
	return false;
}
// Spawns a monster from a wall grating tile!
function spawnWallGratingMonster ()
{//echo("spawnWallGratingMonster()");
	// Loop through grating tiles.
	for (%i = 0; %i < $mazeDimension; %i++)
	{
		for (%j = 0; %j < $mazeDimension; %j++)
		{
			// Check for wall grating.
			if (isObject($mazeRoom[%i, %j])		&&
				$mazeRoom[%i, %j].frame == 51)				// Wall grating frame.
			{
				%xIndex = $mazeRoom[%i, %j].xIndex;
				%yIndex = $mazeRoom[%i, %j].yIndex + 1;
				// Pick a grating within sight of the squad.
				%fowTileImagemap = getWord($fogOfWar.getTileType(%xIndex, %yIndex), 1);
				if (%fowTileImagemap $= "Sprites:blank_1x1")
				{
					// Make sure tile below is not covered by a squad member or other obstruction!
					if (tileIsClear(%xIndex, %yIndex))
					{
						// Burst grating!
						$mazeRoom[%i, %j].frame = 52;		// Wall burst grating frame.
						// Spawn a monster!
						%monster = spawnRandomMonster(%xIndex, %yIndex);
						// Add shadow to monster.
						createUnitShadow(%monster);
						// Add monster to list.
						$monsterList.add(%monster);
						// Play monster discovery shriek!
						playRandomMetalWallCollapseSfx();
						// Play monster discovery shriek!
						playRobotShriekSfx();
						// Update event log.
						updateEventText($whiteColor @ "Wall grating bursts open" @ $defaultColor @ "!");
						// Check for traps!
						characterOnTrap(%monster);
						return true;
					}
				}
			}
		}
	}
	return false;
}


//----------------------------------------------------------------------------------------------------------------


// Handle spawning hole generation.
function handleSpawningHoleGeneration ()
{//echo("handleSpawningHoleGeneration()");
	// Determine monster type for a spawning hole.
	%monsterType = getRandomMonsterType();
	//do {
	//	%monsterType = getRandomMonsterType();
	//} while(%monsterType == 2)		// Don't spawn Bloat holes!
	
	// Create a spawning hole if there are too few monsters on the map and no spawning holes.
	if ($monsterList.getCount() < 2)
	{
		createMonsterSpawningHole(%monsterType);
	}
	
	// Two percent chance to create a spawning hole, per turn.
	%holeSpawnChance = 2;
	%holeSpawnRoll = getRandom(1, 100);
	if (%holeSpawnChance >= %holeSpawnRoll)
	{
		createMonsterSpawningHole(%monsterType);
	}
	
	// Handle any spawning holes.
	handleSpawningHoles();
}

// Handles periodic spawning of monster holes and spawns monsters on hole positions.
function handleSpawningHoles ()
{//echo("handleSpawningHoles()");
	// Make sure $spawningHoles is alive and well.
	if (!isObject($spawningHoles))
	{
		$spawningHoles = new SimSet();
	}
	
	// Determine whether to spawn a monster on each whole.
	%spawnChance = 5;		// 5% chance to spawn a monster per turn, per hole.
	
	for (%i = 0; %i < $spawningHoles.getCount(); %i++)
	{
		// Do not allow more than $maxMonsters amount of monsters!
		if ($monsterList.getCount() >= $maxMonsters)
		{
			
			return false;
		}
		
		%spawnRoll = getRandom(1, 100);
		if (%spawnChance >= %spawnRoll)
		{
			// Grab the spawning hole's x and y indices.
			%xIndex = ($spawningHoles.getObject(%i)).xIndex;
			%yIndex = ($spawningHoles.getObject(%i)).yIndex;
			
			// Check if the spawn hole tile is clear from monsters and squad members!
			if (!isObject($mazeRoom[%xIndex, %yIndex])		&&
				tileClearOfMonsters(%xIndex, %yIndex)		&&
				tileClearOfSquadMembers(%xIndex, %yIndex))
			{//echo("spawning monster from hole!");
				// Spawn a monster of that hole's monster type!
				//%monster = spawnMonster(($spawningHoles.getObject(%i)).monsterType, %xIndex, %yIndex);	// Function is deprecated!
				
				if (isObject(%monster))
				{
					$monsterList.add(%monster);
				}
			}
		}
	}
}

// Creates a monster spawning hole.
function createMonsterSpawningHole (%monsterType)
{//echo("createMonsterSpawningHole()");
	// Make sure $spawningHoles is alive and well.
	if (!isObject($spawningHoles))
	{
		$spawningHoles = new SimSet();
	}
	
	// Find a tile without obstruction and without a monster or squad member on it.
	%tileFound = false;
	do {
		%xIndex = getRandom(0, $mazeDimension - 1);
		%yIndex = getRandom(0, $mazeDimension - 1);
		
		if (!isObject($mazeRoom[%xIndex, %yIndex])		&&
			tileClearOfMonsters(%xIndex, %yIndex)		&&
			tileClearOfSquadMembers(%xIndex, %yIndex))
		{
			%tileFound = true;
		}
	} while (!%tileFound)
	
	// Create a spawning hole.
	%spawningHole = new Sprite()
	{
		SceneLayer = 15;
		scenegraph = levelSceneGraph;
		imageMap = "Spawning_HoleImageMap";
		position = getTilePositionFromIndices(%xIndex, %yIndex);
		size = "4 4";
		visible = true;
		xIndex = %xIndex;
		yIndex = %yIndex;
		monsterType = %monsterType;
	};
	addObjectToScene(%spawningHole);
	
	//echo("%spawningHole.position =" SPC %spawningHole.position);
	// Add the new spawning hole to the global list.
	$spawningHoles.add(%spawningHole);
}

// Function returns true iff a tile holds a unit (squad member or monster).
function tileHasUnit (%xIndex, %yIndex)
{//echo("tileHasUnit()");
	%monster = getMonsterOnTile(%xIndex, %yIndex);
	if (isObject(%monster))
	{
		return %monster;
	}
	%character = getCharacterOnTile(%xIndex, %yIndex);
	if (isObject(%character))
	{
		return %character;
	}
	
	return null;
}

// Function returns true iff a tile is clear (a squad member or monster can move to it).
function tileIsClear (%xIndex, %yIndex)
{//echo("tileIsClear()");
	if ((!isObject($mazeRoom[%xIndex, %yIndex])	|| (isObject($mazeRoom[%xIndex, %yIndex])	&&	$mazeRoom[%xIndex, %yIndex].status == -4))	&&
		tileClearOfMonsters(%xIndex, %yIndex)		&&
		tileClearOfSquadMembers(%xIndex, %yIndex)	&&
		!tileHasConsole(%xIndex, %yIndex)			&&
		!tileHasDispenser(%xIndex, %yIndex)			&&
		!tileHasCryoTube(%xIndex, %yIndex))
	{
		return true;
	}
	else
	{
		return false;
	}
}

function canPlaceElevator (%xIndex, %yIndex)
{//echo("canPlaceElevator()");
	if (!isObject($mazeRoom[%xIndex, %yIndex])	|| (isObject($mazeRoom[%xIndex, %yIndex])	&&	$mazeRoom[%xIndex, %yIndex].status == -4))
	{
		return true;
	}
	else
	{
		return false;
	}
}

// Returns true iff the specified indices is a space tile.
function isSpaceTile (%xIndex, %yIndex)
{//echo("isSpaceTile()");
	if (isObject($mazeRoom[%xIndex, %yIndex]))
	{
		switch$ ($mazeRoom[%xIndex, %yIndex].image)
		{
			case "Sprites:SpaceBackground1":
				return true;
			case "Sprites:SpaceBackground2":
				return true;
			case "Sprites:SpaceBackground3":
				return true;
			case "Sprites:SpaceBackground4":
				return true;
			case "Sprites:SpaceBackground5":
				return true;
			case "Sprites:SpaceBackground6":
				return true;
		}
	}
	/*if ($mazeRoom[%xIndex, %yIndex] == -12)	// Space.
	{
		return true;
	}*/
	if ($mapArr[%yIndex, %xIndex] == 1)		// Space.
	{
		return true;
	}
	return false;
}

// Function returns true iff a tile is clear (a squad member or monster can move to it).
function tileIsClearOfUnits (%xIndex, %yIndex)
{//echo("tileIsClearOfUnits()");
	if (tileClearOfMonsters(%xIndex, %yIndex)	&&
		tileClearOfSquadMembers(%xIndex, %yIndex))
	{
		return true;
	}
	else
	{
		return false;
	}
}

// Function returns true iff a tile will be clear (a squad member or monster can move to it).
function tileWillBeClear (%xIndex, %yIndex)
{//echo("tileWillBeClear()");
	if (tileClearOfMonsters(%xIndex, %yIndex))
	{
		return true;
	}
	else
	{
		return false;
	}
}

// Returns a monster index if any on the specified tile.
function getMonsterIndexOnTile (%xIndex, %yIndex)
{//echo("getMonsterIndexOnTile()");
	// Bounds check.
	if (%xIndex < 0					||
		%yIndex < 0					||
		%xIndex > $mazeDimension	||
		%yIndex > $mazeDimension)
	{
		return -1;
	}
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		if (%monster.xIndex == %xIndex	&&
			%monster.yIndex == %yIndex)
		{
			return %i;
		}
	}
	return -1;
}
// Returns a monster if any on the specified tile.
function getMonsterOnTile (%xIndex, %yIndex)
{//echo("getMonsterOnTile()");
	// Bounds check.
	if (%xIndex < 0					||
		%yIndex < 0					||
		%xIndex > $mazeDimension	||
		%yIndex > $mazeDimension)
	{
		return null;
	}
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		%monster = $monsterList.getObject(%i);
		if (%monster.xIndex == %xIndex	&&
			%monster.yIndex == %yIndex)
		{
			return %monster;
		}
	}
	return null;
}
// Checks if a tile is clear of squad memebers.
function getCharacterOnTile (%xIndex, %yIndex)
{//echo("getCharacterOnTile()");
	for (%i = 0; %i < $maxSquadSize; %i++)
	{
		if (isObject($playerSquad[%i]))
		{
			%character = $playerSquad[%i];
			if (%character.xIndex == %xIndex	&&
				%character.yIndex == %yIndex)
			{
				return %character;
			}
		}
	}
	return null;
}
// Checks if a tile is clear of monsters.
function tileClearOfMonsters (%xIndex, %yIndex)
{//echo("tileClearOfMonsters()");
	for (%i = 0; %i < $monsterList.getCount(); %i++)
	{
		if (($monsterList.getObject(%i)).xIndex == %xIndex	&&
			($monsterList.getObject(%i)).yIndex == %yIndex)
		{
			return false;
		}
	}
	return true;
}
// Checks if a tile is clear of squad memebers.
function tileClearOfSquadMembers (%xIndex, %yIndex)
{//echo("tileClearOfSquadMembers()");
	for (%i = 0; %i < $maxSquadSize; %i++)
	{
		if (isObject($playerSquad[%i])			&&
			$playerSquad[%i].xIndex == %xIndex	&&
			$playerSquad[%i].yIndex == %yIndex)
		{
			return false;
		}
	}
	return true;
}
function isTileBurstGrating (%xIndex, %yIndex)
{//echo("isTileBurstGrating()");
	for (%i = 0; %i < $gratingList.getCount(); %i++)
	{
		%grating = $gratingList.getObject(%i);
		if (%grating.xIndex == %xIndex	&&
			%grating.yIndex == %yIndex)
		{
			if (%grating.frame == 50)
			{
				return true;
			}
		}
	}
	return false;
}