/*-- 
	ForgottenHeights
	Author: Mimmo_O
	
	Last man Standing on sky islands for up to 12 players.
--*/



protected func Initialize()
{
	// Goal.
	CreateObject(Goal_LastManStanding);
	CreateObject(Rule_KillLogs);
	CreateObject(Rule_Gravestones);
	
	//Enviroment.
	Cloud->Place(25);
	SetSkyAdjust(RGBa(250,250,255,128),RGB(200,200,220));
	Sound("BirdsLoop", true, 100, nil, 1);
	
	// Brick edges at horizontal moving bricks.
	var x=[525, 436, 436, 525, 812, 812, 716, 716, 573, 573, 213, 213];
	var y=[692, 677, 692, 677, 653, 668, 500, 485, 500, 485, 677, 692];
	var d=[2, 1, 3, 0, 1, 3, 3, 1, 2, 0, 0, 2];
	for (var i = 0; i < GetLength(x); i++)
	{
		var edge=CreateObject(BrickEdge, x[i], y[i], NO_OWNER);
		edge->Initialize();
		edge->SetP(d[i]);
		edge->SetPosition(x[i],y[i]);
		edge->PermaEdge();
	}
	
	// Vertically moving bricks
	var brick = CreateObject(MovingBrick, 660, 90);
	brick->SetSize(3);
	brick->MoveVertical(80, 144);
	
	var brick = CreateObject(MovingBrick, 592, 270);
	brick->SetSize(2);
	brick->MoveVertical(264, 344);
	var brick = CreateObject(MovingBrick, 632, 285);
	brick->SetSize(2);
	brick->MoveVertical(272, 352);
	var brick = CreateObject(MovingBrick, 672, 300);
	brick->SetSize(2);
	brick->MoveVertical(280, 360);
	
	var brick = CreateObject(MovingBrick, 270, 430);
	brick->SetSize(2);
	brick->MoveVertical(416, 488);
	var brick = CreateObject(MovingBrick, 310, 440);
	brick->SetSize(2);
	brick->MoveVertical(424, 496);
	var brick = CreateObject(MovingBrick, 350, 450);
	brick->SetSize(2);
	brick->MoveVertical(432, 504);
	
	var brick = CreateObject(MovingBrick, 932, 240);
	brick->SetSize(4);
	brick->MoveVertical(232, 536);
	
	var brick = CreateObject(MovingBrick, 368, 200);
	brick->SetSize(3);
	brick->MoveVertical(152, 288);
	
	var brick = CreateObject(MovingBrick, 184, 320);
	brick->SetSize(2);
	brick->MoveVertical(240, 368);
	
	var brick = CreateObject(MovingBrick, 498, 560);
	brick->SetSize(2);
	brick->MoveVertical(480, 680);
	DrawMaterialQuad("Tunnel-Brickback", 478, 478, 497, 478, 497, 552, 478, 552);
	DrawMaterialQuad("Tunnel-Brickback", 478, 670, 497, 670, 497, 680, 478, 680);
	
	var brick = CreateObject(MovingBrick, 170, 600);
	brick->SetSize(2);
	brick->MoveVertical(528, 680);
	DrawMaterialQuad("Tunnel-Brickback", 150, 524, 169, 524, 169, 576, 150, 576);
	DrawMaterialQuad("Tunnel-Brickback", 150, 670, 169, 670, 169, 680, 150, 680);
	
	// Horizontally moving bricks.
	var brick = CreateObject(MovingBrick, 600, 496);
	brick->SetSize(4);
	brick->MoveHorizontal(552, 736);
	
	var brick = CreateObject(MovingBrick, 656, 688);
	brick->SetSize(3);
	brick->MoveHorizontal(504, 668);
	var brick = CreateObject(MovingBrick, 688, 664);
	brick->SetSize(3);
	brick->MoveHorizontal(668, 832);
	
	var brick = CreateObject(MovingBrick, 320, 688);
	brick->SetSize(3);
	brick->MoveHorizontal(192, 456);
	
	// Chests with weapons.
	var chest;
	chest = CreateObject(Chest, 764, 128, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 732, 336, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 116, 400, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 272, 152, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 424, 480, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 872, 520, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	chest = CreateObject(Chest, 72, 208, NO_OWNER);
	chest->MakeInvincible();
	AddEffect("FillChest", chest, 100, 72);
	
	// Some columns as decoration.
	CreateObject(Column, 736, 480, NO_OWNER);
	CreateObject(Column, 860, 392, NO_OWNER);
	CreateObject(Column, 420, 280, NO_OWNER);
	CreateObject(Column, 200, 144, NO_OWNER);
	CreateObject(Column, 556, 480, NO_OWNER);
	CreateObject(Column, 452, 672, NO_OWNER);
	CreateObject(Column, 192, 672, NO_OWNER);
	
	// Grass as decoration.
	var x=[813, 820, 856, 833, 827, 838, 844, 869, 872, 882, 853, 861, 506, 466, 527, 524, 514, 510, 517, 502, 436, 437, 441, 448, 457, 463, 177, 139, 121, 126, 199, 190, 181, 213, 206, 133, 147, 196, 104, 175, 116, 108, 126, 135, 155, 201, 195, 188, 43, 52, 58, 406, 410, 551, 554, 550, 547, 538, 723, 838, 802, 808, 836, 690, 781, 787, 745, 869, 861, 825, 829, 849, 720, 910, 908, 901, 795, 803, 819, 875, 855, 830, 813, 869, 894, 886, 844, 796, 789, 787, 729, 764, 779, 770, 755, 749, 741, 574, 533, 574, 566, 559, 546, 426, 429, 414, 407, 397, 390, 387, 380, 376, 218, 210, 97, 104, 118, 123, 131, 139, 144, 154, 212, 194, 209, 205, 198, 188, 181, 174, 216, 221, 291, 313, 298, 305, 307, 296, 301, 284, 269, 103, 84, 132, 124, 148, 146, 140, 118, 107, 91, 332, 330, 328, 314, 298, 281, 184, 236, 227, 213, 268, 292, 307, 315, 322, 365, 362, 370, 378, 578, 582, 589, 731, 734, 740, 759, 773, 787, 833, 826, 806, 818, 832, 842, 864, 851, 887, 892, 906, 877, 732, 729, 709, 704, 757, 769, 717, 892, 899, 922, 907, 857, 842, 832];
	var y=[648, 646, 645, 634, 636, 629, 623, 628, 633, 640, 620, 621, 668, 669, 673, 666, 655, 648, 660, 643, 675, 664, 658, 653, 646, 646, 669, 655, 673, 662, 661, 653, 652, 672, 670, 660, 645, 500, 518, 493, 508, 516, 499, 500, 484, 519, 517, 493, 207, 205, 204, 283, 277, 282, 289, 275, 268, 259, 127, 137, 258, 254, 223, 336, 343, 331, 333, 389, 374, 394, 387, 372, 479, 522, 513, 508, 484, 486, 484, 498, 474, 483, 477, 493, 500, 500, 469, 472, 469, 464, 476, 468, 460, 462, 467, 468, 469, 482, 453, 475, 470, 468, 460, 460, 451, 461, 460, 460, 462, 469, 477, 483, 412, 405, 403, 398, 382, 377, 373, 374, 373, 373, 398, 376, 389, 384, 381, 373, 372, 372, 235, 229, 232, 272, 271, 270, 255, 243, 250, 226, 220, 191, 192, 207, 204, 223, 216, 213, 193, 188, 187, 126, 119, 147, 140, 121, 131, 141, 131, 132, 125, 131, 124, 116, 116, 116, 88, 93, 84, 75, 77, 84, 92, 116, 112, 108, 107, 108, 108, 131, 111, 108, 107, 204, 196, 197, 188, 193, 196, 212, 179, 318, 316, 310, 316, 317, 323, 307, 372, 369, 367, 363, 372, 372, 379];
	var r=[-50, 0, 0, -50, 0, -50, -30, 90, 50, 60, 0, 0, 0, 0, 60, 60, 60, 45, 0, 0, -45, -45, -45, 0, 0, 0, 0, -45, -45, -45, 0, 0, 0, 45, 0, 0, 0, 85, -35, 0, 0, 0, 0, 0, 0, 35, 0, 0, -35, 0, 0, -85, 0, 45, 95, 95, 95, 0, -45, 45, -45, 0, -45, -45, 45, 95, 0, 0, 0, -35, -95, 0, -35, 75, 75, 0, 45, 0, 90, 90, 60, 0, 0, 0, 0, 0, 0, 60, 0, 60, 0, 0, 0, 0, 0, 0, 0, 45, 90, 90, 0, 0, 0, 0, -90, 0, 0, 0, -40, 0, -40, -40, 40, 30, -30, 0, -30, -30, 0, 0, 0, 0, 90, 40, 40, 40, 0, 0, 0, 0, -40, -20, 50, 50, 50, 0, 50, 50, 50, 0, 0, -40, -40, 50, 0, 90, 50, 0, 50, 0, 0, 90, 55, 55, 0, -35, -35, 0, 0, 0, 0, 0, 0, 0, 0, 0, -55, 0, 0, 0, 55, 0, 0, 0, -35, 0, 0, 0, 0, 35, 35, 0, 0, -35, 0, 0, 0, 35, 0, 0, 0, 0, 0, -35, -45, 0, 0, 0, 0, -45, 45, 0, 10, 0, -50];
	for (var i = 0; i < GetLength(x); i++)
	{
		var grass = CreateObject(Grass, x[i], y[i] + 5, NO_OWNER);
		grass->SetR(r[i]); 
	}
	
	// Blue chest with jar of winds.
	var chest_blue = CreateObject(Chest, 850, 648, NO_OWNER);
	chest_blue->SetClrModulation(RGB(100,180,255));
	AddEffect("FillBlueChest", chest_blue, 100, 72);
	
	// Red chest with club.
	var chest_red = CreateObject(Chest, 124, 520, NO_OWNER);
	chest_red->SetClrModulation(RGB(255, 100, 100));
	AddEffect("FillRedChest", chest_red, 100, 72);
		
	// Wind channel.
	AddEffect("WindChannel", nil, 100, 1);
	return;
}

/*-- Wind channel --*/

global func FxWindChannelStart(object target, proplist effect, int temporary)
{
	if (temporary == 0)
		effect.Divider = 1; 
	return 1;
}

global func FxWindChannelTimer(object target, proplist effect)
{
	// Channel divided into three parts.
	
	// First shaft with upward wind.
	for (var obj in FindObjects(Find_InRect(464, 288, 40, 152)))
	{
		var speed = obj->GetYDir(100);
		if (speed < -360)
			continue;
		obj->SetYDir(speed - 36, 100);
	}
	CreateParticle("AirIntake", 464+Random(40), 344+Random(112), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255));
	
	// Divider with random wind.
	if (!Random(100))
		effect.Divider = Random(3);
	for (var obj in FindObjects(Find_InRect(464, 240, 40, 48)))
	{
		if (effect.Divider == 1)
		{
			var speed = obj->GetYDir(100);
			if (speed < -360)
				continue;
			obj->SetYDir(speed - 36, 100);
		}
		if (effect.Divider == 0)
		{
			var speed = obj->GetXDir(100);
			if (speed > -360)
				obj->SetXDir(speed - 20, 100);			
		}
		if (effect.Divider == 2)
		{
			var speed = obj->GetXDir(100);
			if (speed < 360)
				obj->SetXDir(speed + 20, 100);			
		}
	}
	if (effect.Divider == 1)
		CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255));
	if (effect.Divider == 0)
		CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(-20,-10), -20, 60+Random(10), RGB(100+Random(25),128+Random(20),255));
	if (effect.Divider == 2)
		CreateParticle("AirIntake", 464+Random(40), 280+Random(10), RandomX(10,20), -20, 60+Random(10), RGB(100+Random(25),128+Random(20),255));
		
	// Second shaft with upward wind.
	for (var obj in FindObjects(Find_InRect(464, 96, 40, 144)))
	{
		// Divert at top.
		if (obj->GetY() < 104)
		{
			if (obj->GetX() < 484)
			{
				var speed = obj->GetXDir(100);
				if (speed > -200)
				obj->SetXDir(speed - 16, 100);					
			}
			else
			{
				var speed = obj->GetXDir(100);
				if (speed < 200)
				obj->SetXDir(speed + 16, 100);				
			}			
			//continue;
		}
		var speed = obj->GetYDir(100);
		if (speed < -360)
			continue;
		obj->SetYDir(speed - 36, 100);
	}
	CreateParticle("AirIntake", 464+Random(40), 160+Random(96), RandomX(-1,1), -30, 60+Random(10), RGB(100+Random(25),128+Random(20),255));
	
	return 1;
}

