Commit 56ea6cf2 authored by DailyShana's avatar DailyShana

update attacking process

parent e09dd463
...@@ -60,6 +60,14 @@ void card::attacker_map::addcard(card* pcard) { ...@@ -60,6 +60,14 @@ void card::attacker_map::addcard(card* pcard) {
auto pr = emplace(fid, std::make_pair(pcard, 0)); auto pr = emplace(fid, std::make_pair(pcard, 0));
pr.first->second.second++; pr.first->second.second++;
} }
uint32 card::attacker_map::findcard(card* pcard) {
uint16 fid = pcard ? pcard->fieldid_r : 0;
auto it = find(fid);
if(it == end())
return 0;
else
return it->second.second;
}
void card_data::clear() { void card_data::clear() {
std::memset(this, 0, sizeof(card_data)); std::memset(this, 0, sizeof(card_data));
} }
......
...@@ -105,6 +105,7 @@ public: ...@@ -105,6 +105,7 @@ public:
class attacker_map : public std::unordered_map<uint16, std::pair<card*, uint32> > { class attacker_map : public std::unordered_map<uint16, std::pair<card*, uint32> > {
public: public:
void addcard(card* pcard); void addcard(card* pcard);
uint32 findcard(card* pcard);
}; };
struct sendto_param_t { struct sendto_param_t {
void set(uint8 p, uint8 pos, uint8 loc, uint8 seq = 0) { void set(uint8 p, uint8 pos, uint8 loc, uint8 seq = 0) {
......
...@@ -2251,31 +2251,27 @@ int32 field::effect_replace_check(uint32 code, const tevent& e) { ...@@ -2251,31 +2251,27 @@ int32 field::effect_replace_check(uint32 code, const tevent& e) {
} }
return FALSE; return FALSE;
} }
int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack) { int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack, bool select_target) {
uint8 p = pcard->current.controler;
effect* peffect;
card_vector* pv = NULL;
int32 atype = 0;
card_vector must_attack;
card_vector only_be_attack;
card_vector only_attack;
// find the universal set pv
pcard->direct_attackable = 0; pcard->direct_attackable = 0;
uint8 p = pcard->current.controler;
card_vector auto_attack, only_attack, must_attack;
for(auto cit = player[1 - p].list_mzone.begin(); cit != player[1 - p].list_mzone.end(); ++cit) { for(auto cit = player[1 - p].list_mzone.begin(); cit != player[1 - p].list_mzone.end(); ++cit) {
card* atarget = *cit; card* atarget = *cit;
if(atarget) { if(atarget) {
if(atarget->is_affected_by_effect(EFFECT_ONLY_BE_ATTACKED)) if(atarget->is_affected_by_effect(EFFECT_ONLY_BE_ATTACKED))
only_be_attack.push_back(atarget); auto_attack.push_back(atarget);
if(pcard->is_affected_by_effect(EFFECT_MUST_ATTACK_MONSTER, atarget))
must_attack.push_back(atarget);
if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER, atarget)) if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER, atarget))
only_attack.push_back(atarget); only_attack.push_back(atarget);
if(pcard->is_affected_by_effect(EFFECT_MUST_ATTACK_MONSTER, atarget))
must_attack.push_back(atarget);
} }
} }
if(only_be_attack.size()) { card_vector* pv = nullptr;
int32 atype = 0;
if(auto_attack.size()) {
atype = 1; atype = 1;
if(only_be_attack.size() == 1) if(auto_attack.size() == 1)
pv = &only_be_attack; pv = &auto_attack;
else else
return atype; return atype;
} else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)) { } else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)) {
...@@ -2294,113 +2290,63 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack) ...@@ -2294,113 +2290,63 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack)
atype = 4; atype = 4;
pv = &player[1 - p].list_mzone; pv = &player[1 - p].list_mzone;
} }
// extra count int32 extra_count = 0;
int32 ct1 = 0, ct2 = 0; effect_set eset;
int32 tmp = 0; pcard->filter_effect(EFFECT_EXTRA_ATTACK, &eset);
effect_set exts1, exts2; for(int32 i = 0; i < eset.size(); ++i) {
bool dir = true; int32 val = eset[i]->get_value(pcard);
pcard->filter_effect(EFFECT_EXTRA_ATTACK, &exts1); if(val > extra_count)
for(int32 i = 0; i < exts1.size(); ++i) { extra_count = val;
tmp = exts1[i]->get_value(pcard);
if(tmp > ct1)
ct1 = tmp;
}
pcard->filter_effect(EFFECT_EXTRA_ATTACK_MONSTER, &exts2);
for(int32 i = 0; i < exts2.size(); ++i) {
tmp = exts2[i]->get_value(pcard);
if(tmp > ct2)
ct2 = tmp;
}
if(pcard != core.attacker) {
if(pcard->announce_count < ct1 + 1)
dir = true;
else if(chain_attack && !core.chain_attack_target)
dir = true;
else if(ct2 && pcard->announce_count < ct2 + 1
&& pcard->announced_cards.find(0) == pcard->announced_cards.end() && pcard->battled_cards.find(0) == pcard->battled_cards.end())
dir = false;
else {
// effects with target limit
if((peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL))
&& pcard->announced_cards.find(0) == pcard->announced_cards.end() && pcard->battled_cards.find(0) == pcard->battled_cards.end()
&& pcard->attack_all_target) {
for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
card* atarget = *cit;
if(!atarget)
continue;
// valid target
pduel->lua->add_param(atarget, PARAM_TYPE_CARD);
if(!peffect->check_value_condition(1))
continue;
// enough effect count
auto it = pcard->announced_cards.find(atarget->fieldid_r);
if(it != pcard->announced_cards.end() && (int32)it->second.second >= peffect->get_value(atarget)) {
continue;
}
it = pcard->battled_cards.find(atarget->fieldid_r);
if(it != pcard->battled_cards.end() && (int32)it->second.second >= peffect->get_value(atarget)) {
continue;
}
if(atype == 4 && !atarget->is_capable_be_battle_target(pcard))
continue;
v->push_back(atarget);
}
}
if(chain_attack && core.chain_attack_target
&& 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; int32 extra_count_m = 0;
eset.clear();
pcard->filter_effect(EFFECT_EXTRA_ATTACK_MONSTER, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(pcard);
if(val > extra_count_m)
extra_count_m = val;
} }
} else { bool dir = true;
if(pcard->announce_count <= ct1 + 1) if(pcard->announce_count < extra_count + 1)
dir = true; dir = true;
else if(chain_attack && !core.chain_attack_target) else if(chain_attack && !core.chain_attack_target)
dir = true; dir = true;
else if(ct2 && pcard->announce_count <= ct2 + 1 else if(extra_count_m && pcard->announce_count < extra_count_m + 1
&& pcard->announced_cards.find(0) == pcard->announced_cards.end() && pcard->battled_cards.find(0) == pcard->battled_cards.end()) && pcard->announced_cards.findcard(0) == 0
&& pcard->battled_cards.findcard(0) == 0)
dir = false; dir = false;
else { else {
// effects with target limit effect* peffect;
if((peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL)) && pcard->attack_all_target) { if((peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL)) && pcard->attack_all_target
&& pcard->announced_cards.findcard(0) == 0
&& pcard->battled_cards.findcard(0) == 0) {
for(auto cit = pv->begin(); cit != pv->end(); ++cit) { for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
card* atarget = *cit; card* atarget = *cit;
if(!atarget) if(!atarget)
continue; continue;
// valid target
pduel->lua->add_param(atarget, PARAM_TYPE_CARD); pduel->lua->add_param(atarget, PARAM_TYPE_CARD);
if(!peffect->check_value_condition(1)) if(!peffect->check_value_condition(1))
continue; continue;
// enough effect count if(pcard->announced_cards.findcard(atarget) >= (uint32)peffect->get_value(atarget))
auto it = pcard->announced_cards.find(atarget->fieldid_r);
if(it != pcard->announced_cards.end()
&& (atarget == core.attack_target ? (int32)it->second.second > peffect->get_value(atarget) : (int32)it->second.second >= peffect->get_value(atarget))) {
continue; continue;
} if(pcard->battled_cards.findcard(atarget) >= (uint32)peffect->get_value(atarget))
it = pcard->battled_cards.find(atarget->fieldid_r);
if(it != pcard->battled_cards.end()
&& (atarget == core.attack_target ? (int32)it->second.second > peffect->get_value(atarget) : (int32)it->second.second >= peffect->get_value(atarget))) {
continue; continue;
} if(select_target && atype == 4 && !atarget->is_capable_be_battle_target(pcard))
if(atype == 4 && !atarget->is_capable_be_battle_target(pcard))
continue; continue;
v->push_back(atarget); v->push_back(atarget);
} }
} }
if(chain_attack && core.chain_attack_target if(chain_attack && core.chain_attack_target
&& std::find(pv->begin(), pv->end(), core.chain_attack_target) != pv->end() && std::find(pv->begin(), pv->end(), core.chain_attack_target) != pv->end()
&& (atype != 4 || core.chain_attack_target->is_capable_be_battle_target(pcard))) { && (!select_target || atype != 4 || core.chain_attack_target->is_capable_be_battle_target(pcard))) {
v->push_back(core.chain_attack_target); v->push_back(core.chain_attack_target);
} }
return atype; return atype;
} }
}
if(atype <= 3) { if(atype <= 3) {
*v = *pv; *v = *pv;
return atype; return atype;
} }
// For atype=4(normal), check all cards in pv.
uint32 mcount = 0; uint32 mcount = 0;
for(auto cit = pv->begin(); cit != pv->end(); ++cit) { for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
card* atarget = *cit; card* atarget = *cit;
...@@ -2409,10 +2355,12 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack) ...@@ -2409,10 +2355,12 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack)
if(atarget->is_affected_by_effect(EFFECT_IGNORE_BATTLE_TARGET)) if(atarget->is_affected_by_effect(EFFECT_IGNORE_BATTLE_TARGET))
continue; continue;
mcount++; mcount++;
if(select_target) {
if(atarget->is_affected_by_effect(EFFECT_CANNOT_BE_BATTLE_TARGET, pcard)) if(atarget->is_affected_by_effect(EFFECT_CANNOT_BE_BATTLE_TARGET, pcard))
continue; continue;
if(pcard->is_affected_by_effect(EFFECT_CANNOT_SELECT_BATTLE_TARGET, atarget)) if(pcard->is_affected_by_effect(EFFECT_CANNOT_SELECT_BATTLE_TARGET, atarget))
continue; continue;
}
v->push_back(atarget); v->push_back(atarget);
} }
if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK) || core.attack_player) if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK) || core.attack_player)
...@@ -2420,113 +2368,11 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack) ...@@ -2420,113 +2368,11 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack)
pcard->direct_attackable = 1; pcard->direct_attackable = 1;
return atype; return atype;
} }
// return: core.attack_target is valid or not
bool field::confirm_attack_target() { bool field::confirm_attack_target() {
card* pcard = core.attacker; card_vector cv;
uint8 p = pcard->current.controler; get_attack_target(core.attacker, &cv, core.chain_attack, false);
effect* peffect; return core.attack_target && std::find(cv.begin(), cv.end(), core.attack_target) != cv.end()
card_vector* pv = NULL; || !core.attack_target && core.attacker->direct_attackable;
int32 atype = 0;
card_vector must_attack;
card_vector only_be_attack;
card_vector only_attack;
effect_set eset;
// find the universal set
for(auto cit = player[1 - p].list_mzone.begin(); cit != player[1 - p].list_mzone.end(); ++cit) {
card* atarget = *cit;
if(atarget) {
if(atarget->is_affected_by_effect(EFFECT_ONLY_BE_ATTACKED))
only_be_attack.push_back(atarget);
if(pcard->is_affected_by_effect(EFFECT_MUST_ATTACK_MONSTER, atarget))
must_attack.push_back(atarget);
if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER, atarget))
only_attack.push_back(atarget);
}
}
if(only_be_attack.size()) {
atype = 1;
if(only_be_attack.size() == 1)
pv = &only_be_attack;
else
return false;
} else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)) {
atype = 2;
if(only_attack.size() == 1)
pv = &only_attack;
else
return false;
} else if(pcard->is_affected_by_effect(EFFECT_MUST_ATTACK_MONSTER)) {
atype = 3;
if(must_attack.size())
pv = &must_attack;
else
return false;
} else {
atype = 4;
pv = &player[1 - p].list_mzone;
}
// extra count
int32 ct1 = 0, ct2 = 0;
int32 tmp = 0;
effect_set exts1, exts2;
bool dir = true;
pcard->filter_effect(EFFECT_EXTRA_ATTACK, &exts1);
for(int32 i = 0; i < exts1.size(); ++i) {
tmp = exts1[i]->get_value(pcard);
if(tmp > ct1)
ct1 = tmp;
}
pcard->filter_effect(EFFECT_EXTRA_ATTACK_MONSTER, &exts2);
for(int32 i = 0; i < exts2.size(); ++i) {
tmp = exts2[i]->get_value(pcard);
if(tmp > ct2)
ct2 = tmp;
}
if(pcard->announce_count <= ct1 + 1)
dir = true;
else if(core.chain_attack && !core.chain_attack_target)
dir = true;
else if(ct2 && pcard->announce_count <= ct2 + 1
&& pcard->announced_cards.find(0) == pcard->announced_cards.end() && pcard->battled_cards.find(0) == pcard->battled_cards.end())
dir = false;
else {
// effects with target limit
if((peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL)) && pcard->attack_all_target && core.attack_target) {
// valid target
pduel->lua->add_param(core.attack_target, PARAM_TYPE_CARD);
if(!peffect->check_value_condition(1))
return false;
// enough effect count
auto it = pcard->announced_cards.find(core.attack_target->fieldid_r);
if(it != pcard->announced_cards.end() && (int32)it->second.second > peffect->get_value(core.attack_target)) {
return false;
}
it = pcard->battled_cards.find(core.attack_target->fieldid_r);
if(it != pcard->battled_cards.end() && (int32)it->second.second > peffect->get_value(core.attack_target)) {
return false;
}
return true;
}
if(core.chain_attack && core.chain_attack_target && core.chain_attack_target == core.attack_target) {
return true;
}
return false;
}
uint32 mcount = 0;
for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
card* atarget = *cit;
if(!atarget)
continue;
if(atarget->is_affected_by_effect(EFFECT_IGNORE_BATTLE_TARGET))
continue;
mcount++;
}
if(core.attack_target)
return std::find(pv->begin(), pv->end(), core.attack_target) != pv->end();
else
return (mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK) || core.attack_player)
&& !pcard->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK) && dir;
} }
// update the validity for EFFECT_ATTACK_ALL (approximate solution) // update the validity for EFFECT_ATTACK_ALL (approximate solution)
void field::attack_all_target_check() { void field::attack_all_target_check() {
......
...@@ -429,7 +429,7 @@ public: ...@@ -429,7 +429,7 @@ public:
uint32 get_field_counter(uint8 self, uint8 s, uint8 o, uint16 countertype); uint32 get_field_counter(uint8 self, uint8 s, uint8 o, uint16 countertype);
int32 effect_replace_check(uint32 code, const tevent& e); int32 effect_replace_check(uint32 code, const tevent& e);
int32 get_attack_target(card* pcard, card_vector* v, uint8 chain_attack = FALSE); int32 get_attack_target(card* pcard, card_vector* v, uint8 chain_attack = FALSE, bool select_target = true);
bool confirm_attack_target(); bool confirm_attack_target();
void attack_all_target_check(); void attack_all_target_check();
int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg); int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
......
...@@ -1325,10 +1325,10 @@ int32 scriptlib::card_is_direct_attacked(lua_State *L) { ...@@ -1325,10 +1325,10 @@ int32 scriptlib::card_is_direct_attacked(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
bool ret = false; if(pcard->attacked_cards.findcard(0))
if(pcard->attacked_cards.find(0) != pcard->attacked_cards.end()) lua_pushboolean(L, 1);
ret = true; else
lua_pushboolean(L, ret); lua_pushboolean(L, 0);
return 1; return 1;
} }
int32 scriptlib::card_set_card_target(lua_State *L) { int32 scriptlib::card_set_card_target(lua_State *L) {
......
...@@ -1414,13 +1414,13 @@ int32 scriptlib::duel_change_attacker(lua_State *L) { ...@@ -1414,13 +1414,13 @@ int32 scriptlib::duel_change_attacker(lua_State *L) {
duel* pduel = attacker->pduel; duel* pduel = attacker->pduel;
if(pduel->game_field->core.attacker == attacker) if(pduel->game_field->core.attacker == attacker)
return 0; return 0;
card* attack_target = pduel->game_field->core.attack_target;
pduel->game_field->core.attacker->announce_count++;
pduel->game_field->core.attacker->announced_cards.addcard(attack_target);
pduel->game_field->core.attacker = attacker; pduel->game_field->core.attacker = attacker;
attacker->attack_controler = attacker->current.controler; attacker->attack_controler = attacker->current.controler;
pduel->game_field->core.pre_field[0] = attacker->fieldid_r; pduel->game_field->core.pre_field[0] = attacker->fieldid_r;
if(!ignore_count) { if(!ignore_count) {
card* attack_target = pduel->game_field->core.attack_target;
attacker->announce_count++;
attacker->announced_cards.addcard(attack_target);
if(pduel->game_field->infos.phase == PHASE_DAMAGE) { if(pduel->game_field->infos.phase == PHASE_DAMAGE) {
attacker->attacked_count++; attacker->attacked_count++;
attacker->attacked_cards.addcard(attack_target); attacker->attacked_cards.addcard(attack_target);
...@@ -1447,25 +1447,29 @@ int32 scriptlib::duel_change_attack_target(lua_State *L) { ...@@ -1447,25 +1447,29 @@ int32 scriptlib::duel_change_attack_target(lua_State *L) {
} }
field::card_vector cv; field::card_vector cv;
pduel->game_field->get_attack_target(attacker, &cv, pduel->game_field->core.chain_attack); 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() if(target && std::find(cv.begin(), cv.end(), target) != cv.end()
|| !target && !attacker->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK)) { || !target && !attacker->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK)) {
pduel->game_field->core.attack_target = target; pduel->game_field->core.attack_target = target;
pduel->game_field->core.attack_rollback = FALSE; pduel->game_field->core.attack_rollback = FALSE;
pduel->game_field->core.opp_mzone.clear(); pduel->game_field->core.opp_mzone.clear();
for(uint32 i = 0; i < pduel->game_field->player[1 - turnp].list_mzone.size(); ++i) { uint8 turnp = pduel->game_field->infos.turn_player;
card* pcard = pduel->game_field->player[1 - turnp].list_mzone[i]; for(auto& pcard : pduel->game_field->player[1 - turnp].list_mzone) {
if(pcard) if(pcard)
pduel->game_field->core.opp_mzone.insert(pcard->fieldid_r); pduel->game_field->core.opp_mzone.insert(pcard->fieldid_r);
} }
pduel->game_field->attack_all_target_check(); pduel->game_field->attack_all_target_check();
pduel->write_buffer8(MSG_ATTACK);
pduel->write_buffer32(attacker->get_info_location());
if(target) { 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_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->raise_event(target, EVENT_BE_BATTLE_TARGET, 0, REASON_REPLACE, 0, 1 - turnp, 0);
pduel->game_field->process_single_event(); pduel->game_field->process_single_event();
pduel->game_field->process_instant_event(); pduel->game_field->process_instant_event();
} else pduel->write_buffer32(target->get_info_location());
} else {
pduel->game_field->core.attack_player = TRUE; pduel->game_field->core.attack_player = TRUE;
pduel->write_buffer32(0);
}
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
} else } else
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
...@@ -1478,7 +1482,7 @@ int32 scriptlib::duel_calculate_damage(lua_State *L) { ...@@ -1478,7 +1482,7 @@ int32 scriptlib::duel_calculate_damage(lua_State *L) {
card* attacker = *(card**)lua_touserdata(L, 1); card* attacker = *(card**)lua_touserdata(L, 1);
card* attack_target; card* attack_target;
if(lua_isnil(L, 2)) if(lua_isnil(L, 2))
attack_target = NULL; attack_target = 0;
else { else {
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
attack_target = *(card**)lua_touserdata(L, 2); attack_target = *(card**)lua_touserdata(L, 2);
......
...@@ -2784,7 +2784,6 @@ int32 field::process_idle_command(uint16 step) { ...@@ -2784,7 +2784,6 @@ int32 field::process_idle_command(uint16 step) {
} }
return TRUE; return TRUE;
} }
// core.attack_state_count: Duel.GetActivityCount()
int32 field::process_battle_command(uint16 step) { int32 field::process_battle_command(uint16 step) {
switch(step) { switch(step) {
case 0: { case 0: {
...@@ -2979,16 +2978,9 @@ int32 field::process_battle_command(uint16 step) { ...@@ -2979,16 +2978,9 @@ int32 field::process_battle_command(uint16 step) {
core.units.begin()->step = 5; core.units.begin()->step = 5;
return FALSE; return FALSE;
} }
for(auto cit = player[1 - infos.turn_player].list_mzone.begin(); cit != player[1 - infos.turn_player].list_mzone.end(); ++cit) {
if(*cit) {
add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, infos.turn_player, 31); add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, infos.turn_player, 31);
return FALSE; return FALSE;
} }
}
returns.ivalue[0] = -2;
core.units.begin()->step = 5;
return FALSE;
}
// no target and not direct attackable // no target and not direct attackable
if(core.select_cards.size() == 0) { if(core.select_cards.size() == 0) {
core.units.begin()->arg3 = TRUE; core.units.begin()->arg3 = TRUE;
...@@ -3039,8 +3031,10 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3039,8 +3031,10 @@ int32 field::process_battle_command(uint16 step) {
} }
case 6: { case 6: {
if(returns.ivalue[0] == -1) {//cancel attack manually if(returns.ivalue[0] == -1) {//cancel attack manually
if(core.units.begin()->arg1) if(core.units.begin()->arg1) {
core.chain_attack = FALSE; core.units.begin()->step = 12;
return FALSE;
}
core.units.begin()->step = -1; core.units.begin()->step = -1;
return FALSE; return FALSE;
} }
...@@ -3063,23 +3057,19 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3063,23 +3057,19 @@ int32 field::process_battle_command(uint16 step) {
} }
core.attack_state_count[infos.turn_player]++; core.attack_state_count[infos.turn_player]++;
check_card_counter(core.attacker, 5, infos.turn_player); check_card_counter(core.attacker, 5, infos.turn_player);
core.attacker->announce_count++;
if(!core.units.begin()->arg3)
core.attacker->announced_cards.addcard(core.attack_target);
} }
if(core.units.begin()->arg3) { if(core.units.begin()->arg3) {
core.attacker->announce_count++;
core.chain_attack = FALSE; core.chain_attack = FALSE;
core.units.begin()->step = -1; core.units.begin()->step = -1;
} }
return FALSE; return FALSE;
} }
case 8: { case 8: {
bool evt = false;
attack_all_target_check(); attack_all_target_check();
pduel->write_buffer8(MSG_ATTACK); pduel->write_buffer8(MSG_ATTACK);
pduel->write_buffer32(core.attacker->get_info_location()); pduel->write_buffer32(core.attacker->get_info_location());
if(core.attack_target) { if(core.attack_target) {
evt = true;
raise_single_event(core.attack_target, 0, EVENT_BE_BATTLE_TARGET, 0, 0, 0, 1 - infos.turn_player, 0); 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); 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()); pduel->write_buffer32(core.attack_target->get_info_location());
...@@ -3087,23 +3077,19 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3087,23 +3077,19 @@ int32 field::process_battle_command(uint16 step) {
pduel->write_buffer32(0); pduel->write_buffer32(0);
core.attack_rollback = FALSE; core.attack_rollback = FALSE;
core.opp_mzone.clear(); core.opp_mzone.clear();
for(uint32 i = 0; i < player[1 - infos.turn_player].list_mzone.size(); ++i) { for(auto& pcard : player[1 - infos.turn_player].list_mzone) {
card* pcard = player[1 - infos.turn_player].list_mzone[i];
if(pcard) if(pcard)
core.opp_mzone.insert(pcard->fieldid_r); core.opp_mzone.insert(pcard->fieldid_r);
} }
//core.units.begin()->arg1 ---> is rollbacked //core.units.begin()->arg1 ---> is rollbacked
if(!core.units.begin()->arg1) { if(!core.units.begin()->arg1) {
evt = true;
raise_single_event(core.attacker, 0, EVENT_ATTACK_ANNOUNCE, 0, 0, 0, infos.turn_player, 0); 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); raise_event(core.attacker, EVENT_ATTACK_ANNOUNCE, 0, 0, 0, infos.turn_player, 0);
} }
core.attacker->attack_controler = core.attacker->current.controler; core.attacker->attack_controler = core.attacker->current.controler;
core.pre_field[0] = core.attacker->fieldid_r; core.pre_field[0] = core.attacker->fieldid_r;
if(evt) {
process_single_event(); process_single_event();
process_instant_event(); process_instant_event();
}
core.hint_timing[infos.turn_player] = TIMING_ATTACK; core.hint_timing[infos.turn_player] = TIMING_ATTACK;
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0); add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0);
return FALSE; return FALSE;
...@@ -3134,66 +3120,33 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3134,66 +3120,33 @@ int32 field::process_battle_command(uint16 step) {
return FALSE; return FALSE;
} }
case 11: { case 11: {
uint8 rollback = core.attack_rollback;
bool atk_disabled = false;
uint32 acon = core.attacker->attack_controler;
uint32 afid = core.pre_field[0];
if(core.attacker->is_affected_by_effect(EFFECT_ATTACK_DISABLED)) { if(core.attacker->is_affected_by_effect(EFFECT_ATTACK_DISABLED)) {
core.attacker->reset(EFFECT_ATTACK_DISABLED, RESET_CODE); core.attacker->reset(EFFECT_ATTACK_DISABLED, RESET_CODE);
atk_disabled = true;
pduel->write_buffer8(MSG_ATTACK_DISABLED); pduel->write_buffer8(MSG_ATTACK_DISABLED);
core.attacker->set_status(STATUS_ATTACK_CANCELED, TRUE); core.attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
} }
effect* peffect = is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP); if(is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP)
if(peffect) { || !core.attacker->is_capable_attack() || core.attacker->is_status(STATUS_ATTACK_CANCELED)
core.units.begin()->step = 41; || core.attacker->current.controler != core.attacker->attack_controler
core.units.begin()->arg1 = 2; || core.attacker->fieldid_r != core.pre_field[0]) {
if(is_player_affected_by_effect(infos.turn_player, EFFECT_BP_TWICE)) core.units.begin()->step = 12;
core.units.begin()->arg2 = 1;
else
core.units.begin()->arg2 = 0;
reset_phase(PHASE_DAMAGE);
if(core.attacker->fieldid_r == afid && !atk_disabled) {
core.attacker->attacked_cards.addcard(core.attack_target);
}
if(!peffect->value) {
reset_phase(PHASE_BATTLE_STEP);
adjust_all();
infos.phase = PHASE_BATTLE;
add_process(PROCESSOR_PHASE_EVENT, 0, 0, 0, PHASE_BATTLE, 0);
} else {
core.hint_timing[infos.turn_player] = 0;
reset_phase(PHASE_BATTLE);
adjust_all();
}
return FALSE;
}
if(atk_disabled || !core.attacker->is_capable_attack() || core.attacker->is_status(STATUS_ATTACK_CANCELED)
|| core.attacker->current.controler != acon || core.attacker->fieldid_r != afid) {
core.chain_attack = FALSE;
if(core.attacker->fieldid_r == afid && !atk_disabled) {
core.attacker->attacked_cards.addcard(core.attack_target);
}
core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE);
adjust_all();
return FALSE; return FALSE;
} }
uint8 rollback = core.attack_rollback;
if(!confirm_attack_target()) if(!confirm_attack_target())
rollback = true; rollback = TRUE;
// go to damage step // go to damage step
if(!rollback) { if(!rollback) {
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
attack_all_target_check();
core.units.begin()->step = 18; core.units.begin()->step = 18;
return FALSE; return FALSE;
} }
// attack canceled
card_vector cv; card_vector cv;
get_attack_target(core.attacker, &cv, core.chain_attack); get_attack_target(core.attacker, &cv, core.chain_attack);
if(!cv.size() && !core.attacker->direct_attackable) { if(!cv.size() && !core.attacker->direct_attackable) {
core.chain_attack = FALSE; core.units.begin()->step = 12;
core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE);
adjust_all();
return FALSE; return FALSE;
} }
// replay // replay
...@@ -3211,8 +3164,12 @@ int32 field::process_battle_command(uint16 step) { ...@@ -3211,8 +3164,12 @@ int32 field::process_battle_command(uint16 step) {
core.units.begin()->arg3 = FALSE; core.units.begin()->arg3 = FALSE;
core.attack_cancelable = TRUE; core.attack_cancelable = TRUE;
core.units.begin()->step = 3; core.units.begin()->step = 3;
}
return FALSE; return FALSE;
} }
case 13: {
core.attacker->announce_count++;
core.attacker->announced_cards.addcard(core.attack_target);
core.chain_attack = FALSE; core.chain_attack = FALSE;
core.units.begin()->step = -1; core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE); reset_phase(PHASE_DAMAGE);
...@@ -5370,8 +5327,7 @@ int32 field::adjust_step(uint16 step) { ...@@ -5370,8 +5327,7 @@ int32 field::adjust_step(uint16 step) {
if(core.attack_rollback) if(core.attack_rollback)
return FALSE; return FALSE;
std::set<uint16> fidset; std::set<uint16> fidset;
for(uint32 i = 0; i < player[1 - infos.turn_player].list_mzone.size(); ++i) { for(auto& pcard : player[1 - infos.turn_player].list_mzone) {
card* pcard = player[1 - infos.turn_player].list_mzone[i];
if(pcard) if(pcard)
fidset.insert(pcard->fieldid_r); fidset.insert(pcard->fieldid_r);
} }
......
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