Commit f2fdd11c authored by VanillaSalt's avatar VanillaSalt

update Duel.GetControl

parent b4d52a70
...@@ -463,7 +463,8 @@ public: ...@@ -463,7 +463,8 @@ public:
void change_target_param(uint8 chaincount, int32 param); void change_target_param(uint8 chaincount, int32 param);
void remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint32 countertype, uint32 count); void remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint32 countertype, uint32 count);
void remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max); void remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max);
void get_control(effect* reason_effect, uint32 reason_player, card* pcard, uint32 playerid, uint32 reset_phase, uint32 reset_count); 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* pcard1, card* pcard2, 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 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); void draw(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 count);
...@@ -486,7 +487,7 @@ public: ...@@ -486,7 +487,7 @@ public:
int32 remove_counter(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 countertype, uint16 count); 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 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, card* pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count); 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, card* pcard1, card* pcard2, uint16 reset_phase, uint8 reset_count);
int32 control_adjust(uint16 step); int32 control_adjust(uint16 step);
int32 self_destroy(uint16 step); int32 self_destroy(uint16 step);
......
...@@ -990,8 +990,17 @@ int32 scriptlib::duel_equip_complete(lua_State *L) { ...@@ -990,8 +990,17 @@ int32 scriptlib::duel_equip_complete(lua_State *L) {
int32 scriptlib::duel_get_control(lua_State *L) { int32 scriptlib::duel_get_control(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); card* pcard = 0;
card* target = *(card**) lua_touserdata(L, 1); group* pgroup = 0;
duel* pduel;
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
pcard = *(card**) lua_touserdata(L, 1);
pduel = pcard->pduel;
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
pgroup = *(group**) lua_touserdata(L, 1);
pduel = pgroup->pduel;
} else
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
uint32 playerid = lua_tointeger(L, 2); uint32 playerid = lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
...@@ -1001,8 +1010,10 @@ int32 scriptlib::duel_get_control(lua_State *L) { ...@@ -1001,8 +1010,10 @@ int32 scriptlib::duel_get_control(lua_State *L) {
reset_phase = lua_tointeger(L, 3) & 0x3ff; reset_phase = lua_tointeger(L, 3) & 0x3ff;
reset_count = lua_tointeger(L, 4) & 0xff; reset_count = lua_tointeger(L, 4) & 0xff;
} }
duel* pduel = target->pduel; if(pcard)
pduel->game_field->get_control(pduel->game_field->core.reason_effect, pduel->game_field->core.reason_player, target, playerid, reset_phase, reset_count); pduel->game_field->get_control(pcard, pduel->game_field->core.reason_effect, pduel->game_field->core.reason_player, playerid, reset_phase, reset_count);
else
pduel->game_field->get_control(&pgroup->container, pduel->game_field->core.reason_effect, pduel->game_field->core.reason_player, playerid, reset_phase, reset_count);
pduel->game_field->core.subunits.begin()->type = PROCESSOR_GET_CONTROL_S; pduel->game_field->core.subunits.begin()->type = PROCESSOR_GET_CONTROL_S;
return lua_yield(L, 0); return lua_yield(L, 0);
} }
......
...@@ -105,8 +105,15 @@ void field::remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s, ...@@ -105,8 +105,15 @@ void field::remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s,
void field::remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max) { void field::remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max) {
add_process(PROCESSOR_REMOVEOL_S, 0, (effect*)(size_t) reason, (group*)pcard, (rplayer << 16) + (s << 8) + o, (max << 16) + min); add_process(PROCESSOR_REMOVEOL_S, 0, (effect*)(size_t) reason, (group*)pcard, (rplayer << 16) + (s << 8) + o, (max << 16) + min);
} }
void field::get_control(effect* reason_effect, uint32 reason_player, card* pcard, uint32 playerid, uint32 reset_phase, uint32 reset_count) { void field::get_control(card_set* targets, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count) {
add_process(PROCESSOR_GET_CONTROL, 0, reason_effect, (group*)pcard, 0, (reason_player << 28) + (playerid << 24) + (reset_phase << 8) + reset_count); group* ng = pduel->new_group(*targets);
ng->is_readonly = TRUE;
add_process(PROCESSOR_GET_CONTROL, 0, reason_effect, ng, 0, (reason_player << 28) + (playerid << 24) + (reset_phase << 8) + reset_count);
}
void field::get_control(card* target, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count) {
card_set tset;
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* pcard1, card* pcard2, uint32 reset_phase, uint32 reset_count) { 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, (ptr)pcard2, (reason_player << 28) + (reset_phase << 8) + reset_count); add_process(PROCESSOR_SWAP_CONTROL, 0, reason_effect, (group*)pcard1, (ptr)pcard2, (reason_player << 28) + (reset_phase << 8) + reset_count);
...@@ -779,59 +786,113 @@ int32 field::remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8 ...@@ -779,59 +786,113 @@ int32 field::remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8
} }
return TRUE; return TRUE;
} }
int32 field::get_control(uint16 step, effect * reason_effect, uint8 reason_player, card * pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count) { int32 field::get_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint8 playerid, uint16 reset_phase, uint8 reset_count) {
switch(step) { switch(step) {
case 0: { case 0: {
if(pcard->current.controler == playerid) { core.destroy_set.clear();
returns.ivalue[0] = 1; core.operated_set.clear();
return TRUE; for(auto cit = targets->container.begin(); cit != targets->container.end();) {
auto rm = cit++;
card* pcard = *rm;
pcard->filter_disable_related_cards();
bool change = true;
if(pcard->overlay_target)
change = false;
if(pcard->current.controler == playerid)
change = false;
if(pcard->current.controler == PLAYER_NONE)
change = false;
if(pcard->current.location != LOCATION_MZONE)
change = false;
if(!pcard->is_capable_change_control())
change = false;
if(!pcard->is_affect_by_effect(reason_effect))
change = false;
if((pcard->get_type() & TYPE_TRAPMONSTER) && get_useable_count(playerid, LOCATION_SZONE, playerid, LOCATION_REASON_CONTROL) <= 0)
change = false;
if(!change)
targets->container.erase(pcard);
} }
returns.ivalue[0] = 0; int32 fcount = get_useable_count(playerid, LOCATION_MZONE, playerid, LOCATION_REASON_CONTROL);
if(pcard->overlay_target) if(fcount <= 0) {
return TRUE; core.destroy_set.swap(targets->container);
if(pcard->current.controler == PLAYER_NONE) core.units.begin()->step = 5;
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;
if(get_useable_count(playerid, LOCATION_MZONE, playerid, LOCATION_REASON_CONTROL) <= 0) {
core.units.begin()->step = 3;
return FALSE; return FALSE;
} }
if((pcard->get_type() & TYPE_TRAPMONSTER) && get_useable_count(playerid, LOCATION_SZONE, playerid, LOCATION_REASON_CONTROL) <= 0) if(targets->container.size() > fcount) {
return TRUE; core.select_cards.clear();
pcard->filter_disable_related_cards(); for(auto cit = targets->container.begin(); cit != targets->container.end(); ++cit)
if(pcard->unique_code && (pcard->unique_location & LOCATION_MZONE)) core.select_cards.push_back(*cit);
remove_unique_card(pcard); pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(playerid);
pduel->write_buffer32(502);
uint32 ct = targets->container.size() - fcount;
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, ct + (ct << 16));
} else
core.units.begin()->step = 1;
}
case 1: {
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
card* pcard = core.select_cards[returns.bvalue[i + 1]];
core.destroy_set.insert(pcard);
targets->container.erase(pcard);
}
return FALSE;
}
case 2: {
for(auto cit = targets->container.begin(); cit != targets->container.end(); ++cit) {
if((*cit)->unique_code && ((*cit)->unique_location & LOCATION_MZONE))
remove_unique_card(*cit);
}
targets->it = targets->container.begin();
}
case 3: {
if(targets->it == targets->container.end()) {
core.units.begin()->step = 4;
return FALSE;
}
card* pcard = *targets->it;
move_to_field(pcard, playerid, playerid, LOCATION_MZONE, pcard->current.position); move_to_field(pcard, playerid, playerid, LOCATION_MZONE, pcard->current.position);
pcard->set_status(STATUS_ATTACK_CANCELED, TRUE);
return FALSE; return FALSE;
} }
case 1: { case 4: {
if(pcard->unique_code && (pcard->unique_location & LOCATION_MZONE)) card* pcard = *targets->it;
add_unique_card(pcard); pcard->set_status(STATUS_ATTACK_CANCELED, TRUE);
set_control(pcard, playerid, reset_phase, reset_count); set_control(pcard, playerid, reset_phase, reset_count);
pcard->reset(RESET_CONTROL, RESET_EVENT); pcard->reset(RESET_CONTROL, RESET_EVENT);
pcard->filter_disable_related_cards(); pcard->filter_disable_related_cards();
adjust_instant(); ++targets->it;
core.units.begin()->step = 2;
return FALSE; return FALSE;
} }
case 2: { case 5: {
raise_single_event(pcard, 0, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, playerid, 0); adjust_instant();
for(auto cit = targets->container.begin(); cit != targets->container.end(); ) {
card* pcard = *cit++;
if(!(pcard->current.location & LOCATION_ONFIELD)) {
targets->container.erase(pcard);
continue;
}
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, playerid, 0);
}
if(targets->container.size())
raise_event(&targets->container, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, playerid, 0);
process_single_event(); process_single_event();
raise_event(pcard, EVENT_CONTROL_CHANGED, reason_effect, REASON_EFFECT, reason_player, playerid, 0);
process_instant_event(); process_instant_event();
return FALSE; return FALSE;
} }
case 3: { case 6: {
returns.ivalue[0] = 1; if(core.destroy_set.size())
return TRUE; destroy(&core.destroy_set, 0, REASON_RULE, PLAYER_NONE);
return FALSE;
} }
case 4: { case 7: {
destroy(pcard, 0, REASON_RULE, PLAYER_NONE); core.operated_set = targets->container;
returns.ivalue[0] = targets->container.size();
pduel->delete_group(targets);
return TRUE; return TRUE;
} }
} }
...@@ -928,7 +989,7 @@ int32 field::control_adjust(uint16 step) { ...@@ -928,7 +989,7 @@ int32 field::control_adjust(uint16 step) {
pduel->write_buffer8(MSG_HINT); pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG); pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(infos.turn_player); pduel->write_buffer8(infos.turn_player);
pduel->write_buffer32(504); pduel->write_buffer32(502);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1, count + (count << 16)); add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1, count + (count << 16));
} }
} else } else
...@@ -948,7 +1009,7 @@ int32 field::control_adjust(uint16 step) { ...@@ -948,7 +1009,7 @@ int32 field::control_adjust(uint16 step) {
pduel->write_buffer8(MSG_HINT); pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG); pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(infos.turn_player); pduel->write_buffer8(infos.turn_player);
pduel->write_buffer32(504); pduel->write_buffer32(502);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 0, count + (count << 16)); add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 0, count + (count << 16));
} }
} else } else
...@@ -1033,7 +1094,7 @@ int32 field::control_adjust(uint16 step) { ...@@ -1033,7 +1094,7 @@ int32 field::control_adjust(uint16 step) {
process_single_event(); process_single_event();
process_instant_event(); process_instant_event();
return FALSE; return FALSE;
}; }
case 5: { case 5: {
if(core.destroy_set.size()) if(core.destroy_set.size())
destroy(&core.destroy_set, 0, REASON_RULE, PLAYER_NONE); destroy(&core.destroy_set, 0, REASON_RULE, PLAYER_NONE);
......
...@@ -440,7 +440,7 @@ int32 field::process() { ...@@ -440,7 +440,7 @@ int32 field::process() {
return pduel->bufferlen; return pduel->bufferlen;
} }
case PROCESSOR_GET_CONTROL: { case PROCESSOR_GET_CONTROL: {
if (get_control(it->step, it->peffect, (it->arg2 >> 28) & 0xf, (card*)it->ptarget, (it->arg2 >> 24) & 0xf, (it->arg2 >> 8) & 0x3ff, it->arg2 & 0xff)) { if (get_control(it->step, it->peffect, (it->arg2 >> 28) & 0xf, it->ptarget, (it->arg2 >> 24) & 0xf, (it->arg2 >> 8) & 0x3ff, it->arg2 & 0xff)) {
core.units.pop_front(); core.units.pop_front();
} else } else
it->step++; it->step++;
...@@ -934,7 +934,7 @@ int32 field::process() { ...@@ -934,7 +934,7 @@ int32 field::process() {
add_process(PROCESSOR_GET_CONTROL, 0, it->peffect, it->ptarget, it->arg1, it->arg2); add_process(PROCESSOR_GET_CONTROL, 0, it->peffect, it->ptarget, it->arg1, it->arg2);
it->step++; it->step++;
} else { } else {
pduel->lua->add_param(returns.ivalue[0], PARAM_TYPE_BOOLEAN); pduel->lua->add_param(returns.ivalue[0], PARAM_TYPE_INT);
core.units.pop_front(); core.units.pop_front();
} }
return pduel->bufferlen; return pduel->bufferlen;
......
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