Advertisement
NuAoA

tradeOS

Feb 28th, 2014
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 90.39 KB | None | 0 0
  1. -- TradeOS
  2. local version = 0.51
  3. -- By: NuAoA
  4. -- Feel free to share/modify
  5. if not fs.exists("Draw") then print("Needs Draw api") end
  6. os.loadAPI("Draw")
  7. --[[
  8. TODO:
  9. - see !done
  10. - Add a check when trying to push items into a full player inventory to see if there is a stack
  11. Done:
  12. - Wraps all modem peripherals and exits if one is missing
  13. - Logs PIM location on startup (need to add name selection if multiple people in range)
  14. - creates settings file
  15. - loads settings file (if exists)
  16. - keeps currentPlayer up to date.
  17. ]]--
  18.  
  19. ae_direction = "west"
  20. PimDir = "east"
  21. --[[
  22. Global Variables:
  23. ]]--
  24.  
  25. currentPlayer = nil
  26. modem = {["exists"] = false, ["face"] = nil}
  27. monitor = {["exists"] = false, ["faces"] = nil}
  28. Admins = {} --Have unlimited currency.
  29. PIM_xyz = {}
  30. default_credits = nil
  31. --global_iList_ench = {}
  32. global_iList_IDs = {}
  33. global_iList_trades = {}
  34. player_iList_inv = {}
  35. player_iList = {}
  36. global_alt_names = {}
  37. validAddress = {}
  38. maxTrades = 15
  39. dontUpdate = false
  40. local notFirstBoot = true
  41. money_name = "Creddits" --ONLY CHANGE THIS IF NO PLAYERDATA IS PRESENT (AKA THE FIRST TIME YOU RUN THE PROGRAM)
  42. localSaves = false --Saves playerData locally, not recomended since CC has a 2mb limit, which would fill up pretty quick with 100+ players and 1000+ unique items.
  43. header_sel = {"deposit","withdraw","selling","buy"}
  44. header_current = "deposit"
  45.  
  46. --[[
  47. PreDefined Usefulls:
  48. ]]--
  49. local directions = {"back","front","left","right","top","bottom"}
  50. local dir2 = {"up","down","east","west","south","north"}
  51.  
  52. --[[
  53. error handling
  54. --]]
  55. function ERR(fun,mes,argz,bool)
  56. local file
  57. local prev = ""
  58. if fs.exists("debug.txt") then
  59. file = fs.open("debug.txt","r")
  60. prev = file.readAll()
  61. file.close()
  62. else
  63. prev = "TradeOS Debug File".."\n".."\n"
  64. end
  65. file = fs.open("debug.txt","w")
  66. file.write(prev.."\n")
  67. local str = ""
  68. if bool then
  69. str = " "..tostring(argz)
  70. end
  71. file.write("[ERROR]["..fun.."]".."["..os.day()..","..os.time().."]["..tostring(currentPlayer).."] "..mes..str)
  72. file.close()
  73. if terminate then
  74. print("Press Enter to restart...")
  75. io.read()
  76. os.reboot()
  77. else
  78. end
  79. end
  80.  
  81. --Just a key to add to each screen that allows a quick reboot.
  82. function restart(key)
  83. if key == 41 then return true else return false end
  84. end
  85.  
  86. --[[
  87. Making modem functions easier to call
  88. ]]--
  89.  
  90. sensor = {}
  91. -- Functions:
  92. -- sensor.names()
  93. -- Returns a table of names of players in range of the sensor
  94. -- sensor.location(name[optional])
  95. -- Returns a table of the location of player [name] or the first player it finds
  96.  
  97. function sensor.names()
  98. return modem.wrapped.callRemote(modem.sensor,"getPlayerNames")
  99. end
  100.  
  101. function fixNames(item)
  102. if item == nil or item.id == nil or item.dmg == nil then ERR("fixNames","nil item ID or damage") end
  103. if type(item) == "string" then error("fixedNames, I was passed a string",2) end
  104. local unique = IDtoUnique(item.id,item.dmg)
  105. if global_alt_names[unique] ~= nil then
  106. return tostring(global_alt_names[unique])
  107. else
  108. return tostring(item.name)
  109. end
  110. end
  111.  
  112. function sensor.location(...)
  113. local playername = nil
  114. local pass=false
  115. if #arg>0 then
  116. playername = arg[1]
  117. for k,v in pairs(sensor.names()) do
  118. if playername==v then
  119. pass = true
  120. break
  121. end
  122. end
  123. else
  124. playername = sensor.names()[1]
  125. pass = true
  126. end
  127. if pass then
  128. return modem.wrapped.callRemote(modem.sensor,"getPlayerData",playername)
  129. else
  130. ERR("sensor.location","Tried to look up location data on a player that does not exist")
  131. end
  132. end
  133.  
  134. PIM = {}
  135. -- Functions:
  136. -- PIM.getAllStacks()
  137. -- Returns a table the currentPlayers inventory.
  138. -- PIM.
  139.  
  140. function PIM.getAllStacks()
  141. return modem.wrapped.callRemote(modem.PIM,"getAllStacks")
  142. end
  143.  
  144.  
  145. --from chest to player
  146. function PIM.pullItem(slot,amount)
  147. return modem.wrapped.callRemote(modem.PIM,"pullItem",PimDir,slot,amount)
  148. end
  149.  
  150. --from player to chest
  151. function PIM.pushItem(slot,amount)
  152. return modem.wrapped.callRemote(modem.PIM,"pushItem",PimDir,slot,amount)
  153. end
  154.  
  155. --will dump all the items in the chest into the player inventory
  156. function PIM.dumpAll()
  157. for k,v in pairs(getChestData()) do
  158. PIM.pullItem(k,v.qty)
  159. end
  160. end
  161.  
  162. function PIM.getFreeSlots()
  163. local tab = PIM.getAllStacks()
  164. local count = 4
  165. for k,v in pairs(tab) do
  166. if k<37 then
  167. count = count+1
  168. end
  169. end
  170. return modem.wrapped.callRemote(modem.PIM,"getInventorySize")-count
  171. end
  172.  
  173. ae = {}
  174. -- Functions:
  175. -- ae.suckAll(...)
  176. -- sucks all items into chest, records them as currentPlayer's items or arg[1]
  177. -- ae.extractItem(item,qty)
  178. -- extracts a item from the ae network into a chest. item is default item table.
  179.  
  180. function ae.suckAll(...)
  181. local name
  182. if #arg >0 then
  183. name = arg[1]
  184. else
  185. name = currentPlayer
  186. end
  187. local sum = 0
  188. if not string.match(tostring(modem.wrapped.callRemote(modem.interface,"canHoldNewItem")),"false") then --funky, but format might change down the line
  189. local tab = getChestData()
  190. if tab ~= nil then
  191. for k,v in pairs(tab) do
  192. modem.wrapped.callRemote(modem.interface,"insertItem",k,v.qty,ae_direction)
  193. updatePlayerTable(v,v.qty)
  194. sum = sum +v.qty
  195. end
  196. end
  197. else
  198. userInput("AE Inventory is full, please contact an admin/owner RIGHT MEOW, also talk to them about recovering your item") -- Doesnt work? item appears to dissappear.
  199. end
  200. save_player(name)
  201. return sum
  202. end
  203.  
  204. --extracts item from AE network to chest. returnts true if qty of item is extracted, false if something went wrong.
  205. function ae.extractItem(item,qty)
  206. if qty <= 0 then return end
  207. local temp_tab = modem.wrapped.callRemote(modem.interface,"getAvailableItems")
  208. for index,item_ae in pairs(temp_tab) do
  209. if item_ae.id == item.id then
  210. if item_ae.dmg == item.dmg and item_ae.name == item.name then
  211. if compareEnchantments(item_ae,item) then --we found the item to extract
  212. if item_ae.qty >= qty then --enough items
  213. local extract_tab = deepcopy(item_ae) --Copy AE item incase of any odd NBT data
  214. extract_tab.qty = qty
  215. local extracted = modem.wrapped.callRemote(modem.interface,"extractItem",extract_tab,ae_direction)
  216. if extracted ~= qty then
  217. ERR("ae.extractItem","Wrong amount of items extracted from AE. Perhaps they were not found?")
  218. ERR("ae.extractItem","Attempted "..qty.." of "..fixNames(item).." got",extracted,true)
  219. return false
  220. end
  221. return true
  222. else
  223. ERR("ae.extractItem", "AE NETWORK IS MISSING ITEMS")
  224. ERR("ae.extractItem", "Item:",fixNames(item_ae),true)
  225. ERR("ae.extractItem", "Items in AE:",item_ae.qty,true)
  226. ERR("ae.extractItem", "Attempted:",qty,true)
  227. end
  228. else
  229. ERR("ae.extractItem","Ench check failed")
  230. end
  231. end
  232. end
  233. end
  234. ERR("ae.extractItem","Item not extracted! x"..qty,fixNames(item),true)
  235. return false
  236. --modem.wrapped.callRemote(modem.interface,"extractItem",test[1],ae_direction)
  237. end
  238.  
  239. --gets the data from the chest under the computer
  240. function getChestData()
  241. local p = peripheral.wrap("bottom")
  242. p.condenseItems()
  243. local retTab = p.getAllStacks()
  244. --sometimes retTab is a number, tested this loop and found it runs only 3 times, so no idea whats going on.
  245. while type(retTab) ~= "table" do
  246. retTab = p.getAllStacks()
  247. end
  248. return deepcopy(retTab)
  249. end
  250.  
  251. --add or remove items from the player_iList. if arg[1] is iList then dont change player_iList, just return change.
  252. function updatePlayerTable(item,amount,...)
  253. local temp_tab = deepcopy(item)
  254. local uniqueID = IDtoUnique(item.id,item.dmg)
  255. temp_tab.qty = amount
  256. local iList = {}
  257. if arg[1] ~= nil then iList = deepcopy(arg[1]) else iList = player_iList end
  258. if iList["items"] == nil then
  259. iList["items"] = {}
  260. end
  261. if iList["items"][uniqueID] == nil then
  262. local temp1 = {}
  263. local temp2 = {}
  264. table.insert(temp1,temp_tab)
  265. temp2[item.name] = temp1
  266. iList["items"][uniqueID] = deepcopy(temp2)
  267. elseif iList["items"][uniqueID][item.name] == nil then
  268. local temp1 = {}
  269. table.insert(temp1,temp_tab)
  270. iList["items"][uniqueID][item.name] = deepcopy(temp1)
  271. else
  272. local check,index = compareEnchantments(iList["items"],temp_tab)
  273. if not check then -- item not found
  274. table.insert(iList["items"][uniqueID][item.name],deepcopy(temp_tab))
  275. else
  276. --item exists
  277. if amount+iList["items"][uniqueID][item.name][index].qty < 0 then
  278. error("UpdatePlayerTable tried to remove more items than existed for that player!")
  279. else
  280. iList["items"][uniqueID][item.name][index].qty = iList["items"][uniqueID][item.name][index].qty+amount
  281. end
  282. end
  283. end
  284. if arg[1] ~= nil then return iList else player_iList = deepcopy(iList) end
  285. end
  286.  
  287. --[[
  288. Setup
  289. ]]--
  290.  
  291. function startup()
  292. -- find the modem
  293. for i=1,#directions do
  294. if peripheral.getType(directions[i]) == "modem" then
  295. modem["exists"] = true
  296. modem["face"] = directions[i]
  297. break
  298. end
  299. end
  300. modem.wrapped = peripheral.wrap(modem.face)
  301. modem.wrapped.open(0) --number is nessassary, but irrelvant?
  302. --for i,v in pairs(peripheral.getMethods(modem.face)) do print(i..". "..v) end
  303. local tab = modem.wrapped.getNamesRemote()
  304. for k,v in pairs(tab) do
  305. if string.match(v,"openperipheral_sensor") then
  306. modem.sensor = v
  307. --sensor.names = modem.wrapped.callRemote(modem.sensor,"getPlayerNames")
  308. elseif string.match(v,"pim_") then
  309. modem.PIM = v
  310. elseif string.match(v,"me_interface_") then
  311. modem.interface = v
  312. end
  313. end
  314. --check that we have all peripherals.
  315. if modem.sensor == nil then
  316. ERR("startup","Missing Sensor!",true)
  317. elseif modem.PIM == nil then
  318. ERR("startup","Missing PIM!",true)
  319. elseif modem.interface == nil then
  320. ERR("startup","Missing ME Interface!",true)
  321. end
  322.  
  323. local temp_validAddress = {}
  324. rednet.open("back")
  325.  
  326. local function one()
  327. rednet.broadcast("Ping")
  328. sleep(1)
  329. end
  330. local function two()
  331. while true do
  332. local ID,message = rednet.receive()
  333. if message == "Pong" then
  334. table.insert(temp_validAddress,ID)
  335. end
  336. end
  337. end
  338. parallel.waitForAny(one,two)
  339. if not localSave and #temp_validAddress == 0 then
  340. error("no computers to save to!")
  341. else
  342. table.sort(temp_validAddress)
  343. validAddress[1] = os.getComputerID()
  344. for i=1,#temp_validAddress do
  345. validAddress[i+1] = temp_validAddress[i]
  346. end
  347. end
  348. rednet.broadcast("ValidAddress "..textutils.serialize(validAddress))
  349. loadStuff()
  350. end
  351.  
  352. function getPIMLocation()
  353. print()
  354. print("Need to log PIM location relative to sensor")
  355. print("Please stand on the PIM (get off first if you are already on it, or just jump)")
  356. while true do
  357. local event = os.pullEvent()
  358. if string.match(event,"player_on") then
  359. local name = sensor.names()[1]
  360. local x = math.floor(sensor.location()["position"]["x"])
  361. local y = math.floor(sensor.location()["position"]["y"])
  362. local z = math.floor(sensor.location()["position"]["z"])
  363. print(name.." is on PIM (x,y,z): "..x..","..y..","..z)
  364. print("Is the player name correct? (y/n)")
  365. local str = string.lower(io.read())
  366. if str == "yes" or str == "y" then
  367. print("PIM Position set")
  368. return x,y,z,name
  369. end
  370. end
  371. end
  372. end
  373.  
  374. function firstBoot()
  375. notFirstBoot = false
  376. sleep(1)
  377. term.setCursorPos(1,1)
  378. term.clear()
  379. print("No settings file found, starting configuration")
  380. local x,y,z,name = getPIMLocation()
  381. print("Writing configuration file.")
  382. print(name.." Set as admin. Open settings.txt in computer "..os.computerID().." To make changes or add more")
  383. print("to log out press ctrl+~ and type in password")
  384. print("Opening settings.txt for review. close file to reboot")
  385. local file = fs.open("settings.txt","w")
  386. file.write("TradeHub Configuration File \n")
  387. file.write("Version: "..version.."\n")
  388. file.write("--------------------------------------------".."\n")
  389. file.write("Admins: "..name..",Notch".."\n")
  390. file.write("--Admins have unlimited credits, and can access logs".."\n")
  391. file.write("PIM_Position: "..x.." "..y.." "..z.."\n")
  392. file.write("--Leave this alone unless you know what you are doing".."\n")
  393. file.write("Default_Player_Credits: "..(1000).."\n")
  394. file.write("--The amount of credits each player starts with".."\n")
  395. file.write("Maximum_number_of_active_trades: "..(maxTrades).."\n")
  396. file.write("--The total amount of trades a player can have at the same time".."\n")
  397. file.close()
  398. sleep(4)
  399. shell.run("edit", "settings.txt")
  400. os.reboot()
  401. end
  402.  
  403. --Called on startup
  404. function loadStuff()
  405. if not fs.exists("settings.txt") then
  406. firstBoot()
  407. end
  408. local efile = fs.open("settings.txt","r")
  409. if efile.readAll() ~= nil then
  410. efile:close()
  411. file = io.open("settings.txt","r")
  412. for line in file:lines() do
  413. if string.match(line,"Admins: .") then
  414. for name in string.gmatch(line,"%a+") do
  415. if name ~= "Admins" then
  416. table.insert(Admins,name)
  417. end
  418. end
  419. end
  420. if string.match(line,"PIM_Position: .") then
  421. PIM_xyz["x"] = tonumber(string.match(line,"PIM_Position: (%S+) %S+ %S+"))
  422. PIM_xyz["y"] = tonumber(string.match(line,"PIM_Position: %S+ (%S+) %S+"))
  423. PIM_xyz["z"] = tonumber(string.match(line,"PIM_Position: %S+ %S+ (%S+)"))
  424. end
  425. if string.match(line,"Default_Player_Credits: .") then
  426. default_credits = tonumber(string.match(line,"Default_Player_Credits: (%d+)"))
  427. end
  428. if string.match(line,"Maximum_number_of_active_trades:") then
  429. maxTrades = tonumber(string.match(line,"Maximum_number_of_active_trades: (%d+)"))
  430. end
  431. end
  432. file:close()
  433. end
  434. if fs.exists("Items.data") then
  435. local file = fs.open("Items.data","r")
  436. local temp_tab = textutils.unserialize(file.readAll())
  437. for uniqueID,u_tab in pairs(temp_tab) do
  438. for item_name,n_tab in pairs(u_tab) do
  439. for index,val in pairs(n_tab) do
  440. temp_tab[uniqueID][item_name][index]["name"] = item_name
  441. local id,dam = uniqueToID(uniqueID)
  442. temp_tab[uniqueID][item_name][index]["dmg"] = dam
  443. temp_tab[uniqueID][item_name][index]["id"] = id
  444. end
  445. end
  446. end
  447.  
  448. global_iList_IDs = deepcopy(temp_tab)
  449. file.close()
  450. else
  451. local cred_temp = {}
  452. cred_temp["name"] = money_name
  453. cred_temp["id"] = 1
  454. cred_temp["dmg"] = 1
  455. cred_temp["maxSize"] = 1000000000
  456. cred_temp["ench"] = {}
  457. local tt = {}
  458. tt[1] = cred_temp
  459. local tt2 = {}
  460. tt2[money_name] = tt
  461. global_iList_IDs[IDtoUnique(1,1)] = deepcopy(tt2)
  462. end
  463. --Load Trade Data:
  464. for i=2,#validAddress do
  465. rednet.send(validAddress[i],"DataDump")
  466. while true do
  467. local ID,message = rednet.receive(2)
  468. if ID ~= validAddress[i] then
  469. -- bad computer sending data
  470. ERR("loadStuff","Wrong computer sent message. ID: "..tostring(ID).." message:",message,true)
  471. elseif message == "DataDump Finished" then break
  472. else
  473. local tab = textutils.unserialize(message)
  474. if tab.trades ~= nil then
  475.  
  476. --Save trades to database
  477. --[[
  478. local found,index = compareEnchantments(global_iList_IDs,item)
  479. if not found then ERR("loadStuff","item not found in global list! name:",item.name,true) end
  480. local uniqueID = IDtoUnique(item.id,item.dmg)
  481. local tab1 = {}
  482. local tab2 = {}
  483. local tab3 = {}
  484. tab1[tab.name] = tab["trades"]
  485. tab2[index] = tab1
  486. tab3[item.name] = tab2
  487. if global_iList_trades[uniqueID] == nil then
  488. global_iList_trades[uniqueID] = deepcopy(tab3)
  489. elseif global_iList_trades[uniqueID][item.name] == nil then
  490. global_iList_trades[uniqueID][item.name] = deepcopy(tab2)
  491. elseif global_iList_trades[uniqueID][item.name][index] == nil then
  492. global_iList_trades[uniqueID][item.name][index] = deepcopy(tab1)
  493. elseif global_iList_trades[uniqueID][item.name][index][tab.name] == nil then
  494. global_iList_trades[uniqueID][item.name][index][tab.name] = deepcopy(player_iList["trades"])
  495. end
  496. ]]--
  497. if global_iList_trades[tab.name] ~= nil then ERR("loadStuff","Name already exists in database (save network has duplicates). Player:",tab.name,true) end
  498. global_iList_trades[tab.name] = deepcopy(tab.trades)
  499. end
  500. end
  501. end
  502. end
  503. local file = fs.open("itempanel.csv","r")
  504. global_alt_names = textutils.unserialize(file.readAll())
  505. file.close()
  506. end
  507.  
  508.  
  509.  
  510.  
  511. function save()
  512. local temp_tab = deepcopy(global_iList_IDs)
  513. local file = fs.open("Items.data","w")
  514. local iter = 0
  515. for uniqueID,u_tab in pairs(temp_tab) do
  516. for item_name,n_tab in pairs(u_tab) do
  517. for index,val in pairs(n_tab) do
  518. iter = iter+1
  519. temp_tab[uniqueID][item_name][index]["name"] = nil
  520. temp_tab[uniqueID][item_name][index]["dmg"] = nil
  521. temp_tab[uniqueID][item_name][index]["id"] = nil
  522. end
  523. end
  524. end
  525. file.write(textutils.serialize(temp_tab))
  526. file.close()
  527. end
  528.  
  529. function save_player(name,...)
  530. if type(name) ~= "string" then
  531. error("[save_player] arg is not a string",2)
  532. end
  533. if name == "nilPlayer" then
  534. local function getLine() error("Line",3) end
  535. ERR("save_player","Attempted to save 'nilPlayer'")
  536. ERR("save_player","At the line",pcall(getLine))
  537. end
  538. if not fs.exists("PlayerData") and localSaves then
  539. fs.makeDir("PlayerData")
  540. end
  541. local temp_tab = {}
  542. if arg[1] == nil then
  543. temp_tab = deepcopy(player_iList)
  544. else
  545. temp_tab = deepcopy(arg[1])
  546. end
  547. --Convert from program table to one with zero redundancy. (get rid of ID,name, and rawname)
  548. -- seems setting the value to nil should do the trick
  549.  
  550. for uniqueID,u_tab in pairs(temp_tab["items"]) do
  551. for item_name,n_tab in pairs(u_tab) do
  552. for index,val in pairs(n_tab) do
  553. temp_tab["items"][uniqueID][item_name][index]["name"] = nil
  554. temp_tab["items"][uniqueID][item_name][index]["dmg"] = nil
  555. temp_tab["items"][uniqueID][item_name][index]["rawName"] = nil
  556. temp_tab["items"][uniqueID][item_name][index]["id"] = nil
  557. temp_tab["items"][uniqueID][item_name][index]["maxSize"] = nil
  558. end
  559. end
  560. end
  561. if temp_tab["trades"] ~= nil then global_iList_trades[name] = deepcopy(temp_tab["trades"]) end
  562. --save to file
  563.  
  564. if localSaves then
  565. --local str = string.gsub(name,"%s+","_")
  566. local str = name
  567. local file = fs.open("PlayerData/"..str,"w")
  568. file.write(textutils.serialize(temp_tab))
  569. file.close()
  570. else
  571. local function one()
  572. rednet.send(validAddress[2],"Save "..textutils.serialize(temp_tab))
  573. sleep(.1)
  574. end
  575. local function two()
  576. local id,mess = rednet.receive()
  577. if mess == "Saved" then return
  578. elseif mess == "NoSpace" then
  579. error("Not enough space to save!") --todo, remove
  580. localSave = true
  581. save_player(name,temp_tab)
  582. end
  583. end
  584. parallel.waitForAny(one,two)
  585. end
  586. sleep(0) -- needed to slow down multiple quick saves
  587. end
  588.  
  589. function load_player(name,...)
  590. if name == nil and arg[1] then error("called load_player with nil name",2) end
  591. if name == nil or name == "" then
  592. player_iList["name"] = "nilPlayer"
  593. player_iList["items"] = {}
  594. player_iList["trades"] = {}
  595. player_iList[money_name] = default_credits
  596. return nil
  597. end
  598. --local str = string.gsub(name,"%s+","_")
  599. local temp_tab = {}
  600. local found_player = false
  601. if localSaves then
  602. local str = name
  603. if fs.exists("PlayerData") and fs.exists("PlayerData/"..str) then
  604. --fix table format.
  605. local file = fs.open("PlayerData/"..str,"r")
  606. temp_tab = textutils.unserialize(file.readAll())
  607. file.close()
  608. found_player = true
  609. end
  610. else
  611. local function one()
  612. rednet.broadcast("Load "..name)
  613. sleep(1)
  614. end
  615. local function two()
  616. local ID,message = rednet.receive()
  617. if ID ~= nil then
  618. found_player = true
  619. temp_tab = textutils.unserialize(message)
  620. end
  621. end
  622. parallel.waitForAny(two,one)
  623. if temp_tab == nil and found_player then error("Found player but did not recieve table") end
  624. end
  625. if not found_player then
  626. player_iList["name"] = name
  627. player_iList["items"] = {}
  628. player_iList["trades"] = {}
  629. player_iList[money_name] = default_credits
  630. if arg[1] ~= nil then error("trying to load a player who was not found "..name) end --todo: think about
  631. return
  632. end
  633. for uniqueID,u_tab in pairs(temp_tab["items"]) do
  634. for item_name,n_tab in pairs(u_tab) do
  635. for index,val in pairs(n_tab) do
  636. temp_tab["items"][uniqueID][item_name][index]["name"] = item_name
  637. local id,dam = uniqueToID(uniqueID)
  638. temp_tab["items"][uniqueID][item_name][index]["dmg"] = dam
  639. temp_tab["items"][uniqueID][item_name][index]["id"] = id
  640. local temp_itemTab = getItemTable(temp_tab["items"][uniqueID][item_name][index])
  641. --temp_tab["items"][uniqueID][item_name][index]["rawName"] = temp_itemTab.rawName
  642. temp_tab["items"][uniqueID][item_name][index]["maxSize"] = temp_itemTab.maxSize
  643. end
  644. end
  645. end
  646. if not arg[1] then
  647. player_iList = deepcopy(temp_tab)
  648. else
  649. return temp_tab
  650. end
  651. end
  652.  
  653. --[[
  654. Utility
  655. ]]--
  656.  
  657. -- will hunt global_iList_IDs for a item
  658. -- takes in a partial item table (only ID,Dam,name)
  659. function getItemTable(partial_itemTab)
  660. local found,tab = compareEnchantments(global_iList_IDs,partial_itemTab,true)
  661. if not found then
  662. --throw a error? could easily check elsewhere
  663. else
  664. return tab
  665. end
  666. end
  667.  
  668. --Converts a unique identifer to an item/damage value
  669. function uniqueToID(unique,...)
  670. if type(unique) ~= "number" or unique == nil then
  671. if unique == nil then error("[uniqueToID] nil passed to function!",2) end
  672. error("[uniqueToID] invalid type passed to function! "..type(unique),2)
  673. end
  674. local Dam = math.floor(unique/2^15)
  675. local ID = unique%(2^15)
  676. if arg[1] then return ID..":"..Dam else return ID,Dam end
  677. end
  678.  
  679. -- converts a ID,dam to a unique number
  680. function IDtoUnique(ID,...)
  681. if type(ID) == "string" then
  682. if string.match(ID,"%d+:%d+") then
  683. return tonumber(string.match(ID,"(%d+):%d+")) +(2^15)*tonumber(string.match(ID,"%d+:(%d+)"))
  684. else
  685. error("[IDtoUnique] Invalid string passed to function. "..ID,2)
  686. end
  687. elseif ID == nil or arg[1] == nil then
  688. term.clear()
  689. print(ID)
  690. print(arg[1])
  691. error("[IDtoUnique] Invalid arguments passed to function.",2)
  692. else
  693. return ID+arg[1]*2^15
  694. end
  695. end
  696. --shortens a string to str..".." if its longer than len, else does nothing
  697. function ss(str,len)
  698. if str == nil then
  699. ERR("ss","str is nil")
  700. return "nil"
  701. end
  702. if string.len(str) > len then
  703. return string.sub(item_name,0,len-3)..".."
  704. else
  705. return str
  706. end
  707. end
  708. -- Makes a copy of a table
  709. function deepcopy(orig)
  710. local orig_type = type(orig)
  711. local copy
  712. if orig_type == 'table' then
  713. copy = {}
  714. for orig_key, orig_value in next, orig, nil do
  715. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  716. end
  717. setmetatable(copy, deepcopy(getmetatable(orig)))
  718. else -- number, string, boolean, etc
  719. copy = orig
  720. end
  721. return copy
  722. end
  723.  
  724.  
  725.  
  726. --don't change the current player if dontUpdate
  727. function modifyCurrentPlayer(newPlayer)
  728. while dontUpdate do
  729. sleep(0)
  730. end
  731. --if currentPlayer ~= nil then save_player(currentPlayer) end --Removed becuase it shouldnt ever be nessassary. Changes are saved instantly
  732. currentPlayer = newPlayer
  733. load_player(currentPlayer)
  734. end
  735. -- Will update the currentPlayer Variable based on the player at the location of the PIM when it is stepped on.
  736. function updateCurrentPlayer()
  737. local function getPlayer()
  738. local player_list = sensor.names()
  739. if player_list[1] == nil then return nil end
  740. if #player_list == 0 then return nil end
  741. local player_name = player_list[1]
  742. if #player_list > 1 then
  743. for i=1,#player_list do
  744. if math.floor(sensor.location(player_list[i])["position"]["x"]) == PIM_xyz["x"]
  745. and math.floor(sensor.location(player_list[i])["position"]["y"]) == PIM_xyz["y"]
  746. and math.floor(sensor.location(player_list[i])["position"]["z"]) == PIM_xyz["z"] then
  747. player_name = player_list[i]
  748. break
  749. end
  750. end
  751. end
  752. return player_name
  753. end
  754. local onboot = getPlayer()
  755. if onboot ~= nil then
  756. modifyCurrentPlayer(onboot)
  757. os.queueEvent("updatePlayer")
  758. --load_player(currentPlayer)
  759. end
  760. while true do
  761. local event = os.pullEvent()
  762. if event == "player_on" then
  763. modifyCurrentPlayer(getPlayer())
  764. os.queueEvent("updatePlayer")
  765. --if currentPlayer ~= nil then load_player(currentPlayer) end
  766. elseif event == "player_off" then
  767. --if currentPlayer ~= nil then ae.suckAll() end
  768. modifyCurrentPlayer(nil)
  769. os.queueEvent("updatePlayer")
  770. end
  771. end
  772. end
  773.  
  774.  
  775. -- will interate over a item table of the format table[uniqueID][name][#] = item_table and return the next item_table and enchantment index [#]
  776. -- do not call this with a empty table, or you will crash.
  777. function tableIter(tabl)
  778.  
  779. if type(tabl) ~= "table" or tabl == nil then
  780. term.clear()
  781. print("caught it")
  782. return function () return nil,nil end
  783. end
  784. local done = false
  785. local tab = tabl --deepcopy(tabl)
  786. local uniqueID_key = next(tab,nil)
  787. local u,n,e
  788. local name_key
  789. local ench_key
  790.  
  791. --Some odd formatting to prevent crashing:
  792. if type(tabl) ~= "table" then error("[tableIter] arg1 is not a table? "..type(tabl),2) end
  793. if uniqueID_key == nil then done=true else
  794. if type(tab[uniqueID_key]) ~= "table" then error("[tableIter] arg1 is not a table? "..type(tabl),2) end
  795. name_key = next(tab[uniqueID_key],nil)
  796. if name_key == nil then done=true else
  797. if type(tab[uniqueID_key][name_key]) ~= "table" then error("[tableIter] arg1 is not a table? "..type(tabl),2) end
  798. ench_key = next(tab[uniqueID_key][name_key],nil)
  799. if ench_key == nil then done=true end
  800. end
  801. end
  802.  
  803. return function ()
  804. if done then return nil,nil end --nil,xxx
  805. local ret = tab[uniqueID_key][name_key][ench_key]
  806. local ret_ench_key = ench_key
  807. ench_key,e = next(tab[uniqueID_key][name_key],ench_key)
  808. while ench_key == nil do
  809. name_key,n = next(tab[uniqueID_key],name_key)
  810. while name_key == nil do
  811. uniqueID_key,u = next(tab,uniqueID_key)
  812. if uniqueID_key == nil then
  813. done = true
  814. return ret,ret_ench_key
  815. end
  816. name_key,n = next(tab[uniqueID_key],name_key)
  817. end
  818. ench_key,e = next(tab[uniqueID_key][name_key],ench_key)
  819. end
  820. return ret,ret_ench_key
  821. end
  822. end
  823.  
  824. --stri = search string
  825. --list = ?
  826. -- ... = ?
  827. --returns list[i]=item_table,total found. where list is sorted by the difference in length of str and the item_name/ID
  828. function search(stri,list,...)
  829. local str = string.lower(stri)
  830. local found_list = {}
  831. local iter = 0
  832. local search_list = list --TODO: try without deepcopy()
  833. local function addItem(ind1,inqid,ky,val)
  834. if val.ench ~= nil and #val.ench>0 then ind1 = ind1 +1 end --give priority to non enchanted items, could be improved.
  835. local l_temp = found_list[ind1]
  836. local l_temp1 = {}
  837. local l_temp2 = {}
  838. local l_temp3 = {}
  839.  
  840. l_temp3[ky] = val
  841. l_temp2[val.name] = l_temp3
  842. --l_temp1[unqid] = l_temp2
  843. if found_list[ind1] == nil then
  844. l_temp = {}
  845. l_temp[inqid] = l_temp2
  846. found_list[ind1] = l_temp
  847. elseif found_list[ind1][inqid] == nil then
  848. found_list[ind1][inqid] = l_temp2
  849. elseif found_list[ind1][inqid][val.name] == nil then
  850. found_list[ind1][inqid][val.name] = l_temp3
  851. else
  852. local l_temp4 = found_list[ind1][inqid][val.name]
  853. l_temp4[ky] = val
  854. found_list[ind1][inqid][val.name] = deepcopy(l_temp4)
  855. end
  856. iter = iter+1
  857. end
  858. if search_list ~= nil then
  859. if string.match(str,":") then --ID:Dam
  860. for item,key in tableIter(search_list) do
  861. local uniqueID = IDtoUnique(item.id,item.dmg)
  862. local k = item.id
  863. local n = item.dmg
  864. if string.match(k..":"..n,str) then
  865. addItem((string.len(k..":"..n)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  866. end
  867. end
  868. elseif string.match(str,"%S") or string.match(str,"%s") then -- char
  869. for item,key in tableIter(search_list) do
  870. local uniqueID = IDtoUnique(item.id,item.dmg)
  871. if string.match(string.lower(fixNames(item)),str) then
  872. addItem((string.len(item.name)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  873. end
  874. end
  875. else --just ID
  876. for item,key in tableIter(search_list) do
  877. local uniqueID = IDtoUnique(item.id,item.dmg)
  878. local k = item.id
  879. if string.match(k,str) then
  880. addItem((string.len(k)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  881. end
  882. end
  883. end
  884. --[[
  885. for item,key in tableIter(search_list) do
  886. local uniqueID = IDtoUnique(item.id,item.dmg)
  887. local k = item.id
  888. local n = item.dmg
  889. if string.match(string.lower(item.name),str) then
  890. addItem((string.len(item.name)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  891. elseif string.match(k,str) then
  892. addItem((string.len(k)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  893. elseif string.match(k..":"..n,str) and search_list[uniqueID][item.name][key] ~= nil then
  894. addItem((string.len(k..":"..n)-#str)+1,uniqueID,key,search_list[uniqueID][item.name][key])
  895. end
  896. end
  897. ]]--
  898. end
  899. if #arg > 0 and arg[1] then --TODO
  900. for i=1,20 do
  901. if found_list[i] ~= nil then
  902. for k,v in pairs(found_list[i]) do
  903. return k,iter
  904. end
  905. end
  906. end
  907. --[[
  908. for k,v in pairs(found_list) do
  909. for n,m in pairs(v) do
  910. return n,iter
  911. end
  912. end
  913. ]]--
  914. return false,iter
  915. else
  916. return found_list,iter
  917. end
  918. end
  919.  
  920. function draw1(list,total)
  921. local maxID = 12
  922. for l=0,40 do
  923. term.setCursorPos(1,9+l)
  924. term.clearLine()
  925. end
  926. term.setCursorPos(1,1)
  927. term.write("Total: "..total.." ")
  928. if total < 1 then
  929. sleep(0)
  930. else
  931. local iter =0
  932. for i=1,40 do
  933. if list[i] ~= nil then
  934. for items in tableIter(list[i]) do
  935. term.setCursorPos(1,9+iter)
  936. term.write("("..items.id..":"..items.dmg..")")
  937. term.setCursorPos(maxID+1,9+iter)
  938. term.write(fixNames(items))
  939. iter=iter+1
  940. end
  941. end
  942. if iter > 40 then break end
  943. end
  944. end
  945. end
  946.  
  947. function cleanInput(curr_message,...)
  948. local event,param1,param2,param3,param4,param5
  949. local function char()
  950. event,param1,param2,param3,param4,param5 = os.pullEventRaw("char")
  951.  
  952. end
  953. local function key()
  954. event,param1,param2,param3,param4,param5 = os.pullEventRaw("key")
  955. sleep(0) -- needed to make 'char' events win over 'key'
  956. end
  957. if arg[1] then term.write(curr_message) end
  958. parallel.waitForAny(key,char)
  959. return event,param1,param2,param3,param4,param5
  960. end
  961.  
  962. function getCleanInputAt(x,y,...)
  963. local maxLen = 40
  964. local message = ""
  965. local display = true
  966. if type(arg[1]) == "boolean" then display = arg[1]
  967. elseif arg[1] ~= nil and type(arg[1]) ~= "string" then maxLen = arg[1] end
  968. if arg[2] ~= nil and type(arg[2]) == "string" then message = arg[2] end
  969.  
  970. while true do
  971. if display then
  972. term.setCursorPos(x,y)
  973. for i=1,maxLen do
  974. term.write(" ")
  975. end
  976. term.setCursorPos(x,y)
  977. end
  978. local event,p1,p2 = cleanInput(message,display)
  979. if event == "char" then
  980. if string.len(message) < maxLen then
  981. if display then term.write(p1) end
  982. message = message..p1
  983. os.queueEvent("typing",message,string.len(message))
  984. end
  985. elseif event == "key" then
  986. if p1 == 14 then --backspace
  987. message = string.sub(message,0,string.len(message)-1)
  988. os.queueEvent("typing",message,string.len(message))
  989. elseif p1 == 28 then -- enter
  990. break
  991. end
  992. end
  993. end
  994. return message
  995. end
  996.  
  997. --for now just use search as searchFunc
  998. --drawFunc needs args in format (Returnedlist,total found)
  999. -- arg[1] == last string to search
  1000. function textSearch(x,y,drawFunc,searchFunc,...)
  1001. local notDone = true
  1002. local final = ""
  1003. local itemList = {}
  1004. local totalFound = 0
  1005. local click = 1
  1006. if arg[1] then error("is used") end --TODO
  1007. local function messageListener()
  1008. drawFunc(itemList,0,nil)
  1009. while notDone do
  1010. local event, message, len = os.pullEventRaw("typing")
  1011. final = message
  1012. if message ~= nil then
  1013. if len>0 then
  1014. itemList,totalFound = searchFunc(message,global_iList_IDs)
  1015. drawFunc(itemList,totalFound,message)
  1016. else
  1017. totalFound = 0
  1018. itemList = {}
  1019. drawFunc(itemList,0)
  1020. end
  1021. end
  1022. end
  1023. end
  1024. local function messageListener()
  1025. drawFunc(itemList,0,nil)
  1026. local event, message, len
  1027. local function getEvent()
  1028. event, message, len = os.pullEventRaw("typing")
  1029. end
  1030. local function getEvent2()
  1031. local event2 = os.pullEventRaw("updateNotDone")
  1032. sleep(0.1)
  1033. end
  1034. local function parallelSearch()
  1035. final = message
  1036. if message ~= nil then
  1037. if len>0 then
  1038. itemList,totalFound = searchFunc(message,global_iList_IDs)
  1039. drawFunc(itemList,totalFound,message)
  1040. else
  1041. totalFound = 0
  1042. itemList = {}
  1043. drawFunc(itemList,0)
  1044. end
  1045. end
  1046. while true do sleep(10000) end -- hang until next typing event.
  1047. end
  1048. while notDone do
  1049. parallel.waitForAny(getEvent,parallelSearch,getEvent2)
  1050. end
  1051. end
  1052. local function getText()
  1053. getCleanInputAt(x,y,false)
  1054. notDone = false
  1055. os.queueEvent("updateNotDone")
  1056. end
  1057. local function getClick()
  1058. while true do
  1059. local event,key,xpos,ypos = os.pullEventRaw("mouse_click")
  1060. if ypos> 5 then
  1061. if totalFound >= ypos-5 then
  1062. click = ypos-5
  1063. break
  1064. end
  1065. elseif ypos == 1 then
  1066. local valid,sel = parse_header(xpos,ypos)
  1067. if valid then
  1068. header_current = sel
  1069. os.queueEvent("updateHeader")
  1070. break
  1071. end
  1072. end
  1073. end
  1074. end
  1075. parallel.waitForAny(messageListener,getText,getClick)
  1076. for i=1,100 do
  1077. for item in tableIter(itemList[i]) do
  1078. click = click - 1
  1079. if click <= 0 then
  1080. return item,totalFound
  1081. end
  1082. end
  1083. end
  1084. end
  1085.  
  1086. function testSearch()
  1087. print("start search")
  1088. while true do
  1089. local func = draw1
  1090. textSearch(1,7,func,search)
  1091. sleep(2)
  1092. end
  1093. end
  1094. --[[
  1095. Program
  1096. ]]--
  1097.  
  1098.  
  1099.  
  1100.  
  1101. -- return true if 'item' exists in tab, false if not.
  1102. -- also handles (item,item) compairson.
  1103. --returns boolean,index#(if tab is a standard item list -> table[uniqueID][name][index#] = item table)
  1104. -- if arg[1] then return item table in format boolean,item table/nil if item is not found.
  1105. function compareEnchantments(tab,item,...)
  1106. local unique = IDtoUnique(item.id,item.dmg)
  1107. if tab[unique] == nil then --either bad format or tab is just a item.
  1108. if tab.name ~= nil then --item
  1109. if item.ench == nil or #item.ench == 0 then
  1110. if tab.ench == nil or #tab.ench == 0 then
  1111. return true,nil
  1112. end
  1113. elseif tab.ench == nil or #tab.ench == 0 then
  1114. --nothing, just a check to prevent errors in else
  1115. else
  1116. local match = true
  1117. if #item.ench == #item_tab.ench then
  1118. for key,ench in pairs(item.ench) do
  1119. local pass = false
  1120. for key2,ench2 in pairs(tab.ench) do
  1121. if ench == ench2 then
  1122. pass = true
  1123. break
  1124. end
  1125. end
  1126. if not pass then
  1127. match = false
  1128. break
  1129. end
  1130. end
  1131. if match then return true,nil end
  1132. end
  1133. end
  1134. return false,nil
  1135. else
  1136. --if tab[unique][item.name] == nil then
  1137. error("[compareEnchantments] Item doesn't exist, how do you expect me to check it?",2)
  1138. end
  1139. end
  1140. if tab == nil or tab[unique] == nil or tab[unique][item.name] == nil then
  1141. ERR("compareEnchantments","nil table found")
  1142. ERR("compareEnchantments","item name:",fixNames(item),true)
  1143. error("function is going to crash (nil table)",3)
  1144. end
  1145. for index,item_tab in pairs(tab[unique][item.name]) do
  1146. if item.ench == nil or #item.ench == 0 then
  1147. if item_tab.ench == nil or #item_tab.ench == 0 then
  1148. if arg[1] then return true,deepcopy(item_tab) else return true,index end
  1149. end
  1150. elseif item_tab.ench == nil or #item_tab.ench == 0 then
  1151. --nothing, just a check to prevent errors in else
  1152. else
  1153. local match = true
  1154. if #item.ench == #item_tab.ench then
  1155. for key,ench in pairs(item.ench) do
  1156. local pass = false
  1157. for key2,ench2 in pairs(item_tab.ench) do
  1158. if ench == ench2 then
  1159. pass = true
  1160. break
  1161. end
  1162. end
  1163. if not pass then
  1164. match = false
  1165. break
  1166. end
  1167. end
  1168. if match then
  1169. if arg[1] then return true,deepcopy(item_tab) else return true,index end
  1170. end
  1171. end
  1172. end
  1173. end
  1174. return false,nil
  1175. end
  1176.  
  1177. -- Read the player inventory. Learns item names/IDs/enchantments and creates a table of the players inventory
  1178. function readInventory()
  1179. if currentPlayer == nil then
  1180. ERR("readInventory","there is no current player yet this function was called.",false)
  1181. error("IM THE BITCH WHO CALLED THIS FUNCTION",2)
  1182. return
  1183. end
  1184. dontUpdate = true
  1185. local inv = PIM.getAllStacks()
  1186. if type(inv) ~= "table" then --glitch
  1187. dontUpdate = false
  1188. return
  1189. end
  1190. local need_save = false
  1191. local debug_count = 0 --todo: cleanup
  1192. player_iList_inv = {} -- clear inventory
  1193. for k,v in pairs(inv) do
  1194. if v.ench ~= nil and #v["ench"] == 0 then v["ench"] = deepcopy(v.ench) end -- needed for serialization
  1195. --playerslot = k
  1196. if v.electric == nil then --electric items can't be extracted. (problem with openP)
  1197. local temp_tab = {}
  1198. temp_tab.name = v.name
  1199. temp_tab.id = v.id
  1200. temp_tab.dmg = v.dmg
  1201. --temp_tab.rawName = v.rawName
  1202. temp_tab.maxSize = v.maxSize
  1203. temp_tab.ench = v.ench
  1204. temp_tab.qty = v.qty
  1205. -- log player inventory.
  1206. local uniqueID = IDtoUnique(v.id,v.dmg)
  1207.  
  1208. if k<37 then -- 37-40 are armor slots
  1209. if player_iList_inv[uniqueID] == nil then
  1210. local temp1 = {}
  1211. local temp2 = {}
  1212. table.insert(temp1,temp_tab)
  1213. temp2[v.name] = temp1
  1214. player_iList_inv[uniqueID] = deepcopy(temp2)
  1215. elseif player_iList_inv[uniqueID][v.name] == nil then
  1216. --local temp1 = {}
  1217. --table.insert(temp1,temp_tab)
  1218. player_iList_inv[uniqueID][v.name] = {}
  1219. player_iList_inv[uniqueID][v.name][1] = deepcopy(temp_tab)
  1220. else
  1221. local check,index = compareEnchantments(player_iList_inv,temp_tab)
  1222. if check then -- item already found
  1223. player_iList_inv[uniqueID][v.name][index].qty = player_iList_inv[uniqueID][v.name][index].qty+v.qty
  1224. else
  1225. table.insert(player_iList_inv[uniqueID][v.name],deepcopy(temp_tab))
  1226. end
  1227. end
  1228. end
  1229. temp_tab.qty = nil
  1230.  
  1231. if global_iList_IDs[uniqueID] == nil then
  1232. local temp1 = {}
  1233. local temp2 = {}
  1234. table.insert(temp1,temp_tab)
  1235. temp2[v.name] = temp1
  1236. global_iList_IDs[uniqueID] = deepcopy(temp2)
  1237. need_save = true
  1238.  
  1239. elseif global_iList_IDs[uniqueID][v.name] == nil then
  1240. --local temp1 = {}
  1241. --table.insert(temp1,temp_tab)
  1242. global_iList_IDs[uniqueID][v.name] = {}
  1243. global_iList_IDs[uniqueID][v.name][1] = deepcopy(temp_tab)
  1244. need_save = true
  1245.  
  1246. else
  1247. local check,index = compareEnchantments(global_iList_IDs,temp_tab)
  1248. if not check then -- item not found
  1249. table.insert(global_iList_IDs[uniqueID][v.name],deepcopy(temp_tab))
  1250. need_save = true
  1251. elseif global_iList_IDs[uniqueID][v.name][index]["maxSize"] == nil then
  1252. global_iList_IDs[uniqueID][v.name][index]["maxSize"] = temp_tab.maxSize
  1253. need_save = true
  1254. end
  1255. end
  1256. end
  1257. end
  1258. if need_save then save() end
  1259. --term.setCursorPos(1,1)
  1260. --print(debug_count.." New") --todo: cleanup
  1261. dontUpdate = false
  1262. end
  1263. --[[
  1264. Display
  1265. ]]--
  1266.  
  1267. --Changes a list from ilist[ID][Dam] to ilist[#] = {}
  1268. function index_list(ilist)
  1269. local ret_list = {}
  1270. for val in tableIter(ilist) do
  1271. if val.qty ~= 0 then
  1272. local temp = val
  1273. temp["IDdam"] = val.id..":"..val.dmg
  1274. table.insert(ret_list,temp)
  1275. end
  1276. end
  1277. return deepcopy(ret_list)
  1278. end
  1279.  
  1280. function getShortEnch(ench)
  1281. local ret = ""
  1282. for word in string.gmatch(ench,"%S+") do
  1283. local firstChar=string.sub(word,1,1)
  1284. if firstChar == "I" or firstChar == "V" then
  1285. return ret..":"..word
  1286. elseif word == "Power" then
  1287. ret = "Po"
  1288. elseif word == "Punch" then
  1289. ret = "Pu"
  1290. else
  1291. ret = ret..firstChar
  1292. end
  1293. end
  1294. error("you should never get here!")
  1295. end
  1296. --Displays the players current inventory and allows for items to be deposited into the network.
  1297. function draw_deposit(index)
  1298. local player_ilist_temp = index_list(player_iList_inv)
  1299. if #player_ilist_temp == 0 then
  1300. draw_header("deposit")
  1301. local tc,tt = Draw.emptyScreen(term,51,16)
  1302. Draw.tc(tc,1,1,colors.lightGray,51,16)
  1303. Draw.tt(tt,3,7," You have no items in your inventory to deposit",colors.black)
  1304. Draw.tt(tt,3,8," try bringing some items next time!",colors.black)
  1305. Draw.draw(term,tc,1,4,2^15,tt)
  1306. return {},2
  1307. else
  1308. --[[
  1309. Setting up item list
  1310. --]]
  1311. local item_c,item_t = Draw.emptyScreen(term,50,#player_ilist_temp*2+16)--+2)
  1312.  
  1313. local switch_bg = true
  1314. if index%2 == 1 then
  1315. -- switch_bg = false
  1316. end
  1317. for i=1,#player_ilist_temp do
  1318. local bg_
  1319. if switch_bg then
  1320. bg_ = colors.blue
  1321. switch_bg = false
  1322. else
  1323. bg_ = colors.lightBlue
  1324. switch_bg = true
  1325. end
  1326. local item_name = fixNames(player_ilist_temp[i])
  1327. --item_name = "12345678901234567890123456789012345678901234567890"
  1328. if string.len(item_name) > 43 then
  1329. item_name = string.sub(item_name,0,40)..".."
  1330. end
  1331. Draw.tc(item_c,1,2*i-1,bg_,50,2*i)
  1332. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.yellow)..item_name.."&"..Draw.getHexOf(colors.red).." x"..player_ilist_temp[i].qty)
  1333. local ench_str = ""
  1334. if player_ilist_temp[i].ench ~= nil and #player_ilist_temp[i].ench >0 then
  1335. ench_str = "&"..Draw.getHexOf(colors.red).."Ench: "
  1336. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1337. for k=1,#player_ilist_temp[i].ench do
  1338. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(player_ilist_temp[i].ench[k]).." "
  1339. end
  1340. end
  1341. Draw.tt(item_t,1,2*i," &"..Draw.getHexOf(colors.brown).."("..player_ilist_temp[i].IDdam..") "..ench_str)
  1342. Draw.tt(item_t,41,2*i," &"..Draw.getHexOf(colors.white).." Deposit ")
  1343. Draw.tc(item_c,41,2*i,colors.lime,50,2*i)
  1344. end
  1345. --[[
  1346. Setting up scroll bar
  1347. --]]
  1348. local bar_c,bar_t = Draw.emptyScreen(term,1,16)
  1349. Draw.tc(bar_c,1,1,colors.gray,1,16)
  1350. Draw.tc(bar_c,1,1,colors.lightGray)
  1351. Draw.tt(bar_t,1,1,"^")
  1352. Draw.tc(bar_c,1,16,colors.lightGray)
  1353. Draw.tt(bar_t,1,16,"v")
  1354.  
  1355. local scroll_pos = 2
  1356. if #player_ilist_temp > 8 then
  1357. scroll_pos = math.floor(2+13*((index)/(#player_ilist_temp-8)))
  1358. if scroll_pos > 15 then scroll_pos = 15 end
  1359. end
  1360.  
  1361. Draw.tc(bar_c,1,scroll_pos,colors.purple)
  1362. Draw.draw(term,bar_c,1,4,2^15,bar_t)
  1363. local item_c_f = {}
  1364. local item_t_f = {}
  1365.  
  1366. for i=(index*2+1),#item_c do --player_ilist_temp*2 do
  1367. table.insert(item_c_f,item_c[i])
  1368. table.insert(item_t_f,item_t[i])
  1369. --item_c_f[i-(index*2+1)] = item_c[i]
  1370. --item_t_f[i-(index*2+1)] = item_t[i]
  1371. end
  1372. Draw.draw(term,item_c_f,2,4,2^15,item_t_f)
  1373. draw_header("deposit")
  1374. return player_ilist_temp,scroll_pos
  1375. end
  1376. end
  1377.  
  1378. --takes in a table for that item and transfers amount to the ae network
  1379. function deposit(item,amount)
  1380.  
  1381. --AE:
  1382. --insertItem(slot...,amount...,direction...)
  1383. --extractItem(stack...,direction...)
  1384. local ID = tonumber(string.match(item.IDdam,"(%d+):%d+"))
  1385. local dam = tonumber(string.match(item.IDdam,"%d+:(%d+)"))
  1386. local amount_dep = 0
  1387. please_wait()
  1388. --scan player inventory for items
  1389. dontUpdate = true
  1390. local inv = PIM.getAllStacks()
  1391. function depositItems()
  1392. while amount_dep ~= amount do
  1393. for slot,v in pairs(inv) do
  1394. if v.name == item.name and v.id == ID and v.dmg == dam then -- surely this will locate the item.
  1395. if (amount-amount_dep) > v.maxSize or (amount-amount_dep) > v.qty then
  1396. --PIM.pullItem(slot,v.qty)
  1397. PIM.pushItem(slot,v.qty)
  1398. amount_dep = amount_dep + v.qty
  1399. else
  1400. --PIM.pullItem(slot,(amount-amount_dep))
  1401. PIM.pushItem(slot,(amount-amount_dep))
  1402. amount_dep = amount
  1403. end
  1404. end
  1405. if amount_dep == amount then break end
  1406. end
  1407. --gets here after full inventory scan.
  1408. if amount_dep < 0 or amount-amount_dep < 0 then
  1409. ERR("deposit"," amount_dep less than zero!",amount_dep,true)
  1410. break
  1411. elseif amount-amount_dep>0 then
  1412. userInput("not enough items were found, only "..(amount_dep).." were transfered")
  1413. break
  1414. end
  1415. end
  1416. end
  1417. function watchPlayerExit()
  1418. local event = os.pullEvent("player_off")
  1419. end
  1420. parallel.waitForAny(depositItems,watchPlayerExit)
  1421. if ae.suckAll() ~= amount_dep then
  1422. ERR("deposit","mismatch in item intake -> items taken from inventory != items moved to AE network")
  1423. ERR("deposit"," -> Item:",fixNames(item),true)
  1424. ERR("deposit"," -> Amount:",amount,true)
  1425. end
  1426. dontUpdate = false
  1427. return amount-amount_dep
  1428. end
  1429.  
  1430. function display_deposit()
  1431. local index = 0
  1432. local amount = 0
  1433. if currentPlayer ~= nil then readInventory() end
  1434. while currentPlayer ~= nil and header_current == header_sel[1] do
  1435. local list_temp,scroll_pos = draw_deposit(index)
  1436. while true do
  1437. local event,key,xpos,ypos = os.pullEvent()
  1438. if (event == "mouse_click") then
  1439. if ypos>3 then
  1440. if (xpos == 1 and #list_temp > 8) then --Scroll
  1441. if ypos < scroll_pos+3 and index > 0 then
  1442. index = index - 1
  1443. elseif ypos > scroll_pos+3 and index < #list_temp -8 then
  1444. index = index +1
  1445. end
  1446. break
  1447. elseif xpos>40 and ypos%2 == 1 and (index+(ypos-3)/2) <= #list_temp then
  1448. amount = math.abs(userInput("How much '"..fixNames(list_temp[index+(ypos-3)/2]).."' would you like to deposit?","number",list_temp[index+(ypos-3)/2].qty))
  1449. if amount>list_temp[(ypos-3)/2].qty then
  1450. --DEPOSIT ITEM
  1451. userInput("You are trying to deposit more items than your inventory currently holds, depositing the maximum amount ("..list_temp[index+(ypos-3)/2].qty..") instead.")
  1452. amount = list_temp[index+(ypos-3)/2].qty
  1453. end
  1454. deposit(list_temp[index+(ypos-3)/2],amount)
  1455. term.clear()
  1456. readInventory()
  1457. break
  1458. end
  1459. else
  1460. local valid,sel = parse_header(xpos,ypos)
  1461. if valid then
  1462. header_current = sel
  1463. os.queueEvent("updateHeader")
  1464. break
  1465. end
  1466. end
  1467. elseif event == "key" then
  1468. if (key == 200 or key == 17) and index > 0 then
  1469. index = index -1
  1470. break
  1471. elseif (key == 208 or key ==31) and index < #list_temp -8 then
  1472. index = index +1
  1473. break
  1474. elseif restart(key) then
  1475. os.reboot()
  1476. end
  1477. elseif event == "updatePlayer" then
  1478. break --current_player changed
  1479. end
  1480. end
  1481. end
  1482. end
  1483.  
  1484. function draw_withdraw(index)
  1485. local player_ilist_temp = index_list(player_iList["items"])
  1486. local tc1,tt1 = Draw.emptyScreen(term,3,1)
  1487. Draw.tc(tc1,1,1,colors.lime,4,1)
  1488. Draw.tt(tt1,1,1,"Sell",colors.black)
  1489.  
  1490. --Draw.draw(term,tc1,3,string.len(money_name..": "..player_iList[money_name],colors.black)+1,2^15,tt1)
  1491.  
  1492. if #player_ilist_temp == 0 then
  1493. draw_header("withdraw")
  1494. local tc,tt = Draw.emptyScreen(term,51,16)
  1495. Draw.tc(tc,1,1,colors.lightGray,51,16)
  1496. Draw.tt(tt,3,7," You need to deposit or purchase items before you will ",colors.black)
  1497. Draw.tt(tt,3,8," have any items to withdraw/sell",colors.black)
  1498. Draw.draw(term,tc,1,4,2^15,tt)
  1499. return {},2
  1500. else
  1501. --[[
  1502. Setting up item list
  1503. --]]
  1504. local item_c,item_t = Draw.emptyScreen(term,50,#player_ilist_temp*2+16)--+2)
  1505.  
  1506. local switch_bg = true
  1507. if index%2 == 1 then
  1508. -- switch_bg = false
  1509. end
  1510. for i=1,#player_ilist_temp do
  1511. local bg_
  1512. if switch_bg then
  1513. bg_ = colors.blue
  1514. switch_bg = false
  1515. else
  1516. bg_ = colors.lightBlue
  1517. switch_bg = true
  1518. end
  1519. local item_name = fixNames(player_ilist_temp[i])
  1520. --item_name = "12345678901234567890123456789012345678901234567890"
  1521. if string.len(item_name) > 43 then
  1522. item_name = string.sub(item_name,0,40)..".."
  1523. end
  1524. Draw.tc(item_c,1,2*i-1,bg_,50,2*i)
  1525. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.yellow)..item_name.."&"..Draw.getHexOf(colors.red).." x"..player_ilist_temp[i].qty)
  1526. local ench_str = ""
  1527. if player_ilist_temp[i].ench ~= nil and #player_ilist_temp[i].ench >0 then
  1528. ench_str = "&"..Draw.getHexOf(colors.red).."Ench: "
  1529. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1530. for k=1,#player_ilist_temp[i].ench do
  1531. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(player_ilist_temp[i].ench[k]).." "
  1532. end
  1533. end
  1534. Draw.tt(item_t,1,2*i," &"..Draw.getHexOf(colors.brown).."("..player_ilist_temp[i].IDdam..") "..ench_str)
  1535. Draw.tt(item_t,44,2*i-1," &"..Draw.getHexOf(colors.black).." Sell ")
  1536. Draw.tc(item_c,44,2*i-1,colors.lime,50,2*i)
  1537. Draw.tt(item_t,41,2*i," &"..Draw.getHexOf(colors.white).." Withdraw ")
  1538. Draw.tc(item_c,41,2*i,colors.gray,50,2*i)
  1539. end
  1540. --[[
  1541. Setting up scroll bar
  1542. --]]
  1543. local bar_c,bar_t = Draw.emptyScreen(term,1,16)
  1544. Draw.tc(bar_c,1,1,colors.gray,1,16)
  1545. Draw.tc(bar_c,1,1,colors.lightGray)
  1546. Draw.tt(bar_t,1,1,"^")
  1547. Draw.tc(bar_c,1,16,colors.lightGray)
  1548. Draw.tt(bar_t,1,16,"v")
  1549. local scroll_pos = 2
  1550. if #player_ilist_temp > 8 then
  1551. scroll_pos = math.floor(2+13*((index)/(#player_ilist_temp-8)))
  1552. end
  1553. Draw.tc(bar_c,1,scroll_pos,colors.purple)
  1554. Draw.draw(term,bar_c,1,4,2^15,bar_t)
  1555. local item_c_f = {}
  1556. local item_t_f = {}
  1557.  
  1558. for i=(index*2+1),#item_t do --#player_ilist_temp*2 do
  1559. table.insert(item_c_f,item_c[i])
  1560. table.insert(item_t_f,item_t[i])
  1561. --item_c_f[i-(index*2+1)] = item_c[i]
  1562. --item_t_f[i-(index*2+1)] = item_t[i]
  1563. end
  1564. Draw.draw(term,item_c_f,2,4,2^15,item_t_f)
  1565. draw_header("withdraw")
  1566. Draw.draw(term,tc1,string.len(money_name..": "..player_iList[money_name],colors.black)+1,3,2^15,tt1)
  1567. return player_ilist_temp,scroll_pos
  1568. end
  1569. end
  1570.  
  1571. function withdraw(item,amount)
  1572. --AE:
  1573. --insertItem(slot...,amount...,direction...)
  1574. --extractItem(stack...,direction...)
  1575. if amount <=0 then return end
  1576. please_wait()
  1577. local ID = tonumber(string.match(item.IDdam,"(%d+):%d+"))
  1578. local dam = tonumber(string.match(item.IDdam,"%d+:(%d+)"))
  1579. local amount_wd = 0
  1580. --scan player inventory for items
  1581. dontUpdate = true
  1582. local count = 0
  1583. local extracted = true
  1584. for i=1,math.floor(amount/item.maxSize) do
  1585. count = count+1
  1586. end
  1587. count = count + amount%item.maxSize
  1588.  
  1589. for i=1,math.floor(amount/item.maxSize) do
  1590. if not ae.extractItem(item,item.maxSize) then extracted = false end
  1591. end
  1592. if amount%item.maxSize ~= 0 then
  1593. if not ae.extractItem(item,amount%item.maxSize) then extracted = false end
  1594. end
  1595. if not extracted then --need to count the amount that was extracted.
  1596. local sum =0
  1597. for k,v in pairs(getChestData()) do
  1598. sum = sum + v.qty
  1599. end
  1600. if sum>0 then
  1601. ERR("withdraw","Tried to extract x"..amount.." "..fixNames(item).." but only got x"..sum)
  1602. ERR("withdraw","Refund x"..(amount-sum).." "..fixNames(item))
  1603. end
  1604. updatePlayerTable(item,-1*sum)
  1605. else
  1606. updatePlayerTable(item,-1*amount)
  1607. end
  1608. PIM.dumpAll()
  1609. save_player(currentPlayer)
  1610. dontUpdate = false
  1611. if not extracted then userInput("There was an error extracting your items, please contact an admin") end
  1612. end
  1613.  
  1614. function display_withdraw()
  1615. local index = 0
  1616. local amount = 0
  1617. local sell_pos =string.len(money_name..": "..player_iList[money_name],colors.black)+1
  1618. while currentPlayer ~= nil and header_current == header_sel[2] do
  1619. local list_temp,scroll_pos = draw_withdraw(index)
  1620. while true do
  1621. local event,key,xpos,ypos = os.pullEvent()
  1622. if (event == "mouse_click") then
  1623. if ypos>3 then
  1624. if (xpos == 1 and #list_temp > 8) then --Scroll
  1625. if ypos < scroll_pos+3 and index > 0 then
  1626. index = index - 1
  1627. elseif ypos > scroll_pos+3 and index < #list_temp -8 then
  1628. index = index +1
  1629. end
  1630. break
  1631. elseif xpos>41 and ypos%2 == 1 and (index+(ypos-3)/2) <= #list_temp then
  1632. amount = math.abs(userInput("How much '"..fixNames(list_temp[index+(ypos-3)/2]).."' would you like to withdraw?","number",list_temp[index+(ypos-3)/2].qty))
  1633. if amount>list_temp[(ypos-3)/2].qty then
  1634. --WITHDRAW ITEM
  1635. userInput("You are trying to withdraw more items than your inventory currently holds, withdrawing the maximum amount ("..list_temp[index+(ypos-3)/2].qty..") instead.")
  1636. amount = list_temp[index+(ypos-3)/2].qty
  1637. end
  1638. if checkIfFits(list_temp[index+(ypos-3)/2],amount) then
  1639. withdraw(list_temp[index+(ypos-3)/2],amount)
  1640. else
  1641. userInput("Your inventory can't hold this many items, free up some space and try again")
  1642. end
  1643. break
  1644. elseif xpos>44 and ypos%2 == 0 and (index+(ypos-3)/2) <= #list_temp then
  1645. display_sell(list_temp[index+(ypos-2)/2])
  1646. break
  1647. end
  1648. elseif ypos == 3 and xpos>= sell_pos and xpos <= sell_pos+3 then
  1649. display_sell(money_name)
  1650. break
  1651. else
  1652. local valid,sel = parse_header(xpos,ypos)
  1653. if valid then
  1654. header_current = sel
  1655. os.queueEvent("updateHeader")
  1656. break
  1657. end
  1658. end
  1659. elseif event == "key" then
  1660. if (key == 200 or key == 17) and index > 0 then
  1661. index = index -1
  1662. break
  1663. elseif (key == 208 or key == 31) and index < #list_temp -8 then
  1664. index = index +1
  1665. break
  1666. elseif restart(key) then
  1667. os.reboot()
  1668. end
  1669. elseif event == "updatePlayer" then
  1670. break --current_player changed
  1671. end
  1672. end
  1673. end
  1674. end
  1675.  
  1676. function setupTrade(item,amt,item_for,amt_for)
  1677. if #player_iList["trades"] > maxTrades then
  1678. userInput("you've reached the maximum number of items you can sell, consider ending the sale of a item (this item was not put up for sale)")
  1679. return
  1680. end
  1681. local tab = {}
  1682. if item_for == money_name then
  1683. tab["cred"] = true
  1684. else
  1685. tab["cred"] = false
  1686. end
  1687. item_for.qty = amt_for
  1688. item_for.rawName = nil
  1689. item_for.maxSize = nil
  1690. item.qty = amt
  1691. item.rawName = nil
  1692. item.maxSize = nil
  1693.  
  1694. tab["wants"] = item_for
  1695. tab["has"] = item
  1696. tab["total"] = 0
  1697. tab["players"] = ""
  1698. table.insert(player_iList["trades"],deepcopy(tab))
  1699. if currentPlayer == nil then ERR("setupTrade","Nil currentPlayer!") else
  1700.  
  1701. global_iList_trades[currentPlayer] = deepcopy(player_iList["trades"])
  1702. --[[
  1703. local found,index = compareEnchantments(global_iList_IDs,item)
  1704. if not found then ERR("setupTrade","item not found in global list! name:",item.name,true) end
  1705. local uniqueID = IDtoUnique(item.id,item.dmg)
  1706. local tab1 = {}
  1707. local tab2 = {}
  1708. local tab3 = {}
  1709. tab1[currentPlayer] = player_iList["trades"]
  1710. tab2[index] = tab1
  1711. tab3[item.name] = tab2
  1712. if global_iList_trades[uniqueID] == nil then
  1713. global_iList_trades[uniqueID] = deepcopy(tab3)
  1714. elseif global_iList_trades[uniqueID][item.name] == nil then
  1715. global_iList_trades[uniqueID][item.name] = deepcopy(tab2)
  1716. elseif global_iList_trades[uniqueID][item.name][index] == nil then
  1717. global_iList_trades[uniqueID][item.name][index] = deepcopy(tab1)
  1718. elseif global_iList_trades[uniqueID][item.name][index][currentPlayer] == nil then
  1719. global_iList_trades[uniqueID][item.name][index][currentPlayer] = deepcopy(player_iList["trades"])
  1720. end
  1721. ]]--
  1722. end
  1723. save_player(currentPlayer)
  1724. end
  1725.  
  1726. function display_sell(item)
  1727. local amount_for = 1
  1728. local amount = 1
  1729. local item_for = {["name"] = "Click to select item",["id"]=1,["dmg"]=1}
  1730. if type(item) == "string" then -- credits.
  1731. item = deepcopy(global_iList_IDs[IDtoUnique(1,1)][money_name][1])
  1732. end
  1733. while currentPlayer ~= nil and header_current == header_sel[2] do
  1734. draw_sell(item,amount,item_for,amount_for)
  1735. while true do
  1736. local event,key,xpos,ypos = os.pullEvent()
  1737. if (event == "mouse_click") then
  1738. if ypos>3 then
  1739. if ypos == 7 and xpos>=11 and xpos<=16 then --Amount per sale
  1740. while true do
  1741. term.setCursorPos(11,7)
  1742. term.write(" ")
  1743. term.setCursorPos(11,7)
  1744. amount = tonumber(io.read())
  1745. if amount ~= nil then
  1746. if amount > item.qty then amount = item.qty end
  1747. break
  1748. else
  1749. --userInput("Please type in a number")
  1750. end
  1751. end
  1752. elseif ypos == 11 and xpos>=15 and xpos<=35 then --For item
  1753. item_for = search_list()
  1754. elseif ypos == 13 and xpos>=11 and xpos<=16 then --For item per sale.
  1755. while true do
  1756. term.setCursorPos(11,13)
  1757. term.write(" ")
  1758. term.setCursorPos(11,13)
  1759. amount_for = tonumber(io.read())
  1760. if amount_for ~= nil then break else
  1761. --userInput("Please type in a number")
  1762. end
  1763. end
  1764. elseif ypos == 17 then
  1765. if xpos <= 22 and xpos >=15 then -- accept
  1766. if item_for.name ~= "Click to select item" then -- item selected
  1767. --trade good, add to playertable.
  1768. if userInput("Sell "..amount.." "..fixNames(item).." for "..amount_for.." "..fixNames(item_for).." ?",true) then
  1769. --setupTrade
  1770. setupTrade(item,amount,item_for,amount_for)
  1771. return
  1772. end
  1773. else
  1774. userInput("Invalid item, please select a item")
  1775. end
  1776. elseif xpos <=35 and xpos >= 28 then --cancel
  1777. return
  1778. end
  1779. end
  1780.  
  1781. --InsertShit
  1782. break
  1783. else
  1784. local valid,sel = parse_header(xpos,ypos)
  1785. if valid then
  1786. header_current = sel
  1787. os.queueEvent("updateHeader")
  1788. break
  1789. end
  1790. end
  1791. elseif event == "key" then
  1792. if restart(key) then
  1793. os.reboot()
  1794. end
  1795. elseif event == "updatePlayer" then
  1796. break --current_player changed
  1797. end
  1798. end
  1799. end
  1800. end
  1801.  
  1802.  
  1803. function search_list()
  1804. local function draw1(list,total,mess)
  1805.  
  1806. if mess == nil then mess = "(type ID:dmg or item name)" end
  1807. local tc,tt = Draw.emptyScreen(term,51,16)
  1808. Draw.tc(tc,1,1,colors.black,51,16)
  1809. Draw.tt(tt,1,1,"Search: &"..Draw.getHexOf(colors.white)..mess,colors.red)
  1810. Draw.tt(tt,1,2,"found: "..total,colors.lime)
  1811. Draw.tc(tc,1,1,colors.lightBlue,51,2)
  1812. Draw.tc(tc,9,1,colors.black,35,1)
  1813. local iter = 3
  1814. for i=1,20 do
  1815. for item in tableIter(list[i]) do
  1816. local ench_str = ""
  1817. if item.ench ~= nil and #item.ench >0 then
  1818. ench_str = "Ench: "
  1819. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1820. for k=1,#item.ench do
  1821. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(item.ench[k]).." "
  1822. end
  1823. end
  1824. Draw.tt(tt,1,iter,ss(fixNames(item),30).." &"..Draw.getHexOf(colors.gray).."("..item.id..":"..item.dmg..") "..ench_str,colors.lime)
  1825. if iter>=16 then break end
  1826. iter = iter+1
  1827. end
  1828. if iter>=16 then break end
  1829. end
  1830. Draw.draw(term,tc,1,4,2^15,tt)
  1831. draw_header("withdraw")
  1832. end
  1833. while true do
  1834. local ret_item,total = textSearch(9,4,draw1,search)
  1835. if ret_item == nil or ret_item.name == nil then
  1836. --ERR("search_list","nil item returned, this should not happen! (but shouldnt be a issue)")
  1837. --Happens when enter is pressed and no item in list
  1838. --term.clear()
  1839. elseif #ret_item.ench >0 then
  1840. userInput("Sorry, I currently do not support setting up a trade that receives enchanted items. Please select another item.")
  1841. else
  1842. return deepcopy(ret_item)
  1843. end
  1844. end
  1845. end
  1846.  
  1847. function draw_sell(item,amount,item_for,amount_for)
  1848. draw_header("withdraw")
  1849.  
  1850. local itemName_c = colors.lime
  1851. local item_for_name = "&"..Draw.getHexOf(itemName_c)..fixNames(item_for)
  1852. if item_for.id ~= nil and item_for.dmg ~= nil then
  1853. item_for_name = Draw.getHexOf(itemName_c)..ss(fixNames(item_for),38).." &"..Draw.getHexOf(colors.gray).."("..item_for.id..":"..item_for.dmg..")"
  1854. end
  1855. local ench_str = ""
  1856. if item.ench ~= nil and #item.ench >0 then
  1857. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1858. for k=1,#item.ench do
  1859. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(item.ench[k]).." "
  1860. end
  1861. else
  1862. ench_str = "none"
  1863. end
  1864. local tc,tt = Draw.emptyScreen(term,51,16)
  1865. Draw.tc(tc,1,1,colors.lightGray,51,16)
  1866. Draw.tt(tt,1,1,"Selling:",colors.red)
  1867. Draw.tt(tt,3,2,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item),38).." &"..Draw.getHexOf(colors.gray).."("..item.id..":"..item.dmg..")",colors.black)
  1868. Draw.tt(tt,3,3,"Enchantments: "..ench_str,colors.black)
  1869. Draw.tt(tt,3,4,"Amount: &"..Draw.getHexOf(colors.red)..amount,colors.black)
  1870. Draw.tc(tc,11,4,colors.black,12+string.len(tostring(amount)),4)
  1871. Draw.tt(tt,1,7,"For:",colors.black)
  1872. Draw.tt(tt,3,8,"Item Name: &"..item_for_name,colors.black)
  1873. Draw.tc(tc,14,8,colors.black,42,8)
  1874. Draw.tt(tt,3,9,"Enchantments: (to be added)",colors.black) --TODO: enchantment pulldowns
  1875. Draw.tt(tt,3,10,"Amount: &"..Draw.getHexOf(colors.red)..amount_for,colors.black)
  1876. Draw.tc(tc,11,10,colors.black,12+string.len(tostring(amount_for)),10)
  1877. Draw.tt(tt,16,14,"Accept",colors.black)
  1878. Draw.tt(tt,29,14,"Cancel",colors.black)
  1879. Draw.tc(tc,15,14,colors.lime,22,14)
  1880. Draw.tc(tc,28,14,colors.green,35,14)
  1881. Draw.draw(term,tc,1,4,2^15,tt)
  1882. end
  1883.  
  1884. function draw_selling(list,index)
  1885. --Draw.draw(term,tc1,3,string.len(money_name..": "..player_iList[money_name],colors.black)+1,2^15,tt1)
  1886.  
  1887. if list == nil then
  1888. draw_header("selling")
  1889. local tc,tt = Draw.emptyScreen(term,51,16)
  1890. Draw.tc(tc,1,1,colors.lightGray,51,16)
  1891. Draw.tt(tt,3,7," No Items for sale. You'll never turn a profit that way. ",colors.black)
  1892. Draw.draw(term,tc,1,4,2^15,tt)
  1893. return {},2
  1894. else
  1895. local item_c,item_t = Draw.emptyScreen(term,50,100*2+16)
  1896. local switch_bg = true
  1897. local i = 1
  1898. for name,tradeIndexTab in pairs(list) do
  1899. for tradeIndex,tradeTab in pairs(tradeIndexTab) do
  1900. local wants = tradeTab.wants
  1901. local has = tradeTab.has
  1902. local bg_
  1903. if switch_bg then
  1904. bg_ = colors.blue
  1905. switch_bg = false
  1906. else
  1907. bg_ = colors.lightBlue
  1908. switch_bg = true
  1909. end
  1910. local item_name = ss(fixNames(has),30)
  1911. local ench_str = ""
  1912. if has.ench ~= nil and #has.ench >0 then
  1913. ench_str = ""
  1914. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1915. for k=1,#has.ench do
  1916. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(has.ench[k]).." "
  1917. end
  1918. end
  1919. Draw.tc(item_c,1,2*i-1,bg_,50,2*i)
  1920. if item_name ~= money_name then
  1921. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.lime)..item_name.."&"..Draw.getHexOf(colors.red).." x"..has.qty.." &"..Draw.getHexOf(colors.brown).."("..has.id..":"..has.dmg..") "..ench_str)
  1922. else
  1923. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.yellow)..item_name.."&"..Draw.getHexOf(colors.red).." x"..has.qty)
  1924. end
  1925. if wants.ench ~= nil and #wants.ench >0 then
  1926. ench_str = ""
  1927. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  1928. for k=1,#wants.ench do
  1929. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(wants.ench[k]).." "
  1930. end
  1931. end
  1932. if wants.name ~= money_name then
  1933. Draw.tt(item_t,1,2*i,"For: &"..Draw.getHexOf(colors.orange)..fixNames(wants).."&"..Draw.getHexOf(colors.red).." x"..wants.qty.." &"..Draw.getHexOf(colors.brown).."("..wants.id..":"..wants.dmg..") "..ench_str,colors.lime)
  1934. else
  1935. Draw.tt(item_t,1,2*i,"For: &"..Draw.getHexOf(colors.yellow)..fixNames(wants).."&"..Draw.getHexOf(colors.red).." x"..wants.qty,colors.lime)
  1936. end
  1937. --Draw.tt(item_t,44,2*i-1," &"..Draw.getHexOf(colors.black)..name)
  1938. --Draw.tc(item_c,44,2*i-1,colors.lime,50,2*i)
  1939. Draw.tt(item_t,41,2*i," &"..Draw.getHexOf(colors.black).." Inspect ")
  1940. Draw.tc(item_c,42,2*i,colors.lime,50,2*i)
  1941. i=i+1
  1942. end
  1943. end
  1944. i=i-1
  1945. --Draw.draw(term,item_c,2,4,2^15,item_t)
  1946.  
  1947. --[[
  1948. Setting up scroll bar
  1949. --]]
  1950. local bar_c,bar_t = Draw.emptyScreen(term,1,16)
  1951. Draw.tc(bar_c,1,1,colors.gray,1,16)
  1952. Draw.tc(bar_c,1,1,colors.lightGray)
  1953. Draw.tt(bar_t,1,1,"^")
  1954. Draw.tc(bar_c,1,16,colors.lightGray)
  1955. Draw.tt(bar_t,1,16,"v")
  1956. local scroll_pos = 2
  1957. if i > 8 then
  1958. scroll_pos = math.floor(2+13*((index)/(i-8)))
  1959. end
  1960. Draw.tc(bar_c,1,scroll_pos,colors.purple)
  1961. Draw.draw(term,bar_c,1,4,2^15,bar_t)
  1962. local item_c_f = {}
  1963. local item_t_f = {}
  1964.  
  1965. for ii=(index*2+1),#item_t do --#player_ilist_temp*2 do
  1966. table.insert(item_c_f,item_c[ii])
  1967. table.insert(item_t_f,item_t[ii])
  1968. --item_c_f[i-(index*2+1)] = item_c[i]
  1969. --item_t_f[i-(index*2+1)] = item_t[i]
  1970. end
  1971. Draw.draw(term,item_c_f,2,4,2^15,item_t_f)
  1972. draw_header("selling")
  1973. --Draw.draw(term,tc1,string.len(money_name..": "..player_iList[money_name],colors.black)+1,3,2^15,tt1)
  1974. return scroll_pos,i
  1975. end
  1976. end
  1977.  
  1978. function selling_inquire(name,tradeIndex)
  1979. local tradeTab = global_iList_trades[name][tradeIndex]
  1980. local function draw_temp()
  1981. local function get_amt(item_t,iList)
  1982. if item_t.name == money_name then --creddits
  1983. return math.floor(iList[money_name]/item_t.qty)
  1984. elseif iList["items"] ~= nil
  1985. and iList["items"][IDtoUnique(item_t.id,item_t.dmg)] ~= nil
  1986. and iList["items"][IDtoUnique(item_t.id,item_t.dmg)][item_t.name] ~= nil then
  1987. local bool,item_temp = compareEnchantments(iList["items"],item_t,true)
  1988. if bool then
  1989. --item found in players shit get quanty
  1990. return math.floor(item_temp.qty/item_t.qty)
  1991. end
  1992. else
  1993. return 0
  1994. end
  1995. end
  1996.  
  1997. local item_for = tradeTab.wants
  1998. local item = tradeTab.has
  1999. -- load functions go here
  2000. local amount = get_amt(item,player_iList)
  2001.  
  2002. local itemName_c = colors.lime
  2003. local ench_str = ""
  2004. if item.ench ~= nil and #item.ench >0 then
  2005. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  2006. for k=1,#item.ench do
  2007. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(item.ench[k]).." "
  2008. end
  2009. else
  2010. ench_str = "none"
  2011. end
  2012. local tc,tt = Draw.emptyScreen(term,51,16)
  2013. Draw.tc(tc,1,1,colors.lightGray,51,16)
  2014. Draw.tt(tt,1,1,"Selling:",colors.black)
  2015. if item.name ~= money_name then
  2016. Draw.tt(tt,3,2,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item),38).." &"..Draw.getHexOf(colors.gray).."("..item.id..":"..item.dmg..") &"..Draw.getHexOf(colors.red).."x"..item.qty,colors.black)
  2017. else
  2018. Draw.tt(tt,3,2,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item),38).." &"..Draw.getHexOf(colors.red).."x"..item.qty,colors.black)
  2019. end
  2020. Draw.tt(tt,3,3,"Enchantments: "..ench_str,colors.black)
  2021. Draw.tt(tt,3,4,"Trades Available: &"..Draw.getHexOf(colors.red)..amount,colors.black)
  2022. Draw.tt(tt,3,5,"Trades Completed: &"..Draw.getHexOf(colors.red)..tradeTab.total,colors.black)
  2023. Draw.tt(tt,1,7,"For:",colors.black)
  2024. if item_for.name ~= money_name then
  2025. Draw.tt(tt,3,8,"Item Name: &"..Draw.getHexOf(itemName_c)..fixNames(item_for).." &"..Draw.getHexOf(colors.gray).."("..item_for.id..":"..item_for.dmg..") &"..Draw.getHexOf(colors.red).."x"..item_for.qty,colors.black)
  2026. else
  2027. Draw.tt(tt,3,8,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item_for),38).." &"..Draw.getHexOf(colors.red).."x"..item_for.qty,colors.black)
  2028. end
  2029. Draw.tt(tt,3,9,"Enchantments: (to be added)",colors.black) --TODO: enchantment pulldowns
  2030.  
  2031. Draw.tt(tt,15,14,"Delete",colors.black)
  2032. Draw.tt(tt,29,14,"Cancel",colors.black)
  2033. Draw.tc(tc,14,14,colors.red,23,14)
  2034. Draw.tc(tc,28,14,colors.green,35,14)
  2035. Draw.draw(term,tc,1,4,2^15,tt)
  2036. draw_header("selling")
  2037. return
  2038. end
  2039. while true do
  2040. sleep(0)
  2041. draw_temp()
  2042. local event,key,xpos,ypos = os.pullEvent()
  2043. if (event == "mouse_click") then
  2044. if ypos>3 then
  2045. if false and ypos == 13 and xpos>=11 and xpos<=16 then --For item per sale. --TODO
  2046. while true do
  2047. term.setCursorPos(11,13)
  2048. term.write(" ")
  2049. term.setCursorPos(11,13)
  2050. amount_for = tonumber(io.read())
  2051. if amount_for ~= nil then break else
  2052. --userInput("Please type in a number")
  2053. end
  2054. end
  2055. elseif ypos == 17 then
  2056. if xpos <= 23 and xpos >=14 then --delete
  2057. player_iList["trades"][tradeIndex] = nil
  2058. global_iList_trades[name][tradeIndex] = nil
  2059. userInput("This trade has been deleted")
  2060. save_player(currentPlayer)
  2061. return
  2062. elseif xpos <=35 and xpos >= 28 then --cancel
  2063. return
  2064. end
  2065. end
  2066. --InsertShit
  2067.  
  2068. else
  2069. local valid,sel = parse_header(xpos,ypos)
  2070. if valid then
  2071. header_current = sel
  2072. os.queueEvent("updateHeader")
  2073. break
  2074. end
  2075. end
  2076. elseif event == "key" then
  2077. if restart(key) then
  2078. os.reboot()
  2079. end
  2080. elseif event == "updatePlayer" then
  2081. break --current_player changed
  2082. end
  2083. end
  2084. end
  2085.  
  2086. function display_selling()
  2087. local index = 0
  2088. local amount = 0
  2089. local list = {}
  2090. while currentPlayer ~= nil and header_current == header_sel[3] do
  2091. list[currentPlayer] = deepcopy(global_iList_trades[currentPlayer])
  2092. local scroll_pos,length = draw_selling(list,index)
  2093. while true do
  2094. local event,key,xpos,ypos = os.pullEvent()
  2095. if (event == "mouse_click") then
  2096. if ypos>3 then
  2097. if (xpos == 1 and length > 8) then --Scroll
  2098. if ypos < scroll_pos+3 and index > 0 then
  2099. index = index - 1
  2100. elseif ypos > scroll_pos+3 and index < length -8 then
  2101. index = index +1
  2102. end
  2103. break
  2104. elseif xpos>41 and ypos%2 == 1 and (index+(ypos-3)/2) <= length then
  2105. local function findItem()
  2106. local i = 1
  2107. for name,tradeIndexTab in pairs(list) do
  2108. for tradeIndex,tradeTab in pairs(tradeIndexTab) do
  2109. if i==(index+(ypos-3)/2) then
  2110. selling_inquire(name,tradeIndex)
  2111. return
  2112. else
  2113. i=i+1
  2114. end
  2115. end
  2116. end
  2117. end
  2118. findItem()
  2119. break
  2120. end
  2121. else
  2122. local valid,sel = parse_header(xpos,ypos)
  2123. if valid then
  2124. header_current = sel
  2125. os.queueEvent("updateHeader")
  2126. break
  2127. end
  2128. end
  2129. elseif event == "key" then
  2130. if (key == 200 or key == 17) and index > 0 then
  2131. index = index -1
  2132. break
  2133. elseif (key == 208 or key == 31) and index < length -8 then
  2134. index = index +1
  2135. break
  2136. elseif restart(key) then
  2137. os.reboot()
  2138. end
  2139. elseif event == "updatePlayer" then
  2140. break --current_player changed
  2141. end
  2142. end
  2143. end
  2144. end
  2145.  
  2146.  
  2147. function draw_buy(list,index)
  2148.  
  2149. local tc1,tt1 = Draw.emptyScreen(term,6,1)
  2150. Draw.tc(tc1,1,1,colors.lime,7,1)
  2151. Draw.tt(tt1,1,1,"Filters",colors.black)
  2152.  
  2153. --Draw.draw(term,tc1,3,string.len(money_name..": "..player_iList[money_name],colors.black)+1,2^15,tt1)
  2154.  
  2155. if list == nil then
  2156. draw_header("buy")
  2157. local tc,tt = Draw.emptyScreen(term,51,16)
  2158. Draw.tc(tc,1,1,colors.lightGray,51,16)
  2159. Draw.tt(tt,3,7," No Items for sale, how depressing! ",colors.black)
  2160. Draw.draw(term,tc,1,4,2^15,tt)
  2161. return {},2
  2162. else
  2163. local item_c,item_t = Draw.emptyScreen(term,50,100*2+16)
  2164. local switch_bg = true
  2165. local i = 1
  2166. for name,tradeIndexTab in pairs(list) do
  2167. for tradeIndex,tradeTab in pairs(tradeIndexTab) do
  2168. local wants = tradeTab.wants
  2169. local has = tradeTab.has
  2170. local bg_
  2171. if switch_bg then
  2172. bg_ = colors.blue
  2173. switch_bg = false
  2174. else
  2175. bg_ = colors.lightBlue
  2176. switch_bg = true
  2177. end
  2178. local item_name = ss(fixNames(has),30)
  2179. local ench_str = ""
  2180. if has.ench ~= nil and #has.ench >0 then
  2181. ench_str = ""
  2182. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  2183. for k=1,#has.ench do
  2184. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(has.ench[k]).." "
  2185. end
  2186. end
  2187. Draw.tc(item_c,1,2*i-1,bg_,50,2*i)
  2188. if item_name ~= money_name then
  2189. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.lime)..item_name.."&"..Draw.getHexOf(colors.red).." x"..has.qty.." &"..Draw.getHexOf(colors.brown).."("..has.id..":"..has.dmg..") "..ench_str)
  2190. else
  2191. Draw.tt(item_t,1,2*i-1," &"..Draw.getHexOf(colors.yellow)..item_name.."&"..Draw.getHexOf(colors.red).." x"..has.qty)
  2192. end
  2193. if wants.ench ~= nil and #wants.ench >0 then
  2194. ench_str = ""
  2195. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  2196. for k=1,#wants.ench do
  2197. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(wants.ench[k]).." "
  2198. end
  2199. end
  2200. if wants.name ~= money_name then
  2201. Draw.tt(item_t,1,2*i,"For: &"..Draw.getHexOf(colors.orange)..fixNames(wants).."&"..Draw.getHexOf(colors.red).." x"..wants.qty.." &"..Draw.getHexOf(colors.brown).."("..wants.id..":"..wants.dmg..") "..ench_str,colors.lime)
  2202. else
  2203. Draw.tt(item_t,1,2*i,"For: &"..Draw.getHexOf(colors.yellow)..fixNames(wants).."&"..Draw.getHexOf(colors.red).." x"..wants.qty,colors.lime)
  2204. end
  2205. --Draw.tt(item_t,44,2*i-1," &"..Draw.getHexOf(colors.black)..name)
  2206. --Draw.tc(item_c,44,2*i-1,colors.lime,50,2*i)
  2207. Draw.tt(item_t,41,2*i," &"..Draw.getHexOf(colors.black).." Inquire ")
  2208. Draw.tc(item_c,42,2*i,colors.lime,50,2*i)
  2209. i=i+1
  2210. end
  2211. end
  2212. i=i-1
  2213. --Draw.draw(term,item_c,2,4,2^15,item_t)
  2214.  
  2215. --[[
  2216. Setting up scroll bar
  2217. --]]
  2218. local bar_c,bar_t = Draw.emptyScreen(term,1,16)
  2219. Draw.tc(bar_c,1,1,colors.gray,1,16)
  2220. Draw.tc(bar_c,1,1,colors.lightGray)
  2221. Draw.tt(bar_t,1,1,"^")
  2222. Draw.tc(bar_c,1,16,colors.lightGray)
  2223. Draw.tt(bar_t,1,16,"v")
  2224. local scroll_pos = 2
  2225. if i > 8 then
  2226. scroll_pos = math.floor(2+13*((index)/(i-8)))
  2227. end
  2228. Draw.tc(bar_c,1,scroll_pos,colors.purple)
  2229. Draw.draw(term,bar_c,1,4,2^15,bar_t)
  2230. local item_c_f = {}
  2231. local item_t_f = {}
  2232.  
  2233. for ii=(index*2+1),#item_t do --#player_ilist_temp*2 do
  2234. table.insert(item_c_f,item_c[ii])
  2235. table.insert(item_t_f,item_t[ii])
  2236. --item_c_f[i-(index*2+1)] = item_c[i]
  2237. --item_t_f[i-(index*2+1)] = item_t[i]
  2238. end
  2239. Draw.draw(term,item_c_f,2,4,2^15,item_t_f)
  2240. draw_header("buy")
  2241. Draw.draw(term,tc1,string.len(money_name..": "..player_iList[money_name],colors.black)+1,3,2^15,tt1)
  2242. return scroll_pos,i
  2243. end
  2244. end
  2245.  
  2246. function buy_inquire(name,tradeIndex)
  2247. local seller_iList = load_player(name,true)
  2248. local tradeTab = global_iList_trades[name][tradeIndex]
  2249. local function draw_temp()
  2250. local function get_amt(item_t,iList)
  2251. if item_t.name == money_name then --creddits
  2252. return math.floor(iList[money_name]/item_t.qty)
  2253. elseif iList["items"] ~= nil
  2254. and iList["items"][IDtoUnique(item_t.id,item_t.dmg)] ~= nil
  2255. and iList["items"][IDtoUnique(item_t.id,item_t.dmg)][item_t.name] ~= nil then
  2256. local bool,item_temp = compareEnchantments(iList["items"],item_t,true)
  2257. if bool then
  2258. --item found in players shit get quanty
  2259. return math.floor(item_temp.qty/item_t.qty)
  2260. end
  2261. else
  2262. return 0
  2263. end
  2264. end
  2265.  
  2266. local item_for = tradeTab.wants
  2267. local item = tradeTab.has
  2268.  
  2269. -- load functions go here
  2270. local amount = get_amt(item,seller_iList)
  2271. local amount_for = get_amt(item_for,player_iList)
  2272.  
  2273.  
  2274.  
  2275. local itemName_c = colors.lime
  2276.  
  2277. local ench_str = ""
  2278. if item.ench ~= nil and #item.ench >0 then
  2279. local colors_tab = {colors.purple,colors.lime,colors.magenta,colors.orange}
  2280. for k=1,#item.ench do
  2281. ench_str = ench_str.."&"..Draw.getHexOf(colors_tab[k])..getShortEnch(item.ench[k]).." "
  2282. end
  2283. else
  2284. ench_str = "none"
  2285. end
  2286. local tc,tt = Draw.emptyScreen(term,51,16)
  2287. Draw.tc(tc,1,1,colors.lightGray,51,16)
  2288. Draw.tt(tt,1,1,"Selling:",colors.black)
  2289. if item.name ~= money_name then
  2290. Draw.tt(tt,3,2,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item),38).." &"..Draw.getHexOf(colors.gray).."("..item.id..":"..item.dmg..") &"..Draw.getHexOf(colors.red).."x"..item.qty,colors.black)
  2291. else
  2292. Draw.tt(tt,3,2,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item),38).." &"..Draw.getHexOf(colors.red).."x"..item.qty,colors.black)
  2293. end
  2294. Draw.tt(tt,3,3,"Enchantments: "..ench_str,colors.black)
  2295. Draw.tt(tt,3,4,"Trades Available: &"..Draw.getHexOf(colors.red)..amount,colors.black)
  2296. Draw.tt(tt,3,5,"Player: &"..Draw.getHexOf(colors.brown)..name,colors.black)
  2297. Draw.tt(tt,1,7,"For:",colors.black)
  2298. if item_for.name ~= money_name then
  2299. Draw.tt(tt,3,8,"Item Name: &"..Draw.getHexOf(itemName_c)..fixNames(item_for).." &"..Draw.getHexOf(colors.gray).."("..item_for.id..":"..item_for.dmg..") &"..Draw.getHexOf(colors.red).."x"..item_for.qty,colors.black)
  2300. else
  2301. Draw.tt(tt,3,8,"Item Name: &"..Draw.getHexOf(itemName_c)..ss(fixNames(item_for),38).." &"..Draw.getHexOf(colors.red).."x"..item_for.qty,colors.black)
  2302. end
  2303. Draw.tt(tt,3,9,"Enchantments: (to be added)",colors.black) --TODO: enchantment pulldowns
  2304. Draw.tt(tt,3,10,"Possible Trades: &"..Draw.getHexOf(colors.red)..amount_for,colors.black)
  2305. Draw.tt(tt,15,14,"Purchase",colors.black)
  2306. Draw.tt(tt,29,14,"Cancel",colors.black)
  2307. if amount_for > 0 then
  2308. Draw.tc(tc,14,14,colors.lime,23,14)
  2309. else
  2310. Draw.tc(tc,14,14,colors.gray,23,14)
  2311. end
  2312. Draw.tc(tc,28,14,colors.green,35,14)
  2313. Draw.draw(term,tc,1,4,2^15,tt)
  2314. draw_header("buy")
  2315. return amount,amount_for
  2316. end
  2317. while true do
  2318. sleep(0)
  2319. local available,possible = draw_temp()
  2320. local event,key,xpos,ypos = os.pullEvent()
  2321. if (event == "mouse_click") then
  2322. if ypos>3 then
  2323. if false and ypos == 13 and xpos>=11 and xpos<=16 then --For item per sale. --TODO
  2324. while true do
  2325. term.setCursorPos(11,13)
  2326. term.write(" ")
  2327. term.setCursorPos(11,13)
  2328. amount_for = tonumber(io.read())
  2329. if amount_for ~= nil then break else
  2330. --userInput("Please type in a number")
  2331. end
  2332. end
  2333. elseif ypos == 17 then
  2334. if xpos <= 23 and xpos >=14 and possible > 0 then --purchace
  2335. if available > 0 then
  2336. -- swap items
  2337. if currentPlayer ~= name then
  2338. if tradeTab.wants.name ~= money_name then
  2339. seller_iList = updatePlayerTable( tradeTab.wants, tradeTab.wants.qty,seller_iList)
  2340. updatePlayerTable(tradeTab.wants,-1*tradeTab.wants.qty)
  2341. else --transfer creds
  2342. seller_iList[money_name] = seller_iList[money_name] + tradeTab.wants.qty
  2343. player_iList[money_name] = player_iList[money_name] - tradeTab.wants.qty
  2344. end
  2345. if tradeTab.has.name ~= money_name then
  2346. updatePlayerTable( tradeTab.has, tradeTab.has.qty) -- add items to players inventory
  2347. seller_iList = updatePlayerTable( tradeTab.has, -1*tradeTab.has.qty,seller_iList)
  2348. else --transfer creds
  2349. seller_iList[money_name] = seller_iList[money_name] - tradeTab.has.qty
  2350. player_iList[money_name] = player_iList[money_name] + tradeTab.has.qty
  2351. end
  2352. seller_iList["trades"][tradeIndex]["total"] = seller_iList["trades"][tradeIndex]["total"]+1
  2353. save_player(currentPlayer)
  2354. save_player(name,seller_iList)
  2355. else
  2356. userInput("You can't trade with yourself silly!")
  2357. end
  2358. else
  2359. userInput("Sorry, this item is sold out!")
  2360. end
  2361. elseif xpos <=35 and xpos >= 28 then --cancel
  2362. return
  2363. end
  2364. end
  2365. --InsertShit
  2366.  
  2367. else
  2368. local valid,sel = parse_header(xpos,ypos)
  2369. if valid then
  2370. header_current = sel
  2371. os.queueEvent("updateHeader")
  2372. break
  2373. end
  2374. end
  2375. elseif event == "key" then
  2376. if restart(key) then
  2377. os.reboot()
  2378. end
  2379. elseif event == "updatePlayer" then
  2380. break --current_player changed
  2381. end
  2382. end
  2383. end
  2384.  
  2385. function display_buy()
  2386. local index = 0
  2387. local amount = 0
  2388. local list = deepcopy(global_iList_trades)
  2389. while currentPlayer ~= nil and header_current == header_sel[4] do
  2390. local scroll_pos,length = draw_buy(list,index)
  2391. while true do
  2392. local event,key,xpos,ypos = os.pullEvent()
  2393. if (event == "mouse_click") then
  2394. if ypos>3 then
  2395. if (xpos == 1 and length > 8) then --Scroll
  2396. if ypos < scroll_pos+3 and index > 0 then
  2397. index = index - 1
  2398. elseif ypos > scroll_pos+3 and index < length -8 then
  2399. index = index +1
  2400. end
  2401. break
  2402. elseif xpos>41 and ypos%2 == 1 and (index+(ypos-3)/2) <= length then
  2403. local function findItem()
  2404. local i = 1
  2405. for name,tradeIndexTab in pairs(list) do
  2406. for tradeIndex,tradeTab in pairs(tradeIndexTab) do
  2407. if i==(index+(ypos-3)/2) then
  2408. buy_inquire(name,tradeIndex)
  2409. return
  2410. else
  2411. i=i+1
  2412. end
  2413. end
  2414. end
  2415. end
  2416. findItem()
  2417. break
  2418. end
  2419. else
  2420. local valid,sel = parse_header(xpos,ypos)
  2421. if valid then
  2422. header_current = sel
  2423. os.queueEvent("updateHeader")
  2424. break
  2425. end
  2426. end
  2427. elseif event == "key" then
  2428. if (key == 200 or key == 17) and index > 0 then
  2429. index = index -1
  2430. break
  2431. elseif (key == 208 or key == 31) and index < length -8 then
  2432. index = index +1
  2433. break
  2434. elseif restart(key) then
  2435. os.reboot()
  2436. end
  2437. elseif event == "updatePlayer" then
  2438. break --current_player changed
  2439. end
  2440. end
  2441. end
  2442. end
  2443.  
  2444. function please_wait()
  2445. local x1,y1 = term.getSize()
  2446. local tt,tc = Draw.emptyScreen(term,x1,y1)
  2447. Draw.tc(tc,1,1,colors.white,x1,y1)
  2448. Draw.tc(tc,3,6,colors.lightBlue,x1-3,12)
  2449. Draw.tt(tt,5,7," Please do not step off the PIM while ",colors.brown)
  2450. Draw.tt(tt,5,8," the program moves your items. ",colors.brown)
  2451. Draw.tt(tt,5,10," Doing so may result in your items being ",colors.red)
  2452. Draw.tt(tt,5,11," lost forver ",colors.red)
  2453. Draw.draw(term,tc,1,1,2^15,tt)
  2454. end
  2455.  
  2456. --will check if a item stack will fit into a players inventory. return true if it can
  2457. function checkIfFits(item,amount)
  2458. local numSlotsNeeded = math.ceil(amount/item.maxSize)
  2459. if numSlotsNeeded > PIM.getFreeSlots() then return false else return true end
  2460. end
  2461. -- function to handle switching between tabs
  2462. function updateDisplay()
  2463. sleep(1)
  2464. function one()
  2465. while true do
  2466. local event = os.pullEvent()
  2467. if event == "updatePlayer" then
  2468. header_current = header_sel[1]
  2469. term.clear()
  2470. break
  2471. elseif event == "updateHeader" then
  2472. break
  2473. end
  2474. end
  2475. end
  2476. function two()
  2477. if currentPlayer == nil then os.pullEvent("updatePlayer") end
  2478. if header_current == header_sel[1] then display_deposit()
  2479. elseif header_current == header_sel[2] then display_withdraw()
  2480.  
  2481. elseif header_current == header_sel[3] then display_selling()
  2482. elseif header_current == header_sel[4] then display_buy()
  2483. end
  2484. end
  2485. local tot =1
  2486. while true do
  2487. sleep(0) --todo cleanup (only there since some displays dont take in user input)
  2488. --term.clear()
  2489. parallel.waitForAny(one,two)
  2490. end
  2491. end
  2492. --parse header input, returns the string of which tab was selected.
  2493. function parse_header(xpos,ypos)
  2494. if ypos == 1 then
  2495. if xpos <13 then
  2496. return true,header_sel[1]
  2497. elseif xpos>13 and xpos<28 then
  2498. return true,header_sel[2]
  2499. elseif xpos>28 and xpos<40 then
  2500. return true,header_sel[3]
  2501. elseif xpos>40 then
  2502. return true,header_sel[4]
  2503. end
  2504. end
  2505. return false,nil
  2506. end
  2507.  
  2508. function draw_header(sel)
  2509. local tc,tt = Draw.emptyScreen(term,51,3)
  2510. Draw.tc(tc,1,1,colors.yellow,51,3)
  2511. Draw.tc(tc,1,1,colors.green,51,1)
  2512. Draw.tc(tc,13,1,colors.yellow,13,1)
  2513. Draw.tc(tc,28,1,colors.yellow,28,1)
  2514. Draw.tc(tc,40,1,colors.yellow,40,1)
  2515. if header_sel[1] == sel then --deposit
  2516. Draw.tc(tc,1,1,colors.lime,12,1)
  2517. elseif header_sel[2] == sel then
  2518. Draw.tc(tc,14,1,colors.lime,27,1)
  2519. elseif header_sel[3] == sel then
  2520. Draw.tc(tc,29,1,colors.lime,39,1)
  2521. elseif header_sel[4] == sel then
  2522. Draw.tc(tc,41,1,colors.lime,51,1)
  2523. else
  2524. error("wrong arg passed to draw_header, see header_sel{}",2)
  2525. end
  2526. Draw.tt(tt,1,1," DEPOSIT | WITHDRAW | SELLING | BUY " ,colors.black)
  2527. if currentPlayer ~= nil then
  2528. Draw.tt(tt,1,2,"Welcome "..currentPlayer,colors.black)
  2529. Draw.tt(tt,1,3,money_name..": &"..Draw.getHexOf(colors.red)..player_iList[money_name],colors.black)
  2530. end
  2531. Draw.draw(term,tc,1,1,2^15,tt)
  2532.  
  2533. end
  2534. --if arg[1] is true then the dialog will be a yes/no dialog. Blank means just 'OK', "string" or "number" will prompt for a custom input of that type.
  2535. function userInput(text,...)
  2536. local screen = term
  2537. local x1,y1 = screen.getSize()
  2538. local t_bg,t_t = Draw.emptyScreen(screen,x1,y1)
  2539. local bg_color = colors.white
  2540. local fg_color = colors.lightBlue
  2541. local b_color = colors.yellow
  2542. local text_color = colors.white
  2543. local xpadding = 4
  2544. local text_start = math.floor(y1/2) -1
  2545. local lines = {}
  2546. if string.len(text) > x1-(2+xpadding*2) then
  2547. local newline = ""
  2548. local i = 1
  2549. for word in string.gmatch(text, "%S+") do
  2550. if string.len(newline.." "..word) > x1-10 then
  2551. lines[i] = newline
  2552. i=i+1
  2553. newline = word
  2554. else
  2555. newline = newline.." "..word
  2556. end
  2557. end
  2558. if newline ~= nil then
  2559. lines[#lines+1] = newline
  2560. end
  2561. text_start = math.floor(y1/2 - #lines/2 -1)
  2562. for i=1,#lines do
  2563. t_t = Draw.tt(t_t,math.floor((x1-string.len(lines[i]))/2),text_start+i,lines[i],text_color)
  2564. end
  2565. else --one line message
  2566. t_t = Draw.tt(t_t,math.floor((x1-string.len(text))/2),text_start,text,text_color)
  2567. end
  2568. t_bg = Draw.tc(t_bg,1,1,bg_color,x1,y1) --background
  2569. t_bg = Draw.tc(t_bg,xpadding,text_start-1,fg_color,x1-xpadding,text_start+4+#lines) --forground
  2570. if arg[1] == nil then
  2571. t_bg = Draw.tc(t_bg,math.floor(x1/2-1),text_start+#lines+3,b_color,math.floor(x1/2+2),text_start+#lines+3)
  2572. t_t = Draw.tt(t_t,math.floor(x1/2),text_start+#lines+3,"OK",colors.black)
  2573. elseif arg[1] == true then
  2574. t_bg = Draw.tc(t_bg,x1/2-9,text_start+#lines+3,b_color,x1/2-5,text_start+#lines+3)
  2575. t_bg = Draw.tc(t_bg,x1/2+5,text_start+#lines+3,b_color,x1/2+8,text_start+#lines+3)
  2576. t_t = Draw.tt(t_t,x1/2-8,text_start+#lines+3,"Yes",colors.black)
  2577. t_t = Draw.tt(t_t,x1/2+6,text_start+#lines+3,"No",colors.black)
  2578. elseif arg[1] == "string" or arg[1] == "number" then
  2579. t_t = Draw.tt(t_t,x1/2-12,text_start+#lines+2,">",text_color)
  2580. t_bg = Draw.tc(t_bg,x1/2-12,text_start+#lines+2,colors.black,x1/2+13,text_start+#lines+2)
  2581. end
  2582. Draw.drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
  2583. if arg[1] == "string" or arg[1] == "number" then
  2584. while true do
  2585. Draw.drawPictureTable(screen, t_bg, 1, 1, colors.black,t_t)
  2586. screen.setCursorPos(x1/2-11,text_start+#lines+2)
  2587. local input
  2588. if arg[2] and type(arg[2]) ~= "number" then
  2589. input = read("*")
  2590. else
  2591. if type(arg[2]) == "number" then
  2592. input = getCleanInputAt(x1/2-11,text_start+#lines+2,25,tostring(arg[2]))
  2593. else
  2594. input = getCleanInputAt(x1/2-11,text_start+#lines+2)
  2595. end
  2596. end
  2597. if arg[1] == "string" then
  2598. if input ~= "" and tostring(input) ~= nil then
  2599. return input
  2600. else
  2601. userInput("The input has to be a string")
  2602. end
  2603. elseif arg[1] == "number" then
  2604. if tonumber(input) ~= nil then
  2605. return tonumber(input)
  2606. elseif input == "" then
  2607. return 0
  2608. else
  2609. userInput("The input has to be a number")
  2610. end
  2611. end
  2612. end
  2613. else
  2614. while true do
  2615. local event, button1, xpos2, ypos2 = os.pullEvent()
  2616. if arg[1] and (event == "mouse_click" or event == "key") then
  2617. if event == "key" and button1 == 28 then
  2618. return true
  2619. end
  2620. if xpos2>=x1/2-10 and xpos2<=x1/2-5 and ypos2 == text_start+#lines+3 then
  2621. return true
  2622. elseif xpos2>=x1/2+4 and xpos2<=x1/2+8 and ypos2 == text_start+#lines+3 then
  2623. return false
  2624. end
  2625. elseif not arg[1] then
  2626. if event =="key" then
  2627. return true
  2628. elseif event == "mouse_click" and xpos2>=x1/2-2 and xpos2<=x1/2+2 and ypos2 == text_start+#lines+3 then
  2629. return true
  2630. end
  2631. end
  2632. end
  2633. end
  2634. end
  2635.  
  2636. function correctChestErrors()
  2637. while true do
  2638. local event = os.pullEvent("player_on")
  2639. local last_player = currentPlayer
  2640. while last_player == nil do
  2641. ERR("correctChestErrors","yep, it happened. currentPlayer should not be set this quickly")
  2642. last_player = currentPlayer
  2643. sleep(0)
  2644. end
  2645. event = os.pullEvent("player_off")
  2646.  
  2647. --wait for dontUpdate to change
  2648. while dontUpdate do
  2649. sleep(0)
  2650. end
  2651. local chestData = getChestData()
  2652. if #chestData > 0 then -- leftover items in chest
  2653. ERR("correctChestErrors", "Items in chest while dontUpdate is",dontUpdate,true)
  2654. ERR("correctChestErrors", "Number of items in chest",#chestData,true)
  2655. for k,v in pairs(chestData) do
  2656. ERR("correctChestErrors", " Item Found: ",fixNames(v),true)
  2657. end
  2658. ERR("correctChestErrors", " Adding items to inventory",last_player,true)
  2659. dontUpdate = true
  2660. load_player(last_player)
  2661. ae.suckAll(last_player)
  2662. load_player(nil)
  2663. dontUpdate = false
  2664. end
  2665. end
  2666. end
  2667.  
  2668. function print_inv()
  2669. term.clear()
  2670. sleep(1)
  2671. print("printinv")
  2672. for itemsz in tableIter(player_iList["items"]) do
  2673. print(itemsz.name)
  2674. end
  2675. io.read()
  2676. end
  2677.  
  2678. function testing()
  2679. while true do
  2680. os.pullEvent("updatePlayer")
  2681. if currentPlayer == nil then
  2682. print_inv()
  2683. else
  2684. --print("NIL!")
  2685. end
  2686. sleep(0)
  2687. end
  2688. end
  2689.  
  2690. function garbage()
  2691. sleep(3)
  2692. --local tabb = deepcopy(global_iList_IDs)
  2693. load_player("NuAoA")
  2694. term.clear()
  2695.  
  2696. local tab = deepcopy(player_iList)
  2697.  
  2698. for i=1,1000 do
  2699. term.clear()
  2700. term.setCursorPos(1,1)
  2701. print(i)
  2702. player_iList = deepcopy(tab)
  2703. player_iList.name = "FakePlayer_"..i
  2704. save_player("FakePlayer_"..i)
  2705.  
  2706. end
  2707. local tab2 = load_player("FakePlayer_999",true)
  2708. term.clear()
  2709. print(tab2.name)
  2710. io.read()
  2711. end
  2712.  
  2713. function display_startup()
  2714. local splashlogo = {
  2715. "444444444444444444 eeeeeee eeee eeee eee eeee ";
  2716. "444444444444444444 e e e e e e e e ";
  2717. "44ffffffffffffff44 e eeee e e e e eee ";
  2718. "44f0ffffffffffff44 e ee eeee e e e ";
  2719. "44ff0fffffffffff44 e e e e e e e e ";
  2720. "44f0ff000fffffff44 e e e e e eee eeee ";
  2721. "44ffffffffffffff44 ";
  2722. "44ffffffffffffff44 333 5 5 5 5 5555 333 ";
  2723. "44ffffffffffffff44 33 5 5 5 5 5 5 33 ";
  2724. "44ffffffffffffff44 33c 5 5 5 5 5 5 c33 ";
  2725. "44ffffffffffffff44 3 c 5555 5 5 555 c 3 ";
  2726. "444444444444444444 c 5 5 5 5 5 5 c ";
  2727. "444444444444444444 c 5 5 5 5 5 5 c ";
  2728. " 5 5 5555 5555 ";
  2729. "";
  2730. }
  2731. --[[
  2732. "8 8 8 8 8888 8888 8888 ";
  2733. "88 8 8 8 8 8 8 8 8 8 ";
  2734. "8 88 8 8 8888 8 8 8888 ";
  2735. "8 8 8888 8 8 8888 8 8 ";
  2736. "";
  2737. }
  2738. ]]--
  2739.  
  2740. term.clear()
  2741. Draw.draw(term, splashlogo, 2, 3, colors.black)
  2742. while notFirstBoot do
  2743. sleep(0.3)
  2744. Draw.draw(term,{"44f0ffffffffffff44",""} , 2, 8, colors.black)
  2745. sleep(0.3)
  2746. Draw.draw(term,{"44f0ff000fffffff44",""} , 2, 8, colors.black)
  2747. end
  2748. while true do
  2749. sleep(10000)
  2750. end
  2751. end
  2752.  
  2753. function checkshit()
  2754. while true do
  2755. local event = os.pullEvent()
  2756. ERR("checkshit",event)
  2757. end
  2758. end
  2759. --[[
  2760. term.clear()
  2761. local temp_tab = modem.wrapped.callRemote(modem.interface,"getAvailableItems")
  2762. for k,v in pairs(temp_tab) do
  2763. print(k)
  2764. kk = deepcopy(v)
  2765. for i=1,100 do
  2766. kk.dmg = i
  2767. if modem.wrapped.callRemote(modem.interface,"extractItem",kk,ae_direction) > 0 then
  2768. print(i)
  2769. end
  2770. end
  2771.  
  2772.  
  2773. ERR("decode",textutils.serialize(v))
  2774. end
  2775. sleep(3)
  2776. os.reboot()
  2777.  
  2778. print("|"..modem.wrapped.callRemote(modem.interface,"canHoldNewItem").."|")
  2779. print(modem.wrapped.callRemote(modem.interface,"getStoredItemCount"))
  2780. print(modem.wrapped.callRemote(modem.interface,"getUnusedItemCount"))
  2781. ]]--
  2782. --ae.extractItem()
  2783. --testae.extractItem()Search()
  2784. parallel.waitForAny(display_startup,startup)
  2785. parallel.waitForAll(updateCurrentPlayer,updateDisplay,correctChestErrors)--,garbage)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement