/************************************************
 ******        LV Objects (Default)        ******
 ******           Version 1.0.1            ******
 ******           July 09, 2007            ******
 ************************************************/

function ninja() {

	ninja.prototype.Create = Create;	// Prototyping allows you to call the ninja's Create() function
	ninja.prototype.Output = Output;	// (and other functions) outside of the function itself.
	ninja.prototype.Prob = Prob;

	var x;
	var y;
	var probability = 0;			// Probability of 0 means this will never be called at random.
	var attempts = 200;			// This is how many random coordinates to try before giving up.
						// An object won't be placed under a solid tile. ninja and exit have
						// very high attempt counts so they're not likely to be skipped.

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);	// Define an x and y position to try.
			this.y = Math.ceil(Math.random()*19);

			for (;this.y<20;this.y++) {		// If the first x,y pos doesn't fit, the ninja will
								// move downward and keep checking for a usable spot.

				if (arrayTiles[this.x][this.y+3]==1 && arrayTiles[this.x][this.y+2]==0 &&
				arrayTiles[this.x][this.y+1]==0 && arrayTiles[this.x][this.y]==0) {
						// If (x,y) is 0, (x,y+1) is 0, (x,y+2) is 0, and (x,y+3) is 1, 
						// the ninja will be placed. (Remember that the N grid starts at the
						// top-left, so the y+1's are looking downward.) With this, the ninja
						// starts two tiles above the ground.

					this.Output();
					return;
				}

			}

		}
                if(arrayTileTypes.length > 0) {
  		  alert("Could not generate ninja. Please try again.");
                }
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,2);		// Quarter-snap of 2 is common. It just
		objPlaceY = tileToObjXY(this.y,2);		// puts it in the center of the tile.
		arrayObjects.push("5^"+objPlaceX+","+objPlaceY);	// This puts a ninja in the object array. :D
	}

}


function exit() {

	exit.prototype.Create = Create;
	exit.prototype.Output = Output;
	exit.prototype.Prob = Prob;

	var x;
	var y;
	var probability = 0;
	var attempts = 200;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {					// the switch

			this.x = Math.floor(Math.random()*29);
			this.y = Math.floor(Math.random()*21);

			if (arrayTiles[this.x][this.y]==0) {
					
				this.switchx = this.x;
				this.switchy = this.y;
				break;

			}
		}

		for (;attempts>0;attempts--) {					// the door

			this.x = Math.floor(Math.random()*30);
			this.y = Math.floor(Math.random()*22);

			for (;this.y<=22;this.y++) {

				if (this.y==22 && arrayTiles[this.x][this.y]==0) {
						// This checks if the exit is testing at the border of the map.
						// If you try to test a value beyond the border, the current
						// map will error out and stop processing.

					this.Output();
					return;

				} else if (arrayTiles[this.x][this.y+1]==1 && arrayTiles[this.x][this.y]==0) {

					this.Output();
					return;

				}
			}
		}

		alert("Could not generate exit door. Please try again.");
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,2);
		objPlaceY = tileToObjXY(this.y,2);
		objSwitchX = tileToObjXY(this.switchx,2);
		objSwitchY = tileToObjXY(this.switchy,2);
		arrayObjects.push("11^"+objPlaceX+","+objPlaceY+","+objSwitchX+","+objSwitchY);
	}

}


function gauss() {

	gauss.prototype.Create = Create;
	gauss.prototype.Output = Output;
	gauss.prototype.Prob = Prob;

	var x;
	var y;
	var probability = 8;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*30);
			this.y = Math.floor(Math.random()*22);

			if (arrayTiles[this.x][this.y]==0 && arrayTiles[this.x+1][this.y]==0 &&
			arrayTiles[this.x][this.y+1]==0 && arrayTiles[this.x+1][this.y+1]==0) {
					// Checks a square of four tiles, two-by-two
				this.x++;
				this.y++;
				this.Output();
				return;
			}
		}
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,Math.floor(Math.random()*4));
		objPlaceY = tileToObjXY(this.y,Math.floor(Math.random()*4));
		arrayObjects.push("3^"+objPlaceX+","+objPlaceY);
	}

}


