Commit bd326e20 authored by salix5's avatar salix5 Committed by GitHub

Add datas.rule_code (#3000)

parent eb94f4eb
......@@ -1401,6 +1401,8 @@ bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, st
}
template <class T>
static bool is_declarable(const T& cd, const std::vector<unsigned int>& opcode) {
if (cd.alias)
return false;
std::stack<int> stack;
for(auto it = opcode.begin(); it != opcode.end(); ++it) {
switch(*it) {
......@@ -1535,9 +1537,9 @@ static bool is_declarable(const T& cd, const std::vector<unsigned int>& opcode)
}
if(stack.size() != 1 || stack.top() == 0)
return false;
if (cd.type & TYPE_TOKEN)
if (!second_code.count(cd.code) && (cd.rule_code || (cd.type & TYPE_TOKEN)))
return false;
return !cd.alias || second_code.find(cd.code) != second_code.end();
return true;
}
void ClientField::UpdateDeclarableList() {
const wchar_t* pname = mainGame->ebANCard->getText();
......@@ -1567,7 +1569,6 @@ void ClientField::UpdateDeclarableList() {
auto cp = _datas.find(code);
if (cp == _datas.end())
continue;
//datas.alias can be double card names or alias
if(is_declarable(cp->second, declare_opcodes)) {
if(pname == str.name || trycode == code) { //exact match or last used
mainGame->lstANCard->insertItem(0, str.name.c_str(), -1);
......
......@@ -7,9 +7,16 @@ namespace ygo {
unsigned char DataManager::scriptBuffer[0x100000] = {};
DataManager dataManager;
static const char SELECT_STMT[] = "SELECT datas.id, datas.ot, datas.alias, datas.setcode, datas.type, datas.atk, datas.def, datas.level, datas.race, datas.attribute, datas.category,"
" texts.name, texts.desc, texts.str1, texts.str2, texts.str3, texts.str4, texts.str5, texts.str6, texts.str7, texts.str8,"
" texts.str9, texts.str10, texts.str11, texts.str12, texts.str13, texts.str14, texts.str15, texts.str16 FROM datas INNER JOIN texts ON datas.id = texts.id";
static constexpr int DATAS_COUNT = 11;
static constexpr int CARD_ARTWORK_VERSIONS_OFFSET = 20;
static inline bool is_alternative(uint32_t code, uint32_t alias) {
return alias && (alias < code + CARD_ARTWORK_VERSIONS_OFFSET) && (code < alias + CARD_ARTWORK_VERSIONS_OFFSET);
}
DataManager::DataManager() : _datas(32768), _strings(32768) {
extra_setcode = {
......@@ -19,6 +26,7 @@ DataManager::DataManager() : _datas(32768), _strings(32768) {
}
bool DataManager::ReadDB(sqlite3* pDB) {
sqlite3_stmt* pStmt = nullptr;
int texts_offset = DATAS_COUNT;
if (sqlite3_prepare_v2(pDB, SELECT_STMT, -1, &pStmt, nullptr) != SQLITE_OK)
return Error(pDB, pStmt);
wchar_t strBuffer[4096];
......@@ -48,23 +56,41 @@ bool DataManager::ReadDB(sqlite3* pDB) {
cd.race = static_cast<decltype(cd.race)>(sqlite3_column_int64(pStmt, 8));
cd.attribute = static_cast<decltype(cd.attribute)>(sqlite3_column_int64(pStmt, 9));
cd.category = static_cast<decltype(cd.category)>(sqlite3_column_int64(pStmt, 10));
// rule_code
if (cd.code == 5405695) {
cd.rule_code = cd.alias;
cd.alias = 0;
}
else if (cd.alias && !(cd.type & TYPE_TOKEN) && !is_alternative(cd.code, cd.alias)) {
cd.rule_code = cd.alias;
cd.alias = 0;
}
auto& cs = _strings[code];
if (const char* text = (const char*)sqlite3_column_text(pStmt, 11)) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, texts_offset + 0)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.name = strBuffer;
}
if (const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, texts_offset + 1)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.text = strBuffer;
}
for (int i = 0; i < DESC_COUNT; ++i) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, 13 + i)) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, (texts_offset + 2) + i)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.desc[i] = strBuffer;
}
}
}
sqlite3_finalize(pStmt);
for (auto& entry : _datas) {
auto& cd = entry.second;
if (cd.rule_code || !cd.alias || (cd.type & TYPE_TOKEN))
continue;
auto it = _datas.find(cd.alias);
if (it == _datas.end())
continue;
cd.rule_code = it->second.rule_code;
}
for (const auto& entry : extra_setcode) {
const auto& code = entry.first;
const auto& list = entry.second;
......
......@@ -34,6 +34,9 @@ struct CardDataC {
uint32_t lscale{};
uint32_t rscale{};
uint32_t link_marker{};
uint32_t rule_code{};
// extra columns
uint32_t ot{};
uint32_t category{};
......@@ -48,6 +51,14 @@ struct CardDataC {
}
return false;
}
uint32_t get_original_code() const {
return alias ? alias : code;
}
uint32_t get_duel_code() const {
return rule_code ? rule_code : get_original_code();
}
};
constexpr int DESC_COUNT = 16;
struct CardString {
......
......@@ -1555,7 +1555,7 @@ void DeckBuilder::FilterCards() {
match = CardNameContains(strings.name.c_str(), elements_iterator->keyword.c_str());
} else if (elements_iterator->type == element_t::type_t::setcode) {
match = data.is_setcodes(elements_iterator->setcodes);
} else if (trycode && (data.code == trycode || data.alias == trycode && is_alternative(data.code, data.alias))){
} else if (trycode && data.get_original_code() == trycode) {
match = true;
} else {
match = CardNameContains(strings.name.c_str(), elements_iterator->keyword.c_str())
......@@ -1875,21 +1875,21 @@ void DeckBuilder::pop_side(int seq) {
GetHoveredCard();
}
bool DeckBuilder::check_limit(code_pointer pointer) {
auto limitcode = pointer->second.alias ? pointer->second.alias : pointer->first;
auto limitcode = pointer->second.get_duel_code();
int limit = 3;
auto flit = filterList->content.find(limitcode);
if(flit != filterList->content.end())
limit = flit->second;
for (auto& card : deckManager.current_deck.main) {
if (card->first == limitcode || card->second.alias == limitcode)
if (card->second.get_duel_code() == limitcode)
limit--;
}
for (auto& card : deckManager.current_deck.extra) {
if (card->first == limitcode || card->second.alias == limitcode)
if (card->second.get_duel_code() == limitcode)
limit--;
}
for (auto& card : deckManager.current_deck.side) {
if (card->first == limitcode || card->second.alias == limitcode)
if (card->second.get_duel_code() == limitcode)
limit--;
}
return limit > 0;
......
......@@ -105,7 +105,7 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
return (gameruleDeckError << 28) | cit->first;
if (cit->second.type & (TYPES_EXTRA_DECK | TYPE_TOKEN))
return (DECKERROR_MAINCOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first;
auto code = cit->second.get_duel_code();
ccount[code]++;
int dc = ccount[code];
if(dc > 3)
......@@ -120,7 +120,7 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
return (gameruleDeckError << 28) | cit->first;
if (!(cit->second.type & TYPES_EXTRA_DECK) || cit->second.type & TYPE_TOKEN)
return (DECKERROR_EXTRACOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first;
auto code = cit->second.get_duel_code();
ccount[code]++;
int dc = ccount[code];
if(dc > 3)
......@@ -135,7 +135,7 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
return (gameruleDeckError << 28) | cit->first;
if (cit->second.type & TYPE_TOKEN)
return (DECKERROR_SIDECOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first;
auto code = cit->second.get_duel_code();
ccount[code]++;
int dc = ccount[code];
if(dc > 3)
......
......@@ -1125,9 +1125,7 @@ void Game::WaitFrameSignal(int frame) {
}
void Game::DrawThumb(code_pointer cp, irr::core::vector2di pos, const LFList* lflist, bool drag) {
auto code = cp->first;
auto lcode = cp->second.alias;
if(lcode == 0)
lcode = code;
auto lcode = cp->second.get_duel_code();
irr::video::ITexture* img = imageManager.GetTextureThumb(code);
if(img == nullptr)
return; //nullptr->getSize() will cause a crash
......
......@@ -1522,10 +1522,7 @@ void Game::ShowCardInfo(int code, bool resize) {
imgCard->setImage(imageManager.GetTexture(code, true));
if (is_valid) {
auto& cd = cit->second;
if (is_alternative(cd.code,cd.alias))
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.alias), cd.alias);
else
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(cd.get_original_code()), cd.get_original_code());
}
else {
myswprintf(formatBuffer, L"%ls[%08d]", dataManager.GetName(code), code);
......@@ -1539,8 +1536,8 @@ void Game::ShowCardInfo(int code, bool resize) {
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
auto target = cit;
if (cd.alias && _datas.find(cd.alias) != _datas.end()) {
target = _datas.find(cd.alias);
if (cd.rule_code && _datas.count(cd.rule_code)) {
target = _datas.find(cd.rule_code);
}
if (target->second.setcode[0]) {
offset = 23;// *yScale;
......
--step 1: add new column
ALTER TABLE datas ADD COLUMN rule_code INTEGER DEFAULT 0;
--step 2: update "treated as X" cards
UPDATE datas
SET rule_code = alias, alias = 0
WHERE id IN (
SELECT id
FROM datas
WHERE NOT (type & 0x4000) AND alias != 0 AND abs(id - alias) >= 20
);
--step 3: update special cards
UPDATE datas
SET rule_code = alias, alias = 0
WHERE id = 5405695;
UPDATE datas
SET rule_code = 13331639
WHERE alias = 6218704;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment