diff --git a/doc/function/add_card_to_set.txt b/doc/function/add_card_to_set.txt new file mode 100644 index 00000000..6a5febda --- /dev/null +++ b/doc/function/add_card_to_set.txt @@ -0,0 +1,21 @@ +Function: add_card_to_set + +--Usage-- +> add_card_to_set(card, set: set) + +Add a [[type:card]] to a [[type:set]]. + +If the input is a collection, all cards contained inside will be added. + +Returns true if a card was actually added to the set. + +This is for use in the CLI. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:card]] The card you want to add. +| @set@ [[type:set]] The set the card must belong to. + +--Examples-- +> # Create a new card and add it to the current set: +> add_card_to_set(new_card([])) diff --git a/doc/function/index.txt b/doc/function/index.txt index 188ddfe0..88316bbd 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -101,8 +101,9 @@ These functions are built into the program, other [[type:function]]s can be defi ! Cards <<< | [[fun:new_card]] Construct a new [[type:card]] object. +| [[fun:add_card_to_set]] Add a [[type:card]] to a [[type:set]]. | [[fun:get_card_styling]] Get the styling data of a [[type:card]]. -| [[fun:get_card_styesheet]] Get the stylesheet of a [[type:card]]. +| [[fun:get_card_stylesheet]] Get the stylesheet of a [[type:card]]. ! HTML export <<< | [[fun:to_html]] Convert [[type:tagged text]] to html. diff --git a/doc/function/new_card.txt b/doc/function/new_card.txt index 80fa03af..c61630c8 100644 --- a/doc/function/new_card.txt +++ b/doc/function/new_card.txt @@ -3,24 +3,30 @@ Function: new_card --Usage-- > new_card(map_of_field_names_to_values) -Create a new [[type:card]] object not already in the set. +Creates a new [[type:card]] object. The card is not automatically added to a set. Use the [[fun:add_card_to_set]] function for that. -The argument is a map of values to set, for example @new_card([name: "My Card"])@ creates a card with the name @"My Card"@, and all other fields at their default value. - -NOTE: you should use underscores instead of spaces in field names. +The argument is a map from card field names to values, for example @new_card([name: "My Card"])@ creates a card with the name @"My Card"@, and all other fields at their default value. + +The map can also contain the following built-in keys: notes, id, linked_card_1 to linked_card_4, linked_relation_1 to linked_relation_4, stylesheet, and styling_data. For styling_data, the value must itself be a map from styling field names to values. Be sure to define a stylesheet before styling_data. + +NOTE: you should use underscores instead of spaces in field names. --Parameters-- ! Parameter Type Description | @input@ [[type:map]] of field names to field values Field values to set -| @ignore_field_not_found@ [[type:boolean]] Optional. If set to true, key/value pairs that don't correspond to a card field will be ignored instead of throwing. +| @ignore_field_not_found@ [[type:boolean]] Optional. If set to true, key/value pairs that don't correspond to a field will be ignored instead of throwing. --Examples-- > # Create a new card > my_card := new_card( -> [ name: "My Card" ->> , type: "Super cool" +> [ name: "My Card" >> , rule_text: "This card is mine!" +>> , stylesheet: "magic-m15-adventure.mse-style" +>> , styling_data: [frames: "Reversed, vehicle", chop_main: "5,5"] > ]) > > # Write an image of the card to a file -> write_image_file(my_card, file: "my_card.jpg") +> write_image_file(my_card, file: "my_card.png") + +> # Add the card to the current set +> add_card_to_set(my_card) diff --git a/src/script/functions/construction.cpp b/src/script/functions/construction.cpp index a8d4ffe6..75aad5ef 100644 --- a/src/script/functions/construction.cpp +++ b/src/script/functions/construction.cpp @@ -37,7 +37,7 @@ SCRIPT_FUNCTION(new_card) { if (key == script_nil) continue; String key_name = key->toString(); // check if the given value is for a built-in field - if (set_builtin_container(game, new_card, value, key_name)) continue; + if (set_builtin_container(game, new_card, value, key_name, ignore_field_not_found)) continue; // find the field value (container) that corresponds to the given value Value* container = get_container(game, new_card, key_name, ignore_field_not_found); if (container == nullptr) continue; @@ -59,7 +59,7 @@ SCRIPT_FUNCTION(new_card) { if (script_key == script_nil) continue; String script_key_name = script_key->toString(); // check if the script value is for a built-in field - if (set_builtin_container(game, new_card, script_value, script_key_name)) continue; + if (set_builtin_container(game, new_card, script_value, script_key_name, ignore_field_not_found)) continue; // find the field value that corresponds to the script value Value* script_container = get_container(game, new_card, script_key_name, ignore_field_not_found); if (script_container == nullptr) continue; @@ -94,7 +94,7 @@ SCRIPT_FUNCTION(new_card) { if (script_key == script_nil) continue; String script_key_name = script_key->toString(); // check if the script value is for a built-in field - if (set_builtin_container(game, new_card, script_value, script_key_name)) continue; + if (set_builtin_container(game, new_card, script_value, script_key_name, ignore_field_not_found)) continue; // find the field value that corresponds to the script value Value* script_container = get_container(game, new_card, script_key_name, ignore_field_not_found); if (script_container == nullptr) continue; @@ -110,9 +110,41 @@ SCRIPT_FUNCTION(new_card) { } SCRIPT_RETURN(new_card); } + +SCRIPT_FUNCTION(add_card_to_set) { + SCRIPT_PARAM_C(ScriptValueP, input); + SCRIPT_PARAM_C(ScriptValueP, set); + ScriptObject* s = dynamic_cast*>(set.get()); + if (s) { + Set& _set = *s->getValue(); + ScriptObject* c = dynamic_cast*>(input.get()); + if (c) { + CardP _card = c->getValue(); + _set.actions.addAction(make_unique(ADD, _set, _card)); + SCRIPT_RETURN(true); + } + if (input->type() == SCRIPT_COLLECTION) { + vector _cards; + ScriptValueP it = input->makeIterator(); + ScriptValueP key; + while (ScriptValueP value = it->next(&key)) { + c = dynamic_cast*>(value.get()); + if (c) { + _cards.push_back(c->getValue()); + } + } + if (!_cards.empty()) { + _set.actions.addAction(make_unique(ADD, _set, _cards)); + SCRIPT_RETURN(true); + } + } + } + SCRIPT_RETURN(false); +} // ----------------------------------------------------------------------------- : Init void init_script_construction_functions(Context& ctx) { ctx.setVariable(_("new_card"), script_new_card); + ctx.setVariable(_("add_card_to_set"), script_add_card_to_set); } diff --git a/src/script/functions/construction_helper.hpp b/src/script/functions/construction_helper.hpp index 4aff7246..7b9f9b33 100644 --- a/src/script/functions/construction_helper.hpp +++ b/src/script/functions/construction_helper.hpp @@ -61,24 +61,80 @@ static void set_container(Value* container, ScriptValueP& value, String key_name } } -static bool set_builtin_container(GameP& game, CardP& card, ScriptValueP& value, String key_name) { +static bool set_builtin_container(GameP& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) { // check if the given value is for a built-in field, if found set it and return true key_name = unified_form(key_name); if (key_name == _("notes") || key_name == _("note")) { card->notes = value->toString(); return true; } else if (key_name == _("style") || key_name == _("stylesheet") || key_name == _("template")) { - if (trim(value->toString()) != wxEmptyString) card->stylesheet = StyleSheet::byGameAndName(*game, value->toString()); + if (trim(value->toString()) != wxEmptyString) { + card->stylesheet = StyleSheet::byGameAndName(*game, value->toString()); + if (card->stylesheet) card->styling_data.init(card->stylesheet->styling_fields); + } return true; } - // else if (key_name == _("id") || key_name == _("multiverse_id")) { - // card->id = value->toString(); + //else if (key_name == _("id") || key_name == _("uid")) { + // card->uid = value->toString(); // return true; //} - - //styling_data; - //linked_card; - //linked_relation_1; + //else if (key_name == _("linked_card") || key_name == _("linked_card_1")) { + // card->linked_card_1 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_card_2")) { + // card->linked_card_2 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_card_3")) { + // card->linked_card_3 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_card_4")) { + // card->linked_card_4 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_relation") || key_name == _("linked_relation_1")) { + // card->linked_relation_1 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_relation_2")) { + // card->linked_relation_2 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_relation_3")) { + // card->linked_relation_3 = value->toString(); + // return true; + //} + //else if (key_name == _("linked_relation_4")) { + // card->linked_relation_4 = value->toString(); + // return true; + //} + else if (key_name == _("styling_data") || key_name == _("style_data") || key_name == _("stylesheet_data") || key_name == _("template_data") || key_name == _("styling") + || key_name == _("styling_fields") || key_name == _("style_fields") || key_name == _("stylesheet_fields") || key_name == _("template_fields")) { + if (value->type() != SCRIPT_COLLECTION) { + throw ScriptError(_ERROR_("styling data not map")); + } + ScriptValueP value_it = value->makeIterator(); + ScriptValueP value_key; + while (ScriptValueP value_value = value_it->next(&value_key)) { + assert(value_key); + if (value_key == script_nil) continue; + String value_key_name = value_key->toString(); + IndexMap::const_iterator style_it = card->styling_data.find(value_key_name); + if (style_it == card->styling_data.end()) { + style_it = card->styling_data.find(value_key_name.Lower()); + if (style_it == card->styling_data.end()) { + if (!ignore_field_not_found) throw ScriptError(_ERROR_1_("no style field with name", value_key_name)); + continue; + } + } + Value* value_container = style_it->get(); + set_container(value_container, value_value, value_key_name); + card->has_styling = true; + } + return true; + } return false; } diff --git a/tools/website/drupal/mse-drupal-modules/highlight.inc b/tools/website/drupal/mse-drupal-modules/highlight.inc index 11558f7a..2fbb536c 100644 --- a/tools/website/drupal/mse-drupal-modules/highlight.inc +++ b/tools/website/drupal/mse-drupal-modules/highlight.inc @@ -96,6 +96,9 @@ $built_in_functions = array( 'built_in_image' =>'', // cards 'new_card' =>'', + 'add_card_to_set' =>'', + 'get_card_styling' =>'', + 'get_card_stylesheet' =>'', // html export 'to_html' =>'', 'symbols_to_html' =>'',