Commit 2ce36751 authored by mercury233's avatar mercury233

Merge branch 'fh' into ai

parents ffaa80fa 9e9b5d8b
......@@ -340,6 +340,7 @@ void ClientField::ClearCommandFlag() {
(*cit)->cmdFlag = 0;
for(cit = attackable_cards.begin(); cit != attackable_cards.end(); ++cit)
(*cit)->cmdFlag = 0;
conti_cards.clear();
deck_act = false;
extra_act = false;
grave_act = false;
......
......@@ -69,6 +69,9 @@ void DeckBuilder::Initialize() {
mainGame->btnLeaveGame->setVisible(true);
mainGame->btnLeaveGame->setText(dataManager.GetSysString(1306));
mainGame->btnSideOK->setVisible(false);
mainGame->btnSideShuffle->setVisible(false);
mainGame->btnSideSort->setVisible(false);
mainGame->btnSideReload->setVisible(false);
filterList = deckManager._lfList[0].content;
mainGame->cbDBLFList->setSelected(0);
ClearSearch();
......@@ -216,6 +219,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if(mainGame->chkCategory[i]->isChecked())
filter_effect |= filter;
mainGame->HideElement(mainGame->wCategories);
InstantSearch();
break;
}
case BUTTON_SIDE_OK: {
......@@ -238,6 +242,10 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
DuelClient::SendBufferToServer(CTOS_UPDATE_DECK, deckbuf, pdeck - deckbuf);
break;
}
case BUTTON_SIDE_RELOAD: {
deckManager.LoadDeck(mainGame->cbDeckSelect->getItem(mainGame->cbDeckSelect->getSelected()));
break;
}
case BUTTON_MSG_OK: {
mainGame->HideElement(mainGame->wMessage);
mainGame->actionSignal.Set();
......@@ -308,6 +316,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
if (mainGame->btnMark[7]->isPressed())
filter_marks |= 0004;
mainGame->HideElement(mainGame->wLinkMarks);
InstantSearch();
break;
}
}
......@@ -328,8 +337,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_KEYWORD: {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter();
InstantSearch();
break;
}
}
......@@ -446,6 +454,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
}
InstantSearch();
break;
}
case COMBOBOX_SORTTYPE: {
......@@ -462,8 +471,13 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
mainGame->ebDefense->setEnabled(true);
}
}
InstantSearch();
break;
}
case COMBOBOX_ATTRIBUTE:
case COMBOBOX_RACE:
case COMBOBOX_LIMIT:
InstantSearch();
}
}
default: break;
......@@ -854,6 +868,10 @@ void DeckBuilder::FilterCards() {
}
SortList();
}
void DeckBuilder::InstantSearch() {
if(mainGame->gameConf.auto_search_limit >= 0 && (wcslen(mainGame->ebCardName->getText()) >= mainGame->gameConf.auto_search_limit))
StartFilter();
}
void DeckBuilder::ClearSearch() {
mainGame->cbCardType->setSelected(0);
mainGame->cbCardType2->setSelected(0);
......
......@@ -17,6 +17,7 @@ public:
void FilterCards();
void StartFilter();
void ClearFilter();
void InstantSearch();
void ClearSearch();
void SortList();
......
#include "deck_manager.h"
#include "data_manager.h"
#include "network.h"
#include "game.h"
#include <algorithm>
......@@ -61,7 +62,7 @@ wchar_t* DeckManager::GetLFListName(int lfhash) {
}
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>* list = 0;
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_
if(!list)
return 0;
int dc = 0;
if(deck.main.size() < 40 || deck.main.size() > 60 || deck.extra.size() > 15 || deck.side.size() > 15)
return 1;
if(deck.main.size() < 40 || deck.main.size() > 60)
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) {
code_pointer cit = deck.main[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2)))
return cit->first;
if(!allow_ocg && (cit->second.ot == 0x1))
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))
return 1;
return (DECKERROR_EXTRACOUNT << 28);
int code = cit->second.alias ? cit->second.alias : cit->first;
ccount[code]++;
dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second))
return cit->first;
if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first;
}
for(size_t i = 0; i < deck.extra.size(); ++i) {
code_pointer cit = deck.extra[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2)))
return cit->first;
if(!allow_ocg && (cit->second.ot == 0x1))
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;
ccount[code]++;
dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second))
return cit->first;
if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first;
}
for(size_t i = 0; i < deck.side.size(); ++i) {
code_pointer cit = deck.side[i];
if((!allow_ocg && (cit->second.ot == 0x1)) || (!allow_tcg && (cit->second.ot == 0x2)))
return cit->first;
if(!allow_ocg && (cit->second.ot == 0x1))
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;
ccount[code]++;
dc = ccount[code];
if(dc > 3)
return (DECKERROR_CARDCOUNT << 28) + cit->first;
auto it = list->find(code);
if(dc > 3 || (it != list->end() && dc > it->second))
return cit->first;
if(it != list->end() && dc > it->second)
return (DECKERROR_LFLIST << 28) + cit->first;
}
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();
int code;
int errorcode = 0;
CardData cd;
for(int i = 0; i < mainc; ++i) {
code = dbuf[i];
if(!dataManager.GetData(code, &cd))
if(!dataManager.GetData(code, &cd)) {
errorcode = code;
continue;
}
if(cd.type & TYPE_TOKEN)
continue;
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) {
}
for(int i = 0; i < sidec; ++i) {
code = dbuf[mainc + i];
if(!dataManager.GetData(code, &cd))
if(!dataManager.GetData(code, &cd)) {
errorcode = code;
continue;
}
if(cd.type & TYPE_TOKEN)
continue;
if(deck.side.size() < 15)
deck.side.push_back(dataManager.GetCodePointer(code)); //verified by GetData()
}
return errorcode;
}
bool DeckManager::LoadSide(Deck& deck, int* dbuf, int mainc, int sidec) {
std::unordered_map<int, int> pcount;
......
......@@ -37,8 +37,8 @@ public:
void LoadLFList();
wchar_t* GetLFListName(int lfhash);
int CheckLFList(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg);
void LoadDeck(Deck& deck, int* dbuf, int mainc, int sidec);
int CheckDeck(Deck& deck, int lfhash, bool allow_ocg, bool allow_tcg);
int LoadDeck(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);
bool LoadDeck(const wchar_t* file);
......
......@@ -1045,7 +1045,16 @@ void Game::DrawThumb(code_pointer cp, position2di pos, std::unordered_map<int, i
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) {
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);
......
......@@ -216,13 +216,52 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
}
case ERRMSG_DECKERROR: {
mainGame->gMutex.Lock();
if(pkt->code == 1)
mainGame->env->addMessageBox(L"", dataManager.GetSysString(1406));
else {
wchar_t msgbuf[256];
myswprintf(msgbuf, dataManager.GetSysString(1407), dataManager.GetName(pkt->code));
mainGame->env->addMessageBox(L"", msgbuf);
unsigned int code = pkt->code & 0xFFFFFFF;
int flag = pkt->code >> 28;
wchar_t msgbuf[256];
switch(flag)
{
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->gMutex.Unlock();
break;
......@@ -282,7 +321,11 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wDeckEdit->setVisible(false);
mainGame->wFilter->setVisible(false);
mainGame->wSort->setVisible(false);
mainGame->stTip->setVisible(false);
mainGame->btnSideOK->setVisible(true);
mainGame->btnSideShuffle->setVisible(true);
mainGame->btnSideSort->setVisible(true);
mainGame->btnSideReload->setVisible(true);
if(mainGame->dInfo.player_type < 7)
mainGame->btnLeaveGame->setVisible(false);
mainGame->btnSpectatorSwap->setVisible(false);
......@@ -484,6 +527,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
mainGame->wInfos->setVisible(true);
mainGame->wPhase->setVisible(true);
mainGame->btnSideOK->setVisible(false);
mainGame->btnSideShuffle->setVisible(false);
mainGame->btnSideSort->setVisible(false);
mainGame->btnSideReload->setVisible(false);
mainGame->btnPhaseStatus->setVisible(false);
mainGame->btnBP->setVisible(false);
mainGame->btnM2->setVisible(false);
......@@ -642,7 +688,6 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
}
wchar_t msg[256];
BufferIO::CopyWStr(pkt->msg, msg, 256);
msg[(len - 3) / 2] = 0;
mainGame->gMutex.Lock();
mainGame->AddChatMsg(msg, player);
mainGame->gMutex.Unlock();
......@@ -977,25 +1022,37 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
case MSG_SELECT_BATTLECMD: {
/*int selecting_player = */BufferIO::ReadInt8(pbuf);
int /*code, */desc, count, con, loc, seq/*, diratt*/;
int code, desc, count, con, loc, seq/*, diratt*/;
ClientCard* pcard;
mainGame->dField.activatable_cards.clear();
mainGame->dField.activatable_descs.clear();
count = BufferIO::ReadInt8(pbuf);
for (int i = 0; i < count; ++i) {
/*code = */BufferIO::ReadInt32(pbuf);
code = BufferIO::ReadInt32(pbuf);
con = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
loc = BufferIO::ReadInt8(pbuf);
seq = BufferIO::ReadInt8(pbuf);
desc = BufferIO::ReadInt32(pbuf);
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_descs.push_back(std::make_pair(desc, 0));
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.activatable_descs.push_back(std::make_pair(desc, flag));
if(flag == EDESC_OPERATION) {
pcard->chain_code = code;
mainGame->dField.conti_cards.push_back(pcard);
mainGame->dField.conti_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();
count = BufferIO::ReadInt8(pbuf);
......@@ -1106,13 +1163,25 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
seq = BufferIO::ReadInt8(pbuf);
desc = BufferIO::ReadInt32(pbuf);
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_descs.push_back(std::make_pair(desc, 0));
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.activatable_descs.push_back(std::make_pair(desc, flag));
if(flag == EDESC_OPERATION) {
pcard->chain_code = code;
mainGame->dField.conti_cards.push_back(pcard);
mainGame->dField.conti_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)) {
mainGame->btnBP->setVisible(true);
......@@ -1469,6 +1538,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int count = BufferIO::ReadInt8(pbuf);
mainGame->dField.selectable_cards.clear();
mainGame->dField.selected_cards.clear();
mainGame->dField.select_panalmode = false;
int c, l, s, t;
unsigned int code;
ClientCard* pcard;
......@@ -3286,7 +3356,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
ClientCard* xcard = new ClientCard;
ccard->overlayed.push_back(xcard);
mainGame->dField.overlay_cards.insert(xcard);
mainGame->gMutex.Unlock();
xcard->overlayTarget = ccard;
xcard->location = 0x80;
xcard->sequence = ccard->overlayed.size() - 1;
......@@ -3440,7 +3509,7 @@ void DuelClient::SendResponse() {
}
}
if(mainGame->dInfo.isSingleMode) {
SingleMode::SetResponse(response_buf);
SingleMode::SetResponse(response_buf, response_len);
mainGame->singleSignal.Set();
} else {
mainGame->dInfo.time_player = 2;
......
......@@ -14,7 +14,7 @@
#include <dirent.h>
#endif
const unsigned short PRO_VERSION = 0x133D;
const unsigned short PRO_VERSION = 0x1340;
namespace ygo {
......@@ -128,6 +128,7 @@ bool Game::Initialize() {
cbRule->addItem(dataManager.GetSysString(1241));
cbRule->addItem(dataManager.GetSysString(1242));
cbRule->addItem(dataManager.GetSysString(1243));
cbRule->setSelected(gameConf.defaultOT - 1);
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->addItem(dataManager.GetSysString(1244));
......@@ -438,6 +439,12 @@ bool Game::Initialize() {
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->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->setLargeStep(10);
......@@ -463,7 +470,7 @@ bool Game::Initialize() {
cbCardType2->setMaxSelectionRows(10);
cbCardType2->addItem(dataManager.GetSysString(1310), 0);
env->addStaticText(dataManager.GetSysString(1315), rect<s32>(205, 2 + 25 / 6, 280, 22 + 25 / 6), false, false, wFilter);
cbLimit = env->addComboBox(rect<s32>(260, 25 / 6, 390, 20 + 25 / 6), wFilter, -1);
cbLimit = env->addComboBox(rect<s32>(260, 25 / 6, 390, 20 + 25 / 6), wFilter, COMBOBOX_LIMIT);
cbLimit->setMaxSelectionRows(10);
cbLimit->addItem(dataManager.GetSysString(1310));
cbLimit->addItem(dataManager.GetSysString(1316));
......@@ -474,13 +481,13 @@ bool Game::Initialize() {
cbLimit->addItem(dataManager.GetSysString(1242));
cbLimit->addItem(dataManager.GetSysString(1243));
env->addStaticText(dataManager.GetSysString(1319), rect<s32>(10, 22 + 50 / 6, 70, 42 + 50 / 6), false, false, wFilter);
cbAttribute = env->addComboBox(rect<s32>(60, 20 + 50 / 6, 190, 40 + 50 / 6), wFilter, -1);
cbAttribute = env->addComboBox(rect<s32>(60, 20 + 50 / 6, 190, 40 + 50 / 6), wFilter, COMBOBOX_ATTRIBUTE);
cbAttribute->setMaxSelectionRows(10);
cbAttribute->addItem(dataManager.GetSysString(1310), 0);
for(int filter = 0x1; filter != 0x80; filter <<= 1)
cbAttribute->addItem(dataManager.FormatAttribute(filter), filter);
env->addStaticText(dataManager.GetSysString(1321), rect<s32>(10, 42 + 75 / 6, 70, 62 + 75 / 6), false, false, wFilter);
cbRace = env->addComboBox(rect<s32>(60, 40 + 75 / 6, 190, 60 + 75 / 6), wFilter, -1);
cbRace = env->addComboBox(rect<s32>(60, 40 + 75 / 6, 190, 60 + 75 / 6), wFilter, COMBOBOX_RACE);
cbRace->setMaxSelectionRows(10);
cbRace->addItem(dataManager.GetSysString(1310), 0);
for(int filter = 0x1; filter != 0x2000000; filter <<= 1)
......@@ -935,6 +942,7 @@ void Game::LoadConfig() {
gameConf.separate_clear_button = 1;
gameConf.auto_search_limit = -1;
gameConf.chkIgnoreDeckChanges = 0;
gameConf.defaultOT = 1;
while(fgets(linebuf, 256, fp)) {
sscanf(linebuf, "%s = %s", strbuf, valbuf);
if(!strcmp(strbuf, "antialias")) {
......@@ -993,6 +1001,8 @@ void Game::LoadConfig() {
gameConf.auto_search_limit = atoi(valbuf);
} else if(!strcmp(strbuf, "ignore_deck_changes")) {
gameConf.chkIgnoreDeckChanges = atoi(valbuf);
} else if(!strcmp(strbuf, "default_ot")) {
gameConf.defaultOT = atoi(valbuf);
} else {
// options allowing multiple words
sscanf(linebuf, "%s = %240[^\n]", strbuf, valbuf);
......@@ -1051,6 +1061,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 = %d\n", gameConf.auto_search_limit);
fprintf(fp, "ignore_deck_changes = %d\n", ((mainGame->chkIgnoreDeckChanges->isChecked()) ? 1 : 0));
fprintf(fp, "default_ot = %d\n", gameConf.defaultOT);
fclose(fp);
}
void Game::ShowCardInfo(int code) {
......
......@@ -40,6 +40,7 @@ struct Config {
int separate_clear_button;
int auto_search_limit;
int chkIgnoreDeckChanges;
int defaultOT;
};
struct DuelInfo {
......@@ -374,6 +375,9 @@ public:
irr::gui::IGUIButton* btnDeleteDeck;
irr::gui::IGUIButton* btnSaveDeckAs;
irr::gui::IGUIButton* btnSideOK;
irr::gui::IGUIButton* btnSideShuffle;
irr::gui::IGUIButton* btnSideSort;
irr::gui::IGUIButton* btnSideReload;
irr::gui::IGUIEditBox* ebDeckname;
//filter
irr::gui::IGUIStaticText* wFilter;
......@@ -540,7 +544,7 @@ extern Game* mainGame;
#define BUTTON_SAVE_DECK 304
#define BUTTON_SAVE_DECK_AS 305
#define BUTTON_DELETE_DECK 306
//#define BUTTON_DBEXIT 307
#define BUTTON_SIDE_RELOAD 307
#define BUTTON_SORT_DECK 308
#define BUTTON_SIDE_OK 309
#define BUTTON_SHUFFLE_DECK 310
......@@ -551,6 +555,8 @@ extern Game* mainGame;
#define SCROLL_FILTER 315
#define EDITBOX_KEYWORD 316
#define BUTTON_CLEAR_FILTER 317
#define COMBOBOX_ATTRIBUTE 318
#define COMBOBOX_RACE 319
#define BUTTON_REPLAY_START 320
#define BUTTON_REPLAY_PAUSE 321
#define BUTTON_REPLAY_STEP 322
......@@ -564,6 +570,7 @@ extern Game* mainGame;
#define BUTTON_CANCEL_SINGLEPLAY 352
#define CHECKBOX_AUTO_SEARCH 360
#define COMBOBOX_SORTTYPE 370
#define COMBOBOX_LIMIT 371
#define BUTTON_MARKS_FILTER 380
#define BUTTON_MARKERS_OK 381
......
......@@ -2,6 +2,9 @@
#include "game.h"
#include "data_manager.h"
#include <event2/thread.h>
#ifdef __APPLE__
#import <CoreFoundation/CoreFoundation.h>
#endif
int enable_log = 0;
bool exit_on_return = false;
......@@ -36,6 +39,15 @@ int main(int argc, char* argv[]) {
#ifndef _WIN32
setlocale(LC_CTYPE, "UTF-8");
#endif
#ifdef __APPLE__
CFURLRef bundle_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef bundle_base_url = CFURLCreateCopyDeletingLastPathComponent(NULL, bundle_url);
CFRelease(bundle_url);
CFStringRef path = CFURLCopyFileSystemPath(bundle_base_url, kCFURLPOSIXPathStyle);
CFRelease(bundle_base_url);
chdir(CFStringGetCStringPtr(path, kCFStringEncodingUTF8));
CFRelease(path);
#endif //__APPLE__
#ifdef _WIN32
#ifndef _DEBUG
wchar_t exepath[MAX_PATH];
......
......@@ -207,6 +207,15 @@ public:
#define ERRMSG_SIDEERROR 0x3
#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_MATCH 0x1
#define MODE_TAG 0x2
......
......@@ -226,7 +226,7 @@ short Replay::ReadInt16() {
if(!is_replaying)
return -1;
short ret = *((short*)pdata);
pdata += 4;
pdata += 2;
return ret;
}
char Replay::ReadInt8() {
......
......@@ -9,6 +9,7 @@ namespace ygo {
#define REPLAY_COMPRESSED 0x1
#define REPLAY_TAG 0x2
#define REPLAY_DECODED 0x4
#define REPLAY_SINGLE_MODE 0x8
struct ReplayHeader {
unsigned int id;
......
This diff is collapsed.
......@@ -43,6 +43,7 @@ public:
static void ReplayRefreshDeck(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 ReplayReload();
static int MessageHandler(long fduel, int type);
};
......
......@@ -252,16 +252,23 @@ void SingleDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
if(ready[dp->type] == is_ready)
return;
if(is_ready) {
bool allow_ocg = host_info.rule == 0 || 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);
if(res) {
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_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;
scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc);
STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR;
scem.code = res;
scem.code = deckerror;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
......@@ -287,7 +294,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf);
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 {
if(deckManager.LoadSide(pdeck[dp->type], (int*)deckbuf, mainc, sidec)) {
ready[dp->type] = true;
......
......@@ -46,6 +46,7 @@ protected:
DuelPlayer* pplayer[2];
bool ready[2];
Deck pdeck[2];
int deck_error[2];
unsigned char hand_result[2];
unsigned char last_response;
std::set<DuelPlayer*> observers;
......
......@@ -10,6 +10,7 @@ namespace ygo {
long SingleMode::pduel = 0;
bool SingleMode::is_closing = false;
bool SingleMode::is_continuing = false;
Replay SingleMode::last_replay;
static byte buffer[0x20000];
......@@ -23,23 +24,18 @@ void SingleMode::StopPlay(bool is_exiting) {
mainGame->actionSignal.Set();
mainGame->singleSignal.Set();
}
void SingleMode::SetResponse(unsigned char* resp) {
void SingleMode::SetResponse(unsigned char* resp, unsigned int len) {
if(!pduel)
return;
last_replay.WriteInt8(len);
last_replay.WriteData(resp, len);
set_responseb(pduel, resp);
}
int SingleMode::SinglePlayThread(void* param) {
char fname2[256];
size_t slen;
if(open_file) {
slen = BufferIO::EncodeUTF8(open_file_name, fname2);
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);
}
const int start_lp = 8000;
const int start_hand = 5;
const int draw_count = 1;
const int opt = 0;
mtrandom rnd;
time_t seed = time(0);
rnd.reset(seed);
......@@ -47,24 +43,44 @@ int SingleMode::SinglePlayThread(void* param) {
set_card_reader((card_reader)DataManager::CardReader);
set_message_handler((message_handler)MessageHandler);
pduel = create_duel(rnd.rand());
set_player_info(pduel, 0, 8000, 5, 1);
set_player_info(pduel, 1, 8000, 5, 1);
mainGame->dInfo.lp[0] = 8000;
mainGame->dInfo.lp[1] = 8000;
set_player_info(pduel, 0, start_lp, start_hand, draw_count);
set_player_info(pduel, 1, start_lp, start_hand, draw_count);
mainGame->dInfo.lp[0] = start_lp;
mainGame->dInfo.lp[1] = start_lp;
myswprintf(mainGame->dInfo.strLP[0], L"%d", mainGame->dInfo.lp[0]);
myswprintf(mainGame->dInfo.strLP[1], L"%d", mainGame->dInfo.lp[1]);
BufferIO::CopyWStr(mainGame->ebNickName->getText(), mainGame->dInfo.hostname, 20);
mainGame->dInfo.clientname[0] = 0;
mainGame->dInfo.turn = 0;
if(!preload_script(pduel, fname2, slen)) {
wchar_t fname[256];
myswprintf(fname, L"./single/%ls", open_file_name);
slen = BufferIO::EncodeUTF8(fname, fname2);
if(!preload_script(pduel, fname2, slen)) {
end_duel(pduel);
return 0;
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];
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->HideElement(mainGame->wSinglePlay);
mainGame->wCardImg->setVisible(true);
......@@ -84,11 +100,24 @@ int SingleMode::SinglePlayThread(void* param) {
mainGame->dInfo.isSingleMode = true;
mainGame->device->setEventReceiver(&mainGame->dField);
mainGame->gMutex.Unlock();
start_duel(pduel, 0);
char engineBuffer[0x1000];
is_closing = false;
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) {
int result = process(pduel);
len = result & 0xffff;
......@@ -98,6 +127,21 @@ int SingleMode::SinglePlayThread(void* param) {
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);
if(!is_closing) {
mainGame->gMutex.Lock();
......
#ifndef SINGLE_MODE_H
#define SINGLE_MODE_H
#include "config.h"
#include "data_manager.h"
#include "deck_manager.h"
#include "../ocgcore/mtrandom.h"
#include "replay.h"
namespace ygo {
......@@ -17,7 +14,7 @@ private:
public:
static bool StartPlay();
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 bool SinglePlayAnalyze(char* msg, unsigned int len);
......@@ -31,6 +28,9 @@ public:
static byte* ScriptReader(const char* script_name, int* slen);
static int MessageHandler(long fduel, int type);
protected:
static Replay last_replay;
};
}
......
......@@ -222,16 +222,23 @@ void TagDuel::PlayerReady(DuelPlayer* dp, bool is_ready) {
if(dp->type > 3 || ready[dp->type] == is_ready)
return;
if(is_ready) {
bool allow_ocg = host_info.rule == 0 || 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);
if(res) {
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_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;
scpc.status = (dp->type << 4) | PLAYERCHANGE_NOTREADY;
NetServer::SendPacketToPlayer(dp, STOC_HS_PLAYER_CHANGE, scpc);
STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR;
scem.code = res;
scem.code = deckerror;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
......@@ -256,7 +263,7 @@ void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
char* deckbuf = (char*)pdata;
int mainc = 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) {
if(dp != host_player)
......
......@@ -48,6 +48,7 @@ protected:
std::set<DuelPlayer*> observers;
bool ready[4];
Deck pdeck[4];
int deck_error[4];
unsigned char hand_result[2];
unsigned char last_response;
Replay last_replay;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Subproject commit 82fb81ad35f999cb1c5d97273d9b429faea99625
Subproject commit b12628811d5f449ab5e0b2242bfc6d474ceb5211
Subproject commit 1d9275b1479a82386d7871f4d9275e8986657157
Subproject commit 5672ac76978214f48d297bb5c49ab9fa5b00f2ef
......@@ -100,6 +100,7 @@
!system 530 请选择对方的卡
!system 531 请选择上级召唤用需要解放的怪兽
!system 532 请选择要取除超量素材的怪兽
!system 533 请选择连接召唤的素材
!system 549 请选择攻击的对象
!system 550 请选择要发动的效果
!system 551 请选择效果的对象
......@@ -318,6 +319,7 @@
!system 1306 退出编辑
!system 1307 打乱
!system 1308 删除
!system 1309 重置
!system 1310 (无)
!system 1311 种类:
!system 1312 怪兽
......@@ -381,12 +383,20 @@
!system 1404 密码错误。
!system 1405 主机拒绝了连接。
!system 1406 无效卡组。
!system 1407 「%ls」的数量不符合当前设定。
!system 1407 「%ls」的数量不符合当前禁限卡表设定。
!system 1408 更换副卡组失败。
!system 1409 等待更换副卡组中...
!system 1410 卡组数量与先前不符合。
!system 1411 版本不匹配(%X.0%X.%X)。
!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 1501 录像结束。
!system 1502 连接已断开。
......@@ -502,6 +512,8 @@
!counter 0x1041 捕食指示物
!counter 0x42 指示物(爆竹鬼)
!counter 0x43 缺陷指示物
!counter 0x44 指示物(弹带城壁龙)
!counter 0x1045 鳞粉指示物
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......@@ -584,6 +596,7 @@
!setname 0x3b 真红眼 レッドアイズ
!setname 0x3c 爬虫妖 レプティレス
!setname 0x3d 六武众 六武衆
!setname 0x103d 影六武众 影六武衆
!setname 0x3e 异虫 ワーム
!setname 0x3f 救世 セイヴァー
!setname 0x40 被封印 封印されし
......@@ -810,8 +823,8 @@
#!setname 0xec 魔界 魔界
!setname 0x10ec 魔界剧团 魔界劇団
!setname 0x20ec 魔界台本 魔界台本
!setname 0xed底恐魔 Subterror
!setname 0x10ed底恐魔 巨魔 Subterror Behemoth
!setname 0xed中族 サブテラー
!setname 0x10ed中族邪界 サブテラーマリス
!setname 0xee 秘旋谍 SPYRAL
!setname 0x10ee 秘旋谍装备 SPYRAL GEAR
!setname 0x20ee 秘旋谍任务 SPYRAL MISSION
......@@ -843,5 +856,15 @@
!setname 0x103 幻变骚灵 オルターガイスト
!setname 0x104 机怪虫 クローラー
!setname 0x105 玄化 メタファイズ
!setname 0x106 复仇死灵 Vendread
!setname 0x107 F.A.
!setname 0x106 复仇死者 ヴェンデット
!setname 0x107 方程式运动员 F.A.
!setname 0x108 魔弹 魔弾
!setname 0x109 天气 天気
!setname 0x10a 珀耳修斯 パーシアス
!setname 0x10b 廷达魔三角 ティンダングル
!setname 0x10c 机界骑士 ジャックナイツ
!setname 0x10d 魔导兽 魔導獣
!setname 0x10e 进化药 進化薬
!setname 0x10f 枪管 ヴァレル
!setname 0x110 眼纳祭神 アイズ・サクリファイス
!setname 0x111 武装龙 アームド・ドラゴン
......@@ -27,3 +27,4 @@ separate_clear_button = 1
#auto_search_limit >= 0: Start search automatically when the user enters N chars.
auto_search_limit = -1
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