__threads = {};
function startThreadOnce( func, p1, p2, p3 )
	if __threads[ func ] then
		return
	end;
	newfunc = function()
		%func( %p1, %p2, %p3);
		__threads[ %func ] = nil;
	end;
	__threads[ func ] = newfunc;
	startThread( newfunc );
end;

SetGameVar("temp.C1M3_Tradeville",0);
hero_visiting = 0;
OUR_HERO_NAME = "Isabell";
ENEMY_HERO_NAME = "Calid";
townx, towny = 32, 28;
n = 0;
gold_region = 0;
gold2_region = 0;
stone_region = 0;
cristall_region = 0;
all_regions = 0;
upg = 0;
IsTutorial = 1;--IsTutorialEnabled();
_t7 = 0;
met = 0;
dialog3 = 0;
count = 0;
current_hero = nil;

if GetDifficulty() == DIFFICULTY_EASY then
	diff = 0;
	print ("easy");
	AddObjectCreatures(OUR_HERO_NAME, 4, 15);
	AddObjectCreatures(OUR_HERO_NAME,6, 8);
end;

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

if GetDifficulty() == DIFFICULTY_HARD then
	diff = 2;
	print ("hard");
	TeachHeroSpell(ENEMY_HERO_NAME, 1);
	TeachHeroSpell(ENEMY_HERO_NAME, 2);
	TeachHeroSpell(ENEMY_HERO_NAME, 237);
	ChangeHeroStat(ENEMY_HERO_NAME, 0, 40000)
	ChangeHeroStat(ENEMY_HERO_NAME, 6, 1);
	for i = 1, 11 do
		for j = 15, 28 do
			if GetObjectCreatures('inferno'..i, j) > 0 then
				count = GetObjectCreatures('inferno'..i, j) / 3 - mod(GetObjectCreatures('inferno'..i, j) / 3);
				AddObjectCreatures('inferno'..i, j, count);
			end;
		end;
	end;
end;

if GetDifficulty() == DIFFICULTY_HEROIC then
	diff = 3;
	print ("heroic");
	TeachHeroSpell(ENEMY_HERO_NAME, 1);
	TeachHeroSpell(ENEMY_HERO_NAME, 2);
	TeachHeroSpell(ENEMY_HERO_NAME, 3);
	TeachHeroSpell(ENEMY_HERO_NAME, 5);
	TeachHeroSpell(ENEMY_HERO_NAME, 236);
	TeachHeroSpell(ENEMY_HERO_NAME, 237);
	GiveHeroWarMachine(ENEMY_HERO_NAME, 1);
	GiveHeroWarMachine(ENEMY_HERO_NAME, 4);
	ChangeHeroStat(ENEMY_HERO_NAME, 0, 60000)
	for i = 1, 4 do
		ChangeHeroStat(ENEMY_HERO_NAME, i, 3);
	end;
	ChangeHeroStat(ENEMY_HERO_NAME, 5, 1);
	ChangeHeroStat(ENEMY_HERO_NAME, 6, 2);
	ChangeHeroStat(ENEMY_HERO_NAME, 8, 10 * GetHeroStat(ENEMY_HERO_NAME, 4));
	AddHeroCreatures(ENEMY_HERO_NAME, 28, 1);
	for i = 1, 11 do
		for j = 15, 28 do
			if GetObjectCreatures('inferno'..i, j) > 0 then
				AddObjectCreatures('inferno'..i, j, GetObjectCreatures('inferno'..i, j));
			end;
		end;
	end;
end;

function vspomozhite()
	SetPlayerResource(PLAYER_1,WOOD,10000);
	SetPlayerResource(PLAYER_1,ORE,10000);
	SetPlayerResource(PLAYER_1,GEM,10000);
	SetPlayerResource(PLAYER_1,CRYSTAL,10000);
	SetPlayerResource(PLAYER_1,MERCURY,10000);
	SetPlayerResource(PLAYER_1,SULFUR,10000);
	SetPlayerResource(PLAYER_1,GOLD,10000);
end;

function delete_inferno()
	for i = 1, 11 do
		RemoveObject( 'inferno'..i );
	end;
end;

function len( x, y )
local l = sqrt( x * x + y * y );
	return l;
end;

