Commit d9f8f64b authored by mercury233's avatar mercury233

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

parents 7facf87d 6641bb30
......@@ -97,8 +97,10 @@ void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::
CGUIImageButton::CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: CGUIButton(environment, parent, id, rectangle) {
isDrawImage = true;
isFixedSize = false;
imageRotation = 0.0f;
imageScale = core::vector2df(1.0f, 1.0f);
imageSize = core::dimension2di(rectangle.getWidth(), rectangle.getHeight());
}
CGUIImageButton* CGUIImageButton::addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id) {
CGUIImageButton* button = new CGUIImageButton(env, parent ? parent : 0, id, rectangle);
......@@ -129,6 +131,23 @@ void CGUIImageButton::draw() {
irr::gui::Draw2DImageRotation(driver, Image, ImageRect, pos, center, imageRotation, imageScale);
IGUIElement::draw();
}
void CGUIImageButton::setImage(video::ITexture* image)
{
if(image)
image->grab();
if(Image)
Image->drop();
Image = image;
if(image) {
ImageRect = core::rect<s32>(core::position2d<s32>(0, 0), image->getOriginalSize());
if(isFixedSize)
imageScale = core::vector2df((irr::f32)imageSize.Width / image->getSize().Width, (irr::f32)imageSize.Height / image->getSize().Height);
}
if(!PressedImage)
setPressedImage(Image);
}
void CGUIImageButton::setDrawImage(bool b) {
isDrawImage = b;
}
......@@ -138,6 +157,10 @@ void CGUIImageButton::setImageRotation(f32 r) {
void CGUIImageButton::setImageScale(core::vector2df s) {
imageScale = s;
}
void CGUIImageButton::setImageSize(core::dimension2di s) {
isFixedSize = true;
imageSize = s;
}
IGUIFont* CGUIImageButton::getOverrideFont( void ) const
{
......
......@@ -17,16 +17,20 @@ public:
CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle);
static CGUIImageButton* addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id);
virtual void draw();
virtual void setImage(video::ITexture* image = 0);
virtual void setDrawImage(bool b);
virtual void setImageRotation(f32 r);
virtual void setImageScale(core::vector2df s);
virtual void setImageSize(core::dimension2di s);
virtual IGUIFont* getOverrideFont(void) const;
virtual IGUIFont* getActiveFont() const;
private:
bool isDrawImage;
bool isFixedSize;
f32 imageRotation;
core::vector2df imageScale;
core::dimension2di imageSize;
};
}
......
......@@ -1271,13 +1271,6 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se
|| check_sum(index, end, acc, count);
}
template <class T>
static bool is_declarable(T const& cd, int declarable_type) {
if(!(cd.type & declarable_type))
return false;
return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN));
}
template <class T>
static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
std::stack<int> stack;
for(auto it = opcode.begin(); it != opcode.end(); ++it) {
......@@ -1418,59 +1411,12 @@ static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN));
}
void ClientField::UpdateDeclarableCodeType() {
const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname);
CardString cstr;
CardData cd;
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
mainGame->lstANCard->clear();
ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str());
ancard.push_back(trycode);
return;
}
if(pname[0] == 0) {
std::vector<int> cache;
cache.swap(ancard);
int sel = mainGame->lstANCard->getSelected();
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declarable_type)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
mainGame->lstANCard->setSelected(cstr.name.c_str());
}
}
if(!ancard.empty())
return;
}
mainGame->lstANCard->clear();
ancard.clear();
for(auto cit = dataManager._strings.begin(); cit != dataManager._strings.end(); ++cit) {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias
if(is_declarable(cp->second, declarable_type)) {
if(pname == cit->second.name) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
} else {
mainGame->lstANCard->addItem(cit->second.name.c_str());
ancard.push_back(cit->first);
}
}
}
}
}
void ClientField::UpdateDeclarableCodeOpcode() {
void ClientField::UpdateDeclarableList() {
const wchar_t* pname = mainGame->ebANCard->getText();
int trycode = BufferIO::GetVal(pname);
CardString cstr;
CardData cd;
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
mainGame->lstANCard->clear();
ancard.clear();
mainGame->lstANCard->addItem(cstr.name.c_str());
......@@ -1484,7 +1430,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
int selcode = (sel == -1) ? 0 : cache[sel];
mainGame->lstANCard->clear();
for(const auto& trycode : cache) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, opcode)) {
if(dataManager.GetString(trycode, &cstr) && dataManager.GetData(trycode, &cd) && is_declarable(cd, declare_opcodes)) {
ancard.push_back(trycode);
mainGame->lstANCard->addItem(cstr.name.c_str());
if(trycode == selcode)
......@@ -1500,7 +1446,7 @@ void ClientField::UpdateDeclarableCodeOpcode() {
if(cit->second.name.find(pname) != std::wstring::npos) {
auto cp = dataManager.GetCodePointer(cit->first); //verified by _strings
//datas.alias can be double card names or alias
if(is_declarable(cp->second, opcode)) {
if(is_declarable(cp->second, declare_opcodes)) {
if(pname == cit->second.name) { //exact match
mainGame->lstANCard->insertItem(0, cit->second.name.c_str(), -1);
ancard.insert(ancard.begin(), cit->first);
......@@ -1512,10 +1458,4 @@ void ClientField::UpdateDeclarableCodeOpcode() {
}
}
}
void ClientField::UpdateDeclarableCode() {
if(opcode.size() == 0)
UpdateDeclarableCodeType();
else
UpdateDeclarableCodeOpcode();
}
}
......@@ -60,14 +60,13 @@ public:
bool select_panalmode;
bool select_ready;
int announce_count;
int declarable_type;
int select_counter_count;
int select_counter_type;
std::vector<ClientCard*> selectable_cards;
std::vector<ClientCard*> selected_cards;
std::set<ClientCard*> selectsum_cards;
std::vector<ClientCard*> selectsum_all;
std::vector<int> opcode;
std::vector<int> declare_opcodes;
std::vector<ClientCard*> display_cards;
std::vector<int> sort_list;
std::map<int, int> player_desc_hints[2];
......@@ -112,9 +111,7 @@ public:
void check_sel_sum_t(const std::set<ClientCard*>& left, int acc);
bool check_sum(std::set<ClientCard*>::const_iterator index, std::set<ClientCard*>::const_iterator end, int acc, int count);
void UpdateDeclarableCodeType();
void UpdateDeclarableCodeOpcode();
void UpdateDeclarableCode();
void UpdateDeclarableList();
irr::gui::IGUIElement* panel;
std::vector<int> ancard;
......
......@@ -23,8 +23,12 @@ bufferevent* DuelClient::client_bev = 0;
char DuelClient::duel_client_read[0x2000];
char DuelClient::duel_client_write[0x2000];
bool DuelClient::is_closing = false;
bool DuelClient::is_swapping = false;
int DuelClient::select_hint = 0;
int DuelClient::select_unselect_hint = 0;
int DuelClient::last_select_hint = 0;
char DuelClient::last_successful_msg[2048];
unsigned int DuelClient::last_successful_msg_length = 0;
wchar_t DuelClient::event_string[256];
mtrandom DuelClient::rnd;
......@@ -863,6 +867,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
char* pbuf = msg;
wchar_t textBuffer[256];
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
if(mainGame->dInfo.curMsg != MSG_RETRY) {
memcpy(last_successful_msg, msg, len);
last_successful_msg_length = len;
}
mainGame->wCmdMenu->setVisible(false);
if(!mainGame->dInfo.isReplay && mainGame->dInfo.curMsg != MSG_WAITING && mainGame->dInfo.curMsg != MSG_CARD_SELECTED) {
mainGame->waitFrame = -1;
......@@ -882,35 +890,97 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
if(mainGame->dInfo.time_player == 1)
mainGame->dInfo.time_player = 2;
if(is_swapping) {
mainGame->gMutex.Lock();
mainGame->dField.ReplaySwap();
mainGame->gMutex.Unlock();
is_swapping = false;
}
switch(mainGame->dInfo.curMsg) {
case MSG_RETRY: {
if(last_successful_msg_length) {
char* p = last_successful_msg;
auto last_msg = BufferIO::ReadUInt8(p);
int err_desc = 1421;
switch(last_msg) {
case MSG_ANNOUNCE_CARD:
err_desc = 1422;
break;
case MSG_ANNOUNCE_ATTRIB:
err_desc = 1423;
break;
case MSG_ANNOUNCE_RACE:
err_desc = 1424;
break;
case MSG_ANNOUNCE_NUMBER:
err_desc = 1425;
break;
case MSG_SELECT_EFFECTYN:
case MSG_SELECT_YESNO:
case MSG_SELECT_OPTION:
err_desc = 1426;
break;
case MSG_SELECT_CARD:
case MSG_SELECT_UNSELECT_CARD:
case MSG_SELECT_TRIBUTE:
case MSG_SELECT_SUM:
case MSG_SORT_CARD:
err_desc = 1427;
break;
case MSG_SELECT_CHAIN:
err_desc = 1428;
break;
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD:
err_desc = 1429;
break;
case MSG_SELECT_POSITION:
err_desc = 1430;
break;
case MSG_SELECT_COUNTER:
err_desc = 1431;
break;
default:
break;
}
mainGame->gMutex.Lock();
mainGame->stMessage->setText(dataManager.GetDesc(err_desc));
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
select_hint = last_select_hint;
return ClientAnalyze(last_successful_msg, last_successful_msg_length);
}
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = false;
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
mainGame->btnStartBot->setEnabled(true);
mainGame->btnBotCancel->setEnabled(true);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
if(bot_mode)
mainGame->ShowElement(mainGame->wSinglePlay);
else
mainGame->ShowElement(mainGame->wLanWindow);
mainGame->gMutex.Unlock();
event_base_loopbreak(client_base);
if(exit_on_return)
mainGame->device->closeDevice();
if(!mainGame->dInfo.isSingleMode) {
mainGame->closeDoneSignal.Reset();
mainGame->closeSignal.Set();
mainGame->closeDoneSignal.Wait();
mainGame->gMutex.Lock();
mainGame->dInfo.isStarted = false;
mainGame->dInfo.isFinished = false;
mainGame->btnCreateHost->setEnabled(true);
mainGame->btnJoinHost->setEnabled(true);
mainGame->btnJoinCancel->setEnabled(true);
mainGame->btnStartBot->setEnabled(true);
mainGame->btnBotCancel->setEnabled(true);
mainGame->stTip->setVisible(false);
mainGame->device->setEventReceiver(&mainGame->menuHandler);
if(bot_mode)
mainGame->ShowElement(mainGame->wSinglePlay);
else
mainGame->ShowElement(mainGame->wLanWindow);
mainGame->gMutex.Unlock();
event_base_loopbreak(client_base);
if(exit_on_return)
mainGame->device->closeDevice();
}
return false;
}
case MSG_HINT: {
......@@ -935,6 +1005,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
case HINT_SELECTMSG: {
select_hint = data;
last_select_hint = data;
break;
}
case HINT_OPSELECTED: {
......@@ -1078,6 +1149,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->dField.Initial(mainGame->LocalPlayer(1), deckc, extrac);
mainGame->dInfo.turn = 0;
mainGame->dInfo.is_shuffling = false;
select_hint = 0;
select_unselect_hint = 0;
last_select_hint = 0;
last_successful_msg_length = 0;
if(mainGame->dInfo.isReplaySwapped) {
std::swap(mainGame->dInfo.hostname, mainGame->dInfo.clientname);
std::swap(mainGame->dInfo.hostname_tag, mainGame->dInfo.clientname_tag);
......@@ -2093,8 +2168,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
mainGame->WaitFrameSignal(11);
}
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit)
for(auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->SetCode(BufferIO::ReadInt32(pbuf));
(*cit)->desc_hints.clear();
}
if(!mainGame->dInfo.isReplay || !mainGame->dInfo.isReplaySkiping) {
for (auto cit = mainGame->dField.hand[player].begin(); cit != mainGame->dField.hand[player].end(); ++cit) {
(*cit)->is_hovered = false;
......@@ -3399,8 +3476,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
case MSG_ANNOUNCE_CARD: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
mainGame->dField.declarable_type = BufferIO::ReadInt32(pbuf);
mainGame->dField.opcode.clear();
int count = BufferIO::ReadUInt8(pbuf);
mainGame->dField.declare_opcodes.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.declare_opcodes.push_back(BufferIO::ReadInt32(pbuf));
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(564));
......@@ -3408,7 +3487,7 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode();
mainGame->dField.UpdateDeclarableList();
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
......@@ -3433,25 +3512,6 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
mainGame->gMutex.Unlock();
return false;
}
case MSG_ANNOUNCE_CARD_FILTER: {
/*int player = */mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int count = BufferIO::ReadUInt8(pbuf);
mainGame->dField.declarable_type = 0;
mainGame->dField.opcode.clear();
for (int i = 0; i < count; ++i)
mainGame->dField.opcode.push_back(BufferIO::ReadInt32(pbuf));
if(select_hint)
myswprintf(textBuffer, L"%ls", dataManager.GetDesc(select_hint));
else myswprintf(textBuffer, dataManager.GetSysString(564));
select_hint = 0;
mainGame->gMutex.Lock();
mainGame->ebANCard->setText(L"");
mainGame->wANCard->setText(textBuffer);
mainGame->dField.UpdateDeclarableCode();
mainGame->PopupElement(mainGame->wANCard);
mainGame->gMutex.Unlock();
return false;
}
case MSG_CARD_HINT: {
int c = mainGame->LocalPlayer(BufferIO::ReadInt8(pbuf));
int l = BufferIO::ReadInt8(pbuf);
......@@ -3735,6 +3795,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
}
return true;
}
void DuelClient::SwapField() {
is_swapping = true;
}
void DuelClient::SetResponseI(int respI) {
*((int*)response_buf) = respI;
response_len = 4;
......
......@@ -29,8 +29,12 @@ private:
static char duel_client_read[0x2000];
static char duel_client_write[0x2000];
static bool is_closing;
static bool is_swapping;
static int select_hint;
static int select_unselect_hint;
static int last_select_hint;
static char last_successful_msg[2048];
static unsigned int last_successful_msg_length;
static wchar_t event_string[256];
static mtrandom rnd;
public:
......@@ -42,6 +46,7 @@ public:
static int ClientThread(void* param);
static void HandleSTOCPacketLan(char* data, unsigned int len);
static int ClientAnalyze(char* msg, unsigned int len);
static void SwapField();
static void SetResponseI(int respI);
static void SetResponseB(void* respB, unsigned char len);
static void SendResponse();
......
......@@ -91,8 +91,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
soundManager.PlaySoundEffect(SOUND_BUTTON);
if(mainGame->dInfo.isReplay)
ReplayMode::SwapField();
else if (mainGame->dInfo.player_type == 7)
mainGame->dField.ReplaySwap();
else if(mainGame->dInfo.player_type == 7)
DuelClient::SwapField();
break;
}
case BUTTON_REPLAY_UNDO: {
......@@ -963,7 +963,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_CHANGED: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......@@ -972,7 +972,7 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case irr::gui::EGET_EDITBOX_ENTER: {
switch(id) {
case EDITBOX_ANCARD: {
UpdateDeclarableCode();
UpdateDeclarableList();
break;
}
}
......
......@@ -10,7 +10,7 @@
#include "netserver.h"
#include "single_mode.h"
const unsigned short PRO_VERSION = 0x134A;
const unsigned short PRO_VERSION = 0x134B;
namespace ygo {
......@@ -414,15 +414,15 @@ bool Game::Initialize() {
wPosSelect->getCloseButton()->setVisible(false);
wPosSelect->setVisible(false);
btnPSAU = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(10, 45, 150, 185), wPosSelect, BUTTON_POS_AU);
btnPSAU->setImageScale(core::vector2df(0.5, 0.5));
btnPSAU->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.5f, CARD_IMG_HEIGHT * 0.5f));
btnPSAD = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(155, 45, 295, 185), wPosSelect, BUTTON_POS_AD);
btnPSAD->setImageScale(core::vector2df(0.5, 0.5));
btnPSAD->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.5f, CARD_IMG_HEIGHT * 0.5f));
btnPSAD->setImage(imageManager.tCover[2]);
btnPSDU = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(300, 45, 440, 185), wPosSelect, BUTTON_POS_DU);
btnPSDU->setImageScale(core::vector2df(0.5, 0.5));
btnPSDU->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.5f, CARD_IMG_HEIGHT * 0.5f));
btnPSDU->setImageRotation(270);
btnPSDD = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(445, 45, 585, 185), wPosSelect, BUTTON_POS_DD);
btnPSDD->setImageScale(core::vector2df(0.5, 0.5));
btnPSDD->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.5f, CARD_IMG_HEIGHT * 0.5f));
btnPSDD->setImageRotation(270);
btnPSDD->setImage(imageManager.tCover[2]);
//card select
......@@ -434,7 +434,7 @@ bool Game::Initialize() {
stCardPos[i]->setBackgroundColor(0xffffffff);
stCardPos[i]->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
btnCardSelect[i] = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(30 + 125 * i, 55, 150 + 125 * i, 225), wCardSelect, BUTTON_CARD_0 + i);
btnCardSelect[i]->setImageScale(core::vector2df(0.6f, 0.6f));
btnCardSelect[i]->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.6f, CARD_IMG_HEIGHT * 0.6f));
}
scrCardList = env->addScrollBar(true, rect<s32>(30, 235, 650, 255), wCardSelect, SCROLL_CARD_SELECT);
btnSelectOK = env->addButton(rect<s32>(300, 265, 380, 290), wCardSelect, BUTTON_CARD_SEL_OK, dataManager.GetSysString(1211));
......@@ -447,7 +447,7 @@ bool Game::Initialize() {
stDisplayPos[i]->setBackgroundColor(0xffffffff);
stDisplayPos[i]->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
btnCardDisplay[i] = irr::gui::CGUIImageButton::addImageButton(env, rect<s32>(30 + 125 * i, 55, 150 + 125 * i, 225), wCardDisplay, BUTTON_DISPLAY_0 + i);
btnCardDisplay[i]->setImageScale(core::vector2df(0.6f, 0.6f));
btnCardDisplay[i]->setImageSize(core::dimension2di(CARD_IMG_WIDTH * 0.6f, CARD_IMG_HEIGHT * 0.6f));
}
scrDisplayList = env->addScrollBar(true, rect<s32>(30, 235, 650, 255), wCardDisplay, SCROLL_CARD_DISPLAY);
btnDisplayOK = env->addButton(rect<s32>(300, 265, 380, 290), wCardDisplay, BUTTON_CARD_DISP_OK, dataManager.GetSysString(1211));
......
......@@ -197,7 +197,7 @@ void NetServer::HandleCTOSPacket(DuelPlayer* dp, char* data, unsigned int len) {
case CTOS_UPDATE_DECK: {
if(!dp->game)
return;
duel_mode->UpdateDeck(dp, pdata);
duel_mode->UpdateDeck(dp, pdata, len - 1);
break;
}
case CTOS_HAND_RESULT: {
......
......@@ -114,7 +114,7 @@ struct DuelPlayer {
class DuelMode {
public:
DuelMode(): host_player(0), pduel(0) {}
DuelMode(): host_player(0), pduel(0), duel_stage(0) {}
virtual ~DuelMode() {}
virtual void Chat(DuelPlayer* dp, void* pdata, int len) {}
virtual void JoinGame(DuelPlayer* dp, void* pdata, bool is_creater) {}
......@@ -123,7 +123,7 @@ public:
virtual void ToObserver(DuelPlayer* dp) {}
virtual void PlayerReady(DuelPlayer* dp, bool is_ready) {}
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos) {}
virtual void UpdateDeck(DuelPlayer* dp, void* pdata) {}
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {}
virtual void StartDuel(DuelPlayer* dp) {}
virtual void HandResult(DuelPlayer* dp, unsigned char res) {}
virtual void TPResult(DuelPlayer* dp, unsigned char tp) {}
......@@ -140,6 +140,7 @@ public:
event* etimer;
DuelPlayer* host_player;
HostInfo host_info;
int duel_stage;
unsigned long pduel;
wchar_t name[20];
wchar_t pass[20];
......@@ -219,4 +220,11 @@ public:
#define MODE_SINGLE 0x0
#define MODE_MATCH 0x1
#define MODE_TAG 0x2
#define DUEL_STAGE_BEGIN 0
#define DUEL_STAGE_FINGER 1
#define DUEL_STAGE_FIRSTGO 2
#define DUEL_STAGE_DUELING 3
#define DUEL_STAGE_SIDING 4
#define DUEL_STAGE_END 5
#endif //NETWORK_H
......@@ -101,6 +101,8 @@ int ReplayMode::ReplayThread(void* param) {
if(is_restarting) {
mainGame->gMutex.Lock();
is_restarting = false;
mainGame->dInfo.isReplaySkiping = true;
Restart(false);
int step = current_step - 1;
if(step < 0)
step = 0;
......@@ -109,10 +111,13 @@ int ReplayMode::ReplayThread(void* param) {
skip_step = 0;
int len = get_message(pduel, (byte*)engineBuffer);
if (len > 0) {
mainGame->gMutex.Unlock();
is_continuing = ReplayAnalyze(engineBuffer, len);
mainGame->gMutex.Lock();
}
} else {
ReplayRefreshDeck(0);
ReplayRefreshDeck(1);
ReplayRefreshExtra(0);
ReplayRefreshExtra(1);
}
if(step == 0) {
Pause(true, false);
......@@ -171,14 +176,14 @@ bool ReplayMode::StartDuel() {
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(0, main, extra);
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_DECK, 0, POS_FACEDOWN_DEFENSE);
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(1, main, extra);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
} else {
int main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
......@@ -186,7 +191,7 @@ bool ReplayMode::StartDuel() {
int extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 0, 0, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(0, main, extra);
mainGame->dField.Initial(mainGame->LocalPlayer(0), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 0, LOCATION_DECK);
......@@ -199,7 +204,7 @@ bool ReplayMode::StartDuel() {
extra = cur_replay.ReadInt32();
for(int i = 0; i < extra; ++i)
new_card(pduel, cur_replay.ReadInt32(), 1, 1, LOCATION_EXTRA, 0, POS_FACEDOWN_DEFENSE);
mainGame->dField.Initial(1, main, extra);
mainGame->dField.Initial(mainGame->LocalPlayer(1), main, extra);
main = cur_replay.ReadInt32();
for(int i = 0; i < main; ++i)
new_tag_card(pduel, cur_replay.ReadInt32(), 1, LOCATION_DECK);
......@@ -267,13 +272,11 @@ void ReplayMode::Restart(bool refresh) {
//mainGame->dInfo.isReplay = true;
}
skip_turn = 0;
is_restarting = true;
}
void ReplayMode::Undo() {
if(skip_step > 0 || current_step == 0)
return;
mainGame->dInfo.isReplaySkiping = true;
Restart(false);
is_restarting = true;
Pause(false, false);
}
bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
......@@ -767,13 +770,8 @@ bool ReplayMode::ReplayAnalyze(char* msg, unsigned int len) {
pbuf += 5;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
return ReadReplayResponse();
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -8,7 +8,6 @@
namespace ygo {
SingleDuel::SingleDuel(bool is_match) {
game_started = false;
match_mode = is_match;
match_kill = 0;
for(int i = 0; i < 2; ++i) {
......@@ -139,7 +138,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer();
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
if(players[0])
......@@ -151,7 +150,7 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started && duel_count == 0) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -164,26 +163,28 @@ void SingleDuel::LeaveGame(DuelPlayer* dp) {
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_SIDING) {
if(!ready[0])
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
if(!ready[1])
NetServer::SendPacketToPlayer(players[1], STOC_DUEL_START);
}
unsigned char wbuf[3];
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - dp->type;
wbuf[2] = 0;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
if(duel_stage != DUEL_STAGE_END) {
unsigned char wbuf[3];
wbuf[0] = MSG_WIN;
wbuf[1] = 1 - dp->type;
wbuf[2] = 0x4;
NetServer::SendBufferToPlayer(players[0], STOC_GAME_MSG, wbuf, 3);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
EndDuel();
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_END);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
}
NetServer::DisconnectPlayer(dp);
}
}
}
......@@ -280,12 +281,20 @@ void SingleDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
return;
LeaveGame(players[pos]);
}
void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
if(dp->type > 1 || ready[dp->type])
return;
char* deckbuf = (char*)pdata;
int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf);
// verify data
if((unsigned)mainc + (unsigned)sidec > (len - 8) / 4) {
STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR;
scem.code = 0;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
if(duel_count == 0) {
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec);
} else {
......@@ -296,6 +305,7 @@ void SingleDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
NetServer::SendPacketToPlayer(players[tp_player], STOC_SELECT_TP);
players[1 - tp_player]->state = 0xff;
players[tp_player]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
} else {
STOC_ErrorMsg scem;
......@@ -312,7 +322,6 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
return;
NetServer::StopListen();
//NetServer::StopBroadcast();
game_started = true;
NetServer::SendPacketToPlayer(players[0], STOC_DUEL_START);
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit) {
......@@ -325,6 +334,7 @@ void SingleDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[1]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3)
......@@ -352,21 +362,24 @@ void SingleDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) {
NetServer::SendPacketToPlayer(players[1], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[1], STOC_SELECT_TP);
tp_player = 1;
players[0]->state = 0xff;
players[1]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[1]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
tp_player = 0;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void SingleDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -489,7 +502,7 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
int winc[3] = {0, 0, 0};
for(int i = 0; i < duel_count; ++i)
......@@ -502,7 +515,7 @@ void SingleDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[1]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
} else {
if(players[0] != pplayer[0]) {
players[0] = pplayer[0];
......@@ -521,6 +534,7 @@ void SingleDuel::DuelEndProc() {
NetServer::SendPacketToPlayer(players[1], STOC_CHANGE_SIDE);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::SendPacketToPlayer(*oit, STOC_WAITING_SIDE);
duel_stage = DUEL_STAGE_SIDING;
}
}
}
......@@ -1337,15 +1351,8 @@ int SingleDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
WaitforResponse(player);
pbuf += 4;
NetServer::SendBufferToPlayer(players[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -18,7 +18,7 @@ public:
virtual void ToObserver(DuelPlayer* dp);
virtual void PlayerReady(DuelPlayer* dp, bool ready);
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len);
virtual void StartDuel(DuelPlayer* dp);
virtual void HandResult(DuelPlayer* dp, unsigned char res);
virtual void TPResult(DuelPlayer* dp, unsigned char tp);
......@@ -53,7 +53,6 @@ protected:
Replay last_replay;
bool match_mode;
int match_kill;
bool game_started;
unsigned char duel_count;
unsigned char tp_player;
unsigned char match_result[3];
......
......@@ -177,13 +177,11 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
mainGame->dInfo.curMsg = BufferIO::ReadUInt8(pbuf);
switch (mainGame->dInfo.curMsg) {
case MSG_RETRY: {
mainGame->gMutex.Lock();
mainGame->stMessage->setText(L"Error occurs.");
mainGame->PopupElement(mainGame->wMessage);
mainGame->gMutex.Unlock();
mainGame->actionSignal.Reset();
mainGame->actionSignal.Wait();
return false;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_HINT: {
/*int type = */BufferIO::ReadInt8(pbuf);
......@@ -681,17 +679,8 @@ bool SingleMode::SinglePlayAnalyze(char* msg, unsigned int len) {
}
break;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
if(!DuelClient::ClientAnalyze(offset, pbuf - offset)) {
mainGame->singleSignal.Reset();
mainGame->singleSignal.Wait();
}
break;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -8,7 +8,6 @@
namespace ygo {
TagDuel::TagDuel() {
game_started = false;
for(int i = 0; i < 4; ++i) {
players[i] = 0;
ready[i] = false;
......@@ -119,7 +118,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
NetServer::StopServer();
} else if(dp->type == NETPLAYER_TYPE_OBSERVER) {
observers.erase(dp);
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_WatchChange scwc;
scwc.watch_count = observers.size();
for(int i = 0; i < 4; ++i)
......@@ -130,7 +129,7 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
}
NetServer::DisconnectPlayer(dp);
} else {
if(!game_started) {
if(duel_stage == DUEL_STAGE_BEGIN) {
STOC_HS_PlayerChange scpc;
players[dp->type] = 0;
ready[dp->type] = false;
......@@ -141,10 +140,11 @@ void TagDuel::LeaveGame(DuelPlayer* dp) {
for(auto pit = observers.begin(); pit != observers.end(); ++pit)
NetServer::SendPacketToPlayer(*pit, STOC_HS_PLAYER_CHANGE, scpc);
NetServer::DisconnectPlayer(dp);
} else {
} else if(duel_stage != DUEL_STAGE_END) {
EndDuel();
DuelEndProc();
}
NetServer::DisconnectPlayer(dp);
}
}
void TagDuel::ToDuelist(DuelPlayer* dp) {
......@@ -256,12 +256,20 @@ void TagDuel::PlayerKick(DuelPlayer* dp, unsigned char pos) {
return;
LeaveGame(players[pos]);
}
void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata) {
void TagDuel::UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len) {
if(dp->type > 3 || ready[dp->type])
return;
char* deckbuf = (char*)pdata;
int mainc = BufferIO::ReadInt32(deckbuf);
int sidec = BufferIO::ReadInt32(deckbuf);
// verify data
if((unsigned)mainc + (unsigned)sidec > (len - 8) / 4) {
STOC_ErrorMsg scem;
scem.msg = ERRMSG_DECKERROR;
scem.code = 0;
NetServer::SendPacketToPlayer(dp, STOC_ERROR_MSG, scem);
return;
}
deck_error[dp->type] = deckManager.LoadDeck(pdeck[dp->type], (int*)deckbuf, mainc, sidec);
}
void TagDuel::StartDuel(DuelPlayer* dp) {
......@@ -270,7 +278,6 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
if(!ready[0] || !ready[1] || !ready[2] || !ready[3])
return;
NetServer::StopListen();
game_started = true;
//NetServer::StopBroadcast();
for(int i = 0; i < 4; ++i)
NetServer::SendPacketToPlayer(players[i], STOC_DUEL_START);
......@@ -284,6 +291,7 @@ void TagDuel::StartDuel(DuelPlayer* dp) {
hand_result[1] = 0;
players[0]->state = CTOS_HAND_RESULT;
players[2]->state = CTOS_HAND_RESULT;
duel_stage = DUEL_STAGE_FINGER;
}
void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
if(res > 3 || dp->state != CTOS_HAND_RESULT)
......@@ -314,19 +322,22 @@ void TagDuel::HandResult(DuelPlayer* dp, unsigned char res) {
} else if((hand_result[0] == 1 && hand_result[1] == 2)
|| (hand_result[0] == 2 && hand_result[1] == 3)
|| (hand_result[0] == 3 && hand_result[1] == 1)) {
NetServer::SendPacketToPlayer(players[2], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[2], STOC_SELECT_TP);
players[0]->state = 0xff;
players[2]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
} else {
NetServer::SendPacketToPlayer(players[0], CTOS_TP_RESULT);
NetServer::SendPacketToPlayer(players[0], STOC_SELECT_TP);
players[2]->state = 0xff;
players[0]->state = CTOS_TP_RESULT;
duel_stage = DUEL_STAGE_FIRSTGO;
}
}
}
void TagDuel::TPResult(DuelPlayer* dp, unsigned char tp) {
if(dp->state != CTOS_TP_RESULT)
return;
duel_stage = DUEL_STAGE_DUELING;
bool swapped = false;
mtrandom rnd;
pplayer[0] = players[0];
......@@ -492,7 +503,7 @@ void TagDuel::DuelEndProc() {
NetServer::ReSendToPlayer(players[3]);
for(auto oit = observers.begin(); oit != observers.end(); ++oit)
NetServer::ReSendToPlayer(*oit);
NetServer::StopServer();
duel_stage = DUEL_STAGE_END;
}
void TagDuel::Surrender(DuelPlayer* dp) {
return;
......@@ -1386,15 +1397,8 @@ int TagDuel::Analyze(char* msgbuffer, unsigned int len) {
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_CARD: {
player = BufferIO::ReadInt8(pbuf);
pbuf += 4;
WaitforResponse(player);
NetServer::SendBufferToPlayer(cur_player[player], STOC_GAME_MSG, offset, pbuf - offset);
return 1;
}
case MSG_ANNOUNCE_NUMBER:
case MSG_ANNOUNCE_CARD_FILTER: {
case MSG_ANNOUNCE_CARD:
case MSG_ANNOUNCE_NUMBER: {
player = BufferIO::ReadInt8(pbuf);
count = BufferIO::ReadUInt8(pbuf);
pbuf += 4 * count;
......
......@@ -18,7 +18,7 @@ public:
virtual void ToObserver(DuelPlayer* dp);
virtual void PlayerReady(DuelPlayer* dp, bool ready);
virtual void PlayerKick(DuelPlayer* dp, unsigned char pos);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata);
virtual void UpdateDeck(DuelPlayer* dp, void* pdata, unsigned int len);
virtual void StartDuel(DuelPlayer* dp);
virtual void HandResult(DuelPlayer* dp, unsigned char res);
virtual void TPResult(DuelPlayer* dp, unsigned char tp);
......@@ -52,7 +52,6 @@ protected:
unsigned char hand_result[2];
unsigned char last_response;
Replay last_replay;
bool game_started;
unsigned char turn_count;
unsigned short time_limit[2];
unsigned short time_elapsed;
......
Subproject commit 79345ca980c5c933dbec08a0b0f6fb1af1a8da20
Subproject commit f79332d76d1b5774fe0105e541d34c7b40e3e54a
Subproject commit 35562e466d6ae7816bf32a2cc2b5bc37deed4aaa
Subproject commit 573645ee990be70d8e7c7ae2fa8a8fad33e9d62e
......@@ -36,12 +36,13 @@
!system 64 二重状态
!system 65 使用效果
!system 66 持续公开
!system 67 原本持有者为对方
!system 70 怪兽卡
!system 71 魔法卡
!system 72 陷阱卡
!system 80 进入战斗阶段
!system 81 进入结束阶段
!system 90 是否不解放怪通常召唤?
!system 90 是否不解放怪通常召唤?
!system 91 是否使用额外的召唤机会?
!system 92 是否要解放对方怪兽进行上级召唤?
!system 93 是否要继续选择素材?
......@@ -438,7 +439,17 @@
!system 1418 额外卡组数量应不超过15张,当前卡组数量为%d张。
!system 1419 副卡组数量应不超过15张,当前卡组数量为%d张。
!system 1420 有额外卡组卡片存在于主卡组,可能是额外卡组数量超过15张。
!system 1421 宣言的卡不符合条件,或无法被主机识别。
!system 1421 操作无效,请重试。
!system 1422 宣言的卡不符合条件,或无法被主机识别。
!system 1423 宣言的属性不符合条件。
!system 1424 宣言的种族不符合条件
!system 1425 宣言的数字不符合条件。
!system 1426 选择的选项不符合条件
!system 1427 选择的卡片不符合条件。
!system 1428 选择的连锁不符合条件。
!system 1429 选择的位置不符合条件。
!system 1430 选择的表示形式不符合条件。
!system 1431 选择的指示物不符合条件。
!system 1500 决斗结束。
!system 1501 录像结束。
!system 1502 连接已断开。
......
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