$numGridsPerBlock = 6;
$numBlocksPerRow = 9;
$numLogicalBlocksPerRow = 5;
$numBlocks = 45;

$blockWidth = 128;
$blockHeight = 192;
$roadWidth = 32;
$gridWidth = 64;
$gridHeight = 64;
$numGridsPerBlockRow = 2;
$objectTester = 0;

$playerBlock[0] = 2;
$playerBlock[1] = 1;

//Grids:
//Determin which grid inside a 2x3 Block gets picked first
//Recall there is 6 grids per block
//               ___ ___                 ___ ___	
//              |   |   |               |   |   |
//              | 4 | 5 |               | 0 | 2 |	
//              |___|___|               |___|___|
//      grid    |   |   |       grid    |   |   |	
//      number: | 2 | 3 |       order:  | 1 | 4 |
//              |___|___|               |___|___|
//              |   |   |               |   |   |
//              | 0 | 1 |               | 3 | 5 |
//              |___|___|               |___|___|
//
//Buildings are drawn left to right, top to bottom.
//
$gOrder[0] = 4;
$gOrder[1] = 2;
$gOrder[2] = 5;
$gOrder[3] = 0;
$gOrder[4] = 3;
$gOrder[5] = 1;

$plotFile = "fps/data/interiors/maps/64x64house1.dif";
 
$streetFile = "fps/data/interiors/maps/terrain_4/terrain_4.dif";
$intersectionFile = "fps/data/interiors/maps/terrain_5/terrain_5.dif";

//Create new structure %name @ location %x, %y, %z
function createPlacedInterior(%index, %name, %x, %y, %z, %rotation, %copyArray, %copies)
{
	if($interiorObjects[%index] != NULL)
	{
		error("There is an error in the logic");
		return;
	}
		
	$interiorObjects[%index] = drawInteriorInstance(%name, %x, %y, %z, %rotation, "Structure", %index, %copyArray, %copies);
	return 1;

	//OLD CODE
	//
	//if($interiorObjects[%index] != NULL)
	//	return;
	//%obj = drawInteriorInstance(%name, %x, %y, %z, %rotation);
	//if(%name $= $building2x2Array[$building2x2ArraySize-1])
	//{
	//	echo("DDDDDDDDDDDDDrawing " @ %name @ " twice!!!" ); 
	//	%obj = drawInteriorInstance(%name, %x, %y, %z, %rotation);
	//}
	//$interiorObjects[%index] = %obj;
	//return 1;
}

//UNDOCUMENTED
function clearBlock(%index)
{
	%actualBlock = getRealFromLogicalBlock(%index);
	error("Deleting block");

	for(%i = 0; %i < $numGridsPerBlock; %i++)
	{
		//Actual Block
		%interiorIndex = getInteriorArrayIndex(%actualBlock, %i);
		
		if($interiorObjects[%interiorIndex] != NULL)
		{
			deleteInterior(%interiorIndex);
		}

		//Copied Blocks
		for(%j = 0; %j < 3; %j++)
		{
			%copyBlock = $copyLookUp[%index * 3 + %j];
			if(%copyBlock != -1)
			{
				%interiorIndex = getInteriorArrayIndex(%copyBlock, %i);

				if($interiorObjects[%interiorIndex] != NULL)
					deleteInterior(%interiorIndex);
			}
		}
	}
}

function deleteInterior(%index)
{
	$interiorObjects[%index].delete();
	$interiorObjects[%index] = NULL;
}

