diff --git a/gframe/data_manager.h b/gframe/data_manager.h index 987c42e08..283a5380d 100644 --- a/gframe/data_manager.h +++ b/gframe/data_manager.h @@ -69,6 +69,14 @@ struct CardDataC { uint32_t ot; uint32_t category; std::vector setcodes; + + static constexpr auto CARD_ARTWORK_VERSIONS_OFFSET = 10; + + bool IsInArtworkOffsetRange() const { + if(alias == 0) + return false; + return (alias - code < CARD_ARTWORK_VERSIONS_OFFSET || code - alias < CARD_ARTWORK_VERSIONS_OFFSET); + } }; struct CardString { std::wstring name; diff --git a/gframe/deck_con.cpp b/gframe/deck_con.cpp index cd932e079..c2e0d1456 100644 --- a/gframe/deck_con.cpp +++ b/gframe/deck_con.cpp @@ -1174,10 +1174,7 @@ bool DeckBuilder::CheckCard(CardDataM* data, SEARCH_MODIFIER modifier, const std if(filter_marks && (data->_data.link_marker & filter_marks) != filter_marks) return false; if((filter_lm != LIMITATION_FILTER_NONE || filterList->whitelist) && filter_lm != LIMITATION_FILTER_ALL) { - uint32_t limitcode = data->_data.code; - auto flit = filterList->content.find(limitcode); - if(flit == filterList->content.end() && data->_data.alias) - flit = filterList->content.find(data->_data.alias); + auto flit = filterList->GetLimitationIterator(&data->_data); int count = 3; if(flit == filterList->content.end()) { if(filterList->whitelist) @@ -1373,31 +1370,27 @@ void DeckBuilder::pop_side(int seq) { bool DeckBuilder::check_limit(CardDataC* pointer) { uint32_t limitcode = pointer->alias ? pointer->alias : pointer->code; int found = 0; - int limit = 3; - banlist_content_t::iterator it; - auto f = [&](const auto pcard)->bool { - if((it = filterList->content.find(pcard->code)) != filterList->content.end()) - limit = it->second; - else if(pcard->alias && (it = filterList->content.find(pcard->alias)) != filterList->content.end()) - limit = it->second; - else if(filterList->whitelist) - limit = 0; - return limit > 0; - }; - auto f2 = [&](const auto& list) { - for(auto& pcard : list) { + int limit = filterList->whitelist ? 0 : 3; + auto endit = filterList->content.end(); + auto it = filterList->GetLimitationIterator(pointer); + if(it != endit) + limit = it->second; + if(limit == 0) + return false; + const auto& deck = gdeckManager->current_deck; + for(auto* plist : { &deck.main , &deck.extra,&deck.side }) { + for(auto& pcard : *plist) { if(pcard->code == limitcode || pcard->alias == limitcode) { - if((it = filterList->content.find(pcard->code)) != filterList->content.end()) + if((it = filterList->content.find(pcard->code)) != endit) limit = std::min(limit, it->second); - else if((it = filterList->content.find(pcard->alias)) != filterList->content.end()) + else if((it = filterList->content.find(pcard->alias)) != endit) limit = std::min(limit, it->second); found++; } if(limit <= found) return false; } - return true; - }; - return f(pointer) && f2(gdeckManager->current_deck.main) && f2(gdeckManager->current_deck.extra) && f2(gdeckManager->current_deck.side); + } + return true; } } diff --git a/gframe/deck_manager.cpp b/gframe/deck_manager.cpp index 053a0118b..c2d0ab373 100644 --- a/gframe/deck_manager.cpp +++ b/gframe/deck_manager.cpp @@ -153,7 +153,7 @@ int DeckManager::TypeCount(std::vector cards, uint32_t type) { } return count; } -inline DeckError CheckCards(const std::vector &cards, LFList* curlist, banlist_content_t* list, +inline DeckError CheckCards(const std::vector &cards, LFList* curlist, DuelAllowedCards allowedCards, banlist_content_t &ccount, DeckError(*additionalCheck)(CardDataC*) = nullptr) { @@ -193,10 +193,9 @@ inline DeckError CheckCards(const std::vector &cards, LFList* curlis int dc = ccount[code]; if (dc > 3) return ret.type = DeckError::CARDCOUNT, ret; - auto it = list->find(cit->code); - if (it == list->end()) - it = list->find(code); - if ((it != list->end() && dc > it->second) || (curlist->whitelist && it == list->end())) + auto it = curlist->GetLimitationIterator(cit); + auto is_end = it == curlist->content.end(); + if ((!is_end && dc > it->second) || (curlist->whitelist && is_end)) return ret.type = DeckError::LFLIST, ret; } return { DeckError::NONE }; @@ -213,7 +212,6 @@ DeckError DeckManager::CheckDeck(Deck& deck, uint32_t lfhash, DuelAllowedCards a DeckError ret{ DeckError::NONE }; if(!curlist) return ret; - auto list = &curlist->content; if(TypeCount(deck.main, forbiddentypes) > 0 || TypeCount(deck.extra, forbiddentypes) > 0 || TypeCount(deck.side, forbiddentypes) > 0) return ret.type = DeckError::FORBTYPE, ret; bool speed = mainGame->extra_rules & DECK_LIMIT_20; @@ -253,19 +251,19 @@ DeckError DeckManager::CheckDeck(Deck& deck, uint32_t lfhash, DuelAllowedCards a } if(ret.type) return ret; - ret = CheckCards(deck.main, curlist, list, allowedCards, ccount, [](CardDataC* cit)->DeckError { + ret = CheckCards(deck.main, curlist, allowedCards, ccount, [](CardDataC* cit)->DeckError { if ((cit->type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ)) || (cit->type & TYPE_LINK && cit->type & TYPE_MONSTER)) return { DeckError::EXTRACOUNT }; return { DeckError::NONE }; }); if (ret.type) return ret; - ret = CheckCards(deck.extra, curlist, list, allowedCards , ccount, [](CardDataC* cit)->DeckError { + ret = CheckCards(deck.extra, curlist, allowedCards , ccount, [](CardDataC* cit)->DeckError { if (!(cit->type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ)) && !(cit->type & TYPE_LINK && cit->type & TYPE_MONSTER)) return { DeckError::EXTRACOUNT }; return { DeckError::NONE }; }); if (ret.type) return ret; - return CheckCards(deck.side, curlist, list, allowedCards, ccount); + return CheckCards(deck.side, curlist, allowedCards, ccount); } uint32_t DeckManager::LoadDeck(Deck& deck, uint32_t* dbuf, uint32_t mainc, uint32_t sidec, uint32_t mainc2, uint32_t sidec2) { cardlist_type mainvect(mainc + mainc2); diff --git a/gframe/deck_manager.h b/gframe/deck_manager.h index 1ea657d3d..2f1c0a682 100644 --- a/gframe/deck_manager.h +++ b/gframe/deck_manager.h @@ -18,6 +18,14 @@ struct LFList { std::wstring listName; banlist_content_t content; bool whitelist; + auto GetLimitationIterator(const CardDataC* pcard) const { + auto flit = content.find(pcard->code); + if(flit == content.end() && pcard->alias) { + if(!whitelist || pcard->IsInArtworkOffsetRange()) + flit = content.find(pcard->alias); + } + return flit; + } }; struct Deck { std::vector main; diff --git a/gframe/drawing.cpp b/gframe/drawing.cpp index 89f9a30e0..fd27d010c 100644 --- a/gframe/drawing.cpp +++ b/gframe/drawing.cpp @@ -1195,10 +1195,7 @@ void Game::WaitFrameSignal(int frame, std::unique_lock& _lck) { } void Game::DrawThumb(CardDataC* cp, irr::core::position2di pos, LFList* lflist, bool drag, const irr::core::recti* cliprect, bool load_image) { auto code = cp->code; - uint32_t limitcode = cp->code; - auto flit = lflist->content.find(limitcode); - if(flit == lflist->content.end() && cp->alias) - flit = lflist->content.find(cp->alias); + auto flit = lflist->GetLimitationIterator(cp); int count = 3; if(flit == lflist->content.end()) { if(lflist->whitelist) diff --git a/gframe/event_handler.cpp b/gframe/event_handler.cpp index 925f761bb..ce292142a 100644 --- a/gframe/event_handler.cpp +++ b/gframe/event_handler.cpp @@ -2283,7 +2283,7 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event, bool& stopPropagation) auto path = mainGame->FindScript(fmt::format(EPRO_TEXT("c{}.lua"), mainGame->showingcard)); if(path.empty()) { auto cd = gDataManager->GetCardData(mainGame->showingcard); - if(cd && cd->alias && (cd->alias - mainGame->showingcard < CARD_ARTWORK_VERSIONS_OFFSET || mainGame->showingcard - cd->alias < CARD_ARTWORK_VERSIONS_OFFSET)) + if(cd && cd->IsInArtworkOffsetRange()) path = mainGame->FindScript(fmt::format(EPRO_TEXT("c{}.lua"), cd->alias)); } if(path.size() && path != EPRO_TEXT("archives")) diff --git a/gframe/game.cpp b/gframe/game.cpp index 60ec371f2..8e500db90 100644 --- a/gframe/game.cpp +++ b/gframe/game.cpp @@ -2343,7 +2343,7 @@ void Game::ShowCardInfo(uint32_t code, bool resize, imgType type) { if(only_texture) return; auto tmp_code = code; - if(cd->alias && (cd->alias - code < CARD_ARTWORK_VERSIONS_OFFSET || code - cd->alias < CARD_ARTWORK_VERSIONS_OFFSET)) + if(cd->IsInArtworkOffsetRange()) tmp_code = cd->alias; stName->setText(gDataManager->GetName(tmp_code).data()); stPasscodeScope->setText(fmt::format(L"[{:08}] {}", tmp_code, gDataManager->FormatScope(cd->ot)).data()); diff --git a/gframe/game.h b/gframe/game.h index 00c362ca5..b704c64e7 100644 --- a/gframe/game.h +++ b/gframe/game.h @@ -743,8 +743,6 @@ irr::core::rect Game::Scale(irr::core::rect rect) { #define POSITION_HINT 0x8000 -#define CARD_ARTWORK_VERSIONS_OFFSET 10 - #define DECK_SEARCH_SCROLL_STEP 100 constexpr float FIELD_X = 4.2f;