2023-09-18 16:31:58 +00:00
|
|
|
function makeBlackjackRequest(action, split = false) {
|
2022-12-29 10:58:51 +00:00
|
|
|
const xhr = new XMLHttpRequest();
|
2023-09-18 16:31:58 +00:00
|
|
|
xhr.open("post", `/casino/twentyone/${action}?hand=${split ? 'split' : 'player'}`);
|
2022-12-29 10:58:51 +00:00
|
|
|
xhr.setRequestHeader('xhr', 'xhr');
|
|
|
|
xhr.onload = handleBlackjackResponse.bind(null, xhr);
|
|
|
|
xhr.blackjackAction = action;
|
|
|
|
return xhr;
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleBlackjackResponse(xhr) {
|
|
|
|
let status;
|
|
|
|
try {
|
|
|
|
const response = JSON.parse(xhr.response);
|
|
|
|
const succeeded = xhr.status >= 200 &&
|
|
|
|
xhr.status < 300 &&
|
|
|
|
response &&
|
2023-08-08 17:06:03 +00:00
|
|
|
!response.details;
|
2022-12-29 10:58:51 +00:00
|
|
|
|
|
|
|
clearResult();
|
|
|
|
status = xhr.status;
|
|
|
|
|
|
|
|
if (status == 429) {
|
|
|
|
throw new Error(response["details"]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (succeeded) {
|
|
|
|
updateBlackjackTable(response.state);
|
|
|
|
updateFeed(response.feed);
|
|
|
|
updatePlayerCurrencies(response.gambler);
|
|
|
|
} else {
|
2024-02-11 17:26:56 +00:00
|
|
|
enableWager();
|
2023-08-08 17:06:03 +00:00
|
|
|
console.error("Error: ", response.details);
|
2022-12-29 10:58:51 +00:00
|
|
|
throw new Error("Error")
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
const results = {
|
|
|
|
deal: "Unable to deal a new hand. Is one in progress?",
|
|
|
|
hit: "Unable to hit.",
|
|
|
|
stay: "Unable to stay.",
|
2023-11-18 17:20:03 +00:00
|
|
|
"double_down": "Unable to double down.",
|
|
|
|
"buy_insurance": "Unable to buy insurance.",
|
2023-09-18 16:31:58 +00:00
|
|
|
"split": "Unable to split"
|
2022-12-29 10:58:51 +00:00
|
|
|
};
|
|
|
|
result = results[xhr.blackjackAction];
|
|
|
|
|
|
|
|
if (status == 429) {
|
|
|
|
result = error.message;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateResult(result, "danger");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateBlackjackActions(state) {
|
|
|
|
const actions = Array.from(document.querySelectorAll('.twentyone-btn'));
|
2023-09-18 16:31:58 +00:00
|
|
|
document.getElementById(`twentyone-SPLIT_ACTIONS`).style.display = 'none'
|
2022-12-29 10:58:51 +00:00
|
|
|
|
|
|
|
// Hide all actions.
|
|
|
|
actions.forEach(action => action.style.display = 'none');
|
|
|
|
|
|
|
|
if (state) {
|
2023-09-18 16:31:58 +00:00
|
|
|
if(state.actions.some((action) => action === 'HIT_SPLIT')) state.actions.push('SPLIT_ACTIONS');
|
|
|
|
|
2022-12-29 10:58:51 +00:00
|
|
|
// Show the correct ones.
|
|
|
|
state.actions.forEach(action => document.getElementById(`twentyone-${action}`).style.display = 'inline-block');
|
|
|
|
} else {
|
|
|
|
const dealButton = document.getElementById(`twentyone-DEAL`);
|
|
|
|
|
|
|
|
if (dealButton) {
|
|
|
|
dealButton.style.display = 'inline-block'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateBlackjackTable(state) {
|
|
|
|
const table = document.getElementById('blackjack-table');
|
|
|
|
const charactersToRanks = {
|
|
|
|
X: "10"
|
|
|
|
};
|
|
|
|
const charactersToSuits = {
|
|
|
|
S: "♠️",
|
|
|
|
H: "♥️",
|
|
|
|
C: "♣️",
|
|
|
|
D: "♦️",
|
|
|
|
};
|
|
|
|
const makeCardset = (from, who, value) => `
|
|
|
|
<div class="blackjack-cardset">
|
|
|
|
<div class="blackjack-cardset-value">
|
|
|
|
${value === -1 ? `${who} went bust` : `${who} has ${value}`}
|
|
|
|
</div>
|
|
|
|
${from
|
|
|
|
.filter(card => card !== "?")
|
|
|
|
.map(([rankCharacter, suitCharacter]) => {
|
|
|
|
const rank = charactersToRanks[rankCharacter] || rankCharacter;
|
|
|
|
const suit = charactersToSuits[suitCharacter] || suitCharacter;
|
|
|
|
return buildPlayingCard(rank, suit);
|
|
|
|
})
|
|
|
|
.join('')}
|
|
|
|
</div>
|
|
|
|
`;
|
|
|
|
const dealerCards = makeCardset(state.dealer, 'Dealer', state.dealer_value);
|
|
|
|
const playerCards = makeCardset(state.player, 'Player', state.player_value);
|
2023-09-18 16:31:58 +00:00
|
|
|
const playerSplitCards = state.has_player_split ? makeCardset(state.player_split, 'Player', state.player_split_value) : '';
|
2022-12-29 10:58:51 +00:00
|
|
|
|
|
|
|
updateBlackjackActions(state);
|
|
|
|
|
|
|
|
table.innerHTML = `
|
|
|
|
<div style="position: relative;">
|
|
|
|
${dealerCards}
|
|
|
|
</div>
|
|
|
|
${playerCards}
|
2023-09-18 16:31:58 +00:00
|
|
|
${playerSplitCards}
|
2022-12-29 10:58:51 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
const currency = state.wager.currency === 'coins' ? 'coins' : 'marseybux';
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
const gameCompleted = ['BLACKJACK', 'WON', 'PUSHED', 'LOST'].indexOf(state.status) !== -1 && (!state.has_player_split || ['WON', 'PUSHED', 'LOST'].indexOf(state.status_split) !== -1);
|
2023-09-28 23:58:09 +00:00
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
if(gameCompleted) {
|
|
|
|
switch (state.status) {
|
|
|
|
case 'BLACKJACK':
|
|
|
|
updateResult(`Blackjack: Received ${state.payout} ${currency}`, "warning");
|
|
|
|
break;
|
|
|
|
case 'WON':
|
|
|
|
if(state.status_split === 'LOST') {
|
|
|
|
updateResult(`Won and Lost: Received 0 ${currency}`, "success");
|
|
|
|
}
|
|
|
|
else if(state.status_split === 'PUSHED') {
|
|
|
|
updateResult(`Won and PUSHED: Received ${state.payout} ${currency}`, "success");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
updateResult(`Won: Received ${state.payout} ${currency}`, "success");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'PUSHED':
|
|
|
|
if(state.status_split === 'WON') {
|
|
|
|
updateResult(`Won and PUSHED: Received ${state.payout} ${currency}`, "success");
|
|
|
|
}
|
|
|
|
else if(state.status_split === 'LOST') {
|
|
|
|
updateResult(`Lost and Pushed: Lost ${state.wager.amount} ${currency}`, "danger");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
updateResult(`Pushed: Received ${state.wager.amount} ${currency}`, "success");
|
|
|
|
}
|
2023-09-28 23:58:09 +00:00
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
break;
|
|
|
|
case 'LOST':
|
|
|
|
if(state.status_split === 'WON') {
|
|
|
|
updateResult(`Won and Lost: Received 0 ${currency}`, "success");
|
|
|
|
}
|
|
|
|
else if(state.status_split === 'PUSHED') {
|
|
|
|
updateResult(`Lost and Pushed: Lost ${state.wager.amount} ${currency}`, "danger");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let lost = state.wager.amount;
|
|
|
|
if (state.player_doubled_down || state.has_player_split) {
|
|
|
|
lost *= 2;
|
|
|
|
}
|
|
|
|
updateResult(`Lost ${lost} ${currency}`, "danger");
|
|
|
|
}
|
2023-09-28 23:58:09 +00:00
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateCardsetBackgrounds(state, true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
updateCardsetBackgrounds(state);
|
2022-12-29 10:58:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
if (state.status === 'PLAYING' || (state.has_player_split && state.status_split === 'PLAYING')) {
|
2023-09-21 13:31:02 +00:00
|
|
|
updateResult(`${state.has_player_split ? state.wager.amount * 2 : state.wager.amount} ${currency} are at stake`, "success");
|
2022-12-29 10:58:51 +00:00
|
|
|
} else {
|
|
|
|
enableWager();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
function updateCardsetBackgrounds(state, complete = false) {
|
2022-12-29 10:58:51 +00:00
|
|
|
const cardsets = Array.from(document.querySelectorAll('.blackjack-cardset'));
|
|
|
|
|
|
|
|
for (const cardset of cardsets) {
|
|
|
|
['PLAYING', 'LOST', 'PUSHED', 'WON', 'BLACKJACK'].forEach(status => cardset.classList.remove(`blackjack-cardset__${status}`));
|
|
|
|
}
|
2023-09-18 16:31:58 +00:00
|
|
|
if(complete){
|
|
|
|
const wager = state.has_player_split ? state?.wager?.amount * 2 : state?.wager?.amount;
|
2023-10-12 13:13:41 +00:00
|
|
|
let dealerShows = state.payout < wager ? 'WON': 'LOST';
|
2023-10-13 12:19:10 +00:00
|
|
|
if(state.payout === wager || (state.player_doubled_down && state.status === 'PUSHED')) dealerShows = 'PUSHED'
|
2023-09-18 16:31:58 +00:00
|
|
|
cardsets[0]?.classList.add(`blackjack-cardset__${dealerShows}`)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
cardsets[0]?.classList.add(`blackjack-cardset__PLAYING`)
|
|
|
|
}
|
|
|
|
cardsets[1]?.classList.add(`blackjack-cardset__${state.status}`)
|
|
|
|
cardsets[2]?.classList.add(`blackjack-cardset__${state.status_split}`)
|
2022-12-29 10:58:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function deal() {
|
|
|
|
const request = makeBlackjackRequest('deal');
|
|
|
|
const { amount, currency } = getWager();
|
|
|
|
const form = new FormData();
|
|
|
|
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
form.append("wager", amount);
|
|
|
|
form.append("currency", currency);
|
|
|
|
|
|
|
|
request.send(form);
|
|
|
|
|
|
|
|
clearResult();
|
|
|
|
disableWager();
|
|
|
|
drawFromDeck();
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
function hit(split = false) {
|
|
|
|
const request = makeBlackjackRequest('hit', split);
|
2022-12-29 10:58:51 +00:00
|
|
|
const form = new FormData();
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
request.send(form);
|
|
|
|
|
|
|
|
drawFromDeck();
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
function hitSplit() {
|
|
|
|
hit(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function stay(split = false) {
|
|
|
|
const request = makeBlackjackRequest('stay', split);
|
2022-12-29 10:58:51 +00:00
|
|
|
const form = new FormData();
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
request.send(form);
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
function staySplit() {
|
|
|
|
stay(true);
|
|
|
|
}
|
|
|
|
|
2022-12-29 10:58:51 +00:00
|
|
|
function doubleDown() {
|
2023-11-18 17:20:03 +00:00
|
|
|
const request = makeBlackjackRequest('double_down');
|
2022-12-29 10:58:51 +00:00
|
|
|
const form = new FormData();
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
request.send(form);
|
|
|
|
|
|
|
|
drawFromDeck();
|
|
|
|
}
|
|
|
|
|
|
|
|
function buyInsurance() {
|
2023-11-18 17:20:03 +00:00
|
|
|
const request = makeBlackjackRequest('buy_insurance');
|
2022-12-29 10:58:51 +00:00
|
|
|
const form = new FormData();
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
request.send(form);
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:31:58 +00:00
|
|
|
function split() {
|
|
|
|
const request = makeBlackjackRequest('split');
|
|
|
|
const form = new FormData();
|
|
|
|
form.append("formkey", formkey());
|
|
|
|
request.send(form);
|
|
|
|
}
|
|
|
|
|
2022-12-29 10:58:51 +00:00
|
|
|
function buildBlackjackDeck() {
|
|
|
|
document.getElementById('blackjack-table-deck').innerHTML = `
|
|
|
|
<div style="position: absolute; top: 150px; left: -100px;">
|
|
|
|
${buildPlayingCardDeck()}
|
|
|
|
</div>
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initializeBlackjack() {
|
|
|
|
buildBlackjackDeck();
|
|
|
|
|
|
|
|
try {
|
|
|
|
const passed = document.getElementById('blackjack-table').dataset.state;
|
|
|
|
const state = JSON.parse(passed);
|
|
|
|
updateBlackjackTable(state);
|
|
|
|
} catch (error) {
|
|
|
|
updateBlackjackActions();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-29 14:20:27 +00:00
|
|
|
initializeBlackjack();
|