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: ...@@ -97,7 +97,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);
} ; };
int32 scrtype; int32 scrtype;
int32 ref_handle; int32 ref_handle;
duel* pduel; duel* pduel;
......
...@@ -330,7 +330,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -330,7 +330,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_ATTACK_ALL 193 #define EFFECT_ATTACK_ALL 193
#define EFFECT_EXTRA_ATTACK 194 #define EFFECT_EXTRA_ATTACK 194
#define EFFECT_MUST_BE_ATTACKED 195 #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_ATTACK_DISABLED 197
#define EFFECT_NO_BATTLE_DAMAGE 200 #define EFFECT_NO_BATTLE_DAMAGE 200
#define EFFECT_AVOID_BATTLE_DAMAGE 201 #define EFFECT_AVOID_BATTLE_DAMAGE 201
...@@ -395,6 +395,10 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -395,6 +395,10 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_HAND_SYNCHRO 339 #define EFFECT_HAND_SYNCHRO 339
#define EFFECT_ADD_FUSION_CODE 340 #define EFFECT_ADD_FUSION_CODE 340
#define EFFECT_ADD_FUSION_SETCODE 341 #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_STARTUP 1000
#define EVENT_FLIP 1001 #define EVENT_FLIP 1001
......
...@@ -146,7 +146,7 @@ void field::reload_field_info() { ...@@ -146,7 +146,7 @@ void field::reload_field_info() {
} }
} }
// Debug.AddCard() will call this function directly // 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) { void field::add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence) {
if (pcard->current.location != 0) if (pcard->current.location != 0)
return; return;
...@@ -1484,7 +1484,7 @@ int32 field::check_spsummon_once(card* pcard, uint8 playerid) { ...@@ -1484,7 +1484,7 @@ int32 field::check_spsummon_once(card* pcard, uint8 playerid) {
auto iter = core.spsummon_once_map[playerid].find(pcard->spsummon_code); auto iter = core.spsummon_once_map[playerid].find(pcard->spsummon_code);
return (iter == core.spsummon_once_map[playerid].end()) || (iter->second == 0); 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) { void field::check_card_counter(card* pcard, int32 counter_type, int32 playerid) {
auto& counter_map = (counter_type == 1) ? core.summon_counter : auto& counter_map = (counter_type == 1) ? core.summon_counter :
(counter_type == 2) ? core.normalsummon_counter : (counter_type == 2) ? core.normalsummon_counter :
...@@ -1649,54 +1649,83 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack, ...@@ -1649,54 +1649,83 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack,
uint8 p = pcard->current.controler; uint8 p = pcard->current.controler;
effect* peffect; effect* peffect;
card* atarget; card* atarget;
pcard->operation_param = 0; card_vector* pv = NULL;
int32 atype = 0;
card_vector must_be_attack; 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) { for(uint32 i = 0; i < 5; ++i) {
atarget = player[1 - p].list_mzone[i]; atarget = player[1 - p].list_mzone[i];
if(atarget && atarget->is_affected_by_effect(EFFECT_MUST_BE_ATTACKED, pcard)) if(atarget){
if(atarget->is_affected_by_effect(EFFECT_MUST_BE_ATTACKED))
must_be_attack.push_back(atarget); 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;
} }
if(pcard->attack_all_target && (peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL))) { else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)){
if(pcard->announced_cards.size()) { 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()) if(must_be_attack.size())
pv = &must_be_attack; pv = &must_be_attack;
else else
return atype;
}
else{
atype = 4;
pv = &player[1 - p].list_mzone; pv = &player[1 - p].list_mzone;
}
if(pcard->attack_all_target && (peffect = pcard->is_affected_by_effect(EFFECT_ATTACK_ALL))) {
if(pcard->battled_cards.size()) {
for(auto cit = pv->begin(); cit != pv->end(); ++cit) { for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
atarget = *cit; atarget = *cit;
if(!atarget) if(!atarget)
continue; continue;
auto it = pcard->announced_cards.find(atarget->fieldid_r); pduel->lua->add_param(atarget, PARAM_TYPE_CARD);
if(it != pcard->announced_cards.end()) { 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)) if(it->second.second >= (uint32)peffect->get_value(atarget))
continue; continue;
} }
if(atarget->is_affected_by_effect(EFFECT_IGNORE_BATTLE_TARGET)) if(atype == 4 && !atarget->is_capable_be_battle_target(pcard))
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))
continue; continue;
v->push_back(atarget); v->push_back(atarget);
} }
return must_be_attack.size() ? TRUE : FALSE; return atype;
} }
} else if(!chain_attack) { } else if(chain_attack && core.chain_attack_target) {
uint32 extrac = 0; if(std::find(pv->begin(), pv->end(), core.chain_attack_target) != pv->end()
if((peffect = pcard->is_affected_by_effect(EFFECT_EXTRA_ATTACK))) && (atype != 4 || core.chain_attack_target->is_capable_be_battle_target(pcard))){
extrac = peffect->get_value(pcard); v->push_back(core.chain_attack_target);
if(pcard->announce_count >= extrac + 1) }
return FALSE; return atype;
}
if(atype <= 3) {
*v = *pv;
return atype;
} }
uint32 mcount = 0; 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) { for(auto cit = pv->begin(); cit != pv->end(); ++cit) {
atarget = *cit; atarget = *cit;
if(!atarget) if(!atarget)
...@@ -1708,17 +1737,12 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack, ...@@ -1708,17 +1737,12 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack,
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;
if(chain_attack && !sub_attack && core.chain_attack_target && atarget != core.chain_attack_target)
continue;
v->push_back(atarget); v->push_back(atarget);
} }
if(must_be_attack.size()) if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK))
return TRUE; && !pcard->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK))
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))
pcard->operation_param = 1; pcard->operation_param = 1;
return must_be_attack.size() ? TRUE : FALSE; return atype;
} }
void field::attack_all_target_check() { void field::attack_all_target_check() {
if(!core.attacker) if(!core.attacker)
......
...@@ -241,15 +241,12 @@ struct processor { ...@@ -241,15 +241,12 @@ struct processor {
uint8 summon_depth; uint8 summon_depth;
uint8 summon_cancelable; uint8 summon_cancelable;
card* attacker; card* attacker;
card* sub_attacker;
card* attack_target; card* attack_target;
card* sub_attack_target;
card* limit_tuner; card* limit_tuner;
group* limit_syn; group* limit_syn;
group* limit_xyz; group* limit_xyz;
int32 limit_xyz_minc; int32 limit_xyz_minc;
int32 limit_xyz_maxc; int32 limit_xyz_maxc;
uint8 attack_cancelable;
uint8 attack_rollback; uint8 attack_rollback;
uint8 effect_damage_step; uint8 effect_damage_step;
int32 battle_damage[2]; int32 battle_damage[2];
......
...@@ -376,7 +376,6 @@ static const struct luaL_Reg duellib[] = { ...@@ -376,7 +376,6 @@ static const struct luaL_Reg duellib[] = {
{ "ShuffleHand", scriptlib::duel_shuffle_hand }, { "ShuffleHand", scriptlib::duel_shuffle_hand },
{ "ShuffleSetCard", scriptlib::duel_shuffle_setcard }, { "ShuffleSetCard", scriptlib::duel_shuffle_setcard },
{ "ChangeAttacker", scriptlib::duel_change_attacker }, { "ChangeAttacker", scriptlib::duel_change_attacker },
{ "ReplaceAttacker", scriptlib::duel_replace_attacker },
{ "ChangeAttackTarget", scriptlib::duel_change_attack_target }, { "ChangeAttackTarget", scriptlib::duel_change_attack_target },
{ "ReplaceAttackTarget", scriptlib::duel_replace_attack_target }, { "ReplaceAttackTarget", scriptlib::duel_replace_attack_target },
{ "CalculateDamage", scriptlib::duel_calculate_damage }, { "CalculateDamage", scriptlib::duel_calculate_damage },
......
...@@ -1166,19 +1166,7 @@ int32 scriptlib::duel_change_attacker(lua_State *L) { ...@@ -1166,19 +1166,7 @@ int32 scriptlib::duel_change_attacker(lua_State *L) {
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* target = *(card**) lua_touserdata(L, 1); card* target = *(card**) lua_touserdata(L, 1);
duel* pduel = target->pduel; duel* pduel = target->pduel;
card* attacker = pduel->game_field->core.attacker; pduel->game_field->core.attacker = target;
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;
return 0; return 0;
} }
int32 scriptlib::duel_change_attack_target(lua_State *L) { int32 scriptlib::duel_change_attack_target(lua_State *L) {
...@@ -1199,10 +1187,23 @@ int32 scriptlib::duel_change_attack_target(lua_State *L) { ...@@ -1199,10 +1187,23 @@ int32 scriptlib::duel_change_attack_target(lua_State *L) {
return 1; return 1;
} }
field::card_vector cv; field::card_vector cv;
pduel->game_field->get_attack_target(attacker, &cv, pduel->game_field->core.chain_attack, TRUE); pduel->game_field->get_attack_target(attacker, &cv, pduel->game_field->core.chain_attack);
if(!target && attacker->operation_param auto turnp=pduel->game_field->infos.turn_player;
|| target && std::find(cv.begin(), cv.end(), target) != cv.end()) { if(!target || std::find(cv.begin(), cv.end(), target) != cv.end()) {
pduel->game_field->core.sub_attack_target = target; 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); lua_pushboolean(L, 1);
} else } else
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
...@@ -2621,8 +2622,6 @@ int32 scriptlib::duel_hint_selection(lua_State *L) { ...@@ -2621,8 +2622,6 @@ int32 scriptlib::duel_hint_selection(lua_State *L) {
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) { for(auto cit = pgroup->container.begin(); cit != pgroup->container.end(); ++cit) {
card* pcard = *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(MSG_BECOME_TARGET);
pduel->write_buffer8(1); pduel->write_buffer8(1);
pduel->write_buffer32(pcard->get_info_location()); pduel->write_buffer32(pcard->get_info_location());
......
This diff is collapsed.
...@@ -373,7 +373,6 @@ public: ...@@ -373,7 +373,6 @@ public:
static int32 duel_shuffle_hand(lua_State *L); static int32 duel_shuffle_hand(lua_State *L);
static int32 duel_shuffle_setcard(lua_State *L); static int32 duel_shuffle_setcard(lua_State *L);
static int32 duel_change_attacker(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_change_attack_target(lua_State *L);
static int32 duel_replace_attack_target(lua_State *L); static int32 duel_replace_attack_target(lua_State *L);
static int32 duel_calculate_damage(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