Commit a856a5dd authored by mercury233's avatar mercury233
parents 4fcbb8cb b1093e82
...@@ -1371,51 +1371,39 @@ int32 card::is_link_state() { ...@@ -1371,51 +1371,39 @@ int32 card::is_link_state() {
int32 card::is_extra_link_state() { int32 card::is_extra_link_state() {
if(current.location != LOCATION_MZONE) if(current.location != LOCATION_MZONE)
return FALSE; return FALSE;
card_set cset; uint32 checked = 1u << current.sequence;
card_set excset; uint32 linked_zone = get_mutual_linked_zone();
for(int32 p = 0; p < 2; ++p) { const auto& list_mzone0 = pduel->game_field->player[current.controler].list_mzone;
card* pcard1 = pduel->game_field->player[p].list_mzone[5]; const auto& list_mzone1 = pduel->game_field->player[1 - current.controler].list_mzone;
if(pcard1) while(true) {
excset.insert(pcard1); if(((linked_zone >> 5) | (linked_zone >> (16 + 6))) & ((linked_zone >> 6) | (linked_zone >> (16 + 5))) & 1)
card* pcard2 = pduel->game_field->player[p].list_mzone[6];
if(pcard2)
excset.insert(pcard2);
card* pcard3 = pduel->game_field->player[1 - p].list_mzone[5];
if(pcard3)
excset.insert(pcard3);
card* pcard4 = pduel->game_field->player[1 - p].list_mzone[6];
if(pcard4)
excset.insert(pcard4);
}
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) != excset->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 TRUE;
int32 checking = (int32)(linked_zone & ~checked);
if(!checking)
return FALSE;
int32 rightmost = checking & (-checking);
checked |= (uint32)rightmost;
if(rightmost < 0x10000) {
for(int32 i = 0; i < 7; ++i) {
if(rightmost & 1) {
card* pcard = list_mzone0[i];
linked_zone |= pcard->get_mutual_linked_zone();
break;
}
rightmost >>= 1;
}
} else {
rightmost >>= 16;
for(int32 i = 0; i < 7; ++i) {
if(rightmost & 1) {
card* pcard = list_mzone1[i];
uint32 zone = pcard->get_mutual_linked_zone();
linked_zone |= (zone << 16) | (zone >> 16);
break;
}
rightmost >>= 1;
}
}
} }
return FALSE; return FALSE;
} }
...@@ -3320,12 +3308,24 @@ int32 card::is_removeable(uint8 playerid) { ...@@ -3320,12 +3308,24 @@ int32 card::is_removeable(uint8 playerid) {
return TRUE; return TRUE;
} }
int32 card::is_removeable_as_cost(uint8 playerid) { int32 card::is_removeable_as_cost(uint8 playerid) {
uint32 redirect = 0;
uint32 dest = LOCATION_REMOVED;
if(current.location == LOCATION_REMOVED) if(current.location == LOCATION_REMOVED)
return FALSE; return FALSE;
if(is_affected_by_effect(EFFECT_CANNOT_USE_AS_COST)) if(is_affected_by_effect(EFFECT_CANNOT_USE_AS_COST))
return FALSE; return FALSE;
if(!is_removeable(playerid)) if(!is_removeable(playerid))
return FALSE; return FALSE;
auto op_param = sendto_param;
sendto_param.location = dest;
if(current.location & LOCATION_ONFIELD)
redirect = leave_field_redirect(REASON_COST) & 0xffff;
if(redirect) dest = redirect;
redirect = destination_redirect(dest, REASON_COST) & 0xffff;
if(redirect) dest = redirect;
sendto_param = op_param;
if(dest != LOCATION_REMOVED)
return FALSE;
return TRUE; return TRUE;
} }
int32 card::is_releasable_by_summon(uint8 playerid, card *pcard) { int32 card::is_releasable_by_summon(uint8 playerid, card *pcard) {
......
...@@ -228,7 +228,6 @@ public: ...@@ -228,7 +228,6 @@ public:
void get_mutual_linked_cards(card_set * cset); void get_mutual_linked_cards(card_set * cset);
int32 is_link_state(); int32 is_link_state();
int32 is_extra_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); int32 is_position(int32 pos);
void set_status(uint32 status, int32 enabled); void set_status(uint32 status, int32 enabled);
int32 get_status(uint32 status); int32 get_status(uint32 status);
......
...@@ -111,6 +111,8 @@ static const struct luaL_Reg cardlib[] = { ...@@ -111,6 +111,8 @@ static const struct luaL_Reg cardlib[] = {
{ "IsLevel", scriptlib::card_is_level }, { "IsLevel", scriptlib::card_is_level },
{ "IsRank", scriptlib::card_is_rank }, { "IsRank", scriptlib::card_is_rank },
{ "IsLink", scriptlib::card_is_link }, { "IsLink", scriptlib::card_is_link },
{ "IsAttack", scriptlib::card_is_attack },
{ "IsDefense", scriptlib::card_is_defense },
{ "IsRace", scriptlib::card_is_race }, { "IsRace", scriptlib::card_is_race },
{ "IsLinkRace", scriptlib::card_is_link_race }, { "IsLinkRace", scriptlib::card_is_link_race },
{ "IsAttribute", scriptlib::card_is_attribute }, { "IsAttribute", scriptlib::card_is_attribute },
......
...@@ -893,33 +893,103 @@ int32 scriptlib::card_is_level(lua_State *L) { ...@@ -893,33 +893,103 @@ int32 scriptlib::card_is_level(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
uint32 tlevel = lua_tointeger(L, 2); uint32 level = pcard->get_level();
if(pcard->get_level() == tlevel) uint32 count = lua_gettop(L) - 1;
lua_pushboolean(L, 1); uint32 result = FALSE;
else for(uint32 i = 0; i < count; ++i) {
lua_pushboolean(L, 0); if(lua_isnil(L, i + 2))
continue;
uint32 tlevel = lua_tointeger(L, i + 2);
if(level == tlevel) {
result = TRUE;
break;
}
}
lua_pushboolean(L, result);
return 1; return 1;
} }
int32 scriptlib::card_is_rank(lua_State *L) { int32 scriptlib::card_is_rank(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
uint32 trank = lua_tointeger(L, 2); uint32 rank = pcard->get_rank();
if(pcard->get_rank() == trank) uint32 count = lua_gettop(L) - 1;
lua_pushboolean(L, 1); uint32 result = FALSE;
else for(uint32 i = 0; i < count; ++i) {
lua_pushboolean(L, 0); if(lua_isnil(L, i + 2))
continue;
uint32 trank = lua_tointeger(L, i + 2);
if(rank == trank) {
result = TRUE;
break;
}
}
lua_pushboolean(L, result);
return 1; return 1;
} }
int32 scriptlib::card_is_link(lua_State *L) { int32 scriptlib::card_is_link(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
uint32 tlink = lua_tointeger(L, 2); uint32 link = pcard->get_link();
if(pcard->get_link() == tlink) uint32 count = lua_gettop(L) - 1;
lua_pushboolean(L, 1); uint32 result = FALSE;
else for(uint32 i = 0; i < count; ++i) {
if(lua_isnil(L, i + 2))
continue;
uint32 tlink = lua_tointeger(L, i + 2);
if(link == tlink) {
result = TRUE;
break;
}
}
lua_pushboolean(L, result);
return 1;
}
int32 scriptlib::card_is_attack(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
if(!(pcard->data.type & TYPE_MONSTER) && !(pcard->get_type() & TYPE_MONSTER) && !(pcard->current.location & LOCATION_MZONE))
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
else {
uint32 atk = pcard->get_attack();
uint32 count = lua_gettop(L) - 1;
uint32 result = FALSE;
for(uint32 i = 0; i < count; ++i) {
if(lua_isnil(L, i + 2))
continue;
uint32 tatk = lua_tointeger(L, i + 2);
if(atk == tatk) {
result = TRUE;
break;
}
}
lua_pushboolean(L, result);
}
return 1;
}
int32 scriptlib::card_is_defense(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
if((pcard->data.type & TYPE_LINK) || (!(pcard->data.type & TYPE_MONSTER) && !(pcard->get_type() & TYPE_MONSTER) && !(pcard->current.location & LOCATION_MZONE)))
lua_pushboolean(L, 0);
else {
uint32 def = pcard->get_defense();
uint32 count = lua_gettop(L) - 1;
uint32 result = FALSE;
for(uint32 i = 0; i < count; ++i) {
if(lua_isnil(L, i + 2))
continue;
uint32 tdef = lua_tointeger(L, i + 2);
if(def == tdef) {
result = TRUE;
break;
}
}
lua_pushboolean(L, result);
}
return 1; return 1;
} }
int32 scriptlib::card_is_race(lua_State *L) { int32 scriptlib::card_is_race(lua_State *L) {
......
...@@ -113,6 +113,8 @@ public: ...@@ -113,6 +113,8 @@ public:
static int32 card_is_level(lua_State *L); static int32 card_is_level(lua_State *L);
static int32 card_is_rank(lua_State *L); static int32 card_is_rank(lua_State *L);
static int32 card_is_link(lua_State *L); static int32 card_is_link(lua_State *L);
static int32 card_is_attack(lua_State *L);
static int32 card_is_defense(lua_State *L);
static int32 card_is_race(lua_State *L); static int32 card_is_race(lua_State *L);
static int32 card_is_link_race(lua_State *L); static int32 card_is_link_race(lua_State *L);
static int32 card_is_attribute(lua_State *L); static int32 card_is_attribute(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