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