Commit c74eab31 authored by mercury233's avatar mercury233
parents a287f9a1 36152ff1
......@@ -1368,6 +1368,51 @@ int32 card::is_link_state() {
return TRUE;
return FALSE;
}
int32 card::is_extra_link_state() {
if(current.location != LOCATION_MZONE)
return FALSE;
card_set cset;
card_set excset;
for(int32 p = 0; p < 2; ++p) {
card* pcard1 = pduel->game_field->player[p].list_mzone[5];
if(pcard1)
excset.insert(pcard1);
card* pcard2 = pduel->game_field->player[p].list_mzone[6];
if(pcard2)
excset.insert(pcard2);
}
if(excset.size() < 2)
return FALSE;
auto cit = excset.begin();
card* pcard = *cit;
excset.erase(pcard);
card_set linked_group1;
pcard->get_mutual_linked_cards(&linked_group1);
if(!linked_group1.size())
return FALSE;
cset.insert(pcard);
return check_extra_link(&cset, &excset, &linked_group1);
}
int32 card::check_extra_link(card_set* cset, card_set* excset, card_set* linked_group1) {
for(auto cit = linked_group1->begin(); cit != linked_group1->end(); ++cit) {
card* pcard = *cit;
if(cset->find(pcard) != cset->end())
continue;
if(excset->find(pcard) != cset->end())
if(cset->find(this) != cset->end())
return TRUE;
card_set linked_group2;
pcard->get_mutual_linked_cards(&linked_group2);
if(!linked_group2.size())
continue;
cset->insert(pcard);
int32 result = check_extra_link(cset, excset, &linked_group2);
cset->erase(pcard);
if(result)
return TRUE;
}
return FALSE;
}
int32 card::is_position(int32 pos) {
return current.position & pos;
}
......
......@@ -227,6 +227,8 @@ public:
uint32 get_mutual_linked_zone();
void get_mutual_linked_cards(card_set * cset);
int32 is_link_state();
int32 is_extra_link_state();
int32 check_extra_link(card_set* cset, card_set* excset, card_set* linked_group1);
int32 is_position(int32 pos);
void set_status(uint32 status, int32 enabled);
int32 get_status(uint32 status);
......
......@@ -577,7 +577,7 @@ int32 field::get_useable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer
pcard = temp_card;
pcard->current.location = LOCATION_EXTRA;
}
int useable_count = 0;
int32 useable_count = 0;
if(core.duel_rule >= 4)
useable_count = get_useable_count_fromex_rule4(pcard, playerid, uplayer, zone, list);
else
......@@ -599,7 +599,7 @@ int32 field::get_spsummonable_count_fromex(card* pcard, uint8 playerid, uint8 up
pcard = temp_card;
pcard->current.location = LOCATION_EXTRA;
}
int spsummonable_count = 0;
int32 spsummonable_count = 0;
if(core.duel_rule >= 4)
spsummonable_count = get_spsummonable_count_fromex_rule4(pcard, playerid, uplayer, zone, list);
else
......@@ -2916,7 +2916,7 @@ int32 field::check_xyz_material(card* scard, int32 findex, int32 lv, int32 min,
effect_set eset;
filter_player_effect(playerid, EFFECT_MUST_BE_XMATERIAL, &eset);
card_set mcset;
for(int i = 0; i < eset.size(); ++i)
for(int32 i = 0; i < eset.size(); ++i)
mcset.insert(eset[i]->handler);
int32 mct = mcset.size();
if(mct > 0) {
......
......@@ -19,6 +19,7 @@
#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
class card;
struct card_data;
......@@ -588,7 +589,7 @@ public:
int32 select_position(uint16 step, uint8 playerid, uint32 code, uint8 positions);
int32 select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max);
int32 select_counter(uint16 step, uint8 playerid, uint16 countertype, uint16 count, uint8 s, uint8 o);
int32 select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int max);
int32 select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int32 max);
int32 sort_card(int16 step, uint8 playerid, uint8 is_chain);
int32 announce_race(int16 step, uint8 playerid, int32 count, int32 available);
int32 announce_attribute(int16 step, uint8 playerid, int32 count, int32 available);
......
......@@ -54,6 +54,7 @@ static const struct luaL_Reg cardlib[] = {
{ "GetMutualLinkedGroupCount", scriptlib::card_get_mutual_linked_group_count },
{ "GetMutualLinkedZone", scriptlib::card_get_mutual_linked_zone },
{ "IsLinkState", scriptlib::card_is_link_state },
{ "IsExtraLinkState", scriptlib::card_is_extra_link_state },
{ "GetColumnGroup", scriptlib::card_get_column_group },
{ "GetColumnGroupCount", scriptlib::card_get_column_group_count },
{ "GetColumnZone", scriptlib::card_get_column_zone },
......@@ -316,6 +317,8 @@ static const struct luaL_Reg effectlib[] = {
{ "IsActivated", scriptlib::effect_is_activated },
{ "GetActivateLocation", scriptlib::effect_get_activate_location },
{ "GetActivateSequence", scriptlib::effect_get_activate_sequence },
{ "CheckCountLimit", scriptlib::effect_check_count_limit },
{ "UseCountLimit", scriptlib::effect_use_count_limit },
{ NULL, NULL }
};
......@@ -354,6 +357,12 @@ static const struct luaL_Reg grouplib[] = {
{ "Equal", scriptlib::group_equal },
{ "IsContains", scriptlib::group_is_contains },
{ "SearchCard", scriptlib::group_search_card },
{ "GetBinClassCount", scriptlib::group_get_bin_class_count },
{ "__add", scriptlib::group_meta_add },
{ "__bor", scriptlib::group_meta_add },
{ "__sub", scriptlib::group_meta_sub },
{ "__band", scriptlib::group_meta_band },
{ "__bxor", scriptlib::group_meta_bxor },
{ NULL, NULL }
};
......
......@@ -413,6 +413,13 @@ int32 scriptlib::card_is_link_state(lua_State *L) {
lua_pushboolean(L, pcard->is_link_state());
return 1;
}
int32 scriptlib::card_is_extra_link_state(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
lua_pushboolean(L, pcard->is_extra_link_state());
return 1;
}
int32 scriptlib::card_get_column_group(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
......
......@@ -1648,8 +1648,10 @@ int32 scriptlib::duel_get_location_count(lua_State *L) {
uint32 zone = 0xff;
if(lua_gettop(L) >= 5)
zone = lua_tointeger(L, 5);
lua_pushinteger(L, pduel->game_field->get_useable_count(NULL, playerid, location, uplayer, reason, zone));
return 1;
uint32 list = 0;
lua_pushinteger(L, pduel->game_field->get_useable_count(NULL, playerid, location, uplayer, reason, zone, &list));
lua_pushinteger(L, list);
return 2;
}
int32 scriptlib::duel_get_mzone_count(lua_State *L) {
check_param_count(L, 1);
......@@ -1695,14 +1697,16 @@ int32 scriptlib::duel_get_mzone_count(lua_State *L) {
reason = lua_tointeger(L, 4);
if(lua_gettop(L) >= 5)
zone = lua_tointeger(L, 5);
lua_pushinteger(L, pduel->game_field->get_useable_count(NULL, playerid, LOCATION_MZONE, uplayer, reason, zone));
uint32 list = 0;
lua_pushinteger(L, pduel->game_field->get_useable_count(NULL, playerid, LOCATION_MZONE, uplayer, reason, zone, &list));
lua_pushinteger(L, list);
if(swapped) {
pduel->game_field->player[0].used_location = used_location[0];
pduel->game_field->player[1].used_location = used_location[1];
pduel->game_field->player[0].list_mzone.swap(list_mzone[0]);
pduel->game_field->player[1].list_mzone.swap(list_mzone[1]);
}
return 1;
return 2;
}
int32 scriptlib::duel_get_location_count_fromex(lua_State *L) {
check_param_count(L, 1);
......@@ -1750,14 +1754,16 @@ int32 scriptlib::duel_get_location_count_fromex(lua_State *L) {
uint32 zone = 0xff;
if(lua_gettop(L) >= 5)
zone = lua_tointeger(L, 5);
lua_pushinteger(L, pduel->game_field->get_useable_count_fromex(scard, playerid, uplayer, zone));
uint32 list = 0;
lua_pushinteger(L, pduel->game_field->get_useable_count_fromex(scard, playerid, uplayer, zone, &list));
lua_pushinteger(L, list);
if(swapped) {
pduel->game_field->player[0].used_location = used_location[0];
pduel->game_field->player[1].used_location = used_location[1];
pduel->game_field->player[0].list_mzone.swap(list_mzone[0]);
pduel->game_field->player[1].list_mzone.swap(list_mzone[1]);
}
return 1;
return 2;
}
int32 scriptlib::duel_get_usable_mzone_count(lua_State *L) {
check_param_count(L, 1);
......
......@@ -504,9 +504,13 @@ int32 scriptlib::effect_is_activatable(lua_State *L) {
uint32 playerid = lua_tointeger(L, 2);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 neglect_loc = 0;
if(lua_gettop(L) > 2)
uint32 neglect_target = 0;
if(lua_gettop(L) > 2) {
neglect_loc = lua_toboolean(L, 3);
lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event, 0, 0, 0, neglect_loc));
if (lua_gettop(L) > 3)
neglect_target = lua_toboolean(L, 4);
}
lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event, 0, 0, neglect_target, neglect_loc));
return 1;
}
int32 scriptlib::effect_is_activated(lua_State * L) {
......@@ -530,3 +534,31 @@ int32 scriptlib::effect_get_activate_sequence(lua_State *L) {
lua_pushinteger(L, peffect->active_sequence);
return 1;
}
int32 scriptlib::effect_check_count_limit(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = lua_tointeger(L, 2);
lua_pushboolean(L, peffect->check_count_limit(p));
return 1;
}
int32 scriptlib::effect_use_count_limit(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = lua_tointeger(L, 2);
uint32 count = 1;
uint32 oath_only = 0;
uint32 code = peffect->count_code;
if(lua_gettop(L) > 2) {
count = lua_tointeger(L, 3);
if (lua_gettop(L) > 3)
oath_only = lua_toboolean(L, 4);
}
if (!oath_only || code & EFFECT_COUNT_CODE_OATH)
while(count) {
peffect->dec_count(p);
count--;
}
return 0;
}
......@@ -632,3 +632,139 @@ int32 scriptlib::group_search_card(lua_State *L) {
}
return 0;
}
int32 scriptlib::group_get_bin_class_count(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2;
int32 er = 0;
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
er |= pduel->lua->get_operation_value(*cit, 2, extraargs);
}
int32 ans = 0;
while(er) {
er &= er - 1;
ans++;
}
lua_pushinteger(L, ans);
return 1;
}
int32 scriptlib::group_meta_add(lua_State* L) {
check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
if(!check_param(L, PARAM_TYPE_CARD, 2, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1);
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 1);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
pgroup->container.insert(*cit);
}
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 2);
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 2);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
pgroup->container.insert(*cit);
}
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_sub(lua_State* L) {
check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
if(!check_param(L, PARAM_TYPE_CARD, 2, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1);
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 1);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
pgroup->container.insert(*cit);
}
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 2);
pgroup->container.erase(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 2);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
pgroup->container.erase(*cit);
}
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_band(lua_State* L) {
check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
if(!check_param(L, PARAM_TYPE_CARD, 2, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
field::card_set check_set;
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1);
check_set.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 1);
check_set = cgroup->container;
}
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 2);
if(check_set.find(ccard) != check_set.end())
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 2);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
if(check_set.find(*cit) != check_set.end())
pgroup->container.insert(*cit);
}
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_bxor(lua_State* L) {
check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
if(!check_param(L, PARAM_TYPE_CARD, 2, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1);
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 1);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit)
pgroup->container.insert(*cit);
}
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 2);
if(pgroup->container.find(ccard) != pgroup->container.end())
pgroup->container.erase(ccard);
else
pgroup->container.insert(ccard);
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* cgroup = *(group**) lua_touserdata(L, 2);
for(auto cit = cgroup->container.begin(); cit != cgroup->container.end(); ++cit) {
if(pgroup->container.find(*cit) != pgroup->container.end())
pgroup->container.erase(*cit);
else
pgroup->container.insert(*cit);
}
}
interpreter::group2value(L, pgroup);
return 1;
}
......@@ -56,6 +56,7 @@ public:
static int32 card_get_mutual_linked_group_count(lua_State *L);
static int32 card_get_mutual_linked_zone(lua_State *L);
static int32 card_is_link_state(lua_State *L);
static int32 card_is_extra_link_state(lua_State *L);
static int32 card_get_column_group(lua_State *L);
static int32 card_get_column_group_count(lua_State *L);
static int32 card_get_column_zone(lua_State *L);
......@@ -316,6 +317,8 @@ public:
static int32 effect_is_activated(lua_State *L);
static int32 effect_get_activate_location(lua_State *L);
static int32 effect_get_activate_sequence(lua_State *L);
static int32 effect_check_count_limit(lua_State *L);
static int32 effect_use_count_limit(lua_State *L);
//Group functions
static int32 group_new(lua_State *L);
......@@ -351,6 +354,7 @@ public:
static int32 group_equal(lua_State *L);
static int32 group_is_contains(lua_State *L);
static int32 group_search_card(lua_State *L);
static int32 group_get_bin_class_count(lua_State *L);
//Duel functions
static int32 duel_enable_global_flag(lua_State *L);
......@@ -566,6 +570,13 @@ public:
static int32 duel_swap_deck_and_grave(lua_State *L);
static int32 duel_majestic_copy(lua_State *L);
//group metamethods
//__len is in the group lib, which is same as group_get_count
static int32 group_meta_add(lua_State *L);
static int32 group_meta_sub(lua_State *L);
static int32 group_meta_band(lua_State *L);
static int32 group_meta_bxor(lua_State *L);
//preload
static int32 debug_message(lua_State *L);
static int32 debug_add_card(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