//::///////////////////////////////////////////////
//:: 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
//:://////////////////////////////////////////////
#include "cas_casinoinc"

void CardCheck();
void AceCheck(int nCard, object oPC);
void InitialDeal(object oPC, int nPlayerNumber);
void DealerDrawRemainingCards();

// Added functions -DarkSorcerer (July 23 2026)
void BlackJack_Start(object oSpeaker);
void BlackJack_HitMe(object oSpeaker, int nPlayerNumber);
void BlackJack_Stand(object oSpeaker, int nPlayerNumber);
void BlackJack_Total(object oSpeaker, int nPlayerNumber);
void BlackJack_Quit(object oSpeaker);
void BlackJack_Join(object oSpeaker);
void BlackJack_Reset();
int GetIsGameRunning();
int GetBlackJackID(object oSpeaker);
int DealerBlackJackCheck(int nCard1, int nCard2);
float DisplayPlayerCards();
void CheckBlackJackPushes();
void ClearPlayerVariables(object oPC);
void ClearDealerVariables();

void main()
{
    object oPC = GetLastSpeaker();
	int nEventNumber = GetUserDefinedEventNumber();
	int nPattern = GetListenPatternNumber();
	
	// on Spawn in - this should run
    // Set the words that the dealer is 'listening' for and give each an event number
    if (nEventNumber == 5000)
    {
        SetListenPattern(OBJECT_SELF, "Start", 500);
        SetListenPattern(OBJECT_SELF, "Hit", 1000);
        SetListenPattern(OBJECT_SELF, "Stand", 2000);
        SetListenPattern(OBJECT_SELF, "Total", 3000);
        SetListenPattern(OBJECT_SELF, "Quit", 4000);
        SetListenPattern(OBJECT_SELF, "Join", 5000);
        SetListenPattern(OBJECT_SELF, "Reset", 6000);
        SetListening(OBJECT_SELF, FALSE);
    }
	
    // on Dialog event - this should fire
	// - Check if Dealer is listening and the one speaking is a PC
    if (nEventNumber == 1004 && GetIsListening(OBJECT_SELF) && GetIsPC(oPC))
    {
		// Get the active player's ID (failsafe checks)
		int nPlayerNumber = GetLocalInt(OBJECT_SELF, "nCurrentPlayer");
		switch (nPattern)
		{
			case 500:  BlackJack_Start(oPC); break;
			case 1000: BlackJack_HitMe(oPC, nPlayerNumber); break;
			case 2000: BlackJack_Stand(oPC, nPlayerNumber); break;
			case 3000: BlackJack_Total(oPC, nPlayerNumber); break;
            case 4000: BlackJack_Quit(oPC); break;
            case 5000: BlackJack_Join(oPC); break;
            case 6000: BlackJack_Reset(); break;
		}
	}
}

