--Script.Load( "maps\\user\\Nebelvolk.lua" ) ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -- -- Mapname:(3) Nebelvolk_MP -- -- Author: NDSfan -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ g_MC_StR = 1 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, 199, 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