Commit 5399fa86 authored by nanahira's avatar nanahira

Merge branch 'master' of github.com:Fluorohydride/ygopro-core

parents 6b47752a 9c1c559d
...@@ -560,7 +560,7 @@ public: ...@@ -560,7 +560,7 @@ public:
//operations //operations
int32 negate_chain(uint8 chaincount); int32 negate_chain(uint8 chaincount);
int32 disable_chain(uint8 chaincount); int32 disable_chain(uint8 chaincount, uint8 forced);
void change_chain_effect(uint8 chaincount, int32 replace_op); void change_chain_effect(uint8 chaincount, int32 replace_op);
void change_target(uint8 chaincount, group* targets); void change_target(uint8 chaincount, group* targets);
void change_target_player(uint8 chaincount, uint8 playerid); void change_target_player(uint8 chaincount, uint8 playerid);
......
...@@ -1962,8 +1962,11 @@ int32 scriptlib::duel_negate_activate(lua_State *L) { ...@@ -1962,8 +1962,11 @@ int32 scriptlib::duel_negate_activate(lua_State *L) {
int32 scriptlib::duel_negate_effect(lua_State *L) { int32 scriptlib::duel_negate_effect(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
uint32 c = (uint32)lua_tointeger(L, 1); uint32 c = (uint32)lua_tointeger(L, 1);
uint8 forced = FALSE;
if(lua_gettop(L) > 1)
forced = lua_toboolean(L, 2);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
lua_pushboolean(L, pduel->game_field->disable_chain(c)); lua_pushboolean(L, pduel->game_field->disable_chain(c, forced));
return 1; return 1;
} }
int32 scriptlib::duel_negate_related_chain(lua_State *L) { int32 scriptlib::duel_negate_related_chain(lua_State *L) {
...@@ -4530,6 +4533,17 @@ int32 scriptlib::duel_is_chain_disablable(lua_State * L) { ...@@ -4530,6 +4533,17 @@ int32 scriptlib::duel_is_chain_disablable(lua_State * L) {
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
return 1; return 1;
} }
int32 scriptlib::duel_is_chain_disabled(lua_State* L) {
check_param_count(L, 1);
int32 chaincount = (int32)lua_tointeger(L, 1);
duel* pduel = interpreter::get_duel_info(L);
if(pduel->game_field->core.chain_solving) {
lua_pushboolean(L, pduel->game_field->is_chain_disabled(chaincount));
return 1;
}
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::duel_check_chain_target(lua_State *L) { int32 scriptlib::duel_check_chain_target(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
...@@ -4985,6 +4999,7 @@ static const struct luaL_Reg duellib[] = { ...@@ -4985,6 +4999,7 @@ static const struct luaL_Reg duellib[] = {
{ "IsPlayerCanAdditionalSummon", scriptlib::duel_is_player_can_additional_summon }, { "IsPlayerCanAdditionalSummon", scriptlib::duel_is_player_can_additional_summon },
{ "IsChainNegatable", scriptlib::duel_is_chain_negatable }, { "IsChainNegatable", scriptlib::duel_is_chain_negatable },
{ "IsChainDisablable", scriptlib::duel_is_chain_disablable }, { "IsChainDisablable", scriptlib::duel_is_chain_disablable },
{ "IsChainDisabled", scriptlib::duel_is_chain_disabled },
{ "CheckChainTarget", scriptlib::duel_check_chain_target }, { "CheckChainTarget", scriptlib::duel_check_chain_target },
{ "CheckChainUniqueness", scriptlib::duel_check_chain_uniqueness }, { "CheckChainUniqueness", scriptlib::duel_check_chain_uniqueness },
{ "GetActivityCount", scriptlib::duel_get_activity_count }, { "GetActivityCount", scriptlib::duel_get_activity_count },
......
...@@ -291,20 +291,23 @@ int32 scriptlib::group_select_unselect(lua_State *L) { ...@@ -291,20 +291,23 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2); group* select_group = *(group**)lua_touserdata(L, 1);
group* pgroup1 = *(group**)lua_touserdata(L, 1); group* unselect_group = 0;
group* pgroup2 = *(group**)lua_touserdata(L, 2); if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
duel* pduel = pgroup1->pduel; unselect_group = *(group**)lua_touserdata(L, 2);
duel* pduel = select_group->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 3); uint32 playerid = (uint32)lua_tointeger(L, 3);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
if(pgroup1->container.size() + pgroup2->container.size() == 0) if(select_group->container.size() == 0 && (!unselect_group || unselect_group->container.size() == 0))
return 0; return 0;
for(auto it = pgroup2->container.begin(); it != pgroup2->container.end(); ++it) { if(unselect_group) {
card* pcard = *it; for(auto it = unselect_group->container.begin(); it != unselect_group->container.end(); ++it) {
for(auto it2 = pgroup1->container.begin(); it2 != pgroup1->container.end(); ++it2) { card* pcard = *it;
if((*it2) == pcard) { for(auto it2 = select_group->container.begin(); it2 != select_group->container.end(); ++it2) {
return 0; if((*it2) == pcard) {
return 0;
}
} }
} }
} }
...@@ -328,11 +331,13 @@ int32 scriptlib::group_select_unselect(lua_State *L) { ...@@ -328,11 +331,13 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
min = max; min = max;
pduel->game_field->core.select_cards.clear(); pduel->game_field->core.select_cards.clear();
pduel->game_field->core.unselect_cards.clear(); pduel->game_field->core.unselect_cards.clear();
for(auto it = pgroup1->container.begin(); it != pgroup1->container.end(); ++it) { for(auto it = select_group->container.begin(); it != select_group->container.end(); ++it) {
pduel->game_field->core.select_cards.push_back(*it); pduel->game_field->core.select_cards.push_back(*it);
} }
for(auto it = pgroup2->container.begin(); it != pgroup2->container.end(); ++it) { if(unselect_group) {
pduel->game_field->core.unselect_cards.push_back(*it); for(auto it = unselect_group->container.begin(); it != unselect_group->container.end(); ++it) {
pduel->game_field->core.unselect_cards.push_back(*it);
}
} }
pduel->game_field->add_process(PROCESSOR_SELECT_UNSELECT_CARD, 0, 0, 0, playerid + (cancelable << 16), min + (max << 16), finishable); pduel->game_field->add_process(PROCESSOR_SELECT_UNSELECT_CARD, 0, 0, 0, playerid + (cancelable << 16), min + (max << 16), finishable);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) {
......
...@@ -18,32 +18,35 @@ int32 field::negate_chain(uint8 chaincount) { ...@@ -18,32 +18,35 @@ int32 field::negate_chain(uint8 chaincount) {
if(chaincount > core.current_chain.size() || chaincount < 1) if(chaincount > core.current_chain.size() || chaincount < 1)
chaincount = (uint8)core.current_chain.size(); chaincount = (uint8)core.current_chain.size();
chain& pchain = core.current_chain[chaincount - 1]; chain& pchain = core.current_chain[chaincount - 1];
card* phandler = pchain.triggering_effect->handler;
if(!(pchain.flag & CHAIN_DISABLE_ACTIVATE) && is_chain_negatable(pchain.chain_count) if(!(pchain.flag & CHAIN_DISABLE_ACTIVATE) && is_chain_negatable(pchain.chain_count)
&& pchain.triggering_effect->handler->is_affect_by_effect(core.reason_effect) ) { && (!phandler->is_has_relation(pchain) || phandler->is_affect_by_effect(core.reason_effect))) {
pchain.flag |= CHAIN_DISABLE_ACTIVATE; pchain.flag |= CHAIN_DISABLE_ACTIVATE;
pchain.disable_reason = core.reason_effect; pchain.disable_reason = core.reason_effect;
pchain.disable_player = core.reason_player; pchain.disable_player = core.reason_player;
if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && (pchain.triggering_effect->handler->current.location == LOCATION_SZONE)) { if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location == LOCATION_SZONE)) {
pchain.triggering_effect->handler->set_status(STATUS_LEAVE_CONFIRMED, TRUE); phandler->set_status(STATUS_LEAVE_CONFIRMED, TRUE);
pchain.triggering_effect->handler->set_status(STATUS_ACTIVATE_DISABLED, TRUE); phandler->set_status(STATUS_ACTIVATE_DISABLED, TRUE);
} }
pduel->write_buffer8(MSG_CHAIN_NEGATED); pduel->write_buffer8(MSG_CHAIN_NEGATED);
pduel->write_buffer8(chaincount); pduel->write_buffer8(chaincount);
if(pchain.triggering_location == LOCATION_DECK if(pchain.triggering_location == LOCATION_DECK
|| core.duel_rule >= 5 && pchain.triggering_location == LOCATION_EXTRA && (pchain.triggering_position & POS_FACEDOWN)) || core.duel_rule >= 5 && pchain.triggering_location == LOCATION_EXTRA && (pchain.triggering_position & POS_FACEDOWN))
pchain.triggering_effect->handler->release_relation(pchain); phandler->release_relation(pchain);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
int32 field::disable_chain(uint8 chaincount) { int32 field::disable_chain(uint8 chaincount, uint8 forced) {
if(core.current_chain.size() == 0) if(core.current_chain.size() == 0)
return FALSE; return FALSE;
if(chaincount > core.current_chain.size() || chaincount < 1) if(chaincount > core.current_chain.size() || chaincount < 1)
chaincount = (uint8)core.current_chain.size(); chaincount = (uint8)core.current_chain.size();
chain& pchain = core.current_chain[chaincount - 1]; chain& pchain = core.current_chain[chaincount - 1];
card* phandler = pchain.triggering_effect->handler;
if(!(pchain.flag & CHAIN_DISABLE_EFFECT) && is_chain_disablable(pchain.chain_count) if(!(pchain.flag & CHAIN_DISABLE_EFFECT) && is_chain_disablable(pchain.chain_count)
&& pchain.triggering_effect->handler->is_affect_by_effect(core.reason_effect)) { && (!phandler->is_has_relation(pchain) || phandler->is_affect_by_effect(core.reason_effect))
&& !(phandler->is_has_relation(pchain) && phandler->is_status(STATUS_DISABLED) && !forced)) {
core.current_chain[chaincount - 1].flag |= CHAIN_DISABLE_EFFECT; core.current_chain[chaincount - 1].flag |= CHAIN_DISABLE_EFFECT;
core.current_chain[chaincount - 1].disable_reason = core.reason_effect; core.current_chain[chaincount - 1].disable_reason = core.reason_effect;
core.current_chain[chaincount - 1].disable_player = core.reason_player; core.current_chain[chaincount - 1].disable_player = core.reason_player;
...@@ -51,7 +54,7 @@ int32 field::disable_chain(uint8 chaincount) { ...@@ -51,7 +54,7 @@ int32 field::disable_chain(uint8 chaincount) {
pduel->write_buffer8(chaincount); pduel->write_buffer8(chaincount);
if(pchain.triggering_location == LOCATION_DECK if(pchain.triggering_location == LOCATION_DECK
|| core.duel_rule >= 5 && pchain.triggering_location == LOCATION_EXTRA && (pchain.triggering_position & POS_FACEDOWN)) || core.duel_rule >= 5 && pchain.triggering_location == LOCATION_EXTRA && (pchain.triggering_position & POS_FACEDOWN))
pchain.triggering_effect->handler->release_relation(pchain); phandler->release_relation(pchain);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
...@@ -4500,9 +4503,10 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret, ...@@ -4500,9 +4503,10 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret,
if(is_location_useable(playerid, LOCATION_PZONE, 1)) if(is_location_useable(playerid, LOCATION_PZONE, 1))
flag |= 0x1u << (core.duel_rule >= 4 ? 12 : 15); flag |= 0x1u << (core.duel_rule >= 4 ? 12 : 15);
if(!flag) { if(!flag) {
core.units.begin()->step = 3;
if(target->current.location != LOCATION_GRAVE) if(target->current.location != LOCATION_GRAVE)
send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP); send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
return TRUE; return FALSE;
} }
if(move_player != playerid) if(move_player != playerid)
flag = flag << 16; flag = flag << 16;
...@@ -4522,9 +4526,10 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret, ...@@ -4522,9 +4526,10 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret,
return FALSE; return FALSE;
} }
if(ct <= 0) { if(ct <= 0) {
core.units.begin()->step = 3;
if(target->current.location != LOCATION_GRAVE) if(target->current.location != LOCATION_GRAVE)
send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP); send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
return TRUE; return FALSE;
} }
if((zone & zone - 1) == 0) { if((zone & zone - 1) == 0) {
for(uint8 seq = 0; seq < 8; seq++) { for(uint8 seq = 0; seq < 8; seq++) {
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <algorithm> #include <algorithm>
#include <stack> #include <stack>
#include <set>
int32 field::select_battle_command(uint16 step, uint8 playerid) { int32 field::select_battle_command(uint16 step, uint8 playerid) {
if(step == 0) { if(step == 0) {
...@@ -226,8 +227,8 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi ...@@ -226,8 +227,8 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty()) if(max == 0 || core.select_cards.empty())
return TRUE; return TRUE;
if(max > 63) if(max > 127)
max = 63; max = 127;
if(max > core.select_cards.size()) if(max > core.select_cards.size())
max = (uint8)core.select_cards.size(); max = (uint8)core.select_cards.size();
if(min > max) if(min > max)
...@@ -258,15 +259,15 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi ...@@ -258,15 +259,15 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
byte c[64] = {}; std::set<int8> c;
uint8 m = (uint8)core.select_cards.size(); uint8 m = (uint8)core.select_cards.size();
for(int32 i = 0; i < returns.bvalue[0]; ++i) { for(int32 i = 0; i < returns.bvalue[0]; ++i) {
int8 v = returns.bvalue[i + 1]; int8 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || v >= 63 || c[v]) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c.insert(v);
} }
return TRUE; return TRUE;
} }
...@@ -528,15 +529,15 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 ...@@ -528,15 +529,15 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
byte c[64] = {}; std::set<int8> c;
uint8 m = (uint8)core.select_cards.size(), tt = 0; uint8 m = (uint8)core.select_cards.size(), tt = 0;
for(int32 i = 0; i < returns.bvalue[0]; ++i) { for(int32 i = 0; i < returns.bvalue[0]; ++i) {
int8 v = returns.bvalue[i + 1]; int8 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c[v]) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c.insert(v);
tt += core.select_cards[v]->release_param; tt += core.select_cards[v]->release_param;
} }
if(tt < min) { if(tt < min) {
...@@ -651,7 +652,7 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -651,7 +652,7 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
} }
return FALSE; return FALSE;
} else { } else {
byte c[64] = {}; std::set<int32> c;
if(max) { if(max) {
int32 oparam[16]; int32 oparam[16];
int32 mcount = (int32)core.must_select_cards.size(); int32 mcount = (int32)core.must_select_cards.size();
...@@ -664,11 +665,11 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -664,11 +665,11 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
int32 m = (int32)core.select_cards.size(); int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) { for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1]; int32 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c[v]) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c.insert(v);
oparam[i] = core.select_cards[v]->sum_param; oparam[i] = core.select_cards[v]->sum_param;
} }
if(!select_sum_check1(oparam, returns.bvalue[0], 0, acc, 0xffff)) { if(!select_sum_check1(oparam, returns.bvalue[0], 0, acc, 0xffff)) {
...@@ -692,11 +693,11 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -692,11 +693,11 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
int32 m = (int32)core.select_cards.size(); int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) { for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1]; int32 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c[v]) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c.insert(v);
int32 op = core.select_cards[v]->sum_param; int32 op = core.select_cards[v]->sum_param;
int32 o1 = op & 0xffff; int32 o1 = op & 0xffff;
int32 o2 = op >> 16; int32 o2 = op >> 16;
...@@ -737,15 +738,15 @@ int32 field::sort_card(int16 step, uint8 playerid) { ...@@ -737,15 +738,15 @@ int32 field::sort_card(int16 step, uint8 playerid) {
} else { } else {
if(returns.bvalue[0] == -1) if(returns.bvalue[0] == -1)
return TRUE; return TRUE;
byte c[64] = {}; std::set<int8> c;
uint8 m = (uint8)core.select_cards.size(); uint8 m = (uint8)core.select_cards.size();
for(uint8 i = 0; i < m; ++i) { for(uint8 i = 0; i < m; ++i) {
int8 v = returns.bvalue[i]; int8 v = returns.bvalue[i];
if(v < 0 || v >= m || c[v]) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c[v] = 1; c.insert(v);
} }
return TRUE; return TRUE;
} }
......
...@@ -3852,6 +3852,8 @@ int32 field::process_turn(uint16 step, uint8 turn_player) { ...@@ -3852,6 +3852,8 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
return FALSE; return FALSE;
} }
case 10: { case 10: {
if(core.new_fchain.size() || core.new_ochain.size())
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0);
add_process(PROCESSOR_PHASE_EVENT, 0, 0, 0, PHASE_BATTLE_START, 0); add_process(PROCESSOR_PHASE_EVENT, 0, 0, 0, PHASE_BATTLE_START, 0);
return FALSE; return FALSE;
} }
......
...@@ -603,6 +603,7 @@ public: ...@@ -603,6 +603,7 @@ public:
static int32 duel_is_player_can_additional_summon(lua_State *L); static int32 duel_is_player_can_additional_summon(lua_State *L);
static int32 duel_is_chain_negatable(lua_State *L); static int32 duel_is_chain_negatable(lua_State *L);
static int32 duel_is_chain_disablable(lua_State *L); static int32 duel_is_chain_disablable(lua_State *L);
static int32 duel_is_chain_disabled(lua_State *L);
static int32 duel_check_chain_target(lua_State *L); static int32 duel_check_chain_target(lua_State *L);
static int32 duel_check_chain_uniqueness(lua_State *L); static int32 duel_check_chain_uniqueness(lua_State *L);
static int32 duel_get_activity_count(lua_State *L); static int32 duel_get_activity_count(lua_State *L);
......
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