//::///////////////////////////////////////////////
//:: Default: BLACK JACK USER DEFINED
//:://////////////////////////////////////////////
/*
    Determines the course of action to be taken
    by the Black Jack dealer during the course of a game
*/
//:://////////////////////////////////////////////
//:: Created By: Keith Warner
//:: Created On: July 15, 2002
//:://////////////////////////////////////////////

// Function to count the total number of tokens in all stacks
#include "x3_inc_string"
#include "cas_casinoinc"

void CardCheck();
void AceCheck(int nCard, object oPC);
void InitialDeal(object oPC);
void DealerDrawRemainingCards();

void main()
{
    // on Spawn in - this should run
    // Set the words that the dealer is 'listening' for and give each an event number
    if (GetUserDefinedEventNumber() == 5000)
    {
        SetListenPattern(OBJECT_SELF, "Start", 500);
        SetListenPattern(OBJECT_SELF, "Hit", 1000);
        //SetListenPattern(OBJECT_SELF, "Hit Me", 1000);
        SetListenPattern(OBJECT_SELF, "Stand", 2000);
        SetListenPattern(OBJECT_SELF, "Total", 3000);
        SetListenPattern(OBJECT_SELF, "Quit", 4000); //NOT IMPLEMENTED YET
        SetListenPattern(OBJECT_SELF, "Join", 5000); //NOT IMPLEMENTED YET
        SetListening(OBJECT_SELF,FALSE);
    }
    // on Dialog event - this should fire
    if (GetUserDefinedEventNumber() == 1004)
    {
        //First off - Check to make sure that the Dealer has been told to start listening.
       if (GetIsListening(OBJECT_SELF))
       {
            //Get the object that the Dealer heard
            object oPC = GetLastSpeaker();
            //If that object is a PC
            if (GetIsPC(oPC))
            {
                // Get what the Dealer heard
                int nPattern = GetListenPatternNumber();
 //*****************************************************************************************
                //When someone says 'Start'
     // Make sure that the game is not already in progress for this player
    if (nPattern == 500) {
        // Make sure that the game is not already in progress for this player
        if (GetLocalInt(oPC, "nGameOn") == 1) {
            string sGreenText = StringToRGBString("What are you trying to pull, " + GetName(oPC) + ", you've already started!", "070");
            SpeakString(sGreenText);
        } else {
            // Get the wager amount from the conversation
            int nWager = GetLocalInt(OBJECT_SELF, "nWager");
            
            // Check for I_CAS_HANDLE item
            object oHandle = GetItemPossessedBy(oPC, "I_CAS_HANDLE");
            if (!GetIsObjectValid(oHandle)) {
                SpeakString("You do not have a token pouch, therefore you cannot play! You can get one by speaking with the help desk and setting your bet to '1' for slot machines.");
                return;
            }

            // Check player's token count
            int nPlayerTokens = GetLocalInt(oHandle, "nCAS_TOKEN");

            if (nPlayerTokens >= nWager) {
                // Deduct the wagered number of tokens from the player
                int nNewTokenTotal = nPlayerTokens - nWager;
                SetLocalInt(oHandle, "nCAS_TOKEN", nNewTokenTotal);

                // Inform the player about the deduction and their new token total
                SendMessageToPC(oPC, "Deducted " + IntToString(nWager) + " tokens. New total: " + IntToString(nNewTokenTotal) + " tokens.");

                // Add one to the number of players variable on the Dealer
                SetLocalInt(OBJECT_SELF, "nNumPlayers", GetLocalInt(OBJECT_SELF, "nNumPlayers") + 1);

                // Zero out the nAceCount variable
                SetLocalInt(oPC, "nAceCount", 0);
                SetLocalInt(oPC, "nGameOn", 1);
            
            // If the number of players playing is currently less than the max number of players
            if (GetLocalInt(OBJECT_SELF, "nNumPlayers") < GetLocalInt(OBJECT_SELF, "nMaxPlayers"))
            {
                InitialDeal(oPC);
                DelayCommand(6.0f, SpeakString(GetName(oPC) + ", you are in. Who else? Please say 'Start'."));
            }
            else
            {
                // Zero out the Dealer's Ace count
                SetLocalInt(OBJECT_SELF, "nAceCount", 0);
                // Draw Dealer's card
                SetLocalInt(OBJECT_SELF, "nDealerTotal", Random(10) + 1);
                // Draw PCs initial hand
                InitialDeal(oPC);

                // If Dealer has an Ace - say so and record it
                if (GetLocalInt(OBJECT_SELF, "nDealerTotal") == 1)
                {
                    DelayCommand(6.0f, SpeakString("Dealer is showing an Ace"));
                    SetLocalInt(OBJECT_SELF, "nAceCount", 1);
                }
                else
                {
                    string sDealerTotal = IntToString(GetLocalInt(OBJECT_SELF, "nDealerTotal"));
                    string sColoredDealerTotal = StringToRGBString("Dealer is showing a " + sDealerTotal, "070");
                    DelayCommand(6.0f, SpeakString(sColoredDealerTotal));
                }

                // Make the Player Counter point to the first player
                string sActionPrompt = StringToRGBString("What do you want to do, " + GetLocalString(OBJECT_SELF, "Player1Tag"), "070");
                DelayCommand(7.5f, SpeakString(sActionPrompt));

                SetLocalString(OBJECT_SELF, "szCurrentPlayer", "1");
            }
        }
        else
        {
            // Not enough tokens
                SpeakString(GetName(oPC) + ", you do not have enough tokens to make this bet! Get Lost! Game Over!!");
                SetListening(OBJECT_SELF, FALSE);
                SetLocalInt(OBJECT_SELF, "nPlayingBlackJack", 0);
    }
}
}

    

//*****************************************************************************************
                // When someone says 'Hit' - Make sure all players are in the game, then go through them
                // one at a time till they say 'Stand'
else if (nPattern == 1000)
{
    // Check if everyone has entered the game
    if (GetLocalInt(OBJECT_SELF, "nNumPlayers") < GetLocalInt(OBJECT_SELF, "nMaxPlayers"))
    {
        SpeakString("Hold your horses! Not everyone is in yet.");
    }
    else
    {
        // Check that only the current player is speaking
        if (GetName(oPC) != GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag"))
        {
            SpeakString("Hold up, " + GetName(oPC) + ", it's not your turn. It's " + GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag") + "'s turn.");
        }
        else
        {
            // Check that the current player has started the game
            if (GetLocalInt(oPC, "nGameOn") == 1)
            {
                // Draw a card
                SetLocalInt(oPC, "nBlackJackNextCard", Random(10) + 1);
                // Check if it's an ace
                AceCheck(GetLocalInt(oPC, "nBlackJackNextCard"), oPC);
                // Add to the Total for that PC
                SetLocalInt(oPC, "nBlackJackTotal", GetLocalInt(oPC, "nBlackJackTotal") + GetLocalInt(oPC, "nBlackJackNextCard"));

                string sNextCard = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackNextCard")), "070");

                if (GetLocalInt(oPC, "nBlackJackNextCard") == 1)
                {
                    SpeakString(GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag") + ". You've been dealt an Ace.");
                }
                else
                {
                    SpeakString(GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag") + ". You've been dealt a " + sNextCard + ".");
                }

                if (GetLocalInt(oPC, "nAceCount") > 0)
                {
                    int nTempTotal = GetLocalInt(oPC, "nBlackJackTotal") + 10;
                    if (nTempTotal > 21)
                    {
                        string sBlackJackTotal = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackTotal")), "070");
                        DelayCommand(2.0f, SpeakString("That gives you a total of " + sBlackJackTotal + "."));
                    }
                    else
                    {
                        string sBlackJackTotal = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackTotal")), "070");
                        string sTempTotal = StringToRGBString(IntToString(nTempTotal), "070");
                        DelayCommand(2.0f, SpeakString("That gives you a total of " + sBlackJackTotal + " or " + sTempTotal + "."));
                    }
                }
                else
                {
                    string sBlackJackTotal = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackTotal")), "070");
                    DelayCommand(2.0f, SpeakString("That gives you a total of " + sBlackJackTotal + "."));
                }

                if (GetLocalInt(oPC, "nBlackJackTotal") > 21)
                {
                    DelayCommand(1.0f, SpeakString("YOU BUSTED " + GetName(oPC) + "! HAHAHAHHAAH!"));
                    SetLocalInt(oPC, "nBusted", 1);
                    DelayCommand(1.0f, AssignCommand(oPC, PlaySound("as_pl_laughingm2")));
                    AssignCommand(OBJECT_SELF, PlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING, 1.0, 1.0));
                    AssignCommand(OBJECT_SELF, ActionSit(GetObjectByTag("DealerChair")));

                    if (StringToInt(GetLocalString(OBJECT_SELF, "szCurrentPlayer")) == GetLocalInt(OBJECT_SELF, "nMaxPlayers"))
                    {
                        DealerDrawRemainingCards();
                        CardCheck();
                    }
                    else
                    {
                        SetLocalString(OBJECT_SELF, "szCurrentPlayer", IntToString(StringToInt(GetLocalString(OBJECT_SELF, "szCurrentPlayer")) + 1));
                        string sPlayerTag = GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag");
                                                DelayCommand(4.0f, SpeakString("What do you want to do, " + sPlayerTag + "?"));
                    }
                }
                else
                {
                    string sBlackJackTotal = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackTotal")), "070");
                    DelayCommand(4.0f, SpeakString("What do you want to do, " + GetLocalString(OBJECT_SELF, "Player" + GetLocalString(OBJECT_SELF, "szCurrentPlayer") + "Tag") + "? Your total is " + sBlackJackTotal + "."));
                }
            }
            else
            {
                SpeakString("What are you trying to pull, " + GetName(oPC) + ", you're not even in the game!");
            }
        }
    }
}


//*****************************************************************************************
                //When someone says 'Stand', end that players turn and if all players have 'Stood' then deal the
                //dealer's cards and see who wins.
                else if (nPattern == 2000)
                {


                    //Check that only the current player is speaking
                    if (GetName(oPC) != GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag"))
                    {
                        if (GetLocalInt(oPC,"nGameOn") != 1)
                        {
                            SpeakString("What are you trying to pull, " + GetName(oPC) + "! We haven't even started yet!");
                        }
                        else
                        {
                            SpeakString("Hold up, its not your turn, " + GetName(oPC) + "! Its your turn, " + GetLocalString(OBJECT_SELF,"Player" + GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag"));
                        }
                    }
                    else
                    {
                        if (GetLocalInt(oPC,"nGameOn") != 1)
                        {
                            SpeakString("What are you trying to pull, " + GetName(oPC) + "! We haven't even started yet!");
                        }
                        else
                        {
                            //Confirm the player's 'Stand'
                            SpeakString(GetName(oPC) + " stands.");

                            //Calculate the Players true total (using Aces) and save it as his total
                            if (GetLocalInt(oPC,"nAceCount") > 0)
                            {
                                int nTempTotal = GetLocalInt(oPC,"nBlackJackTotal")+ 10;
                                if (nTempTotal < 22)
                                {
                                    SetLocalInt(oPC,"nBlackJackTotal",nTempTotal);
                                }
                            }
                            //Set the CurrentPlayer to the Next Player
                            SetLocalString(OBJECT_SELF,"szCurrentPlayer",IntToString(StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer"))+ 1));

                            //Check to see if all PCs have their cards, if so then the dealer can take his
                            if (StringToInt(GetLocalString(OBJECT_SELF,"szCurrentPlayer")) > GetLocalInt(OBJECT_SELF,"nMaxPlayers"))
                            {
                                //Loop for the dealer to get his remaining cards
                                DealerDrawRemainingCards();
                                CardCheck();
                            }
                            //if not all players have their cards - tell the next player that its their turn
                            else
                            {
                                DelayCommand(1.0f,SpeakString("Ok, "+ GetLocalString(OBJECT_SELF,"Player"+ GetLocalString(OBJECT_SELF,"szCurrentPlayer")+"Tag") + ", its your turn"));
                            }
                        }
                    }
                }
//*****************************************************************************************
                //If somebody shouts 'total
else if (nPattern == 3000)
{
    if (GetLocalInt(oPC, "nGameOn") != 1)
    {
        SpeakString("What are you trying to pull, " + GetName(oPC) + "! We haven't even started yet!");
    }
    else
    {
        if (GetLocalInt(oPC, "nAceCount") > 0)
        {
            int nTempTotal = GetLocalInt(oPC, "nBlackJackTotal") + 10;
            if (nTempTotal < 22)
            {
                string sTotal = IntToString(GetLocalInt(oPC, "nBlackJackTotal"));
                string sTempTotal = IntToString(nTempTotal);
                string sColoredTotal = StringToRGBString(sTotal, STRING_COLOR_GREEN);
                string sColoredTempTotal = StringToRGBString(sTempTotal, STRING_COLOR_GREEN);
                SpeakString(GetName(oPC) + ", your total is " + sColoredTotal + " or " + sColoredTempTotal);
            }
            else
            {
                string sTotal = IntToString(GetLocalInt(oPC, "nBlackJackTotal"));
                string sColoredTotal = StringToRGBString(sTotal, STRING_COLOR_GREEN);
                SpeakString(GetName(oPC) + ", your total is " + sColoredTotal);
            }
        }
        else
        {
            string sTotal = IntToString(GetLocalInt(oPC, "nBlackJackTotal"));
            string sColoredTotal = StringToRGBString(sTotal, STRING_COLOR_GREEN);
            SpeakString(GetName(oPC) + ", your total is " + sColoredTotal);
        }
    }
}

//*****************************************************************************************
                //If somebody shouts 'Quit'   NOT IMPLEMENTED YET
                else if (nPattern == 4000)
                {

                }
//*****************************************************************************************
                //If somebody shouts 'Join'    NOT IMPLEMENTED YET
                else if (nPattern == 5000)
                {

                }

            }
       }
    }
}

//*****************************************************************************************
void CardCheck() {
    int nMax = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
    int nWager = GetLocalInt(OBJECT_SELF, "nWager");

    for (int nCount = 1; nCount <= nMax; nCount++) {
        string szName = GetLocalString(OBJECT_SELF, "Player" + IntToString(nCount) + "Tag");
        int nFound = FALSE;
        object oPC = GetFirstPC();

        while (!nFound && GetIsObjectValid(oPC)) {
            if (szName == GetName(oPC)) {
                nFound = TRUE;

                object oHandle = GetItemPossessedBy(oPC, "I_CAS_HANDLE");
                if (!GetIsObjectValid(oHandle)) {
                    continue; // Skip to next player if handle is not found
                }

                int nCurrentTokens = GetLocalInt(oHandle, "nCAS_TOKEN");
                int nCurrentTickets = GetLocalInt(oHandle, "nCAS_TICKET");

                if (GetLocalInt(oPC, "nBusted") == 1) {
                    if (nCurrentTokens >= nWager) {
                        SetLocalInt(oHandle, "nCAS_TOKEN", nCurrentTokens - nWager);
                        SendMessageToPC(oPC, "You busted and lost " + IntToString(nWager) + " tokens.");
                    }
                    SetLocalInt(oPC, "nBusted", 0);
                } else if (GetLocalInt(oPC, "nBlackJack") == 1) {
                    int nTicketsToAward = (nWager * 3) / 2;
                    SetLocalInt(oHandle, "nCAS_TICKET", nCurrentTickets + nTicketsToAward);
                    SendMessageToPC(oPC, "BlackJack! You won " + IntToString(nTicketsToAward) + " tickets.");
                    SetLocalInt(oPC, "nBlackJack", 0);
                } else {
                   
                

                DeleteLocalInt(oPC, "nGameOn");
                DeleteLocalInt(oPC, "nBusted");
                DeleteLocalInt(oPC, "nBlackJack");
            }

            oPC = GetNextPC();
        }
    }

    SetLocalInt(OBJECT_SELF, "nNumPlayers", 0);
    SetLocalInt(OBJECT_SELF, "nBusted", 0);
}

// check to see if the card passed in is an Ace, if so - set a variable on that PC
void AceCheck(int nCard, object oPC)
{
    if (nCard == 1)
    {
        SetLocalInt(oPC,"nAceCount",GetLocalInt(oPC,"nAceCount") + 1);
    }
}

void InitialDeal(object oPC)
{
    // Deal a random card to the PC
    SetLocalInt(oPC, "nBlackJackCard1", Random(10) + 1);
    // Check if it was an Ace
    AceCheck(GetLocalInt(oPC, "nBlackJackCard1"), oPC);
    // Deal a second card to the PC
    SetLocalInt(oPC, "nBlackJackCard2", Random(10) + 1);
    // Check if it was an ace too
    AceCheck(GetLocalInt(oPC, "nBlackJackCard2"), oPC);
    SetLocalInt(oPC, "nBlackJackTotal", GetLocalInt(oPC, "nBlackJackCard1") + GetLocalInt(oPC, "nBlackJackCard2"));
    // Set a variable for each player
    SetLocalString(OBJECT_SELF, "Player" + IntToString(GetLocalInt(OBJECT_SELF, "nNumPlayers")) + "Tag", GetName(oPC));

    string sCard1 = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackCard1")), "070");
    string sCard2 = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackCard2")), "070");

    if (GetLocalInt(oPC, "nBlackJackCard1") == 1)
    {
        if (GetLocalInt(oPC, "nBlackJackCard2") == 1)
        {
            DelayCommand(2.0f, SpeakString(GetName(oPC) + ", you've been dealt an Ace and another Ace"));
        }
        else
        {
            DelayCommand(2.0f, SpeakString(GetName(oPC) + ", you've been dealt an Ace and a " + sCard2));
        }
    }
    else
    {
        if (GetLocalInt(oPC, "nBlackJackCard2") == 1)
        {
            DelayCommand(2.0f, SpeakString(GetName(oPC) + ", you've been dealt a " + sCard1 + " and an Ace."));
        }
        else
        {
            DelayCommand(2.0f, SpeakString(GetName(oPC) + ", you've been dealt a " + sCard1 + " and a " + sCard2));
        }
    }

    string szTempString = ".";
    int nTempTotal = GetLocalInt(oPC, "nBlackJackTotal");
    if (GetLocalInt(oPC, "nAceCount") > 0)
    {
        nTempTotal = nTempTotal + 10;
        if (nTempTotal < 22)
        {
            szTempString = " or " + StringToRGBString(IntToString(nTempTotal), "070");
        }
    }

    string sTotal = StringToRGBString(IntToString(GetLocalInt(oPC, "nBlackJackTotal")), "070");
    DelayCommand(4.0f, SpeakString("This gives you a total of " + sTotal + szTempString));

    // Check for BlackJack
    if (nTempTotal == 21)
    {
        DelayCommand(5.0f, SpeakString("BlackJack!!"));
        SetLocalInt(oPC, "nBlackJack", 1);
        AssignCommand(oPC, PlaySound("as_cv_bell2"));
    }
}


void DealerDrawRemainingCards()
{
    string szTempString = "";
    //Draw cards for the dealer as long as the dealers total is less than 17 - Dealer stands on 17
    do
    {
        SetLocalInt(OBJECT_SELF,"nDealerCard2", Random(10)+1);
        AceCheck(GetLocalInt(OBJECT_SELF,"nDealerCard2"),OBJECT_SELF);
        SetLocalInt(OBJECT_SELF,"nDealerTotal", GetLocalInt(OBJECT_SELF,"nDealerTotal") + GetLocalInt(OBJECT_SELF,"nDealerCard2"));
        //If dealer drew an Ace - say so - calculate the total with any aces the Dealer may have
        if (GetLocalInt(OBJECT_SELF,"nDealerCard2") == 1)
        {
            int nTempTotal = GetLocalInt(OBJECT_SELF,"nDealerTotal") + 10;
            if (nTempTotal > 21)
            {
                szTempString = szTempString + "Dealer draws an Ace for a total of " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerTotal")) + ". ";
            }
            else if (nTempTotal > 16)
            {
                SetLocalInt(OBJECT_SELF,"nDealerTotal",nTempTotal);
                szTempString = szTempString + "Dealer draws an Ace for a total of " + IntToString(nTempTotal)+ ". ";
            }
            else
            {
                szTempString = szTempString + "Dealer draws an Ace for a total of " + IntToString(nTempTotal)+ ". ";
            }
        }
        else
        {
            szTempString = szTempString + "Dealer draws a " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerCard2")) + " for a total of " + IntToString(GetLocalInt(OBJECT_SELF,"nDealerTotal")) + ". ";
        }
    }
    while (GetLocalInt(OBJECT_SELF,"nDealerTotal") < 17);
    SetLocalString(OBJECT_SELF,"szDealerDraw",szTempString);
    //Check to see if the Dealer has gone over 21 and Busted
    if (GetLocalInt(OBJECT_SELF,"nDealerTotal") > 21)
    {

        DelayCommand(3.0f,PlayVoiceChat(VOICE_CHAT_CUSS,OBJECT_SELF));
        SetLocalInt(OBJECT_SELF,"nBusted",1);
    }
    //Display what the dealer has drawn - Best timing seemed to be to say everything at once rather
    //than speaking each time the dealer drew a card.
    DelayCommand(2.0f,SpeakString(GetLocalString(OBJECT_SELF,"szDealerDraw")));
}