Index: binaries/data/mods/public/gui/common/functions_global_object.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_global_object.js	(revision 8123)
+++ binaries/data/mods/public/gui/common/functions_global_object.js	(working copy)
@@ -6,7 +6,7 @@
 // *******************************************
 // messageBox
 // *******************************************
-// @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions
+// @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions, arr mbButtonsCode
 // @return:     void
 // @desc:       Displays a new modal message box.
 // *******************************************
Index: binaries/data/mods/public/gui/page_summary.xml
===================================================================
--- binaries/data/mods/public/gui/page_summary.xml	(revision 0)
+++ binaries/data/mods/public/gui/page_summary.xml	(revision 0)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<page>
+	<include>common/setup.xml</include>
+    <include>common/styles.xml</include>
+    <include>common/sprite1.xml</include>
+    <include>common/init.xml</include>
+	<include>summary/summary.xml</include>
+	<include>common/global.xml</include>
+</page>
Index: binaries/data/mods/public/gui/session_new/session.js
===================================================================
--- binaries/data/mods/public/gui/session_new/session.js	(revision 8123)
+++ binaries/data/mods/public/gui/session_new/session.js	(working copy)
@@ -17,6 +17,8 @@
 // Cache EntityStates
 var g_EntityStates = {}; // {id:entState}
 