function rocket() {

	rocket.prototype.Create = Create;
	rocket.prototype.Output = Output;
	rocket.prototype.Prob = Prob;

	var x;
	var y;
	var probability = 8;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*30);
			this.y = Math.floor(Math.random()*22);

			if (arrayTiles[this.x][this.y]==0 && arrayTiles[this.x+1][this.y]==0 &&
			arrayTiles[this.x][this.y+1]==0 && arrayTiles[this.x+1][this.y+1]==0) {

				this.x++;
				this.y++;
				this.Output();
				return;
			}
		}
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,Math.floor(Math.random()*4));
		objPlaceY = tileToObjXY(this.y,Math.floor(Math.random()*4));
		arrayObjects.push("10^"+objPlaceX+","+objPlaceY);
	}

}


function floorguard() {

	floorguard.prototype.Create = Create;
	floorguard.prototype.Output = Output;
	floorguard.prototype.Prob = Prob;

	var x;
	var y;
	var draw = 1;
	var probability = 6;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*30);
			this.y = Math.floor(Math.random()*22);

			for (;this.y<=22;this.y++) {

				if (this.y==22 && arrayTiles[this.x][this.y]==0) {
						// Moves downward like the ninja. Floor guards, of course,
						// can only be placed directly on the ground.

					this.Output();
					return;

				} else if (arrayTiles[this.x][this.y+1]==1 && arrayTiles[this.x][this.y]==0) {

					this.Output();
					return;

				}
			}
		}
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,2);
		objPlaceY = tileToObjXY(this.y,0);
		arrayObjects.push("4^"+objPlaceX+","+objPlaceY+",1");
	}

}


function laser() {

	laser.prototype.Create = Create;
	laser.prototype.Output = Output;
	laser.prototype.Prob = Prob;

	var x;
	var y;
	var algo;
	var direction;
	var probability = 3;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);	// The drones check a 3x3 area around them,
			this.y = Math.ceil(Math.random()*21);	// so the random positions are 1 short, to
								// keep them from testing outside the border.

			this.direction = Math.floor(Math.random()*4);
			this.algo = Math.floor(Math.random()*1) + 2;

				// The following adds up the values of a three-by-three square, and then
				// then checks if the total is 0. If all the squares are empty, it will be.

			var objTotal = 0;

			for (var j=1;j>=-1;j--) {
				for (var k=1;k>=-1;k--) {
					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output()
				return;
			}
		}
	}

	function Output() {

			objPlaceX = tileToObjXY(this.x,2);
			objPlaceY = tileToObjXY(this.y,2);
			arrayObjects.push("6^"+objPlaceX+","+objPlaceY+","+this.algo+",0,1,"+this.direction);
	}

}


function chaingun() {

	chaingun.prototype.Create = Create;
	chaingun.prototype.Output = Output;
	chaingun.prototype.Prob = Prob;

	var x;
	var y;
	var algo;
	var direction;
	var probability = 3;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);
			this.direction = Math.floor(Math.random()*4);
			this.algo = Math.floor(Math.random()*1) + 2;

			var objTotal = 0;

			for (var j=1;j>=-1;j--) {
				for (var k=1;k>=-1;k--) {
					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output();
				return;
			}
		}
	}

	function Output() {

			objPlaceX = tileToObjXY(this.x,2);
			objPlaceY = tileToObjXY(this.y,2);
			arrayObjects.push("6^"+objPlaceX+","+objPlaceY+","+this.algo+",0,2,"+this.direction);
	}

}


function zap() {

	zap.prototype.Create = Create;
	zap.prototype.Output = Output;
	zap.prototype.Prob = Prob;

	var x;
	var y;
	var algo;
	var seeker;
	var direction;
	var probability = 10;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);
			this.direction = Math.floor(Math.random()*4);
			this.seeker = Math.round(Math.random());
			this.algo = Math.floor(Math.random()*1) + 2;

			var objTotal = 0;

			for (var j=1;j>=-1;j--) {
				for (var k=1;k>=-1;k--) {
					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output()
				return;
			}
		}
	}

	function Output() {

			objPlaceX = tileToObjXY(this.x,2);
			objPlaceY = tileToObjXY(this.y,2);
			arrayObjects.push("6^"+objPlaceX+","+objPlaceY+","+this.algo+","+this.seeker+",0,"+this.direction);
	}

}


