Ich habe eine neue Version erstellt.
Code: Alles auswählen
function InitInterpolisation()
for i = 0,1000 do
Interpolation[i] = math.floor((math.cos(math.pi/(1000-1)*i)+1)/2*1000)
end
end
function Interpoliere(Wert1, Wert2, Nr, Von)
--Interpoliert zwischen 2 Werten
-- Nr ist gibt den Punkt an den man ermitteln möchte. Von die Anzahl der Interpolations schrite
Wert1_Faktor = Interpolation[math.floor((Interpolation_Bereich* Nr) / Von)]
return math.floor((Wert1*Wert1_Faktor) / 1000)
+ math.floor((Wert2*(1000 - Wert1_Faktor)) / 1000)
end
function InterpoliereLinear(Wert1, Wert2, FaktorWert1)
return Wert1*FaktorWert1 + Wert2*(1-FaktorWert1)
end
function Rotate2D(x,y,alpha)
sinus = math.sin(alpha)
cosinus = math.cos(alpha)
ergx = math.floor(x*cosinus + y*sinus)
ergy = math.floor(x*sinus + y*cosinus)
return ergx, ergy
end
function GeneriereKarte()
durchlauf = 1
Persistenz = dlg:getInteger('Persistenz (1-8)')
Temp2D = {}
for i = 0, map:width()-1 do
Werte2D[i] = {}
for j = 0, map:height()-1 do
Werte2D[i][j] = 0
end
end
for durchlauf = 1, dlg:getInteger('Detaillevel (1-8)') do
if durchlauf > 1 then
for i = 0, map:width()-1 do
Temp2D[i] = {}
for j = 0, map:height()-1 do
Temp2D[i][j] = Werte2D[i][j]
Werte2D[i][j] = 0
end;
end
end
AufloesungX = math.floor(map:width() / (durchlauf+1))
AufloesungY = math.floor(map:height() / (durchlauf+1))
for i = 0, map:width()-1 do
for j = 0, map:height()-1 do
if (math.mod(i,AufloesungX) == 0) and
(math.mod(j,AufloesungY) == 0) then
Werte2D[i][j] = math.random(255)
end
if (i == map:width()-1) and
(math.mod(j,AufloesungY) == 0) then
Werte2D[i][j] = math.random(255)
end
if (j == map:height()-1) and
(math.mod(i,AufloesungX) == 0) then
Werte2D[i][j] = math.random(255)
end
end
end
for i = 0, math.floor(map:width() / AufloesungX)-1 do
for j = 0, math.floor(map:height() / AufloesungY)-1 do
for x = 0, AufloesungX-1 do
RandX = (i+1)*AufloesungX
RandY = (j+1)*AufloesungY
if RandX > map:width()-1 then
RandX = map:width()-1
end
if RandY > map:height()-1 then
RandY = map:height()-1
end
x1 = Interpoliere(Werte2D[(i*AufloesungX)][j*AufloesungY], Werte2D[RandX][(j)*AufloesungY],x,AufloesungX)
x2 = Interpoliere(Werte2D[((i)*AufloesungX)][RandY], Werte2D[RandX][RandY],x,AufloesungX)
for y = 0, AufloesungY-1 do
erg = Interpoliere(x1,x2,y, AufloesungY)
Werte2D[(i*AufloesungX)+x][j*AufloesungY+y] = erg
end
end --for x = 0, AufloesungX-1 do
end -- for j = 0, math.floor(map:height() div AufloesungY)-1 do
end --for i = 0, math.floor(map:width() / AufloesungX)-1 do
if durchlauf > 1 then
for x= 0, map:width()-1 do
for y = 0, map:height()-1 do
-- VerschiebungX = math.random(AufloesungX)
-- VerschiebungY = math.random(AufloesungY)
-- if (x+VerschiebungX < map:width()) and
-- (x+VerschiebungY < map:height())then
Werte2D[x][y] = Temp2D[x][y] + math.floor((Werte2D[x][y] - Temp2D[x][y]) / ((durchlauf-1)*Persistenz))
--Temp2D[x][y] + math.floor((Werte2D[x][y] - Temp2D[x][y]) / ((durchlauf-1)*Persistenz))
--math.floor((Temp2D[x][y] + Werte2D[x+VerschiebungX][y+VerschiebungY])/2)
-- math.floor(InterpoliereLinear( Werte2D[x][y],Temp2D[x][y], 1/((durchlauf-1)*Persistenz)) )
end
end
end --if durchlauf > 1 then
end --for durchlauf = 1,6 do
end
function isWater ( position, RandIstWasser )
-- we are creating our own local map variable, as functions should ideally not
-- depend on global variables, only on parameters
local map = asc.getActiveMap()
local kueste = asc.getObjectType( 2502 )
local field = map:getField(position)
-- maybe there is no field for that coordinate
-- because the coordinate is outside the map
if not field then
if RandIstWasser == true then
return true
else
return false
end
end
-- an array holding the names of terrain properties
local waterBits = { 'Water', 'Shallow_water', 'Deep_water', 'Very_shallow_water' }
-- iterating over the array
-- pos will contain the index of the array, which we don't care about
-- value will contain the value, like 'Water', etc.
for pos,value in pairs(waterBits) do
if field:hasProperty( value ) then
if not field:checkForObject( kueste ) then
return true
end
end
end
-- we didn't find any water in the loop
return false
end
function UntersucheUndSetzeKueste()
local map = asc.getActiveMap()
local umgeben = 0;
beach = asc.getObjectType( 2689 )
waves = asc.getObjectType( 2690 )
for i = 0, map:width()-1 do
for j = 0, map:height()-1 do
local feld = map:getField(asc.MapCoordinate(i,j))
WasserAngrenzend = false
kueste_l1 = asc.getObjectType( 2502 )
if isWater(asc.MapCoordinate(i,j), false) == false then
for n = 0,5 do
p = asc.getNeighbouringFieldCoordinate( asc.MapCoordinate(i,j),n )
if isWater(p, false) == true then
asc.placeObject( map, p, waves)
WasserAngrenzend = true
end
end
if WasserAngrenzend then
asc.placeObject( map, asc.MapCoordinate(i,j), beach)
end
end
end
end
end
function SucheFlussStartpunkt()
local map = asc.getActiveMap()
count = 0
gefunden = false
--Startpunkt für den Fluss suchen
--for i = 0, map:width()-1 do
--for j = 0,map:height()-1 do
while gefunden == false do
i = math.random(map:width()-1)
j = math.random(map:height()-1)
if not isWater(asc.MapCoordinate(i,j), false) then
for n = 0,5 do
p = asc.getNeighbouringFieldCoordinate( asc.MapCoordinate(i,j),n )
if isWater(p, false) == true then
if count >= 3 then
gefunden = true
FundKoordinaten = asc.MapCoordinate(i,j);
end
else
count = count + 1
end
end
end
end --while
--end
--end
return gefunden, FundKoordinaten
end
function ZeichneFlusslauefe()
local gefunden, Zeichenposition = SucheFlussStartpunkt();
if gefunden == true then
count = 0
fluss = asc.getTerrainType( 2004 )
asc.placeTerrain( map, Zeichenposition, fluss)
for seiten = 0,5 do
p = asc.getNeighbouringFieldCoordinate( Zeichenposition, seiten )
if isWater(p, false) == false then
count = count + 1
end
if count == 2 then
richtung = seiten
end
end
local FlussBeendet = false
local NaechsteRichtung = 0
local LaengeBisZurKurve = 0
while FlussBeendet == false do
LaengeBisZurKurve = math.random(5)
for i = 1,LaengeBisZurKurve do
Zeichenposition = asc.getNeighbouringFieldCoordinate( Zeichenposition, richtung )
if isWater(Zeichenposition, true) == false then
asc.placeTerrain( map, Zeichenposition, fluss)
else
--FlussBeendet = true
return
end
end
richtung = richtung + math.random(3)-2
if richtung > 5 then
richtung = richtung - 5
end
end
end
end
function StartMapGenerator()
Interpolation={}
Interpolation_Bereich = 1000
InitInterpolisation()
Werte2D={}
map = asc.getActiveMap()
math.randomseed( os.time() )
-- adding various properties
--MainDialog
dlg = asc.PropertyDialog('Terraingenerator by Umpani Ver. 0.2')
dlg:addInteger('Detaillevel (1-8)', 4 )
dlg:addInteger('Persistenz (1-8)', 2 )
dlg:addBool('Karte horizontal spiegeln', false )
dlg:addBool('Karte vertikal spiegeln', false )
dlg:addBool('Strand und Wellen deichnen', true )
result = dlg:run()
--Wasser Dialog
water_dlg = asc.PropertyDialog('Wasserhöhen')
water_dlg:addInteger('Wasserhöhe 1 (1-255)', 120 )
water_dlg:addInteger('Wasserhöhe 2 (1-255)', 90 )
water_dlg:addInteger('Wasserhöhe 3 (1-255)', 50 )
water_dlg:addInteger('Wasserhöhe 4 (1-255)', 30 )
water_dlg:addInteger('Wasserhöhe 5 (1-255)', 20 )
result = water_dlg:run()
--Fluss Dialog
river_dlg = asc.PropertyDialog('Flüsse')
river_dlg:addBool('Flüsse generieren', true )
river_dlg:addInteger('Flussanzahl', 3 )
result = river_dlg:run()
wasser_l1 = asc.getTerrainType( 2004 )
wasser_l2 = asc.getTerrainType( 2002 )
wasser_l3 = asc.getTerrainType( 2001 )
wasser_l4 = asc.getTerrainType( 2003 )
wasser_l5 = asc.getTerrainType( 2005 )
kueste_l1 = asc.getObjectType( 2502 )
gebirge = asc.getObjectType( 2600 )
land = asc.getTerrainType( 2061 )
--Heighmap Generieren
GeneriereKarte()
--Heighmap in Karte Umwandeln
for i = 0, map:width()-1 do
for j = 0, map:height()-1 do
pos = asc.MapCoordinate(i,j)
asc.clearField( map, pos )
if Werte2D[i][j] < water_dlg:getInteger('Wasserhöhe 1 (1-255)') then
asc.placeTerrain( map, pos, wasser_l1)
end
if Werte2D[i][j] < water_dlg:getInteger('Wasserhöhe 2 (1-255)') then
asc.placeTerrain( map, pos, wasser_l2)
end
if Werte2D[i][j] < water_dlg:getInteger('Wasserhöhe 3 (1-255)') then
asc.placeTerrain( map, pos, wasser_l3)
end
if Werte2D[i][j] < water_dlg:getInteger('Wasserhöhe 4 (1-255)') then
asc.placeTerrain( map, pos, wasser_l4)
end
if Werte2D[i][j] < water_dlg:getInteger('Wasserhöhe 5 (1-255)') then
asc.placeTerrain( map, pos, wasser_l5)
end
if Werte2D[i][j] >= water_dlg:getInteger('Wasserhöhe 1 (1-255)') then
asc.placeTerrain( map, pos, land)
end
end
end
--Flüsse zeichnen
if river_dlg:getBool('Flüsse generieren') == true then
for i = 1,river_dlg:getInteger('Flussanzahl') do
ZeichneFlusslauefe()
end
end
--Karte spiegeln vertikal
if dlg:getBool('Karte vertikal spiegeln') == true then
halbX = math.floor((map:width())/2)
for i = 0,halbX do
for j = 0, map:height()-1 do
feld = map:getField(asc.MapCoordinate(i,j))
feldSpiegel = map:getField(asc.MapCoordinate(map:width()-1-i,j))
feldSpiegel:changeTerrainType(feld:getTerrainType())
end
end
end
--Karte spiegeln horizontal
if dlg:getBool('Karte horizontal spiegeln' ) == true then
halbY = math.floor((map:height())/2)
for j = 0, halbY do
for i = 0,map:width()-1 do
feld = map:getField(asc.MapCoordinate(i,j))
feldSpiegel = map:getField(asc.MapCoordinate(i,map:height()-1-j))
feldSpiegel:changeTerrainType(feld:getTerrainType())
end
end
end
--Küsten werden generiert
if dlg:getBool('Strand und Wellen deichnen') == true then
UntersucheUndSetzeKueste()
end
--IstVonWasserUmschlossen(asc.getCursorPosition( map ),2004)
end
asc.infoMessage('Terrain Generator 0.2 - 03.04.2010 by Umpani')
StartMapGenerator()