From 59b2f2180bc6ad485214e62bdc02265e8493a19d Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 22 Oct 2024 21:53:40 +0300
Subject: [PATCH 26/26] Optimize maybe_become_veteran_real()

See RM #1001

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 ai/default/aitools.c | 12 +++++++-----
 common/actions.c     |  8 ++++----
 common/combat.c      |  6 ++++--
 common/unit.c        |  9 ++++++---
 common/unittype.c    | 19 ++++++++++++++++---
 common/unittype.h    |  3 +++
 server/diplomats.c   | 11 +++++++----
 server/edithand.c    |  3 ++-
 server/unittools.c   |  8 ++------
 9 files changed, 51 insertions(+), 28 deletions(-)

diff --git a/ai/default/aitools.c b/ai/default/aitools.c
index 5f95eb9a7e..fd6fb96121 100644
--- a/ai/default/aitools.c
+++ b/ai/default/aitools.c
@@ -154,7 +154,7 @@ void dai_consider_plr_dangerous(struct ai_type *ait, struct player *plr1,
 }
 
 /**********************************************************************//**
-  A helper function for ai_gothere.  Estimates the dangers we will
+  A helper function for ai_gothere. Estimates the dangers we will
   be facing at our destination and tries to find/request a bodyguard if
   needed.
 **************************************************************************/
