Commit 447f9d57 authored by Momobako's avatar Momobako

updc

parent 7824d5c6
......@@ -172,7 +172,7 @@ int32 effect::check_count_limit(uint8 playerid) {
// check if an EFFECT_TYPE_ACTIONS effect can be activated
// for triggering effects, it checks EFFECT_FLAG_DAMAGE_STEP, EFFECT_FLAG_SET_AVAILABLE
// for continuous effect, it checks EFFECT_FLAG_AVAILABLE_BD
int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target, int32 neglect_loc) {
int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target, int32 neglect_loc, int32 neglect_faceup) {
if(!(type & EFFECT_TYPE_ACTIONS))
return FALSE;
if(!check_count_limit(playerid))
......@@ -184,9 +184,11 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(pduel->game_field->check_unique_onfield(handler, playerid, LOCATION_SZONE))
return FALSE;
if(!(handler->data.type & TYPE_COUNTER)) {
if((code < 1132 || code > 1149) && pduel->game_field->infos.phase == PHASE_DAMAGE && !is_flag(EFFECT_FLAG_DAMAGE_STEP))
if((code < 1132 || code > 1149) && pduel->game_field->infos.phase == PHASE_DAMAGE && !is_flag(EFFECT_FLAG_DAMAGE_STEP)
&& !pduel->game_field->get_cteffect(this, playerid, FALSE))
return FALSE;
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)
&& !pduel->game_field->get_cteffect(this, playerid, FALSE))
return FALSE;
}
// additional check for each location
......@@ -247,7 +249,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if((phandler->data.type & TYPE_MONSTER) && (phandler->current.location & LOCATION_SZONE)
&& !in_range(phandler))
return FALSE;
if((phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED))) {
if(!neglect_faceup && (phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED))) {
// effects which can be activated while face-down:
// 1. effects with EFFECT_FLAG_SET_AVAILABLE
// 2. events with FLIP_SET_AVAILABLE
......
......@@ -69,7 +69,7 @@ public:
int32 is_can_be_forbidden();
int32 is_available();
int32 check_count_limit(uint8 playerid);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE, int32 neglect_faceup = FALSE);
int32 is_action_check(uint8 playerid);
int32 is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE);
int32 is_condition_check(uint8 playerid, const tevent& e);
......
......@@ -3326,6 +3326,64 @@ chain* field::get_chain(uint32 chaincount) {
}
return &core.current_chain[chaincount - 1];
}
int32 field::get_cteffect(effect* peffect, int32 playerid, int32 store) {
card* phandler = peffect->get_handler();
if(phandler->data.type != (TYPE_TRAP | TYPE_CONTINUOUS))
return FALSE;
if(!(peffect->type & EFFECT_TYPE_ACTIVATE))
return FALSE;
if(peffect->code != EVENT_FREE_CHAIN)
return FALSE;
if(peffect->cost || peffect->target || peffect->operation)
return FALSE;
if(store) {
core.select_chains.clear();
core.select_options.clear();
}
const bool damage_step = infos.phase == PHASE_DAMAGE && !peffect->is_flag(EFFECT_FLAG_DAMAGE_STEP);
const bool damage_cal = infos.phase == PHASE_DAMAGE_CAL && !peffect->is_flag(EFFECT_FLAG_DAMAGE_CAL);
for(auto efit = phandler->field_effect.begin(); efit != phandler->field_effect.end(); ++efit) {
effect* feffect = efit->second;
if(!(feffect->type & (EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_QUICK_O)))
continue;
if(damage_step && !feffect->is_flag(EFFECT_FLAG_DAMAGE_STEP))
continue;
if(damage_cal && !feffect->is_flag(EFFECT_FLAG_DAMAGE_CAL))
continue;
uint32 code = efit->first;
if(code == EVENT_FREE_CHAIN || code == EVENT_PHASE + infos.phase) {
nil_event.event_code = code;
if(get_cteffect_evt(feffect, playerid, nil_event, store) && !store)
return TRUE;
} else {
for(auto evit = core.point_event.begin(); evit != core.point_event.end(); ++evit) {
if(code != evit->event_code)
continue;
if(get_cteffect_evt(feffect, playerid, *evit, store) && !store)
return TRUE;
}
for(auto evit = core.instant_event.begin(); evit != core.instant_event.end(); ++evit) {
if(code != evit->event_code)
continue;
if(get_cteffect_evt(feffect, playerid, *evit, store) && !store)
return TRUE;
}
}
}
return (store && !core.select_chains.empty()) ? TRUE : FALSE;
}
int32 field::get_cteffect_evt(effect* feffect, int32 playerid, const tevent& e, int32 store) {
if(!feffect->is_activateable(playerid, e, FALSE, FALSE, FALSE, FALSE, TRUE))
return FALSE;
if(store) {
chain newchain;
newchain.evt = e;
newchain.triggering_effect = feffect;
core.select_chains.push_back(newchain);
core.select_options.push_back(feffect->description);
}
return TRUE;
}
int32 field::is_able_to_enter_bp() {
return ((core.duel_options & DUEL_ATTACK_FIRST_TURN) || infos.turn_id != 1)
&& infos.phase < PHASE_BATTLE_START
......
......@@ -461,6 +461,8 @@ public:
int32 is_chain_disabled(uint8 chaincount);
int32 check_chain_target(uint8 chaincount, card* pcard);
chain* get_chain(uint32 chaincount);
int32 get_cteffect(effect* peffect, int32 playerid, int32 store);
int32 get_cteffect_evt(effect* feffect, int32 playerid, const tevent& e, int32 store);
int32 is_able_to_enter_bp();
void add_process(uint16 type, uint16 step, effect* peffect, group* target, ptr arg1, ptr arg2, ptr arg3 = 0, ptr arg4 = 0, void* ptr1 = NULL, void* ptr2 = NULL);
......@@ -595,6 +597,7 @@ public:
#define CHAIN_DISABLE_EFFECT 0x02
#define CHAIN_HAND_EFFECT 0x04
#define CHAIN_CONTINUOUS_CARD 0x08
#define CHAIN_ACTIVATING 0x10
#define CHAININFO_CHAIN_COUNT 0x01
#define CHAININFO_TRIGGERING_EFFECT 0x02
#define CHAININFO_TRIGGERING_PLAYER 0x04
......
......@@ -4365,8 +4365,9 @@ int32 field::add_chain(uint16 step) {
phandler->set_status(STATUS_ACT_FROM_HAND, FALSE);
change_position(phandler, 0, phandler->current.controler, POS_FACEUP, 0);
}
clit.flag |= CHAIN_ACTIVATING;
}
if(phandler->current.location & 0x30)
if(phandler->current.location & (LOCATION_GRAVE | LOCATION_REMOVED))
move_card(phandler->current.controler, phandler, phandler->current.location, 0);
return FALSE;
}
......@@ -4404,6 +4405,7 @@ int32 field::add_chain(uint16 step) {
if(phandler->current.location == LOCATION_HAND)
clit.flag |= CHAIN_HAND_EFFECT;
core.current_chain.push_back(clit);
core.new_chains.pop_front();
check_chain_counter(peffect, clit.triggering_player, clit.chain_count);
// 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)) {
......@@ -4421,14 +4423,74 @@ int32 field::add_chain(uint16 step) {
negeff->reset_flag = RESET_CHAIN | RESET_EVENT | deffect->get_value();
phandler->add_effect(negeff);
}
return FALSE;
}
case 2: {
auto& clit = core.current_chain.back();
int32 playerid = clit.triggering_player;
effect* peffect = clit.triggering_effect;
if(get_cteffect(peffect, playerid, TRUE)) {
const bool damage_step = infos.phase == PHASE_DAMAGE && !peffect->is_flag(EFFECT_FLAG_DAMAGE_STEP);
const bool damage_cal = infos.phase == PHASE_DAMAGE_CAL && !peffect->is_flag(EFFECT_FLAG_DAMAGE_CAL);
if(damage_step || damage_cal) {
returns.ivalue[0] = TRUE;
return FALSE;
}
add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, playerid, 94);
} else
returns.ivalue[0] = FALSE;
return FALSE;
}
case 3: {
if(!returns.ivalue[0]) {
core.select_chains.clear();
core.select_options.clear();
core.units.begin()->step = 4;
return FALSE;
}
if(core.select_chains.size() > 1) {
auto& clit = core.current_chain.back();
add_process(PROCESSOR_SELECT_OPTION, 0, 0, 0, clit.triggering_player, 0);
} else
returns.ivalue[0] = 0;
return FALSE;
}
case 4: {
auto& clit = core.current_chain.back();
chain& ch = core.select_chains[returns.ivalue[0]];
int32 playerid = clit.triggering_player;
effect* peffect = ch.triggering_effect;
card* phandler = peffect->get_handler();
pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_OPSELECTED);
pduel->write_buffer8(playerid);
pduel->write_buffer32(core.select_options[returns.ivalue[0]]);
clit.triggering_effect = peffect;
clit.evt = ch.evt;
phandler->create_relation(clit);
peffect->dec_count(playerid);
core.select_chains.clear();
core.select_options.clear();
effect* deffect = pduel->new_effect();
deffect->owner = phandler;
deffect->code = 0;
deffect->type = EFFECT_TYPE_SINGLE;
deffect->flag[0] = EFFECT_FLAG_CANNOT_DISABLE | EFFECT_FLAG_CLIENT_HINT;
deffect->description = 65;
deffect->reset_flag = RESET_CHAIN;
phandler->add_effect(deffect);
return FALSE;
}
case 5: {
auto& clit = core.current_chain.back();
effect* peffect = clit.triggering_effect;
if(peffect->cost) {
core.sub_solving_event.push_back(clit.evt);
add_process(PROCESSOR_EXECUTE_COST, 0, peffect, 0, clit.triggering_player, 0);
}
core.new_chains.pop_front();
return FALSE;
}
case 2: {
case 6: {
auto& clit = core.current_chain.back();
effect* peffect = clit.triggering_effect;
if(peffect->target) {
......@@ -4437,7 +4499,7 @@ int32 field::add_chain(uint16 step) {
}
return FALSE;
}
case 3: {
case 7: {
break_effect();
auto& clit = core.current_chain.back();
effect* peffect = clit.triggering_effect;
......@@ -4686,7 +4748,7 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
break_effect();
core.chain_solving = TRUE;
card* pcard = peffect->get_handler();
if((peffect->type & EFFECT_TYPE_ACTIVATE) && pcard->is_has_relation(*cait)) {
if((cait->flag & CHAIN_ACTIVATING) && pcard->is_has_relation(*cait)) {
pcard->set_status(STATUS_ACTIVATED, TRUE);
pcard->enable_field_effect(true);
if(core.duel_rule <= 2) {
......
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