zehir = "Zehir";

play = 0
script_check = 0

hard_spells = {5, 6, 11, 12, 14, 15, 17, 19, 34, 43, 236, 237};
heroic_spells = {7, 8, 9, 18, 19, 20, 40, 43, 235};

necromants = {"Straker", "Pelt", "Gles", "Tamika", "Nemor", "Effig", "Muscip"};
demons = {"SKELETON", "WALKING", "ZOMBIE", "MANES", "GHOST", "VAMPIRE", "LICH", "WIGHT", "WRAITH", "DRAGON"};

town_array = {"town1","town2","town3"};
town_array.n = 3;

if GetDifficulty() == DIFFICULTY_EASY then
	dif = 0;
	print ("easy");
end;

if GetDifficulty() == DIFFICULTY_NORMAL then
	dif = 1;
	print ("normal");
end;

if GetDifficulty() == DIFFICULTY_HARD then
	dif = 2;
	print ("hard");
end;

if GetDifficulty() == DIFFICULTY_HEROIC then
	dif = 3;
	print ("heroic");
end;
-------------------------------------------------------------------------
function map_up()
	GiveExp("Aberrar", 5000 + dif * 3000);
	if dif > 1 then
		DenyAIHeroesFlee(3,1);
		startThread(add_demons, 0.25*(dif-1));
		startThread(add_army, "town3", 0.5*(dif-1));
		AddObjectCreatures("town3", 42, 8*dif);
		startThread(add_army, "nar_ankar", 0.5*(dif-1));
		for i =0,5 do
			SetPlayerResource(3, i, 20*dif);
		end;
		local towns = GetObjectNamesByType("TOWN");
		for i, town in towns do
			if town ~= "town1" and town ~= "town2" and town ~= "insar" then
				EnableAIHeroHiring(3, town, nil);
			end;
		end;
		RemoveObjectCreatures("garnizon", 48, 10);
		if dif == 3 then
			AddObjectCreatures("garnizon", 39, 5);
			AddObjectCreatures("garnizon", 29, 60);
			AddObjectCreatures("garnizon", 32, 25);
			AddObjectCreatures("garnizon", 33, 20);
			else AddObjectCreatures("garnizon", 37, 4);
			AddObjectCreatures("garnizon", 30, 40);
			AddObjectCreatures("garnizon", 31, 25);
			AddObjectCreatures("garnizon", 33, 18);
		end;
	end;
	SetRegionBlocked("block", not nil, 3);
	SetObjectiveVisible("obj3", nil);
end;

function boss_nekr(hero)
	if IsInArray(hero, necromants) and IsObjectVisible(1, hero) == nil then
		Trigger(PLAYER_ADD_HERO_TRIGGER, 3, "new_nekr");
		print(hero.." is boss now!");
		sleep(1);
		EnableHeroAI(hero, nil);
		startThread(enable_boss, hero);
	end;
end;

function new_nekr(hero)
	if IsInArray(hero, necromants) and GetHeroStat(hero, 0) < 1000 then
		ChangeHeroStat(hero, 0, 500 + 2000 * dif);
	end;
end;

function enable_boss(hero)
	sleep(1);
	if dif > 1 then
		startThread(teach_spell, hero, hard_spells, dif+1);
		for i=1,4 do
			ChangeHeroStat(hero, i, dif-1);
		end;
		if dif == 3 then
			startThread(teach_spell, hero, heroic_spells, 3);
			SetHeroLootable(hero, nil);
			GiveArtefact(hero, 2);
			GiveArtefact(hero, 9);
			GiveArtefact(hero, 17);
			GiveArtefact(hero, 21);
			GiveArtefact(hero, 23);
			GiveArtefact(hero, 62);
			GiveArtefact(hero, 57);
			GiveArtefact(hero, 44);
			GiveArtefact(hero, 25);
			GiveArtefact(hero, 46);
			GiveHeroSkill(hero, 3);
			GiveHeroSkill(hero, 10);
			if hero ~= "Effig" then
				GiveHeroSkill(hero, 12);
				else GiveHeroSkill(hero, 8);
			end;
			GiveHeroSkill(hero, 6);
			GiveHeroSkill(hero, 7);
		end;
	end;
	sleep(1);
	ChangeHeroStat(hero, 0, 20000 + 20000*dif);
	if GetObjectCreatures(hero, 29) > 0 then
		RemoveObjectCreatures(hero, 29, GetObjectCreatures(hero, 29));
	end;
	if GetObjectCreatures(hero, 33) > 0 then
		RemoveObjectCreatures(hero, 33, GetObjectCreatures(hero, 33));
	end;
	for i = 29,42 do
		if GetObjectCreatures("nar_ankar", i) > 0 then
			AddObjectCreatures(hero, i, GetObjectCreatures("nar_ankar", i));
			RemoveObjectCreatures("nar_ankar", i, GetObjectCreatures("nar_ankar", i));
		end;
	end;
	local x,y = GetObjectPosition(hero);
	if y > 30 then
		SetObjectPosition(hero, 109, 26);
	end;
	sleep(5);
	while IsHeroAlive(hero) do
		if Town_count() == 3 then
			break
		end;
		sleep(10);
	end;
	if IsHeroAlive(hero) then
		print("Boss "..hero.." is enabled!");
		EnableHeroAI(hero, not nil);
	end;
