StartDialogScene("/DialogScenes/Single/SL2/R1/DialogScene.xdb#xpointer(/DialogScene)");

Resources_plus = {{WOOD,5},{ORE,5},{GEM,3},{CRYSTAL,3},{SULFUR,3},{MERCURY,3},{GOLD,3000}};
Resources_minus = {{WOOD,-10},{ORE,-10},{GEM,-5},{CRYSTAL,-5},{SULFUR,-5},{MERCURY,-5},{GOLD,-5000}};
Resources_plus.n = 7;
Resources_minus.n = 7;

hard_spells = {3, 4, 5, 6, 7, 11, 12, 15, 24, 25, 28, 35, 42, 43, 49};
heroic_spells = {8, 9, 10, 18, 19, 20, 34, 40, 51, 235};
artefacts = {1, 2, 5, 8, 9, 11, 14, 16, 17, 18, 19, 21, 24, 25, 26, 27, 28, 29, 31, 55, 56, 57, 59, 60, 61, 62, 64, 65, 66, 67, 69};

AllTowns = {{"Academy","AcademyPoint","AcademyStart"},{"Sylvan","SylvanPoint","SylvanStart"},{"Necropolis","NecropolisPoint","NecropolisStart"},{"Inferno","InfernoPoint","InfernoStart"}};
mags = {"Astral", "Havez", "Tan", "Faiz"};

ArmyMdf = 1;

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

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

if GetDifficulty() == DIFFICULTY_HARD then
	diff = 2;
	DenyAIHeroesFlee(5,1);
	print("hard");
end;

if GetDifficulty() == DIFFICULTY_HEROIC then
	diff = 3;
	for i=2,5 do
		DenyAIHeroesFlee(i,1);
	end;
	print("heroic");
end;

--function calculates multiplier for army of Invaders.
function modificator()
	while 1 do
		sleep(60);
		if diff > 1 then
			ArmyMdf = 2*GetDate(MONTH)*(diff-1);
			else ArmyMdf = GetDate(MONTH)*(0.5 + diff);
		end;
	end;
end;

--function determines moment when necessary start Invasion of imperial forces
function TimeToStartInvasion()
	print("Thread TimeToStartInvasion has been started...");
	while 1 do
		local j = 0;
		sleep(60)
		for i=1,4 do
			if GetObjectOwner(AllTowns[i][1]) == PLAYER_1 then
				j = j + 1;
			end;
		end;
		if j == 4 then
			print("Player has captured all towns on the map");
			startThread(Invasion,40);
			SetObjectiveState("CaptureTowns",OBJECTIVE_COMPLETED);
			StartDialogScene("/DialogScenes/Single/SL2/R2/DialogScene.xdb#xpointer(/DialogScene)");
			break;
		end;
	end;
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 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 ShowMeHero(HeroName)
	local x,y = GetObjectPosition(HeroName);
	OpenCircleFog(x,y,GROUND,15,PLAYER_1);
	MoveCamera(x,y,GROUND);
end;

function Invasion(delay)
		print("Thread Invasion has been started...");
		sleep(1);
		SetObjectiveState("Defence", OBJECTIVE_ACTIVE);
		startThread(ReachTown,"Tan", AllTowns[2][2], AllTowns[2][3]);
		sleep (delay);
		ShowMeHero("Tan");
		print("modificator = ",ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_ARCH_MAGI, 10*ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_MAGI, 10*ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_GENIE, 5*ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_RAKSHASA, 3*ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_STONE_GARGOYLE, 20*ArmyMdf);
		AddHeroCreatures('Tan', CREATURE_GREMLIN, 30*ArmyMdf);
		startThread(ReachTown,"Faiz", AllTowns[1][2], AllTowns[1][3]);
		sleep(delay);
		ShowMeHero("Faiz");
		startThread(ReachTown,"Astral", AllTowns[3][2], AllTowns[3][3]);
		sleep(delay);
		ShowMeHero("Astral");
		startThread(ReachTown,"Havez", AllTowns[4][2], AllTowns[4][3]);
		sleep(delay);
		ShowMeHero("Havez");
		AddHeroCreatures('Faiz', CREATURE_MAGI, 10*ArmyMdf);
		AddHeroCreatures('Faiz', CREATURE_RAKSHASA, 10*ArmyMdf);
		AddHeroCreatures('Faiz', CREATURE_MASTER_GENIE, 12*ArmyMdf);
		AddHeroCreatures('Faiz', CREATURE_GIANT , 4*ArmyMdf);
		AddHeroCreatures('Faiz', CREATURE_STEEL_GOLEM , 25*ArmyMdf);
		AddHeroCreatures('Faiz', CREATURE_MASTER_GREMLIN , 40*ArmyMdf);
			sleep ( 1 );
		AddHeroCreatures('Astral', CREATURE_GENIE, 15*ArmyMdf);
		AddHeroCreatures('Astral', CREATURE_TITAN, 5*ArmyMdf);
		AddHeroCreatures('Astral', CREATURE_ARCH_MAGI, 20*ArmyMdf);
		AddHeroCreatures('Astral', CREATURE_GREMLIN, 100*ArmyMdf);
		AddHeroCreatures('Astral', CREATURE_IRON_GOLEM, 40*ArmyMdf);
			sleep ( 1 );
		AddHeroCreatures('Havez', CREATURE_TITAN , 3*ArmyMdf);
		AddHeroCreatures('Havez', CREATURE_MASTER_GREMLIN , 30*ArmyMdf);
		AddHeroCreatures('Havez', CREATURE_STEEL_GOLEM, 20*ArmyMdf);
		AddHeroCreatures('Havez', CREATURE_ARCH_MAGI, 8*ArmyMdf);
		AddHeroCreatures('Havez', CREATURE_IRON_GOLEM , 25*ArmyMdf);
		AddHeroCreatures('Havez', CREATURE_OBSIDIAN_GARGOYLE , 30*ArmyMdf);
		startThread(PlayerWin);
		print("Army has been added for the all enemy heroes");
		sleep(delay);
		StartDialogScene("/DialogScenes/Single/SL2/R3/DialogScene.xdb#xpointer(/DialogScene)");
		if diff > 1 then
			local exp = 0;
			local heroes = GetPlayerHeroes(1);
			for i, hero in heroes do
				exp = exp + GetHeroStat(hero, 0);
			end;
			for i, hero in mags do
				if GetHeroStat(hero, 0) < exp then
					ChangeHeroStat(hero, 0, 0.5 * (diff-1) * (exp - GetHeroStat(hero, 0)));
				end;
				for j=1,4 do
					ChangeHeroStat(hero, j, diff-1 + random(diff));
				end;
				startThread(teach_spell, hero, hard_spells, diff+2);
				if diff == 3 then
					startThread(teach_spell, hero, heroic_spells, 3);
					startThread(give_art, hero, artefacts, 5);
					SetHeroLootable(hero, nil);
				end;
			end;
		end;
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 ReachTown(HeroName,DestinationRegionName,DeployRegionName)
	print(HeroName," has been deployed and he is going to reach", DestinationRegionName);
	DeployReserveHero(HeroName,RegionToPoint(DeployRegionName));
	print("Waiting...");
	sleep(20);
	MoveHero(HeroName,RegionToPoint(DestinationRegionName));
