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

2658 lines
104 KiB
Plaintext

/******************************************************************************************
TPoker
Texas Hold'em Poker Implementation
Copyright (C) 2018 ThreeKingz (Freddy Borja)
https://github.com/ThreeKingz
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************************/
#include <YSI\y_va>
#include <YSI\y_iterate>
#include <YSI\y_hooks>
/* ** Error checking ** */
#if !defined __irresistible_servervars
#error "You need server variables enabled to track betting."
#endif
forward bool: FoldPlayer(handle, playerid);
/*
native calculate_hand_worth(const hands[], count = sizeof(hands));
* hands[]: an array containing the cards to analyze (between 1 to 7 cards)
* count: the number of cards to analyze (between 1 to 7 cards)
*/
native calculate_hand_worth(const hands[], count = sizeof(hands));
#define T_SendWarning(%0) (printf(" * [TPoker]: " %0))
/******************************************************************************************
Utils
*******************************************************************************************/
stock SetPlayerChatBubbleEx(playerid, color, Float:drawdistance, expiretime, const format[], va_args<>)
{
return SetPlayerChatBubble(playerid, va_return(format, va_start<5>), color, drawdistance, expiretime);
}
stock UpdateDynamic3DTextLabelTextEx(STREAMER_TAG_3D_TEXT_LABEL id, color, const format[], va_args<>)
{
return UpdateDynamic3DTextLabelText(id, color, va_return(format, va_start<3>));
}
stock ShowPlayerDialogEx(playerid, dialogid, style, caption[], button1[], button2[], const format[], va_args<>)
{
return ShowPlayerDialog(playerid, dialogid, style, caption, va_return(format, va_start<7>), button1, button2);
}
/******************************************************************************************
Constants
*******************************************************************************************/
//Limits
#define T_MAX_POKER_TABLES 35
#define T_MAX_CHAIRS_PER_TABLE 7
#define T_CHAIR_MODEL 2120
#define T_MAX_CHIPS_PER_CHAIR 4
#define T_MAX_WAIT_TIME 20 //20 seconds to make a choice
#define T_START_DELAY 5 //5 seconds
#define T_SAVE_PLAYER_POS true
//Max number the chips can express 10^(MAX_CHIP_DIGITS) - 1
#define MAX_CHIP_DIGITS 7
#define T_TABLE_TICK_INTERVAL 500 //(in ms) half a second
#define T_POT_FEE_RATE 0.02
//Layout and design
#define T_Z_OFFSET 0.442852
#define T_CHAIR_RANGE 1.250000
#define T_Z_CAMERA_OFFSET 3.0
#define T_CHIP_OFFSET 0.13
//Length and width of cards
#define T_CARD_X_SIZE 23.0 // 21.000000
#define T_CARD_Y_SIZE 31.0 // 29.000000
#define T_TWO_CARD_DISTANCE 23.904725 //Distance between the two cards each player receives
#define T_CARDS_RADIAL_DISTANCE 144.00000 //Distance from the first card to the center of the table
#define T_SCREEN_CENTER_X 320.00000
#define T_SCREEN_CENTER_Y 215.00000
#define T_CHIPS_DISTANCE 0.6582
#define T_RADIUS 0.971977
#define T_BET_LABEL_COLOR 0x0080FFFF
//Radial distance required to enter a table
#define T_JOIN_TABLE_RANGE 2.5
/*Textdraw constants*/
#define MAIN_POT 0
#define CALL 2
#define RAISE 3
#define FOLD 4
// #define DIALOG_BUY_IN 19232
// #define DIALOG_INPUT_RAISE 9231
#define SendPokerMessage(%0,%1) \
SendClientMessageFormatted(%0, -1, "{4B8774}[POKER] {E5861A}"%1)
#define IsPlayerPlayingPoker(%0) (GetPVarInt(%0,"t_is_in_table"))
/******************************************************************************************
Enums and arrays
*******************************************************************************************/
/* Iterators */
new Iterator:IT_Tables<T_MAX_POKER_TABLES>;
new Iterator:IT_TableCardSet[T_MAX_POKER_TABLES]<52>; //Card sample space
new Iterator:IT_PlayersTable<T_MAX_POKER_TABLES, MAX_PLAYERS>; //Current players in the table (might not be playing but just looking the rest of the players play)
new Iterator:IT_PlayersInGame<T_MAX_POKER_TABLES, MAX_PLAYERS>; //Current players in the table playing
new Iterator:IT_PlayersAllIn<T_MAX_POKER_TABLES, MAX_PLAYERS>;
//Syntax: It_SidepotMembers[_IT[idx_table][idx_chair_slot]]
new Iterator:It_SidepotMembers[T_MAX_POKER_TABLES * T_MAX_CHAIRS_PER_TABLE]<MAX_PLAYERS>;
new Iterator:IT_Sidepots[T_MAX_POKER_TABLES]<T_MAX_CHAIRS_PER_TABLE>;
#define _IT[%0][%1] %0*T_MAX_CHAIRS_PER_TABLE+%1
#define IsValidTable(%0) ((0 <= %0 < T_MAX_POKER_TABLES) && Iter_Contains(IT_Tables, %0))
enum E_TABLE_STATES
{
STATE_IDLE,
STATE_BEGIN, //Game has started
}
//Rankings: from lowest to highest
new const HAND_RANKS[][] =
{
{"Undefined"}, //will never occur
{"High Card"},
{"Pair"},
{"Two Pair"},
{"Three of a Kind"},
{"Straight"},
{"Flush"},
{"Full House"},
{"Four of a Kind"},
{"Straight Flush"},
{"Royal Flush"}
};
enum E_CARD_SUITS
{
SUIT_SPADES,
SUIT_HEARTS,
SUIT_CLUBS,
SUIT_DIAMONDS
};
enum E_CARD_DATA
{
E_CARD_TEXTDRAW[48],
E_CARD_NAME[48],
E_CARD_SUITS:E_CARD_SUIT,
E_CARD_RANK
};
new const CardData[ 52 ] [E_CARD_DATA] = {
//Spades
{"LD_CARD:cd2s", "Two of Spades", SUIT_SPADES, 0},
{"LD_CARD:cd3s", "Three of Spades", SUIT_SPADES, 1},
{"LD_CARD:cd4s", "Four of Spades", SUIT_SPADES, 2},
{"LD_CARD:cd5s", "Five of Spades", SUIT_SPADES, 3},
{"LD_CARD:cd6s", "Six of Spades", SUIT_SPADES, 4},
{"LD_CARD:cd7s", "Seven of Spades", SUIT_SPADES, 5},
{"LD_CARD:cd8s", "Eight of Spades", SUIT_SPADES, 6},
{"LD_CARD:cd9s", "Nine of Spades", SUIT_SPADES, 7},
{"LD_CARD:cd10s", "Ten of Spades", SUIT_SPADES, 8},
{"LD_CARD:cd11s", "Jack of Spades", SUIT_SPADES, 9},
{"LD_CARD:cd12s", "Queen of Spades", SUIT_SPADES, 10},
{"LD_CARD:cd13s", "King of Spades", SUIT_SPADES, 11},
{"LD_CARD:cd1s", "Ace of Spades", SUIT_SPADES, 12},
//Hearts
{"LD_CARD:cd2h", "Two of Hearts", SUIT_HEARTS, 0},
{"LD_CARD:cd3h", "Three of Hearts", SUIT_HEARTS, 1},
{"LD_CARD:cd4h", "Four of Hearts", SUIT_HEARTS, 2},
{"LD_CARD:cd5h", "Five of Hearts", SUIT_HEARTS, 3},
{"LD_CARD:cd6h", "Six of Hearts", SUIT_HEARTS, 4},
{"LD_CARD:cd7h", "Seven of Hearts", SUIT_HEARTS, 5},
{"LD_CARD:cd8h", "Eight of Hearts", SUIT_HEARTS, 6},
{"LD_CARD:cd9h", "Nine of Hearts", SUIT_HEARTS, 7},
{"LD_CARD:cd10h", "Ten of Hearts", SUIT_HEARTS, 8},
{"LD_CARD:cd11h", "Jack of Hearts", SUIT_HEARTS, 9},
{"LD_CARD:cd12h", "Queen of Hearts", SUIT_HEARTS, 10},
{"LD_CARD:cd13h", "King of Hearts", SUIT_HEARTS, 11},
{"LD_CARD:cd1h", "Ace of Hearts", SUIT_HEARTS, 12},
//Clubs
{"LD_CARD:cd2c", "Two of Clubs", SUIT_CLUBS, 0},
{"LD_CARD:cd3c", "Three of Clubs", SUIT_CLUBS, 1},
{"LD_CARD:cd4c", "Four of Clubs", SUIT_CLUBS, 2},
{"LD_CARD:cd5c", "Five of Clubs", SUIT_CLUBS, 3},
{"LD_CARD:cd6c", "Six of Clubs", SUIT_CLUBS, 4},
{"LD_CARD:cd7c", "Seven of Clubs", SUIT_CLUBS, 5},
{"LD_CARD:cd8c", "Eight of Clubs", SUIT_CLUBS, 6},
{"LD_CARD:cd9c", "Nine of Clubs", SUIT_CLUBS, 7},
{"LD_CARD:cd10c", "Ten of Clubs", SUIT_CLUBS, 8},
{"LD_CARD:cd11c", "Jack of Clubs", SUIT_CLUBS, 9},
{"LD_CARD:cd12c", "Queen of Clubs", SUIT_CLUBS, 10},
{"LD_CARD:cd13c", "King of Clubs", SUIT_CLUBS, 11},
{"LD_CARD:cd1c", "Ace of Clubs", SUIT_CLUBS, 12},
//Diamonds
{"LD_CARD:cd2d", "Two of Diamonds", SUIT_DIAMONDS, 0},
{"LD_CARD:cd3d", "Three of Diamonds", SUIT_DIAMONDS, 1},
{"LD_CARD:cd4d", "Four of Diamonds", SUIT_DIAMONDS, 2},
{"LD_CARD:cd5d", "Five of Diamonds", SUIT_DIAMONDS, 3},
{"LD_CARD:cd6d", "Six of Diamonds", SUIT_DIAMONDS, 4},
{"LD_CARD:cd7d", "Seven of Diamonds", SUIT_DIAMONDS, 5},
{"LD_CARD:cd8d", "Eight of Diamonds", SUIT_DIAMONDS, 6},
{"LD_CARD:cd9d", "Nine of Diamonds", SUIT_DIAMONDS, 7},
{"LD_CARD:cd10d", "Ten of Diamonds", SUIT_DIAMONDS, 8},
{"LD_CARD:cd11d", "Jack of Diamonds", SUIT_DIAMONDS, 9},
{"LD_CARD:cd12d", "Queen of Diamonds", SUIT_DIAMONDS, 10},
{"LD_CARD:cd13d", "King of Diamonds", SUIT_DIAMONDS, 11},
{"LD_CARD:cd1d", "Ace of Diamonds", SUIT_DIAMONDS, 12}
};
//Card rank = (array index % 13) | Card native index = 4 * rank + suit
#define GetCardNativeIndex(%0) ((4*((%0) % 13))+_:CardData[(%0)][E_CARD_SUIT])
new const TableRotCorrections[][] =
{
{-1, -1, -1, -1, -1, -1},//0seats
{-1, -1, -1, -1, -1, -1},//1 seat
{ 1, 0, -1, -1, -1, -1},//2 seats
{ 1, 0, 2, -1, -1, -1},//3 seats
{ 1, 0, 3, 2, -1, -1},//4 seats
{ 1, 0, 4, 3, 2, -1},//5 seats
{ 1, 0, 5, 4, 3, 2} //6 seats
};
new const colors[MAX_CHIP_DIGITS] =
{
0xFF0080C0,//1
0xFF008000,//10
0xFF324A4E,//100
0xFF7C4303,//1,000
0xFF63720E,//10,000
0xFFE2C241,//100,000
0xFFE4603F//1,000,000
//0xFFCD270A, //100,000,000
//0xFFFF2424, //1,000,000,000
//0xFFFF2424, //10,000,000,000
};
new const chip_text[MAX_CHIP_DIGITS][8] =
{
{"$1"},
{"$10"},
{"$100"},
{"$1K"},
{"$10K"},
{"$100K"},
{"$1M"}
//{"$10M"},
//{"$100M"},
//{"$1,000M"}
};
/*============*/
enum E_TABLE_ROUNDS
{
ROUND_PRE_FLOP, //no community cards displayed yet
ROUND_FLOP,
ROUND_TURN, //4th com card is shown
ROUND_RIVER //5th community card is shown
};
enum e_TABLE
{
E_TABLE_BUY_IN,
E_TABLE_SMALL_BLIND,
E_TABLE_BIG_BLIND,
E_TABLE_LAST_TO_RAISE,
E_TABLE_LAST_TO_RAISE_SEAT,
E_TABLE_CURRENT_TURN,
E_TABLE_LAST_BET,
E_TABLE_STATES:E_TABLE_CURRENT_STATE,
E_TABLE_PLAYER_DEALER_ID,
E_TABLE_PLAYER_BIG_BLIND_ID,
E_TABLE_PLAYER_SMALL_BLIND_ID,
bool:E_TABLE_CHECK_FIRST,
E_TABLE_FIRST_TURN,
//============SIDEPOTS===================
E_TABLE_POT_CHIPS[T_MAX_CHAIRS_PER_TABLE],
//=======================================
bool: E_TABLE_TIMER_STARTED,
E_TABLE_OBJECT_IDS[2], //Two objects (models 2111 and 2189)
Float:E_TABLE_POS_X,
Float:E_TABLE_POS_Y,
Float:E_TABLE_POS_Z,
E_TABLE_ROUNDS: E_TABLE_CURRENT_ROUND,
E_TABLE_DEALER_SEAT,
E_TABLE_TOTAL_SEATS,
E_TABLE_TIMER_ID,
bool: E_TABLE_LOADING_GAME,
bool: E_TABLE_STING_NEW_GAME,
E_TABLE_COM_CARDS_VALUES[5],
Text3D:E_TABLE_POT_LABEL,
E_TABLE_VIRTUAL_WORLD,
E_TABLE_INTERIOR,
Text3D:E_TABLE_BET_LABELS[T_MAX_CHAIRS_PER_TABLE],
E_TABLE_CHAIR_OBJECT_IDS[T_MAX_CHAIRS_PER_TABLE],
bool:E_TABLE_IS_SEAT_TAKEN[T_MAX_CHAIRS_PER_TABLE],
E_TABLE_CHAIR_PLAYER_ID[T_MAX_CHAIRS_PER_TABLE],
Float:E_TABLE_SEAT_POS_X[T_MAX_CHAIRS_PER_TABLE],
Float:E_TABLE_SEAT_POS_Y[T_MAX_CHAIRS_PER_TABLE],
Float:E_TABLE_SEAT_POS_Z[T_MAX_CHAIRS_PER_TABLE],
E_TABLE_CHIPS[MAX_CHIP_DIGITS],
E_TABLE_CHIPS_LABEL[MAX_CHIP_DIGITS]
};
new TableData[T_MAX_POKER_TABLES + 1][e_TABLE];
new TableChips[T_MAX_POKER_TABLES + 1][T_MAX_CHAIRS_PER_TABLE][MAX_CHIP_DIGITS];
new TableChipsLabel[T_MAX_POKER_TABLES + 1][T_MAX_CHAIRS_PER_TABLE][MAX_CHIP_DIGITS];
#define SetTableFirstTurn(%0,%1) TableData[(%0)][E_TABLE_FIRST_TURN]=%1
#define GetTableFirstTurn(%0) (TableData[(%0)][E_TABLE_FIRST_TURN])
#define GetPlayerSeat(%0) (PlayerData[(%0)][E_PLAYER_CURRENT_CHAIR_SLOT])
enum E_RAISE_CHOICES
{
E_RAISE_BET,
E_RAISE_RAISE,
E_RAISE_ALL_IN
};
enum e_PLAYER
{
bool: E_PLAYER_IS_PLAYING,
E_PLAYER_CURRENT_HANDLE,
E_PLAYER_CURRENT_BET,
E_PLAYER_CARD_VALUES[2],
E_PLAYER_TOTAL_CHIPS,
bool: E_PLAYER_CLICKED_TXT,
E_PLAYER_TIMER_ID,
bool:E_PLAYER_TIMER_STARTED,
bool:E_PLAYER_FOLDED,
//Textdraws
E_RAISE_CHOICES: E_PLAYER_RCHOICE,
PlayerText: E_PLAYER_COMMUNITY_CARDS_TXT[5], //5 cards
PlayerText: E_PLAYER_CARDS_TXT_1[T_MAX_CHAIRS_PER_TABLE],
PlayerText: E_PLAYER_CARDS_TXT_2[T_MAX_CHAIRS_PER_TABLE],
PlayerText: E_PLAYER_CHOICES_TXT[5],
PlayerText: E_PLAYER_INFO_TXT[6],
Text3D:E_PLAYER_3D_LABEL,
/*******/
E_PLAYER_CURRENT_CHAIR_SLOT,
E_PLAYER_CHAIR_ATTACH_INDEX_ID
};
new PlayerData[MAX_PLAYERS + 1][e_PLAYER];
stock SetPlayerClickedTxt(playerid, bool:choice)
{
PlayerData[playerid][E_PLAYER_CLICKED_TXT] = choice;
return 1;
}
#define GetPlayerClickedTxt(%0) (PlayerData[(%0)][E_PLAYER_CLICKED_TXT])
forward Poker_StartGame(handle, dealer);
stock SetLastToRaise(handle, playerid)
{
if(!IsValidTable(handle))
{
return 0;
}
if(!Iter_Contains(IT_PlayersInGame<handle>, playerid))
{
T_SendWarning("[SetLastToRaise] playerid %d is not playing in table ID %d", playerid, handle);
return 0;
}
TableData[handle][E_TABLE_LAST_TO_RAISE] = playerid;
TableData[handle][E_TABLE_LAST_TO_RAISE_SEAT] = GetPlayerSeat(playerid);
return 1;
}
stock ResetLabel(handle)
{
if(!IsValidTable(handle)) return 0;
new const buy_in = TableData[handle][E_TABLE_BUY_IN];
new const small_blind = TableData[handle][E_TABLE_SMALL_BLIND];
UpdateDynamic3DTextLabelTextEx(TableData[handle][E_TABLE_POT_LABEL], COLOR_GREY,
"Press ENTER To Play Poker\n{FFFFFF}%s Minimum\n%s / %s Blinds", cash_format(buy_in), cash_format(small_blind), cash_format(small_blind * 2));
return 1;
}
stock GetClosestTableForPlayer(playerid)
{
new const Float:infinity = Float:0x7F800000;
new Float:tmpdist = infinity;
new Float:Pos[3];
new handle = ITER_NONE;
GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
foreach(new i: IT_Tables)
{
new const Float:dist = VectorSize(Pos[0]-TableData[i][E_TABLE_POS_X], Pos[1]-TableData[i][E_TABLE_POS_Y], Pos[2]-TableData[i][E_TABLE_POS_Z]);
if(dist < tmpdist)
{
tmpdist = dist;
handle = i;
}
}
return handle;
}
stock bool:IsPlayerInRangeOfTable(playerid, handle, Float:range)
{
if(!IsValidTable(handle)) return false;
if(IsPlayerInRangeOfPoint(playerid, range, TableData[handle][E_TABLE_POS_X], TableData[handle][E_TABLE_POS_Y], TableData[handle][E_TABLE_POS_Z])) return true;
return false;
}
/******************************************************************************************
Actual functions
*******************************************************************************************/
stock CreatePokerTable(buy_in, small_blind, Float: X, Float: Y, Float: Z, seats, vworld, interior)
{
new handle = Iter_Free(IT_Tables);
if(handle == ITER_NONE)
{
static overflow;
printf("[POKER ERROR] Reached limit of %d blackjack tables, increase to %d to fix.", T_MAX_POKER_TABLES, T_MAX_POKER_TABLES + ( ++ overflow ) );
return ITER_NONE;
}
if(seats >= T_MAX_CHAIRS_PER_TABLE)
{
T_SendWarning("Max number of chairs per table has been reached. Increase T_MAX_CHAIRS_PER_TABLE.");
return ITER_NONE;
}
if(buy_in <= small_blind || buy_in <= 2 * small_blind)
{
T_SendWarning("Buy in cannot be less than the small blind or big blind.");
return ITER_NONE;
}
//TableData[T_MAX_POKER_TABLES] (dummy array)
memcpy(TableData[handle], TableData[T_MAX_POKER_TABLES], 0, sizeof(TableData[]) * 4, sizeof(TableData[]));
TableData[handle][E_TABLE_BUY_IN] = buy_in;
TableData[handle][E_TABLE_SMALL_BLIND] = small_blind;
TableData[handle][E_TABLE_BIG_BLIND] = small_blind * 2;
TableData[handle][E_TABLE_TOTAL_SEATS] = seats;
TableData[handle][E_TABLE_VIRTUAL_WORLD] = vworld;
TableData[handle][E_TABLE_INTERIOR] = interior;
/* Positions */
TableData[handle][E_TABLE_POS_X] = X;
TableData[handle][E_TABLE_POS_Y] = Y;
TableData[handle][E_TABLE_POS_Z] = Z;
/* Objects */
//Table
TableData[handle][E_TABLE_OBJECT_IDS][0] = CreateDynamicObject(2189, X, Y, Z + T_Z_OFFSET - 0.01, 0.0, 0.0, 0.0, vworld, interior, .priority = 9999);
TableData[handle][E_TABLE_OBJECT_IDS][1] = CreateDynamicObject(2111, X, Y, Z-0.01, 0.0, 0.0, 0.0, vworld, interior, .priority = 9999);
//Textures
if(buy_in >= 10000000) SetDynamicObjectMaterial(TableData[handle][E_TABLE_OBJECT_IDS][0], 0, 2189, "poker_tbl", "roulette_6_256", -52310);
else if (buy_in >= 1000000) SetDynamicObjectMaterial(TableData[handle][E_TABLE_OBJECT_IDS][0], 0, 2189, "poker_tbl", "roulette_6_256", -16737793);
else if (buy_in >= 100000) SetDynamicObjectMaterial(TableData[handle][E_TABLE_OBJECT_IDS][0], 0, 2189, "poker_tbl", "roulette_6_256", -65485);
//Chairs
TableData[handle][E_TABLE_POT_LABEL] = CreateDynamic3DTextLabel("-", -1, X+T_CHIP_OFFSET, Y+T_CHIP_OFFSET, Z+0.5, 10.0, .worldid = vworld, .interiorid = interior);
new Float:angle_step = floatdiv(360.0, float(seats));
for(new i = 0; i < seats; i++)
{
new const Float:unit_posx = floatcos(float(i) * angle_step, degrees);
new const Float:unit_posy = floatsin(float(i) * angle_step, degrees);
new const Float:o_posx = unit_posx * T_CHAIR_RANGE + X;
new const Float:o_posy = unit_posy * T_CHAIR_RANGE + Y;
new const Float:c_posz = Z + 0.36;
TableData[handle][E_TABLE_CHAIR_OBJECT_IDS][i] = CreateDynamicObject(T_CHAIR_MODEL, o_posx, o_posy, Z + 0.25, 0.0, 0.0, angle_step * float(i), vworld, interior, .priority = 9999);
TableData[handle][E_TABLE_SEAT_POS_X][i] = o_posx;
TableData[handle][E_TABLE_SEAT_POS_Y][i] = o_posy;
TableData[handle][E_TABLE_SEAT_POS_Z][i] = Z;
//Currently invisible
TableData[handle][E_TABLE_BET_LABELS][i] = CreateDynamic3DTextLabel("$9", T_BET_LABEL_COLOR & ~0xFF, 0.65 * floatcos(float(i) * angle_step, degrees) + X, 0.65 * floatsin(float(i) * angle_step, degrees) + Y, c_posz, 3.0 , .worldid = vworld, .interiorid = interior);
CreateChips(handle, i);
}
new const Float: or_z = Z + 0.284; //No chips are visible
new Float: a_s = floatdiv(360.0, float(MAX_CHIP_DIGITS));
//center chips
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new Float:rad = 0.11;
new rand = random(20);
new Float:px = rad * floatcos(float(j) * a_s, degrees) + X + T_CHIP_OFFSET;
new Float:py = rad * floatsin(float(j) * a_s, degrees) + Y + T_CHIP_OFFSET;
TableData[handle][E_TABLE_CHIPS][j] = CreateDynamicObject(1902, px, py, or_z + float(rand) * 0.008, 0.0, 0.0, 0.0, vworld, interior, .priority = 9999);
SetDynamicObjectMaterialText(TableData[handle][E_TABLE_CHIPS][j], 0, " ", .backcolor = colors[j]);
TableData[handle][E_TABLE_CHIPS_LABEL][j] = CreateDynamicObject(1905, px, py, or_z + float(rand) * 0.008 + 0.1 + 0.025, 0.0, 0.0, 0.0, vworld, interior, .priority = 9999);
SetDynamicObjectMaterialText(TableData[handle][E_TABLE_CHIPS_LABEL][j],
0, chip_text[j], 50, "Arial", 44, 1, colors[j], -1, 1 );
}
TableData[handle][E_TABLE_CURRENT_STATE] = STATE_IDLE;
Iter_Clear(IT_TableCardSet[handle]);
for(new i = 0; i < 52; i++)
Iter_Add(IT_TableCardSet[handle], i);
/* Sidepots */
Iter_Clear(IT_Sidepots[handle]);
for(new i = 0; i < T_MAX_CHAIRS_PER_TABLE; i++)
{
TableData[handle][E_TABLE_POT_CHIPS][i] = 0;
Iter_Clear(It_SidepotMembers[_IT[handle][i]]);
}
/*=================================================*/
Iter_Add(IT_Tables, handle);
ResetLabel(handle);
ResetChips(handle);
foreach(new i: Player)
{
if(IsPlayerInRangeOfPoint(i, 35.0, X, Y, Z))
{
Streamer_Update(i);
}
}
return handle;
}
stock SetPotChipsValue(handle, value)
{
new
dec_pos = 0,
Float: base_z = TableData[handle][E_TABLE_POS_Z] + 0.284
;
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new Float:c_x, Float:c_y, Float:c_z;
new objectid = TableData[handle][E_TABLE_CHIPS][j];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, base_z);
SetDynamicObjectPos(TableData[handle][E_TABLE_CHIPS_LABEL][j], c_x, c_y, base_z + 0.12);
}
for(new val = value; val != 0; val /= 10)
{
if(dec_pos >= MAX_CHIP_DIGITS) break;
new const digit = val % 10;
if(!digit)
{
dec_pos++;
continue;
}
new Float:c_x, Float:c_y, Float:c_z;
//Chip object
new objectid = TableData[handle][E_TABLE_CHIPS][dec_pos];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, base_z + 0.016 * (float(digit)));
//Chip label:
SetDynamicObjectPos(TableData[handle][E_TABLE_CHIPS_LABEL][dec_pos], c_x, c_y, 0.125 + base_z + 0.016 * (float(digit)));
dec_pos++;
}
return 1;
}
stock CreateChips(handle, i)
{
new Float:angle_step = floatdiv(360.0, float(TableData[handle][E_TABLE_TOTAL_SEATS]));
new const Float:c_posz = TableData[handle][E_TABLE_POS_Z] + 0.36;
new const Float: or_x = 0.70 * floatcos(float(i) * angle_step, degrees) + TableData[handle][E_TABLE_POS_X];
new const Float: or_y = 0.70 * floatsin(float(i) * angle_step, degrees) + TableData[handle][E_TABLE_POS_Y];
new const Float: or_z = c_posz - 0.076;
new Float: a_s = floatdiv(360.0, float(MAX_CHIP_DIGITS));
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new Float:rad = 0.11;
new rand = random(20);
TableChips[handle][i][j] = CreateDynamicObject(1902, rad * floatcos(float(j) * a_s, degrees) + or_x , rad * floatsin(float(j)* a_s, degrees) + or_y, or_z + float(rand) * 0.008, 0.0, 0.0, 0.0, TableData[handle][E_TABLE_VIRTUAL_WORLD], TableData[handle][E_TABLE_INTERIOR], .priority = 9999);
SetDynamicObjectMaterialText(TableChips[handle][i][j], 0, " ", .backcolor = colors[j]);
TableChipsLabel[handle][i][j] = CreateDynamicObject(1905, rad * floatcos(float(j) * a_s, degrees) + or_x , rad * floatsin(float(j)* a_s, degrees) + or_y, or_z + float(rand) * 0.008 + 0.1 + 0.025, 0.0, 0.0, 0.0, TableData[handle][E_TABLE_VIRTUAL_WORLD], TableData[handle][E_TABLE_INTERIOR], .priority = 9999);
SetDynamicObjectMaterialText(TableChipsLabel[handle][i][j], 0, chip_text[j], 50, "Arial", 44, 1, colors[j], -1, 1 );
}
// update users within premise
foreach(new playerid: Player) if(IsPlayerInRangeOfPoint(playerid, 35.0, TableData[handle][E_TABLE_POS_X], TableData[handle][E_TABLE_POS_Y], TableData[handle][E_TABLE_POS_Z])) {
Streamer_Update(playerid);
}
return 1;
}
stock ResetChips(handle)
{
new
Float: base_z = TableData[handle][E_TABLE_POS_Z] + 0.284
;
new seats = TableData[handle][E_TABLE_TOTAL_SEATS];
for(new i = 0; i < seats; i++) {
for(new j = 0; j < MAX_CHIP_DIGITS; j++) {
DestroyDynamicObject(TableChips[handle][i][j]), TableChips[handle][i][j] = -1;
DestroyDynamicObject(TableChipsLabel[handle][i][j]), TableChipsLabel[handle][i][j] = -1;
}
}
/*for(new i = 0; i < seats; i++)
{
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new rand = random(20);
new Float:c_x, Float:c_y, Float:c_z;
new objectid = TableChips[handle][i][j];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, (float(rand) * 0.008) + base_z);
SetDynamicObjectPos(TableChipsLabel[handle][i][j], c_x, c_y, (float(rand) * 0.008) + base_z + 0.125);
}
}*/
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new rand = random(20);
new Float:c_x, Float:c_y, Float:c_z;
new objectid = TableData[handle][E_TABLE_CHIPS][j];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, (float(rand) * 0.008) + base_z);
SetDynamicObjectPos(TableData[handle][E_TABLE_CHIPS_LABEL][j], c_x, c_y, (float(rand) * 0.008) + base_z + 0.125);
}
return 1;
}
stock SetChipsValue(handle, seat, value)
{
new
dec_pos = 0,
Float: base_z = TableData[handle][E_TABLE_POS_Z] + 0.284
;
if (!IsValidDynamicObject(TableChips[handle][seat][0])) CreateChips(handle, seat);
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
new Float:c_x, Float:c_y, Float:c_z;
new objectid = TableChips[handle][seat][j];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, base_z);
SetDynamicObjectPos(TableChipsLabel[handle][seat][j], c_x, c_y, base_z + 0.12);
}
for(new val = value; val != 0; val /= 10)
{
if(dec_pos >= MAX_CHIP_DIGITS) break;
new const digit = val % 10;
if(!digit)
{
dec_pos++;
continue;
}
new Float:c_x, Float:c_y, Float:c_z;
//Chip object
new objectid = TableChips[handle][seat][dec_pos];
GetDynamicObjectPos(objectid, c_x, c_y, c_z);
SetDynamicObjectPos(objectid, c_x, c_y, base_z + 0.016 * (float(digit)));
//Chip label:
SetDynamicObjectPos(TableChipsLabel[handle][seat][dec_pos], c_x, c_y, 0.125 + base_z + 0.016 * (float(digit)));
dec_pos++;
}
return 1;
}
stock DestroyPokertable( handle)
{
if(!Iter_Contains(IT_Tables, handle)) return 0;
if(Iter_Count(IT_PlayersTable<handle>))
{
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(Iter_Contains(IT_PlayersTable<handle>, i))
{
KickPlayerFromTable(i);
}
}
}
TableData[handle][E_TABLE_BUY_IN] = 0;
TableData[handle][E_TABLE_SMALL_BLIND] = 0;
TableData[handle][E_TABLE_BIG_BLIND] = 0;
DestroyDynamicObject(TableData[handle][E_TABLE_OBJECT_IDS][0]);
TableData[handle][E_TABLE_OBJECT_IDS][0] = INVALID_OBJECT_ID;
DestroyDynamicObject(TableData[handle][E_TABLE_OBJECT_IDS][1]);
TableData[handle][E_TABLE_OBJECT_IDS][1] = INVALID_OBJECT_ID;
KillTimer(TableData[handle][E_TABLE_TIMER_ID]);
TableData[handle][E_TABLE_TIMER_ID] = 0;
DestroyDynamic3DTextLabel(TableData[handle][E_TABLE_POT_LABEL]);
for(new i = 0; i < TableData[handle][E_TABLE_TOTAL_SEATS]; i++)
{
DestroyDynamicObject(TableData[handle][E_TABLE_CHAIR_OBJECT_IDS][i]);
TableData[handle][E_TABLE_CHAIR_OBJECT_IDS][i] = INVALID_OBJECT_ID;
TableData[handle][E_TABLE_SEAT_POS_X][i] = 0.0;
TableData[handle][E_TABLE_SEAT_POS_Y][i] = 0.0;
TableData[handle][E_TABLE_SEAT_POS_Z][i] = 0.0;
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
DestroyDynamicObject(TableChips[handle][i][j]), TableChips[handle][i][j] = -1;
DestroyDynamicObject(TableChipsLabel[handle][i][j]), TableChipsLabel[handle][i][j] = -1;
}
}
for(new j = 0; j < MAX_CHIP_DIGITS; j++)
{
DestroyDynamicObject(TableData[handle][E_TABLE_CHIPS][j]);
DestroyDynamicObject(TableData[handle][E_TABLE_CHIPS_LABEL][j]);
}
TableData[handle][E_TABLE_TOTAL_SEATS] = 0;
Iter_Remove(IT_Tables, handle);
Iter_Clear(IT_TableCardSet[handle]);
Iter_Clear(IT_PlayersInGame<handle>);
Iter_Clear(IT_PlayersTable<handle>);
return 1;
}
stock KickPlayerFromTable(playerid)
{
if(!GetPVarInt(playerid, "t_is_in_table")) return 0;
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(!Iter_Contains(IT_PlayersTable<handle>, playerid)) return 0;
new slot = PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT];
new attach_index = PlayerData[playerid][E_PLAYER_CHAIR_ATTACH_INDEX_ID];
RemovePlayerAttachedObject(playerid, attach_index);
ClearAnimations(playerid, 1);
TogglePlayerControllable(playerid, true);
new const Float:angle_step = floatdiv(360.0, TableData[handle][E_TABLE_TOTAL_SEATS]);
//Create the chair object again:
TableData[handle][E_TABLE_CHAIR_OBJECT_IDS][slot] = CreateDynamicObject(T_CHAIR_MODEL, TableData[handle][E_TABLE_SEAT_POS_X][slot], TableData[handle][E_TABLE_SEAT_POS_Y][slot], TableData[handle][E_TABLE_SEAT_POS_Z][slot], 0.0, 0.0, angle_step * float(slot), TableData[handle][E_TABLE_VIRTUAL_WORLD], TableData[handle][E_TABLE_INTERIOR], .priority = 9999);
Internal_RemoveChairSlot(handle, slot);
Iter_Remove(IT_PlayersTable<handle>, playerid);
if(Iter_Contains(IT_PlayersInGame<handle>, playerid)) Iter_Remove(IT_PlayersInGame<handle>, playerid);
SetPlayerPos(playerid, TableData[handle][E_TABLE_SEAT_POS_X][slot], TableData[handle][E_TABLE_SEAT_POS_Y][slot], TableData[handle][E_TABLE_SEAT_POS_Z][slot]);
SetCameraBehindPlayer(playerid);
// remove player chips
for(new j = 0; j < MAX_CHIP_DIGITS; j++) {
DestroyDynamicObject(TableChips[handle][slot][j]), TableChips[handle][slot][j] = -1;
DestroyDynamicObject(TableChipsLabel[handle][slot][j]), TableChipsLabel[handle][slot][j] = -1;
}
// hide textdraws
for(new i = 0; i < TableData[handle][E_TABLE_TOTAL_SEATS]; i++)
{
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i]);
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i]);
PlayerTextDrawDestroy(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i]);
PlayerTextDrawDestroy(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i]);
}
for(new i = 0; i < 5; i++){
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i]);
PlayerTextDrawDestroy(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i]);
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][i]);
PlayerTextDrawDestroy(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][i]);
}
for(new i = 0; i < 6; i++){
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][i]);
PlayerTextDrawDestroy(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][i]);
}
DestroyDynamic3DTextLabel(PlayerData[playerid][E_PLAYER_3D_LABEL]);
UpdateDynamic3DTextLabelText(TableData[handle][E_TABLE_BET_LABELS][slot], 0, " ");
GivePlayerCash(playerid, PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]);
if(PlayerData[playerid][E_PLAYER_TIMER_STARTED])
{
KillTimer(PlayerData[playerid][E_PLAYER_TIMER_ID]);
}
memcpy(PlayerData[playerid], PlayerData[MAX_PLAYERS], 0, sizeof(PlayerData[]) * 4, sizeof(PlayerData[]));
#if T_SAVE_PLAYER_POS == true
SetPlayerPos(playerid, GetPVarFloat(playerid, "t_temp_posX"), GetPVarFloat(playerid, "t_temp_posY"), GetPVarFloat(playerid, "t_temp_posZ"));
SetPlayerFacingAngle(playerid, GetPVarFloat(playerid, "t_temp_angle"));
#endif
SetPVarInt(playerid, "t_is_in_table", 0);
new Float:X, Float:Y, Float:Z;
X = TableData[handle][E_TABLE_POS_X];
Y = TableData[handle][E_TABLE_POS_Y];
Z = TableData[handle][E_TABLE_POS_Z];
foreach(new i: Player)
{
if(IsPlayerInRangeOfPoint(i, 35.0, X, Y, Z))
{
Streamer_Update(i);
}
}
if(!Iter_Count(IT_PlayersTable<handle>))
{
ResetLabel(handle);
ResetChips(handle);
}
return 1;
}
stock Player_CreateTextdraws(playerid)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
new Float:px;
new Float:py;
new Float:t_angle = 0.0;
new const seats = TableData[handle][E_TABLE_TOTAL_SEATS];
switch(seats)
{
case 2: t_angle = 120.0;
case 3: t_angle = 180.0;
case 4: t_angle = 210.0;
case 5: t_angle = 240.0;
case 6: t_angle = 240.0;
}
//Hole cards
new const Float:angle_step = floatdiv(360.0, float(seats));
for(new i = 0; i < TableData[handle][E_TABLE_TOTAL_SEATS]; i++)
{
px = (T_CARDS_RADIAL_DISTANCE * floatcos(float(i) * angle_step + t_angle, degrees)) + T_SCREEN_CENTER_X;
py = (T_CARDS_RADIAL_DISTANCE * floatsin(float(i) * angle_step + t_angle, degrees)) + T_SCREEN_CENTER_Y + 25.0;
PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i] = CreatePlayerTextDraw(playerid, px, py, "LD_POKE:cdback");
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i], T_CARD_X_SIZE, T_CARD_Y_SIZE);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i], 2);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i], 4);
PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i] = CreatePlayerTextDraw(playerid, px + T_TWO_CARD_DISTANCE, py, "LD_POKE:cdback");
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i], T_CARD_X_SIZE, T_CARD_Y_SIZE);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i], 2);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i], 4);
}
//Community cards
for(new i = 0; i < 5; i++)
{
px = i * T_TWO_CARD_DISTANCE + T_SCREEN_CENTER_X - 58.0;
py = T_SCREEN_CENTER_Y + 10.0;
PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i] = CreatePlayerTextDraw(playerid, px, py, "LD_POKE:cdback");
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i], T_CARD_X_SIZE, T_CARD_Y_SIZE);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i], 2);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i], 4);
}
//Buttons
PlayerData[playerid][E_PLAYER_CHOICES_TXT][0] = CreatePlayerTextDraw(playerid, 613.000122, 109.940643, "box");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 0.000000, 8.599979);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 0.000000, 57.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 177);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 0);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 0);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 169);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 1);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][0], 0);
PlayerData[playerid][E_PLAYER_CHOICES_TXT][1] = CreatePlayerTextDraw(playerid, 612.000122, 110.770355, "Options");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 0.182333, 1.039999);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 0.000000, 53.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], -1061109505);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 0);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 1);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][1], 0);
PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL] = CreatePlayerTextDraw(playerid, 615.999755, 131.511154, "Call");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 0.182333, 1.039999);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 10.000000, 49.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], -2139094785);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 0);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 1);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], 0);
//PlayerTextDrawSetSelectable(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], true);
PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE] = CreatePlayerTextDraw(playerid, 615.999755, 148.518554, "Raise");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 0.182333, 1.039999);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 10.000000, 49.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], -1378294017);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 0);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 1);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], 0);
PlayerTextDrawSetSelectable(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], true);
PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD] = CreatePlayerTextDraw(playerid, 615.999755, 165.525954, "Fold");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 0.182333, 1.039999);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 10.000000, 49.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], -1523963137);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 0);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 1);
PlayerTextDrawSetShadow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], 0);
PlayerTextDrawSetSelectable(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD], true);
//Info
PlayerData[playerid][E_PLAYER_INFO_TXT][0] = CreatePlayerTextDraw(playerid, 597.333435, 253.051803, "box");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 0.000000, 7.366664);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 0.000000, 84.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 193);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][0], 1);
PlayerData[playerid][E_PLAYER_INFO_TXT][1] = CreatePlayerTextDraw(playerid, 597.999694, 253.466537, "INFORMATION");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 0.265333, 1.093926);
PlayerTextDrawTextSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 0.000000, 84.000000);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 2);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], -1);
PlayerTextDrawUseBox(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 1);
PlayerTextDrawBoxColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], -2139062017);
PlayerTextDrawSetOutline(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 2);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][1], 1);
PlayerData[playerid][E_PLAYER_INFO_TXT][2] = CreatePlayerTextDraw(playerid, 559.666687, 268.814849, "Chips:_2934123");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], 0.166999, 1.023407);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], 1);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], -1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], 1);
PlayerData[playerid][E_PLAYER_INFO_TXT][3] = CreatePlayerTextDraw(playerid, 559.666687, 279.600128, "Pot:_23124");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], 0.166999, 1.023407);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], 1);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], -1); //10.785279
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], 1);
PlayerData[playerid][E_PLAYER_INFO_TXT][4] = CreatePlayerTextDraw(playerid, 559.666687, 290.385407, "Last_bet:_$4213");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], 0.166999, 1.023407);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], 1);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], -1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], 1);
PlayerData[playerid][E_PLAYER_INFO_TXT][5] = CreatePlayerTextDraw(playerid, 559.666687, 301.170686, "Your_bet:_$124");
PlayerTextDrawLetterSize(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], 0.166999, 1.023407);
PlayerTextDrawAlignment(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], 1);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], -1);
PlayerTextDrawBackgroundColor(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], 255);
PlayerTextDrawFont(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], 1);
PlayerTextDrawSetProportional(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], 1);
return 1;
}
hook OnPlayerConnect(playerid)
{
for(new i = 0; i < MAX_PLAYER_ATTACHED_OBJECTS; i++)
{
if(!IsPlayerAttachedObjectSlotUsed(playerid, i)) continue;
RemovePlayerAttachedObject(playerid, i);
}
return 0;
}
stock AddPlayerToTable(playerid, handle)
{
if(!Iter_Contains(IT_Tables, handle)) return 0;
if(GetPVarInt(playerid, "t_is_in_table")) return 0;
new slot = Internal_GetFreeChairSlot(handle);
if(slot == ITER_NONE)
{
SendPokerMessage(playerid, "There aren't currently any unnocupied seats in this table at the moment. You cannot enter it.");
return 0;
}
if(GetPlayerCash(playerid) < TableData[handle][E_TABLE_BUY_IN]) return SendPokerMessage(playerid, "You don't have enough money to access this table. Buy In: %s", cash_format(TableData[handle][E_TABLE_BUY_IN]));
new index = Player_GetUnusedAttachIndex(playerid);
if(index == cellmin)
{
SendPokerMessage(playerid, "You cannot access this table in this moment.");
return 0;
}
//Reset player data
memcpy(PlayerData[playerid], PlayerData[MAX_PLAYERS], 0, sizeof(PlayerData[]) * 4, sizeof(PlayerData[]));
//Information to set the player's position, angle, etc..
new Float:Pos[3];
Pos[0] = TableData[handle][E_TABLE_SEAT_POS_X][slot];
Pos[1] = TableData[handle][E_TABLE_SEAT_POS_Y][slot];
Pos[2] = TableData[handle][E_TABLE_SEAT_POS_Z][slot];
//new const Float:angle_step = floatdiv(360.0, float(TableData[handle][E_TABLE_TOTAL_SEATS]));
//new Float:facing_angle = (TableData[handle][E_TABLE_TOTAL_SEATS] == 2) ? (270 - angle_step * float(slot + 1)) : angle_step * float(slot + 1);
new Float:facing_angle = atan2(TableData[handle][E_TABLE_POS_Y] - Pos[1], TableData[handle][E_TABLE_POS_X] - Pos[0]) - 90.0;
DestroyDynamicObject(TableData[handle][E_TABLE_CHAIR_OBJECT_IDS][slot]);
SetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
SetPlayerFacingAngle(playerid, facing_angle);
SetPlayerAttachedObject(playerid, index, T_CHAIR_MODEL, 7, 0.061999, -0.046, 0.095999, 90.6, -171.8, -10.5, 1.0, 1.0, 1.0);
SetPlayerCameraPos(playerid, TableData[handle][E_TABLE_POS_X], TableData[handle][E_TABLE_POS_Y], TableData[handle][E_TABLE_POS_Z]+T_Z_CAMERA_OFFSET);
SetPlayerCameraLookAt(playerid, TableData[handle][E_TABLE_POS_X], TableData[handle][E_TABLE_POS_Y], TableData[handle][E_TABLE_POS_Z]);
ApplyAnimation(playerid, "INT_OFFICE", "OFF_Sit_Bored_Loop", 4.1, 1, 1, 1, 0, 0, 1);
new tstr[64];
format(tstr, sizeof(tstr), "%s\n* waiting next game *", ReturnPlayerName(playerid));
PlayerData[playerid][E_PLAYER_3D_LABEL] = CreateDynamic3DTextLabel(tstr, 0x808080FF, Pos[0], Pos[1], Pos[2], 15.0, INVALID_PLAYER_ID, INVALID_VEHICLE_ID, 0, GetPlayerVirtualWorld(playerid), GetPlayerInterior(playerid), -1, 5.0);
//Information that will be used later
PlayerData[playerid][E_PLAYER_CHAIR_ATTACH_INDEX_ID] = index;
PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT] = slot;
PlayerData[playerid][E_PLAYER_CURRENT_HANDLE] = handle;
Player_CreateTextdraws(playerid);
//Iterators
Internal_AddChairSlot(handle, slot);
Iter_Add(IT_PlayersTable<handle>, playerid);
TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot] = playerid;
GivePlayerCash(playerid, -TableData[handle][E_TABLE_BUY_IN]);
PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] = TableData[handle][E_TABLE_BUY_IN];
SendPokerMessage(playerid, "You've been charged %s as a result of joining in the table.", cash_format(TableData[handle][E_TABLE_BUY_IN]));
//Allow players to join a table where a game has already started but there are empty seats remaining (these players will be able to play once the current match finishes)
if(TableData[handle][E_TABLE_CURRENT_STATE] != STATE_BEGIN)
{
if(Iter_Count(IT_PlayersTable<handle>) == 2 && !TableData[handle][E_TABLE_LOADING_GAME]) //Minimum two seats
{
if(!TableData[handle][E_TABLE_STING_NEW_GAME])
{
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"There are currently two players in the table.");
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Any players interested in being part of this game have "#T_START_DELAY" seconds to join the table.");
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"The game will begin in "#T_START_DELAY" seconds...");
Iter_Clear(IT_PlayersInGame<handle>);
TableData[handle][E_TABLE_LOADING_GAME] = true;
SetTimerEx("Poker_StartGame", T_START_DELAY * 1000, false, "ii", handle, INVALID_PLAYER_ID);
}
}
}
else
{
SendPokerMessage(playerid, "You have entered this poker table but the game has already begun.");
SendPokerMessage(playerid, "You must wait until this match is finished to play!");
SendTableMessage(handle, "{25728B}- - Player %s has joined the table... - -", ReturnPlayerName(playerid));
}
foreach(new i: Player)
{
if(IsPlayerInRangeOfPoint(i, 35.0, Pos[0], Pos[1], Pos[2]))
{
Streamer_Update(i);
}
}
#if T_SAVE_PLAYER_POS == true
GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
SetPVarFloat(playerid, "t_temp_posX", Pos[0]);
SetPVarFloat(playerid, "t_temp_posY", Pos[1]);
SetPVarFloat(playerid, "t_temp_posZ", Pos[2]);
GetPlayerFacingAngle(playerid, Pos[0]);
SetPVarFloat(playerid, "t_temp_angle", Pos[0]);
#endif
SetPVarInt(playerid, "t_is_in_table", 1);
return 1;
}
stock SendTableMessage(handle, const format[], va_args<>)
{
new sstr[164];
va_format(sstr, sizeof (sstr), format, va_start<2>);
//strins(sstr, "{cc8e35}-|- {739e82} ", 0);
foreach(new playerid: IT_PlayersTable<handle>)
{
SendClientMessage(playerid, -1, sstr);
// printf( "[poker_%d] %s", handle, sstr);
}
return 1;
}
stock UpdateInfoTextdrawsForPlayer(playerid)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
new tstring[64];
format(tstring, sizeof(tstring), "~g~Chips:_~w~%s", cash_format(PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]));
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][2], tstring);
format(tstring, sizeof(tstring), "~y~Pot:_~w~%s", cash_format(TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT]));
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][3], tstring);
format(tstring, sizeof(tstring), "~r~Last_bet:_~w~%s", cash_format(TableData[handle][E_TABLE_LAST_BET]));
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][4], tstring);
format(tstring, sizeof(tstring), "~r~Your_bet:_~w~%s", cash_format(PlayerData[playerid][E_PLAYER_CURRENT_BET]));
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][5], tstring);
return 1;
}
public Poker_StartGame(handle, dealer)
{
TableData[handle][E_TABLE_STING_NEW_GAME] = false;
if(Iter_Count(IT_PlayersTable<handle>) < 2)
{
TableData[handle][E_TABLE_LOADING_GAME] = false;
return 0;
}
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(!Iter_Contains(IT_PlayersTable<handle>, i)) continue;
if(!PlayerData[i][E_PLAYER_TOTAL_CHIPS])
{
SendPokerMessage(i, "You don't have any chips left.");
SendPokerMessage(i, "You may join the table again and pay the buy-in fee to play once again!");
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been kicked out of the table. [Reason: Ran out of chips]", ReturnPlayerName(i));
KickPlayerFromTable(i);
ShowPlayerDialog(i, -1, DIALOG_STYLE_INPUT, " ", " ", " ", " ");
}
}
if(Iter_Count(IT_PlayersTable<handle>) < 2)
{
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"There aren't enough players to start a game");
TableData[handle][E_TABLE_LOADING_GAME] = false;
return 0;
}
for (new i = 0; i < 5; i ++) {
TableData[handle][E_TABLE_COM_CARDS_VALUES][i] = ITER_NONE;
}
TableData[handle][E_TABLE_LOADING_GAME] = true;
//Add these two players to (currently playing iterator)
Iter_Clear(IT_PlayersInGame<handle>);
Iter_Clear(IT_PlayersAllIn<handle>);
foreach(new i: IT_PlayersTable<handle>)
{
Player_Clearchat(i);
Iter_Add(IT_PlayersInGame<handle>, i);
PlayerPlaySound(i, 1058, 0.0, 0.0, 0.0);
PlayerData[i][E_PLAYER_IS_PLAYING] = true;
ApplyAnimation(i, "INT_OFFICE", "OFF_Sit_Bored_Loop", 4.1, 1, 1, 1, 0, 0, 1);
}
TableData[handle][E_TABLE_CURRENT_STATE] = STATE_BEGIN; //Will prevent players from leaving the table
foreach(new playerid: IT_PlayersInGame<handle>)
{
for(new i = 0; i < TableData[handle][E_TABLE_TOTAL_SEATS]; i++)
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i], "LD_POKE:cdback");
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i], "LD_POKE:cdback");
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i]);
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i]);
}
for(new i = 0; i < 5; i++){
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_COMMUNITY_CARDS_TXT][i]);
}
for(new i = 0; i < 5; i++){
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][i]);
}
for(new i = 0; i < 6; i++){
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][i]);
}
}
TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT] = 0;
dealer = GetTurnAfterDealer(handle);
//Select BB, SB in terms of a random dealer
dealer = (dealer == INVALID_PLAYER_ID) ? Iter_Random(IT_PlayersInGame<handle>) : dealer;
new count = Iter_Count(IT_PlayersInGame<handle>);
if(count < 2)
{
return -1;
}
else if(count == 2)
{
TableData[handle][E_TABLE_PLAYER_DEALER_ID] = dealer;
TableData[handle][E_TABLE_DEALER_SEAT] = PlayerData[dealer][E_PLAYER_CURRENT_CHAIR_SLOT];
TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID] = dealer;
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been chosen to be the dealer and big blind in this first stage of the game!", ReturnPlayerName(dealer));
UpdateDynamic3DTextLabelTextEx(PlayerData[dealer][E_PLAYER_3D_LABEL], -1, "{7AC72E}%s\n{FD4102}Big Blind + Dealer", ReturnPlayerName(dealer));
//small blind..
new next_turn = GetTurnAfterPlayer(handle, dealer);
UpdateDynamic3DTextLabelTextEx(PlayerData[next_turn][E_PLAYER_3D_LABEL], -1, "{7AC72E}%s\n{FD4102}Small Blind", ReturnPlayerName(next_turn));
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been chosen to be the small blind in this first stage of the game!", ReturnPlayerName(next_turn));
TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID] = next_turn;
}
else
{
//Dealer
UpdateDynamic3DTextLabelTextEx(PlayerData[dealer][E_PLAYER_3D_LABEL], -1, "{7AC72E}%s\n{FD4102}Dealer", ReturnPlayerName(dealer));
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been chosen to be the dealer in this first stage of the game!", ReturnPlayerName(dealer));
TableData[handle][E_TABLE_PLAYER_DEALER_ID] = dealer;
TableData[handle][E_TABLE_DEALER_SEAT] = PlayerData[dealer][E_PLAYER_CURRENT_CHAIR_SLOT];
//Big blind
new next_player = GetTurnAfterPlayer(handle, dealer);
UpdateDynamic3DTextLabelTextEx(PlayerData[next_player][E_PLAYER_3D_LABEL], -1, "{7AC72E}%s\n{FD4102}Small Blind", ReturnPlayerName(next_player));
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been chosen to be the Small Blind in this first stage of the game!", ReturnPlayerName(next_player));
TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID] = next_player;
//Small blind
next_player = GetTurnAfterPlayer(handle, next_player);
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been chosen to be the Big Blind in this first stage of the game!", ReturnPlayerName(next_player));
UpdateDynamic3DTextLabelTextEx(PlayerData[next_player][E_PLAYER_3D_LABEL], -1, "{7AC72E}%s\n{FD4102}Big Blind", ReturnPlayerName(next_player));
TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID] = next_player;
}
foreach(new playerid: IT_PlayersInGame<handle>) //loop through the players already in the table
{
if(playerid != TableData[handle][E_TABLE_PLAYER_DEALER_ID] && playerid != TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID] && playerid != TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID])
{
UpdateDynamic3DTextLabelTextEx(PlayerData[playerid][E_PLAYER_3D_LABEL], 0x7AC72EFF, "%s", ReturnPlayerName(playerid));
}
for(new k = 0; k < 6; k++)
{
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_INFO_TXT][k]);
}
UpdateInfoTextdrawsForPlayer(playerid);
Streamer_Update(playerid);
}
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Dealer is shuffling the pack of cards. Cards will be handed out in two seconds...!");
//If everything executes without stop, it wouldn't look that nice for me, so a timer comes handy..
SetTimerEx("Poker_DealCards", 2000, false, "i", handle);
return 1;
}
forward Poker_KickPlayers(handle);
public Poker_KickPlayers(handle)
{
for(new i = 0; i < MAX_PLAYERS; i++)
{
if(!Iter_Contains(IT_PlayersTable<handle>, i)) continue;
if(!PlayerData[i][E_PLAYER_TOTAL_CHIPS])
{
if(GetPlayerCash(i) < TableData[handle][E_TABLE_BUY_IN])
{
SendPokerMessage(i, "You don't have any chips left.");
SendPokerMessage(i, "You may join the table again and pay the buy-in fee to play once again!");
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been kicked out of the table. [Reason: Ran out of chips]", ReturnPlayerName(i));
KickPlayerFromTable(i);
}
else
{
ShowPlayerDialog(i, DIALOG_BUY_IN, DIALOG_STYLE_MSGBOX, "Buy-In", ""COL_WHITE"You've ran out of chips. Do you want to pay the buy-in fee again to continue playing?", "Yes", "No");
}
}
}
//Iter_Clear(IT_PlayersInGame<handle>);
return 1;
}
stock StartNewPokerGame(handle, time)
{
for (new i = 0; i < 5; i ++) {
TableData[handle][E_TABLE_COM_CARDS_VALUES][i] = ITER_NONE;
}
foreach(new i: IT_PlayersInGame<handle>) {
HidePlayerChoices(i);
}
//This will allow players to leave before the new game begins.
TableData[handle][E_TABLE_CURRENT_STATE] = STATE_IDLE;
TableData[handle][E_TABLE_STING_NEW_GAME] = true;
TableData[handle][E_TABLE_FIRST_TURN] = INVALID_PLAYER_ID;
TableData[handle][E_TABLE_CHECK_FIRST] = false;
TableData[handle][E_TABLE_CURRENT_TURN] = INVALID_PLAYER_ID;
TableData[handle][E_TABLE_LOADING_GAME] = false;
ResetLabel(handle);
Iter_Clear(IT_TableCardSet[handle]);
for(new i = 0; i < 52; i++)
Iter_Add(IT_TableCardSet[handle], i);
//Never change this order
Iter_Clear(IT_PlayersAllIn<handle>);
Iter_Clear(IT_Sidepots[handle]);
SetTimerEx("Poker_KickPlayers", 1000 * (time - 5), false, "i", handle);
for(new i = 0; i < T_MAX_CHAIRS_PER_TABLE; i++)
{
TableData[handle][E_TABLE_POT_CHIPS][i] = 0;
Iter_Clear(It_SidepotMembers[_IT[handle][i]]);
}
Iter_Clear(IT_PlayersInGame<handle>);
if(Iter_Count(IT_PlayersTable<handle>) >= 2)
{
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Starting a new game in %d seconds...", time);
SetTimerEx("Poker_StartGame", 1000 * time, false, "ii", handle, INVALID_PLAYER_ID);
}
else
{
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"There are not enough players to start a new game!");
}
return 1;
}
stock GetTurnAfterSeat(handle, seat)
{
seat -= 1;
new target = INVALID_PLAYER_ID;
for(new i = 0, j = TableData[handle][E_TABLE_TOTAL_SEATS]; i < j; i++)
{
if(seat < 0) seat = TableData[handle][E_TABLE_TOTAL_SEATS] - 1;
target = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][seat];
if(Iter_Contains(IT_PlayersInGame<handle>, target) && !Iter_Contains(IT_PlayersAllIn<handle>, target))
{
break;
}
seat--;
}
if(seat < 0 || seat >= T_MAX_CHAIRS_PER_TABLE) return INVALID_PLAYER_ID;
return target;
}
stock GetTurnAfterDealer(handle)
{
new seat = TableData[handle][E_TABLE_DEALER_SEAT];
new target = GetTurnAfterSeat(handle, seat);
if(target == INVALID_PLAYER_ID)
{
printf("Something went wrong while executing GetTurnAfterPlayer");
return -1;
}
return target;
}
stock GetTurnAfterPlayer(handle, playerid)
{
/*Finds the ID of the player to the left of 'playerid', skips players not currently playing or empty seats.
The number of iterations it performs is the number of seats in between both players
Worst case would be the number of seats O(n), n = number of seats, O(1) would be the best case (players next to each other)
*/
new slot = PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT] - 1;
if(slot < 0) slot = TableData[handle][E_TABLE_TOTAL_SEATS] - 1;
for(new i = 0, j = TableData[handle][E_TABLE_TOTAL_SEATS]; i < j; i++)
{
if(slot < 0) slot = TableData[handle][E_TABLE_TOTAL_SEATS] - 1;
new const target = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot];
if(Iter_Contains(IT_PlayersInGame<handle>, target) && !Iter_Contains(IT_PlayersAllIn<handle>, target))
{
break;
}
slot--;
}
if(slot < 0 || slot >= T_MAX_CHAIRS_PER_TABLE) return INVALID_PLAYER_ID;
new target = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot];
if(!Iter_Contains(IT_PlayersInGame<handle>, target)) return INVALID_PLAYER_ID;
new next_player = INVALID_PLAYER_ID;
next_player = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot];
return next_player;
}
stock GetTurnAfterPlayerEx(handle, playerid)
{
/*Finds the ID of the player to the left of 'playerid', skips players not currently playing or empty seats.
The number of iterations it performs is the number of seats in between both players
Worst case would be the number of seats O(n), n = number of seats, O(1) would be the best case (players next to each other)
*/
new slot = PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT] - 1;
if(slot < 0) slot = TableData[handle][E_TABLE_TOTAL_SEATS] - 1;
for(new i = 0, j = TableData[handle][E_TABLE_TOTAL_SEATS]; i < j; i++)
{
if(slot < 0) slot = TableData[handle][E_TABLE_TOTAL_SEATS] - 1;
new const target = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot];
if(Iter_Contains(IT_PlayersInGame<handle>, target))
{
break;
}
slot--;
}
new next_player = INVALID_PLAYER_ID;
next_player = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][slot];
return next_player;
}
stock Internal_GetFreeChairSlot(handle)
{
//This goes in reverse (left)
new seats = TableData[handle][E_TABLE_TOTAL_SEATS];
for(new i = seats; i--; )
{
if(!TableData[handle][E_TABLE_IS_SEAT_TAKEN][i])
{
return i;
}
}
return ITER_NONE;
}
stock Internal_AddChairSlot(handle, slot)
{
TableData[handle][E_TABLE_IS_SEAT_TAKEN][slot] = true;
return 1;
}
stock Internal_RemoveChairSlot(handle, slot)
{
TableData[handle][E_TABLE_IS_SEAT_TAKEN][slot] = false;
return 1;
}
stock RemoveChipsFromPlayer( forplayer, amount)
{
PlayerData[forplayer][E_PLAYER_TOTAL_CHIPS] -= amount;
return 1;
}
stock AbortGame(handle)
{
if(TableData[handle][E_TABLE_CURRENT_STATE] != STATE_BEGIN) return 0;
//Could have used Iter_SafeRemove, prefer not to
for(new playerid = 0; playerid < MAX_PLAYERS; playerid++)
{
if(Iter_Contains(IT_PlayersTable<handle>, playerid))
{
KickPlayerFromTable(playerid);
}
CancelSelectTextDraw(playerid);
}
for(new i = 0; i < 5; i++)
{
TableData[handle][E_TABLE_COM_CARDS_VALUES][i] = ITER_NONE;
}
//This will allow players to leave before the new game begins.
TableData[handle][E_TABLE_CURRENT_STATE] = STATE_IDLE;
TableData[handle][E_TABLE_STING_NEW_GAME] = false;
TableData[handle][E_TABLE_FIRST_TURN] = INVALID_PLAYER_ID;
TableData[handle][E_TABLE_CHECK_FIRST] = false;
TableData[handle][E_TABLE_LOADING_GAME] = false;
ResetLabel(handle);
Iter_Clear(IT_TableCardSet[handle]);
//Never change this order
Iter_Clear(IT_PlayersAllIn<handle>);
Iter_Clear(IT_Sidepots[handle]);
for(new i = 0; i < T_MAX_CHAIRS_PER_TABLE; i++)
{
TableData[handle][E_TABLE_POT_CHIPS][i] = 0;
Iter_Clear(It_SidepotMembers[_IT[handle][i]]);
}
for(new i = 0; i < 52; i++)
Iter_Add(IT_TableCardSet[handle], i);
TableData[handle][E_TABLE_CURRENT_STATE] = STATE_IDLE;
return 1;
}
forward Poker_DealCards(handle);
public Poker_DealCards(handle)
{
foreach(new playerid: IT_PlayersTable<handle>) //loop through the players already in the table
{
if(Iter_Contains(IT_PlayersInGame<handle>, playerid))
{
new seat = TableRotCorrections[TableData[PlayerData[playerid][E_PLAYER_CURRENT_HANDLE]][E_TABLE_TOTAL_SEATS]][ PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT]];
new card1 = Iter_Random(IT_TableCardSet[handle]);
Iter_Remove(IT_TableCardSet[handle], card1);
new card2 = Iter_Random(IT_TableCardSet[handle]);
Iter_Remove(IT_TableCardSet[handle], card2);
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][seat], CardData[card1][E_CARD_TEXTDRAW]);
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][seat], CardData[card2][E_CARD_TEXTDRAW]);
PlayerData[playerid][E_PLAYER_CARD_VALUES][0] = card1;
PlayerData[playerid][E_PLAYER_CARD_VALUES][1] = card2;
foreach(new p: IT_PlayersInGame<handle>)
{
seat = TableRotCorrections[TableData[PlayerData[p][E_PLAYER_CURRENT_HANDLE]][E_TABLE_TOTAL_SEATS]][ PlayerData[p][E_PLAYER_CURRENT_CHAIR_SLOT]];
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][seat]);
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][seat]);
PlayerPlaySound(playerid, 1145, 0.0, 0.0, 0.0 );
}
PlayerData[playerid][E_PLAYER_CURRENT_BET] = 0;
}
else
{
for(new i = 0; i < TableData[handle][E_TABLE_TOTAL_SEATS]; i++)
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i], "LD_POKE:cdback");
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i], "LD_POKE:cdback");
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_1][i]);
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_CARDS_TXT_2][i]);
}
}
}
//Set variables
TableData[handle][E_TABLE_CURRENT_ROUND] = ROUND_PRE_FLOP;
new big_blind = TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID];
new small_blind = TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID];
new bool: b_big_blind = (PlayerData[big_blind][E_PLAYER_TOTAL_CHIPS] > TableData[handle][E_TABLE_BIG_BLIND]);
new bool: b_small_blind = (PlayerData[small_blind][E_PLAYER_TOTAL_CHIPS] > TableData[handle][E_TABLE_SMALL_BLIND]);
if(b_big_blind && b_small_blind)
{
PlayerData[big_blind][E_PLAYER_CURRENT_BET] = TableData[handle][E_TABLE_BIG_BLIND];
PlayerData[small_blind][E_PLAYER_CURRENT_BET] = TableData[handle][E_TABLE_SMALL_BLIND];
SendTableMessage(handle, "{2DD9A9} * * %s posts a small blind of %s.. * *", ReturnPlayerName(TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID]), cash_format(TableData[handle][E_TABLE_SMALL_BLIND]));
SendTableMessage(handle, "{2DD9A9} * * %s posts a big blind of %s.. * *", ReturnPlayerName(TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID]), cash_format(TableData[handle][E_TABLE_BIG_BLIND]));
new next_turn = GetTurnAfterPlayer(handle, TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID]);
TableData[handle][E_TABLE_LAST_BET] = TableData[handle][E_TABLE_BIG_BLIND];
SetLastToRaise(handle, next_turn);
RemoveChipsFromPlayer( big_blind, TableData[handle][E_TABLE_BIG_BLIND]);
RemoveChipsFromPlayer( small_blind, TableData[handle][E_TABLE_SMALL_BLIND]);
TableData[handle][E_TABLE_FIRST_TURN] = next_turn;
TableData[handle][E_TABLE_CHECK_FIRST] = true;
SendTurnMessage(handle, next_turn);
UpdateTable(handle);
}
else
{
new next_turn = GetTurnAfterPlayer(handle, TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID]);
SetLastToRaise(handle, next_turn);
if(!b_small_blind)
{
ForcePlayerAllIn(small_blind, handle, false);
}
else
{
SendTableMessage(handle, "{2DD9A9} * * %s posts a small blind of %s.. * *", ReturnPlayerName(TableData[handle][E_TABLE_PLAYER_SMALL_BLIND_ID]), cash_format(TableData[handle][E_TABLE_SMALL_BLIND]));
RemoveChipsFromPlayer( small_blind, TableData[handle][E_TABLE_SMALL_BLIND]);
PlayerData[small_blind][E_PLAYER_CURRENT_BET] = TableData[handle][E_TABLE_SMALL_BLIND];
}
if(!b_big_blind)
{
TableData[handle][E_TABLE_LAST_TO_RAISE] = big_blind;
TableData[handle][E_TABLE_LAST_BET] = PlayerData[big_blind][E_PLAYER_TOTAL_CHIPS];
ForcePlayerAllIn(big_blind, handle, false);
if(!b_small_blind && GetTurnAfterPlayerEx(handle, next_turn) == small_blind)
{
SetLastToRaise(handle, small_blind);
}
}
else
{
SendTableMessage(handle, "{2DD9A9} * * %s posts a big blind of %s.. * *", ReturnPlayerName(TableData[handle][E_TABLE_PLAYER_BIG_BLIND_ID]), cash_format(TableData[handle][E_TABLE_BIG_BLIND]));
RemoveChipsFromPlayer( big_blind, TableData[handle][E_TABLE_BIG_BLIND]);
PlayerData[big_blind][E_PLAYER_CURRENT_BET] = TableData[handle][E_TABLE_BIG_BLIND];
TableData[handle][E_TABLE_LAST_BET] = TableData[handle][E_TABLE_BIG_BLIND];
}
if(Iter_Contains(IT_PlayersAllIn<handle>, next_turn))
{
CheckPotAndNextTurn(next_turn, handle);
}
else
{
SendTurnMessage(handle, next_turn);
}
UpdateTable(handle);
}
return 1;
}
static stock UpdateTable(handle)
{
foreach(new playerid: IT_PlayersInGame<handle>)
{
UpdateInfoTextdrawsForPlayer(playerid);
new const seat = PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT];
new str[128 ];
format(str, sizeof(str), "{34c5db}Chips: {db8d34}%s\n{db3a34}Last bet: {db8d34}%s", cash_format(PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]), cash_format(PlayerData[playerid][E_PLAYER_CURRENT_BET]));
UpdateDynamic3DTextLabelText(TableData[handle][E_TABLE_BET_LABELS][seat], T_BET_LABEL_COLOR, str);
SetChipsValue(handle, PlayerData[playerid][E_PLAYER_CURRENT_CHAIR_SLOT], PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]);
}
new str[256];
new tmp[10];
format(str, sizeof(str), "{59cdff}Main Pot: {ff9059}%s\n", cash_format(TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT]));
SetPotChipsValue(handle, TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT]);
if(Iter_Count(IT_Sidepots[handle] > 1))
{
strcat(str, "{008000}Side Pot:\n{008080}");
foreach(new i: IT_Sidepots[handle])
{
if(i == MAIN_POT) continue;
format(tmp, sizeof(tmp), "%s\n", cash_format(TableData[handle][E_TABLE_POT_CHIPS][i]));
strcat(str, tmp);
}
}
str[strlen(str)-1] = EOS;
UpdateDynamic3DTextLabelText(TableData[handle][E_TABLE_POT_LABEL], T_BET_LABEL_COLOR, str);
return 1;
}
static stock ShowChoicesToPlayer(playerid)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
//Call or check
if(TableData[handle][E_TABLE_LAST_BET] == PlayerData[playerid][E_PLAYER_CURRENT_BET]) //check
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], "Check");
}
else //call
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], "Call");
}
//Bet, raise or all in
if(TableData[handle][E_TABLE_LAST_BET] == 0)
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], "Bet");
PlayerData[playerid][E_PLAYER_RCHOICE] = E_RAISE_BET;
}
else if(PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] > TableData[handle][E_TABLE_LAST_BET] + PlayerData[playerid][E_PLAYER_CURRENT_BET])
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], "Raise");
PlayerData[playerid][E_PLAYER_RCHOICE] = E_RAISE_RAISE;
}
else //player doesn't have enough money, only option is to go all in
{
PlayerTextDrawSetString(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE], "All In");
PlayerData[playerid][E_PLAYER_RCHOICE] = E_RAISE_ALL_IN;
}
if(PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] + PlayerData[playerid][E_PLAYER_CURRENT_BET] <= TableData[handle][E_TABLE_LAST_BET])
{
//all in and fold are the only options available
PlayerTextDrawSetSelectable(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], false);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], COLOR_RED);
}
else
{
PlayerTextDrawSetSelectable(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], true);
PlayerTextDrawColor(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL], -1);
}
for(new i = 0; i < 5; i++)
{
PlayerTextDrawShow(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][i]);
}
SelectTextDraw(playerid, 0x00FF00FF);
return 1;
}
static stock HidePlayerChoices(playerid)
{
for(new i = 0; i < 5; i++)
{
PlayerTextDrawHide(playerid, PlayerData[playerid][E_PLAYER_CHOICES_TXT][i]);
}
CancelSelectTextDraw(playerid);
return 1;
}
static stock SendTurnMessage(handle, playerid)
{
SetPlayerClickedTxt(playerid, false);
SendTableMessage(handle, "{008080}It's %s{008080}'s turn...", ReturnPlayerName(playerid));
SendPokerMessage(playerid, "It's your turn. You have "#T_MAX_WAIT_TIME" seconds to make a decision.");
TableData[handle][E_TABLE_CURRENT_TURN] = playerid;
PlayerData[playerid][E_PLAYER_TIMER_STARTED] = true;
PlayerData[playerid][E_PLAYER_TIMER_ID] = SetTimerEx("Timer_FoldPlayer", T_MAX_WAIT_TIME * 1000, false, "ii", handle, playerid);
ShowChoicesToPlayer(playerid);
return 1;
}
stock KillPlayerTurnTimer(playerid, bool: callback = false)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(!IsValidTable(handle))
{
//T_SendWarning("[KillPlayerTurnTimer] Invalid handle passed (%d) for playerid: %d", handle, playerid);
return 0;
}
if(!Iter_Contains(IT_PlayersInGame<handle>, playerid))
{
//T_SendWarning("[KillPlayerTurnTimer] Invalid playerid passed: %d, handle: %d, player is not in the game.", playerid, handle);
return 0;
}
if(!PlayerData[playerid][E_PLAYER_TIMER_STARTED]) return 0;
PlayerData[playerid][E_PLAYER_TIMER_STARTED] = false;
if(!callback)
KillTimer(PlayerData[playerid][E_PLAYER_TIMER_ID]);
return 1;
}
forward Timer_FoldPlayer(handle, playerid);
public Timer_FoldPlayer(handle, playerid)
{
if(TableData[handle][E_TABLE_CURRENT_TURN] == playerid && PlayerData[playerid][E_PLAYER_TIMER_STARTED])
{
TableData[handle][E_TABLE_CURRENT_TURN] = INVALID_PLAYER_ID;
HidePlayerChoices(playerid);
ShowPlayerDialog(playerid, -1, DIALOG_STYLE_INPUT, " ", " ", " ", " ");
KillPlayerTurnTimer(playerid, true);
if(!FoldPlayer(handle, playerid))
CheckPotAndNextTurn(playerid, handle);
}
return 1;
}
/*
GetTurnAfterPlayer(handle, playerid); //Returns the playerid of the next turn (skips players that have gone all in)
GetTurnAfterPlayerEx(handle, playerid); //Returns the playerid of the next turn (does not skip players that went all in)
*/
forward CheckRounds(handle, bool: start_showdown);
public CheckRounds(handle, bool: start_showdown)
{
new next_turn = INVALID_PLAYER_ID;
//we can proceed to another round
switch(TableData[handle][E_TABLE_CURRENT_ROUND])
{
case ROUND_PRE_FLOP:
{
//Display 3 cards now
TableData[handle][E_TABLE_CURRENT_ROUND] = ROUND_FLOP;
for(new i = 0; i < 3; i++)
{
new card = Iter_Random(IT_TableCardSet[handle]);
Iter_Remove(IT_TableCardSet[handle], card);
TableData[handle][E_TABLE_COM_CARDS_VALUES][i] = card;
foreach(new k: IT_PlayersTable<handle>)
{
//for(new j = 0; j < 15; j++) SendTableMessage(k, " ");
PlayerTextDrawSetString(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][i], CardData[card][E_CARD_TEXTDRAW]);
PlayerTextDrawShow(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][i]);
PlayerData[k][E_PLAYER_CURRENT_BET] = 0;
PlayerPlaySound(k, 1145, 0.0, 0.0, 0.0 );
}
}
SendTableMessage(handle, "{D07035}======================================================================================");
SendTableMessage(handle, "{D07035} The Flop ");
SendTableMessage(handle, "{D07035}======================================================================================");
TableData[handle][E_TABLE_LAST_BET] = 0;
if(start_showdown)
{
SetTimerEx("CheckRounds", 2000, false, "ib", handle, true);
}
else
{
//Player next to the dealer
next_turn = GetTurnAfterDealer(handle);
SetLastToRaise(handle, next_turn);
//player next to the dealer is the next turn
SendTurnMessage(handle, next_turn);
}
}
case ROUND_FLOP:
{
//Display 1 card
TableData[handle][E_TABLE_CURRENT_ROUND] = ROUND_TURN;
new card = Iter_Random(IT_TableCardSet[handle]);
Iter_Remove(IT_TableCardSet[handle], card);
TableData[handle][E_TABLE_COM_CARDS_VALUES][3] = card;
foreach(new k: IT_PlayersTable<handle>)
{
//for(new j = 0; j < 15; j++) SendTableMessage(k, " ");
PlayerData[k][E_PLAYER_CURRENT_BET] = 0;
PlayerTextDrawSetString(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][3], CardData[card][E_CARD_TEXTDRAW]);
PlayerTextDrawShow(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][3]);
PlayerPlaySound(k, 1145, 0.0, 0.0, 0.0 );
}
TableData[handle][E_TABLE_LAST_BET] = 0;
SendTableMessage(handle, "{D07035}======================================================================================");
SendTableMessage(handle, "{D07035} The Turn ");
SendTableMessage(handle, "{D07035}======================================================================================");
if(start_showdown)
{
SetTimerEx("CheckRounds", 2000, false, "ib", handle, true);
}
else
{
//Player next to the dealer
next_turn = GetTurnAfterDealer(handle);
SetLastToRaise(handle, next_turn);
//player next to the dealer is the next turn
SendTurnMessage(handle, next_turn);
}
}
case ROUND_TURN:
{
//Display 1 more card
TableData[handle][E_TABLE_CURRENT_ROUND] = ROUND_RIVER;
new card = Iter_Random(IT_TableCardSet[handle]);
Iter_Remove(IT_TableCardSet[handle], card);
TableData[handle][E_TABLE_COM_CARDS_VALUES][4] = card;
foreach(new k: IT_PlayersTable<handle>)
{
//for(new j = 0; j < 15; j++) SendTableMessage(k, " ");
PlayerData[k][E_PLAYER_CURRENT_BET] = 0;
PlayerTextDrawSetString(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][4], CardData[card][E_CARD_TEXTDRAW]);
PlayerTextDrawShow(k, PlayerData[k][E_PLAYER_COMMUNITY_CARDS_TXT][4]);
PlayerPlaySound(k, 1145, 0.0, 0.0, 0.0 );
}
TableData[handle][E_TABLE_LAST_BET] = 0;
SendTableMessage(handle, "{D07035}======================================================================================");
SendTableMessage(handle, "{D07035} The River ");
SendTableMessage(handle, "{D07035}======================================================================================");
//SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"%s, %s, %s", CardData[TableData[handle][T_COM_CARDS_VALUES][0]][E_CARD_NAME], CardData[TableData[handle][T_COM_CARDS_VALUES][1]][E_CARD_NAME], CardData[TableData[handle][T_COM_CARDS_VALUES][2]][E_CARD_NAME]);
if(start_showdown)
{
SetTimerEx("CheckRounds", 2000, false, "ib", handle, false);
}
else
{
//Player next to the dealer
next_turn = GetTurnAfterDealer(handle);
SetLastToRaise(handle, next_turn);
//player next to the dealer is the next turn
SendTurnMessage(handle, next_turn);
}
}
case ROUND_RIVER:
{
CheckShowdown(handle);
//Start a new game
StartNewPokerGame(handle, 8);
//Show down
}
}
return 1;
}
stock CheckShowdown(handle)
{
SendTableMessage(handle, "{F25B13}======================================================================================");
SendTableMessage(handle, "{F25B13} Showdown ");
SendTableMessage(handle, "{F25B13}======================================================================================");
foreach(new p: IT_PlayersTable<handle>) //loop through the players already in the table
{
foreach(new k: IT_PlayersInGame<handle>) //loop through the players already in the table
{
new seat = TableRotCorrections[TableData[PlayerData[k][E_PLAYER_CURRENT_HANDLE]][E_TABLE_TOTAL_SEATS]][ PlayerData[k][E_PLAYER_CURRENT_CHAIR_SLOT]];
new card1 = PlayerData[k][E_PLAYER_CARD_VALUES][0];
new card2 = PlayerData[k][E_PLAYER_CARD_VALUES][1];
PlayerTextDrawSetString(p, PlayerData[p][E_PLAYER_CARDS_TXT_1][seat], CardData[card1][E_CARD_TEXTDRAW]);
PlayerTextDrawSetString(p, PlayerData[p][E_PLAYER_CARDS_TXT_2][seat], CardData[card2][E_CARD_TEXTDRAW]);
}
}
if(!Iter_Contains(IT_Sidepots[handle], MAIN_POT))
{
Iter_Add(IT_Sidepots[handle], MAIN_POT);
foreach(new k: IT_PlayersInGame<handle>) //loop through the players already in the table
{
Iter_Add(It_SidepotMembers[_IT[handle][MAIN_POT]], k);
}
}
foreach(new pot_id: IT_Sidepots[handle])
{
new highest_rank = -0x7FFFFFFF;
new PlayerRanks[MAX_PLAYERS];
new high_id = INVALID_PLAYER_ID;
foreach(new p: It_SidepotMembers[_IT[handle][pot_id]])
{
if(!Iter_Contains(IT_PlayersInGame<handle>, p)) continue;
new card[7];
card[0] = GetCardNativeIndex(PlayerData[p][E_PLAYER_CARD_VALUES][0]);
card[1] = GetCardNativeIndex(PlayerData[p][E_PLAYER_CARD_VALUES][1]);
card[2] = GetCardNativeIndex(TableData[handle][E_TABLE_COM_CARDS_VALUES][0]);
card[3] = GetCardNativeIndex(TableData[handle][E_TABLE_COM_CARDS_VALUES][1]);
card[4] = GetCardNativeIndex(TableData[handle][E_TABLE_COM_CARDS_VALUES][2]);
card[5] = GetCardNativeIndex(TableData[handle][E_TABLE_COM_CARDS_VALUES][3]);
card[6] = GetCardNativeIndex(TableData[handle][E_TABLE_COM_CARDS_VALUES][4]);
PlayerRanks[p] = calculate_hand_worth(card, 7);
if(PlayerRanks[p] > highest_rank)
{
highest_rank = PlayerRanks[p];
high_id = p;
}
}
new count = 0;
foreach(new p: It_SidepotMembers[_IT[handle][pot_id]])
{
if(!Iter_Contains(IT_PlayersInGame<handle>, p)) continue;
if(PlayerRanks[p] == highest_rank)
{
count++;
}
}
if(count == 1)
{
foreach(new p: It_SidepotMembers[_IT[handle][pot_id]])
{
if(!Iter_Contains(IT_PlayersInGame<handle>, p)) continue;
if(p == high_id) continue;
ApplyAnimation(p, "INT_OFFICE", "OFF_Sit_Crash", 4.1, 0, 1, 1, 1, 0, 1);
}
new w_chips = floatround(float(TableData[handle][E_TABLE_POT_CHIPS][pot_id]) * (1.0 - T_POT_FEE_RATE));
new fee_earned = floatround((float(TableData[handle][E_TABLE_POT_CHIPS][pot_id]) / 1000.0) * T_POT_FEE_RATE);
UpdateServerVariable( "poker_fees", 0, GetGVarFloat( "poker_fees" ) + fee_earned, "", GLOBAL_VARTYPE_FLOAT );
StockMarket_UpdateEarnings( E_STOCK_CASINO, fee_earned, 0.2 );
GivePlayerCasinoRewardsPoints(high_id, fee_earned, .house_edge = 100.0);
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
SendTableMessage(handle, "{9FCF30}Player {FF8000}%s {9FCF30}has won with a {377CC8}%s", ReturnPlayerName(high_id), HAND_RANKS[highest_rank >> 12]);
SendTableMessage(handle, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee.", cash_format(w_chips), T_POT_FEE_RATE * 100.0, "%%");
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
if (strmatch(HAND_RANKS[highest_rank >> 12], "Royal Flush")) printf("****\nRoyal Flush Player %s\n****\n", ReturnPlayerName(high_id));
PlayerData[high_id][E_PLAYER_TOTAL_CHIPS] += w_chips;
}
else
{
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
SendTableMessage(handle, "{9FCF30}Draw! These players have won with a {377CC8}%s:", HAND_RANKS[highest_rank >> 12]);
new w_chips = floatround(float(TableData[handle][E_TABLE_POT_CHIPS][pot_id]) * (1.0 - T_POT_FEE_RATE));
new fee_earned = floatround((float(TableData[handle][E_TABLE_POT_CHIPS][pot_id]) / 1000.0) * T_POT_FEE_RATE);
UpdateServerVariable( "poker_fees", 0, GetGVarFloat( "poker_fees" ) + fee_earned, "", GLOBAL_VARTYPE_FLOAT );
StockMarket_UpdateEarnings( E_STOCK_CASINO, fee_earned, 0.2 );
new amount = w_chips / count;
//new excess = TableData[handle][E_TABLE_POT_CHIPS][pot_id] % count
foreach(new p: It_SidepotMembers[_IT[handle][pot_id]])
{
if(!Iter_Contains(IT_PlayersInGame<handle>, p)) continue;
if(PlayerRanks[p] == highest_rank)
{
GivePlayerCasinoRewardsPoints(p, floatround(float(fee_earned) / float(count)), .house_edge = 100.0);
SendTableMessage(handle, "{9FCF30}%s", ReturnPlayerName(p));
PlayerData[p][E_PLAYER_TOTAL_CHIPS] += amount;
}
else
{
ApplyAnimation(p, "INT_OFFICE", "OFF_Sit_Crash", 4.1, 0, 1, 1, 1, 0, 1);
}
}
SendTableMessage(handle, "{9FCF30}Each receives 1/%d of the total pot available. | -%0.0f%s percent fee", count, T_POT_FEE_RATE * 100.0, "%%");
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
}
UpdateTable(handle);
}
return 1;
}
stock CheckPotAndNextTurn(playerid, handle)
{
if(GetPVarInt(playerid, "t_Clicked"))
{
SetPVarInt(playerid, "t_Clicked", 0);
}
new next_turn = INVALID_PLAYER_ID;
HidePlayerChoices(playerid);
new bool: is_cycle_complete = false;
next_turn = GetTurnAfterPlayer(handle, playerid);
new last_to_raise = TableData[handle][E_TABLE_LAST_TO_RAISE];
if(next_turn == INVALID_PLAYER_ID){
is_cycle_complete = true;
}
if(!is_cycle_complete)
{
if(next_turn == last_to_raise || next_turn == playerid)
{
is_cycle_complete = true;
}
else
{
//further checking
if(Iter_Count(IT_PlayersAllIn<handle>))
{
new next_player = INVALID_PLAYER_ID;
new last_player = playerid;
for(new i = 0; i < Iter_Count(IT_PlayersInGame<handle>); i++)
{
next_player = GetTurnAfterPlayerEx(handle, last_player);
if(!Iter_Contains(IT_PlayersAllIn<handle>, next_player)) break;
if(next_player == last_to_raise)
{
is_cycle_complete = true;
break;
}
last_player = next_player;
}
}
}
if(!is_cycle_complete)
{
if(!Iter_Contains(IT_PlayersInGame<handle>, last_to_raise))
{
new const total_seats = TableData[handle][E_TABLE_TOTAL_SEATS];
new slot = GetPlayerSeat(playerid) - 1;
if(slot < 0) slot = total_seats - 1;
new next_slot = ITER_NONE;
for(new i = 0; i < total_seats; i++)
{
if(slot < 0) slot = total_seats - 1;
next_slot = slot;
new player = TableData[handle][E_TABLE_CHAIR_PLAYER_ID][next_slot];
if(Iter_Contains(IT_PlayersInGame<handle>, player)) break;
if(next_slot == TableData[handle][E_TABLE_LAST_TO_RAISE_SEAT])
{
is_cycle_complete = true;
break;
}
slot--;
}
}
}
}
/*if(TableData[handle][E_TABLE_FIRST_TURN] == playerid && TableData[handle][E_TABLE_CHECK_FIRST] && PlayerData[playerid][E_PLAYER_FOLDED])
{
new turn = GetTurnAfterPlayer(handle, playerid);
SetLastToRaise(handle, turn);
is_cycle_complete = false;
TableData[handle][E_TABLE_FIRST_TURN] = INVALID_PLAYER_ID;
TableData[handle][E_TABLE_CHECK_FIRST] = false;
}*/
PlayerData[playerid][E_PLAYER_FOLDED] = false;
if(is_cycle_complete)
{
if(Iter_Count(IT_PlayersAllIn<handle>))
{
/*==================================================================================================
Main pot and sidepot creation
==================================================================================================*/
for(new i = 0; i < Iter_Count(IT_PlayersInGame<handle>); i++)
{
new p_count = 0;
new min_bet = cellmax;
foreach(new player: IT_PlayersInGame<handle>)
{
new const player_bet = PlayerData[player][E_PLAYER_CURRENT_BET];
if(!player_bet) continue;
if(player_bet < min_bet)
{
min_bet = player_bet;
}
p_count++;
}
if(!p_count || p_count == 1)
{
break;
}
else //greater than two players
{
new pot_id = Iter_Free(IT_Sidepots[handle]);
TableData[handle][E_TABLE_POT_CHIPS][pot_id] += min_bet * p_count;
foreach(new player: IT_PlayersInGame<handle>)
{
if(!PlayerData[player][E_PLAYER_CURRENT_BET]) continue;
PlayerData[player][E_PLAYER_CURRENT_BET] -= min_bet;
Iter_Add(It_SidepotMembers[_IT[handle][pot_id]], player);
}
Iter_Add(IT_Sidepots[handle], pot_id);
}
}
//Return any excess
foreach(new player: IT_PlayersInGame<handle>)
{
if(!PlayerData[player][E_PLAYER_CURRENT_BET]) continue;
PlayerData[player][E_PLAYER_TOTAL_CHIPS] += PlayerData[player][E_PLAYER_CURRENT_BET];
}
}
else
{
foreach(new player: IT_PlayersInGame<handle>)
{
TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT] += PlayerData[player][E_PLAYER_CURRENT_BET];
}
UpdateTable(handle);
}
new const all_in = Iter_Count(IT_PlayersAllIn<handle>);
new const current_players = Iter_Count(IT_PlayersInGame<handle>);
if(all_in == current_players || all_in == current_players - 1)
{
CheckRounds(handle, true);
}
else
{
CheckRounds(handle, false);
}
}
else
{
SendTurnMessage(handle, next_turn);
}
UpdateTable(handle);
return 1;
}
stock bool: FoldPlayer(handle, playerid)
{
ApplyAnimation(playerid, "INT_OFFICE", "OFF_Sit_Crash", 4.1, 0, 1, 1, 1, 0, 1);
PlayerData[playerid][E_PLAYER_FOLDED] = true;
KillPlayerTurnTimer(playerid);
SendTableMessage(handle, "{2DD9A9} * * %s folds.. * *", ReturnPlayerName(playerid));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{D6230A}** FOLDS ** ");
PlayerData[playerid][E_PLAYER_IS_PLAYING] = false;
TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT] += PlayerData[playerid][E_PLAYER_CURRENT_BET];
HidePlayerChoices(playerid);
Iter_Remove(IT_PlayersInGame<handle>, playerid);
new count = Iter_Count(IT_PlayersInGame<handle>);
if(count == 1)
{
Iter_Remove(IT_PlayersInGame<handle>, playerid);
new winner = Iter_First(IT_PlayersInGame<handle>);
HidePlayerChoices(winner);
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
SendTableMessage(handle, "{9FCF30}Player {FF8000}%s {9FCF30}has won the game!", ReturnPlayerName(winner));
new w_chips = floatround(float(TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT]) * (1.0 - T_POT_FEE_RATE));
new fee_earned = floatround((float(TableData[handle][E_TABLE_POT_CHIPS][MAIN_POT]) / 1000.0) * T_POT_FEE_RATE);
UpdateServerVariable( "poker_fees", 0, GetGVarFloat( "poker_fees" ) + fee_earned, "", GLOBAL_VARTYPE_FLOAT );
GivePlayerCasinoRewardsPoints(winner, fee_earned, .house_edge = 100.0);
SendTableMessage(handle, "{9FCF30}Prize: {377CC8}%s | -%0.0f%s percent fee", cash_format(w_chips), T_POT_FEE_RATE * 100.0, "%%");
SendTableMessage(handle, "{9FCF30}****************************************************************************************");
PlayerData[winner][E_PLAYER_TOTAL_CHIPS] += w_chips;
PlayerData[winner][E_PLAYER_TOTAL_CHIPS] += PlayerData[winner][E_PLAYER_CURRENT_BET];
UpdateTable(handle);
StartNewPokerGame(handle, 8);
TableData[handle][E_TABLE_CURRENT_TURN] = INVALID_PLAYER_ID;
return true;
}
else if(!count)
{
Iter_Remove(IT_PlayersInGame<handle>, playerid);
//Might happen if all the players disconnect
AbortGame(handle);
return true;
}
else if(TableData[handle][E_TABLE_CURRENT_TURN] == playerid)
{
KillTimer(PlayerData[playerid][E_PLAYER_TIMER_ID]);
PlayerData[playerid][E_PLAYER_TIMER_STARTED] = false;
return false;
}
else
{
return false;
}
}
hook OnPlayerClickPlayerTD(playerid, PlayerText:playertextid)
{
if(PlayerData[playerid][E_PLAYER_IS_PLAYING])
{
if(GetPlayerClickedTxt(playerid)) return 1;
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(TableData[handle][E_TABLE_CURRENT_TURN] != playerid) {
HidePlayerChoices(playerid);
return 1;
}
if(playertextid == PlayerData[playerid][E_PLAYER_CHOICES_TXT][FOLD])
{
//Fold
SetPlayerClickedTxt(playerid, true);
if(!FoldPlayer(handle, playerid))
CheckPotAndNextTurn(playerid, handle);
}
else if(playertextid == PlayerData[playerid][E_PLAYER_CHOICES_TXT][CALL])
{
//Call or check
if(TableData[handle][E_TABLE_LAST_BET] == PlayerData[playerid][E_PLAYER_CURRENT_BET]) //check
{
SetPlayerClickedTxt(playerid, true);
KillPlayerTurnTimer(playerid);
SendTableMessage(handle, "{2DD9A9} * * %s checks .. * *", ReturnPlayerName(playerid));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{22B1BD}** CHECKS ** ");
}
else //call
{
new dif = TableData[handle][E_TABLE_LAST_BET] - PlayerData[playerid][E_PLAYER_CURRENT_BET];
if(PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] >= dif)
{
KillPlayerTurnTimer(playerid);
SendTableMessage(handle, "{2DD9A9} * * %s calls %s .. * *", ReturnPlayerName(playerid), cash_format(dif));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{22B1BD}** CALLS %s ** ", cash_format(dif));
RemoveChipsFromPlayer( playerid, dif);
PlayerData[playerid][E_PLAYER_CURRENT_BET] = TableData[handle][E_TABLE_LAST_BET];
SetPlayerClickedTxt(playerid, true);
}
else
{
SendPokerMessage(playerid, "ERROR: You can't call as you don't have enough chips. You have two possible options: going all in or folding.");
return 1;
}
}
CheckPotAndNextTurn(playerid, handle);
}
else if(playertextid == PlayerData[playerid][E_PLAYER_CHOICES_TXT][RAISE])
{
switch(PlayerData[playerid][E_PLAYER_RCHOICE])
{
case E_RAISE_BET:
{
SendPokerMessage(playerid, "Please enter an amount to bet, the total amount of chips you current have is: %d", PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]);
ShowPlayerRaiseDialog(playerid);
HidePlayerChoices(playerid);
}
case E_RAISE_RAISE:
{
SendPokerMessage(playerid, "Please enter an amount to raise, the total amount of chips you current have is: %d", PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]);
HidePlayerChoices(playerid);
ShowPlayerRaiseDialog(playerid);
}
case E_RAISE_ALL_IN:
{
ForcePlayerAllIn(playerid, handle);
SetPlayerClickedTxt(playerid, true);
}
}
}
}
return 1;
}
stock ForcePlayerAllIn(playerid, handle, bool:checkpot = true)
{
ApplyAnimation(playerid, "INT_OFFICE", "OFF_Sit_Idle_Loop", 4.1, 1, 1, 1, 0, 0, 1);
KillPlayerTurnTimer(playerid);
Iter_Add(IT_PlayersAllIn<handle>, playerid);
new raise = PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] + PlayerData[playerid][E_PLAYER_CURRENT_BET];
PlayerData[playerid][E_PLAYER_CURRENT_BET] = raise;
SendTableMessage(handle, "{2DD9A9} * * %s goes all in with %s .. * *", ReturnPlayerName(playerid), cash_format(raise));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{9512CD}** ALL IN with %s ** ", cash_format(raise));
PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] = 0;
if(checkpot)
CheckPotAndNextTurn(playerid, handle);
return 1;
}
stock ShowPlayerRaiseDialog(playerid)
{
return ShowPlayerDialogEx(playerid, DIALOG_INPUT_RAISE, DIALOG_STYLE_INPUT, "{FF8000}Input", "Submit", "Cancel", "{FFFFFF}Please input the desired amount of chips: \n{FFFFFF}You may type {FF8000}%d {FFFFFF} if you want to go All In\n", PlayerData[playerid][E_PLAYER_TOTAL_CHIPS]);
}
hook OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == DIALOG_BUY_IN)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(!IsValidTable(handle)) return 1;
if(!Iter_Contains(IT_PlayersTable<handle>, playerid)) return 1;
if(response)
{
GivePlayerCash(playerid, -TableData[handle][E_TABLE_BUY_IN]);
PlayerData[playerid][E_PLAYER_TOTAL_CHIPS] = TableData[handle][E_TABLE_BUY_IN];
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has paid the buy-in fee of %s chips to keep playing.", ReturnPlayerName(playerid), cash_format(TableData[handle][E_TABLE_BUY_IN]));
}
else
{
SendTableMessage(handle, ""COL_GREY"-- "COL_WHITE"Player %s has been kicked out of the table. [Reason: Failure to pay the buy-in fee]", ReturnPlayerName(playerid));
KickPlayerFromTable(playerid);
}
}
if(dialogid == DIALOG_INPUT_RAISE)
{
if(response)
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(!IsValidTable(handle)) return 0;
if(!Iter_Contains(IT_PlayersTable<handle>, playerid)) return 1;
if(TableData[handle][E_TABLE_CURRENT_STATE] != STATE_BEGIN)
{
SendPokerMessage(playerid, "There isn't any active game at the moment.");
return 0;
}
if(!Iter_Contains(IT_PlayersInGame<handle>, playerid))
{
return 0;
}
new raise = 0;
if(sscanf(inputtext, "d", raise))
{
SendPokerMessage(playerid, "Input must be numeric.");
ShowPlayerRaiseDialog(playerid);
return 1;
}
if(raise < 0)
{
SendPokerMessage(playerid, "Input must be greater than 0.");
ShowPlayerRaiseDialog(playerid);
return 1;
}
else if(raise > PlayerData[playerid][E_PLAYER_TOTAL_CHIPS])
{
SendPokerMessage(playerid, "You don't have that many chips available.");
ShowPlayerRaiseDialog(playerid);
return 1;
}
else if(raise <= TableData[handle][E_TABLE_LAST_BET])
{
SendPokerMessage(playerid, "Value must be greater than the last bet: %s", cash_format(TableData[handle][E_TABLE_LAST_BET]));
ShowPlayerRaiseDialog(playerid);
return 1;
}
else if(raise == PlayerData[playerid][E_PLAYER_TOTAL_CHIPS])
{
ApplyAnimation(playerid, "INT_OFFICE", "OFF_Sit_Idle_Loop", 4.1, 1, 1, 1, 0, 0, 1);
KillPlayerTurnTimer(playerid);
//all in - not mandatory
SendTableMessage(handle, "{2DD9A9} * * %s goes all in with %s .. * *", ReturnPlayerName(playerid), cash_format(raise));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{9512CD}** ALL IN with %s ** ", cash_format(raise));
Iter_Add(IT_PlayersAllIn<handle>, playerid);
RemoveChipsFromPlayer( playerid, raise);
SetLastToRaise(handle, playerid);
PlayerData[playerid][E_PLAYER_CURRENT_BET] += raise;
TableData[handle][E_TABLE_LAST_BET] = PlayerData[playerid][E_PLAYER_CURRENT_BET];
CheckPotAndNextTurn(playerid, handle);
}
else
{
KillPlayerTurnTimer(playerid);
new dif = raise - PlayerData[playerid][E_PLAYER_CURRENT_BET];
TableData[handle][E_TABLE_LAST_BET] = raise;
SetLastToRaise(handle, playerid);
PlayerData[playerid][E_PLAYER_CURRENT_BET] = raise;
RemoveChipsFromPlayer( playerid, dif);
if(PlayerData[playerid][E_PLAYER_RCHOICE] == E_RAISE_BET)
{
SendTableMessage(handle, "{2DD9A9} * * %s bets %s .. * *", ReturnPlayerName(playerid), cash_format(raise));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{31CA15}** BETS %s ** ", cash_format(raise));
}
else
{
SendTableMessage(handle, "{2DD9A9} * * %s raises to %s .. * *", ReturnPlayerName(playerid), cash_format(raise));
SetPlayerChatBubbleEx(playerid, -1, 30.0, 2000, "{31CA15}** RAISES to %s ** ", cash_format(raise));
}
CheckPotAndNextTurn(playerid, handle);
}
}
else
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(!IsValidTable(handle)) return 1;
if(TableData[handle][E_TABLE_CURRENT_TURN] == playerid)
{
SetPlayerClickedTxt(playerid, false);
ShowChoicesToPlayer(playerid);
}
else
{
ShowPlayerDialog(playerid, -1, DIALOG_STYLE_INPUT, " ", " ", " ", " ");
}
}
}
return 1;
}
hook OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(PRESSED(KEY_SECONDARY_ATTACK))
{
new handle = GetClosestTableForPlayer(playerid);
if(handle != ITER_NONE)
{
if(TableData[handle][E_TABLE_VIRTUAL_WORLD] == GetPlayerVirtualWorld(playerid) && TableData[handle][E_TABLE_INTERIOR] == GetPlayerInterior(playerid))
{
if(!Iter_Contains(IT_PlayersTable<handle>, playerid))
{
if(IsPlayerInRangeOfTable(playerid, handle, T_JOIN_TABLE_RANGE))
{
AddPlayerToTable(playerid, handle);
}
}
else
{
if((Iter_Contains(IT_PlayersInGame<handle>, playerid) && TableData[handle][E_TABLE_CURRENT_STATE] == STATE_BEGIN)
|| TableData[T_MAX_POKER_TABLES][E_TABLE_LOADING_GAME])
{
SendPokerMessage(playerid, "You cannot exit this table as there's currently an active match under process.");
return 0;
}
KickPlayerFromTable(playerid);
}
}
}
}
return 1;
}
#if defined AC_INCLUDED
hook OnPlayerDeathEx( playerid, killerid, reason, Float: damage, bodypart )
#else
hook OnPlayerDeath(playerid, killerid, reason)
#endif
{
Player_CheckPokerGame(playerid, "Died");
return 1;
}
hook OnPlayerDisconnect(playerid, reason)
{
Player_CheckPokerGame(playerid, "Disconnected");
return 1;
}
stock Player_CheckPokerGame(playerid, const reason[])
{
if(GetPVarInt(playerid, "t_is_in_table"))
{
new handle = PlayerData[playerid][E_PLAYER_CURRENT_HANDLE];
if(Iter_Contains(IT_PlayersInGame<handle>, playerid)) {
if(!FoldPlayer(handle, playerid)) {
CheckPotAndNextTurn(playerid, handle);
}
}
SendTableMessage(handle, "Player %s has been kicked out from the table [REASON: %s].", ReturnPlayerName(playerid), reason);
KickPlayerFromTable(playerid);
}
return 1;
}
hook OnGameModeExit()
{
for(new i = 0; i < T_MAX_POKER_TABLES; i++)
{
if(!Iter_Contains(IT_Tables, i)) continue;
DestroyPokertable(i);
memcpy(TableData[i], TableData[T_MAX_POKER_TABLES], 0, sizeof(TableData[]) * 4, sizeof(TableData[]));
}
return 1;
}
hook OnGameModeInit()
{
//Setting values to dummy arrays
//Player data:
PlayerData[MAX_PLAYERS][E_PLAYER_CURRENT_HANDLE] = ITER_NONE;
PlayerData[MAX_PLAYERS][E_PLAYER_CURRENT_CHAIR_SLOT] = ITER_NONE;
PlayerData[MAX_PLAYERS][E_PLAYER_CHAIR_ATTACH_INDEX_ID] = ITER_NONE;
PlayerData[MAX_PLAYERS][E_PLAYER_IS_PLAYING] = false;
PlayerData[MAX_PLAYERS][E_PLAYER_TIMER_STARTED] = false;
PlayerData[MAX_PLAYERS][E_PLAYER_CARD_VALUES][0] = ITER_NONE;
PlayerData[MAX_PLAYERS][E_PLAYER_CARD_VALUES][1] = ITER_NONE;
PlayerData[MAX_PLAYERS][E_PLAYER_CURRENT_BET] = 0;
PlayerData[MAX_PLAYERS][E_PLAYER_TOTAL_CHIPS] = 0;
PlayerData[MAX_PLAYERS][E_PLAYER_FOLDED] = false;
TableData[T_MAX_POKER_TABLES][E_TABLE_STING_NEW_GAME] = false;
//Table data
TableData[T_MAX_POKER_TABLES][E_TABLE_TOTAL_SEATS] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_LOADING_GAME] = false;
TableData[T_MAX_POKER_TABLES][E_TABLE_CHECK_FIRST] = false;
TableData[T_MAX_POKER_TABLES][E_TABLE_FIRST_TURN] = INVALID_PLAYER_ID;
TableData[T_MAX_POKER_TABLES][E_TABLE_CURRENT_STATE] = STATE_IDLE;
TableData[T_MAX_POKER_TABLES][E_TABLE_BUY_IN] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_SMALL_BLIND] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_VIRTUAL_WORLD] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_INTERIOR] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_BIG_BLIND] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_POS_X] = 0.0;
TableData[T_MAX_POKER_TABLES][E_TABLE_POS_Y] = 0.0;
TableData[T_MAX_POKER_TABLES][E_TABLE_POS_Z] = 0.0;
TableData[T_MAX_POKER_TABLES][E_TABLE_OBJECT_IDS][0] = 0;
TableData[T_MAX_POKER_TABLES][E_TABLE_OBJECT_IDS][1] = 0;
for(new i = 0; i < T_MAX_CHAIRS_PER_TABLE; i++)
{
TableData[T_MAX_POKER_TABLES][E_TABLE_CHAIR_OBJECT_IDS][i] = INVALID_OBJECT_ID;
TableData[T_MAX_POKER_TABLES][E_TABLE_IS_SEAT_TAKEN][i] = false;
TableData[T_MAX_POKER_TABLES][E_TABLE_CHAIR_PLAYER_ID][i] = INVALID_PLAYER_ID;
TableData[T_MAX_POKER_TABLES][E_TABLE_SEAT_POS_X][i] = 0.0;
TableData[T_MAX_POKER_TABLES][E_TABLE_SEAT_POS_Y][i] = 0.0;
TableData[T_MAX_POKER_TABLES][E_TABLE_SEAT_POS_Z][i] = 0.0;
TableChips[T_MAX_POKER_TABLES][i][0] = 0;
TableChips[T_MAX_POKER_TABLES][i][1] = 0;
TableChips[T_MAX_POKER_TABLES][i][2] = 0;
TableChips[T_MAX_POKER_TABLES][i][3] = 0;
}
// server variables
AddServerVariable( "poker_fees", "0.0", GLOBAL_VARTYPE_FLOAT );
// red dragons casino
CreatePokerTable( 1000000, 10000, 1968.395019, 1027.808959, 991.828002, 2, 23, 10 );
CreatePokerTable( 500000, 5000, 1940.795043, 1008.741027, 991.828002, 3, 23, 10 );
CreatePokerTable( 250000, 2500, 1940.795043, 1027.240966, 991.828002, 3, 23, 10 );
CreatePokerTable( 100000, 1000, 1940.795043, 1021.075012, 991.828002, 4, 23, 10 );
CreatePokerTable( 50000, 500, 1940.795043, 1014.908996, 991.828002, 4, 23, 10 );
CreatePokerTable( 25000, 250, 1968.395019, 1014.609008, 991.828002, 5, 23, 10 );
CreatePokerTable( 10000, 100, 1968.395019, 1021.208984, 991.828002, 6, 23, 10 );
CreatePokerTable( 5000, 50, 1968.395019, 1008.008972, 991.828002, 6, 23, 10 );
// caliguas casino
CreatePokerTable( 250000, 2500, 2273.936035, 1597.272949, 1005.568969, 2, 82, 1 );
CreatePokerTable( 125000, 1250, 2252.936035, 1591.272949, 1005.568969, 2, 82, 1 );
CreatePokerTable( 100000, 1000, 2255.936035, 1597.272949, 1005.568969, 3, 82, 1 );
CreatePokerTable( 50000, 500, 2258.936035, 1591.272949, 1005.568969, 4, 82, 1 );
CreatePokerTable( 25000, 250, 2261.936035, 1597.272949, 1005.568969, 5, 82, 1 );
CreatePokerTable( 10000, 100, 2264.936035, 1591.272949, 1005.568969, 5, 82, 1 );
CreatePokerTable( 5000, 50, 2267.936035, 1597.272949, 1005.568969, 6, 82, 1 );
CreatePokerTable( 2500, 25, 2270.936035, 1591.272949, 1005.568969, 6, 82, 1 );
T_SendWarning("TPoker by ThreeKingz has been succesfully loaded!");
return 1;
}
/******************************************************************************************
Commands
*******************************************************************************************/
CMD:ctable(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return 0;
new seats, small_blind, buy_in;
if(sscanf(params, "ddd", seats, small_blind, buy_in))
{
SendPokerMessage(playerid, "/ctable [number of seats] [small blind] [buy in]");
return 1;
}
//Assumes the player is on a flat surface <Pos[2]-0.6>
new Float:Pos[3];
GetPlayerPos(playerid, Pos[0], Pos[1], Pos[2]);
new table = CreatePokerTable(buy_in, small_blind, Pos[0], Pos[1], Pos[2]-0.6, seats, GetPlayerVirtualWorld(playerid), GetPlayerInterior(playerid));
SendPokerMessage(playerid, "You have created table ID: %d | Small blind: %s | Big blind: %s | Buy In: %s | Seats: %d", table, cash_format(small_blind), cash_format(small_blind*2), cash_format(buy_in), seats);
return 1;
}
CMD:dtable(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return 0;
new ptable = 0;
if(sscanf(params, "d", ptable))
{
SendClientMessage(playerid, 0x3E969FFF, "/ctable [pokertable ID]");
return 1;
}
if(!IsValidTable(ptable))
{
SendClientMessageFormatted(playerid, 0x3E969FFF, "Invalid pokertable ID");
return 1;
}
SendPokerMessage(playerid, "You have deleted poker table ID: %d", ptable);
DestroyPokertable(ptable);
return 1;
}
CMD:agame(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return 0;
new ptable;
if(sscanf(params, "d", ptable))
{
SendPokerMessage(playerid, "/agame [table ID]");
SendPokerMessage(playerid, "Will abort a game if started, ejecting all the players out of the table.");
return 1;
}
if(!IsValidTable(ptable))
{
SendClientMessageFormatted(playerid, 0x3E969FFF, "Invalid pokertable ID");
return 1;
}
if(AbortGame(ptable))
{
SendPokerMessage(playerid, "You have successfully aborted the game on table ID: %d", ptable);
}
else
{
SendPokerMessage(playerid, "No game has started in this table yet.");
}
return 1;
}