Skip to content

Commit

Permalink
Update tribute related functions to support "Ritual Beast Ulti-Reirau…
Browse files Browse the repository at this point in the history
…tari" (#150)

* Update Card.IsReleasable to accept a second, optional parameter for the reason. Update GetReleaseGroup, GetReleaseGroupCount the same way as well, with the new parameter being the 4th. Defaulting it to REASON_COST will prevent massive script changes (cards that tribute by effect already use Card.IsReleasableByEffect).

* Update EFFECT_CANNOT_RELEASE to pass the reason and the reason effect a 4th and 5th parameters to its target function

* Pass the reason down the line until get_release_list, check_release_list,is_player_can_release and card::is_releasable_by_nonsummon, updating internal function calls accordingly

---------

Co-authored-by: Edoardo Lolletti <[email protected]>
  • Loading branch information
NaimSantos and edo9300 authored Nov 12, 2023
1 parent d9b48da commit 7ac33a9
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 28 deletions.
6 changes: 3 additions & 3 deletions card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3646,15 +3646,15 @@ int32_t card::is_releasable_by_summon(uint8_t playerid, card* pcard) {
return FALSE;
if(current.location & (LOCATION_GRAVE | LOCATION_REMOVED))
return FALSE;
if(!pduel->game_field->is_player_can_release(playerid, this))
if(!pduel->game_field->is_player_can_release(playerid, this, REASON_SUMMON))
return FALSE;
if(is_affected_by_effect(EFFECT_UNRELEASABLE_SUM, pcard))
return FALSE;
if(pcard->is_affected_by_effect(EFFECT_TRIBUTE_LIMIT, this))
return FALSE;
return TRUE;
}
int32_t card::is_releasable_by_nonsummon(uint8_t playerid) {
int32_t card::is_releasable_by_nonsummon(uint8_t playerid, uint32_t reason) {
if(is_status(STATUS_SUMMONING))
return FALSE;
if(overlay_target)
Expand All @@ -3663,7 +3663,7 @@ int32_t card::is_releasable_by_nonsummon(uint8_t playerid) {
return FALSE;
if((current.location == LOCATION_HAND) && (data.type & (TYPE_SPELL | TYPE_TRAP)))
return FALSE;
if(!pduel->game_field->is_player_can_release(playerid, this))
if(!pduel->game_field->is_player_can_release(playerid, this, reason))
return FALSE;
if(is_affected_by_effect(EFFECT_UNRELEASABLE_NONSUM))
return FALSE;
Expand Down
2 changes: 1 addition & 1 deletion card.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class card : public lua_obj_helper<PARAM_TYPE_CARD> {
int32_t is_removeable(uint8_t playerid, uint8_t pos = POS_FACEUP, uint32_t reason = REASON_EFFECT);
int32_t is_removeable_as_cost(uint8_t playerid, uint8_t pos = POS_FACEUP);
int32_t is_releasable_by_summon(uint8_t playerid, card* pcard);
int32_t is_releasable_by_nonsummon(uint8_t playerid);
int32_t is_releasable_by_nonsummon(uint8_t playerid, uint32_t reason);
int32_t is_releasable_by_effect(uint8_t playerid, effect* peffect);
int32_t is_capable_send_to_grave(uint8_t playerid);
int32_t is_capable_send_to_hand(uint8_t playerid);
Expand Down
28 changes: 15 additions & 13 deletions field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1725,10 +1725,10 @@ void field::get_player_effect(uint8_t playerid, uint32_t code, effect_set* eset)
eset->push_back(peffect);
}
}
int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t use_oppo) {
int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t use_oppo, uint32_t reason) {
uint32_t rcount = 0;
for(auto& pcard : player[playerid].list_mzone) {
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && pcard->is_releasable_by_nonsummon(playerid)
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && pcard->is_releasable_by_nonsummon(playerid, reason)
&& (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
if(release_list)
release_list->insert(pcard);
Expand All @@ -1738,7 +1738,7 @@ int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_s
}
if(use_hand) {
for(auto& pcard : player[playerid].list_hand) {
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && pcard->is_releasable_by_nonsummon(playerid)
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && pcard->is_releasable_by_nonsummon(playerid, reason)
&& (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
if(release_list)
release_list->insert(pcard);
Expand All @@ -1751,7 +1751,7 @@ int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_s
if(use_oppo) {
for(auto& pcard : player[1 - playerid].list_mzone) {
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && (pcard->is_position(POS_FACEUP) || !fun)
&& pcard->is_releasable_by_nonsummon(playerid) && (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
&& pcard->is_releasable_by_nonsummon(playerid, reason) && (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
if(release_list)
release_list->insert(pcard);
pcard->release_param = 1;
Expand All @@ -1761,7 +1761,7 @@ int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_s
} else {
for(auto& pcard : player[1 - playerid].list_mzone) {
if(pcard && pcard != exc && !(exg && exg->has_card(pcard)) && (pcard->is_position(POS_FACEUP) || !fun)
&& pcard->is_releasable_by_nonsummon(playerid) && (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
&& pcard->is_releasable_by_nonsummon(playerid, reason) && (!fun || pduel->lua->check_matching(pcard, fun, exarg))) {
pcard->release_param = 1;
if(pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE)) {
if(ex_list)
Expand All @@ -1772,7 +1772,7 @@ int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_s
if(!peffect || (peffect->is_flag(EFFECT_FLAG_COUNT_LIMIT) && peffect->count_limit == 0))
continue;
pduel->lua->add_param<PARAM_TYPE_EFFECT>(core.reason_effect);
pduel->lua->add_param<PARAM_TYPE_INT>(REASON_COST);
pduel->lua->add_param<PARAM_TYPE_INT>(reason);
pduel->lua->add_param<PARAM_TYPE_INT>(core.reason_player);
if(!peffect->check_value_condition(3))
continue;
Expand All @@ -1785,13 +1785,13 @@ int32_t field::get_release_list(uint8_t playerid, card_set* release_list, card_s
}
return rcount + ex_oneof_max;
}
int32_t field::check_release_list(uint8_t playerid, int32_t min, int32_t /*max*/, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t check_field, uint8_t to_player, uint8_t zone, card* to_check, uint8_t use_oppo) {
int32_t field::check_release_list(uint8_t playerid, int32_t min, int32_t /*max*/, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t check_field, uint8_t to_player, uint8_t zone, card* to_check, uint8_t use_oppo, uint32_t reason) {
card_set relcard;
//card_set relcard_must;
card_set relcard_oneof;
bool has_to_choose_one = false;
card_set must_choose_one;
int32_t rcount = get_release_list(playerid, &relcard, &relcard, &relcard_oneof, use_hand, fun, exarg, exc, exg, use_oppo);
int32_t rcount = get_release_list(playerid, &relcard, &relcard, &relcard_oneof, use_hand, fun, exarg, exc, exg, use_oppo, reason);
if(check_field) {
int32_t ct = 0;
zone &= (0x1f & get_forced_zones(to_check, playerid, LOCATION_MZONE, to_player, LOCATION_REASON_TOFIELD));
Expand Down Expand Up @@ -1925,15 +1925,15 @@ void field::get_ritual_material(uint8_t playerid, effect* peffect, card_set* mat
&& pcard->is_releasable_by_effect(playerid, peffect);
};
for(auto& pcard : player[playerid].list_mzone) {
if(pcard && mzonecheck(pcard) && pcard->is_releasable_by_nonsummon(playerid))
if(pcard && mzonecheck(pcard) && pcard->is_releasable_by_nonsummon(playerid, REASON_EFFECT))
material->insert(pcard);
}
for(auto& pcard : player[1 - playerid].list_mzone) {
if(pcard && pcard->is_position(POS_FACEUP) && mzonecheck(pcard) && pcard->is_releasable_by_nonsummon(playerid) && pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE))
if(pcard && pcard->is_position(POS_FACEUP) && mzonecheck(pcard) && pcard->is_releasable_by_nonsummon(playerid, REASON_EFFECT) && pcard->is_affected_by_effect(EFFECT_EXTRA_RELEASE))
material->insert(pcard);
}
for(auto& pcard : player[playerid].list_hand)
if((pcard->data.type & TYPE_MONSTER) && pcard->is_releasable_by_nonsummon(playerid))
if((pcard->data.type & TYPE_MONSTER) && pcard->is_releasable_by_nonsummon(playerid, REASON_EFFECT))
material->insert(pcard);
for(auto& pcard : player[playerid].list_grave)
if((pcard->data.type & TYPE_MONSTER) && pcard->is_affected_by_effect(EFFECT_EXTRA_RITUAL_MATERIAL) && pcard->is_removeable(playerid, POS_FACEUP, REASON_EFFECT))
Expand Down Expand Up @@ -2806,7 +2806,7 @@ int32_t field::is_player_can_spsummon_monster(uint8_t playerid, uint8_t toplayer
temp_card->data = {};
return result;
}
int32_t field::is_player_can_release(uint8_t playerid, card* pcard) {
int32_t field::is_player_can_release(uint8_t playerid, card* pcard, uint32_t reason) {
effect_set eset;
filter_player_effect(playerid, EFFECT_CANNOT_RELEASE, &eset);
for(const auto& peff : eset) {
Expand All @@ -2815,7 +2815,9 @@ int32_t field::is_player_can_release(uint8_t playerid, card* pcard) {
pduel->lua->add_param<PARAM_TYPE_EFFECT>(peff);
pduel->lua->add_param<PARAM_TYPE_CARD>(pcard);
pduel->lua->add_param<PARAM_TYPE_INT>(playerid);
if (pduel->lua->check_condition(peff->target, 3))
pduel->lua->add_param<PARAM_TYPE_INT>(reason);
pduel->lua->add_param<PARAM_TYPE_EFFECT>(core.reason_effect);
if (pduel->lua->check_condition(peff->target, 5))
return FALSE;
}
return TRUE;
Expand Down
6 changes: 3 additions & 3 deletions field.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@ class field {
effect* is_player_affected_by_effect(uint8_t playerid, uint32_t code);
void get_player_effect(uint8_t playerid, uint32_t code, effect_set* eset);

int32_t get_release_list(uint8_t playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t use_oppo);
int32_t check_release_list(uint8_t playerid, int32_t min, int32_t max, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t check_field, uint8_t to_player, uint8_t zone, card* to_check, uint8_t use_oppo);
int32_t get_release_list(uint8_t playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t use_oppo, uint32_t reason);
int32_t check_release_list(uint8_t playerid, int32_t min, int32_t max, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint8_t check_field, uint8_t to_player, uint8_t zone, card* to_check, uint8_t use_oppo, uint32_t reason);
int32_t get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, group* mg = nullptr, uint32_t ex = 0, uint32_t releasable = 0xff00ff, uint32_t pos = 0x1);
int32_t get_summon_count_limit(uint8_t playerid);
int32_t get_draw_count(uint8_t playerid);
Expand Down Expand Up @@ -537,7 +537,7 @@ class field {
int32_t is_player_can_flipsummon(uint8_t playerid, card* pcard);
int32_t is_player_can_spsummon_monster(uint8_t playerid, uint8_t toplayer, uint8_t sumpos, uint32_t sumtype, card_data* pdata);
int32_t is_player_can_spsummon_count(uint8_t playerid, uint32_t count);
int32_t is_player_can_release(uint8_t playerid, card* pcard);
int32_t is_player_can_release(uint8_t playerid, card* pcard, uint32_t reason);
int32_t is_player_can_place_counter(uint8_t playerid, card* pcard, uint16_t countertype, uint16_t count);
int32_t is_player_can_remove_counter(uint8_t playerid, card* pcard, uint8_t self, uint8_t oppo, uint16_t countertype, uint16_t count, uint32_t reason);
int32_t is_player_can_remove_overlay_card(uint8_t playerid, group* pcard, uint8_t self, uint8_t oppo, uint16_t count, uint32_t reason);
Expand Down
5 changes: 3 additions & 2 deletions libcard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1879,7 +1879,8 @@ LUA_FUNCTION(IsReleasable) {
check_param_count(L, 1);
const auto pduel = lua_get<duel*>(L);
auto pcard = lua_get<card*, true>(L, 1);
lua_pushboolean(L, pcard->is_releasable_by_nonsummon(pduel->game_field->core.reason_player));
const auto reason = lua_get<uint32_t, REASON_COST>(L, 2);
lua_pushboolean(L, pcard->is_releasable_by_nonsummon(pduel->game_field->core.reason_player, reason));
return 1;
}
LUA_FUNCTION(IsReleasableByEffect) {
Expand All @@ -1888,7 +1889,7 @@ LUA_FUNCTION(IsReleasableByEffect) {
auto pcard = lua_get<card*, true>(L, 1);
auto p = pduel->game_field->core.reason_player;
effect* re = pduel->game_field->core.reason_effect;
lua_pushboolean(L, pcard->is_releasable_by_nonsummon(p) && pcard->is_releasable_by_effect(p, re));
lua_pushboolean(L, pcard->is_releasable_by_nonsummon(p, REASON_EFFECT) && pcard->is_releasable_by_effect(p, re));
return 1;
}
LUA_FUNCTION(IsDiscardable) {
Expand Down
13 changes: 8 additions & 5 deletions libduel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2518,9 +2518,10 @@ LUA_FUNCTION(GetReleaseGroup) {
return 0;
bool hand = lua_get<bool, false>(L, 2);
bool oppo = lua_get<bool, false>(L, 3);
const auto reason = lua_get<uint32_t, REASON_COST>(L,4);
const auto pduel = lua_get<duel*>(L);
group* pgroup = pduel->new_group();
pduel->game_field->get_release_list(playerid, &pgroup->container, &pgroup->container, &pgroup->container, hand, 0, 0, 0, 0, oppo);
pduel->game_field->get_release_list(playerid, &pgroup->container, &pgroup->container, &pgroup->container, hand, 0, 0, 0, 0, oppo, reason);
interpreter::pushobject(L, pgroup);
return 1;
}
Expand All @@ -2536,8 +2537,9 @@ LUA_FUNCTION(GetReleaseGroupCount) {
return 0;
bool hand = lua_get<bool, false>(L, 2);
bool oppo = lua_get<bool, false>(L, 3);
const auto reason = lua_get<uint32_t, REASON_COST>(L, 4);
const auto pduel = lua_get<duel*>(L);
lua_pushinteger(L, pduel->game_field->get_release_list(playerid, 0, 0, 0, hand, 0, 0, 0, 0, oppo));
lua_pushinteger(L, pduel->game_field->get_release_list(playerid, 0, 0, 0, hand, 0, 0, 0, 0, oppo, reason));
return 1;
}
static int32_t check_release_group(lua_State* L, uint8_t use_hand) {
Expand Down Expand Up @@ -2576,7 +2578,7 @@ static int32_t check_release_group(lua_State* L, uint8_t use_hand) {
if((pexception = lua_get<card*>(L, lastarg)) == nullptr)
pexgroup = lua_get<group*>(L, lastarg);
uint32_t extraargs = lua_gettop(L) - lastarg;
int32_t result = pduel->game_field->check_release_list(playerid, min, max, use_hand, findex, extraargs, pexception, pexgroup, check_field, toplayer, zone, to_check, use_oppo);
int32_t result = pduel->game_field->check_release_list(playerid, min, max, use_hand, findex, extraargs, pexception, pexgroup, check_field, toplayer, zone, to_check, use_oppo, REASON_EFFECT);
pduel->game_field->core.must_select_cards.clear();
lua_pushboolean(L, result);
return 1;
Expand Down Expand Up @@ -2629,7 +2631,7 @@ static int32_t select_release_group(lua_State* L, uint8_t use_hand) {
pduel->game_field->core.release_cards.clear();
pduel->game_field->core.release_cards_ex.clear();
pduel->game_field->core.release_cards_ex_oneof.clear();
pduel->game_field->get_release_list(playerid, &pduel->game_field->core.release_cards, &pduel->game_field->core.release_cards_ex, &pduel->game_field->core.release_cards_ex_oneof, use_hand, findex, extraargs, pexception, pexgroup, use_oppo);
pduel->game_field->get_release_list(playerid, &pduel->game_field->core.release_cards, &pduel->game_field->core.release_cards_ex, &pduel->game_field->core.release_cards_ex_oneof, use_hand, findex, extraargs, pexception, pexgroup, use_oppo, REASON_EFFECT);
pduel->game_field->add_process(PROCESSOR_SELECT_RELEASE, 0, 0, (group*)to_check, playerid + (cancelable << 16), (max << 16) + min, check_field + (toplayer << 8) + (zone << 16));
return lua_yieldk(L, 0, (lua_KContext)cancelable, push_return_cards);
}
Expand Down Expand Up @@ -3980,7 +3982,8 @@ LUA_FUNCTION(IsPlayerCanRelease) {
else {
check_param_count(L, 2);
auto pcard = lua_get<card*, true>(L, 2);
lua_pushboolean(L, pduel->game_field->is_player_can_release(playerid, pcard));
const auto reason = lua_get<uint32_t, REASON_COST>(L, 3);
lua_pushboolean(L, pduel->game_field->is_player_can_release(playerid, pcard, reason));
}
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4113,7 +4113,7 @@ int32_t field::release(uint16_t step, group* targets, effect* reason_effect, uin
if(pcard->get_status(STATUS_SUMMONING | STATUS_SPSUMMON_STEP)
|| ((reason & REASON_SUMMON) && !pcard->is_releasable_by_summon(reason_player, pcard->current.reason_card))
|| (!(pcard->current.reason & (REASON_RULE | REASON_SUMMON | REASON_COST))
&& (!pcard->is_affect_by_effect(pcard->current.reason_effect) || !pcard->is_releasable_by_nonsummon(reason_player)))) {
&& (!pcard->is_affect_by_effect(pcard->current.reason_effect) || !pcard->is_releasable_by_nonsummon(reason_player, reason)))) {
pcard->current.reason = pcard->temp.reason;
pcard->current.reason_effect = pcard->temp.reason_effect;
pcard->current.reason_player = pcard->temp.reason_player;
Expand Down

0 comments on commit 7ac33a9

Please sign in to comment.