Commit 17cdeb8c authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro

parents 38385e58 83ad6221
......@@ -18,7 +18,7 @@ ClientCard::ClientCard() {
is_showtarget = false;
is_showchaintarget = false;
is_highlighting = false;
is_disabled = false;
status = 0;
is_reversed = false;
cmdFlag = 0;
code = 0;
......@@ -125,6 +125,8 @@ void ClientCard::UpdateInfo(char* buf) {
base_defense = BufferIO::ReadInt32(buf);
if(flag & QUERY_REASON)
reason = BufferIO::ReadInt32(buf);
if(flag & QUERY_REASON_CARD)
buf += 4;
if(flag & QUERY_EQUIP_CARD) {
int c = BufferIO::ReadInt8(buf);
int l = BufferIO::ReadInt8(buf);
......@@ -162,10 +164,8 @@ void ClientCard::UpdateInfo(char* buf) {
}
if(flag & QUERY_OWNER)
owner = BufferIO::ReadInt32(buf);
if(flag & QUERY_IS_DISABLED)
is_disabled = BufferIO::ReadInt32(buf);
if(flag & QUERY_IS_PUBLIC)
is_public = BufferIO::ReadInt32(buf);
if(flag & QUERY_STATUS)
status = BufferIO::ReadInt32(buf);
if(flag & QUERY_LSCALE) {
lscale = BufferIO::ReadInt32(buf);
myswprintf(lscstring, L"%d", lscale);
......@@ -210,8 +210,14 @@ bool ClientCard::client_card_sort(ClientCard* c1, ClientCard* c2) {
return c1->overlayTarget->sequence < c2->overlayTarget->sequence;
else return c1->sequence < c2->sequence;
else {
if(c1->location & 0x71)
if(c1->location & (LOCATION_DECK | LOCATION_GRAVE | LOCATION_REMOVED | LOCATION_EXTRA)) {
for(size_t i = 0; i < mainGame->dField.chains.size(); ++i) {
auto chit = mainGame->dField.chains[i];
if(c1 == chit.chain_card || chit.target.find(c1) != chit.target.end())
return true;
}
return c1->sequence > c2->sequence;
}
else
return c1->sequence < c2->sequence;
}
......
......@@ -89,8 +89,7 @@ public:
u8 location;
u8 sequence;
u8 position;
u8 is_disabled;
u8 is_public;
u32 status;
u8 cHint;
u32 chValue;
u32 opParam;
......
......@@ -71,6 +71,7 @@ inline int myswprintf(wchar_t(&buf)[N], const wchar_t* fmt, TR... args) {
#include <memory.h>
#include <time.h>
#include "bufferio.h"
#include "myfilesystem.h"
#include "mymutex.h"
#include "mysignal.h"
#include "mythread.h"
......
......@@ -129,7 +129,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
switch(id) {
case BUTTON_CLEAR_DECK: {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1339));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1339));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -185,7 +185,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->gMutex.Lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->cbDBDecks->getItem(sel), dataManager.GetSysString(1337));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -195,7 +195,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case BUTTON_LEAVE_GAME: {
if(is_modified && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1356));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -362,7 +362,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case COMBOBOX_DBDECKS: {
if(is_modified && !mainGame->chkIgnoreDeckChanges->isChecked()) {
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetSysString(1356));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetSysString(1356));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -776,6 +776,34 @@ void DeckBuilder::StartFilter() {
void DeckBuilder::FilterCards() {
results.clear();
const wchar_t* pstr = mainGame->ebCardName->getText();
std::wstring str = std::wstring(pstr);
std::vector<std::wstring> query_elements;
std::vector<std::vector<std::wstring>::iterator> query_elements_track;
size_t element_start = 0;
while(mainGame->gameConf.search_multiple_keywords) {
size_t element_end = str.find_first_of(mainGame->gameConf.search_multiple_keywords == 1 ? L' ' : L'+', element_start);
if(element_end == std::wstring::npos)
break;
size_t length = element_end - element_start;
if(length > 0) {
query_elements.push_back(str.substr(element_start, length));
element_start = element_end + 1;
} else
element_start++;
}
query_elements.push_back(str.substr(element_start));
std::unordered_map<std::wstring, unsigned int> set_code_map;
for(auto elements_iterator = query_elements.begin(); elements_iterator != query_elements.end(); elements_iterator++) {
const wchar_t* element_pointer = elements_iterator->c_str();
if(element_pointer[0] == L'@')
set_code_map[*elements_iterator] = dataManager.GetSetCode(&element_pointer[1]);
else
set_code_map[*elements_iterator] = dataManager.GetSetCode(&element_pointer[0]);
if(element_pointer[0] == 0 || (element_pointer[0] == L'$' && element_pointer[1] == 0) || (element_pointer[0] == L'@' && element_pointer[1] == 0))
query_elements_track.push_back(elements_iterator);
}
for(auto elements_track_iterator = query_elements_track.begin(); elements_track_iterator != query_elements_track.end(); elements_track_iterator++)
query_elements.erase(*elements_track_iterator);
unsigned int set_code = 0;
if(pstr[0] == L'@')
set_code = dataManager.GetSetCode(&pstr[1]);
......@@ -856,24 +884,39 @@ void DeckBuilder::FilterCards() {
if(filter_lm == 7 && data.ot != 4)
continue;
}
if(pstr) {
if(pstr[0] == L'$') {
if(!CardNameContains(text.name.c_str(), &pstr[1]))
continue;
} else if(pstr[0] == L'@' && set_code) {
if(!check_set_code(data, set_code)) continue;
bool is_target = true;
for (auto elements_iterator = query_elements.begin(); elements_iterator != query_elements.end(); elements_iterator++) {
const wchar_t* element_pointer = elements_iterator->c_str();
if (element_pointer[0] == L'$') {
if(!CardNameContains(text.name.c_str(), &element_pointer[1])){
is_target = false;
break;
}
}
else if (element_pointer[0] == L'@' && set_code_map[*elements_iterator]) {
if(!check_set_code(data, set_code_map[*elements_iterator])) {
is_target = false;
break;
}
} else {
int trycode = BufferIO::GetVal(pstr);
int trycode = BufferIO::GetVal(elements_iterator->c_str());
bool tryresult = dataManager.GetData(trycode, 0);
if(!tryresult && !CardNameContains(text.name.c_str(), pstr) && text.text.find(pstr) == std::wstring::npos
&& (!set_code || !check_set_code(data, set_code)))
continue;
if (tryresult && data.code != trycode
&& !(data.alias == trycode && (data.alias - data.code < CARD_ARTWORK_VERSIONS_OFFSET || data.code - data.alias < CARD_ARTWORK_VERSIONS_OFFSET)))
continue;
if(!tryresult && !CardNameContains(text.name.c_str(), elements_iterator->c_str()) && text.text.find(elements_iterator->c_str()) == std::wstring::npos
&& (!set_code_map[*elements_iterator] || !check_set_code(data, set_code_map[*elements_iterator]))) {
is_target = false;
break;
}
if(tryresult && data.code != trycode
&& !(data.alias == trycode && (data.alias - data.code < CARD_ARTWORK_VERSIONS_OFFSET || data.code - data.alias < CARD_ARTWORK_VERSIONS_OFFSET))) {
is_target = false;
break;
}
}
}
results.push_back(ptr);
if(is_target)
results.push_back(ptr);
else
continue;
}
myswprintf(result_string, L"%d", results.size());
if(results.size() > 7) {
......
......@@ -8,47 +8,11 @@ namespace ygo {
DeckManager deckManager;
void DeckManager::LoadLFList() {
void DeckManager::LoadLFListSingle(const char* path) {
LFList* cur = NULL;
FILE* fp = fopen("lflist.conf", "r");
FILE* fp_custom = fopen("expansions/lflist.conf", "r");
FILE* fp = fopen(path, "r");
char linebuf[256];
wchar_t strBuffer[256];
if(fp_custom) {
while(fgets(linebuf, 256, fp_custom)) {
if(linebuf[0] == '#')
continue;
int p = 0, sa = 0, code, count;
if(linebuf[0] == '!') {
sa = BufferIO::DecodeUTF8((const char*)(&linebuf[1]), strBuffer);
while(strBuffer[sa - 1] == L'\r' || strBuffer[sa - 1] == L'\n' ) sa--;
LFList newlist;
_lfList.push_back(newlist);
cur = &_lfList[_lfList.size() - 1];
memcpy(cur->listName, (const void*)strBuffer, 40);
cur->listName[sa] = 0;
cur->content = new std::unordered_map<int, int>;
cur->hash = 0x7dfcee6a;
continue;
}
while(linebuf[p] != ' ' && linebuf[p] != '\t' && linebuf[p] != 0) p++;
if(linebuf[p] == 0)
continue;
linebuf[p++] = 0;
sa = p;
code = atoi(linebuf);
if(code == 0)
continue;
while(linebuf[p] == ' ' || linebuf[p] == '\t') p++;
while(linebuf[p] != ' ' && linebuf[p] != '\t' && linebuf[p] != 0) p++;
linebuf[p] = 0;
count = atoi(&linebuf[sa]);
if(cur == NULL) continue;
(*cur->content)[code] = count;
cur->hash = cur->hash ^ ((code << 18) | (code >> 14)) ^ ((code << (27 + count)) | (code >> (5 - count)));
}
fclose(fp_custom);
}
if(fp) {
while(fgets(linebuf, 256, fp)) {
if(linebuf[0] == '#')
......@@ -60,7 +24,7 @@ void DeckManager::LoadLFList() {
LFList newlist;
_lfList.push_back(newlist);
cur = &_lfList[_lfList.size() - 1];
memcpy(cur->listName, (const void*)strBuffer, 40);
memcpy(cur->listName, (const void*)strBuffer, 20 * sizeof(wchar_t));
cur->listName[sa] = 0;
cur->content = new std::unordered_map<int, int>;
cur->hash = 0x7dfcee6a;
......@@ -84,6 +48,10 @@ void DeckManager::LoadLFList() {
}
fclose(fp);
}
}
void DeckManager::LoadLFList() {
LoadLFListSingle("expansions/lflist.conf");
LoadLFListSingle("lflist.conf");
LFList nolimit;
myswprintf(nolimit.listName, L"N/A");
nolimit.hash = 0;
......@@ -266,6 +234,8 @@ bool DeckManager::LoadDeck(const wchar_t* file) {
return true;
}
bool DeckManager::SaveDeck(Deck& deck, const wchar_t* name) {
if(!FileSystem::IsDirExists(L"./deck") && !FileSystem::MakeDir(L"./deck"))
return false;
wchar_t file[64];
myswprintf(file, L"./deck/%ls.ydk", name);
FILE* fp = OpenDeckFile(file, "w");
......
......@@ -35,6 +35,7 @@ public:
Deck current_deck;
std::vector<LFList> _lfList;
void LoadLFListSingle(const char* path);
void LoadLFList();
wchar_t* GetLFListName(int lfhash);
int CheckDeck(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg);
......
......@@ -382,7 +382,8 @@ void Game::DrawCard(ClientCard* pcard) {
matManager.mTexture.setTexture(0, imageManager.tChainTarget);
driver->setMaterial(matManager.mTexture);
driver->drawVertexPrimitiveList(matManager.vSymbol, 4, matManager.iRectangle, 2);
} else if(pcard->is_disabled && (pcard->location & LOCATION_ONFIELD) && (pcard->position & POS_FACEUP)) {
} else if((pcard->status & (STATUS_DISABLED | STATUS_FORBIDDEN))
&& (pcard->location & LOCATION_ONFIELD) && (pcard->position & POS_FACEUP)) {
matManager.mTexture.setTexture(0, imageManager.tNegated);
driver->setMaterial(matManager.mTexture);
driver->drawVertexPrimitiveList(matManager.vNegate, 4, matManager.iRectangle, 2);
......
......@@ -469,7 +469,7 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->stHostPrepDuelist[2]->setText(L"");
mainGame->stHostPrepDuelist[3]->setText(L"");
mainGame->stHostPrepOB->setText(L"");
mainGame->SetStaticText(mainGame->stHostPrepRule, 180, mainGame->guiFont, (wchar_t*)str.c_str());
mainGame->SetStaticText(mainGame->stHostPrepRule, 180, mainGame->guiFont, str.c_str());
mainGame->RefreshDeck(mainGame->cbDeckSelect);
mainGame->cbDeckSelect->setEnabled(true);
if(mainGame->wCreateHost->isVisible())
......@@ -681,18 +681,26 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->btnCancelOrFinish->setVisible(false);
mainGame->btnShuffle->setVisible(false);
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
char timebuf[40];
strftime(timebuf, 40, "%Y-%m-%d %H-%M-%S", localedtime);
size_t size = strlen(timebuf) + 1;
wchar_t timetext[80];
mbstowcs(timetext, timebuf, size);
tm* localedtime = localtime(&nowtime);
wchar_t timetext[40];
wcsftime(timetext, 40, L"%Y-%m-%d %H-%M-%S", localedtime);
mainGame->ebRSName->setText(timetext);
mainGame->wReplaySave->setText(dataManager.GetSysString(1340));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait();
if(!mainGame->chkAutoSaveReplay->isChecked()) {
mainGame->wReplaySave->setText(dataManager.GetSysString(1340));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait();
}
else {
mainGame->actionParam = 1;
wchar_t msgbuf[256];
myswprintf(msgbuf, dataManager.GetSysString(1367), timetext);
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, msgbuf);
mainGame->PopupElement(mainGame->wACMessage, 20);
mainGame->gMutex.Unlock();
mainGame->WaitFrameSignal(30);
}
if(mainGame->actionParam || !is_host) {
char* prep = pdata;
Replay new_replay;
......@@ -1296,6 +1304,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
wchar_t ynbuf[256];
myswprintf(ynbuf, dataManager.GetSysString(200), dataManager.FormatLocation(l, s), dataManager.GetName(code));
myswprintf(textBuffer, L"%ls\n%ls", event_string, ynbuf);
} else if(desc == 221) {
wchar_t ynbuf[256];
myswprintf(ynbuf, dataManager.GetSysString(221), dataManager.FormatLocation(l, s), dataManager.GetName(code));
myswprintf(textBuffer, L"%ls\n%ls\n%ls", event_string, ynbuf, dataManager.GetSysString(223));
} else if(desc < 2048) {
myswprintf(textBuffer, dataManager.GetSysString(desc), dataManager.GetName(code));
} else {
......@@ -1312,7 +1324,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int desc = BufferIO::ReadInt32(pbuf);
mainGame->dField.highlighting_card = 0;
mainGame->gMutex.Lock();
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(desc));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, dataManager.GetDesc(desc));
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
return false;
......@@ -1550,9 +1562,11 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
if(!forced) {
if(count == 0)
myswprintf(textBuffer, L"%ls\n%ls", dataManager.GetSysString(201), dataManager.GetSysString(202));
else if(select_trigger)
myswprintf(textBuffer, L"%ls\n%ls\n%ls", event_string, dataManager.GetSysString(222), dataManager.GetSysString(223));
else
myswprintf(textBuffer, L"%ls\n%ls", event_string, dataManager.GetSysString(203));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
}
}
......
......@@ -279,7 +279,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnOptionn->setVisible(true);
if(selected_option == 0)
mainGame->btnOptionp->setVisible(false);
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(select_options[selected_option]));
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, dataManager.GetDesc(select_options[selected_option]));
break;
}
case BUTTON_OPTION_NEXT: {
......@@ -288,7 +288,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnOptionp->setVisible(true);
if(selected_option == select_options.size() - 1)
mainGame->btnOptionn->setVisible(false);
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, (wchar_t*)dataManager.GetDesc(select_options[selected_option]));
mainGame->SetStaticText(mainGame->stOptions, 310, mainGame->textFont, dataManager.GetDesc(select_options[selected_option]));
break;
}
case BUTTON_OPTION_0: {
......@@ -424,6 +424,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->wCardSelect->setText(dataManager.GetSysString(568));
list_command = COMMAND_OPERATION;
}
std::sort(selectable_cards.begin(), selectable_cards.end(), ClientCard::client_card_sort);
ShowSelectCard(true, true);
}
break;
......@@ -580,6 +581,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}
}
list_command = COMMAND_LIST;
std::sort(selectable_cards.begin(), selectable_cards.end(), ClientCard::client_card_sort);
ShowSelectCard(true);
break;
}
......@@ -995,6 +997,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->ClearCardInfo(mcard->controler);
}
}
if(id == TEXT_CARD_LIST_TIP) {
mainGame->stCardListTip->setVisible(true);
}
break;
}
case irr::gui::EGET_ELEMENT_LEFT: {
......@@ -1010,6 +1015,9 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
SetShowMark(mcard, false);
mainGame->stCardListTip->setVisible(false);
}
if(id == TEXT_CARD_LIST_TIP) {
mainGame->stCardListTip->setVisible(false);
}
break;
}
default:
......@@ -1789,6 +1797,15 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
switch(id) {
case CHECKBOX_AUTO_SEARCH: {
mainGame->gameConf.auto_search_limit = mainGame->chkAutoSearch->isChecked() ? 0 : -1;
if(mainGame->is_building && !mainGame->is_siding)
mainGame->deckBuilder.InstantSearch();
return true;
break;
}
case CHECKBOX_MULTI_KEYWORDS: {
mainGame->gameConf.search_multiple_keywords = mainGame->chkMultiKeywords->isChecked() ? 1 : 0;
if(mainGame->is_building && !mainGame->is_siding)
mainGame->deckBuilder.InstantSearch();
return true;
break;
}
......@@ -2226,6 +2243,8 @@ void ClientField::ShowCardInfoInList(ClientCard* pcard, irr::gui::IGUIElement* e
if(pcard->code) {
str.append(dataManager.GetName(pcard->code));
}
if(pcard->status & STATUS_PROC_COMPLETE)
str.append(L"\n").append(dataManager.GetSysString(224));
for(size_t i = 0; i < chains.size(); ++i) {
wchar_t formatBuffer[2048];
auto chit = chains[i];
......@@ -2243,9 +2262,14 @@ void ClientField::ShowCardInfoInList(ClientCard* pcard, irr::gui::IGUIElement* e
irr::core::rect<s32> ePos = element->getRelativePosition();
s32 x = (ePos.UpperLeftCorner.X + ePos.LowerRightCorner.X) / 2;
s32 y = ePos.LowerRightCorner.Y;
mainGame->SetStaticText(mainGame->stCardListTip, 160, mainGame->guiFont, str.c_str());
mainGame->SetStaticText(mainGame->stCardListTip, 320, mainGame->guiFont, str.c_str());
irr::core::dimension2d<unsigned int> dTip = mainGame->guiFont->getDimension(mainGame->stCardListTip->getText()) + irr::core::dimension2d<unsigned int>(10, 10);
mainGame->stCardListTip->setRelativePosition(recti(x - dTip.Width / 2, y - 10, x + dTip.Width / 2, y - 10 + dTip.Height));
s32 w = dTip.Width / 2;
if(x - w < 10)
x = w + 10;
if(x + w > 670)
x = 670 - w;
mainGame->stCardListTip->setRelativePosition(recti(x - w, y - 10, x + w, y - 10 + dTip.Height));
mainGame->stCardListTip->setVisible(true);
}
}
......
This diff is collapsed.
......@@ -39,10 +39,12 @@ struct Config {
int draw_field_spell;
int separate_clear_button;
int auto_search_limit;
int search_multiple_keywords;
int chkIgnoreDeckChanges;
int defaultOT;
int enable_bot_mode;
int quick_animation;
int auto_save_replay;
bool enable_sound;
bool enable_music;
double sound_volume;
......@@ -132,11 +134,10 @@ public:
void SaveConfig();
void ShowCardInfo(int code);
void ClearCardInfo(int player = 0);
void AddChatMsg(wchar_t* msg, int player);
void AddChatMsg(const wchar_t* msg, int player);
void ClearChatMsg();
void AddDebugMsg(char* msgbuf);
bool MakeDirectory(const std::string folder);
void initUtils();
void AddDebugMsg(const char* msgbuf);
void ErrorLog(const char* msgbuf);
void ClearTextures();
void CloseDuelWindow();
......@@ -243,10 +244,12 @@ public:
irr::gui::IGUICheckBox* chkAutoChain;
irr::gui::IGUICheckBox* chkWaitChain;
irr::gui::IGUICheckBox* chkQuickAnimation;
irr::gui::IGUICheckBox* chkAutoSaveReplay;
irr::gui::IGUICheckBox* chkHideSetname;
irr::gui::IGUICheckBox* chkHideHintButton;
irr::gui::IGUICheckBox* chkIgnoreDeckChanges;
irr::gui::IGUICheckBox* chkAutoSearch;
irr::gui::IGUICheckBox* chkMultiKeywords;
irr::gui::IGUICheckBox* chkEnableSound;
irr::gui::IGUICheckBox* chkEnableMusic;
irr::gui::IGUIScrollBar* scrSoundVolume;
......@@ -553,6 +556,7 @@ extern Game* mainGame;
#define BUTTON_CARD_4 234
#define SCROLL_CARD_SELECT 235
#define BUTTON_CARD_SEL_OK 236
#define TEXT_CARD_LIST_TIP 237
#define BUTTON_CMD_ACTIVATE 240
#define BUTTON_CMD_SUMMON 241
#define BUTTON_CMD_SPSUMMON 242
......@@ -623,6 +627,7 @@ extern Game* mainGame;
#define BUTTON_LOAD_SINGLEPLAY 351
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECKBOX_AUTO_SEARCH 360
#define CHECKBOX_MULTI_KEYWORDS 372
#define CHECKBOX_ENABLE_SOUND 361
#define CHECKBOX_ENABLE_MUSIC 362
#define SCROLL_VOLUME 363
......
......@@ -248,7 +248,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->gMutex.Lock();
wchar_t textBuffer[256];
myswprintf(textBuffer, L"%ls\n%ls", mainGame->lstReplayList->getListItem(sel), dataManager.GetSysString(1363));
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, (wchar_t*)textBuffer);
mainGame->SetStaticText(mainGame->stQMessage, 310, mainGame->textFont, textBuffer);
mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
......@@ -439,7 +439,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
std::wstring repinfo;
time_t curtime = ReplayMode::cur_replay.pheader.seed;
tm* st = localtime(&curtime);
myswprintf(infobuf, L"%d/%d/%d %02d:%02d:%02d\n", st->tm_year + 1900, st->tm_mon + 1, st->tm_mday, st->tm_hour, st->tm_min, st->tm_sec);
wcsftime(infobuf, 256, L"%Y/%m/%d %H:%M:%S\n", st);
repinfo.append(infobuf);
wchar_t namebuf[4][20];
ReplayMode::cur_replay.ReadName(namebuf[0]);
......@@ -454,7 +454,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", namebuf[0], namebuf[1]);
repinfo.append(infobuf);
mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, (wchar_t*)repinfo.c_str());
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str());
break;
}
case LISTBOX_BOT_LIST: {
......
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#include <string.h>
#include <functional>
#include "bufferio.h"
#ifdef _WIN32
#include <direct.h>
#include <sys/stat.h>
#else
#include <dirent.h>
#include <sys/stat.h>
#endif
#ifdef _WIN32
#include <Windows.h>
class FileSystem {
public:
static bool IsFileExists(const wchar_t* wfile) {
struct _stat fileStat;
return (_wstat(wfile, &fileStat) == 0) && !(fileStat.st_mode & _S_IFDIR);
}
static bool IsFileExists(const char* file) {
wchar_t wfile[1024];
BufferIO::DecodeUTF8(file, wfile);
return IsFileExists(wfile);
}
static bool IsDirExists(const wchar_t* wdir) {
struct _stat fileStat;
return (_wstat(wdir, &fileStat) == 0) && (fileStat.st_mode & _S_IFDIR);
}
static bool IsDirExists(const char* dir) {
wchar_t wdir[1024];
BufferIO::DecodeUTF8(dir, wdir);
return IsDirExists(wdir);
}
static bool MakeDir(const wchar_t* wdir) {
return _wmkdir(wdir) == 0;
}
static bool MakeDir(const char* dir) {
wchar_t wdir[1024];
BufferIO::DecodeUTF8(dir, wdir);
return MakeDir(wdir);
}
static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) {
wchar_t findstr[1024];
wcscpy(findstr, wpath);
wcscat(findstr, L"/*");
WIN32_FIND_DATAW fdataw;
HANDLE fh = FindFirstFileW(findstr, &fdataw);
if(fh == INVALID_HANDLE_VALUE)
return;
do {
cb(fdataw.cFileName, (fdataw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
} while(FindNextFileW(fh, &fdataw));
FindClose(fh);
}
static void TraversalDir(const char* path, const std::function<void(const char*, bool)>& cb) {
wchar_t wpath[1024];
BufferIO::DecodeUTF8(path, wpath);
TraversalDir(wpath, [&cb](const wchar_t* wname, bool isdir) {
char name[1024];
BufferIO::EncodeUTF8(wname, name);
cb(name, isdir);
});
}
};
#else
class FileSystem {
public:
static bool IsFileExists(const char* file) {
struct stat fileStat;
return (stat(file, &fileStat) == 0) && !S_ISDIR(fileStat.st_mode);
}
static bool IsFileExists(const wchar_t* wfile) {
char file[1024];
BufferIO::EncodeUTF8(wfile, file);
return IsFileExists(file);
}
static bool IsDirExists(const char* dir) {
struct stat fileStat;
return (stat(dir, &fileStat) == 0) && S_ISDIR(fileStat.st_mode);
}
static bool IsDirExists(const wchar_t* wdir) {
char dir[1024];
BufferIO::EncodeUTF8(wdir, dir);
return IsDirExists(dir);
}
static bool MakeDir(const char* dir) {
return mkdir(dir, 0775) == 0;
}
static bool MakeDir(const wchar_t* wdir) {
char dir[1024];
BufferIO::EncodeUTF8(wdir, dir);
return MakeDir(dir);
}
static void TraversalDir(const char* path, const std::function<void(const char*, bool)>& cb) {
DIR* dir = nullptr;
struct dirent* dirp = nullptr;
if((dir = opendir(path)) == nullptr)
return;
struct stat fileStat;
while((dirp = readdir(dir)) != nullptr) {
char fname[1024];
strcpy(fname, path);
strcat(fname, "/");
strcat(fname, dirp->d_name);
stat(fname, &fileStat);
cb(dirp->d_name, S_ISDIR(fileStat.st_mode));
}
closedir(dir);
}
static void TraversalDir(const wchar_t* wpath, const std::function<void(const wchar_t*, bool)>& cb) {
char path[1024];
BufferIO::EncodeUTF8(wpath, path);
TraversalDir(path, [&cb](const char* name, bool isdir) {
wchar_t wname[1024];
BufferIO::DecodeUTF8(name, wname);
cb(wname, isdir);
});
}
};
#endif // _WIN32
#endif //FILESYSTEM_H
......@@ -17,6 +17,8 @@ Replay::~Replay() {
delete[] comp_data;
}
void Replay::BeginRecord() {
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return;
#ifdef _WIN32
if(is_recording)
CloseHandle(recording_fp);
......@@ -123,6 +125,8 @@ void Replay::EndRecord() {
is_recording = false;
}
void Replay::SaveReplay(const wchar_t* name) {
if(!FileSystem::IsDirExists(L"./replay") && !FileSystem::MakeDir(L"./replay"))
return;
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls.yrp", name);
#ifdef WIN32
......
......@@ -1487,18 +1487,17 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_POSITION, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0;
while(qlen < len) {
int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf;
int pos = slen - 8;
if(qflag & QUERY_LSCALE)
pos -= 4;
if(qflag & QUERY_RSCALE)
pos -= 4;
if(!qbuf[pos])
int offset = 8;
if(!(qflag & QUERY_CODE))
offset -= 4;
unsigned position = ((*(int*)(qbuf + offset)) >> 24) & 0xff;
if(!(position & POS_FACEUP))
memset(qbuf, 0, slen - 4);
qbuf += slen - 4;
qlen += slen;
......
......@@ -128,18 +128,25 @@ int SingleMode::SinglePlayThread(void* param) {
}
last_replay.EndRecord();
time_t nowtime = time(NULL);
struct tm *localedtime = localtime(&nowtime);
char timebuf[40];
strftime(timebuf, 40, "%Y-%m-%d %H-%M-%S", localedtime);
size_t size = strlen(timebuf) + 1;
wchar_t timetext[80];
mbstowcs(timetext, timebuf, size);
tm* localedtime = localtime(&nowtime);
wchar_t timetext[40];
wcsftime(timetext, 40, L"%Y-%m-%d %H-%M-%S", localedtime);
mainGame->ebRSName->setText(timetext);
mainGame->wReplaySave->setText(dataManager.GetSysString(1340));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait();
if(!mainGame->chkAutoSaveReplay->isChecked()) {
mainGame->wReplaySave->setText(dataManager.GetSysString(1340));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
mainGame->replaySignal.Reset();
mainGame->replaySignal.Wait();
} else {
mainGame->actionParam = 1;
wchar_t msgbuf[256];
myswprintf(msgbuf, dataManager.GetSysString(1367), timetext);
mainGame->SetStaticText(mainGame->stACMessage, 310, mainGame->guiFont, msgbuf);
mainGame->PopupElement(mainGame->wACMessage, 20);
mainGame->gMutex.Unlock();
mainGame->WaitFrameSignal(30);
}
if(mainGame->actionParam)
last_replay.SaveReplay(mainGame->ebRSName->getText());
end_duel(pduel);
......
#include "sound_manager.h"
#ifndef _WIN32
#include <dirent.h>
#endif
#ifdef YGOPRO_USE_IRRKLANG
#ifdef IRRKLANG_STATIC
#include "../ikpmp3/ikpMP3.h"
#endif
......@@ -28,51 +25,23 @@ bool SoundManager::Init() {
}
void SoundManager::RefreshBGMList() {
RefershBGMDir(L"", BGM_DUEL);
RefershBGMDir(L"duel/", BGM_DUEL);
RefershBGMDir(L"menu/", BGM_MENU);
RefershBGMDir(L"deck/", BGM_DECK);
RefershBGMDir(L"advantage/", BGM_ADVANTAGE);
RefershBGMDir(L"disadvantage/", BGM_DISADVANTAGE);
RefershBGMDir(L"win/", BGM_WIN);
RefershBGMDir(L"lose/", BGM_LOSE);
RefershBGMDir(L"duel", BGM_DUEL);
RefershBGMDir(L"menu", BGM_MENU);
RefershBGMDir(L"deck", BGM_DECK);
RefershBGMDir(L"advantage", BGM_ADVANTAGE);
RefershBGMDir(L"disadvantage", BGM_DISADVANTAGE);
RefershBGMDir(L"win", BGM_WIN);
RefershBGMDir(L"lose", BGM_LOSE);
}
void SoundManager::RefershBGMDir(std::wstring path, int scene) {
#ifdef _WIN32
WIN32_FIND_DATAW fdataw;
std::wstring search = L"./sound/BGM/" + path + L"*.*";
HANDLE fh = FindFirstFileW(search.c_str(), &fdataw);
if(fh == INVALID_HANDLE_VALUE)
return;
do {
size_t len = wcslen(fdataw.cFileName);
if((fdataw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || len < 5
|| !(_wcsicmp(fdataw.cFileName + len - 4, L".mp3") == 0 || _wcsicmp(fdataw.cFileName + len - 4, L".ogg") == 0))
continue;
std::wstring filename = path + (std::wstring)fdataw.cFileName;
BGMList[BGM_ALL].push_back(filename);
BGMList[scene].push_back(filename);
} while(FindNextFileW(fh, &fdataw));
FindClose(fh);
#else
DIR * dir;
struct dirent * dirp;
std::wstring wsearchpath = L"./sound/BGM/" + path;
char searchpath[256];
BufferIO::EncodeUTF8(wsearchpath.c_str(), searchpath);
if((dir = opendir(searchpath)) == NULL)
return;
while((dirp = readdir(dir)) != NULL) {
size_t len = strlen(dirp->d_name);
if(len < 5 || !(strcasecmp(dirp->d_name + len - 4, ".mp3") == 0 || strcasecmp(dirp->d_name + len - 4, ".ogg")))
continue;
wchar_t wname[256];
BufferIO::DecodeUTF8(dirp->d_name, wname);
std::wstring filename = path + (std::wstring)wname;
BGMList[BGM_ALL].push_back(filename);
BGMList[scene].push_back(filename);
}
closedir(dir);
#endif
std::wstring search = L"./sound/BGM/" + path;
FileSystem::TraversalDir(search.c_str(), [this, &path, scene](const wchar_t* name, bool isdir) {
if(!isdir && wcsrchr(name, '.') && (!mywcsncasecmp(wcsrchr(name, '.'), L".mp3", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".ogg", 4))) {
std::wstring filename = path + L"/" + name;
BGMList[BGM_ALL].push_back(filename);
BGMList[scene].push_back(filename);
}
});
}
void SoundManager::PlaySoundEffect(int sound) {
#ifdef YGOPRO_USE_IRRKLANG
......
......@@ -1583,18 +1583,17 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, MSG_UPDATE_DATA);
BufferIO::WriteInt8(qbuf, player);
BufferIO::WriteInt8(qbuf, LOCATION_HAND);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
int len = query_field_card(pduel, player, LOCATION_HAND, flag | QUERY_POSITION, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0;
while(qlen < len) {
int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf;
int pos = slen - 8;
if(qflag & QUERY_LSCALE)
pos -= 4;
if(qflag & QUERY_RSCALE)
pos -= 4;
if(!qbuf[pos])
int offset = 8;
if(!(qflag & QUERY_CODE))
offset -= 4;
unsigned position = ((*(int*)(qbuf + offset)) >> 24) & 0xff;
if(!(position & POS_FACEUP))
memset(qbuf, 0, slen - 4);
qbuf += slen - 4;
qlen += slen;
......
Subproject commit a7640393c52035d7321da3877622087d24686baf
Subproject commit 60d8b81d6d89c62e9d40d8bb8f6504f45121b053
Subproject commit 4abdd05e56bfb3a3c369f7f8bed8230f7e10e4c2
Subproject commit 87b2a039e3b02c8fad75aa53719095e60c866466
......@@ -70,6 +70,13 @@
!system 215 已选择数字:
!system 216 在连锁%d发动
!system 217 被连锁%d的[%ls]选择为对象
!system 218 是否使用[%ls]的效果代替支付基本分?
!system 219 是否使用[%ls]的效果代替取除超量素材?
!system 220 是否使用[%ls]的效果代替取除指示物?
!system 221 是否在[%ls]发动[%ls]的诱发效果?
!system 222 是否要发动诱发效果?
!system 223 稍后将询问其他可以发动的效果。
!system 224 已用正规方法特殊召唤
!system 500 请选择要解放的卡
!system 501 请选择要丢弃的手卡
!system 502 请选择要破坏的卡
......@@ -386,11 +393,14 @@
!system 1363 是否删除这个录像?
!system 1364 重命名录像
!system 1365 重命名失败,可能存在同名文件
!system 1366 自动保存录像
!system 1367 录像已自动保存为%ls.yrp
!system 1370 星数↑
!system 1371 攻击↑
!system 1372 守备↑
!system 1373 名称↓
!system 1374 连接标记
!system 1378 使用多个关键词搜索卡片
!system 1380 人机模式
!system 1381 残局模式
!system 1382 人机信息:
......@@ -923,3 +933,4 @@
!setname 0x121 魔妖
!setname 0x122 女武神 Valkyrie
!setname 0x123 蔷薇龙 ローズ・ドラゴン
!setname 0x124 机械天使 機械天使
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