Commit 8804e8c6 authored by salix5's avatar salix5

attack target, replay in battle step

removed:
sub_attacker, sub_attack_target: Changing attack target is done by functions
attack_cancelable: It is removed since it will interrupt attack-announce related parts.
Duel.ReplaceAttacker(): No longer used.

EFFECT_RISE_TO_FULL_HEIGHT: It is used by "Rise to Full Height".
EFFECT_ONLY_ATTACK_MONSTER: The opponent monsters can only attack monster X.
EFFECT_ONLY_BE_ATTACKED: The targets of
EFFECT_RISE_TO_FULL_HEIGHT/EFFECT_ONLY_ATTACK_MONSTER.
EFFECT_MUST_ATTACK_MONSTER: If the opponent monsters attack, they can only attack monster X.
EFFECT_MUST_BE_ATTACKED: The targets of EFFECT_MUST_ATTACK_MONSTER.
EFFECT_MUST_ATTACK: The opponent monsters must attack.

Duel.ChangeAttackTarget(): Now it will change the attacker and raise events.
Duel.HintSelection(): Now it will not move cards.

attack_state_count/announce_count:
1. If no target exists, it increases after attack announce.
2. If there are targets, it increases after traget selection.
parent 67d5fc64
......@@ -97,7 +97,7 @@ public:
class attacker_map : public std::unordered_map<uint16, std::pair<card*, uint32> > {
public:
void addcard(card* pcard);
} ;
};
int32 scrtype;
int32 ref_handle;
duel* pduel;
......
......@@ -330,7 +330,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_ATTACK_ALL 193
#define EFFECT_EXTRA_ATTACK 194
#define EFFECT_MUST_BE_ATTACKED 195
#define EFFECT_AUTO_BE_ATTACKED 196
#define EFFECT_ONLY_BE_ATTACKED 196
#define EFFECT_ATTACK_DISABLED 197
#define EFFECT_NO_BATTLE_DAMAGE 200
#define EFFECT_AVOID_BATTLE_DAMAGE 201
......@@ -395,6 +395,10 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_HAND_SYNCHRO 339
#define EFFECT_ADD_FUSION_CODE 340
#define EFFECT_ADD_FUSION_SETCODE 341
#define EFFECT_RISE_TO_FULL_HEIGHT 342
#define EFFECT_ONLY_ATTACK_MONSTER 343
#define EFFECT_MUST_ATTACK_MONSTER 344
#define EFFECT_PATRICIAN_OF_DARKNESS 345
#define EVENT_STARTUP 1000
#define EVENT_FLIP 1001
......
......@@ -146,7 +146,7 @@ void field::reload_field_info() {
}
}
// Debug.AddCard() will call this function directly
// check Fusion/S/X monster redirection by the rule
// check Fusion/S/X monster redirection by the rule, set fieldid_r
void field::add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence) {
if (pcard->current.location != 0)
return;
......@@ -1484,7 +1484,7 @@ int32 field::check_spsummon_once(card* pcard, uint8 playerid) {
auto iter = core.spsummon_once_map[playerid].find(pcard->spsummon_code);
return (iter == core.spsummon_once_map[playerid].end()) || (iter->second == 0);
}
// increase the binary custom counter
void field::check_card_counter(card* pcard, int32 counter_type, int32 playerid) {
auto& counter_map = (counter_type == 1) ? core.summon_counter :
(counter_type == 2) ? core.normalsummon_counter :
......@@ -1649,54 +1649,83 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack,
uint8 p = pcard->current.controler;
effect* peffect;
card* atarget;
pcard->operation_param = 0;
card_vector* pv = NULL;
int32 atype = 0;
card_vector must_be_attack;
card_vector* pv;
card_vector only_be_attack;
effect_set eset;
pcard->operation_param = 0;
for(uint32 i = 0; i < 5; ++i) {
atarget = player[1 - p].list_mzone[i];
if(atarget && atarget->is_affected_by_effect(EFFECT_MUST_BE_ATTACKED, pcard))
must_be_attack.push_back(atarget);
if(atarget){
if(atarget->is_affected_by_effect(EFFECT_MUST_BE_ATTACKED))
must_be_attack.push_back(atarget);
if(atarget->is_affected_by_effect(EFFECT_ONLY_BE_ATTACKED))
only_be_attack.push_back(atarget);
}
}
pcard->filter_effect(EFFECT_RISE_TO_FULL_HEIGHT, &eset);
if(eset.size()){
atype = 1;
std::set<uint32> idset;
for(int32 i = 0; i < eset.size(); ++i)
idset.insert(eset[i]->label);
if(idset.size()==1 && only_be_attack.size() == 1 && only_be_attack.front()->fieldid_r == *idset.begin())
pv = &only_be_attack;
else
return atype;
}
else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)){
atype = 2;
if(only_be_attack.size() == 1)
pv = &only_be_attack;
else
return atype;
}
else if(pcard->is_affected_by_effect(EFFECT_MUST_ATTACK_MONSTER)){
atype = 3;
if(must_be_attack.size())
pv = &must_be_attack;
else
return atype;
}
else{
atype = 4;
pv = &player[1 - p].list_mzone;
}
if(pcard->attack_all_target && (peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL))) {
if(pcard->announced_cards.size()) {
if(must_be_attack.size())
pv = &must_be_attack;
else
pv = &player[1 - p].list_mzone;
if(pcard->battled_cards.size()) {
for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
atarget = *cit;
if(!atarget)
continue;
auto it = pcard->announced_cards.find(atarget->fieldid_r);
if(it != pcard->announced_cards.end()) {
pduel->lua->add_param(atarget, PARAM_TYPE_CARD);
if(!peffect->check_value_condition(1))
continue;
auto it = pcard->battled_cards.find(atarget->fieldid_r);
if(it != pcard->battled_cards.end()) {
if(it->second.second >= (uint32)peffect->get_value(atarget))
continue;
}
if(atarget->is_affected_by_effect(EFFECT_IGNORE_BATTLE_TARGET))
continue;
if(atarget->is_affected_by_effect(EFFECT_CANNOT_BE_BATTLE_TARGET, pcard))
continue;
if(pcard->is_affected_by_effect(EFFECT_CANNOT_SELECT_BATTLE_TARGET, atarget))
continue;
pduel->lua->add_param(atarget, PARAM_TYPE_CARD);
if(!peffect->check_value_condition(1))
if(atype == 4 && !atarget->is_capable_be_battle_target(pcard))
continue;
v->push_back(atarget);
}
return must_be_attack.size() ? TRUE : FALSE;
return atype;
}
} else if(!chain_attack) {
uint32 extrac = 0;
if((peffect = pcard->is_affected_by_effect(EFFECT_EXTRA_ATTACK)))
extrac = peffect->get_value(pcard);
if(pcard->announce_count >= extrac + 1)
return FALSE;
} else if(chain_attack && core.chain_attack_target) {
if(std::find(pv->begin(), pv->end(), core.chain_attack_target) != pv->end()
&& (atype != 4 || core.chain_attack_target->is_capable_be_battle_target(pcard))){
v->push_back(core.chain_attack_target);
}
return atype;
}
if(atype <= 3) {
*v = *pv;
return atype;
}
uint32 mcount = 0;
if(must_be_attack.size())
pv = &must_be_attack;
else
pv = &player[1 - p].list_mzone;
for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
atarget = *cit;
if(!atarget)
......@@ -1708,17 +1737,12 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack,
continue;
if(pcard->is_affected_by_effect(EFFECT_CANNOT_SELECT_BATTLE_TARGET, atarget))
continue;
if(chain_attack && !sub_attack && core.chain_attack_target && atarget != core.chain_attack_target)
continue;
v->push_back(atarget);
}
if(must_be_attack.size())
return TRUE;
if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK) || sub_attack)
&& !pcard->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK)
&& !(chain_attack && core.chain_attack_target))
if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK))
&& !pcard->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK))
pcard->operation_param = 1;
return must_be_attack.size() ? TRUE : FALSE;
return atype;
}
void field::attack_all_target_check() {
if(!core.attacker)
......
......@@ -241,15 +241,12 @@ struct processor {
uint8 summon_depth;
uint8 summon_cancelable;
card* attacker;
card* sub_attacker;
card* attack_target;
card* sub_attack_target;
card* limit_tuner;
group* limit_syn;
group* limit_xyz;
int32 limit_xyz_minc;
int32 limit_xyz_maxc;
uint8 attack_cancelable;
uint8 attack_rollback;
uint8 effect_damage_step;
int32 battle_damage[2];
......
......@@ -376,7 +376,6 @@ static const struct luaL_Reg duellib[] = {
{ "ShuffleHand", scriptlib::duel_shuffle_hand },
{ "ShuffleSetCard", scriptlib::duel_shuffle_setcard },
{ "ChangeAttacker", scriptlib::duel_change_attacker },
{ "ReplaceAttacker", scriptlib::duel_replace_attacker },
{ "ChangeAttackTarget", scriptlib::duel_change_attack_target },
{ "ReplaceAttackTarget", scriptlib::duel_replace_attack_target },
{ "CalculateDamage", scriptlib::duel_calculate_damage },
......
......@@ -1166,19 +1166,7 @@ int32 scriptlib::duel_change_attacker(lua_State *L) {
check_param(L, PARAM_TYPE_CARD, 1);
card* target = *(card**) lua_touserdata(L, 1);
duel* pduel = target->pduel;
card* attacker = pduel->game_field->core.attacker;
card* attack_target = pduel->game_field->core.attack_target;
attacker->announce_count++;
attacker->announced_cards.addcard(attack_target);
pduel->game_field->core.sub_attacker = target;
return 0;
}
int32 scriptlib::duel_replace_attacker(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* target = *(card**) lua_touserdata(L, 1);
duel* pduel = target->pduel;
pduel->game_field->core.sub_attacker = target;
pduel->game_field->core.attacker = target;
return 0;
}
int32 scriptlib::duel_change_attack_target(lua_State *L) {
......@@ -1199,10 +1187,23 @@ int32 scriptlib::duel_change_attack_target(lua_State *L) {
return 1;
}
field::card_vector cv;
pduel->game_field->get_attack_target(attacker, &cv, pduel->game_field->core.chain_attack, TRUE);
if(!target && attacker->operation_param
|| target && std::find(cv.begin(), cv.end(), target) != cv.end()) {
pduel->game_field->core.sub_attack_target = target;
pduel->game_field->get_attack_target(attacker, &cv, pduel->game_field->core.chain_attack);
auto turnp=pduel->game_field->infos.turn_player;
if(!target || std::find(cv.begin(), cv.end(), target) != cv.end()) {
pduel->game_field->core.attack_target = target;
pduel->game_field->core.attack_rollback = FALSE;
for(uint32 i = 0; i < 5; ++i) {
if(pduel->game_field->player[1 - turnp].list_mzone[i])
pduel->game_field->core.opp_mzone[i] = pduel->game_field->player[1 - turnp].list_mzone[i]->fieldid_r;
else
pduel->game_field->core.opp_mzone[i] = 0;
}
if(target) {
pduel->game_field->raise_single_event(target, 0, EVENT_BE_BATTLE_TARGET, 0, REASON_REPLACE, 0, 1 - turnp, 0);
pduel->game_field->raise_event(target, EVENT_BE_BATTLE_TARGET, 0, REASON_REPLACE, 0, 1 - turnp, 0);
pduel->game_field->process_single_event();
pduel->game_field->process_instant_event();
}
lua_pushboolean(L, 1);
} else
lua_pushboolean(L, 0);
......@@ -2621,8 +2622,6 @@ int32 scriptlib::duel_hint_selection(lua_State *L) {
duel* pduel = pgroup->pduel;
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
card* pcard = *cit;
if(pcard->current.location & 0x30)
pduel->game_field->move_card(pcard->current.controler, pcard, pcard->current.location, 0);
pduel->write_buffer8(MSG_BECOME_TARGET);
pduel->write_buffer8(1);
pduel->write_buffer32(pcard->get_info_location());
......
......@@ -1589,9 +1589,8 @@ int32 field::process_phase_event(int16 step, int32 phase) {
}
return TRUE;
}
// skip_trigger = lower byte of arg1
// skip_freechain = higher byte of arg1
// skip_new = arg2
// move the events from core.instant_event to core.point_event
// skip_trigger = lower byte of arg1, skip_freechain = higher byte of arg1, skip_new = arg2
int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_freechain, int32 skip_new) {
switch(step) {
case 0: {
......@@ -2729,6 +2728,7 @@ int32 field::process_idle_command(uint16 step) {
}
return TRUE;
}
// core.attack_state_count: Duel.GetActivityCount()
int32 field::process_battle_command(uint16 step) {
switch(step) {
case 0: {
......@@ -2785,10 +2785,22 @@ int32 field::process_battle_command(uint16 step) {
continue;
if(!pcard->is_capable_attack_announce(infos.turn_player))
continue;
core.select_cards.clear();
uint8 chain_attack = FALSE;
if(core.chain_attack && core.pre_field[0] == pcard->fieldid_r)
chain_attack = TRUE;
// attack counts
int32 extrac = 0;
int32 tmp = 0;
effect_set exts;
pcard->filter_effect(EFFECT_EXTRA_ATTACK, &exts);
for(int32 i = 0; i < exts.size(); ++i){
tmp = exts[i]->get_value(pcard);
if(tmp > extrac)
extrac = tmp;
}
if(!pcard->is_affected_by_effect(EFFECT_ATTACK_ALL) && !chain_attack && pcard->announce_count >= extrac + 1)
continue;
core.select_cards.clear();
get_attack_target(pcard, &core.select_cards, chain_attack);
if(core.select_cards.size() == 0 && pcard->operation_param == 0)
continue;
......@@ -2807,7 +2819,6 @@ int32 field::process_battle_command(uint16 step) {
core.to_m2 = FALSE;
if(must_attack.size())
core.to_ep = FALSE;
core.attack_cancelable = TRUE;
add_process(PROCESSOR_SELECT_BATTLECMD, 0, 0, 0, infos.turn_player, 0);
return FALSE;
}
......@@ -2845,7 +2856,6 @@ int32 field::process_battle_command(uint16 step) {
card* attacker = core.attackable_cards[sel];
if(core.chain_attack && core.pre_field[0] != attacker->fieldid_r) {
core.chain_attack = FALSE;
core.chain_attack_target = 0;
}
core.attacker = attacker;
core.attacker->set_status(STATUS_ATTACK_CANCELED, FALSE);
......@@ -2856,7 +2866,6 @@ int32 field::process_battle_command(uint16 step) {
core.attacker->filter_effect(EFFECT_ATTACK_COST, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->operation) {
core.attack_cancelable = FALSE;
core.sub_solving_event.push_back(nil_event);
add_process(PROCESSOR_EXECUTE_OPERATION, 0, eset[i], 0, infos.turn_player, 0);
}
......@@ -2892,6 +2901,7 @@ int32 field::process_battle_command(uint16 step) {
case 3: {
//Filter Targers
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]) {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
return FALSE;
}
......@@ -2901,23 +2911,8 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 4: {
//confirm attack_target
card_vector auto_be_attack;
card* atarget;
for(uint32 i = 0; i < 5; ++i) {
atarget = player[1 - infos.turn_player].list_mzone[i];
if(atarget && atarget->is_affected_by_effect(EFFECT_AUTO_BE_ATTACKED))
auto_be_attack.push_back(atarget);
}
if(auto_be_attack.size()) {
core.select_cards = auto_be_attack;
if(core.select_cards.size() == 1)
returns.bvalue[1] = 0;
else
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1 - infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
core.units.begin()->step = 5;
return FALSE;
}
// confirm attack_target(replay start point)
// direct attack
if(core.attacker->operation_param) {
if(core.select_cards.size() == 0) {
returns.ivalue[0] = -2;
......@@ -2934,49 +2929,54 @@ int32 field::process_battle_command(uint16 step) {
core.units.begin()->step = 5;
return FALSE;
}
if(core.units.begin()->arg2) {
if(core.select_cards.size() == 1)
returns.bvalue[1] = 0;
else
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1 - infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
core.units.begin()->step = 5;
return FALSE;
}
// no target
if(core.select_cards.size() == 0) {
if(!core.attack_cancelable) {
if(!core.units.begin()->arg1) {
core.attack_state_count[infos.turn_player]++;
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(0);
}
core.chain_attack = FALSE;
core.units.begin()->step = -1;
return FALSE;
}
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
// must attack monster
if(core.units.begin()->arg2 == 3 || is_player_affected_by_effect(infos.turn_player, EFFECT_PATRICIAN_OF_DARKNESS)) {
if(core.select_cards.size() == 1)
returns.bvalue[1] = 0;
else {
pduel->write_buffer8(MSG_BECOME_TARGET);
pduel->write_buffer8(1);
pduel->write_buffer32(core.attacker->get_info_location());
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, 1 - infos.turn_player, 0x10001);
}
}
else
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player, 0x10001);
core.units.begin()->step = 5;
return FALSE;
}
case 5: {
// the answer of "direct attack or not"
if(returns.ivalue[0]) {
returns.ivalue[0] = -2;
return FALSE;
} else {
if(core.select_cards.size())
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
else
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player, 0x10001);
else {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
}
}
return FALSE;
}
case 6: {
if(returns.ivalue[0] == -1) {
//rollback
if(core.units.begin()->arg1) {
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
}
core.chain_attack = FALSE;
core.units.begin()->step = -1;
return FALSE;
}
if(returns.ivalue[0] == -2)
else if(returns.ivalue[0] == -2)
core.attack_target = 0;
else
core.attack_target = core.select_cards[returns.bvalue[1]];
......@@ -2984,27 +2984,25 @@ int32 field::process_battle_command(uint16 step) {
core.pre_field[1] = core.attack_target->fieldid_r;
else
core.pre_field[1] = 0;
if(!core.units.begin()->arg1) {
core.attack_state_count[infos.turn_player]++;
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
}
return FALSE;
}
case 7: {
core.attack_cancelable = TRUE;
core.sub_attacker = 0;
core.sub_attack_target = (card*)0xffffffff;
core.attack_state_count[infos.turn_player]++;
bool evt = false;
check_card_counter(core.attacker, 5, infos.turn_player);
pduel->write_buffer8(MSG_ATTACK);
pduel->write_buffer32(core.attacker->get_info_location());
if(core.attack_target) {
uint32 reason = ((core.units.begin()->arg1 >> 8) & 0xff) ? REASON_REPLACE : 0;
raise_single_event(core.attack_target, 0, EVENT_BE_BATTLE_TARGET, 0, reason, 0, 1 - infos.turn_player, 0);
raise_event(core.attack_target, EVENT_BE_BATTLE_TARGET, 0, reason, 0, 1 - infos.turn_player, 0);
evt = true;
raise_single_event(core.attack_target, 0, EVENT_BE_BATTLE_TARGET, 0, 0, 0, 1 - infos.turn_player, 0);
raise_event(core.attack_target, EVENT_BE_BATTLE_TARGET, 0, 0, 0, 1 - infos.turn_player, 0);
pduel->write_buffer32(core.attack_target->get_info_location());
} else
pduel->write_buffer32(0);
if(core.attacker->current.location != LOCATION_MZONE) {
core.units.begin()->step = -1;
return FALSE;
}
core.attack_rollback = FALSE;
for(uint32 i = 0; i < 5; ++i) {
if(player[1 - infos.turn_player].list_mzone[i])
......@@ -3012,14 +3010,17 @@ int32 field::process_battle_command(uint16 step) {
else
core.opp_mzone[i] = 0;
}
//core.units.begin()->arg1 ---> is rollbacked or sub_attacked
//core.units.begin()->arg1 ---> is rollbacked
if(!core.units.begin()->arg1) {
evt = true;
raise_single_event(core.attacker, 0, EVENT_ATTACK_ANNOUNCE, 0, 0, 0, infos.turn_player, 0);
raise_event(core.attacker, EVENT_ATTACK_ANNOUNCE, 0, 0, 0, infos.turn_player, 0);
}
core.units.begin()->arg2 = (core.attacker->current.controler << 16) + core.attacker->fieldid_r;
process_single_event();
process_instant_event();
if(evt) {
process_single_event();
process_instant_event();
}
core.hint_timing[infos.turn_player] = TIMING_ATTACK;
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0);
return FALSE;
......@@ -3066,13 +3067,13 @@ int32 field::process_battle_command(uint16 step) {
core.units.begin()->arg1 = 2;
if(is_player_affected_by_effect(infos.turn_player, EFFECT_BP_TWICE))
core.units.begin()->arg2 = 1;
else core.units.begin()->arg2 = 0;
else
core.units.begin()->arg2 = 0;
reset_phase(PHASE_DAMAGE);
if(core.attacker->fieldid_r == afid) {
if(!atk_disabled) {
core.attacker->attacked_cards.addcard(core.attack_target);
}
core.attacker->announce_count++;
attack_all_target_check();
}
if(!peffect->value) {
......@@ -3089,8 +3090,6 @@ int32 field::process_battle_command(uint16 step) {
|| core.attacker->current.controler != acon || core.attacker->fieldid_r != afid) {
core.chain_attack = FALSE;
if(core.attacker->fieldid_r == afid) {
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
attack_all_target_check();
if(!core.attacker->is_status(STATUS_ATTACK_CANCELED)) {
core.attacker->attacked_cards.addcard(core.attack_target);
......@@ -3101,76 +3100,49 @@ int32 field::process_battle_command(uint16 step) {
adjust_all();
return FALSE;
}
if((core.sub_attacker && core.sub_attacker->is_position(POS_FACEUP) && core.sub_attacker->current.location == LOCATION_MZONE)
|| ((core.sub_attack_target != (card*)0xffffffff) && (!core.sub_attack_target || core.sub_attack_target->current.location == LOCATION_MZONE))) {
if(core.sub_attacker)
core.attacker = core.sub_attacker;
if(core.sub_attack_target != (card*)0xffffffff)
core.attack_target = core.sub_attack_target;
core.sub_attacker = 0;
core.sub_attack_target = (card*)0xffffffff;
core.units.begin()->arg1 = core.units.begin()->arg1 | 0x100;
core.units.begin()->step = 6;
return FALSE;
}
uint8 sub_attacked = (core.units.begin()->arg1 >> 8) & 0xff;
core.select_cards.clear();
core.units.begin()->arg2 = get_attack_target(core.attacker, &core.select_cards, core.chain_attack, sub_attacked);
for(uint32 i = 0; i < 5; ++i) {
if(player[1 - infos.turn_player].list_mzone[i]) {
if(!core.opp_mzone[i] || core.opp_mzone[i] != player[1 - infos.turn_player].list_mzone[i]->fieldid_r) {
rollback = true;
break;
}
} else {
if(core.opp_mzone[i]) {
rollback = true;
break;
}
}
}
auto atype = get_attack_target(core.attacker, &core.select_cards, core.chain_attack);
if(!core.attack_target && !core.attacker->operation_param
|| core.attack_target && std::find(core.select_cards.begin(), core.select_cards.end(), core.attack_target) == core.select_cards.end())
|| core.attack_target && atype <= 3
&& std::find(core.select_cards.begin(), core.select_cards.end(), core.attack_target) == core.select_cards.end())
rollback = true;
// go to damage step
if(!rollback) {
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
attack_all_target_check();
core.attacker->attacked_cards.addcard(core.attack_target);
core.units.begin()->step = 19;
adjust_instant();
adjust_all();
return FALSE;
}
// attack canceled
if(!core.select_cards.size() && !core.attacker->operation_param) {
core.attacker->announce_count++;
core.chain_attack = FALSE;
attack_all_target_check();
core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE);
adjust_instant();
adjust_all();
return FALSE;
}
// replay
core.units.begin()->arg2 = atype;
if(!core.attacker->is_affected_by_effect(EFFECT_MUST_ATTACK))
add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, infos.turn_player, 30);
else {
returns.ivalue[0] = TRUE;
core.attack_cancelable = FALSE;
}
return FALSE;
}
case 11: {
// answer of "replay or not"
if(returns.ivalue[0]) {
core.units.begin()->arg1 = TRUE;
core.units.begin()->step = 3;
return FALSE;
}
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
core.chain_attack = FALSE;
attack_all_target_check();
core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE);
adjust_instant();
adjust_all();
return FALSE;
}
......@@ -3182,10 +3154,6 @@ int32 field::process_battle_command(uint16 step) {
core.damage_calculated = FALSE;
core.selfdes_disabled = TRUE;
core.flip_delayed = TRUE;
if(core.sub_attacker)
core.attacker = core.sub_attacker;
if(core.sub_attack_target != (card*)0xffffffff)
core.attack_target = core.sub_attack_target;
core.pre_field[0] = core.attacker->fieldid_r;
if(core.attack_target)
core.pre_field[1] = core.attack_target->fieldid_r;
......@@ -3219,8 +3187,6 @@ int32 field::process_battle_command(uint16 step) {
if(!core.attack_target) {
return FALSE;
}
core.sub_attacker = 0;
core.sub_attack_target = (card*)0xffffffff;
core.attacker->temp.position = core.attacker->current.position;
core.attack_target->temp.position = core.attack_target->current.position;
if(core.attack_target->is_position(POS_FACEDOWN)) {
......@@ -3253,20 +3219,6 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 23: {
if((core.sub_attack_target != (card*)0xffffffff) || core.sub_attacker) {
if(core.sub_attacker)
core.attacker = core.sub_attacker;
if(core.sub_attack_target != (card*)0xffffffff)
core.attack_target = core.sub_attack_target;
core.units.begin()->step = 20;
core.pre_field[0] = core.attacker->fieldid_r;
if(core.attack_target)
core.pre_field[1] = core.attack_target->fieldid_r;
else
core.pre_field[1] = 0;
core.temp_var[2] = 1;
return FALSE;
}
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]
|| ((core.attacker->current.position & POS_DEFENCE) && !(core.attacker->is_affected_by_effect(EFFECT_DEFENCE_ATTACK)))
|| (core.attack_target && (core.attack_target->current.location != LOCATION_MZONE || core.attack_target->fieldid_r != core.pre_field[1]))) {
......@@ -5028,7 +4980,7 @@ int32 field::adjust_step(uint16 step) {
return FALSE;
}
case 1: {
//win check
//win check(deck=0 or lp=0)
uint32 winp = 5, rea = 1;
if(player[0].lp <= 0 && player[1].lp > 0) {
winp = 1;
......@@ -5302,8 +5254,6 @@ int32 field::adjust_step(uint16 step) {
attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
if(core.attack_rollback)
return FALSE;
if(core.sub_attack_target != (card*)0xffffffff)
return FALSE;
for(uint32 i = 0; i < 5; ++i) {
card* pcard = player[1 - infos.turn_player].list_mzone[i];
if(pcard) {
......
......@@ -373,7 +373,6 @@ public:
static int32 duel_shuffle_hand(lua_State *L);
static int32 duel_shuffle_setcard(lua_State *L);
static int32 duel_change_attacker(lua_State *L);
static int32 duel_replace_attacker(lua_State *L);
static int32 duel_change_attack_target(lua_State *L);
static int32 duel_replace_attack_target(lua_State *L);
static int32 duel_calculate_damage(lua_State *L);
......
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