// --- Functions ----------------------------------------------------------------
void BlackJack_Start(object oSpeaker)
{
	// Declarations
	string sPCName = GetName(oSpeaker);
	int nPlayerNumber = GetLocalInt(OBJECT_SELF, "nNumPlayers") + 1;
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	
	// Failsafe - Ensure game is not already in progress for this player
	if (GetLocalInt(oSpeaker, "nGameOn") == 1)
	{
		SpeakString("What are you trying to pull, " + sPCName + ", you've already started!");
		return;
	}
	
	// No Active Players (NEW GAME or ROUND) - Clear Variables
	if (GetLocalInt(OBJECT_SELF, "nNumPlayers") == 0)
	{
		ClearDealerVariables();
	}
	
	// Always clear player variables when starting a game
	ClearPlayerVariables(oSpeaker);
	
	// Ensure the player has the token pouch
	EnsureTokenPouch(oSpeaker);

	// Fetch the token pouch and check the nCAS_TOKEN value
	object oTokenPouch = GetItemPossessedBy(oSpeaker, "I_CAS_CASINOHANDLE");
	int nCasTokens = GetLocalInt(oTokenPouch, "nCAS_TOKEN");
	int nWager = GetLocalInt(OBJECT_SELF, "nWager");
	
	// Compare the nWager with the nCAS_TOKEN value
	if (nCasTokens >= nWager)
	{
		// Deduct the wager from the player's tokens
		AdjustCasValues(oSpeaker, -nWager, 0);

		// Add one to the number of players variable on the Dealer
		SetLocalInt(OBJECT_SELF, "nNumPlayers", nPlayerNumber);
		
		// Deal the player their hand, and only on the final joining player do we also give 
		// the dealer their hand and start the game.
		// * Description edited -DarkSorcerer (July 22, 2026)
		InitialDeal(oSpeaker, nPlayerNumber);
		
		if (nPlayerNumber < nMaxPlayers)
		{
			DelayCommand(2.0f, SpeakString(sPCName + ", you are in. Who else? Please say 'Start'."));
		}
		else
		{
			// Draw Dealer's cards
			int nDealerCard1 = Random(10) + 1;
			int nDealerCard2 = Random(10) + 1;
			AceCheck(nDealerCard1, OBJECT_SELF);
			AceCheck(nDealerCard2, OBJECT_SELF);
			
			// Pre-Define the cards for end-game drawing
			SetLocalInt(OBJECT_SELF, "nDealerCard1", nDealerCard1);
			SetLocalInt(OBJECT_SELF, "nDealerCard2", nDealerCard2);
			SetLocalInt(OBJECT_SELF, "nDealerTotal", nDealerCard1 + nDealerCard2);

			// If Dealer has Blackjack: Game Over (check players for Blackjacks as well)
			// * Players Push if they have a Blackjack; otherwise they lose
			if (DealerBlackJackCheck(nDealerCard1, nDealerCard2))
			{
				DelayCommand(2.0f, SpeakString("Dealer has BlackJack!"));
				DelayCommand(5.5f, CheckBlackJackPushes());
			}
			else 
			{
				// Show players their cards first - then decide on the Dealer's shown card
				float fDelay = DisplayPlayerCards();				
				if (GetLocalInt(OBJECT_SELF, "nDealerCard1") == 1)
				{
					// If Dealer has an Ace
					DelayCommand(fDelay, SpeakString("Dealer is showing an Ace"));
				}
				else
				{
					// Else just say what the dealer has
					DelayCommand(fDelay, SpeakString("Dealer is showing a " + IntToString(nDealerCard1)));
				}

				// Make the Player Counter point to the first player - only they will be able to speak to the Dealer
				// Ask the first player what they want to do
				string sFirstPlayer = GetName(GetLocalObject(OBJECT_SELF, "Player1"));
				DelayCommand(fDelay+2.0f, SpeakString("What do you want to do, " + sFirstPlayer + "?"));
				SetLocalInt(OBJECT_SELF, "nCurrentPlayer", 1);					
			}
		}
	}
	else
	{
		// Not enough tokens to play - kick player
		SpeakString(sPCName + ", you don't have enough tokens to play this game! Get Lost!");
		if (nMaxPlayers > 1)
		{
			SetLocalInt(OBJECT_SELF, "nMaxPlayers", --nMaxPlayers);
		}
		else
		{
			// No more players - shut down game
			ExecuteScript("cas_bj_playtest3", OBJECT_SELF);
		}
	}
}
       
