Commit 97f0a5fc authored by Chrono-Genex's avatar Chrono-Genex Committed by GitHub

fix must material for Contact "C" (#412)

* fix must material

* fix null value
parent 0c9c455b
......@@ -2488,13 +2488,26 @@ void field::attack_all_target_check() {
if(!peffect->get_value(core.attack_target))
core.attacker->attack_all_target = FALSE;
}
int32 field::get_must_material_list(uint8 playerid, uint32 limit, card_set* must_list) {
effect_set eset;
filter_player_effect(playerid, limit, &eset);
for(int32 i = 0; i < eset.size(); ++i)
must_list->insert(eset[i]->handler);
return (int32)must_list->size();
}
int32 field::check_must_material(group* mg, uint8 playerid, uint32 limit) {
card_set must_list;
int32 m = get_must_material_list(playerid, limit, &must_list);
if(m <= 0)
return TRUE;
if(!mg)
return FALSE;
for(auto& pcard : must_list)
if(!mg->has_card(pcard))
return FALSE;
return TRUE;
}
int32 field::check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg) {
if(core.global_flag & GLOBALFLAG_MUST_BE_SMATERIAL) {
effect_set eset;
filter_player_effect(pcard->current.controler, EFFECT_MUST_BE_SMATERIAL, &eset);
if(eset.size())
return check_tuner_material(pcard, eset[0]->handler, findex1, findex2, min, max, smat, mg);
}
if(mg) {
for(auto& tuner : mg->container) {
if(check_tuner_material(pcard, tuner, findex1, findex2, min, max, smat, mg))
......@@ -2539,6 +2552,13 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
return FALSE;
}
int32 playerid = pcard->current.controler;
card_set must_list;
int32 mct = get_must_material_list(playerid, EFFECT_MUST_BE_SMATERIAL, &must_list);
auto tit = must_list.find(tuner);
if(tit != must_list.end()) {
mct--;
must_list.erase(tit);
}
int32 ct = get_spsummonable_count(pcard, playerid);
card_set handover_zone_cards;
if(ct <= 0) {
......@@ -2587,7 +2607,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
if(smat) {
if(pcheck)
pcheck->get_value(smat);
if(!smat->is_position(POS_FACEUP) || !smat->is_can_be_synchro_material(pcard, tuner) || !pduel->lua->check_matching(smat, findex2, 1)) {
if((smat->current.location == LOCATION_MZONE && !smat->is_position(POS_FACEUP)) || !smat->is_can_be_synchro_material(pcard, tuner) || !pduel->lua->check_matching(smat, findex2, 1)) {
pduel->restore_assumes();
return FALSE;
}
......@@ -2604,6 +2624,13 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
nsyn.push_back(smat);
smat->sum_param = smat->get_synchro_level(pcard);
mcount++;
if(mct > 0) {
auto sit = must_list.find(smat);
if(sit != must_list.end()) {
mct--;
must_list.erase(sit);
}
}
if(ct <= 0) {
if(handover_zone_cards.find(smat) != handover_zone_cards.end())
ct++;
......@@ -2619,9 +2646,34 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
}
}
}
if(mct > 0) {
for(auto& mcard : must_list) {
if(mcard == tuner || mcard == smat)
continue;
if(pcheck)
pcheck->get_value(mcard);
if((mcard->current.location == LOCATION_MZONE && !mcard->is_position(POS_FACEUP)) || !mcard->is_can_be_synchro_material(pcard, tuner) || !pduel->lua->check_matching(mcard, findex2, 1)) {
pduel->restore_assumes();
return FALSE;
}
if(ptuner && ptuner->target) {
pduel->lua->add_param(ptuner, PARAM_TYPE_EFFECT);
pduel->lua->add_param(mcard, PARAM_TYPE_CARD);
if(!pduel->lua->get_function_value(ptuner->target, 2)) {
pduel->restore_assumes();
return FALSE;
}
}
min--;
max--;
nsyn.push_back(mcard);
mcard->sum_param = mcard->get_synchro_level(pcard);
mcount++;
}
}
if(mg) {
for(auto& pm : mg->container) {
if(pm == tuner || pm == smat || !pm->is_can_be_synchro_material(pcard, tuner))
if(pm == tuner || pm == smat || must_list.find(pm) != must_list.end() || !pm->is_can_be_synchro_material(pcard, tuner))
continue;
if(ptuner && ptuner->target) {
pduel->lua->add_param(ptuner, PARAM_TYPE_EFFECT);
......@@ -2647,7 +2699,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
if(location & LOCATION_HAND)
cv.insert(cv.end(), player[playerid].list_hand.begin(), player[playerid].list_hand.end());
for(auto& pm : cv) {
if(!pm || pm == tuner || pm == smat || !pm->is_can_be_synchro_material(pcard, tuner))
if(!pm || pm == tuner || pm == smat || must_list.find(pm) != must_list.end() || !pm->is_can_be_synchro_material(pcard, tuner))
continue;
if(ptuner && ptuner->target) {
pduel->lua->add_param(ptuner, PARAM_TYPE_EFFECT);
......@@ -2862,12 +2914,8 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
if(min > max)
return FALSE;
}
effect_set eset;
filter_player_effect(playerid, EFFECT_MUST_BE_XMATERIAL, &eset);
card_set mcset;
for(int32 i = 0; i < eset.size(); ++i)
mcset.insert(eset[i]->handler);
int32 mct = (int32)mcset.size();
int32 mct = get_must_material_list(playerid, EFFECT_MUST_BE_XMATERIAL, &mcset);
if(mct > 0) {
if(ct == 0 && std::none_of(mcset.begin(), mcset.end(),
[=](card* pcard) { return handover_zone_cards.find(pcard) != handover_zone_cards.end(); }))
......
......@@ -478,6 +478,8 @@ public:
int32 get_attack_target(card* pcard, card_vector* v, uint8 chain_attack = FALSE, bool select_target = true);
bool confirm_attack_target();
void attack_all_target_check();
int32 get_must_material_list(uint8 playerid, uint32 limit, card_set* must_list);
int32 check_must_material(group* mg, uint8 playerid, uint32 limit);
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);
int32 check_other_synchro_material(const card_vector& nsyn, int32 lv, int32 min, int32 max, int32 mcount);
......@@ -718,7 +720,7 @@ public:
#define GLOBALFLAG_SCRAP_CHIMERA 0x4
//#define GLOBALFLAG_DELAYED_QUICKEFFECT 0x8
#define GLOBALFLAG_DETACH_EVENT 0x10
#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20
//#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20
#define GLOBALFLAG_SPSUMMON_COUNT 0x40
#define GLOBALFLAG_XMAT_COUNT_LIMIT 0x80
#define GLOBALFLAG_SELF_TOGRAVE 0x100
......
......@@ -2937,6 +2937,47 @@ int32 scriptlib::duel_select_target(lua_State *L) {
return 1;
});
}
int32 scriptlib::duel_get_must_material(lua_State *L) {
check_param_count(L, 2);
int32 playerid = (int32)lua_tointeger(L, 1);
if(playerid != 0 && playerid != 1)
return 0;
uint32 limit = (uint32)lua_tointeger(L, 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
pduel->game_field->get_must_material_list(playerid, limit, &pgroup->container);
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::duel_check_must_material(lua_State *L) {
check_param_count(L, 3);
int32 playerid = (int32)lua_tointeger(L, 1);
if(playerid != 0 && playerid != 1)
return 0;
card* mcard = 0;
group* mgroup = 0;
group* pgroup = 0;
duel* pduel = 0;
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
mcard = *(card**)lua_touserdata(L, 2);
pduel = mcard->pduel;
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
mgroup = *(group**)lua_touserdata(L, 2);
pduel = mgroup->pduel;
} else
pduel = interpreter::get_duel_info(L);
if(mgroup) {
pgroup = pduel->new_group(mgroup->container);
pgroup->is_readonly = TRUE;
} else if(mcard) {
pgroup = pduel->new_group(mcard);
pgroup->is_readonly = TRUE;
} else
pgroup = 0;
uint32 limit = (uint32)lua_tointeger(L, 3);
lua_pushboolean(L, pduel->game_field->check_must_material(pgroup, playerid, limit));
return 1;
}
int32 scriptlib::duel_select_fusion_material(lua_State *L) {
check_action_permission(L);
check_param_count(L, 3);
......@@ -3086,14 +3127,6 @@ int32 scriptlib::duel_check_tuner_material(lua_State *L) {
card* pcard = *(card**) lua_touserdata(L, 1);
card* tuner = *(card**) lua_touserdata(L, 2);
duel* pduel = pcard->pduel;
if(pduel->game_field->core.global_flag & GLOBALFLAG_MUST_BE_SMATERIAL) {
effect_set eset;
pduel->game_field->filter_player_effect(pcard->current.controler, EFFECT_MUST_BE_SMATERIAL, &eset);
if(eset.size() && eset[0]->handler != tuner) {
lua_pushboolean(L, false);
return 1;
}
}
if(!lua_isnil(L, 3))
check_param(L, PARAM_TYPE_FUNCTION, 3);
if(!lua_isnil(L, 4))
......@@ -4708,6 +4741,8 @@ static const struct luaL_Reg duellib[] = {
{ "GetTargetCount", scriptlib::duel_get_target_count },
{ "IsExistingTarget", scriptlib::duel_is_existing_target },
{ "SelectTarget", scriptlib::duel_select_target },
{ "GetMustMaterial", scriptlib::duel_get_must_material },
{ "CheckMustMaterial", scriptlib::duel_check_must_material },
{ "SelectFusionMaterial", scriptlib::duel_select_fusion_material },
{ "SetFusionMaterial", scriptlib::duel_set_fusion_material },
{ "SetSynchroMaterial", scriptlib::duel_set_synchro_material },
......
......@@ -5188,20 +5188,6 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
switch(step) {
case 0: {
core.select_cards.clear();
if(core.global_flag & GLOBALFLAG_MUST_BE_SMATERIAL) {
effect_set eset;
filter_player_effect(pcard->current.controler, EFFECT_MUST_BE_SMATERIAL, &eset);
if(eset.size() && (!mg || mg->has_card(eset[0]->handler))) {
core.select_cards.push_back(eset[0]->handler);
pduel->restore_assumes();
pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(playerid);
pduel->write_buffer32(512);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid + ((uint32)core.summon_cancelable << 16), 0x10001);
return FALSE;
}
}
if(mg) {
for(auto& pm : mg->container) {
if(check_tuner_material(pcard, pm, -3, -2, min, max, smat, mg))
......@@ -5287,6 +5273,14 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
if(pcheck)
pcheck->get_value(smat);
if(min == 0) {
group* pgroup = pduel->new_group();
pgroup->container.insert(tuner);
pgroup->container.insert(smat);
if(!check_must_material(pgroup, playerid, EFFECT_MUST_BE_SMATERIAL)) {
pduel->restore_assumes();
core.limit_tuner = 0;
return TRUE;
}
int32 lv = pcard->get_level();
card_vector nsyn;
nsyn.push_back(tuner);
......@@ -5314,11 +5308,21 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
core.must_select_cards.push_back(smat);
smat->sum_param = smat->get_synchro_level(pcard);
}
card_set must_list;
int32 mct = get_must_material_list(playerid, EFFECT_MUST_BE_SMATERIAL, &must_list);
if(mct > 0) {
for(auto& mcard : must_list) {
if(mcard == tuner || mcard == smat)
continue;
core.must_select_cards.push_back(mcard);
mcard->sum_param = mcard->get_synchro_level(pcard);
}
}
card_vector nsyn(core.must_select_cards);
int32 mcount = (int32)nsyn.size();
if(mg) {
for(auto& pm : mg->container) {
if(pm == tuner || pm == smat || !pm->is_can_be_synchro_material(pcard, tuner))
if(pm == tuner || pm == smat || must_list.find(pm) != must_list.end() || !pm->is_can_be_synchro_material(pcard, tuner))
continue;
if(ptuner && ptuner->target) {
pduel->lua->add_param(ptuner, PARAM_TYPE_EFFECT);
......@@ -5344,7 +5348,7 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
if(location & LOCATION_HAND)
cv.insert(cv.end(), player[playerid].list_hand.begin(), player[playerid].list_hand.end());
for(auto& pm : cv) {
if(!pm || pm == tuner || pm == smat || !pm->is_can_be_synchro_material(pcard, tuner))
if(!pm || pm == tuner || pm == smat || must_list.find(pm) != must_list.end() || !pm->is_can_be_synchro_material(pcard, tuner))
continue;
if(ptuner && ptuner->target) {
pduel->lua->add_param(ptuner, PARAM_TYPE_EFFECT);
......@@ -5557,12 +5561,12 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
core.units.begin()->arg2 = min + (max << 16);
}
}
effect_set eset;
filter_player_effect(playerid, EFFECT_MUST_BE_XMATERIAL, &eset);
card_set mcset;
int32 mct = get_must_material_list(playerid, EFFECT_MUST_BE_XMATERIAL, &mcset);
core.select_cards.clear();
for(int i = 0; i < eset.size(); ++i)
core.select_cards.push_back(eset[i]->handler);
int32 mct = (int32)core.select_cards.size();
for(auto& mcard : mcset) {
core.select_cards.push_back(mcard);
}
if(mct == 0) {
returns.ivalue[0] = 1;
core.units.begin()->step = 1;
......
......@@ -516,6 +516,8 @@ public:
static int32 duel_get_target_count(lua_State *L);
static int32 duel_is_existing_target(lua_State *L);
static int32 duel_select_target(lua_State *L);
static int32 duel_get_must_material(lua_State *L);
static int32 duel_check_must_material(lua_State *L);
static int32 duel_select_fusion_material(lua_State *L);
static int32 duel_set_fusion_material(lua_State *L);
static int32 duel_set_synchro_material(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