/** 
	Playground
	Author: Maikel
	
	Reward for completing the tutorials, a small playground where the player can test all ingame objects.
	
	TODO:
	* Multiple map options.
	* Options for animals, vegetation. 
*/


protected func Initialize()
{
	// Tutorial goal.
	var goal = CreateObject(Goal_Tutorial);
	goal.Name = "$MsgGoalName$";
	goal.Description = "$MsgGoalDescription$";
	
	// Add an effect to track the easter egg for all players.
	AddEffect("EasterEgg", nil, 100, 36);
	
	// Initialize different scenario parts.
	InitVegetation(3);
	InitAnimals(SCENPAR_Animals);
	return;
}

private func InitVegetation(int type)
{
	// No vegetation.
	if (type <= 1)
		return;
	
	var wdt = LandscapeWidth();
	var hgt = LandscapeHeight();

	// Place surface vegetation.
	Tree_Coniferous->Place(10);
	Tree_Coniferous2->Place(10);
	return;
}

private func InitAnimals(int type)
{
	// No animals.
	if (type <= 1)
		return;
	
	var wdt = LandscapeWidth();
	var hgt = LandscapeHeight();
		
	// Sky animals.
	if (FindLocation(Loc_Sky()))
	{
		var amount = BoundBy(wdt * hgt - GetTotalMaterialCount() / 20000, 4, 40);
		Butterfly->Place(amount);
		Mosquito->Place(amount / 2, 10);
		if (type >= 3)
		{
			Zaphive->Place(amount / 2);
		}
	}
	
	// Land animals.
	if (FindLocation(Loc_Sky(), Loc_Wall(CNAT_Bottom)))
	{
		var amount = BoundBy(wdt / 200, 4, 40);
		if (type >= 3)
		{
			Chippie_Egg->Place(amount / 2);
		}
	}

	// Underwater animals.
	if (FindLocation(Loc_Material("Water")))
	{
		var amount = BoundBy(GetMaterialCount(Material("Water")) / 1500, 4, 40);
		Fish->Place(amount);	
		if (type >= 3)
		{
			Piranha->Place(amount / 2);		
		}	
	}
	return;
}


/*-- Player Handling --*/

protected func InitializePlayer(int plr)
{
	// Position player's clonk.
	var clonk = GetCrew(plr, 0);
	clonk->SetPosition(624, 526);
	var effect = AddEffect("ClonkRestore", clonk, 100, 10);
	effect.to_x = 624;
	effect.to_y = 526;
	
	// Standard player zoom for tutorials, set max zoom roughly up to scenario boundaries.
	SetPlayerViewLock(plr, true);
	SetPlayerZoomByViewRange(plr, 400, nil, PLRZOOM_Direct);
	SetPlayerZoomByViewRange(plr, 1200, nil, PLRZOOM_LimitMax);
	
	// Give the player all construction plans.
	var index = 0, def;
	while (def = GetDefinition(index++))
		SetPlrKnowledge(plr, def);

	// Create tutorial guide, add messages, show first.
	var guide = CreateObject(TutorialGuide, 0, 0 , plr);
	var con_spawnmenu = GetPlayerControlAssignment(plr, CON_SpawnMenu, true, true);
	guide->AddGuideMessage(Format("$MsgPlaygroundWelcome$", con_spawnmenu));
	guide->ShowGuideMessage();
	AddEffect("RemoveGuide", clonk, 100, 36 * 10);
	
	// Achievement: Playground is completed by just playing it.
	GainScenarioAchievement("TutorialCompleted", 3);
	return;
}

global func FxRemoveGuideTimer(object target, proplist effect, int time)
{
	return -1;
}

global func FxRemoveGuideStop(object target, proplist effect, int reason, bool  temporary)
{
	if (temporary)
		return;
	
	var guide = FindObject(Find_ID(TutorialGuide));
	if (guide)
	{
		guide->HideGuide();
		guide->RemoveObject();	
	}
}


/*-- Easter Egg --*/

global func FxEasterEggTimer(object target, proplist effect, int time)
{
	// Check whether the landscape has been completely destroyed.	
	if (GetBlastableMaterialCount() < 1000)
	{
		GainScenarioAchievement("TutorialEasterEgg");
		return FX_Execute_Kill;
	}
	return FX_OK;
}

global func GetBlastableMaterialCount()
{
	var total = 0;
	for (var index = 0; index < 256; index++)
	{
		// Only for solids.
		if (GetMaterialVal("Density", "Material", index) < 50)
			continue;
		if (!GetMaterialVal("BlastFree", "Material", index) || !GetMaterialVal("DigFree", "Material", index))
			continue;
		var mat_cnt = GetMaterialCount(index);
		if (mat_cnt != -1)
			total += mat_cnt;
	}
	return total;
}

global func GetTotalMaterialCount()
{	var total = 0;
	for (var index = 0; index < 256; index++)
	{
		var mat_cnt = GetMaterialCount(index);
		if (mat_cnt != -1)
			total += mat_cnt;
	}
	return total;
}


/*-- Clonk Restoring --*/

global func FxClonkRestoreTimer(object target, proplist effect, int time)
{
	return 1;
}

// Relaunches the clonk, from death or removal.
global func FxClonkRestoreStop(object target, effect, int reason, bool  temporary)
{
	if (reason == 3 || reason == 4)
	{
		var restorer = CreateObject(ObjectRestorer, 0, 0, NO_OWNER);
		var x = BoundBy(target->GetX(), 0, LandscapeWidth());
		var y = BoundBy(target->GetY(), 0, LandscapeHeight());
		restorer->SetPosition(x, y);
		var to_x = effect.to_x;
		var to_y = effect.to_y;
		// Respawn new clonk.
		var plr = target->GetOwner();
		var clonk = CreateObject(Clonk, 0, 0, plr);
		clonk->GrabObjectInfo(target);
		SetCursor(plr, clonk);
		clonk->DoEnergy(100000);
		restorer->SetRestoreObject(clonk, nil, to_x, to_y, 0, "ClonkRestore");
	}
	return 1;
}