Commit d065a888 authored by VanillaSalt's avatar VanillaSalt

update swap_control

parent 0a982873
......@@ -471,6 +471,7 @@ public:
void remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max);
void get_control(card_set* targets, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count);
void get_control(card* target, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count);
void swap_control(effect* reason_effect, uint32 reason_player, card_set* targets1, card_set* targets2, uint32 reset_phase, uint32 reset_count);
void swap_control(effect* reason_effect, uint32 reason_player, card* pcard1, card* pcard2, uint32 reset_phase, uint32 reset_count);
void equip(uint32 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step);
void draw(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 count);
......@@ -494,7 +495,7 @@ public:
int32 remove_counter(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 countertype, uint16 count);
int32 remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 min, uint16 max);
int32 get_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint8 playerid, uint16 reset_phase, uint8 reset_count);
int32 swap_control(uint16 step, effect* reason_effect, uint8 reason_player, card* pcard1, card* pcard2, uint16 reset_phase, uint8 reset_count);
int32 swap_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets1, group* targets2, uint16 reset_phase, uint8 reset_count);
int32 control_adjust(uint16 step);
int32 self_destroy(uint16 step);
int32 equip(uint16 step, uint8 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step);
......
......@@ -1049,18 +1049,31 @@ int32 scriptlib::duel_get_control(lua_State *L) {
int32 scriptlib::duel_swap_control(lua_State *L) {
check_action_permission(L);
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_CARD, 2);
card* pcard1 = *(card**) lua_touserdata(L, 1);
card* pcard2 = *(card**) lua_touserdata(L, 2);
card* pcard1 = 0;
card* pcard2 = 0;
group* pgroup1 = 0;
group* pgroup2 = 0;
duel* pduel;
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE) && check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
pcard1 = *(card**) lua_touserdata(L, 1);
pcard2 = *(card**) lua_touserdata(L, 2);
pduel = pcard1->pduel;
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE) && check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
pgroup1 = *(group**) lua_touserdata(L, 1);
pgroup2 = *(group**) lua_touserdata(L, 2);
pduel = pgroup1->pduel;
} else
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
uint32 reset_phase = 0;
uint32 reset_count = 0;
if(lua_gettop(L) > 2) {
reset_phase = lua_tointeger(L, 3) & 0x3ff;
reset_count = lua_tointeger(L, 4) & 0xff;
}
duel* pduel = pcard1->pduel;
if(pcard1)
pduel->game_field->swap_control(pduel->game_field->core.reason_effect, pduel->game_field->core.reason_player, pcard1, pcard2, reset_phase, reset_count);
else
pduel->game_field->swap_control(pduel->game_field->core.reason_effect, pduel->game_field->core.reason_player, &pgroup1->container, &pgroup2->container, reset_phase, reset_count);
pduel->game_field->core.subunits.back().type = PROCESSOR_SWAP_CONTROL_S;
return lua_yield(L, 0);
}
......
......@@ -115,8 +115,19 @@ void field::get_control(card* target, effect* reason_effect, uint32 reason_playe
tset.insert(target);
get_control(&tset, reason_effect, reason_player, playerid, reset_phase, reset_count);
}
void field::swap_control(effect* reason_effect, uint32 reason_player, card_set* targets1, card_set* targets2, uint32 reset_phase, uint32 reset_count) {
group* ng1 = pduel->new_group(*targets1);
ng1->is_readonly = TRUE;
group* ng2 = pduel->new_group(*targets2);
ng2->is_readonly = TRUE;
add_process(PROCESSOR_SWAP_CONTROL, 0, reason_effect, ng1, reason_player, reset_phase, reset_count, 0, ng2);
}
void field::swap_control(effect* reason_effect, uint32 reason_player, card* pcard1, card* pcard2, uint32 reset_phase, uint32 reset_count) {
add_process(PROCESSOR_SWAP_CONTROL, 0, reason_effect, (group*)pcard1, reason_player, reset_phase, reset_count, 0, pcard2);
card_set tset1;
tset1.insert(pcard1);
card_set tset2;
tset2.insert(pcard2);
swap_control(reason_effect, reason_player, &tset1, &tset2, reset_phase, reset_count);
}
void field::equip(uint32 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step) {
add_process(PROCESSOR_EQUIP, 0, NULL, (group*)target, 0, equip_player + (up << 16) + (is_step << 24), 0, 0, equip_card);
......@@ -917,66 +928,104 @@ int32 field::get_control(uint16 step, effect* reason_effect, uint8 reason_player
}
return TRUE;
}
int32 field::swap_control(uint16 step, effect * reason_effect, uint8 reason_player, card * pcard1, card * pcard2, uint16 reset_phase, uint8 reset_count) {
int32 field::swap_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets1, group* targets2, uint16 reset_phase, uint8 reset_count) {
switch(step) {
case 0: {
uint8 p1 = pcard1->current.controler, p2 = pcard2->current.controler;
uint8 l1 = pcard1->current.location, l2 = pcard2->current.location;
uint8 s1 = pcard1->current.sequence, s2 = pcard2->current.sequence;
returns.ivalue[0] = 0;
if(pcard1->overlay_target || pcard2->overlay_target)
if(targets1->container.size() == 0)
return TRUE;
if(targets2->container.size() == 0)
return TRUE;
if(targets1->container.size() != targets2->container.size())
return TRUE;
for(auto cit = targets1->container.begin(); cit != targets1->container.end(); ++cit)
(*cit)->filter_disable_related_cards();
for(auto cit = targets2->container.begin(); cit != targets2->container.end(); ++cit)
(*cit)->filter_disable_related_cards();
auto cit1 = targets1->container.begin();
auto cit2 = targets2->container.begin();
uint8 p1 = (*cit1)->current.controler, p2 = (*cit2)->current.controler;
if(p1 == p2 || p1 == PLAYER_NONE || p2 == PLAYER_NONE)
return TRUE;
if(l1 != LOCATION_MZONE || l2 != LOCATION_MZONE)
for(auto cit = targets1->container.begin(); cit != targets1->container.end(); ++cit) {
card* pcard = *cit;
if(pcard->overlay_target)
return TRUE;
if(pcard->current.controler != p1)
return TRUE;
if(pcard->current.location != LOCATION_MZONE)
return TRUE;
if(!pcard->is_capable_change_control())
return TRUE;
if(!pcard->is_affect_by_effect(reason_effect))
return TRUE;
}
for(auto cit = targets2->container.begin(); cit != targets2->container.end(); ++cit) {
card* pcard = *cit;
if(pcard->overlay_target)
return TRUE;
if(!pcard1->is_capable_change_control() || !pcard2->is_capable_change_control())
if(pcard->current.controler != p2)
return TRUE;
if(!pcard1->is_affect_by_effect(reason_effect) || !pcard2->is_affect_by_effect(reason_effect))
if(pcard->current.location != LOCATION_MZONE)
return TRUE;
if(!pcard->is_capable_change_control())
return TRUE;
pcard1->filter_disable_related_cards();
pcard2->filter_disable_related_cards();
if(pcard1->unique_code && (pcard1->unique_location & LOCATION_MZONE))
remove_unique_card(pcard1);
if(pcard2->unique_code && (pcard2->unique_location & LOCATION_MZONE))
remove_unique_card(pcard2);
if(!pcard->is_affect_by_effect(reason_effect))
return TRUE;
}
for(auto cit = targets1->container.begin(); cit != targets1->container.end(); ++cit) {
card* pcard = *cit;
if(pcard->unique_code && (pcard->unique_location & LOCATION_MZONE))
remove_unique_card(pcard);
}
for(auto cit = targets2->container.begin(); cit != targets2->container.end(); ++cit) {
card* pcard = *cit;
if(pcard->unique_code && (pcard->unique_location & LOCATION_MZONE))
remove_unique_card(pcard);
}
while(cit1 != targets1->container.end()) {
card* pcard1 = *cit1++;
card* pcard2 = *cit2++;
uint8 l1 = pcard1->current.location, l2 = pcard2->current.location;
uint8 s1 = pcard1->current.sequence, s2 = pcard2->current.sequence;
remove_card(pcard1);
remove_card(pcard2);
add_card(p2, pcard1, l2, s2);
add_card(p1, pcard2, l1, s1);
if(pcard1->unique_code && (pcard1->unique_location & LOCATION_MZONE))
add_unique_card(pcard1);
if(pcard2->unique_code && (pcard2->unique_location & LOCATION_MZONE))
add_unique_card(pcard2);
set_control(pcard1, p2, reset_phase, reset_count);
set_control(pcard2, p1, reset_phase, reset_count);
pcard1->reset(RESET_CONTROL, RESET_EVENT);
pcard2->reset(RESET_CONTROL, RESET_EVENT);
pcard1->filter_disable_related_cards();
pcard2->filter_disable_related_cards();
set_control(pcard1, p2, reset_phase, reset_count);
set_control(pcard2, p1, reset_phase, reset_count);
pcard1->set_status(STATUS_ATTACK_CANCELED, TRUE);
pcard2->set_status(STATUS_ATTACK_CANCELED, TRUE);
return FALSE;
}
case 1: {
pduel->write_buffer8(MSG_SWAP);
pduel->write_buffer32(pcard1->data.code);
pduel->write_buffer32(pcard2->get_info_location());
pduel->write_buffer32(pcard2->data.code);
pduel->write_buffer32(pcard1->get_info_location());
adjust_instant();
raise_single_event(pcard1, 0, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, pcard1->current.controler, 0);
raise_single_event(pcard2, 0, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, pcard2->current.controler, 0);
}
return FALSE;
}
case 1: {
targets1->container.insert(targets2->container.begin(), targets2->container.end());
for(auto cit = targets1->container.begin(); cit != targets1->container.end(); ++cit) {
card* pcard = *cit;
pcard->filter_disable_related_cards();
if(pcard->unique_code && (pcard->unique_location & LOCATION_MZONE))
add_unique_card(pcard);
raise_single_event(pcard, 0, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, pcard->current.controler, 0);
}
if(targets1->container.size())
raise_event(&targets1->container, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, 0, 0);
process_single_event();
card_set cset;
cset.insert(pcard1);
cset.insert(pcard2);
raise_event(&cset, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, 0, 0);
process_instant_event();
return FALSE;
}
case 2: {
core.operated_set = targets1->container;
returns.ivalue[0] = 1;
pduel->delete_group(targets1);
pduel->delete_group(targets2);
return TRUE;
}
}
......
......@@ -459,7 +459,7 @@ int32 field::process() {
return pduel->bufferlen;
}
case PROCESSOR_SWAP_CONTROL: {
if (swap_control(it->step, it->peffect, it->arg1, (card*)it->ptarget, (card*)it->ptr1, it->arg2, it->arg3)) {
if (swap_control(it->step, it->peffect, it->arg1, it->ptarget, (group*)it->ptr1, it->arg2, it->arg3)) {
core.units.pop_front();
} else
it->step++;
......
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