Files
Yogstation/code/modules/modular_computers/file_system/programs/blackjack.dm
John Willard 4212a5c805 Ports SSnetworks killings (#22104)
* Ports SSnetworks killings

* Update names.dm

* Removes my debug message and fixes instances it caught
2024-05-31 00:22:12 -05:00

278 lines
8.2 KiB
Plaintext

#define BLACKJACK_CONTINUE 0
#define BLACKJACK_LOSS 1
#define BLACKJACK_WIN 2
#define BLACKJACK_TIE 3
#define BLACKJACK_IDLE 4
#define BLACKJACK_DEALER_TURN 5
#define JACK_CARD "J"
#define QUEEN_CARD "Q"
#define KING_CARD "K"
#define ACE_CARD "A"
/datum/computer_file/program/blackjack
filename = "blackjack"
filedesc = "Nanotrasen Micro Arcade: Blackjack"
program_icon_state = "arcade"
extended_desc = "Nanotrasen does not permit anyone under the age of 21 to partake in gambling. Requires an NTNet connection."
requires_ntnet = TRUE
category = PROGRAM_CATEGORY_GAMES
network_destination = "arcade network"
size = 4
tgui_id = "NtosBlackjack"
program_icon = "gamepad"
var/game_state = BLACKJACK_IDLE
/// Card format is value and suit i.e. "2H" = 2 of Hearts, "KC" = King of Clubs
var/list/active_player_cards = list()
var/list/active_dealer_cards = list()
var/list/current_deck = list()
var/credits_stored = 0
var/active_wager = 0
var/set_wager = 5
var/game_end_reason = ""
var/game_id = 0
var/datum/bank_account/temp_account // Call refresh_id_account() or get_credit_amount() before using this
/datum/computer_file/program/blackjack/proc/refresh_id_account()
temp_account = null
if(holder && istype(holder.holder, /obj/item/modular_computer))
var/obj/item/modular_computer/computer = holder.holder
var/obj/item/card/id/stored_card = computer.GetID()
if(istype(stored_card) && istype(stored_card.registered_account))
temp_account = stored_card.registered_account
return stored_card.registered_account
/datum/computer_file/program/blackjack/proc/get_credit_amount()
refresh_id_account()
return temp_account?.account_balance || credits_stored
/datum/computer_file/program/blackjack/proc/adjust_credits(amt)
if(refresh_id_account())
temp_account.adjust_money(amt)
else
credits_stored += amt
/datum/computer_file/program/blackjack/proc/new_game()
if(set_wager <= 0 || get_credit_amount() < set_wager)
return
game_id++
adjust_credits(-set_wager)
active_wager = set_wager
game_state = BLACKJACK_CONTINUE
game_end_reason = ""
active_player_cards = list()
active_dealer_cards = list()
current_deck = list(
"2S","3S","4S","5S","6S","7S","8S","9S","10S","JS","QS","KS","AS",
"2H","3H","4H","5H","6H","7H","8H","9H","10H","JH","QH","KH","AH",
"2C","3C","4C","5C","6C","7C","8C","9C","10C","JC","QC","KC","AC",
"2D","3D","4D","5D","6D","7D","8D","9D","10D","JD","QD","KD","AD"
)
shuffle_inplace(current_deck)
// smooth
play_snd('sound/machines/switch3.ogg')
active_player_cards += pop(current_deck)
active_dealer_cards += pop(current_deck)
active_player_cards += pop(current_deck)
/datum/computer_file/program/blackjack/proc/calculate_hand_worth(list/hand)
var/worth = 0
var/aces = 0
var/list/hand_copy = LAZYCOPY(hand)
for(var/card in hand_copy)
card = copytext(card, 1, -1) // Remove the suit, we do not care about it
if(text2num(card))
worth += text2num(card)
else
switch(card)
if(JACK_CARD, QUEEN_CARD, KING_CARD) // "Picture" cards are worth 10
worth += 10
if(ACE_CARD) // Aces are calculated last
aces += 1
for(var/i in 1 to aces) // Ace is worth either 1 or 11, whichever is more beneficial
if(worth < 12 - aces) // This algorithm will never surpass 21 unless you have too many aces (somehow)
worth += 11
else
worth += 1
return worth
/datum/computer_file/program/blackjack/ui_data(mob/user)
var/list/data = get_header_data()
data["game_state"] = game_state
data["active_dealer_cards"] = active_dealer_cards
data["active_player_cards"] = active_player_cards
data["credits_stored"] = get_credit_amount()
data["local_credits"] = credits_stored
data["has_id"] = !!temp_account
data["active_wager"] = active_wager
data["set_wager"] = set_wager
data["game_end_reason"] = game_end_reason
return data
/datum/computer_file/program/blackjack/try_insert(obj/item/inserted_item, mob/living/user)
if(!holder || !istype(holder?.holder, /obj/item/modular_computer))
return FALSE
if(!inserted_item.get_item_credit_value())
return FALSE
credits_stored += inserted_item.get_item_credit_value()
QDEL_NULL(inserted_item)
play_snd('sound/machines/ping.ogg')
SStgui.try_update_ui(user, src)
return TRUE
/datum/computer_file/program/blackjack/proc/play_snd(sound_path)
if(holder && istype(holder.holder, /obj/item/modular_computer))
var/obj/item/modular_computer/computer = holder.holder
computer.play_computer_sound(sound_path, 40, 1)
/datum/computer_file/program/blackjack/ui_act(action, list/params, datum/tgui/ui)
. = ..()
if(..())
return .
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
if(user.age < 21) // We do not condone underage gambling
play_snd('sound/machines/buzz-sigh.ogg')
return FALSE
switch(action)
if("PRG_new_game")
new_game()
return TRUE
if("PRG_eject_credits")
if(credits_stored < 1)
return FALSE
var/obj/item/holochip/holochip = new (usr.drop_location(), credits_stored)
usr.put_in_hands(holochip)
to_chat(usr, span_notice("You withdraw [credits_stored] credits into a holochip."))
credits_stored = 0
play_snd('sound/machines/click.ogg')
return TRUE
if("PRG_set_wager")
if(!isnum(text2num(params["wager"])))
return FALSE
var/new_wager = text2num(params["wager"])
if(round(new_wager) < 1)
return FALSE
set_wager = round(new_wager)
play_snd('sound/machines/click.ogg')
return TRUE
if("PRG_hit")
if(game_state != BLACKJACK_CONTINUE)
return FALSE
play_snd('sound/machines/switch3.ogg')
active_player_cards += pop(current_deck)
check_player_hand(usr)
return TRUE
if("PRG_stand")
if(game_state != BLACKJACK_CONTINUE)
return FALSE
game_state = BLACKJACK_DEALER_TURN
addtimer(CALLBACK(src, PROC_REF(dealer_turn), game_id, usr), 1 SECONDS)
play_snd('sound/machines/click.ogg')
return TRUE
if("PRG_double_down")
if(game_state != BLACKJACK_CONTINUE)
return FALSE
if(get_credit_amount() < active_wager)
return
adjust_credits(-active_wager)
active_wager *= 2
play_snd('sound/machines/switch3.ogg')
active_player_cards += pop(current_deck)
if(!check_player_hand(usr))
game_state = BLACKJACK_DEALER_TURN
addtimer(CALLBACK(src, PROC_REF(dealer_turn), game_id, usr), 1 SECONDS)
return TRUE
/datum/computer_file/program/blackjack/proc/check_player_hand(mob/user)
var/worth = calculate_hand_worth(active_player_cards)
if(worth == 21)
game_state = BLACKJACK_DEALER_TURN
addtimer(CALLBACK(src, PROC_REF(dealer_turn), game_id, user), 1 SECONDS)
return TRUE
if(worth > 21)
game_state = BLACKJACK_LOSS
game_end_reason = "You busted!"
active_wager = 0
play_snd('sound/machines/buzz-two.ogg')
return TRUE
return FALSE
/datum/computer_file/program/blackjack/proc/dealer_turn(g_id, mob/user)
if(game_state != BLACKJACK_DEALER_TURN || game_id != g_id)
return
play_snd('sound/machines/switch1.ogg')
active_dealer_cards += pop(current_deck)
SStgui.try_update_ui(user, src)
var/dealer_worth = calculate_hand_worth(active_dealer_cards)
if(dealer_worth < 17) // Dealer draws until it has 17 or higher
addtimer(CALLBACK(src, PROC_REF(dealer_turn), game_id, user), 1 SECONDS)
return
var/player_worth = calculate_hand_worth(active_player_cards)
// check_player_hand() already checked for player bust
if(dealer_worth == player_worth)
game_state = BLACKJACK_TIE
adjust_credits(active_wager)
active_wager = 0
SStgui.try_update_ui(user, src)
play_snd('sound/machines/button1.ogg')
return
if(dealer_worth > 21 || player_worth > dealer_worth)
if(dealer_worth > 21)
game_end_reason = "Dealer busted!"
else
game_end_reason = "You won!"
game_state = BLACKJACK_WIN
adjust_credits(active_wager * 2)
active_wager = 0
SStgui.try_update_ui(user, src)
play_snd('sound/machines/chime.ogg')
return
if(player_worth < dealer_worth) // this is redundant, but it helps understand what is happening
game_state = BLACKJACK_LOSS // | || || |_
game_end_reason = "You lost!"
active_wager = 0
SStgui.try_update_ui(user, src)
play_snd('sound/machines/buzz-two.ogg')
return
#undef BLACKJACK_CONTINUE
#undef BLACKJACK_LOSS
#undef BLACKJACK_WIN
#undef BLACKJACK_TIE
#undef BLACKJACK_IDLE
#undef BLACKJACK_DEALER_TURN
#undef JACK_CARD
#undef QUEEN_CARD
#undef KING_CARD
#undef ACE_CARD