Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.42 KB | None | 0 0
  1.  
  2. require("randomext")
  3.  
  4. local PlanGenerator = {}
  5.  
  6. function findMaxBlock(plan, dimStr)
  7.  
  8. local result
  9. local maximum = -math.huge
  10. for i = 0, plan.numBlocks - 1 do
  11. local block = plan:getNthBlock(i)
  12.  
  13. local d = block.box.upper[dimStr]
  14. if d > maximum then
  15. result = block
  16. maximum = d
  17. end
  18. end
  19.  
  20. return result
  21. end
  22.  
  23. function findMinBlock(plan, dimStr)
  24.  
  25. local result
  26. local minimum = math.huge
  27. for i = 0, plan.numBlocks - 1 do
  28. local block = plan:getNthBlock(i)
  29.  
  30. local d = block.box.lower[dimStr]
  31. if d < minimum then
  32. result = block
  33. minimum = d
  34. end
  35. end
  36.  
  37. return result
  38. end
  39.  
  40. PlanGenerator.findMinBlock = findMinBlock
  41. PlanGenerator.findMaxBlock = findMaxBlock
  42.  
  43. function PlanGenerator.selectMaterial(faction)
  44. local probabilities = Balancing_GetMaterialProbability(faction:getHomeSectorCoordinates())
  45. local material = Material(getValueFromDistribution(probabilities))
  46.  
  47. local sector = Sector()
  48. if sector then
  49. local x, y = sector:getCoordinates()
  50. local distFromCenter = length(vec2(x, y))
  51.  
  52. if material.value == 6 and distFromCenter > Balancing_GetBlockRingMin() then
  53. material.value = 5
  54. end
  55. end
  56.  
  57. return material
  58. end
  59.  
  60. function PlanGenerator.makeCarrierPlan(faction, volume, styleName, material)
  61. local plan = PlanGenerator.makeShipPlan(faction, volume, styleName, material)
  62.  
  63. local tree = PlanBspTree(plan)
  64.  
  65. -- this is a function that will find blocks on the plan which have free space to the +x or -x direction
  66. local checkFree = function(block, offset)
  67. local width = 40
  68. local box = block.box
  69. local displacement = box.size.x * 0.5 + width * 0.5 + 0.01
  70.  
  71. if box.size.y < 1.3 or box.size.z < 1.3 then return false end
  72.  
  73. box.position = box.position + vec3(displacement, displacement, displacement) * offset
  74. box.size = vec3(width, box.size.y, box.size.z)
  75.  
  76. local blocks = {tree:getBlocksByBox(box)}
  77.  
  78. -- if the only block contained, if any, is the block we're currently iterating, then we're good
  79. local free = false
  80. if #blocks == 0 then free = true end
  81. if #blocks == 1 and blocks[0] == block.index then free = true end
  82.  
  83. return free
  84. end
  85.  
  86. -- first, find all blocks that could potentially be spots for hangars
  87. local potentialBlocks = {}
  88. local numBlocks = plan.numBlocks
  89. for i = 0, numBlocks - 1 do
  90. local block = plan:getNthBlock(i)
  91.  
  92. local potential
  93. local free = checkFree(block, vec3(1, 0, 0))
  94. if free then
  95. potential = {block = block, positive = true}
  96. end
  97.  
  98. local free = checkFree(block, vec3(-1, 0, 0))
  99. if free then
  100. potential = potential or {block = block}
  101. potential.negative = true
  102. end
  103.  
  104. if potential then
  105. table.insert(potentialBlocks, potential)
  106. end
  107.  
  108. end
  109.  
  110. local close = function(a, b, e)
  111. return math.abs(a - b) < e
  112. end
  113.  
  114. -- find mirrored blocks
  115. for i = 1, #potentialBlocks do
  116. for j = i + 1, #potentialBlocks do
  117. local pa = potentialBlocks[i]
  118. local pb = potentialBlocks[j]
  119.  
  120. local a = pa.block
  121. local b = pb.block
  122.  
  123. local sa = a.box.size
  124. local sb = b.box.size
  125.  
  126. if
  127. pa.positive ~= pb.positive
  128. and close(sa.x, sb.x, 0.01)
  129. and close(sa.y, sb.y, 0.01)
  130. and close(sa.z, sb.z, 0.01)
  131. and close(a.box.center.z, b.box.center.z, 0.01)
  132. then
  133. pa.mirror = pb
  134. pb.mirror = pa
  135. end
  136. end
  137. end
  138.  
  139. -- sort by y * z area
  140. local comp = function(a, b)
  141. local s1 = a.block.box.size
  142. local s2 = b.block.box.size
  143.  
  144. local area1 = s1.y * s1.z
  145. local area2 = s2.y * s2.z
  146.  
  147. return area1 > area2
  148. end
  149.  
  150. table.sort(potentialBlocks, comp)
  151.  
  152.  
  153. local equip = function(potential)
  154. potential.used = true
  155.  
  156. local block = potential.block
  157.  
  158. if potential.negative then
  159. local size = block.box.size
  160. size.x = math.max(size.x, 2)
  161.  
  162. local pos = block.box.position - vec3((block.box.size.x + size.x) * 0.5, 0, 0)
  163. plan:addBlock(pos, size, block.index, -1, block.color, block.material, Matrix(), BlockType.Hangar)
  164. end
  165.  
  166. if potential.positive then
  167. local size = block.box.size
  168. size.x = math.max(size.x, 2)
  169.  
  170. local pos = block.box.position + vec3((block.box.size.x + size.x) * 0.5, 0, 0)
  171. plan:addBlock(pos, size, block.index, -1, block.color, block.material, Matrix(), BlockType.Hangar)
  172. end
  173.  
  174. end
  175.  
  176. -- for _, potential in pairs(potentialBlocks) do
  177. -- if potential.positive and potential.negative then
  178. -- plan:setBlockColor(block.index, ColorRGB(1, 1, 0))
  179. -- elseif potential.mirror then
  180. -- plan:setBlockColor(block.index, ColorRGB(1, 0, 1))
  181. -- else
  182. -- plan:setBlockColor(block.index, ColorRGB(0, 1, 1))
  183. -- end
  184. -- end
  185.  
  186. local equipped = 0
  187. for _, potential in pairs(potentialBlocks) do
  188. if potential.used then goto continue end
  189.  
  190. equip(potential)
  191. if potential.mirror then
  192. equip(potential.mirror)
  193. end
  194.  
  195. equipped = equipped + 1
  196. if equipped > 5 then break end
  197.  
  198. ::continue::
  199. end
  200.  
  201. CorrectInefficiencies(plan, 1)
  202.  
  203. return plan
  204. end
  205.  
  206. function PlanGenerator.makeFreighterPlan(faction, volume, styleName, material)
  207. local plan = PlanGenerator.makeShipPlan(faction, volume, styleName, material)
  208.  
  209. local box = plan:getBoundingBox()
  210. local volume = plan.volume
  211.  
  212. -- take the smallest axis, double the size, make a box and cut off everything that's not inside it
  213. -- this makes the ship approximately a cube
  214.  
  215. local smallest = math.min(box.size.x, math.min(box.size.y, box.size.z))
  216.  
  217. box = Box(plan:getBlock(0).box.position, vec3(smallest * 2.0, smallest * 2.0, smallest * 2.0))
  218.  
  219. local l = box.lower
  220. local u = box.upper
  221.  
  222. -- find all blocks that are inside the box
  223. local inside = {}
  224. for i = 0, plan.numBlocks - 1 do
  225.  
  226. local block = plan:getNthBlock(i)
  227. local bl = block.box.lower
  228. local bu = block.box.upper
  229.  
  230. if u.x > bl.x
  231. and l.x < bu.x
  232. and u.y > bl.y
  233. and l.y < bu.y
  234. and u.z > bl.z
  235. and l.z < bu.z then
  236. inside[block.index] = true
  237. end
  238. end
  239.  
  240. -- remove all blocks that are outside the box, starting with the children
  241. local remove = true
  242. while remove do
  243. remove = false
  244.  
  245. for i = 0, plan.numBlocks - 1 do
  246. local block = plan:getNthBlock(i)
  247.  
  248. if block.numChildren == 0 and not inside[block.index] then
  249. plan:removeBlock(block.index)
  250. remove = true
  251. break
  252. end
  253. end
  254. end
  255.  
  256. -- find the front-most block
  257. local front = findMaxBlock(plan, "z")
  258.  
  259. local attachment = BlockPlan()
  260.  
  261. local mat = front.material
  262. local parent = front.index
  263. local block = BlockType.Quarters
  264. local s = front.box.size
  265. local p = front.box.position
  266. local c = front.color
  267. local o = Matrix()
  268.  
  269. local container = PlanGenerator.makeContainerPlan({faction.color1, faction.color2, faction.color3})
  270.  
  271. -- get right-most block and add a thruster to it
  272. local containerMaxBlock = findMaxBlock(container, "z")
  273. local containerMinBlock = findMinBlock(container, "z")
  274.  
  275. -- add the thruster
  276. container:addBlock(containerMaxBlock.box.position + vec3(0, 0, containerMaxBlock.box.size.z + 1) * 0.5, vec3(1, 1, 1), containerMaxBlock.index, -1, c, mat, o, BlockType.Thruster)
  277.  
  278. -- rotate the container from z alignment to x alignment
  279. container:rotate(vec3(0, 1, 0), 1)
  280.  
  281. local cs = container:getBoundingBox().size
  282. cs.x = cs.x - 1.0
  283.  
  284. local left = container
  285. local right = copy(left)
  286. right:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  287.  
  288. local containerPadding = getFloat(0.5, 1.0)
  289. s.z = cs.z + containerPadding
  290. p.z = p.z - containerPadding
  291.  
  292. local structureType = getInt(1, 3)
  293. local containers = getInt(7, 12)
  294.  
  295. if structureType == 1 then
  296. for i = 1, containers do
  297. p.z = p.z + s.z
  298. parent = attachment:addBlock(p, s, parent, -1, c, mat, o, block)
  299.  
  300. attachment:addPlanDisplaced(parent, left, 0, p + vec3((cs.x + s.x) * 0.5, 0, 0))
  301. attachment:addPlanDisplaced(parent, right, 0, p - vec3((cs.x + s.x) * 0.5, 0, 0))
  302. end
  303. elseif structureType == 2 then
  304.  
  305. local up = copy(left)
  306. local down = copy(left)
  307.  
  308. up:rotate(vec3(0, 0, 1), 1)
  309. down:rotate(vec3(0, 0, 1), -1)
  310.  
  311. for i = 1, containers do
  312. p.z = p.z + s.z
  313. parent = attachment:addBlock(p, s, parent, -1, c, mat, o, block)
  314.  
  315. attachment:addPlanDisplaced(parent, left, 0, p + vec3((cs.x + s.x) * 0.5, 0, 0))
  316. attachment:addPlanDisplaced(parent, right, 0, p - vec3((cs.x + s.x) * 0.5, 0, 0))
  317.  
  318. attachment:addPlanDisplaced(parent, up, 0, p + vec3(0, (cs.x + s.y) * 0.5, 0))
  319. attachment:addPlanDisplaced(parent, down, 0, p - vec3(0, (cs.x + s.y) * 0.5, 0))
  320. end
  321. elseif structureType == 3 then
  322. s.y = cs.y * 1.5 + 1
  323.  
  324. for i = 1, containers do
  325. p.z = p.z + s.z
  326.  
  327. parent = attachment:addBlock(p, s, parent, -1, c, mat, o, block)
  328.  
  329. attachment:addPlanDisplaced(parent, left, 0, p + vec3((cs.x + s.x) * 0.5, cs.y * 0.75, 0))
  330. attachment:addPlanDisplaced(parent, left, 0, p + vec3((cs.x + s.x) * 0.5, -cs.y * 0.75, 0))
  331. attachment:addPlanDisplaced(parent, right, 0, p - vec3((cs.x + s.x) * 0.5, cs.y * 0.75, 0))
  332. attachment:addPlanDisplaced(parent, right, 0, p - vec3((cs.x + s.x) * 0.5, -cs.y * 0.75, 0))
  333. end
  334. end
  335.  
  336. -- scale the attachment and plan so they match with good volume relations
  337. local scale = (volume * 0.8 / attachment.volume) ^ (1.0 / 3.0)
  338. attachment:scale(vec3(scale, scale, scale))
  339.  
  340. local scale = (volume * 0.2 / plan.volume) ^ (1.0 / 3.0)
  341. plan:scale(vec3(scale, scale, scale))
  342.  
  343. local back = findMinBlock(attachment, "z")
  344. local front = findMaxBlock(plan, "z")
  345.  
  346. local displace = vec3(front.box.position.x, front.box.position.y, front.box.upper.z) - vec3(back.box.position.x, back.box.position.y, back.box.lower.z)
  347. plan:addPlanDisplaced(front.index, attachment, attachment:getNthIndex(0), displace)
  348.  
  349. CorrectInefficiencies(plan, 1)
  350.  
  351. return plan
  352. end
  353.  
  354. function PlanGenerator.makeShipPlan(faction, volume, styleName, material)
  355. local seed = math.random(0xffffffff)
  356.  
  357. if not volume then
  358. volume = Balancing_GetSectorShipVolume(faction:getHomeSectorCoordinates());
  359. local deviation = Balancing_GetShipVolumeDeviation();
  360. volume = volume * deviation
  361. end
  362.  
  363. if not material then
  364. material = PlanGenerator.selectMaterial(faction)
  365. end
  366.  
  367. local style
  368.  
  369. -- we must create the index here, before the 'if' so there is no asynchronous creation of random values
  370. -- otherwise the random values are different depending on whether there is a style yet or not
  371. local randomIndex = math.random(0xffffffff)
  372.  
  373. if styleName == nil then
  374. -- no name for the style specified, just choose a random one.
  375. local styleNames = {faction:getShipStyleNames()}
  376. styleName = styleNames[(randomIndex % tablelength(styleNames)) + 1]
  377.  
  378. style = faction:getShipStyle(styleName)
  379.  
  380. else
  381. -- make sure the style exists, if it doesn't, create it.
  382. style = faction:getShipStyle(styleName)
  383.  
  384. if style == nil then
  385. style = faction:createShipStyle(styleName)
  386. end
  387. end
  388.  
  389. local plan = GeneratePlanFromStyle(style, Seed(seed), volume, 2000, 1, material)
  390.  
  391. return plan
  392. end
  393.  
  394. function PlanGenerator.makeStationPlan(faction, styleName, scale)
  395. scale = scale or 1.0
  396.  
  397. local seed = math.random(0xffffffff)
  398. local volume = Balancing_GetSectorStationVolume(faction:getHomeSectorCoordinates());
  399. local deviation = Balancing_GetStationVolumeDeviation();
  400. volume = volume * deviation
  401.  
  402. local material = PlanGenerator.selectMaterial(faction)
  403. local style;
  404.  
  405. -- we must create the index here, before the 'if' so there is no asynchronous creation of random values
  406. -- otherwise the random values are different depending on whether there is a style yet or not
  407. local randomIndex = math.random(0xffffffff)
  408.  
  409. if styleName == nil then
  410. -- no name for the style specified, just choose a random one.
  411. local styleNames = {faction:getStationStyleNames()}
  412. local numStyles = tablelength(styleNames)
  413.  
  414. if numStyles == 0 then
  415. style = faction:createStationStyle("Style 1")
  416. else
  417. styleName = styleNames[(randomIndex % numStyles) + 1]
  418. style = faction:getStationStyle(styleName)
  419. end
  420. else
  421. -- make sure the style exists, if it doesn't, create it.
  422. style = faction:getStationStyle(styleName)
  423.  
  424. if style == nil then
  425. style = faction:createStationStyle(styleName)
  426. end
  427. end
  428.  
  429. plan = GeneratePlanFromStyle(style, Seed(seed), volume, 7500, 1, material)
  430.  
  431. plan:scale(vec3(scale, scale, scale))
  432.  
  433. return plan
  434. end
  435.  
  436. function PlanGenerator.makeBigAsteroidPlan(size, resources, material, iterations)
  437.  
  438. iterations = iterations or 10
  439.  
  440. local directions = {
  441. vec3(1, 0, 0), vec3(-1, 0, 0),
  442. vec3(0, 1, 0), vec3(0, -1, 0),
  443. vec3(0, 0, 1), vec3(0, 0, -1)
  444. }
  445.  
  446. local plan = PlanGenerator.makeSmallAsteroidPlan(1.0, resources, material)
  447.  
  448. local centers = {plan:getBlock(0)}
  449. local numCenters = 1
  450.  
  451. for i = 1, iterations do
  452.  
  453. local center = centers[getInt(1, numCenters)]
  454. local dir = directions[getInt(1, 6)]
  455.  
  456. -- make a plan and attach it to the selected center in the selected direction
  457. local other = PlanGenerator.makeSmallAsteroidPlan(1.0, resources, material)
  458. local otherCenter = other:getBlock(0)
  459.  
  460. local displacement = (center.box.size + otherCenter.box.size) * dir * 0.5
  461. other:displace(displacement)
  462.  
  463. local index = plan:addPlan(center.index, other, otherCenter.index)
  464.  
  465. table.insert(centers, plan:getBlock(index))
  466. numCenters = numCenters + 1
  467.  
  468. end
  469.  
  470. local scale = size / plan.radius
  471. plan:scale(vec3(scale, scale, scale))
  472.  
  473. return plan
  474. end
  475.  
  476. function PlanGenerator.makeSmallAsteroidPlan(size, resources, material)
  477.  
  478. resources = resources or 0
  479.  
  480. local plan = BlockPlan()
  481.  
  482. local color = material.blockColor
  483.  
  484. local ls = vec3(getFloat(0.1, 0.5), getFloat(0.1, 0.5), getFloat(0.1, 0.5))
  485. local us = vec3(getFloat(0.1, 0.5), getFloat(0.1, 0.5), getFloat(0.1, 0.5))
  486. local s = vec3(1, 1, 1) - ls - us
  487.  
  488. local hls = ls * 0.5
  489. local hus = us * 0.5
  490. local hs = s * 0.5
  491.  
  492. local stone
  493. local edge
  494. local corner
  495.  
  496. if resources == 0 then
  497. stone = BlockType.Stone
  498. edge = BlockType.StoneEdge
  499. corner = BlockType.StoneCorner
  500. else
  501. stone = BlockType.RichStone
  502. edge = BlockType.RichStoneEdge
  503. corner = BlockType.RichStoneCorner
  504. end
  505.  
  506. local ci = plan:addBlock(vec3(0, 0, 0), s, -1, -1, color, material, Matrix(), stone)
  507.  
  508. -- top bottom
  509. plan:addBlock(vec3(0, hs.y + hus.y, 0), vec3(s.x, us.y, s.z), ci, -1, color, material, Matrix(), stone)
  510. plan:addBlock(vec3(0, -hs.y - hls.y, 0), vec3(s.x, ls.y, s.z), ci, -1, color, material, Matrix(), stone)
  511.  
  512. -- left right
  513. plan:addBlock(vec3(hs.x + hus.x, 0, 0), vec3(us.x, s.y, s.z), ci, -1, color, material, Matrix(), stone)
  514. plan:addBlock(vec3(-hs.x - hls.x, 0, 0), vec3(ls.x, s.y, s.z), ci, -1, color, material, Matrix(), stone)
  515.  
  516. -- front back
  517. plan:addBlock(vec3(0, 0, hs.z + hus.z), vec3(s.x, s.y, us.z), ci, -1, color, material, Matrix(), stone)
  518. plan:addBlock(vec3(0, 0, -hs.z - hls.z), vec3(s.x, s.y, ls.z), ci, -1, color, material, Matrix(), stone)
  519.  
  520.  
  521. -- top left right
  522. plan:addBlock(vec3(hs.x + hus.x, hs.y + hus.y, 0), vec3(us.x, us.y, s.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, 1, 0)), edge)
  523. plan:addBlock(vec3(-hs.x - hls.x, hs.y + hus.y, 0), vec3(ls.x, us.y, s.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 1, 0)), edge)
  524.  
  525. -- top front back
  526. plan:addBlock(vec3(0, hs.y + hus.y, hs.z + hus.z), vec3(s.x, us.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, -1), vec3(0, 1, 0)), edge)
  527. plan:addBlock(vec3(0, hs.y + hus.y, -hs.z - hls.z), vec3(s.x, us.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, 1), vec3(0, 1, 0)), edge)
  528.  
  529. -- bottom left right
  530. plan:addBlock(vec3(hs.x + hus.x, -hs.y - hls.y, 0), vec3(us.x, ls.y, s.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, -1, 0)), edge)
  531. plan:addBlock(vec3(-hs.x - hls.x, -hs.y - hls.y, 0), vec3(ls.x, ls.y, s.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, -1, 0)), edge)
  532.  
  533. -- bottom front back
  534. plan:addBlock(vec3(0, -hs.y - hls.y, hs.z + hus.z), vec3(s.x, ls.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, -1), vec3(0, -1, 0)), edge)
  535. plan:addBlock(vec3(0, -hs.y - hls.y, -hs.z - hls.z), vec3(s.x, ls.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, 1), vec3(0, -1, 0)), edge)
  536.  
  537. -- middle left right
  538. plan:addBlock(vec3(hs.x + hus.x, 0, -hs.z - hls.z), vec3(us.x, s.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, 0, -1)), edge)
  539. plan:addBlock(vec3(-hs.x - hls.x, 0, -hs.z - hls.z), vec3(ls.x, s.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 0, -1)), edge)
  540.  
  541. -- middle front back
  542. plan:addBlock(vec3(hs.x + hus.x, 0, hs.z + hus.z), vec3(us.x, s.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, 0, 1)), edge)
  543. plan:addBlock(vec3(-hs.x - hls.x, 0, hs.z + hus.z), vec3(ls.x, s.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 0, 1)), edge)
  544.  
  545.  
  546. -- top edges
  547. -- left right
  548. plan:addBlock(vec3(hs.x + hus.x, hs.y + hus.y, -hs.z - hls.z), vec3(us.x, us.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, 1, 0)), corner)
  549. plan:addBlock(vec3(-hs.x - hls.x, hs.y + hus.y, -hs.z - hls.z), vec3(ls.x, us.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 0, -1)), corner)
  550.  
  551. -- front back
  552. plan:addBlock(vec3(hs.x + hus.x, hs.y + hus.y, hs.z + hus.z), vec3(us.x, us.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, 0, 1)), corner)
  553. plan:addBlock(vec3(-hs.x - hls.x, hs.y + hus.y, hs.z + hus.z), vec3(ls.x, us.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 1, 0)), corner)
  554.  
  555. -- bottom edges
  556. -- left right
  557. plan:addBlock(vec3(hs.x + hus.x, -hs.y - hls.y, -hs.z - hls.z), vec3(us.x, ls.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, 1), vec3(0, -1, 0)), corner)
  558. plan:addBlock(vec3(-hs.x - hls.x, -hs.y - hls.y, -hs.z - hls.z), vec3(ls.x, ls.y, ls.z), ci, -1, color, material, MatrixLookUp(vec3(1, 0, 0), vec3(0, -1, 0)), corner)
  559.  
  560. -- front back
  561. plan:addBlock(vec3(hs.x + hus.x, -hs.y - hls.y, hs.z + hus.z), vec3(us.x, ls.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(-1, 0, 0), vec3(0, -1, 0)), corner)
  562. plan:addBlock(vec3(-hs.x - hls.x, -hs.y - hls.y, hs.z + hus.z), vec3(ls.x, ls.y, us.z), ci, -1, color, material, MatrixLookUp(vec3(0, 0, -1), vec3(0, -1, 0)), corner)
  563.  
  564. plan:scale(vec3(getFloat(0.3, 1.5), getFloat(0.3, 1.5), getFloat(0.3, 1.5)))
  565.  
  566. local r = size * 2.0 / plan.radius
  567. plan:scale(vec3(r, r, r))
  568.  
  569. plan.convex = true
  570.  
  571. return plan
  572.  
  573. end
  574.  
  575. function PlanGenerator.makeGatePlan(seed, color1, color2, color3)
  576.  
  577. local r = random()
  578. local random = r
  579.  
  580. if seed then random = Random(seed) end
  581.  
  582. local bright = color1 or ColorRGB(0.5, 0.5, 0.5)
  583. local dark = color2 or ColorRGB(0.25, 0.25, 0.25)
  584. local colored = color3 or ColorHSV(random:getFloat(0, 360), random:getFloat(0.5, 0.7), random:getFloat(0.4, 0.6))
  585. local iron = Material()
  586. local orientation = Matrix()
  587. local block = BlockType.BlankHull
  588. local edge = BlockType.EdgeHull
  589.  
  590. local slopes = random:getFloat() < 0.5 and true or false
  591. local lightLines = random:getFloat() < 0.35 and true or false
  592. local rings = false
  593. local rings2 = false
  594. local rings3 = false
  595. local bubbleLights = false
  596. local secondaryLine = random:getFloat() < 0.5 and true or false
  597. local secondaryArms = random:getFloat() < 0.35 and true or false
  598.  
  599. if not lightLines then
  600. rings = random:getFloat() < 0.5 and true or false
  601. rings2 = random:getFloat() < 0.5 and true or false
  602. end
  603.  
  604. if not slopes and not rings then
  605. rings3 = true
  606. end
  607.  
  608. if not lightLines then
  609. bubbleLights = true
  610. end
  611.  
  612. local segment = BlockPlan()
  613.  
  614. -- make main arm
  615. -- create 2 possible thicknesses for the default blocks
  616. local t1 = random:getFloat(1.3, 1.75)
  617. local t2 = random:getFloat(0.75, 1.3)
  618.  
  619. -- choose from the 2 thicknesses
  620. local ta = t2
  621. local tb = random:getFloat() < 0.5 and t1 or t2
  622. local tc = random:getFloat() < 0.5 and t1 or t2
  623.  
  624. local ca = random:getFloat() < 0.5 and bright or dark
  625. local cb = random:getFloat() < 0.5 and bright or dark
  626. local cc = random:getFloat() < 0.5 and bright or dark
  627. local cd = bright
  628.  
  629. if not slopes then cd = colored end
  630.  
  631. local root = segment:addBlock(vec3(0, 1 + 1, 0), vec3(ta, 2, ta), -1, -1, ca, iron, orientation, block)
  632. local a = root
  633.  
  634. local b = segment:addBlock(vec3(0, 1 + 3, 0), vec3(tb, 2, tb), a, -1, cb, iron, orientation, block)
  635. local c = segment:addBlock(vec3(0, 1 + 5, 0), vec3(tc, 2, tc), b, -1, cc, iron, orientation, block)
  636. local d = segment:addBlock(vec3(0, 1 + 7, 0), vec3(2.5, 2.5, 2.5), c, -1, cd, iron, orientation, block)
  637.  
  638. -- antennae front back
  639. -- segment:addBlock(vec3(0, 1 + 7, 2), vec3(0.2, 0.2, 2.5), last, -1, white, iron, orientation, block)
  640. -- segment:addBlock(vec3(0, 1 + 7, -2), vec3(0.2, 0.2, 2.5), last, -1, white, iron, orientation, block)
  641.  
  642. -- antennae outside
  643. local antennae = random:getInt(2, 4)
  644.  
  645. for i = 1, antennae do
  646. local p = random:getVector(-1, 1)
  647. local f = random:getFloat(0.25, 1.75)
  648. p.x = 0;
  649.  
  650. local s = vec3(2.5, 0.05, 0.05) * f
  651. segment:addBlock(vec3(2 + s.x * 0.5 - 1, 1 + 7, 0) + p, s, last, -1, bright, iron, orientation, block)
  652. end
  653.  
  654. if secondaryLine then
  655. segment:addBlock(vec3(1, 1 + 2.875, 0), vec3(0.5, 5.75, 0.5), a, -1, ca, iron, MatrixLookUp(vec3(0, 1, 0), vec3(0, 0, -1)), BlockType.Light)
  656. end
  657.  
  658. if bubbleLights then
  659. segment:addBlock(vec3(0, 1 + 7, 1.5), vec3(0.75, 0.75, 2), d, -1, ca, iron, MatrixLookUp(vec3(0, 1, 0), vec3(0, 0, -1)), BlockType.Light)
  660. segment:addBlock(vec3(0, 1 + 7, -1.5), vec3(0.75, 0.75, 2), d, -1, ca, iron, MatrixLookUp(vec3(0, 1, 0), vec3(0, 0, 1)), BlockType.Light)
  661. end
  662.  
  663. if rings then
  664. local h = 0.1
  665.  
  666. segment:addBlock(vec3(0, 1 + 1, 0), vec3(ta, h, ta) + h, a, -1, ca, iron, orientation, block)
  667. segment:addBlock(vec3(0, 1 + 3, 0), vec3(tb, h, tb) + h, b, -1, cb, iron, orientation, block)
  668. segment:addBlock(vec3(0, 1 + 5, 0), vec3(tc, h, tc) + h, c, -1, cc, iron, orientation, block)
  669. segment:addBlock(vec3(0, 1 + 7, 0), vec3(2.5, h, 2.5) + h, d, -1, bright, iron, orientation, block)
  670. end
  671.  
  672. if rings2 then
  673. local h = 0.1
  674.  
  675. segment:addBlock(vec3(0, 1 + 1, 0), vec3(h, 2.5, ta) + h, a, -1, ca, iron, orientation, block)
  676. segment:addBlock(vec3(0, 1 + 3, 0), vec3(h, 2.5, tb) + h, b, -1, cb, iron, orientation, block)
  677. segment:addBlock(vec3(0, 1 + 5, 0), vec3(h, 2.5, tc) + h, c, -1, cc, iron, orientation, block)
  678. segment:addBlock(vec3(0, 1 + 7, 0), vec3(h, 2.5, 2.5) + h, d, -1, bright, iron, orientation, block)
  679. end
  680.  
  681. if rings3 then
  682. local h = 0.5
  683.  
  684. segment:addBlock(vec3(0, 1 + 1, 0), vec3(ta, h, ta) + h, a, -1, ca, iron, orientation, block)
  685. segment:addBlock(vec3(0, 1 + 3, 0), vec3(tb, h, tb) + h, b, -1, cb, iron, orientation, block)
  686. segment:addBlock(vec3(0, 1 + 5, 0), vec3(tc, h, tc) + h, c, -1, cc, iron, orientation, block)
  687. end
  688.  
  689. if lightLines then
  690. local h = 0.05
  691.  
  692. local block = BlockType.Glow
  693. local color = copy(colored)
  694. color.value = 1.0
  695.  
  696. segment:addBlock(vec3(0, 1 + 1, 0), vec3(h, 2, ta) + h, a, -1, color, iron, orientation, block)
  697. segment:addBlock(vec3(0, 1 + 3, 0), vec3(h, 2, tb) + h, b, -1, color, iron, orientation, block)
  698. segment:addBlock(vec3(0, 1 + 5, 0), vec3(h, 2, tc) + h, c, -1, color, iron, orientation, block)
  699.  
  700. if random:getFloat() < 0.5 then
  701. segment:addBlock(vec3(0, 1 + 7, 0), vec3(2.5, h, 2.5) + h, d, -1, color, iron, orientation, block)
  702. else
  703. segment:addBlock(vec3(0, 1 + 7, 0), vec3(h, 2.5, 2.5) + h, d, -1, color, iron, orientation, block)
  704. end
  705. end
  706.  
  707. if slopes then
  708. -- slope segments
  709. local slopeWidth = random:getFloat(t1 + 0.1, 2.5) -- 2.0 to 2.5, but always smaller than the biggest last element
  710. local slopeColor = colored -- one of the 3
  711. local slopeHeight = random:getFloat(0.5, 1.5)
  712. local slopeDist = random:getFloat() < 0.15 and slopeHeight * 0.125 or random:getFloat(slopeHeight * 0.15, slopeHeight * 0.5)
  713. local slopeStart = random:getFloat(3.0, 5.0)
  714.  
  715. local w = slopeWidth
  716. local hw = w * 0.5
  717. local h = slopeHeight
  718. local hh = h * 0.5
  719. local m1 = MatrixLookUp(vec3(1, 0, 0), vec3(0, 1, 0))
  720. local m2 = MatrixLookUp(vec3(-1, 0, 0), vec3(0, -1, 0))
  721.  
  722. for p = slopeStart, 7, slopeDist * 2.0 do
  723. segment:addBlock(vec3(-hw * 0.5, p, 0), vec3(hw, hh, w), last, -1, slopeColor, iron, m1, edge)
  724. segment:addBlock(vec3(hw * 0.5, p + hh, 0), vec3(hw, hh, w), last, -1, slopeColor, iron, m1, edge)
  725.  
  726. segment:addBlock(vec3(-hw * 0.5, p - hh, 0), vec3(hw, hh, w), last, -1, slopeColor, iron, m2, edge)
  727. segment:addBlock(vec3(hw * 0.5, p, 0), vec3(hw, hh, w), last, -1, slopeColor, iron, m2, edge)
  728. end
  729. end
  730.  
  731. local arm = nil
  732. if secondaryArms then
  733. arm = copy(segment)
  734. end
  735.  
  736. local size = vec3(2, 2, 2)
  737. local plan = BlockPlan()
  738. local root = plan:addBlock(vec3(0, -10, 0), size, -1, -1, bright, iron, orientation, block)
  739. plan:addBlock(vec3(0, 10, 0), size, root, -1, bright, iron, orientation, block)
  740.  
  741. plan:addBlock(vec3(10, 0, 0), size, root, -1, bright, iron, orientation, block)
  742. plan:addBlock(vec3(-10, 0, 0), size, root, -1, bright, iron, orientation, block)
  743.  
  744. -- default
  745. segment:displace(vec3(10, 0, 0))
  746. plan:addPlan(0, segment, 0)
  747.  
  748. -- mirrored down
  749. segment:mirror(vec3(0, 1, 0), vec3(0, 0, 0))
  750. plan:addPlan(0, segment, 0)
  751.  
  752. -- mirrored down other side
  753. segment:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  754. plan:addPlan(0, segment, 0)
  755.  
  756. -- default other side
  757. segment:mirror(vec3(0, 1, 0), vec3(0, 0, 0))
  758. plan:addPlan(0, segment, 0)
  759.  
  760. -- turned
  761. segment:rotate(vec3(0, 0, 1), 1)
  762. plan:addPlan(0, segment, 0)
  763.  
  764. segment:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  765. plan:addPlan(0, segment, 0)
  766.  
  767. segment:mirror(vec3(0, 1, 0), vec3(0, 0, 0))
  768. plan:addPlan(0, segment, 0)
  769.  
  770. segment:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  771. plan:addPlan(0, segment, 0)
  772.  
  773. if secondaryArms then
  774. if random:getFloat() < 0.5 then
  775. arm:rotate(vec3(0, 0, 1), 1)
  776. arm:displace(vec3(-10, 0, 0))
  777. plan:addPlan(0, arm, 0)
  778.  
  779. arm:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  780. plan:addPlan(0, arm, 0)
  781. else
  782. arm:rotate(vec3(0, 0, 1), 1)
  783. arm:rotate(vec3(0, 1, 0), 1)
  784.  
  785. arm:displace(vec3(-10, 0, 0))
  786. plan:addPlan(0, arm, 0)
  787.  
  788. arm:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  789. plan:addPlan(0, arm, 0)
  790.  
  791. if random:getFloat() < 0.5 then
  792. arm:mirror(vec3(0, 0, 1), vec3(0, 0, 0))
  793. plan:addPlan(0, arm, 0)
  794.  
  795. arm:mirror(vec3(1, 0, 0), vec3(0, 0, 0))
  796. plan:addPlan(0, arm, 0)
  797. end
  798.  
  799. end
  800. end
  801.  
  802. plan:addBlock(vec3(0, 0, 0), vec3(20, 20, 0.1), root, -1, bright, iron, orientation, BlockType.Portal)
  803.  
  804. local scale = 6
  805. plan:scale(vec3(scale, scale, scale))
  806. return plan
  807. end
  808.  
  809. function PlanGenerator.makeBeaconPlan(colors)
  810. local container = PlanGenerator.makeContainerPlan(colors)
  811.  
  812. container:scale(vec3(0.5, 0.5, 2))
  813.  
  814.  
  815. local maxZ = findMaxBlock(container, "z")
  816. local minZ = findMinBlock(container, "z")
  817.  
  818. container:addBlock(maxZ.box.position + vec3(0, 0, maxZ.box.size.z), maxZ.box.size, maxZ.index, -1, maxZ.color, maxZ.material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 0, 1)), BlockType.Light)
  819. container:addBlock(minZ.box.position - vec3(0, 0, minZ.box.size.z), minZ.box.size, minZ.index, -1, minZ.color, minZ.material, MatrixLookUp(vec3(1, 0, 0), vec3(0, 0, -1)), BlockType.Light)
  820.  
  821.  
  822.  
  823. return container
  824. end
  825.  
  826. function PlanGenerator.makeContainerPlan(colors_in)
  827. local plan = BlockPlan()
  828.  
  829. -- create root block
  830. local root = plan:addBlock(vec3(0, 0, 0), vec3(2, 2, 2), -1, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  831.  
  832.  
  833. local brightColor = getFloat(0.75, 1);
  834. local darkColor = getFloat(0.2, 0.6);
  835.  
  836. local colors = colors_in
  837. if colors == nil then
  838. colors = {}
  839. table.insert(colors, ColorRGB(brightColor, brightColor, brightColor))
  840. table.insert(colors, ColorRGB(darkColor, darkColor, darkColor))
  841. table.insert(colors, ColorRGB(math.random(), math.random(), math.random()))
  842. end
  843.  
  844. -- maybe add to front, back, top, bottom
  845. if math.random() < 0.2 then
  846. local size = math.random() * 1.5 + 0.5 -- 0.5 to 2.0
  847.  
  848. local color = colors[math.random(1, 3)]
  849.  
  850. plan:addBlock(vec3(0, 1 + size / 2, 0), vec3(size, size, size), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  851. plan:addBlock(vec3(0, -(1 + size / 2), 0), vec3(size, size, size), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  852. end
  853.  
  854. if math.random() < 0.2 then
  855. local size = math.random() * 1.5 + 0.5 -- 0.5 to 2.0
  856.  
  857. local color = colors[math.random(1, 3)]
  858.  
  859. plan:addBlock(vec3(1 + size / 2, 0, 0), vec3(size, size, size), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  860. plan:addBlock(vec3(-(1 + size / 2), 0, 0), vec3(size, size, size), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  861. end
  862.  
  863.  
  864.  
  865. -- now add to the sides
  866. local blockPairs = {}
  867. local added = 0
  868. local maxAdded = math.random() * 2.5 + 1.5 -- 1.5 to 4.0
  869. while added < maxAdded do
  870. local thickness;
  871. local size = math.random() * 1.0 + 1.5 -- 1.5 to 2.5
  872.  
  873. if math.random() < 0.3 then
  874. thickness = math.random() * 0.2 + 0.1 -- 0.1 to 0.3
  875. else
  876. thickness = math.random() * 1.5 + 0.5 -- 0.5 to 2.0
  877. end
  878.  
  879. local color = colors[math.random(1, 3)]
  880.  
  881. local a = plan:addBlock(vec3(0, 0, added + thickness / 2), vec3(size, size, thickness), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  882. local b = plan:addBlock(vec3(0, 0, -(added + thickness / 2)), vec3(size, size, thickness), root, -1, color, Material(), Matrix(), BlockType.CargoBay)
  883.  
  884. if thickness > 1.0 then
  885. table.insert(blockPairs, {a = a, b = b})
  886. end
  887.  
  888. added = added + thickness
  889. end
  890.  
  891. for i, blocks in pairs(blockPairs) do
  892. if math.random() < 0.3 then
  893. -- add x blocks
  894. local newWidth = math.random() * 0.3 + 0.7 -- 0.7 to 1.0
  895. local newThick = math.random() * 0.2 + 0.1 -- 0.1 to 0.3
  896. local newSize = vec3(newThick, newWidth, newWidth)
  897.  
  898. -- block a
  899. local size = plan:getBlock(blocks.a).box.size
  900.  
  901. -- +x
  902. local newPos = plan:getBlock(blocks.a).box.position
  903. newPos.x = newPos.x + (size.x / 2 + newSize.x / 2)
  904. plan:addBlock(newPos, newSize, blocks.a, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  905.  
  906. -- -x
  907. local newPos = plan:getBlock(blocks.a).box.position
  908. newPos.x = newPos.x - (size.x / 2 + newSize.x / 2)
  909. plan:addBlock(newPos, newSize, blocks.a, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  910.  
  911.  
  912. -- block b
  913. local size = plan:getBlock(blocks.b).box.size
  914.  
  915. -- +x
  916. local newPos = plan:getBlock(blocks.b).box.position
  917. newPos.x = newPos.x + (size.x / 2 + newSize.x / 2)
  918. plan:addBlock(newPos, newSize, blocks.b, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  919.  
  920. -- -x
  921. local newPos = plan:getBlock(blocks.b).box.position
  922. newPos.x = newPos.x - (size.x / 2 + newSize.x / 2)
  923. plan:addBlock(newPos, newSize, blocks.b, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  924.  
  925. end
  926.  
  927. if math.random() < 0.3 then
  928. -- add x blocks
  929. local newWidth = getFloat(0.7, 1.0) -- 0.7 to 1.0
  930. local newThick = getFloat(0.1, 0.5) -- 0.1 to 0.5
  931. local newSize = vec3(newWidth, newThick, newWidth)
  932.  
  933. -- block a
  934. local size = plan:getBlock(blocks.a).box.size
  935.  
  936. -- +y
  937. local newPos = plan:getBlock(blocks.a).box.position
  938. newPos.y = newPos.y + (size.y / 2 + newSize.y / 2)
  939. plan:addBlock(newPos, newSize, blocks.a, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  940.  
  941. -- -y
  942. local newPos = plan:getBlock(blocks.a).box.position
  943. newPos.y = newPos.y - (size.y / 2 + newSize.y / 2)
  944. plan:addBlock(newPos, newSize, blocks.a, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  945.  
  946.  
  947. -- block b
  948. local size = plan:getBlock(blocks.b).box.size
  949.  
  950. -- +y
  951. local newPos = plan:getBlock(blocks.b).box.position
  952. newPos.y = newPos.y + (size.y / 2 + newSize.y / 2)
  953. plan:addBlock(newPos, newSize, blocks.b, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  954.  
  955. -- -y
  956. local newPos = plan:getBlock(blocks.b).box.position
  957. newPos.y = newPos.y - (size.y / 2 + newSize.y / 2)
  958. plan:addBlock(newPos, newSize, blocks.b, -1, ColorRGB(1, 1, 1), Material(), Matrix(), BlockType.CargoBay)
  959.  
  960. end
  961.  
  962. end
  963.  
  964. local scale = getFloat(0.8, 1.3)
  965. plan:scale(vec3(scale, scale, scale))
  966.  
  967. return plan
  968. end
  969.  
  970.  
  971. return PlanGenerator
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement