[[http://www.siedler-games.de|{{:sg-link.jpg|}}]] ====== Änderungsschutz ====== Angeregt durch die Frage eines Multiplayermapers habe ich ein Script gemacht, in dem man das, was auf der Map steht, in Grenzen schützen kann. \\ \\ Es wird eine Funktion erzeugt, die, wenn sie im Script aufgerufen wird, prüft ob irgendwelche Dinge verändert wurden. Wenn ja, wird es zurückgesetzt \\ \\ Die Prüfung hat zwei Möglichkeiten. \\ \\ Alles was da sein muss, muss in das table **schutzTable**.\\ Alles was da sein muss und nichts neues mehr dazu auf die Map gestellt werden darf, muss in das table **schutzTable2**.\\ Hier darf nicht rein, wovon mehr als 16 auf der Map sind, sonst würde das erste Laden zu lange dauern. \\ Diese beiden Table liegen in einer Datei, die **SchutzTable.lua** heißt: \\ schutzTable={"Wall"} schutzTable2={"XD_VillageCenter","PB_VillageCenter1","PB_VillageCenter2","PB_VillageCenter3","PB_Headquarters3","PB_Headquarters2","PB_Headquarters1","PB_DarkTower3","PB_DarkTower2","PB_DarkTower1"} Diese kann man nach belieben besetzten.\\ Beim Start des nachfolgenden Scripts mit : **lua AenderSchutz.lua "MeineMap.s5x"** oder **lua AenderSchutz.lua "MeineMap"** \\ wird eine Datei erzeugt, die den Namen **MeineMapSchutz.lua** hat. Dort ist dann eine Funktion drin, die, wenn man sie aufruft, alles in den ursprünglichen Stand versetzt. (am Anfang)\\ Du brauchst man : * lua.exe * EntityOut.exe * Die Datei **SchutzTable.lua** * Deine Map * und natürlich dieses Script (bei mir habe ich es **//AenderSchutz.lua//** genannt) \\ alles ins Verzeichnis wo die Map liegt.\\ \\ assert( arg[1], "lua AenderSchutz.lua " ) if string.find(arg[1],"%.") then arg[1] = string.sub(arg[1] ,1 , string.find(arg[1],"%.")-1) end os.execute( 'EntityOut.exe "' .. arg[1]..".s5x" .. '" > EntityOut.tmp' ); local handle = io.output( arg[1].."Schutz.lua" ); handle:write( "function MapSchutz()\n" ); handle:write( "\tlocal myEntities={\n" ); local zeile="\t" myEntities={} dofile("SchutzTable.lua") for line in io.lines( "EntityOut.tmp" ) do if string.sub(line,4) ~= "Type" then local _, _, entitytype, posx, posy, orientation, player, name = string.find( line, "^([^,]+),([%d%.][^,]*),([%d%.][^,]*),([%d%.][^,]*),(%d),(.*)$" ); table.insert(myEntities,{entitytype, posx, posy, orientation, player, name}) end end for i = 1, table.getn(myEntities) do for j = 1, table.getn(schutzTable) do if myEntities[i][1] then if string.find(myEntities[i][1], schutzTable[j]) then zeile=zeile.."{X="..tonumber(myEntities[i][2])..", Y="..tonumber(myEntities[i][3])..",O="..tonumber(myEntities[i][4])..",P="..myEntities[i][5]..",N=\""..myEntities[i][6].."\""..",T=\""..myEntities[i][1].."\"}," if string.len(zeile) > 100 then handle:write( zeile.."\n" ); zeile="\t"; end end end end end handle:write( zeile.."}\n" ); zeile="\t" handle:write( "\tlocal myEntities2Maske={" ); for i = 1,table.getn(schutzTable2) do handle:write( "\""..schutzTable2[i].."\"," ); end handle:write( "}\n" ); handle:write( "\tlocal myEntities2={\n" ); for i = 1, table.getn(myEntities) do for j = 1, table.getn(schutzTable2) do if myEntities[i][1] then if string.find(myEntities[i][1], schutzTable2[j]) then zeile=zeile.."{X="..tonumber(myEntities[i][2])..", Y="..tonumber(myEntities[i][3])..",O="..tonumber(myEntities[i][4])..",P="..myEntities[i][5]..",N=\""..myEntities[i][6].."\""..",T=\""..myEntities[i][1].."\"}," if string.len(zeile) > 100 then handle:write( zeile.."\n" ); zeile="\t"; end end end end end handle:write( zeile.."}\n" ); handle:write( [[ for i = 1,table.getn(myEntities) do local nID=Logic.GetEntityAtPosition(myEntities[i].X,myEntities[i].Y) if not nID then nID=Logic.CreateEntity(Entities[myEntities[i].T],myEntities[i].X,myEntities[i].Y,myEntities[i].O,myEntities[i].P) if myEntities[i].N ~= "" then SetEntityName(nID,myEntities[i].N) end elseif Logic.GetEntityOrientation(nID) ~= myEntities[i].O then DestroyEntity(nID) nID=Logic.CreateEntity(Entities[myEntities[i].T],myEntities[i].X,myEntities[i].Y,myEntities[i].O,myEntities[i].P) if myEntities[i].N ~= "" then SetEntityName(nID,myEntities[i].N) end elseif GetPlayer(nID) ~= myEntities[i].P then ChangePlayer(nID,myEntities[i].P) end end local nSize=Logic.WorldGetSize() local nMitte=nSize/2 nSize=math.sqrt(nSize^2+nSize^2)/2 local jetztEntities={} for i = 1,table.getn(myEntities2Maske) do local data={Logic.GetEntitiesInArea(Entities[myEntities2Maske[i] ],nMitte,nMitte,nSize,16)} table.remove(data,1) for j = 1,table.getn(data) do table.insert(jetztEntities,{Entities[myEntities2Maske[i] ],data[j],Logic.GetEntityOrientation(data[j]),GetPlayer(data[j]),GetPosition(data[j])}) end end for i = table.getn(jetztEntities),1,-1 do for j = table.getn(myEntities2),1,-1 do if jetztEntities[i][1] == Entities[myEntities2[j].T] then if jetztEntities[i][5].X == myEntities2[j].X and jetztEntities[i][5].Y == myEntities2[j].Y then if jetztEntities[i][3] ~= myEntities2[j].O then DestroyEntity(jetztEntities[i][2]) local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P) if myEntities2[j].N ~= "" then SetEntityName(nID,myEntities2[j].N) end end if jetztEntities[i][4] ~= myEntities2[j].P then ChangePlayer(jetztEntities[i][2],myEntities2[j].P) end table.remove(jetztEntities,i) table.remove(myEntities2,j) break end end end end for i =1,table.getn(jetztEntities) do DestroyEntity(jetztEntities[i][2]) end for j =1,table.getn(myEntities2) do if myEntities2[j].T == "XD_VillageCenter" then local nID=Logic.GetEntityAtPosition(myEntities[j].X,myEntities[j].Y) if nID then if not string.find(Logic.GetEntityTypeName(Logic.GetEntityType(nID)),"Village") then -- Villagecenter wurde gelöscht end else local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P) if myEntities2[j].N ~= "" then SetEntityName(nID,myEntities2[j].N) end end else local nID=Logic.CreateEntity(Entities[myEntities2[j].T],myEntities2[j].X,myEntities2[j].Y,myEntities2[j].O,myEntities2[j].P) if myEntities2[j].N ~= "" then SetEntityName(nID,myEntities2[j].N) end end end end ]]);handle:close(); os.execute( "del EntityOut.tmp" );