void BlackJack_HitMe(object oSpeaker, int nPlayerNumber)
{
	object oPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(nPlayerNumber));
	string sPCName = GetName(oSpeaker);
	string sPlayerName = GetName(oPlayer);
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	
	// Go through list of failsafes before applying the 'Hit Me' action
	if (GetLocalInt(OBJECT_SELF, "nNumPlayers") < nMaxPlayers)
	{
		SpeakString("Hold your horses! Not everyone is in yet.");
	}
	else if (sPCName != sPlayerName)
	{
		SpeakString("Hold up, " + sPCName + ", its not your turn. Its " + sPlayerName + "'s turn");
	}
	else if (GetLocalInt(oSpeaker, "nGameOn") != 1)
	{
		SpeakString("What are you trying to pull, " + sPCName + ", you're not even in the game!");
	}
	else
	{
		//Draw a card and check for an Ace
		int nBlackJackNextCard = Random(10) + 1;
		AceCheck(nBlackJackNextCard, oSpeaker);
		//Save the variable and update total
		int nBlackJackTotal = GetLocalInt(oSpeaker, "nBlackJackTotal") + nBlackJackNextCard;
		SetLocalInt(oSpeaker, "nBlackJackNextCard", nBlackJackNextCard);
		SetLocalInt(oSpeaker, "nBlackJackTotal", nBlackJackTotal);
		//Say something different if PC has an Ace
		if (nBlackJackNextCard == 1)
		{
			SpeakString(sPCName+". You've been dealt an Ace");
		}
		else
		{
			//Otherwise just say the total
			SpeakString(sPCName+". You've been dealt a " + IntToString(nBlackJackNextCard));
		}
		//If the PC has any Aces - we may have to give him the option of adding ten to his total
		if (GetLocalInt(oSpeaker, "nAceCount") > 0)
		{
			int nTempTotal = nBlackJackTotal + 10;
			if (nTempTotal > 21)
			{
				//If adding 10 would make it greater than 21 - then he can't use his ace
				DelayCommand(2.0f, SpeakString("That gives you a total of " + IntToString(nBlackJackTotal)));
			}
			else
			{
				//otherwise, he may have two totals since aces can be 1 or 11
				DelayCommand(2.0f, SpeakString("That gives you a total of " + IntToString(nBlackJackTotal) + " or " + IntToString(nTempTotal)));
			}
		}
		else
		{
			DelayCommand(2.0f, SpeakString("That gives you a total of " + IntToString(nBlackJackTotal)));
		}
		//If the PCs true total is greater than 21 then they busted
		if (nBlackJackTotal > 21)
		{
			DelayCommand(4.0f, SpeakString(sPCName + " has Busted. Better luck next time!"));
			SetLocalInt(oSpeaker, "nBusted", 1);
			
			//Check to see if this is the last PC and call CardCheck() if it is
			if (nPlayerNumber == nMaxPlayers)
			{
				DelayCommand(6.0f, DealerDrawRemainingCards());
				DelayCommand(11.0f, CardCheck());
			}
			else
			{
				//If its not - advance to the next player
				int nNextPlayer = nPlayerNumber + 1;
				string sNextPlayer = GetName(GetLocalObject(OBJECT_SELF, "Player"+IntToString(nNextPlayer)));
				DelayCommand(6.0f, SpeakString("What do you want to do, " + sNextPlayer + "?"));
				SetLocalInt(OBJECT_SELF, "nCurrentPlayer", nNextPlayer);
			}
		}
		else
		{
			DelayCommand(4.0f, SpeakString("What do you want to do, " + sPCName + "?"));
		}
	}
}

void BlackJack_Stand(object oSpeaker, int nPlayerNumber)
{
	object oPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(nPlayerNumber));
	string sPCName = GetName(oSpeaker);
	string sPlayerName = GetName(oPlayer);
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	
	// Go through list of failsafes before applying the 'Stand' action
	if (GetLocalInt(OBJECT_SELF, "nNumPlayers") < nMaxPlayers)
	{
		SpeakString("Hold your horses! Not everyone is in yet.");
	}
	else if (sPCName != sPlayerName)
	{
		SpeakString("Hold up, " + sPCName + ", its not your turn. Its " + sPlayerName + "'s turn");
	}
	else if (GetLocalInt(oSpeaker, "nGameOn") != 1)
	{
		SpeakString("What are you trying to pull, " + sPCName + ", you're not even in the game!");
	}
	else
	{
		//Confirm the player's action to 'Stand'
		SpeakString(sPCName + " stands.");
		
		//Calculate the Players true total (using Aces) and save it as his total
		if (GetLocalInt(oSpeaker, "nAceCount") > 0)
		{
			int nTempTotal = GetLocalInt(oSpeaker, "nBlackJackTotal") + 10;
			if (nTempTotal < 22)
			{
				SetLocalInt(oSpeaker, "nBlackJackTotal", nTempTotal);
			}
		}

		//Check to see if all PCs have their cards, if so then the dealer can take his
		if (nPlayerNumber == nMaxPlayers)
		{
			//Loop for the dealer to get his remaining cards
			DelayCommand(2.0f, DealerDrawRemainingCards());
			DelayCommand(7.0f, CardCheck());
		}
		else
		{
			//if not all players have their cards - tell the next player that its their turn
			int nNextPlayer = nPlayerNumber + 1;
			string sNextPlayer = GetName(GetLocalObject(OBJECT_SELF, "Player"+IntToString(nNextPlayer)));
			DelayCommand(2.0f, SpeakString("Ok, " + sNextPlayer + ", its your turn"));
			SetLocalInt(OBJECT_SELF, "nCurrentPlayer", nNextPlayer);
		}
	}
}

