Lion4ever

PIM Shop

May 17th, 2016
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.05 KB | None | 0 0
  1. local fName = "trades"
  2. local nameLength = 12
  3. local chestSide = "down"
  4. local expireDays = math.huge
  5.  
  6. local mon = peripheral.find("monitor")
  7. mon.setBackgroundColor(colors.black)
  8. mon.clear()
  9. local pim = peripheral.find("pim")
  10.  
  11. local chestInv = {}
  12. local deals = {}
  13. local saveData = {deals=deals,chestInv=chestInv}
  14. local buttons = {}
  15. local players = {}
  16. local curPl
  17.  
  18. -- offer=Item,price=Item,owner=uuid,startDay=number,
  19. -- Item has display_name, dmg, max_dmg,qty, max_size, id
  20. if fs.exists(fName) then
  21.   local f = fs.open(fName,"r")
  22.   saveData = textutils.unserialize(f.readAll())
  23.   deals = saveData.deals
  24.   chestInv = saveData.chestInv
  25.   f.close()
  26. end
  27.  
  28. local function save()
  29.   local f = fs.open(fName,"w")
  30.   f.write(textutils.serialize(saveData))
  31.   f.close()
  32. end
  33.  
  34.  
  35. local pInv = {}
  36. local invSlots
  37. local function loadInventory()
  38.   pInv = {}
  39.   invSlots = pim.getAllStacks()
  40.   for i,k in pairs(invSlots) do
  41.     local j=k.basic()
  42.     if pInv[j.id] and pInv[j.id][j.dmg] then
  43.       local t = pInv[j.id][j.dmg]
  44.       table.insert(t.slots,i)
  45.       t.qty = t.qty + j.qty
  46.     else
  47.       pInv[j.id] = pInv[j.id] or {}
  48.       pInv[j.id][j.dmg] = j
  49.       j.slots = {i}
  50.     end
  51.   end
  52. end
  53.  
  54. local function writeItem(I,x,y)
  55.   mon.setCursorPos(x,y)
  56.   mon.write(string.format("%2d %s",math.floor(I.qty),(I.display_name..(" "):rep(nameLength)):sub(1,nameLength)))
  57.   mon.setCursorPos(x,y+1)
  58.   mon.write(string.format("%s%3d",string.rep(" ",nameLength),I.stored))
  59. end
  60.  
  61. local function addButton(d,x,y,revs,name)
  62.   mon.setCursorPos(x,y)
  63.   mon.write(name)
  64.   table.insert(buttons,{xmin=x,xmax=x+#name,y=y,deal=d,reversed=revs,name=name})
  65. end
  66.  
  67. local function addButtons(d,x,y,revs)
  68.   addButton(d,x,y,revs,"1")
  69.   addButton(d,x+2,y,revs,"1/2")
  70.   addButton(d,x+6,y,revs,"all")
  71. end
  72.  
  73. local function hasItem(i,n)
  74.   return pInv[i.id] and pInv[i.id][i.dmg] and pInv[i.id][i.dmg].qty >= n
  75. end
  76.  
  77. local function amount(i)
  78.   return pInv[i.id] and pInv[i.id][i.dmg] and pInv[i.id][i.dmg].qty or 0
  79. end
  80.  
  81. local function drawDeal(d,x,y)
  82.   local bc = colors.gray
  83.   if d.owner == curPl.uuid then
  84.     if d.offer.stored < d.offer.qty then
  85.       bc = colors.red
  86.     else
  87.       bc = colors.blue
  88.     end
  89.   elseif hasItem(d.price,d.price.qty) then
  90.     bc = colors.green
  91.   end
  92.   mon.setBackgroundColor(bc)
  93.   writeItem(d.offer,x,y)
  94.   mon.setCursorPos(x+nameLength+3,y)
  95.   mon.write(" for ")
  96.   mon.setCursorPos(x+nameLength+3,y+1)
  97.   mon.write("     ")
  98.   writeItem(d.price,x+nameLength+8,y)
  99.   mon.setBackgroundColor(colors.orange)
  100.   if d.owner == curPl.uuid then
  101.     addButton(d,x,y+1,nil,"refill")
  102.     addButton(d,x+7,y+1,nil,"delete")
  103.     if d.price.stored > 0 then
  104.       addButton(d,x+14,y+1,nil,"take")
  105.     end
  106.   else
  107.     addButtons(d,x,y+1,false)
  108.     if d.reversable then
  109.       addButtons(d,x+nameLength+8,y+1,true)
  110.     end
  111.   end
  112. end
  113.  
  114. local function updateMonitor()
  115.   mon.setCursorPos(1,1)
  116.   mon.setBackgroundColor(colors.black)
  117.   mon.write("Player: "..curPl.name..string.rep(" ",nameLength))
  118.   buttons = {}
  119.   local dNum = 1
  120.   local mx,my = mon.getSize()
  121.   for j=3,my,3 do
  122.     for i=1,mx - 2*nameLength-11 ,2*nameLength+12 do
  123.       if deals[dNum] then
  124.         drawDeal(deals[dNum],i,j)
  125.         dNum = dNum + 1
  126.       else
  127.         mon.setBackgroundColor(colors.orange)
  128.         addButton(nil,i,j,nil,"New Trade")
  129.         return
  130.       end
  131.     end
  132.   end
  133. end
  134.  
  135. local function updatePlayer()
  136.   if #players == 1 then
  137.     curPl = players[1]
  138.     loadInventory()
  139.   else
  140.     curPl = {name=""}
  141.     pInv = {}
  142.   end
  143.   updateMonitor()
  144. end
  145. updatePlayer()
  146.  
  147. local function copy(t)
  148.   local r = {}
  149.   for i,j in pairs(t) do
  150.     if type(j) == "table" then
  151.       r[i] = copy(j)
  152.     else
  153.       r[i] = j
  154.     end
  155.   end
  156.   return r
  157. end
  158.  
  159. local function store(I,n)
  160.   local rem = n
  161.   if hasItem(I,n) then
  162.     local s = pInv[I.id][I.dmg].slots
  163.     local si = #s
  164.     local sc = 1
  165.     while rem > 0 do
  166.       local qty = invSlots[s[si]].basic().qty
  167.       local k = chestInv[sc]
  168.       while k and (k.id ~= I.id or k.dmg ~= I.dmg or k.max_size <= k.qty) do
  169.         sc = sc + 1
  170.         k = chestInv[sc]
  171.       end
  172.       local restSpace = k and k.max_size-k.qty or math.huge
  173.       local put = pim.pushItem(chestSide,s[si],math.min(rem,qty,restSpace),sc)
  174.       qty = qty - put
  175.       rem = rem - put
  176.       if k then
  177.         k.qty = k.qty + put
  178.       else
  179.         chestInv[sc] = copy(I)
  180.       end
  181.       if qty == 0 then
  182.         si = si - 1
  183.         if si == 0 and rem > 0 then
  184.           I.stored = I.stored+(n-rem)
  185.           return false, n-rem
  186.         end
  187.       end
  188.     end
  189.     I.stored = I.stored+n
  190.     return true,n
  191.   end
  192.   return false,0
  193. end
  194.  
  195. local function giveOut(I,n)
  196.   local rem = n
  197.   local sc = #chestInv
  198.   while rem > 0 do
  199.     local k = chestInv[sc]
  200.     while not k or k.id ~= I.id or k.dmg ~= I.dmg do
  201.       sc = sc - 1
  202.       if sc <= 0 then
  203.         I.stored = I.stored-(n-rem)
  204.         return false,n-rem
  205.       end
  206.       k = chestInv[sc]
  207.     end
  208.     local put = pim.pullItem(chestSide,sc,math.min(rem,chestInv[sc].qty))
  209.     rem = rem - put
  210.     if k then
  211.       k.qty = k.qty - put
  212.       if k.qty == 0 then
  213.         chestInv[sc] = nil
  214.       end
  215.     end
  216.   end
  217.   I.stored = I.stored-n
  218.   return true,n
  219. end
  220.  
  221. while true do
  222.   local e = {os.pullEvent()}
  223.   if e[1] == "player_on" then
  224.     table.insert(players,{name=e[2],uuid=e[3]})
  225.     updatePlayer()
  226.   elseif e[1] == "player_off" then
  227.     for i,j in ipairs(players) do
  228.       if j.uuid == e[3] then
  229.         table.remove(players,i)
  230.         break
  231.       end
  232.     end
  233.     updatePlayer()
  234.   elseif e[1] == "monitor_touch" then
  235.     for i,j in ipairs(buttons) do
  236.       if e[3] >= j.xmin and e[3] <= j.xmax and e[4] == j.y then
  237.         if j.name == "New Trade" then
  238.           local slots = pim.getAllStacks()
  239.           if slots[4] and slots[6] then
  240.             local ofr = slots[4].basic()
  241.             local pri = slots[6].basic()
  242.             ofr.stored = 0
  243.             pri.stored = 0
  244.             table.insert(deals,{offer=ofr,price=pri,owner=curPl.uuid,reversable=slots[5] and true or false,startDay=os.day()})
  245.             save()
  246.             updateMonitor()
  247.           end
  248.         elseif j.name == "delete" then
  249.           for k,l in ipairs(deals) do
  250.             if l == j.deal then
  251.               giveOut(l.price,l.price.stored)
  252.               giveOut(l.offer,l.offer.stored)              
  253.               table.remove(deals,k)
  254.               save()
  255.               mon.setBackgroundColor(colors.black)
  256.               mon.clear()
  257.               updateMonitor()
  258.               break
  259.             end
  260.           end
  261.         elseif j.name == "refill" then
  262.           loadInventory()
  263.           local item = j.deal.offer
  264.           store(item,amount(item))
  265.           save()
  266.           updateMonitor()
  267.         elseif j.name == "take" then
  268.           loadInventory()
  269.           local item = j.deal.price
  270.           if item.stored > 0 then
  271.             giveOut(item,item.stored)            
  272.           end
  273.           save()
  274.           updateMonitor()
  275.         elseif j.name == "1" or j.name == "1/2" or j.name == "all" then
  276.           loadInventory()
  277.           local pri = j.deal.price
  278.           local ofr = j.deal.offer
  279.           if j.reversed then
  280.             pri,ofr = ofr,pri
  281.           end
  282.           local times = 1
  283.           if  j.name == "1/2" then
  284.             times = math.floor(amount(pri) / pri.qty / 2)
  285.           elseif j.name == "all" then
  286.             times = math.floor(amount(pri) / pri.qty)
  287.           end
  288.           local s,taken = store(pri,times * pri.qty)
  289.           if s then
  290.             local s2,given = giveOut(ofr,times * ofr.qty)
  291.             if not s2 then --panic a little bit and try to undo
  292.               loadInventory()
  293.               store(ofr,times * ofr.qty)
  294.               giveOut(pri,times * pri.qty)
  295.               print("Failed to give "..ofr.display_name.. " to "..pim.getInventoryName())
  296.             end
  297.           else
  298.             giveOut(pri,taken)
  299.           end
  300.           save()
  301.           updateMonitor()
  302.         else
  303.           error("Invalid Button press")
  304.         end
  305.       end
  306.     end
  307.   end
  308. end
Advertisement
Add Comment
Please, Sign In to add comment