function fillBlock(%index)
{
	clearBlock(%index);

	randomSeed(getBlockX($playerBlock[0], %index), getBlockY($playerBlock[1], %index));

	%actualBlock = getRealFromLogicalBlock(%index);
	//echo("Filling Block " @ %actualBlock);

	%x = -720;
	%y = -560;
	
	//%initializes all the arrays of the block
	for(%i = 0; %i < $numGridsPerBlock; %i++)
	{
		%hasBuilding[%i] = 0;		//stores if the grid block contains a building. If it does, it is drawn	into the world
		%reserveGrid[%i] = 0;		//Reserves grid so other buildings cannot take up reserved grid in order to fit in the block
		%indexes[%i] = getInteriorArrayIndex(%actualBlock, %i);		//Stores the interiorIndex for each grid
		%fileNames[%i] = "";		//sets default file name of the building in grid to blank
	}
	
	//Running 2 passes
	for(%j = 0; %j < 2; %j++)
	{
		//Goes through the grid order
		for(%i = 0; %i < $numGridsPerBlock; %i++)
		{
			//error("----Order up: " @ $gOrder[%i]);
			
			//If the grid isn't occupied, checks through the logic to see if a building can be placed
			//  Building is always valid unless it doesn't fit into the grid, in which case will be the flag %validBuilding will be set to 0
			if(%reserveGrid[$gOrder[%i]] == 0)	
			{
				%validBuilding = 1;				
				%k = randomGenerate($buildingArraySize);	//Randomly pick one number in the buildingArray (which contains multiple of building #s inside)
				%buildingNum = $buildingArray[%k];
				
				//If the building pulled down from the buildingArray is terrain (building number = -1, 33% chance)
				if(%buildingNum == -1)
				{
					//echo("  This is a terrain");
					%validBuilding = 0;
				}
				//else, find the width and height of the building
				else
				{
					%bWide = $buildingWide[%buildingNum];		//returns the width of specified building
					%bHigh = $buildingHigh[%buildingNum];		//returns the hight of specified building
				}

				//Goes through each grid case. There are 6 grids per block, so 6 cases
				//
				//Possible buildings for grid 0: 1x1
				if($gOrder[%i] == 0)	
				{
					//Building with height > 1 cannot be put here because it draws from top to bottom
					if(%bHigh > 1)			
						%validBuilding = 0;
					//
					//case of 2x1
					//else if(%bWide == 2)
					//{
					//	if(%reserveGrid[1] == 1)	//2x1 
					//		%validBuilding = 0;
					//}
					//
				}
				//Possible buildings for grid 1: 1x1
				else if($gOrder[%i] == 1)	
				{
					//Any building that isn't 1x1 will not be valid
					if((%bHigh != 1) || (%bWide != 1))
						%validBuilding = 0;
				}
				//Possible buildings for grid 2: 1x1, 1x2, 2x2
				else if($gOrder[%i] == 2)	
				{
					//Buildling with height > 2 cannot be put here
					if(%bHigh > 2)
						%validBuilding = 0;
					else if(%bHigh == 2)
					{
						if(%bWide == 2)			//2x2
						{
							if((%reserveGrid[3] == 1) || (%reserveGrid[1] == 1))
								%validBuilding = 0;
						}					
						if(%reserveGrid[0] == 1)	//2x2 or 1x2
							%validBuliding = 0;
					}
				}
				//Possible buildings for grid 3: 1x1, 1x2
				else if($gOrder[%i] == 3)	
				{
					//Buildings with height = 3 cannot be put here
					if(%bHigh == 3)
						%validBuilding = 0;
					//Only buildings with width 1 can be put here
					else if(%bWide == 2)
						%validBuilding = 0;
					else if((%bHigh == 2) && (%reserveGrid[1] == 1))
						%validBuilding = 0;
				}
				//Possible buildings for grid 4: 1x1, 1x2, 1x3, 2x2, 2x3
				else if($gOrder[%i] == 4)
				{
					if(%bWide == 2)
					{
						if(%reserveSpace[5] == 1)	//have to take spot 5 for all 2 wide struct
							%validBuilding = 0;
						if((%bHigh == 3) && (%reserveGrid[1] == 1))	//2x3s
							%validBuilding = 0;
						if((%bHigh >= 2) && (%reserveGrid[3] == 1))	//2x3s or 2x2s
						{
							%validBuilding = 0;
						}
					}
					if((%bHigh == 3) && (%reserveGrid[0] == 1))
						%validBuilding = 0;
					if((%bHigh >= 2) && (%reserveGrid[2] == 1))
						%validBuilding = 0;
				}
				//Possible buildlings for grid 5: 1x1, 1x2, 1x3
				else if($gOrder[%i] == 5)
				{
					if(%bWide > 1)
						%validBuilding = 0;
					else
					{
						if((%bWide >= 2) && (%reserveGrid[3] == 1)) 	//1x2s or 1x3s
							%validBuilding = 0;
						if((%bHigh == 3) && (%reserveGrid[1] == 1))	//1x3s
							%validBuilding = 0;
					}
				}

				//Places the building if it remains valid after the logic
				if(%validBuilding == 1)
				{
					//sets the hasBuilding flag to 1 so it will draw when it passes this grid
					%hasBuilding[$gOrder[%i]] = 1;
					%fileNames[$gOrder[%i]] = "fps/data/interiors/maps/structure_" @ %buildingNum @ "/structure_" @ %buildingNum @ ".dif";
					//reserve the grid so that no other building can use it
					%reserveGrid[$gOrder[%i]] = 1;
					
					//If the building is more than 1x1, reserve other grids so that other possible buildings can't stack on top
					//check comments under "//Grids:" for more information on which grids to reserve
					//
					//1x2 or 2x2
					if(%bWide == 2)		
						%reserveGrid[$gOrder[%i] + 1] = 1;
					//1x2, 1x3, 2x2 or 2x3	
					if(%bHigh >= 2)
					{
						%reserveGrid[$gOrder[%i] - 2] = 1;
						//2x2 or 2x3
						if(%bWide == 2)	
							%reserveGrid[$gOrder[%i] - 1] = 1;
					}
					//1x3 or 2x3
					if(%bHigh == 3)	
					{
						%reserveGrid[$gOrder[%i] - 4] = 1;
						//2x3
						if(%bWide == 2)
							%reserveGrid[$gOrder[%i] - 3] = 1;
					}
				}
			}
		}
	}
	
	
	for(%i = 0; %i < $numGridsPerBlock; %i++)
	{
		//local variables
		%success = 0;
		%randIncr = 0;

		if(%hasBuilding[%i] == 1)
		{
			%copies = 0;
			
			// All even numbered houses have front doors facing the same street
			if(mod(%i, 2) == 0)
			{
				%rotation = 90;
				%deltaX = 0;
				%deltaY = 64;
			}
			// All odd numbered houses have front doors facing the same street
			else
			{
				%rotation = -90;
				%deltaX = 64;
				%deltaY = 0;
			}
			
			%copyArray = %indexes[%i];
			%copies++;
			for(%j = 0; %j < 3; %j++)
			{
				%copyBlock = $copyLookUp[%index * 3 + %j];
				if(%copyBlock != -1)
				{
					%copyArray = %copyArray @ " " @ getInteriorArrayIndex(%copyBlock, %i);
					%copies++;
				}
			}

			%success = createPlacedInterior(%indexes[%i], %fileNames[%i], %x + getX(%indexes[%i]) + %deltaX, %y + getY(%indexes[%i]) + %deltaY, 100, %rotation, %copyArray, %copies);			
			
			//Copied Blocks
			for(%j = 0; %j < 3; %j++)
			{
				%copyBlock = $copyLookUp[%index * 3 + %j];
				if(%copyBlock != -1)
				{
					%interiorIndex = getInteriorArrayIndex(%copyBlock, %i);
					createPlacedInterior(%interiorIndex, %fileNames[%i], %x + getX(%interiorIndex) + %deltaX, %y + getY(%interiorIndex) + %deltaY, 100, %rotation, %copyArray, %copies);
				}
			}
		}
	}
}

