Commit 101ed0bf authored by salix5's avatar salix5 Committed by GitHub

add Card.IsEffectProperty (#648)

* add EFFECT_FLAG_COPY

* card: add filter_effect_container()

avoid unnecessary copy

* card: add find_effect_container()

* card: add find_effect_with_target()

* use template

* update effect_set

* remove unused include

* add Card.IsEffectCode, IsEffectCategory

* rename to Card.IsEffectProperty

* card: update is_effect_property

* effect: add is_monster_effect

* fix exclude condition
parent 59593ffc
......@@ -1770,8 +1770,8 @@ int32 card::add_effect(effect* peffect) {
if (peffect->type & EFFECT_TYPES_TRIGGER_LIKE && is_continuous_event(peffect->code))
return 0;
// the trigger effect in phase is "once per turn" by default
if (peffect->get_code_type() == CODE_PHASE && peffect->code & (PHASE_DRAW | PHASE_STANDBY | PHASE_END) && peffect->type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F)
&& !peffect->is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
if (peffect->get_code_type() == CODE_PHASE && peffect->code & (PHASE_DRAW | PHASE_STANDBY | PHASE_END)
&& peffect->type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F) && !peffect->is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
peffect->flag[0] |= EFFECT_FLAG_COUNT_LIMIT;
peffect->count_limit = 1;
peffect->count_limit_max = 1;
......@@ -1874,8 +1874,10 @@ int32 card::add_effect(effect* peffect) {
return 0;
peffect->id = pduel->game_field->infos.field_id++;
peffect->card_type = data.type;
if(get_status(STATUS_INITIALIZING))
if (get_status(STATUS_INITIALIZING))
peffect->flag[0] |= EFFECT_FLAG_INITIAL;
else if (get_status(STATUS_COPYING_EFFECT))
peffect->flag[0] |= EFFECT_FLAG_COPY;
if (get_status(STATUS_COPYING_EFFECT)) {
peffect->copy_id = pduel->game_field->infos.copy_id;
peffect->reset_flag |= pduel->game_field->core.copy_reset;
......@@ -1884,6 +1886,10 @@ int32 card::add_effect(effect* peffect) {
effect* reason_effect = pduel->game_field->core.reason_effect;
indexer.emplace(peffect, eit);
peffect->handler = this;
if (peffect->is_flag(EFFECT_FLAG_INITIAL))
initial_effect.insert(peffect);
else if (peffect->is_flag(EFFECT_FLAG_COPY))
owning_effect.insert(peffect);
if((peffect->type & EFFECT_TYPE_FIELD)) {
if(peffect->in_range(this) || current.controler != PLAYER_NONE && peffect->is_hand_trigger())
pduel->game_field->add_effect(peffect);
......@@ -1961,6 +1967,10 @@ effect_indexer::iterator card::remove_effect(effect* peffect) {
}
}
auto ret = indexer.erase(index);
if (peffect->is_flag(EFFECT_FLAG_INITIAL))
initial_effect.erase(peffect);
else if (peffect->is_flag(EFFECT_FLAG_COPY))
owning_effect.erase(peffect);
if(peffect->is_flag(EFFECT_FLAG_OATH))
pduel->game_field->effects.oath.erase(peffect);
if(peffect->reset_flag & RESET_PHASE)
......@@ -2001,6 +2011,8 @@ int32 card::copy_effect(uint32 code, uint32 reset, int32 count) {
::read_card(code, &cdata);
if(cdata.type & TYPE_NORMAL)
return -1;
if (!reset)
reset = RESETS_STANDARD;
set_status(STATUS_COPYING_EFFECT, TRUE);
auto cr = pduel->game_field->core.copy_reset;
auto crc = pduel->game_field->core.copy_reset_count;
......@@ -2037,6 +2049,8 @@ int32 card::replace_effect(uint32 code, uint32 reset, int32 count) {
::read_card(code, &cdata);
if(cdata.type & TYPE_NORMAL)
return -1;
if (!reset)
reset = RESETS_STANDARD;
if(is_status(STATUS_EFFECT_REPLACED))
set_status(STATUS_EFFECT_REPLACED, FALSE);
for(auto it = indexer.begin(); it != indexer.end();) {
......@@ -2572,136 +2586,91 @@ void card::set_special_summon_status(effect* peffect) {
spsummon.reason_player = cait->triggering_player;
}
}
void card::filter_effect(int32 code, effect_set* eset, uint8 sort) {
effect* peffect;
auto rg = single_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || is_affect_by_effect(peffect)))
eset->add_item(peffect);
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->is_available() && is_affect_by_effect(peffect))
eset->add_item(peffect);
}
}
for(auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for(; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if(peffect->is_available() && peffect->is_target(this) && is_affect_by_effect(peffect))
eset->add_item(peffect);
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
if (peffect->is_available() && is_affect_by_effect(peffect))
eset->add_item(peffect);
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (!peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_available()
&& peffect->is_target(this) && is_affect_by_effect(peffect))
eset->add_item(peffect);
}
auto default_single_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || c->is_affect_by_effect(peffect));
};
auto default_equip_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_available() && c->is_affect_by_effect(peffect);
};
auto default_target_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_available() && peffect->is_target(c) && c->is_affect_by_effect(peffect);
};
auto default_xmaterial_filter = [](card* c, effect* peffect) -> bool {
return !(peffect->type & EFFECT_TYPE_FIELD) && peffect->is_available() && c->is_affect_by_effect(peffect);
};
auto default_aura_filter = [](card* c, effect* peffect) -> bool {
return !peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_available() && peffect->is_target(c) && c->is_affect_by_effect(peffect);
};
auto accept_filter = [](card* c, effect* peffect) -> bool {
return true;
};
template<typename T>
void card::filter_effect_container(const effect_container& container, uint32 code, effect_filter f, T& eset) {
auto rg = container.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
if (f(this, it->second))
eset.add_item(it->second);
}
}
void card::filter_effect(uint32 code, effect_set* eset, uint8 sort) {
filter_effect_container(single_effect, code, default_single_filter, *eset);
for (const auto& pcard : equiping_cards)
filter_effect_container(pcard->equip_effect, code, default_equip_filter, *eset);
for (const auto& pcard : effect_target_owner)
filter_effect_container(pcard->target_effect, code, default_target_filter, *eset);
for (const auto& pcard : xyz_materials)
filter_effect_container(pcard->xmaterial_effect, code, default_xmaterial_filter, *eset);
filter_effect_container(pduel->game_field->effects.aura_effect, code, default_aura_filter, *eset);
if(sort)
eset->sort();
}
void card::filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort) {
auto rg = single_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first)
eset->add_item(rg.first->second);
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first)
eset->add_item(rg.first->second);
}
for(auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for(; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if(peffect->is_target(pcard))
eset->add_item(peffect);
}
}
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);
}
}
void card::filter_single_continuous_effect(uint32 code, effect_set* eset, uint8 sort) {
filter_effect_container(single_effect, code, accept_filter, *eset);
for (const auto& pcard : equiping_cards)
filter_effect_container(pcard->equip_effect, code, accept_filter, *eset);
auto target_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_target(c);
};
for (const auto& pcard : effect_target_owner)
filter_effect_container(pcard->target_effect, code, target_filter, *eset);
auto xmaterial_filter = [](card* c, effect* peffect) -> bool {
return !(peffect->type & EFFECT_TYPE_FIELD);
};
for (const auto& pcard : xyz_materials)
filter_effect_container(pcard->xmaterial_effect, code, xmaterial_filter, *eset);
if(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);
}
}
void card::filter_self_effect(uint32 code, effect_set* eset, uint8 sort) {
auto single_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE);
};
filter_effect_container(single_effect, code, single_filter, *eset);
auto xmaterial_filter = [](card* c, effect* peffect) -> bool {
return !(peffect->type & EFFECT_TYPE_FIELD);
};
for (const auto& pcard : xyz_materials)
filter_effect_container(pcard->xmaterial_effect, code, xmaterial_filter, *eset);
if (sort)
eset->sort();
}
// refresh this->immune_effect
void card::filter_immune_effect() {
immune_effect.clear();
auto rg = single_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
immune_effect.add_item(peffect);
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
immune_effect.add_item(peffect);
}
}
for (auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if(peffect->is_target(this))
immune_effect.add_item(peffect);
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
immune_effect.add_item(peffect);
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if (peffect->is_target(this))
immune_effect.add_item(peffect);
}
filter_effect_container(single_effect, EFFECT_IMMUNE_EFFECT, accept_filter, immune_effect);
for (const auto& pcard : equiping_cards)
filter_effect_container(pcard->equip_effect, EFFECT_IMMUNE_EFFECT, accept_filter, immune_effect);
auto target_filter = [](card* c, effect* peffect) -> bool {
return peffect->is_target(c);
};
for (const auto& pcard : effect_target_owner)
filter_effect_container(pcard->target_effect, EFFECT_IMMUNE_EFFECT, target_filter, immune_effect);
auto xmaterial_filter = [](card* c, effect* peffect) -> bool {
return !(peffect->type & EFFECT_TYPE_FIELD);
};
for (const auto& pcard : xyz_materials)
filter_effect_container(pcard->xmaterial_effect, EFFECT_IMMUNE_EFFECT, xmaterial_filter, immune_effect);
filter_effect_container(pduel->game_field->effects.aura_effect, EFFECT_IMMUNE_EFFECT, target_filter, immune_effect);
immune_effect.sort();
}
// for all disable-related peffect of this,
......@@ -2948,90 +2917,84 @@ void card::filter_spsummon_procedure_g(uint8 playerid, effect_set* peset) {
pduel->game_field->core.reason_player = op;
}
}
// find an effect with code which affects this
effect* card::is_affected_by_effect(int32 code) {
auto rg = single_effect.equal_range(code);
effect* card::find_effect(const effect_container& container, uint32 code, effect_filter f) {
auto rg = container.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || is_affect_by_effect(peffect)))
return peffect;
if (f(this, it->second))
return it->second;
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && is_affect_by_effect(peffect))
return peffect;
}
return nullptr;
}
effect* card::find_effect_with_target(const effect_container& container, uint32 code, effect_filter_target f, card* target) {
auto rg = container.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
if (f(this, it->second, target))
return it->second;
}
for (auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && peffect->is_target(this) && is_affect_by_effect(peffect))
return peffect;
}
return nullptr;
}
// find an effect with code which affects this
effect* card::is_affected_by_effect(uint32 code) {
effect* peffect = find_effect(single_effect, code, default_single_filter);
if (peffect)
return peffect;
for (const auto& pcard : equiping_cards) {
peffect = find_effect(pcard->equip_effect, code, default_equip_filter);
if (peffect)
return peffect;
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
if (peffect->is_available() && is_affect_by_effect(peffect))
return peffect;
}
for (const auto& pcard : effect_target_owner) {
peffect = find_effect(pcard->target_effect, code, default_target_filter);
if (peffect)
return peffect;
}
rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (!peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_target(this)
&& peffect->is_available() && is_affect_by_effect(peffect))
for (const auto& pcard : xyz_materials) {
peffect = find_effect(pcard->xmaterial_effect, code, default_xmaterial_filter);
if (peffect)
return peffect;
}
peffect = find_effect(pduel->game_field->effects.aura_effect, code, default_aura_filter);
if (peffect)
return peffect;
return nullptr;
}
effect* card::is_affected_by_effect(int32 code, card* target) {
auto rg = single_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || is_affect_by_effect(peffect))
&& peffect->get_value(target))
auto single_filter = [](card* c, effect* peffect, card* target) -> bool {
return default_single_filter(c, peffect) && peffect->get_value(target);
};
effect* peffect = find_effect_with_target(single_effect, code, single_filter, target);
if (peffect)
return peffect;
auto equip_filter = [](card* c, effect* peffect, card* target) -> bool {
return default_equip_filter(c, peffect) && peffect->get_value(target);
};
for (const auto& pcard : equiping_cards) {
peffect = find_effect_with_target(pcard->equip_effect, code, equip_filter, target);
if (peffect)
return peffect;
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
}
for (auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && peffect->is_target(this) && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
if (peffect->is_available() && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
auto target_filter = [](card* c, effect* peffect, card* target) -> bool {
return default_target_filter(c, peffect) && peffect->get_value(target);
};
for (const auto& pcard : effect_target_owner) {
peffect = find_effect_with_target(pcard->target_effect, code, target_filter, target);
if (peffect)
return peffect;
}
rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (!peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_available()
&& peffect->is_target(this) && is_affect_by_effect(peffect) && peffect->get_value(target))
auto xmaterial_filter = [](card* c, effect* peffect, card* target) -> bool {
return default_xmaterial_filter(c, peffect) && peffect->get_value(target);
};
for (const auto& pcard : xyz_materials) {
peffect = find_effect_with_target(pcard->xmaterial_effect, code, xmaterial_filter, target);
if (peffect)
return peffect;
}
auto aura_filter = [](card* c, effect* peffect, card* target) -> bool {
return default_aura_filter(c, peffect) && peffect->get_value(target);
};
peffect = find_effect_with_target(pduel->game_field->effects.aura_effect, code, aura_filter, target);
if (peffect)
return peffect;
return nullptr;
}
int32 card::fusion_check(group* fusion_m, card* cg, uint32 chkf, uint8 not_material) {
......@@ -4196,3 +4159,38 @@ int32 card::is_can_be_link_material(card* scard) {
return FALSE;
return TRUE;
}
/**
* @param filter Lua function filter(e)
*/
int32 card::is_original_effect_property(int32 filter) {
for (const auto& peffect : initial_effect) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
if (pduel->lua->check_condition(filter, 1))
return TRUE;
}
return FALSE;
}
/**
* @param filter Lua function filter(e)
*/
int32 card::is_effect_property(int32 filter) {
for (const auto& peffect : initial_effect) {
if (current.is_location(LOCATION_MZONE) && !peffect->is_monster_effect())
continue;
if (current.is_location(LOCATION_SZONE) && !peffect->in_range(this))
continue;
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
if(pduel->lua->check_condition(filter, 1))
return TRUE;
}
for (const auto& peffect : owning_effect) {
if (current.is_location(LOCATION_MZONE) && !peffect->is_monster_effect())
continue;
if (current.is_location(LOCATION_SZONE) && !peffect->in_range(this))
continue;
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
if (pduel->lua->check_condition(filter, 1))
return TRUE;
}
return FALSE;
}
......@@ -30,6 +30,9 @@ using effect_container = std::multimap<uint32, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using effect_collection = std::unordered_set<effect*>;
using effect_filter = bool(*)(card* self, effect* peffect);
using effect_filter_target = bool(*)(card* self, effect* peffect, card* target);
struct card_state {
uint32 code{ 0 };
uint32 code2{ 0 };
......@@ -210,6 +213,8 @@ public:
effect_indexer indexer;
effect_relation relate_effect;
effect_set_v immune_effect;
effect_collection initial_effect;
effect_collection owning_effect;
explicit card(duel* pd);
~card() = default;
......@@ -320,9 +325,11 @@ public:
void clear_card_target();
void set_special_summon_status(effect* peffect);
void filter_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);
template<typename T>
void filter_effect_container(const effect_container& container, uint32 code, effect_filter f, T& eset);
void filter_effect(uint32 code, effect_set* eset, uint8 sort = TRUE);
void filter_single_continuous_effect(uint32 code, effect_set* eset, uint8 sort = TRUE);
void filter_self_effect(uint32 code, effect_set* eset, uint8 sort = TRUE);
void filter_immune_effect();
void filter_disable_related_cards();
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
......@@ -331,7 +338,9 @@ public:
int32 check_set_procedure(effect* proc, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone);
void filter_spsummon_procedure(uint8 playerid, effect_set* eset, uint32 summon_type, material_info info = null_info);
void filter_spsummon_procedure_g(uint8 playerid, effect_set* eset);
effect* is_affected_by_effect(int32 code);
effect* find_effect(const effect_container& container, uint32 code, effect_filter f);
effect* find_effect_with_target(const effect_container& container, uint32 code, effect_filter_target f, card* target);
effect* is_affected_by_effect(uint32 code);
effect* is_affected_by_effect(int32 code, card* target);
int32 fusion_check(group* fusion_m, card* cg, uint32 chkf, uint8 not_material);
void fusion_select(uint8 playerid, group* fusion_m, card* cg, uint32 chkf, uint8 not_material);
......@@ -392,6 +401,8 @@ public:
int32 is_can_be_ritual_material(card* scard);
int32 is_can_be_xyz_material(card* scard);
int32 is_can_be_link_material(card* scard);
int32 is_original_effect_property(int32 filter);
int32 is_effect_property(int32 filter);
};
//Summon Type in summon_info
......
......@@ -622,6 +622,11 @@ int32 effect::is_hand_trigger() const {
int32 effect::is_initial_single() const {
return (type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && is_flag(EFFECT_FLAG_INITIAL);
}
int32 effect::is_monster_effect() const {
if (range & (LOCATION_SZONE | LOCATION_FZONE | LOCATION_PZONE))
return FALSE;
return TRUE;
}
//return: this can be reset by reset_level or not
//RESET_DISABLE is valid only when owner == handler
int32 effect::reset(uint32 reset_level, uint32 reset_type) {
......
......@@ -11,9 +11,7 @@
#include "common.h"
#include "field.h"
#include "effectset.h"
#include <stdlib.h>
#include <vector>
#include <map>
class card;
class duel;
......@@ -90,6 +88,7 @@ public:
int32 is_chainable(uint8 tp);
int32 is_hand_trigger() const;
int32 is_initial_single() const;
int32 is_monster_effect() const;
int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint8 playerid = PLAYER_NONE);
void recharge();
......@@ -156,6 +155,8 @@ public:
#define RESET_OVERLAY 0x04000000
#define RESET_MSCHANGE 0x08000000
constexpr uint32 RESETS_STANDARD = RESET_TOFIELD | RESET_LEAVE | RESET_TODECK | RESET_TOHAND | RESET_TEMP_REMOVE | RESET_REMOVE | RESET_TOGRAVE | RESET_TURN_SET;
//========== Types ==========
#define EFFECT_TYPE_SINGLE 0x0001 //
#define EFFECT_TYPE_FIELD 0x0002 //
......@@ -191,7 +192,7 @@ enum effect_flag : uint32 {
EFFECT_FLAG_CANNOT_DISABLE = 0x0400,
EFFECT_FLAG_PLAYER_TARGET = 0x0800,
EFFECT_FLAG_BOTH_SIDE = 0x1000,
// EFFECT_FLAG_COPY_INHERIT = 0x2000,
EFFECT_FLAG_COPY = 0x2000,
EFFECT_FLAG_DAMAGE_STEP = 0x4000,
EFFECT_FLAG_DAMAGE_CAL = 0x8000,
EFFECT_FLAG_DELAY = 0x10000,
......@@ -220,7 +221,7 @@ enum effect_flag2 : uint32 {
constexpr effect_flag operator|(effect_flag flag1, effect_flag flag2) {
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2));
}
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_COPY | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
//========== Codes ==========
#define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 //
......
......@@ -26,10 +26,6 @@ struct effect_set {
void remove_item(int index) {
if (index < 0 || index >= count)
return;
if(index == count - 1) {
--count;
return;
}
for(int i = index; i < count - 1; ++i)
container[i] = container[i + 1];
--count;
......@@ -86,10 +82,7 @@ struct effect_set_v {
return (int)container.size();
}
void sort() {
int count = (int)container.size();
if(count < 2)
return;
std::sort(container.begin(), container.begin() + count, effect_sort_id);
std::sort(container.begin(), container.end(), effect_sort_id);
}
effect* const& get_last() const {
assert(container.size());
......
......@@ -16,8 +16,6 @@
#include <set>
#include <map>
#include <list>
#include <array>
#include <functional>
#include <unordered_map>
#include <unordered_set>
......
......@@ -1345,6 +1345,24 @@ int32 scriptlib::card_is_tuner(lua_State* L) {
lua_pushboolean(L, pcard->is_tuner(scard));
return 1;
}
int32 scriptlib::card_is_original_effect_property(lua_State* L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pcard = *(card**)lua_touserdata(L, 1);
int32 filter = interpreter::get_function_handle(L, 2);
lua_pushboolean(L, pcard->is_original_effect_property(filter));
return 1;
}
int32 scriptlib::card_is_effect_property(lua_State* L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pcard = *(card**)lua_touserdata(L, 1);
int32 filter = interpreter::get_function_handle(L, 2);
lua_pushboolean(L, pcard->is_effect_property(filter));
return 1;
}
int32 scriptlib::card_set_status(lua_State *L) {
check_param_count(L, 3);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -3515,6 +3533,8 @@ static const struct luaL_Reg cardlib[] = {
{ "IsStatus", scriptlib::card_is_status },
{ "IsNotTuner", scriptlib::card_is_not_tuner },
{ "IsTuner", scriptlib::card_is_tuner },
{ "IsOriginalEffectProperty", scriptlib::card_is_original_effect_property },
{ "IsEffectProperty", scriptlib::card_is_effect_property },
{ "SetStatus", scriptlib::card_set_status },
{ "IsDualState", scriptlib::card_is_dual_state },
{ "EnableDualState", scriptlib::card_enable_dual_state },
......
......@@ -4792,7 +4792,7 @@ int32 scriptlib::duel_majestic_copy(lua_State *L) {
ceffect->flag[0] &= ~EFFECT_FLAG_INITIAL;
ceffect->effect_owner = PLAYER_NONE;
ceffect->reset_flag = RESET_EVENT + 0x1fe0000 + RESET_PHASE + PHASE_END + RESET_SELF_TURN + RESET_OPPO_TURN;
ceffect->reset_count = 0x1;
ceffect->reset_count = 1;
ceffect->recharge();
if(ceffect->type & EFFECT_TYPE_TRIGGER_F) {
ceffect->type &= ~EFFECT_TYPE_TRIGGER_F;
......
......@@ -151,6 +151,8 @@ public:
static int32 card_is_status(lua_State *L);
static int32 card_is_not_tuner(lua_State *L);
static int32 card_is_tuner(lua_State* L);
static int32 card_is_original_effect_property(lua_State* L);
static int32 card_is_effect_property(lua_State* L);
static int32 card_set_status(lua_State *L);
static int32 card_is_dual_state(lua_State *L);
static int32 card_enable_dual_state(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