[[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;