sfcnr/gamemodes/irresistible/cnr/features/visage/blackjack.pwn

860 lines
38 KiB
Plaintext
Raw Normal View History

/*
* Irresistible Gaming (c) 2018
* Developed by Lorenc Pekaj
* Module: blackjack.inc
* Purpose: a sa-mp blackjack minigame implementation
*/
/* ** Includes ** */
#include < YSI\y_hooks >
/* ** Error checking ** */
#if !defined __irresistible_servervars
#error "You need server variables enabled to track betting."
#endif
/*#if !defined _merrandom_included
#define MRandom random
#endif*/
/* ** Definitions ** */
#define MAX_BLACKJACK_TABLES ( 50 ) // 33
#define MAX_BLACKJACK_CARDS ( 5 )
#define MAX_BLACKJACK_PLAYERS ( 3 )
#define BLACKJACK_DEALER_WAIT ( 500 )
#define BLACKJACK_PLAYER_WAIT ( 10 )
#define BLACKJACK_STATE_NONE ( 0 )
#define BLACKJACK_STATE_TURN ( 1 )
#define BLACKJACK_STATE_BUST ( 2 )
#define BLACKJACK_STATE_STAND ( 3 )
#define BLACKJACK_STATE_WIN ( 4 )
/* ** Constants ** */
stock const g_cardTextdrawData[ 52 ] [ ] = {
"LD_CARD:cd1c", // A Clubs - 0
"LD_CARD:cd2c", // 2 Clubs - 1
"LD_CARD:cd3c", // 3 Clubs - 2
"LD_CARD:cd4c", // 4 Clubs - 3
"LD_CARD:cd5c", // 5 Clubs - 4
"LD_CARD:cd6c", // 6 Clubs - 5
"LD_CARD:cd7c", // 7 Clubs - 6
"LD_CARD:cd8c", // 8 Clubs - 7
"LD_CARD:cd9c", // 9 Clubs - 8
"LD_CARD:cd10c", // 10 Clubs - 9
"LD_CARD:cd11c", // J Clubs - 10
"LD_CARD:cd12c", // Q Clubs - 11
"LD_CARD:cd13c", // K Clubs - 12
"LD_CARD:cd1d", // A Diamonds - 13
"LD_CARD:cd2d", // 2 Diamonds - 14
"LD_CARD:cd3d", // 3 Diamonds - 15
"LD_CARD:cd4d", // 4 Diamonds - 16
"LD_CARD:cd5d", // 5 Diamonds - 17
"LD_CARD:cd6d", // 6 Diamonds - 18
"LD_CARD:cd7d", // 7 Diamonds - 19
"LD_CARD:cd8d", // 8 Diamonds - 20
"LD_CARD:cd9d", // 9 Diamonds - 21
"LD_CARD:cd10d", // 10 Diamonds - 22
"LD_CARD:cd11d", // J Diamonds - 23
"LD_CARD:cd12d", // Q Diamonds - 24
"LD_CARD:cd13d", // K Diamonds - 25
"LD_CARD:cd1h", // A Heats - 26
"LD_CARD:cd2h", // 2 Heats - 27
"LD_CARD:cd3h", // 3 Heats - 28
"LD_CARD:cd4h", // 4 Heats - 29
"LD_CARD:cd5h", // 5 Heats - 30
"LD_CARD:cd6h", // 6 Heats - 31
"LD_CARD:cd7h", // 7 Heats - 32
"LD_CARD:cd8h", // 8 Heats - 33
"LD_CARD:cd9h", // 9 Heats - 34
"LD_CARD:cd10h", // 10 Heats - 35
"LD_CARD:cd11h", // J Heats - 36
"LD_CARD:cd12h", // Q Heats - 37
"LD_CARD:cd13h", // K Heats - 38
"LD_CARD:cd1s", // A Spades - 39
"LD_CARD:cd2s", // 2 Spades - 40
"LD_CARD:cd3s", // 3 Spades - 41
"LD_CARD:cd4s", // 4 Spades - 42
"LD_CARD:cd5s", // 5 Spades - 43
"LD_CARD:cd6s", // 6 Spades - 44
"LD_CARD:cd7s", // 7 Spades - 45
"LD_CARD:cd8s", // 8 Spades - 46
"LD_CARD:cd9s", // 9 Spades - 47
"LD_CARD:cd10s", // 10 Spades - 48
"LD_CARD:cd11s", // J Spades - 49
"LD_CARD:cd12s", // Q Spades - 50
"LD_CARD:cd13s" // K Spades - 51
};
/* ** Variables ** */
enum E_BLACKJACK_DATA
{
bool: E_GAME_STARTED, E_CARDS_DRAWN, E_GAME_TIMER,
E_PAYOUT, E_WORLD, E_RESET_TIMER,
E_DRAW_CARD_TIMER,
E_OBJECT, E_ACTOR,
Float: E_X, Float: E_Y, Float: E_Z,
Float: E_ROTATION,
Text3D: E_DEALER_LABEL, Text3D: E_PLAYER_LABEL[ MAX_BLACKJACK_PLAYERS ]
};
new
g_blackjackData [ MAX_BLACKJACK_TABLES ] [ E_BLACKJACK_DATA ],
Text: g_blackjackTurnTD [ MAX_BLACKJACK_TABLES ] = { Text: INVALID_TEXT_DRAW, ... },
Text: g_blackjackPlayerCards [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_CARDS ] [ MAX_BLACKJACK_PLAYERS ],
Text: g_blackjackDealerCards [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_CARDS ],
g_blackjackDealerCardIndex [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_CARDS ],
g_blackjackPlayerCardIndex [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_CARDS ] [ MAX_BLACKJACK_PLAYERS ],
g_blackjackPlayerState [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_PLAYERS ],
g_blackjackSlotData [ MAX_BLACKJACK_TABLES ] [ MAX_BLACKJACK_PLAYERS ],
p_blackjackTable [ MAX_PLAYERS ] = { -1, ... },
Iterator: blackjacktables < MAX_BLACKJACK_TABLES >
;
/* ** Hooks ** */
hook OnGameModeInit( )
{
// for tracking bets
AddServerVariable( "blackjack_bets", "0.0", GLOBAL_VARTYPE_FLOAT );
AddServerVariable( "blackjack_wins", "0.0", GLOBAL_VARTYPE_FLOAT );
// Reset Textdraw Variables
for ( new i = 0; i < MAX_BLACKJACK_TABLES; i ++ ) {
for ( new x = 0; x < MAX_BLACKJACK_CARDS; x ++ ) {
g_blackjackDealerCards[ i ] [ x ] = Text: INVALID_TEXT_DRAW;
for ( new p = 0; p < MAX_BLACKJACK_PLAYERS; p ++ ) {
g_blackjackPlayerCards[ i ] [ x ] [ p ] = Text: INVALID_TEXT_DRAW;
g_blackjackSlotData[ i ] [ p ] = -1;
}
}
}
// Create blackjack tables
CreateBlackjackTable( 2500, 2230.37500, 1602.75000, 1006.15631, 0.00000, 82 );
CreateBlackjackTable( 5000, 2232.18750, 1604.43750, 1006.15631, 90.0000, 82 );
CreateBlackjackTable( 10000, 2228.49219, 1604.45313, 1006.15631, -90.000, 82 );
CreateBlackjackTable( 25000, 2230.37500, 1606.27344, 1006.15631, 180.000, 82 );
CreateBlackjackTable( 50000, 2241.31250, 1602.75000, 1006.15631, 0.00000, 82 );
CreateBlackjackTable( 75000, 2243.12500, 1604.43750, 1006.15631, 90.0000, 82 );
CreateBlackjackTable( 100000, 2239.42969, 1604.45313, 1006.15631, -90.000, 82 );
CreateBlackjackTable( 125000, 2241.31250, 1606.27344, 1006.15631, 180.000, 82 );
// 4 dragons
CreateBlackjackTable( 25000, 1960.36719, 1015.66412, 992.46881, -90.0000, 23 );
CreateBlackjackTable( 50000, 1962.34375, 1015.66412, 992.46881, 90.00000, 23 );
CreateBlackjackTable( 100000, 1962.34375, 1020.17969, 992.46881, 90.00000, 23 );
CreateBlackjackTable( 250000, 1960.36719, 1020.17188, 992.46881, -90.00000, 23 );
return 1;
}
hook OnPlayerDisconnect( playerid, reason )
{
RemovePlayerFromBlackjack( playerid );
return 1;
}
#if defined AC_INCLUDED
hook OnPlayerDeathEx( playerid, killerid, reason, Float: damage, bodypart )
#else
hook OnPlayerDeath( playerid, killerid, reason )
#endif
{
RemovePlayerFromBlackjack( playerid );
return 1;
}
hook OnPlayerKeyStateChange( playerid, newkeys, oldkeys )
{
static
Float: X, Float: Y, Float: Z;
if ( IsPlayerInCasino( playerid ) )
{
new
blackjack_table = p_blackjackTable[ playerid ];
// Blackjack
if ( blackjack_table != -1 )
{
new
player_index = GetBlackjackPlayerIndex( blackjack_table, playerid );
if ( player_index == -1 )
return SendError( playerid, "You don't seem to be playing any blackjack table." );
if ( PRESSED( KEY_SPRINT ) ) {
if ( ! g_blackjackData[ blackjack_table ] [ E_CARDS_DRAWN ] && g_blackjackData[ blackjack_table ] [ E_GAME_TIMER ] == -1 )
return ( g_blackjackData[ blackjack_table ] [ E_GAME_TIMER ] = SetTimerEx( "BeginBlackJackTurn", BLACKJACK_DEALER_WAIT, false, "d", blackjack_table ) ), 1;
if ( g_blackjackPlayerState[ blackjack_table ] [ player_index ] == BLACKJACK_STATE_TURN ) {
g_blackjackPlayerState[ blackjack_table ] [ player_index ] = BLACKJACK_STATE_STAND;
SendClientMessageToBlackjack( blackjack_table, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has decided to stand.", ReturnPlayerName( playerid ), playerid );
return 1;
}
return 1;
}
if ( PRESSED( KEY_CTRL_BACK ) )
{
if ( g_blackjackPlayerState[ blackjack_table ] [ player_index ] != BLACKJACK_STATE_TURN )
return SendError( playerid, "It's not your turn to hit. Please wait!" );
DrawPlayerBlackjackCard( blackjack_table, player_index );
CheckForBlackjack( blackjack_table );
return 1;
}
}
if ( PRESSED( KEY_SECONDARY_ATTACK ) )
{
if ( p_blackjackTable[ playerid ] != -1 ) {
if ( g_blackjackData[ blackjack_table ] [ E_CARDS_DRAWN ] ) return SendError( playerid, "You cannot exit while you are playing your blackjack hand." );
return RemovePlayerFromBlackjack( playerid, .reset_cam = 1 );
}
foreach(new id : blackjacktables) if ( GetPlayerVirtualWorld( playerid ) == g_blackjackData[ id ] [ E_WORLD ] )
{
if ( IsPlayerInRangeOfPoint( playerid, 3.0, g_blackjackData[ id ] [ E_X ], g_blackjackData[ id ] [ E_Y ], g_blackjackData[ id ] [ E_Z ] ) ) {
new
player_index;
for ( ; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ )
if ( g_blackjackSlotData[ id ] [ player_index ] == -1 )
break;
if ( player_index >= MAX_BLACKJACK_PLAYERS || g_blackjackSlotData[ id ] [ player_index ] != -1 )
return SendError( playerid, "There are no more vacant slots for this table." );
if ( GetPlayerCash( playerid ) < g_blackjackData[ id ] [ E_PAYOUT ] )
return SendError( playerid, "You don't have any money to wager." );
new
Float: lookatX, Float: lookatY, Float: lookatZ,
Float: tmpX, Float: tmpY, Float: tmpZ
;
GetPlayerCameraPos( playerid, X, Y, Z );
GetPlayerCameraFrontVector( playerid, lookatX, lookatY, lookatZ );
tmpX = g_blackjackData[ id ] [ E_X ] - 1.3 * floatcos( g_blackjackData[ id ] [ E_ROTATION ] + 90.0, degrees );
tmpY = g_blackjackData[ id ] [ E_Y ] - 1.3 * floatsin( g_blackjackData[ id ] [ E_ROTATION ] + 90.0, degrees );
tmpZ = g_blackjackData[ id ] [ E_Z ] + 1.7;
InterpolateCameraPos( playerid, X, Y, Z, tmpX, tmpY, tmpZ, 1000, CAMERA_MOVE );
X += floatmul( lookatX, 20.0 );
Y += floatmul( lookatY, 20.0 );
Z += floatmul( lookatZ, 20.0 );
InterpolateCameraLookAt( playerid, X, Y, Z, g_blackjackData[ id ] [ E_X ], g_blackjackData[ id ] [ E_Y ], g_blackjackData[ id ] [ E_Z ] - 1.0, 1000, CAMERA_MOVE );
p_blackjackTable[ playerid ] = id;
g_blackjackSlotData[ id ] [ player_index ] = playerid;
// reset player cards
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ )
g_blackjackPlayerCardIndex[ id ] [ c ] [ player_index ] = -1;
// set player card values
SetBlackjackPlayerLabelValue( id, player_index, 0 );
// show cards to players
for ( new player = 0; player < MAX_BLACKJACK_PLAYERS; player ++ )
{
new
gamerid = g_blackjackSlotData[ id ] [ player ];
// deal only first two cards
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ )
{
TextDrawShowForPlayer( gamerid, g_blackjackDealerCards[ id ] [ c ] );
// show two player cards only
if ( c >= 2 )
continue;
for ( new p = 0; p < GetBlackjackPlayers( id ); p ++ ) {
TextDrawShowForPlayer( gamerid, g_blackjackPlayerCards[ id ] [ c ] [ p ] );
}
}
}
szBigString = "~y~~k~~PED_SPRINT~~w~ - Begin game/Stand~n~~y~~k~~GROUP_CONTROL_BWD~~w~ - Hit~n~~y~~k~~VEHICLE_ENTER_EXIT~~w~ - Exit";
ShowPlayerHelpDialog( playerid, 0, szBigString );
SendServerMessage( playerid, "You have entered the %s hand blackjack table.", number_format( g_blackjackData[ id ] [ E_PAYOUT ] ) );
ApplyAnimation( playerid, "DEALER", "DEALER_IDLE", 4.1, 1, 1, 1, 1, 0, 1 );
return 1;
}
}
}
}
return 1;
}
hook InitializeTextDraws( )
{
for ( new i = 0; i < MAX_BLACKJACK_TABLES; i ++ ) {
initializeBlackjackTextdraws( i );
}
}
/* ** Functions ** */
stock CreateBlackjackTable( payout, Float: X, Float: Y, Float: Z, Float: Angle, world )
{
new
id = Iter_Free(blackjacktables);
if ( id != ITER_NONE )
{
g_blackjackData[ id ] [ E_X ] = X;
g_blackjackData[ id ] [ E_Y ] = Y;
g_blackjackData[ id ] [ E_Z ] = Z;
g_blackjackData[ id ] [ E_ROTATION ] = Angle;
g_blackjackData[ id ] [ E_WORLD ] = world;
g_blackjackData[ id ] [ E_DRAW_CARD_TIMER ] = -1;
g_blackjackData[ id ] [ E_RESET_TIMER ] = -1;
g_blackjackData[ id ] [ E_GAME_TIMER ] = -1;
g_blackjackData[ id ] [ E_PAYOUT ] = payout;
g_blackjackData[ id ] [ E_OBJECT ] = CreateDynamicObject( 2188, X, Y, Z, 0.00000, 0.00000, Angle, .worldid = world, .priority = 9999 );
g_blackjackData[ id ] [ E_ACTOR ] = CreateDynamicActor( 171, X - 0.4 * floatcos( Angle - 90.0, degrees ), Y - 0.4 * floatsin( Angle - 90.0, degrees ), Z, Angle + 180.0, .worldid = world );
g_blackjackData[ id ] [ E_DEALER_LABEL ] = CreateDynamic3DTextLabel( sprintf( "Press ENTER To Play Blackjack\n"COL_WHITE"%s Minimum", number_format( payout ) ), COLOR_GREY, X, Y, Z + 0.25, 15.0, .testlos = 0, .worldid = world );
g_blackjackData[ id ] [ E_PLAYER_LABEL ] [ 0 ] = CreateDynamic3DTextLabel( "Player 0", 0, X + 0.7 * floatcos( Angle - 90.0, degrees ), Y + 0.7 * floatsin( Angle - 90.0, degrees ), Z + 0.05, 15.0, .testlos = 0, .worldid = world );
g_blackjackData[ id ] [ E_PLAYER_LABEL ] [ 1 ] = CreateDynamic3DTextLabel( "Player 1", 0, X + 0.7 * floatcos( Angle - 90.0 - 22.5, degrees ), Y + 0.7 * floatsin( Angle - 90.0 - 22.5, degrees ), Z + 0.05, 15.0, .testlos = 0, .worldid = world );
g_blackjackData[ id ] [ E_PLAYER_LABEL ] [ 2 ] = CreateDynamic3DTextLabel( "Player 2", 0, X + 0.7 * floatcos( Angle - 90.0 + 22.5, degrees ), Y + 0.7 * floatsin( Angle - 90.0 + 22.5, degrees ), Z + 0.05, 15.0, .testlos = 0, .worldid = world );
SetDynamicActorInvulnerable( g_blackjackData[ id ] [ E_ACTOR ], true );
SetDynamicActorVirtualWorld( g_blackjackData[ id ] [ E_ACTOR ], world );
ResetBlackjackTable( id );
Iter_Add( blackjacktables, id );
}
else
{
static overflow;
printf("[BLACKJACK ERROR] Reached limit of %d blackjack tables, increase to %d to fix.", MAX_BLACKJACK_TABLES, MAX_BLACKJACK_TABLES + ( ++ overflow ) );
}
return 1;
}
function DrawPlayerBlackjackCard( tableid, player_index )
{
new
randomCard = MRandom( sizeof( g_blackjackDealerCards ) );
for ( new cardid = 0; cardid < MAX_BLACKJACK_CARDS; cardid ++ ) if ( g_blackjackPlayerCardIndex[ tableid ] [ cardid ] [ player_index ] == -1 ) {
TextDrawSetString( g_blackjackPlayerCards[ tableid ] [ cardid ] [ player_index ], g_cardTextdrawData[ randomCard ] );
foreach (new gamerid : Player) if ( p_blackjackTable[ gamerid ] == tableid ) {
TextDrawShowForPlayer( gamerid, g_blackjackPlayerCards[ tableid ] [ cardid ] [ player_index ] );
PlayerPlaySound( gamerid, 1145, 0.0, 0.0, 0.0 );
}
g_blackjackPlayerCardIndex[ tableid ] [ cardid ] [ player_index ] = randomCard;
SetBlackjackPlayerLabelValue( tableid, player_index, CalculatePlayerHand( tableid, player_index ) );
break;
}
return randomCard;
}
function BeginBlackJackTurn( tableid )
{
new
cardid = g_blackjackData[ tableid ] [ E_CARDS_DRAWN ] ++;
if ( cardid >= MAX_BLACKJACK_CARDS ) {
ResetBlackjackTable( tableid );
return;
}
new
randomCard = MRandom( sizeof( g_blackjackDealerCards ) );
// dealer cards
ApplyDynamicActorAnimation( g_blackjackData[ tableid ] [ E_ACTOR ], "CASINO", "dealone", 4.1, 0, 0, 0, 0, 0 );
ApplyDynamicActorAnimation( g_blackjackData[ tableid ] [ E_ACTOR ], "CASINO", "dealone", 4.1, 0, 0, 0, 0, 0 );
TextDrawSetString( g_blackjackDealerCards[ tableid ] [ cardid ], g_cardTextdrawData[ randomCard ] );
g_blackjackDealerCardIndex[ tableid ] [ cardid ] = randomCard;
SetBlackjackDealerLabelValue( tableid, CalculateDealerHand( tableid ) );
// noise
foreach (new gamerid : Player) if ( p_blackjackTable[ gamerid ] != -1 ) {
PlayerPlaySound( gamerid, 1145, 0.0, 0.0, 0.0 );
}
// deal player first card
if ( cardid == 0 )
{
new blackjack_players = GetBlackjackPlayers( tableid );
new bet_amount = 0;
for ( new player_index = 0; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ ) if ( g_blackjackSlotData[ tableid ] [ player_index ] != -1 )
{
new
gamerid = g_blackjackSlotData[ tableid ] [ player_index ];
if ( GetPlayerCash( gamerid ) < g_blackjackData[ tableid ] [ E_PAYOUT ] ) {
SendError( gamerid, "You don't have any money to wager." );
RemovePlayerFromBlackjack( gamerid, .reset_cam = 1 );
if ( blackjack_players - 1 <= 0 ) return; // no point having an empty table
continue;
}
bet_amount += g_blackjackData[ tableid ] [ E_PAYOUT ];
GivePlayerCash( gamerid, -g_blackjackData[ tableid ] [ E_PAYOUT ] );
DrawPlayerBlackjackCard( tableid, player_index );
if ( cardid < 1 ) { // distribute first two cards to players
g_blackjackData[ tableid ] [ E_DRAW_CARD_TIMER ] = SetTimerEx( "DrawPlayerBlackjackCard", BLACKJACK_DEALER_WAIT, false, "dd", tableid, player_index );
}
}
UpdateServerVariable( "blackjack_bets", 0, GetGVarFloat( "blackjack_bets" ) + ( float( bet_amount ) / 1000000.0 ), "", GLOBAL_VARTYPE_FLOAT );
// begin turns
new
first_player = GetNextAvailableBlackjackPlayer( tableid ),
first_player_index = GetBlackjackPlayerIndex( tableid, first_player )
;
if ( first_player_index != -1 )
g_blackjackPlayerState[ tableid ] [ first_player_index ] = BLACKJACK_STATE_TURN;
g_blackjackData[ tableid ] [ E_GAME_TIMER ] = SetTimerEx( "BlackjackPlayerTurn", BLACKJACK_DEALER_WAIT + 500, false, "ddd", tableid, first_player, BLACKJACK_PLAYER_WAIT );
}
// check for blackjack on players & bot
new
dealer_score = CheckForBlackjack( tableid );
// pull more cards
if ( cardid >= 1 && dealer_score < 17 )
g_blackjackData[ tableid ] [ E_GAME_TIMER ] = SetTimerEx( "BeginBlackJackTurn", BLACKJACK_DEALER_WAIT, false, "d", tableid );
if ( dealer_score >= 17 ) {
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" Table will reset in 5 seconds as all hands have been dealt." );
g_blackjackData[ tableid ] [ E_RESET_TIMER ] = SetTimerEx( "ResetBlackjackTable", 5000, false, "d", tableid );
}
}
stock GetNextAvailableBlackjackPlayer( tableid, exclude = INVALID_PLAYER_ID )
{
new
playerid = INVALID_PLAYER_ID;
for ( new player_index = 0; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ ) if ( g_blackjackSlotData[ tableid ] [ player_index ] != -1 && g_blackjackPlayerState[ tableid ] [ player_index ] == BLACKJACK_STATE_NONE && exclude != g_blackjackSlotData[ tableid ] [ player_index ] && g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] != -1 ) {
playerid = g_blackjackSlotData[ tableid ] [ player_index ];
break;
}
return playerid;
}
function BlackjackPlayerTurn( tableid, playerid, seconds_left )
{
new
player_index = GetBlackjackPlayerIndex( tableid, playerid );
if ( IsPlayerConnected( playerid ) && player_index != -1 && seconds_left >= 0 && g_blackjackPlayerState[ tableid ] [ player_index ] == BLACKJACK_STATE_TURN )
{
foreach (new gamerid : Player) if ( p_blackjackTable[ gamerid ] == tableid ) {
TextDrawSetString( g_blackjackTurnTD[ tableid ], sprintf( "%s has %d seconds left", ReturnPlayerName( playerid ), seconds_left ) );
TextDrawShowForPlayer( gamerid, g_blackjackTurnTD[ tableid ] );
}
g_blackjackData[ tableid ] [ E_GAME_TIMER ] = SetTimerEx( "BlackjackPlayerTurn", 960, false, "ddd", tableid, playerid, seconds_left - 1 );
}
else
{
new
next_player = GetNextAvailableBlackjackPlayer( tableid, playerid );
if ( next_player == INVALID_PLAYER_ID )
{
TextDrawHideForAll( g_blackjackTurnTD[ tableid ] );
g_blackjackData[ tableid ] [ E_GAME_TIMER ] = SetTimerEx( "BeginBlackJackTurn", BLACKJACK_DEALER_WAIT, false, "d", tableid );
}
else
{
new
next_player_index = GetBlackjackPlayerIndex( tableid, next_player );
// otherwise winning hands will get reissued prizes
if ( player_index != -1 && g_blackjackPlayerState[ tableid ] [ player_index ] != BLACKJACK_STATE_WIN && g_blackjackPlayerState[ tableid ] [ player_index ] != BLACKJACK_STATE_BUST )
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_STAND;
g_blackjackPlayerState[ tableid ] [ next_player_index ] = BLACKJACK_STATE_TURN;
g_blackjackData[ tableid ] [ E_GAME_TIMER ] = SetTimerEx( "BlackjackPlayerTurn", 960, false, "ddd", tableid, next_player, BLACKJACK_PLAYER_WAIT );
}
}
}
function ResetBlackjackTable( tableid )
{
if ( tableid == -1 )
return;
// variables
SetBlackjackDealerLabelValue( tableid, -1 );
KillTimer( g_blackjackData[ tableid ] [ E_RESET_TIMER ] ), g_blackjackData[ tableid ] [ E_RESET_TIMER ] = -1;
KillTimer( g_blackjackData[ tableid ] [ E_GAME_TIMER ] ), g_blackjackData[ tableid ] [ E_GAME_TIMER ] = -1;
KillTimer( g_blackjackData[ tableid ] [ E_DRAW_CARD_TIMER ] ), g_blackjackData[ tableid ] [ E_DRAW_CARD_TIMER ] = -1;
g_blackjackData[ tableid ] [ E_CARDS_DRAWN ] = 0;
// card data
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ ) {
g_blackjackDealerCardIndex[ tableid ] [ c ] = -1;
TextDrawSetString( g_blackjackDealerCards[ tableid ] [ c ], "ld_card:cdback" );
for ( new p = 0; p < MAX_BLACKJACK_PLAYERS; p ++ ) {
g_blackjackPlayerState[ tableid ] [ p ] = BLACKJACK_STATE_NONE;
g_blackjackPlayerCardIndex[ tableid ] [ c ] [ p ] = -1;
TextDrawSetString( g_blackjackPlayerCards[ tableid ] [ c ] [ p ], "ld_card:cdback" );
if ( c > 1 ) TextDrawHideForAll( g_blackjackPlayerCards[ tableid ] [ c ] [ p ] );
}
}
// reshow textdraws to players
for ( new player_index = 0; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ )
{
if ( g_blackjackSlotData[ tableid ] [ player_index ] != -1 )
{
new
gamerid = g_blackjackSlotData[ tableid ] [ player_index ];
// reset label
SetBlackjackPlayerLabelValue( tableid, player_index, 0 );
// deal only first two cards
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ )
{
TextDrawShowForPlayer( gamerid, g_blackjackDealerCards[ tableid ] [ c ] );
// show two player cards only
if ( c >= 2 )
continue;
for ( new p = 0; p < GetBlackjackPlayers( tableid ); p ++ ) {
TextDrawShowForPlayer( gamerid, g_blackjackPlayerCards[ tableid ] [ c ] [ p ] );
}
}
}
else SetBlackjackPlayerLabelValue( tableid, player_index, -1 );
}
}
stock CheckForBlackjack( tableid )
{
new
dealer_score = CalculateDealerHand( tableid );
//if ( g_blackjackData[ tableid ] [ E_CARDS_DRAWN ] <= 1 )
// return dealer_score;
//printf("The Dealer score is %d", dealer_score );
SetBlackjackDealerLabelValue( tableid, dealer_score );
// calculate player score
for ( new player_index = 0; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ ) if ( g_blackjackSlotData[ tableid ] [ player_index ] != -1 && g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] != -1 )
{
new playerid = g_blackjackSlotData[ tableid ] [ player_index ];
new player_score = CalculatePlayerHand( tableid, player_index );
SetBlackjackPlayerLabelValue( tableid, player_index, player_score );
if ( g_blackjackPlayerState[ tableid ] [ player_index ] != BLACKJACK_STATE_BUST && g_blackjackPlayerState[ tableid ] [ player_index ] != BLACKJACK_STATE_WIN )
{
new
payout = floatround( float( g_blackjackData[ tableid ] [ E_PAYOUT ] ) * 2.0 );
// check for win
if ( dealer_score == player_score && dealer_score >= 17 ) {
payout = g_blackjackData[ tableid ] [ E_PAYOUT ];
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_WIN;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has been returned %s due to a push.", ReturnPlayerName( playerid ), playerid, number_format( payout ) );
GameTextForPlayer( playerid, sprintf( "~n~~n~~y~%s returned!", number_format( payout ) ), 4000, 3 );
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
GivePlayerCash( playerid, payout );
}
else if ( player_score == 21 ) {
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_WIN;
if ( IsPlayerHandBlackjack( tableid, player_index, player_score ) ) {
payout = floatround( float( g_blackjackData[ tableid ] [ E_PAYOUT ] ) * 2.5 );
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" Blackjack! %s(%d) has won %s!", ReturnPlayerName( playerid ), playerid, number_format( payout ) );
} else {
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has won %s due to a card count of 21!", ReturnPlayerName( playerid ), playerid, number_format( payout ) );
}
GameTextForPlayer( playerid, sprintf( "~n~~n~~g~%s won!", number_format( payout ) ), 4000, 3 );
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
GivePlayerCash( playerid, payout );
}
else if ( dealer_score == 21 ) {
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_BUST;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has lost %s due to a dealer %s.", ReturnPlayerName( playerid ), playerid, number_format( g_blackjackData[ tableid ] [ E_PAYOUT ] ), IsDealerHandBlackjack( tableid, dealer_score ) ? ( "blackjack" ) : ( "21" ) );
GameTextForPlayer( playerid, "~n~~n~~r~No win!", 4000, 3 );
}
else if ( player_score > 21 ) {
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_BUST;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has lost %s due to a bust.", ReturnPlayerName( playerid ), playerid, number_format( g_blackjackData[ tableid ] [ E_PAYOUT ] ) );
GameTextForPlayer( playerid, "~n~~n~~r~No win!", 4000, 3 );
}
else if ( dealer_score > 21 ) {
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_WIN;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has won %s due to a dealer bust.", ReturnPlayerName( playerid ), playerid, number_format( payout ) );
GameTextForPlayer( playerid, sprintf( "~n~~n~~g~%s won!", number_format( payout ) ), 4000, 3 );
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
GivePlayerCash( playerid, payout );
}
else if ( player_score < dealer_score && dealer_score >= 17 ) {
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_BUST;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has lost %s due to a bust.", ReturnPlayerName( playerid ), playerid, number_format( g_blackjackData[ tableid ] [ E_PAYOUT ] ) );
GameTextForPlayer( playerid, "~n~~n~~r~No win!", 4000, 3 );
}
else if ( player_score > dealer_score && dealer_score >= 17 ) {
g_blackjackPlayerState[ tableid ] [ player_index ] = BLACKJACK_STATE_WIN;
SendClientMessageToBlackjack( tableid, COLOR_GREY, "[BLACKJACK]"COL_WHITE" %s(%d) has won %s due to a dealer bust.", ReturnPlayerName( playerid ), playerid, number_format( g_blackjackData[ tableid ] [ E_PAYOUT ] ) );
GameTextForPlayer( playerid, sprintf( "~n~~n~~g~%s won!", number_format( payout ) ), 4000, 3 );
GivePlayerCasinoRewardsPoints( playerid, g_blackjackData[ tableid ] [ E_PAYOUT ], .house_edge = 1.5 );
GivePlayerCash( playerid, payout );
}
// alert world
if ( g_blackjackPlayerState[ tableid ] [ player_index ] == BLACKJACK_STATE_WIN && payout > g_blackjackData[ tableid ] [ E_PAYOUT ] && payout >= 10000 ) {
UpdateServerVariable( "blackjack_wins", 0, GetGVarFloat( "blackjack_wins" ) + ( float( payout ) / 1000000.0 ), "", GLOBAL_VARTYPE_FLOAT );
SendGlobalMessage( -1, ""COL_GREY"[CASINO]{FFFFFF} %s(%d) has won "COL_GOLD"%s"COL_WHITE" from blackjack!", ReturnPlayerName( playerid ), playerid, number_format( payout ) );
}
}
}
return dealer_score;
}
stock RemovePlayerFromBlackjack( playerid, reset_cam = 0 )
{
if ( ! ( 0 <= playerid < MAX_PLAYERS ) )
return 0;
new
blackjack_table = p_blackjackTable[ playerid ];
if ( blackjack_table == -1 )
return 0;
// hide textdraws & reset
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ ) {
TextDrawHideForPlayer( playerid, g_blackjackDealerCards[ blackjack_table ] [ c ] );
for ( new p = 0; p < MAX_BLACKJACK_PLAYERS; p ++ ) {
TextDrawHideForPlayer( playerid, g_blackjackPlayerCards[ blackjack_table ] [ c ] [ p ] );
}
}
TextDrawHideForPlayer( playerid, g_blackjackTurnTD[ blackjack_table ] );
// check if it is a player
new
player_index = GetBlackjackPlayerIndex( blackjack_table, playerid );
if ( player_index != -1 )
{
foreach (new i : Player) if ( p_blackjackTable[ i ] == blackjack_table ) {
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ ) {
g_blackjackPlayerCardIndex[ blackjack_table ] [ c ] [ player_index ] = -1;
g_blackjackPlayerState[ blackjack_table ] [ player_index ] = BLACKJACK_STATE_NONE;
TextDrawSetString( g_blackjackPlayerCards[ blackjack_table ] [ c ] [ player_index ], "ld_card:cdback" );
TextDrawHideForPlayer( i, g_blackjackPlayerCards[ blackjack_table ] [ c ] [ player_index ] );
}
}
g_blackjackSlotData[ blackjack_table ] [ player_index ] = -1;
SetBlackjackPlayerLabelValue( blackjack_table, player_index, -1 );
}
// reset camera?
if ( reset_cam ) {
TogglePlayerControllable( playerid, 1 );
ClearAnimations( playerid );
SetCameraBehindPlayer( playerid );
HidePlayerHelpDialog( playerid );
}
// reset variables
p_blackjackTable[ playerid ] = -1;
// reset table just incase empty
if ( GetBlackjackPlayers( blackjack_table ) <= 0 )
ResetBlackjackTable( blackjack_table );
return 1;
}
stock SendClientMessageToBlackjack( tableid, colour, format[ ], va_args<> )
{
static
out[ 144 ];
va_format( out, sizeof( out ), format, va_start<3> );
for(new i = 0; i < 10; i++) if ( p_blackjackTable[ i ] == tableid ) {
SendClientMessage( i, colour, out );
}
return 1;
}
stock initializeBlackjackTextdraws( id )
{
g_blackjackTurnTD[ id ] = TextDrawCreate(330.000000, 204.000000, "Lorenc has 5 seconds");
TextDrawAlignment(g_blackjackTurnTD[ id ], 2);
TextDrawBackgroundColor(g_blackjackTurnTD[ id ], 255);
TextDrawFont(g_blackjackTurnTD[ id ], 1);
TextDrawLetterSize(g_blackjackTurnTD[ id ], 0.260000, 1.200000);
TextDrawColor(g_blackjackTurnTD[ id ], 16711935);
TextDrawSetOutline(g_blackjackTurnTD[ id ], 1);
TextDrawSetProportional(g_blackjackTurnTD[ id ], 1);
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ )
{
g_blackjackDealerCards[ id ] [ c ] = TextDrawCreate(243.000000 + 35.0 * float( c ), 138.000000, "ld_card:cdback");
TextDrawBackgroundColor( g_blackjackDealerCards[ id ] [ c ], 255);
TextDrawFont( g_blackjackDealerCards[ id ] [ c ], 4);
TextDrawLetterSize( g_blackjackDealerCards[ id ] [ c ], 0.500000, 1.000000);
TextDrawUseBox( g_blackjackDealerCards[ id ] [ c ], 1);
TextDrawBoxColor( g_blackjackDealerCards[ id ] [ c ], 255);
TextDrawTextSize( g_blackjackDealerCards[ id ] [ c ], 30.000000, 51.000000);
}
new
Float: g_blackjackPlayerPosition[ MAX_BLACKJACK_PLAYERS ] [ 2 ] = { { 295.0, 334.0 }, { 205.0, 319.0 }, { 390.0, 329.0 } };
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ )
{
for ( new p = 0; p < MAX_BLACKJACK_PLAYERS; p ++ )
{
g_blackjackPlayerCards[ id ] [ c ] [ p ] = TextDrawCreate( g_blackjackPlayerPosition[ p ] [ 0 ] + 10.0 * float( c ), g_blackjackPlayerPosition[ p ] [ 1 ] - 16.0 * float( c ), "ld_card:cdback" );
TextDrawBackgroundColor( g_blackjackPlayerCards[ id ] [ c ] [ p ], 255 );
TextDrawFont( g_blackjackPlayerCards[ id ] [ c ] [ p ], 4 );
TextDrawLetterSize( g_blackjackPlayerCards[ id ] [ c ] [ p ], 0.5, 0.7 );
TextDrawUseBox( g_blackjackPlayerCards[ id ] [ c ] [ p ], 1 );
TextDrawBoxColor( g_blackjackPlayerCards[ id ] [ c ] [ p ], 255 );
TextDrawTextSize( g_blackjackPlayerCards[ id ] [ c ] [ p ], 22.000000, 37.000000 );
}
}
}
stock IsPlayerHandBlackjack( tableid, player_index, card_count )
{
if ( card_count == 21 && ( g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] == 0 || g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] == 13 || g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] == 26 || g_blackjackPlayerCardIndex[ tableid ] [ 0 ] [ player_index ] == 39 ) )
return true;
if ( card_count == 21 && ( g_blackjackPlayerCardIndex[ tableid ] [ 1 ] [ player_index ] == 0 || g_blackjackPlayerCardIndex[ tableid ] [ 1 ] [ player_index ] == 13 || g_blackjackPlayerCardIndex[ tableid ] [ 1 ] [ player_index ] == 26 || g_blackjackPlayerCardIndex[ tableid ] [ 1 ] [ player_index ] == 39 ) )
return true;
return false;
}
stock IsDealerHandBlackjack( tableid, card_count )
{
if ( card_count == 21 && ( g_blackjackDealerCardIndex[ tableid ] [ 0 ] == 0 || g_blackjackDealerCardIndex[ tableid ] [ 0 ] == 13 || g_blackjackDealerCardIndex[ tableid ] [ 0 ] == 26 || g_blackjackDealerCardIndex[ tableid ] [ 0 ] == 39 ) )
return true;
if ( card_count == 21 && ( g_blackjackDealerCardIndex[ tableid ] [ 1 ] == 0 || g_blackjackDealerCardIndex[ tableid ] [ 1 ] == 13 || g_blackjackDealerCardIndex[ tableid ] [ 1 ] == 26 || g_blackjackDealerCardIndex[ tableid ] [ 1 ] == 39 ) )
return true;
return false;
}
stock GetBlackjackCardValue( card_index )
{
new
card_value = 0;
switch ( card_index )
{
case 0, 13, 26, 39: card_value = 1;
case 1, 14, 27, 40: card_value = 2;
case 2, 15, 28, 41: card_value = 3;
case 3, 16, 29, 42: card_value = 4;
case 4, 17, 30, 43: card_value = 5;
case 5, 18, 31, 44: card_value = 6;
case 6, 19, 32, 45: card_value = 7;
case 7, 20, 33, 46: card_value = 8;
case 8, 21, 34, 47: card_value = 9;
case 9, 22, 35, 48, 10, 23, 36, 49, 11, 24, 37, 50, 12, 25, 38, 51: card_value = 10;
}
return card_value;
}
stock GetBlackjackPlayerIndex( tableid, playerid )
{
for ( new player_index = 0; player_index < MAX_BLACKJACK_PLAYERS; player_index ++ ) if ( playerid == g_blackjackSlotData[ tableid ] [ player_index ] ) {
return player_index;
}
return -1;
}
stock GetBlackjackPlayers( tableid ) {
new
count = 0;
for ( new p = 0; p < MAX_BLACKJACK_PLAYERS; p ++ ) if ( g_blackjackSlotData[ tableid ] [ p ] != -1 )
count ++;
return count;
}
stock SetBlackjackPlayerLabelValue( tableid, player_index, score ) {
if ( score != -1 ) {
new playerid = g_blackjackSlotData[ tableid ] [ player_index ];
UpdateDynamic3DTextLabelText( g_blackjackData[ tableid ] [ E_PLAYER_LABEL ] [ player_index ], COLOR_GOLD, sprintf( "%s\n"COL_GREY"Score:"COL_WHITE" %d", ReturnPlayerName( playerid ), score ) );
} else {
UpdateDynamic3DTextLabelText( g_blackjackData[ tableid ] [ E_PLAYER_LABEL ] [ player_index ], 0, sprintf( "Player %d", player_index ) );
}
}
stock SetBlackjackDealerLabelValue( tableid, score ) {
if ( score != -1 ) {
UpdateDynamic3DTextLabelText( g_blackjackData[ tableid ] [ E_DEALER_LABEL ], COLOR_GREY, sprintf( "Dealer\nScore:"COL_WHITE" %d", score ) );
} else {
UpdateDynamic3DTextLabelText( g_blackjackData[ tableid ] [ E_DEALER_LABEL ], COLOR_WHITE, sprintf( "Press ENTER To Play Blackjack\n"COL_WHITE"%s Minimum", number_format( g_blackjackData[ tableid ] [ E_PAYOUT ] ) ) );
}
}
stock CalculatePlayerHand( tableid, player_index )
{
new
player_score = 0;
// add player cards
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ ) if ( g_blackjackPlayerCardIndex[ tableid ] [ c ] [ player_index ] != -1 ) {
player_score += GetBlackjackCardValue( g_blackjackPlayerCardIndex[ tableid ] [ c ] [ player_index ] ); // aces will add as 1 anyway
}
// double check aces
for ( new a = 0; a < MAX_BLACKJACK_CARDS; a ++ ) if ( GetBlackjackCardValue( g_blackjackPlayerCardIndex[ tableid ] [ a ] [ player_index ] ) == 1 ) {
if ( player_score + 10 <= 21 ) player_score += 10; // if there's aces, just use one as an 11. if count stays under 21 of course
break;
}
return player_score;
}
stock CalculateDealerHand( tableid )
{
new
dealer_score = 0;
// add dealer score
for ( new c = 0; c < MAX_BLACKJACK_CARDS; c ++ ) if ( g_blackjackDealerCardIndex[ tableid ] [ c ] != -1 ) {
dealer_score += GetBlackjackCardValue( g_blackjackDealerCardIndex[ tableid ] [ c ] ); // aces will add as 1 anyway
}
// double check aces
for ( new a = 0; a < MAX_BLACKJACK_CARDS; a ++ ) if ( GetBlackjackCardValue( g_blackjackDealerCardIndex[ tableid ] [ a ] ) == 1 ) {
// if there's aces, just use one as an 11. if count stays under 21 of course
if ( dealer_score + 10 <= 21 ) dealer_score += 10;
break;
}
return dealer_score;
}