end;

function IsInArray(unit, array)
	if IsObjectExists(unit) then
		if array ~= {} then
			for i, id in array do
				if unit == id then
					return not nil
				end;
			end;
		end;
	end;
	return nil
end;

function teach_spell(hero, array, num)
	if IsHeroAlive(hero) then
		local k = 0;
		local l = length(array);
		local m = 2 * (l - mod(l,num))/num
		for i, spell in array do
			if k < num then
				if random(m) == 0 and KnowHeroSpell(hero, spell) == nil then
					TeachHeroSpell(hero, spell);
					k = k + 1;
				end;
			end;
		end;
	end;
end;

function add_army(mon, ind)
	if IsObjectExists(mon) then
		for i = 29, 42 do
			if GetObjectCreatures(mon, i) > 0 then
				AddObjectCreatures(mon, i, ind * GetObjectCreatures(mon, i));
			end;
		end;
	end;
end;

function add_demons(coef)
	local creatures = {};
	for i, name in demons do
		creatures = GetObjectNamesByType(name);
		if creatures ~= {} then
			for j, mon in creatures do
				startThread(add_army, mon, coef);
			end;
		end;
	end;
end;

---Objectives---

function SilverCitiesCaptured()
	if play == 0 then 
		StartDialogScene("/DialogScenes/C6/M2/R2/DialogScene.xdb#xpointer(/DialogScene)");
		SetObjectiveState("obj1",OBJECTIVE_COMPLETED); 
		ChangeHeroStat("Zehir", STAT_EXPERIENCE, 2448);
		local towns = GetObjectNamesByType("TOWN");
		for i, town in towns do
			EnableAIHeroHiring(3, town, not nil);
		end;
		play = play + 1;
		else SetObjectiveState("obj1",OBJECTIVE_COMPLETED); 
	end;
end	

function TownCounter()
	print( "Town_count() = ",Town_count() );
	if Town_count() == 3 then
		SilverCitiesCaptured();
	end;
end;

function Town_count()
	local count = 0;
	for i=1, town_array.n do
		if ( GetObjectOwner(town_array[i]) == PLAYER_1 ) then
			count = count + 1;
		end;
		if ( GetObjectOwner(town_array[i]) == PLAYER_3 ) then
			count = count - 1;
		end;
	end;
	return count; 
end;

function SpellsLearned()
	StartDialogScene("/DialogScenes/C6/M2/R3/DialogScene.xdb#xpointer(/DialogScene)");
end

function UpgradingAlSafir()
	SetTownBuildingLimitLevel("insar", TOWN_BUILDING_MAGIC_GUILD, 2);
	while 1 do
--		i = GetTownBuildingLevel( "insar", TOWN_BUILDING_MAGIC_GUILD )
--		print("ch3ck insar = ",i);
		if GetObjectOwner("town3") == PLAYER_1 and script_check == 0 then
			SetTownBuildingLimitLevel("insar", TOWN_BUILDING_MAGIC_GUILD, 5)
			SetRegionBlocked("block", nil, PLAYER_3);
			script_check = 1;
		end
		if GetObjectOwner("town3") == PLAYER_1 and GetTownBuildingLevel( "town3", TOWN_BUILDING_MAGIC_GUILD ) == 5 then
			sleep(10);
			if GetObjectiveState("obj2") == OBJECTIVE_ACTIVE  then
				SetObjectiveState("obj2",OBJECTIVE_COMPLETED);
				ChangeHeroStat("Zehir", STAT_EXPERIENCE, 2788);
			else
				print("Warning!!! obj2 is not ACTIVE");
			end;
			return 1;
		end;
	sleep();
	end;
