Commit a75565fe authored by nanahira's avatar nanahira

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

parents 7fcafa98 23f54dd0
......@@ -32,6 +32,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);
......@@ -99,6 +100,7 @@ void ClientField::Clear() {
pzone_act[1] = false;
conti_act = false;
deck_reversed = false;
cant_check_grave = false;
RefreshCardCountDisplay();
}
void ClientField::Initial(int player, int deckc, int extrac) {
......@@ -396,6 +398,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) {
......@@ -422,6 +436,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),
......@@ -1245,6 +1261,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;
......@@ -1308,6 +1345,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;
......
......@@ -83,6 +83,7 @@ public:
bool last_chain;
bool deck_reversed;
bool conti_selecting;
bool cant_check_grave;
ClientField();
void Clear();
......@@ -108,10 +109,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();
......@@ -153,5 +158,6 @@ public:
//special cards
#define CARD_MARINE_DOLPHIN 78734254
#define CARD_TWINKLE_MOSS 13857930
#define CARD_QUESTION 38723936
#endif //CLIENT_FIELD_H
......@@ -447,7 +447,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);
......@@ -531,6 +531,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);
......
......@@ -1875,7 +1875,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);
......@@ -1950,6 +1953,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: {
......@@ -2003,6 +2009,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;
......@@ -2018,10 +2026,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);
......@@ -3880,7 +3890,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(chtype == PHINT_DESC_ADD) {
if(value == CARD_QUESTION && player == 0) {
/* if(chtype == PHINT_DESC_ADD) { // KoishiPro disables this
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]--;
......
......@@ -905,6 +905,8 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
} 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),
......@@ -1207,6 +1209,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;
}
......@@ -1257,6 +1261,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;
......@@ -1353,16 +1359,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++;
......@@ -1371,18 +1377,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);
......@@ -1390,18 +1389,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 && min == 0)
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 && selected_cards.size() == 0)
ShowCancelOrFinishButton(1);
else
ShowCancelOrFinishButton(0);
......@@ -1748,6 +1766,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);
......@@ -1772,6 +1792,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);
......@@ -2583,6 +2605,11 @@ void ClientField::CancelOrFinish() {
mainGame->HideElement(mainGame->wQuery, true);
break;
}
if(select_ready) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
}
break;
}
case MSG_SELECT_SUM: {
......@@ -2623,6 +2650,19 @@ void ClientField::CancelOrFinish() {
}
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;
}
}
}
}
......@@ -12,7 +12,7 @@
#include <sstream>
#include <regex>
unsigned short PRO_VERSION = 0x1351;
unsigned short PRO_VERSION = 0x1352;
namespace ygo {
......
......@@ -1068,3 +1068,10 @@
!setname 0x14e 电脑堺 電脳堺
!setname 0x114e 电脑堺门 電脳堺門
!setname 0x14f 双天
!setname 0x150 大贤者 マギストス
#setname 0x151 双子 Twin
!setname 0x1151 直播☆双子 LiveTwin
!setname 0x2151 邪恶★双子 EvilTwin
!setname 0x152 姬丝基勒 キスキル
!setname 0x153 璃拉 リィラ
!setname 0x154 龙辉巧 ドライトロン
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