diff --git a/code/_globalvars/lists/maint_loot_tables.dm b/code/_globalvars/lists/maint_loot_tables.dm index e77957d72a9..918287d43a6 100644 --- a/code/_globalvars/lists/maint_loot_tables.dm +++ b/code/_globalvars/lists/maint_loot_tables.dm @@ -104,6 +104,7 @@ GLOBAL_LIST_INIT(maintenance_loot_tier_1, list( /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/emergency_oxygen/engi, /obj/item/vending_refill/cola, + /obj/item/cardpack/series_one, ) = 85, list( diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index 09b35a6246d..ee8e5bb505e 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -30,7 +30,8 @@ /obj/item/photo, /obj/item/reagent_containers/dropper, /obj/item/screwdriver, - /obj/item/stamp) + /obj/item/stamp, + /obj/item/tcg_card) cant_hold = list( /obj/item/screwdriver/power ) diff --git a/code/modules/economy/merch_items.dm b/code/modules/economy/merch_items.dm index 1344ad8021a..bbc978315c8 100644 --- a/code/modules/economy/merch_items.dm +++ b/code/modules/economy/merch_items.dm @@ -75,6 +75,13 @@ cost = 200 category = MERCH_CAT_TOY +/datum/merch_item/tcg/series_one + name = "Battles of Orion: Series 1" + desc = "The brand-new trading card game on the scene with all your favorite Nanotrasen employees!" + typepath = /obj/item/cardpack/series_one + cost = 100 + category = MERCH_CAT_TOY + /datum/merch_item/katana name = "Replica Katana" desc = "Woefully underpowered in D20." diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index aa465ed3c75..7f2a64ef5a4 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -496,6 +496,16 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ name_by_cmineral = FALSE heads_name = "valid" +/obj/item/coin/thunderdome + name = "thunderdome flipper" + icon_state = "coin_thunderdome_nanotrasen" + cmineral = "thunderdome" + desc = "A Thunderdome TCG flipper, for deciding who gets to go first. Also conveniently acts as a counter, for various purposes." + sideslist = list("nanotrasen", "syndicate") + credits = 20 + name_by_cmineral = FALSE + heads_name = "nanotrasen" + /obj/item/coin/antagtoken/syndicate name = "syndicate coin" credits = 160 diff --git a/code/modules/tcg/pack_1.dm b/code/modules/tcg/pack_1.dm new file mode 100644 index 00000000000..0c7315fc49c --- /dev/null +++ b/code/modules/tcg/pack_1.dm @@ -0,0 +1,316 @@ +/datum/tcg_card/pack_1/ + name = "" + desc = "" + icon_state = "" + rarity = "" + card_type = "" + +// COMMAND + +/datum/tcg_card/pack_1/captain + name = "Captain" + desc = "The head of every Nanotrasen space station who spends most of their shift delegating and protecting the disk." + icon_state = "captain" + rarity = "Rare" + card_type = "Unit" + +/datum/tcg_card/pack_1/renault + name = "Renault" + desc = "The Captain's trusty pet fox who spends most shifts walking around aimlessly in the Captain's Office." + icon_state = "renault" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/ce + name = "Chief Engineer" + desc = "The head of the engineering department and the one who ensures the station runs smoothly. Most of them fail at this." + icon_state = "ce" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/hop + name = "Head of Personnel" + desc = "Never far far from their closest pal, Ian, they defend the ability to give out AA to anyone who passes." + icon_state = "hop" + rarity = "Rare" + card_type = "Unit" + +/datum/tcg_card/pack_1/rd + name = "Research Director" + desc = "The head of the science department who has to wrangle their explosion prone workers around." + icon_state = "rd" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/hos + name = "Head of Security" + desc = "The head of the security department, charged with putting away Syndicate and Assistant scum alike." + icon_state = "hos" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/cmo + name = "Chief Medical Officer" + desc = "The head of the medical department who makes sure their department isn't committing any intentional or unintentional malpractice." + icon_state = "cmo" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/qm + name = "Quartermaster" + desc = "The head of the supply department that makes sure everyone gets their crates and their ores." + icon_state = "qm" + rarity = "Uncommon" + card_type = "Unit" + +// ENGINEERING + +/datum/tcg_card/pack_1/atmos_tech + name = "Atmospheric Technician" + desc = "The workers of the Engineering department who ensure the air is breathable and devoid of anything harmful." + icon_state = "atmos_tech" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/engineer + name = "Station Engineer" + desc = "The main working arm of the Engineering department, Station Engineers keep the hull and all the machines within intact." + icon_state = "engineer" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/poly + name = "Poly" + desc = "An expert in quantum cracker theory, she continues to scare enginee- INTEGRITY FAILING!" + icon_state = "poly" + rarity = "Uncommon" + card_type = "Unit" + +// MEDICAL + +/datum/tcg_card/pack_1/doctor + name = "Medical Doctor" + desc = "Medical Doctors are able to cure almost any ailment that may be inflicted on a worker... while also inflicting some themself." + icon_state = "doctor" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/chemist + name = "Chemist" + desc = "Chemists are definitely not producing meth instead of life-saving chemicals." + icon_state = "chemist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/paramedic + name = "Paramedic" + desc = "The Medical Department's first response member responsible for stabilizing and rescuing Nanotrasen employees." + icon_state = "paramedic" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/virologist + name = "Virologist" + desc = "The virologist is the person you go crying to that you either have the common cold or a disease that kills you in a few minutes. They might have been the cause of both of them." + icon_state = "virologist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/coroner + name = "Coroner" + desc = "Overseer of the morgue, the coroner ensures that dead bodies are properly stored and have their autopsies recorded." + icon_state = "coroner" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/psychologist + name = "Psychologist" + desc = "Hired to offer emotional reassurance to employees aboard Nanotrasen stations but is usually found secretly dealing their drugs to anyone who asks." + icon_state = "psych" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/runtime // the urge to make this card throw a runtime. + name = "Runtime" + desc = "GCAT. Somehow, the four letters used in genomes can spell cat. How purr-ious." + icon_state = "runtime" + rarity = "Uncommon" + card_type = "Unit" + +// RESEARCH + +/datum/tcg_card/pack_1/geneticist + name = "Geneticist" + desc = "Tasked with manipulating humanoid DNA, the Geneticist is able to give out genetic powers to their fellow crew." + icon_state = "geneticist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/roboticist + name = "Roboticist" + desc = "The maintainer of all things cyborg, Roboticists build and maintain cyborgs for the station and are able to build a wide variety of exosuits." + icon_state = "roboticist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/scientist + name = "Scientist" + desc = "A Scientist's job ranges from manning the R&D desk, to mixing chemicals, to setting up tank transfer valve bombs" + icon_state = "scientist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/en + name = "E-N" + desc = "Robotics' adorable and lovable clone of Ian, he's got a heart of gold and can even do your taxes for you! Beware any unexpected sparking though." + icon_state = "e-n" + rarity = "Uncommon" + card_type = "Unit" + +// SECURITY + +/datum/tcg_card/pack_1/warden + name = "Warden" + desc = "Watcher of the armory and the prison wing, the Warden expertly puts down rowdy criminals with Krav Maga." + icon_state = "warden" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/officer + name = "Security Officer" + desc = "The sworn enemy of any greytider, Security Officers are hired to keep the station in order and free of crime." + icon_state = "officer" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/detective + name = "Detective" + desc = "Sometimes masquerading as a noir detective, the Detective uses their deductive skills to help Security find suspects of crimes." + icon_state = "detective" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/araneus + name = "Sergeant Araneus" + desc = "The Head of Security's trusty pet spider is known for her violent retaliations torwards mistreatment." + icon_state = "araneus" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/paperwork + name = "Paperwork" + desc = "The Internal Affair's pet sloth is as mopey as can be and can sometimes get around to eating paperwork. Still slightly faster than a legal case." + icon_state = "paperwork" + rarity = "Uncommon" + card_type = "Unit" + +// SERVICE + +/datum/tcg_card/pack_1/botanist + name = "Botanist" + desc = "The main ingredient provider for the chef, skilled botanist can produce plants that can fill a crewmember up and kill them just as quickly." + icon_state = "botanist" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/mime + name = "Mime" + desc = "..." + icon_state = "mime" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/clown + name = "Clown" + desc = "Honk!" + icon_state = "clown" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/janitor + name = "Janitor" + desc = "The humble Janitor travels the station in search of any messes that need cleaning." + icon_state = "janitor" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/chef + name = "Chef" + desc = "Wielder of CQC within their kitchen, the Chef protects their kitchen from any invaders trying to disrupt the distribution of food to the crew." + icon_state = "chef" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/bartender + name = "Bartender" + desc = "The station's OTHER source of emotional reassurance, the Bartender serves alcohol to anyone who wants it while shooting any disruptive patrons with their shotgun." + icon_state = "bartender" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/chaplain + name = "Chaplain" + desc = "The spirtual leader of the station, the Chaplain offers unique services due to their connection with religious higher-ups." + icon_state = "chaplain" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/librarian + name = "Librarian" + desc = "Usually found within their library writing and printing books, the Librarian is able to loan out books full of knowledge. Don't forget to return them!" + icon_state = "librarian" + rarity = "Common" + card_type = "Unit" + +// SUPPLY + +/datum/tcg_card/pack_1/cargo_tech + name = "Cargo Technician" + desc = "The main workhorse of the Supply department, Cargo Technicians ensure your crates are delivered soon after you order them." + icon_state = "cargo_tech" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/miner + name = "Shaft Miner" + desc = "Pioneers of Lavaland, Shaft Miners brave the horrors in order to bring materials to the station." + icon_state = "miner" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/forklift + name = "Forklift" + desc = "Supply's pet of choice, Forklift has been taught how to carry crates and wouldn't hurt a fly!" + icon_state = "forklift" + rarity = "Uncommon" + card_type = "Unit" + +/datum/tcg_card/pack_1/brad + name = "Brad" + desc = "Residing just on the outskirts of the Mining Outpost, Brad is a cockroach that has adapted to the weather patterns of Lavaland and can withstand them." + icon_state = "brad" + rarity = "Uncommon" + card_type = "Unit" + +// MISC + +/datum/tcg_card/pack_1/assistant + name = "Assistant" + desc = "Hired to assist employees around the station, Assistants tend to do the exact opposite of that." + icon_state = "assistant" + rarity = "Common" + card_type = "Unit" + +/datum/tcg_card/pack_1/greytide + name = "Greytide" + desc = "Born from disgruntled and abused Assistants, the Greytide are a nuisance to Security and the rest of the station alike." + icon_state = "greytide" + rarity = "Rare" + card_type = "Unit" + +/datum/tcg_card/pack_1/mouse + name = "Mouse" + desc = "The bane of engineers around the sector, the Mouse makes any cables they find a nice meal for themself." + icon_state = "mouse" + rarity = "Common" + card_type = "Unit" diff --git a/code/modules/tcg/tcg_cards.dm b/code/modules/tcg/tcg_cards.dm new file mode 100644 index 00000000000..b21af44328a --- /dev/null +++ b/code/modules/tcg/tcg_cards.dm @@ -0,0 +1,461 @@ +#define ROTATED_ANGLE 90 +#define UNROTATED_ANGLE 0 + +// Need a TCG coin or two to replace the gold one that can be dropped. Make it shrink like the cards/packs + +/datum/tcg_card + var/name = "Chrono Legionnare" + var/desc = "You shouldn't be seeing this. You should ahelp this!" + var/icon_state = "chrono" + var/pack = 'icons/obj/tcg/pack1.dmi' + + // This will be probably implemented.... sometime. + // var/health = 0 + // var/attack = 0 + // var/mana = 0 + + var/faction = "Coderbus" + var/rarity = "Unobtainable" + var/card_type = "Unit" + + var/obj/item/tcg_card/card + +/datum/tcg_card/proc/UseSelf(mob/living/user) + return + +/datum/tcg_card/proc/Rotate(mob/living/user) + return + +/datum/tcg_card/proc/Unrotate(mob/living/user) + return + +/obj/item/tcg_card + name = "trading card" + desc = "A flipped trading card." + icon_state = "cardback" + icon = 'icons/obj/tcg/pack1.dmi' + new_attack_chain = TRUE + var/datum_type = /datum/tcg_card + var/datum/tcg_card/card_datum + var/flipped = FALSE + var/rotated = FALSE + + w_class = WEIGHT_CLASS_TINY + +/obj/item/tcg_card/examine(mob/user) + . = ..() + if(flipped) + return + + . += "" + . += "This card has the following stats:" + . += "Rarity: [card_datum.rarity]" + . += "Card Type: [card_datum.card_type]" + +/obj/item/tcg_card/equipped(mob/user, slot, initial) + . = ..() + transform = matrix() + +/obj/item/tcg_card/dropped(mob/user, silent) + . = ..() + transform = matrix(0.5,0,0,0,0.5,0) + +/obj/item/tcg_card/activate_self(mob/user) + if(..()) + return ITEM_INTERACT_COMPLETE + + if(flipped) + flipped = !flipped + if(!flipped) + flipped = TRUE + return ITEM_INTERACT_COMPLETE + +/obj/item/tcg_card/New(loc, new_datum) + . = ..() + + if(new_datum) + datum_type = new_datum + card_datum = new datum_type + icon = card_datum.pack + icon_state = card_datum.icon_state + name = card_datum.name + desc = card_datum.desc + +/obj/item/tcg_card/attack_hand(mob/user) + var/list/choices = list( + "Pick Up" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup"), + "Rotate" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_rotate"), + "Flip" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_flip"), + ) + var/result = show_radial_menu(user, src, choices, require_near = TRUE) + switch(result) + if("Pick Up") + . = ..() + if("Flip") + flipped = !flipped + if(flipped) + icon_state = "cardback" + name = "Battles of Orion card" + desc = "A flipped Battles of Orion-branded card." + else + name = card_datum.name + desc = card_datum.desc + icon_state = card_datum.icon_state + if("Rotate") + var/matrix/ntransform = matrix(transform) + if(rotated) + ntransform.TurnTo(ROTATED_ANGLE , UNROTATED_ANGLE) + else + ntransform.TurnTo(UNROTATED_ANGLE , ROTATED_ANGLE) + rotated = !rotated + animate(src, transform = ntransform, time = 2, easing = (EASE_IN|EASE_OUT)) + if(rotated) + card_datum.Rotate(user) + else + card_datum.Unrotate(user) + +/obj/item/tcg_card/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/tcg_card)) + var/obj/item/tcg_card/second_card = used + if(loc == user && second_card.loc == user) + var/obj/item/tcgcard_hand/hand = new(get_turf(user)) + user.unequip(src) + user.unequip(second_card) + src.forceMove(hand) + second_card.forceMove(hand) + hand.cards.Add(src) + hand.cards.Add(second_card) + user.put_in_hands(hand) + hand.update_icon() + return ITEM_INTERACT_COMPLETE + + var/obj/item/tcgcard_deck/new_deck = new /obj/item/tcgcard_deck(drop_location()) + new_deck.flipped = flipped + user.unequip(second_card) + second_card.forceMove(new_deck) + src.forceMove(new_deck) + new_deck.update_icon(UPDATE_ICON_STATE) + new_deck.update_icon() + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/tcgcard_deck)) + var/obj/item/tcgcard_deck/old_deck = used + if(length(old_deck.contents) >= 30) + to_chat(user, "This pile has too many cards for a regular deck!") + return ITEM_INTERACT_COMPLETE + user.unequip(src) + src.forceMove(old_deck) + flipped = old_deck.flipped + old_deck.update_icon() + update_icon() + return ITEM_INTERACT_COMPLETE + + return ..() + +/obj/item/cardpack + name = "Trading Card Pack: Chrono & Friends" + desc = "This unobtainable group certainly shouldn't be findable and you should ahelp this!" + icon = 'icons/obj/tcg/misc.dmi' + icon_state = "cardpack" + w_class = WEIGHT_CLASS_TINY + new_attack_chain = TRUE + /// The card series to look through + var/list/series = list(/datum/tcg_card/pack_1) + /// The chance there will be a coin in the pack + var/contains_coin = -1 + /// The amount of cards you draw + var/card_count = 5 + /// The rarity table + var/list/rarity_table = list( + "Common" = 900, + "Uncommon" = 300, + "Rare" = 50, + "Legendary" = 3 + ) + /// The amount of cards to draw from the guarenteed rarity table + var/guaranteed_count = 1 + /// The guaranteed rarity table, acts about the same as the rarity table. + var/list/guar_rarity = list( + "Uncommon" = 30, + "Rare" = 9, + "Legendary" = 1 + ) + +/obj/item/cardpack/series_one + name = "Battles of Orion: Series 1" + desc = "Contains five cards from the Series 1 of Battles of Orion! Collect them all!" + series = list(/datum/tcg_card/pack_1) + contains_coin = 10 + +/obj/item/cardpack/equipped(mob/user, slot, initial) + . = ..() + transform = matrix() + +/obj/item/cardpack/dropped(mob/user, silent) + . = ..() + transform = matrix(0.5,0,0,0,0.5,0) + +/obj/item/cardpack/activate_self(mob/user) + if(..()) + return ITEM_INTERACT_COMPLETE + + var/list/cards = buildCardListWithRarity(card_count, guaranteed_count) + var/obj/item/tcgcard_hand/hand = new(get_turf(user)) + + for(var/template in cards) + var/obj/item/tcg_card/card = new(hand, template) + hand.cards.Add(card) + user.put_in_hands(hand) + hand.update_icon() + to_chat(user, "Wow! Check out these cards!") + playsound(loc, 'sound/items/poster_ripped.ogg', 20, TRUE) + if(prob(contains_coin)) + to_chat(user, "...and it came with a flipper, too!") + new /obj/item/coin/thunderdome(get_turf(user)) + // new rulebook goes here + qdel(src) + return ITEM_INTERACT_COMPLETE + +/obj/item/cardpack/proc/buildCardListWithRarity(card_cnt, rarity_cnt) + var/list/return_cards = list() + + var/list/cards = list() + for(var/card_type in series) + for(var/card in subtypesof(card_type)) + var/datum/tcg_card/new_card = new card() + if(new_card.name == "Chrono Legionnare") + continue + cards.Add(card) + qdel(new_card) + var/list/possible_cards = list() + var/list/rarity_cards = list("Legendary" = list(),"Rare" = list(),"Uncommon" = list(),"Common" = list()) + for(var/card in cards) + var/datum/tcg_card/new_card = new card() + if(new_card.name == "Stupid Coder") + continue + possible_cards[card] = rarity_table[new_card.rarity] + var/list/rarity_card_type = rarity_cards[new_card.rarity] + if(!rarity_card_type) + rarity_card_type = list() + rarity_card_type.Add(card) + rarity_cards[new_card.rarity] = rarity_card_type + qdel(new_card) + + for(var/card_counter = 1 to card_count) + var/cardtype = pickweight(possible_cards) + return_cards.Add(cardtype) + + for(var/card_counter = 1 to guaranteed_count) + var/card_list = pickweight(guar_rarity) + return_cards.Add(pick(rarity_cards[card_list])) + + return return_cards + +/obj/item/tcgcard_deck + name = "Trading Card Deck" + desc = "A stack of Battle of Orion cards." + icon = 'icons/obj/tcg/misc.dmi' + icon_state = "deck_up" + w_class = WEIGHT_CLASS_TINY + new_attack_chain = TRUE + + var/flipped = TRUE + var/max_cards = 30 + +/obj/item/tcgcard_deck/examine(mob/user) + . = ..() + . += "\The [src] has [contents.len] cards inside." + +/obj/item/tcgcard_deck/update_icon() + . = ..() + cut_overlays() + if(flipped) + switch(contents.len) + if(1 to 10) + icon_state = "deck_low" + if(11 to 20) + icon_state = "deck_half" + if(21 to INFINITY) + icon_state = "deck_full" + else + icon_state = "deck_up" + +/obj/item/tcgcard_deck/Destroy() + for(var/obj/item/tcg_card/stored_card in contents) + stored_card.forceMove(drop_location()) + . = ..() + +/obj/item/tcgcard_deck/attack_hand(mob/user) + var/list/choices = list( + "Draw" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_draw"), + "Shuffle" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_shuffle"), + "Pickup" = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_pickup"), + ) + var/choice = show_radial_menu(user, src, choices, require_near = TRUE) + if(!check_menu(user)) + return + switch(choice) + if("Draw") + draw_card(user) + if("Shuffle") + shuffle_deck(user) + if("Pickup") + user.put_in_hands(src) + if("Flip") + flip_deck() + +/obj/item/tcgcard_deck/proc/check_menu(mob/user) + if(!istype(user)) + return FALSE + if(user.incapacitated() || !user.Adjacent(src)) + return FALSE + return TRUE + +/obj/item/tcgcard_deck/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(istype(used, /obj/item/tcg_card)) + if(contents.len >= max_cards) + to_chat(user, "This pile has too many cards for a single deck!") + return ITEM_INTERACT_COMPLETE + + var/obj/item/tcg_card/new_card = used + new_card.flipped = flipped + user.unequip(new_card) + new_card.forceMove(src) + update_icon() + return ITEM_INTERACT_COMPLETE + + if(istype(used, /obj/item/tcgcard_hand)) + var/obj/item/tcgcard_hand/hand = used + for(var/obj/item/tcg_card/card in hand.cards) + if(contents.len >= max_cards) + return ITEM_INTERACT_COMPLETE + + card.flipped = flipped + card.forceMove(src) + hand.cards.Remove(card) + update_icon() + return ITEM_INTERACT_COMPLETE + + return ..() + +/obj/item/tcgcard_deck/activate_self(mob/user) + if(..()) + return ITEM_INTERACT_COMPLETE + + shuffle_deck(user) + return ITEM_INTERACT_COMPLETE + +/obj/item/tcgcard_deck/proc/draw_card(mob/user) + if(!contents.len) + return + var/obj/item/tcg_card/drawn_card = contents[contents.len] + drawn_card.flipped = flipped + drawn_card.forceMove(get_turf(user)) + user.put_in_hands(drawn_card) + drawn_card.update_icon() + user.visible_message("[user] draws a card from \the [src]!", \ + "You draw a card from \the [src]!") + update_icon() + if(!contents.len) + qdel(src) + +/obj/item/tcgcard_deck/proc/shuffle_deck(mob/user, visible = TRUE) + if(!contents.len) + return + var/turf/T = get_turf(src) + var/list/shuffled = shuffle(contents.Copy()) + for(var/obj/item/tcg_card/card in contents) + card.forceMove(T) + for(var/obj/item/tcg_card/card in shuffled) + card.forceMove(src) + if(visible) + user.visible_message("[user] shuffles \the [src]!", \ + "You shuffle \the [src]!") + +/obj/item/tcgcard_deck/proc/flip_deck() + flipped = !flipped + var/turf/T = get_turf(src) + var/list/temp_cards = list() + for(var/obj/item/tcg_card/card in contents) + temp_cards.Add(card) + for(var/obj/item/tcg_card/card in temp_cards) + card.forceMove(T) + for(var/i = temp_cards.len to 1 step -1) + var/obj/item/tcg_card/card = temp_cards[i] + card.forceMove(src) + card.flipped = flipped + card.update_icon() + update_icon() + +/obj/item/tcgcard_hand + name = "Card Hand" + desc = "A hand full of Battle of Orion cards." + icon = 'icons/effects/effects.dmi' + icon_state = "nothing" + w_class = WEIGHT_CLASS_TINY + new_attack_chain = TRUE + var/list/cards = list() + +/obj/item/tcgcard_hand/update_icon() + . = ..() + cut_overlays() + var/angular = length(cards) / 2 * -30 + 15 + for(var/obj/item/tcg_card/card in cards) + var/image/I = image(icon = card.icon, icon_state = card.icon_state) + var/matrix/ntransform = matrix(I.transform) + ntransform.TurnTo(angular, 0) + ntransform.Translate(sin(angular) * -15, cos(angular) * 15) + I.transform = ntransform + angular += 30 + overlays += I + + +/obj/item/tcgcard_hand/item_interaction(mob/living/user, obj/item/used, list/modifiers) + if(!istype(used, /obj/item/tcg_card)) + return ..() + + var/obj/item/tcg_card/card = used + if(loc == user && card.loc == user) + user.unequip(card) + card.forceMove(src) + cards.Add(card) + update_icon() + return ITEM_INTERACT_COMPLETE + +/obj/item/tcgcard_hand/activate_self(mob/user) + if(..()) + return ITEM_INTERACT_COMPLETE + + if(loc != user) + return ITEM_INTERACT_COMPLETE + + var/list/choices = list() + for(var/obj/item/tcg_card/card in cards) + choices[card] = image(icon = card.icon, icon_state = card.icon_state) + var/obj/item/tcg_card/choice = show_radial_menu(user, src, choices, require_near = TRUE) + + if(choice) + choice.forceMove(get_turf(src)) + user.put_in_hands(choice) + cards.Remove(choice) + update_icon() + if(length(cards) == 0) + qdel(src) + return ITEM_INTERACT_COMPLETE + +/obj/item/tcgcard_hand/Destroy() + for(var/obj/item/tcg_card/card in cards) + card.forceMove(drop_location()) + cards = list() + . = ..() + +/obj/item/tcgcard_hand/equipped(mob/user, slot, initial) + . = ..() + transform = matrix() + +/obj/item/tcgcard_hand/dropped(mob/user, silent) + . = ..() + transform = matrix(0.5,0,0,0,0.5,0) + +#undef ROTATED_ANGLE +#undef UNROTATED_ANGLE diff --git a/icons/mob/radial.dmi b/icons/mob/radial.dmi index d45748ca2da..d38fa1696ac 100644 Binary files a/icons/mob/radial.dmi and b/icons/mob/radial.dmi differ diff --git a/icons/obj/economy.dmi b/icons/obj/economy.dmi index c81aaaeb571..bb0630e0c2b 100644 Binary files a/icons/obj/economy.dmi and b/icons/obj/economy.dmi differ diff --git a/icons/obj/tcg/misc.dmi b/icons/obj/tcg/misc.dmi new file mode 100644 index 00000000000..babfcaace61 Binary files /dev/null and b/icons/obj/tcg/misc.dmi differ diff --git a/icons/obj/tcg/pack1.dmi b/icons/obj/tcg/pack1.dmi new file mode 100644 index 00000000000..89b1b43dde7 Binary files /dev/null and b/icons/obj/tcg/pack1.dmi differ diff --git a/paradise.dme b/paradise.dme index 83c0017f2b2..d5aff01f59a 100644 --- a/paradise.dme +++ b/paradise.dme @@ -3468,6 +3468,8 @@ #include "code\modules\surgery\organs\subtypes\vox_organs.dm" #include "code\modules\surgery\organs\subtypes\vulpkanin_organs.dm" #include "code\modules\surgery\organs\subtypes\xenos.dm" +#include "code\modules\tcg\pack_1.dm" +#include "code\modules\tcg\tcg_cards.dm" #include "code\modules\telesci\bscrystal.dm" #include "code\modules\telesci\gps.dm" #include "code\modules\telesci\rcs.dm"