======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