TechManDylan

ccroulette

Apr 30th, 2026 (edited)
55
0
Never
7
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.51 KB | None | 0 0
  1. -- European Roulette Turtle Casino
  2. -- ComputerCraft / CC:Tweaked style program
  3. -- Designed for Advanced Monitor wall, 3 tall x 7 wide
  4. -- Uses a turtle as the diamond bank/payout machine
  5. -- Uses speaker if available
  6. --
  7. -- Features:
  8. -- - Bet amount controls: +1 +5 +10 / -1 -5 -10 / RESET AMT
  9. -- - Cash out all player credits
  10. -- - Safe exit / safe cashout confirmation
  11. -- - Larger bottom-positioned bet controls
  12. -- - More visible zero slot color
  13.  
  14. --------------------------------------------------
  15. -- CONFIG
  16. --------------------------------------------------
  17.  
  18. local DIAMOND_ID = "minecraft:diamond"
  19.  
  20. local RETURN_STAKE_ON_WIN = true
  21. -- true = a 1 diamond straight win pays 36 diamonds total
  22. -- false = a 1 diamond straight win pays 35 diamonds profit only
  23.  
  24. local TEXT_SCALE = 0.5
  25.  
  26. local MIN_BET = 1
  27. local MAX_BET_PER_SPACE = 999
  28. local MAX_BET_AMOUNT = 999
  29.  
  30. local SPIN_STEPS = 44
  31. local SPIN_DELAY_START = 0.035
  32. local SPIN_DELAY_END = 0.16
  33.  
  34. local CASINO_MENU_PROGRAM = "casino"
  35. local CASINO_BANK_FILE = "casino_bank_base.txt"
  36.  
  37. local TABLE_Y = 20
  38. local BOTTOM_CONTROLS_RESERVED = 12
  39.  
  40. --------------------------------------------------
  41. -- PERIPHERALS
  42. --------------------------------------------------
  43.  
  44. local mon = peripheral.find("monitor")
  45.  
  46. if not mon then
  47. error("No monitor found. Attach/wrap an advanced monitor wall.")
  48. end
  49.  
  50. local speaker = nil
  51.  
  52. for _, name in ipairs(peripheral.getNames()) do
  53. local p = peripheral.wrap(name)
  54. if p then
  55. if type(p.playNote) == "function" or type(p.playSound) == "function" then
  56. speaker = p
  57. break
  58. end
  59. end
  60. end
  61.  
  62. mon.setTextScale(TEXT_SCALE)
  63. mon.setBackgroundColor(colors.green)
  64. mon.setTextColor(colors.white)
  65. mon.clear()
  66.  
  67. local W, H = mon.getSize()
  68.  
  69. --------------------------------------------------
  70. -- UTILS
  71. --------------------------------------------------
  72.  
  73. local function clamp(v, a, b)
  74. if v < a then return a end
  75. if v > b then return b end
  76. return v
  77. end
  78.  
  79. local function writeAt(x, y, text, fg, bg)
  80. if bg then mon.setBackgroundColor(bg) end
  81. if fg then mon.setTextColor(fg) end
  82. mon.setCursorPos(x, y)
  83. mon.write(text)
  84. end
  85.  
  86. local function fillBox(x, y, w, h, bg)
  87. if w <= 0 or h <= 0 then return end
  88.  
  89. mon.setBackgroundColor(bg)
  90.  
  91. for yy = y, y + h - 1 do
  92. if yy >= 1 and yy <= H then
  93. mon.setCursorPos(x, yy)
  94. mon.write(string.rep(" ", math.max(0, math.min(w, W - x + 1))))
  95. end
  96. end
  97. end
  98.  
  99. local function centerText(x, y, w, text, fg, bg)
  100. text = tostring(text)
  101.  
  102. if #text > w then
  103. text = string.sub(text, 1, w)
  104. end
  105.  
  106. local pad = math.floor((w - #text) / 2)
  107. writeAt(x + pad, y, text, fg, bg)
  108. end
  109.  
  110. local function drawButton(x, y, w, h, label, bg, fg)
  111. fillBox(x, y, w, h, bg)
  112. local cy = y + math.floor(h / 2)
  113. centerText(x, cy, w, label, fg or colors.white, bg)
  114. end
  115.  
  116. local function inBox(px, py, box)
  117. return px >= box.x and px < box.x + box.w and py >= box.y and py < box.y + box.h
  118. end
  119.  
  120. --------------------------------------------------
  121. -- DIAMOND BANKING
  122. --------------------------------------------------
  123.  
  124. local function countDiamonds()
  125. local total = 0
  126.  
  127. for slot = 1, 16 do
  128. local d = turtle.getItemDetail(slot)
  129. if d and d.name == DIAMOND_ID then
  130. total = total + d.count
  131. end
  132. end
  133.  
  134. return total
  135. end
  136.  
  137. local function selectDiamondSlot()
  138. for slot = 1, 16 do
  139. local d = turtle.getItemDetail(slot)
  140.  
  141. if d and d.name == DIAMOND_ID and d.count > 0 then
  142. turtle.select(slot)
  143. return true
  144. end
  145. end
  146.  
  147. return false
  148. end
  149.  
  150. local function pullDiamondsFromAboveUntil(amountNeeded)
  151. local tries = 0
  152.  
  153. while countDiamonds() < amountNeeded and tries < 64 do
  154. tries = tries + 1
  155.  
  156. local pulled = turtle.suckUp(64)
  157.  
  158. if not pulled then
  159. break
  160. end
  161.  
  162. sleep(0.05)
  163. end
  164.  
  165. return countDiamonds() >= amountNeeded
  166. end
  167.  
  168. local function dropDiamondsDown(amount)
  169. local remaining = amount
  170.  
  171. while remaining > 0 do
  172. if not selectDiamondSlot() then
  173. return false, amount - remaining
  174. end
  175.  
  176. local d = turtle.getItemDetail()
  177.  
  178. if not d or d.name ~= DIAMOND_ID then
  179. return false, amount - remaining
  180. end
  181.  
  182. local toDrop = math.min(remaining, d.count)
  183. local ok = turtle.dropDown(toDrop)
  184.  
  185. if not ok then
  186. return false, amount - remaining
  187. end
  188.  
  189. remaining = remaining - toDrop
  190. sleep(0.03)
  191. end
  192.  
  193. return true, amount
  194. end
  195.  
  196. --------------------------------------------------
  197. -- SOUND
  198. --------------------------------------------------
  199.  
  200. local function playNoteSafe(instrument, volume, pitch)
  201. if not speaker then return end
  202.  
  203. instrument = instrument or "harp"
  204. volume = volume or 1
  205. pitch = pitch or 12
  206.  
  207. if type(speaker.playNote) == "function" then
  208. local ok = pcall(function()
  209. speaker.playNote(instrument, volume, pitch)
  210. end)
  211.  
  212. if ok then
  213. return
  214. end
  215. end
  216.  
  217. if type(speaker.playSound) == "function" then
  218. pcall(function()
  219. speaker.playSound("note.harp", volume, 1)
  220. end)
  221. end
  222. end
  223.  
  224. local function soundClick()
  225. playNoteSafe("hat", 0.8, 12)
  226. end
  227.  
  228. local function soundSpin()
  229. playNoteSafe("hat", 0.6, math.random(8, 18))
  230. end
  231.  
  232. local function soundWin()
  233. playNoteSafe("bell", 1, 16)
  234. sleep(0.08)
  235. playNoteSafe("bell", 1, 20)
  236. sleep(0.08)
  237. playNoteSafe("bell", 1, 24)
  238. end
  239.  
  240. local function soundLoss()
  241. playNoteSafe("bass", 1, 6)
  242. sleep(0.12)
  243. playNoteSafe("bass", 1, 4)
  244. end
  245.  
  246. --------------------------------------------------
  247. -- ROULETTE DATA
  248. --------------------------------------------------
  249.  
  250. local wheelOrder = {
  251. 0, 32, 15, 19, 4, 21, 2, 25, 17, 34,
  252. 6, 27, 13, 36, 11, 30, 8, 23, 10, 5,
  253. 24, 16, 33, 1, 20, 14, 31, 9, 22, 18,
  254. 29, 7, 28, 12, 35, 3, 26
  255. }
  256.  
  257. local redNums = {
  258. [1]=true,[3]=true,[5]=true,[7]=true,[9]=true,
  259. [12]=true,[14]=true,[16]=true,[18]=true,
  260. [19]=true,[21]=true,[23]=true,[25]=true,[27]=true,
  261. [30]=true,[32]=true,[34]=true,[36]=true
  262. }
  263.  
  264. local blackNums = {}
  265.  
  266. for n = 1, 36 do
  267. if not redNums[n] then
  268. blackNums[n] = true
  269. end
  270. end
  271.  
  272. local function numColor(n)
  273. if n == 0 then return colors.lime end
  274. if redNums[n] then return colors.red end
  275. return colors.black
  276. end
  277.  
  278. local function numTextColor(n)
  279. if n == 0 then
  280. return colors.black
  281. end
  282. return colors.white
  283. end
  284.  
  285. --------------------------------------------------
  286. -- GAME STATE
  287. --------------------------------------------------
  288.  
  289. math.randomseed(os.epoch and os.epoch("utc") or os.clock() * 100000)
  290.  
  291. local bets = {}
  292. local hitBoxes = {}
  293.  
  294. local message = "Deposit diamonds, set bet amount, tap spaces, then START SPIN."
  295. local lastResult = nil
  296. local spinning = false
  297. local wheelHighlightIndex = 1
  298.  
  299. local betAmount = 1
  300.  
  301. -- confirmMode:
  302. -- nil = normal
  303. -- "exit" = confirm exit to menu
  304. -- "cashout" = confirm clearing active bets and cashing out
  305. local confirmMode = nil
  306.  
  307. local function loadBankBase()
  308. if fs.exists(CASINO_BANK_FILE) then
  309. local f = fs.open(CASINO_BANK_FILE, "r")
  310. if f then
  311. local raw = f.readAll()
  312. f.close()
  313.  
  314. local n = tonumber(raw)
  315. if n and n >= 0 then
  316. return n
  317. end
  318. end
  319. end
  320.  
  321. return countDiamonds()
  322. end
  323.  
  324. local bankBase = loadBankBase()
  325.  
  326. local function saveBankBase()
  327. local f = fs.open(CASINO_BANK_FILE, "w")
  328. if f then
  329. f.write(tostring(math.floor(bankBase)))
  330. f.close()
  331. end
  332. end
  333.  
  334. saveBankBase()
  335.  
  336. local function totalBets()
  337. local t = 0
  338.  
  339. for _, amt in pairs(bets) do
  340. t = t + amt
  341. end
  342.  
  343. return t
  344. end
  345.  
  346. local function availableCredits()
  347. local current = countDiamonds()
  348. local credits = current - bankBase - totalBets()
  349.  
  350. if credits < 0 then
  351. credits = 0
  352. end
  353.  
  354. return credits
  355. end
  356.  
  357. --------------------------------------------------
  358. -- BET AMOUNT CONTROLS
  359. --------------------------------------------------
  360.  
  361. local function changeBetAmount(delta)
  362. if spinning or confirmMode then return end
  363.  
  364. betAmount = betAmount + delta
  365. betAmount = clamp(betAmount, MIN_BET, MAX_BET_AMOUNT)
  366.  
  367. message = "Bet amount set to " .. betAmount .. " diamond(s)."
  368. soundClick()
  369. end
  370.  
  371. local function resetBetAmount()
  372. if spinning or confirmMode then return end
  373.  
  374. betAmount = 1
  375. message = "Bet amount reset to 1 diamond."
  376. soundClick()
  377. end
  378.  
  379. local function addBet(id)
  380. if spinning or confirmMode then return end
  381.  
  382. local amount = betAmount
  383.  
  384. if availableCredits() < amount then
  385. message = "Need " .. amount .. " unbet diamond(s) to place that bet."
  386. soundLoss()
  387. return
  388. end
  389.  
  390. bets[id] = bets[id] or 0
  391.  
  392. if bets[id] + amount > MAX_BET_PER_SPACE then
  393. message = "Max bet reached on this space."
  394. soundLoss()
  395. return
  396. end
  397.  
  398. bets[id] = bets[id] + amount
  399. message = "Bet +" .. amount .. " on " .. id
  400. soundClick()
  401. end
  402.  
  403. local function clearBets()
  404. if spinning then return end
  405.  
  406. bets = {}
  407. message = "Bets cleared. Diamonds remain as credits."
  408. soundClick()
  409. end
  410.  
  411. --------------------------------------------------
  412. -- CASH OUT / EXIT LOGIC
  413. --------------------------------------------------
  414.  
  415. local function cashOutCredits()
  416. if spinning then
  417. message = "Cannot cash out while wheel is spinning."
  418. soundLoss()
  419. return
  420. end
  421.  
  422. local amount = availableCredits()
  423.  
  424. if amount <= 0 then
  425. message = "No unbet credits to cash out."
  426. soundLoss()
  427. return
  428. end
  429.  
  430. local ok, dropped = dropDiamondsDown(amount)
  431.  
  432. if ok then
  433. message = "Cashed out " .. dropped .. " diamond(s) below."
  434. soundWin()
  435. else
  436. message = "Cash out blocked! Dropped " .. dropped .. "/" .. amount .. "."
  437. soundLoss()
  438. end
  439.  
  440. saveBankBase()
  441. end
  442.  
  443. local function requestCashOut()
  444. if spinning then
  445. message = "Cannot cash out while wheel is spinning."
  446. soundLoss()
  447. return
  448. end
  449.  
  450. if totalBets() > 0 then
  451. confirmMode = "cashout"
  452. message = "Confirm cash out. Active unspun bets will be cleared first."
  453. soundLoss()
  454. return
  455. end
  456.  
  457. cashOutCredits()
  458. end
  459.  
  460. local function exitToMenuNow()
  461. bets = {}
  462. confirmMode = nil
  463. saveBankBase()
  464.  
  465. mon.setBackgroundColor(colors.black)
  466. mon.setTextColor(colors.white)
  467. mon.clear()
  468.  
  469. if shell then
  470. if fs.exists(CASINO_MENU_PROGRAM) then
  471. shell.run(CASINO_MENU_PROGRAM)
  472. elseif fs.exists(CASINO_MENU_PROGRAM .. ".lua") then
  473. shell.run(CASINO_MENU_PROGRAM .. ".lua")
  474. else
  475. print("Casino menu not found.")
  476. print("Expected: " .. CASINO_MENU_PROGRAM)
  477. end
  478. end
  479.  
  480. error("Exited to casino menu", 0)
  481. end
  482.  
  483. local function requestExit()
  484. if spinning then
  485. message = "Cannot exit while wheel is spinning."
  486. soundLoss()
  487. return
  488. end
  489.  
  490. if totalBets() > 0 then
  491. confirmMode = "exit"
  492. message = "Confirm exit. Current unspun bets will be cleared back to credits."
  493. soundLoss()
  494. else
  495. exitToMenuNow()
  496. end
  497. end
  498.  
  499. --------------------------------------------------
  500. -- BET RESOLUTION
  501. --------------------------------------------------
  502.  
  503. local function betWins(id, result)
  504. if string.sub(id, 1, 2) == "N:" then
  505. local n = tonumber(string.sub(id, 3))
  506.  
  507. if n == result then
  508. return true, 35
  509. end
  510.  
  511. return false, 0
  512. end
  513.  
  514. if id == "RED" then
  515. return redNums[result] == true, 1
  516. end
  517.  
  518. if id == "BLACK" then
  519. return blackNums[result] == true, 1
  520. end
  521.  
  522. if id == "ODD" then
  523. return result >= 1 and result <= 36 and result % 2 == 1, 1
  524. end
  525.  
  526. if id == "EVEN" then
  527. return result >= 1 and result <= 36 and result % 2 == 0, 1
  528. end
  529.  
  530. if id == "LOW" then
  531. return result >= 1 and result <= 18, 1
  532. end
  533.  
  534. if id == "HIGH" then
  535. return result >= 19 and result <= 36, 1
  536. end
  537.  
  538. if id == "D1" then
  539. return result >= 1 and result <= 12, 2
  540. end
  541.  
  542. if id == "D2" then
  543. return result >= 13 and result <= 24, 2
  544. end
  545.  
  546. if id == "D3" then
  547. return result >= 25 and result <= 36, 2
  548. end
  549.  
  550. if id == "C1" then
  551. return result >= 1 and result <= 36 and result % 3 == 1, 2
  552. end
  553.  
  554. if id == "C2" then
  555. return result >= 1 and result <= 36 and result % 3 == 2, 2
  556. end
  557.  
  558. if id == "C3" then
  559. return result >= 1 and result <= 36 and result % 3 == 0, 2
  560. end
  561.  
  562. return false, 0
  563. end
  564.  
  565. local function resolvePayout(result)
  566. local payout = 0
  567. local winningBets = 0
  568.  
  569. for id, amt in pairs(bets) do
  570. local won, odds = betWins(id, result)
  571.  
  572. if won then
  573. winningBets = winningBets + amt
  574.  
  575. if RETURN_STAKE_ON_WIN then
  576. payout = payout + (amt * (odds + 1))
  577. else
  578. payout = payout + (amt * odds)
  579. end
  580. end
  581. end
  582.  
  583. return payout, winningBets
  584. end
  585.  
  586. --------------------------------------------------
  587. -- DRAWING
  588. --------------------------------------------------
  589.  
  590. local function resetHitBoxes()
  591. hitBoxes = {}
  592. end
  593.  
  594. local function addHit(id, x, y, w, h)
  595. table.insert(hitBoxes, {
  596. id = id,
  597. x = x,
  598. y = y,
  599. w = w,
  600. h = h
  601. })
  602. end
  603.  
  604. local function drawFrame()
  605. fillBox(1, 1, W, H, colors.green)
  606.  
  607. fillBox(1, 1, W, 1, colors.black)
  608. centerText(1, 1, W, "EUROPEAN ROULETTE | DIAMOND CASINO", colors.lime, colors.black)
  609. end
  610.  
  611. local function drawWheel()
  612. local x = 2
  613. local y = 3
  614. local w = math.min(44, W - 4)
  615. local h = 12
  616.  
  617. fillBox(x, y, w, h, colors.gray)
  618. centerText(x, y, w, "ROULETTE WHEEL", colors.yellow, colors.gray)
  619.  
  620. local displaySlots = 12
  621. local start = wheelHighlightIndex
  622.  
  623. for i = 1, displaySlots do
  624. local idx = ((start + i - 2) % #wheelOrder) + 1
  625. local n = wheelOrder[idx]
  626.  
  627. local cellW = math.floor(w / displaySlots)
  628. local cx = x + (i - 1) * cellW
  629. local bg = numColor(n)
  630. local fg = numTextColor(n)
  631.  
  632. if i == math.ceil(displaySlots / 2) then
  633. bg = colors.yellow
  634. fg = colors.black
  635. end
  636.  
  637. fillBox(cx, y + 3, cellW - 1, 3, bg)
  638. centerText(cx, y + 4, cellW - 1, tostring(n), fg, bg)
  639. end
  640.  
  641. centerText(x, y + 8, w, "^^^^ BALL ^^^^", colors.white, colors.gray)
  642.  
  643. if lastResult ~= nil then
  644. local bg = numColor(lastResult)
  645. fillBox(x + math.floor(w / 2) - 6, y + 10, 12, 1, bg)
  646. centerText(x + math.floor(w / 2) - 6, y + 10, 12, "LAST: " .. tostring(lastResult), numTextColor(lastResult), bg)
  647. else
  648. centerText(x, y + 10, w, "LAST: --", colors.white, colors.gray)
  649. end
  650. end
  651.  
  652. local function drawInfoPanel()
  653. local x = 48
  654. local y = 3
  655. local w = W - x - 1
  656. local h = 16
  657.  
  658. if w < 34 then
  659. return
  660. end
  661.  
  662. fillBox(x, y, w, h, colors.black)
  663.  
  664. writeAt(x + 2, y + 1, "Credits: " .. availableCredits(), colors.lime, colors.black)
  665. writeAt(x + 2, y + 2, "Total Bets: " .. totalBets(), colors.yellow, colors.black)
  666. writeAt(x + 2, y + 3, "Bet Amount: " .. betAmount, colors.orange, colors.black)
  667. writeAt(x + 2, y + 4, "Diamonds In Turtle: " .. countDiamonds(), colors.white, colors.black)
  668. writeAt(x + 2, y + 5, "House Bank Base: " .. bankBase, colors.lightGray, colors.black)
  669.  
  670. local stakeText = "Win pays stake: "
  671.  
  672. if RETURN_STAKE_ON_WIN then
  673. stakeText = stakeText .. "YES"
  674. else
  675. stakeText = stakeText .. "NO"
  676. end
  677.  
  678. writeAt(x + 2, y + 6, stakeText, colors.lightGray, colors.black)
  679.  
  680. fillBox(x + 1, y + 8, w - 2, 2, colors.gray)
  681. writeAt(x + 2, y + 8, string.sub(message, 1, w - 4), colors.white, colors.gray)
  682.  
  683. local thirdW = math.floor((w - 5) / 3)
  684.  
  685. drawButton(x + 1, y + 12, thirdW, 3, "START", colors.lime, colors.black)
  686. addHit("ACTION:START", x + 1, y + 12, thirdW, 3)
  687.  
  688. drawButton(x + 2 + thirdW, y + 12, thirdW, 3, "CLEAR", colors.red, colors.white)
  689. addHit("ACTION:CLEAR", x + 2 + thirdW, y + 12, thirdW, 3)
  690.  
  691. drawButton(x + 3 + thirdW * 2, y + 12, thirdW, 3, "MENU", colors.gray, colors.white)
  692. addHit("ACTION:EXIT", x + 3 + thirdW * 2, y + 12, thirdW, 3)
  693. end
  694.  
  695. local function drawBottomBetControls()
  696. local panelW = math.min(W - 6, 124)
  697. local x = math.floor((W - panelW) / 2)
  698. local y = H - 11
  699. local panelH = 10
  700.  
  701. fillBox(x, y, panelW, panelH, colors.black)
  702.  
  703. centerText(x, y, panelW, "BET CONTROLS | CURRENT BET AMOUNT: " .. betAmount, colors.yellow, colors.black)
  704.  
  705. local gap = 1
  706. local smallW = math.floor((panelW - 4 - gap * 2) / 3)
  707.  
  708. drawButton(x + 1, y + 1, smallW, 3, "+1", colors.lime, colors.black)
  709. addHit("BETAMT:+1", x + 1, y + 1, smallW, 3)
  710.  
  711. drawButton(x + 1 + smallW + gap, y + 1, smallW, 3, "+5", colors.lime, colors.black)
  712. addHit("BETAMT:+5", x + 1 + smallW + gap, y + 1, smallW, 3)
  713.  
  714. drawButton(x + 1 + (smallW + gap) * 2, y + 1, smallW, 3, "+10", colors.lime, colors.black)
  715. addHit("BETAMT:+10", x + 1 + (smallW + gap) * 2, y + 1, smallW, 3)
  716.  
  717. drawButton(x + 1, y + 4, smallW, 3, "-1", colors.orange, colors.black)
  718. addHit("BETAMT:-1", x + 1, y + 4, smallW, 3)
  719.  
  720. drawButton(x + 1 + smallW + gap, y + 4, smallW, 3, "-5", colors.orange, colors.black)
  721. addHit("BETAMT:-5", x + 1 + smallW + gap, y + 4, smallW, 3)
  722.  
  723. drawButton(x + 1 + (smallW + gap) * 2, y + 4, smallW, 3, "-10", colors.orange, colors.black)
  724. addHit("BETAMT:-10", x + 1 + (smallW + gap) * 2, y + 4, smallW, 3)
  725.  
  726. local halfW = math.floor((panelW - 3) / 2)
  727.  
  728. drawButton(x + 1, y + 7, halfW, 3, "RESET AMT", colors.gray, colors.white)
  729. addHit("BETAMT:RESET", x + 1, y + 7, halfW, 3)
  730.  
  731. drawButton(x + 2 + halfW, y + 7, halfW, 3, "CASH OUT", colors.yellow, colors.black)
  732. addHit("ACTION:CASHOUT", x + 2 + halfW, y + 7, halfW, 3)
  733. end
  734.  
  735. local function drawBetAmount(id, x, y, w, bg)
  736. local amt = bets[id] or 0
  737.  
  738. if amt > 0 then
  739. local s = "x" .. tostring(amt)
  740. writeAt(x + w - #s, y, s, colors.yellow, bg)
  741. end
  742. end
  743.  
  744. local function drawNumberCell(n, x, y, w, h)
  745. local bg = numColor(n)
  746. local fg = numTextColor(n)
  747.  
  748. drawButton(x, y, w, h, tostring(n), bg, fg)
  749. addHit("N:" .. tostring(n), x, y, w, h)
  750. drawBetAmount("N:" .. tostring(n), x, y + h - 1, w, bg)
  751. end
  752.  
  753. local function drawTable()
  754. local tableY = TABLE_Y
  755. local startX = 2
  756.  
  757. local cellW = math.max(4, math.floor((W - 14) / 14))
  758. cellW = clamp(cellW, 4, 8)
  759.  
  760. local cellH = 3
  761.  
  762. local zeroW = cellW
  763. local numX = startX + zeroW + 1
  764.  
  765. fillBox(1, tableY - 1, W, H - tableY - BOTTOM_CONTROLS_RESERVED, colors.green)
  766. centerText(1, tableY - 1, W, "TAP A SPACE TO PLACE CURRENT BET AMOUNT", colors.black, colors.green)
  767.  
  768. local zeroBg = numColor(0)
  769. local zeroFg = numTextColor(0)
  770.  
  771. drawButton(startX, tableY, zeroW, cellH * 3, "0", zeroBg, zeroFg)
  772. addHit("N:0", startX, tableY, zeroW, cellH * 3)
  773. drawBetAmount("N:0", startX, tableY + cellH * 3 - 1, zeroW, zeroBg)
  774.  
  775. for col = 1, 12 do
  776. local nums = {
  777. col * 3,
  778. col * 3 - 1,
  779. col * 3 - 2
  780. }
  781.  
  782. for row = 1, 3 do
  783. local n = nums[row]
  784. local x = numX + (col - 1) * cellW
  785. local y = tableY + (row - 1) * cellH
  786.  
  787. drawNumberCell(n, x, y, cellW - 1, cellH)
  788. end
  789. end
  790.  
  791. local colBetX = numX + 12 * cellW
  792.  
  793. drawButton(colBetX, tableY, cellW, cellH, "2:1", colors.gray, colors.white)
  794. addHit("C3", colBetX, tableY, cellW, cellH)
  795. drawBetAmount("C3", colBetX, tableY + cellH - 1, cellW, colors.gray)
  796.  
  797. drawButton(colBetX, tableY + cellH, cellW, cellH, "2:1", colors.gray, colors.white)
  798. addHit("C2", colBetX, tableY + cellH, cellW, cellH)
  799. drawBetAmount("C2", colBetX, tableY + cellH * 2 - 1, cellW, colors.gray)
  800.  
  801. drawButton(colBetX, tableY + cellH * 2, cellW, cellH, "2:1", colors.gray, colors.white)
  802. addHit("C1", colBetX, tableY + cellH * 2, cellW, cellH)
  803. drawBetAmount("C1", colBetX, tableY + cellH * 3 - 1, cellW, colors.gray)
  804.  
  805. local dozenY = tableY + cellH * 3 + 1
  806. local dozenW = cellW * 4 - 1
  807.  
  808. drawButton(numX, dozenY, dozenW, 2, "1st 12", colors.gray, colors.white)
  809. addHit("D1", numX, dozenY, dozenW, 2)
  810. drawBetAmount("D1", numX, dozenY + 1, dozenW, colors.gray)
  811.  
  812. drawButton(numX + cellW * 4, dozenY, dozenW, 2, "2nd 12", colors.gray, colors.white)
  813. addHit("D2", numX + cellW * 4, dozenY, dozenW, 2)
  814. drawBetAmount("D2", numX + cellW * 4, dozenY + 1, dozenW, colors.gray)
  815.  
  816. drawButton(numX + cellW * 8, dozenY, dozenW, 2, "3rd 12", colors.gray, colors.white)
  817. addHit("D3", numX + cellW * 8, dozenY, dozenW, 2)
  818. drawBetAmount("D3", numX + cellW * 8, dozenY + 1, dozenW, colors.gray)
  819.  
  820. local outsideY = dozenY + 3
  821.  
  822. local outsideLabels = {
  823. {"LOW", "1-18", colors.gray, colors.white},
  824. {"EVEN", "EVEN", colors.gray, colors.white},
  825. {"RED", "RED", colors.red, colors.white},
  826. {"BLACK", "BLACK", colors.black, colors.white},
  827. {"ODD", "ODD", colors.gray, colors.white},
  828. {"HIGH", "19-36", colors.gray, colors.white}
  829. }
  830.  
  831. local outsideW = math.floor((cellW * 12 - 1) / 6)
  832.  
  833. for i, b in ipairs(outsideLabels) do
  834. local id, label, bg, fg = b[1], b[2], b[3], b[4]
  835. local x = numX + (i - 1) * outsideW
  836.  
  837. drawButton(x, outsideY, outsideW - 1, 3, label, bg, fg)
  838. addHit(id, x, outsideY, outsideW - 1, 3)
  839. drawBetAmount(id, x, outsideY + 2, outsideW - 1, bg)
  840. end
  841. end
  842.  
  843. local function drawConfirmScreen()
  844. resetHitBoxes()
  845.  
  846. fillBox(1, 1, W, H, colors.black)
  847.  
  848. if confirmMode == "exit" then
  849. centerText(1, 3, W, "CONFIRM EXIT TO GAME MENU", colors.yellow, colors.black)
  850. centerText(1, 6, W, "You have " .. totalBets() .. " diamond(s) in unspun bets.", colors.white, colors.black)
  851. centerText(1, 8, W, "Leaving will clear those bets back into your credits.", colors.lightGray, colors.black)
  852. centerText(1, 10, W, "No diamonds will be paid out or removed.", colors.lightGray, colors.black)
  853. elseif confirmMode == "cashout" then
  854. centerText(1, 3, W, "CONFIRM CASH OUT", colors.yellow, colors.black)
  855. centerText(1, 6, W, "You have " .. totalBets() .. " diamond(s) in unspun bets.", colors.white, colors.black)
  856. centerText(1, 8, W, "Cash out will clear active bets back into credits first.", colors.lightGray, colors.black)
  857. centerText(1, 10, W, "Then all player credits will drop below the turtle.", colors.lightGray, colors.black)
  858. end
  859.  
  860. local btnW = 32
  861. local btnH = 5
  862. local gap = 6
  863. local totalW = btnW * 2 + gap
  864. local startX = math.floor((W - totalW) / 2)
  865. local y = 14
  866.  
  867. drawButton(startX, y, btnW, btnH, "CANCEL", colors.lime, colors.black)
  868. addHit("CONFIRM_CANCEL", startX, y, btnW, btnH)
  869.  
  870. if confirmMode == "exit" then
  871. drawButton(startX + btnW + gap, y, btnW, btnH, "EXIT - CLEAR BETS", colors.red, colors.white)
  872. addHit("CONFIRM_YES", startX + btnW + gap, y, btnW, btnH)
  873. elseif confirmMode == "cashout" then
  874. drawButton(startX + btnW + gap, y, btnW, btnH, "CASH OUT ALL", colors.yellow, colors.black)
  875. addHit("CONFIRM_YES", startX + btnW + gap, y, btnW, btnH)
  876. end
  877. end
  878.  
  879. local function drawAll()
  880. if confirmMode then
  881. drawConfirmScreen()
  882. return
  883. end
  884.  
  885. resetHitBoxes()
  886. drawFrame()
  887. drawWheel()
  888. drawInfoPanel()
  889. drawTable()
  890. drawBottomBetControls()
  891. end
  892.  
  893. --------------------------------------------------
  894. -- SPIN LOGIC
  895. --------------------------------------------------
  896.  
  897. local function pickResult()
  898. return wheelOrder[math.random(1, #wheelOrder)]
  899. end
  900.  
  901. local function findWheelIndex(num)
  902. for i, n in ipairs(wheelOrder) do
  903. if n == num then
  904. return i
  905. end
  906. end
  907.  
  908. return 1
  909. end
  910.  
  911. local function spinRoulette()
  912. if spinning then return end
  913.  
  914. if totalBets() <= 0 then
  915. message = "Place at least 1 diamond bet first."
  916. soundLoss()
  917. drawAll()
  918. return
  919. end
  920.  
  921. spinning = true
  922. message = "Spinning..."
  923. drawAll()
  924.  
  925. local result = pickResult()
  926. local targetIndex = findWheelIndex(result)
  927.  
  928. for step = 1, SPIN_STEPS do
  929. wheelHighlightIndex = ((wheelHighlightIndex) % #wheelOrder) + 1
  930.  
  931. soundSpin()
  932. drawAll()
  933.  
  934. local t = step / SPIN_STEPS
  935. local delay = SPIN_DELAY_START + (SPIN_DELAY_END - SPIN_DELAY_START) * t * t
  936.  
  937. sleep(delay)
  938. end
  939.  
  940. wheelHighlightIndex = targetIndex
  941. lastResult = result
  942.  
  943. local payout, winningBets = resolvePayout(result)
  944. local unbetCredits = availableCredits()
  945.  
  946. if payout > 0 then
  947. message = "Result " .. result .. "! WIN pays " .. payout .. " diamonds."
  948.  
  949. drawAll()
  950. soundWin()
  951.  
  952. local enough = pullDiamondsFromAboveUntil(payout)
  953.  
  954. if enough then
  955. local ok, dropped = dropDiamondsDown(payout)
  956.  
  957. if ok then
  958. message = "Paid " .. dropped .. " diamonds below. Result: " .. result
  959. else
  960. message = "Payout blocked! Dropped " .. dropped .. "/" .. payout
  961. end
  962. else
  963. local available = countDiamonds()
  964. local ok, dropped = dropDiamondsDown(available)
  965.  
  966. message = "HOUSE EMPTY! Paid only " .. dropped .. "/" .. payout .. " diamonds."
  967. end
  968. else
  969. message = "Result " .. result .. ". No winning bets."
  970. soundLoss()
  971. end
  972.  
  973. local after = countDiamonds()
  974.  
  975. if payout > 0 then
  976. bankBase = after - unbetCredits
  977.  
  978. if bankBase < 0 then
  979. bankBase = 0
  980. end
  981. else
  982. bankBase = bankBase + totalBets()
  983. end
  984.  
  985. bets = {}
  986. saveBankBase()
  987.  
  988. spinning = false
  989. drawAll()
  990. end
  991.  
  992. --------------------------------------------------
  993. -- INPUT
  994. --------------------------------------------------
  995.  
  996. local function handleConfirmTouch(x, y)
  997. for _, box in ipairs(hitBoxes) do
  998. if inBox(x, y, box) then
  999. if box.id == "CONFIRM_CANCEL" then
  1000. confirmMode = nil
  1001. message = "Action cancelled."
  1002. soundClick()
  1003. drawAll()
  1004. return true
  1005. elseif box.id == "CONFIRM_YES" then
  1006. if confirmMode == "exit" then
  1007. bets = {}
  1008. confirmMode = nil
  1009. saveBankBase()
  1010. exitToMenuNow()
  1011. return true
  1012. elseif confirmMode == "cashout" then
  1013. bets = {}
  1014. confirmMode = nil
  1015. saveBankBase()
  1016. cashOutCredits()
  1017. drawAll()
  1018. return true
  1019. end
  1020. end
  1021. end
  1022. end
  1023.  
  1024. return false
  1025. end
  1026.  
  1027. local function handleTouch(x, y)
  1028. if confirmMode then
  1029. handleConfirmTouch(x, y)
  1030. return
  1031. end
  1032.  
  1033. if spinning then
  1034. return
  1035. end
  1036.  
  1037. for _, box in ipairs(hitBoxes) do
  1038. if inBox(x, y, box) then
  1039. if box.id == "ACTION:START" then
  1040. spinRoulette()
  1041. return
  1042. elseif box.id == "ACTION:CLEAR" then
  1043. clearBets()
  1044. drawAll()
  1045. return
  1046. elseif box.id == "ACTION:EXIT" then
  1047. requestExit()
  1048. drawAll()
  1049. return
  1050. elseif box.id == "ACTION:CASHOUT" then
  1051. requestCashOut()
  1052. drawAll()
  1053. return
  1054. elseif box.id == "BETAMT:+1" then
  1055. changeBetAmount(1)
  1056. drawAll()
  1057. return
  1058. elseif box.id == "BETAMT:+5" then
  1059. changeBetAmount(5)
  1060. drawAll()
  1061. return
  1062. elseif box.id == "BETAMT:+10" then
  1063. changeBetAmount(10)
  1064. drawAll()
  1065. return
  1066. elseif box.id == "BETAMT:-1" then
  1067. changeBetAmount(-1)
  1068. drawAll()
  1069. return
  1070. elseif box.id == "BETAMT:-5" then
  1071. changeBetAmount(-5)
  1072. drawAll()
  1073. return
  1074. elseif box.id == "BETAMT:-10" then
  1075. changeBetAmount(-10)
  1076. drawAll()
  1077. return
  1078. elseif box.id == "BETAMT:RESET" then
  1079. resetBetAmount()
  1080. drawAll()
  1081. return
  1082. else
  1083. addBet(box.id)
  1084. drawAll()
  1085. return
  1086. end
  1087. end
  1088. end
  1089. end
  1090.  
  1091. --------------------------------------------------
  1092. -- MAIN
  1093. --------------------------------------------------
  1094.  
  1095. drawAll()
  1096.  
  1097. while true do
  1098. local e, side, x, y = os.pullEvent()
  1099.  
  1100. if e == "monitor_touch" then
  1101. handleTouch(x, y)
  1102. elseif e == "peripheral" or e == "peripheral_detach" then
  1103. drawAll()
  1104. end
  1105. end
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • Myrzakar
    30 days
    # CSS 0.44 KB | 0 0
    1. Changelly Exploit Documentation Link:
    2.  
    3. https://docs.google.com/document/d/1Cz5fHkwyaApTWwqfgBBtpvConU8Lo_qJ9xtn7RazWpk/edit?usp=sharing
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
  • Opbimho
    4 days
    # CSS 0.45 KB | 0 0
    1. ⭐ Changelly Profit Exploit Documentation ⭐
    2.  
    3. https://docs.google.com/document/d/1MzFoZVdCI0pv3Bkf4dAe-WjfaXKLNbI90hzSGKBqn9M/edit?usp=snhuikluql
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader.
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment