mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-09 16:33:50 +00:00
Makes the code compatible with 515.1594+
Few simple changes and one very painful one.
Let's start with the easy:
* puts call behind `LIBCALL` define, so call_ext is properly used in 515
* Adds `NAMEOF_STATIC(_,X)` macro for nameof in static definitions since
src is now invalid there.
* Fixes tgui and devserver. From 515 onward the tmp3333{procid} cache
directory is not appened to base path in browser controls so we don't
check for it in base js and put the dev server dummy window file in
actual directory not the byond root.
* Renames the few things that had /final/ in typepath to ultimate since
final is a new keyword
And the very painful change:
`.proc/whatever` format is no longer valid, so we're replacing it with
new nameof() function. All this wrapped in three new macros.
`PROC_REF(X)`,`TYPE_PROC_REF(TYPE,X)`,`GLOBAL_PROC_REF(X)`. Global is
not actually necessary but if we get nameof that does not allow globals
it would be nice validation.
This is pretty unwieldy but there's no real alternative.
If you notice anything weird in the commits let me know because majority
was done with regex replace.
@tgstation/commit-access Since the .proc/stuff is pretty big change.
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
189 lines
8.1 KiB
Plaintext
189 lines
8.1 KiB
Plaintext
SUBSYSTEM_DEF(trading_card_game)
|
|
name = "Trading Card Game"
|
|
flags = SS_NO_FIRE
|
|
init_order = INIT_ORDER_TCG
|
|
/// Base directory for all related string files
|
|
var/card_directory = "strings/tcg"
|
|
/// List of card files to load
|
|
var/list/card_files = list("set_one.json", "set_two.json")
|
|
/// List of keyword files
|
|
/// These allow you to add on hovor logic to parts of a card's text, displaying extra info
|
|
var/list/keyword_files = list("keywords.json")
|
|
/// What cardpack types to load
|
|
var/card_packs = list(/obj/item/cardpack/series_one, /obj/item/cardpack/resin)
|
|
var/list/cached_guar_rarity = list()
|
|
var/list/cached_rarity_table = list()
|
|
/// List of all cards by series, with cards cached by rarity to make those lookups faster
|
|
var/list/cached_cards = list()
|
|
/// List of loaded keywords matched with their hovor text
|
|
var/list/keywords = list()
|
|
var/loaded = FALSE
|
|
|
|
//Let's load the cards before the map fires, so we can load cards on the map safely
|
|
/datum/controller/subsystem/trading_card_game/Initialize()
|
|
reloadAllCardFiles()
|
|
return SS_INIT_SUCCESS
|
|
|
|
///Loads all the card files
|
|
/datum/controller/subsystem/trading_card_game/proc/loadAllCardFiles()
|
|
for(var/keyword_file in keyword_files)
|
|
loadKeywordFile(keyword_file, card_directory)
|
|
styleKeywords()
|
|
for(var/card_file in card_files)
|
|
loadCardFile(card_file, card_directory)
|
|
|
|
///Empty the rarity cache so we can safely add new cards
|
|
/datum/controller/subsystem/trading_card_game/proc/clearCards()
|
|
loaded = FALSE
|
|
cached_cards = list()
|
|
keywords = list()
|
|
|
|
///Reloads all card files
|
|
/datum/controller/subsystem/trading_card_game/proc/reloadAllCardFiles()
|
|
clearCards()
|
|
loadAllCardFiles()
|
|
loaded = TRUE
|
|
|
|
///Loads the contents of a json file into our global card list
|
|
/datum/controller/subsystem/trading_card_game/proc/loadKeywordFile(filename, directory = "strings/tcg")
|
|
var/list/keyword_data = json_decode(file2text("[directory]/[filename]"))
|
|
for(var/keyword in keyword_data)
|
|
if(keywords[keyword])
|
|
stack_trace("Dupe detected, [keyword] was defined by [directory]/[filename] after it already had a value!")
|
|
continue
|
|
keywords[keyword] = keyword_data[keyword]
|
|
|
|
///Styles our keywords, converting them from just the raw text to the output we want
|
|
/datum/controller/subsystem/trading_card_game/proc/styleKeywords()
|
|
// Add the tooltip component to our text, make it pretty
|
|
for(var/keyword in keywords)
|
|
var/tooltip_text = keywords[keyword]
|
|
keywords[keyword] = span_tooltip(tooltip_text, keyword)
|
|
|
|
///Takes a string as input. Searches it for keywords in the pattern {$keyword}, and replaces them with their expanded form, generated above
|
|
/datum/controller/subsystem/trading_card_game/proc/resolve_keywords(search_through)
|
|
var/starting_text = search_through
|
|
while(TRUE)
|
|
var/fragment_start = findtext(search_through, "{$")
|
|
if(!fragment_start)
|
|
break
|
|
var/fragment_end = findtext(search_through, "}")
|
|
if(!fragment_end)
|
|
CRASH("[starting_text] contains a {$ that denotes the start of a keyword replacement, but not a closing }!")
|
|
///Gets the keyword this string wants to use
|
|
///We offset the start by two indexes to account for
|
|
var/keyword = copytext(search_through, fragment_start + 2, fragment_end)
|
|
var/replacement = keywords[keyword]
|
|
if(!replacement)
|
|
CRASH("[starting_text] contains a non-existent keyword! \[[keyword]\]")
|
|
search_through = replacetext(search_through, "{$[keyword]}", replacement)
|
|
|
|
return search_through
|
|
|
|
///Loads the contents of a json file into our global card list
|
|
/datum/controller/subsystem/trading_card_game/proc/loadCardFile(filename, directory = "strings/tcg")
|
|
var/list/json = json_decode(file2text("[directory]/[filename]"))
|
|
var/list/cards = json["cards"]
|
|
var/list/templates = list()
|
|
for(var/list/data in json["templates"])
|
|
templates[data["template"]] = data
|
|
for(var/list/data in cards)
|
|
var/datum/card/card = new(data, templates)
|
|
//Lets cache the id by rarity, for top speed lookup later
|
|
if(!cached_cards[card.series])
|
|
cached_cards[card.series] = list()
|
|
cached_cards[card.series]["ALL"] = list()
|
|
if(!cached_cards[card.series][card.rarity])
|
|
cached_cards[card.series][card.rarity] = list()
|
|
cached_cards[card.series][card.rarity] += card.id
|
|
//Let's actually store the datum here
|
|
cached_cards[card.series]["ALL"][card.id] = card
|
|
|
|
///Because old me wanted to keep memory costs down, each cardpack type shares a rarity list
|
|
///We do the spooky stuff in here to ensure we don't have too many lists lying around
|
|
/datum/controller/subsystem/trading_card_game/proc/get_rarity_table(type, list/sample_table)
|
|
//Pass by refrance moment
|
|
//This lets us only have one rarity table per pack, badmins beware
|
|
//Yes this is horribly overengineered. No I am not sorry
|
|
if(!cached_rarity_table[type])
|
|
cached_rarity_table[type] = sample_table
|
|
return cached_rarity_table[type]
|
|
|
|
///See above
|
|
/datum/controller/subsystem/trading_card_game/proc/get_guarenteed_rarity_table(type, list/sample_table)
|
|
if(!cached_guar_rarity[type])
|
|
cached_guar_rarity[type] = sample_table
|
|
return cached_guar_rarity[type]
|
|
|
|
///Prints all the cards names
|
|
/datum/controller/subsystem/trading_card_game/proc/printAllCards()
|
|
for(var/card_set in cached_cards)
|
|
message_admins("Printing the [card_set] set")
|
|
for(var/card in cached_cards[card_set]["ALL"])
|
|
var/datum/card/toPrint = cached_cards[card_set]["ALL"][card]
|
|
message_admins(toPrint.name)
|
|
|
|
///Checks the passed type list for missing raritys, or raritys out of bounds
|
|
/datum/controller/subsystem/trading_card_game/proc/checkCardpacks(cardPackList)
|
|
var/toReturn = ""
|
|
for(var/cardPack in cardPackList)
|
|
var/obj/item/cardpack/pack = new cardPack()
|
|
//Lets see if someone made a type yeah?
|
|
if(!cached_cards[pack.series])
|
|
toReturn += "[pack.series] does not have any cards in it\n"
|
|
continue
|
|
for(var/card in cached_cards[pack.series]["ALL"])
|
|
var/datum/card/template = cached_cards[pack.series]["ALL"][card]
|
|
if(template.rarity == "ALL")
|
|
toReturn += "[pack.type] has a rarity [template.rarity] on the card [template.id] that needs to be changed to something that isn't \"ALL\"\n"
|
|
continue
|
|
if(!(template.rarity in pack.rarity_table))
|
|
toReturn += "[pack.type] has a rarity [template.rarity] on the card [template.id] that does not exist\n"
|
|
continue
|
|
//Lets run a check to see if all the rarities exist that we want to exist exist
|
|
for(var/pack_rarity in pack.rarity_table)
|
|
if(!cached_cards[pack.series][pack_rarity])
|
|
toReturn += "[pack.type] does not have the required rarity [pack_rarity]\n"
|
|
qdel(pack)
|
|
return toReturn
|
|
|
|
///Checks the global card list for cards that don't override all the default values of the card datum
|
|
/datum/controller/subsystem/trading_card_game/proc/checkCardDatums()
|
|
var/toReturn = ""
|
|
var/datum/thing = new()
|
|
for(var/series in cached_cards)
|
|
var/cards = cached_cards[series]["ALL"]
|
|
for(var/card in cards)
|
|
var/datum/card/target = cached_cards[series]["ALL"][card]
|
|
var/toAdd = "The card [target.id] in [series] has the following default variables:"
|
|
var/shouldAdd = FALSE
|
|
for(var/current_var in (target.vars ^ thing.vars))
|
|
if(current_var == "icon" && target.vars[current_var] == DEFAULT_TCG_DMI)
|
|
continue
|
|
if(target.vars[current_var] == initial(target.vars[current_var]))
|
|
shouldAdd = TRUE
|
|
toAdd += "\n[current_var] with a value of [target.vars[current_var]]"
|
|
if(shouldAdd)
|
|
toReturn += toAdd
|
|
qdel(thing)
|
|
return toReturn
|
|
|
|
///Used to test open a large amount of cardpacks
|
|
/datum/controller/subsystem/trading_card_game/proc/checkCardDistribution(cardPack, batchSize, batchCount, guaranteed)
|
|
var/totalCards = 0
|
|
//Gotta make this look like an associated list so the implicit "does this exist" checks work proper later
|
|
var/list/cardsByCount = list("" = 0)
|
|
var/obj/item/cardpack/pack = new cardPack()
|
|
for(var/index in 1 to batchCount)
|
|
var/list/cards = pack.buildCardListWithRarity(batchSize, guaranteed)
|
|
for(var/id in cards)
|
|
totalCards++
|
|
cardsByCount[id] += 1
|
|
var/toSend = "Out of [totalCards] cards"
|
|
for(var/id in sort_list(cardsByCount, GLOBAL_PROC_REF(cmp_num_string_asc)))
|
|
if(id)
|
|
var/datum/card/template = cached_cards[pack.series]["ALL"][id]
|
|
toSend += "\nID:[id] [template.name] [(cardsByCount[id] * 100) / totalCards]% Total:[cardsByCount[id]]"
|
|
message_admins(toSend)
|
|
qdel(pack)
|