Commit 10953b43 authored by mercury233's avatar mercury233

Merge branch 'fh' into Select_Unselect

parents dd22dfdb 96442947
...@@ -39,9 +39,9 @@ struct CardDataC { ...@@ -39,9 +39,9 @@ struct CardDataC {
unsigned int category; unsigned int category;
}; };
struct CardString { struct CardString {
wchar_t* name; std::wstring name;
wchar_t* text; std::wstring text;
wchar_t* desc[16]; std::wstring desc[16];
}; };
typedef std::unordered_map<unsigned int, CardDataC>::const_iterator code_pointer; typedef std::unordered_map<unsigned int, CardDataC>::const_iterator code_pointer;
......
...@@ -203,8 +203,21 @@ void ClientField::AddCard(ClientCard* pcard, int controler, int location, int se ...@@ -203,8 +203,21 @@ void ClientField::AddCard(ClientCard* pcard, int controler, int location, int se
break; break;
} }
case LOCATION_EXTRA: { case LOCATION_EXTRA: {
if(extra_p_count[controler] == 0 || (pcard->position & POS_FACEUP)) {
extra[controler].push_back(pcard); extra[controler].push_back(pcard);
pcard->sequence = extra[controler].size() - 1; pcard->sequence = extra[controler].size() - 1;
} else {
extra[controler].push_back(0);
int p = extra[controler].size() - extra_p_count[controler] - 1;
for(int i = extra[controler].size() - 1; i > p; --i) {
extra[controler][i] = extra[controler][i - 1];
extra[controler][i]->sequence++;
extra[controler][i]->curPos += irr::core::vector3df(0, 0, 0.01f);
extra[controler][i]->mTransform.setTranslation(extra[controler][i]->curPos);
}
extra[controler][p] = pcard;
pcard->sequence = p;
}
if (pcard->position & POS_FACEUP) if (pcard->position & POS_FACEUP)
extra_p_count[controler]++; extra_p_count[controler]++;
break; break;
...@@ -340,6 +353,7 @@ void ClientField::ClearCommandFlag() { ...@@ -340,6 +353,7 @@ void ClientField::ClearCommandFlag() {
(*cit)->cmdFlag = 0; (*cit)->cmdFlag = 0;
for(cit = attackable_cards.begin(); cit != attackable_cards.end(); ++cit) for(cit = attackable_cards.begin(); cit != attackable_cards.end(); ++cit)
(*cit)->cmdFlag = 0; (*cit)->cmdFlag = 0;
conti_cards.clear();
deck_act = false; deck_act = false;
extra_act = false; extra_act = false;
grave_act = false; grave_act = false;
...@@ -635,11 +649,11 @@ void ClientField::ReplaySwap() { ...@@ -635,11 +649,11 @@ void ClientField::ReplaySwap() {
(*cit)->is_moving = false; (*cit)->is_moving = false;
} }
mainGame->dInfo.isFirst = !mainGame->dInfo.isFirst; mainGame->dInfo.isFirst = !mainGame->dInfo.isFirst;
mainGame->dInfo.isReplaySwapped = !mainGame->dInfo.isReplaySwapped;
std::swap(mainGame->dInfo.lp[0], mainGame->dInfo.lp[1]); std::swap(mainGame->dInfo.lp[0], mainGame->dInfo.lp[1]);
for(int i = 0; i < 16; ++i) std::swap(mainGame->dInfo.strLP[0], mainGame->dInfo.strLP[1]);
std::swap(mainGame->dInfo.strLP[0][i], mainGame->dInfo.strLP[1][i]); std::swap(mainGame->dInfo.hostname, mainGame->dInfo.clientname);
for(int i = 0; i < 20; ++i) std::swap(mainGame->dInfo.hostname_tag, mainGame->dInfo.clientname_tag);
std::swap(mainGame->dInfo.hostname[i], mainGame->dInfo.clientname[i]);
for(auto chit = chains.begin(); chit != chains.end(); ++chit) { for(auto chit = chains.begin(); chit != chains.end(); ++chit) {
chit->controler = 1 - chit->controler; chit->controler = 1 - chit->controler;
GetChainLocation(chit->controler, chit->location, chit->sequence, &chit->chain_pos); GetChainLocation(chit->controler, chit->location, chit->sequence, &chit->chain_pos);
...@@ -1360,7 +1374,7 @@ void ClientField::UpdateDeclarableCodeType(bool enter) { ...@@ -1360,7 +1374,7 @@ void ClientField::UpdateDeclarableCodeType(bool enter) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) { if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
mainGame->lstANCard->addItem(cstr.name); mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(trycode); ancard.push_back(trycode);
return; return;
} }
...@@ -1369,15 +1383,15 @@ void ClientField::UpdateDeclarableCodeType(bool enter) { ...@@ -1369,15 +1383,15 @@ void ClientField::UpdateDeclarableCodeType(bool enter) {
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) { for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(wcsstr(cit->second.name, pname) != 0) { if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias //datas.alias can be double card names or alias
if(is_declarable(cp->second, declarable_type)) { if(is_declarable(cp->second, declarable_type)) {
if(wcscmp(pname, cit->second.name) == 0) { //exact match if(pname == cit->second.name) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name, -1); mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first); ancard.insert(ancard.begin(), cit->first);
} else { } else {
mainGame->lstANCard->addItem(cit->second.name); mainGame->lstANCard->addItem(cit->second.name.c_str());
ancard.push_back(cit->first); ancard.push_back(cit->first);
} }
} }
...@@ -1392,7 +1406,7 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) { ...@@ -1392,7 +1406,7 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) { if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) {
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
mainGame->lstANCard->addItem(cstr.name); mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(trycode); ancard.push_back(trycode);
return; return;
} }
...@@ -1401,15 +1415,15 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) { ...@@ -1401,15 +1415,15 @@ void ClientField::UpdateDeclarableCodeOpcode(bool enter) {
mainGame->lstANCard->clear(); mainGame->lstANCard->clear();
ancard.clear(); ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) { for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(wcsstr(cit->second.name, pname) != 0) { if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias //datas.alias can be double card names or alias
if(is_declarable(cp->second, opcode)) { if(is_declarable(cp->second, opcode)) {
if(wcscmp(pname, cit->second.name) == 0) { //exact match if(pname == cit->second.name) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name, -1); mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first); ancard.insert(ancard.begin(), cit->first);
} else { } else {
mainGame->lstANCard->addItem(cit->second.name); mainGame->lstANCard->addItem(cit->second.name.c_str());
ancard.push_back(cit->first); ancard.push_back(cit->first);
} }
} }
......
...@@ -137,6 +137,7 @@ public: ...@@ -137,6 +137,7 @@ public:
void ShowCancelOrFinishButton(int buttonOp); void ShowCancelOrFinishButton(int buttonOp);
void SetShowMark(ClientCard* pcard, bool enable); void SetShowMark(ClientCard* pcard, bool enable);
void SetResponseSelectedCards() const; void SetResponseSelectedCards() const;
void CancelOrFinish();
}; };
} }
......
...@@ -13,8 +13,12 @@ ...@@ -13,8 +13,12 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define myswprintf _swprintf #define myswprintf _swprintf
#define mywcsncasecmp _wcsnicmp
#define mystrncasecmp _strnicmp
#else #else
#define myswprintf swprintf #define myswprintf swprintf
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
#endif #endif
#define socklen_t int #define socklen_t int
...@@ -41,6 +45,8 @@ ...@@ -41,6 +45,8 @@
#include <wchar.h> #include <wchar.h>
#define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__) #define myswprintf(buf, fmt, ...) swprintf(buf, 4096, fmt, ##__VA_ARGS__)
#define mywcsncasecmp wcsncasecmp
#define mystrncasecmp strncasecmp
inline int _wtoi(const wchar_t * s) { inline int _wtoi(const wchar_t * s) {
wchar_t * endptr; wchar_t * endptr;
return (int)wcstol(s, &endptr, 10); return (int)wcstol(s, &endptr, 10);
...@@ -76,5 +82,6 @@ extern int enable_log; ...@@ -76,5 +82,6 @@ extern int enable_log;
extern bool exit_on_return; extern bool exit_on_return;
extern bool open_file; extern bool open_file;
extern wchar_t open_file_name[256]; extern wchar_t open_file_name[256];
extern bool bot_mode;
#endif #endif
...@@ -17,8 +17,7 @@ bool DataManager::LoadDB(const char* file) { ...@@ -17,8 +17,7 @@ bool DataManager::LoadDB(const char* file) {
return Error(pDB); return Error(pDB);
CardDataC cd; CardDataC cd;
CardString cs; CardString cs;
for(int i = 0; i < 16; ++i) cs.desc[i] = 0; int step = 0;
int step = 0, len = 0;
do { do {
step = sqlite3_step(pStmt); step = sqlite3_step(pStmt);
if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE) if(step == SQLITE_BUSY || step == SQLITE_ERROR || step == SQLITE_MISUSE)
...@@ -44,27 +43,21 @@ bool DataManager::LoadDB(const char* file) { ...@@ -44,27 +43,21 @@ bool DataManager::LoadDB(const char* file) {
cd.attribute = sqlite3_column_int(pStmt, 9); cd.attribute = sqlite3_column_int(pStmt, 9);
cd.category = sqlite3_column_int(pStmt, 10); cd.category = sqlite3_column_int(pStmt, 10);
_datas.insert(std::make_pair(cd.code, cd)); _datas.insert(std::make_pair(cd.code, cd));
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, 12), strBuffer); if(const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
if(len) { BufferIO::DecodeUTF8(text, strBuffer);
cs.name = new wchar_t[len + 1]; cs.name = strBuffer;
memcpy(cs.name, strBuffer, (len + 1)*sizeof(wchar_t));
} else cs.name = 0;
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, 13), strBuffer);
if(len) {
cs.text = new wchar_t[len + 1];
memcpy(cs.text, strBuffer, (len + 1)*sizeof(wchar_t));
} else {
cs.text = new wchar_t[1];
cs.text[0] = 0;
} }
for(int i = 14; i < 30; ++i) { if(const char* text = (const char*)sqlite3_column_text(pStmt, 13)) {
len = BufferIO::DecodeUTF8((const char*)sqlite3_column_text(pStmt, i), strBuffer); BufferIO::DecodeUTF8(text, strBuffer);
if(len) { cs.text = strBuffer;
cs.desc[i - 14] = new wchar_t[len + 1];
memcpy(cs.desc[i - 14], strBuffer, (len + 1)*sizeof(wchar_t));
} else cs.desc[i - 14] = 0;
} }
_strings.insert(std::make_pair(cd.code, cs)); for(int i = 0; i < 16; ++i) {
if(const char* text = (const char*)sqlite3_column_text(pStmt, i + 14)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.desc[i] = strBuffer;
}
}
_strings.emplace(cd.code, cs);
} }
} while(step != SQLITE_DONE); } while(step != SQLITE_DONE);
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
...@@ -126,8 +119,8 @@ code_pointer DataManager::GetCodePointer(int code) { ...@@ -126,8 +119,8 @@ code_pointer DataManager::GetCodePointer(int code) {
bool DataManager::GetString(int code, CardString* pStr) { bool DataManager::GetString(int code, CardString* pStr) {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) { if(csit == _strings.end()) {
pStr->name = (wchar_t*)unknown_string; pStr->name = unknown_string;
pStr->text = (wchar_t*)unknown_string; pStr->text = unknown_string;
return false; return false;
} }
*pStr = csit->second; *pStr = csit->second;
...@@ -137,16 +130,16 @@ const wchar_t* DataManager::GetName(int code) { ...@@ -137,16 +130,16 @@ const wchar_t* DataManager::GetName(int code) {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) if(csit == _strings.end())
return unknown_string; return unknown_string;
if(csit->second.name) if(!csit->second.name.empty())
return csit->second.name; return csit->second.name.c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetText(int code) { const wchar_t* DataManager::GetText(int code) {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) if(csit == _strings.end())
return unknown_string; return unknown_string;
if(csit->second.text) if(!csit->second.text.empty())
return csit->second.text; return csit->second.text.c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetDesc(int strCode) { const wchar_t* DataManager::GetDesc(int strCode) {
...@@ -157,8 +150,8 @@ const wchar_t* DataManager::GetDesc(int strCode) { ...@@ -157,8 +150,8 @@ const wchar_t* DataManager::GetDesc(int strCode) {
auto csit = _strings.find(code); auto csit = _strings.find(code);
if(csit == _strings.end()) if(csit == _strings.end())
return unknown_string; return unknown_string;
if(csit->second.desc[offset]) if(!csit->second.desc[offset].empty())
return csit->second.desc[offset]; return csit->second.desc[offset].c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetSysString(int code) { const wchar_t* DataManager::GetSysString(int code) {
......
...@@ -69,6 +69,9 @@ void DeckBuilder::Initialize() { ...@@ -69,6 +69,9 @@ void DeckBuilder::Initialize() {
mainGame->btnLeaveGame->setVisible(true); mainGame->btnLeaveGame->setVisible(true);
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1306)); mainGame->btnLeaveGame->setText(dataManager.GetSysString(1306));
mainGame->btnSideOK->setVisible(false); mainGame->btnSideOK->setVisible(false);
mainGame->btnSideShuffle->setVisible(false);
mainGame->btnSideSort->setVisible(false);
mainGame->btnSideReload->setVisible(false);
filterList = deckManager._lfList[0].content; filterList = deckManager._lfList[0].content;
mainGame->cbDBLFList->setSelected(0); mainGame->cbDBLFList->setSelected(0);
ClearSearch(); ClearSearch();
...@@ -81,6 +84,7 @@ void DeckBuilder::Initialize() { ...@@ -81,6 +84,7 @@ void DeckBuilder::Initialize() {
is_starting_dragging = false; is_starting_dragging = false;
prev_deck = mainGame->cbDBDecks->getSelected(); prev_deck = mainGame->cbDBDecks->getSelected();
prev_operation = 0; prev_operation = 0;
prev_sel = -1;
is_modified = false; is_modified = false;
mainGame->device->setEventReceiver(this); mainGame->device->setEventReceiver(this);
} }
...@@ -181,6 +185,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -181,6 +185,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->PopupElement(mainGame->wQuery); mainGame->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
prev_operation = id; prev_operation = id;
prev_sel = sel;
break; break;
} }
case BUTTON_LEAVE_GAME: { case BUTTON_LEAVE_GAME: {
...@@ -215,6 +220,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -215,6 +220,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
for(int i = 0; i < 32; ++i, filter <<= 1) for(int i = 0; i < 32; ++i, filter <<= 1)
if(mainGame->chkCategory[i]->isChecked()) if(mainGame->chkCategory[i]->isChecked())
filter_effect |= filter; filter_effect |= filter;
mainGame->btnEffectFilter->setPressed(filter_effect > 0);
mainGame->HideElement(mainGame->wCategories); mainGame->HideElement(mainGame->wCategories);
InstantSearch(); InstantSearch();
break; break;
...@@ -239,6 +245,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -239,6 +245,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf); DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf);
break; break;
} }
case BUTTON_SIDE_RELOAD: {
deckManager.LoadDeck(mainGame->cbDeckSelect->getItem(mainGame->cbDeckSelect->getSelected()));
break;
}
case BUTTON_MSG_OK: { case BUTTON_MSG_OK: {
mainGame->HideElement(mainGame->wMessage); mainGame->HideElement(mainGame->wMessage);
mainGame->actionSignal.Set(); mainGame->actionSignal.Set();
...@@ -253,7 +263,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -253,7 +263,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
deckManager.current_deck.extra.clear(); deckManager.current_deck.extra.clear();
deckManager.current_deck.side.clear(); deckManager.current_deck.side.clear();
} else if(prev_operation == BUTTON_DELETE_DECK) { } else if(prev_operation == BUTTON_DELETE_DECK) {
int sel = mainGame->cbDBDecks->getSelected(); int sel = prev_sel;
if(deckManager.DeleteDeck(deckManager.current_deck, mainGame->cbDBDecks->getItem(sel))) { if(deckManager.DeleteDeck(deckManager.current_deck, mainGame->cbDBDecks->getItem(sel))) {
mainGame->cbDBDecks->removeItem(sel); mainGame->cbDBDecks->removeItem(sel);
int count = mainGame->cbDBDecks->getItemCount(); int count = mainGame->cbDBDecks->getItemCount();
...@@ -267,6 +277,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -267,6 +277,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
prev_deck = sel; prev_deck = sel;
is_modified = false; is_modified = false;
} }
prev_sel = -1;
} else if(prev_operation == BUTTON_LEAVE_GAME) { } else if(prev_operation == BUTTON_LEAVE_GAME) {
Terminate(); Terminate();
} else if(prev_operation == COMBOBOX_DBDECKS) { } else if(prev_operation == COMBOBOX_DBDECKS) {
...@@ -309,6 +320,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -309,6 +320,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if (mainGame->btnMark[7]->isPressed()) if (mainGame->btnMark[7]->isPressed())
filter_marks |= 0004; filter_marks |= 0004;
mainGame->HideElement(mainGame->wLinkMarks); mainGame->HideElement(mainGame->wLinkMarks);
mainGame->btnMarksFilter->setPressed(filter_marks > 0);
InstantSearch(); InstantSearch();
break; break;
} }
...@@ -625,6 +637,11 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -625,6 +637,11 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case irr::EMIE_MOUSE_WHEEL: { case irr::EMIE_MOUSE_WHEEL: {
if(!mainGame->scrFilter->isVisible()) if(!mainGame->scrFilter->isVisible())
break; break;
if(mainGame->env->hasFocus(mainGame->scrFilter))
break;
irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement();
if(root->getElementFromPoint(mouse_pos) != root)
break;
if(event.MouseInput.Wheel < 0) { if(event.MouseInput.Wheel < 0) {
if(mainGame->scrFilter->getPos() < mainGame->scrFilter->getMax()) if(mainGame->scrFilter->getPos() < mainGame->scrFilter->getMax())
mainGame->scrFilter->setPos(mainGame->scrFilter->getPos() + 1); mainGame->scrFilter->setPos(mainGame->scrFilter->getPos() + 1);
...@@ -838,12 +855,12 @@ void DeckBuilder::FilterCards() { ...@@ -838,12 +855,12 @@ void DeckBuilder::FilterCards() {
} }
if(pstr) { if(pstr) {
if(pstr[0] == L'$') { if(pstr[0] == L'$') {
if(!CardNameContains(text.name, &pstr[1])) if(!CardNameContains(text.name.c_str(), &pstr[1]))
continue; continue;
} else if(pstr[0] == L'@' && set_code) { } else if(pstr[0] == L'@' && set_code) {
if(!check_set_code(data, set_code)) continue; if(!check_set_code(data, set_code)) continue;
} else { } else {
if(!CardNameContains(text.name, pstr) && wcsstr(text.text, pstr) == 0 if(!CardNameContains(text.name.c_str(), pstr) && text.text.find(pstr) == std::wstring::npos
&& (!set_code || !check_set_code(data, set_code))) && (!set_code || !check_set_code(data, set_code)))
continue; continue;
} }
...@@ -894,6 +911,8 @@ void DeckBuilder::ClearFilter() { ...@@ -894,6 +911,8 @@ void DeckBuilder::ClearFilter() {
filter_marks = 0; filter_marks = 0;
for(int i = 0; i < 8; i++) for(int i = 0; i < 8; i++)
mainGame->btnMark[i]->setPressed(false); mainGame->btnMark[i]->setPressed(false);
mainGame->btnEffectFilter->setPressed(false);
mainGame->btnMarksFilter->setPressed(false);
} }
void DeckBuilder::SortList() { void DeckBuilder::SortList() {
auto left = results.begin(); auto left = results.begin();
......
...@@ -62,6 +62,7 @@ public: ...@@ -62,6 +62,7 @@ public:
code_pointer draging_pointer; code_pointer draging_pointer;
int prev_deck; int prev_deck;
s32 prev_operation; s32 prev_operation;
int prev_sel;
bool is_modified; bool is_modified;
std::unordered_map<int, int>* filterList; std::unordered_map<int, int>* filterList;
......
#include "deck_manager.h" #include "deck_manager.h"
#include "data_manager.h" #include "data_manager.h"
#include "network.h"
#include "game.h" #include "game.h"
#include <algorithm> #include <algorithm>
...@@ -61,7 +62,7 @@ wchar_t* DeckManager::GetLFListName(int lfhash) { ...@@ -61,7 +62,7 @@ wchar_t* DeckManager::GetLFListName(int lfhash) {
} }
return (wchar_t*)dataManager.unknown_string; return (wchar_t*)dataManager.unknown_string;
} }
int DeckManager::CheckLFList(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg) { int DeckManager::CheckDeck(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg) {
std::unordered_map<int, int> ccount; std::unordered_map<int, int> ccount;
std::unordered_map<int, int>* list = 0; std::unordered_map<int, int>* list = 0;
for(size_t i = 0; i < _lfList.size(); ++i) { for(size_t i = 0; i < _lfList.size(); ++i) {
...@@ -73,53 +74,73 @@ int DeckManager::CheckLFList(Deck& deck, int lfhash, bool allow_ocg, bool allow_ ...@@ -73,53 +74,73 @@ int DeckManager::CheckLFList(Deck& deck, int lfhash, bool allow_ocg, bool allow_
if(!list) if(!list)
return 0; return 0;
int dc = 0; int dc = 0;
if(deck.main.size() < 40 || deck.main.size() > 60 || deck.extra.size() > 15 || deck.side.size() > 15) if(deck.main.size() < 40 || deck.main.size() > 60)
return 1; return (DECKERROR_MAINCOUNT << 28) + deck.main.size();
if(deck.extra.size() > 15)
return (DECKERROR_EXTRACOUNT << 28) + deck.extra.size();
if(deck.side.size() > 15)
return (DECKERROR_SIDECOUNT << 28) + deck.side.size();
for(size_t i = 0; i < deck.main.size(); ++i) { for(size_t i = 0; i < deck.main.size(); ++i) {
code_pointer cit = deck.main[i]; code_pointer cit = deck.main[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2))) if(!allow_ocg && (cit->second.ot == 0x1))
return cit->first; return (DECKERROR_OCGONLY << 28) + cit->first;
if(!allow_tcg && (cit->second.ot == 0x2))
return (DECKERROR_TCGONLY << 28) + cit->first;
if(cit->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_TOKEN | TYPE_LINK)) if(cit->second.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_TOKEN | TYPE_LINK))
return 1; return (DECKERROR_EXTRACOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code); auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second)) if(it != list->end() && dc > it->second)
return cit->first; return (DECKERROR_LFLIST << 28) + cit->first;
} }
for(size_t i = 0; i < deck.extra.size(); ++i) { for(size_t i = 0; i < deck.extra.size(); ++i) {
code_pointer cit = deck.extra[i]; code_pointer cit = deck.extra[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2))) if(!allow_ocg && (cit->second.ot == 0x1))
return cit->first; return (DECKERROR_OCGONLY << 28) + cit->first;
if(!allow_tcg && (cit->second.ot == 0x2))
return (DECKERROR_TCGONLY << 28) + cit->first;
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code); auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second)) if(it != list->end() && dc > it->second)
return cit->first; return (DECKERROR_LFLIST << 28) + cit->first;
} }
for(size_t i = 0; i < deck.side.size(); ++i) { for(size_t i = 0; i < deck.side.size(); ++i) {
code_pointer cit = deck.side[i]; code_pointer cit = deck.side[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2))) if(!allow_ocg && (cit->second.ot == 0x1))
return cit->first; return (DECKERROR_OCGONLY << 28) + cit->first;
if(!allow_tcg && (cit->second.ot == 0x2))
return (DECKERROR_TCGONLY << 28) + cit->first;
int code = cit->second.alias ? cit->second.alias : cit->first; int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++; ccount[code]++;
dc = ccount[code]; dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code); auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second)) if(it != list->end() && dc > it->second)
return cit->first; return (DECKERROR_LFLIST << 28) + cit->first;
} }
return 0; return 0;
} }
void DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec) { int DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec) {
deck.clear(); deck.clear();
int code; int code;
int errorcode = 0;
CardData cd; CardData cd;
for(int i = 0; i < mainc; ++i) { for(int i = 0; i < mainc; ++i) {
code = dbuf[i]; code = dbuf[i];
if(!dataManager.GetData(code, &cd)) if(!dataManager.GetData(code, &cd)) {
errorcode = code;
continue; continue;
}
if(cd.type & TYPE_TOKEN) if(cd.type & TYPE_TOKEN)
continue; continue;
else if(cd.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK) && deck.extra.size() < 15) { else if(cd.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK) && deck.extra.size() < 15) {
...@@ -130,13 +151,16 @@ void DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec) { ...@@ -130,13 +151,16 @@ void DeckManager::LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec) {
} }
for(int i = 0; i < sidec; ++i) { for(int i = 0; i < sidec; ++i) {
code = dbuf[mainc + i]; code = dbuf[mainc + i];
if(!dataManager.GetData(code, &cd)) if(!dataManager.GetData(code, &cd)) {
errorcode = code;
continue; continue;
}
if(cd.type & TYPE_TOKEN) if(cd.type & TYPE_TOKEN)
continue; continue;
if(deck.side.size() < 15) if(deck.side.size() < 15)
deck.side.push_back(dataManager.GetCodePointer(code)); //verified by GetData() deck.side.push_back(dataManager.GetCodePointer(code)); //verified by GetData()
} }
return errorcode;
} }
bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) { bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) {
std::unordered_map<int, int> pcount; std::unordered_map<int, int> pcount;
......
...@@ -37,8 +37,8 @@ public: ...@@ -37,8 +37,8 @@ public:
void LoadLFList(); void LoadLFList();
wchar_t* GetLFListName(int lfhash); wchar_t* GetLFListName(int lfhash);
int CheckLFList(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg); int CheckDeck(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg);
void LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec); int LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec);
bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec); bool LoadSide(Deck& deck, int* dbuf, int mainc, int sidec);
FILE* OpenDeckFile(const wchar_t * file, const char * mode); FILE* OpenDeckFile(const wchar_t * file, const char * mode);
bool LoadDeck(const wchar_t* file); bool LoadDeck(const wchar_t* file);
......
...@@ -1045,7 +1045,16 @@ void Game::DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, i ...@@ -1045,7 +1045,16 @@ void Game::DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, i
break; break;
} }
} }
if(mainGame->cbLimit->getSelected() >= 4) { if(mainGame->cbLimit->getSelected() >= 4 && (cp->second.ot & mainGame->gameConf.defaultOT)) {
switch(cp->second.ot) {
case 1:
driver->draw2DImage(imageManager.tOT, recti(pos.X + 7, pos.Y + 50, pos.X + 37, pos.Y + 65), recti(0, 128, 128, 192), 0, 0, true);
break;
case 2:
driver->draw2DImage(imageManager.tOT, recti(pos.X + 7, pos.Y + 50, pos.X + 37, pos.Y + 65), recti(0, 192, 128, 256), 0, 0, true);
break;
}
} else if(mainGame->cbLimit->getSelected() >= 4 || !(cp->second.ot & mainGame->gameConf.defaultOT)) {
switch(cp->second.ot) { switch(cp->second.ot) {
case 1: case 1:
driver->draw2DImage(imageManager.tOT, recti(pos.X + 7, pos.Y + 50, pos.X + 37, pos.Y + 65), recti(0, 0, 128, 64), 0, 0, true); driver->draw2DImage(imageManager.tOT, recti(pos.X + 7, pos.Y + 50, pos.X + 37, pos.Y + 65), recti(0, 0, 128, 64), 0, 0, true);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -40,6 +40,8 @@ struct Config { ...@@ -40,6 +40,8 @@ struct Config {
int separate_clear_button; int separate_clear_button;
int auto_search_limit; int auto_search_limit;
int chkIgnoreDeckChanges; int chkIgnoreDeckChanges;
int defaultOT;
int enable_bot_mode;
}; };
struct DuelInfo { struct DuelInfo {
...@@ -65,6 +67,15 @@ struct DuelInfo { ...@@ -65,6 +67,15 @@ struct DuelInfo {
unsigned char time_player; unsigned char time_player;
unsigned short time_limit; unsigned short time_limit;
unsigned short time_left[2]; unsigned short time_left[2];
bool isReplaySwapped;
};
struct BotInfo {
wchar_t name[256];
wchar_t command[256];
wchar_t desc[256];
bool support_master_rule_3;
bool support_new_master_rule;
}; };
struct FadingUnit { struct FadingUnit {
...@@ -91,6 +102,7 @@ public: ...@@ -91,6 +102,7 @@ public:
void RefreshDeck(irr::gui::IGUIComboBox* cbDeck); void RefreshDeck(irr::gui::IGUIComboBox* cbDeck);
void RefreshReplay(); void RefreshReplay();
void RefreshSingleplay(); void RefreshSingleplay();
void RefreshBot();
void DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, float* cv); void DrawSelectionLine(irr::video::S3DVertex* vec, bool strip, int width, float* cv);
void DrawBackGround(); void DrawBackGround();
void DrawLinkedZones(ClientCard* pcard); void DrawLinkedZones(ClientCard* pcard);
...@@ -126,6 +138,7 @@ public: ...@@ -126,6 +138,7 @@ public:
void SetWindowsIcon(); void SetWindowsIcon();
void FlashWindow(); void FlashWindow();
void SetCursor(ECURSOR_ICON icon);
Mutex gMutex; Mutex gMutex;
Mutex gBuffer; Mutex gBuffer;
...@@ -141,6 +154,7 @@ public: ...@@ -141,6 +154,7 @@ public:
std::list<FadingUnit> fadingList; std::list<FadingUnit> fadingList;
std::vector<int> logParam; std::vector<int> logParam;
std::wstring chatMsg[8]; std::wstring chatMsg[8];
std::vector<BotInfo> botInfo;
int hideChatTimer; int hideChatTimer;
bool hideChat; bool hideChat;
...@@ -221,7 +235,7 @@ public: ...@@ -221,7 +235,7 @@ public:
//main menu //main menu
irr::gui::IGUIWindow* wMainMenu; irr::gui::IGUIWindow* wMainMenu;
irr::gui::IGUIButton* btnLanMode; irr::gui::IGUIButton* btnLanMode;
irr::gui::IGUIButton* btnServerMode; irr::gui::IGUIButton* btnSingleMode;
irr::gui::IGUIButton* btnReplayMode; irr::gui::IGUIButton* btnReplayMode;
irr::gui::IGUIButton* btnTestMode; irr::gui::IGUIButton* btnTestMode;
irr::gui::IGUIButton* btnDeckEdit; irr::gui::IGUIButton* btnDeckEdit;
...@@ -272,10 +286,20 @@ public: ...@@ -272,10 +286,20 @@ public:
irr::gui::IGUIListBox* lstReplayList; irr::gui::IGUIListBox* lstReplayList;
irr::gui::IGUIStaticText* stReplayInfo; irr::gui::IGUIStaticText* stReplayInfo;
irr::gui::IGUIButton* btnLoadReplay; irr::gui::IGUIButton* btnLoadReplay;
irr::gui::IGUIButton* btnDeleteReplay;
irr::gui::IGUIButton* btnRenameReplay;
irr::gui::IGUIButton* btnReplayCancel; irr::gui::IGUIButton* btnReplayCancel;
irr::gui::IGUIEditBox* ebRepStartTurn; irr::gui::IGUIEditBox* ebRepStartTurn;
//single play //single play
irr::gui::IGUIWindow* wSinglePlay; irr::gui::IGUIWindow* wSinglePlay;
irr::gui::IGUIListBox* lstBotList;
irr::gui::IGUIStaticText* stBotInfo;
irr::gui::IGUIButton* btnStartBot;
irr::gui::IGUIButton* btnBotCancel;
irr::gui::IGUICheckBox* chkBotOldRule;
irr::gui::IGUICheckBox* chkBotHand;
irr::gui::IGUICheckBox* chkBotNoCheckDeck;
irr::gui::IGUICheckBox* chkBotNoShuffleDeck;
irr::gui::IGUIListBox* lstSinglePlayList; irr::gui::IGUIListBox* lstSinglePlayList;
irr::gui::IGUIStaticText* stSinglePlayInfo; irr::gui::IGUIStaticText* stSinglePlayInfo;
irr::gui::IGUIButton* btnLoadSinglePlay; irr::gui::IGUIButton* btnLoadSinglePlay;
...@@ -374,6 +398,9 @@ public: ...@@ -374,6 +398,9 @@ public:
irr::gui::IGUIButton* btnDeleteDeck; irr::gui::IGUIButton* btnDeleteDeck;
irr::gui::IGUIButton* btnSaveDeckAs; irr::gui::IGUIButton* btnSaveDeckAs;
irr::gui::IGUIButton* btnSideOK; irr::gui::IGUIButton* btnSideOK;
irr::gui::IGUIButton* btnSideShuffle;
irr::gui::IGUIButton* btnSideSort;
irr::gui::IGUIButton* btnSideReload;
irr::gui::IGUIEditBox* ebDeckname; irr::gui::IGUIEditBox* ebDeckname;
//filter //filter
irr::gui::IGUIStaticText* wFilter; irr::gui::IGUIStaticText* wFilter;
...@@ -475,6 +502,8 @@ extern Game* mainGame; ...@@ -475,6 +502,8 @@ extern Game* mainGame;
#define LISTBOX_REPLAY_LIST 130 #define LISTBOX_REPLAY_LIST 130
#define BUTTON_LOAD_REPLAY 131 #define BUTTON_LOAD_REPLAY 131
#define BUTTON_CANCEL_REPLAY 132 #define BUTTON_CANCEL_REPLAY 132
#define BUTTON_DELETE_REPLAY 133
#define BUTTON_RENAME_REPLAY 134
#define EDITBOX_CHAT 140 #define EDITBOX_CHAT 140
#define BUTTON_MSG_OK 200 #define BUTTON_MSG_OK 200
#define BUTTON_YES 201 #define BUTTON_YES 201
...@@ -540,7 +569,7 @@ extern Game* mainGame; ...@@ -540,7 +569,7 @@ extern Game* mainGame;
#define BUTTON_SAVE_DECK 304 #define BUTTON_SAVE_DECK 304
#define BUTTON_SAVE_DECK_AS 305 #define BUTTON_SAVE_DECK_AS 305
#define BUTTON_DELETE_DECK 306 #define BUTTON_DELETE_DECK 306
//#define BUTTON_DBEXIT 307 #define BUTTON_SIDE_RELOAD 307
#define BUTTON_SORT_DECK 308 #define BUTTON_SORT_DECK 308
#define BUTTON_SIDE_OK 309 #define BUTTON_SIDE_OK 309
#define BUTTON_SHUFFLE_DECK 310 #define BUTTON_SHUFFLE_DECK 310
...@@ -561,6 +590,9 @@ extern Game* mainGame; ...@@ -561,6 +590,9 @@ extern Game* mainGame;
#define BUTTON_REPLAY_SWAP 325 #define BUTTON_REPLAY_SWAP 325
#define BUTTON_REPLAY_SAVE 330 #define BUTTON_REPLAY_SAVE 330
#define BUTTON_REPLAY_CANCEL 331 #define BUTTON_REPLAY_CANCEL 331
#define BUTTON_BOT_START 340
#define LISTBOX_BOT_LIST 341
#define CHECKBOX_BOT_OLD_RULE 342
#define LISTBOX_SINGLEPLAY_LIST 350 #define LISTBOX_SINGLEPLAY_LIST 350
#define BUTTON_LOAD_SINGLEPLAY 351 #define BUTTON_LOAD_SINGLEPLAY 351
#define BUTTON_CANCEL_SINGLEPLAY 352 #define BUTTON_CANCEL_SINGLEPLAY 352
......
...@@ -10,6 +10,7 @@ int enable_log = 0; ...@@ -10,6 +10,7 @@ int enable_log = 0;
bool exit_on_return = false; bool exit_on_return = false;
bool open_file = false; bool open_file = false;
wchar_t open_file_name[256] = L""; wchar_t open_file_name[256] = L"";
bool bot_mode = false;
void GetParameter(char* param, const char* arg) { void GetParameter(char* param, const char* arg) {
#ifdef _WIN32 #ifdef _WIN32
...@@ -77,6 +78,7 @@ int main(int argc, char* argv[]) { ...@@ -77,6 +78,7 @@ int main(int argc, char* argv[]) {
char param[128]; char param[128];
GetParameter(param, &argv[i][2]); GetParameter(param, &argv[i][2]);
ygo::dataManager.LoadDB(param); ygo::dataManager.LoadDB(param);
continue;
} }
if(!strcmp(argv[i], "-e")) { // extra database if(!strcmp(argv[i], "-e")) { // extra database
++i; ++i;
...@@ -151,10 +153,27 @@ int main(int argc, char* argv[]) { ...@@ -151,10 +153,27 @@ int main(int argc, char* argv[]) {
open_file = true; open_file = true;
GetParameterW(open_file_name, &argv[i + 1][0]); GetParameterW(open_file_name, &argv[i + 1][0]);
} }
ClickButton(ygo::mainGame->btnServerMode); ClickButton(ygo::mainGame->btnSingleMode);
if(open_file) if(open_file)
ClickButton(ygo::mainGame->btnLoadSinglePlay); ClickButton(ygo::mainGame->btnLoadSinglePlay);
break; break;
} else if(argc == 2 && strlen(argv[1]) >= 4) {
char* pstrext = argv[1] + strlen(argv[1]) - 4;
if(!mystrncasecmp(pstrext, ".ydk", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnDeckEdit);
break;
}
if(!mystrncasecmp(pstrext, ".yrp", 4)) {
open_file = true;
GetParameterW(open_file_name, &argv[1][0]);
exit_on_return = !keep_on_return;
ClickButton(ygo::mainGame->btnReplayMode);
ClickButton(ygo::mainGame->btnLoadReplay);
break;
}
} }
} }
ygo::mainGame->MainLoop(); ygo::mainGame->MainLoop();
......
...@@ -30,7 +30,25 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -30,7 +30,25 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
case irr::EET_GUI_EVENT: { case irr::EET_GUI_EVENT: {
irr::gui::IGUIElement* caller = event.GUIEvent.Caller; irr::gui::IGUIElement* caller = event.GUIEvent.Caller;
s32 id = caller->getID(); s32 id = caller->getID();
if(mainGame->wQuery->isVisible() && id != BUTTON_YES && id != BUTTON_NO) {
mainGame->wQuery->getParent()->bringToFront(mainGame->wQuery);
break;
}
if(mainGame->wReplaySave->isVisible() && id != BUTTON_REPLAY_SAVE && id != BUTTON_REPLAY_CANCEL) {
mainGame->wReplaySave->getParent()->bringToFront(mainGame->wReplaySave);
break;
}
switch(event.GUIEvent.EventType) { switch(event.GUIEvent.EventType) {
case irr::gui::EGET_ELEMENT_HOVERED: {
if(event.GUIEvent.Caller->getType() == EGUIET_EDIT_BOX)
mainGame->SetCursor(event.GUIEvent.Caller->isEnabled() ? ECI_IBEAM : ECI_NORMAL);
break;
}
case irr::gui::EGET_ELEMENT_LEFT: {
if(event.GUIEvent.Caller->getType() == EGUIET_EDIT_BOX)
mainGame->SetCursor(ECI_NORMAL);
break;
}
case irr::gui::EGET_BUTTON_CLICKED: { case irr::gui::EGET_BUTTON_CLICKED: {
switch(id) { switch(id) {
case BUTTON_MODE_EXIT: { case BUTTON_MODE_EXIT: {
...@@ -46,6 +64,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -46,6 +64,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
break; break;
} }
case BUTTON_JOIN_HOST: { case BUTTON_JOIN_HOST: {
bot_mode = false;
char ip[20]; char ip[20];
const wchar_t* pstr = mainGame->ebJoinHost->getText(); const wchar_t* pstr = mainGame->ebJoinHost->getText();
BufferIO::CopyWStr(pstr, ip, 16); BufferIO::CopyWStr(pstr, ip, 16);
...@@ -62,7 +81,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -62,7 +81,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP; hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = EVUTIL_AI_ADDRCONFIG; hints.ai_flags = EVUTIL_AI_ADDRCONFIG;
int status=evutil_getaddrinfo(hostname, port, &hints, &answer); int status = evutil_getaddrinfo(hostname, port, &hints, &answer);
if(status != 0) { if(status != 0) {
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1412)); mainGame->env->addMessageBox(L"", dataManager.GetSysString(1412));
...@@ -103,6 +122,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -103,6 +122,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
break; break;
} }
case BUTTON_HOST_CONFIRM: { case BUTTON_HOST_CONFIRM: {
bot_mode = false;
BufferIO::CopyWStr(mainGame->ebServerName->getText(), mainGame->gameConf.gamename, 20); BufferIO::CopyWStr(mainGame->ebServerName->getText(), mainGame->gameConf.gamename, 20);
if(!NetServer::StartServer(mainGame->gameConf.serverport)) if(!NetServer::StartServer(mainGame->gameConf.serverport))
break; break;
...@@ -167,7 +187,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -167,7 +187,12 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->btnCreateHost->setEnabled(true); mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true); mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true); mainGame->btnJoinCancel->setEnabled(true);
mainGame->btnStartBot->setEnabled(true);
mainGame->btnBotCancel->setEnabled(true);
mainGame->HideElement(mainGame->wHostPrepare); mainGame->HideElement(mainGame->wHostPrepare);
if(bot_mode)
mainGame->ShowElement(mainGame->wSinglePlay);
else
mainGame->ShowElement(mainGame->wLanWindow); mainGame->ShowElement(mainGame->wLanWindow);
mainGame->wChat->setVisible(false); mainGame->wChat->setVisible(false);
if(exit_on_return) if(exit_on_return)
...@@ -178,6 +203,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -178,6 +203,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->HideElement(mainGame->wMainMenu); mainGame->HideElement(mainGame->wMainMenu);
mainGame->ShowElement(mainGame->wReplay); mainGame->ShowElement(mainGame->wReplay);
mainGame->ebRepStartTurn->setText(L"1"); mainGame->ebRepStartTurn->setText(L"1");
mainGame->stReplayInfo->setText(L"");
mainGame->RefreshReplay(); mainGame->RefreshReplay();
break; break;
} }
...@@ -185,6 +211,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -185,6 +211,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->HideElement(mainGame->wMainMenu); mainGame->HideElement(mainGame->wMainMenu);
mainGame->ShowElement(mainGame->wSinglePlay); mainGame->ShowElement(mainGame->wSinglePlay);
mainGame->RefreshSingleplay(); mainGame->RefreshSingleplay();
mainGame->RefreshBot();
break; break;
} }
case BUTTON_LOAD_REPLAY: { case BUTTON_LOAD_REPLAY: {
...@@ -222,11 +249,90 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -222,11 +249,90 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
ReplayMode::StartReplay(start_turn); ReplayMode::StartReplay(start_turn);
break; break;
} }
case BUTTON_DELETE_REPLAY: {
int sel = mainGame->lstReplayList->getSelected();
if(sel == -1)
break;
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->PopupElement(mainGame->wQuery);
mainGame->gMutex.Unlock();
prev_operation = id;
prev_sel = sel;
break;
}
case BUTTON_RENAME_REPLAY: {
int sel = mainGame->lstReplayList->getSelected();
if(sel == -1)
break;
mainGame->gMutex.Lock();
mainGame->wReplaySave->setText(dataManager.GetSysString(1364));
mainGame->ebRSName->setText(mainGame->lstReplayList->getListItem(sel));
mainGame->PopupElement(mainGame->wReplaySave);
mainGame->gMutex.Unlock();
prev_operation = id;
prev_sel = sel;
break;
}
case BUTTON_CANCEL_REPLAY: { case BUTTON_CANCEL_REPLAY: {
mainGame->HideElement(mainGame->wReplay); mainGame->HideElement(mainGame->wReplay);
mainGame->ShowElement(mainGame->wMainMenu); mainGame->ShowElement(mainGame->wMainMenu);
break; break;
} }
case BUTTON_BOT_START: {
int sel = mainGame->lstBotList->getSelected();
if(sel == -1)
break;
bot_mode = true;
#ifdef _WIN32
if(!NetServer::StartServer(mainGame->gameConf.serverport))
break;
if(!DuelClient::StartClient(0x7f000001, mainGame->gameConf.serverport)) {
NetServer::StopServer();
break;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
wchar_t cmd[MAX_PATH];
int flag = 0;
flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0);
myswprintf(cmd, L"Bot.exe \"%ls\" %d %d", mainGame->botInfo[sel].command, flag, mainGame->gameConf.serverport);
if(!CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
NetServer::StopServer();
break;
}
#else
if(fork() == 0) {
usleep(100000);
char arg1[512];
BufferIO::EncodeUTF8(mainGame->botInfo[sel].command, arg1);
int flag = 0;
flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0);
char arg2[8];
sprintf(arg2, "%d", flag);
char arg3[8];
sprintf(arg3, "%d", mainGame->gameConf.serverport);
execl("./bot", "bot", arg1, arg2, arg3, NULL);
exit(0);
} else {
if(!NetServer::StartServer(mainGame->gameConf.serverport))
break;
if(!DuelClient::StartClient(0x7f000001, mainGame->gameConf.serverport)) {
NetServer::StopServer();
break;
}
}
#endif
mainGame->btnStartBot->setEnabled(false);
mainGame->btnBotCancel->setEnabled(false);
break;
}
case BUTTON_LOAD_SINGLEPLAY: { case BUTTON_LOAD_SINGLEPLAY: {
if(!open_file && mainGame->lstSinglePlayList->getSelected() == -1) if(!open_file && mainGame->lstSinglePlayList->getSelected() == -1)
break; break;
...@@ -271,6 +377,48 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -271,6 +377,48 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->deckBuilder.Initialize(); mainGame->deckBuilder.Initialize();
break; break;
} }
case BUTTON_YES: {
mainGame->HideElement(mainGame->wQuery);
if(prev_operation == BUTTON_DELETE_REPLAY) {
if(Replay::DeleteReplay(mainGame->lstReplayList->getListItem(prev_sel))) {
mainGame->stReplayInfo->setText(L"");
mainGame->lstReplayList->removeItem(prev_sel);
}
}
prev_operation = 0;
prev_sel = -1;
break;
}
case BUTTON_NO: {
mainGame->HideElement(mainGame->wQuery);
prev_operation = 0;
prev_sel = -1;
break;
}
case BUTTON_REPLAY_SAVE: {
mainGame->HideElement(mainGame->wReplaySave);
if(prev_operation == BUTTON_RENAME_REPLAY) {
wchar_t newname[256];
BufferIO::CopyWStr(mainGame->ebRSName->getText(), newname, 256);
if(mywcsncasecmp(newname + wcslen(newname) - 4, L".yrp", 4)) {
myswprintf(newname, L"%ls.yrp", mainGame->ebRSName->getText());
}
if(Replay::RenameReplay(mainGame->lstReplayList->getListItem(prev_sel), newname)) {
mainGame->lstReplayList->setItem(prev_sel, newname, -1);
} else {
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1365));
}
}
prev_operation = 0;
prev_sel = -1;
break;
}
case BUTTON_REPLAY_CANCEL: {
mainGame->HideElement(mainGame->wReplaySave);
prev_operation = 0;
prev_sel = -1;
break;
}
} }
break; break;
} }
...@@ -317,6 +465,13 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -317,6 +465,13 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, (wchar_t*)repinfo.c_str()); mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, (wchar_t*)repinfo.c_str());
break; break;
} }
case LISTBOX_BOT_LIST: {
int sel = mainGame->lstBotList->getSelected();
if(sel == -1)
break;
mainGame->SetStaticText(mainGame->stBotInfo, 200, mainGame->guiFont, mainGame->botInfo[sel].desc);
break;
}
} }
break; break;
} }
...@@ -341,6 +496,10 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -341,6 +496,10 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
} }
break; break;
} }
case CHECKBOX_BOT_OLD_RULE: {
mainGame->RefreshBot();
break;
}
} }
break; break;
} }
......
...@@ -8,6 +8,8 @@ namespace ygo { ...@@ -8,6 +8,8 @@ namespace ygo {
class MenuHandler: public irr::IEventReceiver { class MenuHandler: public irr::IEventReceiver {
public: public:
virtual bool OnEvent(const irr::SEvent& event); virtual bool OnEvent(const irr::SEvent& event);
s32 prev_operation;
int prev_sel;
}; };
......
...@@ -207,6 +207,15 @@ public: ...@@ -207,6 +207,15 @@ public:
#define ERRMSG_SIDEERROR 0x3 #define ERRMSG_SIDEERROR 0x3
#define ERRMSG_VERERROR 0x4 #define ERRMSG_VERERROR 0x4
#define DECKERROR_LFLIST 0x1
#define DECKERROR_OCGONLY 0x2
#define DECKERROR_TCGONLY 0x3
#define DECKERROR_UNKNOWNCARD 0x4
#define DECKERROR_CARDCOUNT 0x5
#define DECKERROR_MAINCOUNT 0x6
#define DECKERROR_EXTRACOUNT 0x7
#define DECKERROR_SIDECOUNT 0x8
#define MODE_SINGLE 0x0 #define MODE_SINGLE 0x0
#define MODE_MATCH 0x1 #define MODE_MATCH 0x1
#define MODE_TAG 0x2 #define MODE_TAG 0x2
......
include "lzma" include "lzma/."
project "ygopro" project "ygopro"
kind "WindowedApp" kind "WindowedApp"
...@@ -18,6 +18,6 @@ project "ygopro" ...@@ -18,6 +18,6 @@ project "ygopro"
configuration "not vs*" configuration "not vs*"
buildoptions { "-std=gnu++0x", "-fno-rtti" } buildoptions { "-std=gnu++0x", "-fno-rtti" }
configuration "not windows" configuration "not windows"
includedirs { "/usr/include/lua", "/usr/include/lua5.2", "/usr/include/lua/5.2", "/usr/include/irrlicht", "/usr/include/freetype2" } includedirs { "/usr/include/lua", "/usr/include/lua5.3", "/usr/include/lua/5.3", "/usr/include/irrlicht", "/usr/include/freetype2" }
excludes { "COSOperator.*" } excludes { "COSOperator.*" }
links { "event_pthreads", "GL", "dl", "pthread" } links { "event_pthreads", "GL", "dl", "pthread" }
...@@ -192,6 +192,36 @@ bool Replay::CheckReplay(const wchar_t* name) { ...@@ -192,6 +192,36 @@ bool Replay::CheckReplay(const wchar_t* name) {
fclose(rfp); fclose(rfp);
return rheader.id == 0x31707279 && rheader.version >= 0x12d0; return rheader.id == 0x31707279 && rheader.version >= 0x12d0;
} }
bool Replay::DeleteReplay(const wchar_t* name) {
wchar_t fname[256];
myswprintf(fname, L"./replay/%ls", name);
#ifdef WIN32
BOOL result = DeleteFileW(fname);
return !!result;
#else
char filefn[256];
BufferIO::EncodeUTF8(fname, filefn);
int result = unlink(filefn);
return result == 0;
#endif
}
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);
#ifdef WIN32
BOOL result = MoveFileW(oldfname, newfname);
return !!result;
#else
char oldfilefn[256];
char newfilefn[256];
BufferIO::EncodeUTF8(oldfname, oldfilefn);
BufferIO::EncodeUTF8(newfname, newfilefn);
int result = rename(oldfilefn, newfilefn);
return result == 0;
#endif
}
bool Replay::ReadNextResponse(unsigned char resp[64]) { bool Replay::ReadNextResponse(unsigned char resp[64]) {
if(pdata - replay_data >= (int)replay_size) if(pdata - replay_data >= (int)replay_size)
return false; return false;
...@@ -226,7 +256,7 @@ short Replay::ReadInt16() { ...@@ -226,7 +256,7 @@ short Replay::ReadInt16() {
if(!is_replaying) if(!is_replaying)
return -1; return -1;
short ret = *((short*)pdata); short ret = *((short*)pdata);
pdata += 4; pdata += 2;
return ret; return ret;
} }
char Replay::ReadInt8() { char Replay::ReadInt8() {
......
...@@ -9,6 +9,7 @@ namespace ygo { ...@@ -9,6 +9,7 @@ namespace ygo {
#define REPLAY_COMPRESSED 0x1 #define REPLAY_COMPRESSED 0x1
#define REPLAY_TAG 0x2 #define REPLAY_TAG 0x2
#define REPLAY_DECODED 0x4 #define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8
struct ReplayHeader { struct ReplayHeader {
unsigned int id; unsigned int id;
...@@ -35,6 +36,8 @@ public: ...@@ -35,6 +36,8 @@ public:
void SaveReplay(const wchar_t* name); void SaveReplay(const wchar_t* name);
bool OpenReplay(const wchar_t* name); bool OpenReplay(const wchar_t* name);
static bool CheckReplay(const wchar_t* name); static bool CheckReplay(const wchar_t* name);
static bool DeleteReplay(const wchar_t* name);
static bool RenameReplay(const wchar_t* oldname, const wchar_t* newname);
bool ReadNextResponse(unsigned char resp[64]); bool ReadNextResponse(unsigned char resp[64]);
void ReadName(wchar_t* data); void ReadName(wchar_t* data);
void ReadHeader(ReplayHeader& header); void ReadHeader(ReplayHeader& header);
......
This diff is collapsed.
...@@ -33,6 +33,8 @@ public: ...@@ -33,6 +33,8 @@ public:
static void Pause(bool is_pause, bool is_step); static void Pause(bool is_pause, bool is_step);
static bool ReadReplayResponse(); static bool ReadReplayResponse();
static int ReplayThread(void* param); static int ReplayThread(void* param);
static bool StartDuel();
static void EndDuel();
static void Restart(bool refresh); static void Restart(bool refresh);
static void Undo(); static void Undo();
static bool ReplayAnalyze(char* msg, unsigned int len); static bool ReplayAnalyze(char* msg, unsigned int len);
...@@ -43,6 +45,7 @@ public: ...@@ -43,6 +45,7 @@ public:
static void ReplayRefreshDeck(int player, int flag = 0x181fff); static void ReplayRefreshDeck(int player, int flag = 0x181fff);
static void ReplayRefreshExtra(int player, int flag = 0x181fff); static void ReplayRefreshExtra(int player, int flag = 0x181fff);
static void ReplayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff); static void ReplayRefreshSingle(int player, int location, int sequence, int flag = 0xf81fff);
static void ReplayReload();
static int MessageHandler(long fduel, int type); static int MessageHandler(long fduel, int type);
}; };
......
...@@ -27,17 +27,10 @@ void SingleDuel::Chat(DuelPlayer* dp, void* pdata, int len) { ...@@ -27,17 +27,10 @@ void SingleDuel::Chat(DuelPlayer* dp, void* pdata, int len) {
scc.player = dp->type; scc.player = dp->type;
unsigned short* msg = (unsigned short*)pdata; unsigned short* msg = (unsigned short*)pdata;
int msglen = BufferIO::CopyWStr(msg, scc.msg, 256); int msglen = BufferIO::CopyWStr(msg, scc.msg, 256);
if(dp->type > 1) {
NetServer::SendBufferToPlayer(players[0], STOC_CHAT, &scc, 4 + msglen * 2); NetServer::SendBufferToPlayer(players[0], STOC_CHAT, &scc, 4 + msglen * 2);
NetServer::ReSendToPlayer(players[1]); NetServer::ReSendToPlayer(players[1]);
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
if((*pit) != dp)
NetServer::ReSendToPlayer(*pit); NetServer::ReSendToPlayer(*pit);
} else {
NetServer::SendBufferToPlayer(players[1 - dp->type], STOC_CHAT, &scc, 4 + msglen * 2);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
}
} }
void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
if(!is_creater) { if(!is_creater) {
...@@ -78,12 +71,14 @@ void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { ...@@ -78,12 +71,14 @@ void SingleDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
if(!players[0] || !players[1]) { if(!players[0] || !players[1]) {
STOC_HS_PlayerEnter scpe; STOC_HS_PlayerEnter scpe;
BufferIO::CopyWStr(dp->name, scpe.name, 20); BufferIO::CopyWStr(dp->name, scpe.name, 20);
if(players[0]) { if(!players[0])
scpe.pos = 0;
else
scpe.pos = 1; scpe.pos = 1;
if(players[0]) {
NetServer::SendPacketToPlayer(players[0], STOC_HS_PLAYER_ENTER, scpe); NetServer::SendPacketToPlayer(players[0], STOC_HS_PLAYER_ENTER, scpe);
} }
if(players[1]) { if(players[1]) {
scpe.pos = 0;
NetServer::SendPacketToPlayer(players[1], STOC_HS_PLAYER_ENTER, scpe); NetServer::SendPacketToPlayer(players[1], STOC_HS_PLAYER_ENTER, scpe);
} }
for(auto pit = observers.begin(); pit != observers.end(); ++pit) for(auto pit = observers.begin(); pit != observers.end(); ++pit)
...@@ -252,16 +247,23 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) { ...@@ -252,16 +247,23 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
if(ready[dp->type] == is_ready) if(ready[dp->type] == is_ready)
return; return;
if(is_ready) { if(is_ready) {
unsigned int deckerror = 0;
if(!host_info.no_check_deck) {
if(deck_error[dp->type]) {
deckerror = (DECKERROR_UNKNOWNCARD << 28) + deck_error[dp->type];
} else {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2; bool allow_ocg = host_info.rule == 0 || host_info.rule == 2;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2; bool allow_tcg = host_info.rule == 1 || host_info.rule == 2;
int res = host_info.no_check_deck ? false : deckManager.CheckLFList(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg); deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg);
if(res) { }
}
if(deckerror) {
STOC_HS_PlayerChange scpc; STOC_HS_PlayerChange scpc;
scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY; scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc); NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc);
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR; scem.msg = ERRMSG_DECKERROR;
scem.code = res; scem.code = deckerror;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
...@@ -287,7 +289,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) { ...@@ -287,7 +289,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
int mainc = BufferIO::ReadInt32(deckbuf); int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf); int sidec = BufferIO::ReadInt32(deckbuf);
if(duel_count == 0) { if(duel_count == 0) {
deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec); deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec);
} else { } else {
if(deckManager.LoadSide(pdeck[dp->type], (int*)deckbuf, mainc, sidec)) { if(deckManager.LoadSide(pdeck[dp->type], (int*)deckbuf, mainc, sidec)) {
ready[dp->type] = true; ready[dp->type] = true;
...@@ -782,6 +784,16 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -782,6 +784,16 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
break; break;
} }
case MSG_CONFIRM_EXTRATOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
NetServer::ReSendToPlayer(players[1]);
for (auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
break;
}
case MSG_CONFIRM_CARDS: { case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf);
...@@ -817,6 +829,18 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -817,6 +829,18 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
RefreshHand(player, 0x781fff, 0); RefreshHand(player, 0x781fff, 0);
break; break;
} }
case MSG_SHUFFLE_EXTRA: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, (pbuf - offset) + count * 4);
for (int i = 0; i < count; ++i)
BufferIO::WriteInt32(pbuf, 0);
NetServer::SendBufferToPlayer(players[1 - player], STOC_GAME_MSG, offset, pbuf - offset);
for (auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
RefreshExtra(player);
break;
}
case MSG_REFRESH_DECK: { case MSG_REFRESH_DECK: {
pbuf++; pbuf++;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
...@@ -1416,8 +1440,10 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) { ...@@ -1416,8 +1440,10 @@ void SingleDuel::RefreshMzone(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_MZONE); BufferIO::WriteInt8(qbuf, LOCATION_MZONE);
int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_MZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
for (int i = 0; i < 5; ++i) { int qlen = 0;
while(qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen;
if (clen == 4) if (clen == 4)
continue; continue;
if (qbuf[11] & POS_FACEDOWN) if (qbuf[11] & POS_FACEDOWN)
...@@ -1436,8 +1462,10 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) { ...@@ -1436,8 +1462,10 @@ void SingleDuel::RefreshSzone(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_SZONE); BufferIO::WriteInt8(qbuf, LOCATION_SZONE);
int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache); int len = query_field_card(pduel, player, LOCATION_SZONE, flag, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
for (int i = 0; i < 8; ++i) { int qlen = 0;
while(qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen;
if (clen == 4) if (clen == 4)
continue; continue;
if (qbuf[11] & POS_FACEDOWN) if (qbuf[11] & POS_FACEDOWN)
...@@ -1456,9 +1484,9 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) { ...@@ -1456,9 +1484,9 @@ void SingleDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_HAND); 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_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0, slen; int qlen = 0;
while(qlen < len) { while(qlen < len) {
slen = BufferIO::ReadInt32(qbuf); int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf; int qflag = *(int*)qbuf;
int pos = slen - 8; int pos = slen - 8;
if(qflag & QUERY_LSCALE) if(qflag & QUERY_LSCALE)
......
...@@ -46,6 +46,7 @@ protected: ...@@ -46,6 +46,7 @@ protected:
DuelPlayer* pplayer[2]; DuelPlayer* pplayer[2];
bool ready[2]; bool ready[2];
Deck pdeck[2]; Deck pdeck[2];
int deck_error[2];
unsigned char hand_result[2]; unsigned char hand_result[2];
unsigned char last_response; unsigned char last_response;
std::set<DuelPlayer*> observers; std::set<DuelPlayer*> observers;
......
...@@ -10,6 +10,7 @@ namespace ygo { ...@@ -10,6 +10,7 @@ namespace ygo {
long SingleMode::pduel = 0; long SingleMode::pduel = 0;
bool SingleMode::is_closing = false; bool SingleMode::is_closing = false;
bool SingleMode::is_continuing = false; bool SingleMode::is_continuing = false;
Replay SingleMode::last_replay;
static byte buffer[0x20000]; static byte buffer[0x20000];
...@@ -23,23 +24,18 @@ void SingleMode::StopPlay(bool is_exiting) { ...@@ -23,23 +24,18 @@ void SingleMode::StopPlay(bool is_exiting) {
mainGame->actionSignal.Set(); mainGame->actionSignal.Set();
mainGame->singleSignal.Set(); mainGame->singleSignal.Set();
} }
void SingleMode::SetResponse(unsigned char* resp) { void SingleMode::SetResponse(unsigned char* resp, unsigned int len) {
if(!pduel) if(!pduel)
return; return;
last_replay.WriteInt8(len);
last_replay.WriteData(resp, len);
set_responseb(pduel, resp); set_responseb(pduel, resp);
} }
int SingleMode::SinglePlayThread(void* param) { int SingleMode::SinglePlayThread(void* param) {
char fname2[256]; const int start_lp = 8000;
size_t slen; const int start_hand = 5;
if(open_file) { const int draw_count = 1;
slen = BufferIO::EncodeUTF8(open_file_name, fname2); const int opt = 0;
open_file = false;
} else {
const wchar_t* name = mainGame->lstSinglePlayList->getListItem(mainGame->lstSinglePlayList->getSelected());
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, fname2);
}
mtrandom rnd; mtrandom rnd;
time_t seed = time(0); time_t seed = time(0);
rnd.reset(seed); rnd.reset(seed);
...@@ -47,24 +43,44 @@ int SingleMode::SinglePlayThread(void* param) { ...@@ -47,24 +43,44 @@ int SingleMode::SinglePlayThread(void* param) {
set_card_reader((card_reader)DataManager::CardReader); set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler); set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand()); pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, 8000, 5, 1); set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, 8000, 5, 1); set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = 8000; mainGame->dInfo.lp[0] = start_lp;
mainGame->dInfo.lp[1] = 8000; mainGame->dInfo.lp[1] = start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]); myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]); myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname, 20); BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname, 20);
mainGame->dInfo.clientname[0] = 0; mainGame->dInfo.clientname[0] = 0;
mainGame->dInfo.turn = 0; mainGame->dInfo.turn = 0;
if(!preload_script(pduel, fname2, slen)) { char filename[256];
size_t slen = 0;
if(open_file) {
open_file = false;
slen = BufferIO::EncodeUTF8(open_file_name, filename);
if(!preload_script(pduel, filename, slen)) {
wchar_t fname[256]; wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name); myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, fname2); slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, fname2, slen)) { if(!preload_script(pduel, filename, slen))
slen = 0;
}
} else {
const wchar_t* name = mainGame->lstSinglePlayList->getListItem(mainGame->lstSinglePlayList->getSelected());
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", name);
slen = BufferIO::EncodeUTF8(fname, filename);
if(!preload_script(pduel, filename, slen))
slen = 0;
}
if(slen == 0) {
end_duel(pduel); end_duel(pduel);
return 0; return 0;
} }
} ReplayHeader rh;
rh.id = 0x31707279;
rh.version = PRO_VERSION;
rh.flag = REPLAY_SINGLE_MODE;
rh.seed = seed;
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
mainGame->HideElement(mainGame->wSinglePlay); mainGame->HideElement(mainGame->wSinglePlay);
mainGame->wCardImg->setVisible(true); mainGame->wCardImg->setVisible(true);
...@@ -84,11 +100,27 @@ int SingleMode::SinglePlayThread(void* param) { ...@@ -84,11 +100,27 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame->dInfo.isSingleMode = true; mainGame->dInfo.isSingleMode = true;
mainGame->device->setEventReceiver(&mainGame->dField); mainGame->device->setEventReceiver(&mainGame->dField);
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
start_duel(pduel, 0);
char engineBuffer[0x1000]; char engineBuffer[0x1000];
is_closing = false; is_closing = false;
is_continuing = true; is_continuing = true;
int len = 0; int len = get_message(pduel, (byte*)engineBuffer);
if (len > 0)
is_continuing = SinglePlayAnalyze(engineBuffer, len);
last_replay.BeginRecord();
last_replay.WriteHeader(rh);
unsigned short buffer[20];
BufferIO::CopyWStr(mainGame->dInfo.hostname, buffer, 20);
last_replay.WriteData(buffer, 40, false);
BufferIO::CopyWStr(mainGame->dInfo.clientname, buffer, 20);
last_replay.WriteData(buffer, 40, false);
last_replay.WriteInt32(start_lp, false);
last_replay.WriteInt32(start_hand, false);
last_replay.WriteInt32(draw_count, false);
last_replay.WriteInt32(opt, false);
last_replay.WriteInt16(slen, false);
last_replay.WriteData(filename, slen, false);
last_replay.Flush();
start_duel(pduel, opt);
while (is_continuing) { while (is_continuing) {
int result = process(pduel); int result = process(pduel);
len = result & 0xffff; len = result & 0xffff;
...@@ -98,6 +130,22 @@ int SingleMode::SinglePlayThread(void* param) { ...@@ -98,6 +130,22 @@ int SingleMode::SinglePlayThread(void* param) {
is_continuing = SinglePlayAnalyze(engineBuffer, len); is_continuing = SinglePlayAnalyze(engineBuffer, len);
} }
} }
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);
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->actionParam)
last_replay.SaveReplay(mainGame->ebRSName->getText());
end_duel(pduel); end_duel(pduel);
if(!is_closing) { if(!is_closing) {
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
...@@ -308,6 +356,13 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) { ...@@ -308,6 +356,13 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
DuelClient::ClientAnalyze(offset, pbuf - offset); DuelClient::ClientAnalyze(offset, pbuf - offset);
break; break;
} }
case MSG_CONFIRM_EXTRATOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_CONFIRM_CARDS: { case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf);
...@@ -328,6 +383,13 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) { ...@@ -328,6 +383,13 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
DuelClient::ClientAnalyze(offset, pbuf - offset); DuelClient::ClientAnalyze(offset, pbuf - offset);
break; break;
} }
case MSG_SHUFFLE_EXTRA: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 4;
DuelClient::ClientAnalyze(offset, pbuf - offset);
break;
}
case MSG_REFRESH_DECK: { case MSG_REFRESH_DECK: {
pbuf++; pbuf++;
DuelClient::ClientAnalyze(offset, pbuf - offset); DuelClient::ClientAnalyze(offset, pbuf - offset);
......
#ifndef SINGLE_MODE_H #ifndef SINGLE_MODE_H
#define SINGLE_MODE_H #define SINGLE_MODE_H
#include "config.h" #include "replay.h"
#include "data_manager.h"
#include "deck_manager.h"
#include "../ocgcore/mtrandom.h"
namespace ygo { namespace ygo {
...@@ -17,7 +14,7 @@ private: ...@@ -17,7 +14,7 @@ private:
public: public:
static bool StartPlay(); static bool StartPlay();
static void StopPlay(bool is_exiting = false); static void StopPlay(bool is_exiting = false);
static void SetResponse(unsigned char* resp); static void SetResponse(unsigned char* resp, unsigned int len);
static int SinglePlayThread(void* param); static int SinglePlayThread(void* param);
static bool SinglePlayAnalyze(char* msg, unsigned int len); static bool SinglePlayAnalyze(char* msg, unsigned int len);
...@@ -31,6 +28,9 @@ public: ...@@ -31,6 +28,9 @@ public:
static byte* ScriptReader(const char* script_name, int* slen); static byte* ScriptReader(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type); static int MessageHandler(long fduel, int type);
protected:
static Replay last_replay;
}; };
} }
......
...@@ -24,8 +24,9 @@ void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) { ...@@ -24,8 +24,9 @@ void TagDuel::Chat(DuelPlayer* dp, void* pdata, int len) {
unsigned short* msg = (unsigned short*)pdata; unsigned short* msg = (unsigned short*)pdata;
int msglen = BufferIO::CopyWStr(msg, scc.msg, 256); int msglen = BufferIO::CopyWStr(msg, scc.msg, 256);
for(int i = 0; i < 4; ++i) for(int i = 0; i < 4; ++i)
if(players[i] != dp)
NetServer::SendBufferToPlayer(players[i], STOC_CHAT, &scc, 4 + msglen * 2); NetServer::SendBufferToPlayer(players[i], STOC_CHAT, &scc, 4 + msglen * 2);
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::ReSendToPlayer(*pit);
} }
void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) { void TagDuel::JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {
if(!is_creater) { if(!is_creater) {
...@@ -222,16 +223,23 @@ void TagDuel::PlayerReady(DuelPlayer* dp, bool is_ready) { ...@@ -222,16 +223,23 @@ void TagDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
if(dp->type > 3 || ready[dp->type] == is_ready) if(dp->type > 3 || ready[dp->type] == is_ready)
return; return;
if(is_ready) { if(is_ready) {
unsigned int deckerror = 0;
if(!host_info.no_check_deck) {
if(deck_error[dp->type]) {
deckerror = (DECKERROR_UNKNOWNCARD << 28) + deck_error[dp->type];
} else {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2; bool allow_ocg = host_info.rule == 0 || host_info.rule == 2;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2; bool allow_tcg = host_info.rule == 1 || host_info.rule == 2;
int res = host_info.no_check_deck ? false : deckManager.CheckLFList(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg); deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg);
if(res) { }
}
if(deckerror) {
STOC_HS_PlayerChange scpc; STOC_HS_PlayerChange scpc;
scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY; scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc); NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc);
STOC_ErrorMsg scem; STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR; scem.msg = ERRMSG_DECKERROR;
scem.code = res; scem.code = deckerror;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem); NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return; return;
} }
...@@ -256,7 +264,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) { ...@@ -256,7 +264,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
char* deckbuf = (char*)pdata; char* deckbuf = (char*)pdata;
int mainc = BufferIO::ReadInt32(deckbuf); int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf); int sidec = BufferIO::ReadInt32(deckbuf);
deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec); deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec);
} }
void TagDuel::StartDuel(DuelPlayer* dp) { void TagDuel::StartDuel(DuelPlayer* dp) {
if(dp != host_player) if(dp != host_player)
...@@ -716,6 +724,18 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -716,6 +724,18 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::ReSendToPlayer(*oit); NetServer::ReSendToPlayer(*oit);
break; break;
} }
case MSG_CONFIRM_EXTRATOP: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
pbuf += count * 7;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
NetServer::ReSendToPlayer(players[1]);
NetServer::ReSendToPlayer(players[2]);
NetServer::ReSendToPlayer(players[3]);
for (auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
break;
}
case MSG_CONFIRM_CARDS: { case MSG_CONFIRM_CARDS: {
player = BufferIO::ReadInt8(pbuf); player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf);
...@@ -757,6 +777,20 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) { ...@@ -757,6 +777,20 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
RefreshHand(player, 0x781fff, 0); RefreshHand(player, 0x781fff, 0);
break; break;
} }
case MSG_SHUFFLE_EXTRA: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadInt8(pbuf);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, (pbuf - offset) + count * 4);
for(int i = 0; i < count; ++i)
BufferIO::WriteInt32(pbuf, 0);
for(int i = 0; i < 4; ++i)
if(players[i] != cur_player[player])
NetServer::SendBufferToPlayer(players[i], STOC_GAME_MSG, offset, pbuf - offset);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
RefreshExtra(player);
break;
}
case MSG_REFRESH_DECK: { case MSG_REFRESH_DECK: {
pbuf++; pbuf++;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset); NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, offset, pbuf - offset);
...@@ -1497,8 +1531,10 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) { ...@@ -1497,8 +1531,10 @@ void TagDuel::RefreshMzone(int player, int flag, int use_cache) {
int pid = (player == 0) ? 0 : 2; int pid = (player == 0) ? 0 : 2;
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3);
NetServer::ReSendToPlayer(players[pid + 1]); NetServer::ReSendToPlayer(players[pid + 1]);
for (int i = 0; i < 5; ++i) { int qlen = 0;
while(qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen;
if (clen == 4) if (clen == 4)
continue; continue;
if (qbuf[11] & POS_FACEDOWN) if (qbuf[11] & POS_FACEDOWN)
...@@ -1521,8 +1557,10 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) { ...@@ -1521,8 +1557,10 @@ void TagDuel::RefreshSzone(int player, int flag, int use_cache) {
int pid = (player == 0) ? 0 : 2; int pid = (player == 0) ? 0 : 2;
NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(players[pid], STOC_GAME_MSG, query_buffer, len + 3);
NetServer::ReSendToPlayer(players[pid + 1]); NetServer::ReSendToPlayer(players[pid + 1]);
for (int i = 0; i < 8; ++i) { int qlen = 0;
while(qlen < len) {
int clen = BufferIO::ReadInt32(qbuf); int clen = BufferIO::ReadInt32(qbuf);
qlen += clen;
if (clen == 4) if (clen == 4)
continue; continue;
if (qbuf[11] & POS_FACEDOWN) if (qbuf[11] & POS_FACEDOWN)
...@@ -1543,9 +1581,9 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) { ...@@ -1543,9 +1581,9 @@ void TagDuel::RefreshHand(int player, int flag, int use_cache) {
BufferIO::WriteInt8(qbuf, LOCATION_HAND); 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_IS_PUBLIC, (unsigned char*)qbuf, use_cache);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3); NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, query_buffer, len + 3);
int qlen = 0, slen; int qlen = 0;
while(qlen < len) { while(qlen < len) {
slen = BufferIO::ReadInt32(qbuf); int slen = BufferIO::ReadInt32(qbuf);
int qflag = *(int*)qbuf; int qflag = *(int*)qbuf;
int pos = slen - 8; int pos = slen - 8;
if(qflag & QUERY_LSCALE) if(qflag & QUERY_LSCALE)
......
...@@ -48,6 +48,7 @@ protected: ...@@ -48,6 +48,7 @@ protected:
std::set<DuelPlayer*> observers; std::set<DuelPlayer*> observers;
bool ready[4]; bool ready[4];
Deck pdeck[4]; Deck pdeck[4];
int deck_error[4];
unsigned char hand_result[2]; unsigned char hand_result[2];
unsigned char last_response; unsigned char last_response;
Replay last_replay; Replay last_replay;
......
This diff is collapsed.
Subproject commit 1f1d9cba25969e85760185a3fbb6f2070beba1aa Subproject commit a4e17256838bf1b657238f554362d9cc9841b233
Subproject commit 0f2bb610e85d5d61faefbf91c6f4c5aa4e52ec3c Subproject commit eacd96e1bc6ed66c00947d30adacffd0157ba8e8
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
!system 95 是否使用[%ls]的效果? !system 95 是否使用[%ls]的效果?
!system 96 是否使用[%ls]的效果代替破坏? !system 96 是否使用[%ls]的效果代替破坏?
!system 97 是否把[%ls]在魔法与陷阱区域放置? !system 97 是否把[%ls]在魔法与陷阱区域放置?
!system 98 是否要解放对方怪兽?
!system 100 先攻 !system 100 先攻
!system 101 后攻 !system 101 后攻
!system 200 是否在[%ls]发动[%ls]的效果? !system 200 是否在[%ls]发动[%ls]的效果?
...@@ -241,7 +242,7 @@ ...@@ -241,7 +242,7 @@
!system 1163 灵摆召唤 !system 1163 灵摆召唤
#menu #menu
!system 1200 联机模式 !system 1200 联机模式
!system 1201 残局模式 !system 1201 单人模式
!system 1202 观看录像 !system 1202 观看录像
!system 1203 N/A !system 1203 N/A
!system 1204 编辑卡组 !system 1204 编辑卡组
...@@ -280,6 +281,8 @@ ...@@ -280,6 +281,8 @@
!system 1244 单局模式 !system 1244 单局模式
!system 1245 比赛模式 !system 1245 比赛模式
!system 1246 TAG !system 1246 TAG
!system 1247 标准对战
!system 1248 自定义
!system 1250 决斗准备 !system 1250 决斗准备
!system 1251 →决斗者 !system 1251 →决斗者
!system 1252 →观战 !system 1252 →观战
...@@ -299,8 +302,6 @@ ...@@ -299,8 +302,6 @@
!system 1276 自动排列连锁顺序 !system 1276 自动排列连锁顺序
!system 1277 没有可连锁的卡时延迟回应 !system 1277 没有可连锁的卡时延迟回应
!system 1278 自动选择魔陷卡片位置 !system 1278 自动选择魔陷卡片位置
!system 1280 标准对战
!system 1281 自定义
!system 1290 忽略对方发言 !system 1290 忽略对方发言
!system 1291 忽略观战者发言 !system 1291 忽略观战者发言
!system 1292 忽略时点 !system 1292 忽略时点
...@@ -319,6 +320,7 @@ ...@@ -319,6 +320,7 @@
!system 1306 退出编辑 !system 1306 退出编辑
!system 1307 打乱 !system 1307 打乱
!system 1308 删除 !system 1308 删除
!system 1309 重置
!system 1310 (无) !system 1310 (无)
!system 1311 种类: !system 1311 种类:
!system 1312 怪兽 !system 1312 怪兽
...@@ -367,11 +369,22 @@ ...@@ -367,11 +369,22 @@
!system 1357 不提示保留对卡组的修改 !system 1357 不提示保留对卡组的修改
!system 1358 键入关键字后自动进行搜索 !system 1358 键入关键字后自动进行搜索
!system 1360 上一步 !system 1360 上一步
!system 1361 删除录像
!system 1362 重命名
!system 1363 是否删除这个录像?
!system 1364 重命名录像
!system 1365 重命名失败,可能存在同名文件
!system 1370 星数↑ !system 1370 星数↑
!system 1371 攻击↑ !system 1371 攻击↑
!system 1372 守备↑ !system 1372 守备↑
!system 1373 名称↓ !system 1373 名称↓
!system 1374 连接标记 !system 1374 连接标记
!system 1380 人机模式
!system 1381 残局模式
!system 1382 人机信息:
!system 1383 使用旧规则(大师规则3)
!system 1384 电脑锁定出剪刀
!system 1385 列表为空,可能未安装合适的人机
!system 1390 等待行动中... !system 1390 等待行动中...
!system 1391 等待行动中.... !system 1391 等待行动中....
!system 1392 等待行动中..... !system 1392 等待行动中.....
...@@ -382,12 +395,20 @@ ...@@ -382,12 +395,20 @@
!system 1404 密码错误。 !system 1404 密码错误。
!system 1405 主机拒绝了连接。 !system 1405 主机拒绝了连接。
!system 1406 无效卡组。 !system 1406 无效卡组。
!system 1407 「%ls」的数量不符合当前设定。 !system 1407 「%ls」的数量不符合当前禁限卡表设定。
!system 1408 更换副卡组失败。 !system 1408 更换副卡组失败。
!system 1409 等待更换副卡组中... !system 1409 等待更换副卡组中...
!system 1410 卡组数量与先前不符合。 !system 1410 卡组数量与先前不符合。
!system 1411 版本不匹配(%X.0%X.%X)。 !system 1411 版本不匹配(%X.0%X.%X)。
!system 1412 无法解析主机地址。 !system 1412 无法解析主机地址。
!system 1413 「%ls」为OCG独有卡,不允许在当前设定下使用。
!system 1414 「%ls」为TCG独有卡,不允许在当前设定下使用。
!system 1415 卡组中「%ls(%d)」无法被主机识别。
!system 1416 卡组中「%ls」的总数量超过3张。
!system 1417 主卡组数量应为40-60张,当前卡组数量为%d张。
!system 1418 额外卡组数量应不超过15张,当前卡组数量为%d张。
!system 1419 副卡组数量应不超过15张,当前卡组数量为%d张。
!system 1420 有额外卡组卡片存在于主卡组,可能是额外卡组数量超过15张。
!system 1500 决斗结束。 !system 1500 决斗结束。
!system 1501 录像结束。 !system 1501 录像结束。
!system 1502 连接已断开。 !system 1502 连接已断开。
...@@ -503,6 +524,10 @@ ...@@ -503,6 +524,10 @@
!counter 0x1041 捕食指示物 !counter 0x1041 捕食指示物
!counter 0x42 指示物(爆竹鬼) !counter 0x42 指示物(爆竹鬼)
!counter 0x43 缺陷指示物 !counter 0x43 缺陷指示物
!counter 0x44 指示物(弹带城壁龙)
!counter 0x1045 鳞粉指示物
!counter 0x46 指示物(刚鬼死斗)
!counter 0x47 指示物(限制代码)
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -527,6 +552,7 @@ ...@@ -527,6 +552,7 @@
!setname 0xd 剑士 セイバー !setname 0xd 剑士 セイバー
!setname 0x100d X-剑士 X-セイバー !setname 0x100d X-剑士 X-セイバー
#setname 0x300d XX-剑士 XX-セイバー #setname 0x300d XX-剑士 XX-セイバー
!setname 0x400d 元素灵剑士 エレメントセイバー
!setname 0xe 电气 エレキ !setname 0xe 电气 エレキ
!setname 0xf 扰乱 おジャマ !setname 0xf 扰乱 おジャマ
!setname 0x10 薰风 ガスタ !setname 0x10 薰风 ガスタ
...@@ -850,3 +876,15 @@ ...@@ -850,3 +876,15 @@
!setname 0x108 魔弹 魔弾 !setname 0x108 魔弹 魔弾
!setname 0x109 天气 天気 !setname 0x109 天气 天気
!setname 0x10a 珀耳修斯 パーシアス !setname 0x10a 珀耳修斯 パーシアス
!setname 0x10b 廷达魔三角 ティンダングル
!setname 0x10c 机界骑士 ジャックナイツ
!setname 0x10d 魔导兽 魔導獣
!setname 0x10e 进化药 進化薬
!setname 0x10f 枪管 ヴァレル
!setname 0x110 眼纳祭神 アイズ・サクリファイス
!setname 0x111 武装龙 アームド・ドラゴン
!setname 0x112 幻崩 トロイメア
!setname 0x113 灵神 霊神
!setname 0x114 空牙团 空牙団
!setname 0x115 闪刀 閃刀
!setname 0x1115 闪刀姬 閃刀姫
#config file #config file
#nickname & gamename should be less than 20 characters #nickname & gamename should be less than 20 characters
use_d3d = 0 use_d3d = 0
use_image_scale = 1
antialias = 2 antialias = 2
errorlog = 1 errorlog = 1
nickname = Player nickname = Player
...@@ -24,6 +25,8 @@ hide_hint_button = 1 ...@@ -24,6 +25,8 @@ hide_hint_button = 1
control_mode = 0 control_mode = 0
draw_field_spell = 1 draw_field_spell = 1
separate_clear_button = 1 separate_clear_button = 1
#auto_search_limit >= 0: Start search automatically when the user enters N chars. #auto_search_limit >= 0: Start search automatically when the user enters N chars
auto_search_limit = -1 auto_search_limit = -1
ignore_deck_changes = 0 ignore_deck_changes = 0
default_ot = 1
enable_bot_mode = 0
textures/ot.png

18.2 KB | W: | H:

textures/ot.png

8.26 KB | W: | H:

textures/ot.png
textures/ot.png
textures/ot.png
textures/ot.png
  • 2-up
  • Swipe
  • Onion skin
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