void BlackJack_Total(object oSpeaker, int nPlayerNumber)
{
	object oPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(nPlayerNumber));
	string sPCName = GetName(oSpeaker);	
	string sPlayerName = GetName(oPlayer);
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	
	if (GetLocalInt(OBJECT_SELF, "nNumPlayers") < nMaxPlayers)
	{
		SpeakString("Hold your horses! Not everyone is in yet.");
	}
	else if (sPCName != sPlayerName)
	{
		SpeakString("Hold up, " + sPCName + ", its not your turn. Its " + sPlayerName + "'s turn");
	}
	else if (GetLocalInt(oSpeaker, "nGameOn") != 1)
	{
		SpeakString("What are you trying to pull, " + sPCName + "! You're not even in the game!");
	}
	else
	{
		int nBlackJackTotal = GetLocalInt(oSpeaker, "nBlackJackTotal");
		if (GetLocalInt(oSpeaker, "nAceCount") > 0)
		{
			int nTempTotal = nBlackJackTotal + 10;
			if (nTempTotal < 22)
			{
				SpeakString(sPCName + ", your total is " + IntToString(nBlackJackTotal)) + " or " + IntToString(nTempTotal));
			}
			else
			{
				SpeakString(sPCName + ", your total is " + IntToString(nBlackJackTotal));
			}
		}
		else
		{
			SpeakString(sPCName + ", your total is " + IntToString(nBlackJackTotal));
		}
	}
}

void BlackJack_Quit(object oSpeaker)
{
	// Declarations
	string sPCName = GetName(oSpeaker);
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	int nPlayerNumber = GetBlackJackID(oSpeaker);
	
	// Ensure no game is currently running
	if (GetIsGameRunning())
	{
		SpeakString(sPCName+", please wait until after the current game.");
	}
	// Check if "Joined" or played at least 1 round..
	else if (GetLocalInt(oSpeaker, "nPlayingBlackJack") == 0 || nPlayerNumber == 0)
	{
		SpeakString(sPCName + ", you're not even in the group!");
	}
	// Only player in the game - Exit completely
	else if (nMaxPlayers == 1)
	{
		// Message and Exit (exiting game clears variables)
		SpeakString("Do come back if you fancy another game!");
		ExecuteScript("cas_bj_playtest3", OBJECT_SELF);
	}
	else
	{				
		// A friendly message
		SpeakString(sPCName+", do come back if you fancy another game!");
		
		// Adjust variables from the player that is leaving
		for (i = nPlayerNumber; i < nMaxPlayers; i++)
		{
			object oNextPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(i+1));
			SetLocalObject(OBJECT_SELF, "Player" + IntToString(i), oNextPlayer);
			SetLocalInt(oNextPlayer, "nBlackJackID", i);
		}
		
		// Reduce maximum number of players and clear the variables
		SetLocalInt(OBJECT_SELF, "nMaxPlayers", --nMaxPlayers);
		ClearPlayerVariables(oSpeaker);
		
		// Last Player notice
		if (nMaxPlayers == 1)
		{
			sPCName = GetName(GetLocalObject(OBJECT_SELF, "Player1"));
			SpeakString(sPCName + ", you are the last player!");
		}
	}
}

