Commit 9a9a8860 authored by salix5's avatar salix5 Committed by GitHub

add get_code_type() (#406)

return: the type of bit field in code
parent 451e3866
...@@ -1583,8 +1583,7 @@ void card::apply_field_effect() { ...@@ -1583,8 +1583,7 @@ void card::apply_field_effect() {
if (current.controler == PLAYER_NONE) if (current.controler == PLAYER_NONE)
return; return;
for (auto& it : field_effect) { for (auto& it : field_effect) {
if (it.second->in_range(this) if (it.second->in_range(this) || it.second->is_hand_trigger()) {
|| ((it.second->range & LOCATION_HAND) && (it.second->type & EFFECT_TYPE_TRIGGER_O) && !(it.second->code & EVENT_PHASE))) {
pduel->game_field->add_effect(it.second); pduel->game_field->add_effect(it.second);
} }
} }
...@@ -1596,8 +1595,7 @@ void card::cancel_field_effect() { ...@@ -1596,8 +1595,7 @@ void card::cancel_field_effect() {
if (current.controler == PLAYER_NONE) if (current.controler == PLAYER_NONE)
return; return;
for (auto& it : field_effect) { for (auto& it : field_effect) {
if (it.second->in_range(this) if (it.second->in_range(this) || it.second->is_hand_trigger()) {
|| ((it.second->range & LOCATION_HAND) && (it.second->type & EFFECT_TYPE_TRIGGER_O) && !(it.second->code & EVENT_PHASE))) {
pduel->game_field->remove_effect(it.second); pduel->game_field->remove_effect(it.second);
} }
} }
...@@ -1726,14 +1724,14 @@ int32 card::add_effect(effect* peffect) { ...@@ -1726,14 +1724,14 @@ int32 card::add_effect(effect* peffect) {
indexer.emplace(peffect, eit); indexer.emplace(peffect, eit);
peffect->handler = this; peffect->handler = this;
if((peffect->type & EFFECT_TYPE_FIELD)) { if((peffect->type & EFFECT_TYPE_FIELD)) {
if(peffect->in_range(this) if(peffect->in_range(this) || current.controler != PLAYER_NONE && peffect->is_hand_trigger())
|| current.controler != PLAYER_NONE && ((peffect->range & LOCATION_HAND) && (peffect->type & EFFECT_TYPE_TRIGGER_O) && !(peffect->code & EVENT_PHASE)))
pduel->game_field->add_effect(peffect); pduel->game_field->add_effect(peffect);
} }
if (current.controler != PLAYER_NONE && !check_target.empty()) { if (current.controler != PLAYER_NONE && !check_target.empty()) {
if(peffect->is_disable_related()) if (peffect->is_disable_related()) {
for(auto& target : check_target) for (auto& target : check_target)
pduel->game_field->add_to_disable_check_list(target); pduel->game_field->add_to_disable_check_list(target);
}
} }
if(peffect->is_flag(EFFECT_FLAG_OATH)) { if(peffect->is_flag(EFFECT_FLAG_OATH)) {
pduel->game_field->effects.oath.emplace(peffect, reason_effect); pduel->game_field->effects.oath.emplace(peffect, reason_effect);
...@@ -1796,14 +1794,14 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) { ...@@ -1796,14 +1794,14 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) {
pduel->game_field->update_disable_check_list(peffect); pduel->game_field->update_disable_check_list(peffect);
} }
field_effect.erase(it); field_effect.erase(it);
if(peffect->in_range(this) if(peffect->in_range(this) || current.controler != PLAYER_NONE && peffect->is_hand_trigger())
|| current.controler != PLAYER_NONE && ((peffect->range & LOCATION_HAND) && (peffect->type & EFFECT_TYPE_TRIGGER_O) && !(peffect->code & EVENT_PHASE)))
pduel->game_field->remove_effect(peffect); pduel->game_field->remove_effect(peffect);
} }
if ((current.controler != PLAYER_NONE) && !get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && !check_target.empty()) { if ((current.controler != PLAYER_NONE) && !get_status(STATUS_DISABLED | STATUS_FORBIDDEN) && !check_target.empty()) {
if (peffect->is_disable_related()) if (peffect->is_disable_related()) {
for(auto& target : check_target) for (auto& target : check_target)
pduel->game_field->add_to_disable_check_list(target); pduel->game_field->add_to_disable_check_list(target);
}
} }
if (peffect->is_flag(EFFECT_FLAG_INITIAL) && peffect->copy_id && is_status(STATUS_EFFECT_REPLACED)) { if (peffect->is_flag(EFFECT_FLAG_INITIAL) && peffect->copy_id && is_status(STATUS_EFFECT_REPLACED)) {
set_status(STATUS_EFFECT_REPLACED, FALSE); set_status(STATUS_EFFECT_REPLACED, FALSE);
......
...@@ -13,7 +13,19 @@ ...@@ -13,7 +13,19 @@
bool effect_sort_id(const effect* e1, const effect* e2) { bool effect_sort_id(const effect* e1, const effect* e2) {
return e1->id < e2->id; return e1->id < e2->id;
}; }
// return: code is an event reserved for EFFECT_TYPE_CONTINUOUS or not
bool is_continuous_event(uint32 code) {
if (code & EVENT_CUSTOM)
return false;
else if (code & 0xf0000)
return false;
else if (code & 0xf000)
return !!(code & EVENT_PHASE_START);
else
return continuous_event.find(code) != continuous_event.end();
}
effect::effect(duel* pd) { effect::effect(duel* pd) {
ref_handle = 0; ref_handle = 0;
pduel = pd; pduel = pd;
...@@ -585,6 +597,9 @@ int32 effect::is_chainable(uint8 tp) { ...@@ -585,6 +597,9 @@ int32 effect::is_chainable(uint8 tp) {
} }
return TRUE; return TRUE;
} }
int32 effect::is_hand_trigger() {
return (range & LOCATION_HAND) && (type & EFFECT_TYPE_TRIGGER_O) && get_code_type() != CODE_PHASE;
}
//return: this can be reset by reset_level or not //return: this can be reset by reset_level or not
//RESET_DISABLE is valid only when owner == handler //RESET_DISABLE is valid only when owner == handler
int32 effect::reset(uint32 reset_level, uint32 reset_type) { int32 effect::reset(uint32 reset_level, uint32 reset_type) {
...@@ -817,3 +832,14 @@ uint32 effect::get_active_type() { ...@@ -817,3 +832,14 @@ uint32 effect::get_active_type() {
} else } else
return owner->get_type(); return owner->get_type();
} }
int32 effect::get_code_type() {
// start from the highest bit
if (code & EVENT_CUSTOM)
return CODE_CUSTOM;
else if (code & 0xf0000)
return CODE_COUNTER;
else if (code & 0xf000)
return CODE_PHASE;
else
return CODE_VALUE;
}
...@@ -83,6 +83,7 @@ public: ...@@ -83,6 +83,7 @@ public:
int32 is_player_effect_target(card* pcard); int32 is_player_effect_target(card* pcard);
int32 is_immuned(card* pcard); int32 is_immuned(card* pcard);
int32 is_chainable(uint8 tp); int32 is_chainable(uint8 tp);
int32 is_hand_trigger();
int32 reset(uint32 reset_level, uint32 reset_type); int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint32 playerid = 2); void dec_count(uint32 playerid = 2);
void recharge(); void recharge();
...@@ -105,6 +106,8 @@ public: ...@@ -105,6 +106,8 @@ public:
void set_activate_location(); void set_activate_location();
void set_active_type(); void set_active_type();
uint32 get_active_type(); uint32 get_active_type();
int32 get_code_type();
bool is_flag(effect_flag flag) const { bool is_flag(effect_flag flag) const {
return !!(this->flag[0] & flag); return !!(this->flag[0] & flag);
} }
...@@ -533,4 +536,14 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -533,4 +536,14 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define DOUBLE_DAMAGE 0x80000000 #define DOUBLE_DAMAGE 0x80000000
#define HALF_DAMAGE 0x80000001 #define HALF_DAMAGE 0x80000001
// The type of bit field in code
#define CODE_CUSTOM 1 // header + id (28 bits)
#define CODE_COUNTER 2 // header + counter_id (16 bits)
#define CODE_PHASE 3 // header + phase_id (12 bits)
#define CODE_VALUE 4 // numeric value, max = 4095
const std::unordered_set<uint32> continuous_event({ EVENT_ADJUST, EVENT_BREAK_EFFECT, EVENT_TURN_END });
bool is_continuous_event(uint32 code);
#endif /* EFFECT_H_ */ #endif /* EFFECT_H_ */
...@@ -1813,7 +1813,7 @@ int32 field::process_instant_event() { ...@@ -1813,7 +1813,7 @@ int32 field::process_instant_event() {
} }
} }
} }
if(ev.event_code == EVENT_ADJUST || ev.event_code == EVENT_BREAK_EFFECT || ((ev.event_code & 0xf000) == EVENT_PHASE_START) && ((ev.event_code & EVENT_CUSTOM) == 0)) if (is_continuous_event(ev.event_code))
continue; continue;
//triggers //triggers
pr = effects.trigger_f_effect.equal_range(ev.event_code); pr = effects.trigger_f_effect.equal_range(ev.event_code);
...@@ -4031,8 +4031,9 @@ int32 field::add_chain(uint16 step) { ...@@ -4031,8 +4031,9 @@ int32 field::add_chain(uint16 step) {
clit.flag |= CHAIN_HAND_EFFECT; clit.flag |= CHAIN_HAND_EFFECT;
core.current_chain.push_back(clit); core.current_chain.push_back(clit);
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 event 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 & (EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_TRIGGER_O)) || peffect->get_code_type() == CODE_PHASE)) {
phandler->create_relation(clit); phandler->create_relation(clit);
} }
peffect->effect_owner = clit.triggering_player; peffect->effect_owner = clit.triggering_player;
...@@ -4194,7 +4195,7 @@ int32 field::solve_continuous(uint16 step) { ...@@ -4194,7 +4195,7 @@ int32 field::solve_continuous(uint16 step) {
return TRUE; return TRUE;
} }
core.continuous_chain.push_back(clit); core.continuous_chain.push_back(clit);
if(peffect->is_flag(EFFECT_FLAG_DELAY) || !(peffect->code & 0x10030000) && (peffect->code & (EVENT_PHASE | EVENT_PHASE_START))) if(peffect->is_flag(EFFECT_FLAG_DELAY) || peffect->get_code_type() == CODE_PHASE)
core.conti_solving = TRUE; core.conti_solving = TRUE;
core.units.begin()->ptarget = (group*)core.reason_effect; core.units.begin()->ptarget = (group*)core.reason_effect;
core.units.begin()->arg2 = core.reason_player; core.units.begin()->arg2 = core.reason_player;
...@@ -4232,7 +4233,7 @@ int32 field::solve_continuous(uint16 step) { ...@@ -4232,7 +4233,7 @@ int32 field::solve_continuous(uint16 step) {
} }
core.continuous_chain.pop_back(); core.continuous_chain.pop_back();
core.solving_continuous.pop_front(); core.solving_continuous.pop_front();
if(peffect->is_flag(EFFECT_FLAG_DELAY) || !(peffect->code & 0x10030000) && (peffect->code & (EVENT_PHASE | EVENT_PHASE_START))) { if(peffect->is_flag(EFFECT_FLAG_DELAY) || peffect->get_code_type() == CODE_PHASE) {
core.conti_solving = FALSE; core.conti_solving = FALSE;
adjust_all(); adjust_all();
return FALSE; return FALSE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment