Nebelvolk Skript - Entwicklung

Dieses Skript ist von der Nebelvolk Map kopiert aus dem Mappack.
Idee stammt von NintendoDS der zunächst eine Singleplayermap zum Nebelvolk gebastelt hatte und das auf MP übertragen wollte. Ich habe das Skript dann etwas überarbeitet

Code

--Script.Load( "maps\\user\\Nebelvolk.lua" )
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    --
    -- Mapname:(3) Nebelvolk_MP
    --
    -- Author: NDSfan
    --
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
function GameCallback_OnGameStart()
 
	Script.Load(Folders.MapTools.."Ai\\Support.lua")
    Script.Load( "Data\\Script\\MapTools\\MultiPlayer\\MultiplayerTools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\Tools.lua" )  
    Script.Load( "Data\\Script\\MapTools\\WeatherSets.lua" )
    IncludeGlobals("Comfort")
 
    -- Init  global MP stuff
    MultiplayerTools.InitCameraPositionsForPlayers()    
    MultiplayerTools.SetUpGameLogicOnMPGameConfig()
    --Diese Funktion muß wegen der freien Peacetime deaktiviert sein, sie wird erst später nach dem Ablauf der Peacetime gesetzt
    --MultiplayerTools.SetUpDiplomacyOnMPGameConfig()
 
    if XNetwork.Manager_DoesExist() == 0 then      
        for i = 1, 8 do
            MultiplayerTools.DeleteFastGameStuff(i)
        end
        local PlayerID = GUI.GetPlayerID()
        Logic.PlayerSetIsHumanFlag( PlayerID, 1 )
        Logic.PlayerSetGameStateToPlaying( PlayerID )
        Logic.SuspendAllEntities() --Hiermit wird festgelegt, das niemand seine Einheiten bewegen kann(alles andere waehre unfair für den Spieler der den Ws einstellen muss
    end
	mpc_playernames = {}
	mpc_playerteams = {}
	for i = 1,8 do
		mpc_playernames[i] = XNetwork.GameInformation_GetLogicPlayerUserName(i)
		mpc_playerteams[i] = XNetwork.GameInformation_GetLogicPlayerTeam(i)
	end
	LoadComforts()
	AddPeriodicSummer(10) 
	SetupEvelanceWeatherGfxSet()
	Mission_InitLocalResources()
	LocalMusic.UseSet = DARKMOORMUSIC
	StartCountdown( 5, StartFriedenszeitBriefing, false )
 
	XGUIEng.TransferMaterials("Hero9_Berserk", 827)   --Berserker
    XGUIEng.TransferMaterials("Research_BlisteringCannonballs", "Build_Alchemist")  --feuertopf
    XGUIEng.TransferMaterials(371, "Build_Blacksmith")  --eisensog
	XGUIEng.TransferMaterials("Hero8_Poison", "Build_Stables") --altar
	XGUIEng.TransferMaterials("Scout_Torches", "Build_Foundry") --altarSkirm
 
	gvMaximalWohnstaetten = 12
	gvMaximalAltare = 3
	StartNebelvolkModification()
 
	-- Nur für Singleplayer:
	--MapEditor_CreateHQDefeatCondition()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function Mission_InitLocalResources()
    local HumenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()
    -- Dies sind die Startresourcen für alle menchlichen Spieler.
	local InitGoldRaw	= 600
	local InitClayRaw	= 1500
	local InitWoodRaw	= 1400
	local InitStoneRaw	= 800
	local InitIronRaw	= 300
	local InitSulfurRaw	= 250
 
    -- Add Players Resources
    for i = 1, 8 do
        Tools.GiveResouces(i, InitGoldRaw , InitClayRaw,InitWoodRaw, InitStoneRaw,InitIronRaw,InitSulfurRaw)
    end
	Tools.GiveResouces(3, InitGoldRaw*0.5 , InitClayRaw,InitWoodRaw*0.5, InitStoneRaw,InitIronRaw*0.5,InitSulfurRaw*0.5)
end
 
-- Comforts:
 
function LoadComforts()
 
 
	function Comfort_TrackEntitysIni()	
		-- Trackt alle initialisierten Entitys
		Track_Entity_Table = {}
		for _pId = 0,8 do
			Track_Entity_Table[_pId] = {}
		end
		Comfort_TrackEntityIni = function(_pId,_eType)
			Track_Entity_Table[_pId][_eType] = {}
			Track_Entity_Table[_pId]["C".._eType] = {} -- hier ob Gebäude fertig konstruiert ist
			Track_Entity_Table[_pId][_eType].tracked = true
			if not(_pId == 0) then
				local temp = {Logic.GetPlayerEntities(_pId, _eType,1)}
				if temp[1] > 0 then
					local latestEntity = temp[2]
					for u = 1, Logic.GetNumberOfEntitiesOfTypeOfPlayer(_pId, _eType) do
						if latestEntity ~= 0 then
							table.insert(Track_Entity_Table[_pId][_eType], latestEntity)
							table.insert(Track_Entity_Table[_pId]["C".._eType], Logic.IsConstructionComplete(latestEntity))
						end		
						latestEntity = Logic.GetNextEntityOfPlayerOfType(latestEntity);
					end
				end			
			else
				Track_Entity_Table[_pId][_eType] = SucheAufDerWelt(_pId,_eType)
				for i = 1, table.getn(Track_Entity_Table[_pId][_eType]) do
					table.insert(Track_Entity_Table[_pId]["C".._eType][i], Logic.IsConstructionComplete(latestEntity))
				end
			end
		end
 
		Comfort_TrackEntity_Created = function(_eId,_pId)
			if _eId == nil then
				_eId = Event.GetEntityID()
				_pId = GetPlayer(_eId)
			end
			local _eType = Logic.GetEntityType(_eId)
			--if Logic.IsBuilding(_eId) == 1 then
			if Comfort_TrackEntity_IsTracked(_pId,_eType) then
				if Track_Entity_Table[_pId][_eType].tracked then
					local _drin = false
					for i = 1, table.getn(Track_Entity_Table[_pId][_eType]) do
						if _eId == Track_Entity_Table[_pId][_eType][i] then
							_drin = true
							Track_Entity_Table[_pId]["C".._eType][i] = Logic.IsConstructionComplete(_eId)
							break
						end
					end
					if not _drin then
						table.insert(Track_Entity_Table[_pId][_eType], _eId)
						table.insert(Track_Entity_Table[_pId]["C".._eType], Logic.IsConstructionComplete(_eId))
					end
				end
			end
		end
 
		Comfort_TrackEntity_Destroyed = function()
			local _eId = Event.GetEntityID()
			local _pId = GetPlayer(_eId)
			local _eType = Logic.GetEntityType(_eId)
			if Comfort_TrackEntity_IsTracked(_pId,_eType) then					
				for i = 1, table.getn(Track_Entity_Table[_pId][_eType]) do
					if _eId == Track_Entity_Table[_pId][_eType][i] then
						table.remove(Track_Entity_Table[_pId][_eType], i)
						table.remove(Track_Entity_Table[_pId]["C".._eType], i)
						break
					end
				end
			end	
		end	
 
		Comfort_TrackEntity_IsTracked = function(_pId, _eType, _TypeOrId)
			if _TypeOrId == false then _eType = Logic.GetEntityType(_eTypeOrId) end
			if type(Track_Entity_Table[_pId]) == "table" then
				if type(Track_Entity_Table[_pId][_eType]) == "table" then
				else return false
				end
			else return false
			end
			return Track_Entity_Table[_pId][_eType].tracked	
		end		
		Comfort_TrackEntity_RemoveTracking = function(_pId, _eType)
			Track_Entity_Table[_pId][_eType] = {}
			Track_Entity_Table[_pId][_eType].tracked = false
		end
		Comfort_TrackEntity_GetCount = function(_pId,_eType,_onlyConstructed)
			assert( type(_pId) == "number", "Spieler ID muss Zahl sein!" )
			assert( type(_eType) == "number", "Entity Typ muss Zahl sein!" )
			assert( Comfort_TrackEntity_IsTracked(_pId,_eType), "Entity Typ wird nicht getrackt!" )
			_onlyConstructed = _onlyConstructed or false
			if not(_onlyConstructed) then
				return table.getn(Track_Entity_Table[_pId][_eType])
			else
				local _count = 0
				for i = 1, table.getn(Track_Entity_Table[_pId]["C".._eType]) do
					_count = _count + Track_Entity_Table[_pId]["C".._eType][i]
				end
				return _count
			end
		end
 
		Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_CREATED, "", "Comfort_TrackEntity_Created", 1)
		Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_DESTROYED, "", "Comfort_TrackEntity_Destroyed", 1)
	end
 
	function Tribute_Comforts()
 
		AddTribute = function( _tribute )
			assert( type( _tribute ) == "table", "Tribut muß ein Table sein" );
			assert( type( _tribute.text ) == "string", "Tribut.text muß ein String sein" );
			assert( type( _tribute.cost ) == "table", "Tribut.cost muß ein Table sein" );
			assert( type( _tribute.pId ) == "number", "Tribut.pId muß eine Nummer sein" );
			assert( not _tribute.Tribute , "Tribut.Tribute darf nicht vorbelegt sein");
 
			uniqueTributeCounter = uniqueTributeCounter or 1;
			_tribute.Tribute = uniqueTributeCounter;
			uniqueTributeCounter = uniqueTributeCounter + 1;
 
			local tResCost = {};
			for k, v in pairs( _tribute.cost ) do
				assert( ResourceType[k] );
				assert( type( v ) == "number" );
				table.insert( tResCost, ResourceType[k] );
				table.insert( tResCost, v );
			end
 
			Logic.AddTribute( _tribute.pId, _tribute.Tribute, 0, 0, _tribute.text, unpack( tResCost ) );
			SetupTributePaid( _tribute );
			return _tribute.Tribute;
		end
 
		CreateATribute = function(_pId, _text, _cost, _callback)
			local tribute =  {};
			tribute.pId = _pId;
			tribute.text = _text;
			tribute.cost = _cost;
			tribute.Callback = _callback;
			return tribute
		end
 
		GameCallback_FulfillTribute = function()
			return 1
		end
 
 
	end
 
	function Umlaute( _text )
		local texttype = type( _text );
		if texttype == "string" then
			_text = string.gsub( _text, "ä", "\195\164" );
			_text = string.gsub( _text, "ö", "\195\182" );
			_text = string.gsub( _text, "ü", "\195\188" );
			_text = string.gsub( _text, "ß", "\195\159" );
			_text = string.gsub( _text, "Ä", "\195\132" );
			_text = string.gsub( _text, "Ö", "\195\150" );
			_text = string.gsub( _text, "Ü", "\195\156" );
			return _text;
		elseif texttype == "table" then
			for k,v in _text do
				_text[k] = Umlaute( v );
			end
			return _text;
		else
			return _text;
		end 
	end
 
	function AutoUmlaut()
		StartBriefingUmlauteOrig = StartBriefing;
		StartBriefing = function( _briefing )
			StartBriefingUmlauteOrig( Umlaute( _briefing ) );
		end
 
		CreateNPCUmlauteOrig = CreateNPC;
		CreateNPC = function( _npc )
			CreateNPCUmlauteOrig( Umlaute( _npc ) );
		end
 
		MessageUmlauteOrig = Message;
		Message = function( _text )
			MessageUmlauteOrig( Umlaute( tostring( _text ) ) );
		end 
	end
 
 
	function CxToolsInclude()
		CxTools = CxTools or {}; 
 
		function CxTools:Init()
			CxTools:InitUnpackFix();
			CxTools:InitTriggers();
		end
 
		--#########################################################################
		--###
		--###	 Utility Functions
		--###
 
		function CxTools.Panic(_text)
			Message("-----------------------------------------");
			Message("Error: " .. tostring(_text));
			Message("-----------------------------------------");
			--assert(true,tostring(_text))
			local _table = { text = _text };
			StartSimpleJob(CxTools.GlobalTriggerDebug, _table);
		end
 
		--#########################################################################
		--###
		--###	 unpack()-Fix
		--###
 
		function CxTools:InitUnpackFix()
			if not unpack{true} then
				local unpack2;
				unpack2 =
					function(_table, _i)
						_i = _i or 1;
						assert(type(_table) == "table");
						if _i <= table.getn(_table) then
							return _table[_i], unpack2(_table, _i + 1);
						end
					end
 
				unpack = unpack2;    
			end
		end
 
		--#########################################################################
		--###
		--###	 Trigger Functions
		--###
 
		--Trigger-Fix / improvement
		function CxTools:InitTriggers()
			CxTools.tTriggers = {};
			CxTools.nTriggerNum = 0;
			CxTools.GlobalTriggerConditionCallbackWrapperName = "TriggerConditionCallbackWrapper";
			CxTools.GlobalTriggerActionCallbackWrapperName = "TriggerActionCallbackWrapper";
			CxTools.GlobalTriggerDebug = "MessageTriggerDebug";
 
			CxTools.Mission_OnSaveGameLoaded = Mission_OnSaveGameLoaded;
			Mission_OnSaveGameLoaded = function() CxTools:HookAPITrigger(); CxTools.Mission_OnSaveGameLoaded(); end;
			CxTools:HookAPITrigger();
 
			assert( not _G[CxTools.GlobalTriggerConditionCallbackWrapperName] );
			_G[CxTools.GlobalTriggerConditionCallbackWrapperName] = 
				function(_sId)
					return CxTools:callbackWrapperCondition(_sId);
				end
 
			assert( not _G[CxTools.GlobalTriggerActionCallbackWrapperName] );
			_G[CxTools.GlobalTriggerActionCallbackWrapperName] = 
				function(_sId)
					return CxTools:callbackWrapperAction(_sId);
				end
 
			--Comfort Functions
			CxTools.StartSimpleJobOrig = StartSimpleJob;
			StartSimpleJob = 
				 function(...)
					 return CxTools:StartSimpleJob(unpack(arg));
				 end
 
			CxTools.StartSimpleHiResJobOrig = StartSimpleHiResJob;
				StartSimpleHiResJob = 
					function(...)
						return CxTools:StartSimpleHiResJob(unpack(arg));
					end
 
			CxTools.StartJobOrig = StartJob;
			StartJob = 
				function(...)
					return CxTools:StartJob(unpack(arg));
				end
 
			CxTools.StartHiResJobOrig = StartHiResJob;
			StartHiResJob = 
				function(...)
					return CxTools:StartHiResJob(unpack(arg));
				end
 
			assert( not _G[CxTools.GlobalTriggerDebug] );
			_G[CxTools.GlobalTriggerDebug] = 
				function(_table)
					assert(type(_table) == "table");
					_table.seconds = _table.seconds or 0;
					_table.seconds = _table.seconds + 1;
					if math.mod(_table.seconds, 15) == 0 then
								Message("-----------------------------------------");
								Message("Error: " .. tostring(_table.text));
								Message("-----------------------------------------");
						if _table.seconds == 45 then
						return true;
					end
					end
				end
		end
 
		function CxTools:HookAPITrigger()
			CxTools.RequestTriggerOrig = Trigger.RequestTrigger;
			CxTools.UnrequestTriggerOrig = Trigger.UnrequestTrigger;
			Trigger.RequestTrigger = 
				function(_event, _fCond, _fAction, _isActive, _pCond, _pAction)
					return CxTools:AddTrigger(_event, _fCond, _fAction, _isActive, _pCond, _pAction);
				end
			Trigger.UnrequestTrigger =
				function( _id )
					CxTools:UnrequestTrigger( _id );
				end
		end
 
		function CxTools:AddTrigger( _eventType, _funcCondition, _funcAction, _isActive, _paramsCond, _paramsAction )
			assert(type(_eventType) == "number");
			assert(not _funcCondition or type(_funcCondition) == "string" or type(_funcCondition) == "function" );
			assert(type(_funcAction) == "string" or type(_funcAction) == "function");
 
			if _isActive == true then
				_isActive = 1;
			elseif _isActive == false then
				_isActive = 0;
			else
				assert( type(_isActive) == "number" and (_isActive == 0 or _isActive == 1) );
			end
 
			_paramsCond = _paramsCond or {};
			_paramsAction = _paramsAction or {};
 
			local sTriggerId = table.getn(CxTools.tTriggers) + 1;
			if sTriggerId > CxTools.nTriggerNum then
				CxTools.nTriggerNum = sTriggerId;
			end
 
			local entry = {};
			entry.sId = sTriggerId;
			if _funcCondition ~= "" then
				 entry.funcCondition = _funcCondition;
			end
			entry.funcAction = _funcAction;
			entry.paramsCond = _paramsCond;
			entry.paramsAction = _paramsAction;
 
			local condition = CxTools.GlobalTriggerConditionCallbackWrapperName;
			local action = CxTools.GlobalTriggerActionCallbackWrapperName;
			if not _funcCondition or _funcCondition == "" then
				condition = nil;
			end
 
			local realTriggerId = CxTools.RequestTriggerOrig( _eventType, condition, action, _isActive, {sTriggerId}, {sTriggerId} );
			entry.realId = realTriggerId;
 
			CxTools.tTriggers[sTriggerId] = entry;
 
			return realTriggerId;
		end
 
		function CxTools:callbackWrapperCondition( _sTriggerId )
			local tRes = { xpcall( function() return CxTools:callbackWrapperConditionReal( _sTriggerId ); end, CxTools.Panic ) };
			table.remove( tRes, 1 );
			return unpack( tRes );
		end
 
		function CxTools:callbackWrapperConditionReal( _sTriggerId )
			assert(type( _sTriggerId) == "number" );
			local entry = CxTools.tTriggers[_sTriggerId];
			assert( entry );
			assert( entry.sId == _sTriggerId );
			assert( entry.funcCondition );
			assert( entry.paramsCond );
 
			local tRes;
			if type(entry.funcCondition) == "function" then
				tRes = { xpcall( function() return entry.funcCondition( unpack( entry.paramsCond ) ); end, CxTools.Panic ) };
			else
				local f = _G[entry.funcCondition];
				assert(type(f) == "function");
				tRes = { xpcall( function() return f( unpack( entry.paramsCond ) ); end, CxTools.Panic ) };
			end
 
			local bNoErr = table.remove( tRes, 1 );
 
			if not bNoErr then
				CxTools.tTriggers[_sTriggerId].err = true;
			end
 
			return bNoErr and unpack( tRes ) or not bNoErr;
		end
 
		function CxTools:callbackWrapperAction( _sTriggerId )
			local tRes = { xpcall( function() return CxTools:callbackWrapperActionReal( _sTriggerId ); end, CxTools.Panic ) };
			table.remove( tRes, 1 );
			return unpack( tRes );
		end
 
		function CxTools:callbackWrapperActionReal( _sTriggerId )
			assert(type( _sTriggerId) == "number" );
			local entry = CxTools.tTriggers[_sTriggerId];
			assert( entry );
			assert( entry.sId == _sTriggerId );
			assert( entry.funcAction );
			assert( entry.paramsAction );
 
			local bNoErr = true;
			local tRes;
			if not entry.err then
				if type(entry.funcAction) == "function" then
					tRes = { xpcall( function() return entry.funcAction( unpack( entry.paramsAction ) ); end, CxTools.Panic ) };
				else
					local f = _G[entry.funcAction];
					assert(type(f) == "function");
					tRes = { xpcall( function() return f( unpack( entry.paramsAction ) ); end, CxTools.Panic ) };
				end
 
				bNoErr = table.remove( tRes, 1 );
			end
 
			-- check return value
			if not bNoErr or entry.err or tRes[1] == true then
				-- Remove this entry, as the trigger is destroyed
				CxTools.tTriggers[_sTriggerId] = nil;
			end
 
			return entry.err or (bNoErr and unpack( tRes ) or not bNoErr);
		end 
 
		function CxTools:UnrequestTrigger( _id )
			--assert( type( _id ) == "number" );
			for i = 1, CxTools.nTriggerNum, 1 do
				local t = CxTools.tTriggers[i];
				if t and t.realId == _id then
					CxTools.tTriggers[i] = nil;
					break;
				end
			end
			CxTools.UnrequestTriggerOrig( _id );
		end
 
 
		--#########################################################################
		--###
		--###	 Trigger Comfort Functions
		--###
 
		function CxTools:StartSimpleJob( _functionname, ...)
			assert(type(_functionname) == "string" or type(_functionname) == "function");
 
			if type(_functionname) == "string" then
				if arg[1] == nil then 
					return CxTools.StartSimpleJobOrig( _functionname );
 
				else
					assert(type(_G[_functionname]) == "function");
					return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_SECOND, "", _functionname, 1, {}, arg );
				end
 
			else
				assert(type(_functionname) == "function");
				return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_SECOND, "", _functionname, 1, {}, arg );
			end
		end
 
		function CxTools:StartSimpleHiResJob( _functionname, ...)
			assert(type(_functionname) == "string" or type(_functionname) == "function");
 
			if type(_functionname) == "string" then
				if arg[1] == nil then 
					return CxTools.StartSimpleHiResJobOrig( _functionname );
 
				else
					assert(type(_G[_functionname]) == "function");
					return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_TURN, "", _functionname, 1, {}, arg );
				end
 
			else
				assert(type(_functionname) == "function");
				return Trigger.RequestTrigger( Events.LOGIC_EVENT_EVERY_TURN, "", _functionname, 1, {}, arg );
			end
		end
 
		function CxTools:StartJob( _functionname, ... )
			assert(type(_functionname) == "string" or (type(_functionname) == "function" and type(arg[1]) == "function"));
 
			if type(_functionname) == "string" then
 
				assert(type(_G["Action_".._functionname]) == "function" and type(_G["Condition_".._functionname]) == "function");
 
				if arg[1] == nil then
					return CxTools.StartJobOrig(_functionname);
 
				else
					assert(type(arg[1]) == "table" and (not arg[2] or type(arg[2]) == "table"));
					return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_SECOND, "Condition_".._functionname, "Action_".._functionname, 1, arg[2], arg[1]);
				end
			else
				 assert((not arg[2] or type(arg[2]) == "table") and (not arg[3] or type(arg[3]) == "table"));
				 return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_SECOND, arg[1], _functionname, 1, arg[3], arg[2]);
			 end
		end
 
		function CxTools:StartHiResJob( _functionname, ... )
			assert(type(_functionname) == "string" or (type(_functionname) == "function" and type(arg[1]) == "function"));
 
			if type(_functionname) == "string" then
 
				assert(type(_G["Action_".._functionname]) == "function" and type(_G["Condition_".._functionname]) == "function");
 
				if arg[1] == nil then
					return CxTools.StartHiResJobOrig(_functionname);
 
				else
					assert(type(arg[1]) == "table" and (not arg[2] or type(arg[2]) == "table"));
					return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, "Condition_".._functionname, "Action_".._functionname, 1, arg[2], arg[1]);
				end
			else
				assert((not arg[2] or type(arg[2]) == "table") and (not arg[3] or type(arg[3]) == "table"));
				return Trigger.RequestTrigger(Events.LOGIC_EVENT_EVERY_TURN, arg[1], _functionname, 1, arg[3], arg[2]);
			end
		end
 
		--#########################################################################
		--###
		--###	 Init!
		--###
 
		CxTools:Init();
	end
 
	function Countdown_and_Peacetime()
 
		PeacetimeEnd = function()
			-- sämtliche Aktionen bei Ende der Friedenszeit
			MultiplayerTools.SetUpDiplomacyOnMPGameConfig()
			-- Sound bei Ende der Friedenszeit
			Sound.PlayGUISound( Sounds.OnKlick_Select_kerberos, 127 )
			-- Nachricht bei Ende der Friedenszeit
			Message( "@color:247,175,9 Der Waffenstillstand ist beendet, lasst die Gefechte beginnen!" )
 
			-- Blockende Entities entfernen
			ReplaceEntity ("gate1", Entities.XD_PalisadeGate2 )
			ReplaceEntity ("gate2", Entities.XD_PalisadeGate2 )
		    ReplaceEntity ("gate3", Entities.XD_PalisadeGate2 )
		end
 
		SetPeacetime = function ( _seconds )
			---hier wird die Funktion special peacetime gestartet
			SpecialPeacetime();
			StartCountdown( _seconds, PeacetimeEnd, true );
		end
 
		SpecialPeacetime = function()
			-- Anzahl der menschlichen Spieler wird hier ermittelt
			local _humenPlayer = XNetwork.GameInformation_GetMapMaximumNumberOfHumanPlayer()
			-- Abfrage ob Standardsituation gegeben ist das jeder sich  mit jedem  verbünden kann
			if XNetwork.GameInformation_GetFreeAlliancesFlag() == 1 then
				-- Feststellung wer mit wem verbündet ist und Festlegung des DiplomatiST für die Peacetime
				if _humenPlayer > 1 then
					for _teampId = 1, _humenPlayer do
						local _teamplayer = mpc_playerteams[_teampId]
						for _oppopId = 1, _humenPlayer do
							if _teampId ~= OppoPlayer then
								local _oppoPlayer = mpc_playerteams[_oppopId]
								if _teamplayer == _oppoPlayer then
									Logic.SetDiplomacyState( _oppopId, _teampId, Diplomacy.Friendly )
								else
									Logic.SetDiplomacyState( _oppopId, _teampId, Diplomacy.Neutral )
								end
							end
						end
					end
				end
			end
		end
		SpecialPeacetimeEnd = function()
			for _teampId = 1, 8 do
				for _oppopId = 1, 8 do
					if _teampId ~= OppoPlayer then
						if mpc_playerteams[_teampId] == mpc_playerteams[_oppopId] then
							Logic.SetDiplomacyState( _oppopId, _teampId, Diplomacy.Friendly )
						else
							Logic.SetDiplomacyState( _oppopId, _teampId, Diplomacy.Hostile )
						end
					end
				end
			end
		end
 
 
		StartCountdown = function (_Limit, _Callback, _Show)
			assert(type(_Limit) == "number")
 
			Counter.Index = (Counter.Index or 0) + 1
 
			if _Show and CountdownIsVisisble() then
				assert(false, "StartCountdown: A countdown is already visible")
			end
 
			Counter["counter" .. Counter.Index] = {Limit = _Limit, TickCount = 0, Callback = _Callback, Show = _Show, Finished = false}
 
			if _Show then
				MapLocal_StartCountDown(_Limit)
			end
 
			if Counter.JobId == nil then
				Counter.JobId = StartSimpleJob("CountdownTick")
			end
 
			return Counter.Index
		end
 
		StopCountdown = function(_Id)
			if Counter.Index == nil then
				return
			end
 
			if _Id == nil then
				for i = 1, Counter.Index do
					if Counter.IsValid("counter" .. i) then
						if Counter["counter" .. i].Show then
							MapLocal_StopCountDown()
						end
						Counter["counter" .. i] = nil
					end
				end
			else
				if Counter.IsValid("counter" .. _Id) then
					if Counter["counter" .. _Id].Show then
						MapLocal_StopCountDown()
					end
					Counter["counter" .. _Id] = nil
				end
			end
		end
 
		CountdownTick = function()
			local empty = true
			for i = 1, Counter.Index do
				if Counter.IsValid("counter" .. i) then
					if Counter.Tick("counter" .. i) then
						Counter["counter" .. i].Finished = true
					end
 
					if Counter["counter" .. i].Finished and not IsBriefingActive() then
						if Counter["counter" .. i].Show then
							MapLocal_StopCountDown()
						end
 
						-- callback function
						if type(Counter["counter" .. i].Callback) == "function" then
							Counter["counter" .. i].Callback()
						end
 
						Counter["counter" .. i] = nil
					end
 
					empty = false
				end
			end
 
			if empty then
				Counter.JobId = nil
				Counter.Index = nil
				return true
			end
		end
 
		CountdownGetTick = function(_Id)
			if Counter.IsValid("counter" .. _Id) then
				return Counter["counter" .. _Id].Limit-Counter["counter" .. _Id].TickCount
			else
				return 0
			end
		end
 
		CountdownIsVisisble = function()
			for i = 1, Counter.Index do
				if Counter.IsValid("counter" .. i) and Counter["counter" .. i].Show then
					return true
				end
			end
			return false
		end
 
	end
	function CreateArmyTroops( _player, _position, _leaderType, _numberOfSoldiers, _troops, _experience, _move )
		local army = {
			player     = _player,
		}
		local tD  = {
			maxNumberOfSoldiers = _numberOfSoldiers,
			minNumberOfSoldiers = 0,
			experiencePoints    = _experience,
			leaderType          = _leaderType,
			position            = _position,
		}
		for i = 1,_troops do
			army[i] = CreateTroop( army , tD )
		end
		if _move ~= nil then
			for i = 1,_troops do
				Move( army[i], _move)
			end
		end
	end 	
	Comfort_TrackEntitysIni()
	Tribute_Comforts()
	Countdown_and_Peacetime()
	AutoUmlaut()
	CxToolsInclude()
end
 
    -- Waffenstillstand Briefing
    -- ________ damit "(Weiter mit Esc)" immer am gleichen Platz steht
 
function StartFriedenszeitBriefing()
 
    local briefing = {};
 
    local AP = function(_page) table.insert(briefing, _page); return _page; end;
 
    AP{
        title	= "Erzähler",
        text	= "Hallo, ihr habt erneut die Aufgabe eure Gegner zu besiegen. @color:0,0,0 _____________________________________________________________________________________ @cr @cr @color:150,150,150 (Weiter mit Esc)"
    };
 
AP{
        title	= "Erzähler",
        text	= "Spieler 1 muss zu beginn des Spiel's den Waffenstillstand im Tributmenü (F3) einstellen. @color:0,0,0 ________________________________________________________ @cr @cr @color:150,150,150 (Weiter mit Esc)"
    };
 
AP{
        title	= "Erzähler",
        text	= "Ihr könnt eure Figuren erst bewegen wenn ein Waffenstillstand gewählt wurde (Man kann jeweils nur eins auswählen). @color:0,0,0 ______________________________ @cr @cr @color:150,150,150 (Weiter mit Esc)"
    };
 
AP{
        title	= "Erzähler",
        text	= "Viel Erfolg!!! @color:0,0,0 __________________________________________________________________________________________________________________________________ @cr @cr @color:150,150,150 (Weiter mit Esc)"
    };
	Message("Spieler "..setupplayer.." muss zu beginn des Spiel's den Waffenstillstand im Tributmenü (F3) einstellen.")
    --StartBriefing(briefing);
