Commit e0395b91 authored by fallenstardust's avatar fallenstardust

sync ocgcore

parent 3d6b8f35
......@@ -632,28 +632,7 @@ int32 field::get_tofield_count(card* pcard, uint8 playerid, uint8 location, uint
return 0;
uint32 flag = player[playerid].disabled_location | player[playerid].used_location;
if(location == LOCATION_MZONE && (reason & LOCATION_REASON_TOFIELD)) {
effect_set eset;
if(uplayer < 2)
filter_player_effect(uplayer, EFFECT_MUST_USE_MZONE, &eset);
if(pcard)
pcard->filter_effect(EFFECT_MUST_USE_MZONE, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT) && eset[i]->count_limit == 0)
continue;
uint32 value = 0x1f;
if(eset[i]->is_flag(EFFECT_FLAG_PLAYER_TARGET))
value = eset[i]->get_value();
else {
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(uplayer, PARAM_TYPE_INT);
pduel->lua->add_param(reason, PARAM_TYPE_INT);
value = eset[i]->get_value(pcard, 3);
}
if(eset[i]->get_handler_player() == playerid)
flag |= ~value & 0x1f;
else
flag |= ~(value >> 16) & 0x1f;
}
filter_must_use_mzone(playerid, uplayer, reason, pcard, &flag);
}
if (location == LOCATION_MZONE)
flag = (flag | ~zone) & 0x1f;
......@@ -675,29 +654,7 @@ int32 field::get_useable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 u
}
int32 field::get_spsummonable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone, uint32* list) {
uint32 flag = player[playerid].disabled_location | player[playerid].used_location;
effect_set eset;
if(uplayer < 2)
filter_player_effect(uplayer, EFFECT_MUST_USE_MZONE, &eset);
if(pcard)
pcard->filter_effect(EFFECT_MUST_USE_MZONE, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT) && eset[i]->count_limit == 0)
continue;
uint32 value = 0x1f;
if(eset[i]->is_flag(EFFECT_FLAG_PLAYER_TARGET))
value = eset[i]->get_value();
else {
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(uplayer, PARAM_TYPE_INT);
pduel->lua->add_param(LOCATION_REASON_TOFIELD, PARAM_TYPE_INT);
value = eset[i]->get_value(pcard, 3);
}
if(eset[i]->get_handler_player() == playerid)
flag |= ~value & 0x7f;
else
flag |= ~(value >> 16) & 0x7f;
}
uint32 linked_zone = get_linked_zone(playerid) | (1u << 5) | (1u << 6);
filter_must_use_mzone(playerid, uplayer, LOCATION_REASON_TOFIELD, pcard, &flag);
if(player[playerid].list_mzone[5] && is_location_useable(playerid, LOCATION_MZONE, 6)
&& check_extra_link(playerid, pcard, 6)) {
flag |= 1u << 5;
......@@ -712,7 +669,8 @@ int32 field::get_spsummonable_count_fromex_rule4(card* pcard, uint8 playerid, ui
if(!is_location_useable(playerid, LOCATION_MZONE, 6))
flag |= 1u << 6;
}
flag = flag | ~zone | ~linked_zone;
uint32 rule_zone = get_rule_zone_fromex(playerid, pcard);
flag = flag | ~zone | ~rule_zone;
if(list)
*list = flag & 0x7f;
int32 count = 5 - field_used_count[flag & 0x1f];
......@@ -776,6 +734,40 @@ uint32 field::get_linked_zone(int32 playerid) {
}
return zones;
}
uint32 field::get_rule_zone_fromex(int32 playerid, card* pcard) {
if(core.duel_rule >= 4) {
if(core.duel_rule >= 5 && pcard && pcard->is_position(POS_FACEDOWN) && (pcard->data.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ)))
return 0x7f;
else
return get_linked_zone(playerid) | (1u << 5) | (1u << 6);
} else {
return 0x1f;
}
}
void field::filter_must_use_mzone(uint8 playerid, uint8 uplayer, uint32 reason, card* pcard, uint32* flag) {
effect_set eset;
if(uplayer < 2)
filter_player_effect(uplayer, EFFECT_MUST_USE_MZONE, &eset);
if(pcard)
pcard->filter_effect(EFFECT_MUST_USE_MZONE, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT) && eset[i]->count_limit == 0)
continue;
uint32 value = 0x1f;
if(eset[i]->is_flag(EFFECT_FLAG_PLAYER_TARGET))
value = eset[i]->get_value();
else {
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(uplayer, PARAM_TYPE_INT);
pduel->lua->add_param(reason, PARAM_TYPE_INT);
value = eset[i]->get_value(pcard, 3);
}
if(eset[i]->get_handler_player() == playerid)
*flag |= ~value & 0x7f;
else
*flag |= ~(value >> 16) & 0x7f;
}
}
void field::get_linked_cards(uint8 self, uint8 s, uint8 o, card_set* cset) {
cset->clear();
uint8 c = s;
......@@ -2396,11 +2388,13 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
}
int32 playerid = pcard->current.controler;
int32 ct = get_spsummonable_count(pcard, playerid);
card_set linked_cards;
card_set handover_zone_cards;
if(ct <= 0) {
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
if(linked_cards.find(tuner) != linked_cards.end())
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, pcard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, pcard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
if(handover_zone_cards.find(tuner) != handover_zone_cards.end())
ct++;
}
int32 location = LOCATION_MZONE;
......@@ -2457,7 +2451,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
smat->sum_param = smat->get_synchro_level(pcard);
mcount++;
if(ct <= 0) {
if(linked_cards.find(smat) != linked_cards.end())
if(handover_zone_cards.find(smat) != handover_zone_cards.end())
ct++;
}
if(min == 0) {
......@@ -2525,7 +2519,7 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
auto start = nsyn.begin() + mcount;
for(auto cit = start; cit != nsyn.end(); ++cit) {
card* pm = *cit;
if(linked_cards.find(pm) == linked_cards.end())
if(handover_zone_cards.find(pm) == handover_zone_cards.end())
continue;
if(start != cit)
std::iter_swap(start, cit);
......@@ -2691,14 +2685,16 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
get_xyz_material(scard, findex, lv, max, mg);
int32 playerid = scard->current.controler;
int32 ct = get_spsummonable_count(scard, playerid);
card_set linked_cards;
card_set handover_zone_cards;
if(ct <= 0) {
int32 ft = ct;
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, scard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, scard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
for(auto cit = core.xmaterial_lst.begin(); cit != core.xmaterial_lst.end(); ++cit) {
card* pcard = cit->second;
if(linked_cards.find(pcard) != linked_cards.end())
if(handover_zone_cards.find(pcard) != handover_zone_cards.end())
ft++;
}
if(ft <= 0)
......@@ -2712,7 +2708,7 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
int32 mct = mcset.size();
if(mct > 0) {
if(ct == 0 && std::none_of(mcset.begin(), mcset.end(),
[=](card* pcard) { return linked_cards.find(pcard) != linked_cards.end(); }))
[=](card* pcard) { return handover_zone_cards.find(pcard) != handover_zone_cards.end(); }))
mct++;
if(mct > max)
return FALSE;
......@@ -2767,7 +2763,7 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
++cit;
}
ct += std::count_if(mcset.begin(), mcset.end(),
[=](card* pcard) { return linked_cards.find(pcard) != linked_cards.end(); });
[=](card* pcard) { return handover_zone_cards.find(pcard) != handover_zone_cards.end(); });
std::multimap<int32, card*, std::greater<int32>> mat;
for(int32 icheck = 1; icheck <= digit; icheck <<= 1) {
mat.clear();
......@@ -2784,7 +2780,7 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
int32 ft = ct;
for(auto cit = mat.begin(); cit != mat.end(); ++cit) {
card* pcard = cit->second;
if(linked_cards.find(pcard) != linked_cards.end())
if(handover_zone_cards.find(pcard) != handover_zone_cards.end())
ft++;
}
if(ft <= 0)
......
......@@ -378,6 +378,8 @@ public:
int32 get_mzone_limit(uint8 playerid, uint8 uplayer, uint32 reason);
int32 get_szone_limit(uint8 playerid, uint8 uplayer, uint32 reason);
uint32 get_linked_zone(int32 playerid);
uint32 get_rule_zone_fromex(int32 playerid, card* pcard);
void filter_must_use_mzone(uint8 playerid, uint8 uplayer, uint32 reason, card* pcard, uint32* flag);
void get_linked_cards(uint8 self, uint8 s, uint8 o, card_set* cset);
int32 check_extra_link(int32 playerid);
int32 check_extra_link(int32 playerid, card* pcard, int32 sequence);
......
......@@ -1899,10 +1899,22 @@ int32 scriptlib::duel_get_location_count_fromex(lua_State *L) {
}
swapped = true;
}
bool use_temp_card = false;
card* scard = 0;
if(lua_gettop(L) >= 4) {
check_param(L, PARAM_TYPE_CARD, 4);
scard = *(card**)lua_touserdata(L, 4);
if(lua_gettop(L) >= 4 && !lua_isnil(L, 4)) {
if(check_param(L, PARAM_TYPE_CARD, 4, TRUE)) {
scard = *(card**)lua_touserdata(L, 4);
} else {
use_temp_card = true;
uint32 type = lua_tointeger(L, 4);
scard = pduel->game_field->temp_card;
scard->current.location = LOCATION_EXTRA;
scard->data.type = TYPE_MONSTER | type;
if(type & TYPE_PENDULUM)
scard->current.position = POS_FACEUP_DEFENSE;
else
scard->current.position = POS_FACEDOWN_DEFENSE;
}
}
uint32 zone = 0xff;
if(lua_gettop(L) >= 5)
......@@ -1916,6 +1928,11 @@ int32 scriptlib::duel_get_location_count_fromex(lua_State *L) {
pduel->game_field->player[0].list_mzone.swap(list_mzone[0]);
pduel->game_field->player[1].list_mzone.swap(list_mzone[1]);
}
if(use_temp_card) {
scard->current.location = 0;
scard->data.type = 0;
scard->current.position = 0;
}
return 2;
}
int32 scriptlib::duel_get_usable_mzone_count(lua_State *L) {
......
......@@ -189,8 +189,6 @@ void field::special_summon_step(card* target, uint32 sumtype, uint32 sumplayer,
add_process(PROCESSOR_SPSUMMON_STEP, 0, core.reason_effect, NULL, zone, 0, 0, 0, target);
}
void field::special_summon_complete(effect* reason_effect, uint8 reason_player) {
if(core.special_summoning.size() == 0)
return;
group* ng = pduel->new_group();
ng->container.swap(core.special_summoning);
ng->is_readonly = TRUE;
......@@ -5181,12 +5179,14 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
core.units.begin()->step = 6;
return FALSE;
}
card_set linked_cards;
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
if(linked_cards.find(tuner) != linked_cards.end())
card_set handover_zone_cards;
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, pcard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, pcard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
if(handover_zone_cards.find(tuner) != handover_zone_cards.end())
ct++;
if(smat && linked_cards.find(smat) != linked_cards.end())
if(smat && handover_zone_cards.find(smat) != handover_zone_cards.end())
ct++;
if(ct > 0) {
core.units.begin()->step = 6;
......@@ -5194,7 +5194,7 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card* pcard, in
}
card_vector* select_cards = new card_vector;
for(auto& pm : core.select_cards) {
if(linked_cards.find(pm) != linked_cards.end())
if(handover_zone_cards.find(pm) != handover_zone_cards.end())
select_cards->push_back(pm);
}
if(select_cards->size() == core.select_cards.size()) {
......@@ -5408,10 +5408,12 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
if(!(core.global_flag & GLOBALFLAG_TUNE_MAGICIAN))
return FALSE;
int32 ct = get_spsummonable_count(scard, playerid);
card_set linked_cards;
card_set handover_zone_cards;
if(ct <= 0) {
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, scard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, scard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
}
for(auto& pcard : core.operated_set) {
effect* peffect = pcard->is_affected_by_effect(EFFECT_TUNE_MAGICIAN_X);
......@@ -5463,7 +5465,7 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
int32 ft = ct;
for(auto cit = mat.begin(); cit != mat.end(); ++cit) {
card* pcard = cit->second;
if(linked_cards.find(pcard) != linked_cards.end())
if(handover_zone_cards.find(pcard) != handover_zone_cards.end())
ft++;
}
if(ft <= 0)
......@@ -5494,11 +5496,13 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
core.units.begin()->step = 4;
return FALSE;
}
card_set linked_cards;
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
card_set handover_zone_cards;
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, scard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, scard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
int32 ft = ct + std::count_if(core.operated_set.begin(), core.operated_set.end(),
[=](card* pcard) { return linked_cards.find(pcard) != linked_cards.end(); });
[=](card* pcard) { return handover_zone_cards.find(pcard) != handover_zone_cards.end(); });
if(ft > 0) {
returns.ivalue[0] = 1;
core.units.begin()->step = 4;
......@@ -5508,7 +5512,7 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
core.select_cards.clear();
for(auto iter = core.xmaterial_lst.begin(); iter != core.xmaterial_lst.end(); ++iter) {
card* pcard = iter->second;
if(linked_cards.find(pcard) != linked_cards.end())
if(handover_zone_cards.find(pcard) != handover_zone_cards.end())
core.select_cards.push_back(pcard);
else
mmax++;
......@@ -5677,17 +5681,19 @@ int32 field::select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* sc
int32 ct = get_spsummonable_count(scard, playerid);
if(ct > 0)
return FALSE;
card_set linked_cards;
uint32 linked_zone = core.duel_rule >= 4 ? get_linked_zone(playerid) | (1u << 5) | (1u << 6) : 0x1f;
get_cards_in_zone(&linked_cards, linked_zone, playerid, LOCATION_MZONE);
card_set handover_zone_cards;
uint32 must_use_zone_flag = 0;
filter_must_use_mzone(playerid, playerid, LOCATION_REASON_TOFIELD, scard, &must_use_zone_flag);
uint32 handover_zone = get_rule_zone_fromex(playerid, scard) & ~must_use_zone_flag;
get_cards_in_zone(&handover_zone_cards, handover_zone, playerid, LOCATION_MZONE);
int32 ft = ct + std::count_if(core.operated_set.begin(), core.operated_set.end(),
[=](card* pcard) { return linked_cards.find(pcard) != linked_cards.end(); });
[=](card* pcard) { return handover_zone_cards.find(pcard) != handover_zone_cards.end(); });
if(ft > 0)
return FALSE;
core.select_cards.clear();
for(auto iter = core.xmaterial_lst.begin(); iter != core.xmaterial_lst.end(); ++iter) {
card* pcard = iter->second;
if(linked_cards.find(pcard) != linked_cards.end())
if(handover_zone_cards.find(pcard) != handover_zone_cards.end())
core.select_cards.push_back(pcard);
}
pduel->write_buffer8(MSG_HINT);
......
......@@ -1783,6 +1783,8 @@ int32 field::process_instant_event() {
effect* peffect = eit->second;
++eit;
uint8 owner_player = peffect->get_handler_player();
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (ev.event_player == 0 || ev.event_player == 1))
owner_player = ev.event_player;
if(peffect->is_activateable(owner_player, ev)) {
newchain.chain_id = 0;
newchain.chain_count = 0;
......@@ -1941,6 +1943,8 @@ int32 field::process_single_event(effect* peffect, const tevent& e, chain_list&
//continuous & trigger (single)
if(peffect->type & EFFECT_TYPE_CONTINUOUS) {
uint8 owner_player = peffect->get_handler_player();
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (e.event_player == 0 || e.event_player == 1))
owner_player = e.event_player;
if(peffect->is_activateable(owner_player, e)) {
chain newchain;
newchain.chain_id = 0;
......
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