Commit 0b8f7ba1 authored by mercury233's avatar mercury233
parents dd4bbf6b 9ed81b99
......@@ -395,6 +395,11 @@ uint32 card::get_type() {
temp.type = 0xffffffff;
return type;
}
uint32 card::get_fusion_type() {
if(current.location == LOCATION_SZONE && (data.type & TYPE_MONSTER))
return data.type;
return get_type();
}
// Atk and def are sepcial cases since text atk/def ? are involved.
// Asuumption: we can only change the atk/def of cards in LOCATION_MZONE.
int32 card::get_base_attack() {
......@@ -942,7 +947,7 @@ uint32 card::get_fusion_attribute(uint8 playerid) {
filter_effect(EFFECT_CHANGE_FUSION_ATTRIBUTE, &effects);
if(!effects.size())
return get_attribute();
uint32 attribute;
uint32 attribute = 0;
for(int32 i = 0; i < effects.size(); ++i) {
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
attribute = effects[i]->get_value(this, 1);
......@@ -1988,13 +1993,29 @@ void card::filter_disable_related_cards() {
}
}
}
// put all summon procedures except ordinay summon in peset (see is_can_be_summoned())
// return value:
// -2 = this has a EFFECT_LIMIT_SUMMON_PROC, 0 available
// -1 = this has a EFFECT_LIMIT_SUMMON_PROC, at least 1 available
// 0 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon ia not available
// 1 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon ia available
int32 card::filter_summon_procedure(uint8 playerid, effect_set* peset, uint8 ignore_count, uint8 min_tribute) {
effect_set eset;
uint8 toplayer;
filter_effect(EFFECT_LIMIT_SUMMON_PROC, &eset);
if(eset.size()) {
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_SPSUM_PARAM)) {
if(eset[i]->o_range == 0)
toplayer = playerid;
else
toplayer = 1 - playerid;
} else
toplayer = playerid;
// the script will check min_tribute, Duel.CheckTribute()
if(eset[i]->check_count_limit(playerid) && is_summonable(eset[i], min_tribute)
&& pduel->game_field->is_player_can_summon(eset[i]->get_value(this), playerid, this))
&& !pduel->game_field->check_unique_onfield(this, toplayer, LOCATION_MZONE)
&& pduel->game_field->is_player_can_summon(eset[i]->get_value(this), playerid, this))
peset->add_item(eset[i]);
}
if(peset->size())
......@@ -2004,39 +2025,42 @@ int32 card::filter_summon_procedure(uint8 playerid, effect_set* peset, uint8 ign
eset.clear();
filter_effect(EFFECT_SUMMON_PROC, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->is_flag(EFFECT_FLAG_SPSUM_PARAM)) {
if(eset[i]->o_range == 0)
toplayer = playerid;
else
toplayer = 1 - playerid;
}
else
toplayer = playerid;
if(eset[i]->check_count_limit(playerid) && is_summonable(eset[i], min_tribute)
&& pduel->game_field->is_player_can_summon(eset[i]->get_value(this), playerid, this))
&& !pduel->game_field->check_unique_onfield(this, toplayer, LOCATION_MZONE)
&& pduel->game_field->is_player_can_summon(eset[i]->get_value(this), playerid, this))
peset->add_item(eset[i]);
}
// ordinary summon
if(!pduel->game_field->is_player_can_summon(SUMMON_TYPE_NORMAL, playerid, this))
return FALSE;
if(pduel->game_field->check_unique_onfield(this, playerid, LOCATION_MZONE))
return FALSE;
int32 rcount = get_summon_tribute_count();
int32 min = rcount & 0xffff, max = (rcount >> 16) & 0xffff;
if(min > 0 && !pduel->game_field->is_player_can_summon(SUMMON_TYPE_ADVANCE, playerid, this))
return FALSE;
int32 fcount = pduel->game_field->get_useable_count(current.controler, LOCATION_MZONE, current.controler, LOCATION_REASON_TOFIELD);
if(max <= -fcount)
return FALSE;
if(min < -fcount + 1)
min = -fcount + 1;
if(max < min_tribute)
return FALSE;
if(!pduel->game_field->is_player_can_summon(SUMMON_TYPE_ADVANCE, playerid, this))
max = 0;
if(min < min_tribute)
min = min_tribute;
if(min == 0)
return TRUE;
int32 m = pduel->game_field->get_summon_release_list(this, 0, 0, 0);
if(m >= min)
return TRUE;
return FALSE;
if(max < min)
return FALSE;
return pduel->game_field->check_tribute(this, min, max, 0, current.controler);
}
// put all set procedures except ordinay set in peset (see is_can_be_summoned())
int32 card::filter_set_procedure(uint8 playerid, effect_set* peset, uint8 ignore_count, uint8 min_tribute) {
effect_set eset;
filter_effect(EFFECT_LIMIT_SET_PROC, &eset);
if(eset.size()) {
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->check_count_limit(playerid) && is_summonable(eset[i], min_tribute)
&& pduel->game_field->is_player_can_mset(eset[i]->get_value(this), playerid, this))
&& pduel->game_field->is_player_can_mset(eset[i]->get_value(this), playerid, this))
peset->add_item(eset[i]);
}
if(peset->size())
......@@ -2047,30 +2071,20 @@ int32 card::filter_set_procedure(uint8 playerid, effect_set* peset, uint8 ignore
filter_effect(EFFECT_SET_PROC, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->check_count_limit(playerid) && is_summonable(eset[i], min_tribute)
&& pduel->game_field->is_player_can_mset(eset[i]->get_value(this), playerid, this))
&& pduel->game_field->is_player_can_mset(eset[i]->get_value(this), playerid, this))
peset->add_item(eset[i]);
}
if(!pduel->game_field->is_player_can_mset(SUMMON_TYPE_NORMAL, playerid, this))
return FALSE;
int32 rcount = get_set_tribute_count();
int32 rcount = get_summon_tribute_count();
int32 min = rcount & 0xffff, max = (rcount >> 16) & 0xffff;
if(min > 0 && !pduel->game_field->is_player_can_mset(SUMMON_TYPE_ADVANCE, playerid, this))
return FALSE;
int32 fcount = pduel->game_field->get_useable_count(current.controler, LOCATION_MZONE, current.controler, LOCATION_REASON_TOFIELD);
if(max <= -fcount)
return FALSE;
if(min < -fcount + 1)
min = -fcount + 1;
if(max < min_tribute)
return FALSE;
if(!pduel->game_field->is_player_can_mset(SUMMON_TYPE_ADVANCE, playerid, this))
max = 0;
if(min < min_tribute)
min = min_tribute;
if(min == 0)
return TRUE;
int32 m = pduel->game_field->get_summon_release_list(this, 0, 0, 0);
if(m >= min)
return TRUE;
return FALSE;
if(max < min)
return FALSE;
return pduel->game_field->check_tribute(this, min, max, 0, current.controler);
}
void card::filter_spsummon_procedure(uint8 playerid, effect_set* peset, uint32 summon_type) {
auto pr = field_effect.equal_range(EFFECT_SPSUMMON_PROC);
......@@ -2089,7 +2103,7 @@ void card::filter_spsummon_procedure(uint8 playerid, effect_set* peset, uint32 s
topos = POS_FACEUP;
toplayer = playerid;
}
if(peffect->is_available() && peffect->check_count_limit(playerid) && is_summonable(peffect)
if(peffect->is_available() && peffect->check_count_limit(playerid) && is_spsummonable(peffect)
&& !pduel->game_field->check_unique_onfield(this, toplayer, LOCATION_MZONE)) {
effect* sumeffect = pduel->game_field->core.reason_effect;
if(!sumeffect)
......@@ -2268,15 +2282,14 @@ int32 card::is_equipable(card* pcard) {
return TRUE;
return FALSE;
}
// check EFFECT_UNSUMMONABLE_CARD
int32 card::is_summonable() {
// check if this is a normal summonable card
int32 card::is_summonable_card() {
if(!(data.type & TYPE_MONSTER))
return FALSE;
return !is_affected_by_effect(EFFECT_UNSUMMONABLE_CARD);
}
// check if this can be summoned/sp_summoned by procedure peffect
// check the condition of peffect
int32 card::is_summonable(effect* peffect) {
// check the condition of sp_summon procedure peffect
int32 card::is_spsummonable(effect* peffect) {
effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_effect = peffect;
......@@ -2309,6 +2322,7 @@ int32 card::is_summonable(effect* peffect) {
pduel->game_field->core.reason_player = op;
return result;
}
// check the condition of summon/set procedure peffect
int32 card::is_summonable(effect* peffect, uint8 min_tribute) {
effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player;
......@@ -2326,10 +2340,13 @@ int32 card::is_summonable(effect* peffect, uint8 min_tribute) {
pduel->game_field->core.reason_player = op;
return result;
}
// if this does not have a summon procedure, it will check ordinary summon
// ignore_count: ignore the summon count in this turn or not
// peffect: effects that change the ordinary summon procedure (c80921533)
// min_tribute: the limit of min tribute number by EFFECT_EXTRA_SUMMON_COUNT
// return: whether playerid can summon this or not
int32 card::is_can_be_summoned(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute) {
if(!is_summonable())
return FALSE;
if(pduel->game_field->check_unique_onfield(this, playerid, LOCATION_MZONE))
if(!is_summonable_card())
return FALSE;
if(!ignore_count && (pduel->game_field->core.extra_summon[playerid] || !is_affected_by_effect(EFFECT_EXTRA_SUMMON_COUNT))
&& pduel->game_field->core.summon_count[playerid] >= pduel->game_field->get_summon_count_limit(playerid))
......@@ -2367,22 +2384,29 @@ int32 card::is_can_be_summoned(uint8 playerid, uint8 ignore_count, effect* peffe
effect* pextra = is_affected_by_effect(EFFECT_EXTRA_SUMMON_COUNT);
if(pextra && !pextra->is_flag(EFFECT_FLAG_FUNC_VALUE)) {
int32 count = pextra->get_value();
if(min_tribute < count)
if((int32)min_tribute < count)
min_tribute = count;
}
}
effect_set proc;
int32 res = filter_summon_procedure(playerid, &proc, ignore_count, min_tribute);
if((peffect && res < 0) || (!peffect && (!res || res == -2) && !proc.size())
|| (peffect && (proc.size() == 0) && !pduel->game_field->is_player_can_summon(peffect->get_value(), playerid, this))) {
pduel->game_field->restore_lp_cost();
return FALSE;
if(peffect) {
if(res < 0 || !pduel->game_field->is_player_can_summon(peffect->get_value(), playerid, this)){
pduel->game_field->restore_lp_cost();
return FALSE;
}
}
else {
if(!proc.size() && res == 0) {
pduel->game_field->restore_lp_cost();
return FALSE;
}
}
}
pduel->game_field->restore_lp_cost();
return TRUE;
}
// return: the tribute count for ordinary advance summon
// return: the min/max number of tribute for an ordinary advance summon of this
int32 card::get_summon_tribute_count() {
int32 min = 0, max = 0;
int32 minul = 0, maxul = 0;
......@@ -2558,10 +2582,9 @@ int32 card::is_can_be_special_summoned(effect * reason_effect, uint32 sumtype, u
pduel->game_field->restore_lp_cost();
return TRUE;
}
// if this does not have a set set procedure, it will check ordinary set (see is_can_be_summoned())
int32 card::is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute) {
if(!(data.type & TYPE_MONSTER))
return FALSE;
if(is_affected_by_effect(EFFECT_UNSUMMONABLE_CARD))
if(!is_summonable_card())
return FALSE;
if(current.location != LOCATION_HAND)
return FALSE;
......@@ -2595,10 +2618,17 @@ int32 card::is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect
}
eset.clear();
int32 res = filter_set_procedure(playerid, &eset, ignore_count, min_tribute);
if((peffect && res < 0) || (!peffect && (!res || res == -2) && !eset.size())
|| (peffect && (eset.size() == 0) && !pduel->game_field->is_player_can_mset(peffect->get_value(), playerid, this))) {
pduel->game_field->restore_lp_cost();
return FALSE;
if(peffect) {
if(res < 0 || !pduel->game_field->is_player_can_mset(peffect->get_value(), playerid, this)){
pduel->game_field->restore_lp_cost();
return FALSE;
}
}
else {
if(!eset.size() && res == 0) {
pduel->game_field->restore_lp_cost();
return FALSE;
}
}
pduel->game_field->restore_lp_cost();
return TRUE;
......@@ -2964,9 +2994,7 @@ int32 card::is_capable_be_effect_target(effect* peffect, uint8 playerid) {
}
return TRUE;
}
int32 card::is_can_be_fusion_material(card* fcard, uint8 ignore_mon) {
if(!ignore_mon && !(get_type() & TYPE_MONSTER))
return FALSE;
int32 card::is_can_be_fusion_material(card* fcard) {
if(is_status(STATUS_FORBIDDEN))
return FALSE;
effect_set eset;
......@@ -2974,6 +3002,14 @@ int32 card::is_can_be_fusion_material(card* fcard, uint8 ignore_mon) {
for(int32 i = 0; i < eset.size(); ++i)
if(eset[i]->get_value(fcard))
return FALSE;
eset.clear();
filter_effect(EFFECT_EXTRA_FUSION_MATERIAL, &eset);
if(eset.size()) {
for(int32 i = 0; i < eset.size(); ++i)
if(eset[i]->get_value(fcard))
return TRUE;
return FALSE;
}
return TRUE;
}
int32 card::is_can_be_synchro_material(card* scard, card* tuner) {
......
......@@ -169,6 +169,7 @@ public:
int32 is_pre_set_card(uint32 set_code);
int32 is_fusion_set_card(uint32 set_code);
uint32 get_type();
uint32 get_fusion_type();
int32 get_base_attack();
int32 get_attack();
int32 get_base_defense();
......@@ -246,8 +247,8 @@ public:
int32 check_fusion_substitute(card* fcard);
int32 is_equipable(card* pcard);
int32 is_summonable();
int32 is_summonable(effect* peffect);
int32 is_summonable_card();
int32 is_spsummonable(effect* peffect);
int32 is_summonable(effect* peffect, uint8 min_tribute);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute);
int32 get_summon_tribute_count();
......@@ -283,7 +284,7 @@ public:
int32 is_control_can_be_changed();
int32 is_capable_be_battle_target(card* pcard);
int32 is_capable_be_effect_target(effect* peffect, uint8 playerid);
int32 is_can_be_fusion_material(card* fcard, uint8 ignore_mon = FALSE);
int32 is_can_be_fusion_material(card* fcard);
int32 is_can_be_synchro_material(card* scard, card* tuner = 0);
int32 is_can_be_ritual_material(card* scard);
int32 is_can_be_xyz_material(card* scard);
......
......@@ -315,7 +315,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_EXTRA_RELEASE 153
#define EFFECT_TRIBUTE_LIMIT 154
#define EFFECT_EXTRA_RELEASE_SUM 155
#define EFFECT_TRIPLE_TRIBUTE 156
//#define EFFECT_TRIPLE_TRIBUTE 156
#define EFFECT_PUBLIC 160
#define EFFECT_COUNTER_PERMIT 0x10000
#define EFFECT_COUNTER_LIMIT 0x20000
......@@ -412,6 +412,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
//#define EFFECT_ADD_FUSION_ATTRIBUTE 349
//#define EFFECT_REMOVE_FUSION_ATTRIBUTE 350
#define EFFECT_CHANGE_FUSION_ATTRIBUTE 351
#define EFFECT_EXTRA_FUSION_MATERIAL 352
#define EVENT_STARTUP 1000
#define EVENT_FLIP 1001
......
......@@ -491,8 +491,9 @@ int32 field::is_location_useable(uint8 playerid, uint8 location, uint8 sequence)
return FALSE;
return TRUE;
}
// return: usable count of LOCATION_MZONE or real LOCATION_SZONE
// store local flag in list
// uplayer: request player, PLAYER_NONE means ignoring EFFECT_MAX_MZONE, EFFECT_MAX_SZONE
// list: store local flag in list
// return: usable count of LOCATION_MZONE or real LOCATION_SZONE of plaerid requested by uplayer (may be negative)
int32 field::get_useable_count(uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32* list) {
if (location != LOCATION_MZONE && location != LOCATION_SZONE)
return 0;
......@@ -1251,7 +1252,15 @@ int32 field::check_release_list(uint8 playerid, int32 count, int32 use_con, int3
}
return FALSE;
}
// return: the max release count of mg or all monsters on field
int32 field::get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_sum, group* mg, uint32 ex) {
int32 m1 = get_summon_release_slist(target, release_list, mg);
int32 m2 = get_summon_release_olist(target, ex_list, ex_list_sum, mg, ex);
return m1 + m2;
}
// let the controller of target be p
// search in mg or mzone of p, and put the tribute monsters in release_list
int32 field::get_summon_release_slist(card* target, card_set* release_list, group* mg) {
uint8 p = target->current.controler;
card* pcard;
uint32 rcount = 0;
......@@ -1262,15 +1271,23 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_
continue;
if(release_list)
release_list->insert(pcard);
if(pcard->is_affected_by_effect(EFFECT_TRIPLE_TRIBUTE, target))
pcard->release_param = 3;
else if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
pcard->release_param = 2;
else
pcard->release_param = 1;
rcount += pcard->release_param;
}
}
return rcount;
}
// ex: the procedure of target can release opponent monster
// ex_list: the tribute monsters controlled by 1-p
// ex_list_sum: the opponent monsters affected by EFFECT_EXTRA_RELEASE_SUM
// search in mg or mzone of 1-p, and maintain ex_list, ex_list_sum
int32 field::get_summon_release_olist(card* target, card_set* ex_list, card_set* ex_list_sum, group* mg, uint32 ex) {
uint8 p = target->current.controler;
card* pcard;
uint32 rcount = 0;
uint32 ex_sum_max = 0;
for(int i = 0; i < 5; ++i) {
pcard = player[1 - p].list_mzone[i];
......@@ -1281,9 +1298,7 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_
if(ex || pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE)) {
if(ex_list)
ex_list->insert(pcard);
if(pcard->is_affected_by_effect(EFFECT_TRIPLE_TRIBUTE, target))
pcard->release_param = 3;
else if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
pcard->release_param = 2;
else
pcard->release_param = 1;
......@@ -1294,9 +1309,7 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_
continue;
if(ex_list_sum)
ex_list_sum->insert(pcard);
if(pcard->is_affected_by_effect(EFFECT_TRIPLE_TRIBUTE, target))
pcard->release_param = 3;
else if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
if(pcard->is_affected_by_effect(EFFECT_DOUBLE_TRIBUTE, target))
pcard->release_param = 2;
else
pcard->release_param = 1;
......@@ -1306,6 +1319,22 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_
}
return rcount + ex_sum_max;
}
// put the monsters of 1-p affected by EFFECT_EXTRA_RELEASE
int32 field::get_summon_release_exlist(card* target, card_set* ex_list, group* mg) {
uint8 p = target->current.controler;
card* pcard;
for(int i = 0; i < 5; ++i) {
pcard = player[1 - p].list_mzone[i];
if(!(pcard && pcard->is_releasable_by_summon(p, target)))
continue;
if(mg && !mg->has_card(pcard))
continue;
if(pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE)) {
ex_list->insert(pcard);
}
}
return TRUE;
}
int32 field::get_summon_count_limit(uint8 playerid) {
effect_set eset;
filter_player_effect(playerid, EFFECT_SET_SUMMON_COUNT_LIMIT, &eset);
......@@ -1326,26 +1355,40 @@ int32 field::get_draw_count(uint8 playerid) {
return count;
}
void field::get_ritual_material(uint8 playerid, effect* peffect, card_set* material) {
card* pcard;
for(int i = 0; i < 5; ++i) {
pcard = player[playerid].list_mzone[i];
if(pcard && pcard->get_level() && pcard->is_affect_by_effect(core.reason_effect)
card* pcard = player[playerid].list_mzone[i];
if(pcard && pcard->get_level() && pcard->is_affect_by_effect(peffect)
&& pcard->is_releasable_by_nonsummon(playerid) && pcard->is_releasable_by_effect(playerid, peffect))
material->insert(pcard);
}
for(int i = 0; i < 5; ++i) {
pcard = player[1 - playerid].list_mzone[i];
if(pcard && pcard->get_level() && pcard->is_affect_by_effect(core.reason_effect)
card* pcard = player[1 - playerid].list_mzone[i];
if(pcard && pcard->get_level() && pcard->is_affect_by_effect(peffect)
&& pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE)
&& pcard->is_releasable_by_nonsummon(playerid) && pcard->is_releasable_by_effect(playerid, peffect))
material->insert(pcard);
}
for(auto cit = player[playerid].list_hand.begin(); cit != player[playerid].list_hand.end(); ++cit)
if(((*cit)->data.type & TYPE_MONSTER) && (*cit)->is_releasable_by_nonsummon(playerid))
material->insert((*cit));
material->insert(*cit);
for(auto cit = player[playerid].list_grave.begin(); cit != player[playerid].list_grave.end(); ++cit)
if(((*cit)->data.type & TYPE_MONSTER) && (*cit)->is_affected_by_effect(EFFECT_EXTRA_RITUAL_MATERIAL) && (*cit)->is_removeable(playerid))
material->insert((*cit));
material->insert(*cit);
}
void field::get_fusion_material(uint8 playerid, card_set* material) {
for(int i = 0; i < 5; ++i) {
card* pcard = player[playerid].list_mzone[i];
if(pcard)
material->insert(pcard);
}
for(int i = 0; i < 8; ++i) {
card* pcard = player[playerid].list_szone[i];
if(pcard && pcard->is_affected_by_effect(EFFECT_EXTRA_FUSION_MATERIAL))
material->insert(pcard);
}
for(auto cit = player[playerid].list_hand.begin(); cit != player[playerid].list_hand.end(); ++cit)
if((*cit)->data.type & TYPE_MONSTER)
material->insert(*cit);
}
void field::ritual_release(card_set* material) {
card_set rel;
......@@ -1531,7 +1574,7 @@ void field::remove_unique_card(card* pcard) {
if(pcard->unique_pos[1])
core.unique_cards[1 - con].erase(pcard);
}
// return: pcard->unique_effect or 0
effect* field::check_unique_onfield(card* pcard, uint8 controler, uint8 location) {
if(!pcard->unique_code)
return 0;
......@@ -2176,6 +2219,47 @@ int32 field::check_tuner_material(card* pcard, card* tuner, int32 findex1, int32
pduel->restore_assumes();
return FALSE;
}
// check if "releasing min~max tributes" is available
int32 field::check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer) {
card_set test, exset;
int32 m1 = 0, m2 = 0;
if(toplayer == pcard->current.controler) {
m1 = get_summon_release_slist(pcard, &test, mg);
m2 = get_summon_release_olist(pcard, NULL, NULL, mg, 0);
} else {
m1 = get_summon_release_olist(pcard, &test, NULL, mg, 1);
m2 = get_summon_release_slist(pcard, NULL, mg);
}
// sum of release count is the real upper bound
if(max > m1 + m2)
max = m1 + m2;
if(min > max)
return FALSE;
int32 fcount = get_useable_count(toplayer, LOCATION_MZONE, pcard->current.controler, LOCATION_REASON_TOFIELD);
// test "releasing i tributes"
for(int32 i = min; i <= max; ++i){
int32 rmax = 0;
if(toplayer == pcard->current.controler) {
get_summon_release_exlist(pcard, &exset, mg);
// let r be the number of monsters released from mzone of toplayer
// r<=i-ex, r<=test
// rmax = min{i-ex, test}
if(i >= (int32)exset.size()){
rmax = i - (int32)exset.size();
if(rmax > (int32)test.size())
rmax = (int32)test.size();
}
else
rmax = 0;
}
else
rmax = (int32)test.size();
// this is the # of slots after the advance summon
if(fcount + rmax - 1 >= 0)
return TRUE;
}
return FALSE;
}
int32 field::check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max) {
if(count > max)
return FALSE;
......@@ -2304,7 +2388,7 @@ int32 field::is_player_can_summon(uint32 sumtype, uint8 playerid, card * pcard)
pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(sumtype, PARAM_TYPE_INT);
if (pduel->lua->check_condition(eset[i]->target, 4))
if(pduel->lua->check_condition(eset[i]->target, 4))
return FALSE;
}
return TRUE;
......
......@@ -363,10 +363,14 @@ public:
int32 get_release_list(uint8 playerid, card_set* release_list, card_set* ex_list, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exp);
int32 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exp);
int32 get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_sum, group* mg = 0, uint32 ex = 0);
int32 get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_sum, group* mg = NULL, uint32 ex = 0);
int32 get_summon_release_slist(card* target, card_set* release_list, group* mg = NULL);
int32 get_summon_release_olist(card* target, card_set* ex_list, card_set* ex_list_sum, group* mg = NULL, uint32 ex = 0);
int32 get_summon_release_exlist(card* target, card_set* ex_list, group* mg = NULL);
int32 get_summon_count_limit(uint8 playerid);
int32 get_draw_count(uint8 playerid);
void get_ritual_material(uint8 playerid, effect* peffect, card_set* material);
void get_fusion_material(uint8 playerid, card_set* material);
void ritual_release(card_set* material);
void get_xyz_material(card* scard, int32 findex, uint32 lv, int32 maxc, group* mg);
void get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset);
......@@ -396,6 +400,7 @@ public:
void attack_all_target_check();
int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer);
static int32 check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max);
static int32 check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 must_count);
static int32 check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin);
......
......@@ -26,6 +26,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsFusionSetCard", scriptlib::card_is_fusion_set_card },
{ "GetType", scriptlib::card_get_type },
{ "GetOriginalType", scriptlib::card_get_origin_type },
{ "GetFusionType", scriptlib::card_get_fusion_type },
{ "GetLevel", scriptlib::card_get_level },
{ "GetRank", scriptlib::card_get_rank },
{ "GetSynchroLevel", scriptlib::card_get_synchro_level },
......@@ -80,6 +81,7 @@ static const struct luaL_Reg cardlib[] = {
{ "GetRealFieldID", scriptlib::card_get_fieldidr },
{ "IsCode", scriptlib::card_is_code },
{ "IsType", scriptlib::card_is_type },
{ "IsFusionType", scriptlib::card_is_fusion_type },
{ "IsRace", scriptlib::card_is_race },
{ "IsAttribute", scriptlib::card_is_attribute },
{ "IsFusionAttribute", scriptlib::card_is_fusion_attribute },
......@@ -427,6 +429,7 @@ static const struct luaL_Reg duellib[] = {
{ "SelectReleaseGroupEx", scriptlib::duel_select_release_group_ex },
{ "GetTributeGroup", scriptlib::duel_get_tribute_group },
{ "GetTributeCount", scriptlib::duel_get_tribute_count },
{ "CheckTribute", scriptlib::duel_check_tribute },
{ "SelectTribute", scriptlib::duel_select_tribute },
{ "GetTargetCount", scriptlib::duel_get_target_count },
{ "IsExistingTarget", scriptlib::duel_is_existing_target },
......@@ -440,6 +443,7 @@ static const struct luaL_Reg duellib[] = {
{ "CheckTunerMaterial", scriptlib::duel_check_tuner_material },
{ "GetRitualMaterial", scriptlib::duel_get_ritual_material },
{ "ReleaseRitualMaterial", scriptlib::duel_release_ritual_material },
{ "GetFusionMaterial", scriptlib::duel_get_fusion_material },
{ "SetSelectedCard", scriptlib::duel_set_must_select_cards },
{ "SetTargetCard", scriptlib::duel_set_target_card },
{ "ClearTargetCard", scriptlib::duel_clear_target_card },
......
......@@ -146,6 +146,13 @@ int32 scriptlib::card_get_origin_type(lua_State *L) {
lua_pushinteger(L, pcard->data.type);
return 1;
}
int32 scriptlib::card_get_fusion_type(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->get_fusion_type());
return 1;
}
int32 scriptlib::card_get_level(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -576,6 +583,17 @@ int32 scriptlib::card_is_type(lua_State *L) {
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_fusion_type(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 ttype = lua_tointeger(L, 2);
if(pcard->get_fusion_type() & ttype)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_race(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -1325,7 +1343,7 @@ int32 scriptlib::card_is_summonable(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card * pcard = *(card**) lua_touserdata(L, 1);
lua_pushboolean(L, pcard->is_summonable());
lua_pushboolean(L, pcard->is_summonable_card());
return 1;
}
int32 scriptlib::card_is_msetable(lua_State *L) {
......@@ -2000,14 +2018,11 @@ int32 scriptlib::card_is_can_be_fusion_material(lua_State *L) {
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
card* fcard = 0;
uint32 ign = FALSE;
if(lua_gettop(L) >= 2 && !lua_isnil(L, 2)) {
check_param(L, PARAM_TYPE_CARD, 2);
fcard = *(card**)lua_touserdata(L, 2);
}
if(lua_gettop(L) >= 3)
ign = lua_toboolean(L, 3);
lua_pushboolean(L, pcard->is_can_be_fusion_material(fcard, ign));
lua_pushboolean(L, pcard->is_can_be_fusion_material(fcard));
return 1;
}
int32 scriptlib::card_is_can_be_synchro_material(lua_State *L) {
......
......@@ -1989,7 +1989,7 @@ int32 scriptlib::duel_get_tribute_group(lua_State *L) {
card* target = *(card**) lua_touserdata(L, 1);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
pduel->game_field->get_summon_release_list(target, &(pgroup->container), &(pgroup->container), 0);
pduel->game_field->get_summon_release_list(target, &(pgroup->container), &(pgroup->container), NULL);
interpreter::group2value(L, pgroup);
return 1;
}
......@@ -2011,7 +2011,27 @@ int32 scriptlib::duel_get_tribute_count(lua_State *L) {
if(lua_gettop(L) >= 3)
ex = lua_toboolean(L, 3);
duel* pduel = interpreter::get_duel_info(L);
lua_pushinteger(L, pduel->game_field->get_summon_release_list(target, 0, 0, 0, mg, ex));
lua_pushinteger(L, pduel->game_field->get_summon_release_list(target, NULL, NULL, NULL, mg, ex));
return 1;
}
int32 scriptlib::duel_check_tribute(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* target = *(card**) lua_touserdata(L, 1);
uint32 min = lua_tointeger(L, 2);
uint32 max = min;
if(lua_gettop(L) >= 3 && !lua_isnil(L, 3))
max = lua_tointeger(L, 3);
group* mg = 0;
if(lua_gettop(L) >= 4 && !lua_isnil(L, 4)) {
check_param(L, PARAM_TYPE_GROUP, 4);
mg = *(group**)lua_touserdata(L, 4);
}
uint8 toplayer = target->current.controler;
if(lua_gettop(L) >= 5 && !lua_isnil(L, 5))
toplayer = lua_tointeger(L, 5);
duel* pduel = target->pduel;
lua_pushboolean(L, pduel->game_field->check_tribute(target, min, max, mg, toplayer));
return 1;
}
int32 scriptlib::duel_select_tribute(lua_State *L) {
......@@ -2297,6 +2317,17 @@ int32 scriptlib::duel_release_ritual_material(lua_State *L) {
pgroup->pduel->game_field->ritual_release(&pgroup->container);
return lua_yield(L, 0);
}
int32 scriptlib::duel_get_fusion_material(lua_State *L) {
check_param_count(L, 1);
int32 playerid = lua_tointeger(L, 1);
if(playerid != 0 && playerid != 1)
return 0;
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
pduel->game_field->get_fusion_material(playerid, &pgroup->container);
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::duel_set_must_select_cards(lua_State *L) {
check_param_count(L, 1);
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
......
......@@ -1532,6 +1532,7 @@ int32 field::summon(uint16 step, uint8 sumplayer, card * target, effect * proc,
target->current.reason_player = sumplayer;
if(proc->operation) {
pduel->lua->add_param(target, PARAM_TYPE_CARD);
pduel->lua->add_param(min_tribute, PARAM_TYPE_INT);
core.sub_solving_event.push_back(nil_event);
add_process(PROCESSOR_EXECUTE_OPERATION, 0, proc, 0, sumplayer, 0);
}
......
......@@ -28,6 +28,7 @@ public:
static int32 card_is_fusion_set_card(lua_State *L);
static int32 card_get_type(lua_State *L);
static int32 card_get_origin_type(lua_State *L);
static int32 card_get_fusion_type(lua_State *L);
static int32 card_get_level(lua_State *L);
static int32 card_get_rank(lua_State *L);
static int32 card_get_synchro_level(lua_State *L);
......@@ -82,6 +83,7 @@ public:
static int32 card_get_fieldidr(lua_State *L);
static int32 card_is_code(lua_State *L);
static int32 card_is_type(lua_State *L);
static int32 card_is_fusion_type(lua_State *L);
static int32 card_is_race(lua_State *L);
static int32 card_is_attribute(lua_State *L);
static int32 card_is_fusion_attribute(lua_State *L);
......@@ -425,6 +427,7 @@ public:
static int32 duel_select_release_group_ex(lua_State *L);
static int32 duel_get_tribute_group(lua_State *L);
static int32 duel_get_tribute_count(lua_State *L);
static int32 duel_check_tribute(lua_State *L);
static int32 duel_select_tribute(lua_State *L);
static int32 duel_get_target_count(lua_State *L);
static int32 duel_is_existing_target(lua_State *L);
......@@ -438,6 +441,7 @@ public:
static int32 duel_check_tuner_material(lua_State *L);
static int32 duel_get_ritual_material(lua_State *L);
static int32 duel_release_ritual_material(lua_State *L);
static int32 duel_get_fusion_material(lua_State *L);
static int32 duel_set_must_select_cards(lua_State *L);
static int32 duel_set_target_card(lua_State *L);
static int32 duel_clear_target_card(lua_State *L);
......
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