[[http://www.siedler-games.de|{{:sg-link.jpg|}}]] **Bauernhof mal anders**. Habe mir die Zeit genommen um einen Film im Spiel zu schreiben. Er ist zwar noch nicht gebrauchsfertig, aber da es im Moment wegen SpeicherProblemen bei Delayjobs so wie so nicht eingebaut werden kann, versuche ich einen Beitrag hier bei Wiki zu schreiben um das mal zu testen. Ein Bauer baut sich eine Parzelle und bestellt diese. Zum Schuß kommt dann ein Händler und holt die Ware ab. Anschließend wird der Bauer bezahlt. Hört sich einfach an, aber anschauen lohnt sich sicher. Soll in der Endversion einstellbar sein ob und wieviel er bekommt. Als Mapschreiber könnte man das so benutzen, daß als Belohnung für irgendetwas der Bauernhof erlaubt wird. Natürlich muß dann der Platz vorhanden sein. Aufgerufen wird der Hof einfach mit: StartDelayFunc(BauernHof, Erstehungspunkt, Winkel) -- Soll noch Gold kommen. Geht aber noch nicht. //**BauernHof**// heißt die Funktion.\\ //**Erstehungspunkt**//: Da wo der Hof hin soll.\\ //**Winkel**//: in welchem Winkel der Hof stehen soll 0-360°. Sieht putzig aus. Ich empfehle aber zunächst die Variable **lSchnell** auf **true** zu lassen. Der erste Durchlauf dauert sonst etwa 30 Minuten. Diesen Code einfach in eine leere Karte, und ab die Post. Habe übrigens viel gelernt wärend ich dies schrieb. Als komplette Karte ist es hier {{leereversuchskarte.zip}}\\ Habe den Hof noch nicht in die Mitte gestellt. Drückt einfach auf den Serf oben. **Und daß mir ja niemand guckt was der Serf hinter dem Bauernhof macht.** -------------------------------------------------------------------------------- -- MapName: Bauernhof-- -- Author: Robert-- -------------------------------------------------------------------------------- -- Include main function Script.Load( Folders.MapTools.."Main.lua" ) IncludeGlobals("MapEditorTools") lSchnell=true --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called from main script to initialize the diplomacy states function InitDiplomacy() end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called from main script to init all resources for player(s) function InitResources() -- set some resources AddGold (1000) AddSulfur(2000) AddIron (3000) AddWood (4000) AddStone (5000) AddClay (0) end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called to setup Technology states on mission start function InitTechnologies() end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called on game start and after save game is loaded, setup your weather gfx -- sets here function InitWeatherGfxSets() SetupNormalWeatherGfxSet() end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called on game start you should setup your weather periods here function InitWeather() AddPeriodicSummer(10) end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called on game start and after save game to initialize player colors function InitPlayerColorMapping() end --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- This function is called on game start after all initialization is done function FirstMapAction() local VictoryConditionType = 1 if VictoryConditionType == 1 then MapEditor_SetupResourceVictoryCondition() elseif VictoryConditionType == 2 then MapEditor_SetupDestroyVictoryCondition(2) end -- Level 0 is deactivated...ignore MapEditor_SetupAI(2, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(3, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(4, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(5, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(6, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(7, 0, 0, 0, "", 0, 0) MapEditor_SetupAI(8, 0, 0, 0, "", 0, 0) Tools.ExploreArea( -1, -1, 900 ) MapEditor_CreateHQDefeatCondition() if lSchnell then SpeedUpGame() SpeedUpGame() SpeedUpGame() SpeedUpGame() SpeedUpGame() end tListe={} StartDelayFunc(BauernHof,{X=9500, Y=9500},45,55555) end -- Quest data MapEditor_QuestTitle = "" MapEditor_QuestDescription = "" function BauernHof(_pPos,_nAngle,_gold) if _gold== nil or not (type(_gold) == "number") then _gold=0 end tHeu = {} nBHofID=Logic.CreateEntity( Entities.PB_Farm2,_pPos.X,_pPos.Y,_nAngle, 2 ) nBHofWinkel=Logic.GetEntityOrientation(nBHofID) nSin=math.sin((math.rad(Logic.GetEntityOrientation(nBHofID)))) nCos=math.cos((math.rad(Logic.GetEntityOrientation(nBHofID)))) nDeltaY1=-60*nSin --- Abstand Y für kleine Pflanzen nDeltaX1=-60*nCos --- Abstand X für kleine Pflanzen nDeltaY2=-300*nSin --- Abstand Y für große Pflanzen nDeltaX2=-300*nCos --- Abstand X für große Pflanzen nAbstandX=-nCos*1000 nAbstandY=-nSin*1000 tRelPos=RelVonPos(nBHofID,{ rechts = 300, zur = 950 }) nBauer=CreateEntity (1,Entities.PU_Serf,RelVonPos(nBHofID,{rechts=-500,zur=1200}),"Bauer") CreateEntity (1,Entities.XD_ScriptEntity,RelVonPos(nBHofID,{rechts=0,zur=500}),"RuhePunkt") DelayShort(3) aPflanzenKlein={} aPflanzenGross={} -- Jetzt werden die Positionen der Pflanzen in ein Table geschreiben, damit man es nachher nicht jedesmal ausrechnen muß for l = 0,20,3 do for k = 0,20,3 do for i = 0,2 do for j= 0,2 do table.insert( aPflanzenKlein,{ X=tRelPos.X+(k+i)*nDeltaX1+(l+j)*nDeltaY1, Y=tRelPos.Y+(k+i)*nDeltaY1-(l+j)*nDeltaX1} ) end end end end -- Da die Pflanzen, die ich brauchte zwei verschiedene Größen haben muß das zweimal gemacht werden for j= 0,4 do for i = 0,4 do table.insert( aPflanzenGross,{ X=tRelPos.X+i*nDeltaX2+j*nDeltaY2, Y=tRelPos.Y+i*nDeltaY2-j*nDeltaX2} ) end end tIron={} -- Hier werden die Positionen der einzelnen Gitter festgelegt und in das table tIron gepackt entry = { entity = Entities.XD_IronGrid4, angle = 0, diffPosition={ rechts = 375, zur = 700 }} -- relativ zum Bauernhof table.insert(tIron, entry) entry = { entity = Entities.XD_IronGrid4, angle = 0, diffPosition={ rechts = 375, zur = 1125 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 0, diffPosition={ rechts = 375, zur = 1575 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 0, diffPosition={ rechts = 375, zur = 2025 }} table.insert(tIron,entry) --Drehung entry = { entity = Entities.XD_IronGrid4, angle = 90, diffPosition={ rechts = 150, zur = 2250 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 90, diffPosition={ rechts = -300, zur = 2250 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 90, diffPosition={ rechts = -750, zur = 2250 }} table.insert(tIron,entry) -- Drehung entry = { entity = Entities.XD_IronGrid4, angle = 180, diffPosition={ rechts = -975, zur = 2025 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 180, diffPosition={ rechts = -975, zur = 1575 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 180, diffPosition={ rechts = -975, zur = 1125 }} table.insert(tIron,entry) entry = { entity = Entities.XD_IronGrid4, angle = 180, diffPosition={ rechts = -975, zur = 700 }} table.insert(tIron,entry) entry = { entity = Entities.XD_MiscBank1, -- noch ne Bank rein angle = 180, diffPosition={ rechts = 300, zur = 700 }} table.insert(tIron,entry) entry = { entity = Entities.XD_MiscTable1, -- ein Tisch zum essen angle = 90, diffPosition={ rechts = 150, zur = 700 }} table.insert(tIron,entry) entry = { entity = Entities.XD_LargeCampFire, -- ein Lagerfeuer zum aufwärmen angle = 270, diffPosition={ rechts = -550, zur = 700 }} table.insert(tIron,entry) local zaehler = table.getn(tIron) -- Ich wußte zwar nachher die Anzahl, nur wenn ich es anders machen wollte, local tEntityPos -- brauchte ich hier nichts mehr zu ändern deshalb: table.getn(tIron) local bauerPos for i = 1, table.getn(tIron) do -- je nachdem woh das Gitter stehl, muß der Bauer ja auch an eine andere Position tEntityPos=RelVonPos(nBHofID,tIron[i].diffPosition) if tIron[i].angle == 0 then -- diese Position ist auch abhängig vom relativen Winkel zum Bauernhof bauerPos=RechtsVonPos(nBHofID,-100,tEntityPos) elseif tIron[i].angle == 90 then bauerPos=ZurEntity(nBHofID,-100,tEntityPos) elseif tIron[i].angle == 180 then bauerPos=RechtsVonPos(nBHofID,-100,tEntityPos) elseif tIron[i].angle == 270 then bauerPos=RechtsVonPos(nBHofID,100,tEntityPos) else return end Laufe("Bauer",bauerPos) -- damit überwache ich, ob der Bauer noch läuft DrehEntity("Bauer",tEntityPos) -- Drehen, damit er auch in Richtung Eisen klopft Logic.SetTaskList( GetEntityId("Bauer"), TaskLists.TL_SERF_BUILD ) -- klopfen Logic.CreateEffect( GGL_Effects.FXBuildingSmoke,tEntityPos.X ,tEntityPos.Y , 4); -- Rauch Logic.CreateEffect( GGL_Effects.FXBuildingSmokeLarge,tEntityPos.X ,tEntityPos.Y , 4); Delay(3) Logic.CreateEffect( GGL_Effects.FXBuildingSmoke,tEntityPos.X ,tEntityPos.Y , 4); Logic.CreateEffect( GGL_Effects.FXBuildingSmokeMedium,tEntityPos.X ,tEntityPos.Y , 4); Delay(3) Logic.CreateEffect( GGL_Effects.FXBuildingSmoke,tEntityPos.X ,tEntityPos.Y , 4); Delay(3) if tIron[i].angle == 0 then bauerPos=RechtsVonPos(nBHofID,-200,tEntityPos) elseif tIron[i].angle == 90 then bauerPos=ZurEntity(nBHofID,-280,tEntityPos) elseif tIron[i].angle == 180 then bauerPos=RechtsVonPos(nBHofID,-280,tEntityPos) elseif tIron[i].angle == 270 then bauerPos=RechtsVonPos(nBHofID,280,tEntityPos) else -- darf es nicht geben, also ende return end SetPosition(GetEntityId("Bauer"),bauerPos) -- Bauer wegstellen, sonst hängt er fest wenn Logic.CreateEntity( tIron[i].entity, tEntityPos.X, tEntityPos.Y,nBHofWinkel+tIron[i].angle, 2 ) -- wie vor das Gitter erzeugt wird end while true do DelayShort(3) PPause() -- pinkeln gehen (hinter dem Bauernhof) Laufe("Bauer","RuhePunkt") -- kleine Pause Delay(5) for i = 5, table.getn(aPflanzenKlein),9 do -- jetzt kommt das oben gemachte table zum Zug Laufe("Bauer",aPflanzenKlein[i]) -- Der Bauer läuft jetzt immer zu einer Position in der Mitte von 9 Pflanzen for k = 1, 9 do if not (k == 5) then -- 5 muß augeklammert werden, da steht er drauf DrehEntity("Bauer",aPflanzenKlein[k+i-5]) -- er dreht sich zu einer Pflanzen-Position Logic.SetTaskList( GetEntityId("Bauer"), TaskLists.TL_SERF_EXTRACT_RESOURCE ) -- jetzt hackt er Delay(1) end Logic.CreateEntity( 297, aPflanzenKlein[k+i-5].X, aPflanzenKlein[k+i-5].Y ) -- und ein haufen dreck entsteht _OP_CleanUp(aPflanzenKlein[k+i-5], 10,Entities.XD_PlantMoor2)-- die Pflanzen dort werden entfernt end end Bewaessern(aPflanzenKlein) --fürs Bewässern eine eigene Funktion Move("Bauer","RuhePunkt") -- Pause Pflanzen(289) -- jetzt wächst alles langsam Pflanzen(301) -- hätte hier die Entity-Namen reinschreiben sollen Pflanzen(300) -- für jede Pflanze Funktion laufen lassen Pflanzen(312) for i = 1 ,table.getn(aPflanzenKlein) do _OP_CleanUp(aPflanzenKlein[i], 1,300) --- letzte kleine Pflanzen entfernen, da ich das nicht in der Funktion gemacht habe end Pflanzen(315) PPause() -- nochmal pinkeln StartDelayFunc(Salesman) -- der Händler kommt for i = 5, table.getn(aPflanzenKlein),9 do -- hier erntet der Bauer nach dem gleichen Schema wie das Hacken oben Laufe("Bauer",aPflanzenKlein[i]) for k = 1, 9 do if not (k == 5) then DrehEntity("Bauer",aPflanzenKlein[k+i-5]) Logic.SetTaskList( GetEntityId("Bauer"), TaskLists.TL_SERF_EXTRACT_WOOD ) Delay(1) end Logic.CreateEntity( Entities.XD_PlantMoor2, aPflanzenKlein[k+i-5].X, aPflanzenKlein[k+i-5].Y ) end _OP_CleanUp(aPflanzenKlein[i], 100,315) if ((i-3) / 7) == math.floor ((i-3) / 7) and i > 5 then table.insert(tHeu,Logic.CreateEntity( Entities.XD_MiscHaybale1, aPflanzenKlein[i].X, aPflanzenKlein[i].Y )) -- nur hier kommen noch Heuballen hin, wenn er eine Reihe fertig hat. SetPosition(GetEntityId("Bauer"),ZurEntity(nBHofID,-200,GetPosition("Bauer"))) end end while IsAlive("Haendler") do Delay(1) end end end function Salesman() --- Das ist jetzt die Arbeit des Händlers local nWieOft=0 CreateEntity(2, Entities.PU_Travelling_Salesman, ZurEntity(nBHofID,-800), "Haendler" ) -- erstmal hinter dem Hof enstehen while true do -- Mach die Schleife bis ich Stop sage while table.getn(tHeu) == 0 do -- Programm warted bis es Heuballen gibt Delay(1) end Laufe("Haendler",GetPosition(tHeu[1]) ) -- Händer läuft zum Heuballen DestroyEntity(tHeu[1]) -- Heuballen verschwindet tHeu={} nWieOft=nWieOft+1 Laufe("Haendler", ZurEntity(nBHofID,-800) )-- Händer läuft hinter den Hof if nWieOft == 7 then -- Wenn alle Ballen geholt sind DestroyEntity("Haendler") -- Händler mit wagen weg CreateEntity(2, Entities.CU_Trader, ZurEntity(nBHofID,-800), "Haendler" )-- Händler ohne Wagen her DelayShort(3) Laufe("Haendler", RechtsVonPos(nBHofID,500) ) -- laufe vor den Hof CreateEntity(1, Entities.XD_MiscTrolley1, ZurEntity(nBHofID,-800), "Karren" ) -- Irgendwo muß der Karren ja sein Laufe("Bauer","RuhePunkt") --Bauer läuft zum Händler Laufe("Haendler", "RuhePunkt" )-- Händler läuft zum Bauern Sound.PlayGUISound(Sounds.VoicesMentor_HAPPY_Farmer) DelayShort(25)-- jetzt wäre der Zeitpunkt für eine Bezahlung --Sound.PlayGUISound(Sounds.VoicesMentor_INFO_Payday_rnd_01) Delay(5) Laufe("Haendler", ZurEntity(nBHofID,-800) ) DestroyEntity("Haendler") DestroyEntity("Karren") return end end end function Pflanzen(nWas) local aListe={} -- hier kommt rein welche Position noch keine neue Pflanze hat if nWas==289 then -- es wird getestet ob es eine kleine oder Große Pflanze ist nWas2=297 -- alte Pflanze merken lGross=false elseif nWas==301 then nWas2=289 lGross=false elseif nWas==300 then nWas2=301 lGross=false elseif nWas==312 then nWas2=300 lGross=true elseif nWas==315 then nWas2=312 lGross=true end if lGross then -- ist es eine große Pflanze ? for i=1,table.getn(aPflanzenGross) do -- So lange noch nicht alle gepflanzt sind table.insert( aListe,aPflanzenGross[i] ) -- Table wird mit den Positionen der großen Pflanzen gefüllt end while table.getn(aListe) > 0 do -- So lange noch nicht alle gepflanzt sind nNummer=GetRandom(table.getn(aListe)) -- Durch Zufall einen aus der Liste auswählen if nNummer==0 then nNummer=1 end _OP_CleanUp(aListe[nNummer], 1,nWas2)-- alte Pflanze weg pPos=aListe[nNummer] Logic.CreateEntity( nWas, pPos.X, pPos.Y )-- neue Pflanze hin Delay(1) -- warte etwas, damit es nach wachsen aussieht table.remove (aListe , nNummer) -- aus dem Table entfernen end else -- kleine Pflanze ?? for i=1,table.getn(aPflanzenKlein) do -- Table wird mit den Positionen der kleinen Pflanzen gefüllt table.insert( aListe,aPflanzenKlein[i] ) end while table.getn(aListe) > 0 do-- So lange noch nicht alle gepflanzt sind nNummer=GetRandom(table.getn(aListe))-- Durch Zufall einen aus der Liste auswählen if nNummer==0 then nNummer=1 end _OP_CleanUp(aListe[nNummer], 1,nWas2)-- alte Pflanze weg pPos=aListe[nNummer] Logic.CreateEntity( nWas, pPos.X, pPos.Y )-- neue Pflanze hin Delay(0.1) -- warte etwas, damit es nach Wachsen aussieht (weil hier wesendlich mehr Pflanzen sind, weniger) table.remove (aListe , nNummer)-- aus dem Table entfernen end end end function PPause() -- Pinkel Pause local tPosBP; local nID; Laufe("Bauer",ZurEntity(nBHofID,-400)); -- Bauer läuft hinter den Hof tPosBP=ZurEntity("Bauer",150); -- Position etwas zum Bauern hin nID=Logic.CreateEntity( Entities.XD_Waterfall4, tPosBP.X, tPosBP.Y, Logic.GetEntityOrientation(GetEntityId("Bauer"))+90, 1 ) -- Wasserfall wird erzeugt Delay(10); -- warten bis fertig DestroyEntity(nID); -- Wasserfall weg end function Bewaessern(_tPflanzenKlein) -- fast wie die Pinkelpause local nIDBauer=GetEntityId("Bauer") -- hat ja immer eine andere local pPosBP local nID for i = 77, table.getn(_tPflanzenKlein)-70,18 do Laufe("Bauer",_tPflanzenKlein[i])-- wie beim Pflanzen pPosBP=ZurEntity("Bauer",-50); -- Abstand zum Bauern for i = 1,72 do -- sieht dann fast so aus, als ob er sich flüssig dreht DrehEntity("Bauer",i*5) -- Bauer immer drehen DestroyEntity(nID) -- alter wasserfall weg nID=Logic.CreateEntity( Entities.XD_Waterfall4, pPosBP.X, pPosBP.Y, Logic.GetEntityOrientation(nIDBauer)+90, 1 ) ´ -- neuer hin end DestroyEntity(nID) end end function Spraenkeln(_tPflanzenKlein) -- Die Funktion ist nicht drin, kann aber eingebaut werden. -- Gedanke war den, das der Bauer immer fortschritlicher wird und nacher nicht mehr selbst bewässern muß local nPos={} nAnfang=-9 for k = -9,400,126 do for i = 1,4 do table.insert(nPos,k+i*18) end end local pPosBP; local nID={} for i = 1,144 do DelayShort(1) for k = 1, table.getn(nPos) do DestroyEntity(nID[k]) pPosBP=_tPflanzenKlein[nPos[k]] nID[k]=Logic.CreateEntity( Entities.XD_Waterfall4, pPosBP.X, pPosBP.Y, i*5, 1 ) end end for k = 1, table.getn(nPos) do DestroyEntity(nID[k]) end end function ZurEntity(_entity, _range, _currPos) -- neu geschrieben -- _entity = die Entity zu deren Winkel man sich bewegen will -- _currPos Die Position auf der man sich befindet -- _tRange= die Entfernung zur Entity (im Winkel der Entity) Weiter weg ist dann negativ if type (_entity) == "string" then _entity = GetEntityId(_entity); end local tPos = GetPosition(_entity) if _currPos == nil then _currPos = tPos elseif type (_currPos) == "string" or type (_currPos) == "number" then _currPos = GetPosition(_currPos) end local nEntityAngle=Logic.GetEntityOrientation(_entity); local nSin=math.sin((math.rad(nEntityAngle))); local nCos=math.cos((math.rad(nEntityAngle))); local tPos = GetPosition(_entity) return {X=_currPos.X-nCos*_range,Y=_currPos.Y-nSin*_range}; -- Rückgabe=neue Position end --*********************************************************************************************************** function Winkel(_Pos1,_Pos2) local delta_X=0; local delta_Y=0; 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 -- Steht auf dem 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 --*********************************************************************************************************** function RechtsVonPos(_entity,_range,_currPos) -- neu geschrieben -- _entity = die Entity zu deren Winkel man nach rechts will -- _currPos Die Position auf der man sich befindet -- _tRange= die Entfernung nach rechts (im Winkel der Entity) Nach links ist dann negativ if type (_entity) == "string" then _entity = GetEntityId(_entity); end local tPos = GetPosition(_entity) if _currPos == nil then _currPos = tPos elseif type (_currPos) == "string" or type (_currPos) == "number" then _currPos = GetPosition(_currPos) end local nEntityAngle=Logic.GetEntityOrientation(_entity); local nSin=math.sin((math.rad(nEntityAngle))); local nCos=math.cos((math.rad(nEntityAngle))); return {X=_currPos.X+nSin*_range,Y=_currPos.Y-nCos*_range}; -- Rückgabe=neue Position end --*********************************************************************************************************** function RelVonPos(_entity,_DiffPos) --- Diffpos = table mit .rechts und .zur local rueckPos={}; rueckPos=RechtsVonPos( _entity, _DiffPos.rechts); rueckPos=ZurEntity( _entity, _DiffPos.zur, rueckPos ); return rueckPos; -- Rückgabe=neue Position end --*********************************************************************************************************** function _OP_CleanUp(_position, _range,_entity) local Data = { Logic.GetEntitiesInArea( _entity, _position.X, _position.Y, _range, 20)}; local i; for i=2, Data[1]+1 do DestroyEntity(Data[i]); end end --*********************************************************************************************************** function DrehEntity(_entity, _angle) ---_angle kann auch Position oder Entity sein local currAngle; if type (_angle) == "table" or type (_angle) == "string" then _angle=Winkel(_entity, _angle); elseif type (_angle) == "number" then if _angle > 10 and IsAlive(_angle) then _angle=Winkel(_entity, _angle); end end while _angle >= 360 do _angle = _angle - 360; end _angle = math.floor(_angle+ 0.5 ) RotateEntity(_entity, _angle); repeat DelayShort(1); currAngle=math.floor(Logic.GetEntityOrientation(GetEntityId(_entity))+ 0.5 ); until currAngle == _angle end --*********************************************************************************************************** function Laufe(_entity,_tPos) local pEntityWarPos=GetPosition(_entity) if type (_tPos) == "string" or type (_tPos) == "number" then _tPos = GetPosition(_tPos); end Move(_entity,_tPos); DelayShort(2) local pEntityIstPos=GetPosition(_entity) while not (pEntityIstPos.X == pEntityWarPos.X and pEntityIstPos.Y == pEntityWarPos.Y) do --er läuft noch pEntityWarPos=GetPosition(_entity) DelayShort(2) pEntityIstPos=GetPosition(_entity) end end --*********************************************************************************************************** function Laeuft(_entity) local pEntityWarPos=GetPosition(_entity) DelayShort(2) local pEntityIstPos=GetPosition(_entity) if (pEntityIstPos.X == pEntityWarPos.X and pEntityIstPos.Y == pEntityWarPos.Y) then return false --er läuft nicht else return true --er läuft end end --*********************************************************************************************************** function DrehEntityRel(_entity, _angle) local currAngle; if type (_angle) == "table" then _angle=Winkel(_entity, _angle); end currAngle=math.floor(Logic.GetEntityOrientation(GetEntityId(_entity))+ 0.5 ); _angle = _angle + currAngle while _angle >= 360 do _angle = _angle - 360; end _angle = math.floor(_angle+ 0.5 ) RotateEntity(_entity, _angle); repeat DelayShort(1); currAngle=math.floor(Logic.GetEntityOrientation(GetEntityId(_entity))+ 0.5 ); until currAngle == _angle end -- Beginn DelayJob 3 --********************************************************************************************************************** CxTools = CxTools or {}; --fix unpack() if needed function unpack2(_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 if not unpack( { true } ) then unpack = unpack2; end CxTools.tDelayFuncs = CxTools.tDelayFuncs or {}; CxTools.tDelayFuncsJob = false; function CxTools:StartDelayFunc( _func, ... ) assert( type(_func) == "function" ); local thread = coroutine.create( _func ); local fThread = function() local tRes = { coroutine.resume( thread, unpack( arg ) ) }; local res = table.remove( tRes, 1 ); if not res then if self.tDelayFuncsJob then EndJob( self.tDelayFuncsJob ); end assert( false, "DelayFunc error: " .. (retval or "unknown") ); end local retval = table.remove( tRes, 1 ); if type( retval ) == "function" then retval( unpack( tRes ) ); retval = nil; end if not retval then return false; -- function ends end assert( type( retval ) == "number" ); assert( math.floor( retval ) == retval ); assert( retval ~= 0 ); return true, retval; -- true, number of seconds to delay end local status, retval = fThread(); if status then local entry = {}; entry.func = fThread; entry.nextTime = Logic.GetCurrentTurn() + retval; table.insert( self.tDelayFuncs, entry ); if not self.tDelayFuncsJob then self.tDelayFuncsJob = StartSimpleHiResJob( "DelayFuncsJob" ); -- Workaround for broken savegame functionalitiy in 1.02 - 1.05 XGUIEng.ShowWidget( gvGUI_WidgetID.MainMenuWindow_SaveGame, 0 ); QuickSave = function() Message( "@color:255,0,0 Das Spiel kann momentan nicht gespeichert werden!" ); end end end end function CxTools:DelayFuncsJob() assert( self.tDelayFuncsJob ); local jobcount = table.getn( self.tDelayFuncs ); if jobcount == 0 then self.tDelayFuncsJob = false; -- Workaround for broken savegame functionalitiy in 1.02 - 1.05 XGUIEng.ShowWidget( gvGUI_WidgetID.MainMenuWindow_SaveGame, 1 ); QuickSave = QuickSaveOrig; return true; end local currentTurn = Logic.GetCurrentTurn(); for i = jobcount, 1, -1 do local entry = self.tDelayFuncs[i]; assert( currentTurn <= entry.nextTime ); if entry.nextTime == currentTurn then local status, retval = entry.func(); if status then entry.nextTime = currentTurn + retval; else table.remove( self.tDelayFuncs, i ); end end end end function CxTools.Delay( _seconds ) assert( type( _seconds ) == "number" ); coroutine.yield( _seconds * 10 ); end function CxTools.DelayShort( _tenthseconds ) assert( type( _tenthseconds ) == "number" ); coroutine.yield( _tenthseconds ); end StartDelayFunc = function( ... ) return CxTools:StartDelayFunc( unpack(arg) ); end; DelayFuncsJob = function() return CxTools:DelayFuncsJob(); end; Delay = CxTools.Delay; DelayShort = CxTools.DelayShort; -- Workaround for broken savegame functionalitiy in 1.02 - 1.05 QuickSaveOrig = QuickSave;