function getInteriorArrayIndex(%blockNumber, %position)
{
	return %blockNumber * 6 + %position;
}

function getRealFromLogicalBlock(%index)
{
	%rowNumberIndex = (integerDivision(%index, $numLogicalBlocksPerRow) + 1) * 9;
	%colPosition = mod(%index, $numLogicalBlocksPerRow) + 2;

	return %rowNumberIndex + %colPosition;
}

function fillWorld()
{
	$Sky.setVisibleDistance(250);
	buildCopyLookUpTable();
	addTriggers();
	drawRoads();
	fillBuildingArray();
	echo("street file = " @ $streetFile);

	randomSeed(0, 0);
	for(%i = 0; %i < 15; %i++)
	{
		fillBlock(%i);
	}
	$isLoaded = 1;
	
	$loading2Done = 1;
}

function updateWorld()
{
	error("Updating World!");
	fillBuildingArray();
}

function drawRoads()
{
	%x = -400;
	%y = -336 + 32;

	//Vertical Roads
	for(%i = -2; %i < 7; %i++)
	{
		for(%j = -1; %j < 4; %j++)
		{
			drawInteriorInstance($intersectionFile, %x + 160*%i, %y - 32 + 224*%j, 100, 0, "Road");
			drawInteriorInstance($streetFile, %x + 160*%i, %y + 224*%j, 100, 0, "Road");
			drawInteriorInstance($streetFile, %x + 160*%i, %y + 224*%j + 64, 100, 0, "Road");
			drawInteriorInstance($streetFile, %x + 160*%i, %y + 224*%j + 128, 100, 0, "Road");

		}
	}

	%x = -400 + 32;
	%y = -336 + 32;

	//Horizontal Roads
	for(%i = -1; %i < 4; %i++)
	{
		for(%j = -2; %j < 7; %j++)
		{
			drawInteriorInstance($streetFile, %x + 160*%j, %y + 224*%i, 100, 90, "Road");
			drawInteriorInstance($streetFile, %x + 160*%j + 64, %y + 224*%i, 100, 90, "Road");
		}
	}
}

