Commit 96bbbedb authored by VanillaSalt's avatar VanillaSalt

add EFFECT_TYPE_XMATERIAL

parent 79b9ee57
...@@ -90,6 +90,7 @@ card::~card() { ...@@ -90,6 +90,7 @@ card::~card() {
single_effect.clear(); single_effect.clear();
field_effect.clear(); field_effect.clear();
equip_effect.clear(); equip_effect.clear();
xmaterial_effect.clear();
relate_effect.clear(); relate_effect.clear();
} }
uint32 card::get_infos(byte* buf, int32 query_flag, int32 use_cache) { uint32 card::get_infos(byte* buf, int32 query_flag, int32 use_cache) {
...@@ -1285,6 +1286,12 @@ int32 card::add_effect(effect* peffect) { ...@@ -1285,6 +1286,12 @@ int32 card::add_effect(effect* peffect) {
check_target = equiping_target; check_target = equiping_target;
else else
check_target = 0; check_target = 0;
} else if (peffect->type & EFFECT_TYPE_XMATERIAL) {
eit = xmaterial_effect.insert(std::make_pair(peffect->code, peffect));
if (overlay_target)
check_target = overlay_target;
else
check_target = 0;
} else } else
return 0; return 0;
peffect->id = pduel->game_field->infos.field_id++; peffect->id = pduel->game_field->infos.field_id++;
...@@ -1362,6 +1369,12 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) { ...@@ -1362,6 +1369,12 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) {
check_target = equiping_target; check_target = equiping_target;
else else
check_target = 0; check_target = 0;
} else if (peffect->type & EFFECT_TYPE_XMATERIAL) {
xmaterial_effect.erase(it);
if (overlay_target)
check_target = overlay_target;
else
check_target = 0;
} }
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) {
if (peffect->is_disable_related()) if (peffect->is_disable_related())
...@@ -1432,7 +1445,7 @@ int32 card::copy_effect(uint32 code, uint32 reset, uint32 count) { ...@@ -1432,7 +1445,7 @@ int32 card::copy_effect(uint32 code, uint32 reset, uint32 count) {
if(!(data.type & TYPE_EFFECT)) { if(!(data.type & TYPE_EFFECT)) {
effect* peffect = pduel->new_effect(); effect* peffect = pduel->new_effect();
if(pduel->game_field->core.reason_effect) if(pduel->game_field->core.reason_effect)
peffect->owner = pduel->game_field->core.reason_effect->handler; peffect->owner = pduel->game_field->core.reason_effect->get_handler();
else else
peffect->owner = this; peffect->owner = this;
peffect->handler = this; peffect->handler = this;
...@@ -1476,7 +1489,7 @@ int32 card::replace_effect(uint32 code, uint32 reset, uint32 count) { ...@@ -1476,7 +1489,7 @@ int32 card::replace_effect(uint32 code, uint32 reset, uint32 count) {
if(!(data.type & TYPE_EFFECT)) { if(!(data.type & TYPE_EFFECT)) {
effect* peffect = pduel->new_effect(); effect* peffect = pduel->new_effect();
if(pduel->game_field->core.reason_effect) if(pduel->game_field->core.reason_effect)
peffect->owner = pduel->game_field->core.reason_effect->handler; peffect->owner = pduel->game_field->core.reason_effect->get_handler();
else else
peffect->owner = this; peffect->owner = this;
peffect->handler = this; peffect->handler = this;
...@@ -1869,6 +1882,14 @@ void card::filter_effect(int32 code, effect_set* eset, uint8 sort) { ...@@ -1869,6 +1882,14 @@ void card::filter_effect(int32 code, effect_set* eset, uint8 sort) {
eset->add_item(peffect); eset->add_item(peffect);
} }
} }
for (auto cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
rg = (*cit)->xmaterial_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);
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code); rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) { for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second; peffect = rg.first->second;
...@@ -1899,6 +1920,11 @@ void card::filter_single_continuous_effect(int32 code, effect_set* eset, uint8 s ...@@ -1899,6 +1920,11 @@ 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 cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
rg = (*cit)->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first)
eset->add_item(rg.first->second);
}
if(sort) if(sort)
eset->sort(); eset->sort();
} }
...@@ -1920,6 +1946,14 @@ void card::filter_immune_effect() { ...@@ -1920,6 +1946,14 @@ void card::filter_immune_effect() {
immune_effect.add_item(peffect); immune_effect.add_item(peffect);
} }
} }
for (auto cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
rg = (*cit)->xmaterial_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->is_available())
immune_effect.add_item(peffect);
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(EFFECT_IMMUNE_EFFECT); rg = pduel->game_field->effects.aura_effect.equal_range(EFFECT_IMMUNE_EFFECT);
for (; rg.first != rg.second; ++rg.first) { for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second; peffect = rg.first->second;
...@@ -1939,6 +1973,8 @@ void card::filter_disable_related_cards() { ...@@ -1939,6 +1973,8 @@ 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)
pduel->game_field->add_to_disable_check_list(overlay_target);
} }
} }
} }
...@@ -2094,6 +2130,14 @@ effect* card::is_affected_by_effect(int32 code) { ...@@ -2094,6 +2130,14 @@ effect* card::is_affected_by_effect(int32 code) {
return peffect; return peffect;
} }
} }
for (auto cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
rg = (*cit)->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->is_available() && is_affect_by_effect(peffect))
return peffect;
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code); rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) { for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second; peffect = rg.first->second;
...@@ -2120,6 +2164,14 @@ effect* card::is_affected_by_effect(int32 code, card* target) { ...@@ -2120,6 +2164,14 @@ effect* card::is_affected_by_effect(int32 code, card* target) {
return peffect; return peffect;
} }
} }
for (auto cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
rg = (*cit)->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
if (peffect->is_available() && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code); rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) { for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second; peffect = rg.first->second;
...@@ -2139,6 +2191,14 @@ effect* card::check_control_effect() { ...@@ -2139,6 +2191,14 @@ effect* card::check_control_effect() {
ret_effect = peffect; ret_effect = peffect;
} }
} }
for (auto cit = xyz_materials.begin(); cit != xyz_materials.end(); ++cit) {
auto rg = (*cit)->xmaterial_effect.equal_range(EFFECT_SET_CONTROL);
for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second;
if(!ret_effect || peffect->id > ret_effect->id)
ret_effect = peffect;
}
}
auto rg = single_effect.equal_range(EFFECT_SET_CONTROL); auto rg = single_effect.equal_range(EFFECT_SET_CONTROL);
for (; rg.first != rg.second; ++rg.first) { for (; rg.first != rg.second; ++rg.first) {
effect* peffect = rg.first->second; effect* peffect = rg.first->second;
...@@ -2886,7 +2946,7 @@ int32 card::is_capable_be_effect_target(effect* peffect, uint8 playerid) { ...@@ -2886,7 +2946,7 @@ int32 card::is_capable_be_effect_target(effect* peffect, uint8 playerid) {
return FALSE; return FALSE;
} }
eset.clear(); eset.clear();
peffect->handler->filter_effect(EFFECT_CANNOT_SELECT_EFFECT_TARGET, &eset); peffect->get_handler()->filter_effect(EFFECT_CANNOT_SELECT_EFFECT_TARGET, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(this, PARAM_TYPE_CARD); pduel->lua->add_param(this, PARAM_TYPE_CARD);
if(eset[i]->get_value(peffect, 1)) if(eset[i]->get_value(peffect, 1))
......
...@@ -152,6 +152,7 @@ public: ...@@ -152,6 +152,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 xmaterial_effect;
effect_indexer indexer; effect_indexer indexer;
effect_relation relate_effect; effect_relation relate_effect;
effect_set_v immune_effect; effect_set_v immune_effect;
......
...@@ -24,6 +24,7 @@ effect::effect(duel* pd) { ...@@ -24,6 +24,7 @@ effect::effect(duel* pd) {
effect_owner = PLAYER_NONE; effect_owner = PLAYER_NONE;
card_type = 0; card_type = 0;
active_type = 0; active_type = 0;
active_handler = 0;
id = 0; id = 0;
code = 0; code = 0;
type = 0; type = 0;
...@@ -71,22 +72,24 @@ int32 effect::is_can_be_forbidden() { ...@@ -71,22 +72,24 @@ int32 effect::is_can_be_forbidden() {
int32 effect::is_available() { int32 effect::is_available() {
if (type & EFFECT_TYPE_ACTIONS) if (type & EFFECT_TYPE_ACTIONS)
return FALSE; return FALSE;
if (type & EFFECT_TYPE_SINGLE) { if ((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
if (handler->current.controler == PLAYER_NONE) card* phandler = get_handler();
card* powner = get_owner();
if (phandler->current.controler == PLAYER_NONE)
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(handler->current.location, handler->current.sequence)) if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler->current.location, phandler->current.sequence))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !handler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY)) if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && (handler->current.location & LOCATION_ONFIELD) && !handler->is_position(POS_FACEUP)) if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && (phandler->current.location & LOCATION_ONFIELD) && !phandler->is_position(POS_FACEUP))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && owner->is_status(STATUS_FORBIDDEN)) if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && powner->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(owner == handler && is_can_be_forbidden() && handler->get_status(STATUS_FORBIDDEN)) if(powner == phandler && is_can_be_forbidden() && phandler->get_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && owner->is_status(STATUS_DISABLED)) if(is_flag(EFFECT_FLAG_OWNER_RELATE) && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && powner->is_status(STATUS_DISABLED))
return FALSE; return FALSE;
if(owner == handler && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && handler->get_status(STATUS_DISABLED)) if(powner == phandler && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && phandler->get_status(STATUS_DISABLED))
return FALSE; return FALSE;
} }
if (type & EFFECT_TYPE_EQUIP) { if (type & EFFECT_TYPE_EQUIP) {
...@@ -152,7 +155,7 @@ int32 effect::check_count_limit(uint8 playerid) { ...@@ -152,7 +155,7 @@ int32 effect::check_count_limit(uint8 playerid) {
uint32 code = count_code & 0xfffffff; uint32 code = count_code & 0xfffffff;
uint32 count = (reset_count >> 12) & 0xf; uint32 count = (reset_count >> 12) & 0xf;
if(code == 1) { if(code == 1) {
if(pduel->game_field->get_effect_code((count_code & 0xf0000000) | handler->fieldid, PLAYER_NONE) >= count) if(pduel->game_field->get_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE) >= count)
return FALSE; return FALSE;
} else { } else {
if(pduel->game_field->get_effect_code(count_code, playerid) >= count) if(pduel->game_field->get_effect_code(count_code, playerid) >= count)
...@@ -235,16 +238,17 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -235,16 +238,17 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER)) if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER))
return FALSE; return FALSE;
} else if(!(type & EFFECT_TYPE_CONTINUOUS)) { } else if(!(type & EFFECT_TYPE_CONTINUOUS)) {
if((handler->data.type & TYPE_MONSTER) && (handler->current.location & LOCATION_SZONE) card* phandler = get_handler();
&& !in_range(handler->current.location, handler->current.sequence)) if((phandler->data.type & TYPE_MONSTER) && (phandler->current.location & LOCATION_SZONE)
&& !in_range(phandler->current.location, phandler->current.sequence))
return FALSE; return FALSE;
if((handler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED))) { if((phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED))) {
// effects which can be activated while face-down: // effects which can be activated while face-down:
// 1. effects with EFFECT_FLAG_SET_AVAILABLE // 1. effects with EFFECT_FLAG_SET_AVAILABLE
// 2. events with FLIP_SET_AVAILABLE // 2. events with FLIP_SET_AVAILABLE
if(!handler->is_position(POS_FACEUP) && !is_flag(EFFECT_FLAG_SET_AVAILABLE) && (code != EVENT_FLIP || !(e.event_value & (FLIP_SET_AVAILABLE >> 16)))) if(!phandler->is_position(POS_FACEUP) && !is_flag(EFFECT_FLAG_SET_AVAILABLE) && (code != EVENT_FLIP || !(e.event_value & (FLIP_SET_AVAILABLE >> 16))))
return FALSE; return FALSE;
if(handler->is_position(POS_FACEUP) && !handler->is_status(STATUS_EFFECT_ENABLED)) if(phandler->is_position(POS_FACEUP) && !phandler->is_status(STATUS_EFFECT_ENABLED))
return FALSE; return FALSE;
} }
if(!(type & (EFFECT_TYPE_FLIP | EFFECT_TYPE_TRIGGER_F)) if(!(type & (EFFECT_TYPE_FLIP | EFFECT_TYPE_TRIGGER_F))
...@@ -254,29 +258,30 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -254,29 +258,30 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if((code < 1134 || code > 1136) && pduel->game_field->infos.phase == PHASE_DAMAGE_CAL && !is_flag(EFFECT_FLAG_DAMAGE_CAL)) if((code < 1134 || code > 1136) && pduel->game_field->infos.phase == PHASE_DAMAGE_CAL && !is_flag(EFFECT_FLAG_DAMAGE_CAL))
return FALSE; return FALSE;
} }
if(handler->current.location == LOCATION_OVERLAY) if(phandler->current.location == LOCATION_OVERLAY)
return FALSE; return FALSE;
if((type & EFFECT_TYPE_FIELD) && (handler->current.controler != playerid) && !is_flag(EFFECT_FLAG_BOTH_SIDE)) if((type & EFFECT_TYPE_FIELD) && (phandler->current.controler != playerid) && !is_flag(EFFECT_FLAG_BOTH_SIDE))
return FALSE; return FALSE;
if(handler->is_status(STATUS_FORBIDDEN)) if(phandler->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER)) if(phandler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER))
return FALSE; return FALSE;
} else { } else {
if(!is_flag(EFFECT_FLAG_AVAILABLE_BD) && (type & EFFECT_TYPE_FIELD) && handler->is_status(STATUS_BATTLE_DESTROYED)) card* phandler = get_handler();
if(!is_flag(EFFECT_FLAG_AVAILABLE_BD) && (type & EFFECT_TYPE_FIELD) && phandler->is_status(STATUS_BATTLE_DESTROYED))
return FALSE; return FALSE;
if(((type & EFFECT_TYPE_FIELD) || ((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE))) && (handler->current.location & LOCATION_ONFIELD) if(((type & EFFECT_TYPE_FIELD) || ((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE))) && (phandler->current.location & LOCATION_ONFIELD)
&& (!handler->is_position(POS_FACEUP) || !handler->is_status(STATUS_EFFECT_ENABLED))) && (!phandler->is_position(POS_FACEUP) || !phandler->is_status(STATUS_EFFECT_ENABLED)))
return FALSE; return FALSE;
if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(handler->current.location, handler->current.sequence)) if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler->current.location, phandler->current.sequence))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && owner->is_status(STATUS_FORBIDDEN)) if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && owner->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(handler == owner && is_can_be_forbidden() && handler->is_status(STATUS_FORBIDDEN)) if(phandler == owner && is_can_be_forbidden() && phandler->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && owner->is_status(STATUS_DISABLED)) if(is_flag(EFFECT_FLAG_OWNER_RELATE) && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && owner->is_status(STATUS_DISABLED))
return FALSE; return FALSE;
if(handler == owner && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && handler->is_status(STATUS_DISABLED)) if(phandler == owner && !is_flag(EFFECT_FLAG_CANNOT_DISABLE) && phandler->is_status(STATUS_DISABLED))
return FALSE; return FALSE;
} }
} else { } else {
...@@ -371,7 +376,8 @@ int32 effect::is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_c ...@@ -371,7 +376,8 @@ int32 effect::is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_c
} }
// check functions: condition // check functions: condition
int32 effect::is_condition_check(uint8 playerid, const tevent& e) { int32 effect::is_condition_check(uint8 playerid, const tevent& e) {
if(!(type & EFFECT_TYPE_ACTIVATE) && (handler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED)) && !handler->is_position(POS_FACEUP)) card* phandler = get_handler();
if(!(type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED)) && !phandler->is_position(POS_FACEUP))
return FALSE; return FALSE;
if(!condition) if(!condition)
return TRUE; return TRUE;
...@@ -415,7 +421,7 @@ int32 effect::is_activate_check(uint8 playerid, const tevent& e, int32 neglect_c ...@@ -415,7 +421,7 @@ int32 effect::is_activate_check(uint8 playerid, const tevent& e, int32 neglect_c
int32 effect::is_target(card* pcard) { int32 effect::is_target(card* pcard) {
if(type & EFFECT_TYPE_ACTIONS) if(type & EFFECT_TYPE_ACTIONS)
return FALSE; return FALSE;
if((type & EFFECT_TYPE_SINGLE) || (type & EFFECT_TYPE_EQUIP)) if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL))
return TRUE; return TRUE;
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))
...@@ -500,7 +506,7 @@ int32 effect::is_chainable(uint8 tp) { ...@@ -500,7 +506,7 @@ int32 effect::is_chainable(uint8 tp) {
return FALSE; return FALSE;
if(pduel->game_field->core.current_chain.size()) { if(pduel->game_field->core.current_chain.size()) {
if(!is_flag(EFFECT_FLAG_FIELD_ONLY) && (type & EFFECT_TYPE_TRIGGER_O) if(!is_flag(EFFECT_FLAG_FIELD_ONLY) && (type & EFFECT_TYPE_TRIGGER_O)
&& (handler->current.location == LOCATION_HAND)) { && (get_handler()->current.location == LOCATION_HAND)) {
if(pduel->game_field->core.current_chain.rbegin()->triggering_effect->get_speed() > 2) if(pduel->game_field->core.current_chain.rbegin()->triggering_effect->get_speed() > 2)
return FALSE; return FALSE;
} else if(sp < pduel->game_field->core.current_chain.rbegin()->triggering_effect->get_speed()) } else if(sp < pduel->game_field->core.current_chain.rbegin()->triggering_effect->get_speed())
...@@ -575,7 +581,7 @@ void effect::dec_count(uint32 playerid) { ...@@ -575,7 +581,7 @@ void effect::dec_count(uint32 playerid) {
if(count_code) { if(count_code) {
uint32 code = count_code & 0xfffffff; uint32 code = count_code & 0xfffffff;
if(code == 1) if(code == 1)
pduel->game_field->add_effect_code((count_code & 0xf0000000) | handler->fieldid, PLAYER_NONE); pduel->game_field->add_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE);
else else
pduel->game_field->add_effect_code(count_code, playerid); pduel->game_field->add_effect_code(count_code, playerid);
} }
...@@ -650,15 +656,25 @@ int32 effect::get_speed() { ...@@ -650,15 +656,25 @@ int32 effect::get_speed() {
} }
return 0; return 0;
} }
card* effect::get_owner() const {
if(type & EFFECT_TYPE_XMATERIAL)
return active_handler ? active_handler : handler->overlay_target;
return owner;
}
uint8 effect::get_owner_player() { uint8 effect::get_owner_player() {
if(effect_owner != PLAYER_NONE) if(effect_owner != PLAYER_NONE)
return effect_owner; return effect_owner;
return owner->current.controler; return get_owner()->current.controler;
}
card* effect::get_handler() const {
if(type & EFFECT_TYPE_XMATERIAL)
return active_handler ? active_handler : handler->overlay_target;
return handler;
} }
uint8 effect::get_handler_player() { uint8 effect::get_handler_player() {
if(is_flag(EFFECT_FLAG_FIELD_ONLY)) if(is_flag(EFFECT_FLAG_FIELD_ONLY))
return effect_owner; return effect_owner;
return handler->current.controler; return get_handler()->current.controler;
} }
int32 effect::in_range(int32 loc, int32 seq) { int32 effect::in_range(int32 loc, int32 seq) {
if(loc != LOCATION_SZONE) if(loc != LOCATION_SZONE)
......
...@@ -50,6 +50,7 @@ public: ...@@ -50,6 +50,7 @@ public:
uint32 hint_timing[2]; uint32 hint_timing[2];
uint32 card_type; uint32 card_type;
uint32 active_type; uint32 active_type;
card* active_handler;
uint16 field_ref; uint16 field_ref;
uint16 status; uint16 status;
void* label_object; void* label_object;
...@@ -84,7 +85,9 @@ public: ...@@ -84,7 +85,9 @@ public:
int32 get_value(effect* peffect, uint32 extraargs = 0); int32 get_value(effect* peffect, uint32 extraargs = 0);
int32 check_value_condition(uint32 extraargs = 0); int32 check_value_condition(uint32 extraargs = 0);
int32 get_speed(); int32 get_speed();
card* get_owner() const;
uint8 get_owner_player(); uint8 get_owner_player();
card* get_handler() const;
uint8 get_handler_player(); uint8 get_handler_player();
int32 in_range(int32 loc, int32 seq); int32 in_range(int32 loc, int32 seq);
bool is_flag(effect_flag flag) const { bool is_flag(effect_flag flag) const {
...@@ -138,6 +141,7 @@ public: ...@@ -138,6 +141,7 @@ public:
#define EFFECT_TYPE_TRIGGER_F 0x0200 // #define EFFECT_TYPE_TRIGGER_F 0x0200 //
#define EFFECT_TYPE_QUICK_F 0x0400 // #define EFFECT_TYPE_QUICK_F 0x0400 //
#define EFFECT_TYPE_CONTINUOUS 0x0800 // #define EFFECT_TYPE_CONTINUOUS 0x0800 //
#define EFFECT_TYPE_XMATERIAL 0x1000 //
//========== Flags ========== //========== Flags ==========
enum effect_flag : uint32 { enum effect_flag : uint32 {
......
...@@ -138,8 +138,8 @@ void field::reload_field_info() { ...@@ -138,8 +138,8 @@ void field::reload_field_info() {
pduel->write_buffer8(core.current_chain.size()); pduel->write_buffer8(core.current_chain.size());
for(auto chit = core.current_chain.begin(); chit != core.current_chain.end(); ++chit) { for(auto chit = core.current_chain.begin(); chit != core.current_chain.end(); ++chit) {
effect* peffect = chit->triggering_effect; effect* peffect = chit->triggering_effect;
pduel->write_buffer32(peffect->handler->data.code); pduel->write_buffer32(peffect->get_handler()->data.code);
pduel->write_buffer32(peffect->handler->get_info_location()); pduel->write_buffer32(peffect->get_handler()->get_info_location());
pduel->write_buffer8(chit->triggering_controler); pduel->write_buffer8(chit->triggering_controler);
pduel->write_buffer8(chit->triggering_location); pduel->write_buffer8(chit->triggering_location);
pduel->write_buffer8(chit->triggering_sequence); pduel->write_buffer8(chit->triggering_sequence);
...@@ -405,7 +405,7 @@ void field::set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 r ...@@ -405,7 +405,7 @@ void field::set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 r
return; return;
effect* peffect = pduel->new_effect(); effect* peffect = pduel->new_effect();
if(core.reason_effect) if(core.reason_effect)
peffect->owner = core.reason_effect->handler; peffect->owner = core.reason_effect->get_handler();
else else
peffect->owner = pcard; peffect->owner = pcard;
peffect->handler = pcard; peffect->handler = pcard;
...@@ -1611,7 +1611,7 @@ void field::set_spsummon_counter(uint8 playerid, bool add, bool chain) { ...@@ -1611,7 +1611,7 @@ void field::set_spsummon_counter(uint8 playerid, bool add, bool chain) {
if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) { if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) {
for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) { for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) {
effect* peffect = *iter; effect* peffect = *iter;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
if(add) { if(add) {
if(peffect->is_available()) { if(peffect->is_available()) {
if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) { if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) {
...@@ -1631,7 +1631,7 @@ int32 field::check_spsummon_counter(uint8 playerid, uint8 ct) { ...@@ -1631,7 +1631,7 @@ int32 field::check_spsummon_counter(uint8 playerid, uint8 ct) {
if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) { if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) {
for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) { for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) {
effect* peffect = *iter; effect* peffect = *iter;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
uint16 val = (uint16)peffect->value; uint16 val = (uint16)peffect->value;
if(peffect->is_available()) { if(peffect->is_available()) {
if(pcard->spsummon_counter[playerid] + ct > val) if(pcard->spsummon_counter[playerid] + ct > val)
...@@ -2574,7 +2574,7 @@ int32 field::is_chain_disablable(uint8 chaincount, uint8 naga_check) { ...@@ -2574,7 +2574,7 @@ int32 field::is_chain_disablable(uint8 chaincount, uint8 naga_check) {
peffect = core.current_chain[chaincount - 1].triggering_effect; peffect = core.current_chain[chaincount - 1].triggering_effect;
if(naga_check && peffect->is_flag(EFFECT_FLAG2_NAGA)) if(naga_check && peffect->is_flag(EFFECT_FLAG2_NAGA))
return FALSE; return FALSE;
if(!peffect->handler->get_status(STATUS_FORBIDDEN)) { if(!peffect->get_handler()->get_status(STATUS_FORBIDDEN)) {
if(peffect->is_flag(EFFECT_FLAG_CANNOT_DISABLE)) if(peffect->is_flag(EFFECT_FLAG_CANNOT_DISABLE))
return FALSE; return FALSE;
filter_field_effect(EFFECT_CANNOT_DISEFFECT, &eset); filter_field_effect(EFFECT_CANNOT_DISEFFECT, &eset);
...@@ -2596,7 +2596,7 @@ int32 field::is_chain_disabled(uint8 chaincount) { ...@@ -2596,7 +2596,7 @@ int32 field::is_chain_disabled(uint8 chaincount) {
pchain = &core.current_chain[chaincount - 1]; pchain = &core.current_chain[chaincount - 1];
if(pchain->flag & CHAIN_DISABLE_EFFECT) if(pchain->flag & CHAIN_DISABLE_EFFECT)
return TRUE; return TRUE;
card* pcard = pchain->triggering_effect->handler; card* pcard = pchain->triggering_effect->get_handler();
effect_set eset; effect_set eset;
pcard->filter_effect(EFFECT_DISABLE_CHAIN, &eset); pcard->filter_effect(EFFECT_DISABLE_CHAIN, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
......
...@@ -444,6 +444,7 @@ public: ...@@ -444,6 +444,7 @@ public:
int32 process_quick_effect(int16 step, int32 skip_freechain, uint8 priority); int32 process_quick_effect(int16 step, int32 skip_freechain, uint8 priority);
int32 process_instant_event(); int32 process_instant_event();
int32 process_single_event(); int32 process_single_event();
int32 process_single_event(effect* peffect, const tevent& e, effect_vector& tp, effect_vector& ntp, event_list& tev, event_list& ntev);
int32 process_idle_command(uint16 step); int32 process_idle_command(uint16 step);
int32 process_battle_command(uint16 step); int32 process_battle_command(uint16 step);
int32 process_damage_step(uint16 step, uint32 new_attack); int32 process_damage_step(uint16 step, uint32 new_attack);
......
...@@ -1361,9 +1361,9 @@ int32 scriptlib::duel_negate_related_chain(lua_State *L) { ...@@ -1361,9 +1361,9 @@ int32 scriptlib::duel_negate_related_chain(lua_State *L) {
if(!pcard->is_affect_by_effect(pduel->game_field->core.reason_effect)) if(!pcard->is_affect_by_effect(pduel->game_field->core.reason_effect))
return 0; return 0;
for(auto it = pduel->game_field->core.current_chain.rbegin(); it != pduel->game_field->core.current_chain.rend(); ++it) { for(auto it = pduel->game_field->core.current_chain.rbegin(); it != pduel->game_field->core.current_chain.rend(); ++it) {
if(it->triggering_effect->handler == pcard && pcard->is_has_relation(*it)) { if(it->triggering_effect->get_handler() == pcard && pcard->is_has_relation(*it)) {
effect* negeff = pduel->new_effect(); effect* negeff = pduel->new_effect();
negeff->owner = pduel->game_field->core.reason_effect->handler; negeff->owner = pduel->game_field->core.reason_effect->get_handler();
negeff->type = EFFECT_TYPE_SINGLE; negeff->type = EFFECT_TYPE_SINGLE;
negeff->code = EFFECT_DISABLE_CHAIN; negeff->code = EFFECT_DISABLE_CHAIN;
negeff->value = it->chain_id; negeff->value = it->chain_id;
...@@ -1636,7 +1636,7 @@ int32 scriptlib::duel_chain_attack(lua_State *L) { ...@@ -1636,7 +1636,7 @@ int32 scriptlib::duel_chain_attack(lua_State *L) {
} }
int32 scriptlib::duel_readjust(lua_State *L) { int32 scriptlib::duel_readjust(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
card* adjcard = pduel->game_field->core.reason_effect->handler; card* adjcard = pduel->game_field->core.reason_effect->get_handler();
pduel->game_field->core.readjust_map[adjcard]++; pduel->game_field->core.readjust_map[adjcard]++;
if(pduel->game_field->core.readjust_map[adjcard] > 3) { if(pduel->game_field->core.readjust_map[adjcard] > 3) {
pduel->game_field->send_to(adjcard, 0, REASON_RULE, pduel->game_field->core.reason_player, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP); pduel->game_field->send_to(adjcard, 0, REASON_RULE, pduel->game_field->core.reason_player, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
...@@ -3171,7 +3171,7 @@ int32 scriptlib::duel_check_chain_uniqueness(lua_State *L) { ...@@ -3171,7 +3171,7 @@ int32 scriptlib::duel_check_chain_uniqueness(lua_State *L) {
} }
std::set<uint32> er; std::set<uint32> er;
for(auto cait = pduel->game_field->core.current_chain.begin(); cait != pduel->game_field->core.current_chain.end(); ++cait) for(auto cait = pduel->game_field->core.current_chain.begin(); cait != pduel->game_field->core.current_chain.end(); ++cait)
er.insert(cait->triggering_effect->handler->get_code()); er.insert(cait->triggering_effect->get_handler()->get_code());
if(er.size() == pduel->game_field->core.current_chain.size()) if(er.size() == pduel->game_field->core.current_chain.size())
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
else else
......
...@@ -397,7 +397,7 @@ int32 scriptlib::effect_get_handler(lua_State *L) { ...@@ -397,7 +397,7 @@ int32 scriptlib::effect_get_handler(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::card2value(L, peffect->handler); interpreter::card2value(L, peffect->get_handler());
return 1; return 1;
} }
int32 scriptlib::effect_get_owner_player(lua_State *L) { int32 scriptlib::effect_get_owner_player(lua_State *L) {
...@@ -461,10 +461,10 @@ int32 scriptlib::effect_get_active_type(lua_State *L) { ...@@ -461,10 +461,10 @@ int32 scriptlib::effect_get_active_type(lua_State *L) {
if(peffect->type & 0x7f0) { if(peffect->type & 0x7f0) {
if(peffect->active_type) if(peffect->active_type)
atype = peffect->active_type; atype = peffect->active_type;
else if((peffect->type & EFFECT_TYPE_ACTIVATE) && (peffect->handler->data.type & TYPE_PENDULUM)) else if((peffect->type & EFFECT_TYPE_ACTIVATE) && (peffect->get_handler()->data.type & TYPE_PENDULUM))
atype = TYPE_PENDULUM + TYPE_SPELL; atype = TYPE_PENDULUM + TYPE_SPELL;
else else
atype = peffect->handler->get_type(); atype = peffect->get_handler()->get_type();
} else } else
atype = peffect->owner->get_type(); atype = peffect->owner->get_type();
lua_pushinteger(L, atype); lua_pushinteger(L, atype);
...@@ -479,10 +479,10 @@ int32 scriptlib::effect_is_active_type(lua_State *L) { ...@@ -479,10 +479,10 @@ int32 scriptlib::effect_is_active_type(lua_State *L) {
if(peffect->type & 0x7f0) { if(peffect->type & 0x7f0) {
if(peffect->active_type) if(peffect->active_type)
atype = peffect->active_type; atype = peffect->active_type;
else if((peffect->type & EFFECT_TYPE_ACTIVATE) && (peffect->handler->data.type & TYPE_PENDULUM)) else if((peffect->type & EFFECT_TYPE_ACTIVATE) && (peffect->get_handler()->data.type & TYPE_PENDULUM))
atype = TYPE_PENDULUM + TYPE_SPELL; atype = TYPE_PENDULUM + TYPE_SPELL;
else else
atype = peffect->handler->get_type(); atype = peffect->get_handler()->get_type();
} else } else
atype = peffect->owner->get_type(); atype = peffect->owner->get_type();
lua_pushboolean(L, atype & tpe); lua_pushboolean(L, atype & tpe);
......
...@@ -322,9 +322,9 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) { ...@@ -322,9 +322,9 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) {
*buf++ = ptduel->game_field->core.current_chain.size(); *buf++ = ptduel->game_field->core.current_chain.size();
for(auto chit = ptduel->game_field->core.current_chain.begin(); chit != ptduel->game_field->core.current_chain.end(); ++chit) { for(auto chit = ptduel->game_field->core.current_chain.begin(); chit != ptduel->game_field->core.current_chain.end(); ++chit) {
effect* peffect = chit->triggering_effect; effect* peffect = chit->triggering_effect;
*((int*)(buf)) = peffect->handler->data.code; *((int*)(buf)) = peffect->get_handler()->data.code;
buf += 4; buf += 4;
*((int*)(buf)) = peffect->handler->get_info_location(); *((int*)(buf)) = peffect->get_handler()->get_info_location();
buf += 4; buf += 4;
*buf++ = chit->triggering_controler; *buf++ = chit->triggering_controler;
*buf++ = chit->triggering_location; *buf++ = chit->triggering_location;
......
...@@ -27,7 +27,7 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) { ...@@ -27,7 +27,7 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort); std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort);
for(i = 0; i < core.select_chains.size(); ++i) { for(i = 0; i < core.select_chains.size(); ++i) {
peffect = core.select_chains[i].triggering_effect; peffect = core.select_chains[i].triggering_effect;
pcard = peffect->handler; pcard = peffect->get_handler();
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
...@@ -125,7 +125,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -125,7 +125,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort); std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort);
for(i = 0; i < core.select_chains.size(); ++i) { for(i = 0; i < core.select_chains.size(); ++i) {
peffect = core.select_chains[i].triggering_effect; peffect = core.select_chains[i].triggering_effect;
pcard = peffect->handler; pcard = peffect->get_handler();
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
...@@ -308,7 +308,7 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo ...@@ -308,7 +308,7 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo
std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort); std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort);
for(uint32 i = 0; i < core.select_chains.size(); ++i) { for(uint32 i = 0; i < core.select_chains.size(); ++i) {
effect* peffect = core.select_chains[i].triggering_effect; effect* peffect = core.select_chains[i].triggering_effect;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY)) if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY))
pduel->write_buffer8(EDESC_OPERATION); pduel->write_buffer8(EDESC_OPERATION);
else if(!(peffect->type & EFFECT_TYPE_ACTIONS)) else if(!(peffect->type & EFFECT_TYPE_ACTIONS))
......
...@@ -1348,8 +1348,8 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1348,8 +1348,8 @@ int32 field::process_phase_event(int16 step, int32 phase) {
auto pr = effects.trigger_f_effect.equal_range(phase_event); auto pr = effects.trigger_f_effect.equal_range(phase_event);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
if(!peffect->is_activateable(check_player, nil_event)) if(!peffect->is_activateable(check_player, nil_event))
continue; continue;
peffect->id = infos.field_id++; peffect->id = infos.field_id++;
...@@ -1391,8 +1391,8 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1391,8 +1391,8 @@ int32 field::process_phase_event(int16 step, int32 phase) {
pr = effects.trigger_o_effect.equal_range(phase_event); pr = effects.trigger_o_effect.equal_range(phase_event);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
if(!peffect->is_activateable(check_player, nil_event)) if(!peffect->is_activateable(check_player, nil_event))
continue; continue;
peffect->id = infos.field_id++; peffect->id = infos.field_id++;
...@@ -1414,8 +1414,8 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1414,8 +1414,8 @@ int32 field::process_phase_event(int16 step, int32 phase) {
pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN); pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
if(!peffect->is_chainable(check_player) || !peffect->is_activateable(check_player, nil_event)) if(!peffect->is_chainable(check_player) || !peffect->is_activateable(check_player, nil_event))
continue; continue;
peffect->id = infos.field_id++; peffect->id = infos.field_id++;
...@@ -1428,8 +1428,8 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1428,8 +1428,8 @@ int32 field::process_phase_event(int16 step, int32 phase) {
pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN); pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
if(!peffect->is_chainable(check_player) || !peffect->is_activateable(check_player, nil_event)) if(!peffect->is_chainable(check_player) || !peffect->is_activateable(check_player, nil_event))
continue; continue;
peffect->id = infos.field_id++; peffect->id = infos.field_id++;
...@@ -1449,7 +1449,7 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1449,7 +1449,7 @@ int32 field::process_phase_event(int16 step, int32 phase) {
core.units.begin()->step = 1; core.units.begin()->step = 1;
return FALSE; return FALSE;
} else if(tf_count == 0 && to_count == 1 && fc_count == 0 && cn_count == 0) { } else if(tf_count == 0 && to_count == 1 && fc_count == 0 && cn_count == 0) {
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_chains[0].triggering_effect->handler, check_player, 0); add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_chains[0].triggering_effect->get_handler(), check_player, 0);
return FALSE; return FALSE;
} else { } else {
pduel->write_buffer8(MSG_HINT); pduel->write_buffer8(MSG_HINT);
...@@ -1493,11 +1493,12 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1493,11 +1493,12 @@ int32 field::process_phase_event(int16 step, int32 phase) {
core.units.begin()->arg2 = is_opponent | priority_passed; core.units.begin()->arg2 = is_opponent | priority_passed;
chain newchain = core.select_chains[returns.ivalue[0]]; chain newchain = core.select_chains[returns.ivalue[0]];
effect* peffect = newchain.triggering_effect; effect* peffect = newchain.triggering_effect;
card* phandler = peffect->get_handler();
if(!(peffect->type & EFFECT_TYPE_ACTIONS)) { if(!(peffect->type & EFFECT_TYPE_ACTIONS)) {
if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY)) if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY))
remove_effect(peffect); remove_effect(peffect);
else else
peffect->handler->remove_effect(peffect); phandler->remove_effect(peffect);
adjust_all(); adjust_all();
core.units.begin()->step = 3; core.units.begin()->step = 3;
} else if(!(peffect->type & EFFECT_TYPE_CONTINUOUS)) { } else if(!(peffect->type & EFFECT_TYPE_CONTINUOUS)) {
...@@ -1507,12 +1508,12 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1507,12 +1508,12 @@ int32 field::process_phase_event(int16 step, int32 phase) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = nil_event; newchain.evt = nil_event;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = check_player; newchain.triggering_player = check_player;
core.new_chains.push_back(newchain); core.new_chains.push_back(newchain);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(check_player); peffect->dec_count(check_player);
core.select_chains.clear(); core.select_chains.clear();
add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0);
...@@ -1533,7 +1534,7 @@ int32 field::process_phase_event(int16 step, int32 phase) { ...@@ -1533,7 +1534,7 @@ int32 field::process_phase_event(int16 step, int32 phase) {
core.chain_limit = 0; core.chain_limit = 0;
} }
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0);
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
...@@ -1627,29 +1628,30 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1627,29 +1628,30 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
//forced trigger //forced trigger
for (auto clit = core.new_fchain_s.begin(); clit != core.new_fchain_s.end(); ++clit) { for (auto clit = core.new_fchain_s.begin(); clit != core.new_fchain_s.end(); ++clit) {
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
if(!peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER | EFFECT_FLAG_BOTH_SIDE) && peffect->handler->is_has_relation(*clit)) { card* phandler = peffect->get_handler();
clit->triggering_player = peffect->handler->current.controler; if(!peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER | EFFECT_FLAG_BOTH_SIDE) && phandler->is_has_relation(*clit)) {
clit->triggering_controler = peffect->handler->current.controler; clit->triggering_player = phandler->current.controler;
clit->triggering_location = peffect->handler->current.location; clit->triggering_controler = phandler->current.controler;
clit->triggering_sequence = peffect->handler->current.sequence; clit->triggering_location = phandler->current.location;
clit->triggering_sequence = phandler->current.sequence;
} }
uint8 tp = clit->triggering_player; uint8 tp = clit->triggering_player;
bool act = true; bool act = true;
if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE) if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)
&& (!(peffect->type & EFFECT_TYPE_FIELD) || peffect->handler->is_has_relation(*clit)) && (!(peffect->type & EFFECT_TYPE_FIELD) || phandler->is_has_relation(*clit))
&& (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43) && (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43)
|| !(peffect->handler->current.location & 0x43) || peffect->handler->is_position(POS_FACEUP))) { || !(phandler->current.location & 0x43) || phandler->is_position(POS_FACEUP))) {
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) {
if(tp == infos.turn_player) { if(tp == infos.turn_player) {
for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) { for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) {
if(tpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(tpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
} }
} else { } else {
for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) { for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) {
if(ntpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(ntpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
...@@ -1663,7 +1665,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1663,7 +1665,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
core.tpchain.push_back(*clit); core.tpchain.push_back(*clit);
else else
core.ntpchain.push_back(*clit); core.ntpchain.push_back(*clit);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(tp); peffect->dec_count(tp);
if(peffect->is_flag(EFFECT_FLAG_CVAL_CHECK)) if(peffect->is_flag(EFFECT_FLAG_CVAL_CHECK))
peffect->get_value(); peffect->get_value();
...@@ -1701,15 +1703,16 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1701,15 +1703,16 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} }
for (auto clit = core.new_ochain_s.begin(); clit != core.new_ochain_s.end(); ++clit) { for (auto clit = core.new_ochain_s.begin(); clit != core.new_ochain_s.end(); ++clit) {
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
if((!peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER | EFFECT_FLAG_BOTH_SIDE) && peffect->handler->is_has_relation(*clit)) card* phandler = peffect->get_handler();
if((!peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER | EFFECT_FLAG_BOTH_SIDE) && phandler->is_has_relation(*clit))
|| (!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && (peffect->type & EFFECT_TYPE_FIELD) || (!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && (peffect->type & EFFECT_TYPE_FIELD)
&& (peffect->range & LOCATION_HAND) && peffect->handler->current.location == LOCATION_HAND)) { && (peffect->range & LOCATION_HAND) && phandler->current.location == LOCATION_HAND)) {
if(!peffect->handler->is_has_relation(*clit)) if(!phandler->is_has_relation(*clit))
peffect->handler->create_relation(*clit); phandler->create_relation(*clit);
clit->triggering_player = peffect->handler->current.controler; clit->triggering_player = phandler->current.controler;
clit->triggering_controler = peffect->handler->current.controler; clit->triggering_controler = phandler->current.controler;
clit->triggering_location = peffect->handler->current.location; clit->triggering_location = phandler->current.location;
clit->triggering_sequence = peffect->handler->current.sequence; clit->triggering_sequence = phandler->current.sequence;
} }
if(clit->triggering_player == infos.turn_player) if(clit->triggering_player == infos.turn_player)
core.tpchain.push_back(*clit); core.tpchain.push_back(*clit);
...@@ -1739,12 +1742,13 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1739,12 +1742,13 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} }
auto clit = core.new_ochain_s.begin(); auto clit = core.new_ochain_s.begin();
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
card* phandler = peffect->get_handler();
uint8 tp = clit->triggering_player; uint8 tp = clit->triggering_player;
bool act = true; bool act = true;
if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE) if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)
&& (!(peffect->type & EFFECT_TYPE_FIELD) || peffect->handler->is_has_relation(*clit)) && (!(peffect->type & EFFECT_TYPE_FIELD) || phandler->is_has_relation(*clit))
&& (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43) && (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43)
|| !(peffect->handler->current.location & 0x43) || peffect->handler->is_position(POS_FACEUP))) { || !(phandler->current.location & 0x43) || phandler->is_position(POS_FACEUP))) {
if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && clit->triggering_location == LOCATION_HAND && (peffect->range & LOCATION_HAND)) { if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && clit->triggering_location == LOCATION_HAND && (peffect->range & LOCATION_HAND)) {
core.new_ochain_h.push_back(*clit); core.new_ochain_h.push_back(*clit);
act = false; act = false;
...@@ -1753,14 +1757,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1753,14 +1757,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) {
if(tp == infos.turn_player) { if(tp == infos.turn_player) {
for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) { for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) {
if(tpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(tpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
} }
} else { } else {
for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) { for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) {
if(ntpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(ntpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
...@@ -1772,7 +1776,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1772,7 +1776,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} else act = false; } else act = false;
if(act) { if(act) {
if(tp == core.current_player) if(tp == core.current_player)
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)peffect->handler, tp, 0); add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)phandler, tp, 0);
else { else {
core.tmp_chain.push_back(*clit); core.tmp_chain.push_back(*clit);
returns.ivalue[0] = FALSE; returns.ivalue[0] = FALSE;
...@@ -1788,7 +1792,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1788,7 +1792,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} }
auto clit = core.new_ochain_s.begin(); auto clit = core.new_ochain_s.begin();
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
uint8 tp = clit->triggering_player; uint8 tp = clit->triggering_player;
core.select_effects.clear(); core.select_effects.clear();
core.select_options.clear(); core.select_options.clear();
...@@ -1798,13 +1802,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1798,13 +1802,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
while(++clit != core.new_ochain_s.end()) { while(++clit != core.new_ochain_s.end()) {
++index; ++index;
peffect = clit->triggering_effect; peffect = clit->triggering_effect;
if(pcard != peffect->handler) card* phandler = peffect->get_handler();
if(pcard != phandler)
continue; continue;
bool act = true; bool act = true;
if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE) if(peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)
&& (!(peffect->type & EFFECT_TYPE_FIELD) || peffect->handler->is_has_relation(*clit)) && (!(peffect->type & EFFECT_TYPE_FIELD) || phandler->is_has_relation(*clit))
&& (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43) && (peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE || (clit->triggering_location & 0x43)
|| !(peffect->handler->current.location & 0x43) || peffect->handler->is_position(POS_FACEUP))) { || !(phandler->current.location & 0x43) || phandler->is_position(POS_FACEUP))) {
if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && clit->triggering_location == LOCATION_HAND && (peffect->range & LOCATION_HAND)) { if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && clit->triggering_location == LOCATION_HAND && (peffect->range & LOCATION_HAND)) {
continue; continue;
} else if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) || !(peffect->type & EFFECT_TYPE_FIELD) } else if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) || !(peffect->type & EFFECT_TYPE_FIELD)
...@@ -1812,14 +1817,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1812,14 +1817,14 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) {
if(tp == infos.turn_player) { if(tp == infos.turn_player) {
for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) { for(auto tpit = core.tpchain.begin(); tpit != core.tpchain.end(); ++tpit) {
if(tpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(tpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
} }
} else { } else {
for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) { for(auto ntpit = core.ntpchain.begin(); ntpit != core.ntpchain.end(); ++ntpit) {
if(ntpit->triggering_effect->handler->data.code == peffect->handler->data.code) { if(ntpit->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
...@@ -1841,7 +1846,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1841,7 +1846,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} }
clit = core.new_ochain_s.begin(); clit = core.new_ochain_s.begin();
peffect = clit->triggering_effect; peffect = clit->triggering_effect;
peffect->handler->set_status(STATUS_CHAINING, TRUE); peffect->get_handler()->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(tp); peffect->dec_count(tp);
if(tp == infos.turn_player) if(tp == infos.turn_player)
core.tpchain.push_back(*clit); core.tpchain.push_back(*clit);
...@@ -1885,16 +1890,17 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1885,16 +1890,17 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
e.reason_player = PLAYER_NONE; e.reason_player = PLAYER_NONE;
for(auto eit = effects.ignition_effect.begin(); eit != effects.ignition_effect.end(); ++eit) { for(auto eit = effects.ignition_effect.begin(); eit != effects.ignition_effect.end(); ++eit) {
effect* peffect = eit->second; effect* peffect = eit->second;
card* phandler = peffect->get_handler();
e.event_code = peffect->code; e.event_code = peffect->code;
if(peffect->handler->current.location == LOCATION_MZONE && peffect->is_chainable(infos.turn_player) if(phandler->current.location == LOCATION_MZONE && peffect->is_chainable(infos.turn_player)
&& peffect->is_activateable(infos.turn_player, e)) { && peffect->is_activateable(infos.turn_player, e)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = e; newchain.evt = e;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = infos.turn_player; newchain.triggering_player = infos.turn_player;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
} }
...@@ -1921,7 +1927,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1921,7 +1927,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
} }
if(core.current_chain.size()) { if(core.current_chain.size()) {
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, skip_trigger | ((skip_freechain | skip_new) << 8), skip_new); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, skip_trigger | ((skip_freechain | skip_new) << 8), skip_new);
} else { } else {
core.used_event.splice(core.used_event.end(), core.point_event); core.used_event.splice(core.used_event.end(), core.point_event);
...@@ -1940,7 +1946,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free ...@@ -1940,7 +1946,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
std::advance(clit, index); std::advance(clit, index);
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
uint8 tp = clit->triggering_player; uint8 tp = clit->triggering_player;
peffect->handler->set_status(STATUS_CHAINING, TRUE); peffect->get_handler()->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(tp); peffect->dec_count(tp);
if(tp == infos.turn_player) if(tp == infos.turn_player)
core.tpchain.push_back(*clit); core.tpchain.push_back(*clit);
...@@ -1965,19 +1971,20 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -1965,19 +1971,20 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
bool act = true; bool act = true;
for(auto ifit = core.quick_f_chain.begin(); ifit != core.quick_f_chain.end(); ++ifit) { for(auto ifit = core.quick_f_chain.begin(); ifit != core.quick_f_chain.end(); ++ifit) {
effect* peffect = ifit->first; effect* peffect = ifit->first;
card* phandler = peffect->get_handler();
if(peffect->is_chainable(ifit->second.triggering_player) && peffect->check_count_limit(ifit->second.triggering_player) if(peffect->is_chainable(ifit->second.triggering_player) && peffect->check_count_limit(ifit->second.triggering_player)
&& peffect->handler->is_has_relation(ifit->second)) { && phandler->is_has_relation(ifit->second)) {
if(ifit->second.triggering_player == infos.turn_player) { if(ifit->second.triggering_player == infos.turn_player) {
act = true; act = true;
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) {
for (auto cait = core.tpchain.begin(); cait != core.tpchain.end(); ++cait) { for (auto cait = core.tpchain.begin(); cait != core.tpchain.end(); ++cait) {
if (cait->triggering_effect->handler->data.code == peffect->handler->data.code) { if (cait->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
} }
for (auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) { for (auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) {
if ((cait->triggering_effect->handler->data.code == peffect->handler->data.code) if ((cait->triggering_effect->get_handler()->data.code == phandler->data.code)
&& (cait->triggering_player == infos.turn_player)) { && (cait->triggering_player == infos.turn_player)) {
act = false; act = false;
break; break;
...@@ -1986,20 +1993,20 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -1986,20 +1993,20 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
} }
if(act) { if(act) {
core.tpchain.push_back(ifit->second); core.tpchain.push_back(ifit->second);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(infos.turn_player); peffect->dec_count(infos.turn_player);
} }
} else { } else {
act = true; act = true;
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE)) {
for (auto cait = core.ntpchain.begin(); cait != core.ntpchain.end(); ++cait) { for (auto cait = core.ntpchain.begin(); cait != core.ntpchain.end(); ++cait) {
if (cait->triggering_effect->handler->data.code == peffect->handler->data.code) { if (cait->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
} }
for (auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) { for (auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) {
if ((cait->triggering_effect->handler->data.code == peffect->handler->data.code) if ((cait->triggering_effect->get_handler()->data.code == phandler->data.code)
&& (cait->triggering_player != infos.turn_player)) { && (cait->triggering_player != infos.turn_player)) {
act = false; act = false;
break; break;
...@@ -2008,7 +2015,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2008,7 +2015,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
} }
if(act) { if(act) {
core.ntpchain.push_back(ifit->second); core.ntpchain.push_back(ifit->second);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(1 - infos.turn_player); peffect->dec_count(1 - infos.turn_player);
} }
} }
...@@ -2034,16 +2041,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2034,16 +2041,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
auto pr = effects.activate_effect.equal_range(evit->event_code); auto pr = effects.activate_effect.equal_range(evit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
if(!peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) { if(!peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *evit; newchain.evt = *evit;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
} }
...@@ -2051,16 +2059,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2051,16 +2059,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
pr = effects.quick_o_effect.equal_range(evit->event_code); pr = effects.quick_o_effect.equal_range(evit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
if(peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) { if(peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *evit; newchain.evt = *evit;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
core.delayed_quick_tmp.erase(std::make_pair(peffect, *evit)); core.delayed_quick_tmp.erase(std::make_pair(peffect, *evit));
...@@ -2075,8 +2084,9 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2075,8 +2084,9 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
} }
for(auto clit = core.new_ochain_h.begin(); clit != core.new_ochain_h.end(); ++clit) { for(auto clit = core.new_ochain_h.begin(); clit != core.new_ochain_h.end(); ++clit) {
effect* peffect = clit->triggering_effect; effect* peffect = clit->triggering_effect;
card* phandler = peffect->get_handler();
bool act = true; bool act = true;
if(clit->triggering_player == priority && !peffect->handler->is_status(STATUS_CHAINING) && peffect->handler->is_has_relation(*clit) if(clit->triggering_player == priority && !phandler->is_status(STATUS_CHAINING) && phandler->is_has_relation(*clit)
&& peffect->is_chainable(priority) && peffect->is_activateable(priority, clit->evt, TRUE)) { && peffect->is_chainable(priority) && peffect->is_activateable(priority, clit->evt, TRUE)) {
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) { for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) {
if(cait->triggering_player == priority) { if(cait->triggering_player == priority) {
...@@ -2086,7 +2096,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2086,7 +2096,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
act = false; act = false;
break; break;
} }
if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE) && cait->triggering_effect->handler->data.code == peffect->handler->data.code) { if(peffect->is_flag(EFFECT_FLAG_CHAIN_UNIQUE) && cait->triggering_effect->get_handler()->data.code == phandler->data.code) {
act = false; act = false;
break; break;
} }
...@@ -2102,16 +2112,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2102,16 +2112,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
auto pr = effects.activate_effect.equal_range(evit->event_code); auto pr = effects.activate_effect.equal_range(evit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) { if(peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_chainable(priority) && peffect->is_activateable(priority, *evit)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *evit; newchain.evt = *evit;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
} }
...@@ -2120,17 +2131,18 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2120,17 +2131,18 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
// delayed quick // delayed quick
for(auto eit = core.delayed_quick.begin(); eit != core.delayed_quick.end(); ++eit) { for(auto eit = core.delayed_quick.begin(); eit != core.delayed_quick.end(); ++eit) {
effect* peffect = eit->first; effect* peffect = eit->first;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
const tevent& evt = eit->second; const tevent& evt = eit->second;
if(peffect->is_chainable(priority) && peffect->is_activateable(priority, evt, TRUE, FALSE, FALSE)) { if(peffect->is_chainable(priority) && peffect->is_activateable(priority, evt, TRUE, FALSE, FALSE)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = evt; newchain.evt = evt;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
} }
...@@ -2141,16 +2153,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2141,16 +2153,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN); auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
if(peffect->is_chainable(priority) && peffect->is_activateable(priority, nil_event)) { if(peffect->is_chainable(priority) && peffect->is_activateable(priority, nil_event)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = nil_event; newchain.evt = nil_event;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
if(check_hint_timing(peffect)) if(check_hint_timing(peffect))
...@@ -2160,16 +2173,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2160,16 +2173,17 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN); pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
if(peffect->is_chainable(priority) && peffect->is_activateable(priority, nil_event)) { if(peffect->is_chainable(priority) && peffect->is_activateable(priority, nil_event)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = nil_event; newchain.evt = nil_event;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = priority; newchain.triggering_player = priority;
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
if(check_hint_timing(peffect)) if(check_hint_timing(peffect))
...@@ -2197,7 +2211,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori ...@@ -2197,7 +2211,7 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
core.new_chains.push_back(newchain); core.new_chains.push_back(newchain);
effect* peffect = newchain.triggering_effect; effect* peffect = newchain.triggering_effect;
core.delayed_quick.erase(std::make_pair(peffect, newchain.evt)); core.delayed_quick.erase(std::make_pair(peffect, newchain.evt));
peffect->handler->set_status(STATUS_CHAINING, TRUE); peffect->get_handler()->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(priority); peffect->dec_count(priority);
add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0);
add_process(PROCESSOR_QUICK_EFFECT, 0, 0, 0, FALSE, 1 - priority); add_process(PROCESSOR_QUICK_EFFECT, 0, 0, 0, FALSE, 1 - priority);
...@@ -2263,65 +2277,68 @@ int32 field::process_instant_event() { ...@@ -2263,65 +2277,68 @@ int32 field::process_instant_event() {
pr = effects.trigger_f_effect.equal_range(elit->event_code); pr = effects.trigger_f_effect.equal_range(elit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
if(!peffect->handler->is_status(STATUS_EFFECT_ENABLED) || !peffect->is_condition_check(peffect->handler->current.controler, *elit)) card* phandler = peffect->get_handler();
if(!phandler->is_status(STATUS_EFFECT_ENABLED) || !peffect->is_condition_check(phandler->current.controler, *elit))
continue; continue;
peffect->s_range = peffect->handler->current.location; peffect->s_range = phandler->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = phandler->current.sequence;
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *elit; newchain.evt = *elit;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1)) if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1))
newchain.triggering_player = elit->event_player; newchain.triggering_player = elit->event_player;
else newchain.triggering_player = peffect->handler->current.controler; else newchain.triggering_player = phandler->current.controler;
core.new_fchain.push_back(newchain); core.new_fchain.push_back(newchain);
peffect->handler->create_relation(newchain); phandler->create_relation(newchain);
} }
pr = effects.trigger_o_effect.equal_range(elit->event_code); pr = effects.trigger_o_effect.equal_range(elit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
if(!peffect->handler->is_status(STATUS_EFFECT_ENABLED) || !peffect->is_condition_check(peffect->handler->current.controler, *elit)) card* phandler = peffect->get_handler();
if(!phandler->is_status(STATUS_EFFECT_ENABLED) || !peffect->is_condition_check(phandler->current.controler, *elit))
continue; continue;
peffect->s_range = peffect->handler->current.location; peffect->s_range = phandler->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = phandler->current.sequence;
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *elit; newchain.evt = *elit;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1)) if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1))
newchain.triggering_player = elit->event_player; newchain.triggering_player = elit->event_player;
else newchain.triggering_player = peffect->handler->current.controler; else newchain.triggering_player = phandler->current.controler;
core.new_ochain.push_back(newchain); core.new_ochain.push_back(newchain);
if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) if(peffect->is_flag(EFFECT_FLAG_FIELD_ONLY)
|| ((peffect->type & EFFECT_TYPE_SINGLE) && !peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE)) || ((peffect->type & EFFECT_TYPE_SINGLE) && !peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE))
|| !(peffect->range & LOCATION_HAND) || (peffect->range & peffect->handler->current.location)) || !(peffect->range & LOCATION_HAND) || (peffect->range & phandler->current.location))
peffect->handler->create_relation(newchain); phandler->create_relation(newchain);
} }
//instant_f //instant_f
pr = effects.quick_f_effect.equal_range(elit->event_code); pr = effects.quick_f_effect.equal_range(elit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; card* phandler = peffect->get_handler();
peffect->o_range = peffect->handler->current.sequence; peffect->s_range = phandler->current.location;
if(peffect->is_activateable(peffect->handler->current.controler, *elit)) { peffect->o_range = phandler->current.sequence;
if(peffect->is_activateable(phandler->current.controler, *elit)) {
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt = *elit; newchain.evt = *elit;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1)) if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1))
newchain.triggering_player = elit->event_player; newchain.triggering_player = elit->event_player;
else newchain.triggering_player = peffect->handler->current.controler; else newchain.triggering_player = phandler->current.controler;
core.quick_f_chain[peffect] = newchain; core.quick_f_chain[peffect] = newchain;
peffect->handler->create_relation(newchain); phandler->create_relation(newchain);
} }
} }
// delayed activate effect // delayed activate effect
...@@ -2330,7 +2347,7 @@ int32 field::process_instant_event() { ...@@ -2330,7 +2347,7 @@ int32 field::process_instant_event() {
pr = effects.quick_o_effect.equal_range(elit->event_code); pr = effects.quick_o_effect.equal_range(elit->event_code);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
if(peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_condition_check(peffect->handler->current.controler, *elit)) if(peffect->is_flag(EFFECT_FLAG_DELAY) && peffect->is_condition_check(peffect->get_handler()->current.controler, *elit))
core.delayed_quick_tmp.insert(std::make_pair(peffect, *elit)); core.delayed_quick_tmp.insert(std::make_pair(peffect, *elit));
} }
} }
...@@ -2356,79 +2373,15 @@ int32 field::process_single_event() { ...@@ -2356,79 +2373,15 @@ int32 field::process_single_event() {
card* starget = elit->trigger_card; card* starget = elit->trigger_card;
uint32 ev = elit->event_code; uint32 ev = elit->event_code;
auto pr = starget->single_effect.equal_range(ev); auto pr = starget->single_effect.equal_range(ev);
const tevent& e = *elit; for(; pr.first != pr.second; ++pr.first) {
for(; pr.first != pr.second;) {
effect* peffect = pr.first->second; effect* peffect = pr.first->second;
++pr.first; process_single_event(peffect, *elit, tp, ntp, tev, ntev);
if(!(peffect->type & EFFECT_TYPE_ACTIONS)) }
continue; for(auto ovit = starget->xyz_materials.begin(); ovit != starget->xyz_materials.end(); ++ovit) {
if((peffect->type & EFFECT_TYPE_FLIP) && (e.event_value & (NO_FLIP_EFFECT >> 16))) pr = (*ovit)->xmaterial_effect.equal_range(ev);
continue; for(; pr.first != pr.second; ++pr.first) {
//continuous & trigger (single) effect* peffect = pr.first->second;
if(peffect->type & EFFECT_TYPE_CONTINUOUS) { process_single_event(peffect, *elit, tp, ntp, tev, ntev);
uint8 owner_player = peffect->get_handler_player();
if(peffect->is_activateable(owner_player, e)) {
if(peffect->is_flag(EFFECT_FLAG_DELAY) && (core.chain_solving || core.conti_solving)) {
if(owner_player == infos.turn_player) {
core.delayed_tp.push_back(peffect);
core.delayed_tev.push_back(e);
} else {
core.delayed_ntp.push_back(peffect);
core.delayed_ntev.push_back(e);
}
} else {
if(owner_player == infos.turn_player) {
tp.push_back(peffect);
tev.push_back(e);
} else {
ntp.push_back(peffect);
ntev.push_back(e);
}
}
}
} else {
if(!peffect->is_condition_check(peffect->handler->current.controler, e))
continue;
peffect->s_range = peffect->handler->current.location;
peffect->o_range = peffect->handler->current.sequence;
chain newchain;
newchain.flag = 0;
newchain.chain_id = infos.field_id++;
newchain.evt = e;
newchain.triggering_effect = peffect;
newchain.triggering_controler = peffect->handler->current.controler;
newchain.triggering_location = peffect->handler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (elit->event_player == 0 || elit->event_player == 1))
newchain.triggering_player = elit->event_player;
else {
if(peffect->handler->current.reason & REASON_TEMPORARY)
newchain.triggering_player = peffect->handler->previous.controler;
else
newchain.triggering_player = newchain.triggering_controler;
}
if(core.flip_delayed && ev == EVENT_FLIP) {
if (peffect->type & EFFECT_TYPE_TRIGGER_O)
core.new_ochain_b.push_back(newchain);
else
core.new_fchain_b.push_back(newchain);
} else {
if (peffect->type & EFFECT_TYPE_TRIGGER_O)
core.new_ochain.push_back(newchain);
else
core.new_fchain.push_back(newchain);
}
peffect->handler->create_relation(newchain);
effect* deffect;
if(deffect = peffect->handler->is_affected_by_effect(EFFECT_DISABLE_EFFECT)) {
effect* negeff = pduel->new_effect();
negeff->owner = deffect->owner;
negeff->type = EFFECT_TYPE_SINGLE;
negeff->code = EFFECT_DISABLE_CHAIN;
negeff->value = newchain.chain_id;
negeff->reset_flag = RESET_EVENT | deffect->get_value();
peffect->handler->add_effect(negeff);
}
} }
} }
} }
...@@ -2445,6 +2398,80 @@ int32 field::process_single_event() { ...@@ -2445,6 +2398,80 @@ int32 field::process_single_event() {
core.single_event.clear(); core.single_event.clear();
return TRUE; return TRUE;
} }
int32 field::process_single_event(effect* peffect, const tevent& e, effect_vector& tp, effect_vector& ntp, event_list& tev, event_list& ntev) {
if(!(peffect->type & EFFECT_TYPE_ACTIONS))
return FALSE;
if((peffect->type & EFFECT_TYPE_FLIP) && (e.event_value & (NO_FLIP_EFFECT >> 16)))
return FALSE;
//continuous & trigger (single)
if(peffect->type & EFFECT_TYPE_CONTINUOUS) {
uint8 owner_player = peffect->get_handler_player();
if(peffect->is_activateable(owner_player, e)) {
if(peffect->is_flag(EFFECT_FLAG_DELAY) && (core.chain_solving || core.conti_solving)) {
if(owner_player == infos.turn_player) {
core.delayed_tp.push_back(peffect);
core.delayed_tev.push_back(e);
} else {
core.delayed_ntp.push_back(peffect);
core.delayed_ntev.push_back(e);
}
} else {
if(owner_player == infos.turn_player) {
tp.push_back(peffect);
tev.push_back(e);
} else {
ntp.push_back(peffect);
ntev.push_back(e);
}
}
}
} else {
card* phandler = peffect->get_handler();
if(!peffect->is_condition_check(phandler->current.controler, e))
return FALSE;
peffect->s_range = phandler->current.location;
peffect->o_range = phandler->current.sequence;
chain newchain;
newchain.flag = 0;
newchain.chain_id = infos.field_id++;
newchain.evt = e;
newchain.triggering_effect = peffect;
newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = phandler->current.sequence;
if(peffect->is_flag(EFFECT_FLAG_EVENT_PLAYER) && (e.event_player == 0 || e.event_player == 1))
newchain.triggering_player = e.event_player;
else {
if(phandler->current.reason & REASON_TEMPORARY)
newchain.triggering_player = phandler->previous.controler;
else
newchain.triggering_player = newchain.triggering_controler;
}
if(core.flip_delayed && e.event_code == EVENT_FLIP) {
if (peffect->type & EFFECT_TYPE_TRIGGER_O)
core.new_ochain_b.push_back(newchain);
else
core.new_fchain_b.push_back(newchain);
} else {
if (peffect->type & EFFECT_TYPE_TRIGGER_O)
core.new_ochain.push_back(newchain);
else
core.new_fchain.push_back(newchain);
}
phandler->create_relation(newchain);
effect* deffect;
if(deffect = phandler->is_affected_by_effect(EFFECT_DISABLE_EFFECT)) {
effect* negeff = pduel->new_effect();
negeff->owner = deffect->owner;
negeff->type = EFFECT_TYPE_SINGLE;
negeff->code = EFFECT_DISABLE_CHAIN;
negeff->value = newchain.chain_id;
negeff->reset_flag = RESET_EVENT | deffect->get_value();
phandler->add_effect(negeff);
}
}
return TRUE;
}
int32 field::process_idle_command(uint16 step) { int32 field::process_idle_command(uint16 step) {
switch(step) { switch(step) {
case 0: { case 0: {
...@@ -2498,8 +2525,8 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2498,8 +2525,8 @@ int32 field::process_idle_command(uint16 step) {
auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN); auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
if(peffect->is_activateable(infos.turn_player, nil_event)) if(peffect->is_activateable(infos.turn_player, nil_event))
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
...@@ -2507,16 +2534,16 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2507,16 +2534,16 @@ int32 field::process_idle_command(uint16 step) {
pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN); pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
if(peffect->is_activateable(infos.turn_player, nil_event)) if(peffect->is_activateable(infos.turn_player, nil_event))
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
} }
for(auto eit = effects.ignition_effect.begin(); eit != effects.ignition_effect.end(); ++eit) { for(auto eit = effects.ignition_effect.begin(); eit != effects.ignition_effect.end(); ++eit) {
peffect = eit->second; peffect = eit->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
if(peffect->is_activateable(infos.turn_player, nil_event)) if(peffect->is_activateable(infos.turn_player, nil_event))
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
...@@ -2533,7 +2560,7 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2533,7 +2560,7 @@ int32 field::process_idle_command(uint16 step) {
effect_set eset; effect_set eset;
filter_field_effect(EFFECT_SPSUMMON_PROC, &eset); filter_field_effect(EFFECT_SPSUMMON_PROC, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
pcard = eset[i]->handler; pcard = eset[i]->get_handler();
if(!eset[i]->check_count_limit(pcard->current.controler)) if(!eset[i]->check_count_limit(pcard->current.controler))
continue; continue;
if(pcard->current.controler == infos.turn_player && pcard->is_special_summonable(infos.turn_player, 0)) if(pcard->current.controler == infos.turn_player && pcard->is_special_summonable(infos.turn_player, 0))
...@@ -2542,7 +2569,7 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2542,7 +2569,7 @@ int32 field::process_idle_command(uint16 step) {
eset.clear(); eset.clear();
filter_field_effect(EFFECT_SPSUMMON_PROC_G, &eset); filter_field_effect(EFFECT_SPSUMMON_PROC_G, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
pcard = eset[i]->handler; pcard = eset[i]->get_handler();
if(!eset[i]->check_count_limit(infos.turn_player)) if(!eset[i]->check_count_limit(infos.turn_player))
continue; continue;
if(pcard->current.controler != infos.turn_player && !eset[i]->is_flag(EFFECT_FLAG_BOTH_SIDE)) if(pcard->current.controler != infos.turn_player && !eset[i]->is_flag(EFFECT_FLAG_BOTH_SIDE))
...@@ -2584,6 +2611,7 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2584,6 +2611,7 @@ int32 field::process_idle_command(uint16 step) {
if(ctype == 5) { if(ctype == 5) {
chain newchain = core.select_chains[sel]; chain newchain = core.select_chains[sel];
effect* peffect = newchain.triggering_effect; effect* peffect = newchain.triggering_effect;
card* phandler = peffect->get_handler();
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt.event_code = peffect->code; newchain.evt.event_code = peffect->code;
...@@ -2593,12 +2621,12 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2593,12 +2621,12 @@ int32 field::process_idle_command(uint16 step) {
newchain.evt.reason = 0; newchain.evt.reason = 0;
newchain.evt.reason_effect = 0; newchain.evt.reason_effect = 0;
newchain.evt.reason_player = PLAYER_NONE; newchain.evt.reason_player = PLAYER_NONE;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = infos.turn_player; newchain.triggering_player = infos.turn_player;
core.new_chains.push_back(newchain); core.new_chains.push_back(newchain);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(infos.turn_player); peffect->dec_count(infos.turn_player);
core.select_chains.clear(); core.select_chains.clear();
add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0);
...@@ -2649,7 +2677,7 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2649,7 +2677,7 @@ int32 field::process_idle_command(uint16 step) {
core.chain_limit = 0; core.chain_limit = 0;
} }
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0);
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
...@@ -2717,7 +2745,7 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2717,7 +2745,7 @@ int32 field::process_idle_command(uint16 step) {
} }
if(core.current_chain.size()) { if(core.current_chain.size()) {
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0);
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
...@@ -2793,8 +2821,8 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2793,8 +2821,8 @@ int32 field::process_battle_command(uint16 step) {
auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN); auto pr = effects.activate_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
if(peffect->is_activateable(infos.turn_player, nil_event) && peffect->get_speed() > 1) if(peffect->is_activateable(infos.turn_player, nil_event) && peffect->get_speed() > 1)
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
...@@ -2802,8 +2830,8 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2802,8 +2830,8 @@ int32 field::process_battle_command(uint16 step) {
pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN); pr = effects.quick_o_effect.equal_range(EVENT_FREE_CHAIN);
for(; pr.first != pr.second; ++pr.first) { for(; pr.first != pr.second; ++pr.first) {
peffect = pr.first->second; peffect = pr.first->second;
peffect->s_range = peffect->handler->current.location; peffect->s_range = peffect->get_handler()->current.location;
peffect->o_range = peffect->handler->current.sequence; peffect->o_range = peffect->get_handler()->current.sequence;
newchain.triggering_effect = peffect; newchain.triggering_effect = peffect;
if(peffect->is_activateable(infos.turn_player, nil_event)) if(peffect->is_activateable(infos.turn_player, nil_event))
core.select_chains.push_back(newchain); core.select_chains.push_back(newchain);
...@@ -2849,6 +2877,7 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2849,6 +2877,7 @@ int32 field::process_battle_command(uint16 step) {
if(ctype == 0) { if(ctype == 0) {
chain newchain = core.select_chains[sel]; chain newchain = core.select_chains[sel];
effect* peffect = newchain.triggering_effect; effect* peffect = newchain.triggering_effect;
card* phandler = peffect->get_handler();
newchain.flag = 0; newchain.flag = 0;
newchain.chain_id = infos.field_id++; newchain.chain_id = infos.field_id++;
newchain.evt.event_code = peffect->code; newchain.evt.event_code = peffect->code;
...@@ -2858,12 +2887,12 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2858,12 +2887,12 @@ int32 field::process_battle_command(uint16 step) {
newchain.evt.reason = 0; newchain.evt.reason = 0;
newchain.evt.reason_effect = 0; newchain.evt.reason_effect = 0;
newchain.evt.reason_player = PLAYER_NONE; newchain.evt.reason_player = PLAYER_NONE;
newchain.triggering_controler = peffect->handler->current.controler; newchain.triggering_controler = phandler->current.controler;
newchain.triggering_location = peffect->handler->current.location; newchain.triggering_location = phandler->current.location;
newchain.triggering_sequence = peffect->handler->current.sequence; newchain.triggering_sequence = phandler->current.sequence;
newchain.triggering_player = infos.turn_player; newchain.triggering_player = infos.turn_player;
core.new_chains.push_back(newchain); core.new_chains.push_back(newchain);
peffect->handler->set_status(STATUS_CHAINING, TRUE); phandler->set_status(STATUS_CHAINING, TRUE);
peffect->dec_count(infos.turn_player); peffect->dec_count(infos.turn_player);
core.select_chains.clear(); core.select_chains.clear();
add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0);
...@@ -2918,7 +2947,7 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2918,7 +2947,7 @@ int32 field::process_battle_command(uint16 step) {
core.chain_limit = 0; core.chain_limit = 0;
} }
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0);
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
...@@ -3599,7 +3628,7 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3599,7 +3628,7 @@ int32 field::process_battle_command(uint16 step) {
} }
if(core.current_chain.size()) { if(core.current_chain.size()) {
for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait) for(auto cait = core.current_chain.begin(); cait != core.current_chain.end(); ++cait)
cait->triggering_effect->handler->set_status(STATUS_CHAINING, FALSE); cait->triggering_effect->get_handler()->set_status(STATUS_CHAINING, FALSE);
add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0); add_process(PROCESSOR_SOLVE_CHAIN, 0, 0, 0, FALSE, 0);
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
...@@ -3925,7 +3954,7 @@ int32 field::process_turn(uint16 step, uint8 turn_player) { ...@@ -3925,7 +3954,7 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) { if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) {
for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) { for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) {
effect* peffect = *iter; effect* peffect = *iter;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
if(!peffect->is_flag(EFFECT_FLAG_NO_TURN_RESET)) { if(!peffect->is_flag(EFFECT_FLAG_NO_TURN_RESET)) {
pcard->spsummon_counter[0] = pcard->spsummon_counter[1] = 0; pcard->spsummon_counter[0] = pcard->spsummon_counter[1] = 0;
pcard->spsummon_counter_rst[0] = pcard->spsummon_counter_rst[1] = 0; pcard->spsummon_counter_rst[0] = pcard->spsummon_counter_rst[1] = 0;
...@@ -4172,10 +4201,11 @@ int32 field::process_turn(uint16 step, uint8 turn_player) { ...@@ -4172,10 +4201,11 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
int32 field::add_chain(uint16 step) { int32 field::add_chain(uint16 step) {
switch (step) { switch (step) {
case 0: { case 0: {
auto& clit = core.new_chains.front();
effect* peffect = clit.triggering_effect;
if (!core.new_chains.size()) if (!core.new_chains.size())
return TRUE; return TRUE;
auto& clit = core.new_chains.front();
effect* peffect = clit.triggering_effect;
card* phandler = peffect->get_handler();
effect_set eset; effect_set eset;
filter_player_effect(clit.triggering_player, EFFECT_ACTIVATE_COST, &eset); filter_player_effect(clit.triggering_player, EFFECT_ACTIVATE_COST, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
...@@ -4192,19 +4222,19 @@ int32 field::add_chain(uint16 step) { ...@@ -4192,19 +4222,19 @@ int32 field::add_chain(uint16 step) {
if(peffect->type & EFFECT_TYPE_ACTIVATE) { if(peffect->type & EFFECT_TYPE_ACTIVATE) {
break_effect(); break_effect();
int32 ecode = 0; int32 ecode = 0;
if(peffect->handler->current.location == LOCATION_HAND) { if(phandler->current.location == LOCATION_HAND) {
if(peffect->handler->data.type & TYPE_TRAP) if(phandler->data.type & TYPE_TRAP)
ecode = EFFECT_TRAP_ACT_IN_HAND; ecode = EFFECT_TRAP_ACT_IN_HAND;
else if((peffect->handler->data.type & TYPE_SPELL) && (peffect->handler->data.type & TYPE_QUICKPLAY) else if((phandler->data.type & TYPE_SPELL) && (phandler->data.type & TYPE_QUICKPLAY)
&& infos.turn_player != peffect->handler->current.controler) && infos.turn_player != phandler->current.controler)
ecode = EFFECT_QP_ACT_IN_NTPHAND; ecode = EFFECT_QP_ACT_IN_NTPHAND;
} else if(peffect->handler->current.location == LOCATION_SZONE) { } else if(phandler->current.location == LOCATION_SZONE) {
if((peffect->handler->data.type & TYPE_TRAP) && peffect->handler->get_status(STATUS_SET_TURN)) if((phandler->data.type & TYPE_TRAP) && phandler->get_status(STATUS_SET_TURN))
ecode = EFFECT_TRAP_ACT_IN_SET_TURN; ecode = EFFECT_TRAP_ACT_IN_SET_TURN;
} }
if(ecode) { if(ecode) {
eset.clear(); eset.clear();
peffect->handler->filter_effect(ecode, &eset); phandler->filter_effect(ecode, &eset);
effect* pactin = 0; effect* pactin = 0;
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
if(!eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT)) { if(!eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
...@@ -4214,30 +4244,30 @@ int32 field::add_chain(uint16 step) { ...@@ -4214,30 +4244,30 @@ int32 field::add_chain(uint16 step) {
} }
if(!pactin) { if(!pactin) {
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->check_count_limit(peffect->handler->current.controler)) { if(eset[i]->check_count_limit(phandler->current.controler)) {
eset[i]->dec_count(peffect->handler->current.controler); eset[i]->dec_count(phandler->current.controler);
break; break;
} }
} }
} }
} }
if(peffect->handler->current.location == LOCATION_HAND) { if(phandler->current.location == LOCATION_HAND) {
peffect->handler->enable_field_effect(false); phandler->enable_field_effect(false);
peffect->handler->set_status(STATUS_ACT_FROM_HAND, TRUE); phandler->set_status(STATUS_ACT_FROM_HAND, TRUE);
move_to_field(peffect->handler, peffect->handler->current.controler, peffect->handler->current.controler, LOCATION_SZONE, POS_FACEUP); move_to_field(phandler, phandler->current.controler, phandler->current.controler, LOCATION_SZONE, POS_FACEUP);
} else { } else {
peffect->handler->set_status(STATUS_ACT_FROM_HAND, FALSE); phandler->set_status(STATUS_ACT_FROM_HAND, FALSE);
change_position(peffect->handler, 0, peffect->handler->current.controler, POS_FACEUP, 0); change_position(phandler, 0, phandler->current.controler, POS_FACEUP, 0);
} }
} }
if(peffect->handler->current.location & 0x30) if(phandler->current.location & 0x30)
move_card(peffect->handler->current.controler, peffect->handler, peffect->handler->current.location, 0); move_card(phandler->current.controler, phandler, phandler->current.location, 0);
return FALSE; return FALSE;
} }
case 1: { case 1: {
auto& clit = core.new_chains.front(); auto& clit = core.new_chains.front();
effect* peffect = clit.triggering_effect; effect* peffect = clit.triggering_effect;
card* phandler = peffect->handler; card* phandler = peffect->get_handler();
if(peffect->type & EFFECT_TYPE_ACTIVATE) { if(peffect->type & EFFECT_TYPE_ACTIVATE) {
clit.triggering_controler = phandler->current.controler; clit.triggering_controler = phandler->current.controler;
clit.triggering_location = phandler->current.location; clit.triggering_location = phandler->current.location;
...@@ -4256,10 +4286,11 @@ int32 field::add_chain(uint16 step) { ...@@ -4256,10 +4286,11 @@ int32 field::add_chain(uint16 step) {
luaL_unref(pduel->lua->lua_state, LUA_REGISTRYINDEX, core.chain_limit); luaL_unref(pduel->lua->lua_state, LUA_REGISTRYINDEX, core.chain_limit);
core.chain_limit = 0; core.chain_limit = 0;
} }
peffect->card_type = peffect->handler->get_type(); peffect->card_type = phandler->get_type();
if((peffect->card_type & 0x5) == 0x5) if((peffect->card_type & 0x5) == 0x5)
peffect->card_type -= TYPE_TRAP; peffect->card_type -= TYPE_TRAP;
peffect->active_type = peffect->card_type; peffect->active_type = peffect->card_type;
peffect->active_handler = peffect->handler->overlay_target;
clit.chain_count = core.current_chain.size() + 1; clit.chain_count = core.current_chain.size() + 1;
clit.target_cards = 0; clit.target_cards = 0;
clit.target_player = PLAYER_NONE; clit.target_player = PLAYER_NONE;
...@@ -4273,7 +4304,7 @@ int32 field::add_chain(uint16 step) { ...@@ -4273,7 +4304,7 @@ int32 field::add_chain(uint16 step) {
check_chain_counter(peffect, clit.triggering_player, clit.chain_count); check_chain_counter(peffect, clit.triggering_player, clit.chain_count);
// triggered events which are not caused by RaiseEvent create relation with the handler // triggered events which are not caused by RaiseEvent create relation with the handler
if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && (!(peffect->type & 0x2a0) || (peffect->code & EVENT_PHASE) == EVENT_PHASE)) { if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) && (!(peffect->type & 0x2a0) || (peffect->code & EVENT_PHASE) == EVENT_PHASE)) {
peffect->handler->create_relation(clit); phandler->create_relation(clit);
} }
peffect->effect_owner = clit.triggering_player; peffect->effect_owner = clit.triggering_player;
// DISABLE_CHAIN should be check before cost // DISABLE_CHAIN should be check before cost
...@@ -4307,6 +4338,7 @@ int32 field::add_chain(uint16 step) { ...@@ -4307,6 +4338,7 @@ int32 field::add_chain(uint16 step) {
break_effect(); break_effect();
auto& clit = core.current_chain.back(); auto& clit = core.current_chain.back();
effect* peffect = clit.triggering_effect; effect* peffect = clit.triggering_effect;
card* phandler = peffect->get_handler();
if(clit.target_cards && clit.target_cards->container.size()) { if(clit.target_cards && clit.target_cards->container.size()) {
if(peffect->is_flag(EFFECT_FLAG_CARD_TARGET)) { if(peffect->is_flag(EFFECT_FLAG_CARD_TARGET)) {
for(auto cit = clit.target_cards->container.begin(); cit != clit.target_cards->container.end(); ++cit) for(auto cit = clit.target_cards->container.begin(); cit != clit.target_cards->container.end(); ++cit)
...@@ -4317,10 +4349,10 @@ int32 field::add_chain(uint16 step) { ...@@ -4317,10 +4349,10 @@ int32 field::add_chain(uint16 step) {
} }
} }
if(peffect->type & EFFECT_TYPE_ACTIVATE) { if(peffect->type & EFFECT_TYPE_ACTIVATE) {
core.leave_confirmed.insert(peffect->handler); core.leave_confirmed.insert(phandler);
if(!(peffect->handler->data.type & (TYPE_CONTINUOUS + TYPE_FIELD + TYPE_EQUIP + TYPE_PENDULUM)) if(!(phandler->data.type & (TYPE_CONTINUOUS + TYPE_FIELD + TYPE_EQUIP + TYPE_PENDULUM))
&& !peffect->handler->is_affected_by_effect(EFFECT_REMAIN_FIELD)) && !phandler->is_affected_by_effect(EFFECT_REMAIN_FIELD))
peffect->handler->set_status(STATUS_LEAVE_CONFIRMED, TRUE); phandler->set_status(STATUS_LEAVE_CONFIRMED, TRUE);
} }
core.phase_action = TRUE; core.phase_action = TRUE;
if(clit.opinfos.count(0x200)) { if(clit.opinfos.count(0x200)) {
...@@ -4359,7 +4391,7 @@ int32 field::add_chain(uint16 step) { ...@@ -4359,7 +4391,7 @@ int32 field::add_chain(uint16 step) {
} }
pduel->write_buffer8(MSG_CHAINED); pduel->write_buffer8(MSG_CHAINED);
pduel->write_buffer8(clit.chain_count); pduel->write_buffer8(clit.chain_count);
raise_event(peffect->handler, EVENT_CHAINING, peffect, 0, clit.triggering_player, clit.triggering_player, clit.chain_count); raise_event(phandler, EVENT_CHAINING, peffect, 0, clit.triggering_player, clit.triggering_player, clit.chain_count);
process_instant_event(); process_instant_event();
if(core.new_chains.size()) if(core.new_chains.size())
add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0); add_process(PROCESSOR_ADD_CHAIN, 0, 0, 0, 0, 0);
...@@ -4375,10 +4407,10 @@ int32 field::sort_chain(uint16 step, uint8 tp) { ...@@ -4375,10 +4407,10 @@ int32 field::sort_chain(uint16 step, uint8 tp) {
core.select_cards.clear(); core.select_cards.clear();
if(tp) if(tp)
for(auto clit = core.tpchain.begin(); clit != core.tpchain.end(); ++clit) for(auto clit = core.tpchain.begin(); clit != core.tpchain.end(); ++clit)
core.select_cards.push_back(clit->triggering_effect->handler); core.select_cards.push_back(clit->triggering_effect->get_handler());
else else
for(auto clit = core.ntpchain.begin(); clit != core.ntpchain.end(); ++clit) for(auto clit = core.ntpchain.begin(); clit != core.ntpchain.end(); ++clit)
core.select_cards.push_back(clit->triggering_effect->handler); core.select_cards.push_back(clit->triggering_effect->get_handler());
add_process(PROCESSOR_SORT_CARD, 0, 0, 0, tp ? infos.turn_player : (1 - infos.turn_player), 1); add_process(PROCESSOR_SORT_CARD, 0, 0, 0, tp ? infos.turn_player : (1 - infos.turn_player), 1);
return FALSE; return FALSE;
} }
...@@ -4517,7 +4549,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2 ...@@ -4517,7 +4549,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
} }
pduel->write_buffer8(MSG_CHAIN_SOLVING); pduel->write_buffer8(MSG_CHAIN_SOLVING);
pduel->write_buffer8(cait->chain_count); pduel->write_buffer8(cait->chain_count);
add_to_disable_check_list(cait->triggering_effect->handler); add_to_disable_check_list(cait->triggering_effect->get_handler());
adjust_instant(); adjust_instant();
raise_event((card*)0, EVENT_CHAIN_ACTIVATING, cait->triggering_effect, 0, cait->triggering_player, cait->triggering_player, cait->chain_count); raise_event((card*)0, EVENT_CHAIN_ACTIVATING, cait->triggering_effect, 0, cait->triggering_player, cait->triggering_player, cait->chain_count);
process_instant_event(); process_instant_event();
...@@ -4541,7 +4573,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2 ...@@ -4541,7 +4573,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
oeit->second = 0; oeit->second = 0;
break_effect(); break_effect();
core.chain_solving = TRUE; core.chain_solving = TRUE;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
if((peffect->type & EFFECT_TYPE_ACTIVATE) && pcard->is_has_relation(*cait)) { if((peffect->type & EFFECT_TYPE_ACTIVATE) && pcard->is_has_relation(*cait)) {
pcard->set_status(STATUS_ACTIVATED, TRUE); pcard->set_status(STATUS_ACTIVATED, TRUE);
pcard->enable_field_effect(true); pcard->enable_field_effect(true);
...@@ -4561,7 +4593,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2 ...@@ -4561,7 +4593,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
case 2: { case 2: {
core.spsummon_state_count_tmp[0] = core.spsummon_state_count[0]; core.spsummon_state_count_tmp[0] = core.spsummon_state_count[0];
core.spsummon_state_count_tmp[1] = core.spsummon_state_count[1]; core.spsummon_state_count_tmp[1] = core.spsummon_state_count[1];
card* pcard = cait->triggering_effect->handler; card* pcard = cait->triggering_effect->get_handler();
if(is_chain_disablable(cait->chain_count)) { if(is_chain_disablable(cait->chain_count)) {
if(is_chain_disabled(cait->chain_count) || (pcard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && pcard->is_has_relation(*cait))) { if(is_chain_disabled(cait->chain_count) || (pcard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && pcard->is_has_relation(*cait))) {
if(!(cait->flag & CHAIN_DISABLE_EFFECT)) { if(!(cait->flag & CHAIN_DISABLE_EFFECT)) {
...@@ -4662,7 +4694,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2 ...@@ -4662,7 +4694,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
} }
case 10: { case 10: {
effect* peffect = cait->triggering_effect; effect* peffect = cait->triggering_effect;
card* pcard = peffect->handler; card* pcard = peffect->get_handler();
if((cait->flag & CHAIN_HAND_EFFECT) && !pcard->is_position(POS_FACEUP) && (pcard->current.location == LOCATION_HAND)) if((cait->flag & CHAIN_HAND_EFFECT) && !pcard->is_position(POS_FACEUP) && (pcard->current.location == LOCATION_HAND))
shuffle(pcard->current.controler, LOCATION_HAND); shuffle(pcard->current.controler, LOCATION_HAND);
if(cait->target_cards && cait->target_cards->container.size()) { if(cait->target_cards && cait->target_cards->container.size()) {
...@@ -4681,6 +4713,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2 ...@@ -4681,6 +4713,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
} }
} }
peffect->active_type = 0; peffect->active_type = 0;
peffect->active_handler = 0;
pcard->release_relation(*cait); pcard->release_relation(*cait);
if(cait->target_cards) if(cait->target_cards)
pduel->delete_group(cait->target_cards); pduel->delete_group(cait->target_cards);
...@@ -4752,8 +4785,8 @@ int32 field::break_effect() { ...@@ -4752,8 +4785,8 @@ int32 field::break_effect() {
if (peffect->is_flag(EFFECT_FLAG_FIELD_ONLY) if (peffect->is_flag(EFFECT_FLAG_FIELD_ONLY)
|| !(peffect->type & EFFECT_TYPE_FIELD) || peffect->in_range(rm->triggering_location, rm->triggering_sequence)) { || !(peffect->type & EFFECT_TYPE_FIELD) || peffect->in_range(rm->triggering_location, rm->triggering_sequence)) {
pduel->write_buffer8(MSG_MISSED_EFFECT); pduel->write_buffer8(MSG_MISSED_EFFECT);
pduel->write_buffer32(peffect->handler->get_info_location()); pduel->write_buffer32(peffect->get_handler()->get_info_location());
pduel->write_buffer32(peffect->handler->data.code); pduel->write_buffer32(peffect->get_handler()->data.code);
} }
core.new_ochain.erase(rm); core.new_ochain.erase(rm);
} }
......
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