town_array = { "Town1", "Town2", "Town3", "Town4", "Town5", "Town6", "Town7" };
hero_array = {"Calid","Deleb","Efion"};
dang_array = {"Dalom","Almegir","Eruina","Menel","Inagost","Ferigl","Segref"};

count = 0;
envassion = 0;
defeathero = 0;

artefacts = {1, 5, 8, 9, 14, 16, 18, 20, 27, 32, 34, 55, 56, 57, 60, 61, 62, 64, 65, 66};

StartDialogScene("/DialogScenes/C4/M3/D1/DialogScene.xdb#xpointer(/DialogScene)");

if GetDifficulty() == DIFFICULTY_EASY then
	print ("easy");
	dif = 0;
	exp = GetHeroStat("Raelag", STAT_EXPERIENCE)/4;
	for i,h in dang_array do
		ChangeHeroStat(dang_array[i], STAT_EXPERIENCE , exp);
	end;
	for a = 0,6 do
		SetPlayerResource(PLAYER_2, a, 0);
		SetPlayerResource(PLAYER_3, a, 0);
	end;
	AddObjectCreatures("Raelag", CREATURE_ASSASSIN , 50);
	AddObjectCreatures("Raelag", CREATURE_BLOOD_WITCH , 30);
	AddObjectCreatures("Raelag", CREATURE_MATRIARCH , 5);
end;

if GetDifficulty() == DIFFICULTY_NORMAL then
	print ("normal");
	dif = 0;
	exp = GetHeroStat("Raelag", STAT_EXPERIENCE)/2;
	for i,hero in dang_array do
		ChangeHeroStat(hero, STAT_EXPERIENCE , exp);
	end;
	for a = 0,6 do
		SetPlayerResource(PLAYER_2, a, 0);
		SetPlayerResource(PLAYER_3, a, 0);
	end;
end;

if GetDifficulty() == DIFFICULTY_HARD then
	print ("Hard");
	dif = 1;
	exp = GetHeroStat("Raelag", STAT_EXPERIENCE);
	for i,h in dang_array do
		ChangeHeroStat(h, STAT_EXPERIENCE , exp);
		AddObjectCreatures(h, CREATURE_ASSASSIN , 30);
		AddObjectCreatures(h, CREATURE_BLOOD_WITCH , 20);
	end;
	DenyAIHeroesFlee(2,1);
end;

if GetDifficulty() == DIFFICULTY_HEROIC then
	print ("Impossible");
	dif = 2;
	exp = GetHeroStat("Raelag", STAT_EXPERIENCE) + GetHeroStat("Kelodin", STAT_EXPERIENCE);
	for i,h in dang_array do
		ChangeHeroStat(dang_array[i], STAT_EXPERIENCE , exp);
		sleep(1);
		ChangeHeroStat(dang_array[i], 8, 10 * GetHeroStat(dang_array[i], 4));
		AddObjectCreatures(dang_array[i], CREATURE_ASSASSIN , 45);
		AddObjectCreatures(dang_array[i], CREATURE_BLOOD_WITCH , 30);
		AddObjectCreatures(dang_array[i], CREATURE_MINOTAUR_KING , 37);
	end;
	DenyAIHeroesFlee(2,1);
	DenyAIHeroesFlee(3,1);
end;

function give_art(hero, array, num)
	if IsHeroAlive(hero) then
		local k = 0;
		local l = length(array);
		local m = 2 * (l - mod(l,num))/num
		for i, art in array do
			if k < num then
				if random(m) == 0 then
					GiveArtefact(hero, art);
					k = k + 1;
				end;
			end;
		end;
	end;
end;

function warlok_up()
	if dif == 2 then
		for i,h in dang_array do
			if random(2) == 0 then
				if random(4) == 0 then
					AddObjectCreatures(dang_array[i], 77 , 6);
					else if random(3) == 0 then
						AddObjectCreatures(dang_array[i], 79 , 3);
						else if random(2) == 0 then
							AddObjectCreatures(dang_array[i], 81 , 1);
							else AddObjectCreatures(dang_array[i], 85 , 4);
						end;
					end;
				end;
			end;
			startThread(give_art, dang_array[i], artefacts, 2);
			if random(2) == 0 then
				SetHeroLootable(dang_array[i], nil);
			end;
		end;
	end;
end;

function load_arts()
	sleep(3);
	if GetGameVar("C4M2_Raelag_AFH") == "1" then
		GiveArtefact("Raelag", 13);
	end;
	if GetGameVar("C4M2_Kelodin_AFH") == "1" then
		GiveArtefact("Kelodin", 13);
	end;
end;