function Objective1()
local n;
	while 1 do
		n = 1;
		sleep( 2 );
		for i = 1, 11 do
			if ( Exists( 'inferno'..i ) ) then
				n = 0;
				break;
			end;
		end;
		if ( n == 1 ) then
			break;
		end;
	end;
	
	StartDialogScene("/DialogScenes/C1/M3/R2/DialogScene.xdb#xpointer(/DialogScene)");
	sleep( 3 );
	SetObjectiveState( 'prim1', OBJECTIVE_COMPLETED );
	GiveExp( 'Isabell', 6000 );
end;

function CalcHavenArmy( heroname )
	costs = { 20, 30, 50, 80, 90, 130, 260, 360, 550, 800, 1250, 1550, 3200, 4200 };
	total = 0;
	for i = 1, 14 do
		total = total + GetHeroCreatures( heroname, i ) * costs[i];
	end;
	return total;
end;

function SetInfernoArmy( heroname, strength )
	local costs = { 25, 45, 40, 60, 110, 160, 240, 350, 480, 666, 1550, 1850, 3666, 4666 };
	local factor = {};
	factor[CREATURE_BALOR] = 0.5 + 0.1 * diff;
	factor[CREATURE_SUCCUBUS] = 3.2 + 0.3 * diff;
	factor[CREATURE_HELL_HOUND] = 5.8 + 0.5 * diff;
	factor[CREATURE_DEMON] = 7.5 + diff;
	factor[CREATURE_IMP] = 7.0 + diff;
	local total = 0;
	local coeff = 0;
	local crap = __difficulty - 1;
	if crap < 0 then
		crap = 0;
	end;
	local minfact = 8 + crap * 4;
	for i = 1, 14 do
		total = total + costs[i] * (factor[i + 15] or 0);
	end;
	if total * minfact >= strength then
		coeff = minfact;
	else
		coeff = strength / total;
	end;
	print('strength = ', strength, '; coeff = ', coeff);
	for i = 1, 14 do
		if factor[i + 15] then
			AddHeroCreatures( heroname, 15 + i, factor[i + 15] * coeff );
		end;
	end;
end;

strcoeff = { 0.25, 0.5, 1.0, 1.25 };
function Objective3()
	if GetObjectiveState("prim3") == OBJECTIVE_ACTIVE then
		SetObjectPosition(ENEMY_HERO_NAME, 118, 92, 0);
		sleep( 1 );
		player_army_strength = CalcHavenArmy( 'Isabell' );
		print( "player str = ", player_army_strength );
		player_army_strength = player_army_strength * strcoeff[__difficulty + 1];
		SetInfernoArmy( ENEMY_HERO_NAME, player_army_strength );
		startThread( EngageHero, 'Isabell' );
		startThread( MeetEnemyHero );
	elseif GetObjectiveState("prim3") == OBJECTIVE_COMPLETED then
		StartDialogScene("/DialogScenes/C1/M3/D1/DialogScene.xdb#xpointer(/DialogScene)", "dialog3end");
		--sleep(5);
		--Win();
	end;
end;

function dialog3end()
	dialog3 = 1;
end;

function treasure_captured()
	TutorialMessageBox("c1_m3_t2");
	if Exists("gold") then
		Trigger(OBJECT_TOUCH_TRIGGER,"gold",nil);
	end;
	if Exists("gold2") then
		Trigger(OBJECT_TOUCH_TRIGGER,"gold2",nil);
	end;
	if Exists("cristall") then
		Trigger(OBJECT_TOUCH_TRIGGER,"cristall",nil);
	end;
end;

function treasure_found()
	TutorialMessageBox("c1_m3_t1");
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold",nil);
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold2",nil);
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"cristall",nil);
end;

function HeroBuiltWarmashine()
	while 1 do
		sleep( 5 );
		if ( HasHeroWarMachine(OUR_HERO_NAME, 1) or HasHeroWarMachine(OUR_HERO_NAME, 3) or HasHeroWarMachine(OUR_HERO_NAME, 4) ) then
			print("Player has got war mashine");
			if IsTutorial == 1 then
				WaitForTutorialMessageBox();
				TutorialMessageBox("c1_m3_t9_2");
			end;
			break;
		end;
	end;
end;

