====== Comfort: Mauern selbst bauen ====== ===== Beschreibung ===== Der Code ermöglicht dass Leibeigene ab sofort Mauern und Tore bauen.\\ Dazu sind Zierobjekte nun zum Mauerbau freigegeben. ===== Anwendung ===== Die Abhängigkeiten müssen im Skript irgendwo auftauchen! Danach einfach in der FMA "SetupWalls()" aufrufen ===== Code ===== function SetupWalls() local _enter=string.char(13) table.insert(GUITooltip_ConstructBuilding_BeforeOrig, function(...) if arg[1] == 31 then XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Mauer @cr @color:255,255,255 Errichtet eine Mauer für eure Siedlung. Bei der Fertigstellung kostet diese Extraressourcen. Eure Siedler fühlen sich sicherer (Motivationsschub)." ) XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 100 @cr Lehm: 100" ) return false elseif arg[1] == 28 then XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Tor @cr @color:255,255,255 Errichtet ein Tor für eure Schutzmauern. Eure Siedler fühlen sich sicherer (Motivationsschub)." ) XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 200 @cr Stein: 100" ) return false elseif arg[1] == 66 then XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Abschlussmauer @cr @color:255,255,255 Errichtet eine Abschlussmauer um Mauerteile zu verbinden oder eine Mauer über die Baugrenzen hinaus zu erweitern. Eure Siedler fühlen sich sicherer (Motivationsschub)." ) XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 300 @cr Stein: 100" ) return false elseif arg[1] == 30 then XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomText, "@color:180,180,180 Mauerturm @cr @color:255,255,255 Errichtet einen Ballistaturm der direkt in der nahesten Mauer platziert wird. Eure Siedler fühlen sich sicherer (Motivationsschub)." ) XGUIEng.SetText( gvGUI_WidgetID.TooltipBottomCosts, "Taler: 400 @cr Stein: 200" ) return false end end ) -- Model ersetzen wenn Mauer errichtet wird WallsOnEntityCreated = function() local _eId = Event.GetEntityID() local _pId = GetPlayer(_eId) local _eType = Logic.GetEntityType(_eId) if _eType == Entities.PB_Beautification04 then Logic.SetModelAndAnimSet(_eId,Models.XD_WallStraight) elseif _eType == Entities.PB_Beautification01 then Logic.SetModelAndAnimSet(_eId,Models.XD_WallStraightGate) elseif _eType == Entities.PB_Beautification05 then Logic.SetModelAndAnimSet(_eId,Models.XD_DarkWallDistorted) elseif _eType == Entities.PB_Beautification03 then Logic.SetModelAndAnimSet(_eId,Models.PB_DarkTower2) end end Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_CREATED, "", "WallsOnEntityCreated", 1) SelfCreatedWalls = {} for i = 0,8 do SelfCreatedWalls[i] = {} end SelfCreatedWalls_PfostenSellTributeIDs = {} SetupWallsMauerplatzieren = function(_eId) local _pId = GetPlayer(_eId) local _PfostenID = 0 local _PfostenID2 = 0 local _pos = GetPosition(_eId) local _eType = Logic.GetEntityType(_eId) if type(SelfCreatedWalls[_pId][_eId]) ~= "table" then local _mauer = 0 local _mauer2 = 0 local _mauerecke1 = 0 local _mauerecke2 = 0 local _istMauer = true local _entfernung = 1200 if _eType ~= Entities.PB_Beautification05 then for u = 1,3 do if u == 1 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraight, _pos.X, _pos.Y, 1200,16)} elseif u == 2 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate, _pos.X, _pos.Y, 1200,16)} elseif u == 3 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate_Closed, _pos.X, _pos.Y, 1200,16)} end for i = 2, table.getn(_mauern) do local _distance = GetDistance(_mauern[i],_eId) if _distance < _entfernung and _distance > 0 and Logic.IsConstructionComplete(_mauern[i]) == 1 then _mauer = _mauern[i] _entfernung = _distance end end end else for u = 1,3 do if u == 1 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraight, _pos.X, _pos.Y, 1200,16)} elseif u == 2 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate, _pos.X, _pos.Y, 1200,16)} elseif u == 3 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate_Closed, _pos.X, _pos.Y, 1200,16)} end for i = 2, table.getn(_mauern) do local _distance = GetDistance(_mauern[i],_eId) if _distance < _entfernung and _distance > 0 and Logic.IsConstructionComplete(_mauern[i]) == 1 then local _orientation = Logic.GetEntityOrientation(_mauern[i]) if _orientation < 90 then _orientation = 270 + _orientation else _orientation = _orientation - 90 end local _posMauer = GetPosition(_mauern[i]) local _ecke1 local _ecke2 if _istMauer then _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 200} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 200} else _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 300} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 300} end local _pfosten ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallCorner, _ecke1.X, _ecke1.Y, 100,16)} if _pfosten[1] == 0 then _mauer = _mauern[i] _entfernung = _distance _mauerecke1 = _ecke1 else _pfosten ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallCorner, _ecke2.X, _ecke2.Y, 100,16)} if _pfosten[1] == 0 then _mauer = _mauern[i] _entfernung = _distance _mauerecke1 = _ecke2 end end end end end if _mauer > 0 then _entfernung = 1200 for u = 1,3 do if u == 1 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraight, _pos.X, _pos.Y, 1200,16)} elseif u == 2 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate, _pos.X, _pos.Y, 1200,16)} elseif u == 3 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraightGate_Closed, _pos.X, _pos.Y, 1200,16)} end for i = 2, table.getn(_mauern) do local _distance = GetDistance(_mauern[i],_eId) if _distance < _entfernung and _distance > 0 and Logic.IsConstructionComplete(_mauern[i]) == 1 then local _orientation = Logic.GetEntityOrientation(_mauern[i]) if _orientation < 90 then _orientation = 270 + _orientation else _orientation = _orientation - 90 end local _posMauer = GetPosition(_mauern[i]) local _ecke1 local _ecke2 if _istMauer then _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 200} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 200} else _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 300} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 300} end local _pfosten ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallCorner, _ecke1.X, _ecke1.Y, 100,16)} if _pfosten[1] == 0 and not(_mauerecke1.X == _ecke1.X and _mauerecke1.Y == _ecke1.Y) then if GetDistance(_ecke1,_mauerecke1) <= 615 then _mauer2 = _mauern[i] _entfernung = _distance _mauerecke2 = _ecke1 end else _pfosten ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallCorner, _ecke2.X, _ecke2.Y, 100,16)} if _pfosten[1] == 0 and not(_mauerecke1.X == _ecke2.X and _mauerecke1.Y == _ecke2.Y) then if GetDistance(_ecke2,_mauerecke1) <= 615 then _mauer2 = _mauern[i] _entfernung = _distance _mauerecke2 = _ecke2 end end end end end end end end if _mauer > 0 then if _mauerecke1 == 0 then local _ecke _orientation = Logic.GetEntityOrientation(_mauer) if _orientation < 90 then _orientation = 270 + _orientation else _orientation = _orientation - 90 end local _posMauer = GetPosition(_mauer) local _ecke1 local _ecke2 if _istMauer then _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 200} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 200,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 200} else _ecke1 = {X=_posMauer.X+math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y+math.sin(_orientation/360*math.pi*2) * 300} _ecke2 = {X=_posMauer.X-math.cos(_orientation/360*math.pi*2) * 300,Y=_posMauer.Y-math.sin(_orientation/360*math.pi*2) * 300} end if GetDistance(_pos,_ecke1) > GetDistance(_pos,_ecke2) then _ecke = _ecke2 else _ecke = _ecke1 end _orientation = Winkel(_ecke,_eId) local _newPos if _eType == Entities.PB_Beautification04 then _newPos = {X=_ecke.X+math.cos((_orientation)/360*math.pi*2) * 200,Y=_ecke.Y+math.sin((_orientation)/360*math.pi*2) * 200} else _newPos = {X=_ecke.X+math.cos((_orientation)/360*math.pi*2) * 300,Y=_ecke.Y+math.sin((_orientation)/360*math.pi*2) * 300} end if _orientation < 90 then _orientation = 270 + _orientation else _orientation = _orientation - 90 end DestroyEntity(_eId) if _eType == Entities.PB_Beautification04 then _eId = Logic.CreateEntity( Entities.XD_WallStraight, _newPos.X, _newPos.Y, _orientation, _pId ) else _eId = Logic.CreateEntity( Entities.XD_WallStraightGate, _newPos.X, _newPos.Y, _orientation, _pId ) end _PfostenID = Logic.CreateEntity( Entities.XD_WallCorner, _ecke.X, _ecke.Y, 0, _pId ) else if _mauerecke2 == 0 then _orientation = Winkel(_mauer,_mauerecke1) local _newPos = {X=_mauerecke1.X+math.cos((_orientation)/360*math.pi*2) * 285,Y=_mauerecke1.Y+math.sin((_orientation)/360*math.pi*2) * 285} _ecke1 = {X=_newPos.X+math.cos(_orientation/360*math.pi*2) * 290,Y=_newPos.Y+math.sin(_orientation/360*math.pi*2) * 290} _ecke2 = {X=_newPos.X-math.cos(_orientation/360*math.pi*2) * 290,Y=_newPos.Y-math.sin(_orientation/360*math.pi*2) * 290} if _orientation < 135 then _orientation = 270 + _orientation - 45 else _orientation = _orientation - 90 - 45 end DestroyEntity(_eId) _eId = Logic.CreateEntity( Entities.XD_WallDistorted, _newPos.X, _newPos.Y, _orientation, _pId ) _PfostenID = Logic.CreateEntity( Entities.XD_WallCorner, _ecke1.X, _ecke1.Y, 0, _pId ) _PfostenID2 = Logic.CreateEntity( Entities.XD_WallCorner, _ecke2.X, _ecke2.Y, 0, _pId ) else _orientation = Winkel(_mauerecke1,_mauerecke2) local _newPos = {X=_mauerecke1.X+math.cos((_orientation)/360*math.pi*2) * 285,Y=_mauerecke1.Y+math.sin((_orientation)/360*math.pi*2) * 285} _ecke1 = {X=_newPos.X+math.cos(_orientation/360*math.pi*2) * 290,Y=_newPos.Y+math.sin(_orientation/360*math.pi*2) * 290} _ecke2 = {X=_newPos.X-math.cos(_orientation/360*math.pi*2) * 290,Y=_newPos.Y-math.sin(_orientation/360*math.pi*2) * 290} if _orientation < 135 then _orientation = 270 + _orientation - 45 else _orientation = _orientation - 90 - 45 end DestroyEntity(_eId) _eId = Logic.CreateEntity( Entities.XD_WallDistorted, _newPos.X, _newPos.Y, _orientation, _pId ) _PfostenID = Logic.CreateEntity( Entities.XD_WallCorner, _ecke1.X, _ecke1.Y, 0, _pId ) _PfostenID2 = Logic.CreateEntity( Entities.XD_WallCorner, _ecke2.X, _ecke2.Y, 0, _pId ) end end else DestroyEntity(_eId) if _eType == Entities.PB_Beautification04 then _eId = Logic.CreateEntity( Entities.XD_WallStraight, _pos.X, _pos.Y, 0, _pId ) elseif _eType == Entities.PB_Beautification01 then _eId = Logic.CreateEntity( Entities.XD_WallStraightGate, _pos.X, _pos.Y, 0, _pId ) elseif _eType == Entities.PB_Beautification05 then _eId = Logic.CreateEntity( Entities.XD_WallDistorted, _pos.X, _pos.Y, 0, _pId ) end end SelfCreatedWalls[_pId][_eId] = {} SelfCreatedWalls[_pId][_eId].ID = _eId function GetSellTributCallback(_pId,_eId) local myfunc = function() local _pos = GetPosition(_eId) DestroyEntity(SelfCreatedWalls[_pId][_eId].ID) Tools.GiveResouces(_pId, 100, nil, nil, nil, nil, nil) Logic.CreateEffect( GGL_Effects.FXBuildingSmoke, _pos.X, _pos.Y, _pId ); end return myfunc end function GetSellTributCallbackPfosten(_pId,_eId) local myfunc = function() local _pos = GetPosition(_eId) DestroyEntity(_eId) Logic.CreateEffect( GGL_Effects.FXBuildingSmoke, _pos.X, _pos.Y, _pId ); end return myfunc end function GetCloseTributCallback(_pId,_eId) local myfunc = function() local _eType = Logic.GetEntityType(_eId) local _eIdNew =_eId local _oldHealth if _eType == Entities.XD_WallStraightGate then _oldHealth = Logic.GetEntityHealth(_eId) _eIdNew = ReplaceEntity (_eId, Entities.XD_WallStraightGate_Closed ) Logic.HurtEntity(_eIdNew,Logic.GetEntityMaxHealth(_eIdNew)-_oldHealth) elseif _eType == Entities.XD_WallStraightGate_Closed then _oldHealth = Logic.GetEntityHealth(_eId) _eIdNew = ReplaceEntity (_eId, Entities.XD_WallStraightGate ) Logic.HurtEntity(_eIdNew,Logic.GetEntityMaxHealth(_eIdNew)-_oldHealth) end if _eIdNew ~= _eId then SelfCreatedWalls[_pId][_eIdNew] = SelfCreatedWalls[_pId][_eId] SelfCreatedWalls[_pId][_eIdNew].ID = _eIdNew MakeInvulnerable(_eIdNew) SelfCreatedWalls[_pId][_eIdNew].SellTributID = AddTribute( CreateATribute(8, "", { Gold = 0}, GetSellTributCallback(_pId,_eIdNew) ) ) SelfCreatedWalls[_pId][_eIdNew].CloseTributID = AddTribute( CreateATribute(8, "", { Gold = 0}, GetCloseTributCallback(_pId,_eIdNew) ) ) end end return myfunc end SelfCreatedWalls[_pId][_eId].CloseTributID = AddTribute( CreateATribute(8, "", { Gold = 0}, GetCloseTributCallback(_pId,_eId) ) ) SelfCreatedWalls[_pId][_eId].SellTributID = AddTribute( CreateATribute(8, "", { Gold = 0}, GetSellTributCallback(_pId,_eId) ) ) SelfCreatedWalls[_pId][_eId].Pfosten = _PfostenID SelfCreatedWalls[_pId][_eId].Pfosten2 = _PfostenID2 SelfCreatedWalls_PfostenSellTributeIDs[_PfostenID] = AddTribute( CreateATribute(8, "", { Gold = 0}, GetSellTributCallbackPfosten(_pId,_PfostenID) ) ) SelfCreatedWalls_PfostenSellTributeIDs[_PfostenID2] = AddTribute( CreateATribute(8, "", { Gold = 0}, GetSellTributCallbackPfosten(_pId,_PfostenID2) ) ) MakeInvulnerable(_eId) MakeInvulnerable(_PfostenID) MakeInvulnerable(_PfostenID2) end return true end SetupWallsTurmplatzieren = function(_eId) local _pId = GetPlayer(_eId) local _pos = GetPosition(_eId) local _eType = Logic.GetEntityType(_eId) local _mauer = 0 local _entfernung = 1200 for u = 1,2 do if u == 1 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallStraight, _pos.X, _pos.Y, 1200,16)} elseif u == 2 then _mauern ={Logic.GetPlayerEntitiesInArea(_pId,Entities.XD_WallDistorted, _pos.X, _pos.Y, 1200,16)} end for i = 2, table.getn(_mauern) do local _distance = GetDistance(_mauern[i],_eId) if _distance < _entfernung and _distance > 0 and Logic.IsConstructionComplete(_mauern[i]) == 1 then local _mauerpos = GetPosition(_mauern[i]) local _turm ={Logic.GetPlayerEntitiesInArea(_pId,Entities.PB_DarkTower2, _mauerpos.X, _mauerpos.Y, 100,16)} if _turm[1] <= 0 then local _turm ={Logic.GetPlayerEntitiesInArea(_pId,Entities.PB_DarkTower3, _mauerpos.X, _mauerpos.Y, 100,16)} if _turm[1] <= 0 then _mauer = _mauern[i] _entfernung = _distance end end end end end if _mauer ~= 0 then local _posMauer = GetPosition(_mauer) DestroyEntity(_eId) Logic.CreateEntity( Entities.PB_DarkTower2, _posMauer.X+1, _posMauer.Y+1, 0, _pId ) else DestroyEntity(_eId) Logic.CreateEntity( Entities.PB_DarkTower2, _pos.X+1, _pos.Y+1, 0, _pId ) end return true end SetupWallsWallDestroyed = function() local _eId = Event.GetEntityID() local _pId = GetPlayer(_eId) if type(SelfCreatedWalls[_pId][_eId]) == "table" then MakeVulnerable(SelfCreatedWalls[_pId][_eId].Pfosten) DestroyEntity(SelfCreatedWalls[_pId][_eId].Pfosten) MakeVulnerable(SelfCreatedWalls[_pId][_eId].Pfosten2) DestroyEntity(SelfCreatedWalls[_pId][_eId].Pfosten2) Logic.RemoveTribute( 8, SelfCreatedWalls[_pId][_eId].SellTributID) Logic.RemoveTribute( 8, SelfCreatedWalls_PfostenSellTributeIDs[SelfCreatedWalls[_pId][_eId].Pfosten]) Logic.RemoveTribute( 8, SelfCreatedWalls_PfostenSellTributeIDs[SelfCreatedWalls[_pId][_eId].Pfosten2]) Logic.RemoveTribute( 8, SelfCreatedWalls[_pId][_eId].CloseTributID) table.remove(SelfCreatedWalls[_pId], _eId) end end table.insert(GameCallback_OnBuildingConstructionComplete_AfterOrig, function(_eId,_pId) local _eType = Logic.GetEntityType(_eId) if _eType == Entities.PB_Beautification04 then StartSimpleJob(SetupWallsMauerplatzieren,_eId) elseif _eType == Entities.PB_Beautification01 then StartSimpleJob(SetupWallsMauerplatzieren,_eId) elseif _eType == Entities.PB_Beautification05 then StartSimpleJob(SetupWallsMauerplatzieren,_eId) elseif _eType == Entities.PB_Beautification03 then -- turm StartSimpleJob(SetupWallsTurmplatzieren,_eId) end end ) table.insert(GameCallback_GUI_SelectionChanged_AfterOrig, function(...) local _eType = Logic.GetEntityType(GUI.GetSelectedEntity()) if _eType == Entities.PB_DarkTower2 then XGUIEng.ShowWidget( 1141, 1); XGUIEng.ShowWidget( 1143, 0); XGUIEng.ShowWidget( 1144, 1); end end ) table.insert(GUI.SellBuilding_AfterOrig, function() if type(SelfCreatedWalls[gv_guipId][GUI.GetSelectedEntity()]) == "table" then GUI.PayTribute( 8, SelfCreatedWalls[gv_guipId][GUI.GetSelectedEntity()].SellTributID) elseif SelfCreatedWalls_PfostenSellTributeIDs[GUI.GetSelectedEntity()] ~= nil then Message("jo") GUI.PayTribute( 8, SelfCreatedWalls_PfostenSellTributeIDs[GUI.GetSelectedEntity()]) end table.remove(SelfCreatedWalls[gv_guipId], GUI.GetSelectedEntity()) end ) table.insert(GUIAction_DoNotDestroyBuilding_BeforeOrig, function() if type(SelfCreatedWalls[gv_guipId][GUI.GetSelectedEntity()]) == "table" then GUI.PayTribute( 8, SelfCreatedWalls[gv_guipId][GUI.GetSelectedEntity()].CloseTributID) end end ) Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_DESTROYED, "", "SetupWallsWallDestroyed", 1) XGUIEng.TransferMaterials(996 , 799 ) --Mauer XGUIEng.TransferMaterials(837 , 796 ) --Tor XGUIEng.TransferMaterials(1140 , 800 ) --Abschlussmauer XGUIEng.TransferMaterials(827 , 798 ) --MauerTurm -- ######################## -- ### Comfort Mauer Rüstung by Noigi WALL_ARMOR = 15; WALL_ARMOR_TECHBONUS = 5; GetWallArmor = function(_pID) local armor = WALL_ARMOR; if Logic.IsTechnologyResearched( _pID, Technologies.T_Masonry ) == 1 then armor = armor+WALL_ARMOR_TECHBONUS; end return armor; end Walls_ActionOnEntityHurt = function() local tarID = Event.GetEntityID2(); local tarPlayer = GetPlayer( tarID ) local tarType = Logic.GetEntityType(tarID); if type(SelfCreatedWalls[tarPlayer][tarID]) == "table" then local attID = Event.GetEntityID1(); local attType = Logic.GetEntityType(attID); local ap = Logic.GetEntityDamage(attID); if ap > 22 then ap = 22 end if attType >= 207 and attType <= 214 then ap = ap*1.5 if ap > 25 then ap = 25 end end local pID = GetPlayer(tarID); local def = GetWallArmor(pID); local dmg = math.max( ap-def, 1 ); local hp = Logic.GetEntityHealth(tarID); if hp > dmg then MakeVulnerable(tarID); Logic.HurtEntity(tarID,dmg); MakeInvulnerable(tarID); else MakeVulnerable(tarID); SetHealth(tarID,0); end end end Trigger.RequestTrigger( Events.LOGIC_EVENT_ENTITY_HURT_ENTITY, "", "Walls_ActionOnEntityHurt", 1); -- ######################## -- ### Comfort Mauer Rüstung GUI table.insert(GUIUpdate_Armor_BeforeOrig, function() local sel = GUI.GetSelectedEntity() local selType = Logic.GetEntityType(sel) if (selType == Entities.XD_WallStraightGate_Closed) or (selType == Entities.XD_WallStraightGate) or (selType == Entities.XD_WallStraight) or (selType == Entities.XD_WallDistorted) then XGUIEng.SetText( XGUIEng.GetCurrentWidgetID(), "@ra "..GetWallArmor(GUI.GetPlayerID()) ); return false end end ) end ===== Abhängigkeiten ===== Folgende Codes müssen auch im Skript sein: ==== Chromix Tools ==== Sagt schon alles: Autor Chromix CxTools = CxTools or {}; function CxTools:Init() CxTools:InitUnpackFix(); CxTools:InitTriggers(); end --######################################################################### --### --### Utility Functions --### function CxTools.Panic(_text) Message("-----------------------------------------"); Message("Error: " .. tostring(_text)); Message("-----------------------------------------"); --assert(false,tostring(_text)) local _table = { text = _text }; StartSimpleJob(CxTools.GlobalTriggerDebug, _table); end function CxTools.PanicOrig(_text) Message("Hallo Welt") assert(false,tostring(_text)) 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 ) 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 ) tRes = { xpcall( function() return CxTools:callbackWrapperActionReal( _sTriggerId ); end, CxTools.PanicOrig ) }; 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(); ==== Winkel & GetDistance ==== Autor mir leider unbekannt FIXME Winkel = function(_Pos1,_Pos2) local delta_X = 0; local delta_Y = 0; local alpha = 0 if type (_Pos1) == "string" or type (_Pos1) == "number" then _Pos1 = GetPosition(GetEntityId(_Pos1)); end if type (_Pos2) == "string" or type (_Pos2) == "number" then _Pos2 = GetPosition(GetEntityId(_Pos2)); end delta_X = _Pos1.X - _Pos2.X delta_Y = _Pos1.Y - _Pos2.Y if delta_X == 0 and delta_Y == 0 then -- Gleicher Punkt return 0 end alpha = math.deg(math.asin(math.abs(delta_X)/(math.sqrt(__pow(delta_X, 2)+__pow(delta_Y, 2))))) if delta_X >= 0 and delta_Y > 0 then alpha = 270 - alpha elseif delta_X < 0 and delta_Y > 0 then alpha = 270 + alpha elseif delta_X < 0 and delta_Y <= 0 then alpha = 90 - alpha elseif delta_X >= 0 and delta_Y <= 0 then alpha = 90 + alpha end return alpha end GetDistance = function(_a, _b) if type(_a) ~= "table" then _a = GetPosition(_a); end if type(_b) ~= "table" then _b = GetPosition(_b); end return math.sqrt((_a.X - _b.X)^2+(_a.Y - _b.Y)^2) end ==== Umlaute ==== Autor mir leider unbekannt FIXME 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 XGUIEng.SetTextOrig = XGUIEng.SetText; XGUIEng.SetText = function(_a,_text) XGUIEng.SetTextOrig(_a, Umlaute( tostring( _text ) )) end end AutoUmlaut() ==== GUI Hacks ==== Diese GUI Hacks müssen irgendwo VOR SetupWalls() ins Skript\\ Die Hacks werden dann in SetupWalls initialisiert\\ ACHTUNG! Die Hacks überschneiden sich mit eigenen Hacks. Bitte nutzt die Vorlage wie in Setupwalls mit table.insert(...) BeforeOrig oder AfterOrig für eure eigenen Hacks dieser Funktionen.\\ \\ Hier ein GUIHack Comfort SetupGUIHack = function(_gui,_mothertable) _mothertable = _mothertable or 0 if _mothertable ~= 0 then if not(type(_G[_mothertable][_gui.."_BeforeOrig"]) == "table") then _G[_mothertable][_gui.."_BeforeOrig"] = {} _G[_mothertable][_gui.."_AfterOrig"] = {} _G[_mothertable][_gui.."_OrigProtected"] = _G[_mothertable][_gui] _G[_mothertable][_gui] = function(...) local DoOrig = true local _result for i = 1,table.getn(_G[_mothertable][_gui.."_BeforeOrig"]) do if _G[_mothertable][_gui.."_BeforeOrig"][i](unpack(arg)) == false then DoOrig = false end end if DoOrig then _result = _G[_mothertable][_gui.."_OrigProtected"](unpack(arg)) end for i = 1,table.getn(_G[_mothertable][_gui.."_AfterOrig"]) do _G[_mothertable][_gui.."_AfterOrig"][i](unpack(arg)) end return _result end end else if not(type(_G[_gui.."_BeforeOrig"]) == "table") then _G[_gui.."_BeforeOrig"] = {} _G[_gui.."_AfterOrig"] = {} _G[_gui.."_OrigProtected"] = _G[_gui] _G[_gui] = function(...) local DoOrig = true local _result for i = 1,table.getn(_G[_gui.."_BeforeOrig"]) do if _G[_gui.."_BeforeOrig"][i](unpack(arg)) == false then DoOrig = false end end --_G[_gui.."_BeforeOrig"][i](unpack(arg)) end if DoOrig then _result = _G[_gui.."_OrigProtected"](unpack(arg)) end for i = 1,table.getn(_G[_gui.."_AfterOrig"]) do _G[_gui.."_AfterOrig"][i](unpack(arg)) end return _result end end end end Und hier mal quer ein paar GUI Hacks. Mit denen ist mindestens der Mauercomfort abgedeckt SetupGUIHack("GUITooltip_ConstructBuilding") SetupGUIHack("SellBuilding","GUI") SetupGUIHack("GUIAction_DoNotDestroyBuilding") SetupGUIHack("GameCallback_OnBuildingConstructionComplete") SetupGUIHack("GUITooltip_ResearchTechnologies") SetupGUIHack("GUIUpdate_Armor") SetupGUIHack("MPTrade_ChangeResourceAmount","GUI") SetupGUIHack("KeyBindings_TogglePause") SetupGUIHack("GUIAction_PlaceBuilding") SetupGUIHack("GUIAction_BlessSettlers") SetupGUIHack("GUITooltip_UpgradeBuilding") SetupGUIHack("GUIAction_ToggleMenu") SetupGUIHack("GameCallback_GUI_SelectionChanged")