Commit 02691a96 authored by mercury233's avatar mercury233
parents 8d935883 f95d9084
......@@ -106,7 +106,7 @@ uint32 card::get_infos(byte* buf, int32 query_flag, int32 use_cache) {
if(query_flag & QUERY_CODE) *p++ = data.code;
if(query_flag & QUERY_POSITION) *p++ = get_info_location();
if(!use_cache) {
if(query_flag & QUERY_ALIAS) q_cache.code = *p++ = get_code();
if(query_flag & QUERY_ALIAS) q_cache.alias = *p++ = get_code();
if(query_flag & QUERY_TYPE) q_cache.type = *p++ = get_type();
if(query_flag & QUERY_LEVEL) q_cache.level = *p++ = get_level();
if(query_flag & QUERY_RANK) q_cache.rank = *p++ = get_rank();
......
......@@ -192,7 +192,7 @@ struct processor {
event_list sub_solving_event;
chain_array select_chains;
chain_array current_chain;
chain_array tmp_chains;
chain_array ignition_priority_chains;
chain_list continuous_chain;
chain_list solving_continuous;
chain_list sub_solving_continuous;
......@@ -560,8 +560,8 @@ public:
int32 summon(uint16 step, uint8 sumplayer, card* target, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 flip_summon(uint16 step, uint8 sumplayer, card* target);
int32 mset(uint16 step, uint8 setplayer, card* ptarget, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 sset(uint16 step, uint8 setplayer, uint8 toplayer, card* ptarget);
int32 sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm);
int32 sset(uint16 step, uint8 setplayer, uint8 toplayer, card* ptarget, effect* reason_effect);
int32 sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm, effect* reason_effect);
int32 special_summon_rule(uint16 step, uint8 sumplayer, card* target, uint32 summon_type);
int32 special_summon_step(uint16 step, group* targets, card* target, uint32 zone);
int32 special_summon(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint32 zone);
......
......@@ -399,9 +399,9 @@ int32 scriptlib::duel_sets(lua_State *L) {
} else
luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
if(pcard)
pduel->game_field->add_process(PROCESSOR_SSET, 0, 0, (group*)pcard, playerid, toplayer);
pduel->game_field->add_process(PROCESSOR_SSET, 0, pduel->game_field->core.reason_effect, (group*)pcard, playerid, toplayer);
else
pduel->game_field->add_process(PROCESSOR_SSET_G, 0, 0, pgroup, playerid, toplayer, confirm);
pduel->game_field->add_process(PROCESSOR_SSET_G, 0, pduel->game_field->core.reason_effect, pgroup, playerid, toplayer, confirm);
return lua_yield(L, 0);
}
int32 scriptlib::duel_create_token(lua_State *L) {
......
......@@ -683,7 +683,7 @@ int32 field::remove_counter(uint16 step, uint32 reason, card* pcard, uint8 rplay
if(core.select_options.size() == 1)
returns.ivalue[0] = 0;
else if(core.select_effects[0] == 0 && core.select_effects.size() == 2)
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_effects[1]->handler, rplayer, 219);
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_effects[1]->handler, rplayer, 220);
else
add_process(PROCESSOR_SELECT_OPTION, 0, 0, 0, rplayer, 0);
return FALSE;
......@@ -759,7 +759,7 @@ int32 field::remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8
if(core.select_options.size() == 1)
returns.ivalue[0] = 0;
else if(core.select_effects[0] == 0 && core.select_effects.size() == 2)
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_effects[1]->handler, rplayer, 220);
add_process(PROCESSOR_SELECT_EFFECTYN, 0, 0, (group*)core.select_effects[1]->handler, rplayer, 219);
else
add_process(PROCESSOR_SELECT_OPTION, 0, 0, 0, rplayer, 0);
return FALSE;
......@@ -2276,7 +2276,7 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
}
return TRUE;
}
int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target) {
int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target, effect* reason_effect) {
switch(step) {
case 0: {
if(!(target->data.type & TYPE_FIELD) && get_useable_count(target, toplayer, LOCATION_SZONE, setplayer, LOCATION_REASON_TOFIELD) <= 0)
......@@ -2322,7 +2322,7 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target) {
pduel->write_buffer32(target->data.code);
pduel->write_buffer32(target->get_info_location());
adjust_instant();
raise_event(target, EVENT_SSET, 0, 0, setplayer, setplayer, 0);
raise_event(target, EVENT_SSET, reason_effect, 0, setplayer, setplayer, 0);
process_instant_event();
if(core.current_chain.size() == 0) {
adjust_all();
......@@ -2333,7 +2333,7 @@ int32 field::sset(uint16 step, uint8 setplayer, uint8 toplayer, card * target) {
}
return TRUE;
}
int32 field::sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm) {
int32 field::sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm, effect* reason_effect) {
switch(step) {
case 0: {
card_set* set_cards = new card_set;
......@@ -2490,7 +2490,7 @@ int32 field::sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget
case 7: {
returns.ivalue[0] = core.operated_set.size();
adjust_instant();
raise_event(&core.operated_set, EVENT_SSET, 0, 0, setplayer, setplayer, 0);
raise_event(&core.operated_set, EVENT_SSET, reason_effect, 0, setplayer, setplayer, 0);
process_instant_event();
if(core.current_chain.size() == 0) {
adjust_all();
......@@ -5944,16 +5944,19 @@ int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player,
effect* peffect = 0;
tevent e;
e.event_cards = 0;
e.reason_effect = core.reason_effect;
e.reason_player = core.reason_player;
e.event_player = playerid;
e.event_value = count;
e.reason = 0;
e.reason_effect = reason_effect;
e.reason_player = reason_player;
for(uint8 i = 0; i < 5; ++i)
core.coin_result[i] = 0;
filter_field_effect(EFFECT_TOSS_COIN_REPLACE, &eset);
for(int32 i = eset.size() - 1; i >= 0; --i) {
if(eset[i]->is_activateable(eset[i]->get_handler_player(), e)) {
peffect = eset[i];
auto pr = effects.continuous_effect.equal_range(EFFECT_TOSS_COIN_REPLACE);
for(auto eit = pr.first; eit != pr.second;) {
effect* pe = eit->second;
++eit;
if(pe->is_activateable(pe->get_handler_player(), e)) {
peffect = pe;
break;
}
}
......@@ -5967,17 +5970,22 @@ int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player,
}
raise_event((card*)0, EVENT_TOSS_COIN_NEGATE, reason_effect, 0, reason_player, playerid, count);
process_instant_event();
return FALSE;
} else {
solve_continuous(peffect->get_handler_player(), peffect, e);
return TRUE;
core.units.begin()->step = 1;
}
return FALSE;
}
case 1: {
raise_event((card*)0, EVENT_TOSS_COIN, reason_effect, 0, reason_player, playerid, count);
process_instant_event();
return TRUE;
}
case 2: {
for(uint8 i = 0; i < 5; ++i)
core.coin_result[i] = (returns.ivalue[0] >> (i * 4)) & 0xf;
return TRUE;
}
}
return TRUE;
}
......@@ -5988,16 +5996,19 @@ int32 field::toss_dice(uint16 step, effect * reason_effect, uint8 reason_player,
effect* peffect = 0;
tevent e;
e.event_cards = 0;
e.reason_effect = core.reason_effect;
e.reason_player = core.reason_player;
e.event_player = playerid;
e.event_value = count1 + (count2 << 16);
e.reason = 0;
e.reason_effect = reason_effect;
e.reason_player = reason_player;
for(int32 i = 0; i < 5; ++i)
core.dice_result[i] = 0;
filter_field_effect(EFFECT_TOSS_DICE_REPLACE, &eset);
for(int32 i = eset.size() - 1; i >= 0; --i) {
if(eset[i]->is_activateable(eset[i]->get_handler_player(), e)) {
peffect = eset[i];
auto pr = effects.continuous_effect.equal_range(EFFECT_TOSS_DICE_REPLACE);
for(auto eit = pr.first; eit != pr.second;) {
effect* pe = eit->second;
++eit;
if(pe->is_activateable(pe->get_handler_player(), e)) {
peffect = pe;
break;
}
}
......@@ -6020,17 +6031,22 @@ int32 field::toss_dice(uint16 step, effect * reason_effect, uint8 reason_player,
}
raise_event((card*)0, EVENT_TOSS_DICE_NEGATE, reason_effect, 0, reason_player, playerid, count1 + (count2 << 16));
process_instant_event();
return FALSE;
} else {
solve_continuous(peffect->get_handler_player(), peffect, e);
return TRUE;
core.units.begin()->step = 1;
}
return FALSE;
}
case 1: {
raise_event((card*)0, EVENT_TOSS_DICE, reason_effect, 0, reason_player, playerid, count1 + (count2 << 16));
process_instant_event();
return TRUE;
}
case 2: {
for(uint8 i = 0; i < 5; ++i)
core.dice_result[i] = (returns.ivalue[0] >> (i * 4)) & 0xf;
return TRUE;
}
}
return TRUE;
}
......
......@@ -395,7 +395,7 @@ int32 field::process() {
return pduel->bufferlen;
}
case PROCESSOR_SSET: {
if (sset(it->step, it->arg1, it->arg2, (card*)(it->ptarget)))
if (sset(it->step, it->arg1, it->arg2, (card*)(it->ptarget), it->peffect))
core.units.pop_front();
else
it->step++;
......@@ -409,7 +409,7 @@ int32 field::process() {
return pduel->bufferlen;
}
case PROCESSOR_SSET_G: {
if (sset_g(it->step, it->arg1, it->arg2, it->ptarget, it->arg3)) {
if (sset_g(it->step, it->arg1, it->arg2, it->ptarget, it->arg3, it->peffect)) {
pduel->lua->add_param(returns.ivalue[0], PARAM_TYPE_INT);
core.units.pop_front();
} else
......@@ -1646,7 +1646,6 @@ int32 field::process_phase_event(int16 step, int32 phase) {
}
return TRUE;
}
// core.tmp_chains: used in step 8 (obsolete ignition effect ruling)
int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_freechain, int32 skip_new) {
switch(step) {
case 0: {
......@@ -1824,7 +1823,7 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
newchain.triggering_effect = peffect;
newchain.set_triggering_state(phandler);
newchain.triggering_player = infos.turn_player;
core.tmp_chains.push_back(newchain);
core.ignition_priority_chains.push_back(newchain);
}
}
}
......@@ -1983,8 +1982,8 @@ int32 field::process_quick_effect(int16 step, int32 skip_freechain, uint8 priori
}
case 2: {
chain newchain;
if(core.tmp_chains.size())
core.select_chains.swap(core.tmp_chains);
if(core.ignition_priority_chains.size())
core.select_chains.swap(core.ignition_priority_chains);
for(auto evit = core.point_event.begin(); evit != core.instant_event.end(); ++evit) {
if(evit == core.point_event.end())
evit = core.instant_event.begin();
......@@ -3143,11 +3142,7 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 21: {
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]
|| core.attacker->current.controler != core.attacker->attack_controler
|| (core.attack_target && (core.attack_target->current.location != LOCATION_MZONE
|| core.attack_target->current.controler != core.attack_target->attack_controler
|| core.attack_target->fieldid_r != core.pre_field[1]))) {
if(core.attacker->is_status(STATUS_ATTACK_CANCELED)) {
core.units.begin()->step = 32;
return FALSE;
}
......@@ -3185,12 +3180,7 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 23: {
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]
|| ((core.attacker->current.position & POS_DEFENSE) && !(core.attacker->is_affected_by_effect(EFFECT_DEFENSE_ATTACK)))
|| core.attacker->current.controler != core.attacker->attack_controler
|| (core.attack_target && (core.attack_target->current.location != LOCATION_MZONE
|| core.attack_target->current.controler != core.attack_target->attack_controler
|| core.attack_target->fieldid_r != core.pre_field[1]))) {
if(core.attacker->is_status(STATUS_ATTACK_CANCELED)) {
core.units.begin()->step = 32;
return FALSE;
}
......@@ -3220,11 +3210,7 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 25: {
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]
|| core.attacker->current.controler != core.attacker->attack_controler
|| (core.attack_target && (core.attack_target->current.location != LOCATION_MZONE
|| core.attack_target->current.controler != core.attack_target->attack_controler
|| core.attack_target->fieldid_r != core.pre_field[1]))) {
if(core.attacker->is_status(STATUS_ATTACK_CANCELED)) {
reset_phase(PHASE_DAMAGE_CAL);
adjust_all();
infos.phase = PHASE_DAMAGE;
......@@ -3473,7 +3459,6 @@ int32 field::process_battle_command(uint16 step) {
}
case 33: {
core.units.begin()->ptarget = 0;
// for unexpected end of damage step
core.damage_calculated = TRUE;
core.selfdes_disabled = FALSE;
core.flip_delayed = FALSE;
......@@ -4357,7 +4342,7 @@ int32 field::add_chain(uint16 step) {
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) && peffect->is_flag(EFFECT_FLAG_CARD_TARGET)) {
if(core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) {
auto& optarget = clit.opinfos[0x200];
if(optarget.op_cards) {
if(optarget.op_player == PLAYER_ALL) {
......@@ -4603,32 +4588,30 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
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
if(cait->triggering_effect->is_flag(EFFECT_FLAG_CARD_TARGET)) {
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& 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();
check_card_counter(*opit, 3, sumplayer);
if((*opit)->spsummon_code)
core.spsummon_once_map[sumplayer][(*opit)->spsummon_code]++;
++opit;
check_card_counter(*opit, 3, 1 - sumplayer);
} else {
uint32 sumplayer = cait->triggering_player;
if(optarget.op_player == 1)
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);
}
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;
if(optarget.op_player == 1)
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);
}
}
}
......@@ -4971,7 +4954,7 @@ int32 field::adjust_step(uint16 step) {
return FALSE;
}
case 1: {
//win check(deck=0 or lp=0)
//win check
uint32 winp = 5, rea = 1;
if(player[0].lp <= 0 && player[1].lp > 0) {
winp = 1;
......@@ -5230,21 +5213,31 @@ int32 field::adjust_step(uint16 step) {
return FALSE;
if(attacker->is_status(STATUS_ATTACK_CANCELED))
return FALSE;
if(!core.attacker->is_capable_attack()
|| core.attacker->current.controler != core.attacker->attack_controler
|| core.attacker->fieldid_r != core.pre_field[0]) {
attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
return FALSE;
}
if(core.attack_rollback)
return FALSE;
std::set<uint16> fidset;
for(auto& pcard : player[1 - infos.turn_player].list_mzone) {
if(pcard)
fidset.insert(pcard->fieldid_r);
if(infos.phase != PHASE_DAMAGE && infos.phase != PHASE_DAMAGE_CAL) {
if(!core.attacker->is_capable_attack()
|| core.attacker->current.controler != core.attacker->attack_controler
|| core.attacker->fieldid_r != core.pre_field[0]) {
attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
return FALSE;
}
if(core.attack_rollback)
return FALSE;
std::set<uint16> fidset;
for(auto& pcard : player[1 - infos.turn_player].list_mzone) {
if(pcard)
fidset.insert(pcard->fieldid_r);
}
if(fidset != core.opp_mzone || !confirm_attack_target())
core.attack_rollback = TRUE;
} else {
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]
|| ((core.attacker->current.position & POS_DEFENSE) && !(core.attacker->is_affected_by_effect(EFFECT_DEFENSE_ATTACK)))
|| core.attacker->current.controler != core.attacker->attack_controler
|| (core.attack_target && (core.attack_target->current.location != LOCATION_MZONE
|| core.attack_target->current.controler != core.attack_target->attack_controler
|| core.attack_target->fieldid_r != core.pre_field[1])))
core.attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
}
if(fidset != core.opp_mzone || !confirm_attack_target())
core.attack_rollback = TRUE;
return FALSE;
}
case 15: {
......
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