bossfight = 0;
count = 0;
count_local = 0;
lich_count = 0;
catapult_dead = 0;
gate_dead = 0;
night = 0;
link_count = 0;

targets_id = {48, 50, 49, 47, 91, 46, 44, 45, 54, 52, 53, 51};
blind_id = {47, 48, 49, 50};
phantom_id = {36, 90, 34, 42, 38, 40, 30, 32};

has_shield = 0;
has_helmet = 0;
has_greaves = 0;
has_antimagic = 0;
is_siege = 0;

victim = "";
human = "";
catapult = "";
gate = "";

function Start()
	if bossfight == 1 then
		print("script battle!");
		EnableDynamicBattleMode(1);
		if GetGameVar("C5M5_"..human.."_shield") == "1" then
			has_shield = 1;
			print(human.." has dwarven shield!");
		end;
		if GetGameVar("C5M5_"..human.."_helmet") == "1" then
			has_helmet = 1;
			print(human.." has dwarven helmet!");
		end;
		if GetGameVar("C5M5_"..human.."_greaves") == "1" then
			has_greaves = 1;
			print(human.." has dwarven greaves!");
		end;
		if GetGameVar("C5M5_"..human.."_antimagic") == "1" then
			has_antimagic = 1;
			setATB(Kolya, 0.75);
			print(human.." knows antimagic!");
		end;
		if GetGameVar("C5M5_night") == "1" then
			night = 1;
		end;
		if GetAttackerWarMachine(WAR_MACHINE_CATAPULT) ~= nil and GetHeroName(GetAttackerHero()) == "Nikolay" then
			print("Kolya sieges human town!");
			is_siege = 1;
			catapult = GetAttackerWarMachine(WAR_MACHINE_CATAPULT);
			gate = GetDefenderBuilding(BUILDING_GATE);
			commandShot(catapult, gate, not nil);
		end;
	end;
end;

