RATDOG/_module/nss/inc_blackjack.nss
Jaysyn904 a005da6b51 Added Daz's persistent NUI storage
Added Daz's persistent NUI storage.  Added instanced player room at the Inn of the Flying Monkey.  Added PnP cockatrice & dire weasel.  Full compile.
2023-02-19 01:10:48 -05:00

1105 lines
39 KiB
Plaintext

/*
Blackjack NUI Game
Created By: Daz
*/
#include "inc_nui"
// CONFIGURATION
const int BJ_MAX_BET = 500;
const int BJ_DOUBLE_DOWN_MIN_POINTS = 9;
const int BJ_DOUBLE_DOWN_MAX_POINTS = 11;
const int BJ_DOUBLE_DOWN_EXCEED_MAX_BET = TRUE;
const int BJ_DEALER_STAND_VALUE = 17;
const float BJ_DEALER_TURN_DELAY_MIN = 0.75f;
const int BJ_DEALER_TURN_DELAY_RANDOM = 75;
const int BJ_HAND_NUM_CARDS = 6;
// *****
const string BJ_WINDOW_ID = "BJ_GAME";
const string BJ_WINDOW_JSON = "BJ_WINDOW_JSON";
const string BJ_WINDOW_GEOMETRY = "BJ_WINDOW_GEOMETRY";
const float BJ_WINDOW_MINIMUM_WIDTH = 100.0f;
const float BJ_WINDOW_HEIGHT = 600.0f;
const float BJ_BUTTON_WIDTH = 125.0f;
const float BJ_CARD_WIDTH = 100.0f;
const float BJ_CARD_HEIGHT = 145.0f;
const int BJ_BLACKJACK_VALUE = 21;
const int BJ_DRAW_CARD_RANDOM = -1;
const int BJ_DRAW_CARD_TOP = 0;
const string BJ_DECK_JSON = "BJ_DECK_JSON";
const string BJ_PLAYER_HAND = "player";
const string BJ_DEALER_HAND = "dealer";
const string BJ_CARD_BACK = "pc_back";
const string BJ_CARD_BLANK = "pc_blank";
const string BJ_PLAYER_CARD_PREFIX = "pcard_";
const string BJ_DEALER_CARD_PREFIX = "dcard_";
const string BJ_ID_BUTTON_HIT = "btn_hit";
const string BJ_ID_BUTTON_DEAL = "btn_deal";
const string BJ_ID_BUTTON_STAND = "btn_stand";
const string BJ_ID_BUTTON_BET = "btn_bet";
const string BJ_ID_BUTTON_DOUBLE_DOWN = "btn_doubledown";
const string BJ_BIND_DEALER_NAME = "dealer_name";
const string BJ_BIND_DEALER_POINTS = "dealer_points";
const string BJ_BIND_PLAYER_NAME = "player_name";
const string BJ_BIND_PLAYER_POINTS = "player_points";
const string BJ_BIND_INFO_TEXT = "info_text";
const string BJ_BIND_BET_AMOUNT = "bet_amount";
const string BJ_BIND_BET_AMOUNT_VISIBLE = "bet_amount_v";
const string BJ_BIND_GOLD_RESULT = "gold_result";
const string BJ_BIND_CURRENT_BET = "current_bet";
const string BJ_BIND_STATS_TOOLTIP = "stats";
const string BJ_PLAYER_STATS = "BJ_PLAYER_STATS";
const int BJ_STATS_TYPE_TOTAL = 0;
const int BJ_STATS_TYPE_WINS = 1;
const int BJ_STATS_TYPE_DRAWS = 2;
const int BJ_STATS_TYPE_LOSSES = 3;
const string BJ_BIND_BUTTON_VISIBLE_HIT = "btn_hit_v";
const string BJ_BIND_BUTTON_VISIBLE_DEAL = "btn_deal_v";
const string BJ_BIND_BUTTON_VISIBLE_STAND = "btn_stand_v";
const string BJ_BIND_BUTTON_VISIBLE_BET = "btn_bet_v";
const string BJ_BIND_BUTTON_VISIBLE_DOUBLE_DOWN = "btn_doubledown_v";
const string BJ_BIND_BUTTON_ENABLED_HIT = "btn_hit_e";
const string BJ_BIND_BUTTON_ENABLED_DEAL = "btn_deal_e";
const string BJ_BIND_BUTTON_ENABLED_STAND = "btn_stand_e";
const string BJ_BIND_BUTTON_ENABLED_BET = "btn_bet_e";
const string BJ_BIND_BUTTON_ENABLED_DOUBLE_DOWN = "btn_doubledown_e";
const string BJ_GAME_STATE = "BJ_GAME_STATE";
const int BJ_GAME_STATE_NONE = 0;
const int BJ_GAME_STATE_DEAL_CARDS = 1;
const int BJ_GAME_STATE_PLAYER_TURN = 2;
const int BJ_GAME_STATE_DEALER_TURN = 3;
const int BJ_GAME_STATE_GAME_OVER = 4;
const int BJ_DEALER_TURN_NONE = 0;
const int BJ_DEALER_TURN_REVEAL_CARD = 1;
const int BJ_DEALER_TURN_DRAW_CARD = 2;
const int BJ_DEALER_TURN_CHECK_POINTS = 3;
const int BJ_DEAL_CARDS_START = 0;
const int BJ_DEAL_CARDS_PEEK = 5;
json BJ_NuiCard(string sPrefix, int nCard);
json BJ_GetWindowJson();
int BJ_GetWindowId(object oPlayer);
json BJ_GetUserData(object oPlayer);
void BJ_SetUserData(object oPlayer, string sKey, json jData);
void BJ_DeleteUserData(object oPlayer, string sKey);
void BJ_ToggleButton(object oPlayer, string sButton, int bEnabled);
void BJ_SetDealer(object oPlayer, object oDealer);
object BJ_GetDealer(object oPlayer);
string BJ_GetDealerName(object oPlayer);
json BJ_CreateDeck();
void BJ_SetDeck(object oPlayer, json jDeck);
json BJ_GetDeck(object oPlayer);
void BJ_DeleteDeck(object oPlayer);
void BJ_ShuffleDeck(object oPlayer);
void BJ_SetHand(object oPlayer, string sHand, json jHand);
json BJ_GetHand(object oPlayer, string sHand);
void BJ_DeleteHand(object oPlayer, string sHand);
void BJ_InsertCardIntoHand(object oPlayer, string sHand, json jCard);
void BJ_SetHandAces(object oPlayer, string sHand, int nAces);
int BJ_GetHandAces(object oPlayer, string sHand);
void BJ_DeleteHandAces(object oPlayer, string sHand);
void BJ_IncreaseHandAces(object oPlayer, string sHand);
void BJ_ResetHands(object oPlayer);
string BJ_GetCardImage(json jCard);
int BJ_GetCardIsAce(json jCard);
int BJ_GetHandIsBlackjack(object oPlayer, string sHand);
json BJ_GetCardFromDeck(object oPlayer, int nIndex);
void BJ_DrawCard(object oPlayer, string sHand);
int BJ_CreateGameWindow(object oPlayer);
void BJ_SetPlayerName(object oPlayer, int nToken, string sName);
void BJ_SetPlayerPoints(object oPlayer, int nToken, int nPoints);
void BJ_SetDealerName(object oPlayer, int nToken, string sName);
void BJ_SetDealerPoints(object oPlayer, int nTokenn, int nPoints);
void BJ_SetInfoText(object oPlayer, int nToken, string sText);
void BJ_SetGoldResultText(object oPlayer, int nToken, string sResult);
void BJ_SetCurrentBetText(object oPlayer, int nToken, string sCurrentBet);
void BJ_SetCard(object oPlayer, int nToken, string sPrefix, int nCard, string sImage);
void BJ_BlankCards(object oPlayer, int nToken);
void BJ_StartGame(object oPlayer, object oDealer);
void BJ_EndGame(object oPlayer);
void BJ_HandleNUIEvents(object oPlayer, int nToken, string sType, string sElement, int nArrayIndex, json jPayload);
void BJ_SetGameState(object oPlayer, int nState, string sInfoText = "", float fBetResultMultiplier = 0.0f);
int BJ_GetGameState(object oPlayer);
void BJ_DeleteGameState(object oPlayer);
float BJ_GetDealerTurnDelay();
void BJ_HandleDealerTurn(object oPlayer, int nToken, int nCurrentState);
void BJ_HandleDealCards(object oPlayer, int nToken, int nCurrentState);
void BJ_UpdateCards(object oPlayer, int nToken);
int BJ_GetCardValue(json jCard);
int BJ_GetHandPoints(object oPlayer, string sHand);
void BJ_UpdatePoints(object oPlayer, int nToken);
void BJ_ToggleBetInput(object oPlayer, int nToken, int bVisible);
int BJ_GetBet(object oPlayer);
void BJ_SetBet(object oPlayer, int nBet);
void BJ_DeleteBet(object oPlayer);
void BJ_IncreaseBet(object oPlayer, int nIncrease);
void BJ_SettleBet(object oPlayer, int nToken, float fMultiplier);
void BJ_PlaySound(object oPlayer, string sSound);
int BJ_GetPlayerCanDoubleDown(object oPlayer);
json BJ_CreateStatsObject();
json BJ_GetStats(object oPlayer);
void BJ_SetStats(object oPlayer, json jStats);
void BJ_UpdateStats(object oPlayer, int nType);
void BJ_UpdateStatsTooltip(object oPlayer, int nToken);
json BJ_NuiCard(string sPrefix, int nCard)
{
string sCard = sPrefix + IntToString(nCard);
json jImage = NuiImage(NuiBind(sCard), JsonInt(NUI_ASPECT_EXACTSCALED), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE));
jImage = NuiWidth(jImage, BJ_CARD_WIDTH);
jImage = NuiHeight(jImage, BJ_CARD_HEIGHT);
return jImage;
}
json BJ_GetWindowJson()
{
json jWindow = GetLocalJson(GetModule(), BJ_WINDOW_JSON);
if (!JsonGetType(jWindow))
{
json jCol;
json jRow;
jCol = JsonArray();
jRow = JsonArray();
{
json jDealerPoints = NuiHeader(NuiBind(BJ_BIND_DEALER_POINTS), 30.0f, 30.0f);
jDealerPoints = NuiTooltip(jDealerPoints, JsonString("Dealer Points"));
jRow = JsonArrayInsert(jRow, jDealerPoints);
json jDealerName = NuiHeader(NuiBind(BJ_BIND_DEALER_NAME), 30.0f);
jRow = JsonArrayInsert(jRow, jDealerName);
}
jCol = NuiInsertRow(jCol, jRow);
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiSpacer());
int nCard;
for (nCard = 0; nCard < BJ_HAND_NUM_CARDS; nCard++)
{
jRow = JsonArrayInsert(jRow, BJ_NuiCard(BJ_DEALER_CARD_PREFIX, nCard));
}
jRow = JsonArrayInsert(jRow, NuiSpacer());
}
jCol = NuiInsertRow(jCol, jRow);
jCol = NuiInsertRow(jCol, JsonArrayInsert(JsonArray(), NuiSpacer()));
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind(BJ_BIND_INFO_TEXT), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE)));
}
jCol = NuiInsertRow(jCol, jRow);
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiLabel(NuiBind(BJ_BIND_GOLD_RESULT), JsonInt(NUI_HALIGN_CENTER), JsonInt(NUI_VALIGN_MIDDLE)));
}
jCol = NuiInsertRow(jCol, jRow);
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiSpacer());
json jBetInput = NuiTextEdit(JsonString("Amount..."), NuiBind(BJ_BIND_BET_AMOUNT), GetStringLength(IntToString(BJ_MAX_BET)), FALSE);
jBetInput = NuiVisible(jBetInput, NuiBind(BJ_BIND_BET_AMOUNT_VISIBLE));
jBetInput = NuiWidth(jBetInput, 100.0f);
jBetInput = NuiHeight(jBetInput, 30.0f);
jRow = JsonArrayInsert(jRow, jBetInput);
json jBetButton = NuiButton(JsonString("Bet"));
jBetButton = NuiTooltip(jBetButton, JsonString("Max " + IntToString(BJ_MAX_BET) + " gold, all bets are final!"));
jBetButton = NuiId(jBetButton, BJ_ID_BUTTON_BET);
jBetButton = NuiEnabled(jBetButton, NuiBind(BJ_BIND_BUTTON_ENABLED_BET));
jBetButton = NuiVisible(jBetButton, NuiBind(BJ_BIND_BUTTON_VISIBLE_BET));
jBetButton = NuiWidth(jBetButton, 100.0f);
jBetButton = NuiHeight(jBetButton, 30.0f);
jRow = JsonArrayInsert(jRow, jBetButton);
jRow = JsonArrayInsert(jRow, NuiSpacer());
}
jCol = NuiInsertRow(jCol, jRow);
jCol = NuiInsertRow(jCol, JsonArrayInsert(JsonArray(), NuiSpacer()));
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiSpacer());
int nCard;
for (nCard = 0; nCard < BJ_HAND_NUM_CARDS; nCard++)
{
jRow = JsonArrayInsert(jRow, BJ_NuiCard(BJ_PLAYER_CARD_PREFIX, nCard));
}
jRow = JsonArrayInsert(jRow, NuiSpacer());
}
jCol = NuiInsertRow(jCol, jRow);
jRow = JsonArray();
{
json jPlayerPoints = NuiHeader(NuiBind(BJ_BIND_PLAYER_POINTS), 30.0f, 30.0f);
jPlayerPoints = NuiTooltip(jPlayerPoints, JsonString("Player Points"));
jRow = JsonArrayInsert(jRow, jPlayerPoints);
json jPlayerName = NuiHeader(NuiBind(BJ_BIND_PLAYER_NAME), 30.0f);
jPlayerName = NuiTooltip(jPlayerName, NuiBind(BJ_BIND_STATS_TOOLTIP));
jRow = JsonArrayInsert(jRow, jPlayerName);
json jPlayerBet = NuiHeader(NuiBind(BJ_BIND_CURRENT_BET), 30.0f, 125.0f);
jRow = JsonArrayInsert(jRow, jPlayerBet);
}
jCol = NuiInsertRow(jCol, jRow);
jRow = JsonArray();
{
jRow = JsonArrayInsert(jRow, NuiSpacer());
json jDealButton = NuiButton(JsonString("Deal"));
jDealButton = NuiId(jDealButton, BJ_ID_BUTTON_DEAL);
jDealButton = NuiEnabled(jDealButton, NuiBind(BJ_BIND_BUTTON_ENABLED_DEAL));
jDealButton = NuiVisible(jDealButton, NuiBind(BJ_BIND_BUTTON_VISIBLE_DEAL));
jDealButton = NuiWidth(jDealButton, BJ_BUTTON_WIDTH);
jDealButton = NuiHeight(jDealButton, 30.0f);
jRow = JsonArrayInsert(jRow, jDealButton);
jRow = JsonArrayInsert(jRow, NuiSpacer());
json jHitButton = NuiButton(JsonString("Hit"));
jHitButton = NuiId(jHitButton, BJ_ID_BUTTON_HIT);
jHitButton = NuiEnabled(jHitButton, NuiBind(BJ_BIND_BUTTON_ENABLED_HIT));
jHitButton = NuiVisible(jHitButton, NuiBind(BJ_BIND_BUTTON_VISIBLE_HIT));
jHitButton = NuiWidth(jHitButton, BJ_BUTTON_WIDTH);
jHitButton = NuiHeight(jHitButton, 30.0f);
jRow = JsonArrayInsert(jRow, jHitButton);
json jDoubleDownButton = NuiButton(JsonString("Double Down"));
jDoubleDownButton = NuiId(jDoubleDownButton, BJ_ID_BUTTON_DOUBLE_DOWN);
jDoubleDownButton = NuiEnabled(jDoubleDownButton, NuiBind(BJ_BIND_BUTTON_ENABLED_DOUBLE_DOWN));
jDoubleDownButton = NuiVisible(jDoubleDownButton, NuiBind(BJ_BIND_BUTTON_VISIBLE_DOUBLE_DOWN));
jDoubleDownButton = NuiWidth(jDoubleDownButton, BJ_BUTTON_WIDTH);
jDoubleDownButton = NuiHeight(jDoubleDownButton, 30.0f);
jRow = JsonArrayInsert(jRow, jDoubleDownButton);
json jStandButton = NuiButton(JsonString("Stand"));
jStandButton = NuiId(jStandButton, BJ_ID_BUTTON_STAND);
jStandButton = NuiEnabled(jStandButton, NuiBind(BJ_BIND_BUTTON_ENABLED_STAND));
jStandButton = NuiVisible(jStandButton, NuiBind(BJ_BIND_BUTTON_VISIBLE_STAND));
jStandButton = NuiWidth(jStandButton, BJ_BUTTON_WIDTH);
jStandButton = NuiHeight(jStandButton, 30.0f);
jRow = JsonArrayInsert(jRow, jStandButton);
jRow = JsonArrayInsert(jRow, NuiSpacer());
}
jCol = NuiInsertRow(jCol, jRow);
json jRoot = NuiCol(jCol);
jWindow = NuiWindow(jRoot, JsonString("Blackjack"), NuiBind(NUI_WINDOW_GEOMETRY_BIND), JsonBool(FALSE), JsonNull(), JsonBool(TRUE), JsonBool(FALSE), JsonBool(TRUE));
SetLocalJson(GetModule(), BJ_WINDOW_JSON, jWindow);
PrintString(JsonDump(jWindow));
}
return jWindow;
}
json BJ_CreateDeck()
{
json jDeck = GetLocalJson(GetModule(), BJ_DECK_JSON);
if (!JsonGetType(jDeck))
{
jDeck = JsonArray();
json jSuits = JsonArray();
jSuits = JsonArrayInsert(jSuits, JsonString("clubs"));
jSuits = JsonArrayInsert(jSuits, JsonString("diamonds"));
jSuits = JsonArrayInsert(jSuits, JsonString("hearts"));
jSuits = JsonArrayInsert(jSuits, JsonString("spades"));
json jValues = JsonArray();
jValues = JsonArrayInsert(jValues, JsonString("2"));
jValues = JsonArrayInsert(jValues, JsonString("3"));
jValues = JsonArrayInsert(jValues, JsonString("4"));
jValues = JsonArrayInsert(jValues, JsonString("5"));
jValues = JsonArrayInsert(jValues, JsonString("6"));
jValues = JsonArrayInsert(jValues, JsonString("7"));
jValues = JsonArrayInsert(jValues, JsonString("8"));
jValues = JsonArrayInsert(jValues, JsonString("9"));
jValues = JsonArrayInsert(jValues, JsonString("10"));
jValues = JsonArrayInsert(jValues, JsonString("j"));
jValues = JsonArrayInsert(jValues, JsonString("q"));
jValues = JsonArrayInsert(jValues, JsonString("k"));
jValues = JsonArrayInsert(jValues, JsonString("a"));
int nSuit, nNumSuits = JsonGetLength(jSuits);
int nValue, nNumValues = JsonGetLength(jValues);
for (nSuit = 0; nSuit < nNumSuits; nSuit++)
{
for (nValue = 0; nValue < nNumValues; nValue++)
{
json jCard = JsonObject();
jCard = JsonObjectSet(jCard, "suit", JsonArrayGet(jSuits, nSuit));
jCard = JsonObjectSet(jCard, "value", JsonArrayGet(jValues, nValue));
jDeck = JsonArrayInsert(jDeck, jCard);
}
}
SetLocalJson(GetModule(), BJ_DECK_JSON, jDeck);
}
return jDeck;
}
int BJ_GetWindowId(object oPlayer)
{
return NuiFindWindow(oPlayer, BJ_WINDOW_ID);
}
json BJ_GetUserData(object oPlayer)
{
json jUserData = NuiGetUserData(oPlayer, NuiFindWindow(oPlayer, BJ_WINDOW_ID));
return !JsonGetType(jUserData) ? JsonObject() : jUserData;
}
void BJ_SetUserData(object oPlayer, string sKey, json jData)
{
NuiSetUserData(oPlayer, NuiFindWindow(oPlayer, BJ_WINDOW_ID), JsonObjectSet(BJ_GetUserData(oPlayer), sKey, jData));
}
void BJ_DeleteUserData(object oPlayer, string sKey)
{
NuiSetUserData(oPlayer, NuiFindWindow(oPlayer, BJ_WINDOW_ID), JsonObjectDel(BJ_GetUserData(oPlayer), sKey));
}
void BJ_ToggleButton(object oPlayer, string sButton, int bEnabled)
{
NuiSetBind(oPlayer, BJ_GetWindowId(oPlayer), sButton + "_e", JsonBool(bEnabled));
NuiSetBind(oPlayer, BJ_GetWindowId(oPlayer), sButton + "_v", JsonBool(bEnabled));
}
void BJ_SetDealer(object oPlayer, object oDealer)
{
BJ_SetUserData(oPlayer, "dealer", JsonString(ObjectToString(oDealer)));
}
object BJ_GetDealer(object oPlayer)
{
return StringToObject(JsonGetString(JsonObjectGet(BJ_GetUserData(oPlayer), "dealer")));
}
string BJ_GetDealerName(object oPlayer)
{
return GetName(BJ_GetDealer(oPlayer));
}
void BJ_SetDeck(object oPlayer, json jDeck)
{
BJ_SetUserData(oPlayer, "deck", jDeck);
}
json BJ_GetDeck(object oPlayer)
{
return JsonObjectGet(BJ_GetUserData(oPlayer), "deck");
}
void BJ_DeleteDeck(object oPlayer)
{
BJ_DeleteUserData(oPlayer, "deck");
}
void BJ_ShuffleDeck(object oPlayer)
{
json jDeck = JsonArray();
int nCard, nNumCards = JsonGetLength(BJ_GetDeck(oPlayer));
for (nCard = 0; nCard < nNumCards; nCard++)
{
jDeck = JsonArrayInsert(jDeck, BJ_GetCardFromDeck(oPlayer, BJ_DRAW_CARD_RANDOM));
}
BJ_SetDeck(oPlayer, jDeck);
}
void BJ_SetHand(object oPlayer, string sHand, json jHand)
{
BJ_SetUserData(oPlayer, "hand_" + sHand, jHand);
}
json BJ_GetHand(object oPlayer, string sHand)
{
json jHand = JsonObjectGet(BJ_GetUserData(oPlayer), "hand_" + sHand);
return !JsonGetType(jHand) ? JsonArray() : jHand;
}
void BJ_DeleteHand(object oPlayer, string sHand)
{
BJ_DeleteUserData(oPlayer, "hand_" + sHand);
}
void BJ_InsertCardIntoHand(object oPlayer, string sHand, json jCard)
{
json jHand = BJ_GetHand(oPlayer, sHand);
jHand = JsonArrayInsert(jHand, jCard);
BJ_SetHand(oPlayer, sHand, jHand);
}
void BJ_SetHandAces(object oPlayer, string sHand, int nAces)
{
BJ_SetUserData(oPlayer, "aces_" + sHand, JsonInt(nAces));
}
int BJ_GetHandAces(object oPlayer, string sHand)
{
return JsonGetInt(JsonObjectGet(BJ_GetUserData(oPlayer), "aces_" + sHand));
}
void BJ_DeleteHandAces(object oPlayer, string sHand)
{
BJ_DeleteUserData(oPlayer, "aces_" + sHand);
}
void BJ_IncreaseHandAces(object oPlayer, string sHand)
{
BJ_SetHandAces(oPlayer, sHand, BJ_GetHandAces(oPlayer, sHand) + 1);
}
void BJ_ResetHands(object oPlayer)
{
BJ_DeleteHand(oPlayer, BJ_PLAYER_HAND);
BJ_DeleteHand(oPlayer, BJ_DEALER_HAND);
BJ_DeleteHandAces(oPlayer, BJ_PLAYER_HAND);
BJ_DeleteHandAces(oPlayer, BJ_DEALER_HAND);
}
string BJ_GetCardImage(json jCard)
{
return "pc_" + JsonGetString(JsonObjectGet(jCard, "value")) + "_" + JsonGetString(JsonObjectGet(jCard, "suit"));
}
int BJ_GetCardIsAce(json jCard)
{
return JsonGetString(JsonObjectGet(jCard, "value")) == "a";
}
int BJ_GetHandIsBlackjack(object oPlayer, string sHand)
{
json jHand = BJ_GetHand(oPlayer, sHand);
if (JsonGetLength(jHand) != 2)
return FALSE;
return (BJ_GetCardValue(JsonArrayGet(jHand, 0)) + BJ_GetCardValue(JsonArrayGet(jHand, 1))) == BJ_BLACKJACK_VALUE;
}
json BJ_GetCardFromDeck(object oPlayer, int nDrawType)
{
json jDeck = BJ_GetDeck(oPlayer);
int nCard = nDrawType == BJ_DRAW_CARD_RANDOM ? Random(JsonGetLength(jDeck)) : 0;
json jCard = JsonArrayGet(jDeck, nCard);
BJ_SetDeck(oPlayer, JsonArrayDel(jDeck, nCard));
return jCard;
}
void BJ_DrawCard(object oPlayer, string sHand)
{
json jCard = BJ_GetCardFromDeck(oPlayer, BJ_DRAW_CARD_TOP);
BJ_InsertCardIntoHand(oPlayer, sHand, jCard);
if (BJ_GetCardIsAce(jCard))
BJ_IncreaseHandAces(oPlayer, sHand);
BJ_PlaySound(oPlayer, "it_paper");
}
int BJ_CreateGameWindow(object oPlayer)
{
int nToken = NuiCreate(oPlayer, BJ_GetWindowJson(), BJ_WINDOW_ID);
json jGeometry = GetLocalJson(oPlayer, BJ_WINDOW_GEOMETRY);
if (!JsonGetType(jGeometry))
jGeometry = NuiGetCenteredGeometryRect(oPlayer, BJ_WINDOW_MINIMUM_WIDTH + (BJ_HAND_NUM_CARDS * BJ_CARD_WIDTH), BJ_WINDOW_HEIGHT);
NuiSetBindWatch(oPlayer, nToken, NUI_WINDOW_GEOMETRY_BIND, TRUE);
NuiSetBind(oPlayer, nToken, NUI_WINDOW_GEOMETRY_BIND, jGeometry);
return nToken;
}
void BJ_SetPlayerName(object oPlayer, int nToken, string sName)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_PLAYER_NAME, JsonString(sName));
}
void BJ_SetPlayerPoints(object oPlayer, int nToken, int nPoints)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_PLAYER_POINTS, JsonString(IntToString(nPoints)));
}
void BJ_SetDealerName(object oPlayer, int nToken, string sName)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_DEALER_NAME, JsonString(sName));
}
void BJ_SetDealerPoints(object oPlayer, int nToken, int nPoints)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_DEALER_POINTS, JsonString(IntToString(nPoints)));
}
void BJ_SetInfoText(object oPlayer, int nToken, string sText)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_INFO_TEXT, JsonString(sText));
}
void BJ_SetGoldResultText(object oPlayer, int nToken, string sResult)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_GOLD_RESULT, JsonString(sResult));
}
void BJ_SetCurrentBetText(object oPlayer, int nToken, string sCurrentBet)
{
NuiSetBind(oPlayer, nToken, BJ_BIND_CURRENT_BET, JsonString(sCurrentBet));
}
void BJ_SetCard(object oPlayer, int nToken, string sPrefix, int nCard, string sImage)
{
NuiSetBind(oPlayer, nToken, sPrefix + IntToString(nCard), JsonString(sImage));
}
void BJ_BlankCards(object oPlayer, int nToken)
{
int nCard;
for (nCard = 0; nCard < BJ_HAND_NUM_CARDS; nCard++)
{
BJ_SetCard(oPlayer, nToken, BJ_PLAYER_CARD_PREFIX, nCard, BJ_CARD_BLANK);
BJ_SetCard(oPlayer, nToken, BJ_DEALER_CARD_PREFIX, nCard, BJ_CARD_BLANK);
}
}
void BJ_StartGame(object oPlayer, object oDealer)
{
int nToken = BJ_GetWindowId(oPlayer);
if (nToken)
return;
SetGuiPanelDisabled(oPlayer, GUI_PANEL_GOLD_INVENTORY, TRUE);
SetGuiPanelDisabled(oPlayer, GUI_PANEL_GOLD_BARTER, TRUE);
nToken = BJ_CreateGameWindow(oPlayer);
BJ_SetDealer(oPlayer, oDealer);
BJ_SetDealerName(oPlayer, nToken, BJ_GetDealerName(oPlayer));
BJ_SetPlayerName(oPlayer, nToken, GetName(oPlayer));
BJ_SetGameState(oPlayer, BJ_GAME_STATE_NONE, "Click the Deal button to play Blackjack!");
}
void BJ_EndGame(object oPlayer)
{
SetGuiPanelDisabled(oPlayer, GUI_PANEL_GOLD_INVENTORY, FALSE);
SetGuiPanelDisabled(oPlayer, GUI_PANEL_GOLD_BARTER, FALSE);
}
void BJ_HandleNUIEvents(object oPlayer, int nToken, string sType, string sElement, int nArrayIndex, json jPayload)
{
if (sType == NUI_EVENT_CLICK)
{
int nGameState = BJ_GetGameState(oPlayer);
if (sElement == BJ_ID_BUTTON_HIT)
{
if (nGameState != BJ_GAME_STATE_PLAYER_TURN)
return;
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DOUBLE_DOWN, FALSE);
BJ_DrawCard(oPlayer, BJ_PLAYER_HAND);
if (BJ_GetHandPoints(oPlayer, BJ_PLAYER_HAND) > BJ_BLACKJACK_VALUE)
{
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Bust! You lose!", 0.0f);
}
else
{
BJ_UpdateCards(oPlayer, nToken);
BJ_UpdatePoints(oPlayer, nToken);
}
}
else if (sElement == BJ_ID_BUTTON_STAND)
{
if (nGameState != BJ_GAME_STATE_PLAYER_TURN)
return;
BJ_SetGameState(oPlayer, BJ_GAME_STATE_DEALER_TURN);
}
else if (sElement == BJ_ID_BUTTON_DEAL)
{
if (nGameState != BJ_GAME_STATE_NONE && nGameState != BJ_GAME_STATE_GAME_OVER)
return;
BJ_SetGameState(oPlayer, BJ_GAME_STATE_DEAL_CARDS);
}
else if (sElement == BJ_ID_BUTTON_BET)
{
if (nGameState != BJ_GAME_STATE_NONE && nGameState != BJ_GAME_STATE_GAME_OVER)
return;
int nAmount = StringToInt(JsonGetString(NuiGetBind(oPlayer, nToken, BJ_BIND_BET_AMOUNT)));
if (nAmount > 0)
{
int nGold = GetGold(oPlayer);
int nMaxBetLeft = BJ_MAX_BET - BJ_GetBet(oPlayer);
nAmount = nAmount > nGold ? nGold : nAmount;
nAmount = nAmount > BJ_MAX_BET ? BJ_MAX_BET : nAmount;
nAmount = nAmount > nMaxBetLeft ? nMaxBetLeft : nAmount;
if (nAmount > 0)
{
AssignCommand(oPlayer, TakeGoldFromCreature(nAmount, oPlayer, TRUE));
BJ_IncreaseBet(oPlayer, nAmount);
}
}
NuiSetBind(oPlayer, nToken, BJ_BIND_BET_AMOUNT, JsonString(""));
}
else if (sElement == BJ_ID_BUTTON_DOUBLE_DOWN)
{
if (nGameState != BJ_GAME_STATE_PLAYER_TURN || !BJ_GetPlayerCanDoubleDown(oPlayer))
return;
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DOUBLE_DOWN, FALSE);
int nBet = BJ_GetBet(oPlayer);
BJ_IncreaseBet(oPlayer, nBet);
AssignCommand(oPlayer, TakeGoldFromCreature(nBet, oPlayer, TRUE));
BJ_DrawCard(oPlayer, BJ_PLAYER_HAND);
if (BJ_GetHandPoints(oPlayer, BJ_PLAYER_HAND) > BJ_BLACKJACK_VALUE)
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Bust! You lose!", 0.0f);
else
BJ_SetGameState(oPlayer, BJ_GAME_STATE_DEALER_TURN);
}
}
else if (sType == NUI_EVENT_CLOSE)
{
if (sElement == NUI_WINDOW_ROOT_GROUP)
{
BJ_EndGame(oPlayer);
}
}
else if (sType == NUI_EVENT_WATCH)
{
if (sElement == NUI_WINDOW_GEOMETRY_BIND)
{
SetLocalJson(oPlayer, BJ_WINDOW_GEOMETRY, NuiGetBind(oPlayer, nToken, NUI_WINDOW_GEOMETRY_BIND));
}
}
}
void BJ_SetGameState(object oPlayer, int nState, string sInfoText = "", float fBetResultMultiplier = 0.0f)
{
BJ_SetUserData(oPlayer, "gamestate", JsonInt(nState));
int nToken = BJ_GetWindowId(oPlayer);
BJ_SetInfoText(oPlayer, nToken, sInfoText);
switch (nState)
{
case BJ_GAME_STATE_NONE:
{
BJ_BlankCards(oPlayer, nToken);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DEAL, TRUE);
BJ_SetBet(oPlayer, 0);
BJ_ToggleBetInput(oPlayer, nToken, TRUE);
BJ_UpdatePoints(oPlayer, nToken);
BJ_UpdateStatsTooltip(oPlayer, nToken);
break;
}
case BJ_GAME_STATE_DEAL_CARDS:
{
BJ_HandleDealCards(oPlayer, nToken, BJ_DEAL_CARDS_START);
break;
}
case BJ_GAME_STATE_PLAYER_TURN:
{
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DEAL, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_HIT, TRUE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_STAND, TRUE);
if (BJ_GetPlayerCanDoubleDown(oPlayer))
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DOUBLE_DOWN, TRUE);
break;
}
case BJ_GAME_STATE_DEALER_TURN:
{
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DEAL, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_HIT, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_STAND, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DOUBLE_DOWN, FALSE);
DelayCommand(BJ_GetDealerTurnDelay(), BJ_HandleDealerTurn(oPlayer, nToken, BJ_DEALER_TURN_REVEAL_CARD));
break;
}
case BJ_GAME_STATE_GAME_OVER:
{
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DEAL, TRUE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_HIT, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_STAND, FALSE);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DOUBLE_DOWN, FALSE);
BJ_SettleBet(oPlayer, nToken, fBetResultMultiplier);
BJ_SetBet(oPlayer, 0);
BJ_ToggleBetInput(oPlayer, nToken, TRUE);
BJ_UpdateCards(oPlayer, nToken);
BJ_UpdatePoints(oPlayer, nToken);
int nStatsType = fBetResultMultiplier == 1.0f ? BJ_STATS_TYPE_DRAWS : fBetResultMultiplier == 0.0f ? BJ_STATS_TYPE_LOSSES : BJ_STATS_TYPE_WINS;
BJ_UpdateStats(oPlayer, nStatsType);
BJ_UpdateStatsTooltip(oPlayer, nToken);
break;
}
}
}
int BJ_GetGameState(object oPlayer)
{
return JsonGetInt(JsonObjectGet(BJ_GetUserData(oPlayer), "gamestate"));
}
void BJ_DeleteGameState(object oPlayer)
{
BJ_DeleteUserData(oPlayer, "gamestate");
}
float BJ_GetDealerTurnDelay()
{
return BJ_DEALER_TURN_DELAY_MIN + (IntToFloat(Random(BJ_DEALER_TURN_DELAY_RANDOM)) / 100.0f);
}
void BJ_HandleDealerTurn(object oPlayer, int nToken, int nCurrentState)
{
if (BJ_GetGameState(oPlayer) != BJ_GAME_STATE_DEALER_TURN || BJ_GetWindowId(oPlayer) != nToken)
return;
int nNextState = BJ_DEALER_TURN_NONE;
if (nCurrentState == BJ_DEALER_TURN_REVEAL_CARD)
{
BJ_UpdateCards(oPlayer, nToken);
BJ_UpdatePoints(oPlayer, nToken);
nNextState = BJ_GetHandPoints(oPlayer, BJ_DEALER_HAND) < BJ_DEALER_STAND_VALUE ? BJ_DEALER_TURN_DRAW_CARD : BJ_DEALER_TURN_CHECK_POINTS;
}
else if (nCurrentState == BJ_DEALER_TURN_DRAW_CARD)
{
BJ_DrawCard(oPlayer, BJ_DEALER_HAND);
BJ_UpdateCards(oPlayer, nToken);
BJ_UpdatePoints(oPlayer, nToken);
nNextState = BJ_GetHandPoints(oPlayer, BJ_DEALER_HAND) < BJ_DEALER_STAND_VALUE ? BJ_DEALER_TURN_DRAW_CARD : BJ_DEALER_TURN_CHECK_POINTS;
}
else if (nCurrentState == BJ_DEALER_TURN_CHECK_POINTS)
{
int nDealerPoints = BJ_GetHandPoints(oPlayer, BJ_DEALER_HAND);
if (nDealerPoints > BJ_BLACKJACK_VALUE)
{
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, BJ_GetDealerName(oPlayer) + " busts! You win!", 2.0f);
}
else
{
int nPlayerPoints = BJ_GetHandPoints(oPlayer, BJ_PLAYER_HAND);
if (nDealerPoints == nPlayerPoints)
{
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Push! Nobody wins or loses!", 1.0f);
}
else if (nDealerPoints > nPlayerPoints)
{
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, BJ_GetDealerName(oPlayer) + " wins!", 0.0f);
}
else
{
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "You win!", 2.0f);
}
}
}
if (nNextState)
DelayCommand(BJ_GetDealerTurnDelay(), BJ_HandleDealerTurn(oPlayer, nToken, nNextState));
}
void BJ_HandleDealCards(object oPlayer, int nToken, int nCurrentState)
{
if (BJ_GetGameState(oPlayer) != BJ_GAME_STATE_DEAL_CARDS || BJ_GetWindowId(oPlayer) != nToken)
return;
switch (nCurrentState)
{
case BJ_DEAL_CARDS_START:
{
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_DEAL, FALSE);
BJ_ToggleBetInput(oPlayer, nToken, FALSE);
BJ_BlankCards(oPlayer, nToken);
BJ_SetGoldResultText(oPlayer, nToken, "");
BJ_SetDeck(oPlayer, BJ_CreateDeck());
BJ_ShuffleDeck(oPlayer);
BJ_ResetHands(oPlayer);
break;
}
case 1:
case 2:
case 3:
case 4:
{
string sHand = nCurrentState > 2 ? BJ_DEALER_HAND : BJ_PLAYER_HAND;
BJ_DrawCard(oPlayer, sHand);
BJ_UpdateCards(oPlayer, nToken);
BJ_UpdatePoints(oPlayer, nToken);
break;
}
case BJ_DEAL_CARDS_PEEK:
{
float fDelay = 0.0f;
if (BJ_GetHandPoints(oPlayer, BJ_DEALER_HAND) >= 10)
{
fDelay = BJ_GetDealerTurnDelay() + 0.5f;
string sDealerName = BJ_GetDealerName(oPlayer);
BJ_SetInfoText(oPlayer, nToken, sDealerName + " peeks at their card...");
if (BJ_GetHandIsBlackjack(oPlayer, BJ_DEALER_HAND))
{
if (BJ_GetHandIsBlackjack(oPlayer, BJ_PLAYER_HAND))
DelayCommand(fDelay, BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Push! Nobody wins or loses!", 1.0f));
else
DelayCommand(fDelay, BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, sDealerName + " has a Blackjack! You lose!", 0.0f));
return;
}
}
if (BJ_GetHandIsBlackjack(oPlayer, BJ_PLAYER_HAND))
{
if (fDelay > 0.0f)
DelayCommand(fDelay, BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Blackjack! You win!", 2.5f));
else
BJ_SetGameState(oPlayer, BJ_GAME_STATE_GAME_OVER, "Blackjack! You win!", 2.5f);
}
else
{
if (fDelay > 0.0f)
DelayCommand(fDelay, BJ_SetGameState(oPlayer, BJ_GAME_STATE_PLAYER_TURN));
else
BJ_SetGameState(oPlayer, BJ_GAME_STATE_PLAYER_TURN);
}
return;
}
}
if (nCurrentState < BJ_DEAL_CARDS_PEEK)
DelayCommand(BJ_GetDealerTurnDelay(), BJ_HandleDealCards(oPlayer, nToken, ++nCurrentState));
}
void BJ_UpdateCards(object oPlayer, int nToken)
{
int nGameState = BJ_GetGameState(oPlayer);
json jPlayerHand = BJ_GetHand(oPlayer, BJ_PLAYER_HAND);
json jDealerHand = BJ_GetHand(oPlayer, BJ_DEALER_HAND);
int nCard, nNumCards = JsonGetLength(jPlayerHand);
for (nCard = 0; nCard < nNumCards; nCard++)
{
BJ_SetCard(oPlayer, nToken, BJ_PLAYER_CARD_PREFIX, nCard, BJ_GetCardImage(JsonArrayGet(jPlayerHand, nCard)));
}
nNumCards = JsonGetLength(jDealerHand);
for (nCard = 0; nCard < nNumCards; nCard++)
{
if (nCard > 0 && (nGameState == BJ_GAME_STATE_DEAL_CARDS || nGameState == BJ_GAME_STATE_PLAYER_TURN))
BJ_SetCard(oPlayer, nToken, BJ_DEALER_CARD_PREFIX, nCard, BJ_CARD_BACK);
else
BJ_SetCard(oPlayer, nToken, BJ_DEALER_CARD_PREFIX, nCard, BJ_GetCardImage(JsonArrayGet(jDealerHand, nCard)));
}
}
int BJ_GetCardValue(json jCard)
{
string sValue = JsonGetString(JsonObjectGet(jCard, "value"));
if (sValue == "a")
return 11;
else if (sValue == "k" || sValue == "q" || sValue == "j")
return 10;
else
return StringToInt(sValue);
}
int BJ_GetHandPoints(object oPlayer, string sHand)
{
int nGameState = BJ_GetGameState(oPlayer);
json jHand = BJ_GetHand(oPlayer, sHand);
if (sHand == BJ_DEALER_HAND && (nGameState == BJ_GAME_STATE_DEAL_CARDS || nGameState == BJ_GAME_STATE_PLAYER_TURN))
{
return BJ_GetCardValue(JsonArrayGet(jHand, 0));
}
int nPoints = 0, nCard, nNumCards = JsonGetLength(jHand);
for (nCard = 0; nCard < nNumCards; nCard++)
{
nPoints += BJ_GetCardValue(JsonArrayGet(jHand, nCard));
}
int nNumAces = BJ_GetHandAces(oPlayer, sHand);
while (nNumAces > 0 && nPoints > BJ_BLACKJACK_VALUE)
{
nPoints -= 10;
nNumAces--;
}
return nPoints;
}
void BJ_UpdatePoints(object oPlayer, int nToken)
{
BJ_SetPlayerPoints(oPlayer, nToken, BJ_GetHandPoints(oPlayer, BJ_PLAYER_HAND));
BJ_SetDealerPoints(oPlayer, nToken, BJ_GetHandPoints(oPlayer, BJ_DEALER_HAND));
}
void BJ_ToggleBetInput(object oPlayer, int nToken, int bVisible)
{
if (bVisible)
bVisible = GetGold(oPlayer);
BJ_ToggleButton(oPlayer, BJ_ID_BUTTON_BET, bVisible);
NuiSetBind(oPlayer, nToken, BJ_BIND_BET_AMOUNT_VISIBLE, JsonBool(bVisible));
}
int BJ_GetBet(object oPlayer)
{
return JsonGetInt(JsonObjectGet(BJ_GetUserData(oPlayer), "bet"));
}
void BJ_SetBet(object oPlayer, int nBet)
{
BJ_SetUserData(oPlayer, "bet", JsonInt(nBet));
BJ_SetCurrentBetText(oPlayer, BJ_GetWindowId(oPlayer), "Bet: " + IntToString(nBet));
}
void BJ_DeleteBet(object oPlayer)
{
BJ_DeleteUserData(oPlayer, "bet");
}
void BJ_IncreaseBet(object oPlayer, int nIncrease)
{
BJ_SetBet(oPlayer, BJ_GetBet(oPlayer) + nIncrease);
}
void BJ_SettleBet(object oPlayer, int nToken, float fMultiplier)
{
int nBet = BJ_GetBet(oPlayer);
if (nBet > 0)
{
int nResult = FloatToInt(nBet * fMultiplier);
if (nResult)
{
BJ_SetGoldResultText(oPlayer, nToken, "Gold: +" + IntToString(nResult));
GiveGoldToCreature(oPlayer, nResult);
BJ_PlaySound(oPlayer, "it_coins");
}
else
{
BJ_SetGoldResultText(oPlayer, nToken, "Gold: -" + IntToString(nBet));
}
}
}
void BJ_PlaySound(object oPlayer, string sSound)
{
AssignCommand(oPlayer, PlaySound(sSound));
}
int BJ_GetPlayerCanDoubleDown(object oPlayer)
{
int nBet = BJ_GetBet(oPlayer);
int nHandValue = BJ_GetHandPoints(oPlayer, BJ_PLAYER_HAND);
int nGold = GetGold(oPlayer);
return nBet > 0 &&
nGold >= nBet &&
(nHandValue >= BJ_DOUBLE_DOWN_MIN_POINTS && nHandValue <= BJ_DOUBLE_DOWN_MAX_POINTS) &&
(BJ_DOUBLE_DOWN_EXCEED_MAX_BET || ((nBet * 2) <= BJ_MAX_BET));
}
json BJ_CreateStatsObject()
{
json jStats = JsonArray();
jStats = JsonArrayInsert(jStats, JsonInt(0));
jStats = JsonArrayInsert(jStats, JsonInt(0));
jStats = JsonArrayInsert(jStats, JsonInt(0));
jStats = JsonArrayInsert(jStats, JsonInt(0));
return jStats;
}
json BJ_GetStats(object oPlayer)
{
json jStats = GetCampaignJson("BJ_" + GetPCPublicCDKey(oPlayer, TRUE), BJ_PLAYER_STATS);
return !JsonGetType(jStats) ? BJ_CreateStatsObject() : jStats;
}
void BJ_SetStats(object oPlayer, json jStats)
{
SetCampaignJson("BJ_" + GetPCPublicCDKey(oPlayer, TRUE), BJ_PLAYER_STATS, jStats);
}
void BJ_UpdateStats(object oPlayer, int nType)
{
json jStats = BJ_GetStats(oPlayer);
jStats = JsonArraySet(jStats, BJ_STATS_TYPE_TOTAL, JsonInt(JsonGetInt(JsonArrayGet(jStats, BJ_STATS_TYPE_TOTAL)) + 1));
jStats = JsonArraySet(jStats, nType, JsonInt(JsonGetInt(JsonArrayGet(jStats, nType)) + 1));
BJ_SetStats(oPlayer, jStats);
}
void BJ_UpdateStatsTooltip(object oPlayer, int nToken)
{
json jStats = BJ_GetStats(oPlayer);
int nTotal = JsonGetInt(JsonArrayGet(jStats, BJ_STATS_TYPE_TOTAL));
int nWins = JsonGetInt(JsonArrayGet(jStats, BJ_STATS_TYPE_WINS));
int nDraws = JsonGetInt(JsonArrayGet(jStats, BJ_STATS_TYPE_DRAWS));
int nLosses = JsonGetInt(JsonArrayGet(jStats, BJ_STATS_TYPE_LOSSES));
string sStats = "Total: 0 | Wins: 0 (0.00%) | Draws: 0 (0.00%) | Losses: 0 (0.00%)";
if (nTotal)
{
sStats = "Total: " + IntToString(nTotal) +
" | Wins: " + IntToString(nWins) + " (" + FloatToString((IntToFloat(nWins) / IntToFloat(nTotal)) * 100.0f , 0, 2) + "%)" +
" | Draws: " + IntToString(nDraws) + " (" + FloatToString((IntToFloat(nDraws) / IntToFloat(nTotal)) * 100.0f , 0, 2) + "%)" +
" | Losses: " + IntToString(nLosses) + " (" + FloatToString((IntToFloat(nLosses) / IntToFloat(nTotal)) * 100.0f , 0, 2) + "%)";
}
NuiSetBind(oPlayer, nToken, BJ_BIND_STATS_TOOLTIP, JsonString(sStats));
}