function thwump() {

	thwump.prototype.Create = Create;
	thwump.prototype.Output = Output;
	thwump.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 4;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*25) + 3;
			this.y = Math.floor(Math.random()*17) + 3;
			this.direction = Math.floor(Math.random()*4);

			switch (this.direction) {	// These are multipliers for the if statement below
				case 0:
					var x = 1;
					var y = 0;
				break;
				case 1:
					var x = 0;
					var y = 1;
				break;
				case 2:
					var x = -1;
					var y = 0;
				break;
				case 3:
					var x = 0;
					var y = -1;
				break;
			}

			if (arrayTiles[this.x][this.y]==0 && arrayTiles[this.x+(1*x)][this.y+(1*y)]==0 &&
			arrayTiles[this.x+(2*x)][this.y+(2*y)]==0 && arrayTiles[this.x+(3*x)][this.y+(3*y)]==0) {
					// Test three squares in the direction the thwump is facing.
					// After all, what good is a thwump that's facing a wall?

				this.Output();
				return;
			}
		}
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,2);
		objPlaceY = tileToObjXY(this.y,2);
		arrayObjects.push("8^"+objPlaceX+","+objPlaceY+","+this.direction);
	}

}


function thwumpGroup() {

	thwumpGroup.prototype.Create = Create;
	thwumpGroup.prototype.Output = Output;
	thwumpGroup.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 3;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {

		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*27) + 2;
			this.y = Math.floor(Math.random()*19) + 2;
			this.direction = Math.floor(Math.random()*4);

			var objTotal = 0;

			for (var j=2;j>=-2;j--) {		// Check a 5x5 square
				for (var k=2;k>=-2;k--) {

					objTotal += arrayTiles[this.x+j][this.y+k];

				}
			}

			if (objTotal==0) {

				this.Output();
				return;
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*4) + 1;
		var objVaryXY = Math.floor(Math.random()*4)/2;
		var objSpread = 5/objCount;

		switch (this.direction) {
			case 0:		// facing up

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {		// This is what creates the staggered positioning
						objPlaceX = tileToObjXY(this.x-1,2);
					} else {
						objPlaceX = tileToObjXY( this.x-objVaryXY ,2);
					}

						// Shifts the thwumps back from the center of the 5x5 square
					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("8^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;		
			case 1:		// facing right

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y-1,2);
					} else {
						objPlaceY = tileToObjXY( this.y-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("8^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
			case 2:		// facing left

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x+1,2);
					} else {
						objPlaceX = tileToObjXY( this.x+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("8^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

				// +x =y
			break;
			case 3:		// facing down

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y+1,2);
					} else {
						objPlaceY = tileToObjXY( this.y+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("8^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
		}
	}

}


function bounceGroup() {
		// All of these Group fuctions are the same. The program could probably be cleaned up slightly by
		// creating a single "Group" function and calling it for each of these cases.

	bounceGroup.prototype.Create = Create;
	bounceGroup.prototype.Output = Output;
	bounceGroup.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 4;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*27) + 2;
			this.y = Math.floor(Math.random()*19) + 2;
			this.direction = Math.floor(Math.random()*4);

			var objTotal = 0;

			for (var j=2;j>=-2;j--) {
				for (var k=2;k>=-2;k--) {

					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output();
				return;
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*4) + 1;
		var objVaryXY = Math.floor(Math.random()*4)/2;
		var objSpread = 5/objCount;

		switch (this.direction) {	// bounce blocks don't have direction, but the groups 
			case 0:			// are still offset from center

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x-1,2);
					} else {
						objPlaceX = tileToObjXY( this.x-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("1^"+objPlaceX+","+objPlaceY);
				}
			break;
			case 1:

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y-1,2);
					} else {
						objPlaceY = tileToObjXY( this.y-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("1^"+objPlaceX+","+objPlaceY);
				}
			break;
			case 2:

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x+1,2);
					} else {
						objPlaceX = tileToObjXY( this.x+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("1^"+objPlaceX+","+objPlaceY);
				}
			break;
			case 3:

				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y+1,2);
					} else {
						objPlaceY = tileToObjXY( this.y+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("1^"+objPlaceX+","+objPlaceY);
				}
			break;
		}
	}

}