end;

--function randomly adds or removes resources from player
function GiveMeMoney()
	print("Thread GiveMeMoney has been started");
	Trigger(NEW_DAY_TRIGGER,nil);
	if mod((GetDate(DAY)-1),7) == 0 then
		local result = 1 + random(6);
		if result == 4 or result == 5 then
			print("Zachot!");
			MessageBox("/Maps/SingleMissions/SL2/ResourcesPlus.txt");
				for i=1,Resources_plus.n do
					print("Resource type is ",Resources_plus[i][1],"Quantity(+) = ",Resources_plus[i][2]);
					SetPlayerResource(PLAYER_1,Resources_plus[i][1],GetPlayerResource(PLAYER_1,Resources_minus[i][1])+Resources_plus[i][2]);
					Trigger(NEW_DAY_TRIGGER,"GiveMeMoney");
				end;
		else
			if result == 6 then
				print("Nizachot");
				MessageBox("/Maps/SingleMissions/SL2/ResourcesMinus.txt");
				for i=1,Resources_minus.n do
					if GetPlayerResource(PLAYER_1,Resources_minus[i][1]) > Resources_minus[i][2] then
						print("Resource type is ",Resources_plus[i][1],"Quantity(-) = ",Resources_plus[i][2]);
						SetPlayerResource(PLAYER_1,Resources_minus[i][1],GetPlayerResource(PLAYER_1,Resources_minus[i][1])-Resources_minus[i][2]);
						Trigger(NEW_DAY_TRIGGER,"GiveMeMoney");
					else
						print("Resource type is ",Resources_plus[i][1],"Quantity(=) = ",GetPlayerResource(PLAYER_1,Resources_minus[i][1]));
						SetPlayerResource(PLAYER_1,Resources_minus[i][1],GetPlayerResource(PLAYER_1,Resources_minus[i][1]));
						Trigger(NEW_DAY_TRIGGER,"GiveMeMoney");
					end;
				end;
			else
				print("Week of nothing");
				Trigger(NEW_DAY_TRIGGER,"GiveMeMoney");
			end;
		end;
	end;
end;

--<====================== WIN ============================>
function PlayerWin()
	print("Thread PlayerWin has been started...");
	while 1 do
		sleep(10);
		if  IsHeroAlive("Faiz")     == nil and
			IsHeroAlive("Tan")     == nil and
			IsHeroAlive("Astral")== nil and
			IsHeroAlive("Havez")   == nil then
			SetObjectiveState("Defence", OBJECTIVE_COMPLETED);
			StartDialogScene("/DialogScenes/Single/SL2/R4/DialogScene.xdb#xpointer(/DialogScene)");
			sleep(10);
			Win(PLAYER_1);
			return
		end;
	end;
end;
--<========================END WIN ============================>

--<====================== LOOSE ============================>
function PlayerLoose()
	print("Thread PlayerLoose has been started...");
	while 1 do
		sleep(10);
		if IsHeroAlive("Effig") == nil then
			print("Hero Raven is dead. You loose.");
			Loose(PLAYER_1);
			return
		end;
	end;
end;
--<========================END LOOSE ============================>

Trigger(NEW_DAY_TRIGGER,"GiveMeMoney");
startThread(modificator);
startThread(TimeToStartInvasion);
--startThread(EnemyRaiders);
startThread(PlayerLoose);