Guest User

Untitled

a guest
Aug 17th, 2017
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.75 KB | None | 0 0
  1. # This filter is for casting Worlds from the raw potential of code
  2. # http://brightmoore.net
  3. # My filters may include code and inspiration from PYMCLEVEL/MCEDIT mentors @Texelelf, @Sethbling, @CodeWarrior0, @Podshot_
  4.  
  5. from pymclevel import TAG_String # @Texelelf
  6. from pymclevel import TileEntity # @Texelelf
  7.  
  8. import time # for timing
  9. from math import sqrt, tan, sin, cos, pi, ceil, floor, acos, atan, asin, degrees, radians, log, atan2
  10. from random import *
  11. from numpy import *
  12. from pymclevel import alphaMaterials, MCSchematic, MCLevel, BoundingBox, MCMaterials
  13. from mcplatform import *
  14. from os import listdir
  15. from os.path import isfile, join
  16. import glob
  17. from pymclevel import TAG_List, TAG_Byte, TAG_Int, TAG_Compound, TAG_Short, TAG_Float, TAG_Double, TAG_String, TAG_Long
  18. # import from @Texelelf
  19. from copy import deepcopy
  20. import bresenham # @Codewarrior0
  21. from random import Random # @Codewarrior0
  22. import inspect # @Texelelf
  23. from PIL import Image
  24. import png
  25.  
  26. # GLOBAL
  27. CHUNKSIZE = 16
  28.  
  29. # Filter pseudocode:
  30. #
  31.  
  32. inputs = (
  33. ("World Foundry", "label"),
  34. ("Divisions:", 30),
  35. ("Radius:",50),
  36. ("Wiggle:",6),
  37. ("Operation:", (
  38. "Surface",
  39. "Wireframe"
  40. )),
  41. ("Palette:", ( "Random",
  42. "Stone",
  43. "Earth",
  44. "Lava",
  45. "prismarine",
  46. "ice",
  47. "redstone",
  48. "sand",
  49. "redsand",
  50. "wood",
  51. "metals",
  52. "Custom"
  53. )),
  54. ("Custom Blocks:", ("string","value=95:3 22:0 24:2 19:0 18:0 3:0 1:0 80:0") ),
  55. ("Seed:", 1),
  56. ("Ocean:", False),
  57. ("Core:", False),
  58. ("Clouds:", False),
  59. ("Cloud Material:", alphaMaterials.WhiteWool),
  60. ("Transparency Threshold", 128),
  61. ("Filename:", ("string","value=")),
  62. ("[email protected]", "label"),
  63. ("http://brightmoore.net", "label"),
  64. )
  65.  
  66. def createSign(level, x, y, z, text): #abrightmoore - convenience method. Due to Jigarbov - this is not a Sign.
  67. ALIASKEY = "WORLD NUMBER"
  68. COMMANDBLOCK = 137
  69. CHUNKSIZE = 16
  70. STANDING_SIGN = 63
  71.  
  72. setBlock(level, (STANDING_SIGN,8), x, y, z)
  73. setBlock(level, (1,0), x, y-1, z)
  74. control = TAG_Compound()
  75. control["id"] = TAG_String("Sign")
  76. control["Text1"] = TAG_String(ALIASKEY)
  77. control["Text2"] = TAG_String(text)
  78. control["Text3"] = TAG_String("Generated by")
  79. control["Text4"] = TAG_String("@abrightmoore")
  80.  
  81. control["x"] = TAG_Int(x)
  82. control["y"] = TAG_Int(y)
  83. control["z"] = TAG_Int(z)
  84. chunka = level.getChunk((int)(x/CHUNKSIZE), (int)(z/CHUNKSIZE))
  85. chunka.TileEntities.append(control)
  86. chunka.dirty = True
  87.  
  88. def worldGeometry(RAND, BASERADIUS, DIVISIONS, WIGGLE):
  89. ANGLEDELTA = 2*pi/(DIVISIONS+1)
  90. OFFSETANGLELAT = pi/DIVISIONS
  91. ANGLEDELTALAT = (pi-OFFSETANGLELAT*2)/DIVISIONS
  92. aWorld = [[BASERADIUS+RAND.randint(-WIGGLE,WIGGLE) for x in range(DIVISIONS)] for x in range(DIVISIONS)]
  93.  
  94. for i in range(RAND.randint(0,DIVISIONS)):
  95. x = RAND.randint(0,DIVISIONS-1)
  96. y = RAND.randint(0,DIVISIONS-1)
  97. w0 = 0
  98. if WIGGLE > 0:
  99. w0 = RAND.randint(1,WIGGLE)
  100. aWorld[x][y] = aWorld[x][y]-w0
  101.  
  102. return aWorld
  103.  
  104. def worldBuilder(level,box,options):
  105. method = "worldBuilder"
  106. (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(level,box,options,method)
  107. print "Seed:"
  108. PARAM = int(options["Seed:"])
  109. if PARAM == 0:
  110. PARAM = randint(0,99999999999)
  111. print PARAM
  112. RAND = Random(PARAM)
  113.  
  114. # MAXWIGGLE = 8
  115.  
  116. R = centreWidth
  117. if centreHeight < R:
  118. R= centreHeight
  119. if centreDepth < R:
  120. R= centreDepth
  121.  
  122.  
  123. DIVISIONS = options["Divisions:"]
  124. if DIVISIONS < 3:
  125. DIVISIONS = RAND.randint(20,60)
  126. BASERADIUS = options["Radius:"] # R-MAXWIGGLE-RAND.randint(0,int(R/3))
  127. if BASERADIUS < 1:
  128. BASERADIUS = R-MAXWIGGLE-RAND.randint(0,int(R/3))
  129. WIGGLE = options["Wiggle:"]
  130. if WIGGLE < 1:
  131. WIGGLE = RAND.randint(2,MAXWIGGLE)
  132. OPERATION = options["Operation:"]
  133.  
  134. if OPERATION == "Wireframe":
  135. materialFill = (0,0) # AIR
  136.  
  137. # A world is a planet spheroid defined by a bunch of altitudes from the centre
  138. aWorld = worldGeometry(RAND, BASERADIUS, DIVISIONS, WIGGLE)
  139.  
  140. # plot the world in the selection box
  141. cx = centreWidth
  142. cy = centreHeight
  143. cz = centreDepth
  144.  
  145. ANGLEDELTA = 2*pi/(DIVISIONS+1)
  146. OFFSETANGLELAT = pi/DIVISIONS
  147. ANGLEDELTALAT = (pi-OFFSETANGLELAT*2)/DIVISIONS
  148. aWorldWiggle = [[RAND.randint(-1,1)*ANGLEDELTALAT/3 for x in range(DIVISIONS)] for x in range(DIVISIONS)]
  149.  
  150. print 'Pallette Selection'
  151. palette = []
  152. palette.append( [ (1,0),(1,1), (1,2), (1,3), (1,4), (1,5), (1,6), (16,0) ] ) # Stone
  153. palette.append( [ (9,0),(9,0), (12,0), (2,0), (18,0), (17,0), (1,0), (13,0) ] ) # Earth
  154. palette.append( [ (11,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # Lava
  155. palette.append( [ (1,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # prismarine
  156. palette.append( [ (2,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # ice
  157. palette.append( [ (3,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # redstone
  158. palette.append( [ (4,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # sand
  159. palette.append( [ (5,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # redsand
  160. palette.append( [ (6,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # wood
  161. palette.append( [ (7,0),(11,0), (87,0), (88,0), (89,0), (153,0), (213,0), (214,0) ] ) # metals
  162. palette.append( [ (49,0),(11,0), (11,0), (11,0), (11,0), (11,0), (11,0), (11,0) ] ) # Lava with Obsidian base
  163. colours = "15 7 8 0 6 2 10 11 3 9 13 5 4 1 14 12".split() # I like this sequence
  164. coloursList = map(int, colours)
  165. coloursListLen = len(coloursList)
  166. RAND2 = Random(42)
  167. # Choose a colour pallette
  168. for i in range(128): # Stained hardened clay variant
  169. gap = RAND2.randint(1,4)
  170. newCols = []
  171. baseIndex = RAND2.randint(0,coloursListLen)
  172. for j in range(8):
  173. newCols.append( (159, (int)(coloursList[(baseIndex+j*gap)%coloursListLen]) ) )
  174. palette.append(newCols)
  175.  
  176. for i in range(8): # Stained glass variants
  177. gap = RAND2.randint(1,4)
  178. newCols = []
  179. baseIndex = RAND2.randint(0,coloursListLen)
  180. for j in range(8):
  181. newCols.append( (95, (int)(coloursList[(baseIndex+j*gap)%coloursListLen]) ) )
  182. palette.append(newCols)
  183.  
  184. for i in range(64): # Wool variants
  185. gap = RAND2.randint(1,4)
  186. newCols = []
  187. baseIndex = RAND2.randint(0,coloursListLen)
  188. for j in range(8):
  189. newCols.append( (35, (int)(coloursList[(baseIndex+j*gap)%coloursListLen]) ) )
  190. palette.append(newCols)
  191. blocks = palette[PARAM%len(palette)]
  192.  
  193. PALETTESELECTED = options["Palette:"]
  194. if PALETTESELECTED == "Stone":
  195. blocks = palette[0]
  196. elif PALETTESELECTED == "Earth":
  197. blocks = palette[1]
  198. elif PALETTESELECTED == "Lava":
  199. blocks = palette[2]
  200. elif PALETTESELECTED == "prismarine":
  201. blocks = palette[3]
  202. elif PALETTESELECTED == "ice":
  203. blocks = palette[4]
  204. elif PALETTESELECTED == "redstone":
  205. blocks = palette[5]
  206. elif PALETTESELECTED == "sand":
  207. blocks = palette[6]
  208. elif PALETTESELECTED == "redsand":
  209. blocks = palette[7]
  210. elif PALETTESELECTED == "wood":
  211. blocks = palette[8]
  212. elif PALETTESELECTED == "metals":
  213. blocks = palette[9]
  214. elif PALETTESELECTED == "Custom":
  215. BLOCKS = options["Custom Blocks:"]
  216. b1 = BLOCKS.split()
  217. plt = []
  218. for i in b1:
  219. bd = i.split(':')
  220. bd1= map(int, bd)
  221. plt.append( (bd1[0],bd1[1]) )
  222.  
  223. if len(plt) >= 8:
  224. blocks = plt
  225. print 'Custom palette blocks loaded.'
  226. else:
  227. print 'Custom palette blocks ignored: it has less than 8 blocks.'
  228.  
  229. print blocks
  230. print 'Pallette Selection complete'
  231.  
  232. print "Forging the planet..."
  233.  
  234. # do the top and bottom bit
  235. NorthPole = BASERADIUS+RAND.randint(-WIGGLE,WIGGLE)
  236. SouthPole = BASERADIUS+RAND.randint(-WIGGLE,WIGGLE)
  237.  
  238. RENDERWORLD = True
  239. if RENDERWORLD == True:
  240. for longitude in xrange(0,DIVISIONS+1): # http://www.bbc.co.uk/staticarchive/e344e73982934a546e4c9909087547478672e9ad.png
  241. if longitude%10 == 0:
  242. print longitude
  243.  
  244. for latitude in xrange(0,DIVISIONS):
  245. longAngle1 = ANGLEDELTA * longitude + aWorldWiggle[longitude%DIVISIONS][(latitude)%DIVISIONS]
  246. latAngle1 = -pi/2+OFFSETANGLELAT+ANGLEDELTALAT * latitude + aWorldWiggle[longitude%DIVISIONS][(latitude)%DIVISIONS]
  247. longAngle2 = ANGLEDELTA * (longitude+1) + aWorldWiggle[(longitude+1)%DIVISIONS][(latitude)]
  248. latAngle2 = -pi/2+OFFSETANGLELAT+ANGLEDELTALAT * (latitude+1) + aWorldWiggle[longitude%DIVISIONS][(latitude+1)%DIVISIONS]
  249.  
  250.  
  251. (x1,z1,y1) = ((aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * cos(longAngle1) * cos(latAngle1) ),
  252. (aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * sin(longAngle1) * cos(latAngle1) ),
  253. (aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * sin(latAngle1) ))
  254. (x2,z2,y2) = ((aWorld[(longitude)%DIVISIONS][(latitude+1)%DIVISIONS] * cos(longAngle1) * cos(latAngle2) ),
  255. (aWorld[(longitude)%DIVISIONS][(latitude+1)%DIVISIONS] * sin(longAngle1) * cos(latAngle2) ),
  256. (aWorld[(longitude)%DIVISIONS][(latitude+1)%DIVISIONS] * sin(latAngle2) ))
  257. (x3,z3,y3) = ((aWorld[(longitude+1)%DIVISIONS][(latitude+1)%DIVISIONS] * cos(longAngle2) * cos(latAngle2) ),
  258. (aWorld[(longitude+1)%DIVISIONS][(latitude+1)%DIVISIONS] * sin(longAngle2) * cos(latAngle2) ),
  259. (aWorld[(longitude+1)%DIVISIONS][(latitude+1)%DIVISIONS] * sin(latAngle2) ))
  260. (x4,z4,y4) = ((aWorld[(longitude+1)%DIVISIONS][(latitude)%DIVISIONS] * cos(longAngle2) * cos(latAngle1) ),
  261. (aWorld[(longitude+1)%DIVISIONS][(latitude)%DIVISIONS] * sin(longAngle2) * cos(latAngle1) ),
  262. (aWorld[(longitude+1)%DIVISIONS][(latitude)%DIVISIONS] * sin(latAngle1) ))
  263. (x0,z0,y0) = ((x1+x2+x3+x4)/4,(z1+z2+z3+z4)/4,(y1+y2+y3+y4)/4)
  264.  
  265. if OPERATION == "Wireframe":
  266. drawTriangleEdge(level, box, options, (cx+x1,cy+y1,cz+z1),(cx+x2,cy+y2,cz+z2),(cx+x0,cy+y0,cz+z0), blocks[PARAM%len(blocks)])
  267. drawTriangleEdge(level, box, options, (cx+x2,cy+y2,cz+z2),(cx+x3,cy+y3,cz+z3),(cx+x0,cy+y0,cz+z0), blocks[PARAM%len(blocks)])
  268. drawTriangleEdge(level, box, options, (cx+x3,cy+y3,cz+z3),(cx+x4,cy+y4,cz+z4),(cx+x0,cy+y0,cz+z0), blocks[PARAM%len(blocks)])
  269. drawTriangleEdge(level, box, options, (cx+x4,cy+y4,cz+z4),(cx+x1,cy+y1,cz+z1),(cx+x0,cy+y0,cz+z0), blocks[PARAM%len(blocks)])
  270.  
  271. else:
  272. drawTriangleColour(level, box, options, (0,0,0), (cx+x1,cy+y1,cz+z1),(cx+x2,cy+y2,cz+z2),(cx+x0,cy+y0,cz+z0), blocks, (cx,cy,cz), BASERADIUS)
  273. drawTriangleColour(level, box, options, (0,0,0), (cx+x2,cy+y2,cz+z2),(cx+x3,cy+y3,cz+z3),(cx+x0,cy+y0,cz+z0), blocks, (cx,cy,cz), BASERADIUS)
  274. drawTriangleColour(level, box, options, (0,0,0), (cx+x3,cy+y3,cz+z3),(cx+x4,cy+y4,cz+z4),(cx+x0,cy+y0,cz+z0), blocks, (cx,cy,cz), BASERADIUS)
  275. drawTriangleColour(level, box, options, (0,0,0), (cx+x4,cy+y4,cz+z4),(cx+x1,cy+y1,cz+z1),(cx+x0,cy+y0,cz+z0), blocks, (cx,cy,cz), BASERADIUS)
  276.  
  277. if latitude == 0: # South pole
  278. latAngle3 = -pi/2
  279. R2 = SouthPole
  280. (x5,z5,y5) = ((R2 * cos(longAngle1) * cos(latAngle3) ),
  281. (R2 * sin(longAngle1) * cos(latAngle3) ),
  282. (R2 * sin(latAngle3) ))
  283. drawTriangleColour(level, box, options, (0,0,0),(cx+x2,cy+y2,cz+z2),(cx+x3,cy+y3,cz+z3),(cx+x5,cy+y5,cz+z5), blocks, (cx,cy,cz), BASERADIUS)
  284.  
  285. if latitude == DIVISIONS-1:
  286. latAngle3 = pi/2
  287. R2 = NorthPole
  288. (x5,z5,y5) = ((R2 * cos(longAngle2) * cos(latAngle3) ),
  289. (R2 * sin(longAngle2) * cos(latAngle3) ),
  290. (R2 * sin(latAngle3) ))
  291. drawTriangleColour(level, box, options, (0,0,0),(cx+x1,cy+y1,cz+z1),(cx+x4,cy+y4,cz+z4),(cx+x5,cy+y5,cz+z5), blocks, (cx,cy,cz), BASERADIUS)
  292.  
  293. if options["Ocean:"] == True:
  294. print "Ocean..."
  295. for y in xrange(0,height):
  296. if y%10 == 0:
  297. print y
  298. for z in xrange(0,depth):
  299. for x in xrange(0,width):
  300. dx = x-cx
  301. dy = y-cy
  302. dz = z-cz
  303. dist = sqrt(dx*dx+dy*dy+dz*dz)
  304. if dist < BASERADIUS and dist >= BASERADIUS-WIGGLE:
  305. block = getBlock(level,x,y,z)
  306. if block == (0,0): # AIR
  307. setBlock(level,blocks[0],x,y,z)
  308.  
  309. if options["Core:"] == True:
  310. print "Core..."
  311. for y in xrange(0,height):
  312. if y%10 == 0:
  313. print y
  314. for z in xrange(0,depth):
  315. for x in xrange(0,width):
  316. dx = x-cx
  317. dy = y-cy
  318. dz = z-cz
  319. dist = sqrt(dx*dx+dy*dy+dz*dz)
  320. if dist <= BASERADIUS-WIGGLE:
  321. block = getBlock(level,x,y,z)
  322. if block == (0,0): # AIR
  323. if RAND.randint(0,100) < 10:
  324. setBlock(level,blocks[RAND.randint(0,len(blocks)-1)],x,y,z)
  325. else:
  326. setBlock(level,blocks[int(dist)%len(blocks)],x,y,z)
  327.  
  328. if options["Clouds:"] == True:
  329. print "Clouds..."
  330. tempDiv = DIVISIONS
  331. tempWorld = aWorld
  332.  
  333. TRANSPARENCY_T = options["Transparency Threshold"]
  334. CLOUDMATERIALID = options["Cloud Material:"].ID
  335. filenameTop = options["Filename:"]
  336. filenameTop = filenameTop.strip()
  337. if filenameTop == "":
  338. filenameTop = askOpenFile("Select a Cloud image...", False)
  339. f = open(filenameTop, "rb")
  340. data = f.read()
  341. f.close()
  342. reader = png.Reader(bytes=data) # @Sethbling
  343. (w, h, pixels1, metadata) = reader.asRGBA8() # @Sethbling
  344. pixels = list(pixels1) # @Sethbling
  345.  
  346. DIVISIONS = w
  347. aWorld = worldGeometry(RAND, BASERADIUS+9, DIVISIONS, 0)
  348. ANGLEDELTA = 2*pi/(DIVISIONS+1)
  349. OFFSETANGLELAT = pi/DIVISIONS
  350. ANGLEDELTALAT = (pi-OFFSETANGLELAT*2)/DIVISIONS
  351. aWorldWiggle = [[RAND.randint(-1,1)*ANGLEDELTALAT/3 for x in range(DIVISIONS)] for x in range(DIVISIONS)]
  352. cloudLayer = [[(0.1,0.1,0.1) for x in range(DIVISIONS)] for x in range(DIVISIONS)]
  353.  
  354. p = 0
  355. q = 0
  356. (px,py,pz) = (0,0,0) # Init
  357. for longitude in xrange(0,DIVISIONS):
  358. if longitude%100 == 0:
  359. print longitude
  360. for latitude in xrange(0,DIVISIONS):
  361. longAngle1 = ANGLEDELTA * longitude + aWorldWiggle[longitude%DIVISIONS][(latitude)%DIVISIONS]
  362. latAngle1 = -pi/2+OFFSETANGLELAT+ANGLEDELTALAT * latitude + aWorldWiggle[longitude%DIVISIONS][(latitude)%DIVISIONS]
  363.  
  364. (x1,z1,y1) = ((aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * cos(longAngle1) * cos(latAngle1) ),
  365. (aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * sin(longAngle1) * cos(latAngle1) ),
  366. (aWorld[(longitude)%DIVISIONS][(latitude)%DIVISIONS] * sin(latAngle1) ))
  367. cloudLayer[longitude][latitude] = (cx+x1,cy+y1,cz+z1)
  368.  
  369. colour = getPixel(pixels, longitude%h, latitude%w) # after @Sethbling
  370. if opaque(colour, TRANSPARENCY_T): # @Sethbling
  371. (theBlock, theBlockData) = closestMaterial(colour) # @Sethbling
  372. (r,g,b,a) = colour
  373. (x_,y_,z_) = cloudLayer[int(longitude)%DIVISIONS][int(latitude)%DIVISIONS]
  374. setBlock(level, (CLOUDMATERIALID,theBlockData), x_,y_,z_ )
  375.  
  376.  
  377. # Cloud swirly shapes- \\\insert sekrit text here
  378. # p = 0
  379. # q = 0
  380. # (px,py,pz) = (0,0,0) # Init
  381. # for i in xrange(0,1000):
  382. # p = 4*DIVISIONS * sin(i*pi/180)
  383. # q = 5*DIVISIONS * cos(i*pi/180)
  384.  
  385. # (px,py,pz) = cloudLayer[int(p)%DIVISIONS][int(q)%DIVISIONS]
  386. # if i > 0:
  387. # c = 0
  388. # for qx, qy, qz in bresenham.bresenham((int(p),0,int(q)),(int(r),0,int(s))):
  389. # if c > 0:
  390. # drawLine(level, blocks[len(blocks)-1], cloudLayer[int(qx)%DIVISIONS][int(qz)%DIVISIONS], cloudLayer[int(px1)%DIVISIONS][int(pz1)%DIVISIONS])
  391. # (px1,py1,pz1) = (qx,qy,qz)
  392. # c = c+1
  393.  
  394. # (r,s) = (p,q)
  395.  
  396. # c = 0
  397. # for qx, qy, qz in bresenham.bresenham((int(DIVISIONS/2),0,int(DIVISIONS/2)),(int(DIVISIONS/2),0,int(0))):
  398. # if c > 0:
  399. # drawLine(level, blocks[len(blocks)-4], cloudLayer[int(qx)][int(qz)], cloudLayer[int(px1)][int(pz1)])
  400. # (px1,py1,pz1) = (qx,qy,qz)
  401. # c = c+1
  402.  
  403. DIVISIONS = tempDiv
  404. aWorld = tempWorld
  405.  
  406. createSign(level, cx, cy, cz, str(PARAM))
  407.  
  408. FuncEnd(level,box,options,method)
  409.  
  410. def getPixel(pixels, x, y): # @Sethbling
  411. idx = x*4
  412. return (pixels[y][idx], pixels[y][idx+1], pixels[y][idx+2], pixels[y][idx+3])
  413.  
  414. def transparent((r, g, b, a)):
  415. return a < 128
  416.  
  417. def opaque((r, g, b, a), threshold):
  418. return a >= threshold
  419.  
  420. def closestMaterial((r, g, b, a)): # @Sethbling
  421. closest = 255*255*3
  422. best = (35, 0)
  423. for (mat, dat, mr, mg, mb) in materials:
  424. (dr, dg, db) = (r-mr, g-mg, b-mb)
  425. dist = dr*dr+dg*dg+db*db
  426. if dist < closest:
  427. closest = dist
  428. best = (mat, dat)
  429. return best
  430.  
  431. # Map fragment originally by @Sethbling - this needs some work to decouple the colour from the intensity.
  432. materials = [
  433. (35, 0, 221, 221, 221),
  434. (35, 1, 219, 125, 62),
  435. (35, 2, 179, 80, 188),
  436. (35, 3, 107, 138, 201),
  437. (35, 4, 177, 166, 39),
  438. (35, 5, 65, 174, 56),
  439. (35, 6, 208, 132, 153),
  440. (35, 7, 64, 64, 64),
  441. (35, 8, 154, 161, 161),
  442. (35, 9, 46, 110, 137),
  443. (35, 10, 126, 61, 181),
  444. (35, 11, 46, 56, 141),
  445. (35, 12, 79, 50, 31),
  446. (35, 13, 53, 70, 27),
  447. (35, 14, 150, 52, 48),
  448. (35, 15, 25, 22, 22),
  449. ]
  450.  
  451. def drawTriangleColour(level, box, options, (ox, oy, oz), (p1x, p1y, p1z), (p2x, p2y, p2z), (p3x, p3y, p3z), blocks, centre, radius):
  452. # for each step along the 'base' draw a line from the apex
  453. dx = p3x - p2x
  454. dy = p3y - p2y
  455. dz = p3z - p2z
  456.  
  457. distHoriz = dx*dx + dz*dz
  458. distance = sqrt(dy*dy + distHoriz)
  459.  
  460. phi = atan2(dy, sqrt(distHoriz))
  461. theta = atan2(dz, dx)
  462.  
  463. iter = 0
  464. while iter <= distance:
  465. (px, py, pz) = ((int)(p2x+iter*cos(theta)*cos(phi)), (int)(p2y+iter*sin(phi)), (int)(p2z+iter*sin(theta)*cos(phi)))
  466. iter = iter+0.5 # slightly oversample because I lack faith.
  467. drawLineColour(level, (ox+px, oy+py, oz+pz), (ox+p1x, oy+p1y, oz+p1z), blocks, centre, radius )
  468.  
  469. def drawTriangleEdge(level, box, options, (p1x, p1y, p1z), (p2x, p2y, p2z), (p3x, p3y, p3z), materialEdge):
  470. drawLine(level, materialEdge, (p1x, p1y, p1z), (p2x, p2y, p2z) )
  471. drawLine(level, materialEdge, (p1x, p1y, p1z), (p3x, p3y, p3z) )
  472. drawLine(level, materialEdge, (p2x, p2y, p2z), (p3x, p3y, p3z) )
  473.  
  474. def perform(originalLevel,originalBox, options):
  475. ''' Feedback to [email protected] '''
  476. # Local variables
  477. method = "Perform"
  478. (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(originalLevel,originalBox,options,method) # Log start
  479. SUCCESS = True
  480. level = originalLevel.extractSchematic(originalBox) # Working set
  481. box = BoundingBox((0,0,0),(width,height,depth))
  482. # Operations go here - switch to the function based on selected operation
  483. worldBuilder(level, box, options)
  484.  
  485. # Conditionally copy back the working area into the world
  486. if SUCCESS == True: # Copy from work area back into the world
  487. b=range(4096); b.remove(0) # @CodeWarrior0 and @Wout12345 explained how to merge schematics
  488. originalLevel.copyBlocksFrom(level, box, (originalBox.minx, originalBox.miny, originalBox.minz ),b)
  489. originalLevel.markDirtyBox(originalBox)
  490.  
  491. FuncEnd(originalLevel,box,options,method) # Log end
  492.  
  493.  
  494.  
  495. ####################################### CLASSES
  496.  
  497.  
  498.  
  499.  
  500. ####################################### LIBS
  501.  
  502. def FuncStart(level, box, options, method):
  503. # abrightmoore -> shim to prepare a function.
  504. print '%s: Started at %s' % (method, time.ctime())
  505. (width, height, depth) = (box.maxx - box.minx, box.maxy - box.miny, box.maxz - box.minz)
  506. centreWidth = math.floor(width / 2)
  507. centreHeight = math.floor(height / 2)
  508. centreDepth = math.floor(depth / 2)
  509. # other initialisation methods go here
  510. return (method, (width, height, depth), (centreWidth, centreHeight, centreDepth))
  511.  
  512. def FuncEnd(level, box, options, method):
  513. print '%s: Ended at %s' % (method, time.ctime())
  514.  
  515. def getBoxSize(box):
  516. return (box.maxx - box.minx, box.maxy - box.miny, box.maxz - box.minz)
  517.  
  518. def getBlock(level,x,y,z):
  519. return (level.blockAt(x,y,z), level.blockDataAt(x,y,z))
  520.  
  521. def setBlock(level, (block, data), x, y, z):
  522. level.setBlockAt(int(x), int(y), int(z), block)
  523. level.setBlockDataAt(int(x), int(y), int(z), data)
  524.  
  525. # Ye Olde GFX Libraries
  526. def drawLine(scratchpad, (blockID, blockData), (x,y,z), (x1,y1,z1) ):
  527. drawLineConstrained(scratchpad, (blockID, blockData), (x,y,z), (x1,y1,z1), 0 )
  528.  
  529. def drawLineColour(scratchpad, (x,y,z), (x1,y1,z1), blocks, centre, radius ):
  530. drawLineConstrainedColour(scratchpad, (x,y,z), (x1,y1,z1), 0, blocks, centre, radius )
  531.  
  532. def drawLineBresenham(scratchpad, (blockID, blockData), (x,y,z), (x1,y1,z1) ):
  533. for px, py, pz in bresenham.bresenham((x,y,z),(x1,y1,z1)):
  534. setBlock(scratchpad,(blockID, blockData),px,py,pz)
  535. setBlock(scratchpad,(blockID, blockData),x1,y1,z1)
  536.  
  537. def drawLineConstrainedColour(level, (x,y,z), (x1,y1,z1), maxLength, blocks, (cx,cy,cz), BASERADIUS ):
  538. dx = x1 - x
  539. dy = y1 - y
  540. dz = z1 - z
  541.  
  542. distHoriz = dx*dx + dz*dz
  543. distance = sqrt(dy*dy + distHoriz)
  544.  
  545. if distance < maxLength or maxLength < 1:
  546. phi = atan2(dy, sqrt(distHoriz))
  547. theta = atan2(dz, dx)
  548. px = 0
  549. py = 0
  550. pz = 0
  551. ddx = 0
  552. ddy = 0
  553. ddz = 0
  554.  
  555. iter = 0
  556. while iter <= distance:
  557. ix = (int)(x+iter*cos(theta)*cos(phi))
  558. iy = (int)(y+iter*sin(phi))
  559. iz = (int)(z+iter*sin(theta)*cos(phi))
  560.  
  561. ddx = ix-cx
  562. ddy = iy-cy
  563. ddz = iz-cz
  564.  
  565. dist = sqrt(ddx*ddx+ddy*ddy+ddz*ddz)
  566. if dist < BASERADIUS-1:
  567. setBlock(level,blocks[0],ix,iy,iz) # Sea
  568. elif dist < BASERADIUS:
  569. setBlock(level,blocks[1],ix,iy,iz) # Lapis
  570. elif dist < BASERADIUS+1:
  571. setBlock(level,blocks[2],ix,iy,iz) # Sand
  572. elif dist < BASERADIUS+2:
  573. setBlock(level,blocks[3],ix,iy,iz) # Plain
  574. elif dist < BASERADIUS+3:
  575. setBlock(level,blocks[4],ix,iy,iz) # Forest
  576. elif dist < BASERADIUS+4:
  577. setBlock(level,blocks[5],ix,iy,iz) # Mt
  578. elif dist < BASERADIUS+5:
  579. setBlock(level,blocks[6],ix,iy,iz) # Snow
  580. elif dist >= BASERADIUS+5:
  581. setBlock(level,blocks[7],ix,iy,iz) # Snow
  582. iter = iter+0.5 # slightly oversample because I lack faith.
  583.  
  584. def drawLineConstrained(scratchpad, (blockID, blockData), (x,y,z), (x1,y1,z1), maxLength ):
  585. dx = x1 - x
  586. dy = y1 - y
  587. dz = z1 - z
  588.  
  589. distHoriz = dx*dx + dz*dz
  590. distance = sqrt(dy*dy + distHoriz)
  591.  
  592. if distance < maxLength or maxLength < 1:
  593. phi = atan2(dy, sqrt(distHoriz))
  594. theta = atan2(dz, dx)
  595.  
  596. iter = 0
  597. while iter <= distance:
  598. scratchpad.setBlockAt((int)(x+iter*cos(theta)*cos(phi)), (int)(y+iter*sin(phi)), (int)(z+iter*sin(theta)*cos(phi)), blockID)
  599. scratchpad.setBlockDataAt((int)(x+iter*cos(theta)*cos(phi)), (int)(y+iter*sin(phi)), (int)(z+iter*sin(theta)*cos(phi)), blockData)
  600. iter = iter+0.5 # slightly oversample because I lack faith.
  601.  
  602.  
  603. def drawLineConstrainedRandom(scratchpad, (blockID, blockData), (x,y,z), (x1,y1,z1), frequency ):
  604. dx = x1 - x
  605. dy = y1 - y
  606. dz = z1 - z
  607.  
  608. distHoriz = dx*dx + dz*dz
  609. distance = sqrt(dy*dy + distHoriz)
  610.  
  611.  
  612. phi = atan2(dy, sqrt(distHoriz))
  613. theta = atan2(dz, dx)
  614.  
  615. iter = 0
  616. while iter <= distance:
  617. if randint(0,99) < frequency:
  618. scratchpad.setBlockAt((int)(x+iter*cos(theta)*cos(phi)), (int)(y+iter*sin(phi)), (int)(z+iter*sin(theta)*cos(phi)), blockID)
  619. scratchpad.setBlockDataAt((int)(x+iter*cos(theta)*cos(phi)), (int)(y+iter*sin(phi)), (int)(z+iter*sin(theta)*cos(phi)), blockData)
  620. iter = iter+0.5 # slightly oversample because I lack faith.
Advertisement
Add Comment
Please, Sign In to add comment