-------------------------------------------------------------------------
-- Name: LUA Script for map Demonic Defense (HOMM5:TOE)                --                                    
--                                                                     --
-- By: mctronic (mctronic@hotmail.com)                                 --
--                                                                     --
-- Date: May 2017                                                    --
--                                                                     --
-------------------------------------------------------------------------
-----------------------------------------------------
--                                                 --
--                    CONSTANTS                    --
--                                                 --
-----------------------------------------------------
MASTERY_NONE = 0;
MASTERY_BASIC = 1;
MASTERY_ADVANCED = 2;
MASTERY_EXPERT = 3;
MASTERY_EXTRA_EXPERT = 4;
LVL1GROWTH = 36;
LVL2GROWTH = 24;
LVL3GROWTH = 18;
LVL4GROWTH = 10;
LVL5GROWTH = 6;
LVL6GROWTH = 4;
LVL7GROWTH = 2;
START_RATIO = 0.25;
SABOTAGE_RATIO = 0.45;

-----------------------------------------------------
--                                                 --
--                GLOBAL VARIABLES                 --
--                                                 --
-----------------------------------------------------
AllBorderGuardKeys = 0;
BonusMarlettoTower1AlreadyAdded = 0;
BonusMarlettoTower2AlreadyAdded = 0;
BonusMarlettoTower3AlreadyAdded = 0;
BonusMarlettoTower4AlreadyAdded = 0;
BonusMarlettoTower5AlreadyAdded = 0;
BonusMarlettoTower6AlreadyAdded = 0;
BonusMercenaryCamp1AlreadyAdded = 0;
BonusMercenaryCamp2AlreadyAdded = 0;
BonusMercenaryCamp3AlreadyAdded = 0;
BonusMercenaryCamp4AlreadyAdded = 0;
BonusMercenaryCamp5AlreadyAdded = 0;
BonusPlanetarium1AlreadyAdded = 0;
BonusPlanetarium2AlreadyAdded = 0;
BonusPlanetarium3AlreadyAdded = 0;
BonusPlanetarium4AlreadyAdded = 0;
BonusPlanetarium5AlreadyAdded = 0;
BonusPlanetarium6AlreadyAdded = 0;
BonusRevelation1AlreadyAdded = 0;
BonusRevelation2AlreadyAdded = 0;
BonusRevelation3AlreadyAdded = 0;
BonusRevelation4AlreadyAdded = 0;
BonusRevelation5AlreadyAdded = 0;
BuildingToGateSpells = "NoBuildingToGateSpells";
BuildingToGateArtifacts = "NoBuildingToGateArtifacts";
BuildingToGateStats = "NoBuildingtoGateStats";
Difficulty = 0.5;
GrailBuilt = 0;
HeroNameExchangeStats = "NoHeroNameExchangeStats";
Lvl1andLvl2SpellArray = {1, 2, 3, 4, 11, 12, 13, 14, 23, 24, 25, 26, 38, 39, 42, 237, 277, 280, 282};
Lvl3LightSpellArray = {28, 29};
Lvl4LightSpellArray = {31, 32, 281};
Lvl5LightSpellArray = {35,48};
Lvl3DarkSpellArray = {15, 17};
Lvl4DarkSpellArray = {18, 19};
Lvl5DarkSpellArray = {20, 21, 278};   
Lvl3DestructiveSpellArray = {5, 6, 236};
Lvl4DestructiveSpellArray = {7, 8};
Lvl5DestructiveSpellArray = {9, 10, 279};
Lvl3SummoningSpellArray = {40, 41, 284};
Lvl4SummoningSpellArray = {43, 283};
Lvl5SummoningSpellArray = {34, 235};
Lvl1Handicap = 0;
Lvl2Handicap = 0;
Lvl3Handicap = 0;
Lvl4Handicap = 4;
Lvl5Handicap = 4;
Lvl6Handicap = 8;
Lvl7Handicap = 8;
MarlettoTower1Visited = 0;
MarlettoTower2Visited = 0;
MarlettoTower3Visited = 0;
MarlettoTower4Visited = 0;
MarlettoTower5Visited = 0;
MarlettoTower6Visited = 0;
MercenaryCamp1Visited = 0;
MercenaryCamp2Visited = 0;
MercenaryCamp3Visited = 0;
MercenaryCamp4Visited = 0;
MercenaryCamp5Visited = 0;
Objective4Active = 0;
Planetarium1Visited = 0;
Planetarium2Visited = 0;
Planetarium3Visited = 0;
Planetarium4Visited = 0;
Planetarium5Visited = 0;
Planetarium6Visited = 0;
Revelation1Visited = 0;
Revelation2Visited = 0;
Revelation3Visited = 0;
Revelation4Visited = 0;
Revelation5Visited = 0;
TearOfAshaObjectiveActive = 0;
TownToSabotage = "NoTownToSabotage";

-----------------------------------------------------
--                                                 --
--                   FUNCTIONS                     --
--                                                 --
-----------------------------------------------------
----------------------------------------------------
-- Primary Stats Exchange between Deleb 
-- and Marder.
----------------------------------------------------
function ExchangeHeroStats()	

	StatAttack = 0;
	StatDefence = 0;
	StatSpellPower = 0;
	StatKnowledge = 0;
	ResourceWood = GetPlayerResource(PLAYER_1,WOOD);
	ResourceOre = GetPlayerResource(PLAYER_1,ORE);
	ResourceMercury = GetPlayerResource(PLAYER_1,MERCURY);
	ResourceSulfur = GetPlayerResource(PLAYER_1,SULFUR);
	ResourceCrystal = GetPlayerResource(PLAYER_1,CRYSTAL);
	ResourceGem = GetPlayerResource(PLAYER_1,GEM);
	ResourceGold = GetPlayerResource(PLAYER_1,GOLD); 

	print("Entering ExchangeHeroStats function...");
	if ResourceWood > 9 and ResourceOre > 9 and ResourceMercury > 4 and ResourceSulfur > 4 and ResourceCrystal > 4 and ResourceGem > 4 and ResourceGold > 4999 then
		if MercenaryCamp1Visited == 1 and BonusMercenaryCamp1AlreadyAdded == 0 then
			StatAttack = StatAttack + 1;
			BonusMercenaryCamp1AlreadyAdded = 1;
		end;
		if MercenaryCamp2Visited == 1 and BonusMercenaryCamp2AlreadyAdded == 0 then
			StatAttack = StatAttack + 1;
			BonusMercenaryCamp2AlreadyAdded = 1;
		end;
		if MercenaryCamp3Visited == 1 and BonusMercenaryCamp3AlreadyAdded == 0 then
			StatAttack = StatAttack + 1;
			BonusMercenaryCamp3AlreadyAdded = 1;
		end;
		if MercenaryCamp4Visited == 1 and BonusMercenaryCamp4AlreadyAdded == 0 then
			StatAttack = StatAttack + 1;
			BonusMercenaryCamp4AlreadyAdded = 1;
		end;
		if MercenaryCamp5Visited == 1 and BonusMercenaryCamp5AlreadyAdded == 0 then
			StatAttack = StatAttack + 1;
			BonusMercenaryCamp5AlreadyAdded = 1;
		end;
		if MarlettoTower1Visited == 1 and BonusMarlettoTower1AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower1AlreadyAdded = 1;
		end;
		if MarlettoTower2Visited == 1 and BonusMarlettoTower2AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower2AlreadyAdded = 1;
		end;
		if MarlettoTower3Visited == 1 and BonusMarlettoTower3AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower3AlreadyAdded = 1;
		end;
		if MarlettoTower4Visited == 1 and BonusMarlettoTower4AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower4AlreadyAdded = 1;
		end;
		if MarlettoTower5Visited == 1 and BonusMarlettoTower5AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower5AlreadyAdded = 1;
		end;
		if MarlettoTower6Visited == 1 and BonusMarlettoTower6AlreadyAdded == 0 then
			StatDefence = StatDefence + 1;
			BonusMarlettoTower6AlreadyAdded = 1;
		end; 
		if Planetarium1Visited == 1 and BonusPlanetarium1AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium1AlreadyAdded = 1;
		end;
		if Planetarium2Visited == 1 and BonusPlanetarium2AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium2AlreadyAdded = 1;
		end;
		if Planetarium3Visited == 1 and BonusPlanetarium3AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium3AlreadyAdded = 1;
		end;
		if Planetarium4Visited == 1 and BonusPlanetarium4AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium4AlreadyAdded = 1;
		end;
		if Planetarium5Visited == 1 and BonusPlanetarium5AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium5AlreadyAdded = 1;
		end;
		if Planetarium6Visited == 1 and BonusPlanetarium6AlreadyAdded == 0 then
			StatSpellPower = StatSpellPower + 1;
			BonusPlanetarium6AlreadyAdded = 1;
		end;
		if Revelation1Visited == 1 and BonusRevelation1AlreadyAdded == 0 then
			StatKnowledge = StatKnowledge + 1;
			BonusRevelation1AlreadyAdded = 1;
		end;
		if Revelation2Visited == 1 and BonusRevelation2AlreadyAdded == 0 then
			StatKnowledge = StatKnowledge + 1;
			BonusRevelation2AlreadyAdded = 1;
		end;
		if Revelation3Visited == 1 and BonusRevelation3AlreadyAdded == 0 then
			StatKnowledge = StatKnowledge + 1;
			BonusRevelation3AlreadyAdded = 1;
		end;
		if Revelation4Visited == 1 and BonusRevelation4AlreadyAdded == 0 then
			StatKnowledge = StatKnowledge + 1;
			BonusRevelation4AlreadyAdded = 1;
		end;      
		if Revelation5Visited == 1 and BonusRevelation5AlreadyAdded == 0 then
			StatKnowledge = StatKnowledge + 1;
			BonusRevelation5AlreadyAdded = 1;
		end;      
		if StatAttack == 0 and StatDefence == 0 and StatSpellPower == 0 and StatKnowledge == 0 then
			MessageBox("Maps/SingleMissions/Demonic Defense/NoStatsGated.txt");
		else  
			ChangeHeroStat(HeroNameExchangeStats, STAT_ATTACK, StatAttack);
			ChangeHeroStat(HeroNameExchangeStats, STAT_DEFENCE, StatDefence);
			ChangeHeroStat(HeroNameExchangeStats, STAT_SPELL_POWER, StatSpellPower);
			ChangeHeroStat(HeroNameExchangeStats, STAT_KNOWLEDGE, StatKnowledge);
			print("atk: ",StatAttack," def: ",StatDefence," spell power: ",StatSpellPower," knowledge: ",StatKnowledge," to ",HeroNameExchangeStats);
			ResourceWood = ResourceWood - 10;
			ResourceOre = ResourceOre - 10;
			ResourceMercury = ResourceMercury - 5;
			ResourceSulfur = ResourceSulfur - 5;
			ResourceCrystal = ResourceCrystal - 5;
			ResourceGem = ResourceGem - 5;
			ResourceGold = ResourceGold - 5000;      
			SetPlayerResources(PLAYER_1, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold);
			x, y, z = GetObjectPosition(BuildingToGateStats);
			PlayVisualEffect("/Effects/_(Effect)/Characters/Gating.xdb#xpointer(/Effect)", "", "", x, y, z, 0, 0);
			Play2DSound("/Sounds/_(Sound)/Spells/TeleportStart.xdb#xpointer(/Sound)");
			sleep(15);
			MessageBox("Maps/SingleMissions/Demonic Defense/StatsGated.txt");
		end;
	else 
		MessageBox("Maps/SingleMissions/Demonic Defense/NotEnoughResources.txt");
	end;      