/*-- Chest contents --*/

global func FxFillChestStart(object target, proplist effect, int temporary)
{
	if (temporary) 
		return 1;
	var w_list = [Shield, Javelin, FireballScroll, Bow, Musket, WindScroll, TeleportScroll];
	for (var i = 0; i < 4; i++)
		target->CreateChestContents(w_list[Random(GetLength(w_list))]);
	return 1;
}

global func FxFillChestTimer(object target, proplist effect)
{
	if (Random(5))
		return 1;
	var w_list = [Balloon, Boompack, IronBomb, Shield, Javelin, Bow, Musket, Boompack, IronBomb, Shield, Javelin, Bow, Musket, TeleportScroll, WindScroll, FireballScroll];

	if (target->ContentsCount() < 6)
		target->CreateChestContents(w_list[Random(GetLength(w_list))]);
	return 1;
}

global func FxFillBlueChestStart(object target, proplist effect, int temporary)
{
	if (temporary) 
		return 1;		
	target->CreateContents(JarOfWinds);
	var w_list = [Firestone, Boompack, Balloon, FireballScroll, WindScroll];
	for (var i = 0; i < 4; i++)
		target->CreateContents(w_list[Random(GetLength(w_list))]);	
	return 1;
}

global func FxFillBlueChestTimer(object target, proplist effect)
{
	if (Random(5))
		return 1;
	var w_list = [Firestone, Boompack, FireballScroll, WindScroll];
	if (target->ContentsCount() < 6)
		target->CreateContents(w_list[Random(GetLength(w_list))]);
		
	if (!FindObject(Find_ID(JarOfWinds)))
		target->CreateContents(JarOfWinds);
	return 1;
}