+var g_GameEnded = false;
+
 function GetEntityState(entId)
 {
 	if (!(entId in g_EntityStates))
@@ -73,9 +75,25 @@
 
 function leaveGame()
 {
+	var simState = Engine.GuiInterfaceCall("GetSimulationState");
+	var playerState = simState.players[Engine.GetPlayerID()];
+	var gameResult = "You have been defeated...";
+	if (playerState.state == "won")
+	{
+		gameResult = "You have won a battle!";
+	}
+	
+	// post defeat player command
+	Engine.PostNetworkCommand({
+		"type": "defeat-player",
+		"playerId": Engine.GetPlayerID()
+	});
+	
 	stopMusic();
 	endGame();
-	Engine.SwitchGuiPage("page_pregame.xml");
+	
+	Engine.SwitchGuiPage("page_summary.xml", { "gameResult" : gameResult });
+	
 }
 
 // Return some data that we'll use when hotloading this file after changes
@@ -86,6 +104,8 @@
 
 function onTick()
 {
+	checkPlayerState();
+
 	while (true)
 	{
 		var message = Engine.PollNetworkClient();
@@ -119,6 +139,26 @@
 		getGUIObjectByName("resourcePop").textcolor = "0 0 0";
 }
 
+function checkPlayerState()
+{
+	var simState = Engine.GuiInterfaceCall("GetSimulationState");
+	var playerState = simState.players[Engine.GetPlayerID()];
+	
+	if(!g_GameEnded)
+	{
+		if (playerState.state == "defeated")
+		{
+			g_GameEnded = true;
+			messageBox(400, 200, "You have been defeated... Want you leave the game now?", "Defeat", 0, ["Yes", "No!"], [leaveGame, null]);
+		}
+		else if (playerState.state == "won")
+		{
+			g_GameEnded = true;
+			messageBox(400, 200, "You have won a battle! Want you leave the game now?", "Victory", 0, ["Yes", "No!"], [leaveGame, null]);
+		}
+	}
+}
+
 function onSimulationUpdate()
 {
 	g_Selection.dirty = false;
Index: binaries/data/mods/public/gui/summary/summary.js
===================================================================
--- binaries/data/mods/public/gui/summary/summary.js	(revision 0)
+++ binaries/data/mods/public/gui/summary/summary.js	(revision 0)
@@ -0,0 +1,5 @@
+function init(data)
+{
+	getGUIObjectByName ("summaryTitleBar").caption = "Summary";
+	getGUIObjectByName ("summaryText").caption = data.gameResult;
+}
Index: binaries/data/mods/public/gui/summary/summary.xml
===================================================================
--- binaries/data/mods/public/gui/summary/summary.xml	(revision 0)
+++ binaries/data/mods/public/gui/summary/summary.xml	(revision 0)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+==========================================
+- SUMMARY SCREEN -
+==========================================
+-->
+
+<objects>
+	<script file="gui/summary/summary.js"/>
+	<object name="summary" 
+			type="image"
+			sprite="bkFillBlack"
+		>
+		<!--
+		==========================================
+		- SUMMARY SCREEN - WINDOW
+		==========================================
+		-->
+
+		<object name="summaryWindow"
+			style="wheatWindowGranite"
+			type="image"
+			size="25 35 100%-25 100%-25"
+		>
+			<object	name="summaryTitleBar"
+				style="wheatWindowTitleBar"
+				type="button"
+			/>
+			
+			<object name="summaryText"
+				type="text"
+				size="50 50 100%-50 100%-200"
+				font="serif-16"
+				text_align="center"
+				text_valign="center"
+			/>
+			
+			<object type="button" style="wheatButton" size="100%-150 100%-40 100% 100%">
+				Main menu
+				<action on="Press"><![CDATA[
+					Engine.SwitchGuiPage("page_pregame.xml");
+				]]></action>
+			</object>
+		</object>
+	</object>
+</objects>
Index: binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml
===================================================================
--- binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml	(revision 8123)
+++ binaries/data/mods/public/maps/scenarios/Pathfinding_demo.xml	(working copy)
@@ -31,7 +31,8 @@
 {
   "NumPlayers":1,
   "Description":"A map for testing unit movement algorithms.",
-  "DefaultStance":"holdfire"
+  "DefaultStance":"holdfire",
+  "GameType":"endless"
 }
 ]]></ScriptSettings>
 	<Entities>
Index: binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml
===================================================================
--- binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml	(revision 8123)
+++ binaries/data/mods/public/maps/scenarios/Pathfinding_terrain_demo.xml	(working copy)
@@ -30,7 +30,8 @@
 	<ScriptSettings><![CDATA[
 {
   "NumPlayers":1,
-  "Description":"A map for testing movement costs and terrain properties in the A* pathfinder."
+  "Description":"A map for testing movement costs and terrain properties in the A* pathfinder.",
+  "GameType":"endless"
 }
 ]]></ScriptSettings>
 	<Entities>
Index: binaries/data/mods/public/maps/scenarios/Units_demo.xml
===================================================================
--- binaries/data/mods/public/maps/scenarios/Units_demo.xml	(revision 8123)
+++ binaries/data/mods/public/maps/scenarios/Units_demo.xml	(working copy)
@@ -84,7 +84,8 @@
 	<ScriptSettings><![CDATA[
 {
   "NumPlayers":1,
-  "Description":"Every unit in the game."
+  "Description":"Every unit in the game.",
+  "GameType":"endless"
 }
 ]]></ScriptSettings>
 	<Entities/>
Index: binaries/data/mods/public/simulation/components/EndGameManager.js
===================================================================
--- binaries/data/mods/public/simulation/components/EndGameManager.js	(revision 0)
+++ binaries/data/mods/public/simulation/components/EndGameManager.js	(revision 0)
@@ -0,0 +1,101 @@
+// Interval, which defines how often game will check end game conditions
+var g_ProgressInterval = 1000;
+
+/* 
+	EndGameManager is the system component, which regularly (by timer) checks 
+	victory/defeat conditions and if it is satisfied ends the game
+*/
+function EndGameManager() {}
+
+EndGameManager.prototype.Schema =
+	"<a:component type='system'/><empty/>";
+	
+EndGameManager.prototype.Init = function()
+{
+	// Game type
+	// given from the map settings
+	// one of: "conquest" and "endless"
+	// "conquest" by default
+	this.gameType = "conquest";
+}
+	
+// Should be started from LoadMapSettings function
+// when gameType is setted
+EndGameManager.prototype.Start = function()
+{
+	if (this.gameType != "endless")
+	{
+		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+		this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, {});
+	}
+}
+
+EndGameManager.prototype.OnDestroy = function()
+{
+	if (this.timer)
+	{
+		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+		cmpTimer.CancelTimer(this.timer);
+	}
+};
+
+EndGameManager.prototype.SetGameType = function(/*string*/ new_game_type)
+{
+	
+	this.gameType = new_game_type;
+}
+
+EndGameManager.prototype.ProgressTimeout = function(data)
+{
+	this.UpdatePlayerStates();
+	
+	// repeat the timer
+	var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
+	this.timer = cmpTimer.SetTimeout(this.entity, IID_EndGameManager, "ProgressTimeout", g_ProgressInterval, data);
+}
+
+EndGameManager.prototype.UpdatePlayerStates = function()
+{
+	var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
+	switch (this.gameType)
+	{
+		case "conquest":
+			for (var i = 0; i < cmpPlayerManager.GetNumPlayers(); i++)
+			{
+				var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
+				var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
+				if (cmpPlayer.GetState() == "active")
+				{
+					if (cmpPlayer.GetConquestCriticalEntitiesCount() == 0)
+					{
+						Engine.PostMessage(playerEntityId, MT_PlayerDefeated, null);
+					}
+				}
+			}
+			// TODO: update this code for allies
+			var alivePlayersCount = 0;
+			var lastAlivePlayerId = -1;
+			// i starts from 1 because we not count gaia player
+			for (var i = 1; i < cmpPlayerManager.GetNumPlayers(); i++)
+			{
+				var playerEntityId = cmpPlayerManager.GetPlayerByID(i);
+				var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
+				if (cmpPlayer.GetState() == "active")
+				{
+					alivePlayersCount++;
+					lastAlivePlayerId = i;
+				}
+			}
+			if (alivePlayersCount == 1)
+			{
+				var playerEntityId = cmpPlayerManager.GetPlayerByID(lastAlivePlayerId);
+				var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player);
+				cmpPlayer.SetState("won");
+			}
+			break;
+		default:
+			// strange game type ...
+	}
+}
+
+Engine.RegisterComponentType(IID_EndGameManager, "EndGameManager", EndGameManager);
Index: binaries/data/mods/public/simulation/components/GuiInterface.js
===================================================================
--- binaries/data/mods/public/simulation/components/GuiInterface.js	(revision 8123)
+++ binaries/data/mods/public/simulation/components/GuiInterface.js	(working copy)
@@ -36,7 +36,8 @@
 			"popCount": cmpPlayer.GetPopulationCount(),
 			"popLimit": cmpPlayer.GetPopulationLimit(),
 			"resourceCounts": cmpPlayer.GetResourceCounts(),
-			"trainingQueueBlocked": cmpPlayer.IsTrainingQueueBlocked()
+			"trainingQueueBlocked": cmpPlayer.IsTrainingQueueBlocked(),
+			"state": cmpPlayer.GetState()
 		};
 		ret.players.push(playerData);
 	}
Index: binaries/data/mods/public/simulation/components/Identity.js
===================================================================
--- binaries/data/mods/public/simulation/components/Identity.js	(revision 8123)
+++ binaries/data/mods/public/simulation/components/Identity.js	(working copy)
@@ -62,12 +62,14 @@
 						"<value>Mechanical</value>" +
 						"<value>Super</value>" +
 						"<value>Hero</value>" +
+						"<value>Structure</value>" +
 						"<value>Civic</value>" +
 						"<value>Economic</value>" +
 						"<value>Defensive</value>" +
 						"<value>Village</value>" +
 						"<value>Town</value>" +
 						"<value>City</value>" +
+						"<value>ConquestCritical</value>" +
 						"<value a:help='Primary weapon type'>Bow</value>" + // TODO: what are these used for?
 						"<value a:help='Primary weapon type'>Javelin</value>" +
 						"<value a:help='Primary weapon type'>Spear</value>" +
Index: binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js
===================================================================
--- binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js	(revision 0)
+++ binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js	(revision 0)
@@ -0,0 +1 @@
+Engine.RegisterInterface("EndGameManager");
Index: binaries/data/mods/public/simulation/components/Player.js
===================================================================
--- binaries/data/mods/public/simulation/components/Player.js	(revision 8123)
+++ binaries/data/mods/public/simulation/components/Player.js	(working copy)
@@ -19,6 +19,14 @@
 		"metal": 500,	
 		"stone": 1000	
 	};
+	// player game state
+	// one of: "active", "defeated", "won"
+	this.state = "active";
+	// buildings count
+	this.structuresCount = 0;
+	// Count of entites that needed for survive in
+	// game of conquest type
+	this.conquestCriticalEntitiesCount = 0;
 };
 
 Player.prototype.SetPlayerID = function(id)
@@ -146,12 +154,47 @@
 	return true;
 };
 
