Commit 49d52fb4 authored by VanillaSalt's avatar VanillaSalt

update check/select_with_sum

parent 68920d71
...@@ -1967,6 +1967,35 @@ int32 field::check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 in ...@@ -1967,6 +1967,35 @@ int32 field::check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 in
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int32 field::check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin) {
while(index < (int32)mats.size()) {
int32 op1 = mats[index]->operation_param & 0xffff;
int32 op2 = (mats[index]->operation_param >> 16) & 0xffff;
if((acc <= op1 && acc + opmin > op1) || (op2 && acc <= op2 && acc + opmin > op2))
return TRUE;
index++;
if(check_with_sum_greater_limit(mats, acc - op1, index, std::min(opmin, op1)))
return TRUE;
if(op2 && check_with_sum_greater_limit(mats, acc - op2, index, std::min(opmin, op2)))
return TRUE;
}
return FALSE;
}
int32 field::check_with_sum_greater_limit_m(const card_vector& mats, int32 acc, int32 index, int32 opmin, int32 must_count) {
if(acc <= 0)
return index == must_count && acc + opmin > 0;
if(index == must_count)
return check_with_sum_greater_limit(mats, acc, index, opmin);
if(index >= (int32)mats.size())
return FALSE;
int32 op1 = mats[index]->operation_param & 0xffff;
int32 op2 = (mats[index]->operation_param >> 16) & 0xffff;
if(check_with_sum_greater_limit_m(mats, acc - op1, index + 1, std::min(opmin, op1), must_count))
return TRUE;
if(op2 && check_with_sum_greater_limit_m(mats, acc - op2, index + 1, std::min(opmin, op2), must_count))
return TRUE;
return FALSE;
}
int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min, int32 max, group* mg) { int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min, int32 max, group* mg) {
get_xyz_material(scard, findex, lv, max, mg); get_xyz_material(scard, findex, lv, max, mg);
return (int32)core.xmaterial_lst.size() >= min; return (int32)core.xmaterial_lst.size() >= min;
......
...@@ -391,6 +391,8 @@ public: ...@@ -391,6 +391,8 @@ public:
int32 check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg); int32 check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
static int32 check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max); static int32 check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max);
static int32 check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 must_count); static int32 check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 must_count);
static int32 check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin);
static int32 check_with_sum_greater_limit_m(const card_vector& mats, int32 acc, int32 index, int32 opmin, int32 must_count);
int32 check_xyz_material(card* pcard, int32 findex, int32 lv, int32 min, int32 max, group* mg); int32 check_xyz_material(card* pcard, int32 findex, int32 lv, int32 min, int32 max, group* mg);
int32 is_player_can_draw(uint8 playerid); int32 is_player_can_draw(uint8 playerid);
......
...@@ -437,6 +437,7 @@ static const struct luaL_Reg duellib[] = { ...@@ -437,6 +437,7 @@ static const struct luaL_Reg duellib[] = {
{ "CheckTunerMaterial", scriptlib::duel_check_tuner_material }, { "CheckTunerMaterial", scriptlib::duel_check_tuner_material },
{ "GetRitualMaterial", scriptlib::duel_get_ritual_material }, { "GetRitualMaterial", scriptlib::duel_get_ritual_material },
{ "ReleaseRitualMaterial", scriptlib::duel_release_ritual_material }, { "ReleaseRitualMaterial", scriptlib::duel_release_ritual_material },
{ "SetSelectedCard", scriptlib::duel_set_must_select_cards },
{ "SetTargetCard", scriptlib::duel_set_target_card }, { "SetTargetCard", scriptlib::duel_set_target_card },
{ "ClearTargetCard", scriptlib::duel_clear_target_card }, { "ClearTargetCard", scriptlib::duel_clear_target_card },
{ "SetTargetPlayer", scriptlib::duel_set_target_player }, { "SetTargetPlayer", scriptlib::duel_set_target_player },
......
...@@ -2222,6 +2222,21 @@ int32 scriptlib::duel_release_ritual_material(lua_State *L) { ...@@ -2222,6 +2222,21 @@ int32 scriptlib::duel_release_ritual_material(lua_State *L) {
pgroup->pduel->game_field->ritual_release(&pgroup->container); pgroup->pduel->game_field->ritual_release(&pgroup->container);
return lua_yield(L, 0); return lua_yield(L, 0);
} }
int32 scriptlib::duel_set_must_select_cards(lua_State *L) {
check_param_count(L, 1);
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* pcard = *(card**) lua_touserdata(L, 1);
duel* pduel = pcard->pduel;
pduel->game_field->core.must_select_cards.clear();
pduel->game_field->core.must_select_cards.push_back(pcard);
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
pduel->game_field->core.must_select_cards.assign(pgroup->container.begin(), pgroup->container.end());
} else
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
return 0;
}
int32 scriptlib::duel_set_target_card(lua_State *L) { int32 scriptlib::duel_set_target_card(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 1); check_param_count(L, 1);
......
...@@ -281,18 +281,21 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) { ...@@ -281,18 +281,21 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) {
int32 acc = lua_tointeger(L, 3); int32 acc = lua_tointeger(L, 3);
int32 min = lua_tointeger(L, 4); int32 min = lua_tointeger(L, 4);
int32 max = lua_tointeger(L, 5); int32 max = lua_tointeger(L, 5);
if(min <= 0) if(min < 0)
min = 1; min = 0;
if(max < min) if(max < min)
max = min; max = min;
int32 extraargs = lua_gettop(L) - 5; int32 extraargs = lua_gettop(L) - 5;
field::card_vector cv; field::card_vector cv(pduel->game_field->core.must_select_cards);
cv.swap(pduel->game_field->core.must_select_cards);
int32 mcount = cv.size(); int32 mcount = cv.size();
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) { for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 2, extraargs); auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), *cit);
cv.push_back(*cit); if(it == pduel->game_field->core.must_select_cards.end())
cv.push_back(*cit);
} }
pduel->game_field->core.must_select_cards.clear();
for(auto cit = cv.begin(); cit != cv.end(); ++cit)
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 2, extraargs);
lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount)); lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount));
return 1; return 1;
} }
...@@ -309,16 +312,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) { ...@@ -309,16 +312,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
int32 acc = lua_tointeger(L, 4); int32 acc = lua_tointeger(L, 4);
int32 min = lua_tointeger(L, 5); int32 min = lua_tointeger(L, 5);
int32 max = lua_tointeger(L, 6); int32 max = lua_tointeger(L, 6);
if(min <= 0) if(min < 0)
min = 1; min = 0;
if(max < min) if(max < min)
max = min; max = min;
int32 extraargs = lua_gettop(L) - 6; int32 extraargs = lua_gettop(L) - 6;
pduel->game_field->core.select_cards.clear(); pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 3, extraargs);
pduel->game_field->core.select_cards.push_back(*cit);
}
for(auto cit = pduel->game_field->core.must_select_cards.begin(); cit != pduel->game_field->core.must_select_cards.end(); ++cit) { for(auto cit = pduel->game_field->core.must_select_cards.begin(); cit != pduel->game_field->core.must_select_cards.end(); ++cit) {
auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), *cit); auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), *cit);
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end()); pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
...@@ -326,8 +325,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) { ...@@ -326,8 +325,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
field::card_vector cv(pduel->game_field->core.must_select_cards); field::card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = cv.size(); int32 mcount = cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end()); cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
if(!field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount)) for(auto cit = cv.begin(); cit != cv.end(); ++cit)
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 3, extraargs);
if(!field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount)) {
pduel->game_field->core.must_select_cards.clear();
return 0; return 0;
}
pduel->game_field->add_process(PROCESSOR_SELECT_SUM_S, 0, 0, 0, acc, playerid + (min << 16) + (max << 24)); pduel->game_field->add_process(PROCESSOR_SELECT_SUM_S, 0, 0, 0, acc, playerid + (min << 16) + (max << 24));
return lua_yield(L, 0); return lua_yield(L, 0);
} }
...@@ -339,18 +342,17 @@ int32 scriptlib::group_check_with_sum_greater(lua_State *L) { ...@@ -339,18 +342,17 @@ int32 scriptlib::group_check_with_sum_greater(lua_State *L) {
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 acc = lua_tointeger(L, 3); int32 acc = lua_tointeger(L, 3);
int32 extraargs = lua_gettop(L) - 3; int32 extraargs = lua_gettop(L) - 3;
int32 sum = 0, op, op1, op2; field::card_vector cv(pduel->game_field->core.must_select_cards);
group::card_set::iterator cit; int32 mcount = cv.size();
for(cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) { for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
op = pduel->lua->get_operation_value(*cit, 2, extraargs); auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), *cit);
op1 = op & 0xffff; if(it == pduel->game_field->core.must_select_cards.end())
op2 = op >> 16; cv.push_back(*cit);
sum += op1 > op2 ? op1 : op2;
} }
if(sum >= acc) pduel->game_field->core.must_select_cards.clear();
lua_pushboolean(L, 1); for(auto cit = cv.begin(); cit != cv.end(); ++cit)
else (*cit)->operation_param = pduel->lua->get_operation_value(*cit, 2, extraargs);
lua_pushboolean(L, 0); lua_pushboolean(L, field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount));
return 1; return 1;
} }
int32 scriptlib::group_select_with_sum_greater(lua_State *L) { int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
...@@ -365,19 +367,20 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) { ...@@ -365,19 +367,20 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
return 0; return 0;
int32 acc = lua_tointeger(L, 4); int32 acc = lua_tointeger(L, 4);
int32 extraargs = lua_gettop(L) - 4; int32 extraargs = lua_gettop(L) - 4;
field::card_set::iterator cit; pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
pduel->game_field->core.select_cards.clear(); for(auto cit = pduel->game_field->core.must_select_cards.begin(); cit != pduel->game_field->core.must_select_cards.end(); ++cit) {
int32 sum = 0, op, op1, op2; auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), *cit);
for(cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) { pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
op = pduel->lua->get_operation_value(*cit, 3, extraargs);
op1 = op & 0xffff;
op2 = op >> 16;
sum += op1 > op2 ? op1 : op2;
(*cit)->operation_param = op;
pduel->game_field->core.select_cards.push_back(*cit);
} }
if(sum < acc) field::card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
for(auto cit = cv.begin(); cit != cv.end(); ++cit)
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 3, extraargs);
if(!field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount)) {
pduel->game_field->core.must_select_cards.clear();
return 0; return 0;
}
pduel->game_field->add_process(PROCESSOR_SELECT_SUM_S, 0, 0, 0, acc, playerid); pduel->game_field->add_process(PROCESSOR_SELECT_SUM_S, 0, 0, 0, acc, playerid);
return lua_yield(L, 0); return lua_yield(L, 0);
} }
......
...@@ -586,23 +586,34 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -586,23 +586,34 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
} }
return TRUE; return TRUE;
} else { } else {
uint8 m = core.select_cards.size(), v = 0; int32 mcount = core.must_select_cards.size();
int32 op, o1, o2, sum = 0, mx = 0, mn = 0x7fffffff; int32 sum = 0, mx = 0, mn = 0x7fffffff;
int16 ms[16]; for(int32 i = 0; i < mcount; ++i) {
for(int32 i = 0; i < returns.bvalue[0]; ++i) { int32 op = core.must_select_cards[i]->operation_param;
v = returns.bvalue[i + 1]; int32 o1 = op & 0xffff;
int32 o2 = op >> 16;
int32 ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms;
mx += (o2 > o1) ? o2 : o1;
if(ms < mn)
mn = ms;
}
int32 m = core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c[v]) { if(v < 0 || v >= m || c[v]) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c[v] = 1;
op = core.select_cards[v]->operation_param; int32 op = core.select_cards[v]->operation_param;
o1 = op & 0xffff; int32 o1 = op & 0xffff;
o2 = op >> 16; int32 o2 = op >> 16;
sum += ms[i] = (o2 && o2 < o1) ? o2 : o1; int32 ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms;
mx += (o2 > o1) ? o2 : o1; mx += (o2 > o1) ? o2 : o1;
if(ms[i] < mn) if(ms < mn)
mn = ms[i]; mn = ms;
} }
if(mx < acc || sum - mn >= acc) { if(mx < acc || sum - mn >= acc) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
......
...@@ -435,6 +435,7 @@ public: ...@@ -435,6 +435,7 @@ public:
static int32 duel_check_tuner_material(lua_State *L); static int32 duel_check_tuner_material(lua_State *L);
static int32 duel_get_ritual_material(lua_State *L); static int32 duel_get_ritual_material(lua_State *L);
static int32 duel_release_ritual_material(lua_State *L); static int32 duel_release_ritual_material(lua_State *L);
static int32 duel_set_must_select_cards(lua_State *L);
static int32 duel_set_target_card(lua_State *L); static int32 duel_set_target_card(lua_State *L);
static int32 duel_clear_target_card(lua_State *L); static int32 duel_clear_target_card(lua_State *L);
static int32 duel_set_target_player(lua_State *L); static int32 duel_set_target_player(lua_State *L);
......
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