global func FxFillRedChestStart(object target, proplist effect, int temporary)
{
	if (temporary) 
		return 1;
	target->CreateContents(Club);
	var w_list = [Firestone, Boompack, FireballScroll, WindScroll];
	for (var i = 0; i < 4; i++)
		target->CreateContents(w_list[Random(GetLength(w_list))]);	
	return 1;
}

global func FxFillRedChestTimer(object target, proplist effect)
{
	if (Random(5))
		return 1;
	var w_list = [Firestone, Boompack, FireballScroll, WindScroll];
	if (target->ContentsCount() < 6)
		target->CreateContents(w_list[Random(GetLength(w_list))]);
		
	if (!FindObject(Find_ID(Club)))
		target->CreateContents(Club);
		
	return 1;
}

global func CreateChestContents(id obj_id)
{
	if (!this)
		return;
	var obj = CreateObject(obj_id);
	if (obj_id == Bow)
		obj->CreateContents(Arrow);
	if (obj_id == Musket)
		obj->CreateContents(LeadShot);
	obj->Enter(this);
	return;
}

/*-- Player control --*/

// GameCall from RelaunchContainer.
func OnClonkLeftRelaunch(object clonk)
{
	var pos = GetRandomSpawn();
	clonk->SetPosition(pos[0],pos[1]);
	CastParticles("Magic",36,12,pos[0],pos[1],30,60,clonk->GetColor(),clonk->GetColor(),clonk);
	return;
}

global func GetRandomSpawn()
{
	var spawns = [[432,270],[136,382],[200,134],[864,190],[856,382],[840,518],[408,86],[536,470]];
	var rand = Random(GetLength(spawns));
	return spawns[rand];
}


// Gamecall from LastManStanding goal, on respawning.
protected func OnPlayerRelaunch(int plr)
{
	var clonk = GetCrew(plr);
	var relaunch = CreateObject(RelaunchContainer, LandscapeWidth() / 2, LandscapeHeight() / 2, clonk->GetOwner());
	relaunch->StartRelaunch(clonk);
	return;
}

func KillsToRelaunch() { return 0; }
func RelaunchWeaponList() { return [Bow, Javelin, Musket, FireballScroll, WindScroll, TeleportScroll]; }
