localize card links, add_link, remove_links

This commit is contained in:
GenevensiS
2025-12-16 19:05:33 +01:00
parent ee0a56f8c0
commit aeed54e4ba
15 changed files with 352 additions and 166 deletions
+18
View File
@@ -0,0 +1,18 @@
Function: add_link
--Usage--
> add_link(input: card, selected_relation: "link type", linked_card: other_card, linked_relation: "link type")
Links the input card and the linked_card together. The link is reciprocal if possible.
(Adds the linked_card to the input card's links, and gives it the linked_relation. Adds the input card to the linked_card's links, and gives it the selected_relation.)
Returns the linked_card, or nil if the linked_card was not found.
--Parameters--
! Parameter Type Description
| @input@ [[type:card]] or [[type:string]] One of the two cards we will link, or the uid of a card.
| @selected_relation@ [[type:string]] The type of link we will give to the input card.
| @linked_card@ [[type:card]] or [[type:string]] The other of the two cards we will link, or the uid of the other card.
| @linked_relation@ [[type:string]] The type of link we will give to the linked card.
| @set@ [[type:set]] The set in which to look for the other card. This can be omitted since 'set' is a predefined variable.
+4 -4
View File
@@ -1,13 +1,13 @@
Function: get_cards_from_link Function: get_cards_from_link
--Usage-- --Usage--
> get_cards_from_link(card: card, input: "link type") > get_cards_from_link(input: card, linked_relation: "link type")
Inspects a given [[type:card]]'s links to find those of the given type, and returns an array containing the linked cards. Inspects a given [[type:card]]'s links to find those of the given type, and returns an array containing the linked cards.
Returns an empty array if no link of the given type, or no card was found. Returns an empty array if no link of the given type, or no card was found.
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @input@ [[type:string]] The type of link we want to find. | @input@ [[type:card]] The card whose links we'll inspect.
| @card@ [[type:card]] The card whose links we'll inspect. | @linked_relation@ [[type:string]] The type of link we want to find.
| @set@ [[type:set]] The set in which to look. This can be omited since 'set' is a predefined variable. | @set@ [[type:set]] The set in which to look. This can be omitted since 'set' is a predefined variable.
+4 -4
View File
@@ -1,14 +1,14 @@
Function: has_link Function: has_link
--Usage-- --Usage--
> has_link(card: card, "link type") > has_link(input: card, linked_relation: "link type")
Inspects a given [[type:card]]'s links to find one of the given type. Inspects a given [[type:card]]'s links to find one of the given type.
Returns true if such a link was found, false otherwise. Returns true if such a link was found, false otherwise.
Note that this function does not check if the linked card exists in the set. For that, use get_card_from_link. Note that this function does not check if the linked card exists in the set. For that, use get_cards_from_link.
--Parameters-- --Parameters--
! Parameter Type Description ! Parameter Type Description
| @input@ [[type:string]] The type of link we want to find. | @input@ [[type:card]] The card whose links we'll inspect.
| @card@ [[type:card]] The card whose links we'll inspect. | @linked_relation@ [[type:string]] The type of link we want to find.
+16
View File
@@ -0,0 +1,16 @@
Function: remove_links
--Usage--
> remove_links(input: card, linked_card: other card)
> remove_links(input: card, linked_relation: "link type")
Breaks the link between the input card and the linked_card. If a linked_relation is given, breaks the link between the input card and all cards with the linked_relation.
Returns an array containing all the cards that were unlinked.
--Parameters--
! Parameter Type Description
| @input@ [[type:card]] or [[type:string]] One of the two cards we will unlink, or the uid of a card.
| @linked_card@ [[type:card]] or [[type:string]] The other of the two cards we will unlink, or the uid of the other card.
| @linked_relation@ [[type:string]] The type of link we will break.
| @set@ [[type:set]] The set in which to look for the other card. This can be omitted since 'set' is a predefined variable.
+35 -5
View File
@@ -156,8 +156,7 @@ void Card::link(const Set& set, const vector<CardP>& linked_cards, const String&
ss << all_missed_cards[pos]->identification(); ss << all_missed_cards[pos]->identification();
if (pos < all_missed_cards.size() - 1) ss << ", "; if (pos < all_missed_cards.size() - 1) ss << ", ";
}; };
String wxString(ss.str().c_str(), wxConvUTF8); queue_message(MESSAGE_WARNING, wxString(ss.str().c_str()));
queue_message(MESSAGE_WARNING, wxString);
} }
} }
@@ -284,7 +283,7 @@ vector<pair<CardP, String>> Card::getLinkedCards(const Set& set) {
return getLinkedCards(set.cards); return getLinkedCards(set.cards);
} }
CardP Card::getOtherFace(const vector<CardP>& cards) { CardP Card::getLinkedOtherFace(const vector<CardP>& cards) {
unordered_set<String> faces; unordered_set<String> faces;
if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) faces.emplace(linked_card_1); if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) faces.emplace(linked_card_1);
if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) faces.emplace(linked_card_2); if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) faces.emplace(linked_card_2);
@@ -295,8 +294,39 @@ CardP Card::getOtherFace(const vector<CardP>& cards) {
} }
return nullptr; return nullptr;
} }
CardP Card::getOtherFace(const Set& set) { CardP Card::getLinkedOtherFace(const Set& set) {
return getOtherFace(set.cards); return getLinkedOtherFace(set.cards);
}
vector<CardP> Card::getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card) {
vector<CardP> other_cards;
THIS_LINKED_PAIRS(this_linked_pairs);
FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get();
String& this_linked_relation = this_linked_pair.second.get();
if (this_linked_relation == link) {
CardP other_card = getCardFromUid(cards, this_linked_uid);
if (other_card) other_cards.push_back(other_card);
else if (erase_if_no_card) {
this_linked_relation = _("");
this_linked_uid = _("");
}
}
}
return other_cards;
}
vector<CardP> Card::getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card) {
return getLinkedCardsFromLink(set.cards, link, erase_if_no_card);
}
CardP Card::getCardFromUid(const vector<CardP>& cards, const String& uid) {
FOR_EACH(card, cards) {
if (card->uid == uid) return card;
}
return nullptr;
}
CardP Card::getCardFromUid(const Set& set, const String& uid) {
return getCardFromUid(set.cards, uid);
} }
IndexMap<FieldP, ValueP>& Card::extraDataFor(const StyleSheet& stylesheet) { IndexMap<FieldP, ValueP>& Card::extraDataFor(const StyleSheet& stylesheet) {
+9 -2
View File
@@ -91,8 +91,15 @@ public:
vector<pair<CardP, String>> getLinkedCards(const vector<CardP>& cards); vector<pair<CardP, String>> getLinkedCards(const vector<CardP>& cards);
vector<pair<CardP, String>> getLinkedCards(const Set& set); vector<pair<CardP, String>> getLinkedCards(const Set& set);
CardP getOtherFace(const vector<CardP>& cards);
CardP getOtherFace(const Set& set); vector<CardP> getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card);
vector<CardP> getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card);
CardP getLinkedOtherFace(const vector<CardP>& cards);
CardP getLinkedOtherFace(const Set& set);
static CardP getCardFromUid(const vector<CardP>& cards, const String& uid);
static CardP getCardFromUid(const Set& set, const String& uid);
/// Find a value in the data by name and type /// Find a value in the data by name and type
template <typename T> T& value(const String& name) { template <typename T> T& value(const String& name) {
+23
View File
@@ -0,0 +1,23 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <data/card_link.hpp>
// ----------------------------------------------------------------------------- : CardLink
CardLink::CardLink() {}
String CardLink::name() {
return selected.get() + _(" // ") + linked.get();
}
IMPLEMENT_REFLECTION_NO_GET_MEMBER(CardLink) {
REFLECT_LOCALIZED(selected);
REFLECT_LOCALIZED(linked);
}
+30
View File
@@ -0,0 +1,30 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#pragma once
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/reflect.hpp>
#include <data/localized_string.hpp>
DECLARE_POINTER_TYPE(CardLink);
// ----------------------------------------------------------------------------- : Card Link
/// Information on a link between two cards in a set
class CardLink : public IntrusivePtrBase<CardLink> {
public:
CardLink();
LocalizedString selected; ///< Type of link for the selected card
LocalizedString linked; ///< Type of link for the linked card
String name();
private:
DECLARE_REFLECTION();
};
+56 -1
View File
@@ -1,4 +1,4 @@
//+----------------------------------------------------------------------------+ //+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers | //| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) | //| License: GNU General Public License 2 or later (see file COPYING) |
@@ -10,6 +10,7 @@
#include <data/game.hpp> #include <data/game.hpp>
#include <data/field.hpp> #include <data/field.hpp>
#include <data/field/choice.hpp> #include <data/field/choice.hpp>
#include <data/card_link.hpp>
#include <data/keyword.hpp> #include <data/keyword.hpp>
#include <data/statistics.hpp> #include <data/statistics.hpp>
#include <data/pack.hpp> #include <data/pack.hpp>
@@ -123,6 +124,60 @@ void Game::validate(Version v) {
} }
} }
} }
// front face/back face card link
card_links.insert(card_links.begin(), make_intrusive<CardLink>());
card_links[0]->selected.default_ = _("Front Face");
card_links[0]->selected.translations = std::unordered_map<String, String>{
{_("ch-s"), _("卡片正面")},
{_("ch-t"), _("卡片正面")},
{_("da"), _("Forside")},
{_("de"), _("Vorderseite")},
{_("en"), _("Front Face")},
{_("es"), _("Cara frontal")},
{_("fr"), _("Face Avant")},
{_("it"), _("Fronte")},
{_("jp"), _("カードの表面")},
{_("ko"), _("카드 앞면")},
{_("pl"), _("Przód")},
{_("pt-br"), _("Frente")},
{_("ru"), _("Лицевая сторона")}
};
card_links[0]->linked.default_ = _("Back Face");
card_links[0]->linked.translations = std::unordered_map<String, String>{
{_("ch-s"), _("卡片背面")},
{_("ch-t"), _("卡片背面")},
{_("da"), _("Bagside")},
{_("de"), _("Rückseite")},
{_("en"), _("Back Face")},
{_("es"), _("Cara posterior")},
{_("fr"), _("Face Arrière")},
{_("it"), _("Retro")},
{_("jp"), _("カードの裏面")},
{_("ko"), _("카드 뒷면")},
{_("pl"), _("Tył")},
{_("pt-br"), _("Verso")},
{_("ru"), _("Обратная сторона")}
};
// localized card link names map
for (auto it = card_links.begin(); it != card_links.end(); ++it) {
CardLinkP link = *it;
String selected_default = link->selected.default_;
for (auto selected_it = link->selected.translations.begin(); selected_it != link->selected.translations.end(); selected_it++) {
String selected_tr = unified_form(selected_it->second);
if (card_links_alt_names.find(selected_tr) != card_links_alt_names.end() && card_links_alt_names[selected_tr] != selected_default) {
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", selected_tr, card_links_alt_names[selected_tr], selected_default));
}
card_links_alt_names.emplace(selected_tr, selected_default);
}
String linked_default = link->linked.default_;
for (auto linked_it = link->linked.translations.begin(); linked_it != link->linked.translations.end(); linked_it++) {
String linked_tr = unified_form(linked_it->second);
if (card_links_alt_names.find(linked_tr) != card_links_alt_names.end() && card_links_alt_names[linked_tr] != linked_default) {
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", linked_tr, card_links_alt_names[linked_tr], linked_default));
}
card_links_alt_names.emplace(linked_tr, linked_default);
}
}
} }
void Game::initCardListColorScript() { void Game::initCardListColorScript() {
+3 -1
View File
@@ -19,6 +19,7 @@ DECLARE_POINTER_TYPE(Style);
DECLARE_POINTER_TYPE(Game); DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StatsDimension); DECLARE_POINTER_TYPE(StatsDimension);
DECLARE_POINTER_TYPE(StatsCategory); DECLARE_POINTER_TYPE(StatsCategory);
DECLARE_POINTER_TYPE(CardLink);
DECLARE_POINTER_TYPE(PackType); DECLARE_POINTER_TYPE(PackType);
DECLARE_POINTER_TYPE(KeywordParam); DECLARE_POINTER_TYPE(KeywordParam);
DECLARE_POINTER_TYPE(KeywordMode); DECLARE_POINTER_TYPE(KeywordMode);
@@ -41,7 +42,7 @@ public:
vector<FieldP> set_fields; ///< Fields for set information vector<FieldP> set_fields; ///< Fields for set information
IndexMap<FieldP,StyleP> default_set_style; ///< Default style for the set fields, because it is often the same IndexMap<FieldP,StyleP> default_set_style; ///< Default style for the set fields, because it is often the same
vector<FieldP> card_fields; ///< Fields on each card vector<FieldP> card_fields; ///< Fields on each card
vector<String> card_links; ///< Possible links between cards vector<CardLinkP> card_links; ///< Possible links between cards
OptionalScript card_list_color_script; ///< Script that determines the color of items in the card list OptionalScript card_list_color_script; ///< Script that determines the color of items in the card list
OptionalScript import_script; ///< Script applied as the last step of the new_card function OptionalScript import_script; ///< Script applied as the last step of the new_card function
vector<String> json_paths; ///< Paths inside JSON files to find the card array vector<String> json_paths; ///< Paths inside JSON files to find the card array
@@ -52,6 +53,7 @@ public:
vector<AddCardsScriptP> add_cards_scripts; ///< Scripts for adding multiple cards to the set vector<AddCardsScriptP> add_cards_scripts; ///< Scripts for adding multiple cards to the set
vector<AutoReplaceP> auto_replaces; ///< Things to autoreplace in textboxes vector<AutoReplaceP> auto_replaces; ///< Things to autoreplace in textboxes
map<String,String> card_fields_alt_names; ///< Other names that fields might go by, for example in CSV files map<String,String> card_fields_alt_names; ///< Other names that fields might go by, for example in CSV files
map<String,String> card_links_alt_names; ///< Localized names that card links go by
bool has_keywords; ///< Does this game use keywords? bool has_keywords; ///< Does this game use keywords?
OptionalScript keyword_match_script; ///< For the keyword editor OptionalScript keyword_match_script; ///< For the keyword editor
vector<KeywordParamP> keyword_parameter_types;///< Types of keyword parameters vector<KeywordParamP> keyword_parameter_types;///< Types of keyword parameters
+14 -8
View File
@@ -8,6 +8,7 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <data/game.hpp> #include <data/game.hpp>
#include <data/card_link.hpp>
#include <gui/card_link_window.hpp> #include <gui/card_link_window.hpp>
#include <gui/control/select_card_list.hpp> #include <gui/control/select_card_list.hpp>
#include <util/window_id.hpp> #include <util/window_id.hpp>
@@ -25,9 +26,8 @@ CardLinkWindow::CardLinkWindow(Window* parent, const SetP& set, const CardP& sel
linked_relation = new wxTextCtrl(this, wxID_ANY, _("")); linked_relation = new wxTextCtrl(this, wxID_ANY, _(""));
relation_type = new wxChoice(this, ID_CARD_LINK_TYPE, wxDefaultPosition, wxDefaultSize, 0, nullptr); relation_type = new wxChoice(this, ID_CARD_LINK_TYPE, wxDefaultPosition, wxDefaultSize, 0, nullptr);
relation_type->Clear(); relation_type->Clear();
relation_type->Append("Front Face // Back Face");
FOR_EACH(link, set->game->card_links) { FOR_EACH(link, set->game->card_links) {
relation_type->Append(link); relation_type->Append(link->name());
} }
relation_type->Append(_LABEL_("custom link")); relation_type->Append(_LABEL_("custom link"));
relation_type->SetSelection(0); relation_type->SetSelection(0);
@@ -69,19 +69,18 @@ void CardLinkWindow::setSelection(const vector<CardP>& cards) {
list->setSelection(cards); list->setSelection(cards);
} }
void CardLinkWindow::setRelationType() { void CardLinkWindow::setRelationType() {
int sel = relation_type->GetSelection(); int index = relation_type->GetSelection();
if (sel == relation_type->GetCount() - 1) { // Custom type if (index >= set->game->card_links.size()) { // Custom type
selected_relation->ChangeValue(_LABEL_("custom link selected")); selected_relation->ChangeValue(_LABEL_("custom link selected"));
selected_relation->Enable(); selected_relation->Enable();
linked_relation->ChangeValue(_LABEL_("custom link linked")); linked_relation->ChangeValue(_LABEL_("custom link linked"));
linked_relation->Enable(); linked_relation->Enable();
} }
else { else {
String relation = relation_type->GetString(sel); CardLinkP link = set->game->card_links[index];
int delimiter_pos = relation.find("//"); selected_relation->ChangeValue(link->selected.get());
selected_relation->ChangeValue(relation.substr(0, delimiter_pos).Trim().Trim(false));
selected_relation->Enable(false); selected_relation->Enable(false);
linked_relation->ChangeValue(delimiter_pos + 2 < relation.Length() ? relation.substr(delimiter_pos + 2).Trim().Trim(false) : _LABEL_("custom link undefined")); linked_relation->ChangeValue(link->linked.get());
linked_relation->Enable(false); linked_relation->Enable(false);
} }
} }
@@ -100,7 +99,14 @@ void CardLinkWindow::onOk(wxCommandEvent&) {
// The linked_cards are the ones selected in this dialogue window // The linked_cards are the ones selected in this dialogue window
vector<CardP> linked_cards; vector<CardP> linked_cards;
getSelection(linked_cards); getSelection(linked_cards);
int index = relation_type->GetSelection();
if (index >= set->game->card_links.size()) { // Custom type
set->actions.addAction(make_unique<LinkCardsAction>(*set, selected_card, linked_cards, selected_relation->GetValue(), linked_relation->GetValue())); set->actions.addAction(make_unique<LinkCardsAction>(*set, selected_card, linked_cards, selected_relation->GetValue(), linked_relation->GetValue()));
}
else {
CardLinkP link = set->game->card_links[index];
set->actions.addAction(make_unique<LinkCardsAction>(*set, selected_card, linked_cards, link->selected.default_, link->linked.default_));
}
// Done // Done
EndModal(wxID_OK); EndModal(wxID_OK);
} }
+1 -1
View File
@@ -37,7 +37,7 @@ void PrintJob::measure_cards() {
if (already_measured_cards.find(card) != already_measured_cards.end()) continue; if (already_measured_cards.find(card) != already_measured_cards.end()) continue;
already_measured_cards.emplace(card); already_measured_cards.emplace(card);
card_layouts.push_back(measure_card(card)); card_layouts.push_back(measure_card(card));
CardP other_face = card->getOtherFace(cards); CardP other_face = card->getLinkedOtherFace(cards);
if (other_face && already_measured_cards.find(other_face) == already_measured_cards.end()) { if (other_face && already_measured_cards.find(other_face) == already_measured_cards.end()) {
already_measured_cards.emplace(other_face); already_measured_cards.emplace(other_face);
card_layouts.push_back(measure_card(other_face)); card_layouts.push_back(measure_card(other_face));
+132 -133
View File
@@ -778,76 +778,35 @@ SCRIPT_FUNCTION(get_card_export_settings) {
SCRIPT_FUNCTION(get_card_from_uid) { SCRIPT_FUNCTION(get_card_from_uid) {
SCRIPT_PARAM_C(Set*, set); SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(String, input);
FOR_EACH(other_card, set->cards) { SCRIPT_RETURN(Card::getCardFromUid(*set, input));
if (other_card->uid == input) SCRIPT_RETURN(other_card);
}
return script_nil;
} }
SCRIPT_FUNCTION(get_cards_from_link) { SCRIPT_FUNCTION(get_cards_from_link) {
SCRIPT_PARAM_C(Set*, set); SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(CardP, card); SCRIPT_PARAM_C(ScriptValueP, input);
SCRIPT_PARAM_C(String, input); CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
SCRIPT_PARAM(String, linked_relation);
ScriptCustomCollectionP ret(new ScriptCustomCollection()); ScriptCustomCollectionP ret(new ScriptCustomCollection());
String trimmed_input = input.Trim().Trim(false); vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation, true);
if (card->linked_relation_1 == trimmed_input) { if (other_cards.size() > 0) {
String uid = card->linked_card_1; FOR_EACH(other_card, other_cards) {
bool found = false;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) {
ret->value.push_back(to_script(other_card)); ret->value.push_back(to_script(other_card));
found = true;
break;
} }
} }
if (!found) { else if (set->game->card_links_alt_names.find(linked_relation) != set->game->card_links_alt_names.end()) {
card->linked_relation_1 = _(""); other_cards = input_card->getLinkedCardsFromLink(*set, set->game->card_links_alt_names[linked_relation], true);
card->linked_card_1 = _(""); FOR_EACH(other_card, other_cards) {
}
}
if (card->linked_relation_2 == trimmed_input) {
String uid = card->linked_card_2;
bool found = false;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) {
ret->value.push_back(to_script(other_card)); ret->value.push_back(to_script(other_card));
found = true;
break;
}
}
if (!found) {
card->linked_relation_2 = _("");
card->linked_card_2 = _("");
}
}
if (card->linked_relation_3 == trimmed_input) {
String uid = card->linked_card_3;
bool found = false;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) {
ret->value.push_back(to_script(other_card));
found = true;
break;
}
}
if (!found) {
card->linked_relation_3 = _("");
card->linked_card_3 = _("");
}
}
if (card->linked_relation_4 == trimmed_input) {
String uid = card->linked_card_4;
bool found = false;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) {
ret->value.push_back(to_script(other_card));
found = true;
break;
}
}
if (!found) {
card->linked_relation_4 = _("");
card->linked_card_4 = _("");
} }
} }
return ret; return ret;
@@ -855,91 +814,129 @@ SCRIPT_FUNCTION(get_cards_from_link) {
SCRIPT_FUNCTION(get_front_face) { SCRIPT_FUNCTION(get_front_face) {
SCRIPT_PARAM_C(Set*, set); SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(CardP, input); SCRIPT_PARAM_C(ScriptValueP, input);
if (input->linked_relation_1 == _("Front Face")) { CardP input_card = nullptr;
String uid = input->linked_card_1; if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
FOR_EACH(other_card, set->cards) { input_card = ic->getValue();
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
} }
input->linked_relation_1 = _(""); else if (input->type() == SCRIPT_STRING) {
input->linked_card_1 = _(""); input_card = Card::getCardFromUid(*set, input->toString());
}
if (input->linked_relation_2 == _("Front Face")) {
String uid = input->linked_card_2;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_2 = _("");
input->linked_card_2 = _("");
}
if (input->linked_relation_3 == _("Front Face")) {
String uid = input->linked_card_3;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_3 = _("");
input->linked_card_3 = _("");
}
if (input->linked_relation_4 == _("Front Face")) {
String uid = input->linked_card_4;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_4 = _("");
input->linked_card_4 = _("");
} }
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil; return script_nil;
} }
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Front Face", true);
if (other_cards.size() == 0) return script_nil;
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple front faces", input_card->identification()));
SCRIPT_RETURN(other_cards[0]);
}
SCRIPT_FUNCTION(get_back_face) { SCRIPT_FUNCTION(get_back_face) {
SCRIPT_PARAM_C(Set*, set); SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(CardP, input); SCRIPT_PARAM_C(ScriptValueP, input);
if (input->linked_relation_1 == _("Back Face")) { CardP input_card = nullptr;
String uid = input->linked_card_1; if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
FOR_EACH(other_card, set->cards) { input_card = ic->getValue();
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
} }
input->linked_relation_1 = _(""); else if (input->type() == SCRIPT_STRING) {
input->linked_card_1 = _(""); input_card = Card::getCardFromUid(*set, input->toString());
}
if (input->linked_relation_2 == _("Back Face")) {
String uid = input->linked_card_2;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_2 = _("");
input->linked_card_2 = _("");
}
if (input->linked_relation_3 == _("Back Face")) {
String uid = input->linked_card_3;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_3 = _("");
input->linked_card_3 = _("");
}
if (input->linked_relation_4 == _("Back Face")) {
String uid = input->linked_card_4;
FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card);
}
input->linked_relation_4 = _("");
input->linked_card_4 = _("");
} }
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil; return script_nil;
} }
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Back Face", true);
if (other_cards.size() == 0) return script_nil;
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple back faces", input_card->identification()));
SCRIPT_RETURN(other_cards[0]);
}
SCRIPT_FUNCTION(add_link) {
SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
SCRIPT_PARAM(ScriptValueP, linked_card);
CardP other_card = nullptr;
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
return script_nil;
}
SCRIPT_PARAM(String, selected_relation);
SCRIPT_PARAM(String, linked_relation);
input_card->link(*set, other_card, selected_relation, linked_relation);
SCRIPT_RETURN(other_card);
}
SCRIPT_FUNCTION(remove_links) {
SCRIPT_PARAM_C(Set*, set);
ScriptCustomCollectionP ret(new ScriptCustomCollection());
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return ret;
}
vector<CardP> other_cards;
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_card, script_nil);
if (linked_card != script_nil) {
CardP other_card = nullptr;
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
}
else other_cards.push_back(other_card);
}
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_relation, script_nil);
if (linked_relation != script_nil) {
if (linked_relation->type() == SCRIPT_STRING) {
vector<CardP> other_other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation->toString(), true);
other_cards.insert(other_cards.end(), other_other_cards.begin(), other_other_cards.end());
}
}
input_card->unlink(other_cards);
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
return ret;
}
SCRIPT_FUNCTION(has_link) { SCRIPT_FUNCTION(has_link) {
SCRIPT_PARAM_C(CardP, card); SCRIPT_PARAM_C(CardP, input);
SCRIPT_PARAM_C(String, input); SCRIPT_PARAM(String, linked_relation);
String trimmed_input = input.Trim().Trim(false); SCRIPT_RETURN(
if ( input->linked_relation_1 == linked_relation ||
card->linked_relation_1 == trimmed_input || input->linked_relation_2 == linked_relation ||
card->linked_relation_2 == trimmed_input || input->linked_relation_3 == linked_relation ||
card->linked_relation_3 == trimmed_input || input->linked_relation_4 == linked_relation
card->linked_relation_4 == trimmed_input );
) SCRIPT_RETURN(true);
SCRIPT_RETURN(false);
} }
// ----------------------------------------------------------------------------- : Keywords // ----------------------------------------------------------------------------- : Keywords
@@ -1045,6 +1042,8 @@ void init_script_basic_functions(Context& ctx) {
ctx.setVariable(_("get_back_face"), script_get_back_face); ctx.setVariable(_("get_back_face"), script_get_back_face);
ctx.setVariable(_("get_front_face"), script_get_front_face); ctx.setVariable(_("get_front_face"), script_get_front_face);
ctx.setVariable(_("has_link"), script_has_link); ctx.setVariable(_("has_link"), script_has_link);
ctx.setVariable(_("add_link"), script_add_link);
ctx.setVariable(_("remove_links"), script_remove_links);
// math // math
ctx.setVariable(_("abs"), script_abs); ctx.setVariable(_("abs"), script_abs);
ctx.setVariable(_("random_real"), script_random_real); ctx.setVariable(_("random_real"), script_random_real);
+1 -1
View File
@@ -137,7 +137,7 @@ void uncanonical_name_form_in_place(String& str) {
} }
} }
String unified_form(String& str) { String unified_form(String str) {
str = trim(str); str = trim(str);
for (String::iterator it = str.begin(); it != str.end(); ++it) { for (String::iterator it = str.begin(); it != str.end(); ++it) {
if (*it == ' ') *it = '_'; if (*it == ' ') *it = '_';
+1 -1
View File
@@ -244,7 +244,7 @@ inline String uncanonical_name_form(String s) {
} }
/// Convert a field name to canonical form, then to lower case, then trim it /// Convert a field name to canonical form, then to lower case, then trim it
String unified_form(String&); String unified_form(String);
/// Convert a field name to a string that can be shown to the user /// Convert a field name to a string that can be shown to the user
String name_to_caption(const String&); String name_to_caption(const String&);