function LostHero( HeroName )
	if ( HeroName == "Raelag" or HeroName == "Kelodin") then
		SetObjectiveState("Survival", OBJECTIVE_FAILED);
		sleep (10);
		Loose();
	end;
end;

function TownCapture(old, new, hero)
	if old == 2 and new == 1 then
		local town = find_town(hero);
		if town ~= nil then
			print(hero.." captured town "..town);
			Trigger(OBJECT_CAPTURE_TRIGGER, town, nil);
			count = count + 1;
			if count == 2 or count == 4 or count == 6 then
				print("starting demon invasion...");
				startThread(Envasion, town);
			end;
		end;
	end;
end;

function find_town(hero)
	if IsHeroAlive(hero) then
		for i, town in town_array do
			if GetObjectOwner(town) == GetObjectOwner(hero) then
				if len(hero, town) < 12 then
					return town;
				end;
			end;
		end;
	end
	return nil;
end;

function Envasion(town)
	envassion = envassion + 1;
	local day = GetDate(DAY);
	while GetDate(DAY) == day do
		sleep(4);
	end;
	if envassion == 1 then
		StartDialogScene("/DialogScenes/C4/M3/R1/DialogScene.xdb#xpointer(/DialogScene)");
		SetObjectiveState("Envasion", OBJECTIVE_ACTIVE);
		x,y,z = RegionToPoint('EnemyHere');
		OpenCircleFog(x, y, z, 2 , 1);
		MoveCamera(x,y,z, 50, 1.57);
	end;
	sleep(1);
	local hero = hero_array[envassion];
	DeployReserveHero(hero, RegionToPoint('EnemyHere'));
	sleep(1);
	startThread(AddTroops, hero);
	SetAIHeroAttractor(town, hero, 2);
	MoveHero(hero, 133, 42, 1);
	print(hero.." want to capture town "..town);
	while IsHeroAlive(hero) do
		sleep(5);
		if GetObjectOwner(town) ~= 1 then
			break;
		end;
	end;
	if IsHeroAlive(hero) then
		SetAIHeroAttractor(town, hero, 0);
		if len(hero, town) < 10 then
			if GetObjectOwner(town) == 3 then
				if dif < 2 then
					EnableHeroAI(hero, nil);
					print(hero.." want to live in town "..town);
				end;
			end;
		end;
	end;
end;

function AddTroops(hero)
	X = (GetDate(MONTH) - 1)*4 + GetDate(WEEK);
	if hero == 'Calid' then
		ChangeHeroStat(hero, STAT_EXPERIENCE , exp);
		AddObjectCreatures(hero, CREATURE_IMP , 16*X + 8*X*dif);
		AddObjectCreatures(hero, CREATURE_HORNED_DEMON , 15*X + 7*X*dif);
		AddObjectCreatures(hero, CREATURE_CERBERI , 8*X + 4*X*dif);
		AddObjectCreatures(hero, CREATURE_INFERNAL_SUCCUBUS , 5*X + 2*X*dif);
		AddObjectCreatures(hero, CREATURE_FRIGHTFUL_NIGHTMARE , 3*X + 1*X*dif);
		if dif > 1 then
			SetHeroLootable(hero, nil);
			for i=1,4 do
				ChangeHeroStat(hero, i, 1);
			end;
			if random(2) == 0 then
				GiveArtefact(hero, 1);
				else GiveArtefact(hero, 9);
			end;
			if random(2) == 0 then
				GiveArtefact(hero, 8);
				else GiveArtefact(hero, 16);
			end;
			if random(2) == 0 then
				GiveArtefact(hero, 20);
				else GiveArtefact(hero, 62);
			end;
			if random(2) == 0 then
				GiveArtefact(hero, 14);
				else GiveArtefact(hero, 56);
			end;
		end;
	end;
	if hero == 'Deleb' then
		exp = GetHeroStat("Raelag", STAT_EXPERIENCE);
		ChangeHeroStat(hero, STAT_EXPERIENCE , exp/(3-dif));
		AddObjectCreatures(hero, CREATURE_IMP , 16*X + 8*X*dif);
		AddObjectCreatures(hero, CREATURE_HORNED_DEMON , 15*X + 7*X*dif);
		AddObjectCreatures(hero, CREATURE_CERBERI , 8*X + 4*X*dif);
		AddObjectCreatures(hero, CREATURE_INFERNAL_SUCCUBUS , 5*X + 2*X*dif);
		AddObjectCreatures(hero, CREATURE_FRIGHTFUL_NIGHTMARE , 3*X + 1*X*dif);
		AddObjectCreatures(hero, CREATURE_BALOR , 2*X + 1*X*dif);
		if dif > 0 then
			for i=1,4 do
				ChangeHeroStat(hero, i, dif);
			end;
			if dif > 1 then
				SetHeroLootable(hero, nil);
				GiveArtefact(hero, 1);
				GiveArtefact(hero, 9);
				GiveArtefact(hero, 20);
				GiveArtefact(hero, 65);
				GiveArtefact(hero, 57);
				GiveArtefact(hero, 32);
				TeachHeroSpell(hero, 9);
				TeachHeroSpell(hero, 21);
			end;
		end;
	end;
	if hero == "Efion" then
		exp = GetHeroStat("Raelag", STAT_EXPERIENCE) + GetHeroStat("Kelodin", STAT_EXPERIENCE);
		ChangeHeroStat(hero, STAT_EXPERIENCE , exp/(3-dif));
		AddObjectCreatures(hero, CREATURE_IMP , 16*X + 8*X*dif);
		AddObjectCreatures(hero, CREATURE_HORNED_DEMON , 15*X + 7*X*dif);
		AddObjectCreatures(hero, CREATURE_CERBERI , 8*X + 4*X*dif);
		AddObjectCreatures(hero, CREATURE_INFERNAL_SUCCUBUS , 5*X + 2*X*dif);
		AddObjectCreatures(hero, CREATURE_FRIGHTFUL_NIGHTMARE , 3*X + 1*X*dif);
		AddObjectCreatures(hero, CREATURE_BALOR , 2*X + 1*X*dif);
		AddObjectCreatures(hero, CREATURE_ARCHDEVIL , 1*X + 1*X*dif);
		if dif > 0 then
			for i=1,4 do
				ChangeHeroStat(hero, i, 1 + dif);
			end;
			if dif > 1 then
				SetHeroLootable(hero, nil);
				GiveArtefact(hero, 43);
				GiveArtefact(hero, 51);
				GiveArtefact(hero, 23);
				GiveArtefact(hero, 59);
				GiveArtefact(hero, 31);
				GiveArtefact(hero, 49);
				GiveArtefact(hero, 36);
				GiveArtefact(hero, 15);
				GiveArtefact(hero, 25);
				GiveArtefact(hero, 66);
				TeachHeroSpell(hero, 9);
				TeachHeroSpell(hero, 18);
			end;
		end;
	end;
