Commit 9d82daac authored by mercury233's avatar mercury233
parents caa7d62a f39885a8
......@@ -91,7 +91,6 @@ card::card(duel* pd) {
std::memset(&temp, 0xff, sizeof(card_state));
unique_pos[0] = unique_pos[1] = 0;
spsummon_counter[0] = spsummon_counter[1] = 0;
spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0;
unique_code = 0;
unique_fieldid = 0;
assume_type = 0;
......@@ -1505,7 +1504,6 @@ void card::apply_field_effect() {
if(unique_code && (current.location & unique_location))
pduel->game_field->add_unique_card(this);
spsummon_counter[0] = spsummon_counter[1] = 0;
spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0;
}
void card::cancel_field_effect() {
if (current.controler == PLAYER_NONE)
......@@ -3593,7 +3591,8 @@ int32 card::is_control_can_be_changed(int32 ignore_mzone, uint32 zone) {
return FALSE;
if(!ignore_mzone && pduel->game_field->get_useable_count(this, 1 - current.controler, LOCATION_MZONE, current.controler, LOCATION_REASON_CONTROL, zone) <= 0)
return FALSE;
if((get_type() & TYPE_TRAPMONSTER) && pduel->game_field->get_useable_count(this, 1 - current.controler, LOCATION_SZONE, current.controler, LOCATION_REASON_CONTROL) <= 0)
if(pduel->game_field->core.duel_rule <= 4 && (get_type() & TYPE_TRAPMONSTER)
&& pduel->game_field->get_useable_count(this, 1 - current.controler, LOCATION_SZONE, current.controler, LOCATION_REASON_CONTROL) <= 0)
return FALSE;
if(is_affected_by_effect(EFFECT_CANNOT_CHANGE_CONTROL))
return FALSE;
......
......@@ -161,7 +161,6 @@ public:
effect* unique_effect;
uint32 spsummon_code;
uint16 spsummon_counter[2];
uint16 spsummon_counter_rst[2];
uint8 assume_type;
uint32 assume_value;
card* equiping_target;
......
......@@ -62,7 +62,6 @@ struct card_sort {
#define POS_DEFENSE 0xc
//Flip effect flags
#define NO_FLIP_EFFECT 0x10000
#define FLIP_SET_AVAILABLE 0x20000
//Types
#define TYPE_MONSTER 0x1 //
......
......@@ -262,10 +262,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type() & TYPE_MONSTER))
return FALSE;
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
if(!phandler->is_position(POS_FACEUP) && !is_flag(EFFECT_FLAG_SET_AVAILABLE) && (code != EVENT_FLIP || !(e.event_value & (FLIP_SET_AVAILABLE >> 16))))
if(!phandler->is_position(POS_FACEUP) && !is_flag(EFFECT_FLAG_SET_AVAILABLE))
return FALSE;
if(phandler->is_position(POS_FACEUP) && !phandler->is_status(STATUS_EFFECT_ENABLED))
return FALSE;
......@@ -278,6 +275,13 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
}
if(phandler->current.location == LOCATION_OVERLAY)
return FALSE;
if(phandler->current.location == LOCATION_DECK
|| pduel->game_field->core.duel_rule >= 5 && phandler->current.location == LOCATION_EXTRA && (phandler->current.position & POS_FACEDOWN)) {
if((type & EFFECT_TYPE_SINGLE) && code != EVENT_TO_DECK)
return FALSE;
if((type & EFFECT_TYPE_FIELD) && !(range & (LOCATION_DECK | LOCATION_EXTRA)))
return FALSE;
}
if((type & EFFECT_TYPE_FIELD) && (phandler->current.controler != playerid) && !is_flag(EFFECT_FLAG_BOTH_SIDE | EFFECT_FLAG_EVENT_PLAYER))
return FALSE;
if(phandler->is_status(STATUS_FORBIDDEN))
......
......@@ -2170,32 +2170,15 @@ void field::check_chain_counter(effect* peffect, int32 playerid, int32 chainid,
}
}
}
void field::set_spsummon_counter(uint8 playerid, bool add, bool chain) {
if(add) {
core.spsummon_state_count[playerid]++;
if(chain)
core.spsummon_state_count_rst[playerid]++;
} else {
if(chain) {
core.spsummon_state_count[playerid] -= core.spsummon_state_count_rst[playerid];
core.spsummon_state_count_rst[playerid] = 0;
} else
core.spsummon_state_count[playerid]--;
}
void field::set_spsummon_counter(uint8 playerid) {
core.spsummon_state_count[playerid]++;
if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) {
for(auto& peffect : effects.spsummon_count_eff) {
card* pcard = peffect->get_handler();
if(add) {
if(peffect->is_available()) {
if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) {
pcard->spsummon_counter[playerid]++;
if(chain)
pcard->spsummon_counter_rst[playerid]++;
}
if(peffect->is_available()) {
if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) {
pcard->spsummon_counter[playerid]++;
}
} else {
pcard->spsummon_counter[playerid] -= pcard->spsummon_counter_rst[playerid];
pcard->spsummon_counter_rst[playerid] = 0;
}
}
}
......@@ -3368,19 +3351,6 @@ int32 field::check_cteffect_hint(effect* peffect, uint8 playerid) {
}
return FALSE;
}
int32 field::check_deck_effect(chain& ch) const {
effect* peffect = ch.triggering_effect;
card* phandler = peffect->get_handler();
if(!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY)
&& ch.triggering_location == LOCATION_DECK && (phandler->current.location & LOCATION_DECK)) {
if((peffect->type & EFFECT_TYPE_SINGLE) && !peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE)
&& peffect->code == EVENT_TO_DECK || (peffect->range & LOCATION_DECK)) {
ch.flag |= CHAIN_DECK_EFFECT;
} else
return FALSE;
}
return TRUE;
}
int32 field::check_hand_trigger(chain& ch) {
effect* peffect = ch.triggering_effect;
card* phandler = peffect->get_handler();
......@@ -3396,23 +3366,6 @@ int32 field::check_hand_trigger(chain& ch) {
}
return TRUE;
}
int32 field::check_trigger_effect(const chain& ch) const {
effect* peffect = ch.triggering_effect;
card* phandler = peffect->get_handler();
if((peffect->type & EFFECT_TYPE_FIELD) && !phandler->is_has_relation(ch))
return FALSE;
if(peffect->code == EVENT_FLIP && infos.phase == PHASE_DAMAGE)
return TRUE;
if((phandler->current.location & LOCATION_DECK) && !(ch.flag & CHAIN_DECK_EFFECT))
return FALSE;
if((ch.triggering_location & (LOCATION_DECK | LOCATION_HAND | LOCATION_EXTRA))
&& (ch.triggering_position & POS_FACEDOWN))
return TRUE;
if(!(phandler->current.location & (LOCATION_DECK | LOCATION_HAND | LOCATION_EXTRA))
|| phandler->is_position(POS_FACEUP))
return TRUE;
return FALSE;
}
int32 field::check_spself_from_hand_trigger(const chain& ch) const {
effect* peffect = ch.triggering_effect;
uint8 tp = ch.triggering_player;
......
......@@ -219,6 +219,7 @@ struct processor {
card_set unique_destroy_set;
card_set self_destroy_set;
card_set self_tograve_set;
card_set trap_monster_adjust_set[2];
card_set release_cards;
card_set release_cards_ex;
card_set release_cards_ex_oneof;
......@@ -240,7 +241,6 @@ struct processor {
std::unordered_map<uint32, uint32> effect_count_code;
std::unordered_map<uint32, uint32> effect_count_code_duel;
std::unordered_map<uint32, uint32> spsummon_once_map[2];
std::unordered_map<uint32, uint32> spsummon_once_map_rst[2];
std::multimap<int32, card*, std::greater<int32>> xmaterial_lst;
ptr temp_var[4];
uint32 global_flag;
......@@ -313,9 +313,6 @@ struct processor {
uint8 normalsummon_state_count[2];
uint8 flipsummon_state_count[2];
uint8 spsummon_state_count[2];
uint8 spsummon_state_count_rst[2];
uint8 spsummon_state_count_tmp[2];
bool spsummon_rst;
uint8 attack_state_count[2];
uint8 battle_phase_count[2];
uint8 battled_count[2];
......@@ -432,7 +429,7 @@ public:
void check_card_counter(card* pcard, int32 counter_type, int32 playerid);
void check_card_counter(group* pgroup, int32 counter_type, int32 playerid);
void check_chain_counter(effect* peffect, int32 playerid, int32 chainid, bool cancel = false);
void set_spsummon_counter(uint8 playerid, bool add = true, bool chain = false);
void set_spsummon_counter(uint8 playerid);
int32 check_spsummon_counter(uint8 playerid, uint8 ct = 1);
int32 check_lp_cost(uint8 playerid, uint32 cost);
......@@ -484,9 +481,7 @@ public:
int32 get_cteffect(effect* peffect, int32 playerid, int32 store);
int32 get_cteffect_evt(effect* feffect, int32 playerid, const tevent& e, int32 store);
int32 check_cteffect_hint(effect* peffect, uint8 playerid);
int32 check_deck_effect(chain& ch) const;
int32 check_hand_trigger(chain& ch);
int32 check_trigger_effect(const chain& ch) const;
int32 check_spself_from_hand_trigger(const chain& ch) const;
int32 is_able_to_enter_bp();
......@@ -565,6 +560,7 @@ public:
int32 swap_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets1, group* targets2, uint16 reset_phase, uint8 reset_count);
int32 control_adjust(uint16 step);
int32 self_destroy(uint16 step, card* ucard, int32 p);
int32 trap_monster_adjust(uint16 step);
int32 equip(uint16 step, uint8 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step);
int32 draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 playerid, uint32 count);
int32 damage(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, card* reason_card, uint8 playerid, uint32 amount, uint32 is_step);
......@@ -626,7 +622,7 @@ public:
#define CHAIN_CONTINUOUS_CARD 0x08
#define CHAIN_ACTIVATING 0x10
#define CHAIN_HAND_TRIGGER 0x20
#define CHAIN_DECK_EFFECT 0x40
//#define CHAIN_DECK_EFFECT 0x40
#define CHAININFO_CHAIN_COUNT 0x01
#define CHAININFO_TRIGGERING_EFFECT 0x02
#define CHAININFO_TRIGGERING_PLAYER 0x04
......@@ -756,6 +752,7 @@ public:
#define PROCESSOR_SWAP_CONTROL 75
#define PROCESSOR_CONTROL_ADJUST 76
#define PROCESSOR_SELF_DESTROY 77
#define PROCESSOR_TRAP_MONSTER_ADJUST 78
#define PROCESSOR_PAY_LPCOST 80
#define PROCESSOR_REMOVE_COUNTER 81
#define PROCESSOR_ATTACK_DISABLE 82
......
......@@ -715,7 +715,6 @@ int32 scriptlib::duel_change_form(lua_State *L) {
if(top > 3) du = (uint32)lua_tointeger(L, 4);
if(top > 4) dd = (uint32)lua_tointeger(L, 5);
if(top > 5 && lua_toboolean(L, 6)) flag |= NO_FLIP_EFFECT;
if(top > 6 && lua_toboolean(L, 7)) flag |= FLIP_SET_AVAILABLE;
if(pcard) {
field::card_set cset;
cset.insert(pcard);
......@@ -4104,7 +4103,7 @@ int32 scriptlib::duel_is_chain_negatable(lua_State * L) {
chain* ch = pduel->game_field->get_chain(chaincount);
if(!ch)
return 0;
if(ch->flag & CHAIN_DECK_EFFECT)
if(ch->triggering_location == LOCATION_DECK)
lua_pushboolean(L, 0);
else
lua_pushboolean(L, 1);
......@@ -4121,7 +4120,7 @@ int32 scriptlib::duel_is_chain_disablable(lua_State * L) {
chain* ch = pduel->game_field->get_chain(chaincount);
if(!ch)
return 0;
if(ch->flag & CHAIN_DECK_EFFECT)
if(ch->triggering_location == LOCATION_DECK)
lua_pushboolean(L, 0);
else
lua_pushboolean(L, 1);
......
This diff is collapsed.
......@@ -490,6 +490,13 @@ int32 field::process() {
it->step++;
return pduel->bufferlen;
}
case PROCESSOR_TRAP_MONSTER_ADJUST: {
if (trap_monster_adjust(it->step))
core.units.pop_front();
else
it->step++;
return pduel->bufferlen;
}
case PROCESSOR_PAY_LPCOST: {
if (pay_lp_cost(it->step, it->arg1, it->arg2))
core.units.pop_front();
......@@ -1306,8 +1313,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
if(phandler->is_has_relation(*clit)) //work around: position and control should be refreshed before raising event
clit->set_triggering_state(phandler);
uint8 tp = clit->triggering_player;
if(check_deck_effect(*clit) && check_trigger_effect(*clit)
&& peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)) {
if(phandler->is_has_relation(*clit) && peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)) {
if(tp == core.current_player)
core.select_chains.push_back(*clit);
} else {
......@@ -1364,7 +1370,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
clit->set_triggering_state(phandler);
}
uint8 tp = clit->triggering_player;
if(check_hand_trigger(*clit) && check_deck_effect(*clit) && check_trigger_effect(*clit)
if(check_hand_trigger(*clit) && phandler->is_has_relation(*clit)
&& peffect->is_chainable(tp) && peffect->is_activateable(tp, clit->evt, TRUE)
&& check_spself_from_hand_trigger(*clit)) {
if(tp == core.current_player)
......@@ -3636,16 +3642,13 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
core.normalsummon_state_count[p] = 0;
core.flipsummon_state_count[p] = 0;
core.spsummon_state_count[p] = 0;
core.spsummon_state_count_rst[p] = 0;
core.attack_state_count[p] = 0;
core.battle_phase_count[p] = 0;
core.battled_count[p] = 0;
core.summon_count[p] = 0;
core.extra_summon[p] = 0;
core.spsummon_once_map[p].clear();
core.spsummon_once_map_rst[p].clear();
}
core.spsummon_rst = false;
for(auto& peffect : effects.rechargeable)
if(!peffect->is_flag(EFFECT_FLAG_NO_TURN_RESET))
peffect->recharge();
......@@ -3666,7 +3669,6 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
card* pcard = peffect->get_handler();
if(!peffect->is_flag(EFFECT_FLAG_NO_TURN_RESET)) {
pcard->spsummon_counter[0] = pcard->spsummon_counter[1] = 0;
pcard->spsummon_counter_rst[0] = pcard->spsummon_counter_rst[1] = 0;
}
}
}
......@@ -4151,43 +4153,6 @@ int32 field::add_chain(uint16 step) {
&& !peffect->is_flag(EFFECT_FLAG_FIELD_ONLY))
clit.flag |= CHAIN_CONTINUOUS_CARD;
core.phase_action = TRUE;
if(clit.opinfos.count(0x200) && clit.opinfos[0x200].op_count) {
core.spsummon_rst = true;
set_spsummon_counter(clit.triggering_player, true, true);
if(clit.opinfos[0x200].op_player == PLAYER_ALL)
set_spsummon_counter(1 - clit.triggering_player, true, true);
if(core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) {
auto& optarget = clit.opinfos[0x200];
if(optarget.op_cards) {
if(optarget.op_player == PLAYER_ALL) {
auto opit = optarget.op_cards->container.begin();
uint32 sumplayer = optarget.op_param;
if((*opit)->spsummon_code) {
core.spsummon_once_map[sumplayer][(*opit)->spsummon_code]++;
core.spsummon_once_map_rst[sumplayer][(*opit)->spsummon_code]++;
}
++opit;
if((*opit)->spsummon_code) {
core.spsummon_once_map[1 - sumplayer][(*opit)->spsummon_code]++;
core.spsummon_once_map_rst[1 - sumplayer][(*opit)->spsummon_code]++;
}
} else {
uint32 sumplayer = clit.triggering_player;
// genarally setting op_player is unnecessary when the effect targets cards
// in the case of CATEGORY_SPECIAL_SUMMON(with EFFECT_FLAG_CARD_TARGET), op_player=0x10
// indecates that it is the opponent that special summons the target monsters
if(peffect->is_flag(EFFECT_FLAG_CARD_TARGET) && optarget.op_player == 0x10)
sumplayer = 1 - sumplayer;
for(auto& pcard : optarget.op_cards->container) {
if(pcard->spsummon_code) {
core.spsummon_once_map[sumplayer][pcard->spsummon_code]++;
core.spsummon_once_map_rst[sumplayer][pcard->spsummon_code]++;
}
}
}
}
}
}
pduel->write_buffer8(MSG_CHAINED);
pduel->write_buffer8(clit.chain_count);
raise_event(phandler, EVENT_CHAINING, peffect, 0, clit.triggering_player, clit.triggering_player, clit.chain_count);
......@@ -4305,18 +4270,6 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
auto cait = core.current_chain.rbegin();
switch(step) {
case 0: {
if(core.spsummon_rst) {
set_spsummon_counter(0, false, true);
set_spsummon_counter(1, false, true);
for(int plr = 0; plr < 2; ++plr) {
for(auto& iter : core.spsummon_once_map[plr]) {
auto spcode = iter.first;
core.spsummon_once_map[plr][spcode] -= core.spsummon_once_map_rst[plr][spcode];
core.spsummon_once_map_rst[plr][spcode] = 0;
}
}
core.spsummon_rst = false;
}
pduel->write_buffer8(MSG_CHAIN_SOLVING);
pduel->write_buffer8(cait->chain_count);
add_to_disable_check_list(cait->triggering_effect->get_handler());
......@@ -4350,8 +4303,6 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
return FALSE;
}
case 2: {
core.spsummon_state_count_tmp[0] = core.spsummon_state_count[0];
core.spsummon_state_count_tmp[1] = core.spsummon_state_count[1];
effect* peffect = cait->triggering_effect;
card* pcard = peffect->get_handler();
if((peffect->type & EFFECT_TYPE_ACTIVATE) && pcard->is_has_relation(*cait)) {
......@@ -4402,47 +4353,6 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
return FALSE;
}
case 4: {
if(core.units.begin()->arg4 == 0) {
if(cait->opinfos.count(0x200) && cait->opinfos[0x200].op_count) {
if(core.spsummon_state_count_tmp[cait->triggering_player] == core.spsummon_state_count[cait->triggering_player])
set_spsummon_counter(cait->triggering_player);
if(cait->opinfos[0x200].op_player == PLAYER_ALL && core.spsummon_state_count_tmp[1 - cait->triggering_player] == core.spsummon_state_count[1 - cait->triggering_player])
set_spsummon_counter(1 - cait->triggering_player);
//sometimes it may add twice, only works for once per turn
auto& optarget = cait->opinfos[0x200];
if(optarget.op_cards) {
if(optarget.op_player == PLAYER_ALL) {
uint32 sumplayer = optarget.op_param;
if(core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) {
auto opit = optarget.op_cards->container.begin();
if((*opit)->spsummon_code)
core.spsummon_once_map[sumplayer][(*opit)->spsummon_code]++;
++opit;
if((*opit)->spsummon_code)
core.spsummon_once_map[1 - sumplayer][(*opit)->spsummon_code]++;
}
auto opit = optarget.op_cards->container.begin();
check_card_counter(*opit, 3, sumplayer);
++opit;
check_card_counter(*opit, 3, 1 - sumplayer);
} else {
uint32 sumplayer = cait->triggering_player;
// genarally setting op_player is unnecessary when the effect targets cards
// in the case of CATEGORY_SPECIAL_SUMMON(with EFFECT_FLAG_CARD_TARGET), op_player=0x10
// indecates that it is the opponent that special summons the target monsters
if(cait->triggering_effect->is_flag(EFFECT_FLAG_CARD_TARGET) && optarget.op_player == 0x10)
sumplayer = 1 - sumplayer;
for(auto& ptarget : optarget.op_cards->container) {
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && ptarget->spsummon_code)
core.spsummon_once_map[sumplayer][ptarget->spsummon_code]++;
check_card_counter(ptarget, 3, sumplayer);
}
}
}
}
}
core.spsummon_state_count_tmp[0] = 0;
core.spsummon_state_count_tmp[1] = 0;
core.chain_solving = FALSE;
if(core.delayed_continuous_tp.size()) {
core.conti_player = infos.turn_player;
......@@ -4839,18 +4749,19 @@ int32 field::adjust_step(uint16 step) {
}
case 3: {
//trap monster
uint8 tp = infos.turn_player;
core.trap_monster_adjust_set[0].clear();
core.trap_monster_adjust_set[1].clear();
for(uint8 p = 0; p < 2; ++p) {
for(auto& pcard : player[tp].list_mzone) {
for(auto& pcard : player[p].list_mzone) {
if(!pcard) continue;
if((pcard->get_type() & TYPE_TRAPMONSTER) && pcard->is_affected_by_effect(EFFECT_DISABLE_TRAPMONSTER)) {
pcard->reset(RESET_TURN_SET, RESET_EVENT);
refresh_location_info_instant();
move_to_field(pcard, tp, tp, LOCATION_SZONE, pcard->current.position, FALSE, 2);
core.re_adjust = TRUE;
core.trap_monster_adjust_set[p].insert(pcard);
}
}
tp = 1 - tp;
}
if(core.trap_monster_adjust_set[0].size() || core.trap_monster_adjust_set[1].size()) {
core.re_adjust = TRUE;
add_process(PROCESSOR_TRAP_MONSTER_ADJUST, 0, 0, 0, 0, 0);
}
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