Commit ea2ad25d authored by VanillaSalt's avatar VanillaSalt

fix

parent e92e8c0b
......@@ -1783,7 +1783,6 @@ int32 field::check_synchro_material(card* pcard, int32 findex1, int32 findex2, i
return FALSE;
}
int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg) {
effect* peffect;
if(tuner && tuner->is_position(POS_FACEUP) && (tuner->get_type() & TYPE_TUNER) && tuner->is_can_be_synchro_material(pcard)) {
effect* pcheck = tuner->is_affected_by_effect(EFFECT_SYNCHRO_CHECK);
if(pcheck)
......@@ -1792,30 +1791,27 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
pduel->restore_assumes();
return FALSE;
}
if((peffect = tuner->is_affected_by_effect(EFFECT_SYNCHRO_MATERIAL_CUSTOM, pcard))) {
if(!peffect->target) {
effect* pcustom = tuner->is_affected_by_effect(EFFECT_SYNCHRO_MATERIAL_CUSTOM, pcard);
if(pcustom) {
if(!pcustom->target) {
pduel->restore_assumes();
return FALSE;
}
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(pcustom, PARAM_TYPE_EFFECT);
pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
pduel->lua->add_param(findex2, PARAM_TYPE_INDEX);
pduel->lua->add_param(min, PARAM_TYPE_INT);
pduel->lua->add_param(max, PARAM_TYPE_INT);
if(pduel->lua->check_condition(peffect->target, 5)) {
if(pduel->lua->check_condition(pcustom->target, 5)) {
pduel->restore_assumes();
return TRUE;
}
} else {
int32 l = tuner->get_synchro_level(pcard);
int32 l1 = l & 0xffff;
//int32 l2 = l >> 16;
int32 lv = pcard->get_level();
lv -= l1;
if(lv <= 0) {
pduel->restore_assumes();
return FALSE;
}
card_vector nsyn;
int32 mcount = 1;
nsyn.push_back(tuner);
tuner->operation_param = tuner->get_synchro_level(pcard);
if(smat) {
if(pcheck)
pcheck->get_value(smat);
......@@ -1823,27 +1819,25 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
pduel->restore_assumes();
return FALSE;
}
l = smat->get_synchro_level(pcard);
l1 = l & 0xffff;
lv -= l1;
min--;
max--;
if(lv <= 0) {
nsyn.push_back(smat);
smat->operation_param = smat->get_synchro_level(pcard);
mcount++;
if(min == 0) {
if(check_with_sum_limit_m(nsyn, lv, 0, 0, 0, 2)) {
pduel->restore_assumes();
if(lv == 0 && min == 0)
return TRUE;
return FALSE;
}
if(max == 0) {
pduel->restore_assumes();
return FALSE;
}
}
card_vector nsyn;
card* pm;
}
if(mg) {
for(auto cit = mg->container.begin(); cit != mg->container.end(); ++cit) {
pm = *cit;
card* pm = *cit;
if(pm != tuner && pm != smat && pm->is_can_be_synchro_material(pcard, tuner)) {
if(pcheck)
pcheck->get_value(pm);
......@@ -1858,7 +1852,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
} else {
for(uint8 p = 0; p < 2; ++p) {
for(int32 i = 0; i < 5; ++i) {
pm = player[p].list_mzone[i];
card* pm = player[p].list_mzone[i];
if(pm && pm != tuner && pm != smat && pm->is_position(POS_FACEUP) && pm->is_can_be_synchro_material(pcard, tuner)) {
if(pcheck)
pcheck->get_value(pm);
......@@ -1871,7 +1865,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
}
}
if(!(core.global_flag & GLOBALFLAG_SCRAP_CHIMERA)) {
if(check_with_sum_limit(&nsyn, lv, 0, 1, min, max)) {
if(check_with_sum_limit_m(nsyn, lv, 0, min, max, mcount)) {
pduel->restore_assumes();
return TRUE;
}
......@@ -1883,33 +1877,45 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
break;
}
if(pscrap) {
for(int32 i = 0; i < mcount; ++i) {
if(!pscrap->get_value(nsyn[i])) {
pduel->restore_assumes();
return FALSE;
}
}
card_vector nsyn_filtered;
for(auto cit = nsyn.begin(); cit != nsyn.end(); ++cit) {
if(!pscrap->get_value(*cit))
nsyn_filtered.push_back(*cit);
}
if(nsyn_filtered.size() == nsyn.size()) {
if(check_with_sum_limit(&nsyn, lv, 0, 1, min, max)) {
if(check_with_sum_limit_m(nsyn, lv, 0, min, max, mcount)) {
pduel->restore_assumes();
return TRUE;
}
} else {
if(check_with_sum_limit(&nsyn_filtered, lv, 0, 1, min, max)) {
if(check_with_sum_limit_m(nsyn_filtered, lv, 0, min, max, mcount)) {
pduel->restore_assumes();
return TRUE;
}
for(int32 i = 0; i < mcount; ++i) {
if(nsyn[i]->is_affected_by_effect(EFFECT_SCRAP_CHIMERA)) {
pduel->restore_assumes();
return FALSE;
}
}
card_vector nsyn_removed;
for(auto cit = nsyn.begin(); cit != nsyn.end(); ++cit) {
if(!(*cit)->is_affected_by_effect(EFFECT_SCRAP_CHIMERA))
nsyn_removed.push_back(*cit);
}
if(check_with_sum_limit(&nsyn_removed, lv, 0, 1, min, max)) {
if(check_with_sum_limit_m(nsyn_removed, lv, 0, min, max, mcount)) {
pduel->restore_assumes();
return TRUE;
}
}
} else {
if(check_with_sum_limit(&nsyn, lv, 0, 1, min, max)) {
if(check_with_sum_limit_m(nsyn, lv, 0, min, max, mcount)) {
pduel->restore_assumes();
return TRUE;
}
......@@ -1920,16 +1926,36 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
pduel->restore_assumes();
return FALSE;
}
int32 field::check_with_sum_limit(card_vector* mats, int32 acc, int32 index, int32 count, int32 min, int32 max) {
if((uint32)index >= mats->size())
int32 field::check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max) {
if(count > max)
return FALSE;
int32 op1 = mats->at(index)->operation_param & 0xffff;
int32 op2 = (mats->at(index)->operation_param >> 16) & 0xffff;
if((op1 == acc || op2 == acc) && count >= min && count <= max)
while(index < (int32)mats.size()) {
int32 op1 = mats[index]->operation_param & 0xffff;
int32 op2 = (mats[index]->operation_param >> 16) & 0xffff;
if((op1 == acc || op2 == acc) && count >= min)
return TRUE;
return (acc > op1 && check_with_sum_limit(mats, acc - op1, index + 1, count + 1, min, max))
|| (op2 && acc > op2 && check_with_sum_limit(mats, acc - op2, index + 1, count + 1, min, max))
|| check_with_sum_limit(mats, acc, index + 1, count, min, max);
index++;
if(acc > op1 && check_with_sum_limit(mats, acc - op1, index, count + 1, min, max))
return TRUE;
if(op2 && acc > op2 && check_with_sum_limit(mats, acc - op2, index, count + 1, min, max))
return TRUE;
}
return FALSE;
}
int32 field::check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 must_count) {
if(acc == 0)
return index == must_count && 0 >= min && 0 <= max;
if(index == must_count)
return check_with_sum_limit(mats, acc, index, 1, min, max);
if(index >= (int32)mats.size())
return FALSE;
int32 op1 = mats[index]->operation_param & 0xffff;
int32 op2 = (mats[index]->operation_param >> 16) & 0xffff;
if(acc >= op1 && check_with_sum_limit_m(mats, acc - op1, index + 1, min, max, must_count))
return TRUE;
if(op2 && acc >= op2 && check_with_sum_limit_m(mats, acc - op2, index + 1, min, max, must_count))
return TRUE;
return FALSE;
}
int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min, int32 max, group* mg) {
if(mg) {
......
......@@ -162,6 +162,7 @@ struct processor {
card_vector attackable_cards;
effect_vector select_effects;
option_vector select_options;
card_vector must_select_cards;
event_list point_event;
event_list instant_event;
event_list queue_event;
......@@ -387,7 +388,8 @@ public:
void attack_all_target_check();
int32 check_synchro_material(card* pcard, 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(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);
int32 check_xyz_material(card* pcard, int32 findex, int32 lv, int32 min, int32 max, group* mg);
int32 is_player_can_draw(uint8 playerid);
......
......@@ -287,11 +287,13 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) {
max = min;
int32 extraargs = lua_gettop(L) - 5;
field::card_vector cv;
cv.swap(pduel->game_field->core.must_select_cards);
int32 mcount = cv.size();
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 2, extraargs);
cv.push_back(*cit);
}
lua_pushboolean(L, field::check_with_sum_limit(&cv, acc, 0, 1, min, max));
lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount));
return 1;
}
int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
......@@ -317,7 +319,14 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
(*cit)->operation_param = pduel->lua->get_operation_value(*cit, 3, extraargs);
pduel->game_field->core.select_cards.push_back(*cit);
}
if(!pduel->game_field->check_with_sum_limit(&pduel->game_field->core.select_cards, acc, 0, 1, min, max))
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);
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
}
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());
if(!field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount))
return 0;
pduel->game_field->add_process(PROCESSOR_SELECT_SUM_S, 0, 0, 0, acc, playerid + (min << 16) + (max << 24));
return lua_yield(L, 0);
......
......@@ -4185,32 +4185,35 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
if(!smat)
return FALSE;
card* tuner = core.limit_tuner;
int32 l = tuner->get_synchro_level(pcard);
int32 l1 = l & 0xffff;
//int32 l2 = l >> 16;
effect* pcheck = tuner->is_affected_by_effect(EFFECT_SYNCHRO_CHECK);
if(pcheck)
pcheck->get_value(smat);
if(min == 1) {
int32 lv = pcard->get_level();
lv -= l1;
l = smat->get_synchro_level(pcard);
l1 = l & 0xffff;
lv -= l1;
if(lv == 0)
card_vector nsyn;
nsyn.push_back(tuner);
nsyn.push_back(smat);
tuner->operation_param = tuner->get_synchro_level(pcard);
smat->operation_param = smat->get_synchro_level(pcard);
if(check_with_sum_limit_m(nsyn, lv, 0, 0, 0, 2))
core.units.begin()->step = 5;
}
return FALSE;
}
case 4: {
int32 lv = pcard->get_level();
int32 mcount = 1;
card* tuner = core.limit_tuner;
effect* pcheck = tuner->is_affected_by_effect(EFFECT_SYNCHRO_CHECK);
int32 l = tuner->get_synchro_level(pcard);
int32 l1 = l & 0xffff;
//int32 l2 = l >> 16;
int32 lv = pcard->get_level();
lv -= l1;
core.must_select_cards.clear();
core.must_select_cards.push_back(tuner);
tuner->operation_param = tuner->get_synchro_level(pcard);
if(smat) {
l = smat->get_synchro_level(pcard);
l1 = l & 0xffff;
lv -= l1;
min--;
max--;
core.must_select_cards.push_back(smat);
smat->operation_param = smat->get_synchro_level(pcard);
mcount++;
}
core.select_cards.clear();
if(mg) {
......@@ -4261,8 +4264,8 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
if(!(*cit)->is_affected_by_effect(EFFECT_SCRAP_CHIMERA))
nsyn_removed.push_back(*cit);
}
if(check_with_sum_limit(&nsyn_filtered, lv, 0, 1, min, max)) {
if(check_with_sum_limit(&nsyn_removed, lv, 0, 1, min, max)) {
if(check_with_sum_limit(nsyn_filtered, lv, 0, 1, min, max)) {
if(check_with_sum_limit(nsyn_removed, lv, 0, 1, min, max)) {
add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, playerid, peffect->description);
core.units.begin()->step = 6;
return FALSE;
......@@ -4283,14 +4286,13 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
case 5: {
lua_pop(pduel->lua->current_state, 2);
group* pgroup = pduel->new_group();
card* pcard;
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
pcard = core.select_cards[returns.bvalue[i + 1]];
int32 mcount = core.must_select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
card* pcard = core.select_cards[returns.bvalue[i + 1]];
pgroup->container.insert(pcard);
}
pgroup->container.insert(core.limit_tuner);
if(smat)
pgroup->container.insert(smat);
pgroup->container.insert(core.must_select_cards.begin(), core.must_select_cards.end());
core.must_select_cards.clear();
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
pduel->restore_assumes();
core.limit_tuner = 0;
......
......@@ -512,15 +512,15 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
}
return TRUE;
}
int32 select_sum_check1(int32* oparam, int32 size, int32 index, int32 count, int32 acc, int32 min) {
static int32 select_sum_check1(const int32* oparam, int32 size, int32 index, int32 acc) {
if(acc == 0 || index == size)
return FALSE;
int32 o1 = oparam[index] & 0xffff;
int32 o2 = oparam[index] >> 16;
if((o1 == acc || o2 == acc) && index == size - 1 && count >= min)
return TRUE;
return (acc > o1 && select_sum_check1(oparam, size, index + 1, count + 1, acc - o1, min))
|| (o2 > 0 && acc > o2 && select_sum_check1(oparam, size, index + 1, count + 1, acc - o2, min));
if(index == size - 1)
return acc == o1 || acc == o2;
return (acc > o1 && select_sum_check1(oparam, size, index + 1, acc - o1))
|| (o2 > 0 && acc > o2 && select_sum_check1(oparam, size, index + 1, acc - o2));
}
int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int32 max) {
if(step == 0) {
......@@ -538,11 +538,19 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
pduel->write_buffer32(acc & 0xffff);
pduel->write_buffer8(min);
pduel->write_buffer8(max);
pduel->write_buffer8(core.must_select_cards.size());
for(uint32 i = 0; i < core.must_select_cards.size(); ++i) {
card* pcard = core.must_select_cards[i];
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location);
pduel->write_buffer8(pcard->current.sequence);
pduel->write_buffer32(pcard->operation_param);
}
pduel->write_buffer8(core.select_cards.size());
card* pcard;
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
for(uint32 i = 0; i < core.select_cards.size(); ++i) {
pcard = core.select_cards[i];
card* pcard = core.select_cards[i];
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location);
......@@ -559,9 +567,12 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
uint8 m = core.select_cards.size(), v = 0;
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
v = returns.bvalue[i + 1];
int32 mcount = core.must_select_cards.size();
for(int32 i = 0; i < mcount; ++i)
oparam[i] = core.must_select_cards[i]->operation_param;
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]) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -569,7 +580,7 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
c[v] = 1;
oparam[i] = core.select_cards[v]->operation_param;
}
if(!select_sum_check1(oparam, returns.bvalue[0], 0, 1, acc, min)) {
if(!select_sum_check1(oparam, returns.bvalue[0], 0, acc)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
......
......@@ -788,11 +788,12 @@ int32 field::process() {
it->step++;
} else {
group* pgroup = pduel->new_group();
card* pcard;
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
pcard = core.select_cards[returns.bvalue[i + 1]];
int32 mcount = core.must_select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
card* pcard = core.select_cards[returns.bvalue[i + 1]];
pgroup->container.insert(pcard);
}
core.must_select_cards.clear();
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
core.units.pop_front();
}
......
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