Commit 18419515 authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master' into develop

parents bcd88be1 86a9ca5d
......@@ -23,9 +23,10 @@
/ikpMP3.dll
/irrKlang.dll
/bin
/.vscode/
/bin/
/build
/obj
/obj/
/event
/freetype
/irrlicht
......
......@@ -417,7 +417,8 @@ void ClientField::ClearChainSelect() {
conti_act = false;
}
// needs to be synchronized with EGET_SCROLL_BAR_CHANGED
void ClientField::ShowSelectCard(bool buttonok, bool chain) {
void ClientField::ShowSelectCard(bool buttonok, bool is_continuous) {
select_continuous = is_continuous;
if(cant_check_grave) {
bool has_card_in_grave = false;
for (auto& pcard : selectable_cards) {
......@@ -444,7 +445,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
// image
if(selectable_cards[i]->code)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->code));
else if(conti_selecting)
else if(select_continuous)
mainGame->imageLoading.insert(std::make_pair(mainGame->btnCardSelect[i], selectable_cards[i]->chain_code));
else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i]->controler + 2]);
......@@ -454,8 +455,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
if(mainGame->dInfo.curMsg != MSG_SORT_CARD) {
// text
wchar_t formatBuffer[2048];
if(conti_selecting)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string);
if(select_continuous)
myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i]->location == LOCATION_OVERLAY)
......@@ -470,7 +471,7 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
if (selectable_cards[i]->is_selected)
mainGame->stCardPos[i]->setBackgroundColor(0xffffff00);
else {
if(conti_selecting)
if(select_continuous)
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
else if(selectable_cards[i]->location == LOCATION_OVERLAY) {
if(selectable_cards[i]->owner != selectable_cards[i]->overlayTarget->controler)
......@@ -1555,7 +1556,8 @@ void ClientField::UpdateDeclarableList() {
int trycode = BufferIO::GetVal(pname);
CardData cd;
if (dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
auto it = dataManager.GetStringPointer(trycode);
auto& _strings = dataManager.GetStringTable();
auto it = _strings.find(trycode);
mainGame->lstANCard->clear();
ancard.clear();
mainGame->lstANCard->addItem(it->second.name.c_str());
......@@ -1568,19 +1570,23 @@ void ClientField::UpdateDeclarableList() {
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager.strings_begin(); cit != dataManager.strings_end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first);
if (cp == dataManager.datas_end())
auto& _datas = dataManager.GetDataTable();
auto& _strings = dataManager.GetStringTable();
for(auto& entry : _strings) {
auto& code = entry.first;
auto& str = entry.second;
if(str.name.find(pname) != std::wstring::npos) {
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 == cit->second.name || trycode == cit->first) { //exact match or last used
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
if(pname == str.name || trycode == code) { //exact match or last used
mainGame->lstANCard->insertItem(0, str.name.c_str(), -1);
ancard.insert(ancard.begin(), code);
} else {
mainGame->lstANCard->addItem(cit->second.name.c_str());
ancard.push_back(cit->first);
mainGame->lstANCard->addItem(str.name.c_str());
ancard.push_back(code);
}
}
}
......
......@@ -86,7 +86,7 @@ public:
ChainInfo current_chain;
bool last_chain{ false };
bool deck_reversed{ false };
bool conti_selecting{ false };
bool select_continuous{ false };
bool cant_check_grave{ false };
bool tag_surrender{ false };
bool tag_teammate_surrender{ false };
......@@ -105,7 +105,7 @@ public:
void ClearCommandFlag();
void ClearSelect();
void ClearChainSelect();
void ShowSelectCard(bool buttonok = false, bool chain = false);
void ShowSelectCard(bool buttonok = false, bool is_continuous = false);
void ShowChainCard();
void ShowLocationCard();
void ShowSelectOption(int select_hint = 0);
......
......@@ -4,9 +4,7 @@
namespace ygo {
const wchar_t* DataManager::unknown_string = L"???";
unsigned char DataManager::scriptBuffer[0x100000] = {};
irr::io::IFileSystem* DataManager::FileSystem = nullptr;
DataManager dataManager;
DataManager::DataManager() : _datas(32768), _strings(32768) {
......@@ -301,7 +299,7 @@ std::wstring DataManager::FormatAttribute(unsigned int attribute) const {
if (attribute & (0x1U << i)) {
if (!buffer.empty())
buffer.push_back(L'|');
buffer.append(GetSysString(1010 + i));
buffer.append(GetSysString(STRING_ID_ATTRIBUTE + i));
}
}
if (buffer.empty())
......@@ -314,7 +312,7 @@ std::wstring DataManager::FormatRace(unsigned int race) const {
if(race & (0x1U << i)) {
if (!buffer.empty())
buffer.push_back(L'|');
buffer.append(GetSysString(1020 + i));
buffer.append(GetSysString(STRING_ID_RACE + i));
}
}
if (buffer.empty())
......@@ -323,12 +321,11 @@ std::wstring DataManager::FormatRace(unsigned int race) const {
}
std::wstring DataManager::FormatType(unsigned int type) const {
std::wstring buffer;
int i = 1050;
for (unsigned filter = TYPE_MONSTER; filter <= TYPE_LINK; filter <<= 1, ++i) {
if (type & filter) {
for (int i = 0; i < TYPES_COUNT; ++i) {
if (type & (0x1U << i)) {
if (!buffer.empty())
buffer.push_back(L'|');
buffer.append(GetSysString(i));
buffer.append(GetSysString(STRING_ID_TYPE + i));
}
}
if (buffer.empty())
......@@ -403,9 +400,9 @@ unsigned char* DataManager::ReadScriptFromIrrFS(const char* script_name, int* sl
#ifdef _WIN32
wchar_t fname[256]{};
BufferIO::DecodeUTF8(script_name, fname);
auto reader = FileSystem->createAndOpenFile(fname);
auto reader = dataManager.FileSystem->createAndOpenFile(fname);
#else
auto reader = FileSystem->createAndOpenFile(script_name);
auto reader = dataManager.FileSystem->createAndOpenFile(script_name);
#endif
if (!reader)
return nullptr;
......
......@@ -68,17 +68,11 @@ public:
code_pointer GetCodePointer(uint32_t code) const;
string_pointer GetStringPointer(uint32_t code) const;
code_pointer datas_begin() const noexcept {
return _datas.cbegin();
const std::unordered_map<uint32_t, CardDataC>& GetDataTable() const {
return _datas;
}
code_pointer datas_end() const noexcept {
return _datas.cend();
}
string_pointer strings_begin() const noexcept {
return _strings.cbegin();
}
string_pointer strings_end() const noexcept {
return _strings.cend();
const std::unordered_map<uint32_t, CardString>& GetStringTable() const {
return _strings;
}
bool GetData(uint32_t code, CardData* pData) const;
bool GetString(uint32_t code, CardString* pStr) const;
......@@ -103,9 +97,15 @@ public:
std::unordered_map<unsigned int, std::wstring> _setnameStrings;
std::unordered_map<unsigned int, std::wstring> _sysStrings;
char errmsg[512]{};
const wchar_t* unknown_string{ L"???" };
irr::io::IFileSystem* FileSystem{};
static constexpr int STRING_ID_ATTRIBUTE = 1010;
static constexpr int STRING_ID_RACE = 1020;
static constexpr int STRING_ID_TYPE = 1050;
static constexpr int TYPES_COUNT = 27;
static unsigned char scriptBuffer[0x100000];
static const wchar_t* unknown_string;
static uint32_t CardReader(uint32_t, card_data*);
static unsigned char* ScriptReaderEx(const char* script_path, int* slen);
......@@ -114,8 +114,6 @@ public:
//read by fread
static unsigned char* ReadScriptFromFile(const char* script_name, int* slen);
static irr::io::IFileSystem* FileSystem;
static bool deck_sort_lv(code_pointer l1, code_pointer l2);
static bool deck_sort_atk(code_pointer l1, code_pointer l2);
static bool deck_sort_def(code_pointer l1, code_pointer l2);
......
......@@ -141,6 +141,7 @@ void DeckBuilder::Terminate() {
bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if(mainGame->dField.OnCommonEvent(event))
return false;
auto& _datas = dataManager.GetDataTable();
switch(event.EventType) {
case irr::EET_GUI_EVENT: {
irr::s32 id = event.GUIEvent.Caller->getID();
......@@ -428,7 +429,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->lstCategories->addItem(catename);
catesel = mainGame->lstCategories->getItemCount() - 1;
} else {
for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) {
for(int i = DECK_CATEGORY_CUSTOM; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), catename, 256)) {
catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474));
......@@ -448,6 +449,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
case BUTTON_RENAME_CATEGORY: {
int catesel = mainGame->lstCategories->getSelected();
if (catesel < DECK_CATEGORY_CUSTOM)
break;
const wchar_t* oldcatename = mainGame->lstCategories->getListItem(catesel);
const wchar_t* newcatename = mainGame->ebDMName->getText();
if(DeckManager::RenameCategory(oldcatename, newcatename)) {
......@@ -458,7 +461,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
catesel = mainGame->lstCategories->getItemCount() - 1;
} else {
catesel = 0;
for(int i = 3; i < (int)mainGame->lstCategories->getItemCount(); i++) {
for(int i = DECK_CATEGORY_CUSTOM; i < (int)mainGame->lstCategories->getItemCount(); i++) {
if(!mywcsncasecmp(mainGame->lstCategories->getListItem(i), newcatename, 256)) {
catesel = i;
mainGame->stACMessage->setText(dataManager.GetSysString(1474));
......@@ -478,11 +481,13 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
}
case BUTTON_DELETE_CATEGORY: {
int catesel = mainGame->lstCategories->getSelected();
if (catesel < DECK_CATEGORY_CUSTOM)
break;
const wchar_t* catename = mainGame->lstCategories->getListItem(catesel);
if(DeckManager::DeleteCategory(catename)) {
mainGame->cbDBCategory->removeItem(catesel);
mainGame->lstCategories->removeItem(catesel);
catesel = 2;
catesel = DECK_CATEGORY_NONE;
mainGame->lstCategories->setSelected(catesel);
RefreshDeckList();
mainGame->lstDecks->setSelected(0);
......@@ -1074,8 +1079,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
dragx = event.MouseInput.X;
dragy = event.MouseInput.Y;
draging_pointer = dataManager.GetCodePointer(hovered_code);
if(draging_pointer == dataManager.datas_end())
draging_pointer = _datas.find(hovered_code);
if (draging_pointer == _datas.end())
break;
if(hovered_pos == 4) {
if(!check_limit(draging_pointer))
......@@ -1128,8 +1133,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
if(hovered_pos == 0 || hovered_seq == -1)
break;
auto pointer = dataManager.GetCodePointer(hovered_code);
if(pointer == dataManager.datas_end())
auto pointer = _datas.find(hovered_code);
if (pointer == _datas.end())
break;
soundManager.PlaySoundEffect(SOUND_CARD_DROP);
if(hovered_pos == 1) {
......@@ -1163,8 +1168,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
} else if(hovered_pos == 3) {
pop_side(hovered_seq);
} else {
auto pointer = dataManager.GetCodePointer(hovered_code);
if(pointer == dataManager.datas_end())
auto pointer = _datas.find(hovered_code);
if (pointer == _datas.end())
break;
if(!check_limit(pointer))
break;
......@@ -1198,8 +1203,8 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
if (is_draging)
break;
auto pointer = dataManager.GetCodePointer(hovered_code);
if (pointer == dataManager.datas_end())
auto pointer = _datas.find(hovered_code);
if (pointer == _datas.end())
break;
if(!check_limit(pointer))
break;
......@@ -1468,10 +1473,13 @@ void DeckBuilder::FilterCards() {
query_elements.push_back(element);
}
}
for(code_pointer ptr = dataManager.datas_begin(); ptr != dataManager.datas_end(); ++ptr) {
const CardDataC& data = ptr->second;
auto strpointer = dataManager.GetStringPointer(ptr->first);
if (strpointer == dataManager.strings_end())
auto& _datas = dataManager.GetDataTable();
auto& _strings = dataManager.GetStringTable();
for (code_pointer ptr = _datas.begin(); ptr != _datas.end(); ++ptr) {
auto& code = ptr->first;
auto& data = ptr->second;
auto strpointer = _strings.find(code);
if (strpointer == _strings.end())
continue;
const CardString& strings = strpointer->second;
if(data.type & TYPE_TOKEN)
......@@ -1877,16 +1885,16 @@ bool DeckBuilder::check_limit(code_pointer pointer) {
auto flit = filterList->content.find(limitcode);
if(flit != filterList->content.end())
limit = flit->second;
for(auto it = deckManager.current_deck.main.begin(); it != deckManager.current_deck.main.end(); ++it) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode)
for (auto& card : deckManager.current_deck.main) {
if (card->first == limitcode || card->second.alias == limitcode)
limit--;
}
for(auto it = deckManager.current_deck.extra.begin(); it != deckManager.current_deck.extra.end(); ++it) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode)
for (auto& card : deckManager.current_deck.extra) {
if (card->first == limitcode || card->second.alias == limitcode)
limit--;
}
for(auto it = deckManager.current_deck.side.begin(); it != deckManager.current_deck.side.end(); ++it) {
if((*it)->first == limitcode || (*it)->second.alias == limitcode)
for (auto& card : deckManager.current_deck.side) {
if (card->first == limitcode || card->second.alias == limitcode)
limit--;
}
return limit > 0;
......
......@@ -5,7 +5,6 @@
namespace ygo {
char DeckManager::deckBuffer[0x10000]{};
DeckManager deckManager;
void DeckManager::LoadLFListSingle(const char* path) {
......@@ -150,42 +149,46 @@ unsigned int DeckManager::CheckDeck(const Deck& deck, unsigned int lfhash, int r
uint32_t DeckManager::LoadDeck(Deck& deck, uint32_t dbuf[], int mainc, int sidec, bool is_packlist) {
deck.clear();
uint32_t errorcode = 0;
CardData cd;
auto& _datas = dataManager.GetDataTable();
for(int i = 0; i < mainc; ++i) {
auto code = dbuf[i];
if(!dataManager.GetData(code, &cd)) {
auto it = _datas.find(code);
if(it == _datas.end()) {
errorcode = code;
continue;
}
auto& cd = it->second;
if (cd.type & TYPE_TOKEN) {
errorcode = code;
continue;
}
if(is_packlist) {
deck.main.push_back(dataManager.GetCodePointer(code));
deck.main.push_back(it);
continue;
}
if (cd.type & TYPES_EXTRA_DECK) {
if (deck.extra.size() < EXTRA_MAX_SIZE)
deck.extra.push_back(dataManager.GetCodePointer(code));
deck.extra.push_back(it);
}
else {
if (deck.main.size() < DECK_MAX_SIZE)
deck.main.push_back(dataManager.GetCodePointer(code));
deck.main.push_back(it);
}
}
for(int i = 0; i < sidec; ++i) {
auto code = dbuf[mainc + i];
if(!dataManager.GetData(code, &cd)) {
auto it = _datas.find(code);
if(it == _datas.end()) {
errorcode = code;
continue;
}
auto& cd = it->second;
if (cd.type & TYPE_TOKEN) {
errorcode = code;
continue;
}
if(deck.side.size() < SIDE_MAX_SIZE)
deck.side.push_back(dataManager.GetCodePointer(code));
deck.side.push_back(it);
}
return errorcode;
}
......@@ -242,15 +245,15 @@ bool DeckManager::LoadSide(Deck& deck, uint32_t dbuf[], int mainc, int sidec) {
void DeckManager::GetCategoryPath(wchar_t* ret, int index, const wchar_t* text) {
wchar_t catepath[256];
switch(index) {
case 0:
case DECK_CATEGORY_PACK:
myswprintf(catepath, L"./pack");
break;
case 1:
case DECK_CATEGORY_BOT:
BufferIO::CopyWideString(mainGame->gameConf.bot_deck_path, catepath);
break;
case -1:
case 2:
case 3:
case DECK_CATEGORY_NONE:
case DECK_CATEGORY_SEPARATOR:
myswprintf(catepath, L"./deck");
break;
default:
......@@ -276,11 +279,11 @@ FILE* DeckManager::OpenDeckFile(const wchar_t* file, const char* mode) {
}
irr::io::IReadFile* DeckManager::OpenDeckReader(const wchar_t* file) {
#ifdef _WIN32
auto reader = DataManager::FileSystem->createAndOpenFile(file);
auto reader = dataManager.FileSystem->createAndOpenFile(file);
#else
char file2[256];
BufferIO::EncodeUTF8(file, file2);
auto reader = DataManager::FileSystem->createAndOpenFile(file2);
auto reader = dataManager.FileSystem->createAndOpenFile(file2);
#endif
return reader;
}
......@@ -290,6 +293,9 @@ bool DeckManager::LoadCurrentDeck(std::istringstream& deckStream, bool is_packli
}
bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) {
current_deck.clear();
if (!file[0])
return false;
char deckBuffer[MAX_YDK_SIZE]{};
auto reader = OpenDeckReader(file);
if(!reader) {
wchar_t localfile[256];
......@@ -316,11 +322,12 @@ bool DeckManager::LoadCurrentDeck(const wchar_t* file, bool is_packlist) {
bool DeckManager::LoadCurrentDeck(int category_index, const wchar_t* category_name, const wchar_t* deckname) {
wchar_t filepath[256];
GetDeckFile(filepath, category_index, category_name, deckname);
bool is_packlist = (category_index == 0);
bool res = LoadCurrentDeck(filepath, is_packlist);
if (res && mainGame->is_building)
bool is_packlist = (category_index == DECK_CATEGORY_PACK);
if(!LoadCurrentDeck(filepath, is_packlist))
return false;
if (mainGame->is_building)
mainGame->deckBuilder.RefreshPackListScroll();
return res;
return true;
}
void DeckManager::SaveDeck(const Deck& deck, std::stringstream& deckStream) {
deckStream << "#created by ..." << std::endl;
......
......@@ -16,6 +16,12 @@ namespace ygo {
constexpr int MAINC_MAX = 250; // the limit of card_state
constexpr int SIDEC_MAX = MAINC_MAX;
constexpr int DECK_CATEGORY_PACK = 0;
constexpr int DECK_CATEGORY_BOT = 1;
constexpr int DECK_CATEGORY_NONE = 2;
constexpr int DECK_CATEGORY_SEPARATOR = 3;
constexpr int DECK_CATEGORY_CUSTOM = 4;
struct LFList {
unsigned int hash{};
std::wstring listName;
......@@ -49,7 +55,7 @@ public:
Deck current_deck;
std::vector<LFList> _lfList;
static char deckBuffer[0x10000];
static constexpr int MAX_YDK_SIZE = 0x10000;
void LoadLFListSingle(const char* path);
void LoadLFList();
......
......@@ -1095,7 +1095,6 @@ void Game::HideElement(irr::gui::IGUIElement * win, bool set_action) {
if(win == wCardSelect) {
for(int i = 0; i < 5; ++i)
btnCardSelect[i]->setDrawImage(false);
dField.conti_selecting = false;
stCardListTip->setVisible(false);
for(auto& pcard : dField.selectable_cards)
dField.SetShowMark(pcard, false);
......@@ -1307,8 +1306,9 @@ void Game::DrawDeckBd() {
else
myswprintf(adBuffer, L"%d/-", ptr->second.attack);
}
myswprintf(textBuffer, L"%ls/%ls %ls%d", dataManager.FormatAttribute(ptr->second.attribute).c_str(), dataManager.FormatRace(ptr->second.race).c_str(),
form, ptr->second.level);
const auto& attribute = dataManager.FormatAttribute(ptr->second.attribute);
const auto& race = dataManager.FormatRace(ptr->second.race);
myswprintf(textBuffer, L"%ls/%ls %ls%d", attribute.c_str(), race.c_str(), form, ptr->second.level);
DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0));
if(ptr->second.type & TYPE_PENDULUM) {
myswprintf(scaleBuffer, L" %d/%d", ptr->second.lscale, ptr->second.rscale);
......@@ -1318,7 +1318,8 @@ void Game::DrawDeckBd() {
} else {
myswprintf(textBuffer, L"%ls", dataManager.GetName(ptr->first));
DrawShadowText(textFont, textBuffer, Resize(860, 165 + i * 66, 955, 185 + i * 66), Resize(1, 1, 0, 0));
myswprintf(textBuffer, L"%ls", dataManager.FormatType(ptr->second.type).c_str());
const auto& type = dataManager.FormatType(ptr->second.type);
myswprintf(textBuffer, L"%ls", type.c_str());
DrawShadowText(textFont, textBuffer, Resize(860, 187 + i * 66, 955, 207 + i * 66), Resize(1, 1, 0, 0));
myswprintf(textBuffer, L"%ls", availBuffer);
DrawShadowText(textFont, textBuffer, Resize(860, 209 + i * 66, 955, 229 + i * 66), Resize(1, 1, 0, 0));
......
......@@ -762,8 +762,11 @@ void DuelClient::HandleSTOCPacketLan(unsigned char* data, int len) {
prep += sizeof new_replay.pheader;
std::memcpy(new_replay.comp_data, prep, len - sizeof new_replay.pheader - 1);
new_replay.comp_size = len - sizeof new_replay.pheader - 1;
if(mainGame->actionParam)
new_replay.SaveReplay(mainGame->ebRSName->getText());
if (mainGame->actionParam) {
bool save_result = new_replay.SaveReplay(mainGame->ebRSName->getText());
if (!save_result)
new_replay.SaveReplay(L"_LastReplay");
}
else
new_replay.SaveReplay(L"_LastReplay");
}
......@@ -1113,7 +1116,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break;
}
case HINT_RACE: {
myswprintf(textBuffer, dataManager.GetSysString(1511), dataManager.FormatRace(data).c_str());
const auto& race = dataManager.FormatRace(data);
myswprintf(textBuffer, dataManager.GetSysString(1511), race.c_str());
mainGame->AddLog(textBuffer);
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer);
......@@ -1123,7 +1127,8 @@ bool DuelClient::ClientAnalyze(unsigned char* msg, int len) {
break;
}
case HINT_ATTRIB: {
myswprintf(textBuffer, dataManager.GetSysString(1511), dataManager.FormatAttribute(data).c_str());
const auto& attribute = dataManager.FormatAttribute(data);
myswprintf(textBuffer, dataManager.GetSysString(1511), attribute.c_str());
mainGame->AddLog(textBuffer);
mainGame->gMutex.lock();
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, textBuffer);
......
......@@ -404,7 +404,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}
} else {
selectable_cards.clear();
conti_selecting = false;
bool is_continuous = false;
switch(command_location) {
case LOCATION_DECK: {
for(size_t i = 0; i < deck[command_controler].size(); ++i)
......@@ -431,15 +431,15 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
break;
}
case POSITION_HINT: {
is_continuous = true;
selectable_cards = conti_cards;
std::sort(selectable_cards.begin(), selectable_cards.end());
auto eit = std::unique(selectable_cards.begin(), selectable_cards.end());
selectable_cards.erase(eit, selectable_cards.end());
conti_selecting = true;
break;
}
}
if(!conti_selecting) {
if (!is_continuous) {
mainGame->wCardSelect->setText(dataManager.GetSysString(566));
list_command = COMMAND_ACTIVATE;
} else {
......@@ -447,7 +447,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
list_command = COMMAND_OPERATION;
}
std::sort(selectable_cards.begin(), selectable_cards.end(), ClientCard::client_card_sort);
ShowSelectCard(true, true);
ShowSelectCard(true, is_continuous);
}
break;
}
......@@ -892,7 +892,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
// image
if(selectable_cards[i + pos]->code)
mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->code));
else if(conti_selecting)
else if(select_continuous)
mainGame->btnCardSelect[i]->setImage(imageManager.GetTexture(selectable_cards[i + pos]->chain_code));
else
mainGame->btnCardSelect[i]->setImage(imageManager.tCover[selectable_cards[i + pos]->controler + 2]);
......@@ -905,8 +905,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
else
myswprintf(formatBuffer, L"");
} else {
if(conti_selecting)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string);
if(select_continuous)
myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY)
......@@ -919,7 +919,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}
mainGame->stCardPos[i]->setText(formatBuffer);
// color
if(conti_selecting)
if(select_continuous)
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY) {
if(selectable_cards[i + pos]->owner != selectable_cards[i + pos]->overlayTarget->controler)
......@@ -1597,7 +1597,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"\nLINK-%d", mcard->link);
str.append(formatBuffer);
}
myswprintf(formatBuffer, L" %ls/%ls", dataManager.FormatRace(mcard->race).c_str(), dataManager.FormatAttribute(mcard->attribute).c_str());
const auto& race = dataManager.FormatRace(mcard->race);
const auto& attribute = dataManager.FormatAttribute(mcard->attribute);
myswprintf(formatBuffer, L" %ls/%ls", race.c_str(), attribute.c_str());
str.append(formatBuffer);
if(mcard->location == LOCATION_HAND && (mcard->type & TYPE_PENDULUM)) {
myswprintf(formatBuffer, L"\n%d/%d", mcard->lscale, mcard->rscale);
......@@ -1622,10 +1624,14 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(211), mcard->chValue);
else if(mcard->cHint == CHINT_CARD)
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(212), dataManager.GetName(mcard->chValue));
else if(mcard->cHint == CHINT_RACE)
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(213), dataManager.FormatRace(mcard->chValue).c_str());
else if(mcard->cHint == CHINT_ATTRIBUTE)
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(214), dataManager.FormatAttribute(mcard->chValue).c_str());
else if(mcard->cHint == CHINT_RACE) {
const auto& race = dataManager.FormatRace(mcard->chValue);
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(213), race.c_str());
}
else if(mcard->cHint == CHINT_ATTRIBUTE) {
const auto& attribute = dataManager.FormatAttribute(mcard->chValue);
myswprintf(formatBuffer, L"\n%ls%ls", dataManager.GetSysString(214), attribute.c_str());
}
else if(mcard->cHint == CHINT_NUMBER)
myswprintf(formatBuffer, L"\n%ls%d", dataManager.GetSysString(215), mcard->chValue);
str.append(formatBuffer);
......
......@@ -76,7 +76,7 @@ bool Game::Initialize() {
ErrorLog("Failed to load textures!");
return false;
}
DataManager::FileSystem = device->getFileSystem();
dataManager.FileSystem = device->getFileSystem();
if(!dataManager.LoadDB(L"cards.cdb")) {
ErrorLog("Failed to load card database (cards.cdb)!");
return false;
......@@ -610,16 +610,16 @@ bool Game::Initialize() {
wANAttribute = env->addWindow(irr::core::rect<irr::s32>(500, 200, 830, 285), false, dataManager.GetSysString(562));
wANAttribute->getCloseButton()->setVisible(false);
wANAttribute->setVisible(false);
for(int filter = 0x1, i = 0; i < 7; filter <<= 1, ++i)
for (int i = 0; i < ATTRIBUTES_COUNT; ++i)
chkAttribute[i] = env->addCheckBox(false, irr::core::rect<irr::s32>(10 + (i % 4) * 80, 25 + (i / 4) * 25, 90 + (i % 4) * 80, 50 + (i / 4) * 25),
wANAttribute, CHECK_ATTRIBUTE, dataManager.FormatAttribute(filter).c_str());
wANAttribute, CHECK_ATTRIBUTE, dataManager.GetSysString(DataManager::STRING_ID_ATTRIBUTE + i));
//announce race
wANRace = env->addWindow(irr::core::rect<irr::s32>(480, 200, 850, 410), false, dataManager.GetSysString(563));
wANRace->getCloseButton()->setVisible(false);
wANRace->setVisible(false);
for(int filter = 0x1, i = 0; i < RACES_COUNT; filter <<= 1, ++i)
for (int i = 0; i < RACES_COUNT; ++i)
chkRace[i] = env->addCheckBox(false, irr::core::rect<irr::s32>(10 + (i % 4) * 90, 25 + (i / 4) * 25, 100 + (i % 4) * 90, 50 + (i / 4) * 25),
wANRace, CHECK_RACE, dataManager.FormatRace(filter).c_str());
wANRace, CHECK_RACE, dataManager.GetSysString(DataManager::STRING_ID_RACE + i));
//selection hint
stHintMsg = env->addStaticText(L"", irr::core::rect<irr::s32>(500, 60, 820, 90), true, false, 0, -1, false);
stHintMsg->setBackgroundColor(0xc0ffffff);
......@@ -754,14 +754,14 @@ bool Game::Initialize() {
cbAttribute = env->addComboBox(irr::core::rect<irr::s32>(60, 20 + 50 / 6, 195, 40 + 50 / 6), wFilter, COMBOBOX_ATTRIBUTE);
cbAttribute->setMaxSelectionRows(10);
cbAttribute->addItem(dataManager.GetSysString(1310), 0);
for (int filter = 0; filter < ATTRIBUTES_COUNT; ++filter)
cbAttribute->addItem(dataManager.FormatAttribute(0x1U << filter).c_str(), 0x1U << filter);
for (int i = 0; i < ATTRIBUTES_COUNT; ++i)
cbAttribute->addItem(dataManager.GetSysString(DataManager::STRING_ID_ATTRIBUTE + i), 0x1U << i);
stRace = env->addStaticText(dataManager.GetSysString(1321), irr::core::rect<irr::s32>(10, 42 + 75 / 6, 70, 62 + 75 / 6), false, false, wFilter);
cbRace = env->addComboBox(irr::core::rect<irr::s32>(60, 40 + 75 / 6, 195, 60 + 75 / 6), wFilter, COMBOBOX_RACE);
cbRace->setMaxSelectionRows(10);
cbRace->addItem(dataManager.GetSysString(1310), 0);
for (int filter = 0; filter < RACES_COUNT; ++filter)
cbRace->addItem(dataManager.FormatRace(0x1U << filter).c_str(), 0x1U << filter);
for (int i = 0; i < RACES_COUNT; ++i)
cbRace->addItem(dataManager.GetSysString(DataManager::STRING_ID_RACE + i), 0x1U << i);
stAttack = env->addStaticText(dataManager.GetSysString(1322), irr::core::rect<irr::s32>(205, 22 + 50 / 6, 280, 42 + 50 / 6), false, false, wFilter);
ebAttack = env->addEditBox(L"", irr::core::rect<irr::s32>(260, 20 + 50 / 6, 340, 40 + 50 / 6), true, wFilter, EDITBOX_INPUTS);
ebAttack->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
......@@ -1114,41 +1114,48 @@ void Game::InitStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, i
scrCardText->setPos(0);
}
std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, irr::u32 pos) {
int pbuffer = 0;
size_t pbuffer = 0;
irr::u32 _width = 0, _height = 0;
wchar_t prev = 0;
wchar_t strBuffer[4096];
std::wstring ret;
wchar_t strBuffer[4096]{};
constexpr size_t buffer_len = sizeof strBuffer / sizeof strBuffer[0] - 1;
const size_t text_len = std::wcslen(text);
for(size_t i = 0; text[i] != 0 && i < std::wcslen(text); ++i) {
for(size_t i = 0; i < text_len ; ++i) {
if (pbuffer >= buffer_len)
break;
wchar_t c = text[i];
irr::u32 w = font->getCharDimension(c).Width + font->getKerningWidth(c, prev);
prev = c;
if(text[i] == L'\r') {
if (c == L'\r') {
continue;
} else if(text[i] == L'\n') {
}
if (c == L'\n') {
strBuffer[pbuffer++] = L'\n';
_width = 0;
_height++;
prev = 0;
if(_height == pos)
if (_height == pos)
pbuffer = 0;
continue;
} else if(_width > 0 && _width + w > cWidth) {
}
if (_width > 0 && _width + w > cWidth) {
strBuffer[pbuffer++] = L'\n';
_width = 0;
_height++;
prev = 0;
if(_height == pos)
if (_height == pos)
pbuffer = 0;
}
if (pbuffer >= buffer_len)
break;
_width += w;
strBuffer[pbuffer++] = c;
}
strBuffer[pbuffer] = 0;
if(pControl) pControl->setText(strBuffer);
ret.assign(strBuffer);
return ret;
if (pControl)
pControl->setText(strBuffer);
return std::wstring(strBuffer);
}
void Game::LoadExpansions() {
FileSystem::TraversalDir(L"./expansions", [](const wchar_t* name, bool isdir) {
......@@ -1168,17 +1175,17 @@ void Game::LoadExpansions() {
}
if (IsExtension(name, L".zip") || IsExtension(name, L".ypk")) {
#ifdef _WIN32
DataManager::FileSystem->addFileArchive(fpath, true, false, irr::io::EFAT_ZIP);
dataManager.FileSystem->addFileArchive(fpath, true, false, irr::io::EFAT_ZIP);
#else
char upath[1024];
BufferIO::EncodeUTF8(fpath, upath);
DataManager::FileSystem->addFileArchive(upath, true, false, irr::io::EFAT_ZIP);
dataManager.FileSystem->addFileArchive(upath, true, false, irr::io::EFAT_ZIP);
#endif
return;
}
});
for(irr::u32 i = 0; i < DataManager::FileSystem->getFileArchiveCount(); ++i) {
auto archive = DataManager::FileSystem->getFileArchive(i)->getFileList();
for(irr::u32 i = 0; i < dataManager.FileSystem->getFileArchiveCount(); ++i) {
auto archive = dataManager.FileSystem->getFileArchive(i)->getFileList();
for(irr::u32 j = 0; j < archive->getFileCount(); ++j) {
#ifdef _WIN32
const wchar_t* fname = archive->getFullFileName(j).c_str();
......@@ -1193,9 +1200,9 @@ void Game::LoadExpansions() {
}
if (IsExtension(fname, L".conf")) {
#ifdef _WIN32
auto reader = DataManager::FileSystem->createAndOpenFile(fname);
auto reader = dataManager.FileSystem->createAndOpenFile(fname);
#else
auto reader = DataManager::FileSystem->createAndOpenFile(uname);
auto reader = dataManager.FileSystem->createAndOpenFile(uname);
#endif
dataManager.LoadStrings(reader);
continue;
......@@ -1559,8 +1566,9 @@ void Game::ShowCardInfo(int code, bool resize) {
if(showingcode == code && !resize)
return;
wchar_t formatBuffer[256];
auto cit = dataManager.GetCodePointer(code);
bool is_valid = (cit != dataManager.datas_end());
auto& _datas = dataManager.GetDataTable();
auto cit = _datas.find(code);
bool is_valid = (cit != _datas.end());
imgCard->setImage(imageManager.GetTexture(code, true));
if (is_valid) {
auto& cd = cit->second;
......@@ -1581,12 +1589,13 @@ void Game::ShowCardInfo(int code, bool resize) {
if (is_valid && !gameConf.hide_setname) {
auto& cd = cit->second;
auto target = cit;
if (cd.alias && dataManager.GetCodePointer(cd.alias) != dataManager.datas_end()) {
target = dataManager.GetCodePointer(cd.alias);
if (cd.alias && _datas.find(cd.alias) != _datas.end()) {
target = _datas.find(cd.alias);
}
if (target->second.setcode[0]) {
offset = 23;// *yScale;
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), dataManager.FormatSetName(target->second.setcode).c_str());
const auto& setname = dataManager.FormatSetName(target->second.setcode);
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), setname.c_str());
stSetName->setText(formatBuffer);
}
else
......@@ -1597,7 +1606,10 @@ void Game::ShowCardInfo(int code, bool resize) {
}
if(is_valid && cit->second.type & TYPE_MONSTER) {
auto& cd = cit->second;
myswprintf(formatBuffer, L"[%ls] %ls/%ls", dataManager.FormatType(cd.type).c_str(), dataManager.FormatRace(cd.race).c_str(), dataManager.FormatAttribute(cd.attribute).c_str());
const auto& type = dataManager.FormatType(cd.type);
const auto& race = dataManager.FormatRace(cd.race);
const auto& attribute = dataManager.FormatAttribute(cd.attribute);
myswprintf(formatBuffer, L"[%ls] %ls/%ls", type.c_str(), race.c_str(), attribute.c_str());
stInfo->setText(formatBuffer);
int offset_info = 0;
irr::core::dimension2d<unsigned int> dtxt = guiFont->getDimension(formatBuffer);
......@@ -1619,10 +1631,11 @@ void Game::ShowCardInfo(int code, bool resize) {
myswprintf(adBuffer, L"%d/%d", cd.attack, cd.defense);
} else {
form = L"LINK-";
const auto& link_marker = dataManager.FormatLinkMarker(cd.link_marker);
if(cd.attack < 0)
myswprintf(adBuffer, L"?/- %ls", dataManager.FormatLinkMarker(cd.link_marker).c_str());
myswprintf(adBuffer, L"?/- %ls", link_marker.c_str());
else
myswprintf(adBuffer, L"%d/- %ls", cd.attack, dataManager.FormatLinkMarker(cd.link_marker).c_str());
myswprintf(adBuffer, L"%d/- %ls", cd.attack, link_marker.c_str());
}
if(cd.type & TYPE_PENDULUM) {
myswprintf(scaleBuffer, L" %d/%d", cd.lscale, cd.rscale);
......@@ -1640,8 +1653,10 @@ void Game::ShowCardInfo(int code, bool resize) {
scrCardText->setRelativePosition(irr::core::rect<irr::s32>(287 * xScale - 20, (83 + offset_arrows) + offset, 287 * xScale, 324 * yScale));
}
else {
if (is_valid)
myswprintf(formatBuffer, L"[%ls]", dataManager.FormatType(cit->second.type).c_str());
if (is_valid) {
const auto& type = dataManager.FormatType(cit->second.type);
myswprintf(formatBuffer, L"[%ls]", type.c_str());
}
else
myswprintf(formatBuffer, L"[%ls]", dataManager.unknown_string);
stInfo->setText(formatBuffer);
......
......@@ -487,7 +487,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(prev_operation == BUTTON_RENAME_REPLAY) {
wchar_t newname[256];
BufferIO::CopyWideString(mainGame->ebRSName->getText(), newname);
if(mywcsncasecmp(newname + std::wcslen(newname) - 4, L".yrp", 4)) {
if (!IsExtension(newname, L".yrp")) {
myswprintf(newname, L"%ls.yrp", mainGame->ebRSName->getText());
}
if(Replay::RenameReplay(mainGame->lstReplayList->getListItem(prev_sel), newname)) {
......
......@@ -21,7 +21,7 @@ class FileSystem {
public:
static void SafeFileName(wchar_t* wfile) {
while((wfile = std::wcspbrk(wfile, L"<>:\"/\\|?*")) != nullptr)
*wfile++ = '_';
*wfile++ = L'_';
}
static bool IsFileExists(const wchar_t* wfile) {
......@@ -125,7 +125,7 @@ class FileSystem {
public:
static void SafeFileName(wchar_t* wfile) {
while((wfile = std::wcspbrk(wfile, L"/")) != nullptr)
*wfile++ = '_';
*wfile++ = L'_';
}
static bool IsFileExists(const char* file) {
......
......@@ -63,23 +63,29 @@ void Replay::EndRecord() {
}
is_recording = false;
}
void Replay::SaveReplay(const wchar_t* name) {
bool Replay::SaveReplay(const wchar_t* base_name) {
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return;
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls.yrp", name);
FILE* rfp = mywfopen(fname, "wb");
return false;
wchar_t filename[256]{};
wchar_t path[256]{};
BufferIO::CopyWideString(base_name, filename);
FileSystem::SafeFileName(filename);
if (myswprintf(path, L"./replay/%ls.yrp", filename) <= 0)
return false;
FILE* rfp = mywfopen(path, "wb");
if(!rfp)
return;
return false;
std::fwrite(&pheader, sizeof pheader, 1, rfp);
std::fwrite(comp_data, comp_size, 1, rfp);
std::fclose(rfp);
return true;
}
bool Replay::OpenReplay(const wchar_t* name) {
FILE* rfp = mywfopen(name, "rb");
if(!rfp) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
if (myswprintf(fname, L"./replay/%ls", name) <= 0)
return false;
rfp = mywfopen(fname, "rb");
}
if(!rfp)
......@@ -131,19 +137,28 @@ bool Replay::OpenReplay(const wchar_t* name) {
return true;
}
bool Replay::DeleteReplay(const wchar_t* name) {
if (std::wcschr(name, L'/') || std::wcschr(name, L'\\'))
return false;
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
if(myswprintf(fname, L"./replay/%ls", name) <= 0)
return false;
return FileSystem::RemoveFile(fname);
}
bool Replay::RenameReplay(const wchar_t* oldname, const wchar_t* newname) {
wchar_t oldfname[256];
wchar_t newfname[256];
myswprintf(oldfname, L"./replay/%ls", oldname);
myswprintf(newfname, L"./replay/%ls", newname);
wchar_t old_path[256];
wchar_t new_path[256];
if (std::wcschr(oldname, L'/') || std::wcschr(oldname, L'\\'))
return false;
if (std::wcschr(newname, L'/') || std::wcschr(newname, L'\\'))
return false;
if (myswprintf(old_path, L"./replay/%ls", oldname) <= 0)
return false;
if (myswprintf(new_path, L"./replay/%ls", newname) <= 0)
return false;
char oldfilefn[1024];
char newfilefn[1024];
BufferIO::EncodeUTF8(oldfname, oldfilefn);
BufferIO::EncodeUTF8(newfname, newfilefn);
BufferIO::EncodeUTF8(old_path, oldfilefn);
BufferIO::EncodeUTF8(new_path, newfilefn);
int result = std::rename(oldfilefn, newfilefn);
return result == 0;
}
......
......@@ -65,7 +65,7 @@ public:
void WriteInt32(int32_t data, bool flush = true);
void Flush();
void EndRecord();
void SaveReplay(const wchar_t* name);
bool SaveReplay(const wchar_t* base_name);
// play
static bool DeleteReplay(const wchar_t* name);
......
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