end;

----------------------------------------------------
-- Add Experience, replenishes mana and adds spells 
-- depending of Skill Mastery to an enemy hero. 
----------------------------------------------------
function ChangeStatsHero(HeroName, Exp)
	
	HeroLevel = GetHeroLevel(HeroName);
	i = 0;

	print("Entering ChangeStatsHero function...");	
	if HeroLevel < 30 then
		ChangeHeroStat(HeroName, STAT_EXPERIENCE, Exp);  
		print(HeroName," gains ", Exp," experience."); 
	end; 
	ChangeHeroStat(HeroName, STAT_MANA_POINTS, 999);
	sleep(1);
	if HeroLevel >= 7 then
		i = 1;
		while i < length(Lvl1andLvl2SpellArray) do                                  
			Spell = Lvl1andLvl2SpellArray[i];      
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);
			end;
			i = i + 1;
		end; 
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_LIGHT_MAGIC) >= MASTERY_BASIC and HeroLevel >= 12 then
		while i < length(Lvl3LightSpellArray) do
			Spell = Lvl3LightSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);  
				print(HeroName," learned the following spell: ", Spell);         
			end;
			i = i + 1;  
		end;
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_LIGHT_MAGIC) >= MASTERY_ADVANCED and HeroLevel >= 17 then
		while i < length(Lvl4LightSpellArray) do
			Spell = Lvl4LightSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);    
				print(HeroName," learned the following spell: ", Spell);                 
			end;        
			i = i + 1; 
		end;         
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_LIGHT_MAGIC) >= MASTERY_EXPERT and HeroLevel >= 22 then
		while i < length(Lvl5LightSpellArray) do
			Spell = Lvl5LightSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);  
				print(HeroName," learned the following spell: ", Spell);                   
			end;  
			i = i + 1;  
		end;
	end; 
	if GetHeroSkillMastery(HeroName,SKILL_DARK_MAGIC) >= MASTERY_BASIC and HeroLevel >= 12 then
		while i < length(Lvl3DarkSpellArray) do
			Spell = Lvl3DarkSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);     
				print(HeroName," learned the following spell: ", Spell);               
			end;
			i = i + 1;  
		end;
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_DARK_MAGIC) >= MASTERY_ADVANCED and HeroLevel >= 17 then
		while i < length(Lvl4DarkSpellArray) do
			Spell = Lvl4DarkSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell); 
				print(HeroName," learned the following spell: ", Spell);                    
			end;        
			i = i + 1; 
		end;         
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_DARK_MAGIC) >= MASTERY_EXPERT and HeroLevel >= 22 then
		while i < length(Lvl5DarkSpellArray) do
			Spell = Lvl5DarkSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);  
				print(HeroName," learned the following spell: ", Spell);                   
			end;  
			i = i + 1;  
		end;
	end; 
	if GetHeroSkillMastery(HeroName,SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_BASIC and HeroLevel >= 12 then
		while i < length(Lvl3DestructiveSpellArray) do
			Spell = Lvl3DestructiveSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);  
				print(HeroName," learned the following spell: ", Spell);                  
			end;
			i = i + 1;  
		end;
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_ADVANCED and HeroLevel >= 17 then
		while i < length(Lvl4DestructiveSpellArray) do
			Spell = Lvl4DestructiveSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);    
				print(HeroName," learned the following spell: ", Spell);                 
			end;        
			i = i + 1; 
		end;         
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_EXPERT and HeroLevel >= 22 then
		while i < length(Lvl5DestructiveSpellArray) do
			Spell = Lvl5DestructiveSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);
				print(HeroName," learned the following spell: ", Spell);                     
			end;  
			i = i + 1;  
		end;
	end; 
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_SUMMONING_MAGIC) >= MASTERY_BASIC and HeroLevel >= 12 then
		while i < length(Lvl3SummoningSpellArray) do
			Spell = Lvl3SummoningSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);      
				print(HeroName," learned the following spell: ", Spell);              
			end;
			i = i + 1;  
		end;
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_SUMMONING_MAGIC) >= MASTERY_ADVANCED and HeroLevel >= 17 then
		while i < length(Lvl4SummoningSpellArray) do
			Spell = Lvl4SummoningSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);   
				print(HeroName," learned the following spell: ", Spell);                  
			end;        
			i = i + 1; 
		end;         
	end;
	i = 1;
	if GetHeroSkillMastery(HeroName,SKILL_SUMMONING_MAGIC) >= MASTERY_EXPERT and HeroLevel >= 22 then
		while i < length(Lvl5SummoningSpellArray) do
			Spell = Lvl5SummoningSpellArray[i];
			if not KnowHeroSpell(HeroName,Spell) then  
				TeachHeroSpell(HeroName,Spell);   
				print(HeroName," learned the following spell: ", Spell);                  
			end;  
			i = i + 1;  
		end;
	end; 
end;

----------------------------------------------------
-- Spells Exchange between Deleb and Marder.
-- Takes into account the Associated Skill Mastery.
----------------------------------------------------
function ExchangeSpells()

	i = 1;
	SpellExchange = 0;
	ResourceWood = GetPlayerResource(PLAYER_1,WOOD);
	ResourceOre = GetPlayerResource(PLAYER_1,ORE);
	ResourceMercury = GetPlayerResource(PLAYER_1,MERCURY);
	ResourceSulfur = GetPlayerResource(PLAYER_1,SULFUR);
	ResourceCrystal = GetPlayerResource(PLAYER_1,CRYSTAL);
	ResourceGem = GetPlayerResource(PLAYER_1,GEM);
	ResourceGold = GetPlayerResource(PLAYER_1,GOLD);   

	print("Entering ExchangeSpells function...");
	if ResourceWood > 9 and ResourceOre > 9 and ResourceMercury > 4 and ResourceSulfur > 4 and ResourceCrystal > 4 and ResourceGem > 4 and ResourceGold > 4999 then                                          
		while i < length(Lvl1andLvl2SpellArray) do                                  
			Spell = Lvl1andLvl2SpellArray[i];      
			if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
				TeachHeroSpell("Marder",Spell);
				print("Marder learned spell: ", Spell);
				SpellExchange = 1;
			end;        
			if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
				TeachHeroSpell("Deleb",Spell);
				print("Deleb learned spell: ", Spell);
				SpellExchange = 1;
			end; 
			i = i + 1;  
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_LIGHT_MAGIC) >= MASTERY_BASIC and GetHeroSkillMastery("Marder",SKILL_LIGHT_MAGIC) >= MASTERY_BASIC then
			while i < length(Lvl3LightSpellArray) do
				Spell = Lvl3LightSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_LIGHT_MAGIC) >= MASTERY_ADVANCED and GetHeroSkillMastery("Marder",SKILL_LIGHT_MAGIC) >= MASTERY_ADVANCED then
			while i < length(Lvl4LightSpellArray) do
				Spell = Lvl4LightSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_LIGHT_MAGIC) >= MASTERY_EXPERT and GetHeroSkillMastery("Marder",SKILL_LIGHT_MAGIC) >= MASTERY_EXPERT then
			while i < length(Lvl5LightSpellArray) do
				Spell = Lvl5LightSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;  
		i = 1;
 		if GetHeroSkillMastery("Deleb",SKILL_DARK_MAGIC) >= MASTERY_BASIC and GetHeroSkillMastery("Marder",SKILL_DARK_MAGIC) >= MASTERY_BASIC then
			while i < length(Lvl3DarkSpellArray) do
				Spell = Lvl3DarkSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_DARK_MAGIC) >= MASTERY_ADVANCED and GetHeroSkillMastery("Marder",SKILL_DARK_MAGIC) >= MASTERY_ADVANCED then
			while i < length(Lvl4DarkSpellArray) do
				Spell = Lvl4DarkSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end; 
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_DARK_MAGIC) >= MASTERY_EXPERT and GetHeroSkillMastery("Marder",SKILL_DARK_MAGIC) >= MASTERY_EXPERT then
			while i < length(Lvl5DarkSpellArray) do
				Spell = Lvl5DarkSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_BASIC and GetHeroSkillMastery("Marder",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_BASIC then
			while i < length(Lvl3DestructiveSpellArray) do
				Spell = Lvl3DestructiveSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_ADVANCED and GetHeroSkillMastery("Marder",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_ADVANCED then
			while i < length(Lvl4DestructiveSpellArray) do
				Spell = Lvl4DestructiveSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_EXPERT and GetHeroSkillMastery("Marder",SKILL_DESTRUCTIVE_MAGIC) >= MASTERY_EXPERT then
			while i < length(Lvl5DestructiveSpellArray) do
				Spell = Lvl5DestructiveSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_SUMMONING_MAGIC) >= MASTERY_BASIC and GetHeroSkillMastery("Marder",SKILL_SUMMONING_MAGIC) >= MASTERY_BASIC then
			while i < length(Lvl3SummoningSpellArray) do
				Spell = Lvl3SummoningSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_SUMMONING_MAGIC) >= MASTERY_ADVANCED and GetHeroSkillMastery("Marder",SKILL_SUMMONING_MAGIC) >= MASTERY_ADVANCED then
			while i < length(Lvl4SummoningSpellArray) do
				Spell = Lvl4SummoningSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		i = 1;
		if GetHeroSkillMastery("Deleb",SKILL_SUMMONING_MAGIC) >= MASTERY_EXPERT and GetHeroSkillMastery("Marder",SKILL_SUMMONING_MAGIC) >= MASTERY_EXPERT then
			while i < length(Lvl5SummoningSpellArray) do
				Spell = Lvl5SummoningSpellArray[i];
				if KnowHeroSpell("Deleb",Spell) and not KnowHeroSpell("Marder",Spell) then  
					TeachHeroSpell("Marder",Spell);
					print("Marder learned spell: ", Spell);
					SpellExchange = 1;
				end;        
				if KnowHeroSpell("Marder",Spell) and not KnowHeroSpell("Deleb",Spell) then
					TeachHeroSpell("Deleb",Spell);
					print("Deleb learned spell: ", Spell);
					SpellExchange = 1;
				end; 
				i = i + 1;  
			end;
		end;
		if SpellExchange == 1 then 
			ResourceWood = ResourceWood - 10;
			ResourceOre = ResourceOre - 10;
			ResourceMercury = ResourceMercury - 5;
			ResourceSulfur = ResourceSulfur - 5;
			ResourceCrystal = ResourceCrystal - 5;
			ResourceGem = ResourceGem - 5;
			ResourceGold = ResourceGold - 5000;      
			SetPlayerResources(PLAYER_1, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold);
			x, y, z = GetObjectPosition(BuildingToGateSpells);
			PlayVisualEffect("/Effects/_(Effect)/Characters/Gating.xdb#xpointer(/Effect)", "", "", x, y, z, 0, 0);
			Play2DSound("/Sounds/_(Sound)/Spells/TeleportStart.xdb#xpointer(/Sound)");
			sleep(15);
			MessageBox("Maps/SingleMissions/Demonic Defense/SpellsGated.txt");
		else
			MessageBox("Maps/SingleMissions/Demonic Defense/NoSpellsGated.txt");
		end;         
	else 
		MessageBox("Maps/SingleMissions/Demonic Defense/NotEnoughResources.txt");
	end;      