function MeetEnemyHero()
	while 1 do
		sleep(2);
		OUR_HERO_X,OUR_HERO_Y = GetObjectPos(OUR_HERO_NAME);
		ENEMY_HERO_X,ENEMY_HERO_Y = GetObjectPos(ENEMY_HERO_NAME);
		--	if IsObjectVisible( PLAYER_1 ,ENEMY_HERO_NAME ) == true then
		if len(OUR_HERO_X - ENEMY_HERO_X,OUR_HERO_Y - ENEMY_HERO_Y) < 7 then
			--print("Player prepares to wage enemy Hero!!!");
			if ( IsTutorial == 1 ) then
				WaitForTutorialMessageBox();
				TutorialMessageBox("c1_m3_t10");
			end;
			--Trigger( REGION_ENTER_AND_STOP_TRIGGER, "enemy", nil );
			--Trigger( REGION_ENTER_WITHOUT_STOP_TRIGGER, "enemy", nil );
			--RemoveHeroCreatures(ENEMY_HERO_NAME,CREATURE_ARCHDEVIL,10000);
			--RemoveHeroCreatures(ENEMY_HERO_NAME,CREATURE_SUCCUBUS,10000);
			--RemoveHeroCreatures(ENEMY_HERO_NAME,CREATURE_HELL_HOUND,10000);
			--AddHeroCreatures(ENEMY_HERO_NAME,CREATURE_SUCCUBUS,5);
			--AddHeroCreatures(ENEMY_HERO_NAME,CREATURE_HELL_HOUND,18);
			break;
		end;
	end;
end;

function EngageHero( heroname )
	while IsHeroAlive( ENEMY_HERO_NAME ) do
		while GetCurrentPlayer() ~= PLAYER_2 do
			sleep( 1 );
		end;
		print('attack ', heroname);
		MoveHero( ENEMY_HERO_NAME, GetObjectPosition( heroname ) );
		while GetCurrentPlayer() ~= PLAYER_1 do
			sleep( 1 );
		end;
	end;
end;

function battle(hero)
	current_hero = hero;
	MessageBox('/Maps/Scenario/C1M3/Battle1.txt', "battle1");
end;

function battle1()
	if diff > 1 then
		StartCombat(current_hero, nil, 5, CREATURE_SKELETON, 65 + diff * 15, CREATURE_SKELETON_ARCHER, 40 + diff * 10, 39, 2 + diff, CREATURE_ZOMBIE, 25  + diff * 8,CREATURE_WALKING_DEAD, 35  + diff * 10, nil,'artefact');
		else
		StartCombat(current_hero, nil, 4, CREATURE_SKELETON, 40 + diff * 15, CREATURE_SKELETON_ARCHER, 25 + diff * 10, CREATURE_ZOMBIE, 15  + diff * 5,CREATURE_WALKING_DEAD, 22  + diff * 8, nil,'artefact');
	end;
end;

function artefact(hero, result)
	if result and IsHeroAlive(hero) then
		MessageBox('/Maps/Scenario/C1M3/Battle2.txt');
		GiveArtefact(hero, ARTIFACT_RING_OF_HASTE );
		Trigger( REGION_ENTER_AND_STOP_TRIGGER, "surprize", nil);
	end;
end;

function BuildingUpgraded()
	while 1 do
		sleep(10);
		if (GetTownBuildingLevel("Bobruisk",TOWN_BUILDING_DWELLING_1) > 1 or
			GetTownBuildingLevel("Bobruisk",TOWN_BUILDING_DWELLING_2) > 1 or
			GetTownBuildingLevel("Bobruisk",TOWN_BUILDING_DWELLING_3) > 1) then
			print("Player makes upgrade in his Town!!!");
			WaitForTutorialMessageBox();
			TutorialMessageBox("c1_m3_t6");
			upg = 1;
			break;
		end;
	end;
end;

function LostHero( heroname )
	if heroname == 'Isabell' then
		SetObjectiveState( "prim4", OBJECTIVE_FAILED );
	elseif ( IsTutorial == 1 ) then
		TutorialMessageBox( 'c1_m2_t7' );
	end;
end;

function Objective2Bonus()
	if GetObjectiveState( 'prim2' ) == OBJECTIVE_COMPLETED then
		GiveExp( 'Isabell', 6000 );
	end;