void BlackJack_Join(object oSpeaker)
{
	// Declarations
	string sPCName = GetName(oSpeaker);
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	
	// Ensure no game is currently running
	if (GetIsGameRunning())
	{
		SpeakString("Let the current game finish first.");
	}
	// Failsafe - you're already in the group
	else if (GetLocalInt(oSpeaker, "nPlayingBlackJack") == 1)
	{
		SpeakString("You're already a part of the group, " + sPCName + "!");
	}
	else
	{
		// Increase maximum players
		SetLocalInt(OBJECT_SELF, "nMaxPlayers", ++nMaxPlayers);
		SetLocalInt(oSpeaker, "nPlayingBlackJack", 1);
		
		// Now declare the player has joined
		SpeakString(sPCName + " has joined the group. Someone speak 'Start' to begin.");
	}
}

void BlackJack_Reset()
{
    int i = 1;
	string sVariable = "Player1";
	object oPC = GetLocalObject(OBJECT_SELF, sVariable);
	while (GetIsObjectValid(oPC))
    {
        ClearPlayerVariables(oPC); 
		oPC = GetLocalObject(OBJECT_SELF, "Player" + IntToString(++i));
    }
    ClearDealerVariables();
    SpeakString("DEBUG :: BlackJack :: Variables have been reset");
}

int GetIsGameRunning()
{
	int i; for (i = 1; i <= GetLocalInt(OBJECT_SELF, "nMaxPlayers"); i++)
	{
		object oPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(i));
		if (!GetIsObjectValid(oPlayer)) continue;
		
		if (GetLocalInt(oPlayer, "nGameOn") == 1)
		{
			return TRUE;
		}
	}
	return FALSE;
}

int GetBlackJackID(object oSpeaker)
{
	string sSpeakerName = GetName(oSpeaker);
	int i, nPlayerNumber = GetLocalInt(oSpeaker, "nBlackJackID");
	if (nPlayerNumber == 0)
	{
		for (i = 1; i <= GetLocalInt(OBJECT_SELF, "nMaxPlayers"); i++)
		{
			object oPlayer = GetLocalObject(OBJECT_SELF, "Player" + IntToString(i));
			if (GetName(oPlayer) == sSpeakerName)
			{
				nPlayerNumber = i;
				break;
			}
		}
	}
	return nPlayerNumber;
}

