MikrySoft

frescafix

Mar 12th, 2014
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.10 KB | None | 0 0
  1. --[[
  2. Fresco v 1.0.0
  3. Matti Vapa, 2013
  4. https://github.com/mattijv/fresco
  5. http://pastebin.com/KU8RWSQd
  6.  
  7. This program will take as an argument a URL to an image file and request a copy of
  8. it via a server that converts it to a proper format. It then reproduces the image
  9. using Glowstone Illuminators from Thermal Expansion. Required mods are
  10.  
  11.     * ComputerCraft (duh)
  12.     * Thermal Expansion
  13.     * OpenPeripheral
  14.     (* MiscPeripherals if you want to use Resupply Station)
  15.  
  16. Instead of a direct URL you can also input a Minecraft username with the -u handle.
  17. The program will download the skin corresponding to the username and build the face
  18. part of the skin.
  19.  
  20. Possible future features:
  21.    
  22.     * Ability to specify a part of the image to be build, so multiple turtles can
  23.       be used for the same picture. This will probably be implemented.
  24.     * Add more comments so people can easily modify this code. Also to pretend that I'm
  25.       a real programmer.
  26.  
  27. Changelog:
  28.  
  29.     0.1.0 - 0.8.0:
  30.                 * Added most features and tested until 6 AM.
  31.    
  32.     0.9.0:
  33.                 * Released for public testing.
  34.     1.0.0:
  35.                 * Added option to build the image horizontally
  36.                 * Cleaning up the code.
  37.                 * Added a licence.
  38.  
  39.  
  40.  
  41. The MIT License (MIT)
  42.  
  43. Copyright (c) 2013 Matti Vapa
  44.  
  45. Permission is hereby granted, free of charge, to any person obtaining a copy
  46. of this software and associated documentation files (the "Software"), to deal
  47. in the Software without restriction, including without limitation the rights
  48. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  49. copies of the Software, and to permit persons to whom the Software is
  50. furnished to do so, subject to the following conditions:
  51.  
  52. The above copyright notice and this permission notice shall be included in
  53. all copies or substantial portions of the Software.
  54.  
  55. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  56. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  57. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  58. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  59. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  60. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  61. THE SOFTWARE.
  62.  
  63.  
  64. ]]--
  65.  
  66. if not http then
  67.     print("HTTP must be enabled.")
  68.     return
  69. end
  70.  
  71.  
  72. VERSION = "1.0.0"
  73.  
  74. print("Fresco v "..VERSION)
  75.  
  76. apiURL = "http://lakka.kapsi.fi:62096"
  77. playerURL = "http://s3.amazonaws.com/MinecraftSkins/"
  78.  
  79. local chest = nil
  80. local supply = nil
  81. local url
  82. local maxsize
  83. local height,width
  84. local row,column
  85. -- for finding the face in the skin file
  86. local offsetY,offsetX = 0,0
  87. local ascend = turtle.up
  88. local descend = turtle.down
  89.  
  90. local usage = function()
  91.     print("Usage:")
  92.     print("fresco [-h] [-u playername] [url] [size]")
  93.     print("Either playername with -u option or url to image must be supplied.")
  94.     print("With -u option the size parameter is the dimensions of the face (default 8 pixels).")
  95.  
  96.     --[[
  97.     print("Options:")
  98.     print("-u    Uses the face from the skin of the player with the name 'playername' as the image.")
  99.     print("      If you use -u you don't need to provide the url as an argument.")
  100.     print("url   The url to the desired picture in the form 'http://www.images.com/coolpic.png'.")
  101.     print("      Not needed if you use -u.")
  102.     print("size  The maximum lenght of the longer side. The image will be (down/up)scaled to fit this size.")
  103.     print("      With -u the size is the size of the players face, default 8 pixels.")
  104.     ]]--
  105. end
  106.  
  107. local move = function(f)
  108.     while turtle.getFuelLevel() < 1 do
  109.         print("Low on fuel. Please add fuel to my inventory and press return.")
  110.         local e,c = os.pullEvent("key")
  111.         while c ~= 28 do
  112.             e,c = os.pullEvent("key")
  113.         end
  114.         print("Checking for fuel...")
  115.         shell.run("refuel all")
  116.     end
  117.     while not f() do
  118.         sleep(0.3)
  119.     end
  120.     sleep(0.1)
  121. end
  122.  
  123. local resupplyFromStation = function()
  124.     while not supply.resupply(1) do
  125.         print("Please restock the Resupply Station.")
  126.         sleep(10)
  127.     end
  128. end
  129.  
  130. local resupplyFromChest = function()
  131.     local r = row
  132.     local c = column
  133.     while r < height do
  134.         move(descend)
  135.         r = r + 1
  136.     end
  137.     turtle.turnLeft()
  138.     while c > 1 do
  139.         move(turtle.forward)
  140.         c = c - 1
  141.     end
  142.     turtle.turnRight()
  143.     move(turtle.back)
  144.     for slot = 1,16 do
  145.         chest.condenseItems()
  146.         while not chest.getStackInSlot(1) do
  147.             print("Please add more Illuminators to the chest.")
  148.             sleep(5)
  149.             chest.condenseItems()
  150.         end
  151.         chest.pushItemIntoSlot("down",1,64,slot)
  152.     end
  153.     move(turtle.forward)
  154.     turtle.turnRight()
  155.     while c < column do
  156.         move(turtle.forward)
  157.         c = c + 1
  158.     end
  159.     turtle.turnLeft()
  160.     while r > row do
  161.         move(ascend)
  162.         r = r - 1
  163.     end
  164. end
  165.  
  166. local placeFront = function(color)
  167.     if turtle.detect() then return end
  168.     if turtle.getItemCount(1) < 2 then
  169.         if supply then
  170.             resupplyFromStation()
  171.         elseif turtle.getItemCount(1) == 0 then
  172.             local slot = 2
  173.             while slot <= 16 do
  174.                 turtle.select(slot)
  175.                 if turtle.transferTo(1) then
  176.                     break
  177.                 end
  178.                 slot = slot + 1
  179.             end
  180.             if slot > 16 then
  181.                 resupplyFromChest()
  182.             end
  183.         end
  184.     end
  185.     turtle.select(1)
  186.     turtle.place()
  187.     local lamp = peripheral.wrap("front")
  188.     lamp.setColor(tonumber(color,16))
  189.     turtle.attack()
  190. end
  191.  
  192. local placeDown = function(color)
  193.     if turtle.detectDown() then return end
  194.     if turtle.getItemCount(1) < 2 then
  195.         if supply then
  196.             resupplyFromStation()
  197.         elseif turtle.getItemCount(1) == 0 then
  198.             local slot = 2
  199.             while slot <= 16 do
  200.                 turtle.select(slot)
  201.                 if turtle.transferTo(1) then
  202.                     break
  203.                 end
  204.                 slot = slot + 1
  205.             end
  206.             if slot > 16 then
  207.                 resupplyFromChest()
  208.             end
  209.         end
  210.     end
  211.     turtle.select(1)
  212.     turtle.placeDown()
  213.     local lamp = peripheral.wrap("bottom")
  214.     lamp.setColor(tonumber(color,16))
  215.     turtle.attackDown()
  216. end
  217.  
  218. local calcFuelNeed = function (h,w)
  219.     local fuel = (h-1)*w+w+1
  220.     if w%2 == 1 then
  221.         fuel = fuel + (h-1)
  222.     end
  223.     if chest then
  224.         local fuelruns = math.floor((w*h-1)/1024)
  225.         for i = 1,fuelruns do
  226.             local columns, frac = math.modf(i*1024/h)
  227.             -- horizontal movement
  228.             fuel = fuel + 2*(columns+1)+2
  229.             -- vertical movement
  230.             if columns % 2 == 1 then
  231.                 fuel = fuel + 2*(h-math.floor(frac*h+0.5)-1)
  232.             else
  233.                 fuel = fuel + 2*(math.floor(frac*h+0.5)-1)
  234.             end
  235.         end
  236.     end
  237.     return fuel
  238. end
  239.  
  240.  
  241. _args = {...}
  242. args = {}
  243.  
  244.  
  245. local place = placeFront
  246.  
  247. local i = 1
  248. while i <= #_args do
  249.     if _args[i] == "-h" then
  250.         place = placeDown
  251.         ascend = turtle.forward
  252.         descend = turtle.back
  253.     elseif _args[i]:sub(1,1) == "-" then
  254.         args[_args[i]] = _args[i+1]
  255.         i = i + 1
  256.     elseif tonumber(_args[i]) ~= nil then
  257.         args["maxsize"] = _args[i]
  258.     else
  259.         args["url"] = _args[i]
  260.     end
  261.     i = i + 1
  262. end
  263.  
  264.  
  265. if not args["url"] and not args["-u"] then
  266.     usage()
  267.     return
  268. else
  269.     if args["-u"] ~= nil then
  270.         url = playerURL..args["-u"]..".png"
  271.         if args["maxsize"] then
  272.                 maxsize = tostring(math.floor(tonumber(args["maxsize"])*(64/8)+0.5))
  273.         end
  274.     else
  275.         url = args["url"]
  276.         maxsize = args["maxsize"]
  277.     end
  278.    
  279. end
  280.  
  281. if not url then
  282.     usage()
  283.     return
  284. end
  285.  
  286. local vars = "url="..url
  287. if maxsize then
  288.     vars = vars.."&maxsize="..maxsize
  289. end
  290. sleep(0.5)
  291. print("Requesting image from")
  292. print(url)
  293. f = http.post(apiURL,vars)
  294. if not f then
  295.     print("No response from image server.")
  296.     return
  297. elseif f.getResponseCode() ~= 200 then
  298.     print("Error while connecting to server!")
  299.     print("Server response")
  300.     print("Code: "..f.getResponseCode())
  301.     print("Message:")
  302.     print(f.readAll())
  303.     return
  304. end
  305.  
  306. local oldSize = f.readLine()
  307. local newSize = f.readLine()
  308. if oldSize ~= newSize then
  309.     print("Original image size was (w,h): "..oldSize)
  310.     print("New size is (w,h): "..newSize)
  311. else
  312.     print("Image size is (w,h): "..newSize)
  313. end
  314.  
  315. local img = {}
  316.  
  317. line = f.readLine()
  318. while line ~= nil do
  319.     table.insert(img,line)
  320.     line = f.readLine()
  321. end
  322. f.close()
  323.  
  324.  
  325. -- X:8, Y:8 to X: 15, Y:15 (top left, bottom right of face)
  326. maxsize = tonumber(maxsize)
  327. if args["-u"] then
  328.     if maxsize then
  329.         -- multiply by 8/64 to get the face size and hack a rounding function
  330.         local size = math.floor(maxsize*0.125+0.5)
  331.         height,width = size,size
  332.         offsetY,offsetX = size,size
  333.     else
  334.         height,width = 8,8
  335.         offsetY,offsetX = 8,8
  336.     end
  337. else
  338.     height,width = #img, #img[1]/8
  339.     row,column = height,1
  340. end
  341.  
  342. row,column = height,1
  343. sleep(0.5)
  344. print("Press return to continue.")
  345. local e,c = os.pullEvent("key")
  346. while c ~= 28 do
  347.     e,c = os.pullEvent("key")
  348. end
  349.  
  350. if peripheral.getType("right") == "resupply" then
  351.     print("Resupply module located, using that for resupply.")
  352.     supply = peripheral.wrap("right")
  353.     if not supply.link() then
  354.         print("\nCould not locate Resupply Station!\nPlease put a Resupply Station near me.")
  355.         return
  356.     end
  357. else
  358.     print("No resupply module, there should be a chest on top of me.")
  359.     if peripheral.getType("top") == nil then
  360.         print("No valid inventory found on top.")
  361.         return
  362.     end
  363.     chest = peripheral.wrap("top")
  364.     if chest.pushItemIntoSlot == nil then
  365.         print("Inventory does not support required operations.")
  366.         return
  367.     end
  368. end
  369. print("Resupply inventory located.")
  370. sleep(0.5)
  371. print("Calculating needed fuel...")
  372. local fuelNeed = calcFuelNeed(height,width)
  373. sleep(0.5)
  374. print("Fuel consumption will be (approximate): "..tostring(fuelNeed))
  375. print("Current fuel level is: "..tostring(turtle.getFuelLevel()))
  376. if turtle.getFuelLevel() < fuelNeed then
  377.     while turtle.getFuelLevel() < fuelNeed do
  378.         print(string.format("Need %d fuel units more.",fuelNeed-turtle.getFuelLevel()))
  379.         print("Please put more fuel into my inventory and press return.")
  380.         local e,c = os.pullEvent("key")
  381.         while c ~= 28 do
  382.             e,c = os.pullEvent("key")
  383.         end
  384.         print("Checking for fuel...")
  385.         shell.run("refuel all")
  386.     end
  387. end
  388. print("Fuel requirements met. Looking for building materials...")
  389. sleep(0.3)
  390. while turtle.getItemCount(1) < 1 do
  391.     if chest then
  392.         print("Please put Glowstone Illuminators into my inventory.")
  393.     else
  394.         print("Please put Glowstone Illuminators into the first slot of my inventory.")
  395.     end
  396.     print("Press return to continue.")
  397.     local e,c = os.pullEvent("key")
  398.     while c ~= 28 do
  399.         e,c = os.pullEvent("key")
  400.     end
  401. end
  402.  
  403. print("Good to go!")
  404. print(string.format("The process will take around %f minutes to finish.",(1.2*fuelNeed)/60))
  405. print("Press return to begin.")
  406. e,c = os.pullEvent("key")
  407. while c ~= 28 do
  408.     e,c = os.pullEvent("key")
  409. end
  410.  
  411. print("Starting printing...")
  412.  
  413. move(turtle.forward)
  414. turtle.select(1)
  415. while true do
  416.     if column > width then break end
  417.     place(img[row+offsetY]:sub(1+8*(column-1+offsetX),1+8*(column-1+offsetX)+7))
  418.     while row > 1 do
  419.         move(ascend)
  420.         row = row - 1
  421.         place(img[row+offsetY]:sub(1+8*(column-1+offsetX),1+8*(column-1+offsetX)+7))
  422.     end
  423.     turtle.turnRight()
  424.     move(turtle.forward)
  425.     turtle.turnLeft()
  426.     column = column + 1
  427.     if column > width then break end
  428.     place(img[row+offsetY]:sub(1+8*(column-1+offsetX),1+8*(column-1+offsetX)+7))
  429.     while row < height do
  430.         move(descend)
  431.         row = row + 1
  432.         place(img[row+offsetY]:sub(1+8*(column-1+offsetX),1+8*(column-1+offsetX)+7))
  433.     end
  434.     turtle.turnRight()
  435.     move(turtle.forward)
  436.     turtle.turnLeft()
  437.     column = column + 1
  438. end
  439.  
  440. if width % 2 == 1 then
  441.     for i = 1, height-1 do
  442.         move(descend)
  443.     end
  444. end
Advertisement
Add Comment
Please, Sign In to add comment