+Player.prototype.GetState = function()
+{
+	return this.state;
+};
+
+Player.prototype.SetState = function(/*string*/ new_state)
+{
+	this.state = new_state;
+};
+
+Player.prototype.GetStructuresCount = function()
+{
+	return this.structuresCount;
+};
+
+Player.prototype.GetConquestCriticalEntitiesCount = function()
+{
+	return this.conquestCriticalEntitiesCount;
+};
+
 // Keep track of population effects of all entities that
 // become owned or unowned by this player
 Player.prototype.OnGlobalOwnershipChanged = function(msg)
 {
+	var cmpIdentity = Engine.QueryInterface(msg.entity, IID_Identity);
+	// Is this entity a structure?
+	var isStructure = (cmpIdentity && cmpIdentity.GetClassesList().indexOf("Structure") != -1);
+
+	// Is this entity critical in conquest game type
+	var isConquestCritical = (cmpIdentity && cmpIdentity.GetClassesList().indexOf("ConquestCritical") != -1);
+	
 	if (msg.from == this.playerID)
 	{
+		if (isStructure) 
+		{
+			this.structuresCount--;
+		}
+		if (isConquestCritical) 
+		{
+			this.conquestCriticalEntitiesCount--;
+		}
 		var cost = Engine.QueryInterface(msg.entity, IID_Cost);
 		if (cost)
 		{
@@ -162,6 +205,14 @@
 	
 	if (msg.to == this.playerID)
 	{
+		if (isStructure) 
+		{
+			this.structuresCount++;
+		}
+		if (isConquestCritical) 
+		{
+			this.conquestCriticalEntitiesCount++;
+		}
 		var cost = Engine.QueryInterface(msg.entity, IID_Cost);
 		if (cost)
 		{
@@ -171,4 +222,18 @@
 	}
 };
 
+Player.prototype.OnPlayerDefeated = function()
+{
+	this.state = "defeated";
+	// Reassign all players's entities to gaia player
+	var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
+	var entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID);
+	for each (var entity in entities)
+	{
+		// Note: maybe we need to reassign units and buildings only?
+		var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);
+		cmpOwnership.SetOwner(0);
+	}
+}
+
 Engine.RegisterComponentType(IID_Player, "Player", Player);
Index: binaries/data/mods/public/simulation/helpers/Commands.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Commands.js	(revision 8123)
+++ binaries/data/mods/public/simulation/helpers/Commands.js	(working copy)
@@ -143,6 +143,14 @@
 				cmpRallyPoint.Unset();
 		}
 		break;
+		
+	case "defeat-player":
+		// get player entity by playerId
+		var cmpPlayerMananager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
+		var playerEntity = cmpPlayerManager.GetPlayerByID(cmd.playerId);
+		// send to player entity "OnPlayerDefeated" message
+		Engine.PostMessage(playerEntity, MT_PlayerDefeated, null);
+		break;
 
 	default:
 		error("Ignoring unrecognised command type '" + cmd.type + "'");
Index: binaries/data/mods/public/simulation/helpers/Setup.js
===================================================================
--- binaries/data/mods/public/simulation/helpers/Setup.js	(revision 8123)
+++ binaries/data/mods/public/simulation/helpers/Setup.js	(working copy)
@@ -12,6 +12,13 @@
 			cmpUnitAI.SetStance(settings.DefaultStance);
 		}
 	}
+	
+	var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
+	if (settings.GameType)
+	{	
+		cmpEndGameManager.SetGameType(settings.GameType);
+	}
+	cmpEndGameManager.Start();
 }
 
 Engine.RegisterGlobal("LoadMapSettings", LoadMapSettings);
Index: binaries/data/mods/public/simulation/templates/template_structure.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_structure.xml	(revision 8123)
+++ binaries/data/mods/public/simulation/templates/template_structure.xml	(working copy)
@@ -2,6 +2,10 @@
 <Entity parent="template_entity_full">
   <Identity>
     <GenericName>Structure</GenericName>
+	<Classes datatype="tokens">
+		Structure
+		ConquestCritical
+	</Classes>
 	<IconSheet>snPortraitSheetBuildings</IconSheet>
   </Identity>
   <BuildRestrictions>
Index: binaries/data/mods/public/simulation/templates/template_unit.xml
===================================================================
--- binaries/data/mods/public/simulation/templates/template_unit.xml	(revision 8123)
+++ binaries/data/mods/public/simulation/templates/template_unit.xml	(working copy)
@@ -2,6 +2,7 @@
 <Entity parent="template_entity_full">
   <Identity>
     <GenericName>Unit</GenericName>
+	<Classes datatype="tokens">ConquestCritical</Classes>
   </Identity>
   <Minimap>
     <Type>unit</Type>
Index: source/simulation2/components/CCmpRangeManager.cpp
===================================================================
--- source/simulation2/components/CCmpRangeManager.cpp	(revision 8123)
+++ source/simulation2/components/CCmpRangeManager.cpp	(working copy)
@@ -365,6 +365,22 @@
 			m_DebugOverlayLines.clear();
 	}
 