end 
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function NebelvolkMultiplayerTributeSetup()
	Tributcallback1 = function()
		NebelvolkPeacetime = 5
		NebelvolkMultiplayerPeacetimeChoosen()
	end
	Tributcallback2 = function()
		NebelvolkPeacetime = 10
		NebelvolkMultiplayerPeacetimeChoosen()
	end
	Tributcallback3 = function()
		NebelvolkPeacetime = 15
		NebelvolkMultiplayerPeacetimeChoosen()
	end		
	NebelvolkMultiplayerPeacetimeChoosen = function()
		for i = 1,3 do Logic.RemoveTribute( setupplayer, NebelvolkMultiplayerTribute[i]) end
		Logic.ResumeAllEntities()
		Sound.PlayGUISound(Sounds.fanfare, 127) 
		Message("@color:100,200,255 "..NebelvolkPeacetime.." Minuten Waffenstillstand: Lasst das Spiel beginnen!")
		SetPeacetime( NebelvolkPeacetime*60 )
		ReBuildAllPlayerVillageCenters()
	end	
	setupplayer = 1
	if XNetwork.Manager_DoesExist() ~= 0 then
		for i = 1,8 do
			if mpc_playernames[i] ~= "" then
				setupplayer = i
				break
			end
		end
	end
	NebelvolkMultiplayerTribute = {}
	NebelvolkMultiplayerTribute[1] = AddTribute( CreateATribute(setupplayer, "@color:150,150,150 5 Minuten Waffenstillstand", { Gold = 0}, Tributcallback1 ) )
	NebelvolkMultiplayerTribute[2] = AddTribute( CreateATribute(setupplayer, "@color:150,150,150 10 Minuten Waffenstillstand", { Gold = 0}, Tributcallback2 ) )
	NebelvolkMultiplayerTribute[3] = AddTribute( CreateATribute(setupplayer, "@color:150,150,150 15 Minuten Waffenstillstand", { Gold = 0}, Tributcallback3 ) )	
