diff --git a/operations.cpp b/operations.cpp index 3b208c8cc..7f92e7e00 100644 --- a/operations.cpp +++ b/operations.cpp @@ -2376,6 +2376,26 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target, e return TRUE; if(target->is_affected_by_effect(EFFECT_CANNOT_SSET)) return TRUE; + uint32 flag = 0; + if(target->data.type & TYPE_FIELD) { + flag = ~(0x1 << 13); + } else { + get_useable_count(target, setplayer, LOCATION_SZONE, toplayer, LOCATION_REASON_TOFIELD, 0xff, &flag); + flag = ((flag & 0xff) << 8) | 0xffff00ff; + flag |= 0xe080e080; + } + pduel->write_buffer8(MSG_HINT); + pduel->write_buffer8(HINT_SELECTMSG); + pduel->write_buffer8(setplayer); + pduel->write_buffer32(target->data.code); + add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, setplayer, flag, 0); + return FALSE; + } + case 1: { + if(returns.bvalue[1] == 0) { + return TRUE; + } + target->to_field_param = returns.bvalue[2]; effect_set eset; target->filter_effect(EFFECT_SSET_COST, &eset); for(int32 i = 0; i < eset.size(); ++i) { @@ -2386,12 +2406,12 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target, e } return FALSE; } - case 1: { + case 2: { target->enable_field_effect(false); - move_to_field(target, setplayer, toplayer, LOCATION_SZONE, POS_FACEDOWN, FALSE, 0, FALSE, (target->data.type & TYPE_FIELD) ? 0x1 << 5 : 0xff); + move_to_field(target, setplayer, toplayer, LOCATION_SZONE, POS_FACEDOWN, FALSE, 0, FALSE, 0x1 << target->to_field_param); return FALSE; } - case 2: { + case 3: { core.phase_action = TRUE; target->set_status(STATUS_SET_TURN, TRUE); if(target->data.type & TYPE_MONSTER) { @@ -4441,6 +4461,14 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret, adjust_all(); } } else if(pzone && location == LOCATION_SZONE && (target->data.type & TYPE_PENDULUM)) { + if((zone & zone - 1) == 0) { // zone was selected in field::add_chain + for(uint8 seq = 0; seq < 9; seq++) { + if((1 << seq) & zone) { + returns.bvalue[2] = seq; + return FALSE; + } + } + } uint32 flag = 0; if(is_location_useable(playerid, LOCATION_PZONE, 0)) flag |= 0x1u << (core.duel_rule >= 4 ? 8 : 14); diff --git a/playerop.cpp b/playerop.cpp index dc50b0edc..8a38ed076 100644 --- a/playerop.cpp +++ b/playerop.cpp @@ -374,8 +374,6 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo } int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) { if(step == 0) { - if(count == 0) - return TRUE; if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { flag = ~flag; int32 filter; @@ -433,14 +431,15 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) } else { uint8 pt = 0; uint32 selected = 0; - for(int8 i = 0; i < count; ++i) { + for(int8 i = 0; i < 1 || i < count; ++i) { uint8 p = returns.bvalue[pt]; uint8 l = returns.bvalue[pt + 1]; uint8 s = returns.bvalue[pt + 2]; uint32 sel = 0x1u << (s + (p == playerid ? 0 : 16) + (l == LOCATION_MZONE ? 0 : 8)); - if((p != 0 && p != 1) + if(!(count == 0 && i == 0 && l == 0) + && ((p != 0 && p != 1) || ((l != LOCATION_MZONE) && (l != LOCATION_SZONE)) - || (sel & flag) || (sel & selected)) { + || (sel & flag) || (sel & selected))) { pduel->write_buffer8(MSG_RETRY); return FALSE; } diff --git a/processor.cpp b/processor.cpp index 4ff0d67ed..9becde00b 100644 --- a/processor.cpp +++ b/processor.cpp @@ -3957,6 +3957,58 @@ int32 field::add_chain(uint16 step) { auto& clit = core.new_chains.front(); effect* peffect = clit.triggering_effect; card* phandler = peffect->get_handler(); + if((peffect->type & EFFECT_TYPE_ACTIVATE) && phandler->current.location == LOCATION_HAND) { + uint32 flag = 0; + if(phandler->data.type & TYPE_PENDULUM) { + if(is_location_useable(clit.triggering_player, LOCATION_PZONE, 0)) + flag |= 0x1u << (core.duel_rule >= 4 ? 8 : 14); + if(is_location_useable(clit.triggering_player, LOCATION_PZONE, 1)) + flag |= 0x1u << (core.duel_rule >= 4 ? 12 : 15); + flag = ~flag; + } else { + uint32 zone = 0xff; + if(!(phandler->data.type & TYPE_FIELD) && peffect->is_flag(EFFECT_FLAG_LIMIT_ZONE)) { + pduel->lua->add_param(clit.triggering_player, PARAM_TYPE_INT); + pduel->lua->add_param(clit.evt.event_cards, PARAM_TYPE_GROUP); + pduel->lua->add_param(clit.evt.event_player, PARAM_TYPE_INT); + pduel->lua->add_param(clit.evt.event_value, PARAM_TYPE_INT); + pduel->lua->add_param(clit.evt.reason_effect, PARAM_TYPE_EFFECT); + pduel->lua->add_param(clit.evt.reason, PARAM_TYPE_INT); + pduel->lua->add_param(clit.evt.reason_player, PARAM_TYPE_INT); + zone = peffect->get_value(7); + if(!zone) + zone = 0xff; + } + if(phandler->data.type & TYPE_FIELD) { + flag = ~(0x1 << 13); + } + else { + get_useable_count(phandler, clit.triggering_player, LOCATION_SZONE, clit.triggering_player, LOCATION_REASON_TOFIELD, zone, &flag); + flag = ((flag & 0xff) << 8) | 0xffff00ff; + flag |= 0xe080e080; + } + } + pduel->write_buffer8(MSG_HINT); + pduel->write_buffer8(HINT_SELECTMSG); + pduel->write_buffer8(clit.triggering_player); + pduel->write_buffer32(phandler->data.code); + add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, clit.triggering_player, flag, 0); + return FALSE; + } + return FALSE; + } + case 1: { + auto& clit = core.new_chains.front(); + effect* peffect = clit.triggering_effect; + card* phandler = peffect->get_handler(); + if((peffect->type & EFFECT_TYPE_ACTIVATE) && phandler->current.location == LOCATION_HAND) { + if(returns.bvalue[1] == 0) { // select place canceled, execute the last part of the last step + core.new_chains.pop_front(); + if(core.new_chains.size()) + add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); + return TRUE; + } + } effect_set eset; filter_player_effect(clit.triggering_player, EFFECT_ACTIVATE_COST, &eset); for(int32 i = 0; i < eset.size(); ++i) { @@ -4004,23 +4056,9 @@ int32 field::add_chain(uint16 step) { } } if(phandler->current.location == LOCATION_HAND) { - uint32 zone = 0xff; - if(!(phandler->data.type & (TYPE_FIELD | TYPE_PENDULUM)) && peffect->is_flag(EFFECT_FLAG_LIMIT_ZONE)) { - pduel->lua->add_param(clit.triggering_player, PARAM_TYPE_INT); - pduel->lua->add_param(clit.evt.event_cards , PARAM_TYPE_GROUP); - pduel->lua->add_param(clit.evt.event_player, PARAM_TYPE_INT); - pduel->lua->add_param(clit.evt.event_value, PARAM_TYPE_INT); - pduel->lua->add_param(clit.evt.reason_effect , PARAM_TYPE_EFFECT); - pduel->lua->add_param(clit.evt.reason, PARAM_TYPE_INT); - pduel->lua->add_param(clit.evt.reason_player, PARAM_TYPE_INT); - zone = peffect->get_value(7); - if(!zone) - zone = 0xff; - } + uint32 zone = 1 << returns.bvalue[2]; phandler->enable_field_effect(false); phandler->set_status(STATUS_ACT_FROM_HAND, TRUE); - if(phandler->data.type & TYPE_FIELD) - zone = 0x1 << 5; move_to_field(phandler, phandler->current.controler, phandler->current.controler, LOCATION_SZONE, POS_FACEUP, FALSE, 0, (phandler->data.type & TYPE_PENDULUM) ? TRUE : FALSE, zone); } else { phandler->set_status(STATUS_ACT_FROM_HAND, FALSE); @@ -4029,7 +4067,7 @@ int32 field::add_chain(uint16 step) { } return FALSE; } - case 1: { + case 2: { auto& clit = core.new_chains.front(); effect* peffect = clit.triggering_effect; card* phandler = peffect->get_handler(); @@ -4084,7 +4122,7 @@ int32 field::add_chain(uint16 step) { core.new_chains.pop_front(); return FALSE; } - case 2: { + case 3: { auto& clit = core.current_chain.back(); int32 playerid = clit.triggering_player; effect* peffect = clit.triggering_effect; @@ -4100,11 +4138,11 @@ int32 field::add_chain(uint16 step) { returns.ivalue[0] = FALSE; return FALSE; } - case 3: { + case 4: { if(!returns.ivalue[0]) { core.select_chains.clear(); core.select_options.clear(); - core.units.begin()->step = 4; + core.units.begin()->step = 5; return FALSE; } if(core.select_chains.size() > 1) { @@ -4114,7 +4152,7 @@ int32 field::add_chain(uint16 step) { returns.ivalue[0] = 0; return FALSE; } - case 4: { + case 5: { auto& clit = core.current_chain.back(); chain& ch = core.select_chains[returns.ivalue[0]]; int32 playerid = clit.triggering_player; @@ -4144,7 +4182,7 @@ int32 field::add_chain(uint16 step) { phandler->add_effect(deffect); return FALSE; } - case 5: { + case 6: { auto& clit = core.current_chain.back(); effect* peffect = clit.triggering_effect; if(peffect->cost) { @@ -4153,7 +4191,7 @@ int32 field::add_chain(uint16 step) { } return FALSE; } - case 6: { + case 7: { auto& clit = core.current_chain.back(); effect* peffect = clit.triggering_effect; if(peffect->target) { @@ -4162,7 +4200,7 @@ int32 field::add_chain(uint16 step) { } return FALSE; } - case 7: { + case 8: { break_effect(); auto& clit = core.current_chain.back(); effect* peffect = clit.triggering_effect;