· 3 months ago · Jun 19, 2025, 01:55 PM
1-- Configuration
2local CHEST_SIDE = "top"
3local MONITOR_SIDE = "right"
4local PASSWORD = "admin123"
5local FIXED_PRICE_FACTOR = 100
6
7-- System settings
8local data = {}
9local monitor = peripheral.wrap(MONITOR_SIDE)
10local chest = peripheral.wrap(CHEST_SIDE)
11monitor.setTextScale(0.5)
12
13-- Initialize data
14local function initData()
15 data = {
16 resources = {
17 ["minecraft:iron_ingot"] = {name = "Iron", base = 1, amount = 0},
18 ["minecraft:gold_ingot"] = {name = "Gold", base = 5, amount = 0},
19 ["minecraft:diamond"] = {name = "Diamond", base = 10, amount = 0},
20 ["minecraft:emerald"] = {name = "Emerald", base = 15, amount = 0}
21 },
22 players = {},
23 discount = 0.5
24 }
25 for _, stack in pairs(chest.list()) do
26 if data.resources[stack.name] then
27 data.resources[stack.name].amount = data.resources[stack.name].amount + stack.count
28 end
29 end
30end
31
32-- Calculate prices
33local function calculatePrices()
34 local total = 0
35 for _, res in pairs(data.resources) do
36 total = total + res.amount
37 end
38
39 local prices = {}
40 for id, res in pairs(data.resources) do
41 if res.amount == 0 then
42 prices[id] = {
43 buy = math.huge,
44 sell = res.base * FIXED_PRICE_FACTOR
45 }
46 else
47 local buyPrice = (total / (res.amount + 1)) * res.base
48 prices[id] = {
49 buy = buyPrice,
50 sell = buyPrice * data.discount
51 }
52 end
53 end
54 return prices
55end
56
57-- Draw UI
58local function drawUI(prices)
59 monitor.clear()
60 local w, h = monitor.getSize()
61
62 -- Header
63 monitor.setCursorPos(1, 1)
64 monitor.write("==== SHOP ====")
65
66 -- Resources list
67 local y = 3
68 for id, res in pairs(data.resources) do
69 monitor.setCursorPos(1, y)
70 if prices[id].buy == math.huge then
71 monitor.write(string.format("%s: Sold out", res.name))
72 else
73 monitor.write(string.format("%s: buy %.1f", res.name, prices[id].buy))
74 end
75
76 monitor.setCursorPos(1, y+1)
77 monitor.write(string.format(" sell: %.1f", prices[id].sell))
78 y = y + 3
79 end
80
81 -- Buttons
82 monitor.setCursorPos(1, h-3)
83 monitor.write("[Buy] [Sell]")
84
85 monitor.setCursorPos(1, h-1)
86 monitor.write("[Balance] [Admin]")
87end
88
89-- Process transaction
90local function processTransaction(isBuy)
91 monitor.clear()
92 monitor.setCursorPos(1, 1)
93 monitor.write(isBuy and "BUY" or "SELL")
94 monitor.setCursorPos(1, 2)
95 monitor.write("Username: ")
96 local player = read()
97
98 monitor.setCursorPos(1, 3)
99 monitor.write("Item ID: ")
100 local resID = read()
101
102 if not data.resources[resID] then
103 monitor.setCursorPos(1, 4)
104 monitor.write("Error: invalid ID!")
105 sleep(2)
106 return
107 end
108
109 monitor.setCursorPos(1, 4)
110 monitor.write("Amount: ")
111 local count = tonumber(read())
112
113 if not count or count <= 0 then
114 monitor.setCursorPos(1, 5)
115 monitor.write("Error: invalid amount!")
116 sleep(2)
117 return
118 end
119
120 local prices = calculatePrices()
121 data.players[player] = data.players[player] or 0
122
123 if isBuy then
124 if prices[resID].buy == math.huge then
125 monitor.setCursorPos(1, 5)
126 monitor.write("Error: item sold out!")
127 sleep(2)
128 return
129 end
130
131 local cost = math.floor(prices[resID].buy * count)
132 if data.players[player] < cost then
133 monitor.setCursorPos(1, 5)
134 monitor.write("Not enough points!")
135 sleep(2)
136 return
137 end
138
139 -- Check stock
140 local available = 0
141 for _, stack in pairs(chest.list()) do
142 if stack.name == resID then
143 available = available + stack.count
144 end
145 end
146
147 if available < count then
148 monitor.setCursorPos(1, 5)
149 monitor.write("Not enough items!")
150 sleep(2)
151 return
152 end
153
154 -- Complete purchase
155 data.players[player] = data.players[player] - cost
156 for slot, stack in pairs(chest.list()) do
157 if stack.name == resID then
158 local toTake = math.min(count, stack.count)
159 chest.pushItems(peripheral.getName(chest), slot, toTake)
160 count = count - toTake
161 if count == 0 then break end
162 end
163 end
164 data.resources[resID].amount = data.resources[resID].amount - count
165
166 monitor.setCursorPos(1, 5)
167 monitor.write("Success! Charged: "..cost)
168 else
169 -- Sell items
170 local reward = math.floor(prices[resID].sell * count)
171
172 -- Check player inventory
173 local playerChest = peripheral.wrap("bottom") or error("Connect player chest below!")
174 local available = 0
175 for _, stack in pairs(playerChest.list()) do
176 if stack.name == resID then
177 available = available + stack.count
178 end
179 end
180
181 if available < count then
182 monitor.setCursorPos(1, 5)
183 monitor.write("Not enough items!")
184 sleep(2)
185 return
186 end
187
188 -- Complete sale
189 for slot, stack in pairs(playerChest.list()) do
190 if stack.name == resID then
191 local toSell = math.min(count, stack.count)
192 playerChest.pushItems(peripheral.getName(chest), slot, toSell)
193 count = count - toSell
194 if count == 0 then break end
195 end
196 end
197 data.resources[resID].amount = data.resources[resID].amount + count
198 data.players[player] = data.players[player] + reward
199
200 monitor.setCursorPos(1, 5)
201 monitor.write("Success! Added: "..reward)
202 end
203
204 monitor.setCursorPos(1, 6)
205 monitor.write("Balance: "..data.players[player])
206 sleep(3)
207end
208
209-- Check balance
210local function checkBalance()
211 monitor.clear()
212 monitor.setCursorPos(1, 1)
213 monitor.write("BALANCE CHECK")
214 monitor.setCursorPos(1, 2)
215 monitor.write("Username: ")
216 local player = read()
217
218 data.players[player] = data.players[player] or 0
219 monitor.setCursorPos(1, 3)
220 monitor.write("Balance: "..data.players[player])
221 sleep(3)
222end
223
224-- Admin panel
225local function adminPanel()
226 monitor.clear()
227 monitor.setCursorPos(1, 1)
228 monitor.write("ADMIN PANEL")
229 monitor.setCursorPos(1, 2)
230 monitor.write("Password: ")
231 local inputPass = read("*")
232
233 if inputPass ~= PASSWORD then
234 monitor.setCursorPos(1, 3)
235 monitor.write("Wrong password!")
236 sleep(2)
237 return
238 end
239
240 while true do
241 monitor.clear()
242 monitor.setCursorPos(1, 1)
243 monitor.write("1. Add resource")
244 monitor.setCursorPos(1, 2)
245 monitor.write("2. Change discount")
246 monitor.setCursorPos(1, 3)
247 monitor.write("3. Exit")
248
249 local choice = tonumber(read())
250 if choice == 1 then
251 monitor.setCursorPos(1, 4)
252 monitor.write("Item ID: ")
253 local id = read()
254
255 monitor.setCursorPos(1, 5)
256 monitor.write("Name: ")
257 local name = read()
258
259 monitor.setCursorPos(1, 6)
260 monitor.write("Base price: ")
261 local base = tonumber(read())
262
263 if id and name and base then
264 data.resources[id] = {
265 name = name,
266 base = base,
267 amount = 0
268 }
269 monitor.setCursorPos(1, 7)
270 monitor.write("Resource added!")
271 sleep(2)
272 end
273 elseif choice == 2 then
274 monitor.setCursorPos(1, 4)
275 monitor.write("New discount (0.1-0.9): ")
276 local discount = tonumber(read())
277
278 if discount and discount >= 0.1 and discount <= 0.9 then
279 data.discount = discount
280 monitor.setCursorPos(1, 5)
281 monitor.write("Discount updated!")
282 sleep(2)
283 end
284 elseif choice == 3 then
285 break
286 end
287 end
288end
289
290-- Main loop
291initData()
292while true do
293 local prices = calculatePrices()
294 drawUI(prices)
295
296 local event, side, x, y = os.pullEvent("monitor_touch")
297 local w, h = monitor.getSize()
298
299 if y >= h-3 and y <= h-1 then
300 if x >= 1 and x <= 4 then
301 processTransaction(true) -- Buy
302 elseif x >= 6 and x <= 10 then
303 processTransaction(false) -- Sell
304 elseif y == h-1 then
305 if x >= 1 and x <= 8 then
306 checkBalance() -- Balance
307 elseif x >= 10 and x <= 16 then
308 adminPanel() -- Admin panel
309 end
310 end
311 end
312end