Commit 4f2b0cd2 authored by DailyShana's avatar DailyShana Committed by GitHub

add EFFECT_TYPE_TARGET (#224)

parent 5dea59cb
......@@ -1553,6 +1553,10 @@ void card::enable_field_effect(bool enabled) {
for (auto& it : equip_effect)
it.second->id = pduel->game_field->infos.field_id++;
}
for (auto& it : target_effect) {
if (it.second->in_range(this))
it.second->id = pduel->game_field->infos.field_id++;
}
if (get_status(STATUS_DISABLED))
reset(RESET_DISABLE, RESET_EVENT);
} else
......@@ -1570,7 +1574,7 @@ int32 card::add_effect(effect* peffect) {
}
if (indexer.find(peffect) != indexer.end())
return 0;
card* check_target = this;
card_set check_target = { this };
if (peffect->type & EFFECT_TYPE_SINGLE) {
if((peffect->code == EFFECT_SET_ATTACK || peffect->code == EFFECT_SET_BASE_ATTACK) && !peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE)) {
for(auto it = single_effect.begin(); it != single_effect.end();) {
......@@ -1608,15 +1612,21 @@ int32 card::add_effect(effect* peffect) {
} else if (peffect->type & EFFECT_TYPE_EQUIP) {
eit = equip_effect.emplace(peffect->code, peffect);
if (equiping_target)
check_target = equiping_target;
check_target = { equiping_target };
else
check_target = 0;
check_target.clear();
} else if(peffect->type & EFFECT_TYPE_TARGET) {
eit = target_effect.emplace(peffect->code, peffect);
if(!effect_target_cards.empty())
check_target = effect_target_cards;
else
check_target.clear();
} else if (peffect->type & EFFECT_TYPE_XMATERIAL) {
eit = xmaterial_effect.emplace(peffect->code, peffect);
if (overlay_target)
check_target = overlay_target;
check_target = { overlay_target };
else
check_target = 0;
check_target.clear();
} else if (peffect->type & EFFECT_TYPE_FIELD) {
eit = field_effect.emplace(peffect->code, peffect);
} else
......@@ -1641,9 +1651,10 @@ int32 card::add_effect(effect* peffect) {
peffect->handler = this;
if (peffect->in_range(this) && (peffect->type & EFFECT_TYPE_FIELD))
pduel->game_field->add_effect(peffect);
if (current.controler != PLAYER_NONE && check_target) {
if (peffect->is_disable_related())
pduel->game_field->add_to_disable_check_list(check_target);
if (current.controler != PLAYER_NONE && !check_target.empty()) {
if(peffect->is_disable_related())
for(auto& target : check_target)
pduel->game_field->add_to_disable_check_list(target);
}
if(peffect->is_flag(EFFECT_FLAG_OATH)) {
pduel->game_field->effects.oath.emplace(peffect, reason_effect);
......@@ -1679,23 +1690,29 @@ void card::remove_effect(effect* peffect) {
remove_effect(peffect, it->second);
}
void card::remove_effect(effect* peffect, effect_container::iterator it) {
card* check_target = this;
card_set check_target = { this };
if (peffect->type & EFFECT_TYPE_SINGLE) {
single_effect.erase(it);
} else if (peffect->type & EFFECT_TYPE_EQUIP) {
equip_effect.erase(it);
if (equiping_target)
check_target = equiping_target;
check_target = { equiping_target };
else
check_target = 0;
check_target.clear();
} else if(peffect->type & EFFECT_TYPE_TARGET) {
target_effect.erase(it);
if(!effect_target_cards.empty())
check_target = effect_target_cards;
else
check_target.clear();
} else if (peffect->type & EFFECT_TYPE_XMATERIAL) {
xmaterial_effect.erase(it);
if (overlay_target)
check_target = overlay_target;
check_target = { overlay_target };
else
check_target = 0;
check_target.clear();
} else if (peffect->type & EFFECT_TYPE_FIELD) {
check_target = 0;
check_target.clear();
if (peffect->is_available() && peffect->is_disable_related()) {
pduel->game_field->update_disable_check_list(peffect);
}
......@@ -1703,9 +1720,10 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) {
if (peffect->in_range(this))
pduel->game_field->remove_effect(peffect);
}
if ((current.controler != PLAYER_NONE) && !get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && check_target) {
if ((current.controler != PLAYER_NONE) && !get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && !check_target.empty()) {
if (peffect->is_disable_related())
pduel->game_field->add_to_disable_check_list(check_target);
for(auto& target : check_target)
pduel->game_field->add_to_disable_check_list(target);
}
if (peffect->is_flag(EFFECT_FLAG_INITIAL) && peffect->copy_id && is_status(STATUS_EFFECT_REPLACED)) {
set_status(STATUS_EFFECT_REPLACED, FALSE);
......@@ -2203,6 +2221,10 @@ void card::set_material(card_set* materials) {
void card::add_card_target(card* pcard) {
effect_target_cards.insert(pcard);
pcard->effect_target_owner.insert(this);
for(auto& it : target_effect) {
if(it.second->is_disable_related())
pduel->game_field->add_to_disable_check_list(pcard);
}
pduel->write_buffer8(MSG_CARD_TARGET);
pduel->write_buffer32(get_info_location());
pduel->write_buffer32(pcard->get_info_location());
......@@ -2212,16 +2234,29 @@ void card::cancel_card_target(card* pcard) {
if(cit != effect_target_cards.end()) {
effect_target_cards.erase(cit);
pcard->effect_target_owner.erase(this);
for(auto& it : target_effect) {
if(it.second->is_disable_related())
pduel->game_field->add_to_disable_check_list(pcard);
}
pduel->write_buffer8(MSG_CANCEL_TARGET);
pduel->write_buffer32(get_info_location());
pduel->write_buffer32(pcard->get_info_location());
}
}
void card::clear_card_target() {
for(auto& pcard : effect_target_owner)
for(auto& pcard : effect_target_owner) {
pcard->effect_target_cards.erase(this);
for(auto& it : pcard->target_effect) {
if(it.second->is_disable_related())
pduel->game_field->add_to_disable_check_list(this);
}
}
for(auto& pcard : effect_target_cards) {
pcard->effect_target_owner.erase(this);
for(auto& it : target_effect) {
if(it.second->is_disable_related())
pduel->game_field->add_to_disable_check_list(pcard);
}
for(auto it = pcard->single_effect.begin(); it != pcard->single_effect.end();) {
auto rm = it++;
effect* peffect = rm->second;
......@@ -2248,6 +2283,14 @@ void card::filter_effect(int32 code, effect_set* eset, uint8 sort) {
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) {
......@@ -2288,6 +2331,14 @@ void card::filter_single_continuous_effect(int32 code, effect_set* eset, uint8 s
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) {
......@@ -2318,6 +2369,14 @@ void card::filter_immune_effect() {
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) {
peffect = rg.first->second;
if(peffect->is_target(this) && peffect->is_available())
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) {
......@@ -2349,7 +2408,10 @@ void card::filter_disable_related_cards() {
pduel->game_field->update_disable_check_list(peffect);
else if ((peffect->type & EFFECT_TYPE_EQUIP) && equiping_target)
pduel->game_field->add_to_disable_check_list(equiping_target);
else if ((peffect->type & EFFECT_TYPE_XMATERIAL) && overlay_target)
else if((peffect->type & EFFECT_TYPE_TARGET) && !effect_target_cards.empty()) {
for(auto& target : effect_target_cards)
pduel->game_field->add_to_disable_check_list(target);
} else if((peffect->type & EFFECT_TYPE_XMATERIAL) && overlay_target)
pduel->game_field->add_to_disable_check_list(overlay_target);
}
}
......@@ -2594,6 +2656,14 @@ effect* card::is_affected_by_effect(int32 code) {
return 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))
return peffect;
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
......@@ -2630,6 +2700,14 @@ effect* card::is_affected_by_effect(int32 code, card* target) {
return 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) && peffect->get_value(target))
return peffect;
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
......@@ -2659,6 +2737,14 @@ effect* card::check_control_effect() {
ret_effect = peffect;
}
}
for (auto& pcard : effect_target_owner) {
auto rg = pcard->target_effect.equal_range(EFFECT_SET_CONTROL);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if(!ret_effect || peffect->is_target(pcard) && peffect->id > ret_effect->id)
ret_effect = peffect;
}
}
for (auto& pcard : xyz_materials) {
auto rg = pcard->xmaterial_effect.equal_range(EFFECT_SET_CONTROL);
for (; rg.first != rg.second; ++rg.first) {
......
......@@ -180,6 +180,7 @@ public:
effect_container single_effect;
effect_container field_effect;
effect_container equip_effect;
effect_container target_effect;
effect_container xmaterial_effect;
effect_indexer indexer;
effect_relation relate_effect;
......
......@@ -114,7 +114,7 @@ int32 effect::is_available() {
return FALSE;
}
}
if (type & EFFECT_TYPE_FIELD) {
if (type & (EFFECT_TYPE_FIELD | EFFECT_TYPE_TARGET)) {
card* phandler = get_handler();
card* powner = get_owner();
if (!is_flag(EFFECT_FLAG_FIELD_ONLY)) {
......@@ -442,6 +442,11 @@ int32 effect::is_target(card* pcard) {
return FALSE;
if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL) && !(type & EFFECT_TYPE_FIELD))
return TRUE;
if((type & EFFECT_TYPE_TARGET) && !(type & EFFECT_TYPE_FIELD)) {
if(pcard->get_status(STATUS_SUMMONING | STATUS_SUMMON_DISABLED | STATUS_ACTIVATE_DISABLED | STATUS_SPSUMMON_STEP))
return FALSE;
return is_fit_target_function(pcard);
}
if(pcard && !is_flag(EFFECT_FLAG_SET_AVAILABLE) && (pcard->current.location & LOCATION_ONFIELD)
&& !pcard->is_position(POS_FACEUP))
return FALSE;
......
......@@ -157,6 +157,7 @@ public:
#define EFFECT_TYPE_CONTINUOUS 0x0800 //
#define EFFECT_TYPE_XMATERIAL 0x1000 //
#define EFFECT_TYPE_GRANT 0x2000 //
#define EFFECT_TYPE_TARGET 0x4000 //
//========== Flags ==========
enum effect_flag : uint32 {
......
......@@ -1381,7 +1381,8 @@ int32 field::equip(uint16 step, uint8 equip_player, card * equip_card, card * ta
return FALSE;
}
if(equip_card->equiping_target) {
equip_card->cancel_card_target(equip_card->equiping_target);
equip_card->effect_target_cards.erase(equip_card->equiping_target);
equip_card->equiping_target->effect_target_owner.erase(equip_card);
equip_card->unequip();
equip_card->enable_field_effect(false);
return FALSE;
......
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