From 1d528751c1b89eb022defab0eafc90d7ae083919 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Fri, 18 Sep 2020 16:05:47 +0800 Subject: [PATCH 1/2] cancel spell activate/set from hand --- operations.cpp | 31 +++++++++++++++++-- playerop.cpp | 8 ++--- processor.cpp | 84 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 93 insertions(+), 30 deletions(-) diff --git a/operations.cpp b/operations.cpp index 645171bb0..6c79da2a8 100644 --- a/operations.cpp +++ b/operations.cpp @@ -2385,6 +2385,25 @@ 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; + } effect_set eset; target->filter_effect(EFFECT_SSET_COST, &eset); for(int32 i = 0; i < eset.size(); ++i) { @@ -2395,12 +2414,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); return FALSE; } - case 2: { + case 3: { core.phase_action = TRUE; target->set_status(STATUS_SET_TURN, TRUE); if(target->data.type & TYPE_MONSTER) { @@ -4433,6 +4452,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) { + 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 10586c9f5..4f2d87514 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; @@ -432,13 +430,13 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) return FALSE; } else { uint8 pt = 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]; - if((p != 0 && p != 1) + if(!(count == 0 && i == 0 && l == 0) && ((p != 0 && p != 1) || ((l != LOCATION_MZONE) && (l != LOCATION_SZONE)) - || ((0x1u << s) & (flag >> (((p == playerid) ? 0 : 16) + ((l == LOCATION_MZONE) ? 0 : 8))))) { + || ((0x1u << s) & (flag >> (((p == playerid) ? 0 : 16) + ((l == LOCATION_MZONE) ? 0 : 8)))))) { pduel->write_buffer8(MSG_RETRY); return FALSE; } diff --git a/processor.cpp b/processor.cpp index 37b91adb9..fe4143580 100644 --- a/processor.cpp +++ b/processor.cpp @@ -3927,6 +3927,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) { + 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) { @@ -3974,23 +4026,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); @@ -3999,7 +4037,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(); @@ -4052,7 +4090,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; @@ -4068,11 +4106,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) { @@ -4082,7 +4120,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; @@ -4112,7 +4150,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) { @@ -4121,7 +4159,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) { @@ -4130,7 +4168,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; From fc71b5bcf000f9005ec8c9c693bd03f9f68bd230 Mon Sep 17 00:00:00 2001 From: mercury233 Date: Wed, 31 Aug 2022 08:44:36 +0800 Subject: [PATCH 2/2] fix --- operations.cpp | 5 +++-- processor.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/operations.cpp b/operations.cpp index 9b81f48ab..7f92e7e00 100644 --- a/operations.cpp +++ b/operations.cpp @@ -2395,6 +2395,7 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target, e 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) { @@ -2407,7 +2408,7 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target, e } 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 3: { @@ -4460,7 +4461,7 @@ 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) { + 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; diff --git a/processor.cpp b/processor.cpp index 6c9337c08..9becde00b 100644 --- a/processor.cpp +++ b/processor.cpp @@ -4002,7 +4002,7 @@ int32 field::add_chain(uint16 step) { 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) { + 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);