Commit a90e6c8a authored by mercury233's avatar mercury233 Committed by GitHub

update selecting tributes (#2304)

parent b3940207
......@@ -1209,6 +1209,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 +1293,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;
......
......@@ -106,10 +106,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();
......
......@@ -1824,6 +1824,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;
......@@ -1839,10 +1841,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);
......
......@@ -1341,11 +1341,10 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
}
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++;
......@@ -1354,18 +1353,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);
......@@ -1373,18 +1365,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);
......@@ -2474,6 +2485,11 @@ void ClientField::CancelOrFinish() {
mainGame->HideElement(mainGame->wQuery, true);
break;
}
if(select_ready) {
SetResponseSelectedCards();
ShowCancelOrFinishButton(0);
DuelClient::SendResponse();
}
break;
}
case MSG_SELECT_SUM: {
......
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