Commit edca1eff authored by mercury233's avatar mercury233

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

parents 895e94cd 988e5916
......@@ -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();
......@@ -243,6 +246,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();
......
#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);
......
......@@ -217,13 +217,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;
......@@ -285,6 +324,9 @@ void DuelClient::HandleSTOCPacketLan(char* data, unsigned int len) {
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);
......@@ -487,6 +529,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);
......@@ -3368,7 +3413,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;
......@@ -3522,7 +3566,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;
......
......@@ -479,6 +479,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);
......@@ -1035,12 +1041,12 @@ void Game::LoadConfig() {
gameConf.separate_clear_button = 1;
gameConf.auto_search_limit = 0;
gameConf.chkIgnoreDeckChanges = 0;
gameConf.defaultOT = 1;
gameConf.enable_sound = true;
gameConf.sound_volume = 0.5;
gameConf.enable_music = true;
gameConf.music_volume = 0.5;
gameConf.music_mode = 1;
gameConf.defaultOT = 1;
while(fgets(linebuf, 256, fp)) {
sscanf(linebuf, "%s = %s", strbuf, valbuf);
if(!strcmp(strbuf, "antialias")) {
......@@ -1099,6 +1105,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 if(!strcmp(strbuf, "enable_sound")) {
gameConf.enable_sound = atoi(valbuf) > 0;
} else if(!strcmp(strbuf, "sound_volume")) {
......@@ -1109,8 +1117,6 @@ void Game::LoadConfig() {
gameConf.music_volume = atof(valbuf) / 100;
} else if(!strcmp(strbuf, "music_mode")) {
gameConf.music_mode = atoi(valbuf);
} else if(!strcmp(strbuf, "default_ot")) {
gameConf.defaultOT = atoi(valbuf);
} else {
// options allowing multiple words
sscanf(linebuf, "%s = %240[^\n]", strbuf, valbuf);
......@@ -1169,6 +1175,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);
fprintf(fp, "enable_sound = %d\n", ((mainGame->chkEnableSound->isChecked()) ? 1 : 0));
fprintf(fp, "enable_music = %d\n", ((mainGame->chkEnableMusic->isChecked()) ? 1 : 0));
fprintf(fp, "#Volume of sound and music, between 0 and 100\n");
......@@ -1179,7 +1186,6 @@ void Game::SaveConfig() {
if(vol < 0) vol = 0; else if(vol > 100) vol = 100;
fprintf(fp, "music_volume = %d\n", vol);
fprintf(fp, "music_mode = %d\n", ((mainGame->chkMusicMode->isChecked()) ? 1 : 0));
fprintf(fp, "default_ot = %d\n", gameConf.defaultOT);
fclose(fp);
}
void Game::PlaySoundEffect(int sound) {
......
......@@ -40,12 +40,12 @@ struct Config {
int separate_clear_button;
int auto_search_limit;
int chkIgnoreDeckChanges;
int defaultOT;
bool enable_sound;
bool enable_music;
double sound_volume;
double music_volume;
int music_mode;
int defaultOT;
};
struct DuelInfo {
......@@ -394,6 +394,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;
......@@ -565,7 +568,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
......
......@@ -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);
......@@ -85,11 +101,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;
......@@ -99,6 +128,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;
......
......@@ -319,6 +319,7 @@
!system 1306 退出编辑
!system 1307 打乱
!system 1308 删除
!system 1309 重置
!system 1310 (无)
!system 1311 种类:
!system 1312 怪兽
......@@ -385,12 +386,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 连接已断开。
......
......@@ -27,10 +27,10 @@ separate_clear_button = 1
#auto_search_limit >= 0: Start search automatically when the user enters N chars.
auto_search_limit = 0
ignore_deck_changes = 0
default_ot = 1
enable_sound = 1
enable_music = 1
#Volume of sound and music, between 0 and 100
sound_volume = 50
music_volume = 50
music_mode = 1
default_ot = 1
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