Commit 23c0a61a authored by Momobako's avatar Momobako

updcore

parent d361e21c
......@@ -365,7 +365,8 @@ void field::move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequenc
if(preplayer == playerid) {
pduel->write_buffer32(pcard->get_info_location());
pduel->write_buffer32(pcard->current.reason);
}
} else
pcard->fieldid = infos.field_id++;
return;
} else if(location == LOCATION_HAND) {
if(preplayer == playerid)
......@@ -419,6 +420,20 @@ void field::move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequenc
}
add_card(playerid, pcard, location, sequence, pzone);
}
void field::swap_card(card* pcard1, card* pcard2) {
uint8 p1 = pcard1->current.controler, p2 = pcard2->current.controler;
uint8 l1 = pcard1->current.location, l2 = pcard2->current.location;
uint8 s1 = pcard1->current.sequence, s2 = pcard2->current.sequence;
remove_card(pcard1);
remove_card(pcard2);
add_card(p2, pcard1, l2, s2);
add_card(p1, pcard2, l1, s1);
pduel->write_buffer8(MSG_SWAP);
pduel->write_buffer32(pcard1->data.code);
pduel->write_buffer32(pcard2->get_info_location());
pduel->write_buffer32(pcard2->data.code);
pduel->write_buffer32(pcard1->get_info_location());
}
// add EFFECT_SET_CONTROL
void field::set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count) {
if((core.remove_brainwashing && pcard->is_affected_by_effect(EFFECT_REMOVE_BRAINWASHING)) || pcard->refresh_control_status() == playerid)
......@@ -1800,47 +1815,33 @@ void field::adjust_disable_check_list() {
void field::adjust_self_destroy_set() {
if(core.selfdes_disabled || !core.unique_destroy_set.empty() || !core.self_destroy_set.empty() || !core.self_tograve_set.empty())
return;
core.unique_destroy_set.clear();
card_set cset;
int32 p = infos.turn_player;
for(int32 p1 = 0; p1 < 2; ++p1) {
std::vector<card*> uniq_set;
for(auto iter = core.unique_cards[p].begin(); iter != core.unique_cards[p].end(); ++iter) {
card* ucard = *iter;
if(ucard->is_position(POS_FACEUP) && ucard->get_status(STATUS_EFFECT_ENABLED)
&& !ucard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN)) {
card_set cset;
ucard->get_unique_target(&cset, p);
if(cset.size() == 0)
ucard->unique_fieldid = 0;
else if(cset.size() == 1) {
auto cit = cset.begin();
ucard->unique_fieldid = (*cit)->fieldid;
} else {
card* mcard = 0;
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
if(ucard->unique_fieldid == pcard->fieldid) {
mcard = pcard;
break;
}
if(!mcard || pcard->fieldid < mcard->fieldid)
mcard = pcard;
}
ucard->unique_fieldid = mcard->fieldid;
cset.erase(mcard);
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
core.unique_destroy_set.insert(pcard);
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = ucard->unique_effect;
pcard->current.reason_player = ucard->current.controler;
}
}
} else
uniq_set.push_back(ucard);
}
}
std::sort(uniq_set.begin(), uniq_set.end(), [](card* lhs, card* rhs) { return lhs->fieldid < rhs->fieldid; });
for(auto iter = uniq_set.begin(); iter != uniq_set.end(); ++iter) {
card* pcard = *iter;
add_process(PROCESSOR_SELF_DESTROY, 0, 0, 0, p, 0, 0, 0, pcard);
core.unique_destroy_set.insert(pcard);
}
p = 1 - p;
}
cset.clear();
card_set cset;
for(uint8 p = 0; p < 2; ++p) {
for(auto cit = player[p].list_mzone.begin(); cit != player[p].list_mzone.end(); ++cit) {
card* pcard = *cit;
......@@ -1853,17 +1854,11 @@ void field::adjust_self_destroy_set() {
cset.insert(pcard);
}
}
core.self_destroy_set.clear();
core.self_tograve_set.clear();
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_DESTROY);
if(peffect) {
core.self_destroy_set.insert(pcard);
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = peffect;
pcard->current.reason_player = peffect->get_handler_player();
}
}
if(core.global_flag & GLOBALFLAG_SELF_TOGRAVE) {
......@@ -1872,15 +1867,13 @@ void field::adjust_self_destroy_set() {
effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_TOGRAVE);
if(peffect) {
core.self_tograve_set.insert(pcard);
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = peffect;
pcard->current.reason_player = peffect->get_handler_player();
}
}
}
if(!core.unique_destroy_set.empty() || !core.self_destroy_set.empty() || !core.self_tograve_set.empty())
add_process(PROCESSOR_SELF_DESTROY, 0, 0, 0, 0, 0);
if(!core.self_destroy_set.empty())
add_process(PROCESSOR_SELF_DESTROY, 10, 0, 0, 0, 0);
if(!core.self_tograve_set.empty())
add_process(PROCESSOR_SELF_DESTROY, 20, 0, 0, 0, 0);
}
void field::add_unique_card(card* pcard) {
uint8 con = pcard->current.controler;
......
......@@ -259,6 +259,7 @@ struct processor {
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];
......@@ -344,6 +345,7 @@ public:
void add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence, uint8 pzone = FALSE);
void remove_card(card* pcard);
void move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence, uint8 pzone = FALSE);
void swap_card(card* pcard1, card* pcard2);
void set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count);
card* get_field_card(uint32 playerid, uint32 location, uint32 sequence);
int32 is_location_useable(uint32 playerid, uint32 location, uint32 sequence, uint8 neglect_used = 0);
......@@ -527,7 +529,7 @@ public:
int32 get_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint8 playerid, uint16 reset_phase, uint8 reset_count, uint32 zone);
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);
int32 self_destroy(uint16 step, card* ucard, int32 p);
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);
......
......@@ -856,7 +856,7 @@ int32 field::get_control(uint16 step, effect* reason_effect, uint8 reason_player
if((pcard->get_type() & TYPE_TRAPMONSTER) && get_useable_count(playerid, LOCATION_SZONE, playerid, LOCATION_REASON_CONTROL) <= 0)
change = false;
if(!change)
targets->container.erase(pcard);
targets->container.erase(rm);
}
int32 fcount = get_useable_count(playerid, LOCATION_MZONE, playerid, LOCATION_REASON_CONTROL, zone);
if(fcount <= 0) {
......@@ -902,8 +902,6 @@ int32 field::get_control(uint16 step, effect* reason_effect, uint8 reason_player
}
card* pcard = *targets->it;
move_to_field(pcard, playerid, playerid, LOCATION_MZONE, pcard->current.position, FALSE, 0, FALSE, zone);
pcard->fieldid = infos.field_id++;
pcard->fieldid_r = pcard->fieldid;
return FALSE;
}
case 4: {
......@@ -1218,20 +1216,9 @@ int32 field::control_adjust(uint16 step) {
while(cit1 != core.control_adjust_set[0].end() && cit2 != core.control_adjust_set[1].end()) {
card* pcard1 = *cit1++;
card* pcard2 = *cit2++;
uint8 p1 = pcard1->current.controler, p2 = pcard2->current.controler;
uint8 l1 = pcard1->current.location, l2 = pcard2->current.location;
uint8 s1 = pcard1->current.sequence, s2 = pcard2->current.sequence;
remove_card(pcard1);
remove_card(pcard2);
add_card(p2, pcard1, l2, s2);
add_card(p1, pcard2, l1, s1);
swap_card(pcard1, pcard2);
pcard1->reset(RESET_CONTROL, RESET_EVENT);
pcard2->reset(RESET_CONTROL, RESET_EVENT);
pduel->write_buffer8(MSG_SWAP);
pduel->write_buffer32(pcard1->data.code);
pduel->write_buffer32(pcard2->get_info_location());
pduel->write_buffer32(pcard2->data.code);
pduel->write_buffer32(pcard1->get_info_location());
}
card_set* adjust_set = new card_set;
core.units.begin()->ptarget = (group*)adjust_set;
......@@ -1282,36 +1269,85 @@ int32 field::control_adjust(uint16 step) {
}
return TRUE;
}
int32 field::self_destroy(uint16 step) {
int32 field::self_destroy(uint16 step, card* ucard, int32 p) {
switch(step) {
case 0: {
if(!core.unique_destroy_set.empty())
destroy(&core.unique_destroy_set, 0, REASON_RULE, 5);
return FALSE;
core.unique_destroy_set.erase(ucard);
if(core.unique_cards[p].find(ucard) == core.unique_cards[p].end())
return TRUE;
card_set cset;
ucard->get_unique_target(&cset, p);
if(cset.size() == 0)
ucard->unique_fieldid = 0;
else if(cset.size() == 1) {
auto cit = cset.begin();
ucard->unique_fieldid = (*cit)->fieldid;
} else {
card* mcard = 0;
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
if(ucard->unique_fieldid == pcard->fieldid) {
mcard = pcard;
break;
}
if(!mcard || pcard->fieldid < mcard->fieldid)
mcard = pcard;
}
ucard->unique_fieldid = mcard->fieldid;
cset.erase(mcard);
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = ucard->unique_effect;
pcard->current.reason_player = ucard->current.controler;
}
destroy(&cset, 0, REASON_RULE, 5);
}
return TRUE;
}
case 1: {
core.unique_destroy_set.clear();
core.operated_set.clear();
if(!core.self_destroy_set.empty())
destroy(&core.self_destroy_set, 0, REASON_EFFECT, 5);
case 10: {
if(core.self_destroy_set.empty())
return FALSE;
auto it = core.self_destroy_set.begin();
card* pcard = *it;
effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_DESTROY);
if(peffect) {
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = peffect;
pcard->current.reason_player = peffect->get_handler_player();
destroy(pcard, 0, REASON_EFFECT, 5);
}
core.self_destroy_set.erase(it);
core.units.begin()->step = 9;
return FALSE;
}
case 2: {
core.self_destroy_set.clear();
core.operated_set.clear();
case 11: {
returns.ivalue[0] = 0;
if(!(core.global_flag & GLOBALFLAG_SELF_TOGRAVE))
return TRUE;
if(!core.self_tograve_set.empty())
send_to(&core.self_tograve_set, 0, REASON_EFFECT, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
else
return TRUE;
core.operated_set.clear();
return TRUE;
}
case 20: {
if(core.self_tograve_set.empty())
return FALSE;
auto it = core.self_tograve_set.begin();
card* pcard = *it;
effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_TOGRAVE);
if(peffect) {
pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player;
pcard->current.reason_effect = peffect;
pcard->current.reason_player = peffect->get_handler_player();
send_to(pcard, 0, REASON_EFFECT, PLAYER_NONE, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
}
core.self_tograve_set.erase(it);
core.units.begin()->step = 19;
return FALSE;
}
case 3: {
core.self_tograve_set.clear();
core.operated_set.clear();
case 21: {
returns.ivalue[0] = 0;
core.operated_set.clear();
return TRUE;
}
}
......
......@@ -480,7 +480,7 @@ int32 field::process() {
return pduel->bufferlen;
}
case PROCESSOR_SELF_DESTROY: {
if (self_destroy(it->step)) {
if (self_destroy(it->step, (card*)it->ptr1, it->arg1)) {
core.units.pop_front();
} else
it->step++;
......@@ -2839,6 +2839,7 @@ 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;
}
......@@ -2872,25 +2873,20 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
} else if(ctype == 1) {
core.units.begin()->step = 2;
core.units.begin()->arg3 = FALSE;
card* attacker = core.attackable_cards[sel];
if(core.chain_attack && core.chain_attacker_id != attacker->fieldid) {
core.chain_attack = FALSE;
core.chain_attacker_id = 0;
}
core.attacker = attacker;
core.attacker->set_status(STATUS_ATTACK_CANCELED, FALSE);
core.pre_field[0] = core.attacker->fieldid_r;
core.phase_action = TRUE;
core.attack_state_count[infos.turn_player]++;
check_card_counter(core.attacker, 5, infos.turn_player);
core.attacker->announce_count++;
effect_set eset;
filter_player_effect(infos.turn_player, EFFECT_ATTACK_COST, &eset, FALSE);
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);
adjust_all();
}
}
return FALSE;
......@@ -2921,12 +2917,12 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 3: {
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->fieldid_r != core.pre_field[0]) {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
core.units.begin()->arg1 = FALSE;
if(core.attacker->current.location != LOCATION_MZONE || core.attacker->current.controler != infos.turn_player || core.attacker->fieldid_r != core.pre_field[0]) {
core.units.begin()->arg3 = TRUE;
core.units.begin()->step = 6;
return FALSE;
}
core.units.begin()->arg1 = FALSE;
return FALSE;
}
case 4: {
......@@ -2951,10 +2947,10 @@ int32 field::process_battle_command(uint16 step) {
core.units.begin()->step = 5;
return FALSE;
}
// no target
// no target and not direct attackable
if(core.select_cards.size() == 0) {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
core.units.begin()->arg3 = TRUE;
core.units.begin()->step = 6;
return FALSE;
}
// must attack monster
......@@ -2976,7 +2972,7 @@ int32 field::process_battle_command(uint16 step) {
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(infos.turn_player);
pduel->write_buffer32(549);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player + (core.units.begin()->arg1 ? 0x20000 : 0), 0x10001);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
}
core.units.begin()->step = 5;
return FALSE;
......@@ -2991,20 +2987,22 @@ int32 field::process_battle_command(uint16 step) {
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(infos.turn_player);
pduel->write_buffer32(549);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player, 0x10001);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, infos.turn_player + (core.attack_cancelable ? 0x20000 : 0), 0x10001);
} else {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
core.units.begin()->arg3 = TRUE;
core.units.begin()->step = 6;
}
}
return FALSE;
}
case 6: {
if(returns.ivalue[0] == -1) {
core.chain_attack = FALSE;
if(returns.ivalue[0] == -1) {//cancel attack manually
if(core.units.begin()->arg1)
core.chain_attack = FALSE;
core.units.begin()->step = -1;
return FALSE;
} else if(returns.ivalue[0] == -2)
}
if(returns.ivalue[0] == -2)
core.attack_target = 0;
else
core.attack_target = core.select_cards[returns.bvalue[1]];
......@@ -3012,11 +3010,28 @@ 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.attacker->announced_cards.addcard(core.attack_target);
return FALSE;
}
case 7: {
if(!core.units.begin()->arg1) {
core.phase_action = TRUE;
if(core.chain_attack && core.chain_attacker_id != core.attacker->fieldid) {
core.chain_attack = FALSE;
core.chain_attacker_id = 0;
}
core.attack_state_count[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) {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
}
return FALSE;
}
case 8: {
bool evt = false;
attack_all_target_check();
pduel->write_buffer8(MSG_ATTACK);
......@@ -3052,9 +3067,9 @@ int32 field::process_battle_command(uint16 step) {
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0);
return FALSE;
}
case 8: {
case 9: {
if(is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP) || core.attack_rollback) {
core.units.begin()->step = 9;
core.units.begin()->step = 10;
return FALSE;
}
pduel->write_buffer8(MSG_HINT);
......@@ -3070,14 +3085,14 @@ int32 field::process_battle_command(uint16 step) {
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, 0);
return FALSE;
}
case 9: {
case 10: {
if(returns.ivalue[0])
core.units.begin()->step = 7;
core.units.begin()->step = 8;
else
adjust_all();
return FALSE;
}
case 10: {
case 11: {
uint8 rollback = core.attack_rollback;
bool atk_disabled = false;
uint32 acon = core.attacker->attack_controler;
......@@ -3146,10 +3161,12 @@ int32 field::process_battle_command(uint16 step) {
}
return FALSE;
}
case 11: {
case 12: {
// answer of "replay or not"
if(returns.ivalue[0]) {
core.units.begin()->arg1 = TRUE;
core.units.begin()->arg3 = FALSE;
core.attack_cancelable = TRUE;
core.units.begin()->step = 3;
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