function goldGroup() {

	goldGroup.prototype.Create = Create;
	goldGroup.prototype.Output = Output;
	goldGroup.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 4;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*28) + 1;
			this.y = Math.floor(Math.random()*20) + 1;
			this.direction = Math.floor(Math.random()*4);

			var objTotal = 0;

			for (var j=1;j>=-1;j--) {
				for (var k=1;k>=-1;k--) {

					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output();
				return;
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*3) + 2;
		var objVaryXY = Math.floor(Math.random()*2)/2;
		var objSpread = 5/objCount;

		switch (this.direction) {
			case 0:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x-1,2);
					} else {
						objPlaceX = tileToObjXY( this.x-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-1.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

			break;
			case 1:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y-1,2);
					} else {
						objPlaceY = tileToObjXY( this.y-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-1.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

			break;
			case 2:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x+1,2);
					} else {
						objPlaceX = tileToObjXY( this.x+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-1.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

			break;
			case 3:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y+1,2);
					} else {
						objPlaceY = tileToObjXY( this.y+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-1.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

			break;
		}
	}

}


function onewayGroup() {

	onewayGroup.prototype.Create = Create;
	onewayGroup.prototype.Output = Output;
	onewayGroup.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 4;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*27) + 2;
			this.y = Math.floor(Math.random()*19) + 2;
			this.direction = Math.floor(Math.random()*4);

			var objTotal = 0;

			for (var j=2;j>=-2;j--) {
				for (var k=2;k>=-2;k--) {

					objTotal += arrayTiles[this.x+j][this.y+k];
				}
			}

			if (objTotal==0) {

				this.Output();
				return;
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*4) + 1;
		var objVaryXY = Math.floor(Math.random()*4)/2;
		var objSpread = 5/objCount;

		switch (this.direction) {
			case 0:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x-1,2);
					} else {
						objPlaceX = tileToObjXY( this.x-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("7^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
			case 1:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y-1,2);
					} else {
						objPlaceY = tileToObjXY( this.y-objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("7^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
			case 2:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceX = tileToObjXY(this.x+1,2);
					} else {
						objPlaceX = tileToObjXY( this.x+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("7^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
			case 3:
				for (var i=objCount;i>0;i--) {

					if (i%2 == 0) {
						objPlaceY = tileToObjXY(this.y+1,2);
					} else {
						objPlaceY = tileToObjXY( this.y+objVaryXY ,2);
					}

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("7^"+objPlaceX+","+objPlaceY+","+this.direction);
				}

			break;
		}
	}

}


function mineField() {
		// Note to modders: The mines tend to clump together. If anyone wants to force them to
		// spread out evenly, it would make for a way better minefield. I'm thinking, divide
		// the output area evenly into sections and put one mine in each section.

	mineField.prototype.Create = Create;
	mineField.prototype.Output = Output;
	mineField.prototype.Prob = Prob;

	var x;
	var y;
	var probability = 10;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*25) + 3;
			this.y = Math.floor(Math.random()*17) + 3;

			var objTotal = 0;

			for (var j=3;j>=-3;j--) {	// 7x7. This requires a lot of space, for whatever reason
				for (var k=3;k>=-3;k--) {

					objTotal += arrayTiles[this.x+j][this.y+k];

				}

				if (objTotal==0) {

					this.Output();
					return;
				}
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*6) + 1;

		for (var i=objCount;i>0;i--) {
				// Just pure random

			var quarterX = Math.floor(Math.random()*4);
			var quarterY = Math.floor(Math.random()*4);
			var objX = this.x - 3 + Math.floor(Math.random()*6);
			var objY = this.y - 3 + Math.floor(Math.random()*6);

			objPlaceX = tileToObjXY(objX,quarterX);
			objPlaceY = tileToObjXY(objY,quarterY);

			arrayObjects.push("12^"+objPlaceX+","+objPlaceY);
		}
	}
}


function launchpad() {
		// Launch pads always spawn against a wall or the ground. I didn't think a
		// down-facing (roof-mounted) one was necessary, so I left it out.

	launchpad.prototype.Create = Create;
	launchpad.prototype.Output = Output;
	launchpad.prototype.Prob = Prob;

	var x;
	var y;
	var x2;
	var y2;
	var probability = 5;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.floor(Math.random()*30);
			this.y = Math.floor(Math.random()*22);
			this.direction = Math.ceil(Math.random()*3);

			switch (this.direction) {
				case 1:		// facing up

					for (var i=10;i>0;i--) {
						for (;this.y<=22;this.y++) {

							this.x2 = 0;
							this.y2 = -1;

							if (this.y==22) {

								if (arrayTiles[this.x][this.y]==0) {
									this.y++;
									this.Output();
									return;
								}

							} else if (arrayTiles[this.x][this.y+1]==1 && arrayTiles[this.x][this.y]==0) {

								this.y++;
								this.Output();
								return;
							}
						}
					}

				break;
				case 2:		// facing left

					for (var i=10;i>0;i--) {
						for (;this.x<=30;this.x++) {

							this.x2 = -1;
							this.y2 = 0;

							if (this.x==30) {

								if (arrayTiles[this.x][this.y]==0) {
									this.x++;
									this.Output();
									return;
								}

							} else if (arrayTiles[this.x+1][this.y]==1 && arrayTiles[this.x][this.y]==0) {

								this.x++;
								this.Output();
								return;
							}
						}
					}

				break;
				case 3:		// facing right

					for (var i=10;i>0;i--) {
						for(;this.x>=0;this.x--) {

							this.x2= 1;
							this.y2 = 0;

							if (this.x==0) {

								if (arrayTiles[this.x][this.y]==0) {
									this.Output();
									return;
								}

							} else if (arrayTiles[this.x-1][this.y]==1 && arrayTiles[this.x][this.y]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
			}
		}
	}

	function Output() {

		if (this.y2==-1) {	// Quarter-snap settings for the ground-mounted one
			var quarterY = 0;
			var quarterX = 2;
		} else {		// Wall-mounted
			var quarterY = 2;
			var quarterX = 0;
		}

		objPlaceX = tileToObjXY(this.x,quarterX);
		objPlaceY = tileToObjXY(this.y,quarterY);
		arrayObjects.push("2^"+objPlaceX+","+objPlaceY+","+this.x2+","+this.y2);
	}

}


function goldWall() {
		// Wall- / roof-mounted row of gold. This function is a Frankenstein mix of the Group and
		// launchpad ones. (Create() from launchpad, Output() from Group, plus some modifications)

	goldWall.prototype.Create = Create;
	goldWall.prototype.Output = Output;
	goldWall.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 12;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);
			this.direction = Math.ceil(Math.random()*3);

			switch (this.direction) {
				case 1:

					for (var i=10;i>0;i--) {
						for (;this.y<=22;this.y++) {

							if (this.y==22) {

								if (arrayTiles[this.x-1][this.y]==0 && arrayTiles[this.x][this.y]==0 &&
								arrayTiles[this.x+1][this.y]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x][this.y+1]==1 && arrayTiles[this.x-1][this.y]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x+1][this.y]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
				case 2:

					for (var i=10;i>0;i--) {
						for (;this.x<=30;this.x++) {

							if (this.x==30) {

								if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==0
								 && arrayTiles[this.x][this.y+1]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x+1][this.y]==1 && arrayTiles[this.x][this.y-1]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x][this.y+1]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
				case 3:

					for (var i=10;i>0;i--) {
						for(;this.x>=0;this.x--) {

							if (this.x==0) {

								if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==0
								&& arrayTiles[this.x][this.y+1]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x-1][this.y]==1 && arrayTiles[this.x][this.y-1]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x][this.y+1]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
			}
		}
	}

	function Output() {

		objPlaceX = tileToObjXY(this.x,2);
		objPlaceY = tileToObjXY(this.y,2);
		var objCount = Math.ceil(Math.random()*3) + 2;
		var objSpread = 5/objCount;
		if (this.direction==3) {this.direction = 2};

		switch (this.direction) {
			case 1:
				for (var i=objCount;i>0;i--) {

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

				// -x =y
			break;
			case 2:
				for (var i=objCount;i>0;i--) {

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("0^"+objPlaceX+","+objPlaceY);
				}

				// =x -y
			break;
		}
	}
}


function mineWall() {
		// Same as goldWall, but with the quarter snaps modified.
		// mineWalls spawn halfway into a tile, goldWalls spawn above it.

	mineWall.prototype.Create = Create;
	mineWall.prototype.Output = Output;
	mineWall.prototype.Prob = Prob;

	var x;
	var y;
	var direction;
	var probability = 16;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);
			this.direction = Math.ceil(Math.random()*3);

			switch (this.direction) {
				case 1:

					for (var i=10;i>0;i--) {
						for (;this.y<=22;this.y++) {

							if (this.y==22) {

								if (arrayTiles[this.x-1][this.y]==0 && arrayTiles[this.x][this.y]==0 &&
								arrayTiles[this.x+1][this.y]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x][this.y+1]==1 && arrayTiles[this.x-1][this.y]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x+1][this.y]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
				case 2:

					for (var i=10;i>0;i--) {
						for (;this.x<=30;this.x++) {

							if (this.x==30) {

								if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==0
								 && arrayTiles[this.x][this.y+1]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x+1][this.y]==1 && arrayTiles[this.x][this.y-1]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x][this.y+1]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
				case 3:

					for (var i=10;i>0;i--) {
						for(;this.x>=0;this.x--) {

							if (this.x==0) {

								if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==0
								&& arrayTiles[this.x][this.y+1]==0) {

									this.Output();
									return;
								}

							} else if (arrayTiles[this.x-1][this.y]==1 && arrayTiles[this.x][this.y-1]==0 &&
							arrayTiles[this.x][this.y]==0 && arrayTiles[this.x][this.y+1]==0) {

								this.Output();
								return;
							}
						}
					}

				break;
			}
		}
	}

	function Output() {

		var objCount = Math.ceil(Math.random()*3) + 2;
		var objSpread = 5/objCount;

		switch (this.direction) {
			case 1:
				for (var i=objCount;i>0;i--) {

					objPlaceY = tileToObjXY(this.y+1,0);

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceX = tileToObjXY( this.x+objParShift ,2);
					arrayObjects.push("12^"+objPlaceX+","+objPlaceY);
				}

				// -x =y
			break;
			case 2:
				for (var i=objCount;i>0;i--) {

					objPlaceX = tileToObjXY(this.x+1,0);

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("12^"+objPlaceX+","+objPlaceY);
				}

				// =x -y
			break;
			case 3:
				for (var i=objCount;i>0;i--) {

					objPlaceX = tileToObjXY(this.x,0);

					var objParShift = (i*objSpread)-(objSpread/2)-2.5;
					objPlaceY = tileToObjXY( this.y+objParShift ,2);
					arrayObjects.push("12^"+objPlaceX+","+objPlaceY);
				}

				// =x -y
			break;
		}
	}
}


function doorNormal() {
		// The door functions look for stretches of solid tile, store and entry point and exit point,
		// and then cut out a tunnel through the tile. It very rarely ends up functioning in the map,
		// but it still maps a nice style modification.

	doorNormal.prototype.Create = Create;
	doorNormal.prototype.Output = Output;
	doorNormal.prototype.Prob = Prob;

	var x;
	var y;
	var x2;
	var y2;
	var direction = 1;
	var probability = 3;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);

			if (Math.random()>0.5) {

				this.direction = 1;

				for (;this.y<21;this.y++) {

					if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==1 &&
					arrayTiles[this.x-1][this.y]==1 && arrayTiles[this.x+1][this.y]==1) {

						this.x2 = this.x;
						this.y2 = this.y;

						for (;this.y2<21;this.y2++) {

							if (arrayTiles[this.x2][this.y2]==1 && arrayTiles[this.x2][this.y2+1]==0 &&
							arrayTiles[this.x2-1][this.y2]==1 && arrayTiles[this.x2+1][this.y2]==1) {

								this.x++;
								this.y++;
								this.x2++;
								this.y2++;

								this.Output();
								return;
							}
						}
					}
				}

			} else {

				this.direction = 2;

				for (;this.x<29;this.x++) {

					if (arrayTiles[this.x-1][this.y]==0 && arrayTiles[this.x][this.y]==1 &&
					arrayTiles[this.x][this.y-1]==1 && arrayTiles[this.x+1][this.y+1]==1) {

						this.x2 = this.x;
						this.y2 = this.y;

						for (;this.x2<29;this.x2++) {
							if (arrayTiles[this.x2][this.y2]==1 && arrayTiles[this.x2+1][this.y2]==0 &&
							arrayTiles[this.x2][this.y2-1]==1 && arrayTiles[this.x2][this.y2+1]==1) {

								this.x++;
								this.y++;
								this.x2++;
								this.y2++;

								this.Output();
								return;
							}
						}
					}
				}
			}
		}
	}

	function Output() {

		if (this.direction==1) {

			arrayObjects.push("9^"+this.x+","+this.y+",1,0,"+this.x+","+this.y+",0,0,-1");
			arrayObjects.push("9^"+this.x+","+this.y+",1,0,"+this.x2+","+this.y2+",0,0,0");

			for (var i=this.y2-this.y;i>=0;i--) {

				arrayTiles[this.x-1][this.y-1+i] = 0;
			}

		} else if (this.direction==2) {

			arrayObjects.push("9^"+this.x+","+this.y+",0,0,"+this.x+","+this.y+",0,-1,0");
			arrayObjects.push("9^"+this.x+","+this.y+",0,0,"+this.x2+","+this.y2+",0,0,0");

			for (var i=this.x2-this.x;i>=0;i--) {

				arrayTiles[this.x-1+i][this.y-1] = 0;
			}
		}
	}

}


