#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#define PLUGIN "VideoPoker"
#define AUTHOR "Albernaz o Carniceiro Demoniaco"
#define VERSION "1.4"
new const CFG_FILENAME[] = "videopoker.ini";
new const CFG_DICTIONARY[] = "videopoker.txt";
const CFG_MAX_PARAM_SIZE = 50;
new CFG_SITE_URL[CFG_MAX_PARAM_SIZE];
new CFG_CARD_PATH[CFG_MAX_PARAM_SIZE];
new CFG_IMAGES_PATH[CFG_MAX_PARAM_SIZE];
new CARD_ACTIONS_ML[][] = {"VP_DISCARD","VP_HOLD"}
enum CVARS_LIST
{
BET_VALUE_MIN,
CHAT_MESSAGES, // Chat messages announcing the results of the games played
ENABLED, // 0 - game disabled , 1 - game enabled(Bad load of the cfg file sets it to 0
START_METHOD // 0 - command videopoker, 1 - command say videopoker, 2 - both (Needs restart)
}
new CVARS[CVARS_LIST];
new CVARS_MIN[CVARS_LIST];
new CVARS_MAX[CVARS_LIST];
const N_CARDS_PER_SUIT = 13;
const N_SUITS = 4;
new cardFiguresNames[N_CARDS_PER_SUIT][] = { "Asz" , "Kettes", "Harmas", "Negyes", "Otos" , "Hatos", "Hetes", "Nyolcas", "Kilences", "Tizes", "Bubi","Dama","Kiraly" } ;
new cardSuitNames[N_SUITS][] = { "Kor" ,"Karo","Treff","Pikk"};
enum CARD
{
SUIT,
VALUE,
ID
}
const N_IDS = 33;
const N_CARDS = 52;
new decks[N_IDS][N_CARDS][CARD];
new decksCount[N_IDS];
const PER_PLAYER_MAX_CARDS = 5;
new bool:holdCard[N_IDS][PER_PLAYER_MAX_CARDS]
new decksPlayers[N_IDS][PER_PLAYER_MAX_CARDS][CARD];
new decksPlayersCount[N_IDS];
new betValues[N_IDS];
new inGame[N_IDS];
new gameOver[N_IDS];
enum GAME_RESULT
{
LOSE,
PAIR_OF_JACKS_OR_BETTER,
TWO_PAIRS,
THREE_OF_A_KIND,
STRAIGHT,
FLUSH,
FULL_HOUSE,
FOUR_OF_A_KIND,
STRAIGHT_FLUSH,
ROYAL_FLUSH
}
enum GAME_VALUES
{
ACE,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING
}
enum GAME_SUITS
{
HEARTS,
DIAMONDS,
CLUBS,
SPADES
}
enum GAME_DATA
{
PAIRS,
TRIPLES,
FOURTUPLE,
SUITS,
PAIR_VALUE
}
new GAME_RESULTS_TEXT[GAME_RESULT][] = {"","VP_PAIR_OF_JACKS_OR_BETTER","VP_TWO_PAIRS","VP_THREE_OF_A_KIND","VP_STRAIGHT","VP_FLUSH","VP_FULL_HOUSE","VP_FOUR_OF_A_KIND","VP_STRAIGHT_FLUSH","VP_ROYAL_FLUSH"};
new MONEY_MULTIPLY[GAME_RESULT] = {0,1,2,3,4,5,6,7,8,9}
#define OFFSET_CSMONEY 115
fm_get_user_money(index)
{
return get_pdata_int(index, OFFSET_CSMONEY);
}
fm_set_user_money(index, money, flash = 1)
{
set_pdata_int(index, OFFSET_CSMONEY, money);
message_begin(MSG_ONE, get_user_msgid("Money"), {0,0,0}, index);
write_long(money);
write_byte(flash ? 1 : 0);
message_end();
}
public plugin_cfg()
{
handleConfigFile();
}
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_dictionary(CFG_DICTIONARY);
handleCvars();
switch(getCvar(START_METHOD))
{
case 0:
{
register_clcmd("videopoker","showMenuVideoPoker");
}
case 1:
{
register_clcmd("say videopoker","showMenuVideoPoker");
}
case 2:
{
register_clcmd("videopoker","showMenuVideoPoker");
register_clcmd("say videopoker","showMenuVideoPoker");
}
}
}
handleCvars()
{
CVARS[BET_VALUE_MIN] = register_cvar("vp_min_bet_val", "100");
CVARS[CHAT_MESSAGES] = register_cvar("vp_chat_msgs", "1");
CVARS[ENABLED] = register_cvar("vp_enabled", "1", FCVAR_SERVER);
CVARS[START_METHOD] = register_cvar("vp_start_method", "2")
CVARS_MIN[BET_VALUE_MIN] = 100;
CVARS_MIN[CHAT_MESSAGES] = 0;
CVARS_MIN[ENABLED] = 0;
CVARS_MIN[START_METHOD] = 0;
CVARS_MAX[BET_VALUE_MIN] = 100000;
CVARS_MAX[CHAT_MESSAGES] = 1;
CVARS_MAX[ENABLED] = 1;
CVARS_MAX[START_METHOD] = 2;
}
handleConfigFile()
{
const configsDirLastIndex = 49;
new configsDir[configsDirLastIndex+1];
get_configsdir(configsDir,configsDirLastIndex);
const fileNameLastIndex = configsDirLastIndex + 15;
new fileName[fileNameLastIndex+1];
format(fileName,fileNameLastIndex,"%s/%s",configsDir,CFG_FILENAME);
new sucess = 0;
if(file_exists(fileName))
{
new file = fopen(fileName,"r");
if( !feof(file) )
{
fgets (file, CFG_SITE_URL, CFG_MAX_PARAM_SIZE-1);
sucess = 1;
}
if( !feof(file) )
fgets (file, CFG_CARD_PATH, CFG_MAX_PARAM_SIZE-1);
else
format(CFG_CARD_PATH,CFG_MAX_PARAM_SIZE-1,"");
if( !feof(file) )
fgets (file, CFG_IMAGES_PATH, CFG_MAX_PARAM_SIZE-1);
else
format(CFG_IMAGES_PATH,CFG_MAX_PARAM_SIZE-1,"");
}
set_pcvar_num(CVARS[ENABLED],sucess);
}
getCvar(CVARS_LIST:CVAR)
{
new cvarValue = get_pcvar_num(CVARS[CVAR]);
if(cvarValue < CVARS_MIN[CVAR])
cvarValue = CVARS_MIN[CVAR];
else if(cvarValue > CVARS_MAX[CVAR])
cvarValue = CVARS_MAX[CVAR];
set_pcvar_num(CVARS[CVAR],cvarValue);
return cvarValue;
}
motdShowTable(id)
{
const motdLast = 1299;
new motd[motdLast+1];
const styleLast = 299;
new style[styleLast+1];
format(style,styleLast,"<style>body{padding-top:5%%;font-family:Verdana, Arial, Helvetica, sans-serif;background-image: url('%s%sbackground.png'); text-align:center; width:60%%;margin:auto;margin-top:2%%;}.pi{padding:2%%;font-size:11px;}.m{padding:3%%;}.c{display:inline;}</style>",CFG_SITE_URL,CFG_IMAGES_PATH);
format(motd,motdLast,"%s",style);
format(motd,motdLast,"%s%s",motd,"<div'>");
for(new i=0; i< decksPlayersCount[id]; i++)
{
format(motd,motdLast,"%s<div class='c'><img src='%s%s%sOf%s.png'></div>",motd,CFG_SITE_URL,CFG_CARD_PATH,cardFiguresNames[ decksPlayers[id][i][ID]], cardSuitNames[ decksPlayers[id][i][SUIT] ]);
}
format(motd,motdLast,"%s%s",motd,"</div>");
format(motd,motdLast,"%s%s",motd,"<div class='m'> ");
const MSG_LAST_INDEX= 50;
new msg[MSG_LAST_INDEX+1];
if(gameOver[id])
{
new GAME_RESULT:gameResult = getGameResult(id)
switch(gameResult)
{
case LOSE:
{
format(msg,MSG_LAST_INDEX,"%L",id,"VP_MSG_MOTD_LOST");
}
default:
{
format(msg,MSG_LAST_INDEX,"%L (%L)",id,"VP_MSG_MOTD_WIN",id,GAME_RESULTS_TEXT[gameResult]);
}
}
}
format(motd,motdLast,"%s%s",motd,msg);
format(motd,motdLast,"%s%s",motd,"</div>");
show_motd(id,motd);
}
renewDeck(deck[N_CARDS][CARD],&count)
{
count = 0;
for(new i=0;i<N_SUITS;i++)
{
new j;
new newCard[CARD];
newCard[SUIT] = i;
newCard[ID] = 0;
newCard[VALUE] = 14;
deck[count++] = newCard;
for(j=1;j<=12;j++)
{
new newCard[CARD];
newCard[SUIT] = i;
newCard[ID] = j;
newCard[VALUE] = j+1;
deck[count++] = newCard;
}
}
}
public showMenuVideoPoker(id)
{
if(getCvar(ENABLED))
{
if(!inGame[id] && !gameOver[id])
{
showMenuStart(id);
}
else if(gameOver[id])
{
showMenuGameOver(id);
}
else if(inGame[id])
{
showMenuInGame(id);
}
}
return PLUGIN_CONTINUE;
}
public showMenuGameOver(id)
{
new menu = menu_create("","handleMenuGameOver");
const TITLE_LAST_INDEX = 60 + CFG_MAX_PARAM_SIZE;
new fullTitle[TITLE_LAST_INDEX+1];
format(fullTitle,TITLE_LAST_INDEX,"%L^n^n",id,"VP_TITLE_MENU");
const MSG_LAST_INDEX = 60;
new msg[MSG_LAST_INDEX+1];
new GAME_RESULT:gameResult = getGameResult(id)
switch (gameResult)
{
case 0:
{
format(msg,MSG_LAST_INDEX,"%L",id,"VP_MSG_MENU_LOST",betValues[id]);
}
default:
{
format(msg,MSG_LAST_INDEX,"%L (%L)",id,"VP_MSG_MENU_WIN",betValues[id]*MONEY_MULTIPLY[gameResult],id,GAME_RESULTS_TEXT[gameResult]);
}
}
format(fullTitle,TITLE_LAST_INDEX,"%s%s",fullTitle,msg);
menu_setprop(menu,MPROP_TITLE,fullTitle);
new exitML[10]
format(exitML,9,"\r%L",id,"VP_MSG_MENU_EXIT");
menu_setprop(menu, MPROP_EXITNAME, exitML);
const SHOW_TABLE_LAST_INDEX = 15;
new showTable[SHOW_TABLE_LAST_INDEX+1];
format(showTable,SHOW_TABLE_LAST_INDEX,"%L",id,"VP_MSG_MENU_SHOW_TABLE");
const NEW_GAME_LAST_INDEX = 15;
new newGame[NEW_GAME_LAST_INDEX+1];
format(newGame,NEW_GAME_LAST_INDEX,"%L",id,"VP_MSG_MENU_NEW_GAME");
menu_additem(menu, showTable,"1");
menu_additem(menu, newGame,"2");
menu_display(id,menu,0);
}
public handleMenuGameOver(id , menu , item)
{
if( item < 0 )
return PLUGIN_CONTINUE;
new access, callback;
new actionString[2];
menu_item_getinfo(menu,item,access, actionString ,2,_,_, callback);
new action = str_to_num(actionString);
switch(action)
{
case 1:
{
showMenuGameOver(id);
motdShowTable(id);
}
case 2:
{
doReset(id);
showMenuStart(id);
}
}
return PLUGIN_HANDLED;
}
public showMenuInGame(id)
{
new menu = menu_create("","handleMenuInGame");
const TITLE_LAST_INDEX = CFG_MAX_PARAM_SIZE + 1;
new title[TITLE_LAST_INDEX+1];
format(title,TITLE_LAST_INDEX,"%L^n^n",id,"VP_TITLE_MENU");
menu_setprop(menu,MPROP_TITLE,title);
new exitML[10]
format(exitML,9,"\r%L",id,"VP_MSG_MENU_EXIT");
menu_setprop(menu, MPROP_EXITNAME, exitML);
new cardFigureName[20];
new cardSuitName[20]
new ML_FIGURE_NAME[24]
new ML_SUIT_NAME[24]
const cardTextLen = sizeof cardFigureName + 1 + 5 + 1 + sizeof cardSuitName + 1 + 4 + 20;
new cardText[cardTextLen]
new actionString[] = "1"
for(new i=0;i<PER_PLAYER_MAX_CARDS;i++)
{
format(cardFigureName,19,cardFiguresNames[decksPlayers[id][i][ID]]);
format(cardSuitName,19,cardSuitNames[decksPlayers[id][i][SUIT]]);
strtoupper(cardFigureName);
strtoupper(cardSuitName);
format(ML_FIGURE_NAME,23,"VP_FIGURE_NAME_%s",cardFigureName);
format(ML_SUIT_NAME,23,"VP_SUIT_NAME_%s",cardSuitName);
new hold = _:holdCard[id][i]
format(cardText,cardTextLen-1,"%L %L %L (^"%s%L\w^")",id,ML_FIGURE_NAME,id,"VP_FIGURE_SUIT_CONNECTOR",id,ML_SUIT_NAME,(hold ? "\y":"\r"),id,CARD_ACTIONS_ML[hold]);
menu_additem(menu,cardText,actionString);
actionString[0]++;
}
menu_addtext(menu,"",0);
const SHOW_TABLE_LAST_INDEX = 15;
new showTable[SHOW_TABLE_LAST_INDEX+1];
format(showTable,SHOW_TABLE_LAST_INDEX,"%L",id,"VP_MSG_MENU_SHOW_TABLE")
const PROCEED_LAST_INDEX = 20;
new stopText[PROCEED_LAST_INDEX+1];
format(stopText,PROCEED_LAST_INDEX,"%L",id,"VP_MSG_MENU_PROCEED");
menu_additem(menu, showTable,"6");
menu_additem(menu, stopText,"7");
menu_display(id,menu,0);
return PLUGIN_CONTINUE;
}
public handleMenuInGame(id , menu , item)
{
if( item < 0 )
return PLUGIN_CONTINUE;
new access, callback;
new actionString[2];
menu_item_getinfo(menu,item,access, actionString ,2,_,_, callback);
new action = str_to_num(actionString);
switch(action)
{
case 1..5:
{
holdCard[id][action-1] = !holdCard[id][action-1]
showMenuInGame(id);
}
case 6:
{
showMenuInGame(id);
motdShowTable(id);
}
case 7:
{
stop(id);
showMenuVideoPoker(id);
motdShowTable(id);
}
}
return PLUGIN_HANDLED;
}
public showMenuStart(id)
{
new menu = menu_create("","handleMenuStart");
const TITLE_LAST_INDEX = 30 + CFG_MAX_PARAM_SIZE;
new titleFull[TITLE_LAST_INDEX+1];
format(titleFull,TITLE_LAST_INDEX,"%L^n^n",id,"VP_TITLE_MENU");
new cvarBetValueMin = getCvar(BET_VALUE_MIN);
menu_setprop(menu,MPROP_PERPAGE,7);
if(fm_get_user_money(id) < cvarBetValueMin)
{
format(titleFull,TITLE_LAST_INDEX,"%L",id,"VP_MSG_MENU_WARN_MIN_BET",cvarBetValueMin);
new exitML[10]
format(exitML,9,"\r%L",id,"VP_MSG_MENU_EXIT");
menu_additem(menu,exitML,"0");
menu_setprop(menu,MPROP_EXIT,MEXIT_NEVER);
}
else
{
if(betValues[id] < cvarBetValueMin)
betValues[id] = cvarBetValueMin;
if(betValues[id] > fm_get_user_money(id))
betValues[id] = fm_get_user_money(id);
format(titleFull,TITLE_LAST_INDEX,"%s%L",titleFull,id,"VP_MSG_MENU_BET_VALUE",betValues[id]);
const RAISE_BET_LAST_INDEX = 30;
const DOWN_BET_LAST_INDEX = 30;
const BET_ALL_LAST_INDEX = 15;
const START_GAME_LAST_INDEX = 15;
new raiseBet[RAISE_BET_LAST_INDEX+1];
new downBet[DOWN_BET_LAST_INDEX+1];
new betAll[BET_ALL_LAST_INDEX+1];
new startGameText[START_GAME_LAST_INDEX+1];
format(betAll,BET_ALL_LAST_INDEX,"%L",id,"VP_MSG_MENU_BET_ALL");
format(startGameText,START_GAME_LAST_INDEX,"%L",id,"VP_MSG_MENU_START");
format(raiseBet,RAISE_BET_LAST_INDEX,"%L",id,"VP_MSG_MENU_RAISE_BET",100);
format(downBet,DOWN_BET_LAST_INDEX,"%L",id,"VP_MSG_MENU_DOWN_BET",100);
menu_additem(menu, raiseBet,"1");
menu_additem(menu, downBet,"2");
menu_addtext(menu, "",0);
format(raiseBet,RAISE_BET_LAST_INDEX,"%L",id,"VP_MSG_MENU_RAISE_BET",1000);
format(downBet,DOWN_BET_LAST_INDEX,"%L",id,"VP_MSG_MENU_DOWN_BET",1000);
menu_additem(menu, raiseBet,"3");
menu_additem(menu, downBet,"4");
menu_addtext(menu, "",0);
menu_additem(menu, betAll,"5");
menu_addtext(menu, "^n",0);
menu_additem(menu, startGameText,"6");
menu_addtext(menu,"",1);
}
menu_setprop(menu,MPROP_BACKNAME,"");
menu_setprop(menu,MPROP_NEXTNAME,"");
menu_setprop(menu,MPROP_TITLE,titleFull);
new exitML[10]
format(exitML,9,"\r%L",id,"VP_MSG_MENU_EXIT");
menu_setprop(menu, MPROP_EXITNAME, exitML);
menu_display(id,menu,0);
return PLUGIN_CONTINUE;
}
public handleMenuStart(id , menu , item)
{
if( item < 0 )
return PLUGIN_CONTINUE;
new access, callback;
new actionString[2];
menu_item_getinfo(menu,item,access, actionString ,2,_,_, callback);
new action = str_to_num(actionString);
switch(action)
{
case 1:
{
betValues[id] += 100;
showMenuStart(id)
}
case 2:
{
betValues[id] -= 100;
showMenuStart(id)
}
case 3:
{
betValues[id] += 1000;
showMenuStart(id)
}
case 4:
{
betValues[id] -= 1000;
showMenuStart(id)
}
case 5:
{
betValues[id] = fm_get_user_money(id);
showMenuStart(id)
}
case 6:
{
if(fm_get_user_money(id) < getCvar(BET_VALUE_MIN))
{
showMenuStart(id)
}
else
{
startGame(id);
showMenuVideoPoker(id);
motdShowTable(id);
}
}
}
return PLUGIN_HANDLED;
}
getRandomCard(deck[N_CARDS][CARD],&count)
{
if(!count)
renewDeck(deck,count);
new randIndex = random(count);
new newCard[CARD];
newCard = deck[randIndex];
deck[randIndex] = deck[--count];
return newCard;
}
givePlayerCard(deck[N_CARDS][CARD],&deckCount,deckPlayer[PER_PLAYER_MAX_CARDS][CARD],&deckPlayerCount)
{
deckPlayer[deckPlayerCount++] = getRandomCard(deck,deckCount);
}
startGame(id)
{
new money = fm_get_user_money(id);
fm_set_user_money(id,money - betValues[id]);
inGame[id] = 1;
gameOver[id] = 0;
decksCount[id] = 0;
decksPlayersCount[id] = 0;
renewDeck(decks[id],decksCount[id]);
givePlayerCard(decks[id],decksCount[id],decksPlayers[id],decksPlayersCount[id]);
givePlayerCard(decks[id],decksCount[id],decksPlayers[id],decksPlayersCount[id]);
givePlayerCard(decks[id],decksCount[id],decksPlayers[id],decksPlayersCount[id]);
givePlayerCard(decks[id],decksCount[id],decksPlayers[id],decksPlayersCount[id]);
givePlayerCard(decks[id],decksCount[id],decksPlayers[id],decksPlayersCount[id]);
for(new i=0;i<PER_PLAYER_MAX_CARDS;i++)
holdCard[id][i] = true;
}
stop(id)
{
for(new i=0;i<PER_PLAYER_MAX_CARDS;i++)
if(!holdCard[id][i])
decksPlayers[id][i] = getRandomCard(decks[id],decksCount[id]);
doGameOver(id);
}
GAME_RESULT:getGameResult(id)
{
new gameValues[GAME_VALUES]
new gameSuits[GAME_SUITS]
new gameData[GAME_DATA]
for(new i=0;i<PER_PLAYER_MAX_CARDS;i++)
{
new thisCard[CARD]
thisCard = decksPlayers[id][i];
new GAME_VALUES:cardID = GAME_VALUES:thisCard[ID]
new GAME_SUITS:cardSuit = GAME_SUITS:thisCard[SUIT]
if(!gameValues[cardID])
{
gameValues[cardID] = 1
}
else
{
gameValues[cardID]++;
switch(gameValues[cardID])
{
case 2:
{
gameData[PAIR_VALUE] = thisCard[VALUE]
gameData[PAIRS]++
}
case 3:
{
gameData[PAIRS]--
gameData[TRIPLES]++
}
case 4:
{
gameData[TRIPLES]--
gameData[FOURTUPLE]++
}
}
}
if(!gameSuits[cardSuit])
{
gameSuits[cardSuit] = 1
gameData[SUITS]++;
}
else
{
gameSuits[cardSuit]++
}
}
if(gameData[FOURTUPLE])
{
return FOUR_OF_A_KIND;
}
else if(gameData[TRIPLES])
{
if(gameData[PAIRS])
return FULL_HOUSE
else
return THREE_OF_A_KIND
}
else if(gameData[PAIRS])
{
if(gameData[PAIRS] == 2)
return TWO_PAIRS;
else if(gameData[PAIR_VALUE] > 10)
return PAIR_OF_JACKS_OR_BETTER;
}
else
{
new higherValue = 2;
new lowerValue = 14;
for(new i=0;i<PER_PLAYER_MAX_CARDS;i++)
{
new value = decksPlayers[id][i][VALUE];
if(value > higherValue)
higherValue = value;
if(value < lowerValue)
lowerValue = value;
}
new bool:isStraight = (lowerValue + 4) == higherValue;
if(gameData[SUITS] == 1)
{
if(isStraight)
{
if(higherValue == 14)
return ROYAL_FLUSH;
else
return STRAIGHT_FLUSH
}
else
{
return FLUSH
}
}
else if(isStraight)
{
return STRAIGHT;
}
}
return LOSE
}
doGameOver(id)
{
gameOver[id] = 1;
inGame[id]= 0;
new money = fm_get_user_money(id);
new name[32];
get_user_name(id,name,31);
new betValue = betValues[id];
new GAME_RESULT:gameResult = getGameResult(id);
switch (getGameResult(id))
{
case 0:
{
if(getCvar(CHAT_MESSAGES))
client_print(0,print_chat,"%L",id,"VP_MSG_CHAT_LOST",name,betValue);
}
default:
{
new moneyToPay = betValue * MONEY_MULTIPLY[gameResult];
fm_set_user_money(id,money + betValue + moneyToPay);
if(getCvar(CHAT_MESSAGES))
client_print(0,print_chat,"%L (%L)",id,"VP_MSG_CHAT_WIN",name,moneyToPay,id,GAME_RESULTS_TEXT[gameResult]);
}
}
}
doReset(id)
{
gameOver[id] = 0;
inGame[id] = 0;
betValues[id] = getCvar(BET_VALUE_MIN);
}
public client_connect(id)
{
doReset(id)
}
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1038\\ f0\\ fs16 \n\\ par }
*/