end;

----------------------------------------------------
-- Artifacts Exchange between Deleb and Marder. 
----------------------------------------------------
function ExchangeArtifacts()      

	Artifact = 1;
	ArtifactExchange = 0;
	ResourceWood = GetPlayerResource(PLAYER_1,WOOD);
	ResourceOre = GetPlayerResource(PLAYER_1,ORE);
	ResourceMercury = GetPlayerResource(PLAYER_1,MERCURY);
	ResourceSulfur = GetPlayerResource(PLAYER_1,SULFUR);
	ResourceCrystal = GetPlayerResource(PLAYER_1,CRYSTAL);
	ResourceGem = GetPlayerResource(PLAYER_1,GEM);
	ResourceGold = GetPlayerResource(PLAYER_1,GOLD);  

	print("Entering ExchangeArtifacts function..."); 
	if ResourceWood > 9 and ResourceOre > 9 and ResourceMercury > 4 and ResourceSulfur > 4 and ResourceCrystal > 4 and ResourceGem > 4 and ResourceGold > 4999 then
		while Artifact < 97 do
			if HasArtefact("Deleb", Artifact) and not HasArtefact("Marder", Artifact) then
				GiveArtefact("Marder", Artifact);
				print("Marder gets Artifact: ", Artifact); 
				ArtifactExchange = 1;
			end; 
			if HasArtefact("Marder", Artifact) and not HasArtefact("Deleb", Artifact) then
				GiveArtefact("Deleb", Artifact);
				print("Deleb gets Artifact: ", Artifact); 
				ArtifactExchange = 1;         
			end;  
			Artifact = Artifact + 1;    
		end;
		if ArtifactExchange == 1 then
			ResourceWood = ResourceWood - 10;
			ResourceOre = ResourceOre - 10;
			ResourceMercury = ResourceMercury - 5;
			ResourceSulfur = ResourceSulfur - 5;
			ResourceCrystal = ResourceCrystal - 5;
			ResourceGem = ResourceGem - 5;
			ResourceGold = ResourceGold - 5000;
			SetPlayerResources(PLAYER_1, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold);
			x, y, z = GetObjectPosition(BuildingToGateArtifacts);
			PlayVisualEffect("/Effects/_(Effect)/Characters/Gating.xdb#xpointer(/Effect)", "", "", x, y, z, 0, 0);
			Play2DSound("/Sounds/_(Sound)/Spells/AnimateDead.xdb#xpointer(/Sound)");
			sleep(15);
			MessageBox("Maps/SingleMissions/Demonic Defense/ArtifactsGated.txt");
		else
			MessageBox("Maps/SingleMissions/Demonic Defense/NoArtifactsGated.txt");
		end;
	else 
		MessageBox("Maps/SingleMissions/Demonic Defense/NotEnoughResources.txt");
	end;      
end;
------------------------------------------------------------
-- Disables the Associated Garrison upon Capturing the Town.
------------------------------------------------------------
function town1capture(oldOwner, newOwner, heroname, townname)   
	print("Entering Town1capture function...");
	Play2DSound("/Sounds/_(Sound)/SFX/Screams.xdb#xpointer(/Sound)");	
	sleep(1);
	if townname == "AcademyTown" and newOwner == PLAYER_1 then
		if GetObjectOwner("AcademyGarrison") ~= PLAYER_NONE then
			SetObjectOwner("AcademyGarrison", PLAYER_NONE);
			sleep(2);
		end;          
	end;
	if townname == "HavenTown" and newOwner == PLAYER_1 then
		if GetObjectOwner("HavenGarrison") ~= PLAYER_NONE then
			SetObjectOwner("HavenGarrison", PLAYER_NONE);
			sleep(2);
		end;          
	end;   
	if townname == "SylvanTown" and newOwner == PLAYER_1 then
		if GetObjectOwner("SylvanGarrison") ~= PLAYER_NONE then
			SetObjectOwner("SylvanGarrison", PLAYER_NONE);
			sleep(2);
		end;          
	end;
	if townname == "FortressTown" and newOwner == PLAYER_1 then
		if GetObjectOwner("FortressGarrison") ~= PLAYER_NONE then
			SetObjectOwner("FortressGarrison", PLAYER_NONE);
			sleep(2);
		end;          
	end;
end;

------------------------------------------------------------
-- Sets the number of Resources for the Player.
------------------------------------------------------------
function SetPlayerResources(PlayerID, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold)
	print("Entering SetPlayerResources function...");
	SetPlayerResource(PlayerID,WOOD,ResourceWood);
	SetPlayerResource(PlayerID,ORE,ResourceOre);
	SetPlayerResource(PlayerID,MERCURY,ResourceMercury);
	SetPlayerResource(PlayerID,SULFUR,ResourceSulfur);
	SetPlayerResource(PlayerID,CRYSTAL,ResourceCrystal);
	SetPlayerResource(PlayerID,GEM,ResourceGem);
	SetPlayerResource(PlayerID,GOLD,ResourceGold);
end;

------------------------------------------------------------
-- Adds a number of Creatures to a Hero. 
------------------------------------------------------------
function AddCreaturestoHero(HeroName, CreatureID1, Qty1, CreatureID2, Qty2, CreatureID3, Qty3, CreatureID4, Qty4, CreatureID5, Qty5, CreatureID6, Qty6, CreatureID7, Qty7)
	print("Entering AddCreaturestoHero function...");
	AddHeroCreatures(HeroName,CreatureID1, Qty1);
	AddHeroCreatures(HeroName,CreatureID2, Qty2);
	AddHeroCreatures(HeroName,CreatureID3, Qty3);
	AddHeroCreatures(HeroName,CreatureID4, Qty4);
	AddHeroCreatures(HeroName,CreatureID5, Qty5);
	AddHeroCreatures(HeroName,CreatureID6, Qty6);
	AddHeroCreatures(HeroName,CreatureID7, Qty7);
end;

