Advertisement
LuaWeaver

SB Terrain

May 29th, 2014
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.73 KB | None | 0 0
  1. local function getNoise() --replace modulescript
  2.     return function(s,f)
  3.         local final={}
  4.        
  5.         --find closest power of two
  6.         local stepPo2=-1 --what power of two we used to get the value
  7.         do
  8.             local po2=0
  9.             repeat
  10.                 stepPo2=stepPo2+1
  11.                 po2=2^stepPo2 --the actual value
  12.             until po2+1>=s
  13.             s=po2+1 --set the adjusted size
  14.         end
  15.        
  16.         for i=1,s do --prepare the table
  17.             final[i]={}
  18.             for j=1,s do
  19.                 if (j==1 or j==s) and (i==1 or i==s) then
  20.                     final[i][j]=math.min(math.max(math.random()*(math.random()>0.5 and 0.5 or -0.5),-0.5),0.5)
  21.                 end
  22.             end
  23.         end
  24.        
  25.         local step=0 --set current iteration
  26.         while step<stepPo2 do --while we haven't gotten to a step that's above our max size
  27.             --i derived these values on pen+paper
  28.             local offset=2^(stepPo2-step-1) --the amount of grid spaces we move each time
  29.             local numSteps=2^step --the number of grid spaces we have to set in the square step
  30.            
  31.             local function halt()
  32.                 if step>3 and math.random()<0.3 then
  33.                     --wait()
  34.                 end
  35.             end
  36.            
  37.             --diamond step
  38.             for xPos=offset+1,s-1,offset*2 do
  39.                 for yPos=offset+1,s-1,offset*2 do
  40.                     final[yPos][xPos]=math.min(math.max(
  41.                         (final[yPos-offset][xPos-offset]+  --top-left
  42.                          final[yPos-offset][xPos+offset]+  --top-right
  43.                          final[yPos+offset][xPos+offset]+  --bottom-right
  44.                          final[yPos+offset][xPos-offset])/ --bottom-left
  45.                          4+math.random()*(math.random()>0.5 and 1 or -1)*f^(step+1), --average and displacement
  46.                          -0.5),0.5)
  47.                     halt()
  48.                 end
  49.             end
  50.            
  51.             --square step
  52.             for xPos=1+offset,s,offset*2 do
  53.                 for yPos=1,s,offset*2 do
  54.                     local count,sum=0,0 --for the average
  55.                     if xPos-offset>=1 then --all of these checks are to make sure it is in-bounds
  56.                         count=count+1
  57.                         sum=sum+final[yPos][xPos-offset]
  58.                     end
  59.                     if xPos+offset<s then
  60.                         count=count+1
  61.                         sum=sum+final[yPos][xPos+offset]
  62.                     end
  63.                     if yPos-offset>=1 then
  64.                         count=count+1
  65.                         sum=sum+final[yPos-offset][xPos]
  66.                     end
  67.                     if yPos+offset<s then
  68.                         count=count+1
  69.                         sum=sum+final[yPos+offset][xPos]
  70.                     end
  71.                     if count>0 then --no division by zero, please
  72.                         final[yPos][xPos]=math.min(math.max(sum/count+math.random()*(math.random()>0.5 and 1 or -1)*f^(step+1),-0.5),0.5) -- average step and displacement
  73.                     end
  74.                 end
  75.                 halt()
  76.             end
  77.             for xPos=1,s,offset*2 do
  78.                 for yPos=1+offset,s,offset*2 do
  79.                     local count,sum=0,0 --for the average
  80.                     if xPos-offset>=1 then --all of these checks are to make sure it is in-bounds
  81.                         count=count+1
  82.                         sum=sum+final[yPos][xPos-offset]
  83.                     end
  84.                     if xPos+offset<s then
  85.                         count=count+1
  86.                         sum=sum+final[yPos][xPos+offset]
  87.                     end
  88.                     if yPos-offset>=1 then
  89.                         count=count+1
  90.                         sum=sum+final[yPos-offset][xPos]
  91.                     end
  92.                     if yPos+offset<s then
  93.                         count=count+1
  94.                         sum=sum+final[yPos+offset][xPos]
  95.                     end
  96.                     if count>0 then --no division by zero, please
  97.                         final[yPos][xPos]=math.min(math.max(sum/count+math.random()*(math.random()>0.5 and 1 or -1)*f^(step+1),-0.5),0.5) -- average step and displacement
  98.                     end
  99.                 end
  100.                 halt()
  101.             end
  102.            
  103.             step=step+1 -- go onto the next iteration
  104.             print(step)
  105.         end
  106.         return final
  107.     end
  108. end
  109.  
  110. local function gen()
  111.     --[[for i,v in pairs(workspace:children()) do
  112.         if (v:IsA("BasePart") or v:IsA("Hint")) and not v:IsA("Terrain") then
  113.             v:Destroy()
  114.         end
  115.     end]]
  116.     local start=tick()
  117.    
  118.     local getNoise=getNoise()
  119.    
  120.     local array=getNoise(2^8+1,0.45)
  121.    
  122.     local noiseFinish=tick()
  123.    
  124.     local amp=120
  125.     local size=3
  126.     local waterHeight=math.random(-20,-5)
  127.     local sandHeight=math.random(5,8)
  128.    
  129.     local water=Instance.new("Part",workspace)
  130.     water.FormFactor="Custom"
  131.     water.Anchored=true
  132.     water.Size=Vector3.new(size*#array,amp/2,size*#array)
  133.     water.CFrame=CFrame.new(size*#array/2,waterHeight-3,size*#array/2)-Vector3.new(0,0.5,0)
  134.     water.BrickColor=BrickColor.new("Toothpaste")
  135.     water.Transparency=0.8
  136.     water.CanCollide=false
  137.    
  138.     for y,row in pairs(array) do
  139.         for x,height in pairs(row) do
  140.             local p=Instance.new("Part",workspace)
  141.             p.FormFactor="Custom"
  142.             p.Size=Vector3.new(size,amp/2,size)
  143.             p.CFrame=CFrame.new(x*size,math.floor(array[y][x]*amp),y*size)
  144.             p.Anchored=true
  145.             Instance.new("BlockMesh",p)
  146.             if math.floor(array[y][x]*amp)<=waterHeight+sandHeight then
  147.                 p.BrickColor=BrickColor.new("Pastel yellow")
  148.                 p.Material="Plastic"
  149.             else
  150.                 p.BrickColor=BrickColor.new("Earth green")
  151.                 p.Material="Grass"
  152.             end
  153.         end
  154.     end
  155.    
  156.     workspace.Message.Text="Generated in "..tick()-start.." seconds. Noise generated in "..noiseFinish-start.." seconds."
  157. end
  158.  
  159. game.Players.PlayerAdded:connect(function(p)
  160.     p.Chatted:connect(function(m)
  161.         if m:lower()=="regen" then
  162.             gen()
  163.         end
  164.     end)
  165. end)
  166.  
  167. gen()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement