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:
//operations
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_target(uint8 chaincount, group* targets);
void change_target_player(uint8 chaincount, uint8 playerid);
......
......@@ -1962,8 +1962,11 @@ int32 scriptlib::duel_negate_activate(lua_State *L) {
int32 scriptlib::duel_negate_effect(lua_State *L) {
check_param_count(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);
lua_pushboolean(L, pduel->game_field->disable_chain(c));
lua_pushboolean(L, pduel->game_field->disable_chain(c, forced));
return 1;
}
int32 scriptlib::duel_negate_related_chain(lua_State *L) {
......@@ -4530,6 +4533,17 @@ int32 scriptlib::duel_is_chain_disablable(lua_State * L) {
lua_pushboolean(L, 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) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 2);
......@@ -4985,6 +4999,7 @@ static const struct luaL_Reg duellib[] = {
{ "IsPlayerCanAdditionalSummon", scriptlib::duel_is_player_can_additional_summon },
{ "IsChainNegatable", scriptlib::duel_is_chain_negatable },
{ "IsChainDisablable", scriptlib::duel_is_chain_disablable },
{ "IsChainDisabled", scriptlib::duel_is_chain_disabled },
{ "CheckChainTarget", scriptlib::duel_check_chain_target },
{ "CheckChainUniqueness", scriptlib::duel_check_chain_uniqueness },
{ "GetActivityCount", scriptlib::duel_get_activity_count },
......
......@@ -291,20 +291,23 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
check_action_permission(L);
check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2);
group* pgroup1 = *(group**)lua_touserdata(L, 1);
group* pgroup2 = *(group**)lua_touserdata(L, 2);
duel* pduel = pgroup1->pduel;
group* select_group = *(group**)lua_touserdata(L, 1);
group* unselect_group = 0;
if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
unselect_group = *(group**)lua_touserdata(L, 2);
duel* pduel = select_group->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 3);
if(playerid != 0 && playerid != 1)
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;
for(auto it = pgroup2->container.begin(); it != pgroup2->container.end(); ++it) {
card* pcard = *it;
for(auto it2 = pgroup1->container.begin(); it2 != pgroup1->container.end(); ++it2) {
if((*it2) == pcard) {
return 0;
if(unselect_group) {
for(auto it = unselect_group->container.begin(); it != unselect_group->container.end(); ++it) {
card* pcard = *it;
for(auto it2 = select_group->container.begin(); it2 != select_group->container.end(); ++it2) {
if((*it2) == pcard) {
return 0;
}
}
}
}
......@@ -328,11 +331,13 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
min = max;
pduel->game_field->core.select_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);
}
for(auto it = pgroup2->container.begin(); it != pgroup2->container.end(); ++it) {
pduel->game_field->core.unselect_cards.push_back(*it);
if(unselect_group) {
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);
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) {
if(chaincount > core.current_chain.size() || chaincount < 1)
chaincount = (uint8)core.current_chain.size();
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)
&& 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.disable_reason = core.reason_effect;
pchain.disable_player = core.reason_player;
if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && (pchain.triggering_effect->handler->current.location == LOCATION_SZONE)) {
pchain.triggering_effect->handler->set_status(STATUS_LEAVE_CONFIRMED, TRUE);
pchain.triggering_effect->handler->set_status(STATUS_ACTIVATE_DISABLED, TRUE);
if((pchain.triggering_effect->type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location == LOCATION_SZONE)) {
phandler->set_status(STATUS_LEAVE_CONFIRMED, TRUE);
phandler->set_status(STATUS_ACTIVATE_DISABLED, TRUE);
}
pduel->write_buffer8(MSG_CHAIN_NEGATED);
pduel->write_buffer8(chaincount);
if(pchain.triggering_location == LOCATION_DECK
|| 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 FALSE;
}
int32 field::disable_chain(uint8 chaincount) {
int32 field::disable_chain(uint8 chaincount, uint8 forced) {
if(core.current_chain.size() == 0)
return FALSE;
if(chaincount > core.current_chain.size() || chaincount < 1)
chaincount = (uint8)core.current_chain.size();
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)
&& 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].disable_reason = core.reason_effect;
core.current_chain[chaincount - 1].disable_player = core.reason_player;
......@@ -51,7 +54,7 @@ int32 field::disable_chain(uint8 chaincount) {
pduel->write_buffer8(chaincount);
if(pchain.triggering_location == LOCATION_DECK
|| 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 FALSE;
......@@ -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))
flag |= 0x1u << (core.duel_rule >= 4 ? 12 : 15);
if(!flag) {
core.units.begin()->step = 3;
if(target->current.location != LOCATION_GRAVE)
send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
return TRUE;
return FALSE;
}
if(move_player != playerid)
flag = flag << 16;
......@@ -4522,9 +4526,10 @@ int32 field::move_to_field(uint16 step, card* target, uint32 enable, uint32 ret,
return FALSE;
}
if(ct <= 0) {
core.units.begin()->step = 3;
if(target->current.location != LOCATION_GRAVE)
send_to(target, 0, REASON_RULE, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
return TRUE;
return FALSE;
}
if((zone & zone - 1) == 0) {
for(uint8 seq = 0; seq < 8; seq++) {
......
......@@ -13,6 +13,7 @@
#include <algorithm>
#include <stack>
#include <set>
int32 field::select_battle_command(uint16 step, uint8 playerid) {
if(step == 0) {
......@@ -226,8 +227,8 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi
returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty())
return TRUE;
if(max > 63)
max = 63;
if(max > 127)
max = 127;
if(max > core.select_cards.size())
max = (uint8)core.select_cards.size();
if(min > max)
......@@ -258,15 +259,15 @@ int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 mi
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
byte c[64] = {};
std::set<int8> c;
uint8 m = (uint8)core.select_cards.size();
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
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);
return FALSE;
}
c[v] = 1;
c.insert(v);
}
return TRUE;
}
......@@ -528,15 +529,15 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
byte c[64] = {};
std::set<int8> c;
uint8 m = (uint8)core.select_cards.size(), tt = 0;
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
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);
return FALSE;
}
c[v] = 1;
c.insert(v);
tt += core.select_cards[v]->release_param;
}
if(tt < min) {
......@@ -651,7 +652,7 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
}
return FALSE;
} else {
byte c[64] = {};
std::set<int32> c;
if(max) {
int32 oparam[16];
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
int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
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);
return FALSE;
}
c[v] = 1;
c.insert(v);
oparam[i] = core.select_cards[v]->sum_param;
}
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
int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
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);
return FALSE;
}
c[v] = 1;
c.insert(v);
int32 op = core.select_cards[v]->sum_param;
int32 o1 = op & 0xffff;
int32 o2 = op >> 16;
......@@ -737,15 +738,15 @@ int32 field::sort_card(int16 step, uint8 playerid) {
} else {
if(returns.bvalue[0] == -1)
return TRUE;
byte c[64] = {};
std::set<int8> c;
uint8 m = (uint8)core.select_cards.size();
for(uint8 i = 0; i < m; ++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);
return FALSE;
}
c[v] = 1;
c.insert(v);
}
return TRUE;
}
......
......@@ -3852,6 +3852,8 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
return FALSE;
}
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);
return FALSE;
}
......
......@@ -603,6 +603,7 @@ public:
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_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_uniqueness(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