------------------------------------------------------------
-- Creates a Caravan (Gates Creatures) on a given day.
-- The caravan is created only if one or multiple dwellings
-- is owned by the player.
------------------------------------------------------------
function CreateInfernoCaravan() 
	print("Entering CreateInfernoCaravan function...");   
	if GetDate( DAY_OF_WEEK ) == 7 and (GetObjectOwner("ImpDwelling") == PLAYER_1 or GetObjectOwner("DemonDwelling") == PLAYER_1 or GetObjectOwner("HellHoundDwelling") == PLAYER_1 or GetObjectOwner("SuccubusDwelling") == PLAYER_1 or GetObjectOwner("HellChargerDwelling") == PLAYER_1 or GetObjectOwner("PitFiendDwelling") == PLAYER_1 or GetObjectOwner("DevilDwelling") == PLAYER_1) then
		PlayVisualEffect("/Effects/_(Effect)/Characters/Gating.xdb#xpointer(/Effect)", "", "", 62, 61, 0, 0, 0);
		CreateCaravan("InfernoCaravan",PLAYER_1,0,62,61,0,71,67);
		sleep(2);
		if GetObjectOwner("ImpDwelling") == PLAYER_1 then
			AddObjectCreatures("InfernoCaravan",CREATURE_FAMILIAR, 16);
		end;      
		if GetObjectOwner("DemonDwelling") == PLAYER_1 then 
			AddObjectCreatures("InfernoCaravan",CREATURE_DEMON, 15);
		end;
		if GetObjectOwner("HellHoundDwelling") == PLAYER_1 then 
			AddObjectCreatures("InfernoCaravan",CREATURE_HELL_HOUND, 8);
		end;
		if GetObjectOwner("SuccubusDwelling") == PLAYER_1 then
			AddObjectCreatures("InfernoCaravan",CREATURE_SUCCUBUS, 5);
		end;
		if GetObjectOwner("HellChargerDwelling") == PLAYER_1 then
			AddObjectCreatures("InfernoCaravan",CREATURE_NIGHTMARE, 3);
		end;
		if GetObjectOwner("PitFiendDwelling") == PLAYER_1 then
			AddObjectCreatures("InfernoCaravan",CREATURE_PIT_FIEND, 2);
		end;
		if GetObjectOwner("DevilDwelling") == PLAYER_1 then	
			AddObjectCreatures("InfernoCaravan",CREATURE_DEVIL, 1);     
		end; 
		MessageBox("Maps/SingleMissions/Demonic Defense/CaravanMessage.txt");
	end;
end;

