local QBCore = exports['qb-core']:GetCoreObject() -- =========================================== ranks = {'02', '03', '04', '05', '06', '07', '08', '09', '10', --[['11',]] 'JACK', 'QUEEN', 'KING', 'ACE'} suits = {'SPD', 'HRT', 'DIA', 'CLUB'} function shuffle(tbl) for i = #tbl, 2, -1 do local j = math.random(i) tbl[i], tbl[j] = tbl[j], tbl[i] end return tbl end function getDeck() local tDeck = {} for _,rank in pairs(ranks) do for _,suit in pairs(suits) do table.insert(tDeck, suit .. "_" .. rank) end end return shuffle(tDeck) end function takeCard(tDeck) return table.remove(tDeck, math.random(1,#tDeck)) end function cardValue(card) local rank = 10 for i=2,11 do if string.find(card, tostring(i)) then rank = i end end if string.find(card, 'ACE') then rank = 11 end return rank end function handValue(hand) local tmpValue = 0 local numAces = 0 for i,v in pairs(hand) do tmpValue = tmpValue + cardValue(v) end for i,v in pairs(hand) do if string.find(v, 'ACE') then numAces = numAces + 1 end end repeat if tmpValue > 21 and numAces > 0 then tmpValue = tmpValue - 10 numAces = numAces - 1 else break end until numAces == 0 return tmpValue end players = {} timeTracker = {} tableTracker = {} getChipsCallback = nil takeChipsCallback = nil giveChipsCallback = nil function FindPlayerIdx(tbl, src) for i = 1, #tbl do if tbl[i].player == src then return i end end return nil end function SetGetChipsCallback(cb) getChipsCallback = cb end function SetTakeChipsCallback(cb) takeChipsCallback = cb end function SetGiveChipsCallback(cb) giveChipsCallback = cb end function GiveMoney(player, money) if giveChipsCallback ~= nil then giveChipsCallback(player, tonumber(money)) end end function TakeMoney(player, money) if takeChipsCallback ~= nil then takeChipsCallback(player, tonumber(money)) end end function HaveAllPlayersBetted(table) for i,v in pairs(table) do if v.bet < 1 then return false end end return true end function ArePlayersStillIn(table) for i,v in pairs(table) do if v.player_in == true then return true end end return false end function PlayDealerAnim(dealer, animDict, anim) TriggerClientEvent("BLACKJACK:PlayDealerAnim", -1, dealer, animDict, anim) end function PlayDealerSpeech(dealer, speech) TriggerClientEvent("BLACKJACK:PlayDealerSpeech", -1, dealer, speech) end function SetPlayerBet(i, seat, bet, betId, double, split) split = split or false double = double or false local num = FindPlayerIdx(players[i], source) if num ~= nil then if double == false and split == false then TakeMoney(source, bet) players[i][num].bet = tonumber(bet) end TriggerClientEvent("BLACKJACK:PlaceBetChip", -1, i, 5-seat, bet, double, split) else DebugPrint("TABLE "..i..": PLAYER "..source.." ATTEMPTED BET BUT NO LONGER TRACKED?") end end RegisterServerEvent("BLACKJACK:SetPlayerBet") AddEventHandler('BLACKJACK:SetPlayerBet', SetPlayerBet) function CheckPlayerBet(i, bet) local Player = QBCore.Functions.GetPlayer(source) local ItemList = { ["casino_redchip"] = 1, } local playerChips = Player.Functions.GetItemByName("casino_redchip") local canBet = false if Player.PlayerData.items ~= nil and next(Player.PlayerData.items) ~= nil then for k, v in pairs(Player.PlayerData.items) do if Player.PlayerData.items[k] ~= nil then if ItemList[Player.PlayerData.items[k].name] ~= nil then if playerChips.amount >= bet then canBet = true end end end end end TriggerClientEvent("BLACKJACK:BetReceived", source, canBet) end RegisterServerEvent("BLACKJACK:CheckPlayerBet") AddEventHandler("BLACKJACK:CheckPlayerBet", CheckPlayerBet) function SortPlayers(pTable) local temp for i=1,#pTable-1 do for j=i+1,#pTable do if pTable[i].seat < pTable[j].seat then temp = pTable[i] pTable[i] = pTable[j] pTable[j] = temp end end end return pTable end RegisterServerEvent("BLACKJACK:ReceivedMove") function StartTableThread(i) Citizen.CreateThread(function() local index = i -- DebugPrint(index) while true do Wait(0) if players[index] and #players[index] ~= 0 then DebugPrint("WAITING FOR ALL PLAYERS AT TABLE "..index.." TO PLACE THEIR BETS.") PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_place_bet_request") PlayDealerSpeech(index, "MINIGAME_DEALER_PLACE_CHIPS") repeat for i,v in pairs(players[index]) do TriggerClientEvent("BLACKJACK:SyncTimer", v.player, bettingTime - timeTracker[index]) end -- Remove players from round who didn't bet in time Wait(1000) timeTracker[index] = timeTracker[index] + 1 until HaveAllPlayersBetted(players[index]) or #players[index] == 0 or timeTracker[index] >= bettingTime if #players[index] == 0 then DebugPrint("BETTING ENDED AT TABLE "..index..", NO MORE PLAYERS") -- break else for i,v in pairs(players[index]) do if v.bet < 1 then v.player_in = false end end -- Remove players from round who didn't bet in time if ArePlayersStillIn(players[index]) then -- did everyone just not bet? DebugPrint("BETS PLACED AT TABLE "..index..", STARTING GAME") PlayDealerSpeech(index, "MINIGAME_DEALER_CLOSED_BETS") local currentPlayers = {table.unpack(players[i])} local deck = getDeck() local dealerHand = {} local dealerVisibleHand = {} TriggerClientEvent("BLACKJACK:UpdateDealerHand", -1, index, handValue(dealerVisibleHand)) currentPlayers = SortPlayers(currentPlayers) local gameRunning = true Wait(1500) for x=1,2 do local card = takeCard(deck) table.insert(dealerHand, card) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, 0, #dealerHand, card, #dealerHand == 1) if #dealerHand == 1 then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_deal_card_self") DebugPrint("TABLE "..index..": DEALT DEALER [HIDDEN]") else PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_deal_card_self_second_card") DebugPrint("TABLE "..index..": DEALT DEALER "..card) table.insert(dealerVisibleHand, card) end Wait(2000) TriggerClientEvent("BLACKJACK:UpdateDealerHand", -1, index, handValue(dealerVisibleHand)) if #dealerHand > 1 then PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..cardValue(dealerHand[2])) end for i,v in pairs(currentPlayers) do if v.player_in then local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.hand+1, card) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_deal_card_player_0" .. 5-v.seat) table.insert(v.hand, card) Wait(2000) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.hand) == 21 then TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "good") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS BLACKJACK") GiveMoney(v.player, v.bet*2.5) v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_BLACKJACK") else PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) end end end end -- female_dealer_focus_player_01_idle if handValue(dealerHand) == 21 then DebugPrint("TABLE "..index..": DEALER HAS BLACKJACK") PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_check_and_turn_card") dealerVisibleHand = dealerHand TriggerClientEvent("BLACKJACK:DealerTurnOverCard", -1, index) Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_BLACKJACK") TriggerClientEvent("BLACKJACK:UpdateDealerHand", -1, index, handValue(dealerVisibleHand)) for i,v in pairs(currentPlayers) do TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") end gameRunning = false elseif cardValue(dealerHand[2]) == 10 or cardValue(dealerHand[2]) == 11 then DebugPrint("TABLE "..index..": DEALER HAS A 10, CHECKING..") PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_check_card") if ChackCardPropAnim then TriggerClientEvent("BLACKJACK:DealerCheckCard", -1, index) end Wait(2000) end if gameRunning == true then for i,v in pairs(currentPlayers) do if v.player_in then if tableTracker[tostring(v.player)] == nil then DebugPrint("TABLE "..index..": "..v.player.." WAS PUT OUT DUE TO LEAVING") v.player_in = false TriggerClientEvent("BLACKJACK:RetrieveCards", -1, index, v.seat) else PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_intro") Wait(1500) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_ANOTHER_CARD") while v.player_in == true and #v.hand < 5 do timeTracker[index] = 0 Wait(0) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle") DebugPrint("TABLE "..index..": AWAITING MOVE FROM "..GetPlayerName(v.player):upper()) TriggerClientEvent("BLACKJACK:RequestMove", v.player, moveTime - timeTracker[index]) local receivedMove = false local move = "stand" local eventHandler = AddEventHandler("BLACKJACK:ReceivedMove", function(m) if source ~= v.player then return end move = m receivedMove = true end) while receivedMove == false and tableTracker[tostring(v.player)] ~= nil and timeTracker[index] < moveTime do for i,v in pairs(currentPlayers) do TriggerClientEvent("BLACKJACK:SyncTimer", v.player, moveTime - timeTracker[index]) end Wait(1000) timeTracker[index] = timeTracker[index] + 1 end --repeat Wait(0) until receivedMove == true RemoveEventHandler(eventHandler) if tableTracker[tostring(v.player)] == nil then DebugPrint("TABLE "..index..": "..v.player.." WAS PUT OUT DUE TO LEAVING") v.player_in = false TriggerClientEvent("BLACKJACK:RetrieveCards", -1, index, v.seat) else if move == "hit" then local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.hand+1, card) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_card_player_0" .. 5-v.seat) table.insert(v.hand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.hand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) break elseif handValue(v.hand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(1000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) end elseif move == "double" then TakeMoney(v.player, v.bet) v.bet = v.bet*2 -- TriggerClientEvent("BLACKJACK:PlaceBetChip", -1, i, 5-v.seat, betId) local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.hand+1, card) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_card_player_0" .. 5-v.seat) table.insert(v.hand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.hand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) break elseif handValue(v.hand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) end break elseif move == "split" then TakeMoney(v.player, v.bet) v.bet = v.bet*2 -- TriggerClientEvent("BLACKJACK:PlaceBetChip", -1, i, 5-v.seat, betId) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_split_card_player_0" .. 5-v.seat) v.splitHand = {} local splitCard = table.remove(v.hand, 2) table.insert(v.splitHand, splitCard) Wait(500) TriggerClientEvent("BLACKJACK:SplitHand", -1, index, v.seat, #v.splitHand, v.hand, v.splitHand) Wait(1000) local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.hand+1, card, false, false) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_card_player_0" .. 5-v.seat) -- female_dealer_focus_player_01_idle_split table.insert(v.hand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.hand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_BLACKJACK") break elseif handValue(v.hand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) end local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.splitHand+1, card, false, true) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_second_card_player_0" .. 5-v.seat) table.insert(v.splitHand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.splitHand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.splitHand)) break elseif handValue(v.splitHand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.splitHand)) end -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_intro") -- Wait(1500) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_ANOTHER_CARD") repeat Wait(0) timeTracker[index] = 0 PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle") DebugPrint("TABLE "..index..": AWAITING MOVE FROM "..GetPlayerName(v.player):upper()) TriggerClientEvent("BLACKJACK:RequestMove", v.player, moveTime - timeTracker[index]) local receivedMove = false local move = "stand" local eventHandler = AddEventHandler("BLACKJACK:ReceivedMove", function(m) if source ~= v.player then return end move = m receivedMove = true end) while receivedMove == false and tableTracker[tostring(v.player)] ~= nil and timeTracker[index] < moveTime do for i,v in pairs(currentPlayers) do TriggerClientEvent("BLACKJACK:SyncTimer", v.player, moveTime - timeTracker[index]) end Wait(1000) timeTracker[index] = timeTracker[index] + 1 end --repeat Wait(0) until receivedMove == true RemoveEventHandler(eventHandler) if tableTracker[tostring(v.player)] == nil then DebugPrint("TABLE "..index..": "..v.player.." WAS PUT OUT DUE TO LEAVING") v.player_in = false TriggerClientEvent("BLACKJACK:RetrieveCards", -1, index, v.seat) print("breaking on 1st hand") break else if move == "hit" then local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.hand+1, card, false, false) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_card_player_0" .. 5-v.seat) table.insert(v.hand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.hand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) break elseif handValue(v.hand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(1000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.hand)) end elseif move == "stand" then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro_split") -- Wait(1500) break end end until handValue(v.hand) >= 21 or #v.hand == 5 if v.player_in == true then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_intro_split") Wait(1500) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_ANOTHER_CARD") repeat Wait(0) timeTracker[index] = 0 PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_split") print(""..v.player) DebugPrint("TABLE "..index..": AWAITING MOVE FROM "..GetPlayerName(v.player):upper()) TriggerClientEvent("BLACKJACK:RequestMove", v.player, moveTime - timeTracker[index]) local receivedMove = false local move = "stand" local eventHandler = AddEventHandler("BLACKJACK:ReceivedMove", function(m) if source ~= v.player then return end move = m receivedMove = true end) while receivedMove == false and tableTracker[tostring(v.player)] ~= nil and timeTracker[index] < moveTime do for i,v in pairs(currentPlayers) do TriggerClientEvent("BLACKJACK:SyncTimer", v.player, moveTime - timeTracker[index]) end Wait(1000) timeTracker[index] = timeTracker[index] + 1 end --repeat Wait(0) until receivedMove == true RemoveEventHandler(eventHandler) if tableTracker[tostring(v.player)] == nil then DebugPrint("TABLE "..index..": "..v.player.." WAS PUT OUT DUE TO LEAVING") v.player_in = false TriggerClientEvent("BLACKJACK:RetrieveCards", -1, index, v.seat) break else if move == "hit" then local card = takeCard(deck) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, v.seat, #v.splitHand+1, card, false, true) -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_hit_second_card_player_0" .. 5-v.seat) table.insert(v.splitHand, card) Wait(1500) DebugPrint("TABLE "..index..": DEALT "..GetPlayerName(v.player):upper().." "..card) if handValue(v.splitHand) == 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS 21") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.splitHand)) break elseif handValue(v.splitHand) > 21 then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WENT BUST") -- v.player_in = false PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_PLAYER_BUST") else -- Wait(1000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(v.splitHand)) end elseif move == "stand" then break end end until handValue(v.splitHand) >= 21 or #v.splitHand == 5 if handValue(v.hand) > 21 and handValue(v.splitHand) > 21 then v.player_in = false end PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro_split") Wait(1500) end break -- end elseif move == "stand" then -- PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") -- Wait(1500) break end end end if not v.splitHand then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_dealer_focus_player_0".. 5-v.seat .."_idle_outro") Wait(1500) end end end end -- Remove offline players from table local j = 1 while j <= #currentPlayers do local player = currentPlayers[j] if tableTracker[tostring(player.player)] == nil then DebugPrint("TABLE "..index..": "..player.player.." WAS REMOVED FROM PLAYERS LIST FOR LEAVING") table.remove(currentPlayers, j) else j = j + 1 end end if ArePlayersStillIn(currentPlayers) then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_turn_card") TriggerClientEvent("BLACKJACK:DealerTurnOverCard", -1, index) dealerVisibleHand = dealerHand Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(dealerHand)) TriggerClientEvent("BLACKJACK:UpdateDealerHand", -1, index, handValue(dealerVisibleHand)) end if handValue(dealerHand) < 17 and ArePlayersStillIn(currentPlayers) then repeat local card = takeCard(deck) table.insert(dealerHand, card) TriggerClientEvent("BLACKJACK:GiveCard", -1, index, 0, #dealerHand, card, #dealerHand == 1) PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_deal_card_self_second_card") DebugPrint("TABLE "..index..": DEALT DEALER "..card) Wait(2000) PlayDealerSpeech(index, "MINIGAME_BJACK_DEALER_"..handValue(dealerHand)) TriggerClientEvent("BLACKJACK:UpdateDealerHand", -1, index, handValue(dealerVisibleHand)) until handValue(dealerHand) >= 17 end end if handValue(dealerHand) > 21 then PlayDealerSpeech(index, "MINIGAME_DEALER_BUSTS") -- elseif handValue(dealerHand) < 21 and ArePlayersStillIn(currentPlayers) then -- PlayDealerSpeech(index, "MINIGAME_DEALER_WINS") end DebugPrint("TABLE "..index..": DEALER HAS "..handValue(dealerHand)) for i,v in pairs(currentPlayers) do -- if v.player_in then DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." HAS "..handValue(v.hand)) if v.player_in == true and (handValue(v.hand) > handValue(dealerHand) or handValue(dealerHand) > 21) then -- WIN if v.splitHand then if handValue(v.splitHand) > handValue(dealerHand) or handValue(dealerHand) > 21 then -- WIN TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "good") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WON") v.player_in = false end end TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "good") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." WON") GiveMoney(v.player, v.bet*2) v.player_in = false end if v.player_in == true and handValue(v.hand) == handValue(dealerHand) then -- PUSH if v.splitHand then if handValue(v.splitHand) == handValue(dealerHand) then -- PUSH TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "impartial") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." IS PUSH") v.player_in = false end end TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "impartial") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." IS PUSH") GiveMoney(v.player, v.bet) v.player_in = false end if v.player_in == true and handValue(v.hand) < handValue(dealerHand) and handValue(dealerHand) <= 21 then -- LOSE if v.splitHand then if handValue(v.splitHand) < handValue(dealerHand) and handValue(dealerHand) <= 21 then -- LOSE TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." LOST") v.player_in = false end end TriggerClientEvent("BLACKJACK:GameEndReaction", v.player, "bad") DebugPrint("TABLE "..index..": "..GetPlayerName(v.player):upper().." LOST") v.player_in = false end -- end end if handValue(dealerHand) >= 17 then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@shared@dealer@", "female_dealer_reaction_impartial_var0"..math.random(1,3)) elseif handValue(dealerHand) > 21 then PlayDealerAnim(index, "anim_casino_b@amb@casino@games@shared@dealer@", "female_dealer_reaction_good_var0"..math.random(1,3)) else PlayDealerAnim(index, "anim_casino_b@amb@casino@games@shared@dealer@", "female_dealer_reaction_bad_var0"..math.random(1,3)) end Wait(2500) for i,v in pairs(currentPlayers) do PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_retrieve_cards_player_0".. 5-v.seat) Wait(600) TriggerClientEvent("BLACKJACK:RetrieveCardsWithAnim", -1, index, v.seat) Wait(1400) v.bet = 0 v.player_in = true v.hand = {} v.splitHand = nil end PlayDealerAnim(index, "anim_casino_b@amb@casino@games@blackjack@dealer", "female_retrieve_own_cards_and_remove") Wait(600) TriggerClientEvent("BLACKJACK:RetrieveCardsWithAnim", -1, index, 0) Wait(1400) timeTracker[index] = 0 for i,v in pairs(currentPlayers) do TriggerClientEvent("BLACKJACK:RequestBets", v.player, index, timeTracker[index]) end -- while true do Wait(0) end else for i,v in pairs(players[index]) do v.bet = 0 v.player_in = true v.hand = {} v.splitHand = nil end timeTracker[index] = 0 end end end end end) end Citizen.CreateThread(function() -- INIT for i,_ in pairs(tables) do StartTableThread(i) players[i] = {} timeTracker[i] = 0 end end) function PlayerSatDown(i, seat) table.insert(players[i], {player = source, seat = seat, hand = {}, player_in = true, bet = 0}) tableTracker[tostring(source)] = i TriggerClientEvent("BLACKJACK:RequestBets", source, i) DebugPrint(GetPlayerName(source):upper() .. " SAT DOWN AT TABLE " .. i) DebugPrint(#players[i]) end RegisterServerEvent("BLACKJACK:PlayerSatDown") AddEventHandler('BLACKJACK:PlayerSatDown', PlayerSatDown) function PlayerSatUp(i) DebugPrint(GetPlayerName(source):upper() .. " LEFT TABLE "..i) local num = FindPlayerIdx(players[i], source) if num ~= nil then DebugPrint(GetPlayerName(source):upper() .. " SUCCESSFULLY REMOVED FROM TABLE "..i) table.remove(players[i], num) tableTracker[tostring(source)] = nil PlayDealerSpeech(i, "MINIGAME_DEALER_LEAVE_NEUTRAL_GAME") end end RegisterServerEvent("BLACKJACK:PlayerSatUp") AddEventHandler('BLACKJACK:PlayerSatUp', PlayerSatUp) function PlayerLeft() local playerTbl = tableTracker[tostring(source)] if playerTbl ~= nil then DebugPrint(GetPlayerName(source):upper() .. " LEFT SERVER") local num = FindPlayerIdx(players[playerTbl], source) if num ~= nil then DebugPrint(GetPlayerName(source):upper() .. " REMOVED FROM TABLE FOR LEAVING") table.remove(players[playerTbl], num) end tableTracker[tostring(source)] = nil end end AddEventHandler("playerDropped", PlayerLeft) function PlayerRemove(i) DebugPrint(GetPlayerName(source):upper() .. " LEFT TABLE "..i) local num = FindPlayerIdx(players[i], source) if num ~= nil then DebugPrint(GetPlayerName(source):upper() .. " SUCCESSFULLY REMOVED FROM TABLE "..i) local playerInfo = players[i][num] if playerInfo.player_in then if playerInfo.bet > 0 then GiveMoney(source, playerInfo.bet) -- give money back as player was removed before losing or winning? end end table.remove(players[i], num) tableTracker[tostring(source)] = nil PlayDealerSpeech(i, "MINIGAME_DEALER_LEAVE_NEUTRAL_GAME") end end RegisterServerEvent("BLACKJACK:PlayerRemove") AddEventHandler('BLACKJACK:PlayerRemove', PlayerRemove) exports("SetGetChipsCallback", SetGetChipsCallback) exports("SetTakeChipsCallback", SetTakeChipsCallback) exports("SetGiveChipsCallback", SetGiveChipsCallback) -- ==================================================================================== Added local ItemList = { ["casino_redchip"] = 1 } QBCore.Functions.CreateCallback('BLACKJACKKGV:server:blackChipsAmount', function(source, cb) local retval = 0 local Player = QBCore.Functions.GetPlayer(source) if Player.PlayerData.items ~= nil and next(Player.PlayerData.items) ~= nil then for k, v in pairs(Player.PlayerData.items) do if Player.PlayerData.items[k] ~= nil then if ItemList[Player.PlayerData.items[k].name] ~= nil then retval = retval + (ItemList[Player.PlayerData.items[k].name] * Player.PlayerData.items[k].amount) end end end end cb(retval) end) function SetExports() exports["casino-blackjackKGV"]:SetGetChipsCallback(function(source) local src = source local Player = QBCore.Functions.GetPlayer(src) local Chips = Player.Functions.GetItemByName("casino_redchip") local minAmount = 10 if Chips ~= nil then if Chips.amount >= minAmount then Chips = Chips else return TriggerClientEvent('QBCore:Notify', src, 'You dont have enough Casino Chips', 'error') end else return TriggerClientEvent('QBCore:Notify', src, 'You dont have any Casino Chips', 'error') end end) exports["casino-blackjackKGV"]:SetTakeChipsCallback(function(source, amount) local Player = QBCore.Functions.GetPlayer(source) if Player ~= nil then Player.Functions.RemoveItem("casino_redchip", amount) TriggerClientEvent('inventory:client:ItemBox', source, QBCore.Shared.Items['casino_redchip'], "remove", amount) end end) exports["casino-blackjackKGV"]:SetGiveChipsCallback(function(source, amount) local src = source local Player = QBCore.Functions.GetPlayer(source) if Player ~= nil then if Player.Functions.AddItem('casino_redchip', amount, nil, {["quality"] = 100}) then TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items["casino_redchip"], "add", amount) TriggerClientEvent('QBCore:Notify', src, "You Won "..math.floor(amount).." Casino Chips!") else TriggerClientEvent('QBCore:Notify', src, 'You have to much in your pockets', 'error') end end end) end AddEventHandler("onResourceStart", function(resourceName) if ("casino-blackjackKGV" == resourceName) then Citizen.Wait(1000) SetExports() end end) SetExports()