mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
add card uid map
This commit is contained in:
+10
-14
@@ -30,13 +30,6 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector<CardP>&
|
||||
// We always assume uid conflicts occur because a card was copy-pasted into the same set,
|
||||
// and never because two different cards randomly got assigned the same uid
|
||||
if (!action.adding) return;
|
||||
// Tally existing unique ids
|
||||
unordered_map<String, CardP> all_existing_cards;
|
||||
unordered_set<String> all_existing_uids;
|
||||
FOR_EACH(card, set.cards) {
|
||||
all_existing_cards.insert({ card->uid, card });
|
||||
all_existing_uids.insert(card->uid);
|
||||
}
|
||||
// Tally added unique ids
|
||||
unordered_map<String, CardP> all_added_uids;
|
||||
for (size_t pos = 0; pos < action.steps.size(); ++pos) {
|
||||
@@ -49,7 +42,7 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector<CardP>&
|
||||
String old_uid = added_pair.first;
|
||||
CardP added_card = added_pair.second;
|
||||
// Assign new unique id if necessary
|
||||
if (all_existing_cards.find(old_uid) == all_existing_cards.end()) continue;
|
||||
if (set.card_uids.find(old_uid) == set.card_uids.end()) continue;
|
||||
String new_uid = generate_uid();
|
||||
added_card->uid = new_uid;
|
||||
all_added_uids.insert({ new_uid, added_card });
|
||||
@@ -58,14 +51,14 @@ AddCardAction::AddCardAction(AddingOrRemoving ar, Set& set, const vector<CardP>&
|
||||
FOR_EACH(linked_pair, linked_pairs) {
|
||||
String& linked_uid = linked_pair.first.get();
|
||||
if (linked_uid.empty()) continue;
|
||||
// If it's an added card, replace the link
|
||||
// If it's an added card, update the link
|
||||
if (all_added_uids.find(linked_uid) != all_added_uids.end()) {
|
||||
all_added_uids.at(linked_uid)->updateLinkedUID(old_uid, new_uid);
|
||||
}
|
||||
// Otherwise, if it's an existing card, create an action to copy the link
|
||||
else if (all_existing_cards.find(linked_uid) != all_existing_cards.end()) {
|
||||
CardP linked_card = all_existing_cards.at(linked_uid);
|
||||
int linked_index = linked_card->findFreeLink(new_uid, all_existing_uids);
|
||||
else if (set.card_uids.find(linked_uid) != set.card_uids.end()) {
|
||||
CardP linked_card = set.card_uids.at(linked_uid);
|
||||
int linked_index = linked_card->findFreeLink(new_uid, set.card_uids);
|
||||
if (linked_index < 0) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_1_("not enough free links", linked_card->identification()));
|
||||
}
|
||||
@@ -88,7 +81,9 @@ void AddCardAction::perform(bool to_undo) {
|
||||
// Update card links
|
||||
for (size_t i = 0; i < card_link_actions.size(); ++i) {
|
||||
card_link_actions[i]->perform(to_undo);
|
||||
}
|
||||
}
|
||||
// Update uid map
|
||||
set.buildUidMap();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Reorder cards
|
||||
@@ -249,7 +244,8 @@ void ChangeCardUIDAction::perform(bool to_undo) {
|
||||
FOR_EACH(c, set.cards) {
|
||||
c->updateLinkedUID(card->uid, uid);
|
||||
}
|
||||
swap(card->uid, uid);
|
||||
swap(card->uid, uid);
|
||||
set.buildUidMap();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Pack types
|
||||
|
||||
+88
-45
@@ -67,7 +67,7 @@ bool Card::contains(QuickFilterPart const& query) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
vector<int> Card::findFreeLinks(vector<String>& linked_uids, const unordered_set<String>& all_existing_uids) {
|
||||
vector<int> Card::findFreeLinks(vector<String>& linked_uids, const unordered_map<String, CardP>& all_existing_uids) {
|
||||
vector<int> freeIndexes;
|
||||
int count = min(4, (int)linked_uids.size());
|
||||
LINK_PAIRS(linked_pairs, this);
|
||||
@@ -109,7 +109,7 @@ vector<int> Card::findFreeLinks(vector<String>& linked_uids, const unordered_set
|
||||
}
|
||||
return freeIndexes;
|
||||
}
|
||||
int Card::findFreeLink(const String& linked_uid, const unordered_set<String>& all_existing_uids) {
|
||||
int Card::findFreeLink(const String& linked_uid, const unordered_map<String, CardP>& all_existing_uids) {
|
||||
vector<String> linked_uids { linked_uid };
|
||||
return findFreeLinks(linked_uids, all_existing_uids)[0];
|
||||
}
|
||||
@@ -155,12 +155,26 @@ void Card::updateLinkedUID(const String& old_uid, const String& new_uid) {
|
||||
if (index >= 0) getLinkedUID(index) = new_uid;
|
||||
}
|
||||
|
||||
vector<CardP> Card::getLinkedRelationCards(const vector<CardP>& cards, const String& linked_relation, bool erase_if_no_card) {
|
||||
//vector<CardP> Card::getLinkedRelationCards(const vector<CardP>& cards, const String& linked_relation, bool erase_if_no_card) {
|
||||
// vector<CardP> other_cards;
|
||||
// vector<int> indexes = findRelationLinks(linked_relation);
|
||||
// for (size_t i = 0; i < indexes.size(); ++i) {
|
||||
// String& linked_uid = getLinkedUID(indexes[i]);
|
||||
// CardP other_card = getUIDCard(cards, linked_uid);
|
||||
// if (other_card) other_cards.push_back(other_card);
|
||||
// else if (erase_if_no_card) {
|
||||
// linked_uid = _("");
|
||||
// getLinkedRelation(indexes[i]) = _("");
|
||||
// }
|
||||
// }
|
||||
// return other_cards;
|
||||
//}
|
||||
vector<CardP> Card::getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card) {
|
||||
vector<CardP> other_cards;
|
||||
vector<int> indexes = findRelationLinks(linked_relation);
|
||||
for (size_t i = 0; i < indexes.size(); ++i) {
|
||||
String& linked_uid = getLinkedUID(indexes[i]);
|
||||
CardP other_card = getUIDCard(cards, linked_uid);
|
||||
CardP other_card = getUIDCard(set, linked_uid);
|
||||
if (other_card) other_cards.push_back(other_card);
|
||||
else if (erase_if_no_card) {
|
||||
linked_uid = _("");
|
||||
@@ -169,51 +183,76 @@ vector<CardP> Card::getLinkedRelationCards(const vector<CardP>& cards, const Str
|
||||
}
|
||||
return other_cards;
|
||||
}
|
||||
vector<CardP> Card::getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card) {
|
||||
return getLinkedRelationCards(set.cards, linked_relation, erase_if_no_card);
|
||||
}
|
||||
|
||||
vector<pair<CardP, String>> Card::getLinkedCards(const vector<CardP>& cards) {
|
||||
unordered_map<String, String> links{
|
||||
{ linked_card_1, linked_relation_1 },
|
||||
{ linked_card_2, linked_relation_2 },
|
||||
{ linked_card_3, linked_relation_3 },
|
||||
{ linked_card_4, linked_relation_4 }
|
||||
};
|
||||
//vector<pair<CardP, String>> Card::getLinkedCards(const vector<CardP>& cards) {
|
||||
// unordered_map<String, String> links{
|
||||
// { linked_card_1, linked_relation_1 },
|
||||
// { linked_card_2, linked_relation_2 },
|
||||
// { linked_card_3, linked_relation_3 },
|
||||
// { linked_card_4, linked_relation_4 }
|
||||
// };
|
||||
// vector<pair<CardP, String>> linked_cards;
|
||||
// FOR_EACH(other_card, cards) {
|
||||
// if (links.find(other_card->uid) != links.end()) {
|
||||
// linked_cards.push_back(make_pair(other_card, links.at(other_card->uid)));
|
||||
// }
|
||||
// }
|
||||
// return linked_cards;
|
||||
//}
|
||||
vector<pair<CardP, String>> Card::getLinkedCards(const Set& set) {
|
||||
vector<pair<CardP, String>> linked_cards;
|
||||
FOR_EACH(other_card, cards) {
|
||||
if (links.find(other_card->uid) != links.end()) {
|
||||
linked_cards.push_back(make_pair(other_card, links.at(other_card->uid)));
|
||||
}
|
||||
CardP other_card_1 = getUIDCard(set, linked_card_1);
|
||||
if (other_card_1) {
|
||||
linked_cards.push_back(make_pair(other_card_1, linked_relation_1));
|
||||
}
|
||||
CardP other_card_2 = getUIDCard(set, linked_card_2);
|
||||
if (other_card_2) {
|
||||
linked_cards.push_back(make_pair(other_card_2, linked_relation_2));
|
||||
}
|
||||
CardP other_card_3 = getUIDCard(set, linked_card_3);
|
||||
if (other_card_3) {
|
||||
linked_cards.push_back(make_pair(other_card_3, linked_relation_3));
|
||||
}
|
||||
CardP other_card_4 = getUIDCard(set, linked_card_4);
|
||||
if (other_card_4) {
|
||||
linked_cards.push_back(make_pair(other_card_4, linked_relation_4));
|
||||
}
|
||||
return linked_cards;
|
||||
}
|
||||
vector<pair<CardP, String>> Card::getLinkedCards(const Set& set) {
|
||||
return getLinkedCards(set.cards);
|
||||
}
|
||||
|
||||
CardP Card::getLinkedOtherFaceCard(const vector<CardP>& cards) {
|
||||
unordered_set<String> faces;
|
||||
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_3 == _("Front Face") || linked_relation_3 == _("Back Face")) faces.emplace(linked_card_3);
|
||||
if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) faces.emplace(linked_card_4);
|
||||
FOR_EACH(other_card, cards) {
|
||||
if (faces.find(other_card->uid) != faces.end()) return other_card;
|
||||
//CardP Card::getLinkedOtherFaceCard(const vector<CardP>& cards) {
|
||||
// unordered_set<String> faces;
|
||||
// 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_3 == _("Front Face") || linked_relation_3 == _("Back Face")) faces.emplace(linked_card_3);
|
||||
// if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) faces.emplace(linked_card_4);
|
||||
// FOR_EACH(other_card, cards) {
|
||||
// if (faces.find(other_card->uid) != faces.end()) return other_card;
|
||||
// }
|
||||
// return nullptr;
|
||||
//}
|
||||
CardP Card::getLinkedOtherFaceCard(const Set& set) {
|
||||
if (linked_relation_1 == _("Front Face") || linked_relation_1 == _("Back Face")) {
|
||||
CardP other_card_1 = getUIDCard(set, linked_card_1);
|
||||
if (other_card_1) return other_card_1;
|
||||
}
|
||||
if (linked_relation_2 == _("Front Face") || linked_relation_2 == _("Back Face")) {
|
||||
CardP other_card_2 = getUIDCard(set, linked_card_2);
|
||||
if (other_card_2) return other_card_2;
|
||||
}
|
||||
if (linked_relation_3 == _("Front Face") || linked_relation_3 == _("Back Face")) {
|
||||
CardP other_card_3 = getUIDCard(set, linked_card_3);
|
||||
if (other_card_3) return other_card_3;
|
||||
}
|
||||
if (linked_relation_4 == _("Front Face") || linked_relation_4 == _("Back Face")) {
|
||||
CardP other_card_4 = getUIDCard(set, linked_card_4);
|
||||
if (other_card_4) return other_card_4;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
CardP Card::getLinkedOtherFaceCard(const Set& set) {
|
||||
return getLinkedOtherFaceCard(set.cards);
|
||||
}
|
||||
|
||||
void Card::addLink(const Set& set, CardP& linked_card, const String& selected_relation, const String& linked_relation) {
|
||||
unordered_set<String> all_existing_uids;
|
||||
FOR_EACH(card, set.cards) {
|
||||
all_existing_uids.insert(card->uid);
|
||||
}
|
||||
|
||||
int index = findFreeLink(linked_card->uid, all_existing_uids);
|
||||
int index = findFreeLink(linked_card->uid, set.card_uids);
|
||||
if (index < 0) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_1_("not enough free links", identification()));
|
||||
return;
|
||||
@@ -221,7 +260,7 @@ void Card::addLink(const Set& set, CardP& linked_card, const String& selected_re
|
||||
getLinkedUID(index) = linked_card->uid;
|
||||
getLinkedRelation(index) = linked_relation;
|
||||
|
||||
index = linked_card->findFreeLink(uid, all_existing_uids);
|
||||
index = linked_card->findFreeLink(uid, set.card_uids);
|
||||
if (index < 0) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_1_("not enough free links", linked_card->identification()));
|
||||
}
|
||||
@@ -246,15 +285,19 @@ void Card::removeLink(const CardP& linked_card)
|
||||
}
|
||||
}
|
||||
|
||||
CardP Card::getUIDCard(const vector<CardP>& cards, const String& uid) {
|
||||
FOR_EACH(card, cards) {
|
||||
if (card->uid == uid) return card;
|
||||
//CardP Card::getUIDCard(const vector<CardP>& cards, const String& uid) {
|
||||
// FOR_EACH(card, cards) {
|
||||
// if (card->uid == uid) return card;
|
||||
// }
|
||||
// return nullptr;
|
||||
//}
|
||||
CardP Card::getUIDCard(const Set& set, const String& uid) {
|
||||
auto it = set.card_uids.find(uid);
|
||||
if (it != set.card_uids.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
CardP Card::getUIDCard(const Set& set, const String& uid) {
|
||||
return getUIDCard(set.cards, uid);
|
||||
}
|
||||
|
||||
IndexMap<FieldP, ValueP>& Card::extraDataFor(const StyleSheet& stylesheet) {
|
||||
return extra_data.get(stylesheet.name(), stylesheet.extra_card_fields);
|
||||
|
||||
+6
-6
@@ -106,8 +106,8 @@ public:
|
||||
}
|
||||
|
||||
/// Find the index of a free link slot to write to. Returns -1 if not found.
|
||||
int findFreeLink (const String& linked_uid, const unordered_set<String>& all_existing_uids);
|
||||
vector<int> findFreeLinks(vector<String>& linked_uids, const unordered_set<String>& all_existing_uids);
|
||||
int findFreeLink (const String& linked_uid, const unordered_map<String, CardP>& all_existing_uids);
|
||||
vector<int> findFreeLinks(vector<String>& linked_uids, const unordered_map<String, CardP>& all_existing_uids);
|
||||
|
||||
/// Find the index of a link slot that references the linked_uid. Returns -1 if not found.
|
||||
int findUIDLink(const String& linked_uid);
|
||||
@@ -125,18 +125,18 @@ public:
|
||||
//void updateLinkedRelation(const String& old_relation, const String& new_relation);
|
||||
|
||||
/// Get the card with the given uid.
|
||||
static CardP getUIDCard(const vector<CardP>& cards, const String& uid);
|
||||
//static CardP getUIDCard(const vector<CardP>& cards, const String& uid);
|
||||
static CardP getUIDCard(const Set& set, const String& uid);
|
||||
/// Get all the cards linked to this card with the given relation.
|
||||
vector<CardP> getLinkedRelationCards(const vector<CardP>& cards, const String& linked_relation, bool erase_if_no_card = true);
|
||||
//vector<CardP> getLinkedRelationCards(const vector<CardP>& cards, const String& linked_relation, bool erase_if_no_card = true);
|
||||
vector<CardP> getLinkedRelationCards(const Set& set, const String& linked_relation, bool erase_if_no_card = true);
|
||||
|
||||
/// Get all the cards linked to this card.
|
||||
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);
|
||||
|
||||
/// Get the back face or front face of this card.
|
||||
CardP getLinkedOtherFaceCard(const vector<CardP>& cards);
|
||||
//CardP getLinkedOtherFaceCard(const vector<CardP>& cards);
|
||||
CardP getLinkedOtherFaceCard(const Set& set);
|
||||
|
||||
/// Link a card to this card.
|
||||
|
||||
+14
-1
@@ -22,6 +22,7 @@
|
||||
#include <util/tagged_string.hpp> // for 0.2.7 fix
|
||||
#include <util/order_cache.hpp>
|
||||
#include <util/delayed_index_maps.hpp>
|
||||
#include <util/uid.hpp>
|
||||
#include <script/script_manager.hpp>
|
||||
#include <script/profiler.hpp>
|
||||
#include <wx/sstream.h>
|
||||
@@ -67,6 +68,16 @@ void Set::updateStyles(const CardP& card, bool only_content_dependent) {
|
||||
void Set::updateDelayed() {
|
||||
script_manager->updateDelayed();
|
||||
}
|
||||
void Set::buildUidMap() {
|
||||
card_uids.clear();
|
||||
FOR_EACH(c, cards) {
|
||||
while (card_uids.find(c->uid) != card_uids.end()) {
|
||||
queue_message(MESSAGE_WARNING, _("Multiple cards found with same uid:\n") + c->identification() + _("\n") + card_uids[c->uid]->identification() + _("\nPlease notify someone on the Discord server."));
|
||||
c->uid = generate_uid();
|
||||
}
|
||||
card_uids[c->uid] = c;
|
||||
}
|
||||
}
|
||||
|
||||
Context& Set::getContextForThumbnails() {
|
||||
assert(!wxThread::IsMain());
|
||||
@@ -188,7 +199,9 @@ void Set::validate(Version file_app_version) {
|
||||
// we want at least one card
|
||||
if (cards.empty()) cards.push_back(make_intrusive<Card>(*game));
|
||||
// update scripts
|
||||
script_manager->updateAll();
|
||||
script_manager->updateAll();
|
||||
// build uid map
|
||||
buildUidMap();
|
||||
}
|
||||
|
||||
void reflect_version_check(Reader& handler, const Char* key, intrusive_ptr<Packaged> const& package) {
|
||||
|
||||
+14
-11
@@ -45,21 +45,22 @@ public:
|
||||
Set(const StyleSheetP& stylesheet);
|
||||
~Set();
|
||||
|
||||
GameP game; ///< The game this set uses
|
||||
StyleSheetP stylesheet; ///< The default stylesheet
|
||||
GameP game; ///< The game this set uses
|
||||
StyleSheetP stylesheet; ///< The default stylesheet
|
||||
/// The values on the fields of the set
|
||||
/** The indices should correspond to the set_fields in the Game */
|
||||
IndexMap<FieldP, ValueP> data;
|
||||
IndexMap<FieldP, ValueP> data;
|
||||
/// Extra values for specific stylesheets, indexed by stylesheet name
|
||||
DelayedIndexMaps<FieldP,ValueP> styling_data;
|
||||
vector<CardP> cards; ///< The cards in the set
|
||||
vector<KeywordP> keywords; ///< Additional keywords used in this set
|
||||
vector<PackTypeP> pack_types; ///< Additional/replacement pack types
|
||||
String apprentice_code; ///< Code to use for apprentice (magic only)
|
||||
|
||||
ActionStack actions; ///< Actions performed on this set and the cards in it
|
||||
KeywordDatabase keyword_db; ///< Database for matching keywords, must be cleared when keywords change
|
||||
VCSP vcs; ///< The version control system to use
|
||||
vector<CardP> cards; ///< The cards in the set
|
||||
unordered_map<String, CardP> card_uids; ///< The uids of the cards in the set
|
||||
vector<KeywordP> keywords; ///< Additional keywords used in this set
|
||||
vector<PackTypeP> pack_types; ///< Additional/replacement pack types
|
||||
String apprentice_code; ///< Code to use for apprentice (magic only)
|
||||
|
||||
ActionStack actions; ///< Actions performed on this set and the cards in it
|
||||
KeywordDatabase keyword_db; ///< Database for matching keywords, must be cleared when keywords change
|
||||
VCSP vcs; ///< The version control system to use
|
||||
|
||||
/// A context for performing scripts
|
||||
/** Should only be used from the main thread! */
|
||||
@@ -71,6 +72,8 @@ public:
|
||||
void updateStyles(const CardP& card, bool only_content_dependent);
|
||||
/// Update scripts that were delayed
|
||||
void updateDelayed();
|
||||
/// Update uid map
|
||||
void buildUidMap();
|
||||
/// A context for performing scripts
|
||||
/** Should only be used from the thumbnail thread! */
|
||||
Context& getContextForThumbnails();
|
||||
|
||||
Reference in New Issue
Block a user