Joker Poker, feat. You have UNOOOO (#20598)

<img width="125" alt="dreamseeker_Ipg96rH5Bq"
src="https://github.com/user-attachments/assets/9da6e048-a33c-4198-90ee-e47a05fc85a0"
/>


![dreamseeker_z2UllenFYc](https://github.com/user-attachments/assets/2f6791fe-3a23-4534-9f40-9758eb62dd7d)

- rscadd: "Streamlines card mechanics. Click on others to deal to them,
yourself to draw. Ctrl-click to draw, Alt-click to shuffle."
- rscadd: "Adds KOTAHI, the shedding type card game fun for the whole
family."
  - rscadd: "Tweaks throw sound volume."
  - bugfix: "Fixes some runtimes with cards."
  - imageadd: "New sprites for playing cards."

Also seperates picking cards into it's own verb, and no more tooltips
when concealed. No more cheating.

(Also changes the throw sound volume, so it doesn't horribly spike the
volume when you're dealing normally)

KOTAHI sprites by CevUI, modified by myself.
This commit is contained in:
Wowzewow (Wezzy)
2025-04-13 10:14:05 +00:00
committed by GitHub
parent 621266cd8d
commit 305038f064
14 changed files with 334 additions and 115 deletions
+1
View File
@@ -2254,6 +2254,7 @@
#include "code\modules\games\cardemon.dm"
#include "code\modules\games\cards.dm"
#include "code\modules\games\gamehelm.dm"
#include "code\modules\games\kotahi.dm"
#include "code\modules\games\spaceball_cards.dm"
#include "code\modules\games\tarot.dm"
#include "code\modules\ghostroles\spawner\base.dm"
-2
View File
@@ -36,10 +36,8 @@
#define EQUIP_SOUND_VOLUME 30
#define PICKUP_SOUND_VOLUME 15
#define DROP_SOUND_VOLUME 20
#define YEET_SOUND_VOLUME 90
#define BLOCK_SOUND_VOLUME 70
//default byond sound environments
#define SOUND_ENVIRONMENT_OFF -2
#define SOUND_ENVIRONMENT_NONE -1
+2 -2
View File
@@ -455,12 +455,12 @@
if(SEND_SIGNAL(hit_atom, COMSIG_ATOM_PREHITBY, src, throwingdatum) & COMSIG_HIT_PREVENTED)
return
var/volume = get_volume_by_throwforce_and_or_w_class()
if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
var/mob/living/L = hit_atom
if(L.in_throw_mode)
playsound(hit_atom, pickup_sound, PICKUP_SOUND_VOLUME, TRUE)
else
var/volume = get_volume_by_throwforce_and_or_w_class()
if(throwforce > 0)
if(mob_throw_hit_sound)
playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1)
@@ -471,7 +471,7 @@
else
playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
else
playsound(src, drop_sound, YEET_SOUND_VOLUME)
playsound(src, drop_sound, volume)
var/itempush = TRUE
if(w_class < WEIGHT_CLASS_NORMAL)
+1 -1
View File
@@ -37,7 +37,7 @@
/obj/item/tajcard
name = "collectable tajaran card"
desc = "A collectable card with an illustration of a famous Tajaran figure, usually found inside cigarette packets."
icon = 'icons/obj/playing_cards.dmi'
icon = 'icons/obj/item/playing_cards.dmi'
icon_state = "tajcig"
drop_sound = 'sound/items/drop/paper.ogg'
pickup_sound = 'sound/items/pickup/paper.ogg'
+1 -1
View File
@@ -126,7 +126,7 @@
SPAN_NOTICE("You shuffle \the [src].")\
)
playsound(src.loc, 'sound/items/cardshuffle.ogg', 100, 1, -4)
playsound(src.loc, 'sound/items/cards/cardshuffle.ogg', 100, 1, -4)
stored_card_names = shuffle(stored_card_names)
@@ -11,6 +11,10 @@
display_name = "deck of cards"
path = /obj/item/deck/cards
/datum/gear/toy/kotahi
display_name = "KOTAHI cards"
path = /obj/item/deck/kotahi
/datum/gear/toy/tarot
display_name = "deck of tarot cards"
path = /obj/item/deck/tarot
+210 -104
View File
@@ -6,8 +6,23 @@
/obj/item/deck
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/playing_cards.dmi'
icon = 'icons/obj/item/playing_cards.dmi'
var/list/cards = list()
var/hand_type
/obj/item/deck/attack(mob/living/target_mob, mob/living/user, target_zone)
if (user.a_intent == I_HURT)
. = ..()
if(length(cards))
if(target_mob == user)
attack_self(user)
else
deal_card(user, target_mob)
/obj/item/deck/attack_self(mob/user, modifiers)
if(length(cards))
deal_card(user, user)
. = ..()
/obj/item/deck/proc/generate_deck() //the procs that creates the cards
return
@@ -15,9 +30,11 @@
/obj/item/deck/cards
name = "deck of cards"
desc = "A simple deck of playing cards."
desc_info = "Ctrl-click to draw/deal. Alt-click to shuffle."
icon_state = "deck"
drop_sound = 'sound/items/drop/paper.ogg'
pickup_sound = 'sound/items/pickup/paper.ogg'
hand_type = /obj/item/hand/cards
/obj/item/deck/Initialize()
. = ..()
@@ -27,27 +44,13 @@
var/datum/playingcard/P
for(var/suit in list("spades","clubs","diamonds","hearts"))
var/colour
if(suit == "spades" || suit == "clubs")
colour = "black_"
else
colour = "red_"
for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten"))
for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten", "jack","queen","king"))
P = new()
P.name = "[number] of [suit]"
P.card_icon = "[colour]num"
P.card_icon = "[number]_[suit]"
P.back_icon = "card_back"
cards += P
for(var/number in list("jack","queen","king"))
P = new()
P.name = "[number] of [suit]"
P.card_icon = "[colour]col"
P.back_icon = "card_back"
cards += P
for(var/i = 0,i<2,i++)
P = new()
P.name = "joker"
@@ -55,8 +58,8 @@
cards += P
/obj/item/deck/attack_hand(mob/user)
if(cards.len && (user.l_hand == src || user.r_hand == src))
draw_card(user, FALSE)
if(length(cards) && (user.l_hand == src || user.r_hand == src))
deal_card(user, user)
else
..()
@@ -66,24 +69,62 @@
for(var/datum/playingcard/P in H.cards)
cards += P
qdel(attacking_item)
to_chat(user, SPAN_NOTICE("You place your cards at the bottom of \the [src]."))
return
..()
/obj/item/deck/verb/draw_card()
/obj/item/deck/verb/drawcard()
set category = "Object"
set name = "Draw"
set desc = "Draw a card from a deck."
set desc = "Draw a card from the deck."
set src in view(1)
select_card(usr)
draw_card(usr)
/obj/item/deck/proc/select_card(var/mob/user)
if(use_check_and_message(user, USE_DISALLOW_SILICONS))
/obj/item/deck/proc/draw_card(var/mob/user)
if(use_check_and_message(user, USE_DISALLOW_SILICONS) || !Adjacent(user))
return
if(!iscarbon(user))
to_chat(user, SPAN_WARNING("Your simple form can't operate \the [src]."))
if(!cards.len)
if(!length(cards))
to_chat(usr, SPAN_WARNING("There are no cards in \the [src]."))
return
var/obj/item/hand/H
if(user.l_hand && istype(user.l_hand, /obj/item/hand))
H = user.l_hand
else if(user.r_hand && istype(user.r_hand, /obj/item/hand))
H = user.r_hand
else
H = new hand_type(get_turf(src))
H.concealed = TRUE
if(!user.put_in_hands(H))
return
if(!H || !user)
return
var/datum/playingcard/P = cards[1]
H.cards += P
cards -= P
H.update_icon()
balloon_alert_to_viewers("<b>\The [user]</b> draws a card.")
if(!length(cards))
qdel(src)
/obj/item/deck/verb/pickcard()
set category = "Object"
set name = "Pick"
set desc = "Pick a card from the deck."
set src in view(1)
pick_card(usr)
/obj/item/deck/proc/pick_card(var/mob/user)
if(use_check_and_message(user, USE_DISALLOW_SILICONS) || !Adjacent(user))
return
if(!iscarbon(user))
to_chat(user, SPAN_WARNING("Your simple form can't operate \the [src]."))
if(!length(cards))
to_chat(usr, SPAN_WARNING("There are no cards in \the [src]."))
return
@@ -93,7 +134,7 @@
else if(user.r_hand && istype(user.r_hand,/obj/item/hand))
H = user.r_hand
else
H = new /obj/item/hand(get_turf(src))
H = new hand_type(get_turf(src))
user.put_in_hands(H)
if(!H || !user)
@@ -102,7 +143,7 @@
var/list/to_discard = list()
for(var/datum/playingcard/P in cards)
to_discard[P.name] = P
var/discarding = tgui_input_list(user, "Which card do you wish to draw?", "Deck of Cards", to_discard)
var/discarding = tgui_input_list(user, "Which card do you wish to pick?", "Deck of Cards", to_discard)
if(!discarding || !to_discard[discarding] || !user || !src)
return
@@ -110,43 +151,60 @@
H.cards += P
cards -= P
H.update_icon()
user.visible_message("<b>\The [user]</b> draws a card.", SPAN_NOTICE("You draw the [P.name]."))
balloon_alert_to_viewers("<b>\The [user]</b> picks out a card.")
if(!length(cards))
qdel(src)
/obj/item/deck/verb/deal_card()
/obj/item/deck/verb/dealcard()
set category = "Object"
set name = "Deal"
set desc = "Deal a card from a deck."
set desc = "Deal a card from the deck."
set src in view(1)
if(usr.stat || !Adjacent(usr))
deal_card(usr, FALSE)
/obj/item/deck/proc/deal_card(mob/user, mob/living/target)
if(use_check_and_message(user, USE_DISALLOW_SILICONS) || !Adjacent(user))
return
if(!iscarbon(user))
to_chat(user, SPAN_WARNING("Your simple form can't operate \the [src]."))
if(!length(cards))
to_chat(usr, SPAN_WARNING("There are no cards in \the [src]."))
return
if(!cards.len)
to_chat(usr, SPAN_WARNING("There are no cards in the deck."))
if(!target)
var/list/players = list()
for(var/mob/living/player in viewers(3))
if(!player.stat)
players += player
target = tgui_input_list(usr, "Who do you wish to deal a card?", "Deal", players)
if(target == user)
draw_card(user)
return
var/list/players = list()
for(var/mob/living/player in viewers(3))
if(!player.stat)
players += player
if((istype(get_step(target,target.dir), /obj/machinery/door/window) || istype(get_step(target,target.dir), /obj/structure/window)) && target.density)
return // should stop you from dragging through windows
var/mob/living/M = tgui_input_list(usr, "Who do you wish to deal a card?", "Deal", players)
if(!usr || !src || !M) return
if(!length(cards))
to_chat(user, SPAN_WARNING("There are no cards in the deck."))
return
deal_at(usr, M)
var/obj/item/hand/H = new hand_type(user.loc)
/obj/item/deck/proc/deal_at(mob/user, mob/target)
var/obj/item/hand/H = new(get_step(user, user.dir))
H.randpixel = 6
H.randpixel_xy()
H.cards += cards[1]
cards -= cards[1]
H.concealed = 1
H.concealed = TRUE
H.update_icon()
if(user==target)
user.visible_message("<b>\The [user]</b> deals a card to [user.get_pronoun("himself")].")
else
user.visible_message("<b>\The [user]</b> deals a card to \the [target].")
H.throw_at(get_step(target,target.dir),10,1,H)
user.do_attack_animation(src, null)
balloon_alert_to_viewers("<b>\The [user]</b> deals a card.")
H.throw_at(get_step(target,target.dir), 10, 1, user, FALSE)
if(!length(cards))
qdel(src)
/obj/item/hand/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/hand))
@@ -158,45 +216,47 @@
qdel(src)
H.update_icon()
return
if(istype(attacking_item, /obj/item/deck))
var/obj/item/deck/D = attacking_item
for(var/datum/playingcard/P in cards)
D.cards += P
qdel(src)
return
..()
/obj/item/deck/attack_self(var/mob/user as mob)
/obj/item/deck/afterattack(obj/target, mob/user, proximity)
if(!ishuman(target))
return
var/mob/living/carbon/human/H = target
if(target == user)
return
if (H in range(user, 3))
deal_card(user, H)
/obj/item/deck/CtrlClick(var/mob/user as mob)
draw_card(user)
/obj/item/deck/AltClick(var/mob/user as mob)
. = ..()
var/list/newcards = list()
while(cards.len)
while(length(cards))
var/datum/playingcard/P = pick(cards)
newcards += P
cards -= P
cards = newcards
playsound(src.loc, 'sound/items/cardshuffle.ogg', 100, 1, -4)
user.visible_message("<b>\The [user]</b> shuffles [src].")
playsound(src.loc, 'sound/items/cards/cardshuffle.ogg', 100, 1, -4)
balloon_alert_to_viewers("<b>\The [user]</b> shuffles [src].")
/obj/item/deck/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params)
if(!user || !over)
return
if(!Adjacent(user) || !over.Adjacent(user))
return // should stop you from dragging through windows
if(!ishuman(over) || !(over in viewers(3)))
return
if(!cards.len)
to_chat(user, SPAN_WARNING("There are no cards in the deck."))
return
deal_at(user, over)
/obj/item/pack/
/obj/item/pack
name = "card pack"
desc = "For those with disposible income."
icon = 'icons/obj/playing_cards.dmi'
icon = 'icons/obj/item/playing_cards.dmi'
icon_state = "card_pack"
drop_sound = 'sound/items/drop/paper.ogg'
pickup_sound = 'sound/items/pickup/paper.ogg'
w_class = WEIGHT_CLASS_TINY
var/list/cards = list()
/obj/item/pack/attack_self(var/mob/user as mob)
user.visible_message("<b>\The [user]</b> rips open \the [src]!")
var/obj/item/hand/H = new()
@@ -211,18 +271,22 @@
/obj/item/hand
name = "hand of cards"
desc = "Some playing cards."
icon = 'icons/obj/playing_cards.dmi'
icon = 'icons/obj/item/playing_cards.dmi'
icon_state = null
drop_sound = 'sound/items/drop/paper.ogg'
pickup_sound = 'sound/items/pickup/paper.ogg'
w_class = WEIGHT_CLASS_TINY
var/deck_type
var/concealed = 0
var/concealed = TRUE
var/list/cards = list()
/obj/item/hand/cards
deck_type = /obj/item/deck/cards
/obj/item/hand/MouseEntered(location, control, params)
. = ..()
if(cards.len == 1 && (!concealed || Adjacent(usr)))
if(length(cards) == 1 && !concealed)
var/datum/playingcard/P = cards[1]
openToolTip(usr, src, params, P.name)
@@ -230,15 +294,15 @@
. = ..()
closeToolTip(usr)
/obj/item/hand/verb/discard()
/obj/item/hand/verb/pickcard()
set category = "Object"
set name = "Discard"
set desc = "Place a card from your hand in front of you."
set name = "Pick"
set desc = "Pick a card from your hand in front of you."
set src in usr
draw_card(usr)
pick_card(usr)
/obj/item/hand/proc/draw_card(var/mob/user, var/deploy_in_front = TRUE)
/obj/item/hand/proc/pick_card(var/mob/user, var/deploy_in_front = TRUE)
var/list/to_discard = list()
for(var/datum/playingcard/P in cards)
to_discard[P.name] = P
@@ -256,41 +320,57 @@
H.concealed = FALSE
H.update_icon()
src.update_icon()
playsound(src, 'sound/items/cards/cardflip.ogg', 50, TRUE)
balloon_alert_to_viewers("<b>\The [user]</b> picks out a card.")
if(deploy_in_front)
user.visible_message("<b>\The [user]</b> plays \the [discarding].")
H.forceMove(get_step(usr, usr.dir))
else
to_chat(user, SPAN_NOTICE("You draw \the [discarding]."))
user.put_in_hands(H)
if(!cards.len)
if(!length(cards))
qdel(src)
/obj/item/hand/attack_hand(mob/user)
if(cards.len > 1 && (user.l_hand == src || user.r_hand == src))
draw_card(user, FALSE)
if(length(cards) > 1 && (user.l_hand == src || user.r_hand == src))
pick_card(user, FALSE)
else
..()
/obj/item/hand/attack_self(var/mob/user as mob)
concealed(user)
/obj/item/hand/CtrlClick(var/mob/user as mob)
pick_card(user)
/obj/item/hand/AltClick(mob/user)
concealed(user)
/obj/item/hand/proc/concealed(var/mob/user as mob)
concealed = !concealed
update_icon()
user.visible_message("\The [user] [concealed ? "conceals" : "reveals"] their hand.")
if(locate(/obj/structure/table) in loc)
update_icon(user.dir)
else
update_icon()
playsound(src, 'sound/items/cards/cardflip.ogg', 50, TRUE)
balloon_alert_to_viewers("\The [user] [concealed ? "conceals" : "reveals"] their hand.")
/obj/item/hand/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
. = ..()
if((!concealed || src.loc == user) && cards.len)
if(cards.len > 1)
if((!concealed || src.loc == user) && length(cards))
if(length(cards) > 1)
. += "It contains: "
for(var/datum/playingcard/P in cards)
. += "The [P.name]. [P.desc ? "<i>[P.desc]</i>" : ""]"
/obj/item/hand/update_icon(var/direction = 0)
if(randpixel)
randpixel = 0
randpixel_xy(0)
if(!cards.len)
if(!length(cards))
qdel(src)
return
else if(cards.len > 1)
else if(length(cards) > 1)
name = "hand of cards"
desc = "Some playing cards."
else
@@ -299,29 +379,25 @@
ClearOverlays()
if(cards.len == 1)
if(length(cards) == 1)
var/datum/playingcard/P = cards[1]
var/image/I = new(src.icon, (concealed ? "[P.back_icon]" : "[P.card_icon]") )
I.pixel_x += (-5+rand(10))
I.pixel_y += (-5+rand(10))
AddOverlays(I)
return
var/offset = FLOOR(20/cards.len, 1)
var/offset = FLOOR(20/length(cards), 1)
var/matrix/M = matrix()
if(direction)
switch(direction)
if(NORTH)
M.Translate( 0, 0)
M.Turn(0)
if(SOUTH)
M.Translate( 0, 4)
M.Turn(180)
if(WEST)
M.Turn(90)
M.Translate( 3, 0)
M.Turn(270)
if(EAST)
M.Turn(90)
M.Translate(-2, 0)
var/i = 0
for(var/datum/playingcard/P in cards)
var/image/I = new(src.icon, (concealed ? "[P.back_icon]" : "[P.card_icon]") )
@@ -340,12 +416,42 @@
i++
/obj/item/hand/dropped(mob/user)
. = ..()
if(locate(/obj/structure/table, loc))
src.update_icon(user.dir)
..()
if(locate(/obj/structure/table) in get_step(user, user.dir))
update_icon(user.dir)
else
update_icon()
update_icon(0)
/obj/item/hand/pickup(mob/user as mob)
..()
src.update_icon()
update_icon()
/obj/item/hand/verb/deck_card()
set category = "Object"
set name = "Deck"
set desc = "Turn this hand of cards into a deck."
set src in usr
create_deck(usr)
/obj/item/hand/proc/create_deck(var/mob/user)
if(use_check_and_message(user, USE_DISALLOW_SILICONS) || !Adjacent(user))
return
if(!iscarbon(user))
to_chat(user, SPAN_WARNING("Your simple form can't operate \the [src]."))
if(!length(cards))
to_chat(usr, SPAN_WARNING("There are no cards in \the [src]."))
return
if(!deck_type)
to_chat(usr, SPAN_WARNING("You can't turn \the [src] into a deck."))
return
var/obj/item/deck/D = new deck_type(new(user.loc))
if(!D || !user)
return
D.cards = cards
balloon_alert_to_viewers("<b>\The [user]</b> turns his hand into a deck.")
qdel(src)
user.put_in_hands(D)
+38
View File
@@ -0,0 +1,38 @@
/obj/item/deck/kotahi
name = "\improper KOTAHI deck"
desc = "A deck of kotahi cards. House rules to argue over not included."
icon_state = "deck_kotahi"
hand_type = /obj/item/hand/kotahi
/obj/item/hand/kotahi
deck_type = /obj/item/deck/kotahi
/obj/item/deck/kotahi/generate_deck()
var/datum/playingcard/P
for(var/colour in list("red","yellow","green","blue"))
P = new()
P.name = "[colour] zero"
P.card_icon = "kotahi_[colour]_zero"
P.back_icon = "kotahi_back"
cards += P //kotahi decks have only one colour of each 0, weird huh?
for(var/number in list("skip","reverse","draw 2","one","two","three","four","five","six","seven","eight","nine")) //two of each colour of number
P = new()
P.name = "[colour] [number]"
P.card_icon = "kotahi_[colour]_[number]"
P.back_icon = "kotahi_back"
cards += P
cards += P
for(var/i = 0,i<4,i++) //4 wilds and draw 4s
P = new()
P.name = "wildcard"
P.card_icon = "kotahi_wild"
P.back_icon = "kotahi_back"
cards += P
for(var/i = 0,i<4,i++)
P = new()
P.name = "draw 4"
P.card_icon = "kotahi_draw4"
P.back_icon = "kotahi_back"
cards += P
+15 -5
View File
@@ -5,6 +5,10 @@
name = "deck of tarot cards"
desc = "For all your occult needs!"
icon_state = "deck_tarot"
hand_type = /obj/item/hand/tarot
/obj/item/hand/tarot
deck_type = /obj/item/deck/tarot
/obj/item/deck/tarot/generate_deck()
var/datum/playingcard/P
@@ -15,8 +19,6 @@
P.back_icon = "card_back_tarot"
cards += P
for(var/suit in list("wands","pentacles","cups","swords"))
for(var/number in list("ace","two","three","four","five","six","seven","eight","nine","ten","page","knight","queen","king"))
P = new()
P.name = "[number] of [suit]"
@@ -24,7 +26,7 @@
P.back_icon = "card_back_tarot"
cards += P
/obj/item/deck/tarot/attack_self(var/mob/user as mob)
/obj/item/deck/tarot/AltClick(var/mob/user as mob)
var/list/newcards = list()
while(cards.len)
var/datum/playingcard/P = pick(cards)
@@ -34,14 +36,18 @@
newcards += P
cards -= P
cards = newcards
playsound(src.loc, 'sound/items/cardshuffle.ogg', 100, 1, -4)
user.visible_message("\The [user] shuffles [src].")
playsound(src.loc, 'sound/items/cards/cardshuffle.ogg', 100, 1, -4)
user.visible_message("\The [user] shuffles \the [src].")
/obj/item/deck/tarot/adhomai
name = "adhomian divination cards deck"
desc = "An adhomian deck of divination cards, used to read the one's fortune or play games."
icon_state = "deck_adhomai"
hand_type = /obj/item/hand/tarot/adhomai
/obj/item/hand/tarot/adhomai
deck_type = /obj/item/deck/tarot/adhomai
/obj/item/deck/tarot/adhomai/generate_deck()
var/datum/playingcard/P
@@ -119,6 +125,10 @@
name = "qwei'paqui colonist deck"
desc = "A Skrellian deck of tarot cards depicting the local constellations of planets outside Nralakk."
icon_state = "deck_nonnralakk"
hand_type = /obj/item/hand/tarot/nonnralakk
/obj/item/hand/tarot/nonnralakk
deck_type = /obj/item/deck/tarot/nonnralakk
/obj/item/deck/tarot/nonnralakk/generate_deck()
var/datum/playingcard/P
+62
View File
@@ -0,0 +1,62 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# - (fixes bugs)
# wip
# - (work in progress)
# qol
# - (quality of life)
# soundadd
# - (adds a sound)
# sounddel
# - (removes a sound)
# rscadd
# - (adds a feature)
# rscdel
# - (removes a feature)
# imageadd
# - (adds an image or sprite)
# imagedel
# - (removes an image or sprite)
# spellcheck
# - (fixes spelling or grammar)
# experiment
# - (experimental change)
# balance
# - (balance changes)
# code_imp
# - (misc internal code change)
# refactor
# - (refactors code)
# config
# - (makes a change to the config files)
# admin
# - (makes changes to administrator tools)
# server
# - (miscellaneous changes to server)
#################################
# Your name.
author: Wowzewow (Wezzy)
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Streamlines card mechanics. Click on others to deal to them, yourself to draw. Ctrl-click to draw, Alt-click to shuffle."
- rscadd: "Adds KOTAHI, the shedding type card game fun for the whole family."
- rscadd: "Tweaks throw sound volume."
- bugfix: "Fixes some runtimes with cards."
- imageadd: "New sprites for playing cards."
Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.