end;

function EnableTutorial()
	SetGameVar( "temp.tutorial", 1 );
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold","treasure_found");
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold2","treasure_found");
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"cristall","treasure_found");
	--Trigger( REGION_ENTER_WITHOUT_STOP_TRIGGER, "enemy", nil );
	--Trigger( REGION_ENTER_AND_STOP_TRIGGER, "enemy", "MeetEnemyHero" );
	if Exists("gold") == true then
		Trigger(OBJECT_TOUCH_TRIGGER, "gold", "treasure_captured" );
	end;
	if Exists("gold2") == true then
		Trigger(OBJECT_TOUCH_TRIGGER, "gold2", "treasure_captured" );
	end;
	if Exists("cristall") == true then
		Trigger(OBJECT_TOUCH_TRIGGER, "cristall", "treasure_captured" );
	end;
end;

function DisableTutorial()
	SetGameVar( "temp.tutorial", 0 );
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold", nil );
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"gold2", nil );
	Trigger(REGION_ENTER_AND_STOP_TRIGGER,"cristall", nil );
	--Trigger( REGION_ENTER_AND_STOP_TRIGGER, "enemy", nil );
	--Trigger( REGION_ENTER_WITHOUT_STOP_TRIGGER, "enemy", "MeetEnemyHero" );
	if Exists("gold") then
		Trigger(OBJECT_TOUCH_TRIGGER, "gold", nil );
	end;
	if Exists("gold2") then
		Trigger(OBJECT_TOUCH_TRIGGER, "gold2", nil );
	end;
	if Exists("cristall") then
		Trigger(OBJECT_TOUCH_TRIGGER, "cristall", nil );
	end;
end;

COMBAT = 9999;
THREAD = 9998;

TutorialTriggers = {
	{ "c1_m3_t1", REGION_ENTER_AND_STOP_TRIGGER, "gold", "treasure_found", 0 },
	{ "c1_m3_t1", REGION_ENTER_AND_STOP_TRIGGER, "gold2", "treasure_found", 0 },
	{ "c1_m3_t1", REGION_ENTER_AND_STOP_TRIGGER, "cristall", "treasure_found", 0 },
	{ "c1_m3_t2", OBJECT_TOUCH_TRIGGER, "gold", "treasure_captured", 0 },
	{ "c1_m3_t2", OBJECT_TOUCH_TRIGGER, "gold2", "treasure_captured", 0 },
	{ "c1_m3_t2", OBJECT_TOUCH_TRIGGER, "cristall", "treasure_captured", 0 },
	
	{ "c1_m3_t6", THREAD, 0, BuildingUpgraded, 0 },
	{ "c1_m3_t9_2", THREAD, 0, HeroBuiltWarmashine, 0 },
};

function CheckTutorialTriggers()
	while 1 do
		sleep( 5 );
		for i, TutorialItem in TutorialTriggers do
			if IsTutorialItemEnabled( TutorialItem[1]  ) then
				if (TutorialItem[5] == 0) then
					if TutorialItem[2] == COMBAT then
						SetGameVar( "temp." .. TutorialItem[1], 1 );
					elseif TutorialItem[2] == THREAD then
						startThreadOnce( TutorialItem[4] );
					else
						if ( ( TutorialItem[2] == OBJECT_TOUCH_TRIGGER ) and Exists( TutorialItem[3]) ) or ( TutorialItem[2] ~= OBJECT_TOUCH_TRIGGER ) then
							Trigger( TutorialItem[2], TutorialItem[3], TutorialItem[4] );
						end;
					end;
					TutorialItem[5] = 1;
				end;
			else
				if (TutorialItem[5] == 1) then
					if TutorialItem[2] == COMBAT then
						SetGameVar( "temp." .. TutorialItem[1], 0 );
					elseif TutorialItem[2] ~= THREAD then
						if ( ( TutorialItem[2] == OBJECT_TOUCH_TRIGGER ) and Exists( TutorialItem[3]) ) or ( TutorialItem[2] ~= OBJECT_TOUCH_TRIGGER ) then
							Trigger( TutorialItem[2], TutorialItem[3], nil );
						end;
					end;
					TutorialItem[5] = 0;
				end;
			end;
		end;
	end;
