Commit 4acc89c4 authored by nanahira's avatar nanahira

update

parent ba1c618c
......@@ -65,7 +65,7 @@ card::card(duel* pd) {
ref_handle = 0;
pduel = pd;
owner = PLAYER_NONE;
operation_param = 0;
sendto_param.clear();
release_param = 0;
sum_param = 0;
position_param = 0;
......@@ -3165,7 +3165,50 @@ effect* card::check_indestructable_by_effect(effect* peffect, uint8 playerid) {
return 0;
}
int32 card::is_destructable_by_effect(effect* peffect, uint8 playerid) {
return !check_indestructable_by_effect(peffect, playerid);
if(!is_affect_by_effect(peffect))
return FALSE;
if(check_indestructable_by_effect(peffect, playerid))
return FALSE;
effect_set eset;
eset.clear();
filter_effect(EFFECT_INDESTRUCTABLE, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(REASON_EFFECT, PARAM_TYPE_INT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
if(eset[i]->check_value_condition(3)) {
return FALSE;
break;
}
}
eset.clear();
filter_effect(EFFECT_INDESTRUCTABLE_COUNT, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
if((eset[i]->reset_count & 0xf00) == 0)
continue;
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(REASON_EFFECT, PARAM_TYPE_INT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
if(eset[i]->check_value_condition(3)) {
return FALSE;
break;
}
} else {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(REASON_EFFECT, PARAM_TYPE_INT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
int32 ct;
if(ct = eset[i]->get_value(3)) {
auto it = indestructable_effects.insert(std::make_pair(eset[i]->id, 0));
if(it.first->second + 1 <= ct) {
return FALSE;
break;
}
}
}
}
return TRUE;
}
int32 card::is_removeable(uint8 playerid) {
if(!pduel->game_field->is_player_can_remove(playerid, this))
......@@ -3278,14 +3321,14 @@ int32 card::is_capable_cost_to_grave(uint8 playerid) {
return FALSE;
if(!is_capable_send_to_grave(playerid))
return FALSE;
uint32 op_param = operation_param;
operation_param = dest << 8;
auto op_param = sendto_param;
sendto_param.location = dest;
if(current.location & LOCATION_ONFIELD)
redirect = leave_field_redirect(REASON_COST) & 0xffff;
if(redirect) dest = redirect;
redirect = destination_redirect(dest, REASON_COST) & 0xffff;
if(redirect) dest = redirect;
operation_param = op_param;
sendto_param = op_param;
if(dest != LOCATION_GRAVE)
return FALSE;
return TRUE;
......@@ -3301,14 +3344,14 @@ int32 card::is_capable_cost_to_hand(uint8 playerid) {
return FALSE;
if(!is_capable_send_to_hand(playerid))
return FALSE;
uint32 op_param = operation_param;
operation_param = dest << 8;
auto op_param = sendto_param;
sendto_param.location = dest;
if(current.location & LOCATION_ONFIELD)
redirect = leave_field_redirect(REASON_COST) & 0xffff;
if(redirect) dest = redirect;
redirect = destination_redirect(dest, REASON_COST) & 0xffff;
if(redirect) dest = redirect;
operation_param = op_param;
sendto_param = op_param;
if(dest != LOCATION_HAND)
return FALSE;
return TRUE;
......@@ -3324,14 +3367,14 @@ int32 card::is_capable_cost_to_deck(uint8 playerid) {
return FALSE;
if(!is_capable_send_to_deck(playerid))
return FALSE;
uint32 op_param = operation_param;
operation_param = dest << 8;
auto op_param = sendto_param;
sendto_param.location = dest;
if(current.location & LOCATION_ONFIELD)
redirect = leave_field_redirect(REASON_COST) & 0xffff;
if(redirect) dest = redirect;
redirect = destination_redirect(dest, REASON_COST) & 0xffff;
if(redirect) dest = redirect;
operation_param = op_param;
sendto_param = op_param;
if(dest != LOCATION_DECK)
return FALSE;
return TRUE;
......@@ -3347,14 +3390,14 @@ int32 card::is_capable_cost_to_extra(uint8 playerid) {
return FALSE;
if(!is_capable_send_to_deck(playerid))
return FALSE;
uint32 op_param = operation_param;
operation_param = dest << 8;
auto op_param = sendto_param;
sendto_param.location = dest;
if(current.location & LOCATION_ONFIELD)
redirect = leave_field_redirect(REASON_COST) & 0xffff;
if(redirect) dest = redirect;
redirect = destination_redirect(dest, REASON_COST) & 0xffff;
if(redirect) dest = redirect;
operation_param = op_param;
sendto_param = op_param;
if(dest != LOCATION_DECK)
return FALSE;
return TRUE;
......
......@@ -104,6 +104,24 @@ public:
public:
void addcard(card* pcard);
};
struct sendto_param_t {
void set(uint8 p, uint8 pos, uint8 loc, uint8 seq = 0) {
playerid = p;
position = pos;
location = loc;
sequence = seq;
}
void clear() {
playerid = 0;
position = 0;
location = 0;
sequence = 0;
}
uint8 playerid;
uint8 position;
uint8 location;
uint8 sequence;
};
int32 scrtype;
int32 ref_handle;
duel* pduel;
......@@ -116,7 +134,7 @@ public:
uint8 summon_player;
uint32 summon_info;
uint32 status;
uint32 operation_param;
sendto_param_t sendto_param;
uint32 release_param;
uint32 sum_param;
uint32 position_param;
......@@ -467,7 +485,7 @@ public:
#define STATUS_SUMMON_DISABLED 0x20000 //
#define STATUS_ACTIVATE_DISABLED 0x40000 //
#define STATUS_EFFECT_REPLACED 0x80000
#define STATUS_UNION 0x100000
#define STATUS_FUTURE_FUSION 0x100000
#define STATUS_ATTACK_CANCELED 0x200000
#define STATUS_INITIALIZING 0x400000
#define STATUS_ACTIVATED 0x800000
......
......@@ -164,7 +164,7 @@ void field::add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence
return;
if((pcard->data.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) && (location & (LOCATION_HAND | LOCATION_DECK))) {
location = LOCATION_EXTRA;
pcard->operation_param = (pcard->operation_param & 0x00ffffff) | (POS_FACEDOWN_DEFENSE << 24);
pcard->sendto_param.position = POS_FACEDOWN_DEFENSE;
}
pcard->current.controler = playerid;
pcard->current.location = location;
......@@ -192,14 +192,14 @@ void field::add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence
if(!core.shuffle_check_disabled)
core.shuffle_deck_check[playerid] = TRUE;
}
pcard->operation_param = (pcard->operation_param & 0x00ffffff) | (POS_FACEDOWN << 24);
pcard->sendto_param.position = POS_FACEDOWN;
break;
}
case LOCATION_HAND: {
player[playerid].list_hand.push_back(pcard);
pcard->current.sequence = player[playerid].list_hand.size() - 1;
uint32 pos = pcard->is_affected_by_effect(EFFECT_PUBLIC) ? POS_FACEUP : POS_FACEDOWN;
pcard->operation_param = (pcard->operation_param & 0x00ffffff) | (pos << 24);
pcard->sendto_param.position = pos;
if(!(pcard->current.reason & REASON_DRAW) && !core.shuffle_check_disabled)
core.shuffle_hand_check[playerid] = TRUE;
break;
......@@ -217,7 +217,7 @@ void field::add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence
case LOCATION_EXTRA: {
player[playerid].list_extra.push_back(pcard);
pcard->current.sequence = player[playerid].list_extra.size() - 1;
if((pcard->data.type & TYPE_PENDULUM) && ((pcard->operation_param >> 24) & POS_FACEUP))
if((pcard->data.type & TYPE_PENDULUM) && (pcard->sendto_param.position & POS_FACEUP))
++player[playerid].extra_p_count;
break;
}
......@@ -299,7 +299,7 @@ void field::move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequenc
uint8 presequence = pcard->current.sequence;
if((pcard->data.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)) && (location & (LOCATION_HAND | LOCATION_DECK))) {
location = LOCATION_EXTRA;
pcard->operation_param = (pcard->operation_param & 0x00ffffff) | (POS_FACEDOWN_DEFENSE << 24);
pcard->sendto_param.position = POS_FACEDOWN_DEFENSE;
}
if (pcard->current.location) {
if (pcard->current.location == location) {
......@@ -411,7 +411,7 @@ void field::move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequenc
&& (((pcard->current.location == LOCATION_MZONE) && !pcard->is_status(STATUS_SUMMON_DISABLED))
|| ((pcard->current.location == LOCATION_SZONE) && !pcard->is_status(STATUS_ACTIVATE_DISABLED)))) {
location = LOCATION_EXTRA;
pcard->operation_param = (pcard->operation_param & 0x00ffffff) | (POS_FACEUP_DEFENSE << 24);
pcard->sendto_param.position = POS_FACEUP_DEFENSE;
}
remove_card(pcard);
}
......@@ -2115,12 +2115,11 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack)
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())
if(idset.size() == 1 && only_be_attack.size() == 1 && only_be_attack.front()->fieldid_r == *idset.begin())
pv = &only_be_attack;
else
return atype;
}
else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)) {
} else if(pcard->is_affected_by_effect(EFFECT_ONLY_ATTACK_MONSTER)) {
atype = 2;
if(only_be_attack.size() == 1)
pv = &only_be_attack;
......
......@@ -662,7 +662,7 @@ int32 scriptlib::card_get_destination(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
lua_pushinteger(L, (pcard->operation_param >> 8) & 0xff);
lua_pushinteger(L, pcard->sendto_param.location);
return 1;
}
int32 scriptlib::card_get_leave_field_dest(lua_State *L) {
......
......@@ -39,7 +39,7 @@ int32 scriptlib::debug_add_card(lua_State *L) {
if(pduel->game_field->is_location_useable(playerid, location, sequence)) {
card* pcard = pduel->new_card(code);
pcard->owner = owner;
pcard->operation_param = position << 24;
pcard->sendto_param.position = position;
if(location == LOCATION_PZONE) {
int32 seq = pduel->game_field->core.duel_rule >= 4 ? sequence * 4 : sequence + 6;
pduel->game_field->add_card(playerid, pcard, LOCATION_SZONE, seq, TRUE);
......
......@@ -1667,6 +1667,8 @@ int32 scriptlib::duel_get_chain_info(lua_State *L) {
uint32 args = lua_gettop(L) - 1;
duel* pduel = interpreter::get_duel_info(L);
chain* ch = pduel->game_field->get_chain(c);
if(!ch)
return 0;
for(uint32 i = 0; i < args; ++i) {
flag = lua_tointeger(L, 2 + i);
switch(flag) {
......
This diff is collapsed.
......@@ -2839,9 +2839,9 @@ int32 field::process_battle_command(uint16 step) {
uint8 chain_attack = FALSE;
if(core.chain_attack && core.chain_attacker_id == pcard->fieldid)
chain_attack = TRUE;
core.select_cards.clear();
get_attack_target(pcard, &core.select_cards, chain_attack);
if(core.select_cards.size() == 0 && pcard->direct_attackable == 0)
card_vector cv;
get_attack_target(pcard, &cv, chain_attack);
if(cv.size() == 0 && pcard->direct_attackable == 0)
continue;
core.attackable_cards.push_back(pcard);
if(pcard->is_affected_by_effect(EFFECT_FIRST_ATTACK))
......@@ -3061,7 +3061,8 @@ int32 field::process_battle_command(uint16 step) {
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);
}
core.units.begin()->arg2 = (core.attacker->current.controler << 16) + core.attacker->fieldid_r;
core.attacker->attack_controler = core.attacker->current.controler;
core.pre_field[0] = core.attacker->fieldid_r;
if(evt) {
process_single_event();
process_instant_event();
......@@ -3098,16 +3099,16 @@ int32 field::process_battle_command(uint16 step) {
case 10: {
uint8 rollback = core.attack_rollback;
bool atk_disabled = false;
uint32 acon = core.units.begin()->arg2 >> 16;
uint32 afid = core.units.begin()->arg2 & 0xffff;
uint32 acon = core.attacker->attack_controler;
uint32 afid = core.pre_field[0];
if(core.attacker->is_affected_by_effect(EFFECT_ATTACK_DISABLED)) {
core.attacker->reset(EFFECT_ATTACK_DISABLED, RESET_CODE);
atk_disabled = true;
pduel->write_buffer8(MSG_ATTACK_DISABLED);
core.attacker->set_status(STATUS_ATTACK_CANCELED, TRUE);
}
effect* peffect;
if((peffect = is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP))) {
effect* peffect = is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP);
if(peffect) {
core.units.begin()->step = 41;
core.units.begin()->arg1 = 2;
if(is_player_affected_by_effect(infos.turn_player, EFFECT_BP_TWICE))
......@@ -3143,26 +3144,13 @@ int32 field::process_battle_command(uint16 step) {
rollback = true;
// go to damage step
if(!rollback) {
infos.phase = PHASE_DAMAGE;
core.chain_attack = FALSE;
core.units.begin()->arg1 = FALSE;
core.damage_calculated = FALSE;
core.selfdes_disabled = TRUE;
core.flip_delayed = TRUE;
core.pre_field[0] = core.attacker->fieldid_r;
if(core.attack_target)
core.pre_field[1] = core.attack_target->fieldid_r;
else
core.pre_field[1] = 0;
core.attacker->attacked_count++;
core.attacker->attacked_cards.addcard(core.attack_target);
core.battled_count[infos.turn_player]++;
core.units.begin()->step = 19;
adjust_all();
core.units.begin()->step = 18;
return FALSE;
}
// attack canceled
if(!core.select_cards.size() && !core.attacker->direct_attackable) {
card_vector cv;
get_attack_target(core.attacker, &cv, core.chain_attack);
if(!cv.size() && !core.attacker->direct_attackable) {
core.chain_attack = FALSE;
core.units.begin()->step = -1;
reset_phase(PHASE_DAMAGE);
......@@ -3190,14 +3178,32 @@ int32 field::process_battle_command(uint16 step) {
adjust_all();
return FALSE;
}
case 19: {
infos.phase = PHASE_DAMAGE;
core.chain_attack = FALSE;
core.units.begin()->arg1 = FALSE;
core.damage_calculated = FALSE;
core.selfdes_disabled = TRUE;
core.flip_delayed = TRUE;
core.attacker->attack_controler = core.attacker->current.controler;
core.pre_field[0] = core.attacker->fieldid_r;
if(core.attack_target) {
core.attack_target->attack_controler = core.attack_target->current.controler;
core.pre_field[1] = core.attack_target->fieldid_r;
} else
core.pre_field[1] = 0;
core.attacker->attacked_count++;
core.attacker->attacked_cards.addcard(core.attack_target);
core.battled_count[infos.turn_player]++;
adjust_all();
return FALSE;
}
case 20: {
// start of PHASE_DAMAGE;
pduel->write_buffer8(MSG_DAMAGE_STEP_START);
raise_single_event(core.attacker, 0, EVENT_BATTLE_START, 0, 0, 0, 0, 0);
core.attacker->attack_controler = core.attacker->current.controler;
if(core.attack_target) {
raise_single_event(core.attack_target, 0, EVENT_BATTLE_START, 0, 0, 0, 0, 1);
core.attack_target->attack_controler = core.attack_target->current.controler;
}
raise_event((card*)0, EVENT_BATTLE_START, 0, 0, 0, 0, 0);
process_single_event();
......@@ -3211,7 +3217,6 @@ int32 field::process_battle_command(uint16 step) {
pduel->write_buffer8(1);
pduel->write_buffer32(40);
add_process(PROCESSOR_POINT_EVENT, 0, 0, 0, 0, TRUE);
core.temp_var[2] = 0;
return FALSE;
}
case 21: {
......@@ -3235,12 +3240,11 @@ int32 field::process_battle_command(uint16 step) {
return FALSE;
}
case 22: {
int32 r = core.temp_var[2] == 0 ? 0 : REASON_REPLACE;
raise_single_event(core.attacker, 0, EVENT_BATTLE_CONFIRM, 0, r, 0, 0, 0);
raise_single_event(core.attacker, 0, EVENT_BATTLE_CONFIRM, 0, 0, 0, 0, 0);
if(core.attack_target) {
if(core.attack_target->temp.position & POS_FACEDOWN)
core.pre_field[1] = core.attack_target->fieldid_r;
raise_single_event(core.attack_target, 0, EVENT_BATTLE_CONFIRM, 0, r, 0, 0, 1);
raise_single_event(core.attack_target, 0, EVENT_BATTLE_CONFIRM, 0, 0, 0, 0, 1);
}
raise_event((card*)0, EVENT_BATTLE_CONFIRM, 0, 0, 0, 0, 0);
process_single_event();
......@@ -3440,7 +3444,6 @@ int32 field::process_battle_command(uint16 step) {
case 28: {
card_set des;
effect* peffect;
uint32 dest, seq;
if(core.attacker->is_status(STATUS_BATTLE_RESULT)
&& core.attacker->current.location == LOCATION_MZONE && core.attacker->fieldid_r == core.pre_field[0]) {
des.insert(core.attacker);
......@@ -3452,14 +3455,14 @@ int32 field::process_battle_command(uint16 step) {
core.attacker->current.reason = REASON_BATTLE;
core.attacker->current.reason_card = core.attack_target;
core.attacker->current.reason_player = core.attack_target->current.controler;
dest = LOCATION_GRAVE;
seq = 0;
uint32 dest = LOCATION_GRAVE;
uint32 seq = 0;
if((peffect = core.attack_target->is_affected_by_effect(EFFECT_BATTLE_DESTROY_REDIRECT)) && (core.attacker->data.type & TYPE_MONSTER)) {
dest = peffect->get_value(core.attacker);
seq = dest >> 16;
dest &= 0xffff;
}
core.attacker->operation_param = (POS_FACEUP << 24) + (((uint32)core.attacker->owner) << 16) + (dest << 8) + seq;
core.attacker->sendto_param.set(core.attacker->owner, POS_FACEUP, dest, seq);
core.attacker->set_status(STATUS_DESTROY_CONFIRMED, TRUE);
}
if(core.attack_target && core.attack_target->is_status(STATUS_BATTLE_RESULT)
......@@ -3473,14 +3476,14 @@ int32 field::process_battle_command(uint16 step) {
core.attack_target->current.reason = REASON_BATTLE;
core.attack_target->current.reason_card = core.attacker;
core.attack_target->current.reason_player = core.attacker->current.controler;
dest = LOCATION_GRAVE;
seq = 0;
uint32 dest = LOCATION_GRAVE;
uint32 seq = 0;
if((peffect = core.attacker->is_affected_by_effect(EFFECT_BATTLE_DESTROY_REDIRECT)) && (core.attack_target->data.type & TYPE_MONSTER)) {
dest = peffect->get_value(core.attack_target);
seq = dest >> 16;
dest &= 0xffff;
}
core.attack_target->operation_param = (POS_FACEUP << 24) + (((uint32)core.attack_target->owner) << 16) + (dest << 8) + seq;
core.attack_target->sendto_param.set(core.attack_target->owner, POS_FACEUP, dest, seq);
core.attack_target->set_status(STATUS_DESTROY_CONFIRMED, TRUE);
}
core.attacker->set_status(STATUS_BATTLE_RESULT, 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