Commit f757e38c authored by salix5's avatar salix5 Committed by GitHub

Update spell counter (#367)

parent 50680705
...@@ -2181,30 +2181,21 @@ int32 card::remove_counter(uint16 countertype, uint16 count) { ...@@ -2181,30 +2181,21 @@ int32 card::remove_counter(uint16 countertype, uint16 count) {
pduel->write_buffer16(count); pduel->write_buffer16(count);
return TRUE; return TRUE;
} }
// return: the player can put a counter on this or not
int32 card::is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc) { int32 card::is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc) {
effect_set eset; effect_set eset;
if(count > 0) { if (!pduel->game_field->is_player_can_place_counter(playerid, this, countertype, count))
if(!pduel->game_field->is_player_can_place_counter(playerid, this, countertype, count))
return FALSE; return FALSE;
if(!loc && (!(current.location & LOCATION_ONFIELD) || !is_position(POS_FACEUP))) if (!loc && (!(current.location & LOCATION_ONFIELD) || !is_position(POS_FACEUP)))
return FALSE; return FALSE;
}
uint32 check = countertype & COUNTER_WITHOUT_PERMIT; uint32 check = countertype & COUNTER_WITHOUT_PERMIT;
if(!check) { if(!check) {
filter_effect(EFFECT_COUNTER_PERMIT + (countertype & 0xffff), &eset); filter_effect(EFFECT_COUNTER_PERMIT + (countertype & 0xffff), &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
uint32 prange = eset[i]->get_value(); uint32 prange = eset[i]->range;
if(loc) if(loc)
check = loc & prange; check = loc & prange;
else if(current.location & LOCATION_ONFIELD) { else
uint32 filter = TRUE;
if(eset[i]->target) {
pduel->lua->add_param(eset[i], PARAM_TYPE_EFFECT);
pduel->lua->add_param(this, PARAM_TYPE_CARD);
filter = pduel->lua->check_condition(eset[i]->target, 2);
}
check = current.is_location(prange) && is_position(POS_FACEUP) && filter;
} else
check = TRUE; check = TRUE;
if(check) if(check)
break; break;
...@@ -2226,6 +2217,27 @@ int32 card::is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, ...@@ -2226,6 +2217,27 @@ int32 card::is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count,
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
// return: this have a EFFECT_COUNTER_PERMIT of countertype or not
int32 card::is_can_have_counter(uint16 countertype) {
effect_set eset;
if (countertype & COUNTER_WITHOUT_PERMIT)
return FALSE;
else {
filter_self_effect(EFFECT_COUNTER_PERMIT + (countertype & 0xffff), &eset);
if (current.is_location(LOCATION_ONFIELD)) {
for (int32 i = 0; i < eset.size(); ++i) {
if (eset[i]->is_single_ready())
return TRUE;
}
return FALSE;
}
else if (eset.size())
return TRUE;
else
return FALSE;
}
return FALSE;
}
int32 card::get_counter(uint16 countertype) { int32 card::get_counter(uint16 countertype) {
auto cmit = counters.find(countertype); auto cmit = counters.find(countertype);
if(cmit == counters.end()) if(cmit == counters.end())
...@@ -2378,6 +2390,25 @@ void card::filter_single_continuous_effect(int32 code, effect_set* eset, uint8 s ...@@ -2378,6 +2390,25 @@ void card::filter_single_continuous_effect(int32 code, effect_set* eset, uint8 s
if(sort) if(sort)
eset->sort(); eset->sort();
} }
void card::filter_self_effect(int32 code, effect_set* eset, uint8 sort) {
auto rg = single_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if(peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE))
eset->add_item(rg.first->second);
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
eset->add_item(peffect);
}
}
if (sort)
eset->sort();
}
// refresh this->immune_effect // refresh this->immune_effect
void card::filter_immune_effect() { void card::filter_immune_effect() {
immune_effect.clear(); immune_effect.clear();
......
...@@ -281,6 +281,7 @@ public: ...@@ -281,6 +281,7 @@ public:
int32 add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly); int32 add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly);
int32 remove_counter(uint16 countertype, uint16 count); int32 remove_counter(uint16 countertype, uint16 count);
int32 is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc); int32 is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc);
int32 is_can_have_counter(uint16 countertype);
int32 get_counter(uint16 countertype); int32 get_counter(uint16 countertype);
void set_material(card_set* materials); void set_material(card_set* materials);
void add_card_target(card* pcard); void add_card_target(card* pcard);
...@@ -290,6 +291,7 @@ public: ...@@ -290,6 +291,7 @@ public:
void filter_effect(int32 code, effect_set* eset, uint8 sort = TRUE); void filter_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_single_effect(int32 code, effect_set* eset, uint8 sort = TRUE); void filter_single_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort = TRUE); void filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_self_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_immune_effect(); void filter_immune_effect();
void filter_disable_related_cards(); void filter_disable_related_cards();
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
......
...@@ -63,10 +63,9 @@ int32 effect::is_self_destroy_related() { ...@@ -63,10 +63,9 @@ int32 effect::is_self_destroy_related() {
return FALSE; return FALSE;
} }
int32 effect::is_can_be_forbidden() { int32 effect::is_can_be_forbidden() {
uint32 ctr = code & 0xf0000;
if (is_flag(EFFECT_FLAG_CANNOT_DISABLE) && !is_flag(EFFECT_FLAG_CANNOT_NEGATE)) if (is_flag(EFFECT_FLAG_CANNOT_DISABLE) && !is_flag(EFFECT_FLAG_CANNOT_NEGATE))
return FALSE; return FALSE;
if (code == EFFECT_CHANGE_CODE || ctr == EFFECT_COUNTER_PERMIT || ctr == EFFECT_COUNTER_LIMIT) if (code == EFFECT_CHANGE_CODE)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
...@@ -150,6 +149,31 @@ int32 effect::is_available() { ...@@ -150,6 +149,31 @@ int32 effect::is_available() {
status &= ~EFFECT_STATUS_AVAILABLE; status &= ~EFFECT_STATUS_AVAILABLE;
return res; return res;
} }
// check if a effect is EFFECT_TYPE_SINGLE and is ready
// check: range, enabled, condition
int32 effect::is_single_ready() {
if(type & EFFECT_TYPE_ACTIONS)
return FALSE;
if((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
card* phandler = get_handler();
card* powner = get_owner();
if(phandler->current.controler == PLAYER_NONE)
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && (phandler->current.location & LOCATION_ONFIELD) && !phandler->is_position(POS_FACEUP))
return FALSE;
}
else
return FALSE;
if(!condition)
return TRUE;
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
int32 res = pduel->lua->check_condition(condition, 1);
return res;
}
// reset_count: count of effect reset // reset_count: count of effect reset
// count_limit: left count of activation // count_limit: left count of activation
// count_limit_max: max count of activation // count_limit_max: max count of activation
......
...@@ -69,6 +69,7 @@ public: ...@@ -69,6 +69,7 @@ public:
int32 is_self_destroy_related(); int32 is_self_destroy_related();
int32 is_can_be_forbidden(); int32 is_can_be_forbidden();
int32 is_available(); int32 is_available();
int32 is_single_ready();
int32 check_count_limit(uint8 playerid); int32 check_count_limit(uint8 playerid);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE, int32 neglect_faceup = FALSE); int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE, int32 neglect_faceup = FALSE);
int32 is_action_check(uint8 playerid); int32 is_action_check(uint8 playerid);
......
...@@ -2754,9 +2754,10 @@ int32 scriptlib::card_enable_counter_permit(lua_State *L) { ...@@ -2754,9 +2754,10 @@ int32 scriptlib::card_enable_counter_permit(lua_State *L) {
peffect->owner = pcard; peffect->owner = pcard;
peffect->type = EFFECT_TYPE_SINGLE; peffect->type = EFFECT_TYPE_SINGLE;
peffect->code = EFFECT_COUNTER_PERMIT | countertype; peffect->code = EFFECT_COUNTER_PERMIT | countertype;
peffect->value = prange; peffect->flag[0] = EFFECT_FLAG_SINGLE_RANGE;
peffect->range = prange;
if(lua_gettop(L) > 3 && lua_isfunction(L, 4)) if(lua_gettop(L) > 3 && lua_isfunction(L, 4))
peffect->target = interpreter::get_function_handle(L, 4); peffect->condition = interpreter::get_function_handle(L, 4);
pcard->add_effect(peffect); pcard->add_effect(peffect);
return 0; return 0;
} }
...@@ -2788,13 +2789,11 @@ int32 scriptlib::card_is_can_turn_set(lua_State *L) { ...@@ -2788,13 +2789,11 @@ int32 scriptlib::card_is_can_turn_set(lua_State *L) {
return 1; return 1;
} }
int32 scriptlib::card_is_can_add_counter(lua_State *L) { int32 scriptlib::card_is_can_add_counter(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 3);
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 countertype = (uint32)lua_tointeger(L, 2); uint32 countertype = (uint32)lua_tointeger(L, 2);
uint32 count = 0; uint32 count = (uint32)lua_tointeger(L, 3);
if(lua_gettop(L) > 2)
count = (uint32)lua_tointeger(L, 3);
uint8 singly = FALSE; uint8 singly = FALSE;
if(lua_gettop(L) > 3) if(lua_gettop(L) > 3)
singly = lua_toboolean(L, 4); singly = lua_toboolean(L, 4);
...@@ -2817,6 +2816,14 @@ int32 scriptlib::card_is_can_remove_counter(lua_State *L) { ...@@ -2817,6 +2816,14 @@ int32 scriptlib::card_is_can_remove_counter(lua_State *L) {
lua_pushboolean(L, pcard->pduel->game_field->is_player_can_remove_counter(playerid, pcard, 0, 0, countertype, count, reason)); lua_pushboolean(L, pcard->pduel->game_field->is_player_can_remove_counter(playerid, pcard, 0, 0, countertype, count, reason));
return 1; return 1;
} }
int32 scriptlib::card_is_can_have_counter(lua_State* L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**)lua_touserdata(L, 1);
uint32 countertype = (uint32)lua_tointeger(L, 2);
lua_pushboolean(L, pcard->is_can_have_counter(countertype));
return 1;
}
int32 scriptlib::card_is_can_overlay(lua_State *L) { int32 scriptlib::card_is_can_overlay(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
...@@ -3425,6 +3432,7 @@ static const struct luaL_Reg cardlib[] = { ...@@ -3425,6 +3432,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsCanTurnSet", scriptlib::card_is_can_turn_set }, { "IsCanTurnSet", scriptlib::card_is_can_turn_set },
{ "IsCanAddCounter", scriptlib::card_is_can_add_counter }, { "IsCanAddCounter", scriptlib::card_is_can_add_counter },
{ "IsCanRemoveCounter", scriptlib::card_is_can_remove_counter }, { "IsCanRemoveCounter", scriptlib::card_is_can_remove_counter },
{ "IsCanHaveCounter", scriptlib::card_is_can_have_counter },
{ "IsCanOverlay", scriptlib::card_is_can_overlay }, { "IsCanOverlay", scriptlib::card_is_can_overlay },
{ "IsCanBeFusionMaterial", scriptlib::card_is_can_be_fusion_material }, { "IsCanBeFusionMaterial", scriptlib::card_is_can_be_fusion_material },
{ "IsCanBeSynchroMaterial", scriptlib::card_is_can_be_synchro_material }, { "IsCanBeSynchroMaterial", scriptlib::card_is_can_be_synchro_material },
......
...@@ -252,6 +252,7 @@ public: ...@@ -252,6 +252,7 @@ public:
static int32 card_is_can_turn_set(lua_State *L); static int32 card_is_can_turn_set(lua_State *L);
static int32 card_is_can_add_counter(lua_State *L); static int32 card_is_can_add_counter(lua_State *L);
static int32 card_is_can_remove_counter(lua_State *L); static int32 card_is_can_remove_counter(lua_State *L);
static int32 card_is_can_have_counter(lua_State* L);
static int32 card_is_can_overlay(lua_State *L); static int32 card_is_can_overlay(lua_State *L);
static int32 card_is_can_be_fusion_material(lua_State *L); static int32 card_is_can_be_fusion_material(lua_State *L);
static int32 card_is_can_be_synchro_material(lua_State *L); static int32 card_is_can_be_synchro_material(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