function drawInteriorInstance(%fileName, %x, %y, %z, %rotation, %name, %index, %copyArray, %copies)
{
	%obj = new InteriorInstance()
	{
		position = %x@" "@%y@" "@%z;
		rotation = "0 0 1 "@%rotation;
		interiorFile = %fileName;
		name = %name;
		index = %index;
		copyArray = %copyArray;
		copies = %copies;
	};

	return(%obj);
}

function getX(%index)
{
	%div = integerDivision(%index, $numGridsPerBlock);
	%rem = mod(%index, $numGridsPerBlock);

	%gridX = mod(%div, $numBlocksPerRow) * ($blockWidth + $roadWidth) + $roadWidth;

	%interBlockX = mod(%rem, $numGridsPerBlockRow) * $gridWidth;

	return %gridX + %interBlockX;
}

function getY(%index)
{
	%div = integerDivision(%index, $numGridsPerBlock);
	%rem = mod(%index, $numGridsPerBlock);

	%gridY = integerDivision(%div, $numBlocksPerRow) * ($blockHeight + $roadWidth) + $roadWidth;

	%interBlockY = integerDivision(%rem, $numGridsPerBlockRow) * $gridHeight;

	return %gridY + %interBlockY;
}

function getBlockX(%playerX, %blockIndex)
{
	%localX = mod(%playerX, $numLogicalBlocksPerRow);

	%distance = %localX - mod(%blockIndex, $numLogicalBlocksPerRow);

	if(%distance > 2)
		return (5 - %distance) + %playerX;
	else if(%distance < -2)
		return (-5 - %distance) + %playerX;
	else
		return %playerX - %distance;
}

function getBlockY(%playerY, %blockIndex)
{
	%localY = mod(%playerY, 3);

	%distance = %localY - integerDivision(%blockIndex, $numLogicalBlocksPerRow);

	if(%distance == -2)
		return %playerY - 1;
	else if(%distance == 2)
		return %playerY + 1;
	else
		return %playerY - %distance;
}

function mod(%value, %divisor)
{
	%mod = (%value) % (%divisor);
	return %mod;
}

function integerDivision(%value, %divisor)
{
	%mod = mod(%value, %divisor);
	%div = (%value / %divisor) - (%mod / %divisor);
	return %div;
}

//Adds triggers which trigger block redrawing as well as player transporting (for pacman system)
function addTriggers()
{
	%x = -400 + 11;
	%y = -336 + 11;
	//Road triggers to toggle block redraws
	//Vertical
	for(%i = 0; %i < 5; %i++)
	{
		new Trigger() {
			position = (%x + 160*%i)@" 336 100";
			rotation = "1 0 0 0";
			scale = "10 672 20";
			dataBlock = "BlockRedrawTrigger";
			polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
			location = %i;
		};
	}

	%y += 10;
	//Horizontal
	for(%i = 0; %i < 3; %i++)
	{
		new Trigger() {
			position = "-400 "@(%y + 224*%i)@" 100";
			rotation = "1 0 0 0";
			scale = "800 10 20";
			dataBlock = "BlockRedrawTrigger";
			polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
			location = 5 + %i;
		};
	}

	//Edge Triggers to toggle player transport
	//North
	new Trigger() {
		position = "-400 -336 100";
		rotation = "1 0 0 0";
		scale = "800 10 20";
		dataBlock = "EdgeOfWorldTrigger";
		polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
		location = 0;
	};

	//South
	new Trigger() {
		position = "-400 346 100";
		rotation = "1 0 0 0";
		scale = "800 10 20";
		dataBlock = "EdgeOfWorldTrigger";
		polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
		location = 2;
	};

	//East
	new Trigger() {
		position = "400 346 100";
		rotation = "1 0 0 0";
		scale = "10 692 20";
		dataBlock = "EdgeOfWorldTrigger";
		polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
		location = 1;
	};

	//West
	new Trigger() {
		position = "-410 346 100";
		rotation = "1 0 0 0";
		scale = "10 692 20";
		dataBlock = "EdgeOfWorldTrigger";
		polyhedron = "0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000";
		location = 3;
	};
}