@@ -167,9 +167,10 @@ static bool dai_gothere_bodyguard(struct ai_type *ait,
   struct unit *guard = aiguard_guard_of(ait, punit);
   const struct veteran_level *vlevel;
   bool bg_needed = FALSE;
+  const struct unit_type *ptype;
 
   if (is_barbarian(unit_owner(punit))) {
-    /* barbarians must have more courage (ie less brains) */
+    /* Barbarians must have more courage (ie less brains) */
     aiguard_clear_guard(ait, punit);
     return FALSE;
   }
@@ -198,17 +199,18 @@ static bool dai_gothere_bodyguard(struct ai_type *ait,
   /* If we are fast, there is less danger.
    * FIXME: that assumes that most units have move_rate == SINGLE_MOVE;
    * not true for all rulesets */
-  danger /= (unit_type_get(punit)->move_rate / SINGLE_MOVE);
+  ptype = unit_type_get(punit);
+  danger /= (ptype->move_rate / SINGLE_MOVE);
   if (unit_has_type_flag(punit, UTYF_IGTER)) {
     danger /= 1.5;
   }
 
-  vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
+  vlevel = utype_veteran_level(ptype, punit->veteran);
   fc_assert_ret_val(vlevel != NULL, FALSE);
 
   /* We look for the bodyguard where we stand. */
   if (guard == NULL || unit_tile(guard) != unit_tile(punit)) {
-    int my_def = (punit->hp * unit_type_get(punit)->defense_strength
+    int my_def = (punit->hp * ptype->defense_strength
                   * POWER_FACTOR * vlevel->power_fact / 100);
 
     if (danger >= my_def) {
diff --git a/common/actions.c b/common/actions.c
index 56bddfe6fe..5de676b01b 100644
--- a/common/actions.c
+++ b/common/actions.c
@@ -4391,10 +4391,10 @@ static struct act_prob ap_dipl_battle_win(const struct unit *pattacker,
 
   /* Veteran attack and defense bonus */
   {
-    const struct veteran_level *vatt =
-        utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
-    const struct veteran_level *vdef =
-        utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
+    const struct veteran_level *vatt
+      = utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
+    const struct veteran_level *vdef
+      = utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
 
     chance += vatt->power_fact - vdef->power_fact;
   }
diff --git a/common/combat.c b/common/combat.c
index 068db74448..9d0b151640 100644
--- a/common/combat.c
+++ b/common/combat.c
@@ -569,13 +569,15 @@ int base_get_attack_power(const struct unit_type *punittype,
 int base_get_defense_power(const struct unit *punit)
 {
   const struct veteran_level *vlevel;
+  const struct unit_type *ptype;
 
   fc_assert_ret_val(punit != NULL, 0);
 
-  vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
+  ptype = unit_type_get(punit);
+  vlevel = utype_veteran_level(ptype, punit->veteran);
   fc_assert_ret_val(vlevel != NULL, 0);
 
-  return unit_type_get(punit)->defense_strength * POWER_FACTOR
+  return ptype->defense_strength * POWER_FACTOR
          * vlevel->power_fact / 100;
 }
 
diff --git a/common/unit.c b/common/unit.c
index c5f3e9d8b3..e9665ec6f2 100644
--- a/common/unit.c
+++ b/common/unit.c
@@ -495,18 +495,21 @@ bool can_unit_change_homecity(const struct civ_map *nmap,
 int get_activity_rate(const struct unit *punit)
 {
   const struct veteran_level *vlevel;
+  const struct unit_type *ptype;
+  int move_rate;
 
   fc_assert_ret_val(punit != NULL, 0);
 
-  vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
+  ptype = unit_type_get(punit);
+  vlevel = utype_veteran_level(ptype, punit->veteran);
   fc_assert_ret_val(vlevel != NULL, 0);
 
   /* The speed of the settler depends on its base move_rate, not on
    * the number of moves actually remaining or the adjusted move rate.
    * This means sea formers won't have their activity rate increased by
    * Magellan's, and it means injured units work just as fast as
-   * uninjured ones.  Note the value is never less than SINGLE_MOVE. */
-  int move_rate = unit_type_get(punit)->move_rate;
+   * uninjured ones. Note the value is never less than SINGLE_MOVE. */
+  move_rate = unit_type_get(punit)->move_rate;
 
   /* All settler actions are multiplied by ACTIVITY_FACTOR. */
   return ACTIVITY_FACTOR
diff --git a/common/unittype.c b/common/unittype.c
index c97ee5f6a3..dc7f176479 100644
--- a/common/unittype.c
+++ b/common/unittype.c
@@ -2577,6 +2577,19 @@ const struct veteran_system *
   return game.veteran;
 }
 
+/**********************************************************************//**
+  Return veteran level properties of given veterancy system
+  in given veterancy level.
+**************************************************************************/
+const struct veteran_level *
+  vsystem_veteran_level(const struct veteran_system *vsystem, int level)
+{
+  fc_assert_ret_val(vsystem->definitions != NULL, NULL);
+  fc_assert_ret_val(vsystem->levels > level, NULL);
+
+  return (vsystem->definitions + level);
+}
+
 /**********************************************************************//**
   Return veteran level properties of given unit in given veterancy level.
 **************************************************************************/
@@ -2586,10 +2599,8 @@ const struct veteran_level *
   const struct veteran_system *vsystem = utype_veteran_system(punittype);
 
   fc_assert_ret_val(vsystem != NULL, NULL);
-  fc_assert_ret_val(vsystem->definitions != NULL, NULL);
-  fc_assert_ret_val(vsystem->levels > level, NULL);
 
-  return (vsystem->definitions + level);
+  return vsystem_veteran_level(vsystem, level);
 }
 
 /**********************************************************************//**
@@ -2627,11 +2638,13 @@ int utype_veteran_levels(const struct unit_type *punittype)
 bool utype_veteran_has_power_bonus(const struct unit_type *punittype)
 {
   int i, initial_power_fact = utype_veteran_level(punittype, 0)->power_fact;
+
   for (i = 1; i < utype_veteran_levels(punittype); i++) {
     if (utype_veteran_level(punittype, i)->power_fact > initial_power_fact) {
       return TRUE;
     }
   }
+
   return FALSE;
 }
 
diff --git a/common/unittype.h b/common/unittype.h
index 3c61c97f5f..4854efaf17 100644
--- a/common/unittype.h
+++ b/common/unittype.h
@@ -790,6 +790,9 @@ int utype_buy_gold_cost(const struct city *pcity,
 const struct veteran_system *
   utype_veteran_system(const struct unit_type *punittype);
 int utype_veteran_levels(const struct unit_type *punittype);
+const struct veteran_level *
+  vsystem_veteran_level(const struct veteran_system *vsystem, int level)
+  fc__attribute((nonnull (1)));
 const struct veteran_level *
   utype_veteran_level(const struct unit_type *punittype, int level);
 const char *utype_veteran_name_translation(const struct unit_type *punittype,
diff --git a/server/diplomats.c b/server/diplomats.c
index 4724e751c3..8b366f3365 100644
--- a/server/diplomats.c
+++ b/server/diplomats.c
@@ -1986,7 +1986,9 @@ static bool diplomat_success_vs_defender(struct unit *pattacker,
       *vatt = utype_veteran_level(unit_type_get(pattacker), pattacker->veteran);
     const struct veteran_level
       *vdef = utype_veteran_level(unit_type_get(pdefender), pdefender->veteran);
+
     fc_assert_ret_val(vatt != NULL && vdef != NULL, FALSE);
+
     chance += vatt->power_fact - vdef->power_fact;
   }
 
@@ -2267,6 +2269,7 @@ static void diplomat_escape_full(struct player *pplayer,
 {
   int escapechance;
   struct city *spyhome;
+  const struct unit_type *dipltype = unit_type_get(pdiplomat);
 
   fc_assert(paction->actor.is_unit.moves_actor == MAK_ESCAPE);
 
@@ -2274,9 +2277,9 @@ static void diplomat_escape_full(struct player *pplayer,
    * unpromoted unit's power factor */
   {
     const struct veteran_level
-      *vunit = utype_veteran_level(unit_type_get(pdiplomat), pdiplomat->veteran);
+      *vunit = utype_veteran_level(dipltype, pdiplomat->veteran);
     const struct veteran_level
-      *vbase = utype_veteran_level(unit_type_get(pdiplomat), 0);
+      *vbase = utype_veteran_level(dipltype, 0);
 
     escapechance = game.server.diplchance
       + (vunit->power_fact - vbase->power_fact);
@@ -2287,7 +2290,7 @@ static void diplomat_escape_full(struct player *pplayer,
                               FALSE, FALSE, TRUE, FALSE, NULL);
 
   if (spyhome
-      && !utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))
+      && !utype_is_consumed_by_action(paction, dipltype)
       && (unit_has_type_flag(pdiplomat, UTYF_SUPERSPY)
           || fc_rand (100) < escapechance)) {
     /* Attacking Spy/Diplomat survives. */
@@ -2325,7 +2328,7 @@ static void diplomat_escape_full(struct player *pplayer,
     }
   }
 
-  if (!utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
+  if (!utype_is_consumed_by_action(paction, dipltype)) {
     /* The unit was caught, not spent. It must therefore be deleted by
      * hand. */
     wipe_unit(pdiplomat, ULR_CAUGHT, NULL);
diff --git a/server/edithand.c b/server/edithand.c
index 078201f908..32f678d601 100644
--- a/server/edithand.c
+++ b/server/edithand.c
@@ -658,7 +658,8 @@ void handle_edit_unit(struct connection *pc,
 
   if (packet->veteran != punit->veteran) {
     int v = packet->veteran;
-    if (!utype_veteran_level(putype, v)) {
+
+    if (utype_veteran_level(putype, v) == NULL) {
       notify_conn(pc->self, NULL, E_BAD_COMMAND, ftc_editor,
                   _("Invalid veteran level %d for unit %d (%s)."),
                   v, id, unit_link(punit));
diff --git a/server/unittools.c b/server/unittools.c
index de9a5de90e..c13399f80e 100644
--- a/server/unittools.c
+++ b/server/unittools.c
@@ -247,7 +247,7 @@ static bool maybe_become_veteran_real(struct unit *punit, int base_chance,
   fc_assert_ret_val(vsystem != NULL, FALSE);
   fc_assert_ret_val(vsystem->levels > punit->veteran, FALSE);
 
-  vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
+  vlevel = vsystem_veteran_level(vsystem, punit->veteran);
   fc_assert_ret_val(vlevel != NULL, FALSE);
 
   if (punit->veteran + 1 >= vsystem->levels
@@ -743,21 +743,17 @@ static bool total_activity_done(struct tile *ptile, enum unit_activity act,
 void notify_unit_experience(struct unit *punit)
 {
   const struct veteran_level *vlevel;
-#ifndef FREECIV_NDEBUG
   const struct veteran_system *vsystem;
-#endif
 
   if (!punit) {
     return;
   }
 
-#ifndef FREECIV_NDEBUG
   vsystem = utype_veteran_system(unit_type_get(punit));
   fc_assert_ret(vsystem != NULL);
   fc_assert_ret(vsystem->levels > punit->veteran);
-#endif /* FREECIV_NDEBUG */
 
-  vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
+  vlevel = vsystem_veteran_level(vsystem, punit->veteran);
   fc_assert_ret(vlevel != NULL);
 
   notify_player(unit_owner(punit), unit_tile(punit),
-- 
2.45.2

