mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* Ports SSnetworks killings * Update names.dm * Removes my debug message and fixes instances it caught
278 lines
8.2 KiB
Plaintext
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
|