Files
2026-02-06 15:18:23 -06:00

377 lines
20 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
mse version: 2.0.0
short name: Field Test
full name: version 1.1
position hint: 120
icon: icon.png
version: 2026-02-06
installer group: magic/Export/lackeyccg
depends on:
package: magic.mse-game
version: 2009-07-23
game: magic
create directory: true
file type: *.txt|*.txt|*.*|*.*
# By Cajun
option field:
type: text
name: set code
description: The set code for the set
option field:
type: text
name: v mana replacement
description: exports V mana as a replacement text string
option field:
type: boolean
name: export images
script:
# replace shenanigans
template_vers := "1.1"
fix_tm := replace@(match:"™", replace:"TM")
fixed_set_code := {
trim(fix_tm(if options.set_code != "" then options.set_code else set.set_code))
}
apos_fix := replace@(match:"", replace:"'")
## clean up strays that will mess up the json
escape_backslash := replace@(match:"\\\\", replace:"\\\\\\\\")
escape_quotes := replace@(match:"\"", replace:"\\\\\"")
escape_breaks := replace@(match:"\n", replace:"\\\\n")
apos_fix := replace@(match:"", replace:"'")
remove_tabs := replace@(match:"\t", replace:"") +
replace@(match:" ", replace:"") +
replace@(match:" +", replace:" ")
remove_controls := replace@(match:"\r", replace:"")
sanitize := to_text +
escape_backslash +
escape_breaks +
escape_quotes +
remove_controls +
remove_tabs +
apos_fix +
trim
v_rep := {
if input != "V"
then input
else if options.v_mana_replacement == ""
then input
else
options.v_mana_replacement
}
type_trim := replace@(match:"Basic ", replace:"")+
replace@(match:"Legendary", replace:"")+
replace@(match:"Snow ", replace:"")+
replace@(match:"World ", replace:"")+
replace@(match:"Token ", replace:"")
export_me := {
if contains(card.notes, match:"!noexport")
then false
else true
}
# process the name
exporter_name_filter := filter_text@(match:"!subname [^\n!]+")
exporter_name_grabber := replace@(match:"!subname ", replace:"")
card_name := { if exporter_name_grabber(exporter_name_filter(card.notes)) != "" then exporter_name_grabber(exporter_name_filter(card.notes)) else remove_tags(card.name) }
database_name := {
if exporter_name_grabber(exporter_name_filter(card.notes)) != ""
then exporter_name_grabber(exporter_name_filter(card.notes))
else if card.name_2 != "" and match(card.shape, match:"(double|adventure|split|aftermath)")
then remove_tags(card.name) + "//" + remove_tags(card.name_2)
else remove_tags(card.name)
}
rename_filter := filter_text@(match:"!renameof [^\n!]+")
rename_grabber := replace@(match:"!renameof ", replace:"")
filter_rename := { rename_grabber(rename_filter(card.notes)) }
# process type
token_export := { contains(card.shape, match:"token") or contains(card.shape, match:"emblem") or contains(card.shape, match:"rulestip") or contains(card.notes, match:"!tokenshape") }
# process rarity
use_promo := match@(match:"!promo\\b")
use_bonus := { card.rarity == "special" and not use_promo(card.notes) }
rarity_name := { if use_bonus() then "Bonus" else if card.rarity == "special" then "Promo" else if token_export() then "Token" else if card.rarity == "mythic rare" then "M" else if card.rarity == "rare" then "R" else if card.rarity == "uncommon" then "U" else if card.rarity == "common" then "C" else "L" }
lb_rarity_code := { "*" + fixed_set_code() + " " + rarity_name() + "*" }
# !addtoken !replacetoken !tokentag !addconjure
add_token_filter := filter_text@(match:"!addtoken [^\n!]+")
add_token_grabber := replace@(match:"!addtoken ", replace:"")
replace_token_filter := filter_text@(match:"!replacetoken [^\n!]+")
replace_token_grabber := replace@(match:"!replacetoken ", replace:"")
token_tag_filter := filter_text@(match:"!tokentag [^\n!]+")
token_tag_grabber := replace@(match:"!tokentag ", replace:"")
add_spellbook_filter := filter_text@(match:"!spellbook [^\n!]+")
add_spellbook_grabber := replace@(match:"!spellbook ", replace:"")
token_scripts := {
add_token_argument := add_token_grabber(add_token_filter(card.notes))
replace_token_argument := replace_token_grabber(replace_token_filter(card.notes))
token_tag_argument := token_tag_grabber(token_tag_filter(card.notes))
spellbook_tag_argument := add_spellbook_grabber(add_spellbook_filter(card.notes))
output := ""
if add_token_argument != "" then output := output + "\"aa\": \"" + add_token_argument + "\"" + (if replace_token_argument != "" or token_tag_argument != "" then ", " else "")
if replace_token_argument != "" then output := output + "\"rr\": \"" + replace_token_argument + "\"" + (if token_tag_argument != "" then ", " else "")
if token_tag_argument != "" then output := output + "\"t\": \"" + token_tag_argument + "\""
if spellbook_tag_argument != "" then output := output + "\"c\": \"" + spellbook_tag_argument + "\""
if output != "" then output := "\"tokenscripts\": \{" + output + "\}, "
output
}
# !notes tag
notes_filter := filter_text@(match:"!notes? [^\n!]+")
notes_grabber := replace@(match:"!notes? ", replace:"")
+replace@(match:"([^,]+)", replace:{"\"" + sanitize(_1) + "\""})
+replace@(match:"italics", replace:"italic")
card_note_array := { "[" + (if notes_grabber(notes_filter(card.notes)) != "" then notes_grabber(notes_filter(card.notes)) else "") + "]" }
# process text for LackeyBot
lackey_bot_rule_filter := replace@(match:"", replace:"'")+
replace@(match:"\n", replace:"\\\\n")+
replace@(match:";;", replace:"\\\\n\\\\n")+
replace@(match:"[(]", replace:"*(")+
replace@(match:"[)]", replace: ")*")+
replace@(match:"[*][(][)][*]", replace:"()")+
replace@(match:"\"", replace:"”")+
replace@(match:" ”", replace:" “")
break_cleaner := replace@(match:"\n", replace:"")
+ replace@(match:"\"", replace:"\\\\\"")
+ replace@(match:" — *$", replace:"")
quote_replace := replace@(match:"\"", replace:"\\\\\"")
mana_script := replace@(match:"(2|H|W|U|B|R|G|S|C|I)/(W|U|B|R|G|S|C|I)", replace:{"\{"+_1+"/"+_2+"\}"})+
replace@(match:"(X|Y|Z|W|U|B|R|G|S|C|I)", in_context:"(?<!\{)(?<!/)<match>", replace:{"\{"+_1+"\}"})+
replace@(match:"([1-9][0-9])", in_context:"(?<!\{)(?<!\\/)<match>", replace:{"\{"+_1+"\}"})+
replace@(match:"([0-9])", in_context:"(?<!\{)(?<!\\/)<match>(?!})", replace:{"\{"+_1+"\}"})+
replace@(match:"V", replace:{"\{"+v_rep("V")+"\}"})
lackey_bot_mana_filter := replace@(match:"<sym(-auto)?>([0-9WUBRGCSHEQTXYZEDVI/]+)</sym(-auto)?>", replace:{"\{"+_2+"}"})+
replace@(match:"([0-9HSCWUBRGXYZEDV/])", in_context:"\{[0-9HSCWUBRGXYZEDVI/]*<match>[0-9HSCWUBRGXYZEDVI/]*}", replace:{"\{"+v_rep(_1)+"}"})+
replace@(match:"}\{/}\{", replace:"/")+
replace@(match:"\{([0-9])}\{([0-9])}", replace:{"\{"+_1+_2+"}"})+
replace@(match:"\{\{", replace:"\{")+
replace@(match:"}}", replace:"}")
color_condense := replace@(match:"(, )?(artifact|multicolor|land|hybrid|horizontal|vertical|radial|overlay)", replace: "")
indicator_color_name := {
cond := color_condense(input)
if cond == "white" then "\{White\} "
else if cond == "blue" then "\{Blue\} "
else if cond == "black" then "\{Black\} "
else if cond == "red" then "\{Red\} "
else if cond == "green" then "\{Green\} "
else if cond == "white, blue" then "\{White/Blue\} "
else if cond == "blue, black" then "\{Blue/Black\} "
else if cond == "black, red" then "\{Black/Red\} "
else if cond == "red, green" then "\{Red/Green\} "
else if cond == "white, green" then "\{Green/White\} "
else if cond == "white, black" then "\{White/Black\} "
else if cond == "blue, red" then "\{Blue/Red\} "
else if cond == "black, green" then "\{Black/Green\} "
else if cond == "white, red" then "\{Red/White\} "
else if cond == "blue, green" then "\{Green/Blue\} "
else if cond == "white, black, red" then "\{White/Black/Red\} "
else if cond == "blue, red, green" then "\{Blue/Red/Green\} "
else if cond == "white, black, green" then "\{Black/Green/White\} "
else if cond == "white, blue, red" then "\{Red/White/Blue\} "
else if cond == "blue, black, green" then "\{Green/Blue/Black\} "
else if cond == "white, blue, black" then "\{White/Blue/Black\} "
else if cond == "blue, black, red" then "\{Blue/Black/Red\} "
else if cond == "black, red, green" then "\{Black/Red/Green\} "
else if cond == "white, red, green" then "\{Red/Green/White\} "
else if cond == "white, blue, green" then "\{Green/White/Blue\} "
else ""
}
silver_patch := {
is_silver := contains(card.casting_cost, match:"I")
if not is_silver then input
else if input == "" then "\{Silver\} "
else replace(input, match:"\{", replace:"\{Silver/")
}
lackey_shape := {
if contains(card.shape, match: "adventure")
then "adventure"
else if contains(card.shape, match: "aftermath") or contains(card.shape, match: "split")
then "split"
else if contains(card.shape, match:"double")
then "doubleface"
else if contains(card.shape, match:"plane card")
then "planar"
else "normal"
}
trim_zeroes := replace@(match: "^0+", replace: "")+
replace@(match: "a?/[0-9b]+", replace: "")
corrected_card_number := {
(if card.custom_card_number != "" then trim_zeroes(card.custom_card_number) else card_number())
+ (if card.rarity == "special" and set.sort_special_rarity == "separate numbering" then "s" else "")
}
lackey_bot_flavor := {"*" + input + "*" }
apos_filter := replace@(match:"", replace:"'")
paragraph_count := replace@(match:"\n", replace:"~")+
filter_text@(match:"~")
ftlv1 := { contains(card.notes, match:"!ftlv1") }
flavor_saga := filter_text@(match:"!flavorsaga")
text_script := {
## diverge
if ftlv1() then input := replace(input, match:"<i>[^\n]+</i>\n", replace:"");
## fuse
if contains(card.shape, match:"split") and card.rule_text_3 != ""
then input := input + "\\n" + card.rule_text_3
## upgrade
replace(
remove_tags(input),
match:"[ ][ ]+•",
replace: "\\n•"
)
}
leveler_text := {
card.rule_text + "\\n" +
"[LEVEL " + card.level_1 + "] " + card.rule_text_2 + "\\n" +
"[LEVEL " + card.level_2 + "] " + card.rule_text_3 + "\\n"
}
flavor_script := { if input == "<i-flavor></i-flavor>" then ""
else replace(italic_filter(input), match:"\n", replace:"\\n") + "\n"
}
italic_filter := replace@(match:"<i(?:-flavor|-auto)?>( )?(.*?)( )?</i(?:-flavor|-auto)?>", replace:"\\1*\\2*\\3") +
replace@(match:"\\*\\*+", replace:"")
text_processing1 := {text_processing(input, box:"")}
text_processing2 := {text_processing(input, box:"2")}
textpends := "!(append|prepend|inpend|exitpend)"
text_processing := {
blocks := split_text(card.notes, match:textpends+box+" ")
cmds := break_text(card.notes, match:textpends+box+" ")
if length(cmds) > 0 then (
shift := if blocks[0] == "" or not contains(card.notes, match:cmds[0]+blocks[0]) then 1 else 0
for x from 0 to length(cmds)-1 do (
cmd := replace(to_lower(cmds[x]), match:"2? $", replace:"");
inf := replace(blocks[x+shift], match:"\n.*", replace:"");
input := command_processing[cmd](input, info:inf);
""
)
)
input
}
command_processing := [
"!append": {
input + lackey_bot_rule_filter(info)
},
"!prepend": {
lackey_bot_rule_filter(info) + input
},
"!exitpend": {
input
},
"!inpend": {
swaps := split_text(info, match:"/replace/")
apps := split_text(info, match:"/add/")
if length(swaps) > 1 then
replace(input, match:swaps.0, replace:lackey_bot_rule_filter(swaps.1))
else if length(apps) > 1 then
replace(input, match:"(.*)({apps.0})(.*)", replace:"\\1\\2{lackey_bot_rule_filter(apps.1)}\\3")
else input
}
]
walker_text := {
lackey_bot_mana_filter(
lackey_bot_rule_filter(
(if card.loyalty_cost_1 != "" then "[" + card.loyalty_cost_1 + "]: ")
+ (if card.level_1_text != "" then card.level_1_text else split_text(match:"\n", card.rule_text).0)
+ "\\n"
+ "[" + card.loyalty_cost_2 + "]" + (if card.loyalty_cost_2 !="" then ": ") + (if card.level_2_text != "" then card.level_2_text+"\\n" else if contains(paragraph_count(card.rule_text), match:"~") then split_text(match:"\n", card.rule_text).1+"\\n")
+ "[" + card.loyalty_cost_3 + "]" + (if card.loyalty_cost_3 !="" then ": ") + (if card.level_3_text != "" then card.level_3_text+"\\n" else if contains(paragraph_count(card.rule_text), match:"~~") then split_text(match:"\n", card.rule_text).2+"\\n")
+ ( if card.loyalty_cost_4 != "" then "[" + card.loyalty_cost_4 + "]" +": ") + (if card.level_4_text != "" then card.level_4_text+"\\n" else if contains(paragraph_count(card.rule_text), match:"~~~") then split_text(match:"\n", card.rule_text).3+"\\n")
+ ( if card.loyalty_cost_5 != "" then "[" + card.loyalty_cost_5 + "]" +": ") + (if card.level_5_text != "" then card.level_5_text+"\\n" else if contains(paragraph_count(card.rule_text), match:"~~~~") then split_text(match:"\n", card.rule_text).4+"\\n")
+ ( if card.loyalty_cost_6 != "" then "[" + card.loyalty_cost_6 + "]" +": ") + (if card.level_6_text != "" then card.level_6_text+"\\n" else if contains(paragraph_count(card.rule_text), match:"~~~~") then split_text(match:"\n", card.rule_text).5+"\\n")
)
)
}
walker_text_2 := {
lackey_bot_mana_filter(
lackey_bot_rule_filter(
(if card.loyalty_cost_9 != "" then "[" + card.loyalty_cost_9 + "]: ") +(if card.level_9_text != "" then card.level_9_text else split_text(match:"\n", card.rule_text_2).0)+"\\n"
+ "[" + card.loyalty_cost_10 + "]" +(if card.loyalty_cost_10 !="" then ": ") +(if card.level_10_text != "" then card.level_10_text+"\\n" else if contains(paragraph_count(card.rule_text_2), match:"~") then split_text(match:"\n", card.rule_text_2).1+"\\n")
+ "[" + card.loyalty_cost_11 + "]" +(if card.loyalty_cost_11 !="" then ": ") +(if card.level_11_text != "" then card.level_11_text+"\\n" else if contains(paragraph_count(card.rule_text_2), match:"~~") then split_text(match:"\n", card.rule_text_2).2+"\\n")
+ ( if card.loyalty_cost_12 != "" then "[" + card.loyalty_cost_12 + "]" +": ") +(if card.level_12_text != "" then card.level_12_text+"\\n" else if contains(paragraph_count(card.rule_text_2), match:"~~~") then split_text(match:"\n", card.rule_text_2).3+"\\n")
+ ( if card.loyalty_cost_13 != "" then "[" + card.loyalty_cost_13 + "]" +": ") +(if card.level_13_text != "" then card.level_13_text+"\\n" else if contains(paragraph_count(card.rule_text_2), match:"~~~~") then split_text(match:"\n", card.rule_text_2).4+"\\n")
+ ( if card.loyalty_cost_14 != "" then "[" + card.loyalty_cost_14 + "]" +": ") +(if card.level_14_text != "" then card.level_14_text+"\\n" else if contains(paragraph_count(card.rule_text_2), match:"~~~~") then split_text(match:"\n", card.rule_text_2).5+"\\n")
)
)
}
write_normal:= {
" \{"
+ (if export_me() then "" else "\"skip\": true, ")
+ "\"fullName\": \"" + sanitize(apos_fix(database_name())) + "\", "
+ "\"cardName\": \"" + sanitize(remove_tags(card_name())) + "\", "
+ "\"manaCost\": \"" + mana_script(card.casting_cost) + "\", "
+ "\"typeLine\": \"" + sanitize(card.type) + "\", "
+ "\"rarityLine\": \"" + lb_rarity_code() + "\", "
+ "\"rulesText\": \"" + text_processing1(if card.special_text != "" then lackey_bot_rule_filter(text_script(lackey_bot_mana_filter(card.special_text))) else lackey_bot_rule_filter(text_script(lackey_bot_mana_filter(card.rule_text))),) + "\", "
+ "\"flavorText\": \"" + sanitize(flavor_script(card.flavor_text)) + "\", "
+ "\"power\": " + (if card.power == "*" then "\"★\"" else if card.power == "" then "\"\"" else if (to_number(card.power) or else false != card.power) then "\"" + card.power + "\"" else card.power) + ", "
+ "\"toughness\": " + (if card.toughness == "*" then "\"★\"" else if card.toughness == "" then "\"\"" else if (to_number(card.toughness) or else false != card.toughness) then "\"" + card.toughness + "\"" else card.toughness) + ", "
+ "\"loyalty\": " + (if (to_number(card.loyalty) or else false != card.loyalty) then "\"" + card.loyalty + "\"" else card.loyalty) + ", "
+ "\"color\": \"" + (if contains(card.super_type, match:"Land") then "" else silver_patch(indicator_color_name(card.card_color))) + "\", "
+ "\"cmc\": " + cmc(card.casting_cost) + ", "
+ "\"cardType\": \"" + type_trim(card.super_type) + "\", "
+ (if contains(card.shape, match: "split") or contains(card.shape, match:"double") or contains(card.shape, match:"adventure") or contains(card.shape, match:"aftermath") then secondCard())
+ "\"rarity\": \"" + (if rarity_name() == "Token" then "token" else if rarity_name() == "Bonus" then "bonus" else if rarity_name() == "Masterpiece" then "masterpiece" else card.rarity) + "\", "
+ "\"shape\": \"" + lackey_shape() + "\", "
+ "\"setID\": \"" + (if token_export() then "tokens" else fixed_set_code()) + "\", "
+ "\"cardID\": \"" + (if token_export() then fixed_set_code() else "") + position(of:card, in:set) + "\", "
+ (if token_export() then "\"parentSet\": \"" + fixed_set_code() + "\", " else "")
+ "\"notes\": " + card_note_array() + ", "
+ (if filter_rename() != "" then "\"rename\": \"" + filter_rename() + "\", " else "")
+ token_scripts()
+ "\"artist\": \"" + sanitize(card.illustrator)
+ (if contains(card.shape, match: "split") or contains(card.shape, match:"double") and card.illustrator != card.illustrator_2 and card.illustrator_2 != "" then
"\", \"artist2\": \"" + sanitize(card.illustrator_2))
+ "\"\},\n"
}
secondCard := {
(
if card.alias_2 != "" then
"\"cardName2\": \"" + sanitize(card.alias_2) + "\", "
+ "\"alias2\": \"" + sanitize(remove_tags(card.name_2)) + "\", "
else "\"cardName2\": \"" + sanitize(remove_tags(card.name_2)) + "\", "
)
+ "\"manaCost2\": \"" + mana_script(card.casting_cost_2) + "\", "
+ "\"typeLine2\": \"" + sanitize(card.type_2) + "\", "
+ "\"rarityLine2\": \"" + lb_rarity_code() + "\", "
+ "\"rulesText2\": \"" + text_processing2(if card.special_text_2 != "" then lackey_bot_rule_filter(text_script(lackey_bot_mana_filter(card.special_text_2))) else lackey_bot_rule_filter(text_script(lackey_bot_mana_filter(card.rule_text_2)))) + "\", "
+ "\"flavorText2\": \"" + sanitize(flavor_script(card.flavor_text_2)) + "\", "
+ "\"power2\": " + (if card.power_2 == "*" then "\"★\"" else if card.power_2 == "" then "\"\"" else if (to_number(card.power_2) or else false != card.power_2) then "\"" + card.power_2 + "\"" else card.power_2) + ", "
+ "\"toughness2\": " + (if card.toughness_2 == "*" then "\"★\"" else if card.toughness_2 == "" then "\"\"" else if (to_number(card.toughness_2) or else false != card.toughness_2) then "\"" + card.toughness_2 + "\"" else card.toughness_2) + ", "
+ "\"loyalty2\": " + (if (to_number(card.loyalty_2) or else false != card.loyalty_2) then "\"" + card.loyalty_2 + "\"" else card.loyalty_2) + ", "
+ "\"color2\": \"" + (if contains(card.super_type, match:"Land") then "" else silver_patch(indicator_color_name(card.card_color_2))) + "\", "
+ "\"cmc2\": " + cmc(card.casting_cost_2) + ", "
+ "\"cardType2\": \"" + type_trim(card.super_type_2) + "\", "
}
write_update := {write_normal()}
write_cards := to_text(for each card in cards do write_update())
clean_cards := replace@(match:",\n$", replace: "\n")
+replace@(match:"", replace:"'")
write_set := "\"meta\":\{\"version\":\"{template_vers}\", \"setID\": \"{fixed_set_code()}\", \"title\": \"{quote_replace(set.title)}\"\},"
####################################
file_name := {
(
if token_export() then fixed_set_code()+corrected_card_number()
else corrected_card_number()
)
+".jpg"
}
if options.export_images then
for each card in cards do if not export_me() then "" else write_image_file(card, directory: "{fixed_set_code()}", file:(if token_export() then fixed_set_code() else "") + position(of:card, in:set)+".jpg");""
to_string("\{" + write_set + "\n\"cards\":[\n"+clean_cards(write_cards) +"]\n\}")