//*****************************************************************************************
void CardCheck()
{
	float fDelay = 0.0f;
    int nCount, nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
    for (nCount = 1; nCount <= nMaxPlayers; nCount++)
    {
		object oPC = GetLocalObject(OBJECT_SELF, "Player" + IntToString(nCount));
		if (!GetIsObjectValid(oPC)) 
		{
			SpeakString("Uh oh, Player " + IntToString(nCount) + " doesn't exist?");
			continue;
		}
		// We do not clear "nBlackJackID" or "nPlayingBlackJack", only "nGameOn"
		// so that the 'Quit' command is still available to them
        DeleteLocalInt(oPC, "nGameOn");

        string sLogMessage;
        string sCharacterName = GetName(oPC);
        string sPlayerUsername = GetPCPlayerName(oPC);
        string sPCId = IntToString(PLAYER_GetId(oPC));
		int nBlackJackTotal = GetLocalInt(oPC, "nBlackJackTotal");
		int nDealerTotal = GetLocalInt(OBJECT_SELF, "nDealerTotal");
        int nWager = GetLocalInt(OBJECT_SELF, "nWager");
        int nReward = 0;

        if (GetLocalInt(oPC, "nBusted") == 1)
        {
            DeleteLocalInt(oPC, "nBusted");
			DelayCommand(fDelay, SpeakString(sCharacterName + ", you busted! Better luck next time."));
            DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CUSS, oPC));
            sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") lost " + IntToString(nWager) + " tokens for busting.";
        }
        else if (GetLocalInt(oPC, "nBlackJack") == 1)
        {
			nReward = nWager * 4;
			DeleteLocalInt(oPC, "nBlackJack");
            DelayCommand(fDelay, SpeakString("BlackJack for " + sCharacterName + "!!!!"));
            DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_mg_telepin1")));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CHEER, oPC));
			DelayCommand(fDelay+2.0f, AdjustCasValues(oPC, 0, nReward));
            DelayCommand(fDelay+2.0f, SendMessageToPC(oPC, "You have won: " + IntToString(nReward) + " Tickets!"));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") won " + IntToString(nReward) + " tickets for Blackjack.";
        }
        else if (GetLocalInt(OBJECT_SELF, "nBusted") == 1)
        {
			nReward = nWager * 3;
			DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_mg_telepin1")));
			DelayCommand(fDelay, SpeakString("I busted, so you win, " + sCharacterName + "!!!!"));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CHEER, oPC));
			DelayCommand(fDelay+2.0f, AdjustCasValues(oPC, 0, nReward));
			DelayCommand(fDelay+2.0f, SendMessageToPC(oPC, "You won: " + IntToString(nReward) + " tickets!"));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") won " + IntToString(nReward) + " tickets as dealer busted.";
		}
		else if (nDealerTotal > nBlackJackTotal)
		{
			DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_mg_telepout1")));
			DelayCommand(fDelay, SpeakString(sCharacterName + ", you lost this round. Maybe next time!"));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CUSS, oPC));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") lost " + IntToString(nWager) + " tokens.";
		}
		else if (nDealerTotal < nBlackJackTotal)
		{
			nReward = nWager * 3;
			DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_mg_telepin1")));
			DelayCommand(fDelay, SpeakString(sCharacterName + ", you win!!!!"));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CHEER, oPC));
			DelayCommand(fDelay+2.0f, AdjustCasValues(oPC, 0, nReward));
			DelayCommand(fDelay+2.0f, SendMessageToPC(oPC, "You have won: " + IntToString(nReward) + " Tickets!"));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") won " + IntToString(nReward) + " tickets.";
		}
		else
		{
			nReward = nWager;
			DelayCommand(fDelay, SpeakString(sCharacterName + ", we push!!!!"));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_TAUNT, oPC));
			DelayCommand(fDelay+2.0f, AdjustCasValues(oPC, 0, nReward));
			DelayCommand(fDelay+2.0f, SendMessageToPC(oPC, "You will get " + IntToString(nReward) + " Tickets for the push."));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") pushed with dealer. They got" + IntToString(nReward) + "tickets.";
		}
        Log(sLogMessage, "cas");
		fDelay = fDelay + 1.5f;
    }
    SetLocalInt(OBJECT_SELF, "nNumPlayers", 0);
    SetLocalInt(OBJECT_SELF, "nBusted", 0);
	SetLocalInt(OBJECT_SELF, "nCurrentPlayer", 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, int nPlayerNumber)
{
	//Deal random cards to the Player and check for Aces (either 1 or 11)
	int nBlackJackCard1 = Random(10) + 1;
	int nBlackJackCard2 = Random(10) + 1;
    AceCheck(nBlackJackCard1, oPC);
	AceCheck(nBlackJackCard2, oPC);
	
	//Save card values and the Total
	SetLocalInt(oPC, "nBlackJackCard1", nBlackJackCard1);
	SetLocalInt(oPC, "nBlackJackCard2", nBlackJackCard2);
	SetLocalInt(oPC, "nBlackJackTotal", nBlackJackCard1 + nBlackJackCard2);
	
	//Check for BlackJack
	int nTempTotal = GetLocalInt(oPC, "nBlackJackTotal");
	if (GetLocalInt(oPC, "nAceCount") > 0)
	{
		nTempTotal = nTempTotal + 10;
		if (nTempTotal == 21)
		{
			// BlackJack! (to be checked and called later)
			SetLocalInt(oPC, "nBlackJack", 1);
		}
	}
	
	//Set PCs as local objects (easier to obtain the object in searches)
	SetLocalObject(OBJECT_SELF, "Player" + IntToString(nPlayerNumber), oPC);
	
	//Set this player as "active" for the game (for checks)
	SetLocalInt(oPC, "nPlayingBlackJack", 1); // "Group" tracking
	SetLocalInt(oPC, "nBlackJackID", nPlayerNumber); // for the 'Quit' and 'Join' commands
	SetLocalInt(oPC, "nGameOn", 1); // is "Active" (in a game)
}