function DefenderHeroMove(hero)
	if AI_side == DEFENDER and bossfight == 1 then
		print("Kolya moving...");
		if GetUnitManaPoints(hero) < 100 and link_count == 0 then
			victim = GetTarget(human_side, targets_id);
			if victim ~= nil then
				print("Kolyan wants to gain mana from "..victim);
				startThread(cast, hero, 58, victim);
				link_count = 1;
				return not nil
				else return nil
			end;
		end;
		if GetUnitManaPoints(hero) > 50 then
			count = count + 1;
			local mana = GetUnitManaPoints(hero);
			elfs = GetCreatures(human_side);
			count_local = 0;
			if count == 1 and night == 1  then
				count = 0;
				night = 2;
				undead = GetCreatures(AI_side);
				for i, cr in undead do
					if GetCreatureType(cr) == 42 then
						startThread(cast, hero, 31, cr);
						count_local = count_local + 1;
					end;
				end;
				if count_local > 0 then
					return not nil
					else return nil;
				end;
			end;
			if has_antimagic == 0 then
				if count == 1 or count == 9 or count == 18  then
					UnitCastGlobalSpell(hero, 59);
					return not nil
				end;
				if count == 2 and has_helmet == 0 then
						for i, unit in elfs do
						if IsUnitInArray(unit, blind_id) then 
							count_local = count_local + 1;
							startThread(cast, hero, 19, unit);
						end;
					end;
					if count_local > 0 then
						return not nil
						else return nil;
					end;
				end;
				if count == 3 then
					victim = GetTarget(AI_side, phantom_id);
					if victim ~= nil then
						print("Kolyan wants to clone "..victim);
						startThread(cast, hero, 40, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 4 then
					victim = GetTarget(human_side, targets_id);
					if victim ~= nil then
						print("Kolyan wants to control "..victim);
						startThread(cast, hero, 20, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 5 and has_shield == 0 then
					for i, unit in elfs do
						if unit ~= victim then
							startThread(cast, hero, 18, unit);
							i = i + 1;
						end;
					end;
					return not nil
				end;
				if count == 6 then
					victim = GetTarget(human_side, targets_id);
					if victim ~= nil then
						UnitCastGlobalSpell(hero, 213);
						return not nil
						else
						for i, unit in elfs do
							startThread(cast, hero, 13, unit);
						end;
					end;
				end;
				if count == 7 and has_greaves == 0 then
					UnitCastGlobalSpell(hero, 212);
					return not nil
				end;
				if count == 8 then
					UnitCastGlobalSpell(hero, 221);
					return not nil
				end;
				if count == 9 then
					UnitCastGlobalSpell(hero, 235);
					return not nil
				end;
				if count == 10 then
					UnitCastGlobalSpell(hero, 43);
					return not nil
				end;
				if count == 11 or count == 13 then
					for i, unit in elfs do
						startThread(cast, hero, 13, unit);
					end;
				end;
				if count > 15 then
					UnitCastGlobalSpell(hero, 21);
					return not nil
				end;
			else 
				if count == 1 or count == 9 or count == 18  then
					UnitCastGlobalSpell(hero, 59);
					setATB(Kolya, 0.65);
					return not nil
				end;
				if count == 2 and has_helmet == 0 then
					for i, unit in elfs do
						if IsUnitInArray(unit, blind_id) then 
							count_local = count_local + 1;
							startThread(cast, hero, 19, unit);
						end;
					end;
					if count_local > 0 then
						setATB(Kolya, 0.5);
						return not nil
						else return nil;
					end;
				end;
				if count == 3 and has_shield == 0 then
					for i, unit in elfs do
						if unit ~= victim then
							startThread(cast, hero, 18, unit);
							i = i + 1;
						end;
					end;
					return not nil
				end;
				if count == 4 then
					victim = GetTarget(AI_side, phantom_id);
					if victim ~= nil then
						print("Kolyan wants to clone "..victim);
						startThread(cast, hero, 40, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 5 then
					UnitCastGlobalSpell(hero, 235);
					return not nil
				end;
				if count == 6 then
					UnitCastGlobalSpell(hero, 43);
					return not nil
				end;
				if count == 7 then
					UnitCastGlobalSpell(hero, 221);
					return not nil
				end;
			end;
		end;
	end;
	return nil;
end;

function AttackerHeroMove(hero)
	if AI_side == ATTACKER and bossfight == 1 then
		print("Kolya moving...");
		if GetUnitManaPoints(hero) < 100 and link_count == 0 then
			victim = GetTarget(human_side, targets_id);
			if victim ~= nil then
				print("Kolyan wants to gain mana from "..victim);
				startThread(cast, hero, 58, victim);
				link_count = 1;
				return not nil
				else return nil
			end;
		end;
		if GetUnitManaPoints(hero) > 50 then
			count = count + 1;
			local mana = GetUnitManaPoints(hero);
			elfs = GetCreatures(human_side);
			count_local = 0;
			if count == 1 and night == 1  then
				count = 0;
				night = 2;
				undead = GetCreatures(AI_side);
				for i, cr in undead do
					if GetCreatureType(cr) == 42 then
						startThread(cast, hero, 31, cr);
						count_local = count_local + 1;
					end;
				end;
				if count_local > 0 then
					return not nil
					else return nil;
				end;
			end;
			if has_antimagic == 0 then
				if count == 1 or count == 9 or count == 18  then
					UnitCastGlobalSpell(hero, 59);
					return not nil
				end;
				if count == 2 and has_helmet == 0 then
						for i, unit in elfs do
						if IsUnitInArray(unit, blind_id) then 
							count_local = count_local + 1;
							startThread(cast, hero, 19, unit);
						end;
					end;
					if count_local > 0 then
						return not nil
						else return nil;
					end;
				end;
				if count == 3 then
					victim = GetTarget(AI_side, phantom_id);
					if victim ~= nil then
						print("Kolyan wants to clone "..victim);
						startThread(cast, hero, 40, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 4 then
					victim = GetTarget(human_side, targets_id);
					if victim ~= nil then
						print("Kolyan wants to control "..victim);
						startThread(cast, hero, 20, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 5 and has_shield == 0 then
					for i, unit in elfs do
						if unit ~= victim then
							startThread(cast, hero, 18, unit);
							i = i + 1;
						end;
					end;
					return not nil
				end;
				if count == 6 then
					victim = GetTarget(human_side, targets_id);
					if victim ~= nil then
						UnitCastGlobalSpell(hero, 213);
						return not nil
						else
						for i, unit in elfs do
							startThread(cast, hero, 13, unit);
						end;
					end;
				end;
				if count == 7 and has_greaves == 0 then
					UnitCastGlobalSpell(hero, 212);
					return not nil
				end;
				if count == 8 then
					UnitCastGlobalSpell(hero, 221);
					return not nil
				end;
				if count == 9 then
					UnitCastGlobalSpell(hero, 235);
					return not nil
				end;
				if count == 10 then
					UnitCastGlobalSpell(hero, 43);
					return not nil
				end;
				if count == 11 or count == 13 then
					for i, unit in elfs do
						startThread(cast, hero, 13, unit);
					end;
				end;
				if count > 15 then
					UnitCastGlobalSpell(hero, 21);
					return not nil
				end;
			else 
				if count == 1 or count == 9 or count == 18  then
					UnitCastGlobalSpell(hero, 59);
					setATB(Kolya, 0.65);
					return not nil
				end;
				if count == 2 and has_helmet == 0 then
					for i, unit in elfs do
						if IsUnitInArray(unit, blind_id) then 
							count_local = count_local + 1;
							startThread(cast, hero, 19, unit);
						end;
					end;
					if count_local > 0 then
						setATB(Kolya, 0.5);
						return not nil
						else return nil;
					end;
				end;
				if count == 3 and has_shield == 0 then
					for i, unit in elfs do
						if unit ~= victim then
							startThread(cast, hero, 18, unit);
							i = i + 1;
						end;
					end;
					return not nil
				end;
				if count == 4 then
					victim = GetTarget(AI_side, phantom_id);
					if victim ~= nil then
						print("Kolyan wants to clone "..victim);
						startThread(cast, hero, 40, victim);
						return not nil
						else return nil
					end;
				end;
				if count == 5 then
					UnitCastGlobalSpell(hero, 235);
					return not nil
				end;
				if count == 6 then
					UnitCastGlobalSpell(hero, 43);
					return not nil
				end;
				if count == 7 then
					UnitCastGlobalSpell(hero, 221);
					return not nil
				end;
			end;
		end;
	end;
	return nil;
end;

function DefenderCreatureMove(unit)
	if GetCreatureType(unit) == 38 then
		lich_count = lich_count + 1;
		if lich_count == 1 and bossfight == 1 and AI_side == DEFENDER then
			UnitCastGlobalSpell(unit, 210);
			SetUnitManaPoints(unit, GetUnitMaxManaPoints(unit));
			return not nil
		end;
		if lich_count == 2 and bossfight == 1 and AI_side == DEFENDER then
			UnitCastGlobalSpell(unit, 215);
			SetUnitManaPoints(unit, GetUnitMaxManaPoints(unit));
			return not nil
		end;
		if lich_count == 3 and bossfight == 1 and AI_side == DEFENDER then
			local enemies = GetCreatures(human_side);
			if enemy ~= nil then
				for i, cr in enemies do
					startThread(cast, unit, 14, cr);
					i = i + 1;
				end;
			end;
			return not nil
		end;
	end;
end;

function AttackerCreatureMove(unit)
	if GetCreatureType(unit) == 38 then
		lich_count = lich_count + 1;
		if lich_count == 1 and bossfight == 1 and AI_side == ATTACKER then
			UnitCastGlobalSpell(unit, 210);
			SetUnitManaPoints(unit, GetUnitMaxManaPoints(unit));
			lich_count = lich_count + 1;
			return not nil
		end;
		if lich_count == 2 and bossfight == 1 and AI_side == ATTACKER then
			UnitCastGlobalSpell(unit, 215);
			SetUnitManaPoints(unit, GetUnitMaxManaPoints(unit));
			lich_count = lich_count + 1;
			return not nil
		end;
		if lich_count == 3 and bossfight == 1 and AI_side == ATTACKER then
			local enemies = GetCreatures(human_side);
			if enemy ~= nil then
				for i, cr in enemies do
					startThread(cast, unit, 14, cr);
					i = i + 1;
				end;
			end;
			return not nil
		end;
	end;
end;

function AttackerWarMachineDeath(unit)
	if unit == catapult then
		catapult_dead = 1;
		if gate_dead == 0 and is_siege == 1 then
			print("catapult was destroyed, Kolya will be very angry!");
		end;
	end;
end;

function DefenderBuildingDeath(unit)
	if unit == gate then
		gate_dead = 1;
	end;
end;

function IsUnitInArray(unit, array)
	for i, elem in array do
		if GetCreatureType(unit) == elem then
			return not nil;
		end;
	end;
	return nil;
end;

function cast(hero, spell, target)
	UnitCastAimedSpell(hero, spell, target);
	print("casting spell "..spell);
end;

function GetTarget(side, array)
	local units = GetCreatures(side);
	for i, id in array do
		for j, unit in units do
			if GetCreatureType(unit) == id then
				return unit;
			end;
		end;
	end;
	return nil;
end;

if GetAttackerHero() ~= nil and GetDefenderHero() ~= nil then
	if GetHeroName(GetAttackerHero()) == "Nikolay" then
		print("Kolyan is attacking");
		human_side = DEFENDER;
		AI_side = ATTACKER;
		bossfight = 1;
		Kolya = GetAttackerHero();
		human = GetHeroName(GetDefenderHero());
		SetUnitManaPoints(Kolya, 2*GetUnitMaxManaPoints(Kolya));
		else if GetHeroName(GetDefenderHero()) == "Nikolay" then
			print("Defend yourself, Kolyan!");
			human_side = ATTACKER;
			AI_side = DEFENDER;
			bossfight = 1;
			Kolya = GetDefenderHero();
			human = GetHeroName(GetAttackerHero());
			SetUnitManaPoints(Kolya, 2*GetUnitMaxManaPoints(Kolya));
		end;
	end;
end;