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