Commit 552b057f authored by VanillaSalt's avatar VanillaSalt

update EXTRA_SUMMON_COUNT, SPSUMMON_PROC

parent 5ca4cd4b
...@@ -2405,16 +2405,15 @@ int32 card::filter_summon_procedure(uint8 playerid, effect_set* peset, uint8 ign ...@@ -2405,16 +2405,15 @@ int32 card::filter_summon_procedure(uint8 playerid, effect_set* peset, uint8 ign
effect_set eset; effect_set eset;
filter_effect(EFFECT_EXTRA_SUMMON_COUNT, &eset); filter_effect(EFFECT_EXTRA_SUMMON_COUNT, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min = val & 0xff; eset[i]->get_value(this, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if(new_min < min) if(new_min < min)
new_min = min; new_min = min;
if(new_zone) new_zone &= zone;
new_zone &= zone; if(pduel->game_field->check_tribute(this, new_min, max, 0, current.controler, new_zone, releasable))
else
new_zone = zone;
if(pduel->game_field->check_tribute(this, new_min, max, 0, current.controler, new_zone))
return TRUE; return TRUE;
} }
} else } else
...@@ -2439,16 +2438,15 @@ int32 card::check_summon_procedure(effect* peffect, uint8 playerid, uint8 ignore ...@@ -2439,16 +2438,15 @@ int32 card::check_summon_procedure(effect* peffect, uint8 playerid, uint8 ignore
effect_set eset; effect_set eset;
filter_effect(EFFECT_EXTRA_SUMMON_COUNT, &eset); filter_effect(EFFECT_EXTRA_SUMMON_COUNT, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; eset[i]->get_value(this, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if(new_min_tribute < (int32)min_tribute) if(new_min_tribute < (int32)min_tribute)
new_min_tribute = min_tribute; new_min_tribute = min_tribute;
if(new_zone) new_zone &= zone;
new_zone &= zone; if(is_summonable(peffect, new_min_tribute, new_zone, releasable))
else
new_zone = zone;
if(is_summonable(peffect, new_min_tribute, new_zone))
return TRUE; return TRUE;
} }
} else } else
...@@ -2490,16 +2488,15 @@ int32 card::filter_set_procedure(uint8 playerid, effect_set* peset, uint8 ignore ...@@ -2490,16 +2488,15 @@ int32 card::filter_set_procedure(uint8 playerid, effect_set* peset, uint8 ignore
effect_set eset; effect_set eset;
filter_effect(EFFECT_EXTRA_SET_COUNT, &eset); filter_effect(EFFECT_EXTRA_SET_COUNT, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min = val & 0xff; eset[i]->get_value(this, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if(new_min < min) if(new_min < min)
new_min = min; new_min = min;
if(new_zone) new_zone &= zone;
new_zone &= zone; if(pduel->game_field->check_tribute(this, new_min, max, 0, current.controler, new_zone, releasable))
else
new_zone = zone;
if(pduel->game_field->check_tribute(this, new_min, max, 0, current.controler, new_zone))
return TRUE; return TRUE;
} }
} else } else
...@@ -2521,16 +2518,15 @@ int32 card::check_set_procedure(effect* peffect, uint8 playerid, uint8 ignore_co ...@@ -2521,16 +2518,15 @@ int32 card::check_set_procedure(effect* peffect, uint8 playerid, uint8 ignore_co
effect_set eset; effect_set eset;
filter_effect(EFFECT_EXTRA_SET_COUNT, &eset); filter_effect(EFFECT_EXTRA_SET_COUNT, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; eset[i]->get_value(this, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if(new_min_tribute < (int32)min_tribute) if(new_min_tribute < (int32)min_tribute)
new_min_tribute = min_tribute; new_min_tribute = min_tribute;
if(new_zone) new_zone &= zone;
new_zone &= zone; if(is_summonable(peffect, new_min_tribute, new_zone, releasable))
else
new_zone = zone;
if(is_summonable(peffect, new_min_tribute, new_zone))
return TRUE; return TRUE;
} }
} else } else
...@@ -2848,7 +2844,7 @@ int32 card::is_spsummonable(effect* peffect) { ...@@ -2848,7 +2844,7 @@ int32 card::is_spsummonable(effect* peffect) {
return result; return result;
} }
// check the condition of summon/set procedure peffect // check the condition of summon/set procedure peffect
int32 card::is_summonable(effect* peffect, uint8 min_tribute, uint32 zone) { int32 card::is_summonable(effect* peffect, uint8 min_tribute, uint32 zone, uint32 releasable) {
effect* oreason = pduel->game_field->core.reason_effect; effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player; uint8 op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_effect = peffect; pduel->game_field->core.reason_effect = peffect;
...@@ -2859,7 +2855,8 @@ int32 card::is_summonable(effect* peffect, uint8 min_tribute, uint32 zone) { ...@@ -2859,7 +2855,8 @@ int32 card::is_summonable(effect* peffect, uint8 min_tribute, uint32 zone) {
pduel->lua->add_param(this, PARAM_TYPE_CARD); pduel->lua->add_param(this, PARAM_TYPE_CARD);
pduel->lua->add_param(min_tribute, PARAM_TYPE_INT); pduel->lua->add_param(min_tribute, PARAM_TYPE_INT);
pduel->lua->add_param(zone, PARAM_TYPE_INT); pduel->lua->add_param(zone, PARAM_TYPE_INT);
if(pduel->lua->check_condition(peffect->condition, 4)) pduel->lua->add_param(releasable, PARAM_TYPE_INT);
if(pduel->lua->check_condition(peffect->condition, 5))
result = TRUE; result = TRUE;
pduel->game_field->restore_lp_cost(); pduel->game_field->restore_lp_cost();
pduel->game_field->core.reason_effect = oreason; pduel->game_field->core.reason_effect = oreason;
......
...@@ -296,7 +296,7 @@ public: ...@@ -296,7 +296,7 @@ public:
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);
int32 is_summonable(effect* peffect, uint8 min_tribute, uint32 zone = 0x1f); int32 is_summonable(effect* peffect, uint8 min_tribute, uint32 zone = 0x1f, uint32 releasable = 0xff00ff);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f); int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 get_summon_tribute_count(); int32 get_summon_tribute_count();
int32 get_set_tribute_count(); int32 get_set_tribute_count();
......
...@@ -627,6 +627,35 @@ int32 effect::get_value(effect* peffect, uint32 extraargs) { ...@@ -627,6 +627,35 @@ int32 effect::get_value(effect* peffect, uint32 extraargs) {
return (int32)value; return (int32)value;
} }
} }
void effect::get_value(uint32 extraargs, std::vector<int32>* result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 1 + extraargs, result);
} else {
pduel->lua->params.clear();
result->push_back((int32)value);
}
}
void effect::get_value(card* pcard, uint32 extraargs, std::vector<int32>* result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result);
} else {
pduel->lua->params.clear();
result->push_back((int32)value);
}
}
void effect::get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result);
} else {
pduel->lua->params.clear();
result->push_back((int32)value);
}
}
int32 effect::check_value_condition(uint32 extraargs) { int32 effect::check_value_condition(uint32 extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
......
...@@ -83,6 +83,9 @@ public: ...@@ -83,6 +83,9 @@ public:
int32 get_value(uint32 extraargs = 0); int32 get_value(uint32 extraargs = 0);
int32 get_value(card* pcard, uint32 extraargs = 0); int32 get_value(card* pcard, uint32 extraargs = 0);
int32 get_value(effect* peffect, uint32 extraargs = 0); int32 get_value(effect* peffect, uint32 extraargs = 0);
void get_value(uint32 extraargs, std::vector<int32>* result);
void get_value(card* pcard, uint32 extraargs, std::vector<int32>* result);
void get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result);
int32 check_value_condition(uint32 extraargs = 0); int32 check_value_condition(uint32 extraargs = 0);
int32 get_speed(); int32 get_speed();
card* get_owner() const; card* get_owner() const;
......
...@@ -1574,12 +1574,12 @@ int32 field::check_release_list(uint8 playerid, int32 count, int32 use_con, int3 ...@@ -1574,12 +1574,12 @@ int32 field::check_release_list(uint8 playerid, int32 count, int32 use_con, int3
return FALSE; return FALSE;
} }
// return: the max release count of mg or all monsters on field // 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 field::get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_sum, group* mg, uint32 ex, uint32 releasable) {
uint8 p = target->current.controler; uint8 p = target->current.controler;
uint32 rcount = 0; uint32 rcount = 0;
for(auto cit = player[p].list_mzone.begin(); cit != player[p].list_mzone.end(); ++cit) { for(auto cit = player[p].list_mzone.begin(); cit != player[p].list_mzone.end(); ++cit) {
card* pcard = *cit; card* pcard = *cit;
if(pcard && pcard->is_releasable_by_summon(p, target)) { if(pcard && ((releasable >> pcard->current.sequence) & 1) && pcard->is_releasable_by_summon(p, target)) {
if(mg && !mg->has_card(pcard)) if(mg && !mg->has_card(pcard))
continue; continue;
if(release_list) if(release_list)
...@@ -1594,7 +1594,7 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_ ...@@ -1594,7 +1594,7 @@ int32 field::get_summon_release_list(card* target, card_set* release_list, card_
uint32 ex_sum_max = 0; uint32 ex_sum_max = 0;
for(auto cit = player[1 - p].list_mzone.begin(); cit != player[1 - p].list_mzone.end(); ++cit) { for(auto cit = player[1 - p].list_mzone.begin(); cit != player[1 - p].list_mzone.end(); ++cit) {
card* pcard = *cit; card* pcard = *cit;
if(!pcard || !pcard->is_releasable_by_summon(p, target)) if(!pcard || !((releasable >> (pcard->current.sequence + 16)) & 1) || !pcard->is_releasable_by_summon(p, target))
continue; continue;
if(mg && !mg->has_card(pcard)) if(mg && !mg->has_card(pcard))
continue; continue;
...@@ -2638,12 +2638,12 @@ int32 field::check_other_synchro_material(const card_vector& nsyn, int32 lv, int ...@@ -2638,12 +2638,12 @@ int32 field::check_other_synchro_material(const card_vector& nsyn, int32 lv, int
} }
return FALSE; return FALSE;
} }
int32 field::check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer, uint32 zone) { int32 field::check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer, uint32 zone, uint32 releasable) {
int32 ex = FALSE; int32 ex = FALSE;
if(toplayer == 1 - pcard->current.controler) if(toplayer == 1 - pcard->current.controler)
ex = TRUE; ex = TRUE;
card_set release_list, ex_list; card_set release_list, ex_list;
int32 m = get_summon_release_list(pcard, &release_list, &ex_list, 0, mg, ex); int32 m = get_summon_release_list(pcard, &release_list, &ex_list, 0, mg, ex, releasable);
if(max > m) if(max > m)
max = m; max = m;
if(min > max) if(min > max)
......
...@@ -384,7 +384,7 @@ public: ...@@ -384,7 +384,7 @@ 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* exc, group* exg); 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* exc, group* exg);
int32 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg); int32 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg);
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_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_sum, group* mg = NULL, uint32 ex = 0, uint32 releasable = 0xff00ff);
int32 get_summon_count_limit(uint8 playerid); int32 get_summon_count_limit(uint8 playerid);
int32 get_draw_count(uint8 playerid); int32 get_draw_count(uint8 playerid);
void get_ritual_material(uint8 playerid, effect* peffect, card_set* material); void get_ritual_material(uint8 playerid, effect* peffect, card_set* material);
...@@ -419,7 +419,7 @@ public: ...@@ -419,7 +419,7 @@ public:
int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg); 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_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_other_synchro_material(const card_vector& nsyn, int32 lv, int32 min, int32 max, int32 mcount); int32 check_other_synchro_material(const card_vector& nsyn, int32 lv, int32 min, int32 max, int32 mcount);
int32 check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer, uint32 zone = 0x1f); int32 check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer, uint32 zone = 0x1f, uint32 releasable = 0xff00ff);
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(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_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); static int32 check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin);
......
...@@ -794,7 +794,7 @@ void interpreter::push_param(lua_State* L, bool is_coroutine) { ...@@ -794,7 +794,7 @@ void interpreter::push_param(lua_State* L, bool is_coroutine) {
} }
params.clear(); params.clear();
} }
int32 interpreter::call_function(int32 f, uint32 param_count, uint32 ret_count) { int32 interpreter::call_function(int32 f, uint32 param_count, int32 ret_count) {
if (!f) { if (!f) {
sprintf(pduel->strbuffer, "\"CallFunction\": attempt to call a null function."); sprintf(pduel->strbuffer, "\"CallFunction\": attempt to call a null function.");
handle_message(pduel, 1); handle_message(pduel, 1);
...@@ -838,7 +838,7 @@ int32 interpreter::call_function(int32 f, uint32 param_count, uint32 ret_count) ...@@ -838,7 +838,7 @@ int32 interpreter::call_function(int32 f, uint32 param_count, uint32 ret_count)
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::call_card_function(card* pcard, char* f, uint32 param_count, uint32 ret_count) { int32 interpreter::call_card_function(card* pcard, char* f, uint32 param_count, int32 ret_count) {
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.code, f); sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.code, f);
handle_message(pduel, 1); handle_message(pduel, 1);
...@@ -878,7 +878,7 @@ int32 interpreter::call_card_function(card* pcard, char* f, uint32 param_count, ...@@ -878,7 +878,7 @@ int32 interpreter::call_card_function(card* pcard, char* f, uint32 param_count,
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::call_code_function(uint32 code, char* f, uint32 param_count, uint32 ret_count) { int32 interpreter::call_code_function(uint32 code, char* f, uint32 param_count, int32 ret_count) {
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCodeFunction\": incorrect parameter count"); sprintf(pduel->strbuffer, "\"CallCodeFunction\": incorrect parameter count");
handle_message(pduel, 1); handle_message(pduel, 1);
...@@ -1039,6 +1039,36 @@ int32 interpreter::get_function_value(int32 f, uint32 param_count) { ...@@ -1039,6 +1039,36 @@ int32 interpreter::get_function_value(int32 f, uint32 param_count) {
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<int32>* result) {
int32 is_success = OPERATION_FAIL;
if(!f) {
params.clear();
return is_success;
}
int32 stack_top = lua_gettop(current_state);
no_action++;
call_depth++;
if (call_function(f, param_count, LUA_MULTRET)) {
int32 stack_newtop = lua_gettop(current_state);
for (int32 index = stack_top + 1; index <= stack_newtop; ++index) {
int32 return_value = 0;
if (lua_isboolean(current_state, index))
return_value = lua_toboolean(current_state, index);
else
return_value = lua_tointeger(current_state, index);
result->push_back(return_value);
}
lua_settop(current_state, stack_top);
is_success = OPERATION_SUCCESS;
}
no_action--;
call_depth--;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return is_success;
}
int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_value, uint16 step) { int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_value, uint16 step) {
*yield_value = 0; *yield_value = 0;
if (!f) { if (!f) {
......
...@@ -22,6 +22,7 @@ extern "C" { ...@@ -22,6 +22,7 @@ extern "C" {
#include "common.h" #include "common.h"
#include <unordered_map> #include <unordered_map>
#include <list> #include <list>
#include <vector>
#include <cstring> #include <cstring>
class card; class card;
...@@ -52,19 +53,20 @@ public: ...@@ -52,19 +53,20 @@ public:
void unregister_effect(effect* peffect); void unregister_effect(effect* peffect);
void register_group(group* pgroup); void register_group(group* pgroup);
void unregister_group(group* pgroup); void unregister_group(group* pgroup);
int32 load_script(char* buffer); int32 load_script(char* buffer);
int32 load_card_script(uint32 code); int32 load_card_script(uint32 code);
void add_param(void* param, int32 type, bool front = false); void add_param(void* param, int32 type, bool front = false);
void add_param(ptr param, int32 type, bool front = false); void add_param(ptr param, int32 type, bool front = false);
void push_param(lua_State* L, bool is_coroutine = false); void push_param(lua_State* L, bool is_coroutine = false);
int32 call_function(int32 f, uint32 param_count, uint32 ret_count); int32 call_function(int32 f, uint32 param_count, int32 ret_count);
int32 call_card_function(card *pcard, char *f, uint32 param_count, uint32 ret_count); int32 call_card_function(card *pcard, char *f, uint32 param_count, int32 ret_count);
int32 call_code_function(uint32 code, char *f, uint32 param_count, uint32 ret_count); int32 call_code_function(uint32 code, char *f, uint32 param_count, int32 ret_count);
int32 check_condition(int32 f, uint32 param_count); int32 check_condition(int32 f, uint32 param_count);
int32 check_matching(card* pcard, int32 findex, int32 extraargs); int32 check_matching(card* pcard, int32 findex, int32 extraargs);
int32 get_operation_value(card* pcard, int32 findex, int32 extraargs); int32 get_operation_value(card* pcard, int32 findex, int32 extraargs);
int32 get_function_value(int32 f, uint32 param_count); int32 get_function_value(int32 f, uint32 param_count);
int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result);
int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step); int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step);
static void card2value(lua_State* L, card* pcard); static void card2value(lua_State* L, card* pcard);
......
...@@ -1461,8 +1461,9 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui ...@@ -1461,8 +1461,9 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui
core.units.begin()->step = 3; core.units.begin()->step = 3;
if(!ignore_count && !core.extra_summon[sumplayer]) { if(!ignore_count && !core.extra_summon[sumplayer]) {
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
if(!val) { eset[i]->get_value(target, 0, &retval);
if(retval.size() < 2) {
core.units.begin()->ptr1 = eset[i]; core.units.begin()->ptr1 = eset[i];
return FALSE; return FALSE;
} }
...@@ -1483,21 +1484,19 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui ...@@ -1483,21 +1484,19 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui
} }
if(!ignore_count && !core.extra_summon[sumplayer]) { if(!ignore_count && !core.extra_summon[sumplayer]) {
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; eset[i]->get_value(target, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
bool unchanged = true; int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
if(new_zone && (new_zone & zone) != zone) { int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff - retval[2] : retval[2]) : 0xff00ff;
new_zone &= zone; new_zone &= zone;
unchanged = false; bool unchanged = (new_zone == zone);
} else
new_zone = zone;
if(peffect) { if(peffect) {
if(new_min_tribute < (int32)min_tribute) { if(new_min_tribute < (int32)min_tribute) {
new_min_tribute = min_tribute; new_min_tribute = min_tribute;
unchanged = false; unchanged = false;
} }
if(!target->is_summonable(peffect, new_min_tribute, new_zone)) if(!target->is_summonable(peffect, new_min_tribute, new_zone, releasable))
continue; continue;
} else { } else {
int32 rcount = target->get_summon_tribute_count(); int32 rcount = target->get_summon_tribute_count();
...@@ -1513,7 +1512,7 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui ...@@ -1513,7 +1512,7 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui
min = new_min_tribute; min = new_min_tribute;
unchanged = false; unchanged = false;
} }
if(!check_tribute(target, min, max, 0, target->current.controler, new_zone)) if(!check_tribute(target, min, max, 0, target->current.controler, new_zone, releasable))
continue; continue;
} }
if(unlimited < 0 && unchanged) if(unlimited < 0 && unchanged)
...@@ -1535,14 +1534,16 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui ...@@ -1535,14 +1534,16 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui
case 2: { case 2: {
effect* pextra = core.select_effects[returns.ivalue[0]]; effect* pextra = core.select_effects[returns.ivalue[0]];
core.units.begin()->ptr1 = pextra; core.units.begin()->ptr1 = pextra;
int32 releasable = 0xff00ff;
if(pextra) { if(pextra) {
int32 val = pextra->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; pextra->get_value(target, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if((int32)min_tribute < new_min_tribute) if((int32)min_tribute < new_min_tribute)
min_tribute = new_min_tribute; min_tribute = new_min_tribute;
if(new_zone) zone &= new_zone;
zone &= new_zone;
core.units.begin()->arg1 = sumplayer + (ignore_count << 8) + (min_tribute << 16) + (zone << 24); core.units.begin()->arg1 = sumplayer + (ignore_count << 8) + (min_tribute << 16) + (zone << 24);
} }
if(proc) { if(proc) {
...@@ -1565,7 +1566,7 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui ...@@ -1565,7 +1566,7 @@ int32 field::summon(uint16 step, uint8 sumplayer, card* target, effect* proc, ui
core.release_cards.clear(); core.release_cards.clear();
core.release_cards_ex.clear(); core.release_cards_ex.clear();
core.release_cards_ex_sum.clear(); core.release_cards_ex_sum.clear();
int32 rcount = get_summon_release_list(target, &core.release_cards, &core.release_cards_ex, &core.release_cards_ex_sum); int32 rcount = get_summon_release_list(target, &core.release_cards, &core.release_cards_ex, &core.release_cards_ex_sum, NULL, 0, releasable);
if(rcount == 0) { if(rcount == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
core.units.begin()->step = 3; core.units.begin()->step = 3;
...@@ -2010,8 +2011,9 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint ...@@ -2010,8 +2011,9 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
core.units.begin()->step = 3; core.units.begin()->step = 3;
if(!ignore_count && !core.extra_summon[setplayer]) { if(!ignore_count && !core.extra_summon[setplayer]) {
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
if(!val) { eset[i]->get_value(target, 0, &retval);
if(retval.size() < 2) {
core.units.begin()->ptr1 = eset[i]; core.units.begin()->ptr1 = eset[i];
return FALSE; return FALSE;
} }
...@@ -2032,21 +2034,19 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint ...@@ -2032,21 +2034,19 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
} }
if(!ignore_count && !core.extra_summon[setplayer]) { if(!ignore_count && !core.extra_summon[setplayer]) {
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
int32 val = eset[i]->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; eset[i]->get_value(target, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
bool unchanged = true; int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
if(new_zone && (new_zone & zone) != zone) { int32 releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff - retval[2] : retval[2]) : 0xff00ff;
new_zone &= zone; new_zone &= zone;
unchanged = false; bool unchanged = (new_zone == zone);
} else
new_zone = zone;
if(peffect) { if(peffect) {
if(new_min_tribute < (int32)min_tribute) { if(new_min_tribute < (int32)min_tribute) {
new_min_tribute = min_tribute; new_min_tribute = min_tribute;
unchanged = false; unchanged = false;
} }
if(!target->is_summonable(peffect, new_min_tribute, new_zone)) if(!target->is_summonable(peffect, new_min_tribute, new_zone, releasable))
continue; continue;
} else { } else {
int32 rcount = target->get_set_tribute_count(); int32 rcount = target->get_set_tribute_count();
...@@ -2062,7 +2062,7 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint ...@@ -2062,7 +2062,7 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
min = new_min_tribute; min = new_min_tribute;
unchanged = false; unchanged = false;
} }
if(!check_tribute(target, min, max, 0, target->current.controler, new_zone)) if(!check_tribute(target, min, max, 0, target->current.controler, new_zone, releasable))
continue; continue;
} }
if(unlimited < 0 && unchanged) if(unlimited < 0 && unchanged)
...@@ -2084,14 +2084,16 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint ...@@ -2084,14 +2084,16 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
case 2: { case 2: {
effect* pextra = core.select_effects[returns.ivalue[0]]; effect* pextra = core.select_effects[returns.ivalue[0]];
core.units.begin()->ptr1 = pextra; core.units.begin()->ptr1 = pextra;
int32 releasable = 0xff00ff;
if(pextra) { if(pextra) {
int32 val = pextra->get_value(); std::vector<int32> retval;
int32 new_min_tribute = val & 0xff; pextra->get_value(target, 0, &retval);
int32 new_zone = (val >> 16) & 0x1f; int32 new_min_tribute = retval.size() > 0 ? retval[0] : 0;
int32 new_zone = retval.size() > 1 ? retval[1] : 0x1f;
releasable = retval.size() > 2 ? (retval[2] < 0 ? 0xff00ff + retval[2] : retval[2]) : 0xff00ff;
if((int32)min_tribute < new_min_tribute) if((int32)min_tribute < new_min_tribute)
min_tribute = new_min_tribute; min_tribute = new_min_tribute;
if(new_zone) zone &= new_zone;
zone &= new_zone;
core.units.begin()->arg1 = setplayer + (ignore_count << 8) + (min_tribute << 16) + (zone << 24); core.units.begin()->arg1 = setplayer + (ignore_count << 8) + (min_tribute << 16) + (zone << 24);
} }
if(proc) { if(proc) {
...@@ -2114,7 +2116,7 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint ...@@ -2114,7 +2116,7 @@ int32 field::mset(uint16 step, uint8 setplayer, card* target, effect* proc, uint
core.release_cards.clear(); core.release_cards.clear();
core.release_cards_ex.clear(); core.release_cards_ex.clear();
core.release_cards_ex_sum.clear(); core.release_cards_ex_sum.clear();
int32 rcount = get_summon_release_list(target, &core.release_cards, &core.release_cards_ex, &core.release_cards_ex_sum); int32 rcount = get_summon_release_list(target, &core.release_cards, &core.release_cards_ex, &core.release_cards_ex_sum, NULL, 0, releasable);
if(rcount == 0) { if(rcount == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
core.units.begin()->step = 3; core.units.begin()->step = 3;
...@@ -2386,7 +2388,7 @@ int32 field::sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget ...@@ -2386,7 +2388,7 @@ int32 field::sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget
} }
return TRUE; return TRUE;
} }
int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card * target, uint32 summon_type) { int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card* target, uint32 summon_type) {
switch(step) { switch(step) {
case 0: { case 0: {
effect_set eset; effect_set eset;
...@@ -2457,7 +2459,12 @@ int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card * target, ui ...@@ -2457,7 +2459,12 @@ int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card * target, ui
case 3: { case 3: {
effect* peffect = core.units.begin()->peffect; effect* peffect = core.units.begin()->peffect;
target->material_cards.clear(); target->material_cards.clear();
target->summon_info = (peffect->get_value(target) & 0xf00ffff) | SUMMON_TYPE_SPECIAL | ((uint32)target->current.location << 16); std::vector<int32> retval;
peffect->get_value(target, 0, &retval);
uint32 summon_info = retval.size() > 0 ? retval[0] : 0;
uint32 zone = retval.size() > 1 ? retval[1] : 0xff;
core.units.begin()->arg3 = zone;
target->summon_info = (summon_info & 0xf00ffff) | SUMMON_TYPE_SPECIAL | ((uint32)target->current.location << 16);
if(peffect->operation) { if(peffect->operation) {
pduel->lua->add_param(target, PARAM_TYPE_CARD); pduel->lua->add_param(target, PARAM_TYPE_CARD);
if(core.limit_tuner || core.limit_syn) { if(core.limit_tuner || core.limit_syn) {
...@@ -2495,9 +2502,7 @@ int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card * target, ui ...@@ -2495,9 +2502,7 @@ int32 field::special_summon_rule(uint16 step, uint8 sumplayer, card * target, ui
} }
if(positions == 0) if(positions == 0)
positions = POS_FACEUP_ATTACK; positions = POS_FACEUP_ATTACK;
uint32 zone = (peffect->get_value(target) >> 16) & 0xff; uint32 zone = core.units.begin()->arg3;
if(zone == 0)
zone = 0xff;
target->enable_field_effect(false); target->enable_field_effect(false);
move_to_field(target, sumplayer, targetplayer, LOCATION_MZONE, positions, FALSE, 0, FALSE, zone); move_to_field(target, sumplayer, targetplayer, LOCATION_MZONE, positions, FALSE, 0, FALSE, zone);
target->current.reason = REASON_SPSUMMON; target->current.reason = REASON_SPSUMMON;
......
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