void DealerDrawRemainingCards()
{
	//Draw cards for the dealer as long as the dealers total is less than 17 - Dealer stands on 17
	string szTempString = "";
	int nDealerTotal = GetLocalInt(OBJECT_SELF, "nDealerCard1");
	while (nDealerTotal < 17)
    {
		//
		int nDealerNextCard = Random(10) + 1;
		if (GetLocalInt(OBJECT_SELF, "nDealerCard1") == nDealerTotal)
		{
			//use currently pre-drawn cards
			nDealerNextCard = GetLocalInt(OBJECT_SELF, "nDealerCard2");
			nDealerTotal = GetLocalInt(OBJECT_SELF, "nDealerTotal");
		}
		else 
		{
			//update the total with the new card
			AceCheck(nDealerNextCard, OBJECT_SELF);
			nDealerTotal = nDealerTotal + nDealerNextCard;
		}
        //If dealer drew an Ace - say so - calculate the total with any aces the Dealer may have
        if (nDealerNextCard == 1)
        {
            int nTempTotal = nDealerTotal + 10;
            if (nTempTotal > 21)
            {
                szTempString = szTempString + "Dealer draws an Ace for a total of " + IntToString(nDealerTotal) + ". ";
            }
            else if (nTempTotal > 16)
			{
				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(nDealerNextCard) + " for a total of " + IntToString(nDealerTotal) + ". ";
        }
    }
	
	//Update current total (for calls later)
	SetLocalInt(OBJECT_SELF, "nDealerTotal", nDealerTotal);
    
	//Check to see if the Dealer has gone over 21 and Busted
    if (nDealerTotal > 21)
    {
        DelayCommand(1.5f, 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.
    SpeakString(szTempString);
}

float DisplayPlayerCards()
{
	int i, nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	float fDelay = 2.0f;
	
    for (i = 1; i <= nMaxPlayers; i++)
    {
        object oPC = GetLocalObject(OBJECT_SELF, "Player" + IntToString(i));
		if (!GetIsObjectValid(oPC)) 
		{
			DelayCommand(fDelay, SpeakString("Whoops, Player " + IntToString(i) + " does not exist?"));
			continue;
		}
		
		string sPCName = GetName(oPC);
        int nBlackJackCard1 = GetLocalInt(oPC, "nBlackJackCard1");
        int nBlackJackCard2 = GetLocalInt(oPC, "nBlackJackCard2");
        int nBlackJackTotal = GetLocalInt(oPC, "nBlackJackTotal");
        
        if (nBlackJackCard1 == 1)
        {
            if (nBlackJackCard2 == 1)
            {
                DelayCommand(fDelay, SpeakString(sPCName + ", you've been dealt an Ace and another Ace"));
            }
            else
            {
                DelayCommand(fDelay, SpeakString(sPCName + ", you've been dealt an Ace and a " + IntToString(nBlackJackCard2)));
            }
        }
        else if (nBlackJackCard2 == 1)
        {
            DelayCommand(fDelay, SpeakString(sPCName + ", you've been dealt a " + IntToString(nBlackJackCard1) + " and an Ace."));
        }
        else
        {
            DelayCommand(fDelay, SpeakString(sPCName + ", you've been dealt a " + IntToString(nBlackJackCard1) + " and a " + IntToString(nBlackJackCard2)));
        }
        string szTempString = ".";
        if (GetLocalInt(oPC, "nAceCount") > 0)
        {
            int nTempTotal = nBlackJackTotal + 10;
            if (nTempTotal < 22)
            {
                szTempString = " or " + IntToString(nTempTotal) + ".";
            }
        }
		fDelay = fDelay + 3.5;
        DelayCommand(fDelay, SpeakString("This gives you a total of " + IntToString(nBlackJackTotal) + szTempString));
		
		//Check for BlackJack
        if (GetLocalInt(oPC, "nBlackJack") == 1)
        {
			fDelay = fDelay + 7.0f;
            DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_cv_bell2")));
            DelayCommand(fDelay, SpeakString(sPCName + ", you've got BlackJack!!"));
        }
		
		if (i < nMaxPlayers)
		{
			// Increase delay
			fDelay = fDelay + 1.5f;
		}
    }
	return fDelay;
}

int DealerBlackJackCheck(int nCard1, int nCard2)
{
    int nTempTotal = nCard1 + nCard2;
	if (GetLocalInt(OBJECT_SELF, "nAceCount") > 0) 
	{
		nTempTotal = nTempTotal + 10;
	}
	// does dealer have a blackjack?
	return nTempTotal == 21 ? TRUE : FALSE;
}

void CheckBlackJackPushes()
{
	string sLogMessage;
	int nMaxPlayers = GetLocalInt(OBJECT_SELF, "nMaxPlayers");
	int nReward = GetLocalInt(OBJECT_SELF, "nWager");
	float fDelay = 0.0f;
	
	// Checks each player for a Black Jack(push) or they lose
	int i; for (i = 1; i <= nMaxPlayers; i++)
	{
		object oPC = GetLocalObject(OBJECT_SELF, "Player" + IntToString(i));
		if (!GetIsObjectValid(oPC)) 
		{
			DelayCommand(fDelay, SpeakString("Whoops, Player " + IntToString(i) + " does not exist?"));
			continue;
		}
		// We do not clear "nBlackJackID" or "nPlayingBlackJack", only "nGameOn"
		// so that the 'Quit' command is still available to them
		DeleteLocalInt(oPC, "nGameOn");
		
		string sCharacterName = GetName(oPC);
		string sPlayerUsername = GetPCPlayerName(oPC);
		string sPCId = IntToString(PLAYER_GetId(oPC));
		
		if (GetLocalInt(oPC, "nBlackJack") == 1)
		{
			// Push
			DeleteLocalInt(oPC, "nBlackJack");
			DelayCommand(fDelay, SpeakString(sCharacterName + " also has BlackJack, we push!!!!"));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_TAUNT, oPC));
			DelayCommand(fDelay+2.0f, AdjustCasValues(oPC, 0, nReward));
			DelayCommand(fDelay+2.0f, SendMessageToPC(oPC, "You will get " + IntToString(nReward) + " Tickets for the push."));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") pushed with dealer. They got" + IntToString(nReward) + "tickets.";
		}
		else
		{
			// Lose
			DelayCommand(fDelay, SpeakString(sCharacterName + ", you lose. Better luck next time!"));
			DelayCommand(fDelay, AssignCommand(oPC, PlaySound("as_mg_telepout1")));
			DelayCommand(fDelay+1.5f, PlayVoiceChat(VOICE_CHAT_CUSS, oPC));
			sLogMessage = "Character: " + sCharacterName + ", Player Name: " + sPlayerUsername + " (" + sPCId + ") lost " + IntToString(nReward) + " tokens.";
		}
		Log(sLogMessage, "cas");
		fDelay = fDelay + 1.5f;
	}
	SetLocalInt(OBJECT_SELF, "nNumPlayers", 0);
	SetLocalInt(OBJECT_SELF, "nCurrentPlayer", 0);
}

void ClearPlayerVariables(object oPC)
{
	DeleteLocalInt(oPC, "nAceCount");
	DeleteLocalInt(oPC, "nBlackJack");
	DeleteLocalInt(oPC, "nBlackJackCard1");
	DeleteLocalInt(oPC, "nBlackJackCard2");
	DeleteLocalInt(oPC, "nBlackJackNextCard");
	DeleteLocalInt(oPC, "nBlackJackTotal");
	DeleteLocalInt(oPC, "nBusted");
	DeleteLocalInt(oPC, "nGameOn");
	DeleteLocalInt(oPC, "nPlayingBlackJack");
	DeleteLocalInt(oPC, "nBlackJackID");
}

void ClearDealerVariables()
{
	int i = 1;
	string sVariable = "Player1";
	while (GetIsObjectValid(GetLocalObject(OBJECT_SELF, sVariable)))
	{
		DeleteLocalObject(OBJECT_SELF, sVariable);
		sVariable = "Player" + IntToString(++i);
	}
	DeleteLocalInt(OBJECT_SELF, "nAceCount");
	DeleteLocalInt(OBJECT_SELF, "nBusted");
	DeleteLocalInt(OBJECT_SELF, "nDealerCard1");
	DeleteLocalInt(OBJECT_SELF, "nDealerCard2");
	DeleteLocalInt(OBJECT_SELF, "nDealerTotal");
}