end
 
-- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
function NebelZahltagJob() 
	for _pId = 1,3 do	
		Nebel_timeOut[_pId] = Nebel_timeOut[_pId] or false
		Nebel_bezahlt[_pId] = Nebel_bezahlt[_pId] or false		
		if 	Logic.GetPlayerPaydayTimeLeft(_pId) < 2000  then
			Nebel_timeOut[_pId] = true
		elseif Logic.GetPlayerPaydayTimeLeft(_pId) > 118000 then
			Nebel_timeOut[_pId] = false
			Nebel_bezahlt[_pId] = false
		end		
		if Nebel_timeOut[_pId] and not Nebel_bezahlt[_pId] then	
			local _nebelGold = (Comfort_TrackEntity_GetCount(_pId,Entities.CB_Evil_Tower1,true) + Comfort_TrackEntity_GetCount(_pId,Entities.PB_Tower1,true)) * 100
			local _nebelEisen = Comfort_TrackEntity_GetCount(_pId,Entities.PB_Beautification02,true) * 100
			local _nebelSchwefel = Comfort_TrackEntity_GetCount(_pId,Entities.PB_Beautification09,true) * 100
			local _nebelAltare = Comfort_TrackEntity_GetCount(_pId,Entities.PB_Beautification10,true)
			local _nebelAltareSpeer = Comfort_TrackEntity_GetCount(_pId,Entities.PB_Beautification11,true)
			Tools.GiveResouces(_pId, _nebelGold , 0, 0, 0, _nebelEisen, _nebelSchwefel)		
			if _pId == GUI.GetPlayerID() then
				Message("Ihr erhaltet: @color:235,255,53 ".._nebelGold.." Gold - @color:150,150,150 ".._nebelEisen.." Eisen - @color:252,164,39 ".._nebelSchwefel.." Schwefel")
				Message("Ihr erhaltet: @color:226,0,0 ".._nebelAltare.." Nebelkrieger - @color:0,140,2 ".._nebelAltareSpeer.." Nebelspeeris")
			end
			for i = 1,_nebelAltare  do
				CreateArmyTroops( _pId, GetPosition("army".._pId), Entities.CU_Evil_LeaderBearman1, 16, 1, 0, nil )
			end
			for i = 1,_nebelAltareSpeer  do
				CreateArmyTroops( _pId, GetPosition("army".._pId), Entities.CU_Evil_LeaderSkirmisher1, 16, 1, 0, nil )
			end
			Nebel_bezahlt[_pId] = true	
		end
	end
end
 
function StartNebelvolkModification() 
	Camera.ZoomSetFactorMax(2)
	for i = 1,3 do
		Logic.AddMercenaryOffer( GetEntityId( "merc"..i ), Entities.PV_Cannon3, 99, ResourceType.Gold, 200, ResourceType.Sulfur, 500  )
	end	
	-- Für MP erstmal Friedenszeiteinstellung abwarten
	Logic.SuspendAllEntities()
	-- Peacetime Tribute
	NebelvolkMultiplayerTributeSetup()
	for _pId = 1,8 do
		-- zu überwachende Gebäude initialisieren
		Comfort_TrackEntityIni(_pId,Entities.PB_Tower1) -- Wohnstätte / turm in konstruktion
		Comfort_TrackEntityIni(_pId,Entities.CB_Evil_Tower1) -- Wohnstätte / turm fertig
		Comfort_TrackEntityIni(_pId,Entities.PB_Beautification02) -- Eisen
		Comfort_TrackEntityIni(_pId,Entities.PB_Beautification09) -- Feuer
		Comfort_TrackEntityIni(_pId,Entities.PB_Residence1) -- Haus
		Comfort_TrackEntityIni(_pId,Entities.PB_Farm1) -- Farm
		Comfort_TrackEntityIni(_pId,Entities.PB_Sawmill1) -- Säge
		Comfort_TrackEntityIni(_pId,Entities.PB_Beautification10) -- Altar
		Comfort_TrackEntityIni(_pId,Entities.PB_Beautification11) -- AltatSpeer
 
		-- Hier werden die Technologien vorgegeben
		-- Beispiel Mathematik, Konstruktion und Sprengfähigkeit des Dieben
		-- Befehlsatz einfach Kommentierung durch entfernen der beiden Bindestriche rausnehmen
		-- Unitechnologien
		local i = _pId			
		ResearchTechnology(Technologies.GT_Mercenaries, i) 	
		ResearchTechnology(Technologies.GT_StandingArmy, i) 	
		ResearchTechnology(Technologies.GT_Tactics, i)	
		ResearchTechnology(Technologies.GT_Construction, i) 	
		ResearchTechnology(Technologies.GT_ChainBlock, i)
		ResearchTechnology(Technologies.GT_Alchemy, i)  
		ResearchTechnology(Technologies.GT_Metallurgy, i) 
		ResearchTechnology(Technologies.UP1_Village, i) 
		--ResearchTechnology(Technologies.B_Sawmill, i) 
 
		--ForbidTechnology(Technologies.B_Farm, i)
		ForbidTechnology(Technologies.B_Brickworks, i)
		ForbidTechnology(Technologies.B_University, i)
		ForbidTechnology(Technologies.MU_LeaderSpear, i)
 
		ForbidTechnology(Technologies.B_Beautification01, i)	
		ForbidTechnology(Technologies.B_Beautification02, i)
		ForbidTechnology(Technologies.B_Beautification03, i)
		ForbidTechnology(Technologies.B_Beautification04, i)
		ForbidTechnology(Technologies.B_Beautification05, i)
		ForbidTechnology(Technologies.B_Beautification06, i)
		ForbidTechnology(Technologies.B_Beautification07, i)
		ForbidTechnology(Technologies.B_Beautification08, i)
		ForbidTechnology(Technologies.B_Beautification09, i)
		ForbidTechnology(Technologies.B_Beautification10, i)
		ForbidTechnology(Technologies.B_Beautification11, i)
		ForbidTechnology(Technologies.B_Beautification12, i)
		ForbidTechnology(Technologies.T_UpgradeBow1, i)
 
		ForbidTechnology(Technologies.UP1_Sawmill, i)
		ForbidTechnology(Technologies.UP1_Headquarter, i)
		ForbidTechnology(Technologies.UP1_Tower, i);
		ForbidTechnology(Technologies.UP2_Tower, i);
		ForbidTechnology(Technologies.UP1_Residence, i);
		ForbidTechnology(Technologies.T_BlessSettlers2, i);		
	end
	-- Gebäude setzen GUI hack und
	-- MaximalAnzahlCheck an Gebäuden
	GUIAction_PlaceBuilding_Orig = GUIAction_PlaceBuilding
	GUIAction_PlaceBuilding = function( _a)
		local _ok = true
		if _a == UpgradeCategories.Blacksmith then
            _a = UpgradeCategories.Beautification02
		elseif _a == UpgradeCategories.Alchemist then
            _a = UpgradeCategories.Beautification09
		elseif _a == UpgradeCategories.Stable then
            _a = UpgradeCategories.Beautification10
		elseif _a == UpgradeCategories.Foundry then
            _a = UpgradeCategories.Beautification11
		end
		local gvMaxWohn = gvMaximalWohnstaetten
		local gvMaxAltar = gvMaximalAltare
		if GUI.GetPlayerID() == 3 then
			gvMaxAltar = gvMaxAltar + 1
			gvMaxWohn = gvMaxWohn + 5
		end
		if _a == UpgradeCategories.Tower then
			if (table.getn(Track_Entity_Table[ GUI.GetPlayerID()][ Entities.CB_Evil_Tower1 ]) + table.getn(Track_Entity_Table[ GUI.GetPlayerID()][ Entities.PB_Tower1 ]))>= gvMaxWohn then
				Message("Ihr duerft maximal "..gvMaxWohn.." Wohnstaetten bauen!")
				_ok = false
			end
		elseif _a == UpgradeCategories.Beautification10 then
			if table.getn(Track_Entity_Table[ GUI.GetPlayerID()][ Entities.PB_Beautification10 ]) >= gvMaxAltar then
				Message("Ihr duerft maximal "..gvMaxAltar.." Altare bauen!")
				_ok = false
			end		
		elseif _a == UpgradeCategories.Beautification11 then
			if table.getn(Track_Entity_Table[ GUI.GetPlayerID()][ Entities.PB_Beautification11 ]) >= gvMaxAltar then
				Message("Ihr duerft maximal "..gvMaxAltar.." Skirm-Altare bauen!")
				_ok = false
			end		
		end		
		if _ok then
			GUIAction_PlaceBuilding_Orig(_a)
		end
	end	
 
	-- Tooltips
	GUITooltip_ConstructBuilding_Orig = GUITooltip_ConstructBuilding
    GUITooltip_ConstructBuilding = function(_e1,_e2,_e3,_e4,_e5)
        GUITooltip_ConstructBuilding_Orig(_e1,_e2,_e3,_e4,_e5)
        if string.find(_e2,"MenuSerf/blacksmith_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Eisensog @cr @color:255,255,255 Errichtet einen Eisenmagnet an der angegebenen Stelle. Dadurch erhaltet ihr 100 Eisen pro Zahltag." )
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 200 @cr Stein: 100" )
		elseif string.find(_e2 ,"MenuSerf/Tower_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Wohnst\195\164tte @cr @color:255,255,255 Errichtet eine Wohnst\195\164tte an der angegebenen Stelle. Dadurch erhaltet ihr zus\195\164tzlich 100 Taler pro Zahltag. (maximal 12)" )
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Holz: 200 @cr Stein: 200" )		
		elseif string.find(_e2 , "MenuSerf/alchemist_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Feuertopf @cr @color:255,255,255 Errichtet einen Feuertopf an der angegebenen Stelle. Dadurch erhaltet ihr 100 Schwefel pro Zahltag." )
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 100 @cr Holz: 100" )
		elseif string.find(_e2 , "MenuSerf/residence_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Nebelwohnhaus @cr @color:255,255,255 Errichtet ein Nebelwohnhaus an der angegebenen Stelle f\195\188r die Arbeiter der Nebelminen." )
		elseif string.find(_e2 , "MenuSerf/farm_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Nebelbauernhof @cr @color:255,255,255 Errichtet einen Nebelbauernhof an der angegebenen Stelle." )
		elseif string.find(_e2 , "MenuSerf/stables_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Altar @cr @color:255,255,255 Errichtet einen Altar an der angegebenen Stelle. Dadurch erhaltet Ihr pro Zahltag einen Trupp Nebelkrieger vor eurem Haupthaus. (maximal 3; Spieler 1 + 2 maximal 2)" )
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 400 @cr Eisen: 200" )
		elseif string.find(_e2, "MenuSerf/foundry_normal") ~= nil then
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Skirm-Altar @cr @color:255,255,255 Errichtet einen Skirm-Altar an der angegebenen Stelle. Dadurch erhaltet Ihr pro Zahltag einen Trupp Skrim-Nebelkrieger vor eurem Haupthaus. (maximal 2)" )
			XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 400 @cr Stein: 200" )
		end
    end
 
	-- Gebäudeübersicht aufrufen
    GUIAction_OnlineHelp_Orig = GUIAction_OnlineHelp;
    GUIAction_OnlineHelp = function()   
            for _pId = 1,3 do
				Message("Spieler ".._pId.." Wohnst\195\164tten: "..Comfort_TrackEntity_GetCount(_pId,Entities.CB_Evil_Tower1,true) + Comfort_TrackEntity_GetCount(_pId,Entities.PB_Tower1,true))
			end
    end
    GUITooltip_Generic_Orig = GUITooltip_Generic;
    GUITooltip_Generic = function( a, b, c )
        GUITooltip_Generic_Orig( a, b, c );
            local newString, numberOfChanges = string.gsub( a, "MenuMap/", "" );
            if numberOfChanges == 1 then
                if newString == "OnlineHelp" then
                    XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Geb\195\164ude\195\188bersicht @cr @color:255,255,255 Hier könnt Ihr Euch einen Überblick über Eure bisher gebauten Geb\195\164de verschaffen." );
                end
            end        
    end
 
	-- Militäreinheiten kaufen
	GUIAction_BuyMilitaryUnit_Orig = GUIAction_BuyMilitaryUnit
	GUIAction_BuyMilitaryUnit = function(_a)
		if _a == UpgradeCategories.LeaderBow then
			_a = UpgradeCategories.Evil_LeaderSkirmisher
		end
		if _a == UpgradeCategories.LeaderSword then
			_a = UpgradeCategories.Evil_LeaderBearman
		end
		GUIAction_BuyMilitaryUnit_Orig(_a)
	end
 
	-- Models ersetzen wenn bestimmtes Gebäude erstellt wurde
	NebelvolkOnEntityCreated = function()
		local _eId = Event.GetEntityID()
		local _pId = GetPlayer(_eId)
		local _eType = Logic.GetEntityType(_eId)
		if _eType == Entities.PB_Tower1 then -- Wohnstätte
			Logic.SetModelAndAnimSet(_eId,Models.CB_EvilTower1)
		elseif _eType == Entities.PB_Beautification02  then -- Eisen
			Logic.SetModelAndAnimSet(_eId,Models.XD_Evil_Camp01)
		elseif _eType == Entities.PB_Beautification09  then -- Feuer
			Logic.SetModelAndAnimSet(_eId,Models.XD_Evil_Camp04)
		elseif _eType == Entities.PB_Residence1 then -- Haus
			Logic.SetModelAndAnimSet(_eId,Models.XD_RuinHouse1)
		elseif _eType == Entities.PB_Farm1 then -- Farm
			Logic.SetModelAndAnimSet(_eId,Models.XD_RuinTower1)
		elseif _eType == Entities.PB_Sawmill1 then -- Säge
			Logic.SetModelAndAnimSet(_eId,Models.CB_SteamMashine)
		elseif _eType == Entities.PB_Beautification10 then -- Altar
			Logic.SetModelAndAnimSet(_eId,Models.XD_Evil_Camp02)
		elseif _eType == Entities.PB_Beautification11 then -- SpeerAltar
			Logic.SetModelAndAnimSet(_eId,Models.XD_Evil_Camp05)
		end
	end
	-- Anti Abreiss Bug
	gvAlreadyDestructed = {}
    for _pId=1,8 do
        gvAlreadyDestructed[_pId] = 0
    end	
	GUI.SellBuilding_OrigProtected = GUI.SellBuilding;
    GUI.SellBuilding = function()
		if gvAlreadyDestructed[GUI.GetPlayerID()] == GUI.GetSelectedEntity() then
			Message("Gebäude wird bereits abgerissen!")
		else
			gvAlreadyDestructed[GUI.GetPlayerID()] = GUI.GetSelectedEntity()		
			GUI.SellBuilding_OrigProtected(GUI.GetSelectedEntity())
		end		
    end
	TuermeErsetzenJob = function(_eId)
		ReplaceEntity(_eId,Entities.CB_Evil_Tower1)
		return true
	end
	GameCallback_OnBuildingConstructionComplete_Orig = GameCallback_OnBuildingConstructionComplete
	GameCallback_OnBuildingConstructionComplete = function(_eId,_pId)
		GameCallback_OnBuildingConstructionComplete_Orig(_eId,_pId)
		Comfort_TrackEntity_Created(_eId,_pId)
		local _eType = Logic.GetEntityType(_eId)
		if _eType == Entities.PB_Tower1 then 
			StartSimpleJob(TuermeErsetzenJob,_eId)
		end
	end
	Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_CREATED, "", "NebelvolkOnEntityCreated", 1)
	Nebel_timeOut = {}
	Nebel_bezahlt = {}
	StartSimpleJob("NebelZahltagJob")
 
	gv_Entities_Dorfzentren = {Entities.PB_VillageCenter1, 
							Entities.PB_VillageCenter2, 
							Entities.PB_VillageCenter3}
 
	for _pId = 1,8 do
		for i = 1,3 do
			Comfort_TrackEntityIni(_pId,gv_Entities_Dorfzentren[i])
		end
	end
	ReBuildAllPlayerVillageCenters = function()   	
		for _pId = 1, 8 do
			for u = 1,table.getn(mpc_villageCenters[_pId][ 1] ) do
				Logic.CreateEntity( gv_Entities_Dorfzentren[1], mpc_villageCenters[_pId][1][u].pos.X, mpc_villageCenters[_pId][1][u].pos.Y, 0, _pId )
			end
		end
	end
 
	ClearAllPlayerVillageCenters = function()
		mpc_villageCenters = {}
		for _pId = 1,8 do
			mpc_villageCenters[_pId] = {} 
			for v = 1,table.getn(gv_Entities_Dorfzentren) do
				mpc_villageCenters[_pId][v] = {}
				for u = 1, table.getn( Track_Entity_Table[_pId][ gv_Entities_Dorfzentren[v] ] ) do
					mpc_villageCenters[_pId][v][u] = {}
					mpc_villageCenters[_pId][v][u].pos = GetPosition ( Track_Entity_Table[_pId][ gv_Entities_Dorfzentren[v] ][1] )
					DestroyEntity ( Track_Entity_Table[_pId][ gv_Entities_Dorfzentren[v] ][1] )
				end
			end		
		end
	end
	ClearAllPlayerVillageCenters()
	--Testjob = function()
	--	Message("EvilTuerme:"..Comfort_TrackEntity_GetCount(1,Entities.CB_Evil_Tower1,true).." Gesamt:"..Comfort_TrackEntity_GetCount(1,Entities.CB_Evil_Tower1))
	--	Message("Tuerme:"..Comfort_TrackEntity_GetCount(1,Entities.PB_Tower1,true).." Gesamt:"..Comfort_TrackEntity_GetCount(1,Entities.PB_Tower1))
	--end
	--StartSimpleJob(Testjob)
end