end;

function Infernohero(inferno_hero)
	if inferno_hero == 'Calid' or inferno_hero == 'Deleb' or inferno_hero == 'Efion' then
		defeathero = defeathero + 1;
		print (defeathero);
		print (inferno_hero);
		if defeathero == 3 then
			StartDialogScene("/DialogScenes/C4/M3/R2/DialogScene.xdb#xpointer(/DialogScene)");
			SetObjectiveState("Envasion", OBJECTIVE_COMPLETED);
			sleep (5);
			LevelUpHero("Raelag");
		end;
	end;
end;

function len(x,y)
	local l = 1000;
	if IsObjectExists(x) and IsObjectExists(y) then
		local x1,y1,z1 = GetObjectPosition(x);
		local x2,y2,z2 = GetObjectPosition(y);
		if z1 == z2 then
			l = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
		end;
	end;
	return l;
end;

function victory()
	while 1 do 
		sleep(1);
		if GetObjectOwner("Town7") == 1 and GetObjectOwner("Town6") == 1 and GetObjectOwner("Town5") == 1 and GetObjectOwner("Town4") == 1 and GetObjectOwner("Town3") == 1 and GetObjectOwner("Town2") == 1 and GetObjectOwner("Town1") == 1 then
			Trigger (PLAYER_REMOVE_HERO_TRIGGER, PLAYER_3, nil);
			Save("quicksave");
			StartDialogScene("/DialogScenes/C4/M3/D2/DialogScene.xdb#xpointer(/DialogScene)");
			SetObjectiveState("prim1", OBJECTIVE_COMPLETED);
			if HasArtefact("Raelag", 13) then
				SetGameVar("C4M3_Raelag_AFH", 1);
				else SetGameVar("C4M3_Raelag_AFH", 0);
			end;
			if HasArtefact("Kelodin", 13) then
				SetGameVar("C4M3_Kelodin_AFH", 1);
				else SetGameVar("C4M3_Kelodin_AFH", 0);
			end;
			sleep(5);
			LevelUpHero("Raelag");
			sleep(5);
			Win();
		break;
		end;
	end;
end;

for i=1,7 do
	Trigger (OBJECT_CAPTURE_TRIGGER, 'Town'..i, 'TownCapture');
end;
Trigger( PLAYER_REMOVE_HERO_TRIGGER, PLAYER_1, "LostHero" );

startThread(load_arts);
startThread( victory );
startThread(warlok_up);
Trigger (PLAYER_REMOVE_HERO_TRIGGER, PLAYER_3, 'Infernohero');