mirror of
https://github.com/araxiaonline/AIO-Blackjack.git
synced 2026-06-13 03:02:26 -04:00
453 lines
18 KiB
Lua
453 lines
18 KiB
Lua
--Made by Manmadedrummer for Araxia Server
|
|
|
|
local AIO = AIO or require("AIO")
|
|
|
|
if AIO.AddAddon() then
|
|
return
|
|
end
|
|
|
|
local BlackjackHandler = AIO.AddHandlers("Blackjack", {})
|
|
|
|
-- Constants
|
|
local REQUIRED_GOLD = 500 * 10000 -- 500 gold in copper
|
|
|
|
-- Function to check if the player has enough gold
|
|
local function CanPlayerAffordGame()
|
|
return GetMoney() >= REQUIRED_GOLD
|
|
end
|
|
|
|
local REQUIRED_BET_GOLD = 200 * 10000 -- 200 gold in copper
|
|
|
|
-- Function to check if the player has enough gold for the bet
|
|
local function CanPlayerAffordBet()
|
|
return GetMoney() >= REQUIRED_BET_GOLD
|
|
end
|
|
|
|
-- Declare buttons and game state variables at the top to avoid nil errors
|
|
local drawButton, standButton, betButton, playAgainButton
|
|
local gameActive = true -- Flag to track if the game is active
|
|
local playerCardFrames = {} -- Stores player card frames for easy reset
|
|
local dealerCardFrames = {} -- Stores dealer card frames for easy reset
|
|
local currentBet = 0 -- Track current bet amount
|
|
|
|
-- Function to disable buttons after the game ends
|
|
local function DisableButtons()
|
|
if drawButton then drawButton:Disable() end
|
|
if standButton then standButton:Disable() end
|
|
if betButton then betButton:Disable() end
|
|
end
|
|
|
|
-- Function to enable buttons for a new game
|
|
local function EnableButtons()
|
|
if drawButton then drawButton:Enable() end
|
|
if standButton then standButton:Enable() end
|
|
if betButton then betButton:Enable() end
|
|
end
|
|
|
|
-- Function to clear all existing card frames
|
|
local function ClearCardFrames()
|
|
for _, frame in ipairs(playerCardFrames) do
|
|
frame:Hide()
|
|
end
|
|
for _, frame in ipairs(dealerCardFrames) do
|
|
frame:Hide()
|
|
end
|
|
playerCardFrames = {}
|
|
dealerCardFrames = {}
|
|
end
|
|
|
|
-- Complete mapping of card values to their image file paths
|
|
local cardImagePaths = {
|
|
-- Clubs
|
|
["Club_2"] = "Interface\\Cards\\Club_2.blp",
|
|
["Club_3"] = "Interface\\Cards\\Club_3.blp",
|
|
["Club_4"] = "Interface\\Cards\\Club_4.blp",
|
|
["Club_5"] = "Interface\\Cards\\Club_5.blp",
|
|
["Club_6"] = "Interface\\Cards\\Club_6.blp",
|
|
["Club_7"] = "Interface\\Cards\\Club_7.blp",
|
|
["Club_8"] = "Interface\\Cards\\Club_8.blp",
|
|
["Club_9"] = "Interface\\Cards\\Club_9.blp",
|
|
["Club_10"] = "Interface\\Cards\\Club_10.blp",
|
|
["Club_J"] = "Interface\\Cards\\Club_11.blp", -- Jack
|
|
["Club_Q"] = "Interface\\Cards\\Club_12.blp", -- Queen
|
|
["Club_K"] = "Interface\\Cards\\Club_13.blp", -- King
|
|
["Club_A"] = "Interface\\Cards\\Club_14.blp", -- Ace
|
|
|
|
-- Diamonds
|
|
["Diamond_2"] = "Interface\\Cards\\Diamond_2.blp",
|
|
["Diamond_3"] = "Interface\\Cards\\Diamond_3.blp",
|
|
["Diamond_4"] = "Interface\\Cards\\Diamond_4.blp",
|
|
["Diamond_5"] = "Interface\\Cards\\Diamond_5.blp",
|
|
["Diamond_6"] = "Interface\\Cards\\Diamond_6.blp",
|
|
["Diamond_7"] = "Interface\\Cards\\Diamond_7.blp",
|
|
["Diamond_8"] = "Interface\\Cards\\Diamond_8.blp",
|
|
["Diamond_9"] = "Interface\\Cards\\Diamond_9.blp",
|
|
["Diamond_10"] = "Interface\\Cards\\Diamond_10.blp",
|
|
["Diamond_J"] = "Interface\\Cards\\Diamond_11.blp", -- Jack
|
|
["Diamond_Q"] = "Interface\\Cards\\Diamond_12.blp", -- Queen
|
|
["Diamond_K"] = "Interface\\Cards\\Diamond_13.blp", -- King
|
|
["Diamond_A"] = "Interface\\Cards\\Diamond_14.blp", -- Ace
|
|
|
|
-- Hearts
|
|
["Hearts_2"] = "Interface\\Cards\\Hearts_2.blp",
|
|
["Hearts_3"] = "Interface\\Cards\\Hearts_3.blp",
|
|
["Hearts_4"] = "Interface\\Cards\\Hearts_4.blp",
|
|
["Hearts_5"] = "Interface\\Cards\\Hearts_5.blp",
|
|
["Hearts_6"] = "Interface\\Cards\\Hearts_6.blp",
|
|
["Hearts_7"] = "Interface\\Cards\\Hearts_7.blp",
|
|
["Hearts_8"] = "Interface\\Cards\\Hearts_8.blp",
|
|
["Hearts_9"] = "Interface\\Cards\\Hearts_9.blp",
|
|
["Hearts_10"] = "Interface\\Cards\\Hearts_10.blp",
|
|
["Hearts_J"] = "Interface\\Cards\\Hearts_11.blp", -- Jack
|
|
["Hearts_Q"] = "Interface\\Cards\\Hearts_12.blp", -- Queen
|
|
["Hearts_K"] = "Interface\\Cards\\Hearts_13.blp", -- King
|
|
["Hearts_A"] = "Interface\\Cards\\Hearts_14.blp", -- Ace
|
|
|
|
-- Spades
|
|
["Spades_2"] = "Interface\\Cards\\Spades_2.blp",
|
|
["Spades_3"] = "Interface\\Cards\\Spades_3.blp",
|
|
["Spades_4"] = "Interface\\Cards\\Spades_4.blp",
|
|
["Spades_5"] = "Interface\\Cards\\Spades_5.blp",
|
|
["Spades_6"] = "Interface\\Cards\\Spades_6.blp",
|
|
["Spades_7"] = "Interface\\Cards\\Spades_7.blp",
|
|
["Spades_8"] = "Interface\\Cards\\Spades_8.blp",
|
|
["Spades_9"] = "Interface\\Cards\\Spades_9.blp",
|
|
["Spades_10"] = "Interface\\Cards\\Spades_10.blp",
|
|
["Spades_J"] = "Interface\\Cards\\Spades_11.blp", -- Jack
|
|
["Spades_Q"] = "Interface\\Cards\\Spades_12.blp", -- Queen
|
|
["Spades_K"] = "Interface\\Cards\\Spades_13.blp", -- King
|
|
["Spades_A"] = "Interface\\Cards\\Spades_14.blp", -- Ace
|
|
}
|
|
|
|
-- Function to create and display the Blackjack game frame
|
|
local function CreateBlackjackFrame()
|
|
-- Create the main frame
|
|
local frame = CreateFrame("Frame", "BlackjackFrame", UIParent)
|
|
frame:SetSize(720, 520) -- Frame size
|
|
frame:SetPoint("CENTER", UIParent, "CENTER")
|
|
|
|
frame:SetBackdrop({
|
|
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
|
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
|
tile = true, tileSize = 32, edgeSize = 32,
|
|
insets = { left = 11, right = 12, top = 12, bottom = 11 }
|
|
})
|
|
frame:SetBackdropColor(0, 0, 0, 1)
|
|
|
|
local closeButton = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
|
|
closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT")
|
|
|
|
-- Create the player's and dealer's hands tables to hold drawn cards
|
|
local playerHand = {}
|
|
local dealerHand = {}
|
|
|
|
-- Create FontStrings to display the values of the hands
|
|
local dealerValueText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
|
|
dealerValueText:SetPoint("TOPLEFT", frame, "TOPLEFT", 20, -25)
|
|
dealerValueText:SetText("Dealer Value: 0")
|
|
|
|
local playerValueText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
|
|
playerValueText:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 20, 25)
|
|
playerValueText:SetText("Player Value: 0")
|
|
|
|
-- Create FontString to display the bet amount
|
|
local betValueText = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
|
|
betValueText:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -20, 25)
|
|
betValueText:SetText("Bet: 0g")
|
|
|
|
-- Function to create a label and a card next to it
|
|
local function CreateLabelAndCard(labelText, card, parentFrame, labelX, labelY, cardX, cardOffset, isDealer)
|
|
-- Create the label
|
|
local label = parentFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
label:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", labelX, labelY)
|
|
label:SetText(labelText)
|
|
|
|
-- Create the card next to the label
|
|
local cardSize = 128
|
|
local cardFrame = CreateFrame("Frame", nil, parentFrame)
|
|
cardFrame:SetSize(cardSize, cardSize)
|
|
cardFrame:SetPoint("TOPLEFT", label, "TOPRIGHT", cardX + cardOffset, 0)
|
|
|
|
local texture = cardFrame:CreateTexture(nil, "BACKGROUND")
|
|
texture:SetAllPoints(cardFrame)
|
|
|
|
-- Get the direct image path from the mapping
|
|
local imagePath = cardImagePaths[card.suit .. "_" .. card.displayValue]
|
|
|
|
if texture then
|
|
texture:SetTexture(imagePath)
|
|
else
|
|
print("Error: Could not find card image at path: " .. imagePath)
|
|
end
|
|
|
|
cardFrame.texture = texture
|
|
|
|
-- Add to appropriate card frame list
|
|
if isDealer then
|
|
table.insert(dealerCardFrames, cardFrame)
|
|
else
|
|
table.insert(playerCardFrames, cardFrame)
|
|
end
|
|
end
|
|
|
|
-- Function to generate a random card with correct values
|
|
local function GetRandomCard(excludeCard)
|
|
local suits = {"Club", "Diamond", "Hearts", "Spades"}
|
|
local values = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}
|
|
|
|
local card
|
|
repeat
|
|
local suit = suits[math.random(#suits)]
|
|
local value = values[math.random(#values)]
|
|
|
|
card = { suit = suit, displayValue = value }
|
|
until not (excludeCard and excludeCard.suit == card.suit and excludeCard.displayValue == card.displayValue)
|
|
|
|
return card
|
|
end
|
|
|
|
-- Function to calculate the total value of a hand
|
|
local function CalculateHandValue(hand)
|
|
local total = 0
|
|
local aces = 0
|
|
|
|
for _, card in ipairs(hand) do
|
|
local value = card.displayValue
|
|
if value == "J" or value == "Q" or value == "K" then
|
|
total = total + 10
|
|
elseif value == "A" then
|
|
total = total + 11
|
|
aces = aces + 1
|
|
else
|
|
total = total + tonumber(value)
|
|
end
|
|
end
|
|
|
|
-- Adjust for aces
|
|
while total > 21 and aces > 0 do
|
|
total = total - 10
|
|
aces = aces - 1
|
|
end
|
|
|
|
return total
|
|
end
|
|
|
|
-- Function to start a new game by randomizing the dealer and player cards
|
|
local function StartNewGame()
|
|
gameActive = true -- Set the game as active
|
|
currentBet = 0 -- Reset the current bet
|
|
betValueText:SetText("Bet: 0g") -- Reset bet display
|
|
ClearCardFrames() -- Clear any existing cards from the previous game
|
|
|
|
-- Generate two random cards for the dealer
|
|
local dealerCard1 = GetRandomCard()
|
|
local dealerCard2 = GetRandomCard(dealerCard1)
|
|
dealerHand = {dealerCard1, dealerCard2}
|
|
|
|
-- Generate one random card for the player
|
|
local playerCard1 = GetRandomCard(dealerCard1)
|
|
playerHand = {playerCard1}
|
|
|
|
-- Display the dealer's label and cards
|
|
CreateLabelAndCard("Dealer:", dealerCard1, frame, 20, -40, 10, 0, true)
|
|
|
|
-- Display the player's label and cards
|
|
CreateLabelAndCard("Player:", playerCard1, frame, 20, -320, 10, 0, false)
|
|
|
|
-- Update the displayed hand values
|
|
dealerValueText:SetText("Dealer Value: " .. CalculateHandValue({dealerCard1}))
|
|
playerValueText:SetText("Player Value: " .. CalculateHandValue(playerHand))
|
|
|
|
EnableButtons() -- Re-enable the buttons for a new game
|
|
playAgainButton:Disable() -- Disable play again until the game is over
|
|
end
|
|
|
|
-- Function to handle the drawing of an additional card for the player
|
|
local function DrawCardForPlayer()
|
|
if gameActive and #playerHand < 4 then -- Limiting the player to drawing a maximum of 4 cards
|
|
-- Generate a new card for the player
|
|
local newCard = GetRandomCard()
|
|
|
|
-- Add the new card to the player's hand
|
|
table.insert(playerHand, newCard)
|
|
|
|
-- Display the new card next to the previous ones
|
|
CreateLabelAndCard("", newCard, frame, 0, -320, 150, (#playerHand - 1) * 140, false)
|
|
|
|
-- Update the player's hand value display
|
|
playerValueText:SetText("Player Value: " .. CalculateHandValue(playerHand))
|
|
|
|
-- Request the server to play the draw card sound
|
|
AIO.Handle("Blackjack", "HandleDrawCard")
|
|
|
|
-- Check if the player busts
|
|
if CalculateHandValue(playerHand) > 21 then
|
|
print("Player busts! |cffFF0000Dealer wins.|r") -- Red text for dealer win
|
|
gameActive = false -- Deactivate the game
|
|
DisableButtons()
|
|
playAgainButton:Enable() -- Enable the play again button
|
|
end
|
|
elseif not gameActive then
|
|
print("The game is over. Please close the frame and start a new game.")
|
|
else
|
|
print("|cffff69b4Player cannot draw more than 4 cards.|r")
|
|
end
|
|
end
|
|
|
|
-- Function to handle the dealer's actions after the player stands
|
|
local function DealerTurn()
|
|
if gameActive then
|
|
-- Reveal the dealer's second card
|
|
CreateLabelAndCard("", dealerHand[2], frame, 0, -40, 150, 0, true)
|
|
|
|
-- Continue drawing cards for the dealer until the total is 17 or more
|
|
while CalculateHandValue(dealerHand) < 17 do
|
|
local newCard = GetRandomCard()
|
|
table.insert(dealerHand, newCard)
|
|
CreateLabelAndCard("", newCard, frame, 0, -40, 150, (#dealerHand - 2) * 140, true)
|
|
end
|
|
|
|
-- Update the dealer's hand value display
|
|
dealerValueText:SetText("Dealer Value: " .. CalculateHandValue(dealerHand))
|
|
|
|
-- Determine the winner and display the result
|
|
local playerTotal = CalculateHandValue(playerHand)
|
|
local dealerTotal = CalculateHandValue(dealerHand)
|
|
local playerHasBlackjack = #playerHand == 2 and playerTotal == 21
|
|
local dealerHasBlackjack = #dealerHand == 2 and dealerTotal == 21
|
|
|
|
if dealerHasBlackjack and not playerHasBlackjack then
|
|
print("|cffFF0000Dealer wins.|r")
|
|
elseif dealerHasBlackjack and playerHasBlackjack then
|
|
print("|cffFF7F00Push, bets are returned. Try again!|r")
|
|
AIO.Handle("Blackjack", "HandlePlayerWin", currentBet, 1)
|
|
elseif playerHasBlackjack then
|
|
print("Player got a BLACKJACK!!!")
|
|
AIO.Handle("Blackjack", "HandlePlayerWin", currentBet, 3)
|
|
elseif playerTotal > 21 then
|
|
print("Player busts! |cffFF0000Dealer wins.|r")
|
|
elseif playerTotal == dealerTotal then
|
|
print("|cffFF7F00Push, bets are returned. Try again!|r")
|
|
AIO.Handle("Blackjack", "HandlePlayerWin", currentBet, 1)
|
|
elseif dealerTotal > 21 or playerTotal > dealerTotal then
|
|
print("Player wins!")
|
|
AIO.Handle("Blackjack", "HandlePlayerWin", currentBet, 2)
|
|
else
|
|
print("|cffFF0000Dealer wins.|r")
|
|
end
|
|
|
|
gameActive = false -- Deactivate the game after dealer's turn
|
|
DisableButtons()
|
|
playAgainButton:Enable() -- Enable the play again button
|
|
else
|
|
print("The game is over. Please close the frame and start a new game.")
|
|
end
|
|
end
|
|
|
|
-- Function to handle betting
|
|
-- local function PlaceBet()
|
|
-- if gameActive and #playerHand == 1 then -- Allow betting only before drawing the second card
|
|
-- local betAmount = 200 * 10000 -- 200 gold in copper
|
|
-- currentBet = currentBet + betAmount
|
|
-- betValueText:SetText("Bet: " .. (currentBet / 10000) .. "g") -- Update bet amount display in gold
|
|
--
|
|
-- -- Deduct the bet amount from the player's money
|
|
-- AIO.Handle("Blackjack", "HandleBet", betAmount)
|
|
--
|
|
-- -- Play the sound when the bet is placed
|
|
-- AIO.Handle("Blackjack", "HandlePlaySound", 895)
|
|
-- else
|
|
-- print("|cffff69b4You can only bet before drawing the second card.|r")
|
|
-- end
|
|
-- end
|
|
|
|
local function PlaceBet()
|
|
if gameActive and #playerHand == 1 then -- Allow betting only before drawing the second card
|
|
if CanPlayerAffordBet() then
|
|
local betAmount = 200 * 10000 -- 200 gold in copper
|
|
currentBet = currentBet + betAmount
|
|
betValueText:SetText("Bet: " .. (currentBet / 10000) .. "g") -- Update bet amount display in gold
|
|
|
|
-- Deduct the bet amount from the player's money
|
|
AIO.Handle("Blackjack", "HandleBet", betAmount)
|
|
|
|
-- Play the sound when the bet is placed
|
|
AIO.Handle("Blackjack", "HandlePlaySound", 895)
|
|
else
|
|
print("|cffff7f00You don't have enough gold to place a bet!|r")
|
|
end
|
|
else
|
|
print("|cffff69b4You can only bet before drawing the second card.|r")
|
|
end
|
|
end
|
|
|
|
-- Create a button for drawing a card
|
|
drawButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
drawButton:SetSize(100, 30)
|
|
drawButton:SetPoint("CENTER", frame, "CENTER", -100, -40)
|
|
drawButton:SetText("Draw Card")
|
|
drawButton:SetScript("OnClick", function()
|
|
if gameActive then
|
|
DrawCardForPlayer()
|
|
else
|
|
DisableButtons()
|
|
end
|
|
end)
|
|
|
|
-- Create a button for standing (ending the player's turn)
|
|
standButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
standButton:SetSize(100, 30)
|
|
standButton:SetPoint("CENTER", frame, "CENTER", 20, -40)
|
|
standButton:SetText("Stand")
|
|
standButton:SetScript("OnClick", function()
|
|
if gameActive then
|
|
DealerTurn()
|
|
else
|
|
DisableButtons()
|
|
end
|
|
end)
|
|
|
|
-- Create a button for betting
|
|
betButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
betButton:SetSize(100, 30)
|
|
betButton:SetPoint("CENTER", frame, "CENTER", 140, -40)
|
|
betButton:SetText("Bet")
|
|
betButton:SetScript("OnClick", function()
|
|
if gameActive then
|
|
PlaceBet()
|
|
else
|
|
DisableButtons()
|
|
end
|
|
end)
|
|
|
|
-- Create a button for playing again
|
|
playAgainButton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
|
|
playAgainButton:SetSize(100, 30)
|
|
playAgainButton:SetPoint("CENTER", frame, "CENTER", 260, -40)
|
|
playAgainButton:SetText("Play Again")
|
|
playAgainButton:SetScript("OnClick", function()
|
|
if not gameActive then
|
|
if CanPlayerAffordGame() then
|
|
AIO.Handle("Blackjack", "HandleStartGame")
|
|
StartNewGame()
|
|
else
|
|
print("|cffff7f00You don't have enough gold to play again!|r")
|
|
end
|
|
else
|
|
DisableButtons()
|
|
end
|
|
end)
|
|
playAgainButton:Disable()
|
|
|
|
|
|
-- Start the game for the first time when the frame is shown
|
|
StartNewGame()
|
|
|
|
frame:Show()
|
|
end
|
|
|
|
-- AIO handler function to trigger the frame display
|
|
function BlackjackHandler.ShowBlackjackFrame()
|
|
CreateBlackjackFrame()
|
|
end
|