Commit 4bb2465e authored by mercury233's avatar mercury233
parents 3fc1ec0d 8e4e8bac
...@@ -76,6 +76,7 @@ card::card(duel* pd) { ...@@ -76,6 +76,7 @@ card::card(duel* pd) {
spsummon_counter[0] = spsummon_counter[1] = 0; spsummon_counter[0] = spsummon_counter[1] = 0;
spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0; spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0;
unique_code = 0; unique_code = 0;
unique_fieldid = 0;
assume_type = 0; assume_type = 0;
assume_value = 0; assume_value = 0;
spsummon_code = 0; spsummon_code = 0;
...@@ -2289,18 +2290,42 @@ int32 card::check_fusion_substitute(card* fcard) { ...@@ -2289,18 +2290,42 @@ int32 card::check_fusion_substitute(card* fcard) {
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int32 card::is_equipable(card* pcard) { int32 card::check_unique_code(card* pcard) {
effect_set eset; if(!unique_code)
if(this == pcard || pcard->current.location != LOCATION_MZONE)
return FALSE;
filter_effect(EFFECT_EQUIP_LIMIT, &eset);
if(eset.size() == 0)
return FALSE; return FALSE;
for(int32 i = 0; i < eset.size(); ++i) if(unique_code == 1) {
if(eset[i]->get_value(pcard)) pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
return TRUE; return pduel->lua->get_function_value(unique_function, 1);
}
uint32 code1 = pcard->get_code();
uint32 code2 = pcard->get_another_code();
if(code1 == unique_code || (code2 && code2 == unique_code))
return TRUE;
return FALSE; return FALSE;
} }
void card::get_unique_target(card_set* cset, int32 controler) {
cset->clear();
for(int32 p = 0; p < 2; ++p) {
if(!unique_pos[p])
continue;
const auto& player = pduel->game_field->player[controler ^ p];
if(unique_location & LOCATION_MZONE) {
for(int32 i = 0; i < 5; ++i) {
card* pcard = player.list_mzone[i];
if(pcard && pcard->is_position(POS_FACEUP) && !pcard->is_status(STATUS_BATTLE_DESTROYED)
&& check_unique_code(pcard))
cset->insert(pcard);
}
}
if(unique_location & LOCATION_SZONE) {
for(int32 i = 0; i < 8; ++i) {
card* pcard = player.list_szone[i];
if(pcard && pcard->is_position(POS_FACEUP) && check_unique_code(pcard))
cset->insert(pcard);
}
}
}
}
// check if this is a normal summonable card // check if this is a normal summonable card
int32 card::is_summonable_card() { int32 card::is_summonable_card() {
if(!(data.type & TYPE_MONSTER)) if(!(data.type & TYPE_MONSTER))
......
...@@ -126,15 +126,16 @@ public: ...@@ -126,15 +126,16 @@ public:
uint16 turnid; uint16 turnid;
uint16 turn_counter; uint16 turn_counter;
uint8 unique_pos[2]; uint8 unique_pos[2];
uint16 unique_uid; uint32 unique_fieldid;
uint32 unique_code; uint32 unique_code;
uint32 unique_location; uint32 unique_location;
int32 unique_function;
effect* unique_effect;
uint32 spsummon_code; uint32 spsummon_code;
uint16 spsummon_counter[2]; uint16 spsummon_counter[2];
uint16 spsummon_counter_rst[2]; uint16 spsummon_counter_rst[2];
uint8 assume_type; uint8 assume_type;
uint32 assume_value; uint32 assume_value;
effect* unique_effect;
card* equiping_target; card* equiping_target;
card* pre_equip_target; card* pre_equip_target;
card* overlay_target; card* overlay_target;
...@@ -247,7 +248,8 @@ public: ...@@ -247,7 +248,8 @@ public:
void fusion_select(uint8 playerid, group* fusion_m, card* cg, uint32 chkf); void fusion_select(uint8 playerid, group* fusion_m, card* cg, uint32 chkf);
int32 check_fusion_substitute(card* fcard); int32 check_fusion_substitute(card* fcard);
int32 is_equipable(card* pcard); int32 check_unique_code(card* pcard);
void get_unique_target(card_set* cset, int32 controler);
int32 is_summonable_card(); int32 is_summonable_card();
int32 is_fusion_summonable_card(uint32 summon_type); int32 is_fusion_summonable_card(uint32 summon_type);
int32 is_spsummonable(effect* peffect); int32 is_spsummonable(effect* peffect);
......
...@@ -1477,15 +1477,55 @@ void field::adjust_disable_check_list() { ...@@ -1477,15 +1477,55 @@ void field::adjust_disable_check_list() {
} }
} while(effects.disable_check_list.size()); } while(effects.disable_check_list.size());
} }
// adjust check_unique_onfield(), EFFECT_SELF_DESTROY, EFFECT_SELF_TOGRAVE // adjust SetUniqueOnField(), EFFECT_SELF_DESTROY, EFFECT_SELF_TOGRAVE
void field::adjust_self_destroy_set() { void field::adjust_self_destroy_set() {
if(core.selfdes_disabled || !core.self_destroy_set.empty() || !core.self_tograve_set.empty()) if(core.selfdes_disabled || !core.unique_destroy_set.empty() || !core.self_destroy_set.empty() || !core.self_tograve_set.empty())
return; return;
core.unique_destroy_set.clear();
card_set cset; card_set cset;
int32 p = infos.turn_player;
for(int32 p1 = 0; p1 < 2; ++p1) {
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)) {
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;
}
}
}
}
p = 1 - p;
}
cset.clear();
for(uint8 p = 0; p < 2; ++p) { for(uint8 p = 0; p < 2; ++p) {
for(uint8 i = 0; i < 5; ++i) { for(uint8 i = 0; i < 5; ++i) {
card* pcard = player[p].list_mzone[i]; card* pcard = player[p].list_mzone[i];
if(pcard && pcard->is_position(POS_FACEUP)) if(pcard && pcard->is_position(POS_FACEUP) && !pcard->is_status(STATUS_BATTLE_DESTROYED))
cset.insert(pcard); cset.insert(pcard);
} }
for(uint8 i = 0; i < 8; ++i) { for(uint8 i = 0; i < 8; ++i) {
...@@ -1496,11 +1536,10 @@ void field::adjust_self_destroy_set() { ...@@ -1496,11 +1536,10 @@ void field::adjust_self_destroy_set() {
} }
core.self_destroy_set.clear(); core.self_destroy_set.clear();
core.self_tograve_set.clear(); core.self_tograve_set.clear();
effect* peffect;
for(auto cit = cset.begin(); cit != cset.end(); ++cit) { for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit; card* pcard = *cit;
if((peffect = check_unique_onfield(pcard, pcard->current.controler, pcard->current.location)) effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_DESTROY);
|| (peffect = pcard->is_affected_by_effect(EFFECT_SELF_DESTROY)) && !pcard->is_status(STATUS_BATTLE_DESTROYED)) { if(peffect) {
core.self_destroy_set.insert(pcard); core.self_destroy_set.insert(pcard);
pcard->temp.reason_effect = pcard->current.reason_effect; pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player; pcard->temp.reason_player = pcard->current.reason_player;
...@@ -1511,7 +1550,8 @@ void field::adjust_self_destroy_set() { ...@@ -1511,7 +1550,8 @@ void field::adjust_self_destroy_set() {
if(core.global_flag & GLOBALFLAG_SELF_TOGRAVE) { if(core.global_flag & GLOBALFLAG_SELF_TOGRAVE) {
for(auto cit = cset.begin(); cit != cset.end(); ++cit) { for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit; card* pcard = *cit;
if(peffect = pcard->is_affected_by_effect(EFFECT_SELF_TOGRAVE)) { effect* peffect = pcard->is_affected_by_effect(EFFECT_SELF_TOGRAVE);
if(peffect) {
core.self_tograve_set.insert(pcard); core.self_tograve_set.insert(pcard);
pcard->temp.reason_effect = pcard->current.reason_effect; pcard->temp.reason_effect = pcard->current.reason_effect;
pcard->temp.reason_player = pcard->current.reason_player; pcard->temp.reason_player = pcard->current.reason_player;
...@@ -1520,7 +1560,7 @@ void field::adjust_self_destroy_set() { ...@@ -1520,7 +1560,7 @@ void field::adjust_self_destroy_set() {
} }
} }
} }
if(!core.self_destroy_set.empty() || !core.self_tograve_set.empty()) 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); add_process(PROCESSOR_SELF_DESTROY, 0, 0, 0, 0, 0);
} }
void field::add_unique_card(card* pcard) { void field::add_unique_card(card* pcard) {
...@@ -1529,7 +1569,7 @@ void field::add_unique_card(card* pcard) { ...@@ -1529,7 +1569,7 @@ void field::add_unique_card(card* pcard) {
core.unique_cards[con].insert(pcard); core.unique_cards[con].insert(pcard);
if(pcard->unique_pos[1]) if(pcard->unique_pos[1])
core.unique_cards[1 - con].insert(pcard); core.unique_cards[1 - con].insert(pcard);
pcard->unique_uid = infos.copy_id++; pcard->unique_fieldid = 0;
} }
void field::remove_unique_card(card* pcard) { void field::remove_unique_card(card* pcard) {
...@@ -1543,16 +1583,21 @@ void field::remove_unique_card(card* pcard) { ...@@ -1543,16 +1583,21 @@ void field::remove_unique_card(card* pcard) {
} }
// return: pcard->unique_effect or 0 // return: pcard->unique_effect or 0
effect* field::check_unique_onfield(card* pcard, uint8 controler, uint8 location) { effect* field::check_unique_onfield(card* pcard, uint8 controler, uint8 location) {
if(!pcard->unique_code)
return 0;
for(auto iter = core.unique_cards[controler].begin(); iter != core.unique_cards[controler].end(); ++iter) { for(auto iter = core.unique_cards[controler].begin(); iter != core.unique_cards[controler].end(); ++iter) {
card* ucard = *iter; card* ucard = *iter;
if((ucard != pcard) && ucard->is_position(POS_FACEUP) && ucard->get_status(STATUS_EFFECT_ENABLED) if((ucard != pcard) && ucard->is_position(POS_FACEUP) && ucard->get_status(STATUS_EFFECT_ENABLED)
&& (ucard->unique_code == pcard->unique_code) && (ucard->unique_location & location) && !ucard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN)
&& (!(pcard->current.location & ucard->unique_location) || pcard->is_position(POS_FACEDOWN) && ucard->unique_fieldid && ucard->check_unique_code(pcard) && (ucard->unique_location & location))
|| ((!pcard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN) || !ucard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN)) && ucard->unique_uid < pcard->unique_uid))) return ucard->unique_effect;
return pcard->unique_effect;
} }
if(!pcard->unique_code || !(pcard->unique_location & location) || pcard->get_status(STATUS_DISABLED | STATUS_FORBIDDEN))
return 0;
card_set cset;
pcard->get_unique_target(&cset, controler);
if(pcard->check_unique_code(pcard))
cset.insert(pcard);
if(cset.size() >= 2)
return pcard->unique_effect;
return 0; return 0;
} }
......
...@@ -199,6 +199,7 @@ struct processor { ...@@ -199,6 +199,7 @@ struct processor {
card_set special_summoning; card_set special_summoning;
card_set equiping_cards; card_set equiping_cards;
card_set control_adjust_set[2]; card_set control_adjust_set[2];
card_set unique_destroy_set;
card_set self_destroy_set; card_set self_destroy_set;
card_set self_tograve_set; card_set self_tograve_set;
card_set release_cards; card_set release_cards;
......
...@@ -2346,7 +2346,11 @@ int32 scriptlib::card_set_unique_onfield(lua_State *L) { ...@@ -2346,7 +2346,11 @@ int32 scriptlib::card_set_unique_onfield(lua_State *L) {
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
pcard->unique_pos[0] = lua_tointeger(L, 2); pcard->unique_pos[0] = lua_tointeger(L, 2);
pcard->unique_pos[1] = lua_tointeger(L, 3); pcard->unique_pos[1] = lua_tointeger(L, 3);
pcard->unique_code = lua_tointeger(L, 4); if(lua_isfunction(L, 4)) {
pcard->unique_code = 1;
pcard->unique_function = interpreter::get_function_handle(L, 4);
} else
pcard->unique_code = lua_tointeger(L, 4);
uint32 location = LOCATION_ONFIELD; uint32 location = LOCATION_ONFIELD;
if(lua_gettop(L) > 4) if(lua_gettop(L) > 4)
location = lua_tointeger(L, 5) & LOCATION_ONFIELD; location = lua_tointeger(L, 5) & LOCATION_ONFIELD;
......
...@@ -1182,24 +1182,12 @@ int32 field::control_adjust(uint16 step) { ...@@ -1182,24 +1182,12 @@ int32 field::control_adjust(uint16 step) {
int32 field::self_destroy(uint16 step) { int32 field::self_destroy(uint16 step) {
switch(step) { switch(step) {
case 0: { case 0: {
if(core.self_destroy_set.empty()) { if(!core.unique_destroy_set.empty())
core.units.begin()->step = 1; destroy(&core.unique_destroy_set, 0, REASON_RULE, 5);
return FALSE;
}
card_set cset;
for (auto cit = core.self_destroy_set.begin(); cit != core.self_destroy_set.end();) {
auto rm = cit++;
card* pcard = *rm;
if(pcard->current.reason_effect->code == EFFECT_UNIQUE_CHECK) {
cset.insert(pcard);
core.self_destroy_set.erase(rm);
}
}
if(!cset.empty())
destroy(&cset, 0, REASON_RULE, 5);
return FALSE; return FALSE;
} }
case 1: { case 1: {
core.unique_destroy_set.clear();
core.operated_set.clear(); core.operated_set.clear();
if(!core.self_destroy_set.empty()) if(!core.self_destroy_set.empty())
destroy(&core.self_destroy_set, 0, REASON_EFFECT, 5); destroy(&core.self_destroy_set, 0, REASON_EFFECT, 5);
...@@ -1235,6 +1223,7 @@ int32 field::equip(uint16 step, uint8 equip_player, card * equip_card, card * ta ...@@ -1235,6 +1223,7 @@ int32 field::equip(uint16 step, uint8 equip_player, card * equip_card, card * ta
if(equip_card == target || target->current.location != LOCATION_MZONE) if(equip_card == target || target->current.location != LOCATION_MZONE)
return TRUE; return TRUE;
if(equip_card->equiping_target) { if(equip_card->equiping_target) {
equip_card->cancel_card_target(equip_card->equiping_target);
equip_card->unequip(); equip_card->unequip();
equip_card->enable_field_effect(false); equip_card->enable_field_effect(false);
return FALSE; 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