function doorLocked() {

	doorLocked.prototype.Create = Create;
	doorLocked.prototype.Output = Output;
	doorLocked.prototype.Prob = Prob;

	var x;
	var y;
	var x2;
	var y2;
	var switchx;
	var switchy;
	var direction = 1;
	var probability = 3;
	var attempts = 10;

	function Prob() {
		return probability;
	}

	function Create() {
		for (;attempts>0;attempts--) {

			this.x = Math.ceil(Math.random()*29);
			this.y = Math.ceil(Math.random()*21);

			if (Math.random()>0.5) {

				this.direction = 1;

				for (;this.y<21;this.y++) {

					if (arrayTiles[this.x][this.y-1]==0 && arrayTiles[this.x][this.y]==1 &&
					arrayTiles[this.x-1][this.y]==1 && arrayTiles[this.x+1][this.y]==1) {

						this.x2 = this.x;
						this.y2 = this.y;

						for (;this.y2<21;this.y2++) {

							if (arrayTiles[this.x2][this.y2]==1 && arrayTiles[this.x2][this.y2+1]==0 &&
							arrayTiles[this.x2-1][this.y2]==1 && arrayTiles[this.x2+1][this.y2]==1) {

								this.x++;
								this.y++;
								this.x2++;
								this.y2++;

								for (var i=10;i>0;i--) {

									this.switchx = Math.floor(Math.random()*29);
									this.switchy = Math.floor(Math.random()*21);

									if (arrayTiles[this.switchx][this.switchy]==0) {

										this.Output();
										return;
									}
								}
							}
						}
					}
				}

			} else {

				this.direction = 2;

				for (;this.x<29;this.x++) {

					if (arrayTiles[this.x-1][this.y]==0 && arrayTiles[this.x][this.y]==1 &&
					arrayTiles[this.x][this.y-1]==1 && arrayTiles[this.x+1][this.y+1]==1) {

						this.x2 = this.x;
						this.y2 = this.y;

						for (;this.x2<29;this.x2++) {
							if (arrayTiles[this.x2][this.y2]==1 && arrayTiles[this.x2+1][this.y2]==0 &&
							arrayTiles[this.x2][this.y2-1]==1 && arrayTiles[this.x2][this.y2+1]==1) {

								this.x++;
								this.y++;
								this.x2++;
								this.y2++;

								for (var i=10;i>0;i--) {

									this.switchx = Math.floor(Math.random()*29);
									this.switchy = Math.floor(Math.random()*21);

									if (arrayTiles[this.switchx][this.switchy]==0) {

										this.Output();
										return;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	function Output() {

		if (this.direction==1) {

			objSwitchX = tileToObjXY(this.switchx,2);
			objSwitchY = tileToObjXY(this.switchy,2);

			arrayObjects.push("9^"+objSwitchX+","+objSwitchY+",1,0,"+this.x+","+this.y+",1,0,-1");
			arrayObjects.push("9^"+objSwitchX+","+objSwitchY+",1,0,"+this.x2+","+this.y2+",1,0,0");

			for (var i=this.y2-this.y;i>=0;i--) {

				arrayTiles[this.x-1][this.y-1+i] = 0;
			}

		} else if (this.direction==2) {

			objSwitchX = tileToObjXY(this.switchx,2);
			objSwitchY = tileToObjXY(this.switchy,2);

			arrayObjects.push("9^"+objSwitchX+","+objSwitchY+",0,0,"+this.x+","+this.y+",1,-1,0");
			arrayObjects.push("9^"+objSwitchX+","+objSwitchY+",0,0,"+this.x2+","+this.y2+",1,0,0");

			for (var i=this.x2-this.x;i>=0;i--) {

				arrayTiles[this.x-1+i][this.y-1] = 0;
			}
		}
	}
}