end

function obj3()
	while 1 do
		if GetObjectiveState("obj1") == OBJECTIVE_COMPLETED and GetObjectiveState("obj2") == OBJECTIVE_COMPLETED then
			sleep(1);
			SetObjectiveVisible("obj3", not nil);
		end;
		sleep();
	end;
end

-- lorekeep = nar ankar

function CapturingNarAnkar()
	Save("Scene_17");
	sleep(20);
	ChangeHeroStat("Zehir", STAT_EXPERIENCE, 2378);
	StartDialogScene("/DialogScenes/C6/M2/D1/DialogScene.xdb#xpointer(/DialogScene)");
	SetObjectiveState("obj3",OBJECTIVE_COMPLETED);
	Trigger(OBJECT_CAPTURE_TRIGGER, "nar_ankar", nil);
end

function dialog4()
	while 1 do
		if GetObjectiveState("obj1")==OBJECTIVE_COMPLETED and GetObjectiveState("obj2")==OBJECTIVE_COMPLETED then
			sleep(20);
			StartDialogScene("/DialogScenes/C6/M2/R4/DialogScene.xdb#xpointer(/DialogScene)");
			sleep();
			break;
		end;
	sleep(5)
	end;
end;

--WinLoose--
function WinLoose()
	while 1 do
		if GetObjectiveState("obj1") == OBJECTIVE_COMPLETED and GetObjectiveState("obj2") == OBJECTIVE_COMPLETED and
			GetObjectiveState("obj3") == OBJECTIVE_COMPLETED and GetObjectiveState("obj4") == OBJECTIVE_COMPLETED then
			Win();
			return
		end;
		if GetObjectiveState("obj1") == OBJECTIVE_FAILED or GetObjectiveState("obj2") == OBJECTIVE_FAILED or
			GetObjectiveState("obj3") == OBJECTIVE_FAILED or GetObjectiveState("obj4") == OBJECTIVE_FAILED then
			sleep(20);
			Loose();
			return
		end;
		sleep();
	end;
end;

function obj4()
	if GetObjectiveState("obj4") == OBJECTIVE_UNKNOWN then
		SetObjectiveState('obj4',OBJECTIVE_ACTIVE);
		else
		print("Warning!!! obj4 is not UNKNOWN");
	end;
		while 1 do
			if IsHeroAlive("Zehir")==nil then
				print("Zehir is dead!!!");
				if GetObjectiveState("obj4") == OBJECTIVE_ACTIVE or GetObjectiveState("obj4") == OBJECTIVE_COMPLETED then
					SetObjectiveState("obj4",OBJECTIVE_FAILED);
					else
					print("Warning!!! obj4 is not ACTIVE or COMPLETED");
				end;
				return 1;
			end;
		if GetObjectiveState("obj1") == OBJECTIVE_COMPLETED and GetObjectiveState("obj2") == OBJECTIVE_COMPLETED
			and GetObjectiveState("obj3") == OBJECTIVE_COMPLETED then
			if GetObjectiveState("obj4") == OBJECTIVE_ACTIVE  then
				SetObjectiveState('obj4',OBJECTIVE_COMPLETED);
				else
				print("Warning!!! obj4 is not ACTIVE");
			end;
			return 1;
		end;
	sleep(2);
	end;
end;

function obj1()
	if GetObjectiveState("obj1") == OBJECTIVE_UNKNOWN then
		SetObjectiveState('obj1',OBJECTIVE_ACTIVE);
	else
		print("Warning!!! obj1 is not UNKNOWN");
	end;
sleep();
end;

-- perform script
StartDialogScene("/DialogScenes/C6/M2/R1/DialogScene.xdb#xpointer(/DialogScene)");

Trigger(OBJECT_CAPTURE_TRIGGER, "nar_ankar", "CapturingNarAnkar");
Trigger(OBJECT_CAPTURE_TRIGGER, "town1", "TownCounter");
Trigger(OBJECT_CAPTURE_TRIGGER, "town2", "TownCounter");
Trigger(OBJECT_CAPTURE_TRIGGER, "town3", "TownCounter");
Trigger(PLAYER_ADD_HERO_TRIGGER, 3, "boss_nekr");

startThread(UpgradingAlSafir);
startThread(obj4);
startThread(obj3);
startThread(obj1);
startThread(WinLoose);
startThread(map_up);