end;

function CheckTutorial()
	while 1 do
		sleep( 5 );
		if IsTutorialEnabled() then
			if (IsTutorial == 0) then
				EnableTutorial();
				IsTutorial = 1;
			end;
		else
			if (IsTutorial == 1) then
				DisableTutorial();
				IsTutorial = 0;
			end;
		end;
	end;
end;

function ToWin()
	while 1 do
		sleep( 3 );
		if ( GetObjectiveState( 'prim1' ) == OBJECTIVE_COMPLETED ) and ( GetObjectiveState( 'prim2' ) == OBJECTIVE_COMPLETED ) and 
		( GetObjectiveState( 'prim3' ) == OBJECTIVE_COMPLETED ) and (dialog3 == 1) then
			if HasArtefact("Isabell", 22) then
				SetGameVar("C1M3_Ring", 1);
				print("saving ring of speed...");
				else SetGameVar("C1M3_Ring", 0);
			end;
			sleep( 3 );
			Win();
		end;
	end;
end;

function CheckHeroInTown()
heroes = {};
	while 1 do
		sleep( 1 );
		heroes = GetPlayerHeroes( PLAYER_1 );
		for i, hero in heroes do
			if GetTownHero( 'Bobruisk') ~= hero then
				x, y = GetObjectPos( hero );
				--print( i, hero );

				if ( x ~= townx ) or ( y ~= towny ) then
					if hero_visiting == 1 then
						SetGameVar( 'temp.hero_visiting', 0 );
						hero_visiting = 0;
					end;
				else
					if hero_visiting == 0 then
						SetGameVar( 'temp.hero_visiting', 1 );
						hero_visiting = 1;
						break;
					end;
				end;
			end;
		end;
	end;
end;

function EasyMode()
	if diff > 1 then
		return
	end;
	CreateMonster( "monster1", CREATURE_ARCHER, 35, 58, 46, 0, 0, 0 );
	CreateMonster( "monster2", CREATURE_ARCHER, 33, 77, 26, 0, 0, 0 );
	CreateMonster( "monster3", CREATURE_SWORDSMAN, 24, 29, 63, 0, 0, 0 );
	CreateMonster( "monster4", CREATURE_FOOTMAN, 27, 73, 36, 0, 0, 0 );
	
	CreateMonster( "monster5", CREATURE_GRIFFIN, 14, 74, 65, 0, 0, 0 );
	CreateMonster( "monster6", CREATURE_CAVALIER, 7, 85, 70, 0, 0, 0 );
	CreateMonster( "monster7", CREATURE_GRIFFIN, 15, 42, 82, 0, 0, 0 );
end;

------------------------------
EasyMode();

EnableHeroAI( ENEMY_HERO_NAME, nil );
StartDialogScene("/DialogScenes/C1/M3/R1/DialogScene.xdb#xpointer(/DialogScene)");
sleep(1);
SetObjectiveState( 'prim1', OBJECTIVE_ACTIVE );

startThread(Objective1);
startThread(ToWin);
startThread( CheckHeroInTown );

Trigger( PLAYER_REMOVE_HERO_TRIGGER, PLAYER_1, 'LostHero' );
Trigger( REGION_ENTER_AND_STOP_TRIGGER, "surprize", "battle" );
Trigger( OBJECTIVE_STATE_CHANGE_TRIGGER, 'prim3', 'Objective3' );
--Trigger( OBJECTIVE_STATE_CHANGE_TRIGGER, 'prim1', 'Objective1' );
Trigger( OBJECTIVE_STATE_CHANGE_TRIGGER, 'prim2', 'Objective2Bonus' );

-- tutorial related --
TutorialActivateHint( "hero_meet" );
TutorialActivateHint( "c1_m3_levelup" );
startThread( CheckTutorialTriggers );
SetGameVar( "temp.tutorial", 1 );

if ( IsTutorial == 1 ) then
	--EnableTutorial();
	--startThreadOnce(BuildingUpgraded);
	--startThreadOnce(HeroBuiltWarmashine);
else
	--Trigger( REGION_ENTER_WITHOUT_STOP_TRIGGER, "enemy", "MeetEnemyHero" );
end;
--startThread( CheckTutorial );