diff --git a/data/magic.mse-game/game b/data/magic.mse-game/game index d3357db7..999e53ba 100644 --- a/data/magic.mse-game/game +++ b/data/magic.mse-game/game @@ -1,4 +1,4 @@ -mse version: 0.3.6 +mse version: 0.3.7 short name: Magic full name: Magic the Gathering installer group: magic/game files @@ -21,23 +21,23 @@ init script: ############################################################## Sorting mana symbols # correctly sort a mana symbol (no guild mana) - mana_sort := sort_rule(order: "XYZI[0123456789]S(WUBRG)") + mana_sort := sort_text@(order: "XYZI[0123456789]S(WUBRG)") # correctly sort guild mana - mana_sort_guild := sort_rule(order: "[XYZI01234567890SWUBRG/|]") + - replace_rule( + mana_sort_guild := sort_text@(order: "[XYZI01234567890SWUBRG/|]") + + replace@( match: "./.|././.|./././.|.[|]", in_context: "(^|[^/])($|[^/])", replace: {sort_text(order:"in_place((WUBRG)")} ) - mana_has_guild := match_rule(match: "[/|]") # Is there guild or half mana in the input? + mana_has_guild := match@(match: "[/|]") # Is there guild or half mana in the input? # A mana cost can contain both normal and guild mana mana_filter := to_upper + { if mana_has_guild() then mana_sort_guild() else mana_sort() } # Like mana filter, only also allow tap symbols: - tap_filter := sort_rule(order: "") - mana_filter_t := replace_rule( # Remove [] used for forcing mana symbols + tap_filter := sort_text@(order: "") + mana_filter_t := replace@( # Remove [] used for forcing mana symbols match: "[\\[\\]]", replace: "" ) + { tap_filter() + mana_filter() } @@ -59,8 +59,8 @@ init script: color_names_4 := { color_name(colors.0) + ", " + color_name(colors.1) + ", " + color_name(colors.2) + ", " + color_name(colors.3) } color_names_5 := { color_name(colors.0) + ", " + color_name(colors.1) + ", " + color_name(colors.2) + ", " + color_name(colors.3) + ", " + color_name(colors.4) } # color based on mana cost, input = a mana cost - color_filter := sort_rule(order: "") - color_filterH := sort_rule(order: "") + color_filter := sort_text@(order: "") + color_filterH := sort_text@(order: "") mana_to_color := { count := number_of_items(in: colors) if hybrid == "" then @@ -86,13 +86,13 @@ init script: # color based on land text box, input = textbox contents color_text_filter := # remove activation costs - replace_rule( + replace@( match: "]*>[^<]+]*>" in_context: "(?ix) (\\n|^)[^:]*(,|:) | (pays?|additional|costs?)[ ]", replace: "" ) + # keep only mana - filter_rule(match: "]*>([^<]+)") + color_filter; + filter_text@(match: "]*>([^<]+)") + color_filter; # get the land frame for a "WUBRG"-style input. land_multicolor := { count := number_of_items(in: colors) @@ -137,12 +137,12 @@ init script: } # The color of a card - is_creature := match_rule(match: "(?i)Creature") - is_tribal := match_rule(match: "(?i)Tribal") - is_artifact := match_rule(match: "(?i)Artifact") - is_land := match_rule(match: "(?i)Land") - is_enchantment := match_rule(match: "(?i)Enchantment") - is_spell := match_rule(match: "(?i)Instant|Sorcery") + is_creature := match@(match: "(?i)Creature") + is_tribal := match@(match: "(?i)Tribal") + is_artifact := match@(match: "(?i)Artifact") + is_land := match@(match: "(?i)Land") + is_enchantment := match@(match: "(?i)Enchantment") + is_spell := match@(match: "(?i)Instant|Sorcery") card_color := { # usually the color of mana text_color := text_to_color(rules_text, land: is_land(type)); @@ -156,20 +156,18 @@ init script: }; # Number of colors in a card_color - card_color_color_count := { - for each choice in ["white","blue","black","red","green","artifact"] do to_int(chosen()) - } + card_color_color_count := count_chosen@(choices: "white,blue,black,red,green,artifact") # Clean up color field card_color_filter := { colors := card_color_color_count() if colors > 2 then input := remove_choice(choice: "overlay") if colors > 1 then ( - input := require_choice(choice1: "multicolor", choice2: "hybrid", choice3: "land", choice4: "artifact") - input := exclusive_choice(choice1: "multicolor", choice2: "hybrid") - input := require_exclusive_choice(choice1: "horizontal", choice2: "vertical", choice3: "radial", choice4: "overlay") + input := require_choice(choices: "multicolor, hybrid, land, artifact") + input := exclusive_choice(choices: "multicolor, hybrid") + input := require_exclusive_choice(choices: "horizontal, vertical, radial, overlay") ) else - input := remove_choice(choice1: "radial", choice2: "horizontal", choice3: "vertical", choice4: "overlay", choice5: "hybrid", choice6: "reversed") + input := remove_choice(choices: "radial, horizontal, vertical, overlay, hybrid, reversed") if chosen(choice:"overlay") then input := remove_choice(choice: "reversed") input @@ -192,7 +190,7 @@ init script: } # Process the name for sorting rules (specifically, remove "The", "A", and "And" at the beginning, and make lowercase) sort_name := - replace_rule (match: "^(The|An?) ", replace: "") + + replace@(match: "^(The|An?) ", replace: "") + to_lower is_multicolor := { chosen(choice: "multicolor") and input != "artifact, multicolor" } @@ -277,7 +275,7 @@ init script: # replaces — correctly add := "" # default is nothing - separate_words := remove_tags + trim + replace_rule(match:" ", replace: {spacer}) + separate_words := remove_tags + trim + replace@(match:" ", replace: {spacer}) for_mana_costs := format_cost := { if input.separator_before == "—" and contains(input.param, match: " ") then ( if contains(input.param, match:",") then ( @@ -289,16 +287,16 @@ init script: ) else "{add}{input.param}" } - alternative_cost := replace_rule(match:"^[A-Z]", replace: { to_lower() }) - combined_cost := replace_rule(match:", [A-Z]", replace: { to_lower() })+ - replace_rule(match:",", replace:" and")+ - replace_rule(match:"^[STQXYZIWUBRG0-9/|]", in_context: "(^|[[:space:]])", replace: "&")+ - replace_rule(match:"^[A-Z]", replace: { to_lower() }) - long_dash := replace_rule(match:"-", replace:"—") + alternative_cost := replace@(match:"^[A-Z]", replace: { to_lower() }) + combined_cost := replace@(match:", [A-Z]", replace: { to_lower() })+ + replace@(match:",", replace:" and")+ + replace@(match:"^[STQXYZIWUBRG0-9/|]", in_context: "(^|[[:space:]])", replace: "&")+ + replace@(match:"^[A-Z]", replace: { to_lower() }) + long_dash := replace@(match:"-", replace:"—") # Utilities for keywords has_cc := { card.casting_cost != "" } has_pt := { card.pt != "" } - contains_target := match_rule(match:"(?i)([^a-z]|^)target([^a-z]|$)") + contains_target := match@(match:"(?i)([^a-z]|^)target([^a-z]|$)") is_targeted := { contains_target(card.rule_text) } ############################################################## The text box @@ -328,73 +326,73 @@ init script: | , # keyword argument that is declared as cost "; # truncates the name of legends - legend_filter := replace_rule(match:", [A-Z,a-z,Æ,0-9,' ]*", replace: "" )+ - replace_rule(match:"the [A-Z,a-z,Æ,0-9,' ]*", replace: "" ) + legend_filter := replace@(match:", [A-Z,a-z,Æ,0-9,' ]*", replace: "" )+ + replace@(match:"the [A-Z,a-z,Æ,0-9,' ]*", replace: "" ) # the rule text filter # - adds mana symbols # - makes text in parentheses italic text_filter := # step 1 : remove all automatic tags - tag_remove_rule(tag: "") + - tag_remove_rule(tag: "") + + remove_tag@(tag: "") + + remove_tag@(tag: "") + # step 2 : reminder text for keywords - expand_keywords_rule( + expand_keywords@( default_expand: { chosen(choice:mode, set.automatic_reminder_text) }, combine: { if mode == "pseudo" then "{keyword}" else "{keyword} ({process_english_hints(reminder)})" } ) + # step 2b : move action keywords' reminder text to the end of the line - replace_rule( + replace@( match: "((?:(?!]*>)(((?!]*>[^)]+[)]]*>)([^\n]+)\\1" replace: "\\2\\1" ) + # step 3a : expand shortcut words ~ and CARDNAME - replace_rule( + replace@( match: "~|~THIS~|CARDNAME", in_context: "(^|[[:space:]]|\\()", # TODO: Allow any punctuation before replace: "" ) + # step 3b : expand shortcut words ` and shortened LEGENDNAME - replace_rule( + replace@( match: "LEGENDNAME", in_context: "(^|[[:space:]]|\\()", # TODO: Allow any punctuation before replace: "" ) + # step 3c : fill in atom fields - tag_contents_rule( + tag_contents@( tag: "", contents: { if card_name=="" then "CARDNAME" else card_name } ) + - tag_contents_rule( + tag_contents@( tag: "", contents: { if card_name=="" then "LEGENDNAME" else legend_filter(card_name) } ) + # step 4 : explict non mana symbols - replace_rule( + replace@( match: "\\][STQXYZIWUBRG0-9/|]+\\[", replace: {"" + mana_filter_t() + ""} ) + # step 5 : add mana & tap symbols - replace_rule( + replace@( match: "[STQXYZIWUBRG0-9/|]+", in_context: mana_context, replace: {"" + mana_filter_t() + ""} ) + # step 5b : add explict mana symbols - replace_rule( + replace@( match: "\\[[STQXYZIWUBRG0-9/|]+\\]", replace: {"" + mana_filter_t() + ""} ) + # step 7 : italic reminder text - replace_rule( + replace@( match: "[(]([^)\n]|[(][^)\n]*[)])*[)]?", in_context: "(^|[[:space:]])|&") + # step 8 : automatic capitalization - replace_rule( + replace@( match: "[a-z]", in_context: "[(]()?[^)]|[ ]*: |—| — ", replace: to_upper) + @@ -406,27 +404,27 @@ init script: # - makes all text italic flavor_text_filter := # step 1 : remove italic tags - tag_remove_rule(tag: "") + + remove_tag@(tag: "") + # step 2 : surround by tags { "" + input + "" } + # curly quotes curly_quotes # Move the cursor past the separator in the p/t and type boxes - type_over_pt := replace_rule(match:"/$", replace:"") - type_over_type := replace_rule(match:" ?-$", replace:"") + type_over_pt := replace@(match:"/$", replace:"") + type_over_type := replace@(match:" ?-$", replace:"") super_type_filter := - tag_remove_rule(tag: "{input}" } - space_to_wltags := replace_rule(match:"( +| )", - replace:{"{_1}"}) + space_to_wltags := replace@(match:"( +| )", + replace:{"{_1}"}) sub_type_filter := - tag_remove_rule(tag: "$", replace: "") + # remove trailing soft space - tag_remove_rule(tag: "$", replace: "") + # remove trailing soft space + remove_tag@(tag: " abs(some_number) + +Returns the absolute value of a number. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:int]] or [[type:double]] Number to determine the absolute value of + +--Examples-- +> abs(1.5) == 1.5 +> abs(-1) == 1 diff --git a/doc/function/index.txt b/doc/function/index.txt index 887619a3..ceb2058f 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -6,9 +6,15 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:to_string]] Convert any value to a [[type:string]] | [[fun:to_int]] Convert any value to a [[type:int]] | [[fun:to_real]] Convert any value to a [[type:double]] +| [[fun:to_number]] Convert any value to a number | [[fun:to_boolean]] Convert any value to a [[type:boolean]] | [[fun:to_color]] Convert any value to a [[type:color]] - + +! Numbers <<< +| [[fun:abs]] Absolute value +| [[fun:random_int]] Generate a random [[type:int]]. +| [[fun:random_real]] Generate a random [[type:double]]. + ! Text manipulation <<< | [[fun:to_upper]] Convert a string to upper case, @"aBc" -> "ABC"@. | [[fun:to_lower]] Convert a string to lower case, @"aBc" -> "abc"@. @@ -37,6 +43,8 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:number_of_items]] Return the number of items in a list. | [[fun:sort_list]] Sort a list. | [[fun:filter_list]] Filter a list, keeping only elements that match a predicate. +| [[fun:random_shuffle]] Randomly shuffle a list. +| [[fun:random_select]] Pick random elements from a list. ! Keywords <<< | [[fun:expand_keywords]] Expand the keywords in a piece of text. diff --git a/doc/function/random_int.txt b/doc/function/random_int.txt new file mode 100644 index 00000000..2f9af862 --- /dev/null +++ b/doc/function/random_int.txt @@ -0,0 +1,25 @@ +Function: random_int + +DOC_MSE_VERSION: since 0.3.7 + +--Usage-- +> random_int(begin: lower bound, end: upper bound) + +Returns a random [[type:int]] between @begin@ and @end@. +By default @begin: 0@ is used. +The random number @x@ will be in the range @begin <= x < end@. + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Default Description +| @begin@ [[type:int]] @0@ Lower end point of the range the number will be in. +| @end@ [[type:int]] ''required'' Upper end point of the range the number will be in. + +--Examples-- +> random_int(end:10) == 2 +> random_int(end:10) == 5 +> random_int(begin:100, end:200) == 43 + +--See also-- +| [[fun:random_real]] Generate a random [[type:double]]. diff --git a/doc/function/random_real.txt b/doc/function/random_real.txt new file mode 100644 index 00000000..9d2d6179 --- /dev/null +++ b/doc/function/random_real.txt @@ -0,0 +1,24 @@ +Function: random_real + +DOC_MSE_VERSION: since 0.3.7 + +--Usage-- +> random_real(begin: lower bound, end: upper bound) + +Returns a random [[type:double]] between @begin@ and @end@. +By default the range @0.0@ to @1.0@ is used. + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Default Description +| @begin@ [[type:double]] @0.0@ Lower end point of the range the number will be in. +| @end@ [[type:double]] @1.0@ Upper end point of the range the number will be in. + +--Examples-- +> random_real() == 0.1451651461 +> random_real() == 0.7521351365 +> random_real(begin:100, end:200) == 193.2914351341 + +--See also-- +| [[fun:random_int]] Generate a random [[type:int|integer number]]. diff --git a/doc/function/random_select.txt b/doc/function/random_select.txt new file mode 100644 index 00000000..2f9a92fb --- /dev/null +++ b/doc/function/random_select.txt @@ -0,0 +1,32 @@ +Function: random_select + +DOC_MSE_VERSION: since 0.3.7 + +--Usage-- +> random_select(some_list, count: some_number, replace: some_boolean) + +Randomly select a number of items from a list. + +If the @count@ parameter is not given, then a single item is picked at random. + +Otherwise @count@ ''different'' items are selected (selection without replacment). +Setting the @replace@ parameter allows the same item to occur more than once in the result (selection with replacment). + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:list]] List to shuffle. +| @count@ [[type:int]] Number of items to select. +| @replace@ [[type:boolean]] Select with replacement? + +--Examples-- +> random_select([1,2,3,4]) == 4 +> random_select([1,2,3,4]) == 2 +> random_select([1,2,3,4], count:3) == [2,3,1] +> random_select([1,2,3,4], count:3) == [3,1,4] +> random_select([1,2,3,4], count:3, replace: true) == [2,3,2] +> random_select([1,2,3,4], count:3, replace: true) == [1,3,4] + +--See also-- +| [[fun:random_shuffle]] Randomly shuffle a list. diff --git a/doc/function/random_shuffle.txt b/doc/function/random_shuffle.txt new file mode 100644 index 00000000..5a92daf1 --- /dev/null +++ b/doc/function/random_shuffle.txt @@ -0,0 +1,21 @@ +Function: random_shuffle + +DOC_MSE_VERSION: since 0.3.7 + +--Usage-- +> random_shuffle(some_list) + +Randomly shuffle a list, putting the elements in a different order. + +Since the result is random, calling the function twice will give a different answer. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:list]] List to shuffle. + +--Examples-- +> random_shuffle([1,2,3,4]) == [4,1,2,3] +> random_shuffle([1,2,3,4]) == [2,3,4,1] + +--See also-- +| [[fun:random_select]] Pick random elements from a list. diff --git a/doc/function/to_int.txt b/doc/function/to_int.txt index d07cd696..31eed073 100644 --- a/doc/function/to_int.txt +++ b/doc/function/to_int.txt @@ -16,9 +16,11 @@ Convert any value to a [[type:int]]. | @input@ ''any type'' Value to convert to an integer number --Examples-- -> to_int(1.5) == "1" -> to_int("15") == "15" -> to_int(true) == 1 +> to_int(1.5) == "1" +> to_int("15") == "15" +> to_int(true) == 1 +> to_int(rgb(255,255,255)) == 255 --See also-- | [[fun:to_real]] Convert any value to a [[type:double]] +| [[fun:to_number]] Convert any value to a number diff --git a/doc/function/to_number.txt b/doc/function/to_number.txt new file mode 100644 index 00000000..29041b2f --- /dev/null +++ b/doc/function/to_number.txt @@ -0,0 +1,25 @@ +Function: to_number + +DOC_MSE_VERSION: since 0.3.7 + +--Usage-- +> to_number(any value) + +Convert any value to a number. +If the number can be represented as an [[type:int|integer number]] that is done. +Otherwise it is converted to a [[type:double]]. + + +--Parameters-- +! Parameter Type Description +| @input@ ''any type'' Value to convert to a number + +--Examples-- +> to_number(1) == 1 +> to_number(1.5) == 1.5 +> to_number("1") == 1 +> to_number("1.5") == 1.5 + +--See also-- +| [[fun:to_int]] Convert any value to a [[type:int]] +| [[fun:to_real]] Convert any value to a [[type:double]] diff --git a/doc/function/to_real.txt b/doc/function/to_real.txt index c23def60..c8cdf3f5 100644 --- a/doc/function/to_real.txt +++ b/doc/function/to_real.txt @@ -14,7 +14,8 @@ Convert any value to a [[type:double]]. --Examples-- > to_real(1) == 1.0 -> to_real("1.5") == "1.5" +> to_real("1.5") == 1.5 --See also-- | [[fun:to_int]] Convert any value to a [[type:int]] +| [[fun:to_number]] Convert any value to a number diff --git a/doc/script/index.txt b/doc/script/index.txt index 64b477c1..e36e22a8 100644 --- a/doc/script/index.txt +++ b/doc/script/index.txt @@ -34,6 +34,7 @@ See also: | @a / b@ [[script:operators|Floating point division]] | @a div b@ [[script:operators|Integer division]] | @a mod b@ [[script:operators|Remainder]] +| @a ^ b@ [[script:operators|Exponentiation]] | @not a@ [[type:boolean|Boolean not]] | @a and b@ [[type:boolean|Boolean conjunction]] | @a or b@ [[type:boolean|Boolean disjunction]] diff --git a/doc/script/operators.txt b/doc/script/operators.txt index 30f79887..6f940f59 100644 --- a/doc/script/operators.txt +++ b/doc/script/operators.txt @@ -10,8 +10,11 @@ MSE script supports most basic mathamatical operators: | @a - b@ @3 - 2 == 1@ Substract two numbers | @a * b@ @3 * 2 == 6@ Multiply two numbers | @a / b@ @3 / 2 == 1.5@ Divide two numbers. Does not round, always produces a [[type:double]]. -| @a div b@ @3 div 2 == 1@ Divide two numbers. Rounds towards zero, producing an [[type:int]].
+| @a div b@ @3 div 2 == 1@ DOC_MSE_VERSION: since 0.3.7 + Divide two numbers. Rounds towards zero, producing an [[type:int]]. | @a mod b@ @3 mod 2 == 1@ Take the remainder after integer division (modulo) +| @a ^ b@ @3 ^ 2 == 9@ DOC_MSE_VERSION: since 0.3.7 + Exponentation, raise a to the power b.
The numbers can be [[type:double]]s, so to calculate a square root use @2^0.5 == 1.41421356237@. | @-a@ @-(3 + 2) == -5@ Negate a number (make it negative if positive and vice versa) ===The + operator===