------------------------------------------------------------
-- Sabotages a Hero by reducing the number of creatures 
-- within the Hero. Sabotage only can work if a enemy hero 
-- is within reach.
------------------------------------------------------------
function SabotageHero()

	Hero1MoveCost = 0;
	Hero2MoveCost = 99999;
	HeroExist = 0;
	HeroName = "NoHeroName";
	HeroNameArray = GetObjectsInRegion("InfernoGarrisonRegion", OBJECT_HERO); 
	i = 0;	
	ResourceWood = GetPlayerResource(PLAYER_1,WOOD);
	ResourceOre = GetPlayerResource(PLAYER_1,ORE);
	ResourceMercury = GetPlayerResource(PLAYER_1,MERCURY);
	ResourceSulfur = GetPlayerResource(PLAYER_1,SULFUR);
	ResourceCrystal = GetPlayerResource(PLAYER_1,CRYSTAL);
	ResourceGem = GetPlayerResource(PLAYER_1,GEM);
	ResourceGold = GetPlayerResource(PLAYER_1,GOLD);   
	tx = 71;
	ty = 87;
	tz = 11;
	x = 0;
	y = 0;
	z = 0;

	print("Entering SabotageHero function...");   
	while i <  length(HeroNameArray) do
		if HeroNameArray[i] ~= "Deleb" and HeroNameArray[i] ~= "Marder" and HeroNameArray[i] ~= nil then
			Hero1MoveCost = CalcHeroMoveCost(HeroNameArray[i], 71, 67);
				if Hero1MoveCost < Hero2MoveCost then
					Hero2MoveCost = Hero1MoveCost;
					HeroName = HeroNameArray[i];      
				end;	
		end;
		i = i + 1;
	end;	   	
	print(HeroName, " is the nearest enemy from the Inferno Town.");
	if ResourceWood > 9 and ResourceOre > 9 and ResourceMercury > 4 and ResourceSulfur > 4 and ResourceCrystal > 4 and ResourceGem > 4 and ResourceGold > 4999 then
		if HeroName == "Una" then
			Upglvl1Creature = CREATURE_STOUT_DEFENDER;           
			Upglvl2Creature = CREATURE_AXE_THROWER;
			Upglvl3Creature = CREATURE_BLACKBEAR_RIDER;
			Upglvl4Creature = CREATURE_BERSERKER;
			Upglvl5Creature = CREATURE_FLAME_MAGE;
			Upglvl6Creature = CREATURE_WARLORD;
			Upglvl7Creature = CREATURE_MAGMA_DRAGON;  
			HeroExist = 1;           
		end; 
		if HeroName == "Vegeyr" then
			Upglvl1Creature = CREATURE_STONE_DEFENDER;
			Upglvl2Creature = CREATURE_HARPOONER;
			Upglvl3Creature = CREATURE_WHITE_BEAR_RIDER;
			Upglvl4Creature = CREATURE_BATTLE_RAGER;
			Upglvl5Creature = CREATURE_FLAME_KEEPER;
			Upglvl6Creature = CREATURE_THUNDER_THANE;
			Upglvl7Creature = CREATURE_LAVA_DRAGON;   
			HeroExist = 1;              
		end;   
		if HeroName == "Orrin" then
			Upglvl1Creature = CREATURE_MILITIAMAN;
			Upglvl2Creature = CREATURE_MARKSMAN;
			Upglvl3Creature = CREATURE_SWORDSMAN;
			Upglvl4Creature = CREATURE_ROYAL_GRIFFIN;
			Upglvl5Creature = CREATURE_CLERIC;
			Upglvl6Creature = CREATURE_PALADIN;
			Upglvl7Creature = CREATURE_ARCHANGEL;   
			HeroExist = 1;                    
		end;
		if HeroName == "Ving" then
			Upglvl1Creature = CREATURE_LANDLORD;
			Upglvl2Creature = CREATURE_LONGBOWMAN;
			Upglvl3Creature = CREATURE_VINDICATOR;
			Upglvl4Creature = CREATURE_BATTLE_GRIFFIN;
			Upglvl5Creature = CREATURE_ZEALOT;
			Upglvl6Creature = CREATURE_CHAMPION;
			Upglvl7Creature = CREATURE_SERAPH;     
			HeroExist = 1;                  
		end;
		if HeroName == "Metlirn" then
			Upglvl1Creature = CREATURE_SPRITE;
			Upglvl2Creature = CREATURE_WAR_DANCER;
			Upglvl3Creature = CREATURE_GRAND_ELF;
			Upglvl4Creature = CREATURE_DRUID_ELDER;
			Upglvl5Creature = CREATURE_WAR_UNICORN;
			Upglvl6Creature = CREATURE_TREANT_GUARDIAN;
			Upglvl7Creature = CREATURE_GOLD_DRAGON;  
			HeroExist = 1;                 
		end;
		if HeroName == "Diraya" then
			Upglvl1Creature = CREATURE_DRYAD;
			Upglvl2Creature = CREATURE_BLADE_SINGER;
			Upglvl3Creature = CREATURE_SHARP_SHOOTER;
			Upglvl4Creature = CREATURE_HIGH_DRUID;
			Upglvl5Creature = CREATURE_WHITE_UNICORN;
			Upglvl6Creature = CREATURE_ANGER_TREANT;
			Upglvl7Creature = CREATURE_RAINBOW_DRAGON;   
			HeroExist = 1;                
		end;
		if HeroName == "Nur" then
			Upglvl1Creature = CREATURE_MASTER_GREMLIN;
			Upglvl2Creature = CREATURE_OBSIDIAN_GARGOYLE;
			Upglvl3Creature = CREATURE_STEEL_GOLEM;
			Upglvl4Creature = CREATURE_ARCH_MAGI;
			Upglvl5Creature = CREATURE_MASTER_GENIE;
			Upglvl6Creature = CREATURE_RAKSHASA_RUKH;
			Upglvl7Creature = CREATURE_TITAN;  
			HeroExist = 1;           
		end;
		if HeroName == "Astral" then
			Upglvl1Creature = CREATURE_GREMLIN_SABOTEUR;
			Upglvl2Creature = CREATURE_MARBLE_GARGOYLE;
			Upglvl3Creature = CREATURE_OBSIDIAN_GOLEM;
			Upglvl4Creature = CREATURE_COMBAT_MAGE;
			Upglvl5Creature = CREATURE_DJINN_VIZIER;
			Upglvl6Creature = CREATURE_RAKSHASA_KSHATRI;
			Upglvl7Creature = CREATURE_STORM_LORD;
			HeroExist = 1;           
		end;
		if HeroExist == 1 then           
			MoveCamera(tx, ty, 0, 30, 1, 0, 1, 1, 1);
			PlayVisualEffect("/Effects/_(Effect)/Arenas/InfernoSiege/BigTowerShot.xdb#xpointer(/Effect)", "", "", tx, ty, tz, 0, 0);
			sleep(6);
			Play2DSound( "/Sounds/_(Sound)/WarMachines/Ballista/rangeattack.xdb#xpointer(/Sound)" );  
			x,y,z = GetObjectPosition(HeroName);
			MoveCamera(x, y, 0, 30, 1, 0, 1, 1, 0);
			sleep(15);	 
			PlayVisualEffect("/Effects/_(Effect)/Spells/Implosion.xdb#xpointer(/Effect)", "", "", x, y, z, 0, 0);
			Play2DSound( "/Sounds/_(Sound)/Spells/Implosion.xdb#xpointer(/Sound)" );
			sleep(35);     
			if GetHeroCreatures(HeroName, Upglvl1Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl1Creature, GetHeroCreatures(HeroName, Upglvl1Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl2Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl2Creature, GetHeroCreatures(HeroName, Upglvl2Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl3Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl3Creature, GetHeroCreatures(HeroName, Upglvl3Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl4Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl4Creature, GetHeroCreatures(HeroName, Upglvl4Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl5Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl5Creature, GetHeroCreatures(HeroName, Upglvl5Creature)*SABOTAGE_RATIO );
			end;
			if GetHeroCreatures(HeroName, Upglvl6Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl6Creature, GetHeroCreatures(HeroName, Upglvl6Creature)*SABOTAGE_RATIO );
			end;
			if GetHeroCreatures(HeroName, Upglvl7Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl7Creature, GetHeroCreatures(HeroName, Upglvl7Creature)*SABOTAGE_RATIO );
			end;      
			MessageBox("Maps/SingleMissions/Demonic Defense/SabotageMessage.txt");
			ResourceWood = ResourceWood - 10;
			ResourceOre = ResourceOre - 10;
			ResourceMercury = ResourceMercury - 5;
			ResourceSulfur = ResourceSulfur - 5;
			ResourceCrystal = ResourceCrystal - 5;
			ResourceGem = ResourceGem - 5;
			ResourceGold = ResourceGold - 5000;
			SetPlayerResources(PLAYER_1, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold);
		else
			MessageBox("Maps/SingleMissions/Demonic Defense/NoHeroInGarrisonMessage.txt");
		end;
	else 
		MessageBox("Maps/SingleMissions/Demonic Defense/NotEnoughResources.txt");
	end;
end;

------------------------------------------------------------
-- Sabotages a selected Town by reducing the   
-- number of creatures within the town
------------------------------------------------------------
function SabotageTown()

	HeroName="NoHeroName";
	ResourceWood = GetPlayerResource(PLAYER_1,WOOD);
	ResourceOre = GetPlayerResource(PLAYER_1,ORE);
	ResourceMercury = GetPlayerResource(PLAYER_1,MERCURY);
	ResourceSulfur = GetPlayerResource(PLAYER_1,SULFUR);
	ResourceCrystal = GetPlayerResource(PLAYER_1,CRYSTAL);
	ResourceGem = GetPlayerResource(PLAYER_1,GEM);
	ResourceGold = GetPlayerResource(PLAYER_1,GOLD);
	TownExist = 0;
	tx = 0;
	ty = 0;
	tz = 0;   
	x = 0;
	y = 0;
	z = 0;

	print("Entering SabotageTown function...");   
	if ResourceWood > 9 and ResourceOre > 9 and ResourceMercury > 4 and ResourceSulfur > 4 and ResourceCrystal > 4 and ResourceGem > 4 and ResourceGold > 4999 then
		if TownToSabotage == "FortressTown" and GetObjectOwner("FortressTown") == PLAYER_2 then
			x = 13;
			y = 8;  
			z = 0;  
			tx = 64;
			ty = 50;  
			tz = 11;  
			TownExist = 1;
			HeroName = "Ingvar"; 
			Upglvl1Creature = CREATURE_STONE_DEFENDER;
			Upglvl2Creature = CREATURE_AXE_THROWER;
			Upglvl3Creature = CREATURE_BLACKBEAR_RIDER;
			Upglvl4Creature = CREATURE_BATTLE_RAGER;
			Upglvl5Creature = CREATURE_FLAME_MAGE;
			Upglvl6Creature = CREATURE_WARLORD;
			Upglvl7Creature = CREATURE_MAGMA_DRAGON;              
		end; 
		if TownToSabotage == "HavenTown" and GetObjectOwner("HavenTown") == PLAYER_3 then
			x = 49;
			y = 8; 
			z = 0;    
			tx = 64;
			ty = 50;  
			tz = 11;    
			TownExist = 1;
			HeroName = "Sarge";
			Upglvl1Creature = CREATURE_LANDLORD;
			Upglvl2Creature = CREATURE_LONGBOWMAN;
			Upglvl3Creature = CREATURE_VINDICATOR;
			Upglvl4Creature = CREATURE_BATTLE_GRIFFIN;
			Upglvl5Creature = CREATURE_CLERIC;
			Upglvl6Creature = CREATURE_CHAMPION;
			Upglvl7Creature = CREATURE_ARCHANGEL;          
		end;   
		if TownToSabotage == "SylvanTown" and GetObjectOwner("SylvanTown") == PLAYER_4 then
			x = 88;
			y = 8; 
			z = 0; 
			tx = 79;
			ty = 50;  
			tz = 11;  
			TownExist = 1;
			HeroName = "Ossir";  
			Upglvl1Creature = CREATURE_SPRITE;
			Upglvl2Creature = CREATURE_WAR_DANCER;
			Upglvl3Creature = CREATURE_SHARP_SHOOTER;
			Upglvl4Creature = CREATURE_DRUID_ELDER;
			Upglvl5Creature = CREATURE_WHITE_UNICORN;
			Upglvl6Creature = CREATURE_ANGER_TREANT;
			Upglvl7Creature = CREATURE_GOLD_DRAGON;               
		end;
		if TownToSabotage == "AcademyTown" and GetObjectOwner("AcademyTown") == PLAYER_5 then
			x = 124;
			y = 8;  
			z = 5;  
			tx = 79;
			ty = 50;
			tz = 11;  
			TownExist = 1;
			HeroName = "Sufi";
			Upglvl1Creature = CREATURE_MASTER_GREMLIN;
			Upglvl2Creature = CREATURE_OBSIDIAN_GARGOYLE;
			Upglvl3Creature = CREATURE_STEEL_GOLEM;
			Upglvl4Creature = CREATURE_COMBAT_MAGE;
			Upglvl5Creature = CREATURE_DJINN_VIZIER;
			Upglvl6Creature = CREATURE_RAKSHASA_KSHATRI;
			Upglvl7Creature = CREATURE_STORM_LORD;          
		end;
		if TownExist == 1 then
			OpenCircleFog(x, y, 0, 4, PLAYER_1);      
			MoveCamera(tx, ty, 0, 30, 1, 0, 1, 1, 1);
			PlayVisualEffect("/Effects/_(Effect)/Arenas/InfernoSiege/BigTowerShot.xdb#xpointer(/Effect)", "", "", tx, ty, tz, 0, 0);
			sleep(6);
			Play2DSound( "/Sounds/_(Sound)/WarMachines/Ballista/rangeattack.xdb#xpointer(/Sound)" );      
			MoveCamera(x, y, 0, 30, 1, 0, 1, 1, 0);
			sleep(15);
			PlayVisualEffect("/Effects/_(Effect)/Spells/FireBallHit.xdb#xpointer(/Effect)", "", "", x, y, z, 0, 0);
			Play2DSound( "/Sounds/_(Sound)/Spells/FireBallHit.xdb#xpointer(/Sound)" );
			sleep(5);     
			if GetHeroCreatures(HeroName, Upglvl1Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl1Creature, GetHeroCreatures(HeroName, Upglvl1Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl2Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl2Creature, GetHeroCreatures(HeroName, Upglvl2Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl3Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl3Creature, GetHeroCreatures(HeroName, Upglvl3Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl4Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl4Creature, GetHeroCreatures(HeroName, Upglvl4Creature)*SABOTAGE_RATIO );
			end;      
			if GetHeroCreatures(HeroName, Upglvl5Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl5Creature, GetHeroCreatures(HeroName, Upglvl5Creature)*SABOTAGE_RATIO );
		        end;
			if GetHeroCreatures(HeroName, Upglvl6Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl6Creature, GetHeroCreatures(HeroName, Upglvl6Creature)*SABOTAGE_RATIO );
			end;
			if GetHeroCreatures(HeroName, Upglvl7Creature)*SABOTAGE_RATIO >= 1 then
				RemoveHeroCreatures(HeroName, Upglvl7Creature, GetHeroCreatures(HeroName, Upglvl7Creature)*SABOTAGE_RATIO );
			end;      
			MessageBox("Maps/SingleMissions/Demonic Defense/SabotageMessage.txt");
			ResourceWood = ResourceWood - 10;
			ResourceOre = ResourceOre - 10;
			ResourceMercury = ResourceMercury - 5;
			ResourceSulfur = ResourceSulfur - 5;
			ResourceCrystal = ResourceCrystal - 5;
			ResourceGem = ResourceGem - 5;
			ResourceGold = ResourceGold - 5000;
			SetPlayerResources(PLAYER_1, ResourceWood, ResourceOre, ResourceMercury, ResourceSulfur, ResourceCrystal, ResourceGem, ResourceGold);
		else
			MessageBox("Maps/SingleMissions/Demonic Defense/TownAlreadyCapturedMessage.txt");
		end;
	else 
		MessageBox("Maps/SingleMissions/Demonic Defense/NotEnoughResources.txt");
	end;
end;

---------------------------------------------------------------
-- Deploys a Enemy Hero to Attack the Inferno Town.
-- The Deployed Enemy Hero is randomly selected between 8 
-- Reserved Heroes and the associated army grows each week. 
-- An Enemy Hero is Deployed on 2 given days. The function 
-- attempts 2 times to Deploy an Enemy Hero. 
---------------------------------------------------------------
function AttackInfernoTown()

	HeroName = "NoHeroName";
	EnemyDeployed = 0;   
	LoopCounter = 0;
	PlayerID = 0;
	TownOwner = "TownNone";
	week = GetDate(MONTH)*4 - 4 + GetDate(WEEK);

	print("Entering AttackInfernoTown function...");
	if GetDate( DAY_OF_WEEK ) == 1 or GetDate( DAY_OF_WEEK ) == 4 then
		ExpHero1 = GetHeroStat("Deleb", STAT_EXPERIENCE);
		ExpHero2 = GetHeroStat("Marder", STAT_EXPERIENCE);
		if ExpHero1 <= ExpHero2 then
			Exp = ExpHero1;	
		else
			Exp = ExpHero2;	
		end;
		while EnemyDeployed == 0 and LoopCounter < 2 do
			rnd = random(8);
			if rnd == 0 and GetObjectOwner("FortressTown") == PLAYER_2 then   
				HeroName = "Una";
				Start = "FortressStartRegion";
				TownOwner = "FortressTown";
				PlayerID = PLAYER_2;
				Upglvl1Creature = CREATURE_STOUT_DEFENDER;           
				Upglvl2Creature = CREATURE_AXE_THROWER;
				Upglvl3Creature = CREATURE_BLACKBEAR_RIDER;
				Upglvl4Creature = CREATURE_BERSERKER;
				Upglvl5Creature = CREATURE_FLAME_MAGE;
				Upglvl6Creature = CREATURE_WARLORD;
				Upglvl7Creature = CREATURE_MAGMA_DRAGON; 
			end;
			if rnd == 1 and GetObjectOwner("FortressTown") == PLAYER_2 then  
				HeroName = "Vegeyr";
				Start = "FortressStartRegion"; 
				TownOwner = "FortressTown";
				PlayerID = PLAYER_2;
				Upglvl1Creature = CREATURE_STONE_DEFENDER;
				Upglvl2Creature = CREATURE_HARPOONER;
				Upglvl3Creature = CREATURE_WHITE_BEAR_RIDER;
				Upglvl4Creature = CREATURE_BATTLE_RAGER;
				Upglvl5Creature = CREATURE_FLAME_KEEPER;
				Upglvl6Creature = CREATURE_THUNDER_THANE;
				Upglvl7Creature = CREATURE_LAVA_DRAGON;            
			end;
			if rnd == 2 and GetObjectOwner("HavenTown") == PLAYER_3  then 
				HeroName = "Orrin"; 
				Start = "HavenStartRegion"; 
				TownOwner = "HavenTown";
				PlayerID = PLAYER_3;
				Upglvl1Creature = CREATURE_MILITIAMAN;
				Upglvl2Creature = CREATURE_MARKSMAN;
				Upglvl3Creature = CREATURE_SWORDSMAN;
				Upglvl4Creature = CREATURE_ROYAL_GRIFFIN;
				Upglvl5Creature = CREATURE_CLERIC;
				Upglvl6Creature = CREATURE_PALADIN;
				Upglvl7Creature = CREATURE_ARCHANGEL;
			end;
			if rnd == 3 and GetObjectOwner("HavenTown") == PLAYER_3 then 
				HeroName = "Ving";
				Start = "HavenStartRegion"; 
				TownOwner = "HavenTown";
				PlayerID = PLAYER_3;
				Upglvl1Creature = CREATURE_LANDLORD;
				Upglvl2Creature = CREATURE_LONGBOWMAN;
				Upglvl3Creature = CREATURE_VINDICATOR;
				Upglvl4Creature = CREATURE_BATTLE_GRIFFIN;
				Upglvl5Creature = CREATURE_ZEALOT;
				Upglvl6Creature = CREATURE_CHAMPION;
				Upglvl7Creature = CREATURE_SERAPH; 
			end;
			if rnd == 4 and GetObjectOwner("SylvanTown") == PLAYER_4 then  
				HeroName = "Metlirn";
				Start = "SylvanStartRegion";
				TownOwner = "SylvanTown";
				PlayerID = PLAYER_4;   
				Upglvl1Creature = CREATURE_SPRITE;
				Upglvl2Creature = CREATURE_WAR_DANCER;
				Upglvl3Creature = CREATURE_GRAND_ELF;
				Upglvl4Creature = CREATURE_DRUID_ELDER;
				Upglvl5Creature = CREATURE_WAR_UNICORN;
				Upglvl6Creature = CREATURE_TREANT_GUARDIAN;
				Upglvl7Creature = CREATURE_GOLD_DRAGON;
			end;
			if rnd == 5 and GetObjectOwner("SylvanTown") == PLAYER_4 then 
				HeroName = "Diraya";
				Start = "SylvanStartRegion";
				TownOwner = "SylvanTown";
				PlayerID = PLAYER_4;   
				Upglvl1Creature = CREATURE_DRYAD;
				Upglvl2Creature = CREATURE_BLADE_SINGER;
				Upglvl3Creature = CREATURE_SHARP_SHOOTER;
				Upglvl4Creature = CREATURE_HIGH_DRUID;
				Upglvl5Creature = CREATURE_WHITE_UNICORN;
				Upglvl6Creature = CREATURE_ANGER_TREANT;
				Upglvl7Creature = CREATURE_RAINBOW_DRAGON;  
			end;
			if rnd == 6 and GetObjectOwner("AcademyTown") == PLAYER_5 then 
				HeroName = "Nur";
				Start = "AcademyStartRegion";
				TownOwner = "AcademyTown";
				PlayerID = PLAYER_5;   
				Upglvl1Creature = CREATURE_MASTER_GREMLIN;
				Upglvl2Creature = CREATURE_OBSIDIAN_GARGOYLE;
				Upglvl3Creature = CREATURE_STEEL_GOLEM;
				Upglvl4Creature = CREATURE_ARCH_MAGI;
				Upglvl5Creature = CREATURE_MASTER_GENIE;
				Upglvl6Creature = CREATURE_RAKSHASA_RUKH;
				Upglvl7Creature = CREATURE_TITAN;
			end;
			if rnd == 7 and GetObjectOwner("AcademyTown") == PLAYER_5 then
				HeroName = "Astral";
				Start = "AcademyStartRegion";
				TownOwner = "AcademyTown";
				PlayerID = PLAYER_5;  
				Upglvl1Creature = CREATURE_GREMLIN_SABOTEUR;
				Upglvl2Creature = CREATURE_MARBLE_GARGOYLE;
				Upglvl3Creature = CREATURE_OBSIDIAN_GOLEM;
				Upglvl4Creature = CREATURE_COMBAT_MAGE;
				Upglvl5Creature = CREATURE_DJINN_VIZIER;
				Upglvl6Creature = CREATURE_RAKSHASA_KSHATRI;
				Upglvl7Creature = CREATURE_STORM_LORD;
			end;
			if not IsHeroAlive(HeroName) and TownOwner ~= "TownNone" then
				ChangeStatsHero(HeroName, Exp);
			        DeployReserveHero(HeroName, RegionToPoint(Start));  
				sleep(1);    
				if IsHeroAlive(HeroName) then     -- On rare occasions, for unknown reasons, the hero is not deployed. 
					print(HeroName," is Deployed");            
					EnemyDeployed = 1;			                                
					if CanMoveHero(HeroName, 71, 67) then 
						if LVL1GROWTH*week*Difficulty-Lvl1Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl1Creature, LVL1GROWTH*week*Difficulty-Lvl1Handicap);          
							sleep(1);
						end;                        
						if LVL2GROWTH*week*Difficulty-Lvl2Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl2Creature, LVL2GROWTH*week*Difficulty-Lvl2Handicap);          
							sleep(1);
						end; 
						if LVL3GROWTH*week*Difficulty-Lvl3Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl3Creature, LVL3GROWTH*week*Difficulty-Lvl3Handicap);          
							sleep(1);
						end;
						if LVL4GROWTH*week*Difficulty-Lvl4Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl4Creature, LVL4GROWTH*week*Difficulty-Lvl4Handicap);   
							sleep(1);       
						end;   
						if LVL5GROWTH*week*Difficulty-Lvl5Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl5Creature, LVL5GROWTH*week*Difficulty-Lvl5Handicap);        
							sleep(1);  
						end;   
						if LVL6GROWTH*week*Difficulty-Lvl6Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl6Creature, LVL6GROWTH*week*Difficulty-Lvl6Handicap);    
							sleep(1);      
						end; 
						if LVL7GROWTH*week*Difficulty-Lvl7Handicap >= 1 then
							AddHeroCreatures(HeroName, Upglvl7Creature, LVL7GROWTH*week*Difficulty-Lvl7Handicap);
							sleep(1);          
						end;                 					
						EnableHeroAI(HeroName, nil);                         
						MoveHero(HeroName, 71, 67);
						print(HeroName," moving to the Inferno Town");
						EnableHeroAI(HeroName, true);  
					else
						if IsHeroAlive(HeroName) then
							RemoveObject(HeroName);                      
							print(HeroName," cannot move to the Inferno Town. Removing ", HeroName);
							EnemyDeployed = 0;
						end;
					end;
				else
					print(HeroName, " is not deployed.");
				end;   	
			else
				print(HeroName, " is not deployed or already alive on map.");
			end;
			LoopCounter = LoopCounter + 1;  
		end;
	end;
end;

------------------------------------------------------------
-- Adds creatures to Heroes Defending Town.
------------------------------------------------------------
function GrowArmies()
	print("Entering GrowArmies function...");
	if GetDate( DAY_OF_WEEK ) == 1 then
		if IsHeroAlive("Ingvar") then
			AddCreaturestoHero("Ingvar", CREATURE_STONE_DEFENDER, LVL1GROWTH, CREATURE_AXE_THROWER, LVL2GROWTH, CREATURE_BLACKBEAR_RIDER, LVL3GROWTH, CREATURE_BATTLE_RAGER, LVL4GROWTH, CREATURE_FLAME_MAGE, LVL5GROWTH, CREATURE_WARLORD, LVL6GROWTH, CREATURE_MAGMA_DRAGON, LVL7GROWTH);      
			print("Fortress Creatures Added");
		end;
		if IsHeroAlive("Sarge") then
			AddCreaturestoHero("Sarge", CREATURE_LANDLORD, LVL1GROWTH, CREATURE_LONGBOWMAN, LVL2GROWTH, CREATURE_VINDICATOR, LVL3GROWTH, CREATURE_BATTLE_GRIFFIN, LVL4GROWTH, CREATURE_CLERIC, LVL5GROWTH, CREATURE_CHAMPION, LVL6GROWTH, CREATURE_ARCHANGEL, LVL7GROWTH);
			print("Haven Creatures Added");
		end;
		if IsHeroAlive("Ossir") then
			AddCreaturestoHero("Ossir", CREATURE_SPRITE, LVL1GROWTH, CREATURE_WAR_DANCER, LVL2GROWTH, CREATURE_SHARP_SHOOTER, LVL3GROWTH, CREATURE_DRUID_ELDER, LVL4GROWTH, CREATURE_WHITE_UNICORN, LVL5GROWTH, CREATURE_ANGER_TREANT, LVL6GROWTH, CREATURE_GOLD_DRAGON, LVL7GROWTH);
			print("Sylvan Creatures Added");
		end;
		if IsHeroAlive("Sufi") then
			AddCreaturestoHero("Sufi", CREATURE_MASTER_GREMLIN, LVL1GROWTH, CREATURE_OBSIDIAN_GARGOYLE, LVL2GROWTH, CREATURE_STEEL_GOLEM, LVL3GROWTH, CREATURE_COMBAT_MAGE, LVL4GROWTH, CREATURE_DJINN_VIZIER, LVL5GROWTH, CREATURE_RAKSHASA_KSHATRI, LVL6GROWTH, CREATURE_STORM_LORD, LVL7GROWTH);
			print("Academy Creatures Added");
		end;   
	end;
end;
-------------------------------------------------------------------
-- Checks if all Enemies have been defeated and all Towns Captured.
-------------------------------------------------------------------
function CheckDefeatAll()
	print("Entering CheckDefeatAll function..."); 
	if GetObjectOwner("FortressTown") == PLAYER_1 and GetObjectOwner("HavenTown") == PLAYER_1 and GetObjectOwner("SylvanTown") == PLAYER_1 and GetObjectOwner("AcademyTown") == PLAYER_1 then
		if not IsHeroAlive("Ingvar") and not IsHeroAlive("Sarge") and not IsHeroAlive("Ossir") and not IsHeroAlive("Sufi") and not IsHeroAlive("Una") and not IsHeroAlive("Vegeyr") and not IsHeroAlive("Orrin") and not IsHeroAlive("Ving") and not IsHeroAlive("Metlirn") and not IsHeroAlive("Diraya") and not IsHeroAlive("Nur") and not IsHeroAlive("Astral") then
			sleep(40); -- To let the scream sound finish if needed.
			StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneEnd/DialogScene.xdb#xpointer(/DialogScene)");
			SetObjectiveState( 'Objective0', OBJECTIVE_COMPLETED );
			sleep(1);
			Win();
		end;
	end;
end;

------------------------------------------------------------
-- Plays various Dialog Scenes. 
------------------------------------------------------------
function PlayDialogSceneStatsGatingBuilding()
	StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneGateStats/DialogScene.xdb#xpointer(/DialogScene)");
	Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "StatsGatingRegion", nil);
end;

function PlayDialogSceneSpellsGatingBuilding()
	StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneGateSpells/DialogScene.xdb#xpointer(/DialogScene)");
	Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "SpellsGatingRegion", nil);
end;

function PlayDialogSceneArtifactsGatingBuilding()
	StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneGateArtifacts/DialogScene.xdb#xpointer(/DialogScene)");
	Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "ArtifactsGatingRegion", nil);
end;

function PlayDialogSceneLoss()
	StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneLoss/DialogScene.xdb#xpointer(/DialogScene)");
	Loose();
end;

------------------------------------------------------------
-- Player Loses the game if the Inferno Town is captured
------------------------------------------------------------
function InfernoCapture(oldOwner, newOwner, heroname, townname) 
	print("Entering InfernoCapture function...");
	SetObjectiveState( 'Objective3', OBJECTIVE_FAILED );
	PlayDialogSceneLoss();
end;

------------------------------------------------------------
-- Multiple Functions to Execute on a New Day. Also 
-- displays time left to complete mission.
------------------------------------------------------------
function NewDay()
	GrowArmies();
	CreateInfernoCaravan();
	AttackInfernoTown();
	if GetDate(DAY) == 113 then
		MessageBox("Maps/SingleMissions/Demonic Defense/TwoMonthsLeftMessage.txt");
	end;
	if GetDate(DAY) == 141 then
		MessageBox("Maps/SingleMissions/Demonic Defense/OneMonthLeftMessage.txt");
	end;
	if GetDate(DAY) == 155 then
		MessageBox("Maps/SingleMissions/Demonic Defense/TwoWeeksLeftMessage.txt");
	end;
	if GetDate(DAY) == 162 then
		MessageBox("Maps/SingleMissions/Demonic Defense/OneWeekLeftMessage.txt");
	end;
	if GetDate(DAY) == 169 then
		SetObjectiveState( 'Objective0', OBJECTIVE_FAILED );
		sleep(1);      
		PlayDialogSceneLoss();
	end;
end;

------------------------------------------------------------
-- Multiple Prompts to Sabotage a given Town, to 
-- Exchange Spells and to Exchange Artifacts. A Cancel 
-- function as well.
------------------------------------------------------------
function OnCancel()

end;

function QuestionSabotageFortressTown()
	TownToSabotage = "FortressTown";
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionSabotageFortressTown.txt","SabotageTown","OnCancel");
end;

function QuestionSabotageHavenTown()
	TownToSabotage = "HavenTown";
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionSabotageHavenTown.txt","SabotageTown","OnCancel");
end;

function QuestionSabotageSylvanTown()
	TownToSabotage = "SylvanTown";
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionSabotageSylvanTown.txt","SabotageTown","OnCancel");
end;

function QuestionSabotageAcademyTown()
	TownToSabotage = "AcademyTown";
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionSabotageAcademyTown.txt","SabotageTown","OnCancel");
end;

function QuestionExchangeSpells(HeroName, ObjectName)
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionExchangeSpells.txt","ExchangeSpells","OnCancel");
	BuildingToGateSpells = ObjectName;
end;

function QuestionExchangeArtifacts(HeroName, ObjectName)
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionExchangeArtifacts.txt","ExchangeArtifacts","OnCancel");
	BuildingToGateArtifacts = ObjectName;
end;

function QuestionExchangeHeroStats(HeroName, ObjectName)
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionExchangeHeroStats.txt","ExchangeHeroStats","OnCancel");
	BuildingToGateStats = ObjectName;
	if HeroName == "Deleb" then   
		HeroNameExchangeStats = "Marder";
	else
		HeroNameExchangeStats = "Deleb";
	end;
end;

function QuestionSabotageHero()   
	QuestionBox("Maps/SingleMissions/Demonic Defense/QuestionSabotageHero.txt","SabotageHero","OnCancel");
end;
------------------------------------------------------------
-- Multiple functions for Primary Stats Buildings.
------------------------------------------------------------
function VisitMercenaryCamp1()
	MercenaryCamp1Visited = 1;
end;

function VisitMercenaryCamp2()
	MercenaryCamp2Visited = 1;
end;

function VisitMercenaryCamp3()
	MercenaryCamp3Visited = 1;
end;

function VisitMercenaryCamp4()
	MercenaryCamp4Visited = 1;
end;

function VisitMercenaryCamp5()
	MercenaryCamp5Visited = 1;
end;

function VisitMarlettoTower1()
	MarlettoTower1Visited = 1;
end;

function VisitMarlettoTower2()
	MarlettoTower2Visited = 1;
end;

function VisitMarlettoTower3()
	MarlettoTower3Visited = 1;
end;

function VisitMarlettoTower4()
	MarlettoTower4Visited = 1;
end;

function VisitMarlettoTower5()
	MarlettoTower5Visited = 1;
end;

function VisitMarlettoTower6()
	MarlettoTower6Visited = 1;
end;

function VisitRevelation1()
	Revelation1Visited = 1;
end;

function VisitRevelation2()
	Revelation2Visited = 1;
end;

function VisitRevelation3()
	Revelation3Visited = 1;
end;

function VisitRevelation4()
	Revelation4Visited = 1;
end;

function VisitRevelation5()
	Revelation5Visited = 1;
end;

function VisitPlanetarium1()
	Planetarium1Visited = 1;
end;

function VisitPlanetarium2()
	Planetarium2Visited = 1;
end;

function VisitPlanetarium3()
	Planetarium3Visited = 1;
end;

function VisitPlanetarium4()
	Planetarium4Visited = 1;
end;

function VisitPlanetarium5()
	Planetarium5Visited = 1;
end;

function VisitPlanetarium6()
	Planetarium6Visited = 1;
end;

------------------------------------------------------------
-- Adds Objective 4 (Gain access the tunnel and the tower 
-- switches) to the player.
------------------------------------------------------------
function AddObjective4()
	if ( GetObjectiveState( 'Objective4' ) ~= OBJECTIVE_ACTIVE and Objective4Active ~= 1 ) then
		StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneKeyBegin/DialogScene.xdb#xpointer(/DialogScene)");
		SetObjectiveState( 'Objective4', OBJECTIVE_ACTIVE );
		sleep(1);
		Objective4Active = 1;
		Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "WightsRegion", nil);
	end;
end;

------------------------------------------------------------
-- Checks if the player has gained all the keys from the 
-- keymaster tents.
------------------------------------------------------------
function CheckAllBorderGuardKeys()
	if HasBorderguardKey(PLAYER_1, BLUE_KEY) and HasBorderguardKey(PLAYER_1, YELLOW_KEY) and HasBorderguardKey(PLAYER_1, GREEN_KEY) and HasBorderguardKey(PLAYER_1, ORANGE_KEY) and AllBorderGuardKeys ~= 1 then 
		StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneKeyEnd/DialogScene.xdb#xpointer(/DialogScene)");
		SetObjectiveState( 'Objective4', OBJECTIVE_COMPLETED );
		sleep(1);
		LevelUpHero('Deleb');
		LevelUpHero('Marder');
		Trigger(OBJECT_TOUCH_TRIGGER, "BlueKeyMasterTent", nil);
		Trigger(OBJECT_TOUCH_TRIGGER, "GreenKeyMasterTent", nil);
		Trigger(OBJECT_TOUCH_TRIGGER, "OrangeKeyMasterTent", nil);
		Trigger(OBJECT_TOUCH_TRIGGER, "YellowKeyMasterTent", nil);
		AllBorderGuardKeys = 1;
	end;
end;

------------------------------------------------------------
-- Adds the Tear of Asha objective to the player.
------------------------------------------------------------
function AddTearOfAshaObjective()
	if ( GetObjectiveState( 'TearOfAsha' ) ~= OBJECTIVE_ACTIVE and TearOfAshaObjectiveActive ~= 1 ) then  
		StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneAshaStart/DialogScene.xdb#xpointer(/DialogScene)");
		SetObjectiveState( "TearOfAsha", OBJECTIVE_ACTIVE );
		sleep(1);
		TearOfAshaObjectiveActive = 1; 
		Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "TearOfAshaRegion", nil);
	end; 
end;

------------------------------------------------------------
-- Checks if the player has setup the Tear of Asha in the  
-- Inferno Town.
------------------------------------------------------------
function CheckTearOfAsha()
	while 1 do 
		if GetTownBuildingLevel( "InfernoTown", TOWN_BUILDING_GRAIL ) == 1 and GrailBuilt ~= 1 then
			StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneAshaEnd/DialogScene.xdb#xpointer(/DialogScene)");
			PlayVisualEffect("/Effects/_(Effect)/Buildings/Towns/DemonSoveren_Citadel.(Effect).xdb#xpointer(/Effect)", "InfernoTown", "", 0, 0, 0, 0, 0);
			SetObjectiveState( "TearOfAsha", OBJECTIVE_COMPLETED );	
			sleep(1);		
			LevelUpHero('Deleb');
			LevelUpHero('Marder');
			GrailBuilt = 1;
			break;
		end;
		sleep(15);
	end;
end;

-----------------------------------------------------
--                                                 --
--                    START                        --
--                                                 --
-----------------------------------------------------
if GetDifficulty() == DIFFICULTY_HARD then
	Difficulty = 0.5;
end;
if GetDifficulty() == DIFFICULTY_HEROIC then
	Difficulty = 0.55; 
end;

StartDialogScene("/DialogScenes/Demonic Defense/DialogSceneStart/DialogScene.xdb#xpointer(/DialogScene)");

AddObjectCreatures("InfernoTown", CREATURE_FAMILIAR, LVL1GROWTH/START_RATIO);
AddObjectCreatures("InfernoTown", CREATURE_DEMON, LVL2GROWTH/START_RATIO);
AddObjectCreatures("InfernoTown", CREATURE_HELL_HOUND, LVL3GROWTH/START_RATIO);
AddObjectCreatures("InfernoTown", CREATURE_SUCCUBUS, LVL4GROWTH/START_RATIO);
AddObjectCreatures("InfernoTown", CREATURE_NIGHTMARE, LVL5GROWTH/START_RATIO);
AddObjectCreatures("InfernoTown", CREATURE_PIT_FIEND, LVL6GROWTH/START_RATIO);

SetPlayerResources(PLAYER_1, 15, 15, 8, 8, 8, 8, 15000);
SetPlayerResources(PLAYER_2, 999, 999, 999, 999, 999, 999, 500000);

AllowHeroHiringByRaceInTown("InfernoTown", -1, 0);

SetObjectiveState( "Objective0", OBJECTIVE_ACTIVE );
SetObjectiveState( "Objective1", OBJECTIVE_ACTIVE );
SetObjectiveState( "Objective2", OBJECTIVE_ACTIVE );
SetObjectiveState( "Objective3", OBJECTIVE_ACTIVE );

EnableHeroAI("Ingvar",nil);
EnableHeroAI("Sarge",nil);
EnableHeroAI("Ossir",nil);
EnableHeroAI("Sufi",nil);

SetRegionBlocked("InfernoEntranceRegion", true, PLAYER_1); 

OpenCircleFog(71, 89, 0, 4, PLAYER_1);

Trigger(OBJECT_CAPTURE_TRIGGER, "AcademyTown", "town1capture");
Trigger(OBJECT_CAPTURE_TRIGGER, "AcademyTown", "town1capture");
Trigger(OBJECT_CAPTURE_TRIGGER, "FortressTown", "town1capture");
Trigger(OBJECT_CAPTURE_TRIGGER, "HavenTown", "town1capture");
Trigger(OBJECT_CAPTURE_TRIGGER, "SylvanTown", "town1capture");
Trigger(OBJECT_CAPTURE_TRIGGER, "InfernoTown", "InfernoCapture");
Trigger(OBJECT_TOUCH_TRIGGER,"LavaTowerSwitch1","QuestionSabotageFortressTown");
Trigger(OBJECT_TOUCH_TRIGGER,"LavaTowerSwitch2","QuestionSabotageHavenTown");
Trigger(OBJECT_TOUCH_TRIGGER,"LavaTowerSwitch3","QuestionSabotageSylvanTown");
Trigger(OBJECT_TOUCH_TRIGGER,"LavaTowerSwitch4","QuestionSabotageAcademyTown");
Trigger(OBJECT_TOUCH_TRIGGER,"LavaTowerSwitch5","QuestionSabotageHero");
Trigger(OBJECT_TOUCH_TRIGGER, "ArtifactGatingBuilding1", "QuestionExchangeArtifacts");
Trigger(OBJECT_TOUCH_TRIGGER, "ArtifactGatingBuilding2", "QuestionExchangeArtifacts");
Trigger(OBJECT_TOUCH_TRIGGER, "ArtifactGatingBuilding3", "QuestionExchangeArtifacts");
Trigger(OBJECT_TOUCH_TRIGGER, "ArtifactGatingBuilding4", "QuestionExchangeArtifacts");
Trigger(OBJECT_TOUCH_TRIGGER, "SpellGatingBuilding1", "QuestionExchangeSpells");
Trigger(OBJECT_TOUCH_TRIGGER, "SpellGatingBuilding2", "QuestionExchangeSpells");
Trigger(OBJECT_TOUCH_TRIGGER, "SpellGatingBuilding3", "QuestionExchangeSpells");
Trigger(OBJECT_TOUCH_TRIGGER, "SpellGatingBuilding4", "QuestionExchangeSpells");
Trigger(OBJECT_TOUCH_TRIGGER, "StatGatingBuilding1", "QuestionExchangeHeroStats");
Trigger(OBJECT_TOUCH_TRIGGER, "StatGatingBuilding2", "QuestionExchangeHeroStats");
Trigger(OBJECT_TOUCH_TRIGGER, "StatGatingBuilding3", "QuestionExchangeHeroStats");
Trigger(OBJECT_TOUCH_TRIGGER, "StatGatingBuilding4", "QuestionExchangeHeroStats");
Trigger(OBJECT_TOUCH_TRIGGER, "MercenaryCamp1", "VisitMercenaryCamp1");
Trigger(OBJECT_TOUCH_TRIGGER, "MercenaryCamp2", "VisitMercenaryCamp2");
Trigger(OBJECT_TOUCH_TRIGGER, "MercenaryCamp3", "VisitMercenaryCamp3");
Trigger(OBJECT_TOUCH_TRIGGER, "MercenaryCamp4", "VisitMercenaryCamp4");
Trigger(OBJECT_TOUCH_TRIGGER, "MercenaryCamp5", "VisitMercenaryCamp5");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower1", "VisitMarlettoTower1");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower2", "VisitMarlettoTower2");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower3", "VisitMarlettoTower3");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower4", "VisitMarlettoTower4");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower5", "VisitMarlettoTower5");
Trigger(OBJECT_TOUCH_TRIGGER, "MarlettoTower6", "VisitMarlettoTower6");
Trigger(OBJECT_TOUCH_TRIGGER, "Revelation1", "VisitRevelation1");
Trigger(OBJECT_TOUCH_TRIGGER, "Revelation2", "VisitRevelation2");
Trigger(OBJECT_TOUCH_TRIGGER, "Revelation3", "VisitRevelation3");
Trigger(OBJECT_TOUCH_TRIGGER, "Revelation4", "VisitRevelation4");
Trigger(OBJECT_TOUCH_TRIGGER, "Revelation5", "VisitRevelation5");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium1", "VisitPlanetarium1");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium2", "VisitPlanetarium2");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium3", "VisitPlanetarium3");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium4", "VisitPlanetarium4");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium5", "VisitPlanetarium5");
Trigger(OBJECT_TOUCH_TRIGGER, "Planetarium6", "VisitPlanetarium6");
Trigger(PLAYER_REMOVE_HERO_TRIGGER, PLAYER_1, "PlayDialogSceneLoss");
Trigger(PLAYER_REMOVE_HERO_TRIGGER, PLAYER_2, "CheckDefeatAll");
Trigger(PLAYER_REMOVE_HERO_TRIGGER, PLAYER_3, "CheckDefeatAll");
Trigger(PLAYER_REMOVE_HERO_TRIGGER, PLAYER_4, "CheckDefeatAll");
Trigger(PLAYER_REMOVE_HERO_TRIGGER, PLAYER_5, "CheckDefeatAll");
Trigger(OBJECT_TOUCH_TRIGGER, "BlueKeyMasterTent", "CheckAllBorderGuardKeys");
Trigger(OBJECT_TOUCH_TRIGGER, "GreenKeyMasterTent", "CheckAllBorderGuardKeys");
Trigger(OBJECT_TOUCH_TRIGGER, "OrangeKeyMasterTent", "CheckAllBorderGuardKeys");
Trigger(OBJECT_TOUCH_TRIGGER, "YellowKeyMasterTent", "CheckAllBorderGuardKeys");
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "WightsRegion", "AddObjective4");
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "TearOfAshaRegion", "AddTearOfAshaObjective");
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "StatsGatingRegion", "PlayDialogSceneStatsGatingBuilding");
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "SpellsGatingRegion", "PlayDialogSceneSpellsGatingBuilding");
Trigger(REGION_ENTER_WITHOUT_STOP_TRIGGER, "ArtifactsGatingRegion", "PlayDialogSceneArtifactsGatingBuilding");
Trigger(NEW_DAY_TRIGGER,"NewDay");

startThread(CheckTearOfAsha);

-----------------------------------------------------
--                                                 --
--                    END                          --
--                                                 --
-----------------------------------------------------

