Guest User

ccsand

a guest
Jul 10th, 2013
1,249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 41.80 KB | None | 0 0
  1. --[[
  2. CCSand by CosmoConsole
  3. Supports Redirect API created by GopherAtl
  4.  
  5. License: Creative Commons Attribution-NonCommercial-ShareAlike (http://creativecommons.org/licenses/by-nc-sa/3.0/)
  6.  
  7. A program coded with LUA for dan200's (Daniel Ratcliffe) ComputerCraft mod (http://www.computercraft.info/)
  8. created for Minecraft by Mojang AB (http://minecraft.net/)
  9.  
  10. This program is a falling sand-type of simulator game.
  11.  
  12. Do not change anything beyond this if you are not sure what to do.
  13. --]]
  14.  
  15. -- Build no 111
  16.  
  17. --assert(true, "Program is in development phase. Remove the first line if you're a debugger.")
  18. version = " v0.5"
  19. if term.isColor() == false then
  20.  error("This program requires an Advanced Computer")
  21. end
  22.  
  23. paused = true
  24. on = true
  25. drawing = false
  26. dirty = true
  27. particleLimit = 1000
  28. page = 0
  29. sel = 1
  30. fps = 10
  31. menu = false
  32. debug = false
  33. shouldRender = false
  34. buffer=term
  35. API = false
  36. ipart = nil
  37. statusbar = ""
  38. textReset = os.startTimer(5)
  39. brushSize = 1
  40.  
  41. logs = fs.open("ccsand.log", "a")
  42. function log(s)
  43.  logs.writeLine(os.day() .. "-" .. textutils.formatTime(os.time(),true) .. "; " .. s)
  44. end
  45.  
  46.  
  47.  
  48. -- elements = [1] = {name, bg, fg, ch, type, spread%, grav%, weight, flam, init, inil, inic, ltp, ltr, htp, htr, inv, func, tc, expl, tool}
  49. -- (l/h)t(p/r) = low/high temperature point/reaction
  50. -- inv = can other materials go into it
  51. -- func = own function
  52. -- ini(t/l/c) = initial temperature/life/co-type
  53. -- type; solid = 0, powder = 1, liquid = 2
  54. elements = {
  55.  [0] = {" Air ", colors.black, colors.white, " ", 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 0, 0, 0},
  56.  [1] = {" Sand", colors.yellow, colors.white, ":", 1, 20, 90, 52, 0, 295, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 35, 0, 0},
  57.  [2] = {" Wall", colors.lime, colors.lime, ".", 0, 0, 0, 100, 0, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 80, 0, 0},
  58.  [3] = {"Water", colors.blue, colors.lightBlue, "~", 2, 8, 95, 30, 0, 295, 0, 0, 272.9, 16, 373.1, 15, 0, ["func"] = nil, 25, 0, 0},
  59.  [4] = {" Void", colors.purple, colors.black, "+", 0, 0, 0, 100, 0, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = nil, 80, 0, 0},
  60.  [5] = {"Crazy", colors.white, colors.blue, "X", 0, 0, 0, 0, 0, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = nil, 70, 0, 0},
  61.  [6] = {"  N2 ", colors.lightBlue, colors.white, ":", 0, 0, 0, 10, 0, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = gas_movement, 30, 0, 0},
  62.  [7] = {" Fire", colors.orange, colors.yellow, "^", 2, 8, -100, 24, 0, 595, 20, 0, 373, 18, -1, 0, 1, ["func"] = fire, 40, 0, 0},
  63.  [8] = {" Oil ", colors.green, colors.yellow, "~", 2, 8, 95, 28, 80, 295, 0, 0, -1, 0, 600, 7, 0, ["func"] = nil, 40, 0, 0},
  64.  [9] = {"  O2 ", colors.lightBlue, colors.white, "O", 0, 0, 0, 10, 90, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = gas_movement, 30, 0, 0},
  65.  [10] = {" Wood", colors.yellow, colors.brown, ":", 0, 0, 0, 100, 60, 293, 0, 0, -1, 0, 600, 7, 0, ["func"] = nil, 55, 0, 0},
  66.  [11] = {" TNT ", colors.red, colors.pink, "T", 0, 0, 0, 100, 100, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 35, 1, 0},
  67.  [12] = {"Insul", colors.lightGray, colors.magenta, ":", 0, 0, 0, 100, 0, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 0, 0, 0},
  68.  [13] = {"*Heat", colors.red, colors.black, "H", 0, 0, 0, 100, 100, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 35, 1, 1},
  69.  [14] = {"*Cool", colors.blue, colors.black, "C", 0, 0, 0, 100, 0, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = nil, 0, 0, 2},
  70.  [15] = {"Steam", colors.lightGray, colors.white, ";", 2, 8, -95, 10, 0, 395, 0, 0, 373, 3, -1, 0, 0, ["func"] = nil, 25, 0, 0},
  71.  [16] = {" Ice ", colors.cyan, colors.lightBlue, "o", 0, 0, 0, 100, 0, 253, 0, 0, -1, 0, 273, 3, 0, ["func"] = nil, 50, 0, 0},
  72.  [17] = {"Plasm", colors.magenta, colors.yellow, "^", 2, 8, -100, 24, 0, 7595, 20, 5373, 7, 0, -1, 0, 1, ["func"] = fire, 40, 0, 0},
  73.  [18] = {"Smoke", colors.gray, colors.black, "o", 2, 8, -100, 24, 0, 325, 10, 0, -1, 0, 423, 7, 1, ["func"] = death, 40, 0, 0},
  74.  [19] = {"CFire", colors.blue, colors.cyan, "^", 2, 8, -100, 24, 0, 10, 20, 0, -1, 0, 173, 0, 1, ["func"] = death, 40, 0, 0},
  75.  [20] = {"Neutr", colors.lightBlue, colors.cyan, ".", 0, 0, 0, 0, 0, 293, 15, -8, -1, 0, -1, 0, 1, ["func"] = neutrons, 25, 0, 0},
  76.  [21] = {" Lava", colors.red, colors.orange, "~", 2, 8, 95, 30, 0, 2095, 0, 22, 1095, -1, -1, 0, 0, ["func"] = ignite, 50, 0, 0},
  77.  [22] = {"Stone", colors.gray, colors.lightGray, ":", 1, 20, 96, 65, 0, 295, 0, 0, -1, 0, 1100, 21, 0, ["func"] = nil, 70, 0, 0},
  78.  [23] = {"Metal", colors.blue, colors.gray, "X", 0, 0, 0, 100, 0, 293, 0, 0, -1, 0, 1150, 21, 0, ["func"] = nil, 90, 0, 0},
  79.  [24] = {" CO2 ", colors.lightGray, colors.gray, "O", 1, 20, 15, 10, 0, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = co2, 30, 0, 0},
  80.  [25] = {"  H2 ", colors.lightBlue, colors.cyan, "O", 2, 0, -1, 5, 0, 295, 0, 0, -1, 0, -1, 0, 1, ["func"] = h2, 30, 0, 0},
  81.  [26] = {"Clone", colors.cyan, colors.yellow, "C", 0, 0, 0, 100, 0, 293, 0, 0, -1, 0, -1, 0, 0, ["func"] = clone, 70, 0, 0},
  82. }
  83.  
  84. if debug == true then
  85.  log("CCSand opened in debug mode!")
  86. end
  87.  
  88. local splashes = {
  89.  "CC stands for CosmoConsole and ComputerCraft",
  90.  "You need Advanced Computers for this",
  91.  "Try to save & load!",
  92.  "This game doesn't have moving solids"
  93. }
  94.  
  95.  
  96. statusbar = splashes[math.random(1, #splashes)]
  97.  
  98.  
  99. if debug then log("Searching for Redirect API created by GopherAtl") end
  100. if redirect then
  101.  buffer=redirect.createRedirectBuffer()
  102.  if debug then log("Redirect buffer enabled") end
  103. else
  104.  local ok=pcall(os.loadAPI,"redirect")
  105.  if not ok then ok=pcall(os.loadAPI,shell.dir().."/redirect") end
  106.  if (ok) and (redirect) then
  107.   buffer=redirect.createRedirectBuffer()
  108.   if debug then log("Redirect buffer loaded and enabled") end
  109.   API = true
  110.  else
  111.   if debug then log("Redirect buffer not found") end
  112.  end
  113.  term.restore()
  114. end
  115. term.clear()
  116.  
  117. creationTemp = nil
  118. creationCotype = nil
  119. creationLife = nil
  120.  
  121. MAX_TEMP = 9999
  122. MIN_TEMP = 0
  123.  
  124.  
  125.  
  126. --print("Press Q to Quit!")
  127.  
  128.  
  129. function trim(s)
  130.   return (s:gsub("^%s*(.-)%s*$", "%1"))
  131. end
  132. function log2(input)
  133.  return (math.log(input)/math.log(2))
  134. end
  135. function round(num, idp)
  136.   local mult = 10^(idp or 0)
  137.   return math.floor(num * mult + 0.5) / mult
  138. end
  139. function openMenu()
  140.  term.setBackgroundColor(colors.brown)
  141.  term.setTextColor(colors.yellow)
  142.  term.setCursorPos(47, 19)
  143.  write(version)
  144.  term.setBackgroundColor(colors.gray)
  145.  term.setTextColor(colors.white)
  146.  menu = true
  147.  dirty = true
  148. end
  149. function pause()
  150.  --write("Pause toggled")
  151.  paused = not paused
  152. end
  153.  
  154.  
  155. function quit()
  156.  --term.clear()
  157.  --term.setCursorPos(5, 5)
  158.  --print("Thank you for playing!")
  159.  --print("ccSand by CosmoConsole")
  160.  --os.sleep(3)
  161.  term.clear()
  162.  term.setCursorPos(1, 1)
  163.  logs.close()
  164.  on = false
  165. end
  166.  
  167. --log("CCSand opened.")
  168. grid = {1, 40, 1, 17}
  169. --40x17 grid
  170.  
  171. lx = 0
  172. ly = 0
  173.  
  174.  
  175.  
  176. -- [particle_id] = {id, x, y, type, life, cotype, temp}
  177. -- particle 0 to avoid 'nil'
  178. particles = {
  179. }  --[0] = {0, 0, 0, 0, 0, 0, 0}
  180.  
  181.  
  182. -- particle ID begins at 1. 0 is air.
  183. part_id = 1
  184.  
  185.  
  186. function getParticleCalled(i)
  187.  for k, v in pairs(particles) do
  188.   if v[1] == i then
  189.    return k
  190.   end
  191.  end
  192.  return 0
  193. end
  194. function getParticleAt(x,y)
  195.  for k, v in pairs(particles) do
  196.   if v[2] == x then
  197.    if v[3] == y then
  198.     return k
  199.    end
  200.   end
  201.  end
  202.  return 0
  203. end
  204. function render2(pt,rx,ry)
  205.  if rx < grid[1] then return end
  206.  if rx > grid[2] then return end
  207.  if ry < grid[3] then return end
  208.  if ry > grid[4] then return end
  209.  term.setCursorPos(rx,ry)
  210.  term.setBackgroundColor(elements[pt][2])
  211.  term.setTextColor(elements[pt][3])
  212.  print(elements[pt][4])
  213.  --buffer[rx[ry]] = {elements[pt][4], elements[pt][2], elements[pt][3]}
  214. end
  215. function render(rx,ry,part)
  216.  if part == nil then
  217.   p = getParticleAt(rx,ry)
  218.  else
  219.   p = part
  220.   rx = part[2]
  221.   ry = part[3]
  222.  end
  223.  if rx < grid[1] then return end
  224.  if rx > grid[2] then return end
  225.  if ry < grid[3] then return end
  226.  if ry > grid[4] then return end
  227.  px = particles[p]
  228.  term.setCursorPos(rx,ry)
  229.  if px == nil then
  230.   px = {0,0,0,0,0,0,0}
  231.  end
  232.  term.setBackgroundColor(elements[px[4]][2])
  233.  term.setTextColor(elements[px[4]][3])
  234.  print(elements[px[4]][4])
  235. end
  236. function createParticle(x,y,type,life,cotype,temp)
  237.  if getParticleAt(x,y) ~= 0 then
  238.   return 0
  239.  end
  240.  if x == nil then
  241.   return 0
  242.  end
  243.  if y == nil then
  244.   return 0
  245.  end
  246.  if type == nil then
  247.   return 0
  248.  end
  249.  if y > grid[4] then
  250.   return 0
  251.  end
  252.  if y < grid[3] then
  253.   return 0
  254.  end
  255.  if x > grid[2] then
  256.   return 0
  257.  end
  258.  if x < grid[1] then
  259.   return 0
  260.  end
  261.  if #particles > particleLimit then
  262.   return 0
  263.  end
  264.  l = elements[type][11]
  265.  if life ~= nil then l = life end
  266.  if l < 0 then l = math.random(0 - l) end
  267.  c = elements[type][12]
  268.  if cotype ~= nil then c = cotype end
  269.  if c < 0 then c = math.random(0 - c) end
  270.  t = elements[type][10]
  271.  if temp ~= nil then t = temp end
  272.  i = part_id
  273.  part_id = part_id + 1
  274.  if debug == true then
  275.   log("Creating particle of " .. type .. " at " .. x .. "," .. y)
  276.  end
  277.  dirty = true
  278.  render(x, y, table.insert(particles, {i, x, y, type, l, c, t}))
  279.  return i
  280. end
  281. function killParticle(i)
  282.  if particles[i] then
  283.   px = particles[i][2]
  284.   py = particles[i][3]
  285.   if debug == true then
  286.    log("Killing particle #" .. particles[i][1] .. " at " .. px .. "," .. py)
  287.   end
  288.   if i == ipart then ipart = nil end
  289.   table.remove(particles, i)
  290.   dirty = true
  291.   --render(px,py)
  292.  end
  293.  return true
  294. end
  295. function drawElement(i,x,y)
  296.  if elements[i] == nil then return end
  297.  tx = elements[i][3]
  298.  bx = elements[i][2]
  299.  if bx == tx then
  300.   tx = colors.white
  301.  end
  302.  if bx == 256 then
  303.   tx = colors.black
  304.  end
  305.  if bx < 128 then
  306.   tx = colors.black
  307.  end
  308.  --log("drawElement: tx is " .. tx .. " and bx is " .. bx)
  309.  term.setBackgroundColor(bx)
  310.  term.setTextColor(tx)
  311.  x1, y1 = term.getCursorPos()
  312.  term.setCursorPos(x,y)
  313.  write(elements[i][1])
  314.  term.setBackgroundColor(colors.gray)
  315.  term.setTextColor(colors.white)
  316.  term.setCursorPos(x1, y1)
  317. end
  318. function selectElement(i)
  319.  if i > (#elements) then return end
  320.  sel = i
  321.  drawElement(i,46,17)
  322. end
  323. function kissa()
  324.  for i = 1,1000 do
  325.   drawElement(math.random(0,#elements),math.random(1,50),math.random(1,17))
  326.  end
  327. end
  328.  
  329. function info(x,y)
  330.  if y > grid[4] then return end
  331.  if y < grid[3] then return end
  332.  if x > grid[2] then return end
  333.  if x < grid[1] then return end
  334.  local pxy = getParticleAt(x,y)
  335.  if pxy ~= 0 then
  336.   ipart = particles[pxy]
  337.  else
  338.   ipart = nil
  339.  end
  340.  dirty = true
  341. end
  342. function closeMenu()
  343.  dirty = true
  344.  menu = false
  345.  term.setBackgroundColor(colors.brown)
  346.  term.setTextColor(colors.yellow)
  347.  term.setCursorPos(1, 19)
  348.  write(string.rep(" ", 51))
  349.  term.setCursorPos(1, 19)
  350.  write("ccSand by CosmoConsole")
  351.  term.setCursorPos(47, 19)
  352.  write(version)
  353.  term.setBackgroundColor(colors.gray)
  354.  term.setTextColor(colors.white)
  355. end
  356. function drawPage(i)
  357.  ep = (i * 16) + 1
  358.  term.setBackgroundColor(colors.gray)
  359.  term.setTextColor(colors.white)
  360.  for iterator_a=1,17 do
  361.   term.setCursorPos(41,iterator_a)
  362.   write("           ")
  363.  end
  364.  for iterator_a=1,8 do
  365.   drawElement(ep,41,iterator_a+3)
  366.   ep = ep + 1
  367.   drawElement(ep,46,iterator_a+3)
  368.   ep = ep + 1
  369.  end
  370.  term.setBackgroundColor(colors.lightGray)
  371.  term.setTextColor(colors.white)
  372.  term.setCursorPos(42, 2)
  373.  write("<")
  374.  term.setCursorPos(49, 2)
  375.  write(">")
  376.  term.setBackgroundColor(colors.gray)
  377.  term.setTextColor(colors.white)
  378.  term.setCursorPos(45, 2)
  379.  write("  ")
  380.  term.setCursorPos(45, 2)
  381.  write(page + 1)
  382. end
  383. function menuToggle()
  384.  if menu == true then
  385.   closeMenu()
  386.  else
  387.   openMenu()
  388.  end
  389. end
  390. function particleMove(p1,p2,px,py)
  391.  pm1 = particles[p1]
  392.  pm2 = particles[p2]
  393.  if p2 == 0 then
  394.   inGrid = false
  395.   if px >= grid[1] then
  396.    if px <= grid[2] then
  397.     if py >= grid[3] then
  398.      if py <= grid[4] then
  399.       inGrid = true
  400.      end
  401.     end
  402.    end
  403.   end
  404.   if inGrid == true then
  405.    if particles[p1] == nil then return false end
  406.    opx = particles[p1][2]
  407.    opy = particles[p1][3]
  408.    particles[p1][2] = px
  409.    particles[p1][3] = py
  410.    render(px,py)
  411.    render(opx,opy)
  412.    dirty = true
  413.    if debug == true then
  414.     log("Moving particle #" .. particles[p1][1] .. " from " .. opx .. "," .. opy .. " to " .. px .. "," .. py)
  415.    end
  416.    return true
  417.   else
  418.    killParticle(p1)
  419.    return true
  420.   end
  421.  end
  422.  return false
  423. end
  424. function particleSwitch(p1,p2,px,py)
  425.  pm1 = particles[p1]
  426.  pm2 = particles[p2]
  427.  if p2 == 0 then
  428.   inGrid = false
  429.   if px >= grid[1] then
  430.    if px <= grid[2] then
  431.     if py >= grid[3] then
  432.      if py <= grid[4] then
  433.       inGrid = true
  434.      end
  435.     end
  436.    end
  437.   end
  438.   if inGrid == true then
  439.    opx = particles[p1][2]
  440.    opy = particles[p1][3]
  441.    particles[p1][2] = px
  442.    particles[p1][3] = py
  443.    render(px,py)
  444.    render(opx,opy)
  445.    dirty = true
  446.    if debug == true then
  447.     log("Moving particle #" .. particles[p1][1] .. " from " .. opx .. "," .. opy .. " to " .. px .. "," .. py)
  448.    end
  449.   else
  450.    killParticle(p1)
  451.   end
  452.  else
  453.   if particles[p2][4] == 4 then
  454.    if debug == true then
  455.     log("VOID: *slurp*")
  456.    end
  457.    killParticle(p1)
  458.    return
  459.   end
  460.   --particles[p1][2] = pm2[2]
  461.   --particles[p2][2] = pm1[2]
  462.   --particles[p1][3] = pm2[3]
  463.   --particles[p2][3] = pm1[3]
  464.    opx = particles[p2][2]
  465.    opy = particles[p2][3]
  466.    particles[p2][2] = particles[p1][2]
  467.    particles[p2][3] = particles[p1][3]
  468.    particles[p1][2] = opx
  469.    particles[p1][3] = opy
  470.    dirty = true
  471.   if debug == true then
  472.    log("Switching particles between " .. pm1[2] .. "," .. pm1[3] .. " and " .. pm2[2] .. "," .. pm2[3])
  473.   end
  474.  end
  475. end
  476. function notYetImplemented()
  477.  term.setBackgroundColor(colors.brown)
  478.  term.setTextColor(colors.yellow)
  479.  term.setCursorPos(1, 19)
  480.  write(string.rep(" ", 51))
  481.  term.setCursorPos(1, 19)
  482.  write("Not yet implemented")
  483.  term.setCursorPos(47, 19)
  484.  write(version)
  485.  term.setBackgroundColor(colors.gray)
  486.  term.setTextColor(colors.white)
  487. end
  488. function rect(xa,ya,xb,yb)
  489.  if not (xa and xb and ya and yb) then
  490.   return
  491.  end
  492.  local dp = 0
  493.  for xi=xa,xb do
  494.   for yi=ya,yb do
  495.    if elements[sel][20] == 0 then
  496.     createParticle(p2,p3,sel,creationLife,creationCotype,creationTemp)
  497.    elseif elements[sel][20] == 1 then
  498.     if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.min(particles[getParticleAt(p2,p3)][7] + 5, MAX_TEMP) end
  499.    elseif elements[sel][20] == 2 then
  500.     if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.max(particles[getParticleAt(p2,p3)][7] - 5, MIN_TEMP) end
  501.    end
  502.    dp = dp + 1
  503.   end
  504.  end
  505.  return xa .. "-" .. xb .. "," .. ya .. "-" .. yb .. ";" .. dp .. " vs " .. (((xb - xa) + 1) * ((yb - ya) + 1))
  506. end
  507. function arect(xa,ya,xb,yb)
  508.  if not (xa and xb and ya and yb) then
  509.   return
  510.  end
  511.  local dp = 0
  512.  for xi=xa,xb do
  513.   for yi=ya,yb do
  514.    createParticle(xi, yi, 0)
  515.    dp = dp + 1
  516.   end
  517.  end
  518.  return xa .. "-" .. xb .. "," .. ya .. "-" .. yb .. ";" .. dp .. " vs " .. (((xb - xa) + 1) * ((yb - ya) + 1))
  519. end
  520. function setStatus(sx)
  521.  textReset = os.startTimer(5)
  522.  statusbar = string.sub(sx, 1, 51)
  523.  dirty = true
  524. end
  525. local fileEngine = nil
  526. local fileName = nil
  527. local serid = nil
  528. function saveAt()
  529.  fileEngine = fs.open(fileName, "w")
  530.  fileEngine.write(serid)
  531.  fileEngine.close()
  532.  fileEngine = nil
  533. end
  534. function loadAt()
  535.  fileEngine = fs.open(fileName, "r")
  536.  particles = textutils.unserialize(fileEngine.readAll())
  537.  fileEngine.close()
  538.  fileEngine = nil
  539. end
  540. function save()
  541.  term.setCursorPos(1, 18)
  542.  term.setBackgroundColor(colors.brown)
  543.  term.setTextColor(colors.yellow)
  544.  write(string.rep(" ", 51))
  545.  term.setCursorPos(1, 18)
  546.  sleep(0.5)
  547.  write(">")
  548.  cons = read()
  549.  closeMenu()
  550.  if trim(cons) == "" then
  551.   redraw()
  552.   timeout = os.startTimer(0)
  553.   return
  554.  end
  555.  fileName = cons
  556.  ok = true
  557.  serid = textutils.serialize(particles)
  558.  --ok, err = pcall(setFileEngineWrite)
  559.  ok, err = pcall(saveAt)
  560.  if ok then
  561.   setStatus("Successfully saved")
  562.  else
  563.   if err then setStatus(tostring(err)) end
  564.  end
  565.  timeout = os.startTimer(0)
  566. end
  567. function load()
  568.  term.setCursorPos(1, 18)
  569.  term.setBackgroundColor(colors.brown)
  570.  term.setTextColor(colors.yellow)
  571.  write(string.rep(" ", 51))
  572.  term.setCursorPos(1, 18)
  573.  sleep(0.5)
  574.  write(">")
  575.  cons = read()
  576.  closeMenu()
  577.  dirty = true
  578.  if trim(cons) == "" then
  579.   redraw()
  580.   timeout = os.startTimer(0)
  581.   return
  582.  end
  583.  fileName = cons
  584.  ok = true
  585.  --ok, err = pcall(setFileEngineRead)
  586.  ok, err = pcall(loadAt)
  587.  if ok then
  588.   setStatus("Successfully loaded")
  589.  else
  590.   if err then setStatus(tostring(err)) end
  591.  end
  592.  timeout = os.startTimer(0)
  593. end
  594. function clear()
  595.  particles = {}
  596.  term.setBackgroundColor(colors.black)
  597.  term.setTextColor(colors.white)
  598.  for i = 1,16 do
  599.   term.setCursorPos(1,i)
  600.   write(string.rep(" ", 40))
  601.  end
  602.  term.setBackgroundColor(colors.gray)
  603.  term.setTextColor(colors.white)
  604.  closeMenu()
  605. end
  606. function mquit()
  607.  if menu == true then
  608.   quit()
  609.  end
  610. end
  611. function mload()
  612.  if menu == true then
  613.   load()
  614.  end
  615. end
  616. function msave()
  617.  if menu == true then
  618.   save()
  619.  end
  620. end
  621. function mclear()
  622.  if menu == true then
  623.   clear()
  624.  end
  625. end
  626. function redraw()
  627.  if debug then log("Can I redraw now?") end
  628.  if buffer.isBuffer then term.redirect(buffer) end
  629.  term.setBackgroundColor(colors.black)
  630.  term.setTextColor(colors.white)
  631.  if debug then log("Redraw: Clearing buffer") end
  632.  for i = 1,17 do
  633.   term.setCursorPos(1,i)
  634.   write(string.rep(" ", 40))
  635.  end
  636.  if debug then log("Redraw: Buffer clear. Starting particle render.") end
  637.  for k, v in ipairs(particles) do
  638.   render2(v[4], v[2], v[3])
  639.  end
  640.  term.setBackgroundColor(colors.brown)
  641.  term.setTextColor(colors.yellow)
  642.  term.setCursorPos(1, 19)
  643.  write(string.rep(" ", 51))
  644.  term.setCursorPos(1, 19)
  645.  write(statusbar)
  646.  term.setBackgroundColor(colors.gray)
  647.  term.setTextColor(colors.white)
  648.  term.setCursorPos(1, 18)
  649.  write(string.rep(" ", 51))
  650.  term.setCursorPos(11, 18)
  651.  write("[MENU]")
  652.  drawPage(page)
  653.  drawElement(sel,46,17)
  654.  if debug then log("Redraw: Rendered particles.") end
  655.  if menu == true then
  656.   term.setBackgroundColor(colors.brown)
  657.   term.setTextColor(colors.yellow)
  658.   term.setCursorPos(1, 19)
  659.   write(string.rep(" ", 51))
  660.   term.setCursorPos(1, 19)
  661.   write("[EN]Quit  [L]oad  [S]ave  [C]lear")
  662.   term.setBackgroundColor(colors.gray)
  663.   term.setTextColor(colors.white)
  664.  end
  665.  if ipart == nil then
  666.   drawElement(0,41,17)
  667.   term.setCursorPos(41,16)
  668.   print("                 ")
  669.  else
  670.   drawElement(ipart[4],41,17)
  671.   term.setCursorPos(41,16)
  672.   print("                 ")
  673.   term.setCursorPos(41,16)
  674.   print(ipart[5])
  675.   term.setCursorPos(46,16)
  676.   print(ipart[6])
  677.   term.setCursorPos(41,18)
  678.   print("          ")
  679.   term.setCursorPos(41,18)
  680.   print((ipart[7] - 273.15) .. " C")
  681.  end
  682.  term.setBackgroundColor(colors.gray)
  683.  term.setTextColor(colors.white)
  684.  if buffer.isBuffer then
  685.   if debug then log("Buffering.") end
  686.   term.restore()
  687.   buffer.blit()
  688.  end
  689.  dirty = false
  690. end
  691. function setPage(i)
  692.  if i == -1 then
  693.   i = 15
  694.  end
  695.  page = i % 16f
  696.  drawPage(i % 16)
  697. end
  698. function nextPage()
  699.  setPage(page + 1)
  700. end
  701. function previousPage()
  702.  setPage(page - 1)
  703. end
  704.  
  705. timeout = os.startTimer(0.1)
  706.  
  707. function explode(x, y)
  708.  local part
  709.  if getParticleAt(x-1,y) ~= 0 then
  710.   part = getParticleAt(x-1,y)
  711.   particles[part][7] = particles[part][7] + 40
  712.   particleMove(part,0,x-2,y)
  713.   particleMove(part,0,x-1,y-1)
  714.   particleMove(part,0,x-1,y+1)
  715.  end
  716.  if getParticleAt(x+1,y) ~= 0 then
  717.   part = getParticleAt(x+1,y)
  718.   particles[part][7] = particles[part][7] + 40
  719.   particleMove(part,0,x+2,y)
  720.   particleMove(part,0,x+1,y-1)
  721.   particleMove(part,0,x+1,y+1)
  722.  end
  723.  if getParticleAt(x,y-1) ~= 0 then
  724.   part = getParticleAt(x,y-1)
  725.   particles[part][7] = particles[part][7] + 40
  726.   particleMove(part,0,x,y-2)
  727.   particleMove(part,0,x+1,y-1)
  728.   particleMove(part,0,x-1,y-1)
  729.  end
  730.  if getParticleAt(x,y+1) ~= 0 then
  731.   part = getParticleAt(x,y+1)
  732.   particles[part][7] = particles[part][7] + 40
  733.   particleMove(part,0,x,y+2)
  734.   particleMove(part,0,x+1,y+1)
  735.   particleMove(part,0,x-1,y+1)
  736.  end
  737. end
  738.  
  739. function clone(p, k, x, y)
  740.  if getParticleAt(x-1,y) ~= 0 then
  741.   if p[6] == 0 then
  742.    if particles[getParticleAt(x-1,y)][4] ~= 26 then
  743.     particles[k][6] = particles[getParticleAt(x-1,y)][4]
  744.    end
  745.   end
  746.  end
  747.  if p[6] ~= 0 then
  748.   if math.random(1,2) == 1 then createParticle(x-1, y, p[6]) end
  749.   if math.random(1,2) == 1 then createParticle(x+1, y, p[6]) end
  750.   if math.random(1,2) == 1 then createParticle(x-1, y+1, p[6]) end
  751.   if math.random(1,2) == 1 then createParticle(x+1, y+1, p[6]) end
  752.   if math.random(1,2) == 1 then createParticle(x-1, y-1, p[6]) end
  753.   if math.random(1,2) == 1 then createParticle(x+1, y-1, p[6]) end
  754.   if math.random(1,2) == 1 then createParticle(x, y-1, p[6]) end
  755.   if math.random(1,2) == 1 then createParticle(x, y+1, p[6]) end
  756.  end
  757. end
  758. function co2(p, k, x, y)
  759.  if getParticleAt(x-1,y) ~= 0 then
  760.   if particles[getParticleAt(x-1,y)][4] == 7 then
  761.    killParticle(getParticleAt(x-1,y))
  762.   end
  763.  end
  764.  if getParticleAt(x+1,y) ~= 0 then
  765.   if particles[getParticleAt(x+1,y)][4] == 7 then
  766.    killParticle(getParticleAt(x+1,y))
  767.   end
  768.  end
  769.  if getParticleAt(x,y-1) ~= 0 then
  770.   if particles[getParticleAt(x,y-1)][4] == 7 then
  771.    killParticle(getParticleAt(x,y-1))
  772.   end
  773.  end
  774.  if getParticleAt(x,y+1) ~= 0 then
  775.   if particles[getParticleAt(x,y+1)][4] == 7 then
  776.    killParticle(getParticleAt(x,y+1))
  777.   end
  778.  end
  779.  gas_movement(p, k, x, y)
  780. end
  781.  
  782. function gas_movement(p, k, x, y)
  783.  local m = math.random(1, 5)
  784.  if m == 1 then particleMove(k, getParticleAt(x-1,y), x-1, y) end
  785.  if m == 2 then particleMove(k, getParticleAt(x+1,y), x+1, y) end
  786.  if m == 3 then particleMove(k, getParticleAt(x,y-1), x, y-1) end
  787.  if m == 4 then particleMove(k, getParticleAt(x,y+1), x, y+1) end
  788. end
  789. function ignite(p, k, x, y)
  790.  if getParticleAt(x-1,y) ~= 0 then
  791.   if elements[particles[getParticleAt(x-1,y)][4]][9] ~= 0 then
  792.    if elements[particles[getParticleAt(x-1,y)][4]][9] >= math.random(100) then
  793.     killParticle(getParticleAt(x-1,y))
  794.     createParticle(x-1,y,7)
  795.     if elements[particles[getParticleAt(x-1,y)][4]][19] ~= 0 then
  796.      explode(x-1,y)
  797.     end
  798.    end
  799.   end
  800.  end
  801.  if getParticleAt(x+1,y) ~= 0 then
  802.   if elements[particles[getParticleAt(x+1,y)][4]][9] ~= 0 then
  803.    if elements[particles[getParticleAt(x+1,y)][4]][9] >= math.random(100) then
  804.     killParticle(getParticleAt(x+1,y))
  805.     createParticle(x+1,y,7)
  806.     if elements[particles[getParticleAt(x+1,y)][4]][19] ~= 0 then
  807.      explode(x+1,y)
  808.     end
  809.    end
  810.   end
  811.  end
  812.  if getParticleAt(x,y-1) ~= 0 then
  813.   if elements[particles[getParticleAt(x,y-1)][4]][9] ~= 0 then
  814.    if elements[particles[getParticleAt(x,y-1)][4]][9] >= math.random(100) then
  815.     killParticle(getParticleAt(x,y-1))
  816.     createParticle(x,y-1,7)
  817.     if elements[particles[getParticleAt(x,y-1)][4]][19] ~= 0 then
  818.      explode(x,y-1)
  819.     end
  820.    end
  821.   end
  822.  end
  823.  if getParticleAt(x,y+1) ~= 0 then
  824.   if elements[particles[getParticleAt(x,y+1)][4]][9] ~= 0 then
  825.    if elements[particles[getParticleAt(x,y+1)][4]][9] >= math.random(100) then
  826.     killParticle(getParticleAt(x,y+1))
  827.     createParticle(x,y+1,7)
  828.     if elements[particles[getParticleAt(x,y+1)][4]][19] ~= 0 then
  829.      explode(x,y+1)
  830.     end
  831.    end
  832.   end
  833.  end
  834. end
  835. function fire(p, k, x, y)
  836.  if getParticleAt(x-1,y) ~= 0 then
  837.   if elements[particles[getParticleAt(x-1,y)][4]][9] ~= 0 then
  838.    if elements[particles[getParticleAt(x-1,y)][4]][9] >= math.random(100) then
  839.     killParticle(getParticleAt(x-1,y))
  840.     createParticle(x-1,y,7)
  841.     if elements[particles[getParticleAt(x-1,y)][4]][19] ~= 0 then
  842.      explode(x-1,y)
  843.     end
  844.    end
  845.   end
  846.  end
  847.  if getParticleAt(x+1,y) ~= 0 then
  848.   if elements[particles[getParticleAt(x+1,y)][4]][9] ~= 0 then
  849.    if elements[particles[getParticleAt(x+1,y)][4]][9] >= math.random(100) then
  850.     killParticle(getParticleAt(x+1,y))
  851.     createParticle(x+1,y,7)
  852.     if elements[particles[getParticleAt(x+1,y)][4]][19] ~= 0 then
  853.      explode(x+1,y)
  854.     end
  855.    end
  856.   end
  857.  end
  858.  if getParticleAt(x,y-1) ~= 0 then
  859.   if elements[particles[getParticleAt(x,y-1)][4]][9] ~= 0 then
  860.    if elements[particles[getParticleAt(x,y-1)][4]][9] >= math.random(100) then
  861.     killParticle(getParticleAt(x,y-1))
  862.     createParticle(x,y-1,7)
  863.     if elements[particles[getParticleAt(x,y-1)][4]][19] ~= 0 then
  864.      explode(x,y-1)
  865.     end
  866.    end
  867.   end
  868.  end
  869.  if getParticleAt(x,y+1) ~= 0 then
  870.   if elements[particles[getParticleAt(x,y+1)][4]][9] ~= 0 then
  871.    if elements[particles[getParticleAt(x,y+1)][4]][9] >= math.random(100) then
  872.     killParticle(getParticleAt(x,y+1))
  873.     createParticle(x,y+1,7)
  874.     if elements[particles[getParticleAt(x,y+1)][4]][19] ~= 0 then
  875.      explode(x,y+1)
  876.     end
  877.    end
  878.   end
  879.  end
  880.  death(p, k, x, y)
  881. end
  882. function seri()
  883.  log(textutils.serialize(particles))
  884. end
  885. function h2(p, k, x, y)
  886.  local igni = false
  887.  if getParticleAt(x-1,y) ~= 0 then
  888.   if particles[getParticleAt(x-1,y)][4] == 7 then
  889.    igni = true
  890.   end
  891.  end
  892.  if getParticleAt(x+1,y) ~= 0 then
  893.   if particles[getParticleAt(x+1,y)][4] == 7 then
  894.    igni = true
  895.   end
  896.  end
  897.  if getParticleAt(x,y-1) ~= 0 then
  898.   if particles[getParticleAt(x,y-1)][4] == 7 then
  899.    igni = true
  900.   end
  901.  end
  902.  if getParticleAt(x,y+1) ~= 0 then
  903.   if particles[getParticleAt(x,y+1)][4] == 7 then
  904.    igni = true
  905.   end
  906.  end
  907.  if igni then
  908.   killParticle(k)
  909.   createParticle(x, y, 7, nil, 15, nil)
  910.  end
  911.  if particles[k] then gas_movement(p, k, x, y) end
  912. end
  913. function neutrons(p, k, x, y)
  914.  if (particles[k]) then
  915.   if (p[6] == 1) then
  916.    if particleMove(k, getParticleAt(x,y-1), x, y - 1) == false then
  917.     particles[k][6] = math.random(1,8)
  918.    end
  919.   elseif (p[6] == 2) then
  920.    if particleMove(k, getParticleAt(x,y+1), x, y + 1) == false then
  921.     particles[k][6] = math.random(1,8)
  922.    end
  923.   elseif (p[6] == 3) then
  924.    if particleMove(k, getParticleAt(x-1,y+1), x - 1, y + 1) == false then
  925.     particles[k][6] = math.random(1,8)
  926.    end
  927.   elseif (p[6] == 4) then
  928.    if particleMove(k, getParticleAt(x-1,y), x - 1, y) == false then
  929.     particles[k][6] = math.random(1,8)
  930.    end
  931.   elseif (p[6] == 5) then
  932.    if particleMove(k, getParticleAt(x-1,y), x - 1, y - 1) == false then
  933.     particles[k][6] = math.random(1,8)
  934.    end
  935.   elseif (p[6] == 6) then
  936.    if particleMove(k, getParticleAt(x+1,y - 1), x + 1, y - 1) == false then
  937.     particles[k][6] = math.random(1,8)
  938.    end
  939.   elseif (p[6] == 7) then
  940.    if particleMove(k, getParticleAt(x+1,y), x + 1, y) == false then
  941.     particles[k][6] = math.random(1,8)
  942.    end
  943.   elseif (p[6] == 8) then
  944.    if particleMove(k, getParticleAt(x+1,y+1), x + 1, y + 1) == false then
  945.     particles[k][6] = math.random(1,8)
  946.    end
  947.   end
  948.  end
  949.  if (particles[k]) then death(p, k, x, y) end
  950. end
  951. function death(p, k, x, y)
  952.  particles[k][5] = p[5] - 1
  953.  if particles[k] then
  954.   if particles[k][5] == 0 then
  955.    if particles[k][4] == 7 then
  956.     if particles[k][6] == 15 then
  957.      if particles[k] then killParticle(k) end
  958.      createParticle(x, y, 15)
  959.     else
  960.      if particles[k] then killParticle(k) end
  961.      createParticle(x, y, 18)
  962.     end
  963.    else
  964.     killParticle(k)
  965.    end
  966.   end
  967.  end
  968. end
  969.  
  970. redraw()
  971.  
  972. function temp_conduct(k)
  973.  local sides = 0
  974.  local top = false
  975.  local bottom = false
  976.  local left = false
  977.  local right = false
  978.  local ot = particles[k][7]
  979.  local x = particles[k][2]
  980.  local y = particles[k][3]
  981.  local cond = {0, 0, 0, 0} --udlr
  982.  if getParticleAt(x,y-1) ~= 0 then
  983.   up = true
  984.   sides = sides + 1
  985.   cond[1] = math.min(elements[particles[getParticleAt(x,y-1)][4]][18], elements[particles[getParticleAt(x,y)][4]][18])
  986.  end
  987.  if getParticleAt(x,y+1) ~= 0 then
  988.   down = true
  989.   sides = sides + 1
  990.   cond[2] = math.min(elements[particles[getParticleAt(x,y+1)][4]][18], elements[particles[getParticleAt(x,y)][4]][18])
  991.  end
  992.  if getParticleAt(x-1,y) ~= 0 then
  993.   left = true
  994.   sides = sides + 1
  995.   cond[3] = math.min(elements[particles[getParticleAt(x-1,y)][4]][18], elements[particles[getParticleAt(x,y)][4]][18])
  996.  end
  997.  if getParticleAt(x+1,y) ~= 0 then
  998.   right = true
  999.   sides = sides + 1
  1000.   cond[4] = math.min(elements[particles[getParticleAt(x+1,y)][4]][18], elements[particles[getParticleAt(x,y)][4]][18])
  1001.  end
  1002.  if sides > 0 then
  1003.   for iter = 1,4 do
  1004.    cond[iter] = cond[iter] / (sides + 1)
  1005.    cond[iter] = cond[iter] * 1.5
  1006.   end
  1007.  end
  1008.  if cond[1] > 0 then
  1009.   local rt = particles[getParticleAt(x,y-1)][7]
  1010.   local tt = (ot + rt) / 2
  1011.   local oto = tt - ot
  1012.   local rto = tt - rt
  1013.   oto = oto / cond[1]
  1014.   rto = rto / cond[1]
  1015.   particles[getParticleAt(x,y)][7] = round(ot + oto, 2)
  1016.   particles[getParticleAt(x,y-1)][7] = round(rt + rto, 2)
  1017.  end
  1018.  if cond[2] > 0 then
  1019.   local rt = particles[getParticleAt(x,y+1)][7]
  1020.   local tt = (ot + rt) / 2
  1021.   local oto = tt - ot
  1022.   local rto = tt - rt
  1023.   oto = oto / cond[2]
  1024.   rto = rto / cond[2]
  1025.   particles[getParticleAt(x,y)][7] = round(ot + oto, 2)
  1026.   particles[getParticleAt(x,y+1)][7] = round(rt + rto, 2)
  1027.  end
  1028.  if cond[3] > 0 then
  1029.   local rt = particles[getParticleAt(x-1,y)][7]
  1030.   local tt = (ot + rt) / 2
  1031.   local oto = tt - ot
  1032.   local rto = tt - rt
  1033.   oto = oto / cond[3]
  1034.   rto = rto / cond[3]
  1035.   particles[getParticleAt(x,y)][7] = round(ot + oto, 2)
  1036.   particles[getParticleAt(x-1,y)][7] = round(rt + rto, 2)
  1037.  end
  1038.  if cond[4] > 0 then
  1039.   local rt = particles[getParticleAt(x+1,y)][7]
  1040.   local tt = (ot + rt) / 2
  1041.   local oto = tt - ot
  1042.   local rto = tt - rt
  1043.   oto = oto / cond[4]
  1044.   rto = rto / cond[4]
  1045.   particles[getParticleAt(x,y)][7] = round(ot + oto, 2)
  1046.   particles[getParticleAt(x+1,y)][7] = round(rt + rto, 2)
  1047.  end
  1048. end
  1049.  
  1050. buttons = {
  1051.  [1] = {11, 16, 18, 18, " Menu ", menuToggle, true},
  1052.  [2] = {1, 6, 18, 18, "  ||  ", pause, true},
  1053.  [3] = {41, 45, 4, 4, "elem01", function () return selectElement((page * 16) + 1) end, true},
  1054.  [4] = {46, 50, 4, 4, "elem02", function () return selectElement((page * 16) + 2) end, true},
  1055.  [5] = {41, 45, 5, 5, "elem03", function () return selectElement((page * 16) + 3) end, true},
  1056.  [6] = {46, 50, 5, 5, "elem04", function () return selectElement((page * 16) + 4) end, true},
  1057.  [7] = {41, 45, 6, 6, "elem05", function () return selectElement((page * 16) + 5) end, true},
  1058.  [8] = {46, 50, 6, 6, "elem06", function () return selectElement((page * 16) + 6) end, true},
  1059.  [9] = {41, 45, 7, 7, "elem07", function () return selectElement((page * 16) + 7) end, true},
  1060.  [10] = {46, 50, 7, 7, "elem08", function () return selectElement((page * 16) + 8) end, true},
  1061.  [11] = {41, 45, 8, 8, "elem09", function () return selectElement((page * 16) + 9) end, true},
  1062.  [12] = {46, 50, 8, 8, "elem0a", function () return selectElement((page * 16) + 10) end, true},
  1063.  [13] = {41, 45, 9, 9, "elem0b", function () return selectElement((page * 16) + 11) end, true},
  1064.  [14] = {46, 50, 9, 9, "elem0c", function () return selectElement((page * 16) + 12) end, true},
  1065.  [15] = {41, 45, 10, 10, "elem0d", function () return selectElement((page * 16) + 13) end, true},
  1066.  [16] = {46, 50, 10, 10, "elem0e", function () return selectElement((page * 16) + 14) end, true},
  1067.  [17] = {41, 45, 11, 11, "elem0f", function () return selectElement((page * 16) + 15) end, true},
  1068.  [18] = {46, 50, 11, 11, "elem10", function () return selectElement((page * 16) + 16) end, true},
  1069.  [19] = {1, 8, 19, 19, "quit", mquit, true},
  1070.  [20] = {11, 16, 19, 19, "load", mload, true},
  1071.  [21] = {19, 24, 19, 19, "save", msave, true},
  1072.  [22] = {26, 32, 19, 19, "clear", mclear, true},
  1073.  [23] = {42, 42, 2, 2, "pprev", previousPage, true},
  1074.  [24] = {49, 49, 2, 2, "pnext", nextPage, true}
  1075. }
  1076.  
  1077. function simulate()
  1078.  xParticles = particles
  1079.  for k, v in ipairs(xParticles) do
  1080.   temp_conduct(k)
  1081.   e = elements[v[4]]
  1082.   continue = false
  1083.   if e[13] ~= -1 then
  1084.    if particles[k][7] <= e[13] then
  1085.     killParticle(k)
  1086.     if e[14] == -1 then
  1087.      createParticle(v[2], v[3], v[6], v[5], 0, v[7])
  1088.     else
  1089.      createParticle(v[2], v[3], e[14], v[5], v[6], v[7])
  1090.     end
  1091.     continue = true
  1092.    end
  1093.   end
  1094.   if e[15] ~= -1 then
  1095.    if particles[k][7] >= e[15] then
  1096.     killParticle(k)
  1097.     if e[16] == 21 then
  1098.      createParticle(v[2], v[3], e[16], v[5], v[4], v[7])
  1099.     else
  1100.      createParticle(v[2], v[3], e[16], v[5], v[6], v[7])
  1101.     end
  1102.     continue = true
  1103.    end
  1104.   end
  1105.   if continue == false then
  1106.   if e[5] ~= 0 then
  1107.    --Should move
  1108.    grav = e[7]
  1109.    spr = e[6]
  1110.    px = v[2]
  1111.    py = v[3]
  1112.    gf = math.floor(grav / 100)
  1113.    gp = grav % 100
  1114.    if gp >= math.random(100) then
  1115.     gf = gf + 1
  1116.    end
  1117.    gstep = -1
  1118.    sgf = 1
  1119.    if grav < 0 then
  1120.     gstep = 1
  1121.     sgf = -1
  1122.    end
  1123.    spread = false
  1124.    if spr >= math.random(100) then
  1125.     spread = true
  1126.    end
  1127.    if grav ~= 0 then
  1128.     --Can move down? If yes, then do it and ignore the rest.
  1129.     canGoDown = gf
  1130.     for i=gf,sgf,gstep do
  1131.      if getParticleAt(px,py+i) ~= 0 then
  1132.       if (elements[particles[getParticleAt(px,py+i)][4]][17] == 0) and (elements[particles[getParticleAt(px,py+i)][4]][8] >= e[8]) then
  1133.        canGoDown = (i + gstep)
  1134.       end
  1135.      end
  1136.     end
  1137.     if canGoDown ~= 0 then
  1138.      sp = 0
  1139.      if spread then
  1140.       sp = math.random(2)
  1141.       if sp == 2 then
  1142.        sp = -1
  1143.       end
  1144.      end
  1145.      if getParticleAt(px+sp,py+canGoDown) ~= 0 then
  1146.       if (elements[particles[getParticleAt(px+sp,py+canGoDown)][4]][17] == 0) then
  1147.        sp = 0
  1148.       end
  1149.      end
  1150.      --particleSwitch call: particle 1 table ID, particle 2 table ID, where particle 1 tries to move (X), where particle 1 tries to move (Y)
  1151.      if (sp ~= 0) and (canGoDown ~= 0) then
  1152.       particleSwitch(k, getParticleAt(px+sp,py+canGoDown), px+sp, py+canGoDown)
  1153.      end
  1154.     else
  1155.      --Okay, it cannot go down, how about diagonals? (1px left/right and 1px down).
  1156.      --First, can it go down-left diagonally?
  1157.      canGoDL = true
  1158.      if getParticleAt(px-1,py+sgf) ~= 0 then
  1159.       if (elements[particles[getParticleAt(px-1,py+sgf)][4]][17] == 0) and (elements[particles[getParticleAt(px-1,py+sgf)][4]][8] >= e[8]) then
  1160.        canGoDL = false
  1161.       end
  1162.      end
  1163.      canGoDR = true
  1164.      if getParticleAt(px+1,py+sgf) ~= 0 then
  1165.       if (elements[particles[getParticleAt(px+1,py+sgf)][4]][17] == 0) and (elements[particles[getParticleAt(px+1,py+sgf)][4]][8] >= e[8]) then
  1166.        canGoDR = false
  1167.       end
  1168.      end
  1169.      if (canGoDR) and (canGoDL) then
  1170.       dir = math.random(1,2)
  1171.       if dir == 1 then
  1172.        particleSwitch(k, getParticleAt(px+1,py+sgf), px+1, py+sgf)
  1173.       elseif dir == 2 then
  1174.        particleSwitch(k, getParticleAt(px-1,py+sgf), px-1, py+sgf)
  1175.       end
  1176.      elseif (canGoDR) or (canGoDL) then
  1177.       if canGoDR == true then particleSwitch(k, getParticleAt(px+1,py+sgf), px+1, py+sgf) end
  1178.       if canGoDL == true then particleSwitch(k, getParticleAt(px-1,py+sgf), px-1, py+sgf) end
  1179.      elseif (canGoDR == false) and (canGoDL == false) then
  1180.       --How about left/right (not down)? (Liquids only)
  1181.       if e[5] == 2 then
  1182.        canGoLeft = true
  1183.        canGoRight = true
  1184.        if getParticleAt(px-1,py) ~= 0 then
  1185.         if elements[particles[getParticleAt(px-1,py)][4]][17] == 0 then
  1186.          canGoLeft = false
  1187.         end
  1188.        end
  1189.        if getParticleAt(px+1,py) ~= 0 then
  1190.         if elements[particles[getParticleAt(px+1,py)][4]][17] == 0 then
  1191.          canGoRight = false
  1192.         end
  1193.        end
  1194.        if (canGoLeft) and (canGoRight) then
  1195.         dir = math.random(1,2)
  1196.         if dir == 1 then
  1197.          particleMove(k, getParticleAt(px-1,py), px-1, py)
  1198.         elseif dir == 2 then
  1199.          particleMove(k, getParticleAt(px+1,py), px+1, py)
  1200.         end
  1201.        else
  1202.         if canGoLeft then particleSwitch(k, getParticleAt(px-1,py), px-1, py) end
  1203.         if canGoRight then particleSwitch(k, getParticleAt(px+1,py), px+1, py) end
  1204.        end
  1205.       end
  1206.      end
  1207.     end
  1208.     end
  1209.    end
  1210.   end
  1211.   if e["func"] then
  1212.    --they get particle data, it's key, then X and Y
  1213.    if debug == true then
  1214.     log("Reached element function")
  1215.    end
  1216.    if particles[k] then
  1217.     e["func"](v, k, v[2], v[3])
  1218.    end
  1219.   end
  1220.   if particles[k] then
  1221.    if v[4] == 0 then
  1222.     killParticle(k)
  1223.    end
  1224.   end
  1225.  end
  1226. end
  1227. function setLife(i)
  1228.  local pc = getParticleAt(lx,ly)
  1229.  if pc == 0 then
  1230.   return
  1231.  end
  1232.  if lx == 0 then
  1233.   return
  1234.  end
  1235.  if ly == 0 then
  1236.   return
  1237.  end
  1238.  particles[pc][5] = i
  1239. end
  1240. function setCotype(i)
  1241.  local pc = getParticleAt(lx,ly)
  1242.  if pc == 0 then
  1243.   return
  1244.  end
  1245.  if lx == 0 then
  1246.   return
  1247.  end
  1248.  if ly == 0 then
  1249.   return
  1250.  end
  1251.  particles[pc][6] = i
  1252. end
  1253. function heat(i)
  1254.  local pc = getParticleAt(lx,ly)
  1255.  if pc == 0 then
  1256.   return
  1257.  end
  1258.  if lx == 0 then
  1259.   return
  1260.  end
  1261.  if ly == 0 then
  1262.   return
  1263.  end
  1264.  particles[pc][7] = math.min(particles[pc][7] + i, MAX_TEMP)
  1265. end
  1266. function cool(i)
  1267.  local pc = getParticleAt(lx,ly)
  1268.  if pc == 0 then
  1269.   return
  1270.  end
  1271.  if lx == 0 then
  1272.   return
  1273.  end
  1274.  if ly == 0 then
  1275.   return
  1276.  end
  1277.  particles[pc][7] = math.max(particles[pc][7] - i, MIN_TEMP)
  1278. end
  1279.  
  1280. term.clear()
  1281. term.setCursorPos(1,1)
  1282. info(1,1)
  1283.  
  1284. while on do
  1285.  evt, p1, p2, p3, p4, p5 = os.pullEvent()
  1286.  if evt == "key" then
  1287.   --print(p1 .. " pressed")
  1288.   if p1 == 57 then
  1289.    pause()
  1290.   elseif p1 == 33 then
  1291.    if paused then simulate() end
  1292.   elseif p1 == 14 then
  1293.    term.setCursorPos(1, 18)
  1294.    term.setBackgroundColor(colors.brown)
  1295.    term.setTextColor(colors.yellow)
  1296.    write(string.rep(" ", 51))
  1297.    term.setCursorPos(1, 18)
  1298.    write(">")
  1299.    cons = read()
  1300.    term.setCursorPos(1, 18)
  1301.    func, e = loadstring(cons, "lua")
  1302.    func2, e2 = loadstring("return " .. cons, "lua")
  1303.    nfp = 0
  1304.    if not func then
  1305.     if func2 then
  1306.      func = func2
  1307.      e = nil
  1308.      nfp = 1
  1309.     end
  1310.    else
  1311.     if func2 then
  1312.      func = func2
  1313.     end
  1314.    end
  1315.    setfenv(func,getfenv())
  1316.    result = {pcall(func)}
  1317.    if result[1] then
  1318.     nii = 1
  1319.     resulter = ">"
  1320.     while (result[nii + 1] ~= nil) or (nii <= nfp) do
  1321.      resulter = resulter .. tostring(result[nii + 1])
  1322.      nii = nii + 1
  1323.     end
  1324.     statusBar = string.sub(resulter, 1, 51)
  1325.     dirty = true
  1326.    else
  1327.     statusBar = string.sub(tostring(result[2]), 1, 51)
  1328.     dirty = true
  1329.    end
  1330.    term.setBackgroundColor(colors.gray)
  1331.    term.setTextColor(colors.white)
  1332.    term.setCursorPos(1, 18)
  1333.    write(string.rep(" ", 51))
  1334.    textReset = os.startTimer(5)
  1335.    timeout = os.startTimer(0)
  1336.   end
  1337.   if (p1 == keys.leftCtrl) or (p1 == keys.rightCtrl) then
  1338.    if menu == true then
  1339.     closeMenu()
  1340.    else
  1341.     openMenu()
  1342.    end
  1343.   end
  1344.   if menu == true then
  1345.    if p1 == 46 then
  1346.     clear()
  1347.    end
  1348.    if p1 == 28 then
  1349.     quit()
  1350.    end
  1351.    if p1 == 31 then
  1352.     save()
  1353.    end
  1354.    if p1 == 38 then
  1355.     load()
  1356.    end
  1357.   end
  1358.  elseif evt == "mouse_drag" then
  1359.   if p2 >= grid[1] then
  1360.    if p2 <= grid[2] then
  1361.     if p3 >= grid[3] then
  1362.      if p3 <= grid[4] then
  1363.       if drawing == true then
  1364.        if p1 == 1 then
  1365.         if brushSize <= 1 then
  1366.          if elements[sel][20] == 0 then
  1367.           createParticle(p2,p3,sel,creationLife,creationCotype,creationTemp)
  1368.          elseif elements[sel][20] == 1 then
  1369.           if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.min(particles[getParticleAt(p2,p3)][7] + 5, MAX_TEMP) end
  1370.          elseif elements[sel][20] == 2 then
  1371.           if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.max(particles[getParticleAt(p2,p3)][7] - 5, MIN_TEMP) end
  1372.          end
  1373.         else
  1374.          local bs = (brushSize - 1)
  1375.          local ds = (brushSize * 2) - 1
  1376.          rect(p2-bs, p3-bs, (p2-bs)+ds, (p3-bs)+ds)
  1377.         end
  1378.        elseif p1 == 2 then
  1379.         if brushSize <= 1 then
  1380.          killParticle(getParticleAt(p2,p3))
  1381.         else
  1382.          local bs = (brushSize - 1)
  1383.          local ds = (brushSize * 2) - 1
  1384.          arect(p2-bs, p3-bs, (p2-bs)+ds, (p3-bs)+ds)
  1385.         end
  1386.        end        
  1387.       end
  1388.      end
  1389.     end
  1390.    end
  1391.   end
  1392.  elseif evt == "mouse_click" then
  1393.   --write(p1 .. "," .. p2 .. "," .. p3 .. "  ")
  1394.   if p2 >= grid[1] then
  1395.    if p2 <= grid[2] then
  1396.     if p3 >= grid[3] then
  1397.      if p3 <= grid[4] then
  1398.       drawing = true
  1399.       if p1 == 3 then
  1400.        info(p2, p3)
  1401.       end
  1402.       if p1 == 1 then
  1403.        lx = p2
  1404.        ly = p3
  1405.        if brushSize <= 1 then
  1406.         if elements[sel][20] == 0 then
  1407.          createParticle(p2,p3,sel,creationLife,creationCotype,creationTemp)
  1408.         elseif elements[sel][20] == 1 then
  1409.          if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.min(particles[getParticleAt(p2,p3)][7] + 5, MAX_TEMP) end
  1410.         elseif elements[sel][20] == 2 then
  1411.          if getParticleAt(p2,p3) ~= 0 then particles[getParticleAt(p2,p3)][7] = math.max(particles[getParticleAt(p2,p3)][7] - 5, MIN_TEMP) end
  1412.         end
  1413.        else
  1414.         local bs = (brushSize - 1)
  1415.         local ds = (brushSize * 2) - 1
  1416.         rect(p2-bs, p3-bs, (p2-bs)+ds, (p3-bs)+ds)
  1417.        end
  1418.       end
  1419.       if p1 == 2 then
  1420.        if brushSize <= 1 then
  1421.         killParticle(getParticleAt(p2,p3))
  1422.        else
  1423.         local bs = (brushSize - 1)
  1424.         local ds = (brushSize * 2) - 1
  1425.         arect(p2-bs, p3-bs, (p2-bs)+ds, (p3-bs)+ds)
  1426.        end
  1427.       end
  1428.      else
  1429.       drawing = false
  1430.      end
  1431.     else
  1432.      drawing = false
  1433.     end
  1434.    else
  1435.     drawing = false
  1436.    end
  1437.   else
  1438.    drawing = false
  1439.   end
  1440.   for k, v in pairs(buttons) do
  1441.    term.setCursorPos(1, k)
  1442.    --print(p2 .. "," .. p3 .. " vs " .. v[1] .. "-" .. v[2] .. "," .. v[3] .. "-" .. v[4])
  1443.    if p2 >= v[1] then
  1444.     if p2 <= v[2] then
  1445.      if p3 >= v[3] then
  1446.       if p3 <= v[4] then
  1447.        --print(v[func])
  1448.        if v[7] == true then
  1449.         v[6]()
  1450.         break
  1451.        end
  1452.       end
  1453.      end
  1454.     end
  1455.    end
  1456.   end
  1457.  elseif evt == "timer" and p1 == timeout then
  1458.   timeout = os.startTimer(1 / fps)
  1459.   --shouldRender = not shouldRender
  1460.   pb = colors.gray
  1461.   pf = colors.white
  1462.   if paused == true then
  1463.    pb = colors.white
  1464.    pf = colors.black
  1465.   else
  1466.    if menu == false then
  1467.     simulate()
  1468.     --if shouldRender == true then redraw() end
  1469.    end
  1470.   end
  1471.   --if dirty then redraw() end
  1472.   redraw()
  1473.   term.setBackgroundColor(pb)
  1474.   term.setTextColor(pf)
  1475.   term.setCursorPos(1, 18)
  1476.   write("[ || ]")
  1477.   term.setBackgroundColor(colors.gray)
  1478.   term.setTextColor(colors.white)
  1479.  elseif evt == "timer" and p1 == textReset then
  1480.   statusbar = "ccSand by CosmoConsole                        " .. version
  1481.   dirty = true
  1482.  end
  1483. end
  1484.  
  1485. if API then os.unloadAPI("redirect") end
  1486.  
  1487. term.setBackgroundColor(colors.black)
  1488. term.setTextColor(colors.white)
  1489. term.clear()
  1490. term.setCursorPos(1,1)
Advertisement
Add Comment
Please, Sign In to add comment