Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------intro--------------------------------
- -- One Sign Shop (ATM and Store) --
- -- --
- -- Created: 25/8/2020 Author: SuB_Zoid --
- -- --
- -- For Ultimate Reloaded --
- ---------------------------------------------------------------------
- ---------------------------------------------------------------------
- -- V v V v V v V v V v V v V Variables V v V v V v V v V v V v V --
- ---------------------------------------------------------------------
- mATM=peripheral.wrap("monitor_7") ------(vp1)
- mStore=peripheral.wrap("monitor_6") ------(vp2)
- psa=peripheral.wrap("playerSensor_8") ------(vp3)
- psb=peripheral.wrap("playerSensor_11") ------(vp4)
- psc=peripheral.wrap("playerSensor_3") ------(vp3)
- psd=peripheral.wrap("playerSensor_9") ------(vp4)
- me=peripheral.wrap("meBridge_0")
- store={} --store items Databasetable ------(v1)
- local T ={} --player DatabaseTable ------(v2)
- local bgc= colors.black --background color --*Temp val*------(v3)
- local ri=0 --rs current state --*func val*------(v4) Toggle()
- local dri=0 --rs last state --*func val*------(v5) Toggle()
- local AB=6 --player sensor to sensor length in x --*func val*------(v6) Triangulate
- local AC=6 --player sensor to sensor length in y --*func val*------(v7) Triangulate
- local AD=6 --player sensor to sensor length in x --*func val*------(v8) Triangulate
- local pInside={} --current players inside ------(v9)
- local minimumStock=1 --minimum stock (minimum stock is multiplied by the minimum selling quantity) ------(v10)
- local osTimer = 1 -- touch screen pull event timeout time
- ---------------------------------------------------------------------
- -- V v V v V v V v V v V v V functions V v V v V v V v V v V v V --
- ---------------------------------------------------------------------
- --ATM - Store Credit Purchase Toggle - RS Toggle input: LEFT ------(f1)
- function Toggle(name)
- local ri=redstone.getAnalogueInput("left") --rs current state
- local rsDistance=0 --distance from first lever to PC
- id=findPlayer(name)
- if ri~=dri and ri>0 then
- if ri==(15-rsDistance) then T[id].bal=T[id].bal + 50 end
- if ri==(14-rsDistance) then T[id].bal=T[id].bal + 100 end
- if ri==(13-rsDistance) then T[id].bal=T[id].bal + 500 end
- if ri==(12-rsDistance) then T[id].bal=T[id].bal + 1000 end
- if ri==(11-rsDistance) then T[id].bal=T[id].bal + 5000 end
- if ri==(10-rsDistance) then T[id].bal=T[id].bal + 10000 end
- end
- dri=ri --rs last state
- end
- function C(Mo) --clear monitor ------(f2)
- Mo.setBackgroundColor(bgc)
- Mo.clear()
- end
- function atmMonitor(name,mode) --ATM Monitor ------(f3)
- C(mATM)
- if mode == 0 then
- id=findPlayer(name)
- mATM.setCursorPos(2,6)
- mATM.write(" Welcome! We are Open ")
- mATM.setCursorPos(2,7)
- mATM.write(" Entrance --> ")
- elseif mode==1 then
- id=findPlayer(name)
- mATM.setCursorPos(2,6)
- mATM.write("Welcome ")
- mATM.write(T[id].player)
- mATM.write("!")
- mATM.setCursorPos(2,7)
- mATM.write("Your balance is: $")
- mATM.write(T[id].bal)
- end
- end
- function getNearby() --used inside triangulate ------(f4)
- a=psa.getNearbyPlayers()
- b=psb.getNearbyPlayers()
- c=psc.getNearbyPlayers()
- d=psd.getNearbyPlayers()
- pabcd={}
- for ia=1,table.getn(a) do
- table.insert(pabcd,{player=a[ia].player,da=a[ia].distance,db=26,dc=26,dd=26})
- for ib=1,table.getn(b) do
- if b[ib].player==a[ia].player then pabcd[ia].db=b[ib].distance end
- end
- for ic=1,table.getn(c) do
- if c[ic].player==a[ia].player then pabcd[ia].dc=c[ic].distance end
- end
- for id=1,table.getn(d) do
- if d[id].player==a[ia].player then pabcd[ia].dd=d[id].distance end
- end
- end
- return pabcd
- end
- function triangulate() --returns the players inside the room ------(f5)
- pabcd=getNearby()
- playersInside={}
- for id=1,table.getn(pabcd) do
- X=(pabcd[id].da^2+AB^2-pabcd[id].db^2)/(2*AB)
- Y=(pabcd[id].da^2+AC^2-pabcd[id].dc^2)/(2*AC)
- Z=-1*(pabcd[id].da^2+AD^2-pabcd[id].dd^2)/(2*AD)
- inOut=(X>0.29 and X<5.71) and (Y>0.29 and Y<4.71) and (Z>0 and Z<4.3) --in = true
- if inOut then
- table.insert(playersInside,pabcd[id].player)
- end
- end
- return playersInside
- end
- function register(name) --registers a new player to the database ------(f6)
- bool=true
- for i=1,table.getn(T) do
- if T[i].player == name then
- bool=false
- break
- end
- end
- if bool then
- write(name)
- print(" registered!")
- table.insert(T,{player=name,bal=0})
- end
- end
- function findPlayer(name) --findPlayers player's location in database ------(f7)
- for i=1,table.getn(T) do
- if T[i].player == name then
- return(i)
- end
- end
- end
- function findItem(name) --findPlayers player's location in database ------(f7.1)
- for i=1,table.getn(store) do
- if store[i].item == name then
- return(i)
- end
- end
- end
- function backup() --backup ------(f8)
- local output = textutils.serialize(T)
- local handle = assert(fs.open("vars", "w"), "Couldn't save vars") -- this will give you an error if something's gone wrong
- handle.write(output) -- this is where the magic happens, we're storing the entire "target" table
- handle.close()
- end
- function load()
- local handle = assert(fs.open("vars", "r"), "Couldn't load vars") -- this file is opened in read mode
- local input = handle.readAll() -- input is now the serialized table
- handle.close()
- return textutils.unserialize(input) -- this will decode our table
- end
- function getData() --Data Function (you can change the link here)
- local link = "https://docs.google.com/spreadsheets/d/1BXy2tNcxcvf8EJX4__cicnSpYHB3Oh4QlRGn_MW1mY8/export?format=csv"
- local fileName = "data.csv"
- shell.run("wget", link, fileName)
- local csv = fs.open(fileName, "r")
- local cR = 1 -- counter row
- local result = {}
- while true do
- local line = csv.readLine()
- if not line then break end --EOF
- cC = 1 -- counter column
- last = ""
- out = {}
- for i in string.gmatch(line,"[^,]*") do
- if i ~= "" then
- out[cC] = i
- cC = cC+1
- elseif last == "" then
- out[cC] = i
- cC = cC+1
- end
- last = i
- end
- result[cR] = out
- cR = cR+1
- end
- csv.close()
- fs.delete(fileName)
- --print("result[4][1] (4th row, 1st column)")
- --print(result[4][1])
- local dataStore={}
- table.insert(dataStore,{item="nil",name="nil",meta=0,nbt ="",qtyS=0,price=0})
- table.insert(dataStore,{item="nil2",name="nil",meta=0,nbt ="",qtyS=0,price=0})
- for i=3,result[1][1] do
- local itemNameMerge=result[i][3]..":"..result[i][4]
- table.insert(dataStore,{item=result[i][2],name=itemNameMerge,meta=tonumber(result[i][5]),nbt =result[i][6],qtyS=tonumber(result[i][8]),price=tonumber(result[i][1]),available=false,stock=0,craftable=false})
- end
- return dataStore
- end
- function buy(idItem) --buys item, enter item id in store[id] ------(f9)
- local name = pInside[1]
- local id=findPlayer(name)
- if idItem ~= 0 and T[id].bal>=store[idItem].price then
- if store[idItem].available then --successfull buy
- mStore.setBackgroundColor(colors.black)
- P("monitor_6",{2,17},colors.green,0,tostring(store[idItem].qtyS) .. " " .. store[idItem].item .. " purchased! ")
- mStore.setTextColor(colors.white)
- if store[idItem].craftable and ((minimumStock+2)*store[idItem].qtyS>store[idItem].stock) then
- me.craft(store[idItem].name,store[idItem].meta,store[idItem].qtyS,store[idItem].nbt) --this will make sure items are automatically crafted when they run out
- end
- T[id].bal=T[id].bal-store[idItem].price
- me.retrieve(store[idItem].name,store[idItem].meta,store[idItem].qtyS,"up",store[idItem].nbt)
- elseif (not store[idItem].available) and store[idItem].craftable then --no stock but still craftable
- mStore.setBackgroundColor(colors.black)
- P("monitor_6",{2,17},colors.yellow,0,"Crafting " .. tostring(store[idItem].qtyS) .." " .. store[idItem].item .. " ")
- mStore.setTextColor(colors.white)
- local originalStock=store[idItem].stock
- local breakLoop=false
- for i=1,store[idItem].qtyS do
- local ccc=0
- availability()
- beforeCraftStock=store[idItem].stock
- me.craft(store[idItem].name,store[idItem].meta,1,store[idItem].nbt)
- local a1,a2,a3,a4 = os.pullEvent("craftingComplete")
- local MaxCountsAllowed=0.11*a4+5
- local crafting=true
- local breakLoop=0
- while crafting do
- availability()
- mStore.setBackgroundColor(colors.black)
- P("monitor_6",{1,21},colors.yellow,0,"Crafted: " .. tostring(store[idItem].stock-originalStock))
- mStore.setTextColor(colors.white)
- if store[idItem].stock > beforeCraftStock then
- crafting=false
- print("wtf is this")
- end
- if ccc>=MaxCountsAllowed then
- crafting=false
- breakLoop=1
- end
- sleep(0.2)
- ccc=ccc+1
- if store[idItem].stock >= store[idItem].qtyS then
- sleep(0.5)
- me.retrieve(store[idItem].name,store[idItem].meta,store[idItem].qtyS,"up",store[idItem].nbt)
- crafting=false
- breakLoop=2
- T[id].bal=T[id].bal-store[idItem].price
- P("monitor_6",{1,21},colors.white,0," ")
- P("monitor_6",{2,17},colors.green,0,tostring(store[idItem].qtyS) .. " " .. store[idItem].item .. " purchased! ")
- mStore.setTextColor(colors.white)
- end
- end
- P("monitor_6",{1,21},colors.white,0," ")
- print("breakLoop="..breakLoop)
- if breakLoop==2 then break end --succesfull crafting and retrieving
- if breakLoop==1 then --craft unsuccessfull - break whole operation
- mStore.setBackgroundColor(colors.black)
- P("monitor_6",{2,17},colors.red,0,"Ingredients Not Available ")
- mStore.setTextColor(colors.white)
- break
- end
- end
- me.craft(store[idItem].name,store[idItem].meta,store[idItem].qtyS,store[idItem].nbt)
- end
- elseif idItem ~= 0 and T[id].bal<=store[idItem].price then
- mStore.setBackgroundColor(colors.black)
- P("monitor_6",{2,17},colors.red,0,"Purchase failed: Refill balance ")
- mStore.setTextColor(colors.white)
- end
- end
- function availability() ------(f10)
- currentItems={}
- currentCraftable={}
- currentItems=me.listItems() --compare: name, amount, meta, nbt
- currentCraftable=me.listCraft() ------------------------********* double check me ********
- for i=1,table.getn(store) do
- for j=1,table.getn(currentItems) do --available
- if store[i].name==currentItems[j].name and store[i].meta==currentItems[j].meta and store[i].nbt==currentItems[j].nbt then
- store[i].stock=currentItems[j].amount
- if currentItems[j].amount > (minimumStock*store[i].qtyS) then
- store[i].available=true
- store[i].stock=currentItems[j].amount
- else
- store[i].available=false
- end
- break
- end
- store[i].available=false
- store[i].stock=0
- end
- for k=1,table.getn(currentCraftable) do --craftable
- if store[i].name==currentCraftable[k].name and store[i].meta==currentCraftable[k].meta and store[i].nbt==currentCraftable[k].nbt then
- store[i].craftable=true
- break
- end
- store[i].craftable=false
- end
- end
- end
- local tableStart=1 --used for scrolling the onScreen table used in f11
- local touchFeedBack = false
- local x1=0
- local y1=0 -- touch screen pos
- function storeMonitor(name) ------(f11)
- local line={1,10}
- local txtc = colors.white
- local id=findPlayer(name)
- local onScreen= {} --used to convert between onscreen values and T
- local printableCounter= 0 --used to count printable values
- local counter=1 --onScreen timer
- --clear + scroll
- for i=3,19 do
- mStore.setCursorPos(1,i)
- mStore.setBackgroundColor(colors.black)
- mStore.write(" ")
- end
- P("monitor_6",{1,1},txtc,0," ")
- P("monitor_6",{1,28},txtc,0," ")
- mStore.setBackgroundColor(colors.lightGray)
- mStore.setCursorPos(1,4)
- mStore.write("^")
- mStore.setCursorPos(1,19)
- mStore.write("v")
- mStore.setBackgroundColor(colors.black)
- --2 lines space for stats
- line=P("monitor_6",line,txtc,0," ")
- line=P("monitor_6",{line[1],41},txtc,0," ")
- line={1,2}
- line=P("monitor_6",line,txtc,0,"Player: ")
- line=P("monitor_6",line,txtc,0,pInside[1])
- line=P("monitor_6",{line[1],32},txtc,0,"balance: $")
- line=P("monitor_6",line,txtc,1,T[id].bal)
- line=P("monitor_6",{line[1],2},txtc,0,"System Status: ")
- --1 line table header
- mStore.setBackgroundColor(colors.purple)
- mStore.setTextColor(colors.black)
- mStore.setCursorPos(1,3)
- mStore.write(" Item Qty Price Stock Craftable")
- mStore.setTextColor(colors.white)
- mStore.setBackgroundColor(colors.black)
- --table content
- line={4,1}
- if tableStart == 0 then
- line=P("monitor_6",{line[1],2},txtc,1," ")
- onScreen[counter]=0
- counter=counter+1
- end
- for i=1,table.getn(store) do
- if store[i].available or store[i].craftable then
- printableCounter=printableCounter+1
- if printableCounter >= tableStart then
- onScreen[counter]=i
- if (counter+tableStart)%2==0 then
- mStore.setBackgroundColor(colors.black)
- else
- mStore.setBackgroundColor(colors.gray)
- end
- if x1>1 and x1<=45 and y1<=19 and y1>3 and counter == y1-3 then
- print("hi- x:" .. tostring(x1) .. " y:" .. tostring(y1))
- if T[id].bal >= store[i].price then
- mStore.setBackgroundColor(colors.green)
- else
- mStore.setBackgroundColor(colors.red)
- end
- end
- line=P("monitor_6",{line[1],2},txtc,0,store[i].item)
- line=P("monitor_6",line,txtc,0," ")
- line=P("monitor_6",{line[1],23},txtc,0,tostring(store[i].qtyS))
- line=P("monitor_6",{line[1],27},txtc,0,"$ ")
- line=P("monitor_6",line,txtc,0,store[i].price)
- line=P("monitor_6",{line[1],37},txtc,0,tostring(store[i].stock))
- if store[i].craftable then
- line=P("monitor_6",{line[1],45},txtc,1,"Yes")
- else
- line=P("monitor_6",{line[1],45},txtc,1,"No")
- end
- counter=counter+1
- end
- end
- end
- x1,y1=touch()
- --print("monitor cought - x1:" .. tostring(x1) .. " y1:" .. tostring(y1))
- if x1==1 and y1==4 then
- if tableStart>1 then
- tableStart=tableStart-15
- else
- mStore.setBackgroundColor(colors.red)
- mStore.setCursorPos(1,4)
- mStore.write("^")
- mStore.setBackgroundColor(colors.black)
- sleep(0.1)
- end
- elseif x1==1 and y1==19 then
- if tableStart<=(printableCounter-15) then
- tableStart=tableStart+15
- else
- mStore.setBackgroundColor(colors.red)
- mStore.setCursorPos(1,19)
- mStore.write("v")
- mStore.setBackgroundColor(colors.black)
- sleep(0.1)
- end
- end
- if tableStart==0 and y1==4 then return 0 end
- if x1>1 and x1<=45 and y1<=19 and y1>3 and table.getn(onScreen)>=(y1-3) and (y1-3)>0 then
- print("x1: " .. tostring(x1) .. " y1: " .. tostring(y1))
- print("purchase:" .. store[(onScreen[y1-3])].item)
- print(table.getn(onScreen))
- return onScreen[y1-3]
- end
- return 0
- end
- function P(monitor,pos,textColor,special,txt) --monitor print function ------(f12)
- -- USAGE: P("monitor",i,txtc,0,"<enter text here>")
- --special: # of lines to skip
- -- "m" for middle txt + skip 1 line
- -- "m2" for middle txt + skip 2 lines
- M=peripheral.wrap(monitor)
- if special == "m" or special == "m2" then
- pos[2]= math.floor(71/2 - string.len(txt)/2)
- end
- M.setCursorPos(pos[2],pos[1])
- M.setTextColor(textColor)
- M.write(txt)
- if special ~= "m" and special ~= "m2" then
- if special > 0 then
- lineValue= pos[1] + special
- letterValue=2
- elseif special ==0 then
- lineValue= pos[1]
- letterValue= pos[2] + string.len(txt)
- end
- else
- if special == "m" then
- lineValue= pos[1] + 1
- letterValue= 2
- elseif special == "m2" then
- lineValue= pos[1] + 2
- letterValue= 2
- end
- end
- return({lineValue,letterValue})
- end
- function touch() --monitor touch function ------(f12)
- local Y3=0
- local X3=0
- local eventtocatch = 'monitor_touch' --(for example)
- local timeout = os.startTimer(osTimer)
- local A,side,X2,Y2 = os.pullEvent()
- if A=='timer' and side==timeout then
- Y3=0
- X3=0
- elseif A==eventtocatch and side=="monitor_6"then
- X3=X2
- Y3=Y2
- end
- --print("tourch return - x:" .. tostring(X3) .. " y:" .. tostring(Y3))
- return X3,Y3
- end
- function resetBalance() --Reset Balance for player inside ------(f13)
- local name = pInside[1]
- local id=findPlayer(name)
- T[id].bal=0
- end
- ---------------------------------------------------------------------
- -- V v V v V v V v V v V v V Main Loop V v V v V v V v V v V v V --
- ---------------------------------------------------------------------
- print("loading...")
- for i=1,10 do
- sleep(0.1)
- write(i*10)
- print("%")
- end
- print("loading Complete...")
- T=load()
- store=getData()
- availability()
- C(mStore)
- C(mATM)
- local r1=0
- local r2=0
- write(findItem("Redstone"))
- write(": ")
- write(store[findItem("Redstone")].item)
- write(store[findItem("Redstone")].price)
- write("availability: ")
- if store[findItem("Redstone")].available then write("yes") else write("no") end
- write("stock: ")
- print(store[findItem("Redstone")].stock)
- while true do
- pInside=triangulate()
- if table.getn(pInside)==0 then
- redstone.setOutput("right",true) -- shop empty
- atmMonitor("test",0)
- pInside[1]="test"
- sleep(0.1)
- C(mStore)
- elseif table.getn(pInside)==1 then
- redstone.setOutput("right",false) --player inside
- register(pInside[1])
- buy(storeMonitor(pInside[1]))
- availability()
- Toggle(pInside[1])
- atmMonitor(pInside[1],1)
- else
- redstone.setOutput("right",true) -- ERROR! two players inside
- sleep(0.05)
- end
- --reset balance function
- r1=redstone.getInput("back")
- if (r1 and (not r2)) then
- resetBalance()
- end
- r2=r1
- backup()
- end
Add Comment
Please, Sign In to add comment