+	virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId)
+	{
+		std::vector<entity_id_t> entities;
+
+		u32 ownerMask = CalcOwnerMask(playerId);
+
+		for (std::map<entity_id_t, EntityData>::const_iterator it = m_EntityData.begin(); it != m_EntityData.end(); ++it)
+		{
+			// Check owner and add to list if corresponds
+			if ((it->second.ownerMask & ownerMask))
+				entities.push_back(it->first);
+		}
+
+		return entities;
+	}
+
 private:
 
 	/**
Index: source/simulation2/components/ICmpRangeManager.cpp
===================================================================
--- source/simulation2/components/ICmpRangeManager.cpp	(revision 8123)
+++ source/simulation2/components/ICmpRangeManager.cpp	(working copy)
@@ -29,4 +29,5 @@
 DEFINE_INTERFACE_METHOD_1("DisableActiveQuery", void, ICmpRangeManager, DisableActiveQuery, ICmpRangeManager::tag_t)
 DEFINE_INTERFACE_METHOD_1("ResetActiveQuery", std::vector<entity_id_t>, ICmpRangeManager, ResetActiveQuery, ICmpRangeManager::tag_t)
 DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpRangeManager, SetDebugOverlay, bool)
+DEFINE_INTERFACE_METHOD_1("GetEntitiesByPlayer", std::vector<entity_id_t>, ICmpRangeManager, GetEntitiesByPlayer, int)
 END_INTERFACE_WRAPPER(RangeManager)
Index: source/simulation2/components/ICmpRangeManager.h
===================================================================
--- source/simulation2/components/ICmpRangeManager.h	(revision 8123)
+++ source/simulation2/components/ICmpRangeManager.h	(working copy)
@@ -116,6 +116,14 @@
 	 */
 	virtual void SetDebugOverlay(bool enabled) = 0;
 
+	/**
+	 * Returns list of all entities for specific player
+	 * Note: this function probably needs to be moved to some new
+	 * CmpEntitiesManager component with all other entities tracking 
+	 * code placed in this component
+	 */
+	virtual std::vector<entity_id_t> GetEntitiesByPlayer(int playerId) = 0;
+
 	DECLARE_INTERFACE_TYPE(RangeManager)
 };
 
Index: source/simulation2/MessageTypes.h
===================================================================
--- source/simulation2/MessageTypes.h	(revision 8123)
+++ source/simulation2/MessageTypes.h	(working copy)
@@ -310,4 +310,19 @@
 	ICmpPathfinder::Path path;
 };
 
+
+/**
+ * Sent to player when it was defeated
+ */
+class CMessagePlayerDefeated : public CMessage
+{
+public:
+    DEFAULT_MESSAGE_IMPL(PlayerDefeated)
+
+    CMessagePlayerDefeated()
+    {
+    }
+};
+
+
 #endif // INCLUDED_MESSAGETYPES
Index: source/simulation2/scripting/MessageTypeConversions.cpp
===================================================================
--- source/simulation2/scripting/MessageTypeConversions.cpp	(revision 8123)
+++ source/simulation2/scripting/MessageTypeConversions.cpp	(working copy)
@@ -245,6 +245,18 @@
 
 ////////////////////////////////////////////////////////////////
 
+jsval CMessagePlayerDefeated::ToJSVal(ScriptInterface& UNUSED(scriptInterface)) const
+{
+	return JSVAL_VOID;
+}
+
+CMessage* CMessagePlayerDefeated::FromJSVal(ScriptInterface& UNUSED(scriptInterface), jsval UNUSED(val))
+{
+	return new CMessagePlayerDefeated();
+}
+
+////////////////////////////////////////////////////////////////
+
 CMessage* CMessageFromJSVal(int mtid, ScriptInterface& scriptingInterface, jsval val)
 {
 	switch (mtid)
Index: source/simulation2/Simulation2.cpp
===================================================================
--- source/simulation2/Simulation2.cpp	(revision 8123)
+++ source/simulation2/Simulation2.cpp	(working copy)
@@ -112,6 +112,7 @@
 			LOAD_SCRIPTED_COMPONENT("GuiInterface");
 			LOAD_SCRIPTED_COMPONENT("PlayerManager");
 			LOAD_SCRIPTED_COMPONENT("Timer");
+			LOAD_SCRIPTED_COMPONENT("EndGameManager");
 
 #undef LOAD_SCRIPTED_COMPONENT
 		}
Index: source/simulation2/TypeList.h
===================================================================
--- source/simulation2/TypeList.h	(revision 8123)
+++ source/simulation2/TypeList.h	(working copy)
@@ -45,6 +45,7 @@
 MESSAGE(RangeUpdate)
 MESSAGE(TerrainChanged)
 MESSAGE(PathResult)
+MESSAGE(PlayerDefeated)
 
 // TemplateManager must come before all other (non-test) components,
 // so that it is the first to be (de)serialized
