Advertisement
SwellzD

just_shop

Jun 19th, 2025 (edited)
1,097
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.39 KB | None | 0 0
  1. -- Configuration
  2. local CHEST_SIDE = "minecraft:chest_367"
  3. local MONITOR_SIDE = "monitor_12"
  4. local PLAYER_CHEST_SIDE = "minecraft:barrel_1343"
  5. local ADMIN_PASSWORD = "sanabi"
  6. local FIXED_PRICE_FACTOR = 1
  7. local BUTTON_HIGHLIGHT_TIME = 0.3
  8.  
  9. --Muchtix loh
  10.  
  11. -- System settings
  12. local data = {}
  13. local monitor = peripheral.wrap(MONITOR_SIDE)
  14. local chest = peripheral.wrap(CHEST_SIDE)
  15. local playerChest = peripheral.wrap(PLAYER_CHEST_SIDE)
  16. monitor.setTextScale(0.6)
  17. local lastHighlight = 0
  18. local highlightedButton = nil
  19. local inTransaction = false
  20.  
  21. -- Sync resources with chest
  22. local function syncWithChest()
  23.     -- Reset amounts
  24.     for _, resource in pairs(data.resources) do
  25.         resource.amount = 0
  26.     end
  27.    
  28.     -- Scan chest
  29.     for slot, stack in pairs(chest.list()) do
  30.         if data.resources[stack.name] then
  31.             data.resources[stack.name].amount = data.resources[stack.name].amount + stack.count
  32.         end
  33.     end
  34. end
  35.  
  36. -- Initialize data
  37. local function initData()
  38.     data = {
  39.         resources = {
  40.             ["minecraft:iron_ingot"] = {name = "Iron", base = 1, amount = 0},
  41.             ["minecraft:gold_ingot"] = {name = "Gold", base = 1, amount = 0},
  42.             ["minecraft:diamond"] = {name = "Diamond", base = 5, amount = 0},
  43.             ["create:zinc_ingot"] = {name = "Zinc", base = 4, amount = 0}
  44.         },
  45.         balance = 0,
  46.         discount = 0.7,
  47.         selectedItem = ""
  48.     }
  49.     syncWithChest()
  50. end
  51.  
  52. -- Calculate prices
  53. local function calculatePrices()
  54.     syncWithChest() -- Always sync before calculating
  55.    
  56.     local total = 0
  57.     for _, res in pairs(data.resources) do
  58.         total = total + res.amount
  59.     end
  60.  
  61.     local prices = {}
  62.     for id, res in pairs(data.resources) do
  63.         if res.amount == 0 then
  64.             prices[id] = {
  65.                 buy = math.huge,
  66.                 sell = res.base * FIXED_PRICE_FACTOR
  67.             }
  68.         else
  69.             local buyPrice = (total / (res.amount + 1)) * res.base
  70.             prices[id] = {
  71.                 buy = buyPrice,
  72.                 sell = buyPrice * data.discount
  73.             }
  74.         end
  75.     end
  76.     return prices
  77. end
  78.  
  79. -- Draw numeric keyboard with cancel button
  80. local function drawNumericKeyboard()
  81.     local keys = {
  82.         "7","8","9",
  83.         "4","5","6",
  84.         "1","2","3",
  85.         "0","<","OK"
  86.     }
  87.    
  88.     local w, h = monitor.getSize()
  89.     local keyWidth = 4
  90.     local keyHeight = 2
  91.     local startX = math.floor((w - 3 * keyWidth) / 2)
  92.     local startY = h - 15
  93.    
  94.     for i, key in ipairs(keys) do
  95.         local row = math.floor((i-1)/3)
  96.         local col = (i-1) % 3
  97.        
  98.         local x = startX + col * (keyWidth + 1)
  99.         local y = startY + row * (keyHeight + 1)
  100.        
  101.         monitor.setCursorPos(x, y)
  102.         monitor.write("["..key.."]")
  103.     end
  104.    
  105.     -- Cancel button at bottom
  106.     monitor.setCursorPos(math.floor(w/2)-5, h-2)
  107.     monitor.write("[ Cancel ]")
  108. end
  109.  
  110. -- Highlight button temporarily
  111. local function highlightButton(name, x, y, width)
  112.     monitor.setCursorPos(x, y)
  113.     monitor.setBackgroundColor(colors.gray)
  114.     monitor.write(string.rep(" ", width))
  115.     monitor.setCursorPos(x, y)
  116.     monitor.write(name)
  117.     monitor.setBackgroundColor(colors.black)
  118.     highlightedButton = {name = name, x = x, y = y, width = width}
  119.     lastHighlight = os.clock()
  120. end
  121.  
  122. -- Highlight key on keyboard
  123. local function highlightKey(x, y, key)
  124.     monitor.setCursorPos(x, y)
  125.     monitor.setBackgroundColor(colors.gray)
  126.     monitor.write("["..key.."]")
  127.     monitor.setBackgroundColor(colors.black)
  128. end
  129.  
  130. -- Draw UI with button highlighting
  131. local function drawUI(prices)
  132.     monitor.clear()
  133.     local w, h = monitor.getSize()
  134.    
  135.     -- Header with balance
  136.     monitor.setCursorPos(1, 1)
  137.     monitor.write("SHOP")
  138.     monitor.setCursorPos(w - 10, 1)
  139.     monitor.write("$:"..data.balance)
  140.    
  141.     -- Resources list
  142.     local y = 3
  143.     for id, res in pairs(data.resources) do
  144.         local isSelected = (id == data.selectedItem)
  145.         if isSelected then
  146.             monitor.setBackgroundColor(colors.gray)
  147.         end
  148.        
  149.         monitor.setCursorPos(1, y)
  150.         if prices[id].buy == math.huge then
  151.             monitor.write(string.format("%s: Sold out", res.name))
  152.         else
  153.             monitor.write(string.format("%s: buy %.1f", (res.name)..(" x ")..tostring(res.amount), prices[id].buy))
  154.         end
  155.        
  156.         monitor.setCursorPos(1, y+1)
  157.         monitor.write(string.format("  sell: %.1f", prices[id].sell))
  158.        
  159.         if isSelected then
  160.             monitor.setBackgroundColor(colors.black)
  161.         end
  162.         y = y + 3
  163.     end
  164.    
  165.     -- Buttons with highlighting - moved down
  166.     local now = os.clock()
  167.     if highlightedButton and (now - lastHighlight < BUTTON_HIGHLIGHT_TIME) then
  168.         monitor.setCursorPos(highlightedButton.x, highlightedButton.y)
  169.         monitor.setBackgroundColor(colors.gray)
  170.         monitor.write(highlightedButton.name)
  171.         monitor.setBackgroundColor(colors.black)
  172.     else
  173.         highlightedButton = nil
  174.         -- Moved buttons down one line
  175.         monitor.setCursorPos(1, h-4)
  176.         monitor.write("[Buy] [Sell]")
  177.        
  178.         -- Admin button in bottom right corner
  179.         monitor.setCursorPos(w - 7, h-1)
  180.         monitor.write("[Admin]")
  181.     end
  182. end
  183.  
  184. -- Process transaction
  185. local function processTransaction(isBuy)
  186.     if data.selectedItem == "" then
  187.         monitor.clear()
  188.         monitor.setCursorPos(1, 1)
  189.         monitor.write("Select an item first!")
  190.         sleep(2)
  191.         return
  192.     end
  193.    
  194.     local resID = data.selectedItem
  195.     inTransaction = true
  196.    
  197.     while inTransaction do
  198.         monitor.clear()
  199.         monitor.setCursorPos(1, 1)
  200.         monitor.write(isBuy and "BUY" or "SELL")
  201.         monitor.setCursorPos(1, 2)
  202.         monitor.write("Item: "..data.resources[resID].name)
  203.        
  204.         local count = 0
  205.         local inputStr = ""
  206.         local w, h = monitor.getSize()
  207.         local startX = math.floor((w - 3 * 4) / 2)
  208.         local startY = h - 15
  209.        
  210.         -- Input amount with numeric keyboard
  211.         local inputActive = true
  212.         while inputActive do
  213.             -- Clear input area
  214.             monitor.setCursorPos(1, 3)
  215.             monitor.write("Amount: "..inputStr..string.rep(" ", 10))
  216.            
  217.             drawNumericKeyboard()
  218.            
  219.             local event, side, x, y = os.pullEvent("monitor_touch")
  220.            
  221.             -- Check if Cancel button pressed
  222.             if y >= h-3 and y <= h-1 and x >= math.floor(w/2)-5 and x <= math.floor(w/2)+5 then
  223.                 inTransaction = false
  224.                 return
  225.             end
  226.            
  227.             -- Calculate which key was pressed
  228.             local row = math.floor((y - startY) / 3)
  229.             local col = math.floor((x - startX) / 5)
  230.            
  231.             if row >= 0 and col >= 0 and row <= 3 and col <= 2 then
  232.                 local keyIndex = row * 3 + col + 1
  233.                 local keys = {"7","8","9","4","5","6","1","2","3","0","<","OK"}
  234.                
  235.                 if keyIndex >= 1 and keyIndex <= #keys then
  236.                     local key = keys[keyIndex]
  237.                    
  238.                     -- Highlight the key briefly
  239.                     highlightKey(startX + col * 5, startY + row * 3, key)
  240.                     sleep(0.1) -- Make highlight visible
  241.                    
  242.                     if key == "<" then
  243.                         inputStr = inputStr:sub(1, -2)
  244.                     elseif key == "OK" then
  245.                         count = tonumber(inputStr)
  246.                         if count and count > 0 then
  247.                             inputActive = false
  248.                         end
  249.                     else
  250.                         inputStr = inputStr .. key
  251.                     end
  252.                 end
  253.             end
  254.         end
  255.        
  256.         local prices = calculatePrices()
  257.        
  258.         if isBuy then
  259.             if prices[resID].buy == math.huge then
  260.                 monitor.clear()
  261.                 monitor.setCursorPos(1, 1)
  262.                 monitor.write("Error: item sold out!")
  263.                 sleep(2)
  264.                 return
  265.             end
  266.            
  267.             local cost = math.floor(prices[resID].buy * count)
  268.             if data.balance < cost then
  269.                 monitor.clear()
  270.                 monitor.setCursorPos(1, 1)
  271.                 monitor.write("Not enough points!")
  272.                 sleep(2)
  273.                 return
  274.             end
  275.            
  276.             -- Check stock
  277.             local available = 0
  278.             for _, stack in pairs(chest.list()) do
  279.                 if stack.name == resID then
  280.                     available = available + stack.count
  281.                 end
  282.             end
  283.            
  284.             if available < count then
  285.                 monitor.clear()
  286.                 monitor.setCursorPos(1, 1)
  287.                 monitor.write("Not enough items in shop!")
  288.                 sleep(2)
  289.                 return
  290.             end
  291.            
  292.             -- Complete purchase (move to player chest)
  293.             local moved = 0
  294.             for slot, stack in pairs(chest.list()) do
  295.                 if stack.name == resID and count > 0 then
  296.                     local toTake = math.min(count, stack.count)
  297.                     -- Move to player chest
  298.                     local transferred = chest.pushItems(peripheral.getName(playerChest), slot, toTake)
  299.                     if transferred > 0 then
  300.                         moved = moved + transferred
  301.                         count = count - transferred
  302.                         if count == 0 then break end
  303.                     end
  304.                 end
  305.             end
  306.            
  307.             if moved == 0 then
  308.                 monitor.clear()
  309.                 monitor.setCursorPos(1, 1)
  310.                 monitor.write("Error: no space in player chest!")
  311.                 sleep(2)
  312.                 return
  313.             end
  314.            
  315.             data.balance = data.balance - math.floor(prices[resID].buy * moved)
  316.            
  317.             monitor.clear()
  318.             monitor.setCursorPos(1, 1)
  319.             monitor.write("Success! Charged: "..(math.floor(prices[resID].buy * moved)))
  320.             monitor.setCursorPos(1, 2)
  321.             monitor.write("Balance: "..data.balance)
  322.             sleep(3)
  323.             inTransaction = false
  324.         else
  325.             -- Sell items
  326.             local reward = math.floor(prices[resID].sell * count)
  327.            
  328.             -- Check player inventory
  329.             local available = 0
  330.             for _, stack in pairs(playerChest.list()) do
  331.                 if stack.name == resID then
  332.                     available = available + stack.count
  333.                 end
  334.             end
  335.            
  336.             if available < count then
  337.                 monitor.clear()
  338.                 monitor.setCursorPos(1, 1)
  339.                 monitor.write("Not enough items!")
  340.                 sleep(2)
  341.                 return
  342.             end
  343.            
  344.             -- Complete sale (move to shop chest)
  345.             local moved = 0
  346.             for slot, stack in pairs(playerChest.list()) do
  347.                 if stack.name == resID and count > 0 then
  348.                     local toSell = math.min(count, stack.count)
  349.                     -- Move to shop chest
  350.                     local transferred = playerChest.pushItems(peripheral.getName(chest), slot, toSell)
  351.                     if transferred > 0 then
  352.                         moved = moved + transferred
  353.                         count = count - transferred
  354.                         if count == 0 then break end
  355.                     end
  356.                 end
  357.             end
  358.            
  359.             if moved == 0 then
  360.                 monitor.clear()
  361.                 monitor.setCursorPos(1, 1)
  362.                 monitor.write("Error: no space in shop chest!")
  363.                 sleep(2)
  364.                 return
  365.             end
  366.            
  367.             data.balance = data.balance + math.floor(prices[resID].sell * moved)
  368.            
  369.             monitor.clear()
  370.             monitor.setCursorPos(1, 1)
  371.             monitor.write("Success! Added: "..(math.floor(prices[resID].sell * moved)))
  372.             monitor.setCursorPos(1, 2)
  373.             monitor.write("Balance: "..data.balance)
  374.             sleep(3)
  375.             inTransaction = false
  376.         end
  377.     end
  378.    
  379.     syncWithChest() -- Update after transaction
  380. end
  381.  
  382. -- Admin panel
  383. local function adminPanel()
  384.     local adminActive = true
  385.     while adminActive do
  386.         monitor.clear()
  387.         monitor.setCursorPos(1, 1)
  388.         monitor.write("ADMIN PANEL")
  389.         monitor.setCursorPos(1, 2)
  390.         monitor.write("Password: ")
  391.         local inputPass = read("*")
  392.        
  393.         if inputPass ~= ADMIN_PASSWORD then
  394.             monitor.setCursorPos(1, 3)
  395.             monitor.write("Wrong password!")
  396.             sleep(2)
  397.             return
  398.         end
  399.        
  400.         local choice = 0
  401.         while choice ~= 4 do
  402.             monitor.clear()
  403.             monitor.setCursorPos(1, 1)
  404.             monitor.write("1. Add resource")
  405.             monitor.setCursorPos(1, 2)
  406.             monitor.write("2. Change discount")
  407.             monitor.setCursorPos(1, 3)
  408.             monitor.write("3. Set balance")
  409.             monitor.setCursorPos(1, 4)
  410.             monitor.write("4. Back")
  411.            
  412.             choice = tonumber(read())
  413.             if choice == 1 then
  414.                 monitor.setCursorPos(1, 5)
  415.                 monitor.write("Item ID: ")
  416.                 local id = read()
  417.                
  418.                 monitor.setCursorPos(1, 6)
  419.                 monitor.write("Name: ")
  420.                 local name = read()
  421.                
  422.                 monitor.setCursorPos(1, 7)
  423.                 monitor.write("Base price: ")
  424.                 local base = tonumber(read())
  425.                
  426.                 if id and name and base then
  427.                     data.resources[id] = {
  428.                         name = name,
  429.                         base = base,
  430.                         amount = 0
  431.                     }
  432.                     monitor.setCursorPos(1, 8)
  433.                     monitor.write("Resource added!")
  434.                     sleep(2)
  435.                 end
  436.             elseif choice == 2 then
  437.                 monitor.setCursorPos(1, 5)
  438.                 monitor.write("New discount (0.1-0.9): ")
  439.                 local discount = tonumber(read())
  440.                
  441.                 if discount and discount >= 0.1 and discount <= 0.9 then
  442.                     data.discount = discount
  443.                     monitor.setCursorPos(1, 6)
  444.                     monitor.write("Discount updated!")
  445.                     sleep(2)
  446.                 end
  447.             elseif choice == 3 then
  448.                 monitor.setCursorPos(1, 5)
  449.                 monitor.write("New balance: ")
  450.                 local newBalance = tonumber(read())
  451.                
  452.                 if newBalance then
  453.                     data.balance = newBalance
  454.                     monitor.setCursorPos(1, 6)
  455.                     monitor.write("Balance updated!")
  456.                     sleep(2)
  457.                 end
  458.             elseif choice == 4 then
  459.                 adminActive = false
  460.             end
  461.         end
  462.     end
  463. end
  464.  
  465. -- Main loop
  466. initData()
  467.  
  468. while true do
  469.     local prices = calculatePrices()
  470.     drawUI(prices)
  471.    
  472.     local event, side, x, y = os.pullEvent("monitor_touch")
  473.     local w, h = monitor.getSize()
  474.    
  475.     -- Resource selection
  476.     if y >= 3 and y <= h-5 then
  477.         local resourceY = 3
  478.         for id, res in pairs(data.resources) do
  479.             if y >= resourceY and y < resourceY + 2 then
  480.                 data.selectedItem = id
  481.                 break
  482.             end
  483.             resourceY = resourceY + 3
  484.         end
  485.     end
  486.    
  487.     -- Button handling with highlighting
  488.     if not inTransaction then
  489.         -- Buy/Sell buttons moved down to h-4
  490.         if y >= h-4 and y <= h-3 then
  491.             if x >= 1 and x <= 4 then -- Buy
  492.                 highlightButton("Buy", 1, h-4, 4)
  493.                 processTransaction(true)
  494.             elseif x >= 6 and x <= 10 then -- Sell
  495.                 highlightButton("Sell", 6, h-4, 4)
  496.                 processTransaction(false)
  497.             end
  498.         -- Admin button in bottom right corner
  499.         elseif y >= h-1 and x >= w-7 and x <= w-1 then
  500.             highlightButton("Admin", w-7, h-1, 7)
  501.             adminPanel()
  502.         end
  503.     end
  504. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement