Commit 98fa5080 authored by mercury233's avatar mercury233

Merge branch 'patch-bot-select-deckfile' into patch-deck-category

parents 5179735f 44afc673
......@@ -29,6 +29,7 @@ ClientField::ClientField() {
conti_act = false;
deck_reversed = false;
conti_selecting = false;
cant_check_grave = false;
for(int p = 0; p < 2; ++p) {
mzone[p].resize(7, 0);
szone[p].resize(8, 0);
......@@ -93,6 +94,7 @@ void ClientField::Clear() {
pzone_act[1] = false;
conti_act = false;
deck_reversed = false;
cant_check_grave = false;
}
void ClientField::Initial(int player, int deckc, int extrac) {
ClientCard* pcard;
......@@ -384,6 +386,18 @@ void ClientField::ClearChainSelect() {
}
// needs to be synchronized with EGET_SCROLL_BAR_CHANGED
void ClientField::ShowSelectCard(bool buttonok, bool chain) {
if(cant_check_grave) {
bool has_card_in_grave = false;
for(size_t i = 0; i < selectable_cards.size(); ++i) {
if(selectable_cards[i]->location == LOCATION_GRAVE) {
has_card_in_grave = true;
break;
}
}
if(has_card_in_grave) {
std::random_shuffle(selectable_cards.begin(), selectable_cards.end());
}
}
int startpos;
size_t ct;
if(selectable_cards.size() <= 5) {
......@@ -410,6 +424,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
wchar_t formatBuffer[2048];
if(conti_selecting)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(selectable_cards[i]->overlayTarget->location, selectable_cards[i]->overlayTarget->sequence),
......@@ -429,7 +445,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
mainGame->stCardPos[i]->setOverrideColor(0xff0000ff);
if(selectable_cards[i]->overlayTarget->controler)
mainGame->stCardPos[i]->setBackgroundColor(0xffd0d0d0);
else mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
else
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
} else if(selectable_cards[i]->location == LOCATION_DECK || selectable_cards[i]->location == LOCATION_EXTRA || selectable_cards[i]->location == LOCATION_REMOVED) {
if(selectable_cards[i]->position & POS_FACEDOWN)
mainGame->stCardPos[i]->setOverrideColor(0xff0000ff);
......@@ -449,7 +466,8 @@ void ClientField::ShowSelectCard(bool buttonok, bool chain) {
wchar_t formatBuffer[2048];
myswprintf(formatBuffer, L"%d", sort_list[i]);
mainGame->stCardPos[i]->setText(formatBuffer);
} else mainGame->stCardPos[i]->setText(L"");
} else
mainGame->stCardPos[i]->setText(L"");
mainGame->stCardPos[i]->setBackgroundColor(0xffffffff);
}
mainGame->stCardPos[i]->setVisible(true);
......@@ -1209,6 +1227,27 @@ bool ClientField::CheckSelectSum() {
return ret;
}
}
bool ClientField::CheckSelectTribute() {
std::set<ClientCard*> selable;
for(auto sit = selectsum_all.begin(); sit != selectsum_all.end(); ++sit) {
(*sit)->is_selectable = false;
(*sit)->is_selected = false;
selable.insert(*sit);
}
for(size_t i = 0; i < selected_cards.size(); ++i) {
selected_cards[i]->is_selectable = true;
selected_cards[i]->is_selected = true;
selable.erase(selected_cards[i]);
}
selectsum_cards.clear();
bool ret = check_sel_sum_trib_s(selable, 0, 0);
selectable_cards.clear();
for(auto sit = selectsum_cards.begin(); sit != selectsum_cards.end(); ++sit) {
(*sit)->is_selectable = true;
selectable_cards.push_back(*sit);
}
return ret;
}
bool ClientField::check_min(const std::set<ClientCard*>& left, std::set<ClientCard*>::const_iterator index, int min, int max) {
if (index == left.end())
return false;
......@@ -1272,6 +1311,52 @@ bool ClientField::check_sum(std::set<ClientCard*>::const_iterator index, std::se
|| (l2 > 0 && acc > l2 && check_sum(index, end, acc - l2, count + 1))
|| check_sum(index, end, acc, count);
}
bool ClientField::check_sel_sum_trib_s(const std::set<ClientCard*>& left, int index, int acc) {
if(acc > select_max)
return false;
if(index == (int)selected_cards.size()) {
check_sel_sum_trib_t(left, acc);
return acc >= select_min && acc <= select_max;
}
int l = selected_cards[index]->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
bool res1 = false, res2 = false;
res1 = check_sel_sum_trib_s(left, index + 1, acc + l1);
if(l2 > 0)
res2 = check_sel_sum_trib_s(left, index + 1, acc + l2);
return res1 || res2;
}
void ClientField::check_sel_sum_trib_t(const std::set<ClientCard*>& left, int acc) {
for(auto sit = left.begin(); sit != left.end(); ++sit) {
if(selectsum_cards.find(*sit) != selectsum_cards.end())
continue;
std::set<ClientCard*> testlist(left);
testlist.erase(*sit);
int l = (*sit)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
if(check_sum_trib(testlist.begin(), testlist.end(), acc + l1)
|| (l2 > 0 && check_sum_trib(testlist.begin(), testlist.end(), acc + l2))) {
selectsum_cards.insert(*sit);
}
}
}
bool ClientField::check_sum_trib(std::set<ClientCard*>::const_iterator index, std::set<ClientCard*>::const_iterator end, int acc) {
if(acc >= select_min && acc <= select_max)
return true;
if(acc > select_max || index == end)
return false;
int l = (*index)->opParam;
int l1 = l & 0xffff;
int l2 = l >> 16;
if((acc + l1 >= select_min && acc + l1 <= select_max) || (acc + l2 >= select_min && acc + l2 <= select_max))
return true;
++index;
return check_sum_trib(index, end, acc + l1)
|| check_sum_trib(index, end, acc + l2)
|| check_sum_trib(index, end, acc);
}
template <class T>
static bool is_declarable(T const& cd, const std::vector<int>& opcode) {
std::stack<int> stack;
......
......@@ -81,6 +81,7 @@ public:
bool last_chain;
bool deck_reversed;
bool conti_selecting;
bool cant_check_grave;
ClientField();
void Clear();
......@@ -106,10 +107,14 @@ public:
void FadeCard(ClientCard* pcard, int alpha, int frame);
bool ShowSelectSum(bool panelmode);
bool CheckSelectSum();
bool CheckSelectTribute();
bool check_min(const std::set<ClientCard*>& left, std::set<ClientCard*>::const_iterator index, int min, int max);
bool check_sel_sum_s(const std::set<ClientCard*>& left, int index, int acc);
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);
bool check_sel_sum_trib_s(const std::set<ClientCard*>& left, int index, int acc);
void check_sel_sum_trib_t(const std::set<ClientCard*>& left, int acc);
bool check_sum_trib(std::set<ClientCard*>::const_iterator index, std::set<ClientCard*>::const_iterator end, int acc);
void UpdateDeclarableList();
......@@ -146,5 +151,6 @@ public:
//special cards
#define CARD_MARINE_DOLPHIN 78734254
#define CARD_TWINKLE_MOSS 13857930
#define CARD_QUESTION 38723936
#endif //CLIENT_FIELD_H
......@@ -144,8 +144,8 @@ inline void ShowBigCard(int code, float zoom) {
inline void ZoomBigCard(s32 centerx = -1, s32 centery = -1) {
if(mainGame->deckBuilder.bigcard_zoom >= 4)
mainGame->deckBuilder.bigcard_zoom = 4;
if(mainGame->deckBuilder.bigcard_zoom <= 0.2)
mainGame->deckBuilder.bigcard_zoom = 0.2;
if(mainGame->deckBuilder.bigcard_zoom <= 0.2f)
mainGame->deckBuilder.bigcard_zoom = 0.2f;
ITexture* img = imageManager.GetBigPicture(mainGame->deckBuilder.bigcard_code, mainGame->deckBuilder.bigcard_zoom);
mainGame->imgBigCard->setImage(img);
auto size = img->getSize();
......@@ -769,12 +769,12 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
break;
}
case BUTTON_BIG_CARD_ZOOM_IN: {
bigcard_zoom += 0.2;
bigcard_zoom += 0.2f;
ZoomBigCard();
break;
}
case BUTTON_BIG_CARD_ZOOM_OUT: {
bigcard_zoom -= 0.2;
bigcard_zoom -= 0.2f;
ZoomBigCard();
break;
}
......
......@@ -408,7 +408,7 @@ void Game::DrawShadowText(CGUITTFont * font, const core::stringw & text, const c
void Game::DrawMisc() {
static irr::core::vector3df act_rot(0, 0, 0);
int rule = (dInfo.duel_rule >= 4) ? 1 : 0;
irr::core::matrix4 im, ic, it;
irr::core::matrix4 im, ic, it, ig;
act_rot.Z += 0.02f;
im.setRotationRadians(act_rot);
matManager.mTexture.setTexture(0, imageManager.tAct);
......@@ -492,6 +492,18 @@ void Game::DrawMisc() {
driver->drawVertexPrimitiveList(matManager.vChainNum, 4, matManager.iRectangle, 2);
}
}
if(dField.cant_check_grave) {
matManager.mTexture.setTexture(0, imageManager.tNegated);
driver->setMaterial(matManager.mTexture);
ig.setTranslation(vector3df((matManager.vFieldGrave[0][rule][0].Pos.X + matManager.vFieldGrave[0][rule][1].Pos.X) / 2,
(matManager.vFieldGrave[0][rule][0].Pos.Y + matManager.vFieldGrave[0][rule][2].Pos.Y) / 2, dField.grave[0].size() * 0.01f + 0.02f));
driver->setTransform(irr::video::ETS_WORLD, ig);
driver->drawVertexPrimitiveList(matManager.vNegate, 4, matManager.iRectangle, 2);
ig.setTranslation(vector3df((matManager.vFieldGrave[1][rule][0].Pos.X + matManager.vFieldGrave[1][rule][1].Pos.X) / 2,
(matManager.vFieldGrave[1][rule][0].Pos.Y + matManager.vFieldGrave[1][rule][2].Pos.Y) / 2, dField.grave[1].size() * 0.01f + 0.02f));
driver->setTransform(irr::video::ETS_WORLD, ig);
driver->drawVertexPrimitiveList(matManager.vNegate, 4, matManager.iRectangle, 2);
}
//finish button
if(btnCancelOrFinish->isVisible() && dField.select_ready)
DrawSelectionLine(btnCancelOrFinish, 2, 0xffffff00);
......
......@@ -1692,7 +1692,10 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
case MSG_SELECT_PLACE:
case MSG_SELECT_DISFIELD: {
int selecting_player = BufferIO::ReadInt8(pbuf);
mainGame->dField.select_min = BufferIO::ReadInt8(pbuf);
int count = BufferIO::ReadInt8(pbuf);
mainGame->dField.select_min = count > 0 ? count : 1;
mainGame->dField.select_ready = false;
mainGame->dField.select_cancelable = count == 0;
mainGame->dField.selectable_field = ~BufferIO::ReadInt32(pbuf);
if(selecting_player == mainGame->LocalPlayer(1))
mainGame->dField.selectable_field = (mainGame->dField.selectable_field >> 16) | (mainGame->dField.selectable_field << 16);
......@@ -1767,6 +1770,9 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
DuelClient::SendResponse();
return true;
}
if(mainGame->dField.select_cancelable) {
mainGame->dField.ShowCancelOrFinishButton(1);
}
return false;
}
case MSG_SELECT_POSITION: {
......@@ -1820,6 +1826,8 @@ 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.selectsum_all.clear();
mainGame->dField.selectsum_cards.clear();
mainGame->dField.select_panalmode = false;
int c, l, s, t;
unsigned int code;
......@@ -1835,10 +1843,12 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
if (code && pcard->code != code)
pcard->SetCode(code);
mainGame->dField.selectable_cards.push_back(pcard);
pcard->opParam = t;
mainGame->dField.selectsum_all.push_back(pcard);
pcard->opParam = t << 16 | 1;
pcard->select_seq = i;
pcard->is_selectable = true;
}
mainGame->dField.CheckSelectTribute();
if(select_hint)
myswprintf(textBuffer, L"%ls(%d-%d)", dataManager.GetDesc(select_hint),
mainGame->dField.select_min, mainGame->dField.select_max);
......@@ -3617,7 +3627,14 @@ int DuelClient::ClientAnalyze(char * msg, unsigned int len) {
int chtype = BufferIO::ReadInt8(pbuf);
int value = BufferIO::ReadInt32(pbuf);
auto& player_desc_hints = mainGame->dField.player_desc_hints[player];
if(value == CARD_QUESTION && player == 0) {
if(chtype == PHINT_DESC_ADD) {
mainGame->dField.cant_check_grave = true;
} else if(chtype == PHINT_DESC_REMOVE) {
mainGame->dField.cant_check_grave = false;
}
}
else if(chtype == PHINT_DESC_ADD) {
player_desc_hints[value]++;
} else if(chtype == PHINT_DESC_REMOVE) {
player_desc_hints[value]--;
......
......@@ -881,14 +881,16 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnCardSelect[i]->setRelativePosition(rect<s32>(30 + i * 125, 55, 30 + 120 + i * 125, 225));
// text
wchar_t formatBuffer[2048];
if(sort_list.size()) {
if(sort_list[pos + i] > 0)
if(mainGame->dInfo.curMsg == MSG_SORT_CARD) {
if(sort_list[pos + i])
myswprintf(formatBuffer, L"%d", sort_list[pos + i]);
else
myswprintf(formatBuffer, L"");
} else {
if(conti_selecting)
myswprintf(formatBuffer, L"%ls", DataManager::unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(selectable_cards[i + pos]->overlayTarget->location, selectable_cards[i + pos]->overlayTarget->sequence),
......@@ -1189,6 +1191,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
case LOCATION_GRAVE: {
if(grave[hovered_controler].size() == 0)
break;
if(cant_check_grave)
break;
ShowMenu(COMMAND_LIST, x, y);
break;
}
......@@ -1239,6 +1243,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
int command_flag = 0;
if(grave[hovered_controler].size() == 0)
break;
if(cant_check_grave)
break;
for(size_t i = 0; i < grave[hovered_controler].size(); ++i)
command_flag |= grave[hovered_controler][i]->cmdFlag;
command_flag |= COMMAND_LIST;
......@@ -1335,16 +1341,16 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
selected_field = 0;
DuelClient::SetResponseB(respbuf, p);
DuelClient::SendResponse();
ShowCancelOrFinishButton(0);
}
}
}
break;
}
case MSG_SELECT_CARD:
case MSG_SELECT_TRIBUTE: {
if (!(hovered_location & 0xe) || !clicked_card || !clicked_card->is_selectable)
case MSG_SELECT_CARD: {
if(!(hovered_location & 0xe) || !clicked_card || !clicked_card->is_selectable)
break;
if (clicked_card->is_selected) {
if(clicked_card->is_selected) {
clicked_card->is_selected = false;
int i = 0;
while(selected_cards[i] != clicked_card) i++;
......@@ -1353,18 +1359,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
clicked_card->is_selected = true;
selected_cards.push_back(clicked_card);
}
int min = selected_cards.size(), max = 0;
if (mainGame->dInfo.curMsg == MSG_SELECT_CARD) {
max = selected_cards.size();
} else {
for(size_t i = 0; i < selected_cards.size(); ++i)
max += selected_cards[i]->opParam;
}
if (min >= select_max) {
if(selected_cards.size() >= select_max) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
} else if (max >= select_min) {
} else if(selected_cards.size() >= select_min) {
if(selected_cards.size() == selectable_cards.size()) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
......@@ -1372,18 +1371,37 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
} else {
select_ready = true;
ShowCancelOrFinishButton(2);
if(mainGame->dInfo.curMsg == MSG_SELECT_TRIBUTE) {
wchar_t wbuf[256], *pwbuf = wbuf;
BufferIO::CopyWStrRef(dataManager.GetSysString(209), pwbuf, 256);
*pwbuf++ = L'\n';
BufferIO::CopyWStrRef(dataManager.GetSysString(210), pwbuf, 256);
mainGame->stQMessage->setText(wbuf);
mainGame->PopupElement(mainGame->wQuery);
}
} else {
select_ready = false;
if(select_cancelable && selected_cards.size() == 0)
ShowCancelOrFinishButton(1);
else
ShowCancelOrFinishButton(0);
}
break;
}
case MSG_SELECT_TRIBUTE: {
if (!(hovered_location & 0xe) || !clicked_card || !clicked_card->is_selectable)
break;
if(clicked_card->is_selected) {
auto it = std::find(selected_cards.begin(), selected_cards.end(), clicked_card);
selected_cards.erase(it);
} else {
selected_cards.push_back(clicked_card);
}
if(CheckSelectTribute()) {
if(selectsum_cards.size() == 0) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
} else {
select_ready = true;
ShowCancelOrFinishButton(2);
}
} else {
select_ready = false;
if (select_cancelable && min == 0)
if (select_cancelable && selected_cards.size() == 0)
ShowCancelOrFinishButton(1);
else
ShowCancelOrFinishButton(0);
......@@ -1719,6 +1737,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
display_cards.clear();
switch(event.KeyInput.Key) {
case irr::KEY_F1:
if(cant_check_grave)
break;
loc_id = 1004;
for(auto it = grave[0].rbegin(); it != grave[0].rend(); ++it)
display_cards.push_back(*it);
......@@ -1743,6 +1763,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}
break;
case irr::KEY_F5:
if(cant_check_grave)
break;
loc_id = 1004;
for(auto it = grave[1].rbegin(); it != grave[1].rend(); ++it)
display_cards.push_back(*it);
......@@ -2316,14 +2338,22 @@ void ClientField::SetShowMark(ClientCard* pcard, bool enable) {
}
void ClientField::ShowCardInfoInList(ClientCard* pcard, irr::gui::IGUIElement* element, irr::gui::IGUIElement* parent) {
std::wstring str(L"");
wchar_t formatBuffer[2048];
if(pcard->code) {
str.append(dataManager.GetName(pcard->code));
}
if(pcard->overlayTarget) {
myswprintf(formatBuffer, dataManager.GetSysString(225), dataManager.GetName(pcard->overlayTarget->code), pcard->overlayTarget->sequence + 1);
str.append(L"\n").append(formatBuffer);
}
if((pcard->status & STATUS_PROC_COMPLETE)
&& (pcard->type & (TYPE_RITUAL | TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK | TYPE_SPSUMMON)))
str.append(L"\n").append(dataManager.GetSysString(224));
for(auto iter = pcard->desc_hints.begin(); iter != pcard->desc_hints.end(); ++iter) {
myswprintf(formatBuffer, L"\n*%ls", dataManager.GetDesc(iter->first));
str.append(formatBuffer);
}
for(size_t i = 0; i < chains.size(); ++i) {
wchar_t formatBuffer[2048];
auto chit = chains[i];
if(pcard == chit.chain_card) {
myswprintf(formatBuffer, dataManager.GetSysString(216), i + 1);
......@@ -2469,6 +2499,11 @@ void ClientField::CancelOrFinish() {
mainGame->HideElement(mainGame->wQuery, true);
break;
}
if(select_ready) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
}
break;
}
case MSG_SELECT_SUM: {
......@@ -2506,6 +2541,20 @@ void ClientField::CancelOrFinish() {
if(mainGame->wCardSelect->isVisible()) {
DuelClient::SetResponseI(-1);
mainGame->HideElement(mainGame->wCardSelect, true);
sort_list.clear();
}
break;
}
case MSG_SELECT_PLACE: {
if(select_cancelable) {
unsigned char respbuf[3];
respbuf[0] = mainGame->LocalPlayer(0);
respbuf[1] = 0;
respbuf[2] = 0;
mainGame->dField.selectable_field = 0;
DuelClient::SetResponseB(respbuf, 3);
DuelClient::SendResponse();
ShowCancelOrFinishButton(0);
}
break;
}
......
......@@ -10,7 +10,7 @@
#include "netserver.h"
#include "single_mode.h"
const unsigned short PRO_VERSION = 0x1351;
const unsigned short PRO_VERSION = 0x1352;
namespace ygo {
......@@ -71,14 +71,70 @@ bool Game::Initialize() {
dataManager.LoadStrings("./expansions/strings.conf");
env = device->getGUIEnvironment();
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12);
lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48);
guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(!numFont) {
const wchar_t* numFontPaths[] = {
L"C:/Windows/Fonts/arialbd.ttf",
L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf",
L"/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc",
L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Bold.ttc",
L"/System/Library/Fonts/SFNSTextCondensed-Bold.otf",
L"/System/Library/Fonts/SFNS.ttf",
L"./fonts/numFont.ttf",
L"./fonts/numFont.ttc",
L"./fonts/numFont.otf"
};
for(const wchar_t* path : numFontPaths) {
myswprintf(gameConf.numfont, path);
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
if(numFont)
break;
}
}
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(!textFont) {
const wchar_t* textFontPaths[] = {
L"C:/Windows/Fonts/msyh.ttc",
L"C:/Windows/Fonts/msyh.ttf",
L"C:/Windows/Fonts/simsun.ttc",
L"/usr/share/fonts/truetype/DroidSansFallbackFull.ttf",
L"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
L"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
L"/System/Library/Fonts/PingFang.ttc",
L"./fonts/textFont.ttf",
L"./fonts/textFont.ttc",
L"./fonts/textFont.otf"
};
for(const wchar_t* path : textFontPaths) {
myswprintf(gameConf.textfont, path);
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
if(textFont)
break;
}
}
if(!numFont || !textFont) {
wchar_t fpath[1024];
fpath[0] = 0;
FileSystem::TraversalDir(L"./fonts", [&fpath](const wchar_t* name, bool isdir) {
if(!isdir && wcsrchr(name, '.') && (!mywcsncasecmp(wcsrchr(name, '.'), L".ttf", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".ttc", 4) || !mywcsncasecmp(wcsrchr(name, '.'), L".otf", 4))) {
myswprintf(fpath, L"./fonts/%ls", name);
}
});
if(fpath[0] == 0) {
ErrorLog("Failed to load font(s)!");
return false;
}
if(!numFont) {
myswprintf(gameConf.numfont, fpath);
numFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 16);
}
if(!textFont) {
myswprintf(gameConf.textfont, fpath);
textFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
}
}
adFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 12);
lpcFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.numfont, 48);
guiFont = irr::gui::CGUITTFont::createTTFont(env, gameConf.textfont, gameConf.textfontsize);
smgr = device->getSceneManager();
device->setWindowCaption(L"YGOPro");
device->setResizable(true);
......@@ -710,6 +766,9 @@ bool Game::Initialize() {
btnBotCancel = env->addButton(rect<s32>(459, 331, 569, 356), tabBot, BUTTON_CANCEL_SINGLEPLAY, dataManager.GetSysString(1210));
env->addStaticText(dataManager.GetSysString(1382), rect<s32>(360, 10, 550, 30), false, true, tabBot);
stBotInfo = env->addStaticText(L"", rect<s32>(360, 40, 560, 160), false, true, tabBot);
cbBotDeck = env->addComboBox(rect<s32>(360, 130, 560, 155), tabBot);
cbBotDeck->setMaxSelectionRows(6);
cbBotDeck->setVisible(false);
cbBotRule = env->addComboBox(rect<s32>(360, 165, 560, 190), tabBot, COMBOBOX_BOT_RULE);
cbBotRule->addItem(dataManager.GetSysString(1262));
cbBotRule->addItem(dataManager.GetSysString(1263));
......@@ -806,7 +865,6 @@ bool Game::Initialize() {
stCardListTip->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
stCardListTip->setVisible(false);
device->setEventReceiver(&menuHandler);
LoadConfig();
if(!soundManager.Init()) {
chkEnableSound->setChecked(false);
chkEnableSound->setEnabled(false);
......@@ -1123,6 +1181,7 @@ void Game::RefreshBot() {
newinfo.support_master_rule_3 = !!strstr(linebuf, "SUPPORT_MASTER_RULE_3");
newinfo.support_new_master_rule = !!strstr(linebuf, "SUPPORT_NEW_MASTER_RULE");
newinfo.support_master_rule_2020 = !!strstr(linebuf, "SUPPORT_MASTER_RULE_2020");
newinfo.select_deckfile = !!strstr(linebuf, "SELECT_DECKFILE");
int rule = cbBotRule->getSelected() + 3;
if((rule == 3 && newinfo.support_master_rule_3)
|| (rule == 4 && newinfo.support_new_master_rule)
......@@ -1138,8 +1197,23 @@ void Game::RefreshBot() {
for(unsigned int i = 0; i < botInfo.size(); ++i) {
lstBotList->addItem(botInfo[i].name);
}
if(botInfo.size() == 0)
if(botInfo.size() == 0) {
SetStaticText(stBotInfo, 200, guiFont, dataManager.GetSysString(1385));
}
else {
cbBotDeck->clear();
cbBotDeck->setVisible(false);
irr::gui::IGUIComboBox* cbDeck = cbBotDeck;
FileSystem::TraversalDir(gameConf.bot_deck_path, [cbDeck](const wchar_t* name, bool isdir) {
if(!isdir && wcsrchr(name, '.') && !mywcsncasecmp(wcsrchr(name, '.'), L".ydk", 4)) {
size_t len = wcslen(name);
wchar_t deckname[256];
wcsncpy(deckname, name, len - 4);
deckname[len - 4] = 0;
cbDeck->addItem(deckname);
}
});
}
}
void Game::LoadConfig() {
FILE* fp = fopen("system.conf", "r");
......@@ -1153,7 +1227,7 @@ void Game::LoadConfig() {
gameConf.use_image_scale = 1;
gameConf.antialias = 0;
gameConf.serverport = 7911;
gameConf.textfontsize = 12;
gameConf.textfontsize = 14;
gameConf.nickname[0] = 0;
gameConf.gamename[0] = 0;
gameConf.bot_deck_path[0] = 0;
......@@ -1164,6 +1238,7 @@ void Game::LoadConfig() {
gameConf.lasthost[0] = 0;
gameConf.lastport[0] = 0;
gameConf.roompass[0] = 0;
gameConf.bot_deck_path[0] = 0;
//settings
gameConf.chkMAutoPos = 0;
gameConf.chkSTAutoPos = 1;
......@@ -1208,7 +1283,7 @@ void Game::LoadConfig() {
enable_log = atoi(valbuf);
} else if(!strcmp(strbuf, "textfont")) {
BufferIO::DecodeUTF8(valbuf, wstr);
int textfontsize;
int textfontsize = gameConf.textfontsize;
sscanf(linebuf, "%s = %s %d", strbuf, valbuf, &textfontsize);
gameConf.textfontsize = textfontsize;
BufferIO::CopyWStr(wstr, gameConf.textfont, 256);
......@@ -1226,6 +1301,9 @@ void Game::LoadConfig() {
} else if(!strcmp(strbuf, "roompass")) {
BufferIO::DecodeUTF8(valbuf, wstr);
BufferIO::CopyWStr(wstr, gameConf.roompass, 20);
} else if(!strcmp(strbuf, "bot_deck_path")) {
BufferIO::DecodeUTF8(valbuf, wstr);
BufferIO::CopyWStr(wstr, gameConf.bot_deck_path, 64);
} else if(!strcmp(strbuf, "automonsterpos")) {
gameConf.chkMAutoPos = atoi(valbuf);
} else if(!strcmp(strbuf, "autospellpos")) {
......
......@@ -95,6 +95,7 @@ struct BotInfo {
bool support_master_rule_3;
bool support_new_master_rule;
bool support_master_rule_2020;
bool select_deckfile;
};
struct FadingUnit {
......@@ -374,6 +375,7 @@ public:
irr::gui::IGUIStaticText* stBotInfo;
irr::gui::IGUIButton* btnStartBot;
irr::gui::IGUIButton* btnBotCancel;
irr::gui::IGUIComboBox* cbBotDeck;
irr::gui::IGUIComboBox* cbBotRule;
irr::gui::IGUICheckBox* chkBotHand;
irr::gui::IGUICheckBox* chkBotNoCheckDeck;
......
......@@ -298,9 +298,14 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
wchar_t cmd[MAX_PATH];
wchar_t arg1[512];
if(mainGame->botInfo[sel].select_deckfile)
myswprintf(arg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, mainGame->cbBotDeck->getItem(mainGame->cbBotDeck->getSelected()));
else
myswprintf(arg1, L"%ls", mainGame->botInfo[sel].command);
int flag = 0;
flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0);
myswprintf(cmd, L"Bot.exe \"%ls\" %d %d", mainGame->botInfo[sel].command, flag, mainGame->gameConf.serverport);
myswprintf(cmd, L"Bot.exe \"%ls\" %d %d", arg1, flag, mainGame->gameConf.serverport);
if(!CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
NetServer::StopServer();
......@@ -309,8 +314,13 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
#else
if(fork() == 0) {
usleep(100000);
wchar_t warg1[512];
if(mainGame->botInfo[sel].select_deckfile)
myswprintf(warg1, L"%ls DeckFile='%ls'", mainGame->botInfo[sel].command, mainGame->cbBotDeck->getItem(mainGame->cbBotDeck->getSelected()));
else
myswprintf(warg1, L"%ls", mainGame->botInfo[sel].command);
char arg1[512];
BufferIO::EncodeUTF8(mainGame->botInfo[sel].command, arg1);
BufferIO::EncodeUTF8(warg1, arg1);
int flag = 0;
flag += (mainGame->chkBotHand->isChecked() ? 0x1 : 0);
char arg2[8];
......@@ -519,6 +529,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
if(sel == -1)
break;
mainGame->SetStaticText(mainGame->stBotInfo, 200, mainGame->guiFont, mainGame->botInfo[sel].desc);
mainGame->cbBotDeck->setVisible(mainGame->botInfo[sel].select_deckfile);
break;
}
}
......
This diff is collapsed.
Subproject commit 4d2e3603745b8e92ab0248c9ff49174d0cbb4f5a
Subproject commit 242b903fda8ba2e17c053be465abcd9508404dec
Subproject commit 216c4754fb203fe2f598fee02ace05e54f7cea55
Subproject commit b6819fc3480b886fd6f1a840297e8df2367e0c43
......@@ -17,7 +17,7 @@
!system 22 主要阶段中
!system 23 即将结束主要阶段
!system 24 战斗阶段中
!system 25 战斗结束阶段中
!system 25 战斗阶段结束时
!system 26 结束阶段中
!system 27 抽卡前
!system 28 战斗阶段开始
......@@ -80,6 +80,7 @@
!system 222 是否要发动诱发效果?
!system 223 稍后将询问其他可以发动的效果。
!system 224 已用正规方法特殊召唤
!system 225 叠放于[%ls](%d)下
!system 500 请选择要解放的卡
!system 501 请选择要丢弃的手卡
!system 502 请选择要破坏的卡
......@@ -485,9 +486,9 @@
!system 1500 决斗结束。
!system 1501 录像结束。
!system 1502 连接已断开。
!system 1510 对方选择了:[%ls]
!system 1511 对方宣言了:[%ls]
!system 1512 对方选择了:[%d]
!system 1510 玩家选择了:[%ls]
!system 1511 玩家宣言了:[%ls]
!system 1512 玩家选择了:[%d]
!system 1600 卡片改变了表示形式
!system 1601 盖放了卡片
!system 1602 卡的控制权改变了
......@@ -498,7 +499,7 @@
!system 1607 [%ls]反转召唤中
!system 1608 怪兽反转召唤成功
!system 1609 [%ls]的效果发动
!system 1610 [%ls](%ls,%d)成为对象
!system 1610 [%ls](%ls,%d)成为对象或目标
!system 1611 我方抽了%d张卡
!system 1612 对方抽了%d张卡
!system 1613 我方受到%d伤害
......@@ -521,24 +522,24 @@
!victory 0x2 没有卡可抽
!victory 0x3 超时
!victory 0x4 失去连接
!victory 0x10 「被封印的艾克佐迪亚」效果胜利
!victory 0x11 「终焉的倒计时」效果胜利
!victory 0x12 「毒蛇神 维诺米纳迦」效果胜利
!victory 0x13 「光之创造神 哈拉克提」效果胜利
!victory 0x14 「究极封印神 艾克佐迪奥斯」效果胜利
!victory 0x15 「通灵盘」效果胜利
!victory 0x16 「最终一战!」效果胜利
!victory 0x17No.88 机关傀儡-命运狮子」效果胜利
!victory 0x18 「混沌No.88 机关傀儡-灾厄狮子」效果胜利
!victory 0x19 「头奖壶7效果胜利
!victory 0x1a 「魂之接力」效果胜利
!victory 0x1b 「鬼计惰天使」效果胜利
!victory 0x1c 「幻煌龙的天涡」效果胜利
!victory 0x1d 「方程式运动员胜利团队」效果胜利
!victory 0x1e 「飞行象」效果胜利
!victory 0x1f 「守护神 艾克佐迪亚」效果胜利
!victory 0x20 「真艾克佐迪亚」效果胜利
!victory 0xffff 由于「%ls的效果获得比赛胜利
!victory 0x10 「被封印的艾克佐迪亚」特殊胜利
!victory 0x11 「终焉的倒计时」特殊胜利
!victory 0x12 「毒蛇神 维诺米纳迦」特殊胜利
!victory 0x13 「光之创造神 哈拉克提」特殊胜利
!victory 0x14 「究极封印神 艾克佐迪奥斯」特殊胜利
!victory 0x15 「通灵盘」特殊胜利
!victory 0x16 「最终一战!」特殊胜利
!victory 0x17No.88 机关傀儡-命运狮子」特殊胜利
!victory 0x18 「混沌No.88 机关傀儡-灾厄狮子」特殊胜利
!victory 0x19 「头奖壶7特殊胜利
!victory 0x1a 「魂之接力」特殊胜利
!victory 0x1b 「鬼计惰天使」特殊胜利
!victory 0x1c 「幻煌龙的天涡」特殊胜利
!victory 0x1d 「方程式运动员胜利团队」特殊胜利
!victory 0x1e 「飞行象」特殊胜利
!victory 0x1f 「守护神 艾克佐迪亚」特殊胜利
!victory 0x20 「真艾克佐迪亚」特殊胜利
!victory 0xffff 由于「%ls」获得比赛胜利
#counters
!counter 0x1 魔力指示物
!counter 0x1002 楔指示物
......@@ -621,6 +622,10 @@
!counter 0x55 指示物(隐居者的大釜)
!counter 0x56 炎星指示物
!counter 0x57 幻魔指示物
!counter 0x58 指示物(祢须三破鸣比)
!counter 0x59 落魂指示物
!counter 0x5a 指示物(岩战之试炼)
!counter 0x5b 指示物(北极天熊北斗星)
#setnames, using tab for comment
!setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス
......@@ -668,7 +673,7 @@
!setname 0x1a 黑蝎 黒蠍
!setname 0x1b 幻兽 幻獣
!setname 0x101b 幻兽机 幻獣機
#setname 0x1c N/A
!setname 0x1c 死之信息 死のメッセージ
!setname 0x1d 核成 コアキメイル
!setname 0x1e 茧状体 C(コクーン)
!setname 0x1f 新空间侠 N(ネオスペーシアン)
......@@ -796,7 +801,9 @@
!setname 0x7c 炎舞
!setname 0x7d 阳炎 ヘイズ
!setname 0x107d 阳炎兽 陽炎獣
!setname 0x7e 异热同心武器 ZW(ゼアル・ウェポン)
!setname 0x7e 异热同心 ゼアル
!setname 0x107e 异热同心武器 ZW(ゼアル・ウェポン)
!setname 0x207e 异热同心从者 ZS(ゼアル・サーバス)
!setname 0x7f 霍普 ホープ
!setname 0x107f 希望皇 霍普 希望皇ホープ
!setname 0x207f 未来皇 霍普 未来皇ホープ
......@@ -813,7 +820,7 @@
!setname 0x89 洞 ホール
#setname 0x8a 虫惑 蟲惑
!setname 0x108a 虫惑魔 蟲惑魔
!setname 0x8b 恶餐 マリスボラス
!setname 0x8b 食恶 マリスボラス
#setname 0x8c 德鲁伊 ドルイド
!setname 0x8d 鬼计 ゴーストリック
!setname 0x8e 吸血鬼 ヴァンパイア
......@@ -927,6 +934,7 @@
!setname 0xe3 方界
!setname 0xe4 精灵剑士 エルフの剣士
!setname 0xe5 光波 サイファー
!setname 0x10e5 光波龙 サイファー・ドラゴン
!setname 0xe6 花札卫 花札衛
!setname 0xe7 沉默剑士 サイレント・ソードマン
!setname 0xe8 沉默魔术师 サイレント・マジシャン
......@@ -979,7 +987,8 @@
!setname 0x10d 魔导兽|非「魔导」 魔導獣
!setname 0x10e 进化药 進化薬
!setname 0x10f 枪管 ヴァレル
!setname 0x110 眼纳祭神 アイズ・サクリファイス
!setname 0x110 纳祭 サクリファイス
!setname 0x1110 眼纳祭神 アイズ・サクリファイス
!setname 0x111 武装龙 アームド・ドラゴン
!setname 0x112 幻崩 トロイメア
!setname 0x113 灵神 霊神
......@@ -998,7 +1007,7 @@
!setname 0x11f 奈芙提斯 ネフティス
!setname 0x120 调皮宝贝 プランキッズ
!setname 0x121 魔妖
!setname 0x122 女武神 ワルキューレ
!setname 0x122 女武神|非「武神」 ワルキューレ
!setname 0x123 蔷薇 ローズ
!setname 0x1123 蔷薇龙 ローズ・ドラゴン
!setname 0x124 机械天使 機械天使
......@@ -1015,7 +1024,7 @@
!setname 0x12f 蜂军 BF(ビー・フォース)
!setname 0x130 破械
!setname 0x1130 破械神
!setname 0x131Dream Mirror
!setname 0x131魔镜 夢魔鏡
!setname 0x132 斩机 斬機
!setname 0x133 半龙女仆 ドラゴンメイド
!setname 0x134 王战 ジェネレイド
......@@ -1029,7 +1038,7 @@
!setname 0x13c 代码破坏者 コードブレイカー
!setname 0x13d 星义 ネメシス
!setname 0x13e 巴巴罗斯 バルバロス
!setname 0x13f 巡掠海魔 Plunder Patroll
!setname 0x13f 海造贼 海造賊
!setname 0x140 魔救 アダマシア
!setname 0x141 六花
#setname 0x142 黄金国 エルド
......@@ -1047,8 +1056,36 @@
!setname 0x14b 机块 機塊
#setname 0x14c 灵术 霊術
!setname 0x314c 地灵术 地霊術
#setname 0x514c 水灵术 水霊術
!setname 0x514c 水灵术 水霊術
!setname 0x614c 火灵术 火霊術
#setname 0x914c 风灵术 風霊術
!setname 0x914c 风灵术 風霊術
#setname 0xa14c 光灵术 光霊術
#setname 0xc14c 暗灵术 闇霊術
!setname 0x14d 铁兽 トライブリゲード
!setname 0x14e 电脑堺 電脳堺
!setname 0x114e 电脑堺门 電脳堺門
!setname 0x14f 双天
!setname 0x150 大贤者 マギストス
#setname 0x151 双子 Twin
!setname 0x1151 直播☆双子 LiveTwin
!setname 0x2151 邪恶★双子 EvilTwin
!setname 0x152 姬丝基勒 キスキル
!setname 0x153 璃拉 リィラ
!setname 0x154 龙辉巧 ドライトロン
!setname 0x155 护宝炮妖 スプリガンズ
!setname 0x156 治安战警队 SForce
!setname 0x157 突变体 Myutant
#setname 0x158 圣 サン
!setname 0x1158 圣蔓 サンヴァイン
!setname 0x2158 圣天树 サンアバロン
!setname 0x159 圣夜骑士 ホーリーナイツ
!setname 0x15a 人偶怪兽 ドール・モンスター
!setname 0x15b 惊乐 アメイズメント
!setname 0x15c 游乐设施 アトラクション
!setname 0x15d 烙印
!setname 0x15e 降阶魔法 RDM
!setname 0x15f 岩战 War Rock
!setname 0x160 源质兽 Materiactor
!setname 0x161 溟界
!setname 0x162 七音服 ドレミコード
!setname 0x163 北极天熊 ベアルクティ
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