//Build Copy Look Up Table
//Each logical block number contains up to 3 physical blocks where it should be drawn
function buildCopyLookUpTable()
{
	//0
	$copyLookUp[0] = 16;
	$copyLookUp[1] = 38;
	$copyLookUp[2] = 43;

	//1
	$copyLookUp[3] = 17;
	$copyLookUp[4] = 39;
	$copyLookUp[5] = 44;

	//2
	$copyLookUp[6] = 40;
	$copyLookUp[7] = -1;
	$copyLookUp[8] = -1;

	//3
	$copyLookUp[9] = 9;
	$copyLookUp[10] = 36;
	$copyLookUp[11] = 41;

	//4
	$copyLookUp[12] = 10;
	$copyLookUp[13] = 37;
	$copyLookUp[14] = 42;

	//5
	$copyLookUp[15] = 25;
	$copyLookUp[16] = -1;
	$copyLookUp[17] = -1;

	//6
	$copyLookUp[18] = 26;
	$copyLookUp[19] = -1;
	$copyLookUp[20] = -1;

	//7
	$copyLookUp[21] = -1;
	$copyLookUp[22] = -1;
	$copyLookUp[23] = -1;

	//8
	$copyLookUp[24] = 18;
	$copyLookUp[25] = -1;
	$copyLookUp[26] = -1;

	//9
	$copyLookUp[27] = 19;
	$copyLookUp[28] = -1;
	$copyLookUp[29] = -1;

	//10
	$copyLookUp[30] = 2;
	$copyLookUp[31] = 7;
	$copyLookUp[32] = 34;

	//11
	$copyLookUp[33] = 3;
	$copyLookUp[34] = 8;
	$copyLookUp[35] = 35;

	//12
	$copyLookUp[36] = 4;
	$copyLookUp[37] = -1;
	$copyLookUp[38] = -1;

	//13
	$copyLookUp[39] = 0;
	$copyLookUp[40] = 5;
	$copyLookUp[41] = 27;

	//14
	$copyLookUp[42] = 1;
	$copyLookUp[43] = 6;
	$copyLookUp[44] = 28;
}

