Commit b9b4e27a authored by mercury233's avatar mercury233

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

parents c2f9e7e7 9e9b5d8b
...@@ -340,6 +340,7 @@ void ClientField::ClearCommandFlag() { ...@@ -340,6 +340,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;
......
...@@ -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();
...@@ -239,6 +242,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -239,6 +242,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();
......
#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);
......
...@@ -216,13 +216,52 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -216,13 +216,52 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
} }
case ERRMSG_DECKERROR: { case ERRMSG_DECKERROR: {
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
if(pkt->code == 1) unsigned int code = pkt->code & 0xFFFFFFF;
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1406)); int flag = pkt->code >> 28;
else { wchar_t msgbuf[256];
wchar_t msgbuf[256]; switch(flag)
myswprintf(msgbuf, dataManager.GetSysString(1407), dataManager.GetName(pkt->code)); {
mainGame->env->addMessageBox(L"", msgbuf); case DECKERROR_LFLIST: {
myswprintf(msgbuf, dataManager.GetSysString(1407), dataManager.GetName(code));
break;
}
case DECKERROR_OCGONLY: {
myswprintf(msgbuf, dataManager.GetSysString(1413), dataManager.GetName(code));
break;
}
case DECKERROR_TCGONLY: {
myswprintf(msgbuf, dataManager.GetSysString(1414), dataManager.GetName(code));
break;
}
case DECKERROR_UNKNOWNCARD: {
myswprintf(msgbuf, dataManager.GetSysString(1415), dataManager.GetName(code), code);
break;
}
case DECKERROR_CARDCOUNT: {
myswprintf(msgbuf, dataManager.GetSysString(1416), dataManager.GetName(code));
break;
}
case DECKERROR_MAINCOUNT: {
myswprintf(msgbuf, dataManager.GetSysString(1417), code);
break;
} }
case DECKERROR_EXTRACOUNT: {
if(code>0)
myswprintf(msgbuf, dataManager.GetSysString(1418), code);
else
myswprintf(msgbuf, dataManager.GetSysString(1420));
break;
}
case DECKERROR_SIDECOUNT: {
myswprintf(msgbuf, dataManager.GetSysString(1419), code);
break;
}
default: {
myswprintf(msgbuf, dataManager.GetSysString(1406));
break;
}
}
mainGame->env->addMessageBox(L"", msgbuf);
mainGame->cbDeckSelect->setEnabled(true); mainGame->cbDeckSelect->setEnabled(true);
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
break; break;
...@@ -284,6 +323,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -284,6 +323,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wSort->setVisible(false); mainGame->wSort->setVisible(false);
mainGame->stTip->setVisible(false); mainGame->stTip->setVisible(false);
mainGame->btnSideOK->setVisible(true); mainGame->btnSideOK->setVisible(true);
mainGame->btnSideShuffle->setVisible(true);
mainGame->btnSideSort->setVisible(true);
mainGame->btnSideReload->setVisible(true);
if(mainGame->dInfo.player_type < 7) if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false); mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSpectatorSwap->setVisible(false); mainGame->btnSpectatorSwap->setVisible(false);
...@@ -485,6 +527,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -485,6 +527,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wInfos->setVisible(true); mainGame->wInfos->setVisible(true);
mainGame->wPhase->setVisible(true); mainGame->wPhase->setVisible(true);
mainGame->btnSideOK->setVisible(false); mainGame->btnSideOK->setVisible(false);
mainGame->btnSideShuffle->setVisible(false);
mainGame->btnSideSort->setVisible(false);
mainGame->btnSideReload->setVisible(false);
mainGame->btnPhaseStatus->setVisible(false); mainGame->btnPhaseStatus->setVisible(false);
mainGame->btnBP->setVisible(false); mainGame->btnBP->setVisible(false);
mainGame->btnM2->setVisible(false); mainGame->btnM2->setVisible(false);
...@@ -643,7 +688,6 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) { ...@@ -643,7 +688,6 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
} }
wchar_t msg[256]; wchar_t msg[256];
BufferIO::CopyWStr(pkt->msg, msg, 256); BufferIO::CopyWStr(pkt->msg, msg, 256);
msg[(len - 3) / 2] = 0;
mainGame->gMutex.Lock(); mainGame->gMutex.Lock();
mainGame->AddChatMsg(msg, player); mainGame->AddChatMsg(msg, player);
mainGame->gMutex.Unlock(); mainGame->gMutex.Unlock();
...@@ -978,25 +1022,37 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -978,25 +1022,37 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
} }
case MSG_SELECT_BATTLECMD: { case MSG_SELECT_BATTLECMD: {
/*int selecting_player = */BufferIO::ReadInt8(pbuf); /*int selecting_player = */BufferIO::ReadInt8(pbuf);
int /*code, */desc, count, con, loc, seq/*, diratt*/; int code, desc, count, con, loc, seq/*, diratt*/;
ClientCard* pcard; ClientCard* pcard;
mainGame->dField.activatable_cards.clear(); mainGame->dField.activatable_cards.clear();
mainGame->dField.activatable_descs.clear(); mainGame->dField.activatable_descs.clear();
count = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
/*code = */BufferIO::ReadInt32(pbuf); code = BufferIO::ReadInt32(pbuf);
con = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf)); con = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
loc = BufferIO::ReadInt8(pbuf); loc = BufferIO::ReadInt8(pbuf);
seq = BufferIO::ReadInt8(pbuf); seq = BufferIO::ReadInt8(pbuf);
desc = BufferIO::ReadInt32(pbuf); desc = BufferIO::ReadInt32(pbuf);
pcard = mainGame->dField.GetCard(con, loc, seq); pcard = mainGame->dField.GetCard(con, loc, seq);
int flag = 0;
if(code & 0x80000000) {
flag = EDESC_OPERATION;
code &= 0x7fffffff;
}
mainGame->dField.activatable_cards.push_back(pcard); mainGame->dField.activatable_cards.push_back(pcard);
mainGame->dField.activatable_descs.push_back(std::make_pair(desc, 0)); mainGame->dField.activatable_descs.push_back(std::make_pair(desc, flag));
pcard->cmdFlag |= COMMAND_ACTIVATE; if(flag == EDESC_OPERATION) {
if (pcard->location == LOCATION_GRAVE) pcard->chain_code = code;
mainGame->dField.grave_act = true; mainGame->dField.conti_cards.push_back(pcard);
else if (pcard->location == LOCATION_REMOVED) mainGame->dField.conti_act = true;
mainGame->dField.remove_act = true; pcard->cmdFlag |= COMMAND_OPERATION;
} else {
pcard->cmdFlag |= COMMAND_ACTIVATE;
if (pcard->location == LOCATION_GRAVE)
mainGame->dField.grave_act = true;
else if (pcard->location == LOCATION_REMOVED)
mainGame->dField.remove_act = true;
}
} }
mainGame->dField.attackable_cards.clear(); mainGame->dField.attackable_cards.clear();
count = BufferIO::ReadInt8(pbuf); count = BufferIO::ReadInt8(pbuf);
...@@ -1107,13 +1163,25 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -1107,13 +1163,25 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
seq = BufferIO::ReadInt8(pbuf); seq = BufferIO::ReadInt8(pbuf);
desc = BufferIO::ReadInt32(pbuf); desc = BufferIO::ReadInt32(pbuf);
pcard = mainGame->dField.GetCard(con, loc, seq); pcard = mainGame->dField.GetCard(con, loc, seq);
int flag = 0;
if(code & 0x80000000) {
flag = EDESC_OPERATION;
code &= 0x7fffffff;
}
mainGame->dField.activatable_cards.push_back(pcard); mainGame->dField.activatable_cards.push_back(pcard);
mainGame->dField.activatable_descs.push_back(std::make_pair(desc, 0)); mainGame->dField.activatable_descs.push_back(std::make_pair(desc, flag));
pcard->cmdFlag |= COMMAND_ACTIVATE; if(flag == EDESC_OPERATION) {
if (pcard->location == LOCATION_GRAVE) pcard->chain_code = code;
mainGame->dField.grave_act = true; mainGame->dField.conti_cards.push_back(pcard);
else if (pcard->location == LOCATION_REMOVED) mainGame->dField.conti_act = true;
mainGame->dField.remove_act = true; pcard->cmdFlag |= COMMAND_OPERATION;
} else {
pcard->cmdFlag |= COMMAND_ACTIVATE;
if (pcard->location == LOCATION_GRAVE)
mainGame->dField.grave_act = true;
else if (pcard->location == LOCATION_REMOVED)
mainGame->dField.remove_act = true;
}
} }
if(BufferIO::ReadInt8(pbuf)) { if(BufferIO::ReadInt8(pbuf)) {
mainGame->btnBP->setVisible(true); mainGame->btnBP->setVisible(true);
...@@ -3288,7 +3356,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) { ...@@ -3288,7 +3356,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
ClientCard* xcard = new ClientCard; ClientCard* xcard = new ClientCard;
ccard->overlayed.push_back(xcard); ccard->overlayed.push_back(xcard);
mainGame->dField.overlay_cards.insert(xcard); mainGame->dField.overlay_cards.insert(xcard);
mainGame->gMutex.Unlock();
xcard->overlayTarget = ccard; xcard->overlayTarget = ccard;
xcard->location = 0x80; xcard->location = 0x80;
xcard->sequence = ccard->overlayed.size() - 1; xcard->sequence = ccard->overlayed.size() - 1;
...@@ -3442,7 +3509,7 @@ void DuelClient::SendResponse() { ...@@ -3442,7 +3509,7 @@ void DuelClient::SendResponse() {
} }
} }
if(mainGame->dInfo.isSingleMode) { if(mainGame->dInfo.isSingleMode) {
SingleMode::SetResponse(response_buf); SingleMode::SetResponse(response_buf, response_len);
mainGame->singleSignal.Set(); mainGame->singleSignal.Set();
} else { } else {
mainGame->dInfo.time_player = 2; mainGame->dInfo.time_player = 2;
......
...@@ -158,6 +158,7 @@ bool Game::Initialize() { ...@@ -158,6 +158,7 @@ bool Game::Initialize() {
cbRule->addItem(dataManager.GetSysString(1241)); cbRule->addItem(dataManager.GetSysString(1241));
cbRule->addItem(dataManager.GetSysString(1242)); cbRule->addItem(dataManager.GetSysString(1242));
cbRule->addItem(dataManager.GetSysString(1243)); cbRule->addItem(dataManager.GetSysString(1243));
cbRule->setSelected(gameConf.defaultOT - 1);
env->addStaticText(dataManager.GetSysString(1227), rect<s32>(20, 90, 220, 110), false, false, wCreateHost); env->addStaticText(dataManager.GetSysString(1227), rect<s32>(20, 90, 220, 110), false, false, wCreateHost);
cbMatchMode = env->addComboBox(rect<s32>(140, 85, 300, 110), wCreateHost); cbMatchMode = env->addComboBox(rect<s32>(140, 85, 300, 110), wCreateHost);
cbMatchMode->addItem(dataManager.GetSysString(1244)); cbMatchMode->addItem(dataManager.GetSysString(1244));
...@@ -468,6 +469,12 @@ bool Game::Initialize() { ...@@ -468,6 +469,12 @@ bool Game::Initialize() {
btnClearDeck = env->addButton(rect<s32>(115, 99, 165, 120), wDeckEdit, BUTTON_CLEAR_DECK, dataManager.GetSysString(1304)); btnClearDeck = env->addButton(rect<s32>(115, 99, 165, 120), wDeckEdit, BUTTON_CLEAR_DECK, dataManager.GetSysString(1304));
btnSideOK = env->addButton(rect<s32>(510, 40, 820, 80), 0, BUTTON_SIDE_OK, dataManager.GetSysString(1334)); btnSideOK = env->addButton(rect<s32>(510, 40, 820, 80), 0, BUTTON_SIDE_OK, dataManager.GetSysString(1334));
btnSideOK->setVisible(false); btnSideOK->setVisible(false);
btnSideShuffle = env->addButton(rect<s32>(310, 100, 370, 130), 0, BUTTON_SHUFFLE_DECK, dataManager.GetSysString(1307));
btnSideShuffle->setVisible(false);
btnSideSort = env->addButton(rect<s32>(375, 100, 435, 130), 0, BUTTON_SORT_DECK, dataManager.GetSysString(1305));
btnSideSort->setVisible(false);
btnSideReload = env->addButton(rect<s32>(440, 100, 500, 130), 0, BUTTON_SIDE_RELOAD, dataManager.GetSysString(1309));
btnSideReload->setVisible(false);
// //
scrFilter = env->addScrollBar(false, recti(999, 161, 1019, 629), 0, SCROLL_FILTER); scrFilter = env->addScrollBar(false, recti(999, 161, 1019, 629), 0, SCROLL_FILTER);
scrFilter->setLargeStep(10); scrFilter->setLargeStep(10);
...@@ -961,6 +968,7 @@ void Game::LoadConfig() { ...@@ -961,6 +968,7 @@ void Game::LoadConfig() {
gameConf.separate_clear_button = 1; gameConf.separate_clear_button = 1;
gameConf.auto_search_limit = -1; gameConf.auto_search_limit = -1;
gameConf.chkIgnoreDeckChanges = 0; gameConf.chkIgnoreDeckChanges = 0;
gameConf.defaultOT = 1;
while(fgets(linebuf, 256, fp)) { while(fgets(linebuf, 256, fp)) {
sscanf(linebuf, "%s = %s", strbuf, valbuf); sscanf(linebuf, "%s = %s", strbuf, valbuf);
if(!strcmp(strbuf, "antialias")) { if(!strcmp(strbuf, "antialias")) {
...@@ -1019,6 +1027,8 @@ void Game::LoadConfig() { ...@@ -1019,6 +1027,8 @@ void Game::LoadConfig() {
gameConf.auto_search_limit = atoi(valbuf); gameConf.auto_search_limit = atoi(valbuf);
} else if(!strcmp(strbuf, "ignore_deck_changes")) { } else if(!strcmp(strbuf, "ignore_deck_changes")) {
gameConf.chkIgnoreDeckChanges = atoi(valbuf); gameConf.chkIgnoreDeckChanges = atoi(valbuf);
} else if(!strcmp(strbuf, "default_ot")) {
gameConf.defaultOT = atoi(valbuf);
} else { } else {
// options allowing multiple words // options allowing multiple words
sscanf(linebuf, "%s = %240[^\n]", strbuf, valbuf); sscanf(linebuf, "%s = %240[^\n]", strbuf, valbuf);
...@@ -1077,6 +1087,7 @@ void Game::SaveConfig() { ...@@ -1077,6 +1087,7 @@ void Game::SaveConfig() {
fprintf(fp, "#auto_search_limit >= 0: Start search automatically when the user enters N chars\n"); fprintf(fp, "#auto_search_limit >= 0: Start search automatically when the user enters N chars\n");
fprintf(fp, "auto_search_limit = %d\n", gameConf.auto_search_limit); fprintf(fp, "auto_search_limit = %d\n", gameConf.auto_search_limit);
fprintf(fp, "ignore_deck_changes = %d\n", ((mainGame->chkIgnoreDeckChanges->isChecked()) ? 1 : 0)); fprintf(fp, "ignore_deck_changes = %d\n", ((mainGame->chkIgnoreDeckChanges->isChecked()) ? 1 : 0));
fprintf(fp, "default_ot = %d\n", gameConf.defaultOT);
fclose(fp); fclose(fp);
} }
void Game::ShowCardInfo(int code) { void Game::ShowCardInfo(int code) {
......
...@@ -45,6 +45,7 @@ struct Config { ...@@ -45,6 +45,7 @@ struct Config {
int separate_clear_button; int separate_clear_button;
int auto_search_limit; int auto_search_limit;
int chkIgnoreDeckChanges; int chkIgnoreDeckChanges;
int defaultOT;
}; };
struct DuelInfo { struct DuelInfo {
...@@ -385,6 +386,9 @@ public: ...@@ -385,6 +386,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;
...@@ -557,7 +561,7 @@ extern HostInfo game_info; ...@@ -557,7 +561,7 @@ extern HostInfo game_info;
#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
......
...@@ -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
......
...@@ -280,7 +280,7 @@ short Replay::ReadInt16() { ...@@ -280,7 +280,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;
......
This diff is collapsed.
...@@ -43,6 +43,7 @@ public: ...@@ -43,6 +43,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);
}; };
......
...@@ -361,16 +361,23 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) { ...@@ -361,16 +361,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) {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2; unsigned int deckerror = 0;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2; if(!host_info.no_check_deck) {
int res = host_info.no_check_deck ? false : deckManager.CheckLFList(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg); if(deck_error[dp->type]) {
if(res) { deckerror = (DECKERROR_UNKNOWNCARD << 28) + deck_error[dp->type];
} else {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2;
deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg);
}
}
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;
} }
...@@ -402,7 +409,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) { ...@@ -402,7 +409,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;
......
...@@ -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];
wchar_t fname[256]; size_t slen = 0;
myswprintf(fname, L"./single/%ls", open_file_name); if(open_file) {
slen = BufferIO::EncodeUTF8(fname, fname2); open_file = false;
if(!preload_script(pduel, fname2, slen)) { slen = BufferIO::EncodeUTF8(open_file_name, filename);
end_duel(pduel); if(!preload_script(pduel, filename, slen)) {
return 0; wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, filename);
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);
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,24 @@ int SingleMode::SinglePlayThread(void* param) { ...@@ -84,11 +100,24 @@ 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);
last_replay.WriteData(mainGame->dInfo.hostname, 40, false);
last_replay.WriteData(mainGame->dInfo.clientname, 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 +127,21 @@ int SingleMode::SinglePlayThread(void* param) { ...@@ -98,6 +127,21 @@ 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->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();
......
#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;
}; };
} }
......
...@@ -325,16 +325,23 @@ void TagDuel::PlayerReady(DuelPlayer* dp, bool is_ready) { ...@@ -325,16 +325,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) {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2; unsigned int deckerror = 0;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2; if(!host_info.no_check_deck) {
int res = host_info.no_check_deck ? false : deckManager.CheckLFList(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg); if(deck_error[dp->type]) {
if(res) { deckerror = (DECKERROR_UNKNOWNCARD << 28) + deck_error[dp->type];
} else {
bool allow_ocg = host_info.rule == 0 || host_info.rule == 2;
bool allow_tcg = host_info.rule == 1 || host_info.rule == 2;
deckerror = deckManager.CheckDeck(pdeck[dp->type], host_info.lflist, allow_ocg, allow_tcg);
}
}
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;
} }
...@@ -365,7 +372,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) { ...@@ -365,7 +372,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)
......
...@@ -52,6 +52,7 @@ protected: ...@@ -52,6 +52,7 @@ protected:
#endif #endif
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;
......
#[2017.10][2017.9 TCG][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1] #[2017.10][2017.11 TCG][2017.7][2017.4][2017.1][2016.10][2016.7][2016.4][2016.1][2015.10][2015.4][2015.1][2014.10][2014.7][2014.4][2014.2][2013.9][2017.9 TCG][2017.6 TCG][2017.3 TCG][2016.8 TCG][2016.4 TCG][2015.11 TCG][2015.7 TCG][2015.4 TCG][2015.1 TCG][2014.10 TCG][2014.7 TCG][2014.4 TCG][2014.1.1 TCG][2013.10.11 TCG][2013.3.1][2012.9.1][2012.3.1][2011.9.1]
!2017.10 !2017.10
#forbidden #forbidden
20663556 0 --イレカエル 20663556 0 --イレカエル
...@@ -153,7 +153,7 @@ ...@@ -153,7 +153,7 @@
66399653 2 --ユニオン格納庫 66399653 2 --ユニオン格納庫
40605147 2 --神の通告 40605147 2 --神の通告
!2017.9 TCG !2017.11 TCG
#forbidden #forbidden
27279764 0 --アポクリフォート・キラー 27279764 0 --アポクリフォート・キラー
20663556 0 --イレカエル 20663556 0 --イレカエル
...@@ -250,6 +250,8 @@ ...@@ -250,6 +250,8 @@
78872731 1 --十二獣モルモラット 78872731 1 --十二獣モルモラット
78868119 1 --深海のディーヴァ 78868119 1 --深海のディーヴァ
22499034 1 --真竜戦士イグニスH 22499034 1 --真竜戦士イグニスH
04474060 1 --SPYRAL GEAR-ドローン
78080961 1 --SPYRAL-ジーニアス
81275020 1 --SRベイゴマックス 81275020 1 --SRベイゴマックス
48063985 1 --聖霊獣騎 カンナホーク 48063985 1 --聖霊獣騎 カンナホーク
23434538 1 --増殖するG 23434538 1 --増殖するG
...@@ -268,6 +270,7 @@ ...@@ -268,6 +270,7 @@
70903634 1 --封印されし者の右腕 70903634 1 --封印されし者の右腕
44519536 1 --封印されし者の左足 44519536 1 --封印されし者の左足
08124921 1 --封印されし者の右足 08124921 1 --封印されし者の右足
09929398 1 --BF-朧影のゴウフウ
26674724 1 --ブリューナクの影霊衣 26674724 1 --ブリューナクの影霊衣
10802915 1 --魔界発現世行きデスガイド 10802915 1 --魔界発現世行きデスガイド
89463537 1 --ユニコールの影霊衣 89463537 1 --ユニコールの影霊衣
...@@ -294,6 +297,7 @@ ...@@ -294,6 +297,7 @@
70368879 1 --成金ゴブリン 70368879 1 --成金ゴブリン
22842126 1 --汎神の帝王 22842126 1 --汎神の帝王
53129443 1 --ブラック·ホール 53129443 1 --ブラック·ホール
73468603 1 --盆回し
15854426 1 --霞の谷の神風 15854426 1 --霞の谷の神風
77565204 1 --未来融合-フューチャー·フュージョン 77565204 1 --未来融合-フューチャー·フュージョン
58577036 1 --名推理 58577036 1 --名推理
...@@ -2606,6 +2610,187 @@ ...@@ -2606,6 +2610,187 @@
53582587 2 --激流葬 53582587 2 --激流葬
29401950 2 --奈落の落とし穴 29401950 2 --奈落の落とし穴
!2017.9 TCG
#forbidden
27279764 0 --アポクリフォート・キラー
20663556 0 --イレカエル
44910027 0 --ヴィクトリー・ドラゴン
20366274 0 --エルシャドール・ネフィリム
40044918 0 --E·HERO エアーマン
53804307 0 --焔征竜-ブラスター
68819554 0 --Emダメージ・ジャグラー
07563579 0 --Emヒグルミ
17330916 0 --EMモンキーボード
82301904 0 --混沌帝龍 -終焉の使者-
79106360 0 --カオスポッド
90411554 0 --巌征竜-レドックス
08903700 0 --儀式魔人リリーサー
17412721 0 --旧神ノーデン
65536818 0 --源竜星-ボウテンコウ
34124316 0 --サイバーポッド
88071625 0 --The tyrant NEPTUNE
48905153 0 --十二獣ドランシア
85115440 0 --十二獣ブルホーン
21593977 0 --処刑人-マキュラ
30539496 0 --真竜皇リトスアジムD
58984738 0 --真竜拳士ダイナマイトK
81122844 0 --発条空母ゼンマイティ
00581014 0 --ダイガスタ・エメラル
61468779 0 --地霊神グランソイル
56570271 0 --DHERO ディスクガイ
69015963 0 --デビル·フランケン
18326736 0 --星守の騎士 プトレマイオス
33184167 0 --同族感染ウィルス
90307777 0 --影霊衣の術士 シュリット
54719828 0 --No.16 色の支配者ショック·ルーラー
26400609 0 --瀑征竜-タイダル
78706415 0 --ファイバーポッド
93369354 0 --フィッシュボーグ-ガンナー
31178212 0 --マジェスペクター・ユニコーン
34206604 0 --魔導サイエンティスト
33508719 0 --メタモルポット
96782886 0 --メンタルマスター
03078576 0 --八汰烏
34086406 0 --ラヴァルバル·チェイン
89399912 0 --嵐征竜-テンペスト
46772449 0 --励輝士 ヴェルズビュート
41482598 0 --悪夢の蜃気楼
44763025 0 --いたずら好きな双子悪魔
19613556 0 --大嵐
17375316 0 --押収
35059553 0 --カイザーコロシアム
74191942 0 --苦渋の選択
42829885 0 --強引な番兵
45986603 0 --強奪
55144522 0 --強欲な壺
04031928 0 --心変わり
23557835 0 --次元融合
83764718 0 --死者蘇生
57953380 0 --生還の宝札
60682203 0 --大寒波
67616300 0 --チキンレース
48130397 0 --超融合
67169062 0 --貪欲な壺
27770341 0 --超再生能力
69243953 0 --蝶の短剣-エルマ
72892473 0 --手札抹殺
79571449 0 --天使の施し
42703248 0 --ハリケーン
18144506 0 --ハーピィの羽根帚
70828912 0 --早すぎた埋葬
34906152 0 --マスドライバー
46448938 0 --魔導書の神判
46411259 0 --突然変異
85602018 0 --遺言状
27174286 0 --異次元からの帰還
93016201 0 --王宮の弾圧
41420027 0 --神の宣告
05851097 0 --虚無空間
57585212 0 --自爆スイッチ
03280747 0 --第六感
64697231 0 --ダスト·シュート
35316708 0 --刻の封印
80604091 0 --血の代償
28566710 0 --ラストバトル!
#limit
85103922 1 --アーティファクト-モラルタ
64034255 1 --A·ジェネクス·バードマン
45222299 1 --イビリチュア·ガストクラーケ
11877465 1 --イビリチュア·マインドオーガス
99177923 1 --インフェルニティ·デーモン
68184115 1 --甲虫装機 ダンセル
69207766 1 --甲虫装機 ホーネット
27552504 1 --永遠の淑女 ベアトリーチェ
65518099 1 --クリフォート・ツール
38572779 1 --幻創のミセラサウルス
55885348 1 --Kozmo-ダークシミター
78872731 1 --十二獣モルモラット
78868119 1 --深海のディーヴァ
22499034 1 --真竜戦士イグニスH
81275020 1 --SRベイゴマックス
48063985 1 --聖霊獣騎 カンナホーク
23434538 1 --増殖するG
65192027 1 --ダーク·アームド·ドラゴン
15341821 1 --ダンディライオン
96570609 1 --天帝アイテール
16226786 1 --深淵の暗殺者
80344569 1 --N·グラン·モール
18239909 1 --爆竜剣士イグニスターP
57143342 1 --彼岸の悪鬼 ガトルホッグ
20758643 1 --彼岸の悪鬼 グラバースニッチ
70583986 1 --氷結界の虎王ドゥローレン
52687916 1 --氷結界の龍 トリシューラ
33396948 1 --封印されしエクゾディア
07902349 1 --封印されし者の左腕
70903634 1 --封印されし者の右腕
44519536 1 --封印されし者の左足
08124921 1 --封印されし者の右足
26674724 1 --ブリューナクの影霊衣
10802915 1 --魔界発現世行きデスガイド
89463537 1 --ユニコールの影霊衣
88264978 1 --レッドアイズ·ダークネスメタルドラゴン
33782437 1 --一時休戦
66957584 1 --インフェルニティガン
72405967 1 --王家の生け贄
81439173 1 --おろかな埋葬
67723438 1 --緊急テレポート
45305419 1 --継承の印
17639150 1 --機殻の生贄
99330325 1 --妨げられた壊獣の眠り
12580477 1 --サンダー·ボルト
95308449 1 --終焉のカウントダウン
74845897 1 --真炎の爆発
35125879 1 --真竜皇の復活
37520316 1 --精神操作
32807846 1 --増援
54447022 1 --ソウル・チャージ
14087893 1 --月の書
81674782 1 --次元の裂け目
79844764 1 --帝王の烈旋
11110587 1 --隣の芝刈り
70368879 1 --成金ゴブリン
22842126 1 --汎神の帝王
53129443 1 --ブラック·ホール
15854426 1 --霞の谷の神風
77565204 1 --未来融合-フューチャー·フュージョン
58577036 1 --名推理
43040603 1 --モンスターゲート
23171610 1 --リミッター解除
14733538 1 --竜呼相打つ
27970830 1 --六武の門
02295440 1 --ワン·フォー·ワン
09059700 1 --インフェルニティ・バリア
61740673 1 --王宮の勅命
84749824 1 --神の警告
94192409 1 --強制脱出装置
53582587 1 --激流葬
82732705 1 --スキルドレイン
73599290 1 --ソウルドレイン
29401950 1 --奈落の落とし穴
83555666 1 --破壊輪
17078030 1 --光の護封壁
30241314 1 --マクロコスモス
32723153 1 --マジカル·エクスプロージョン
54974237 1 --闇のデッキ破壊ウイルス
#semi limit
85087012 2 --カードガンナー
74311226 2 --海皇の竜騎隊
72989439 2 --カオス·ソルジャー -開闢の使者-
59297550 2 --ゼンマイマジシャン
90953320 2 --TG ハイパー·ライブラリアン
28297833 2 --ネクロフェイス
50321796 2 --氷結界の龍 ブリューナク
41386308 2 --マスマティシャン
71564252 2 --ライオウ
92746535 2 --竜剣士ラスターP
48976825 2 --異次元からの埋葬
06417578 2 --神の写し身との接触
96729612 2 --儀式の準備
87910978 2 --洗脳-ブレインコントロール
91623717 2 --連鎖爆撃
29843091 2 --おジャマトリオ
36468556 2 --停戦協定
!2017.6 TCG !2017.6 TCG
#forbidden #forbidden
27279764 0 --アポクリフォート・キラー 27279764 0 --アポクリフォート・キラー
......
Subproject commit ac6ff6e3d12b54d260612fc7223469110e32fbb5 Subproject commit 2ede4eddc9456e468e2193c06405ee1ef3a6ae37
Subproject commit 9d747af65bc6017d6f7327bbabba3d4e6d0b31b6 Subproject commit 14f463531b85d36bdbae8252a71905c1ef61a574
...@@ -319,6 +319,7 @@ ...@@ -319,6 +319,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 怪兽
...@@ -382,12 +383,20 @@ ...@@ -382,12 +383,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 +512,8 @@ ...@@ -503,6 +512,8 @@
!counter 0x1041 捕食指示物 !counter 0x1041 捕食指示物
!counter 0x42 指示物(爆竹鬼) !counter 0x42 指示物(爆竹鬼)
!counter 0x43 缺陷指示物 !counter 0x43 缺陷指示物
!counter 0x44 指示物(弹带城壁龙)
!counter 0x1045 鳞粉指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -850,3 +861,10 @@ ...@@ -850,3 +861,10 @@
!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 武装龙 アームド・ドラゴン
...@@ -27,3 +27,4 @@ separate_clear_button = 1 ...@@ -27,3 +27,4 @@ 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
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