From ff1a8a70665e894c8034bbc7273f79e1fc219aa6 Mon Sep 17 00:00:00 2001 From: Edoardo Lolletti Date: Thu, 15 Feb 2024 00:41:02 +0100 Subject: [PATCH] Fix EFFECT_COUNTER_LIMIT handling In case of multiple of those effects being applied, the value of the latest applied was being used, rather than the smallest of them all --- card.cpp | 22 ++++++++++++---------- card.h | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/card.cpp b/card.cpp index 26f373cb..99dd5b76 100644 --- a/card.cpp +++ b/card.cpp @@ -4,7 +4,7 @@ * * SPDX-License-Identifier: AGPL-3.0-or-later */ -#include //std::sort +#include //std::sort, std::min #include //std::memcpy #include //std::pair, std::make_pair, std::swap #include @@ -2302,7 +2302,7 @@ int32_t card::destination_redirect(uint8_t destination, uint32_t /*reason*/) { } // cmit->second[0]: permanent // cmit->second[1]: reset while negated -int32_t card::add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly) { +int32_t card::add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, bool singly) { if(!is_can_add_counter(playerid, countertype, count, singly, 0)) return FALSE; uint16_t cttype = countertype & ~COUNTER_NEED_ENABLE; @@ -2315,12 +2315,12 @@ int32_t card::add_counter(uint8_t playerid, uint16_t countertype, uint16_t count uint16_t pcount = count; if(singly) { effect_set eset; - uint16_t limit = 0; + auto limit = UINT16_MAX + 1; filter_effect(EFFECT_COUNTER_LIMIT + cttype, &eset); for(const auto& peffect : eset) - limit = peffect->get_value(); - if(limit) { - uint16_t mcount = limit - get_counter(cttype); + limit = std::min(static_cast(peffect->get_value()), limit); + if(limit != (UINT16_MAX + 1)) { + uint16_t mcount = static_cast(limit) - get_counter(cttype); if(pcount > mcount) pcount = mcount; } @@ -2361,7 +2361,7 @@ int32_t card::remove_counter(uint16_t countertype, uint16_t count) { message->write(count); return TRUE; } -int32_t card::is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly, uint32_t loc) { +int32_t card::is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, bool singly, uint32_t loc) { effect_set eset; if(count > 0) { if(!pduel->game_field->is_player_can_place_counter(playerid, this, countertype, count)) @@ -2396,15 +2396,17 @@ int32_t card::is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_ if(!check) return FALSE; uint16_t cttype = countertype & ~COUNTER_NEED_ENABLE; - int32_t limit = -1; + auto limit = UINT16_MAX + 1; int32_t cur = 0; auto cmit = counters.find(cttype); if(cmit != counters.end()) cur = cmit->second[0] + cmit->second[1]; filter_effect(EFFECT_COUNTER_LIMIT + cttype, &eset); for(const auto& peffect : eset) - limit = peffect->get_value(); - if(limit > 0 && (cur + (singly ? 1 : count) > limit)) + limit = std::min(static_cast(peffect->get_value()), limit); + if(singly) + count = 1; + if((limit != (UINT16_MAX + 1)) && (cur + count > limit)) return FALSE; return TRUE; } diff --git a/card.h b/card.h index 219a6811..f1fc7a08 100644 --- a/card.h +++ b/card.h @@ -281,9 +281,9 @@ class card : public lua_obj_helper { void release_relation(effect* peffect); int32_t leave_field_redirect(uint32_t reason); int32_t destination_redirect(uint8_t destination, uint32_t reason); - int32_t add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly); + int32_t add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, bool singly); int32_t remove_counter(uint16_t countertype, uint16_t count); - int32_t is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly, uint32_t loc); + int32_t is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, bool singly, uint32_t loc); int32_t get_counter(uint16_t countertype); void set_material(card_set materials); void add_card_target(card* pcard);