function fillBuildingArray()
{
	%numBuildings = $StructureInfo.count;
	error("Building new Building Array!");
	echo("There are " @ %numBuildings @ " buildings");

	$buildingArraySize = 0;
	
	for(%i = 0; %i < %numBuildings; %i++)
	{
		//error("Likelihood: " @ $StructureInfo.contents[%i, 0]);
		
		//Fill building array with appropriate probabilities
		//A Structure with probability 10 is put in the array 10 times
		
		for(%j = 0; %j < $StructureInfo.contents[%i, 0]; %j++)
		{
			//Filename = "fps/data/interiors/maps/structure_[StructureID]/structure_[StructureID].dif"

			$buildingArray[$buildingArraySize] = $StructureInfo.contents[%i, 1];			
			$buildingArraySize++;
			
			if(0){	//block comment
				if($StructureInfo.contents[%i, 1] == 8)
				{
					$buildingArray[$buildingArraySize] = $StructureInfo.contents[%i, 1];			
					$buildingArraySize++;
				}
				if($StructureInfo.contents[%i, 1] == 24)
				{
					$buildingArray[$buildingArraySize] = $StructureInfo.contents[%i, 1];			
					$buildingArraySize++;

				}
			}
		}
		
		$buildingName[$StructureInfo.contents[%i, 1]] = "fps/data/interiors/maps/structure_" @ $StructureInfo.contents[%i, 1] @ "/structure_" @ $StructureInfo.contents[%i, 1] @ ".dif";
				
		//Getting Dimension of the building
		%testObj = new InteriorInstance() {interiorFile = "fps/data/interiors/maps/structure_" @ $StructureInfo.contents[%i, 1] @ "/structure_" @ $StructureInfo.contents[%i, 1] @ ".dif"; };
		%testbox = %testObj.getObjectBox();	
		%width = getWord(%testbox, 3) - getWord(%testbox, 0);
		%height = getWord(%testbox, 4) - getWord(%testbox, 1);	
		%numBlocksWide = integerDivision(%width, $gridWidth);
		%numBlocksHigh = mceil(integerDivision(%height, $gridHeight));
		
		$buildingWide[$StructureInfo.contents[%i, 1]] = %numBlocksWide;
		$buildingHigh[$StructureInfo.contents[%i, 1]] = %numBlocksHigh;
		%testObj.delete();
		
		if(%numBlocksWide > 2)
			error("-----------------Structures can only be 2 Wide. This is " @ %numBlocksWide @ " wide. NOT ALLOWED.");
		if(%numBlocksHigh > 3)
			error("-----------------Structures can only be 3 High. This is " @ %numBlocksHigh @ " high. NOT ALLOWED.");

		//error("Building #" @ $StructureInfo.contents[%i, 1]);
		//error("  fps/data/interiors/maps/structure_" @ $StructureInfo.contents[%i, 1] @ "/structure_" @ $StructureInfo.contents[%i, 1] @ ".dif");
		//error("    Width X Height: " @ %numBlocksWide @ " x " @ %numBlocksHigh);
	}
	
	//Adds one third chance of the building being just terrain (will return "-1"..which cannot be a valid structure #)
	%oneThird = mCeil(integerDivision($buildingArraySize, 3));
	for(%i = 0; %i < %oneThird; %i++)
	{
		$buildingArray[$buildingArraySize] = -1;
		$buildingArraySize++;
	}
	
}

function setLocalRegionList(%regionList)  //%regionList is a ScriptObject (Array)
{
	$localRegionList = %regionList;
}

function setCurrentRegion(%RegionInfo, %TerrainInfo, %StructureInfo)
{
	//One Dimensional Array with elements in the following order (index starting at 0, increasing from left to right)
	//[ID][Name][is Meta-Region][Latitude][Longitude][Radius][Color R][Color G][Color B]
	$RegionInfo = %RegionInfo;
	
	//Two dimensional array.  Index[%i, %j] where %i is the structure entry and %j is the parameter of the structure
	//For the parameter at %j = 5, there is a third dimention, [%i, 5, %k], which contains the Char ID / Likelihood
	//ie - $TerrainInfo[0, 5, 0] is the first character id for the first structure, [0, 5, 1] is the Likelihood
	//[Probability for Terrain][Terrain ID][Type][Maximum Character Count][Character List Size]
	//[Character ID][Likelihood]
	$TerrainInfo = %TerrainInfo;
	
	//Two dimenaional array as above
	//Parameters 5 and 6 both have a 3rd dimension - 5 is for characters and 6 is for inventory
	//[Probability for Structure][Structure ID][Max Character Count][Max Inventory Count][Char. List Size][Inv. List Size]
	//[Char. ID][Likelihood]
	//[Inv. ID][Likelihood]	
	$StructureInfo = %StructureInfo;
	
	if($isLoaded)
	{
		error("----------------Updating World----------------");
		updateWorld();
	}
	else
		fillWorld();
}

//*********************//
//                     //
//MATH HELPER FUNCTIONS//
//                     //
//*********************//

// seeds the random number generator
function randomSeed(%x, %y)
{
	$randx = %x * 798 + 631;
	$randy = %y * 478 + 325;
}

// generates random number
function randomGenerate(%limit)
{
	if(%limit <= 0)
		return 0;

	$randx = $randx * 521 - (integerDivision($randx, 458) * 965);
	while($randx < 0) $randx += 254;
	while($randx > 60000) $randx = integerDivision($randx, 847);

	$randy = $randy * 852 - (integerDivision($randy, 547) * 123);
	while($randy < 0) $randy += 325;
	while($randy > 60000) $randy = integerDivision($randy, 852);

	%num = ($randy - $randx) ;
	while(%num < 0) %num += 302;

	//echo($randx @" " @ $randy @ " " @ mod(%num, %limit));

	return absoluteValue(mod(%num, %limit));
}

function absoluteValue(%value)
{
	if(%value < 0)
		return %value * -1;
	else
		return %value;
}
