From bf092a778452d2c4261571cbe1459b17268ae792 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Fri, 12 May 2023 20:48:42 +0300 Subject: [PATCH 24/24] Delay city size change when restoring protected unit upkeep Actually updating the city while calculating what needs to be done caused the data to get inconsistent. Some of the used values were from the city before it had shrunk, and others (reduced production) from the smaller city. See osdn #48023 Signed-off-by: Marko Lindqvist --- server/cityturn.c | 46 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/server/cityturn.c b/server/cityturn.c index 0e4fb076d5..ba6d2ccfa4 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -2431,12 +2431,18 @@ static void upgrade_unit_prod(struct city *pcity) } /**********************************************************************//** - Disband units if we don't have enough shields to support them. Returns - FALSE if the _city_ is disbanded as a result. + Disband units if we don't have enough shields to support them. + + @param pplayer city owner + @param pcity city to check + @return whether the _city_ is disbanded as a result. **************************************************************************/ static bool city_distribute_surplus_shields(struct player *pplayer, - struct city *pcity) + struct city *pcity) { + int size_reduction = 0; + struct unit *sacrifizer; + if (pcity->surplus[O_SHIELD] < 0) { unit_list_iterate_safe(pcity->units_supported, punit) { if (utype_upkeep_cost(unit_type_get(punit), pplayer, O_SHIELD) > 0 @@ -2468,14 +2474,9 @@ static bool city_distribute_surplus_shields(struct player *pplayer, int upkeep = utype_upkeep_cost(unit_type_get(punit), pplayer, O_SHIELD); if (upkeep > 0 && pcity->surplus[O_SHIELD] < 0) { - notify_player(pplayer, city_tile(pcity), - E_UNIT_LOST_MISC, ftc_server, - _("Citizens in %s perish for their failure to " - "upkeep %s!"), - city_link(pcity), unit_link(punit)); - if (!city_reduce_size(pcity, 1, NULL, "upkeep_failure")) { - return FALSE; - } + + size_reduction++; + sacrifizer = punit; /* No upkeep for the unit this turn. */ pcity->surplus[O_SHIELD] += upkeep; @@ -2488,6 +2489,29 @@ static bool city_distribute_surplus_shields(struct player *pplayer, pcity->before_change_shields = pcity->shield_stock; pcity->last_turns_shield_surplus = pcity->surplus[O_SHIELD]; + /* Previous turn values stored, and they are consistent with + * other previous turn data. + * Now reduce city size, likely messing all the values. */ + if (size_reduction > 0) { + if (size_reduction == 1) { + notify_player(pplayer, city_tile(pcity), + E_UNIT_LOST_MISC, ftc_server, + _("Citizens in %s perish for their failure to " + "upkeep %s!"), + city_link(pcity), unit_link(sacrifizer)); + } else { + notify_player(pplayer, city_tile(pcity), + E_UNIT_LOST_MISC, ftc_server, + _("Citizens in %s perish for their failure to " + "upkeep units!"), + city_link(pcity)); + } + + if (!city_reduce_size(pcity, size_reduction, NULL, "upkeep_failure")) { + return FALSE; + } + } + return TRUE; } -- 2.39.2