Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] Re: (PR#13503) change unit types to use pointers
Home

[Freeciv-Dev] Re: (PR#13503) change unit types to use pointers

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#13503) change unit types to use pointers
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 20 Jul 2005 20:18:43 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13503 >

Jason Short wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=13503 >
> 
> This patch changes unit types to use pointers-to-structs instead of
> Unit_type_id values.  This is a large patch but the potential for bugs
> is pretty low.


Index: ai/advdiplomacy.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdiplomacy.c,v
retrieving revision 1.82
diff -p -u -r1.82 advdiplomacy.c
--- ai/advdiplomacy.c   4 Jul 2005 17:48:35 -0000       1.82
+++ ai/advdiplomacy.c   19 Jul 2005 03:41:42 -0000
@@ -674,7 +674,8 @@ static int ai_war_desire(struct player *
    * enemy expansionism */
   city_list_iterate(pplayer->cities, pcity) {
     if (pcity->is_building_unit 
-        && unit_type_flag(pcity->currently_building, F_CITIES)) {
+        && unit_type_flag(get_unit_type(pcity->currently_building),
+                         F_CITIES)) {
       kill_desire -= 1;
     }
   } city_list_iterate_end;
Index: ai/advdomestic.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advdomestic.c,v
retrieving revision 1.134
diff -p -u -r1.134 advdomestic.c
--- ai/advdomestic.c    9 Jul 2005 10:19:47 -0000       1.134
+++ ai/advdomestic.c    19 Jul 2005 03:41:42 -0000
@@ -57,7 +57,7 @@ static void ai_choose_help_wonder(struct
    * on this continent */
   int caravans = 0;
   /* The type of the caravan */
-  Unit_type_id unit_type;
+  struct unit_type *unit_type;
   struct city *wonder_city = find_city_by_id(ai->wonder_city);
 
   if (num_role_units(F_HELP_WONDER) == 0) {
@@ -85,7 +85,8 @@ static void ai_choose_help_wonder(struct
   /* Count caravans being built */
   city_list_iterate(pplayer->cities, acity) {
     if (acity->is_building_unit
-        && unit_type_flag(acity->currently_building, F_HELP_WONDER)
+        && unit_type_flag(get_unit_type(acity->currently_building),
+                         F_HELP_WONDER)
         && tile_get_continent(acity->tile) == continent) {
       caravans++;
     }
@@ -93,7 +94,7 @@ static void ai_choose_help_wonder(struct
 
   unit_type = best_role_unit(pcity, F_HELP_WONDER);
 
-  if (unit_type == U_LAST) {
+  if (!unit_type) {
     /* We cannot build such units yet
      * but we will consider it to stimulate science */
     unit_type = get_role_unit(F_HELP_WONDER, 0);
@@ -105,7 +106,9 @@ static void ai_choose_help_wonder(struct
     Impr_type_id wonder = wonder_city->currently_building;
     int want = wonder_city->ai.building_want[wonder];
     int dist = pcity->ai.distance_to_wonder_city /
-               get_unit_type(unit_type)->move_rate;
+               unit_type->move_rate;
+
+    assert(!wonder_city->is_building_unit);
 
     want /= MAX(dist, 1);
     CITY_LOG(LOG_DEBUG, pcity, "want %s to help wonder in %s with %d", 
@@ -117,7 +120,7 @@ static void ai_choose_help_wonder(struct
       if (can_build_unit(pcity, unit_type)) {
         choice->want = want;
         choice->type = CT_NONMIL;
-        choice->choice = unit_type;
+        choice->choice = unit_type->index;
       } else {
         CITY_LOG(LOG_DEBUG, pcity, "would but could not build %s, bumped reqs",
                  unit_name(unit_type));
@@ -138,17 +141,16 @@ void domestic_advisor_choose_build(struc
   /* Government of the player */
   struct government *gov = get_gov_pplayer(pplayer);
   /* Unit type with certain role */
-  Unit_type_id unit_type;
+  struct unit_type *unit_type;
 
   init_choice(choice);
 
   /* Find out desire for settlers (terrain improvers) */
   unit_type = best_role_unit(pcity, F_SETTLERS);
 
-  if (unit_type != U_LAST
-      && (pcity->id != ai->wonder_city
-          || get_unit_type(unit_type)->pop_cost == 0)
-      && pcity->surplus[O_FOOD] > utype_upkeep_cost(get_unit_type(unit_type),
+  if (!unit_type
+      && (pcity->id != ai->wonder_city || unit_type->pop_cost == 0)
+      && pcity->surplus[O_FOOD] > utype_upkeep_cost(unit_type,
                                                    pplayer, gov, O_FOOD)) {
     /* The settler want is calculated in settlers.c called from
      * ai_manage_cities.  The expand value is the % that the AI should
@@ -177,10 +179,10 @@ void domestic_advisor_choose_build(struc
   /* Basically, copied from above and adjusted. -- jjm */
   unit_type = best_role_unit(pcity, F_CITIES);
 
-  if (unit_type != U_LAST
+  if (!unit_type
       && (pcity->id != ai->wonder_city
-          || get_unit_type(unit_type)->pop_cost == 0)
-      && pcity->surplus[O_FOOD] >= utype_upkeep_cost(get_unit_type(unit_type),
+          || unit_type->pop_cost == 0)
+      && pcity->surplus[O_FOOD] >= utype_upkeep_cost(unit_type,
                                                     pplayer, gov, O_FOOD)) {
     /* founder_want calculated in settlers.c, called from ai_manage_cities(). 
*/
     int want = pcity->ai.founder_want;
@@ -205,12 +207,13 @@ void domestic_advisor_choose_build(struc
       /* We might need boats even if there are boats free,
        * if they are blockaded or in inland seas. */
       struct ai_data *ai = ai_data_get(pplayer);
+
       CITY_LOG(LOG_DEBUG, pcity, "desires founders with passion %d and asks"
               " for a new boat (%d of %d free)",
               want, ai->stats.available_boats, ai->stats.boats);
       choice->want = 0 - want;
       choice->type = CT_NONMIL;
-      choice->choice = unit_type; /* default */
+      choice->choice = unit_type->index; /* default */
       choice->need_boat = TRUE;
       ai_choose_role_unit(pplayer, pcity, choice, L_FERRYBOAT, -want);
     }
Index: ai/advmilitary.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v
retrieving revision 1.192
diff -p -u -r1.192 advmilitary.c
--- ai/advmilitary.c    30 Apr 2005 17:09:24 -0000      1.192
+++ ai/advmilitary.c    19 Jul 2005 03:41:43 -0000
@@ -49,25 +49,31 @@ static unsigned int assess_danger(struct
 /**************************************************************************
   Choose the best unit the city can build to defend against attacker v.
 **************************************************************************/
-Unit_type_id ai_choose_defender_versus(struct city *pcity, Unit_type_id v)
+struct unit_type *ai_choose_defender_versus(struct city *pcity,
+                                           const struct unit_type *v)
 {
-  Unit_type_id bestid = 0; /* ??? Zero is legal value! (Settlers by default) */
-  int j, m;
+  struct unit_type *bestunit = NULL;
   int best = 0;
 
-  simple_ai_unit_type_iterate(i) {
-    m = unit_types[i].move_type;
-    if (can_build_unit(pcity, i) && (m == LAND_MOVING || m == SEA_MOVING)) {
-      j = get_virtual_defense_power(v, i, pcity->tile, FALSE, FALSE);
-      if (j > best || (j == best && unit_build_shield_cost(i) <=
-                                    unit_build_shield_cost(bestid))) {
-        best = j;
-        bestid = i;
+  simple_ai_unit_type_iterate(punittype) {
+    const int move_type = punittype->move_type;
+
+    if (can_build_unit(pcity, punittype)
+       && (move_type == LAND_MOVING || move_type == SEA_MOVING)) {
+      const int defense = get_virtual_defense_power(v, punittype,
+                                                   pcity->tile,
+                                                   FALSE, FALSE);
+
+      if (defense > best || (defense == best
+                            && unit_build_shield_cost(punittype) <=
+                            unit_build_shield_cost(bestunit))) {
+        best = defense;
+        bestunit = punittype;
       }
     }
   } simple_ai_unit_type_iterate_end;
 
-  return bestid;
+  return bestunit;
 }
 
 /********************************************************************** 
@@ -89,28 +95,28 @@ void military_advisor_choose_tech(struct
   desirability without regard to cost, unless costs are equal. This is
   very wrong. FIXME, use amortize on time to build.
 **************************************************************************/
-static Unit_type_id ai_choose_attacker(struct city *pcity,
-                                       enum unit_move_type which)
+static struct unit_type *ai_choose_attacker(struct city *pcity,
+                                           enum unit_move_type which)
 {
-  Unit_type_id bestid = -1;
+  struct unit_type *bestid = NULL;
   int best = -1;
   int cur;
 
-  simple_ai_unit_type_iterate(i) {
-    cur = ai_unit_attack_desirability(i);
-    if (which == unit_types[i].move_type) {
-      if (can_build_unit(pcity, i)
+  simple_ai_unit_type_iterate(punittype) {
+    cur = ai_unit_attack_desirability(punittype);
+    if (which == punittype->move_type) {
+      if (can_build_unit(pcity, punittype)
           && (cur > best
               || (cur == best
-                  && unit_build_shield_cost(i)
+                  && unit_build_shield_cost(punittype)
                      <= unit_build_shield_cost(bestid)))) {
         best = cur;
-        bestid = i;
+        bestid = punittype;
       }
     }
   } simple_ai_unit_type_iterate_end;
 
-  return (best <= 0 ? -1 : bestid);
+  return bestid;
 }
 
 /**************************************************************************
@@ -121,36 +127,39 @@ static Unit_type_id ai_choose_attacker(s
   We should only be passed with L_DEFEND_GOOD role for now, since this
   is the only role being considered worthy of bodyguarding in findjob.
 **************************************************************************/
-static Unit_type_id ai_choose_bodyguard(struct city *pcity,
-                                        enum unit_move_type move_type,
-                                        enum unit_role_id role)
+static struct unit_type *ai_choose_bodyguard(struct city *pcity,
+                                            enum unit_move_type move_type,
+                                            enum unit_role_id role)
 {
-  Unit_type_id bestid = -1;
-  int j, best = 0;
+  struct unit_type *bestid = NULL;
+  int best = 0;
 
-  simple_ai_unit_type_iterate(i) {
+  simple_ai_unit_type_iterate(punittype) {
     /* Only consider units of given role, or any if L_LAST */
     if (role != L_LAST) {
-      if (!unit_has_role(i, role)) {
+      if (!unit_has_role(punittype, role)) {
         continue;
       }
     }
 
     /* Only consider units of same move type */
-    if (unit_types[i].move_type != move_type) {
+    if (punittype->move_type != move_type) {
       continue;
     }
 
     /* Now find best */
-    if (can_build_unit(pcity, i)) {
-      j = ai_unit_defence_desirability(i);
-      if (j > best || (j == best && unit_build_shield_cost(i) <=
-                               unit_build_shield_cost(bestid))) {
-        best = j;
-        bestid = i;
+    if (can_build_unit(pcity, punittype)) {
+      const int desire = ai_unit_defence_desirability(punittype);
+
+      if (desire > best
+         || (desire == best && unit_build_shield_cost(punittype) <=
+             unit_build_shield_cost(bestid))) {
+        best = desire;
+        bestid = punittype;
       }
     }
   } simple_ai_unit_type_iterate_end;
+
   return bestid;
 }
 
@@ -600,27 +609,27 @@ static unsigned int assess_danger(struct
   How much we would want that unit to defend a city? (Do not use this 
   function to find bodyguards for ships or air units.)
 **************************************************************************/
-int ai_unit_defence_desirability(Unit_type_id i)
+int ai_unit_defence_desirability(const struct unit_type *punittype)
 {
-  int desire = get_unit_type(i)->hp;
-  int attack = get_unit_type(i)->attack_strength;
-  int defense = get_unit_type(i)->defense_strength;
+  int desire = punittype->hp;
+  int attack = punittype->attack_strength;
+  int defense = punittype->defense_strength;
 
   /* Sea and helicopters often have their firepower set to 1 when
    * defending. We can't have such units as defenders. */
-  if (unit_types[i].move_type != SEA_MOVING
-      && unit_types[i].move_type != HELI_MOVING) {
+  if (punittype->move_type != SEA_MOVING
+      && punittype->move_type != HELI_MOVING) {
     /* Sea units get 1 firepower in Pearl Harbour,
      * and helicopters very bad against air units */
-    desire *= get_unit_type(i)->firepower;
+    desire *= punittype->firepower;
   }
   desire *= defense;
-  desire += get_unit_type(i)->move_rate / SINGLE_MOVE;
+  desire += punittype->move_rate / SINGLE_MOVE;
   desire += attack;
-  if (unit_type_flag(i, F_PIKEMEN)) {
+  if (unit_type_flag(punittype, F_PIKEMEN)) {
     desire += desire / 2;
   }
-  if (unit_type_flag(i, F_GAMELOSS)) {
+  if (unit_type_flag(punittype, F_GAMELOSS)) {
     desire /= 10; /* but might actually be worth it */
   }
   return desire;
@@ -629,32 +638,32 @@ int ai_unit_defence_desirability(Unit_ty
 /************************************************************************** 
   How much we would want that unit to attack with?
 **************************************************************************/
-int ai_unit_attack_desirability(Unit_type_id i)
+int ai_unit_attack_desirability(const struct unit_type *punittype)
 {
-  int desire = get_unit_type(i)->hp;
-  int attack = get_unit_type(i)->attack_strength;
-  int defense = get_unit_type(i)->defense_strength;
+  int desire = punittype->hp;
+  int attack = punittype->attack_strength;
+  int defense = punittype->defense_strength;
 
-  desire *= get_unit_type(i)->move_rate;
-  desire *= get_unit_type(i)->firepower;
+  desire *= punittype->move_rate;
+  desire *= punittype->firepower;
   desire *= attack;
   desire += defense;
-  if (unit_type_flag(i, F_IGTER)) {
+  if (unit_type_flag(punittype, F_IGTER)) {
     desire += desire / 2;
   }
-  if (unit_type_flag(i, F_GAMELOSS)) {
+  if (unit_type_flag(punittype, F_GAMELOSS)) {
     desire /= 10; /* but might actually be worth it */
   }
-  if (unit_type_flag(i, F_CITYBUSTER)) {
+  if (unit_type_flag(punittype, F_CITYBUSTER)) {
     desire += desire / 2;
   }
-  if (unit_type_flag(i, F_IGTIRED)) {
+  if (unit_type_flag(punittype, F_IGTIRED)) {
     desire += desire / 4;
   }
-  if (unit_type_flag(i, F_MARINES)) {
+  if (unit_type_flag(punittype, F_MARINES)) {
     desire += desire / 4;
   }
-  if (unit_type_flag(i, F_IGWALL)) {
+  if (unit_type_flag(punittype, F_IGWALL)) {
     desire += desire / 4;
   }
   return desire;
@@ -673,82 +682,82 @@ static void process_defender_want(struct
   int tech_desire[U_LAST];
   /* Our favourite unit. */
   int best = -1;
-  Unit_type_id best_unit_type = 0; /* zero is settler but not a problem */
+  struct unit_type *best_unit_type = NULL;
 
   memset(tech_desire, 0, sizeof(tech_desire));
   
-  simple_ai_unit_type_iterate (unit_type) {
-      int move_type = unit_types[unit_type].move_type;
-      int desire; /* How much we want the unit? */
-
-      /* Only consider proper defenders - otherwise waste CPU and
-       * bump tech want needlessly. */
-      if (!unit_has_role(unit_type, L_DEFEND_GOOD)
-          && !unit_has_role(unit_type, L_DEFEND_OK)) {
-        continue;
-      }
+  simple_ai_unit_type_iterate(punittype) {
+    int move_type = punittype->move_type;
+    int desire; /* How much we want the unit? */
+
+    /* Only consider proper defenders - otherwise waste CPU and
+     * bump tech want needlessly. */
+    if (!unit_has_role(punittype, L_DEFEND_GOOD)
+       && !unit_has_role(punittype, L_DEFEND_OK)) {
+      continue;
+    }
 
-      desire = ai_unit_defence_desirability(unit_type);
+    desire = ai_unit_defence_desirability(punittype);
 
-      if (!unit_has_role(unit_type, L_DEFEND_OK)) {
-        desire /= 2; /* not good, just ok */
-      }
+    if (!unit_has_role(punittype, L_DEFEND_OK)) {
+      desire /= 2; /* not good, just ok */
+    }
 
-      if (unit_type_flag(unit_type, F_FIELDUNIT)) {
-        /* Causes unhappiness even when in defense, so not a good
-         * idea for a defender, unless it is _really_ good */
-       desire /= 2;
-      }      
+    if (unit_type_flag(punittype, F_FIELDUNIT)) {
+      /* Causes unhappiness even when in defense, so not a good
+       * idea for a defender, unless it is _really_ good */
+      desire /= 2;
+    }      
 
-      desire /= POWER_DIVIDER/2; /* Good enough, no rounding errors. */
-      desire *= desire;
-      
-      if (can_build_unit(pcity, unit_type)) {
-        /* We can build the unit now... */
-      
-        if (walls && move_type == LAND_MOVING) {
-          desire *= pcity->ai.wallvalue;
-          /* TODO: More use of POWER_FACTOR ! */
-          desire /= POWER_FACTOR;
-        }
-        
-        if ((desire > best ||
-             (desire == best && unit_build_shield_cost(unit_type) <=
-                                unit_build_shield_cost(best_unit_type)))
-            && unit_build_shield_cost(unit_type) <= pcity->shield_stock + 40) {
-          best = desire;
-          best_unit_type = unit_type;
-        }
-      } else if (can_eventually_build_unit(pcity, unit_type)) {
-        /* We first need to develop the tech required by the unit... */
+    desire /= POWER_DIVIDER/2; /* Good enough, no rounding errors. */
+    desire *= desire;
 
-        /* Cost (shield equivalent) of gaining these techs. */
-        /* FIXME? Katvrr advises that this should be weighted more heavily in
-         * big danger. */
-        int tech_cost = total_bulbs_required_for_goal(pplayer,
-                          unit_types[unit_type].tech_requirement) / 4
-                        / city_list_size(pplayer->cities);
-        
-        /* Contrary to the above, we don't care if walls are actually built 
-         * - we're looking into the future now. */
-        if (move_type == LAND_MOVING) {
-          desire *= pcity->ai.wallvalue;
-          desire /= POWER_FACTOR;
-        }
+    if (can_build_unit(pcity, punittype)) {
+      /* We can build the unit now... */
+
+      if (walls && move_type == LAND_MOVING) {
+       desire *= pcity->ai.wallvalue;
+       /* TODO: More use of POWER_FACTOR ! */
+       desire /= POWER_FACTOR;
+      }
 
-        /* Yes, there's some similarity with kill_desire(). */
-        /* TODO: Explain what shield cost has to do with tech want. */
-        tech_desire[unit_type] = (desire * danger /
-                                 (unit_build_shield_cost(unit_type)
-                                  + tech_cost));
+      if ((desire > best ||
+          (desire == best && unit_build_shield_cost(punittype) <=
+           unit_build_shield_cost(best_unit_type)))
+         && unit_build_shield_cost(punittype) <= pcity->shield_stock + 40) {
+       best = desire;
+       best_unit_type = punittype;
       }
+    } else if (can_eventually_build_unit(pcity, punittype)) {
+      /* We first need to develop the tech required by the unit... */
+
+      /* Cost (shield equivalent) of gaining these techs. */
+      /* FIXME? Katvrr advises that this should be weighted more heavily in
+       * big danger. */
+      int tech_cost = total_bulbs_required_for_goal(pplayer,
+                                       punittype->tech_requirement) / 4
+       / city_list_size(pplayer->cities);
+        
+      /* Contrary to the above, we don't care if walls are actually built 
+       * - we're looking into the future now. */
+      if (move_type == LAND_MOVING) {
+       desire *= pcity->ai.wallvalue;
+       desire /= POWER_FACTOR;
+      }
+
+      /* Yes, there's some similarity with kill_desire(). */
+      /* TODO: Explain what shield cost has to do with tech want. */
+      tech_desire[punittype->index] = (desire * danger /
+                                      (unit_build_shield_cost(punittype)
+                                       + tech_cost));
+    }
   } simple_ai_unit_type_iterate_end;
 
   if (best == -1) {
     CITY_LOG(LOG_DEBUG, pcity, "Ooops - we cannot build any defender!");
   }
 
-  if (!walls && unit_types[best_unit_type].move_type == LAND_MOVING) {
+  if (!walls && best_unit_type->move_type == LAND_MOVING) {
     best *= pcity->ai.wallvalue;
     best /= POWER_FACTOR;
   }
@@ -756,21 +765,21 @@ static void process_defender_want(struct
   if (best <= 0) best = 1; /* Avoid division by zero below. */
 
   /* Update tech_want for appropriate techs for units we want to build. */
-  simple_ai_unit_type_iterate (unit_type) {
-    if (tech_desire[unit_type] > 0) {
-      Tech_type_id tech_req = unit_types[unit_type].tech_requirement;
+  simple_ai_unit_type_iterate(punittype) {
+    if (tech_desire[punittype->index] > 0) {
+      Tech_type_id tech_req = punittype->tech_requirement;
       /* TODO: Document or fix the algorithm below. I have no idea why
        * it is written this way, and the results seem strange to me. - Per */
-      int desire = tech_desire[unit_type]
+      int desire = tech_desire[punittype->index]
                    * unit_build_shield_cost(best_unit_type) / best;
       
       pplayer->ai.tech_want[tech_req] += desire;
       TECH_LOG(LOG_DEBUG, pplayer, tech_req, "+ %d for %s to defend %s",
-               desire, unit_name(unit_type), pcity->name);
+               desire, unit_name(punittype), pcity->name);
     }
   } simple_ai_unit_type_iterate_end;
   
-  choice->choice = best_unit_type;
+  choice->choice = best_unit_type->index;
   choice->want = danger;
   choice->type = CT_DEFENDER;
   return;
@@ -794,10 +803,12 @@ static void process_defender_want(struct
   consider units of the same move_type as best_choice
 **************************************************************************/
 static void process_attacker_want(struct city *pcity,
-                                  int value, Unit_type_id victim_unit_type,
+                                  int value,
+                                 struct unit_type *victim_unit_type,
                                   int veteran, struct tile *ptile,
                                   struct ai_choice *best_choice,
-                                  struct unit *boat, Unit_type_id boattype)
+                                  struct unit *boat,
+                                 struct unit_type *boattype)
 {
   struct player *pplayer = city_owner(pcity);
   /* The enemy city.  acity == NULL means stray enemy unit */
@@ -811,7 +822,7 @@ static void process_attacker_want(struct
 
   assert(orig_move_type == SEA_MOVING || orig_move_type == LAND_MOVING);
 
-  if (orig_move_type == LAND_MOVING && !boat && boattype < U_LAST) {
+  if (orig_move_type == LAND_MOVING && !boat && boattype) {
     /* cost of ferry */
     needferry = unit_build_shield_cost(boattype);
   }
@@ -822,9 +833,9 @@ static void process_attacker_want(struct
     victim_count += unit_list_size(ptile->units);
   }
 
-  simple_ai_unit_type_iterate (unit_type) {
-    Tech_type_id tech_req = unit_types[unit_type].tech_requirement;
-    int move_type = unit_types[unit_type].move_type;
+  simple_ai_unit_type_iterate(punittype) {
+    Tech_type_id tech_req = punittype->tech_requirement;
+    int move_type = punittype->move_type;
     int tech_dist;
     
     if (tech_req != A_LAST) {
@@ -836,10 +847,10 @@ static void process_attacker_want(struct
     if ((move_type == LAND_MOVING || (move_type == SEA_MOVING && shore))
         && tech_req != A_LAST
         && (tech_dist > 0 
-            || unit_types[unit_type].obsoleted_by == U_NOT_OBSOLETED
+            || punittype->obsoleted_by == U_NOT_OBSOLETED
             || !can_build_unit_direct(pcity, 
-                                      unit_types[unit_type].obsoleted_by))
-        && unit_types[unit_type].attack_strength > 0 /* or we'll get SIGFPE */
+                                      punittype->obsoleted_by))
+        && punittype->attack_strength > 0 /* or we'll get SIGFPE */
         && move_type == orig_move_type) {
       /* TODO: Case for Airport. -- Raahul */
       int will_be_veteran = (move_type == LAND_MOVING
@@ -848,17 +859,17 @@ static void process_attacker_want(struct
       /* FIXME? Katvrr advises that this should be weighted more heavily in big
        * danger. */
       int tech_cost = total_bulbs_required_for_goal(pplayer,
-                        unit_types[unit_type].tech_requirement) / 4
+                        punittype->tech_requirement) / 4
                       / city_list_size(pplayer->cities);
-      int move_rate = unit_types[unit_type].move_rate;
+      int move_rate = punittype->move_rate;
       int move_time;
-      int bcost_balanced = build_cost_balanced(unit_type);
+      int bcost_balanced = build_cost_balanced(punittype);
       /* See description of kill_desire() for info about this variables. */
-      int bcost = unit_build_shield_cost(unit_type);
+      int bcost = unit_build_shield_cost(punittype);
       int vuln;
-      int attack = unittype_att_rating(unit_type, will_be_veteran,
+      int attack = unittype_att_rating(punittype, will_be_veteran,
                                        SINGLE_MOVE,
-                                       unit_types[unit_type].hp);
+                                       punittype->hp);
       /* Values to be computed */
       int desire, want;
       
@@ -873,24 +884,24 @@ static void process_attacker_want(struct
       
       attack *= attack;
 
-      if (unit_type_flag(unit_type, F_IGTER)) {
+      if (unit_type_flag(punittype, F_IGTER)) {
         /* TODO: Use something like IGTER_MOVE_COST. -- Raahul */
         move_rate *= SINGLE_MOVE;
       }
 
       /* Set the move_time appropriatelly. */
       if (acity) {
-        move_time = turns_to_enemy_city(unit_type, acity, move_rate,
-                                        (boattype < U_LAST), boat, boattype);
+        move_time = turns_to_enemy_city(punittype, acity, move_rate,
+                                        (boattype != NULL), boat, boattype);
       } else {
         /* Target is in the field */
-        move_time = turns_to_enemy_unit(unit_type, move_rate, ptile,
+        move_time = turns_to_enemy_unit(punittype, move_rate, ptile,
                                         victim_unit_type);
       }
 
       /* Estimate strength of the enemy. */
       
-      vuln = unittype_def_rating_sq(unit_type, victim_unit_type,
+      vuln = unittype_def_rating_sq(punittype, victim_unit_type,
                                     ptile, FALSE, veteran);
 
       /* Not bothering to s/!vuln/!pdef/ here for the time being. -- Syela
@@ -937,31 +948,32 @@ static void process_attacker_want(struct
           /* This is a future unit, tell the scientist how much we need it */
           pplayer->ai.tech_want[tech_req] += want;
           TECH_LOG(LOG_DEBUG, pplayer, tech_req, "+ %d for %s vs %s(%d,%d)",
-                   want, unit_name(unit_type), (acity ? acity->name : 
+                   want, unit_name(punittype), (acity ? acity->name : 
                    unit_name(victim_unit_type)), TILE_XY(ptile));
         } else if (want > best_choice->want) {
-          if (can_build_unit(pcity, unit_type)) {
+          if (can_build_unit(pcity, punittype)) {
             /* This is a real unit and we really want it */
 
             CITY_LOG(LOG_DEBUG, pcity, "overriding %s(%d) with %s(%d)"
                      " [attack=%d,value=%d,move_time=%d,vuln=%d,bcost=%d]",
-                     unit_name(best_choice->choice), best_choice->want,
-                     unit_name(unit_type), want, attack, value, move_time,
+                     unit_name(get_unit_type(best_choice->choice)),
+                    best_choice->want,
+                     unit_name(punittype), want, attack, value, move_time,
                      vuln, bcost);
 
-            best_choice->choice = unit_type;
+            best_choice->choice = punittype->index;
             best_choice->want = want;
             best_choice->type = CT_ATTACKER;
           } else if (can_build_improvement(pcity,
-                            get_unit_type(unit_type)->impr_requirement)) {
+                                          punittype->impr_requirement)) {
            /* Building this unit requires a specific type of improvement.
             * So we build this improvement instead.  This may not be the
             * best behavior. */
-            Impr_type_id id = get_unit_type(unit_type)->impr_requirement;
+            Impr_type_id id = punittype->impr_requirement;
 
             CITY_LOG(LOG_DEBUG, pcity, "building %s to build %s",
                      get_improvement_type(id)->name,
-                     get_unit_type(unit_type)->name);
+                     punittype->name);
             best_choice->choice = id;
             best_choice->want = want;
             best_choice->type = CT_BUILDING;
@@ -993,7 +1005,7 @@ static void kill_something_with(struct p
   /* Benefit from fighting the target */
   int benefit;
   /* Enemy defender type */
-  Unit_type_id def_type;
+  struct unit_type *def_type;
   /* Target coordinates */
   struct tile *ptile;
   /* Our transport */
@@ -1003,14 +1015,14 @@ static void kill_something_with(struct p
   /* Defender of the target city/tile */
   struct unit *pdef; 
   /* Type of the boat (real or a future one) */
-  Unit_type_id boattype = U_LAST;
+  struct unit_type *boattype = NULL;
   bool go_by_boat;
   /* Is the defender veteran? */
   int def_vet;
   struct ai_choice best_choice;
 
   init_choice(&best_choice);
-  best_choice.choice = myunit->type;
+  best_choice.choice = myunit->type->index;
   best_choice.type = CT_ATTACKER;
   best_choice.want = choice->want;
 
@@ -1044,7 +1056,7 @@ static void kill_something_with(struct p
   
   if (acity) {
     /* Our move rate */
-    int move_rate = unit_types[myunit->type].move_rate;
+    int move_rate = myunit->type->move_rate;
     /* Distance to target (in turns) */
     int move_time;
     /* Rating of enemy defender */
@@ -1068,13 +1080,13 @@ static void kill_something_with(struct p
         boattype = ferryboat->type;
       } else {
         boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
-        if (boattype == U_LAST) {
+        if (!boattype) {
           /* We pretend that we can have the simplest boat --
           * to stimulate tech */
           boattype = get_role_unit(L_FERRYBOAT, 0);
         }
       }
-      assert(SEA_MOVING == unit_types[boattype].move_type);
+      assert(SEA_MOVING == boattype->move_type);
 
       go_by_boat = !(WARMAP_COST(ptile) <= (MIN(6, move_rate) * THRESHOLD)
                      && goto_is_sane(myunit, acity->tile, TRUE));
@@ -1133,7 +1145,7 @@ static void kill_something_with(struct p
   
   if (!go_by_boat) {
     process_attacker_want(pcity, benefit, def_type, def_vet, ptile, 
-                          &best_choice, NULL, U_LAST);
+                          &best_choice, NULL, NULL);
   } else { 
     /* Attract a boat to our city or retain the one that's already here */
     assert(is_ground_unit(myunit));
@@ -1171,7 +1183,7 @@ static void kill_something_with(struct p
     if want is 0 this advisor doesn't want anything
 ***********************************************************************/
 static void ai_unit_consider_bodyguard(struct city *pcity,
-                                       Unit_type_id unit_type,
+                                       struct unit_type *punittype,
                                        struct ai_choice *choice)
 {
   struct unit *virtualunit;
@@ -1179,14 +1191,15 @@ static void ai_unit_consider_bodyguard(s
   struct unit *aunit = NULL;
   struct city *acity = NULL;
 
-  virtualunit = create_unit_virtual(pplayer, pcity, unit_type,
-                                    do_make_unit_veteran(pcity, unit_type));
+  virtualunit = create_unit_virtual(pplayer, pcity, punittype,
+                                    do_make_unit_veteran(pcity, punittype));
 
   if (choice->want < 100) {
-    int want = look_for_charge(pplayer, virtualunit, &aunit, &acity);
+    const int want = look_for_charge(pplayer, virtualunit, &aunit, &acity);
+
     if (want > choice->want) {
       choice->want = want;
-      choice->choice = unit_type;
+      choice->choice = punittype->index;
       choice->type = CT_DEFENDER;
     }
   }
@@ -1209,9 +1222,11 @@ static void adjust_ai_unit_choice(struct
   Impr_type_id id;
 
   /* Sanity */
-  if (!is_unit_choice_type(choice->type)) return;
-  if (unit_type_flag(choice->choice, F_NONMIL)) return;
-  if (do_make_unit_veteran(pcity, choice->choice)) return;
+  if (!is_unit_choice_type(choice->type)
+      || unit_type_flag(get_unit_type(choice->choice), F_NONMIL)
+      || do_make_unit_veteran(pcity, get_unit_type(choice->choice))) {
+    return;
+  }
 
   move_type = get_unit_type(choice->choice)->move_type;
   switch(move_type) {
@@ -1251,7 +1266,7 @@ void military_advisor_choose_build(struc
                                   struct ai_choice *choice)
 {
   struct ai_data *ai = ai_data_get(pplayer);
-  Unit_type_id unit_type;
+  struct unit_type *punittype;
   unsigned int our_def, urgency;
   struct tile *ptile = pcity->tile;
   struct unit *virtualunit;
@@ -1384,9 +1399,9 @@ void military_advisor_choose_build(struc
   }
 
   /* Consider making a land bodyguard */
-  unit_type = ai_choose_bodyguard(pcity, LAND_MOVING, L_DEFEND_GOOD);
-  if (unit_type >= 0) {
-    ai_unit_consider_bodyguard(pcity, unit_type, choice);
+  punittype = ai_choose_bodyguard(pcity, LAND_MOVING, L_DEFEND_GOOD);
+  if (punittype >= 0) {
+    ai_unit_consider_bodyguard(pcity, punittype, choice);
   }
 
   /* If we are in severe danger, don't consider attackers. This is probably
@@ -1402,9 +1417,9 @@ void military_advisor_choose_build(struc
   ai_choose_diplomat_offensive(pplayer, pcity, choice);
 
   /* Consider making a sea bodyguard */
-  unit_type = ai_choose_bodyguard(pcity, SEA_MOVING, L_DEFEND_GOOD);
-  if (unit_type >= 0) {
-    ai_unit_consider_bodyguard(pcity, unit_type, choice);
+  punittype = ai_choose_bodyguard(pcity, SEA_MOVING, L_DEFEND_GOOD);
+  if (punittype >= 0) {
+    ai_unit_consider_bodyguard(pcity, punittype, choice);
   }
 
   /* Consider making an airplane */
@@ -1412,10 +1427,10 @@ void military_advisor_choose_build(struc
 
   /* Check if we want a sailing attacker. Have to put sailing first
      before we mung the seamap */
-  unit_type = ai_choose_attacker(pcity, SEA_MOVING);
-  if (unit_type >= 0) {
-    virtualunit = create_unit_virtual(pplayer, pcity, unit_type,
-                                      do_make_unit_veteran(pcity, unit_type));
+  punittype = ai_choose_attacker(pcity, SEA_MOVING);
+  if (punittype >= 0) {
+    virtualunit = create_unit_virtual(pplayer, pcity, punittype,
+                                      do_make_unit_veteran(pcity, punittype));
     kill_something_with(pplayer, pcity, virtualunit, choice);
     destroy_unit_virtual(virtualunit);
   }
@@ -1423,9 +1438,9 @@ void military_advisor_choose_build(struc
   /* Consider a land attacker or a ferried land attacker
    * (in which case, we might want a ferry before an attacker)
    */
-  unit_type = ai_choose_attacker(pcity, LAND_MOVING);
-  if (unit_type >= 0) {
-    virtualunit = create_unit_virtual(pplayer, pcity, unit_type, 1);
+  punittype = ai_choose_attacker(pcity, LAND_MOVING);
+  if (punittype >= 0) {
+    virtualunit = create_unit_virtual(pplayer, pcity, punittype, 1);
     kill_something_with(pplayer, pcity, virtualunit, choice);
     destroy_unit_virtual(virtualunit);
   }
Index: ai/advmilitary.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.h,v
retrieving revision 1.22
diff -p -u -r1.22 advmilitary.h
--- ai/advmilitary.h    30 Apr 2005 17:09:24 -0000      1.22
+++ ai/advmilitary.h    19 Jul 2005 03:41:43 -0000
@@ -18,7 +18,8 @@
 
 struct ai_choice;
 
-Unit_type_id ai_choose_defender_versus(struct city *pcity, Unit_type_id v);
+struct unit_type *ai_choose_defender_versus(struct city *pcity,
+                                           const struct unit_type *versus);
 void military_advisor_choose_tech(struct player *pplayer,
                                  struct ai_choice *choice);
 void  military_advisor_choose_build(struct player *pplayer, struct city *pcity,
@@ -27,7 +28,7 @@ void assess_danger_player(struct player 
 int assess_defense_quadratic(struct city *pcity);
 int assess_defense_unit(struct city *pcity, struct unit *punit, bool igwall);
 int assess_defense(struct city *pcity);
-int ai_unit_defence_desirability(Unit_type_id i);
-int ai_unit_attack_desirability(Unit_type_id i);
+int ai_unit_defence_desirability(const struct unit_type *punittype);
+int ai_unit_attack_desirability(const struct unit_type *punittype);
 
 #endif  /* FC__ADVMILITARY_H */
Index: ai/aiair.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiair.c,v
retrieving revision 1.32
diff -p -u -r1.32 aiair.c
--- ai/aiair.c  5 May 2005 18:32:46 -0000       1.32
+++ ai/aiair.c  19 Jul 2005 03:41:43 -0000
@@ -391,24 +391,27 @@ bool ai_choose_attacker_air(struct playe
     return FALSE;
   }
 
-  unit_type_iterate(u_type) {
-    if (get_unit_type(u_type)->move_type != AIR_MOVING) continue;
-    if (can_build_unit(pcity, u_type)) {
+  unit_type_iterate(punittype) {
+    if (punittype->move_type != AIR_MOVING) {
+      continue;
+    }
+    if (can_build_unit(pcity, punittype)) {
       struct unit *virtual_unit = 
-       create_unit_virtual(pplayer, pcity, u_type, 
-                            do_make_unit_veteran(pcity, u_type));
+       create_unit_virtual(pplayer, pcity, punittype, 
+                            do_make_unit_veteran(pcity, punittype));
       int profit = find_something_to_bomb(virtual_unit, pcity->tile);
+
       if (profit > choice->want){
        /* Update choice */
        choice->want = profit;
-       choice->choice = u_type;
+       choice->choice = punittype->index;
        choice->type = CT_ATTACKER;
        want_something = TRUE;
        freelog(LOG_DEBUG, "%s wants to build %s (want=%d)",
-               pcity->name, get_unit_type(u_type)->name, profit);
+               pcity->name, punittype->name, profit);
       } else {
       freelog(LOG_DEBUG, "%s doesn't want to build %s (want=%d)",
-               pcity->name, get_unit_type(u_type)->name, profit);
+               pcity->name, punittype->name, profit);
       }
       destroy_unit_virtual(virtual_unit);
     }
Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.230
diff -p -u -r1.230 aicity.c
--- ai/aicity.c 4 Jul 2005 17:48:35 -0000       1.230
+++ ai/aicity.c 19 Jul 2005 03:41:43 -0000
@@ -640,7 +640,7 @@ static void adjust_building_want_by_effe
 **************************************************************************/
 static void calculate_city_clusters(struct player *pplayer)
 {
-  Unit_type_id unittype;
+  struct unit_type *punittype;
   struct unit *ghost;
   int range;
 
@@ -652,11 +652,11 @@ static void calculate_city_clusters(stru
     return; /* ruleset has no help wonder unit */
   }
 
-  unittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
-  if (unittype == U_LAST) {
-    unittype = get_role_unit(F_HELP_WONDER, 0); /* simulate future unit */
+  punittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
+  if (!punittype) {
+    punittype = get_role_unit(F_HELP_WONDER, 0); /* simulate future unit */
   }
-  ghost = create_unit_virtual(pplayer, NULL, unittype, 0);
+  ghost = create_unit_virtual(pplayer, NULL, punittype, 0);
   range = unit_move_rate(ghost) * 4;
 
   city_list_iterate(pplayer->cities, pcity) {
@@ -695,7 +695,7 @@ static void calculate_wonder_helpers(str
 {
   struct pf_map *map;
   struct pf_parameter parameter;
-  Unit_type_id unittype;
+  struct unit_type *punittype;
   struct unit *ghost;
   int maxrange;
   struct city *wonder_city = find_city_by_id(ai->wonder_city);
@@ -712,11 +712,11 @@ static void calculate_wonder_helpers(str
     return;
   }
 
-  unittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
-  if (unittype == U_LAST) {
+  punittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
+  if (!punittype) {
     return;
   }
-  ghost = create_unit_virtual(pplayer, wonder_city, unittype, 0);
+  ghost = create_unit_virtual(pplayer, wonder_city, punittype, 0);
   maxrange = unit_move_rate(ghost) * 7;
 
   pft_fill_unit_parameter(&parameter, ghost);
@@ -789,7 +789,7 @@ void ai_manage_buildings(struct player *
       /* Downtown is the number of cities within a certain pf range.
        * These may be able to help with caravans. Also look at the whole
        * continent. */
-      if (first_role_unit_for_player(pplayer, F_HELP_WONDER) != U_LAST) {
+      if (first_role_unit_for_player(pplayer, F_HELP_WONDER)) {
         value += pcity->ai.downtown;
         value += ai->stats.cities[pcity->tile->continent] / 8;
       }
@@ -867,33 +867,33 @@ void ai_manage_buildings(struct player *
 static void ai_barbarian_choose_build(struct player *pplayer, 
                                      struct ai_choice *choice)
 {
-  Unit_type_id bestunit = -1;
+  struct unit_type *bestunit = NULL;
   int i, bestattack = 0;
 
   /* Choose the best unit among the basic ones */
   for(i = 0; i < num_role_units(L_BARBARIAN_BUILD); i++) {
-    Unit_type_id iunit = get_role_unit(L_BARBARIAN_BUILD, i);
+    struct unit_type *iunit = get_role_unit(L_BARBARIAN_BUILD, i);
 
-    if (get_unit_type(iunit)->attack_strength > bestattack) {
+    if (iunit->attack_strength > bestattack) {
       bestunit = iunit;
-      bestattack = get_unit_type(iunit)->attack_strength;
+      bestattack = iunit->attack_strength;
     }
   }
 
   /* Choose among those made available through other civ's research */
   for(i = 0; i < num_role_units(L_BARBARIAN_BUILD_TECH); i++) {
-    Unit_type_id iunit = get_role_unit(L_BARBARIAN_BUILD_TECH, i);
+    struct unit_type *iunit = get_role_unit(L_BARBARIAN_BUILD_TECH, i);
 
-    if (game.info.global_advances[get_unit_type(iunit)->tech_requirement]
-       && get_unit_type(iunit)->attack_strength > bestattack) {
+    if (game.info.global_advances[iunit->tech_requirement]
+       && iunit->attack_strength > bestattack) {
       bestunit = iunit;
-      bestattack = get_unit_type(iunit)->attack_strength;
+      bestattack = iunit->attack_strength;
     }
   }
 
   /* If found anything, put it into the choice */
-  if (bestunit != -1) {
-    choice->choice = bestunit;
+  if (bestunit) {
+    choice->choice = bestunit->index;
     /* FIXME: 101 is the "overriding military emergency" indicator */
     choice->want   = 101;
     choice->type   = CT_ATTACKER;
@@ -939,11 +939,11 @@ static void ai_city_choose_build(struct 
     CITY_LOG(LOG_ERROR, pcity, "Falling back - didn't want to build soldiers,"
             " workers, caravans, settlers, or buildings!");
     pcity->ai.choice.want = 1;
-    if (best_role_unit(pcity, F_TRADE_ROUTE) != U_LAST) {
-      pcity->ai.choice.choice = best_role_unit(pcity, F_TRADE_ROUTE);
+    if (best_role_unit(pcity, F_TRADE_ROUTE)) {
+      pcity->ai.choice.choice = best_role_unit(pcity, F_TRADE_ROUTE)->index;
       pcity->ai.choice.type = CT_NONMIL;
-    } else if (best_role_unit(pcity, F_SETTLERS) != U_LAST) {
-      pcity->ai.choice.choice = best_role_unit(pcity, F_SETTLERS);
+    } else if (best_role_unit(pcity, F_SETTLERS)) {
+      pcity->ai.choice.choice = best_role_unit(pcity, F_SETTLERS)->index;
       pcity->ai.choice.type = CT_NONMIL;
     } else {
       CITY_LOG(LOG_ERROR, pcity, "Cannot even build a fallback "
@@ -957,7 +957,7 @@ static void ai_city_choose_build(struct 
 
     CITY_LOG(LOG_DEBUG, pcity, "wants %s with desire %d.",
             (is_unit_choice_type(pcity->ai.choice.type) ?
-             unit_name(pcity->ai.choice.choice) :
+             unit_name(get_unit_type(pcity->ai.choice.choice)) :
              get_improvement_name(pcity->ai.choice.choice)),
             pcity->ai.choice.want);
     
@@ -1022,8 +1022,10 @@ static void increase_maxbuycost(struct p
 static void ai_upgrade_units(struct city *pcity, int limit, bool military)
 {
   struct player *pplayer = city_owner(pcity);
+
   unit_list_iterate(pcity->tile->units, punit) {
-    int id = can_upgrade_unittype(pplayer, punit->type);
+    struct unit_type *punittype = can_upgrade_unittype(pplayer, punit->type);
+
     if (military && (!is_military_unit(punit) || !is_ground_unit(punit))) {
       /* Only upgrade military units this round */
       continue;
@@ -1032,16 +1034,17 @@ static void ai_upgrade_units(struct city
       /* Only civilians or tranports this round */
       continue;
     }
-    if (id >= 0) {
-      int cost = unit_upgrade_price(pplayer, punit->type, id);
+    if (punittype) {
+      int cost = unit_upgrade_price(pplayer, punit->type, punittype);
       int real_limit = limit;
+
       /* Triremes are DANGEROUS!! We'll do anything to upgrade 'em. */
       if (unit_flag(punit, F_TRIREME)) {
         real_limit = pplayer->ai.est_upkeep;
       }
       if (pplayer->economic.gold - cost > real_limit) {
         CITY_LOG(LOG_BUY, pcity, "Upgraded %s to %s for %d (%s)",
-                 unit_type(punit)->name, unit_types[id].name, cost,
+                 unit_type(punit)->name, punittype->name, cost,
                  military ? "military" : "civilian");
         handle_unit_upgrade(city_owner(pcity), punit->id);
       } else {
@@ -1129,7 +1132,7 @@ static void ai_spend_gold(struct player 
     }
 
     if (bestchoice.type != CT_BUILDING
-        && unit_type_flag(bestchoice.choice, F_CITIES)) {
+        && unit_type_flag(get_unit_type(bestchoice.choice), F_CITIES)) {
       if (get_city_bonus(pcity, EFT_GROWTH_FOOD) == 0
           && pcity->size == 1
           && city_granary_size(pcity->size)
@@ -1154,7 +1157,8 @@ static void ai_spend_gold(struct player 
                 || (pplayer->economic.gold - buycost < limit);
 
     if (bestchoice.type == CT_ATTACKER
-       && buycost > unit_build_shield_cost(bestchoice.choice) * 2) {
+       && buycost
+       > unit_build_shield_cost(get_unit_type(bestchoice.choice)) * 2) {
        /* Too expensive for an offensive unit */
        continue;
     }
@@ -1169,7 +1173,8 @@ static void ai_spend_gold(struct player 
             || (bestchoice.want > 200 && pcity->ai.urgency > 1))) {
       /* Buy stuff */
       CITY_LOG(LOG_BUY, pcity, "Crash buy of %s for %d (want %d)",
-               bestchoice.type != CT_BUILDING ? unit_name(bestchoice.choice)
+               bestchoice.type != CT_BUILDING
+              ? unit_name(get_unit_type(bestchoice.choice))
                : get_improvement_name(bestchoice.choice), buycost,
                bestchoice.want);
       really_handle_city_buy(pplayer, pcity);
@@ -1178,7 +1183,8 @@ static void ai_spend_gold(struct player 
                && assess_defense(pcity) == 0) {
       /* We have no gold but MUST have a defender */
       CITY_LOG(LOG_BUY, pcity, "must have %s but can't afford it (%d < %d)!",
-              unit_name(bestchoice.choice), pplayer->economic.gold, buycost);
+              unit_name(get_unit_type(bestchoice.choice)),
+              pplayer->economic.gold, buycost);
       try_to_sell_stuff(pplayer, pcity);
       if (pplayer->economic.gold - pplayer->ai.est_upkeep >= buycost) {
         CITY_LOG(LOG_BUY, pcity, "now we can afford it (sold something)");
Index: ai/aicity.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.h,v
retrieving revision 1.27
diff -p -u -r1.27 aicity.h
--- ai/aicity.h 30 Apr 2005 17:09:25 -0000      1.27
+++ ai/aicity.h 19 Jul 2005 03:41:43 -0000
@@ -23,7 +23,6 @@ struct ai_choice;
 void ai_manage_cities(struct player *pplayer);
 void ai_manage_buildings(struct player *pplayer);
 
-Unit_type_id ai_choose_defender_versus(struct city *pcity, Unit_type_id v);
 int ai_eval_calc_city(struct city *pcity, struct ai_data *ai);
 
 #endif  /* FC__AICITY_H */
Index: ai/aidata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidata.c,v
retrieving revision 1.72
diff -p -u -r1.72 aidata.c
--- ai/aidata.c 9 Jul 2005 10:19:47 -0000       1.72
+++ ai/aidata.c 19 Jul 2005 03:41:43 -0000
@@ -501,7 +501,8 @@ void ai_data_phase_init(struct player *p
 
     /* Check for nuke capability */
     for (i = 0; i < nuke_units; i++) {
-      Unit_type_id nuke = get_role_unit(F_NUCLEAR, i);
+      struct unit_type *nuke = get_role_unit(F_NUCLEAR, i);
+
       if (can_player_build_unit_direct(aplayer, nuke)) { 
         ai->threats.nuclear = 1;
       }
Index: ai/aidiplomat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidiplomat.c,v
retrieving revision 1.54
diff -p -u -r1.54 aidiplomat.c
--- ai/aidiplomat.c     21 Jun 2005 16:21:00 -0000      1.54
+++ ai/aidiplomat.c     19 Jul 2005 03:41:43 -0000
@@ -111,22 +111,22 @@ void ai_choose_diplomat_defensive(struct
      to protect us. If we see an enemy diplomat and we don't have diplomat
      tech... race it! */
   if (def != 0 && pcity->ai.diplomat_threat && !pcity->ai.has_diplomat) {
-    Unit_type_id u = best_role_unit(pcity, F_DIPLOMAT);
+    struct unit_type *u = best_role_unit(pcity, F_DIPLOMAT);
 
-    if (u < U_LAST) {
+    if (u) {
        freelog(LOG_DIPLOMAT_BUILD, 
                "A defensive diplomat will be built in city %s.", pcity->name);
        choice->want = 16000; /* diplomat more important than soldiers */
        pcity->ai.urgency = 1;
        choice->type = CT_DEFENDER;
-       choice->choice = u;
+       choice->choice = u->index;
     } else if (num_role_units(F_DIPLOMAT) > 0) {
       /* We don't know diplomats yet... */
       freelog(LOG_DIPLOMAT_BUILD,
               "A defensive diplomat is wanted badly in city %s.", pcity->name);
       u = get_role_unit(F_DIPLOMAT, 0);
-      if (u != U_LAST) {
-        Tech_type_id tech_req = get_unit_type(u)->tech_requirement;
+      if (u) {
+        Tech_type_id tech_req = u->tech_requirement;
 
         pplayer->ai.tech_want[tech_req] += DIPLO_DEFENSE_WANT;
         TECH_LOG(LOG_DEBUG, pplayer, tech_req, "+ %d for %s in diplo defense",
@@ -144,10 +144,10 @@ void ai_choose_diplomat_offensive(struct
                                   struct city *pcity,
                                   struct ai_choice *choice)
 {
-  Unit_type_id u = best_role_unit(pcity, F_DIPLOMAT);
+  struct unit_type *ut = best_role_unit(pcity, F_DIPLOMAT);
   struct ai_data *ai = ai_data_get(pplayer);
 
-  if (u >= U_LAST) {
+  if (ut) {
     /* We don't know diplomats yet! */
     return;
   }
@@ -161,13 +161,12 @@ void ai_choose_diplomat_offensive(struct
   {
     struct pf_map *map;
     struct pf_parameter parameter;
-    struct unit_type *ut = get_unit_type(u);
     struct city *acity;
     int want, loss, p_success, p_failure, time_to_dest;
     int gain_incite = 0, gain_theft = 0, gain = 1;
     int incite_cost;
-    struct unit *punit = create_unit_virtual(pplayer, pcity, u,
-                                             do_make_unit_veteran(pcity, u));
+    struct unit *punit = create_unit_virtual(pplayer, pcity, ut,
+                                             do_make_unit_veteran(pcity, ut));
 
     pft_fill_unit_parameter(&parameter, punit);
     map = pf_create_map(&parameter);
@@ -177,7 +176,8 @@ void ai_choose_diplomat_offensive(struct
     pf_destroy_map(map);
     destroy_unit_virtual(punit);
 
-    if (acity == NULL || BV_ISSET(ai->stats.diplomat_reservations, acity->id)) 
{
+    if (acity == NULL
+       || BV_ISSET(ai->stats.diplomat_reservations, acity->id)) {
       /* Found no target or city already considered */
       return;
     }
@@ -202,12 +202,12 @@ void ai_choose_diplomat_offensive(struct
       gain_theft = total_bulbs_required(pplayer) * TRADE_WEIGHTING;
     }
     gain = MAX(gain_incite, gain_theft);
-    loss = unit_build_shield_cost(u) * SHIELD_WEIGHTING;
+    loss = unit_build_shield_cost(ut) * SHIELD_WEIGHTING;
 
     /* Probability to succeed, assuming no defending diplomat */
     p_success = game.info.diplchance;
     /* Probability to lose our unit */
-    p_failure = (unit_type_flag(u, F_SPY) ? 100 - p_success : 100);
+    p_failure = (unit_type_flag(ut, F_SPY) ? 100 - p_success : 100);
 
     /* Get the time to dest in turns (minimum 1 turn) */
     time_to_dest = (time_to_dest + ut->move_rate - 1) / ut->move_rate;
@@ -222,7 +222,7 @@ void ai_choose_diplomat_offensive(struct
     }
 
     want = military_amortize(pplayer, pcity, want, time_to_dest, 
-                             unit_build_shield_cost(u));
+                             unit_build_shield_cost(ut));
 
     if (!player_has_embassy(pplayer, city_owner(acity))
         && want < 99) {
@@ -241,7 +241,7 @@ void ai_choose_diplomat_offensive(struct
               gain_theft, time_to_dest);
       choice->want = want;
       choice->type = CT_NONMIL; /* so we don't build barracks for it */
-      choice->choice = u;
+      choice->choice = ut->index;
       BV_SET(ai->stats.diplomat_reservations, acity->id);
     }
   }
@@ -379,7 +379,8 @@ static void find_city_to_diplomat(struct
 **************************************************************************/
 static struct city *ai_diplomat_defend(struct player *pplayer,
                                        struct unit *punit,
-                                       Unit_type_id utype, struct pf_map *map)
+                                       const struct unit_type *utype,
+                                      struct pf_map *map)
 {
   int best_dist = 30; /* any city closer than this is better than none */
   int best_urgency = 0;
Index: ai/aiferry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiferry.c,v
retrieving revision 1.22
diff -p -u -r1.22 aiferry.c
--- ai/aiferry.c        7 May 2005 13:35:24 -0000       1.22
+++ ai/aiferry.c        19 Jul 2005 03:41:43 -0000
@@ -770,7 +770,8 @@ static bool aiferry_find_interested_city
     if (pcity && pcity->owner == pferry->owner
         && (pcity->ai.choice.need_boat 
             || (pcity->is_building_unit
-               && unit_has_role(pcity->currently_building, L_FERRYBOAT)))) {
+               && unit_has_role(get_unit_type(pcity->currently_building),
+                                L_FERRYBOAT)))) {
       bool really_needed = TRUE;
       int turns = city_turns_to_build(pcity, pcity->currently_building,
                                       pcity->is_building_unit, TRUE);
@@ -779,7 +780,8 @@ static bool aiferry_find_interested_city
                pcity->name, TILE_XY(pcity->tile));
 
       if (pos.turn > turns && pcity->is_building_unit
-          && unit_has_role(pcity->currently_building, L_FERRYBOAT)) {
+          && unit_has_role(get_unit_type(pcity->currently_building),
+                          L_FERRYBOAT)) {
         UNIT_LOG(LOGLEVEL_FERRY, pferry, "%s is NOT suitable: "
                  "will finish building its own ferry too soon", pcity->name);
         continue;
Index: ai/aihunt.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aihunt.c,v
retrieving revision 1.19
diff -p -u -r1.19 aihunt.c
--- ai/aihunt.c 4 Jul 2005 17:48:35 -0000       1.19
+++ ai/aihunt.c 19 Jul 2005 03:41:43 -0000
@@ -62,17 +62,16 @@ static struct unit *ai_hunter_find(struc
 /**************************************************************************
   Guess best hunter unit type.
 **************************************************************************/
-static Unit_type_id ai_hunter_guess_best(struct city *pcity,
-                                         enum unit_move_type umt)
+static struct unit_type *ai_hunter_guess_best(struct city *pcity,
+                                             enum unit_move_type umt)
 {
-  Unit_type_id bestid = -1;
+  struct unit_type *bestid = NULL;
   int best = 0;
 
-  unit_type_iterate(i) {
-    struct unit_type *ut = get_unit_type(i);
+  unit_type_iterate(ut) {
     int desire;
 
-    if (ut->move_type != umt || !can_build_unit(pcity, i)
+    if (ut->move_type != umt || !can_build_unit(pcity, ut)
         || ut->attack_strength < ut->transport_capacity) {
       continue;
     }
@@ -83,24 +82,24 @@ static Unit_type_id ai_hunter_guess_best
               * ut->move_rate
               + ut->defense_strength) / MAX(UNITTYPE_COSTS(ut), 1);
 
-    if (unit_type_flag(i, F_CARRIER)
-        || unit_type_flag(i, F_MISSILE_CARRIER)) {
+    if (unit_type_flag(ut, F_CARRIER)
+        || unit_type_flag(ut, F_MISSILE_CARRIER)) {
       desire += desire / 6;
     }
-    if (unit_type_flag(i, F_IGTER)) {
+    if (unit_type_flag(ut, F_IGTER)) {
       desire += desire / 2;
     }
-    if (unit_type_flag(i, F_IGTIRED)) {
+    if (unit_type_flag(ut, F_IGTIRED)) {
       desire += desire / 8;
     }
-    if (unit_type_flag(i, F_PARTIAL_INVIS)) {
+    if (unit_type_flag(ut, F_PARTIAL_INVIS)) {
       desire += desire / 4;
     }
-    if (unit_type_flag(i, F_NO_LAND_ATTACK)) {
+    if (unit_type_flag(ut, F_NO_LAND_ATTACK)) {
       desire -= desire / 4; /* less flexibility */
     }
     /* Causes continual unhappiness */
-    if (unit_type_flag(i, F_FIELDUNIT)) {
+    if (unit_type_flag(ut, F_FIELDUNIT)) {
       desire /= 2;
     }
 
@@ -109,7 +108,7 @@ static Unit_type_id ai_hunter_guess_best
 
     if (desire > best) {
         best = desire;
-        bestid = i;
+        bestid = ut;
     }
   } unit_type_iterate_end;
 
@@ -123,7 +122,8 @@ static void ai_hunter_missile_want(struc
                                    struct city *pcity,
                                    struct ai_choice *choice)
 {
-  int best = -1, best_unit_type = -1;
+  int best = -1;
+  struct unit_type *best_unit_type = NULL;
   bool have_hunter = FALSE;
 
   unit_list_iterate(pcity->tile->units, punit) {
@@ -141,11 +141,10 @@ static void ai_hunter_missile_want(struc
     return;
   }
 
-  unit_type_iterate(i) {
-    struct unit_type *ut = get_unit_type(i);
+  unit_type_iterate(ut) {
     int desire;
 
-    if (!BV_ISSET(ut->flags, F_MISSILE) || !can_build_unit(pcity, i)) {
+    if (!BV_ISSET(ut->flags, F_MISSILE) || !can_build_unit(pcity, ut)) {
       continue;
     }
 
@@ -158,7 +157,7 @@ static void ai_hunter_missile_want(struc
               * ut->move_rate) / UNITTYPE_COSTS(ut) + 1;
 
     /* Causes continual unhappiness */
-    if (unit_type_flag(i, F_FIELDUNIT)) {
+    if (unit_type_flag(ut, F_FIELDUNIT)) {
       desire /= 2;
     }
 
@@ -167,13 +166,13 @@ static void ai_hunter_missile_want(struc
 
     if (desire > best) {
         best = desire;
-        best_unit_type = i;
+        best_unit_type = ut;
     }
   } unit_type_iterate_end;
 
   if (best > choice->want) {
     CITY_LOG(LOGLEVEL_HUNT, pcity, "pri missile w/ want %d", best);
-    choice->choice = best_unit_type;
+    choice->choice = best_unit_type->index;
     choice->want = best;
     choice->type = CT_ATTACKER;
   } else if (best != -1) {
@@ -186,7 +185,8 @@ static void ai_hunter_missile_want(struc
   Support function for ai_hunter_choice()
 **************************************************************************/
 static void eval_hunter_want(struct player *pplayer, struct city *pcity,
-                             struct ai_choice *choice, int best_type,
+                             struct ai_choice *choice,
+                            struct unit_type *best_type,
                              int veteran)
 {
   struct unit *virtualunit;
@@ -197,7 +197,7 @@ static void eval_hunter_want(struct play
   destroy_unit_virtual(virtualunit);
   if (want > choice->want) {
     CITY_LOG(LOGLEVEL_HUNT, pcity, "pri hunter w/ want %d", want);
-    choice->choice = best_type;
+    choice->choice = best_type->index;
     choice->want = want;
     choice->type = CT_ATTACKER;
   }
@@ -209,11 +209,13 @@ static void eval_hunter_want(struct play
 void ai_hunter_choice(struct player *pplayer, struct city *pcity,
                       struct ai_choice *choice)
 {
-  int best_land_hunter = ai_hunter_guess_best(pcity, LAND_MOVING);
-  int best_sea_hunter = ai_hunter_guess_best(pcity, SEA_MOVING);
+  struct unit_type *best_land_hunter
+    = ai_hunter_guess_best(pcity, LAND_MOVING);
+  struct unit_type *best_sea_hunter
+    = ai_hunter_guess_best(pcity, SEA_MOVING);
   struct unit *hunter = ai_hunter_find(pplayer, pcity);
 
-  if ((best_land_hunter == -1 && best_sea_hunter == -1)
+  if ((!best_land_hunter && !best_sea_hunter)
       || is_barbarian(pplayer) || !pplayer->is_alive
       || ai_handicap(pplayer, H_TARGETS)) {
     return; /* None available */
@@ -224,11 +226,11 @@ void ai_hunter_choice(struct player *ppl
     return;
   }
 
-  if (best_sea_hunter >= 0) {
+  if (best_sea_hunter) {
     eval_hunter_want(pplayer, pcity, choice, best_sea_hunter, 
                      do_make_unit_veteran(pcity, best_sea_hunter));
   }
-  if (best_land_hunter >= 0) {
+  if (best_land_hunter) {
     eval_hunter_want(pplayer, pcity, choice, best_land_hunter, 
                      do_make_unit_veteran(pcity, best_land_hunter));
   }
Index: ai/aisettler.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aisettler.c,v
retrieving revision 1.25
diff -p -u -r1.25 aisettler.c
--- ai/aisettler.c      14 Jul 2005 19:25:43 -0000      1.25
+++ ai/aisettler.c      19 Jul 2005 03:41:44 -0000
@@ -585,15 +585,16 @@ void find_best_city_placement(struct uni
           && tile_get_city(punit->tile))) {
     if (!ferry) {
       /* No boat?  Get a virtual one! */
-      Unit_type_id boattype
+      struct unit_type *boattype
         = best_role_unit_for_player(pplayer, L_FERRYBOAT);
 
-      if (boattype == U_LAST) {
+      if (boattype == NULL) {
         /* Sea travel not possible yet. Bump tech want for ferries. */
-        Unit_type_id boattype = get_role_unit(L_FERRYBOAT, 0);
+        struct unit_type *boattype = get_role_unit(L_FERRYBOAT, 0);
 
-        if (boattype != U_LAST) {
-          Tech_type_id tech_req = unit_types[boattype].tech_requirement;
+        if (boattype != NULL) {
+          Tech_type_id tech_req
+           = unit_types[boattype->index].tech_requirement;
 
           pplayer->ai.tech_want[tech_req] += FERRY_TECH_WANT;
           TECH_LOG(LOG_DEBUG, pplayer, tech_req, "+ %d for %s to ferry 
settler",
Index: ai/aitech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitech.c,v
retrieving revision 1.60
diff -p -u -r1.60 aitech.c
--- ai/aitech.c 23 Jun 2005 21:58:23 -0000      1.60
+++ ai/aitech.c 19 Jul 2005 03:41:44 -0000
@@ -208,26 +208,27 @@ void ai_manage_tech(struct player *pplay
   wants for techs to get better units with given role, but only for the
   cheapest to research "next" unit up the "chain".
 **************************************************************************/
-Unit_type_id ai_wants_role_unit(struct player *pplayer, struct city *pcity,
-                                int role, int want)
+struct unit_type *ai_wants_role_unit(struct player *pplayer,
+                                    struct city *pcity,
+                                    int role, int want)
 {
   int i, n;
   Tech_type_id best_tech = A_NONE;
   int best_cost = FC_INFINITY;
-  Unit_type_id best_unit = U_LAST;
-  Unit_type_id build_unit = U_LAST;
+  struct unit_type *best_unit = NULL;
+  struct unit_type *build_unit = NULL;
 
   n = num_role_units(role);
   for (i = n - 1; i >= 0; i--) {
-    Unit_type_id iunit = get_role_unit(role, i);
-    Tech_type_id itech = get_unit_type(iunit)->tech_requirement;
+    struct unit_type *iunit = get_role_unit(role, i);
+    Tech_type_id itech = iunit->tech_requirement;
 
     if (can_build_unit(pcity, iunit)) {
       build_unit = iunit;
       break;
     } else if (can_eventually_build_unit(pcity, iunit)) {
       int cost = 0;
-      Impr_type_id iimpr = get_unit_type(iunit)->impr_requirement;
+      Impr_type_id iimpr = iunit->impr_requirement;
 
       if (itech != A_LAST && get_invention(pplayer, itech) != TECH_KNOWN) {
         /* See if we want to invent this. */
@@ -266,7 +267,7 @@ Unit_type_id ai_wants_role_unit(struct p
 
   if (best_tech != A_NONE) {
     /* Crank up chosen tech want */
-    if (build_unit != U_LAST) {
+    if (build_unit != NULL) {
       /* We already have a role unit of this kind */
       want /= 2;
     }
Index: ai/aitech.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitech.h,v
retrieving revision 1.9
diff -p -u -r1.9 aitech.h
--- ai/aitech.h 30 Apr 2005 17:09:25 -0000      1.9
+++ ai/aitech.h 19 Jul 2005 03:41:44 -0000
@@ -18,7 +18,8 @@
 
 void ai_manage_tech(struct player *pplayer); 
 void ai_next_tech_goal(struct player *pplayer);
-Unit_type_id ai_wants_role_unit(struct player *pplayer, struct city *pcity,
-                                int role, int want);
+struct unit_type *ai_wants_role_unit(struct player *pplayer,
+                                    struct city *pcity,
+                                    int role, int want);
 
 #endif  /* FC__AITECH_H */
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.155
diff -p -u -r1.155 aitools.c
--- ai/aitools.c        14 Jul 2005 19:25:43 -0000      1.155
+++ ai/aitools.c        19 Jul 2005 03:41:44 -0000
@@ -206,10 +206,11 @@ static void ai_gothere_bodyguard(struct 
   dcity = tile_get_city(dest_tile);
   if (dcity && HOSTILE_PLAYER(pplayer, ai, city_owner(dcity))) {
     /* Assume enemy will build another defender, add it's attack strength */
-    int d_type = ai_choose_defender_versus(dcity, punit->type);
+    struct unit_type *d_type = ai_choose_defender_versus(dcity, punit->type);
+
     danger += 
       unittype_att_rating(d_type, do_make_unit_veteran(dcity, d_type), 
-                          SINGLE_MOVE, unit_types[d_type].hp);
+                          SINGLE_MOVE, d_type->hp);
   }
   danger *= POWER_DIVIDER;
 
@@ -1132,10 +1133,10 @@ void copy_if_better_choice(struct ai_cho
 void ai_choose_role_unit(struct player *pplayer, struct city *pcity,
                         struct ai_choice *choice, int role, int want)
 {
-  Unit_type_id iunit = ai_wants_role_unit(pplayer, pcity, role, want);
+  struct unit_type *iunit = ai_wants_role_unit(pplayer, pcity, role, want);
 
-  if (iunit != U_LAST) {
-    choice->choice = iunit;
+  if (iunit != NULL) {
+    choice->choice = iunit->index;
   }
 }
 
Index: ai/aitools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.h,v
retrieving revision 1.56
diff -p -u -r1.56 aitools.h
--- ai/aitools.h        13 Jul 2005 16:49:39 -0000      1.56
+++ ai/aitools.h        19 Jul 2005 03:41:44 -0000
@@ -17,7 +17,6 @@
 
 #include "fc_types.h"
 #include "unit.h"              /* enum ai_unit_task */
-#include "unittype.h"          /* Unit_type_id */
 
 struct ai_choice;
 struct pf_path;
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.364
diff -p -u -r1.364 aiunit.c
--- ai/aiunit.c 14 Jul 2005 19:25:43 -0000      1.364
+++ ai/aiunit.c 19 Jul 2005 03:41:44 -0000
@@ -82,7 +82,7 @@ static void ai_military_defend(struct pl
 static void ai_military_attack(struct player *pplayer,struct unit *punit);
 
 static int unit_move_turns(struct unit *punit, struct tile *ptile);
-static bool unit_role_defender(Unit_type_id type);
+static bool unit_role_defender(const struct unit_type *punittype);
 static int unit_def_rating_sq(struct unit *punit, struct unit *pdef);
 
 /*
@@ -97,9 +97,9 @@ static int unit_def_rating_sq(struct uni
  *
  * Not dealing with planes yet.
  *
- * Terminated by U_LAST.
+ * Terminated by NULL.
  */
-Unit_type_id simple_ai_types[U_LAST];
+struct unit_type *simple_ai_types[U_LAST];
 
 /**************************************************************************
   Move defenders around with airports. Since this expends all our 
@@ -305,22 +305,20 @@ static int unit_move_turns(struct unit *
   the want equation (see, e.g.  find_something_to_kill) instead of
   just build_cost to make AI build more balanced units (with def > 1).
 *********************************************************************/
-int build_cost_balanced(Unit_type_id type)
+int build_cost_balanced(const struct unit_type *punittype)
 {
-  struct unit_type *ptype = get_unit_type(type);
-
-  return 2 * unit_build_shield_cost(type) * ptype->attack_strength /
-      (ptype->attack_strength + ptype->defense_strength);
+  return 2 * unit_build_shield_cost(punittype) * punittype->attack_strength /
+      (punittype->attack_strength + punittype->defense_strength);
 }
 
 /**************************************************************************
   Attack rating of this kind of unit.
 **************************************************************************/
-int unittype_att_rating(Unit_type_id type, int veteran,
+int unittype_att_rating(const struct unit_type *punittype, int veteran,
                         int moves_left, int hp)
 {
-  return base_get_attack_power(type, veteran, moves_left) * hp
-         * get_unit_type(type)->firepower / POWER_DIVIDER;
+  return base_get_attack_power(punittype, veteran, moves_left) * hp
+         * punittype->firepower / POWER_DIVIDER;
 }
 
 /********************************************************************** 
@@ -378,7 +376,7 @@ static int unit_def_rating_sq(struct uni
 int unit_def_rating_basic(struct unit *punit)
 {
   return base_get_defense_power(punit) * punit->hp *
-         unit_types[punit->type].firepower / POWER_DIVIDER;
+    punit->type->firepower / POWER_DIVIDER;
 }
 
 /********************************************************************** 
@@ -395,13 +393,14 @@ int unit_def_rating_basic_sq(struct unit
   See get_virtual_defense_power for the arguments att_type, def_type,
   x, y, fortified and veteran.
 **************************************************************************/
-int unittype_def_rating_sq(Unit_type_id att_type, Unit_type_id def_type,
+int unittype_def_rating_sq(const struct unit_type *att_type,
+                          const struct unit_type *def_type,
                            struct tile *ptile, bool fortified, int veteran)
 {
   int v = get_virtual_defense_power(att_type, def_type, ptile,
-                                    fortified, veteran) *
-          unit_types[def_type].hp *
-          unit_types[def_type].firepower / POWER_DIVIDER;
+                                    fortified, veteran)
+    * def_type->hp * def_type->firepower / POWER_DIVIDER;
+
   return v * v;
 }
 
@@ -820,12 +819,12 @@ static bool find_beachhead(struct unit *
 /*************************************************************************
   Does the unit with the id given have the flag L_DEFEND_GOOD?
 **************************************************************************/
-static bool unit_role_defender(Unit_type_id type)
+static bool unit_role_defender(const struct unit_type *punittype)
 {
-  if (unit_types[type].move_type != LAND_MOVING) {
+  if (punittype->move_type != LAND_MOVING) {
     return FALSE; /* temporary kluge */
   }
-  return (unit_has_role(type, L_DEFEND_GOOD));
+  return (unit_has_role(punittype, L_DEFEND_GOOD));
 }
 
 /*************************************************************************
@@ -931,7 +930,7 @@ int look_for_charge(struct player *pplay
 ***********************************************************************/
 static void ai_military_findjob(struct player *pplayer,struct unit *punit)
 {
-  struct unit_type *punittype = get_unit_type(punit->type);
+  struct unit_type *punittype = punit->type;
 
   CHECK_UNIT(punit);
 
@@ -1058,14 +1057,14 @@ static void ai_military_defend(struct pl
 
  Requires ready warmap(s).  Assumes punit is ground or sailing.
 ***************************************************************************/
-int turns_to_enemy_city(Unit_type_id our_type,  struct city *acity,
+int turns_to_enemy_city(const struct unit_type *our_type, struct city *acity,
                         int speed, bool go_by_boat, 
-                        struct unit *boat, Unit_type_id boattype)
+                        struct unit *boat, const struct unit_type *boattype)
 {
-  switch(unit_types[our_type].move_type) {
+  switch (our_type->move_type) {
   case LAND_MOVING:
     if (go_by_boat) {
-      int boatspeed = unit_types[boattype].move_rate;
+      int boatspeed = boattype->move_rate;
       int move_time = (WARMAP_SEACOST(acity->tile)) / boatspeed;
       
       if (unit_type_flag(boattype, F_TRIREME) && move_time > 2) {
@@ -1105,12 +1104,13 @@ int turns_to_enemy_city(Unit_type_id our
 
  Requires precomputed warmap.  Assumes punit is ground or sailing. 
 ************************************************************************/ 
-int turns_to_enemy_unit(Unit_type_id our_type, int speed, struct tile *ptile,
-                        Unit_type_id enemy_type)
+int turns_to_enemy_unit(const struct unit_type *our_type,
+                       int speed, struct tile *ptile,
+                        const struct unit_type *enemy_type)
 {
   int dist;
 
-  switch(unit_types[our_type].move_type) {
+  switch (our_type->move_type) {
   case LAND_MOVING:
     dist = WARMAP_COST(ptile);
     break;
@@ -1128,7 +1128,7 @@ int turns_to_enemy_unit(Unit_type_id our
   /* if dist <= move_rate, we hit the enemy right now */    
   if (dist > speed) { 
     /* Weird attempt to take into account enemy running away... */
-    dist *= unit_types[enemy_type].move_rate;
+    dist *= enemy_type->move_rate;
     if (unit_type_flag(enemy_type, F_IGTER)) {
       dist *= 3;
     }
@@ -1213,7 +1213,7 @@ int find_something_to_kill(struct player
   bool handicap = ai_handicap(pplayer, H_TARGETS);
   struct unit *ferryboat = NULL;
   /* Type of our boat (a future one if ferryboat == NULL) */
-  Unit_type_id boattype = U_LAST;
+  struct unit_type *boattype = NULL;
   bool unhap = FALSE;
   struct city *pcity;
   /* this is a kluge, because if we don't set x and y with !punit->id,
@@ -1326,7 +1326,7 @@ int find_something_to_kill(struct player
                            ferryboat, SEA_MOVING);
   } else {
     boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
-    if (boattype == U_LAST) {
+    if (boattype == NULL) {
       /* We pretend that we can have the simplest boat -- to stimulate tech */
       boattype = get_role_unit(L_FERRYBOAT, 0);
     }
@@ -1389,7 +1389,8 @@ int find_something_to_kill(struct player
                                       go_by_boat, ferryboat, boattype);
 
       if (move_time > 1) {
-        Unit_type_id def_type = ai_choose_defender_versus(acity, punit->type);
+        struct unit_type *def_type
+         = ai_choose_defender_versus(acity, punit->type);
         int v = unittype_def_rating_sq(punit->type, def_type,
                                        acity->tile, FALSE,
                                        do_make_unit_veteran(acity, def_type));
@@ -1872,7 +1873,7 @@ static void ai_manage_hitpoint_recovery(
   struct player *pplayer = unit_owner(punit);
   struct city *pcity = tile_get_city(punit->tile);
   struct city *safe = NULL;
-  struct unit_type *punittype = get_unit_type(punit->type);
+  struct unit_type *punittype = punit->type;
 
   CHECK_UNIT(punit);
 
@@ -2254,15 +2255,16 @@ void ai_manage_units(struct player *ppla
  Whether unit_type test is on the "upgrade path" of unit_type base,
  even if we can't upgrade now.
 **************************************************************************/
-bool is_on_unit_upgrade_path(Unit_type_id test, Unit_type_id base)
+bool is_on_unit_upgrade_path(const struct unit_type *test,
+                            const struct unit_type *base)
 {
   /* This is the real function: */
   do {
-    base = unit_types[base].obsoleted_by;
+    base = base->obsoleted_by;
     if (base == test) {
       return TRUE;
     }
-  } while (base != -1);
+  } while (base);
   return FALSE;
 }
 
@@ -2270,7 +2272,8 @@ bool is_on_unit_upgrade_path(Unit_type_i
 Barbarian leader tries to stack with other barbarian units, and if it's
 not possible it runs away. When on coast, it may disappear with 33% chance.
 **************************************************************************/
-static void ai_manage_barbarian_leader(struct player *pplayer, struct unit 
*leader)
+static void ai_manage_barbarian_leader(struct player *pplayer,
+                                      struct unit *leader)
 {
   Continent_id con = tile_get_continent(leader->tile);
   int safest = 0;
@@ -2403,16 +2406,16 @@ void update_simple_ai_types(void)
 {
   int i = 0;
 
-  unit_type_iterate(id) {
-    if (!unit_type_flag(id, F_NONMIL)
-       && !unit_type_flag(id, F_MISSILE)
-       && !unit_type_flag(id, F_NO_LAND_ATTACK)
-        && get_unit_type(id)->move_type != AIR_MOVING
-       && get_unit_type(id)->transport_capacity < 8) {
-      simple_ai_types[i] = id;
+  unit_type_iterate(punittype) {
+    if (!unit_type_flag(punittype, F_NONMIL)
+       && !unit_type_flag(punittype, F_MISSILE)
+       && !unit_type_flag(punittype, F_NO_LAND_ATTACK)
+        && punittype->move_type != AIR_MOVING
+       && punittype->transport_capacity < 8) {
+      simple_ai_types[i] = punittype;
       i++;
     }
   } unit_type_iterate_end;
 
-  simple_ai_types[i] = U_LAST;
+  simple_ai_types[i] = NULL;
 }
Index: ai/aiunit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.h,v
retrieving revision 1.59
diff -p -u -r1.59 aiunit.h
--- ai/aiunit.h 30 Apr 2005 17:09:25 -0000      1.59
+++ ai/aiunit.h 19 Jul 2005 03:41:45 -0000
@@ -45,7 +45,7 @@
 struct ai_choice;
 struct pf_path;
 
-extern Unit_type_id simple_ai_types[U_LAST];
+extern struct unit_type *simple_ai_types[U_LAST];
 
 void ai_manage_units(struct player *pplayer); 
 void ai_manage_unit(struct player *pplayer, struct unit *punit);
@@ -55,39 +55,43 @@ int could_unit_move_to_tile(struct unit 
 int look_for_charge(struct player *pplayer, struct unit *punit,
                     struct unit **aunit, struct city **acity);
 
-int turns_to_enemy_city(Unit_type_id our_type, struct city *acity,
+int turns_to_enemy_city(const struct unit_type *our_type, struct city *acity,
                         int speed, bool go_by_boat, 
-                        struct unit *boat, Unit_type_id boattype);
-int turns_to_enemy_unit(Unit_type_id our_type, int speed, struct tile *ptile, 
-                        Unit_type_id enemy_type);
+                        struct unit *boat, const struct unit_type *boattype);
+int turns_to_enemy_unit(const struct unit_type *our_type,
+                       int speed, struct tile *ptile, 
+                        const struct unit_type *enemy_type);
 int find_something_to_kill(struct player *pplayer, struct unit *punit, 
                           struct tile **ptile);
 
-int build_cost_balanced(Unit_type_id type);
-int unittype_att_rating(Unit_type_id type, int veteran,
+int build_cost_balanced(const struct unit_type *punittype);
+int unittype_att_rating(const struct unit_type *punittype, int veteran,
                         int moves_left, int hp);
 int unit_att_rating(struct unit *punit);
 int unit_def_rating_basic(struct unit *punit);
 int unit_def_rating_basic_sq(struct unit *punit);
-int unittype_def_rating_sq(Unit_type_id att_type, Unit_type_id def_type,
+int unittype_def_rating_sq(const struct unit_type *att_type,
+                          const struct unit_type *def_type,
                            struct tile *ptile, bool fortified, int veteran);
 int kill_desire(int benefit, int attack, int loss, int vuln, int attack_count);
 
-bool is_on_unit_upgrade_path(Unit_type_id test, Unit_type_id base);
+bool is_on_unit_upgrade_path(const struct unit_type *test,
+                            const struct unit_type *base);
 
 void update_simple_ai_types(void);
 
-#define simple_ai_unit_type_iterate(m_i)                                      \
-{                                                                             \
-  int m_c;                                                                    \
-  for (m_c = 0;; m_c++) {                                                     \
-    Unit_type_id m_i = simple_ai_types[m_c];                                  \
-    if (m_i == U_LAST) {                                                      \
-      break;                                                                  \
+#define simple_ai_unit_type_iterate(m_i)                                    \
+{                                                                           \
+  int m_c;                                                                  \
+  for (m_c = 0;; m_c++) {                                                   \
+    struct unit_type * m_i = simple_ai_types[m_c];                         \
+                                                                           \
+    if (!m_i) {                                                                
    \
+      break;                                                                \
     }
 
-#define simple_ai_unit_type_iterate_end                                       \
- }                                                                            \
+#define simple_ai_unit_type_iterate_end                                     \
+ }                                                                          \
 }
 
 #endif  /* FC__AIUNIT_H */
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.81
diff -p -u -r1.81 citydlg_common.c
--- client/citydlg_common.c     4 Jul 2005 17:48:36 -0000       1.81
+++ client/citydlg_common.c     19 Jul 2005 03:41:45 -0000
@@ -219,7 +219,7 @@ void get_city_dialog_production(struct c
   stock = pcity->shield_stock;
 
   if (pcity->is_building_unit) {
-    cost = unit_build_shield_cost(pcity->currently_building);
+    cost = unit_build_shield_cost(get_unit_type(pcity->currently_building));
   } else {
     cost = impr_build_shield_cost(pcity->currently_building);
   }
@@ -275,8 +275,8 @@ void get_city_dialog_production_full(cha
     int cost;
 
     if (is_unit) {
-      name = get_unit_name(id);
-      cost = unit_build_shield_cost(id);
+      name = get_unit_name(get_unit_type(id));
+      cost = unit_build_shield_cost(get_unit_type(id));
     } else {
       name = get_impr_name_ex(pcity, id);
       cost = impr_build_shield_cost(id);
@@ -303,7 +303,7 @@ void get_city_dialog_production_row(char
   if (is_unit) {
     struct unit_type *ptype = get_unit_type(id);
 
-    my_snprintf(buf[0], column_size, unit_name(id));
+    my_snprintf(buf[0], column_size, unit_name(ptype));
 
     /* from unit.h get_unit_name() */
     if (ptype->fuel > 0) {
@@ -315,7 +315,7 @@ void get_city_dialog_production_row(char
       my_snprintf(buf[1], column_size, "%d/%d/%d", ptype->attack_strength,
                  ptype->defense_strength, ptype->move_rate / 3);
     }
-    my_snprintf(buf[2], column_size, "%d", unit_build_shield_cost(id));
+    my_snprintf(buf[2], column_size, "%d", unit_build_shield_cost(ptype));
   } else {
     struct player *pplayer = game.player_ptr;
 
@@ -638,7 +638,8 @@ static bool base_city_queue_insert(struc
     bool old_is_unit;
 
     /* Insert as current production. */
-    if (item_is_unit && !can_build_unit_direct(pcity, item_id)) {
+    if (item_is_unit
+       && !can_build_unit_direct(pcity, get_unit_type(item_id))) {
       return FALSE;
     }
     if (!item_is_unit && !can_build_improvement_direct(pcity, item_id)) {
@@ -655,7 +656,8 @@ static bool base_city_queue_insert(struc
   } else if (position >= 1
             && position <= worklist_length(&pcity->worklist)) {
     /* Insert into middle. */
-    if (item_is_unit && !can_eventually_build_unit(pcity, item_id)) {
+    if (item_is_unit
+       && !can_eventually_build_unit(pcity, get_unit_type(item_id))) {
       return FALSE;
     }
     if (!item_is_unit && !can_eventually_build_improvement(pcity, item_id)) {
@@ -667,7 +669,8 @@ static bool base_city_queue_insert(struc
     }
   } else {
     /* Insert at end. */
-    if (item_is_unit && !can_eventually_build_unit(pcity, item_id)) {
+    if (item_is_unit
+       && !can_eventually_build_unit(pcity, get_unit_type(item_id))) {
       return FALSE;
     }
     if (!item_is_unit && !can_eventually_build_improvement(pcity, item_id)) {
Index: client/cityrepdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/cityrepdata.c,v
retrieving revision 1.51
diff -p -u -r1.51 cityrepdata.c
--- client/cityrepdata.c        10 May 2005 17:01:23 -0000      1.51
+++ client/cityrepdata.c        19 Jul 2005 03:41:45 -0000
@@ -140,7 +140,7 @@ static const char *cr_entry_attack(const
 
   unit_list_iterate(pcity->tile->units, punit) {
     /* What about allied units?  Should we just count them? */
-    attack_best[3] = get_unit_type(punit->type)->attack_strength;
+    attack_best[3] = punit->type->attack_strength;
 
     /* Now that the element is appended to the end of the list, we simply
        do an insertion sort. */
@@ -172,7 +172,7 @@ static const char *cr_entry_defense(cons
 
   unit_list_iterate(pcity->tile->units, punit) {
     /* What about allied units?  Should we just count them? */
-    defense_best[3] = get_unit_type(punit->type)->defense_strength;
+    defense_best[3] = punit->type->defense_strength;
 
     /* Now that the element is appended to the end of the list, we simply
        do an insertion sort. */
@@ -377,7 +377,7 @@ static const char *cr_entry_building(con
 
     if(pcity->is_building_unit) {
       name = get_unit_type(pcity->currently_building)->name;
-      cost = unit_build_shield_cost(pcity->currently_building);
+      cost = unit_build_shield_cost(get_unit_type(pcity->currently_building));
     } else {
       name = get_impr_name_ex(pcity, pcity->currently_building);
       cost = impr_build_shield_cost(pcity->currently_building);
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.169
diff -p -u -r1.169 climisc.c
--- client/climisc.c    4 Jul 2005 17:48:36 -0000       1.169
+++ client/climisc.c    19 Jul 2005 03:41:45 -0000
@@ -180,7 +180,7 @@ void client_change_all(cid x, cid y)
          !(pcity->is_building_unit) &&
          (pcity->currently_building == fr_id))) &&
        ((to_is_unit &&
-         can_build_unit (pcity, to_id)) ||
+         can_build_unit (pcity, get_unit_type(to_id))) ||
         (!to_is_unit &&
          can_build_improvement (pcity, to_id))))
       {
@@ -537,7 +537,7 @@ int wid_id(wid wid)
 bool city_can_build_impr_or_unit(struct city *pcity, cid cid)
 {
   if (cid_is_unit(cid))
-    return can_build_unit(pcity, cid_id(cid));
+    return can_build_unit(pcity, get_unit_type(cid_id(cid)));
   else
     return can_build_improvement(pcity, cid_id(cid));
 }
@@ -548,13 +548,12 @@ bool city_can_build_impr_or_unit(struct 
 bool city_unit_supported(struct city *pcity, cid cid)
 {
   if (cid_is_unit(cid)) {
-    int unit_type = cid_id(cid);
+    struct unit_type *unit_type = get_unit_type(cid_id(cid));
 
     unit_list_iterate(pcity->units_supported, punit) {
       if (punit->type == unit_type)
        return TRUE;
-    }
-    unit_list_iterate_end;
+    } unit_list_iterate_end;
   }
   return FALSE;
 }
@@ -565,7 +564,7 @@ bool city_unit_supported(struct city *pc
 bool city_unit_present(struct city *pcity, cid cid)
 {
   if (cid_is_unit(cid)) {
-    int unit_type = cid_id(cid);
+    struct unit_type *unit_type = get_unit_type(cid_id(cid));
 
     unit_list_iterate(pcity->tile->units, punit) {
       if (punit->type == unit_type)
@@ -598,7 +597,7 @@ static int cid_get_section(cid cid)
   int id = cid_id(cid);
 
   if (is_unit) {
-    if (unit_type_flag(id, F_NONMIL)) {
+    if (unit_type_flag(get_unit_type(id), F_NONMIL)) {
       return 2;
     } else {
       return 3;
@@ -652,8 +651,8 @@ void name_and_sort_items(int *pcids, int
     pitem->cid = pcids[i];
 
     if (is_unit) {
-      name = get_unit_name(id);
-      cost = unit_build_shield_cost(id);
+      name = get_unit_name(get_unit_type(id));
+      cost = unit_build_shield_cost(get_unit_type(id));
     } else {
       name = get_impr_name_ex(pcity, id);
       if (building_has_effect(id, EFT_PROD_TO_GOLD)) {
@@ -759,8 +758,10 @@ int collect_cids3(cid * dest_cids)
     }
   } impr_type_iterate_end;
 
-  unit_type_iterate(id) {
-    if (can_player_build_unit(game.player_ptr, id)) {
+  unit_type_iterate(punittype) {
+    const int id = punittype->index;
+
+    if (can_player_build_unit(game.player_ptr, punittype)) {
       dest_cids[cids_used] = cid_encode(TRUE, id);
       cids_used++;
     }
@@ -796,16 +797,17 @@ int collect_cids4(cid * dest_cids, struc
     }
   } impr_type_iterate_end;
 
-  unit_type_iterate(id) {
-    bool can_build = can_player_build_unit(game.player_ptr, id);
+  unit_type_iterate(punittype) {
+    bool can_build = can_player_build_unit(game.player_ptr, punittype);
     bool can_eventually_build =
-       can_player_eventually_build_unit(game.player_ptr, id);
+       can_player_eventually_build_unit(game.player_ptr, punittype);
+    const int id = punittype->index;
 
     /* If there's a city, can the city build the unit? */
     if (pcity) {
-      can_build = can_build && can_build_unit(pcity, id);
+      can_build = can_build && can_build_unit(pcity, punittype);
       can_eventually_build = can_eventually_build &&
-         can_eventually_build_unit(pcity, id);
+         can_eventually_build_unit(pcity, punittype);
     }
 
     if ((advanced_tech && can_eventually_build) ||
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.119
diff -p -u -r1.119 helpdata.c
--- client/helpdata.c   14 Jul 2005 19:25:44 -0000      1.119
+++ client/helpdata.c   19 Jul 2005 03:41:45 -0000
@@ -366,9 +366,9 @@ void boot_help_texts(void)
        struct help_list *category_nodes = help_list_new();
        
        if (current_type == HELP_UNIT) {
-         unit_type_iterate(i) {
+         unit_type_iterate(punittype) {
            pitem = new_help_item(current_type);
-           my_snprintf(name, sizeof(name), " %s", unit_name(i));
+           my_snprintf(name, sizeof(name), " %s", unit_name(punittype));
            pitem->topic = mystrdup(name);
            pitem->text = mystrdup("");
            help_list_append(category_nodes, pitem);
@@ -660,26 +660,24 @@ char *helptext_building(char *buf, size_
 
   if (building_has_effect(which, EFT_ENABLE_NUKE)
       && num_role_units(F_NUCLEAR) > 0) {
-    Unit_type_id u;
+    struct unit_type *u;
     Tech_type_id t;
 
     u = get_role_unit(F_NUCLEAR, 0);
-    assert(u < game.control.num_unit_types);
-    t = get_unit_type(u)->tech_requirement;
+    CHECK_UNIT_TYPE(u);
+    t = u->tech_requirement;
     assert(t < game.control.num_tech_types);
 
     cat_snprintf(buf, bufsz,
                 _("* Allows all players with knowledge of %s "
                   "to build %s units.\n"),
-                get_tech_name(game.player_ptr, t), get_unit_type(u)->name);
+                get_tech_name(game.player_ptr, t), u->name);
     cat_snprintf(buf, bufsz, "  ");
   }
 
   insert_allows(&source, buf + strlen(buf), bufsz - strlen(buf));
 
-  unit_type_iterate(utype) {
-    const struct unit_type *u = get_unit_type(utype);
-
+  unit_type_iterate(u) {
     if (u->impr_requirement == which) {
       if (u->tech_requirement != A_LAST) {
        cat_snprintf(buf, bufsz, _("* Allows %s (with %s).\n"), u->name,
@@ -738,14 +736,11 @@ static int techs_with_flag_string(enum t
   Append misc dynamic text for units.
   Transport capacity, unit flags, fuel.
 *****************************************************************/
-void helptext_unit(char *buf, int i, const char *user_text)
+void helptext_unit(char *buf, struct unit_type *utype, const char *user_text)
 {
-  struct unit_type *utype;
-
   assert(buf&&user_text);
-  utype = get_unit_type(i);
   if (!utype) {
-    freelog(LOG_ERROR, "Unknown unit %d.", i);
+    freelog(LOG_ERROR, "Unknown unit!");
     strcpy(buf, user_text);
     return;
   }
@@ -756,18 +751,18 @@ void helptext_unit(char *buf, int i, con
            _("* Can only be built with %s as government.\n"), 
             get_government_name(utype->gov_requirement));
   }
-  if (unit_type_flag(i, F_NOBUILD)) {
+  if (unit_type_flag(utype, F_NOBUILD)) {
     sprintf(buf + strlen(buf),
            _("* May not be built in cities.\n"));
   }
-  if (unit_type_flag(i, F_NOHOME)) {
+  if (unit_type_flag(utype, F_NOHOME)) {
     sprintf(buf + strlen(buf), _("* Never has a home city.\n"));
   }
-  if (unit_type_flag(i, F_GAMELOSS)) {
+  if (unit_type_flag(utype, F_GAMELOSS)) {
     sprintf(buf + strlen(buf),
            _("* Losing this unit will lose you the game!\n"));
   }
-  if (unit_type_flag(i, F_UNIQUE)) {
+  if (unit_type_flag(utype, F_UNIQUE)) {
     sprintf(buf + strlen(buf),
            _("* Each player may only have one of this type of unit.\n"));
   }
@@ -776,12 +771,12 @@ void helptext_unit(char *buf, int i, con
            utype->pop_cost);
   }
   if (utype->transport_capacity>0) {
-    if (unit_type_flag(i, F_CARRIER)) {
+    if (unit_type_flag(utype, F_CARRIER)) {
       sprintf(buf + strlen(buf),
              PL_("* Can carry and refuel %d air unit.\n",
                  "* Can carry and refuel %d air units.\n",
                  utype->transport_capacity), utype->transport_capacity);
-    } else if (unit_type_flag(i, F_MISSILE_CARRIER)) {
+    } else if (unit_type_flag(utype, F_MISSILE_CARRIER)) {
       sprintf(buf + strlen(buf),
              PL_("* Can carry and refuel %d missile unit.\n",
                  "* Can carry and refuel %d missile units.\n",
@@ -793,7 +788,7 @@ void helptext_unit(char *buf, int i, con
                  utype->transport_capacity), utype->transport_capacity);
     }
   }
-  if (unit_type_flag(i, F_TRADE_ROUTE)) {
+  if (unit_type_flag(utype, F_TRADE_ROUTE)) {
     /* TRANS: "Manhattan" distance is the distance along gridlines, with
      * no diagonals allowed. */
     sprintf(buf + strlen(buf), _("* Can establish trade routes (must travel "
@@ -801,26 +796,27 @@ void helptext_unit(char *buf, int i, con
                                 "tiles [in Manhattan distance] from this "
                                 "unit's home city).\n"));
   }
-  if (unit_type_flag(i, F_HELP_WONDER)) {
+  if (unit_type_flag(utype, F_HELP_WONDER)) {
     sprintf(buf + strlen(buf),
            _("* Can help build wonders (adds %d production).\n"),
            utype->build_cost);
   }
-  if (unit_type_flag(i, F_UNDISBANDABLE)) {
+  if (unit_type_flag(utype, F_UNDISBANDABLE)) {
     sprintf(buf + strlen(buf), _("* May not be disbanded.\n"));
   } else {
     sprintf(buf + strlen(buf), _("* May be disbanded in a city to "
                                 "recover 50%% of the production cost.\n"));
   }
-  if (unit_type_flag(i, F_CITIES)) {
+  if (unit_type_flag(utype, F_CITIES)) {
     sprintf(buf + strlen(buf), _("* Can build new cities.\n"));
   }
-  if (unit_type_flag(i, F_ADD_TO_CITY)) {
+  if (unit_type_flag(utype, F_ADD_TO_CITY)) {
     sprintf(buf + strlen(buf), _("* Can add on %d population to "
                                 "cities of no more than size %d.\n"),
-           unit_pop_value(i), game.info.add_to_size_limit - unit_pop_value(i));
+           unit_pop_value(utype),
+           game.info.add_to_size_limit - unit_pop_value(utype));
   }
-  if (unit_type_flag(i, F_SETTLERS)) {
+  if (unit_type_flag(utype, F_SETTLERS)) {
     char buf2[1024];
 
     /* Roads, rail, mines, irrigation. */
@@ -865,120 +861,120 @@ void helptext_unit(char *buf, int i, con
     sprintf(buf + strlen(buf),
            _("* Can clean nuclear fallout from tiles.\n"));
   }
-  if (unit_type_flag(i, F_TRANSFORM)) {
+  if (unit_type_flag(utype, F_TRANSFORM)) {
     sprintf(buf + strlen(buf), _("* Can transform tiles.\n"));
   }
-  if (unit_type_flag(i, F_AIRBASE)) {
+  if (unit_type_flag(utype, F_AIRBASE)) {
     sprintf(buf + strlen(buf), _("* Can build airbases.\n"));
   }
-  if (is_ground_unittype(i) && !unit_type_flag(i, F_SETTLERS)) {
+  if (is_ground_unittype(utype) && !unit_type_flag(utype, F_SETTLERS)) {
     sprintf(buf + strlen(buf),
            _("* May fortify, granting a 50%% defensive bonus.\n"));
   }
-  if (is_ground_unittype(i)) {
+  if (is_ground_unittype(utype)) {
     sprintf(buf + strlen(buf),
            _("* May pillage to destroy infrastructure from tiles.\n"));
   }
-  if (unit_type_flag(i, F_DIPLOMAT)) {
-    if (unit_type_flag(i, F_SPY)) {
+  if (unit_type_flag(utype, F_DIPLOMAT)) {
+    if (unit_type_flag(utype, F_SPY)) {
       sprintf(buf + strlen(buf), _("* Can perform diplomatic actions,"
                                   " plus special spy abilities.\n"));
     } else {
       sprintf(buf + strlen(buf), _("* Can perform diplomatic actions.\n"));
     }
   }
-  if (unit_type_flag(i, F_SUPERSPY)) {
+  if (unit_type_flag(utype, F_SUPERSPY)) {
     sprintf(buf + strlen(buf), _("* Will never lose a "
                                 "diplomat-versus-diplomat fight.\n"));
   }
-  if (unit_type_flag(i, F_UNBRIBABLE)) {
+  if (unit_type_flag(utype, F_UNBRIBABLE)) {
     sprintf(buf + strlen(buf), _("* May not be bribed.\n"));
   }
-  if (unit_type_flag(i, F_FIGHTER)) {
+  if (unit_type_flag(utype, F_FIGHTER)) {
     sprintf(buf + strlen(buf), _("* Can attack enemy air units.\n"));
   }
-  if (unit_type_flag(i, F_PARTIAL_INVIS)) {
+  if (unit_type_flag(utype, F_PARTIAL_INVIS)) {
     sprintf(buf + strlen(buf), _("* Is invisible except when next to an"
                                 " enemy unit or city.\n"));
   }
-  if (unit_type_flag(i, F_NO_LAND_ATTACK)) {
+  if (unit_type_flag(utype, F_NO_LAND_ATTACK)) {
     sprintf(buf + strlen(buf), _("* Can only attack units on ocean squares"
                                 " (no land attacks).\n"));
   }
-  if (unit_type_flag(i, F_MARINES)) {
+  if (unit_type_flag(utype, F_MARINES)) {
     sprintf(buf + strlen(buf),
            _("* Can attack from aboard sea units: against"
              " enemy cities and onto land squares.\n"));
   }
-  if (unit_type_flag(i, F_PARATROOPERS)) {
+  if (unit_type_flag(utype, F_PARATROOPERS)) {
     sprintf(buf + strlen(buf),
            _("* Can be paradropped from a friendly city"
              " (Range: %d).\n"), utype->paratroopers_range);
   }
-  if (unit_type_flag(i, F_PIKEMEN)) {
+  if (unit_type_flag(utype, F_PIKEMEN)) {
     sprintf(buf + strlen(buf), _("* Gets double defense against units"
                                 " specified as 'mounted'.\n"));
   }
-  if (unit_type_flag(i, F_HORSE)) {
+  if (unit_type_flag(utype, F_HORSE)) {
     sprintf(buf + strlen(buf),
            _("* Counts as 'mounted' against certain defenders.\n"));
   }
-  if (unit_type_flag(i, F_MISSILE)) {
+  if (unit_type_flag(utype, F_MISSILE)) {
     sprintf(buf + strlen(buf),
            _("* A missile unit: gets used up in making an attack.\n"));
-  } else if(unit_type_flag(i, F_ONEATTACK)) {
+  } else if(unit_type_flag(utype, F_ONEATTACK)) {
     sprintf(buf + strlen(buf),
            _("* Making an attack ends this unit's turn.\n"));
   }
-  if (unit_type_flag(i, F_NUCLEAR)) {
+  if (unit_type_flag(utype, F_NUCLEAR)) {
     sprintf(buf + strlen(buf),
            _("* This unit's attack causes a nuclear explosion!\n"));
   }
-  if (unit_type_flag(i, F_CITYBUSTER)) {
+  if (unit_type_flag(utype, F_CITYBUSTER)) {
     sprintf(buf + strlen(buf),
            _("* Gets double firepower when attacking cities.\n"));
   }
-  if (unit_type_flag(i, F_IGWALL)) {
+  if (unit_type_flag(utype, F_IGWALL)) {
     sprintf(buf + strlen(buf), _("* Ignores the effects of city walls.\n"));
   }
-  if (unit_type_flag(i, F_BOMBARDER)) {
+  if (unit_type_flag(utype, F_BOMBARDER)) {
     sprintf(buf + strlen(buf),
            _("* Does bombard attacks (%d per turn).  These attacks will "
              "only damage (never kill) the defender but has no risk to "
              "the attacker.\n"), utype->bombard_rate);
   }
-  if (unit_type_flag(i, F_AEGIS)) {
+  if (unit_type_flag(utype, F_AEGIS)) {
     sprintf(buf + strlen(buf),
            _("* Gets quintuple defence against missiles and aircraft.\n"));
   }
-  if (unit_type_flag(i, F_IGTER)) {
+  if (unit_type_flag(utype, F_IGTER)) {
     sprintf(buf + strlen(buf),
            _("* Ignores terrain effects (treats all squares as roads).\n"));
   }
-  if (unit_type_flag(i, F_IGTIRED)) {
+  if (unit_type_flag(utype, F_IGTIRED)) {
     sprintf(buf + strlen(buf),
            _("* Attacks with full strength even if less than "
              "one movement left.\n"));
   }
-  if (unit_type_flag(i, F_IGZOC)) {
+  if (unit_type_flag(utype, F_IGZOC)) {
     sprintf(buf + strlen(buf), _("* Ignores zones of control.\n"));
   }
-  if (unit_type_flag(i, F_NONMIL)) {
+  if (unit_type_flag(utype, F_NONMIL)) {
     sprintf(buf + strlen(buf), _("* A non-military unit"
                                 " (cannot attack; no martial law).\n"));
   }
-  if (unit_type_flag(i, F_FIELDUNIT)) {
+  if (unit_type_flag(utype, F_FIELDUNIT)) {
     sprintf(buf + strlen(buf), _("* A field unit: one unhappiness applies"
                                 " even when non-aggressive.\n"));
   }
-  if (unit_type_flag(i, F_NO_VETERAN)) {
+  if (unit_type_flag(utype, F_NO_VETERAN)) {
     sprintf(buf + strlen(buf),
            _("* Will never achieve veteran status.\n"));
   } else {
     sprintf(buf + strlen(buf),
            _("* May become veteran through training or combat.\n"));
   }
-  if (unit_type_flag(i, F_TRIREME)) {
+  if (unit_type_flag(utype, F_TRIREME)) {
     Tech_type_id tech1 = find_tech_by_flag(0, TF_REDUCE_TRIREME_LOSS1);
     Tech_type_id tech2 = find_tech_by_flag(0, TF_REDUCE_TRIREME_LOSS2);
     sprintf(buf + strlen(buf),
@@ -1007,23 +1003,25 @@ void helptext_unit(char *buf, int i, con
 
     n = num_role_units(F_CARRIER);
     for (j = 0; j < n; j++) {
-      Unit_type_id id = get_role_unit(F_CARRIER, j);
+      struct unit_type *punittype = get_role_unit(F_CARRIER, j);
 
       mystrlcpy(allowed_units[num_allowed_units],
-               unit_name(id), sizeof(allowed_units[num_allowed_units]));
+               unit_name(punittype),
+               sizeof(allowed_units[num_allowed_units]));
       num_allowed_units++;
       assert(num_allowed_units < ARRAY_SIZE(allowed_units));
     }
 
-    if (unit_type_flag(i, F_MISSILE)) {
+    if (unit_type_flag(utype, F_MISSILE)) {
       n = num_role_units(F_MISSILE_CARRIER);
 
       for (j = 0; j < n; j++) {
-       Unit_type_id id = get_role_unit(F_MISSILE_CARRIER, j);
+       struct unit_type *punittype = get_role_unit(F_MISSILE_CARRIER, j);
 
-       if (get_unit_type(id)->transport_capacity > 0) {
+       if (punittype->transport_capacity > 0) {
          mystrlcpy(allowed_units[num_allowed_units],
-                   unit_name(id), sizeof(allowed_units[num_allowed_units]));
+                   unit_name(punittype),
+                   sizeof(allowed_units[num_allowed_units]));
          num_allowed_units++;
          assert(num_allowed_units < ARRAY_SIZE(allowed_units));
        }
@@ -1472,12 +1470,10 @@ void helptext_government(char *buf, int 
              "bonuses against unhappiness will instead give gold.\n"));
   }
 #endif
-  unit_type_iterate(ut) {
-    struct unit_type *utype = get_unit_type(ut);
-
+  unit_type_iterate(utype) {
     if (utype->gov_requirement == i) {
       sprintf(buf + strlen(buf),
-             _("* Allows you to build %s.\n"), unit_name(ut));
+             _("* Allows you to build %s.\n"), unit_name(utype));
     }
   } unit_type_iterate_end;
   strcat(buf, user_text);
@@ -1487,15 +1483,13 @@ void helptext_government(char *buf, int 
 /****************************************************************
   Returns pointer to static string with eg: "1 shield, 1 unhappy"
 *****************************************************************/
-char *helptext_unit_upkeep_str(int i)
+char *helptext_unit_upkeep_str(struct unit_type *utype)
 {
   static char buf[128];
-  struct unit_type *utype;
   int any = 0;
 
-  utype = get_unit_type(i);
   if (!utype) {
-    freelog(LOG_ERROR, "Unknown unit %d.", i);
+    freelog(LOG_ERROR, "Unknown unit!");
     return "";
   }
 
Index: client/helpdata.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.h,v
retrieving revision 1.14
diff -p -u -r1.14 helpdata.h
--- client/helpdata.h   14 Jul 2005 19:25:44 -0000      1.14
+++ client/helpdata.h   19 Jul 2005 03:41:45 -0000
@@ -40,13 +40,14 @@ const struct help_item *help_iter_next(v
 
 char *helptext_building(char *buf, size_t bufsz, Impr_type_id which,
                        const char *user_text);
-void helptext_unit(char *buf, int i, const char *user_text);
+void helptext_unit(char *buf, struct unit_type *punittype,
+                  const char *user_text);
 void helptext_tech(char *buf, int i, const char *user_text);
 void helptext_terrain(char *buf, const struct terrain *pterrain,
                      const char *user_text);
 void helptext_government(char *buf, int i, const char *user_text);
 
-char *helptext_unit_upkeep_str(int i);
+char *helptext_unit_upkeep_str(struct unit_type *punittype);
 
 #define help_items_iterate(pitem) {       \
         const struct help_item *pitem;    \
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.56
diff -p -u -r1.56 mapctrl_common.c
--- client/mapctrl_common.c     4 Jul 2005 17:48:36 -0000       1.56
+++ client/mapctrl_common.c     19 Jul 2005 03:41:45 -0000
@@ -340,12 +340,12 @@ void clipboard_copy_production(struct ti
     if (!can_player_build_unit_direct(game.player_ptr, punit->type))  {
       my_snprintf(msg, sizeof(msg),
       _("You don't know how to build %s!"),
-        unit_types[punit->type].name);
+                 punit->type->name);
       append_output_window(msg);
       return;
     }
     clipboard_is_unit = TRUE;
-    clipboard = punit->type;
+    clipboard = punit->type->index;
   }
   upgrade_canvas_clipboard();
 
@@ -409,9 +409,11 @@ static void clipboard_send_production_pa
 void upgrade_canvas_clipboard(void)
 {
   if (clipboard_is_unit)  {
-    int u = can_upgrade_unittype(game.player_ptr, clipboard);
-    if (u != -1)  {
-      clipboard = u;
+    struct unit_type *u = can_upgrade_unittype(game.player_ptr,
+                                              get_unit_type(clipboard));
+
+    if (u)  {
+      clipboard = u->index;
     }
   }
 }
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.534
diff -p -u -r1.534 packhand.c
--- client/packhand.c   18 Jul 2005 22:46:27 -0000      1.534
+++ client/packhand.c   19 Jul 2005 03:41:46 -0000
@@ -82,7 +82,8 @@ static int reports_thaw_requests_size = 
 static struct unit * unpackage_unit(struct packet_unit_info *packet)
 {
   struct unit *punit = create_unit_virtual(get_player(packet->owner), NULL,
-                                          packet->type, packet->veteran);
+                                          get_unit_type(packet->type),
+                                          packet->veteran);
 
   /* Owner, veteran, and type fields are already filled in by
    * create_unit_virtual. */
@@ -141,7 +142,8 @@ static struct unit * unpackage_unit(stru
 static struct unit *unpackage_short_unit(struct packet_unit_short_info *packet)
 {
   struct unit *punit = create_unit_virtual(get_player(packet->owner), NULL,
-                                          packet->type, FALSE);
+                                          get_unit_type(packet->type),
+                                          FALSE);
 
   /* Owner and type fields are already filled in by create_unit_virtual. */
   punit->id = packet->id;
@@ -2078,7 +2080,7 @@ void handle_ruleset_unit(struct packet_r
   u->transport_capacity = p->transport_capacity;
   u->hp                 = p->hp;
   u->firepower          = p->firepower;
-  u->obsoleted_by       = p->obsoleted_by;
+  u->obsoleted_by = get_unit_type(p->obsoleted_by);
   u->fuel               = p->fuel;
   u->flags              = p->flags;
   u->roles              = p->roles;
@@ -2099,7 +2101,7 @@ void handle_ruleset_unit(struct packet_r
 
   u->helptext = mystrdup(p->helptext);
 
-  tileset_setup_unit_type(tileset, p->id);
+  tileset_setup_unit_type(tileset, u);
 }
 
 /**************************************************************************
Index: client/repodlgs_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/repodlgs_common.c,v
retrieving revision 1.25
diff -p -u -r1.25 repodlgs_common.c
--- client/repodlgs_common.c    5 May 2005 18:32:47 -0000       1.25
+++ client/repodlgs_common.c    19 Jul 2005 03:41:46 -0000
@@ -95,10 +95,8 @@ void get_economy_report_units_data(struc
                                   int *num_entries_used, int *total_cost)
 {
   int count, cost, partial_cost;
-  struct unit_type *unittype;
 
-  unit_type_iterate(utype) {
-    unittype = get_unit_type(utype);
+  unit_type_iterate(unittype) {
     cost = utype_upkeep_cost(unittype, game.player_ptr,
                              get_gov_pplayer(game.player_ptr), O_GOLD);
 
@@ -113,7 +111,7 @@ void get_economy_report_units_data(struc
     city_list_iterate(game.player_ptr->cities, pcity) {
       unit_list_iterate(pcity->units_supported, punit) {
 
-       if (punit->type == utype) {
+       if (punit->type == unittype) {
          count++;
          partial_cost += punit->upkeep[O_GOLD];
        }
@@ -127,7 +125,7 @@ void get_economy_report_units_data(struc
 
     (*total_cost) += partial_cost;
 
-    entries[*num_entries_used].type = utype;
+    entries[*num_entries_used].type = unittype;
     entries[*num_entries_used].count = count;
     entries[*num_entries_used].cost = cost;
     entries[*num_entries_used].total_cost = partial_cost;
@@ -346,7 +344,7 @@ void sell_all_improvements(Impr_type_id 
   The "message" string will be filled with a GUI-friendly message about
   what was sold.
 ****************************************************************************/
-void disband_all_units(Unit_type_id type, bool in_cities_only,
+void disband_all_units(struct unit_type *punittype, bool in_cities_only,
                       char *message, size_t message_sz)
 {
   int count = 0;
@@ -357,9 +355,9 @@ void disband_all_units(Unit_type_id type
     return;
   }
 
-  if (unit_type_flag(type, F_UNDISBANDABLE)) {
+  if (unit_type_flag(punittype, F_UNDISBANDABLE)) {
     my_snprintf(message, message_sz, _("%s cannot be disbanded."),
-               unit_name(type));
+               unit_name(punittype));
     return;
   }
 
@@ -369,7 +367,7 @@ void disband_all_units(Unit_type_id type
     unit_list_iterate(pcity->units_supported, punit) {
       struct city *incity = tile_get_city(punit->tile);
 
-      if (punit->type == type
+      if (punit->type == punittype
          && (!in_cities_only
              || (incity && city_owner(incity) == game.player_ptr))) {
        count++;
@@ -380,9 +378,9 @@ void disband_all_units(Unit_type_id type
 
   if (count > 0) {
     my_snprintf(message, message_sz, _("Disbanded %d %s."),
-               count, unit_name(type));
+               count, unit_name(punittype));
   } else {
     my_snprintf(message, message_sz, _("No %s could be disbanded."),
-               unit_name(type));
+               unit_name(punittype));
   }
 }
Index: client/repodlgs_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/repodlgs_common.h,v
retrieving revision 1.8
diff -p -u -r1.8 repodlgs_common.h
--- client/repodlgs_common.h    30 Apr 2005 17:09:25 -0000      1.8
+++ client/repodlgs_common.h    19 Jul 2005 03:41:46 -0000
@@ -27,7 +27,7 @@ struct improvement_entry
 
 struct unit_entry
 {
-  Unit_type_id type;
+  struct unit_type *type;
   int count, cost, total_cost;
 };
 
@@ -75,7 +75,7 @@ void settable_options_free(void);
 
 void sell_all_improvements(Impr_type_id impr, bool obsolete_only,
                           char *message, size_t message_sz);
-void disband_all_units(Unit_type_id type, bool in_cities_only,
+void disband_all_units(struct unit_type *punittype, bool in_cities_only,
                       char *message, size_t message_sz);
 
 #endif /* FC__REPODLGS_COMMON_H */
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.315
diff -p -u -r1.315 tilespec.c
--- client/tilespec.c   18 Jul 2005 22:46:27 -0000      1.315
+++ client/tilespec.c   19 Jul 2005 03:41:47 -0000
@@ -881,8 +881,8 @@ void tilespec_reread(const char *new_til
   terrain_type_iterate(pterrain) {
     tileset_setup_tile_type(tileset, pterrain);
   } terrain_type_iterate_end;
-  unit_type_iterate(id) {
-    tileset_setup_unit_type(tileset, id);
+  unit_type_iterate(punittype) {
+    tileset_setup_unit_type(tileset, punittype);
   } unit_type_iterate_end;
   government_iterate(gov) {
     tileset_setup_government(tileset, gov->index);
@@ -2339,11 +2339,9 @@ static struct sprite* lookup_sprite_tag_
   Set unit_type sprite value; should only happen after
   tilespec_load_tiles().
 ***********************************************************************/
-void tileset_setup_unit_type(struct tileset *t, int id)
+void tileset_setup_unit_type(struct tileset *t, struct unit_type *ut)
 {
-  struct unit_type *ut = get_unit_type(id);
-
-  t->sprites.unittype[id]
+  t->sprites.unittype[ut->index]
     = lookup_sprite_tag_alt(t, ut->graphic_str, ut->graphic_alt,
                            TRUE, "unit_type", ut->name);
 
@@ -2791,7 +2789,7 @@ static int fill_unit_sprite_array(const 
     }
   }
 
-  ADD_SPRITE(t->sprites.unittype[punit->type], TRUE,
+  ADD_SPRITE(t->sprites.unittype[punit->type->index], TRUE,
             FULL_TILE_X_OFFSET + t->unit_offset_x,
             FULL_TILE_Y_OFFSET + t->unit_offset_y);
 
@@ -4374,13 +4372,14 @@ struct sprite *get_government_sprite(con
 /****************************************************************************
   Return the sprite for the unit type (the base "unit" sprite).
 ****************************************************************************/
-struct sprite *get_unittype_sprite(const struct tileset *t, Unit_type_id id)
+struct sprite *get_unittype_sprite(const struct tileset *t,
+                                  const struct unit_type *punittype)
 {
-  if (id < 0 || id >= game.control.num_unit_types) {
+  if (!punittype) {
     assert(0);
     return NULL;
   }
-  return t->sprites.unittype[id];
+  return t->sprites.unittype[punittype->index];
 }
 
 /**************************************************************************
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.156
diff -p -u -r1.156 tilespec.h
--- client/tilespec.h   18 Jul 2005 22:46:27 -0000      1.156
+++ client/tilespec.h   19 Jul 2005 03:41:47 -0000
@@ -112,7 +112,7 @@ void tilespec_reread(const char *tileset
 void tilespec_reread_callback(struct client_option *option);
 
 void tileset_setup_specialist_type(struct tileset *t, int id);
-void tileset_setup_unit_type(struct tileset *t, int id);
+void tileset_setup_unit_type(struct tileset *t, struct unit_type *punittype);
 void tileset_setup_impr_type(struct tileset *t, int id);
 void tileset_setup_tech_type(struct tileset *t, int id);
 void tileset_setup_tile_type(struct tileset *t,
@@ -195,7 +195,8 @@ struct sprite *get_tech_sprite(const str
 struct sprite *get_building_sprite(const struct tileset *t, Impr_type_id b);
 struct sprite *get_government_sprite(const struct tileset *t,
                                     const struct government *gov);
-struct sprite *get_unittype_sprite(const struct tileset *t, Unit_type_id id);
+struct sprite *get_unittype_sprite(const struct tileset *t,
+                                  const struct unit_type *punittype);
 struct sprite *get_sample_city_sprite(const struct tileset *t,
                                      int city_style);
 struct sprite *get_arrow_sprite(const struct tileset *t);
Index: client/agents/agents.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/agents/agents.c,v
retrieving revision 1.33
diff -p -u -r1.33 agents.c
--- client/agents/agents.c      3 May 2005 06:48:04 -0000       1.33
+++ client/agents/agents.c      19 Jul 2005 03:41:47 -0000
@@ -519,7 +519,7 @@ void agents_unit_changed(struct unit *pu
 
   freelog(LOG_DEBUG,
          "A: agents_unit_changed(unit=%d) type=%s pos=(%d,%d) owner=%s",
-         punit->id, unit_types[punit->type].name, TILE_XY(punit->tile),
+         punit->id, punit->type->name, TILE_XY(punit->tile),
          unit_owner(punit)->name);
 
   for (i = 0; i < agents.entries_used; i++) {
@@ -545,7 +545,7 @@ void agents_unit_new(struct unit *punit)
 
   freelog(LOG_DEBUG,
          "A: agents_new_unit(unit=%d) type=%s pos=(%d,%d) owner=%s",
-         punit->id, unit_types[punit->type].name, TILE_XY(punit->tile),
+         punit->id, punit->type->name, TILE_XY(punit->tile),
          unit_owner(punit)->name);
 
   for (i = 0; i < agents.entries_used; i++) {
@@ -572,7 +572,7 @@ void agents_unit_remove(struct unit *pun
 
   freelog(LOG_DEBUG,
          "A: agents_remove_unit(unit=%d) type=%s pos=(%d,%d) owner=%s",
-         punit->id, unit_types[punit->type].name, TILE_XY(punit->tile),
+         punit->id, punit->type->name, TILE_XY(punit->tile),
          unit_owner(punit)->name);
 
   for (i = 0; i < agents.entries_used; i++) {
Index: client/agents/cma_fec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/agents/cma_fec.c,v
retrieving revision 1.31
diff -p -u -r1.31 cma_fec.c
--- client/agents/cma_fec.c     7 Feb 2005 08:14:48 -0000       1.31
+++ client/agents/cma_fec.c     19 Jul 2005 03:41:47 -0000
@@ -286,7 +286,7 @@ static const char *get_prod_complete_str
 
   stock = pcity->shield_stock;
   if (pcity->is_building_unit) {
-    cost = unit_build_shield_cost(pcity->currently_building);
+    cost = unit_build_shield_cost(get_unit_type(pcity->currently_building));
   } else {
     if (get_current_construction_bonus(pcity, EFT_PROD_TO_GOLD) > 0) {
       my_snprintf(buffer, sizeof(buffer),
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.130
diff -p -u -r1.130 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        4 Jul 2005 17:48:36 -0000       1.130
+++ client/gui-gtk-2.0/citydlg.c        19 Jul 2005 03:41:47 -0000
@@ -1516,7 +1516,7 @@ static void city_dialog_update_building(
   get_city_dialog_production(pcity, buf, sizeof(buf));
 
   if (pcity->is_building_unit) {
-    cost = unit_build_shield_cost(pcity->currently_building);
+    cost = unit_build_shield_cost(get_unit_type(pcity->currently_building));
     descr = get_unit_type(pcity->currently_building)->name;
   } else {
     cost = impr_build_shield_cost(pcity->currently_building);;
@@ -1559,8 +1559,8 @@ static void city_dialog_update_building(
 
       cid_decode(items[item].cid, &is_unit, &id);
       if (is_unit) {
-       name = unit_name(id);
-       sprite = get_unittype_sprite(tileset, id);
+       name = unit_name(get_unit_type(id));
+       sprite = get_unittype_sprite(tileset, get_unit_type(id));
       } else {
        name = get_improvement_name(id);
        sprite = get_building_sprite(tileset, id);
@@ -2093,7 +2093,7 @@ static gboolean present_unit_callback(Gt
       GINT_TO_POINTER(punit->id));
     gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
 
-    if (can_upgrade_unittype(game.player_ptr, punit->type) == -1) {
+    if (can_upgrade_unittype(game.player_ptr, punit->type) == NULL) {
       gtk_widget_set_sensitive(item, FALSE);
     }
 
Index: client/gui-gtk-2.0/graphics.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.c,v
retrieving revision 1.45
diff -p -u -r1.45 graphics.c
--- client/gui-gtk-2.0/graphics.c       10 Apr 2005 01:59:31 -0000      1.45
+++ client/gui-gtk-2.0/graphics.c       19 Jul 2005 03:41:47 -0000
@@ -102,11 +102,11 @@ void load_cursors(void)
 /***************************************************************************
  ...
 ***************************************************************************/
-void create_overlay_unit(struct canvas *pcanvas, int i)
+void create_overlay_unit(struct canvas *pcanvas, struct unit_type *punittype)
 {
   int x1, x2, y1, y2;
   int width, height;
-  struct sprite *sprite = get_unittype_sprite(tileset, i);
+  struct sprite *sprite = get_unittype_sprite(tileset, punittype);
 
   sprite_get_bounding_box(sprite, &x1, &y1, &x2, &y2);
   if (pcanvas->type == CANVAS_PIXBUF) {
Index: client/gui-gtk-2.0/graphics.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/graphics.h,v
retrieving revision 1.17
diff -p -u -r1.17 graphics.h
--- client/gui-gtk-2.0/graphics.h       28 Mar 2005 16:59:14 -0000      1.17
+++ client/gui-gtk-2.0/graphics.h       19 Jul 2005 03:41:47 -0000
@@ -21,7 +21,7 @@
 #include "canvas.h"
 #include "sprite.h"
 
-void create_overlay_unit(struct canvas *pcanvas, int i);
+void create_overlay_unit(struct canvas *pcanvas, struct unit_type *punittype);
 
 extern struct sprite *intro_gfx_sprite;
 extern struct sprite *radar_gfx_sprite;
Index: client/gui-gtk-2.0/helpdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/helpdlg.c,v
retrieving revision 1.55
diff -p -u -r1.55 helpdlg.c
--- client/gui-gtk-2.0/helpdlg.c        14 Jul 2005 19:25:44 -0000      1.55
+++ client/gui-gtk-2.0/helpdlg.c        19 Jul 2005 03:41:48 -0000
@@ -782,15 +782,14 @@ static void help_update_wonder(const str
 ...
 **************************************************************************/
 static void help_update_unit_type(const struct help_item *pitem,
-                                 char *title, int i)
+                                 char *title, struct unit_type *utype)
 {
   char *buf = &long_buffer[0];
 
   create_help_page(HELP_UNIT);
 
-  if (i<game.control.num_unit_types) {
-    struct unit_type *utype = get_unit_type(i);
-    sprintf(buf, "%d", unit_build_shield_cost(i));
+  if (utype) {
+    sprintf(buf, "%d", unit_build_shield_cost(utype));
     gtk_label_set_text(GTK_LABEL(help_ulabel[0][1]), buf);
     sprintf(buf, "%d", utype->attack_strength);
     gtk_label_set_text(GTK_LABEL(help_ulabel[0][4]), buf);
@@ -802,7 +801,8 @@ static void help_update_unit_type(const 
     gtk_label_set_text(GTK_LABEL(help_ulabel[2][1]), buf);
     sprintf(buf, "%d", utype->hp);
     gtk_label_set_text(GTK_LABEL(help_ulabel[2][4]), buf);
-    gtk_label_set_text(GTK_LABEL(help_ulabel[3][1]), 
helptext_unit_upkeep_str(i));
+    gtk_label_set_text(GTK_LABEL(help_ulabel[3][1]),
+                      helptext_unit_upkeep_str(utype));
     sprintf(buf, "%d", utype->vision_range);
     gtk_label_set_text(GTK_LABEL(help_ulabel[3][4]), buf);
     if(utype->tech_requirement==A_LAST) {
@@ -816,10 +816,11 @@ static void help_update_unit_type(const 
     if (utype->obsoleted_by == U_NOT_OBSOLETED) {
       gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]), _("None"));
     } else {
-      gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]), 
get_unit_type(utype->obsoleted_by)->name);
+      gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]),
+                        utype->obsoleted_by->name);
     }
 
-    helptext_unit(buf, i, pitem->text);
+    helptext_unit(buf, utype, pitem->text);
 
     gtk_text_buffer_set_text(help_text, buf, -1);
     gtk_widget_show(help_text_sw);
@@ -830,7 +831,7 @@ static void help_update_unit_type(const 
 
       store.type = CANVAS_PIXCOMM;
       store.v.pixcomm = GTK_PIXCOMM(unit_tile);
-      create_overlay_unit(&store, i);
+      create_overlay_unit(&store, utype);
     }
     gtk_pixcomm_thaw(GTK_PIXCOMM(unit_tile));
     gtk_widget_show(unit_tile);
@@ -959,8 +960,10 @@ static void help_update_tech(const struc
       }
     } impr_type_iterate_end;
 
-    unit_type_iterate(j) {
-      if(i!=get_unit_type(j)->tech_requirement) continue;
+    unit_type_iterate(punittype) {
+      if (i != punittype->tech_requirement) {
+       continue;
+      }
       hbox = gtk_hbox_new(FALSE, 0);
       gtk_container_add(GTK_CONTAINER(help_vbox), hbox);
       w = gtk_label_new(_("Allows"));
Index: client/gui-gtk-2.0/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/repodlgs.c,v
retrieving revision 1.92
diff -p -u -r1.92 repodlgs.c
--- client/gui-gtk-2.0/repodlgs.c       16 Jul 2005 09:04:53 -0000      1.92
+++ client/gui-gtk-2.0/repodlgs.c       19 Jul 2005 03:41:48 -0000
@@ -831,7 +831,7 @@ static void economy_command_callback(str
     if (response== ECONOMY_SELL_OBSOLETE) {
       return;
     }
-    disband_all_units(i, FALSE, buf, sizeof(buf));
+    disband_all_units(get_unit_type(i), FALSE, buf, sizeof(buf));
   }
 
   shell = gtk_message_dialog_new(
@@ -898,7 +898,7 @@ void economy_report_dialog_update(void)
       g_value_unset(&value);
     
       economy_row_type[i + nbr_impr].is_impr = FALSE;
-      economy_row_type[i + nbr_impr].type = entries_units[i].type;
+      economy_row_type[i + nbr_impr].type = entries_units[i].type->index;
     }
 
     my_snprintf(economy_total, sizeof(economy_total),
@@ -1057,17 +1057,20 @@ void create_activeunits_report_dialog(bo
 static void activeunits_selection_callback(GtkTreeSelection *selection,
                                           gpointer data)
 {
-  int ut;
+  struct unit_type *utype;
   GtkTreeModel *model;
   GtkTreeIter it;
 
-  ut = U_LAST;
+  utype = NULL;
   if (gtk_tree_selection_get_selected(activeunits_selection, &model, &it)) {
+    int ut;
+
     gtk_tree_model_get(model, &it, AU_COL + 1, &ut, -1);
+    utype = get_unit_type(ut);
   }
 
 
-  if (ut == U_LAST) {
+  if (utype == NULL) {
     gui_dialog_set_response_sensitive(activeunits_dialog_shell,
                                      ACTIVEUNITS_NEAREST, FALSE);
 
@@ -1078,7 +1081,7 @@ static void activeunits_selection_callba
                                      ACTIVEUNITS_NEAREST,
                                      can_client_issue_orders());       
     
-    if (can_upgrade_unittype(game.player_ptr, ut) != -1) {
+    if (can_upgrade_unittype(game.player_ptr, utype) != NULL) {
       gui_dialog_set_response_sensitive(activeunits_dialog_shell,
                                        ACTIVEUNITS_UPGRADE,
                                        can_client_issue_orders());     
@@ -1092,7 +1095,8 @@ static void activeunits_selection_callba
 /****************************************************************
 ...
 *****************************************************************/
-static struct unit *find_nearest_unit(Unit_type_id type, struct tile *ptile)
+static struct unit *find_nearest_unit(const struct unit_type *type,
+                                     struct tile *ptile)
 {
   struct unit *best_candidate;
   int best_dist = 99999;
@@ -1123,7 +1127,7 @@ static struct unit *find_nearest_unit(Un
 static void activeunits_command_callback(struct gui_dialog *dlg, int response,
                                          gpointer data)
 {
-  int           ut1, ut2;
+  struct unit_type *utype1 = NULL;
   GtkTreeModel *model;
   GtkTreeIter   it;
 
@@ -1137,19 +1141,21 @@ static void activeunits_command_callback
   }
 
   /* nearest & upgrade commands. */
-  ut1 = U_LAST;
   if (gtk_tree_selection_get_selected(activeunits_selection, &model, &it)) {
-    gtk_tree_model_get(model, &it, AU_COL + 1, &ut1, -1);
+    int ut;
+
+    gtk_tree_model_get(model, &it, AU_COL + 1, &ut, -1);
+    utype1 = get_unit_type(ut);
   }
 
-  CHECK_UNIT_TYPE(ut1);
+  CHECK_UNIT_TYPE(utype1);
 
   if (response == ACTIVEUNITS_NEAREST) {
     struct tile *ptile;
     struct unit *punit;
 
     ptile = get_center_tile_mapcanvas();
-    if ((punit = find_nearest_unit(ut1, ptile))) {
+    if ((punit = find_nearest_unit(utype1, ptile))) {
       center_tile_mapcanvas(punit->tile);
 
       if (punit->activity == ACTIVITY_IDLE
@@ -1161,8 +1167,7 @@ static void activeunits_command_callback
     }
   } else {
     GtkWidget *shell;
-
-    ut2 = can_upgrade_unittype(game.player_ptr, ut1);
+    struct unit_type *ut2 = can_upgrade_unittype(game.player_ptr, utype1);
 
     shell = gtk_message_dialog_new(
          NULL,
@@ -1170,15 +1175,15 @@ static void activeunits_command_callback
          GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
          _("Upgrade as many %s to %s as possible for %d gold each?\n"
            "Treasury contains %d gold."),
-         unit_types[ut1].name, unit_types[ut2].name,
-         unit_upgrade_price(game.player_ptr, ut1, ut2),
+         utype1->name, ut2->name,
+         unit_upgrade_price(game.player_ptr, utype1, ut2),
          game.player_ptr->economic.gold);
     setup_dialog(shell, gui_dialog_get_toplevel(dlg));
 
     gtk_window_set_title(GTK_WINDOW(shell), _("Upgrade Obsolete Units"));
 
     if (gtk_dialog_run(GTK_DIALOG(shell)) == GTK_RESPONSE_YES) {
-      dsend_packet_unit_type_upgrade(&aconnection, ut1);
+      dsend_packet_unit_type_upgrade(&aconnection, utype1->index);
     }
 
     gtk_widget_destroy(shell);
@@ -1210,10 +1215,10 @@ void activeunits_report_dialog_update(vo
 
     memset(unitarray, '\0', sizeof(unitarray));
     unit_list_iterate(game.player_ptr->units, punit) {
-      (unitarray[punit->type].active_count)++;
+      (unitarray[punit->type->index].active_count)++;
       if (punit->homecity) {
        output_type_iterate(o) {
-         unitarray[punit->type].upkeep[o] += punit->upkeep[o];
+         unitarray[punit->type->index].upkeep[o] += punit->upkeep[o];
        } output_type_iterate_end;
       }
     } unit_list_iterate_end;
@@ -1226,33 +1231,35 @@ void activeunits_report_dialog_update(vo
 
     k = 0;
     memset(&unittotals, '\0', sizeof(unittotals));
-    unit_type_iterate(i) {
-    
-      if (unitarray[i].active_count > 0
-         || unitarray[i].building_count > 0) {
-       can = (can_upgrade_unittype(game.player_ptr, i) != -1);
+    unit_type_iterate(punittype) {
+      if (unitarray[punittype->index].active_count > 0
+         || unitarray[punittype->index].building_count > 0) {
+       can = (can_upgrade_unittype(game.player_ptr, punittype) != NULL);
        
         gtk_list_store_append(activeunits_store, &it);
        gtk_list_store_set(activeunits_store, &it,
                1, can,
-               2, unitarray[i].building_count,
-               3, unitarray[i].active_count,
-               4, unitarray[i].upkeep[O_SHIELD],
-               5, unitarray[i].upkeep[O_FOOD],
-               6, unitarray[i].upkeep[O_GOLD],
+               2, unitarray[punittype->index].building_count,
+               3, unitarray[punittype->index].active_count,
+               4, unitarray[punittype->index].upkeep[O_SHIELD],
+               5, unitarray[punittype->index].upkeep[O_FOOD],
+               6, unitarray[punittype->index].upkeep[O_GOLD],
                7, TRUE,
-               8, ((unitarray[i].active_count > 0) ? i : U_LAST), -1);
+               8, ((unitarray[punittype->index].active_count > 0)
+                   ? punittype->index : U_LAST),
+               -1);
        g_value_init(&value, G_TYPE_STRING);
-       g_value_set_static_string(&value, unit_name(i));
+       g_value_set_static_string(&value, unit_name(punittype));
        gtk_list_store_set_value(activeunits_store, &it, 0, &value);
        g_value_unset(&value);
 
        k++;
-       unittotals.active_count += unitarray[i].active_count;
+       unittotals.active_count += unitarray[punittype->index].active_count;
        output_type_iterate(o) {
-         unittotals.upkeep[o] += unitarray[i].upkeep[o];         
+         unittotals.upkeep[o] += unitarray[punittype->index].upkeep[o];        
  
        } output_type_iterate_end;
-       unittotals.building_count += unitarray[i].building_count;
+       unittotals.building_count
+         += unitarray[punittype->index].building_count;
       }
     } unit_type_iterate_end;
 
Index: client/gui-gtk-2.0/wldlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/wldlg.c,v
retrieving revision 1.45
diff -p -u -r1.45 wldlg.c
--- client/gui-gtk-2.0/wldlg.c  10 Apr 2005 01:59:31 -0000      1.45
+++ client/gui-gtk-2.0/wldlg.c  19 Jul 2005 03:41:48 -0000
@@ -972,7 +972,7 @@ static void cell_render_func(GtkTreeView
 
       store.type = CANVAS_PIXBUF;
       store.v.pixbuf = pix;
-      create_overlay_unit(&store, id);
+      create_overlay_unit(&store, get_unit_type(id));
 
       g_object_set(rend, "pixbuf", pix, NULL);
       g_object_unref(pix);
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.354
diff -p -u -r1.354 city.c
--- common/city.c       14 Jul 2005 19:25:45 -0000      1.354
+++ common/city.c       19 Jul 2005 03:41:49 -0000
@@ -372,7 +372,8 @@ int city_buy_cost(const struct city *pci
   int cost, build = pcity->shield_stock;
 
   if (pcity->is_building_unit) {
-    cost = unit_buy_gold_cost(pcity->currently_building, build);
+    cost = unit_buy_gold_cost(get_unit_type(pcity->currently_building),
+                             build);
   } else {
     cost = impr_buy_gold_cost(pcity->currently_building, build);
   }
@@ -453,23 +454,24 @@ bool can_eventually_build_improvement(co
   Return whether given city can build given unit, ignoring whether unit 
   is obsolete.
 **************************************************************************/
-bool can_build_unit_direct(const struct city *pcity, Unit_type_id id)
+bool can_build_unit_direct(const struct city *pcity,
+                          const struct unit_type *punittype)
 {
   Impr_type_id impr_req;
 
-  if (!can_player_build_unit_direct(city_owner(pcity), id)) {
+  if (!can_player_build_unit_direct(city_owner(pcity), punittype)) {
     return FALSE;
   }
 
   /* Check to see if the unit has a building requirement. */
-  impr_req = get_unit_type(id)->impr_requirement;
+  impr_req = punittype->impr_requirement;
   assert(impr_req <= B_LAST && impr_req >= 0);
   if (impr_req != B_LAST && !city_got_building(pcity, impr_req)) {
     return FALSE;
   }
 
   /* You can't build naval units inland. */
-  if (!is_ocean_near_tile(pcity->tile) && is_sailing_unittype(id)) {
+  if (!is_ocean_near_tile(pcity->tile) && is_sailing_unittype(punittype)) {
     return FALSE;
   }
   return TRUE;
@@ -479,13 +481,14 @@ bool can_build_unit_direct(const struct 
   Return whether given city can build given unit; returns 0 if unit is 
   obsolete.
 **************************************************************************/
-bool can_build_unit(const struct city *pcity, Unit_type_id id)
+bool can_build_unit(const struct city *pcity,
+                   const struct unit_type *punittype)
 {  
-  if (!can_build_unit_direct(pcity, id)) {
+  if (!can_build_unit_direct(pcity, punittype)) {
     return FALSE;
   }
-  while ((id = unit_types[id].obsoleted_by) != U_NOT_OBSOLETED) {
-    if (can_player_build_unit_direct(city_owner(pcity), id)) {
+  while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
+    if (can_player_build_unit_direct(city_owner(pcity), punittype)) {
        return FALSE;
     }
   }
@@ -496,16 +499,17 @@ bool can_build_unit(const struct city *p
   Return whether player can eventually build given unit in the city;
   returns 0 if unit can never possibly be built in this city.
 **************************************************************************/
-bool can_eventually_build_unit(const struct city *pcity, Unit_type_id id)
+bool can_eventually_build_unit(const struct city *pcity,
+                              const struct unit_type *punittype)
 {
   /* Can the _player_ ever build this unit? */
-  if (!can_player_eventually_build_unit(city_owner(pcity), id)) {
+  if (!can_player_eventually_build_unit(city_owner(pcity), punittype)) {
     return FALSE;
   }
 
   /* Some units can be built only in certain cities -- for instance,
      ships may be built only in cities adjacent to ocean. */
-  if (!is_ocean_near_tile(pcity->tile) && is_sailing_unittype(id)) {
+  if (!is_ocean_near_tile(pcity->tile) && is_sailing_unittype(punittype)) {
     return FALSE;
   }
 
@@ -1252,7 +1256,7 @@ int city_turns_to_build(const struct cit
   int city_shield_stock = include_shield_stock ?
       city_change_production_penalty(pcity, id, id_is_unit) : 0;
   int improvement_cost = id_is_unit ?
-    unit_build_shield_cost(id) : impr_build_shield_cost(id);
+    unit_build_shield_cost(get_unit_type(id)) : impr_build_shield_cost(id);
 
   if (include_shield_stock && (city_shield_stock >= improvement_cost)) {
     return 1;
@@ -2397,11 +2401,11 @@ struct city *create_city_virtual(struct 
   init_worklist(&pcity->worklist);
 
   {
-    int u = best_role_unit(pcity, L_FIRSTBUILD);
+    struct unit_type *u = best_role_unit(pcity, L_FIRSTBUILD);
 
-    if (u < U_LAST && u >= 0) {
+    if (u) {
       pcity->is_building_unit = TRUE;
-      pcity->currently_building = u;
+      pcity->currently_building = u->index;
     } else {
       bool found = FALSE;
 
@@ -2417,11 +2421,11 @@ struct city *create_city_virtual(struct 
       } impr_type_iterate_end;
 
       if (!found) {
-       unit_type_iterate(id) {
-         if (can_build_unit_direct(pcity, id)) {
+       unit_type_iterate(punittype) {
+         if (can_build_unit_direct(pcity, punittype)) {
            found = TRUE;
            pcity->is_building_unit = TRUE;
-           pcity->currently_building = id;
+           pcity->currently_building = punittype->index;
          }
        } unit_type_iterate_end;
       }
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.216
diff -p -u -r1.216 city.h
--- common/city.h       4 Jul 2005 17:48:37 -0000       1.216
+++ common/city.h       19 Jul 2005 03:41:49 -0000
@@ -386,9 +386,12 @@ bool can_build_improvement_direct(const 
 bool can_build_improvement(const struct city *pcity, Impr_type_id id);
 bool can_eventually_build_improvement(const struct city *pcity,
                                      Impr_type_id id);
-bool can_build_unit(const struct city *pcity, Unit_type_id id);
-bool can_build_unit_direct(const struct city *pcity, Unit_type_id id);
-bool can_eventually_build_unit(const struct city *pcity, Unit_type_id id);
+bool can_build_unit(const struct city *pcity,
+                   const struct unit_type *punittype);
+bool can_build_unit_direct(const struct city *pcity,
+                          const struct unit_type *punittype);
+bool can_eventually_build_unit(const struct city *pcity,
+                              const struct unit_type *punittype);
 bool city_can_use_specialist(const struct city *pcity,
                             Specialist_type_id type);
 bool city_got_building(const struct city *pcity,  Impr_type_id id); 
Index: common/combat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v
retrieving revision 1.59
diff -p -u -r1.59 combat.c
--- common/combat.c     14 Jul 2005 19:25:45 -0000      1.59
+++ common/combat.c     19 Jul 2005 03:41:49 -0000
@@ -356,14 +356,15 @@ int get_attack_power(const struct unit *
  status. Set moves_left to SINGLE_MOVE to disable the reduction of
  power caused by tired units.
 **************************************************************************/
-int base_get_attack_power(Unit_type_id type, int veteran, int moves_left)
+int base_get_attack_power(const struct unit_type *punittype,
+                         int veteran, int moves_left)
 {
   int power;
 
-  power = get_unit_type(type)->attack_strength * POWER_FACTOR;
-  power *= get_unit_type(type)->veteran[veteran].power_fact;
+  power = punittype->attack_strength * POWER_FACTOR;
+  power *= punittype->veteran[veteran].power_fact;
 
-  if (!unit_type_flag(type, F_IGTIRED) && moves_left < SINGLE_MOVE) {
+  if (!unit_type_flag(punittype, F_IGTIRED) && moves_left < SINGLE_MOVE) {
     power = (power * moves_left) / SINGLE_MOVE;
   }
   return power;
@@ -416,8 +417,8 @@ int get_total_attack_power(const struct 
 May be called with a non-existing att_type to avoid any unit type
 effects.
 **************************************************************************/
-static int defense_multiplication(Unit_type_id att_type,
-                                 Unit_type_id def_type,
+static int defense_multiplication(const struct unit_type *att_type,
+                                 const struct unit_type *def_type,
                                  const struct tile *ptile,
                                  int defensepower, bool fortified)
 {
@@ -426,7 +427,7 @@ static int defense_multiplication(Unit_t
 
   CHECK_UNIT_TYPE(def_type);
 
-  if (att_type != U_LAST) {
+  if (att_type) {
     CHECK_UNIT_TYPE(att_type);
 
     if (unit_type_flag(def_type, F_PIKEMEN)
@@ -480,14 +481,15 @@ static int defense_multiplication(Unit_t
  May be called with a non-existing att_type to avoid any effects which
  depend on the attacker.
 **************************************************************************/
-int get_virtual_defense_power(Unit_type_id att_type, Unit_type_id def_type,
+int get_virtual_defense_power(const struct unit_type *att_type,
+                             const struct unit_type *def_type,
                              const struct tile *ptile,
                              bool fortified, int veteran)
 {
-  int defensepower = unit_types[def_type].defense_strength;
+  int defensepower = def_type->defense_strength;
   int db;
 
-  if (unit_types[def_type].move_type == LAND_MOVING
+  if (def_type->move_type == LAND_MOVING
       && is_ocean(ptile->terrain)) {
     /* Ground units on ship doesn't defend. */
     return 0;
@@ -498,7 +500,7 @@ int get_virtual_defense_power(Unit_type_
     db += (db * terrain_control.river_defense_bonus) / 100;
   }
   defensepower *= db;
-  defensepower *= get_unit_type(def_type)->veteran[veteran].power_fact;
+  defensepower *= def_type->veteran[veteran].power_fact;
 
   return defense_multiplication(att_type, def_type, ptile, defensepower,
                                fortified);
Index: common/combat.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.h,v
retrieving revision 1.16
diff -p -u -r1.16 combat.h
--- common/combat.h     30 Apr 2005 17:09:27 -0000      1.16
+++ common/combat.h     19 Jul 2005 03:41:49 -0000
@@ -48,12 +48,14 @@ struct city *sdi_defense_close(const str
                               const struct tile *ptile);
 
 int get_attack_power(const struct unit *punit);
-int base_get_attack_power(Unit_type_id type, int veteran, int moves_left);
+int base_get_attack_power(const struct unit_type *punittype,
+                         int veteran, int moves_left);
 int base_get_defense_power(const struct unit *punit);
 int get_defense_power(const struct unit *punit);
 int get_total_defense_power(const struct unit *attacker,
                            const struct unit *defender);
-int get_virtual_defense_power(Unit_type_id att_type, Unit_type_id def_type,
+int get_virtual_defense_power(const struct unit_type *attacker,
+                             const struct unit_type *defender,
                              const struct tile *ptile,
                              bool fortified, int veteran);
 int get_total_attack_power(const struct unit *attacker,
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.28
diff -p -u -r1.28 fc_types.h
--- common/fc_types.h   28 Jun 2005 17:21:01 -0000      1.28
+++ common/fc_types.h   19 Jul 2005 03:41:49 -0000
@@ -54,6 +54,8 @@ enum output_type_id {
 #define O_COUNT num_output_types
 #define O_MAX O_LAST /* Changing this breaks network compatibility. */
 
+/* Some integers here could be uint8 values perhaps, but this is probably
+ * not worth it.  Storage space is not an issue for these types. */
 typedef signed short Continent_id;
 typedef int Terrain_type_id;
 typedef int Specialist_type_id;
@@ -62,6 +64,7 @@ typedef enum output_type_id Output_type_
 typedef enum unit_activity Activity_type_id;
 typedef int Nation_type_id;
 typedef int Team_type_id;
+typedef int Unit_type_id;
 
 struct city;
 struct connection;
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.229
diff -p -u -r1.229 game.c
--- common/game.c       16 Jul 2005 08:59:26 -0000      1.229
+++ common/game.c       19 Jul 2005 03:41:49 -0000
@@ -568,9 +568,7 @@ void translate_data_names(void)
     tthis->name = Q_(tthis->name_orig);
   } tech_type_iterate_end;
 
-  unit_type_iterate(i) {
-    struct unit_type *tthis = &unit_types[i];
-
+  unit_type_iterate(tthis) {
     tthis->name = Q_(tthis->name_orig);
   } unit_type_iterate_end;
 
Index: common/improvement.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/improvement.h,v
retrieving revision 1.50
diff -p -u -r1.50 improvement.h
--- common/improvement.h        14 Jul 2005 19:25:45 -0000      1.50
+++ common/improvement.h        19 Jul 2005 03:41:49 -0000
@@ -20,7 +20,6 @@
 #include "effects.h"
 #include "fc_types.h"
 #include "tech.h"              /* Tech_type_id */
-#include "unittype.h"          /* Unit_Class_id, Unit_type_id */
 
 /* B_LAST is a value which is guaranteed to be larger than all
  * actual Impr_type_id values.  It is used as a flag value;
Index: common/movement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.c,v
retrieving revision 1.13
diff -p -u -r1.13 movement.c
--- common/movement.c   14 Jul 2005 19:25:45 -0000      1.13
+++ common/movement.c   19 Jul 2005 03:41:49 -0000
@@ -30,8 +30,8 @@
 #include "terrain.h"
 
 
-static bool can_unit_type_transport(Unit_type_id transporter,
-                                    Unit_type_id transported);
+static bool can_unit_type_transport(const struct unit_type *transporter,
+                                   const struct unit_type *transported);
 
 /****************************************************************************
   This function calculates the move rate of the unit, taking into 
@@ -129,36 +129,36 @@ bool is_ground_unit(const struct unit *p
 /****************************************************************************
   Return TRUE iff this unit type is a sailing/naval/sea/water unit type.
 ****************************************************************************/
-bool is_sailing_unittype(Unit_type_id id)
+bool is_sailing_unittype(const struct unit_type *punittype)
 {
-  return (unit_types[id].move_type == SEA_MOVING);
+  return (punittype->move_type == SEA_MOVING);
 }
 
 
 /****************************************************************************
   Return TRUE iff this unit type is an air unit type (including missiles).
 ****************************************************************************/
-bool is_air_unittype(Unit_type_id id)
+bool is_air_unittype(const struct unit_type *punittype)
 {
-  return (unit_types[id].move_type == AIR_MOVING);
+  return (punittype->move_type == AIR_MOVING);
 }
 
 
 /****************************************************************************
   Return TRUE iff this unit type is a helicopter unit type.
 ****************************************************************************/
-bool is_heli_unittype(Unit_type_id id)
+bool is_heli_unittype(const struct unit_type *punittype)
 {
-  return (unit_types[id].move_type == HELI_MOVING);
+  return (punittype->move_type == HELI_MOVING);
 }
 
 
 /****************************************************************************
   Return TRUE iff this unit type is a ground/land/normal unit type.
 ****************************************************************************/
-bool is_ground_unittype(Unit_type_id id)
+bool is_ground_unittype(const struct unit_type *punittype)
 {
-  return (unit_types[id].move_type == LAND_MOVING);
+  return (punittype->move_type == LAND_MOVING);
 }
 
 
@@ -185,7 +185,7 @@ bool can_unit_exist_at_tile(const struct
 bool is_native_terrain(const struct unit *punit,
                        const struct terrain *pterrain)
 {
-  switch (unit_types[punit->type].move_type) {
+  switch (punit->type->move_type) {
   case LAND_MOVING:
     return !is_ocean(pterrain);
   case SEA_MOVING:
@@ -217,7 +217,7 @@ bool can_unit_survive_at_tile(const stru
 
   /* TODO: check for dangerous positions (like triremes in deep water). */
 
-  switch (unit_types[punit->type].move_type) {
+  switch (punit->type->move_type) {
   case LAND_MOVING:
   case SEA_MOVING:
     return TRUE;
@@ -242,12 +242,12 @@ bool can_unit_survive_at_tile(const stru
     5. You're moving from an ocean square (from a boat)
     6. The spot you're moving from or to is in your ZOC
 ****************************************************************************/
-bool can_step_taken_wrt_to_zoc(Unit_type_id type,
+bool can_step_taken_wrt_to_zoc(const struct unit_type *punittype,
                                const struct player *unit_owner,
                                const struct tile *src_tile,
                                const struct tile *dst_tile)
 {
-  if (unit_type_really_ignores_zoc(type)) {
+  if (unit_type_really_ignores_zoc(punittype)) {
     return TRUE;
   }
   if (is_allied_unit_tile(dst_tile, unit_owner)) {
@@ -324,7 +324,7 @@ bool can_unit_move_to_tile(const struct 
     8) There is not a peaceful but un-allied city on the target tile.
     9) There is no non-allied unit blocking (zoc) [or igzoc is true].
 **************************************************************************/
-enum unit_move_result test_unit_move_to_tile(Unit_type_id type,
+enum unit_move_result test_unit_move_to_tile(const struct unit_type *punittype,
                                             const struct player *unit_owner,
                                             enum unit_activity activity,
                                             const struct tile *src_tile,
@@ -354,7 +354,7 @@ enum unit_move_result test_unit_move_to_
     return MR_DESTINATION_OCCUPIED_BY_NON_ALLIED_UNIT;
   }
 
-  if (unit_types[type].move_type == LAND_MOVING) {
+  if (punittype->move_type == LAND_MOVING) {
     /* 4) */
     if (is_ocean(dst_tile->terrain) &&
        ground_unit_transporter_capacity(dst_tile, unit_owner) <= 0) {
@@ -366,7 +366,7 @@ enum unit_move_result test_unit_move_to_
     /* Moving from ocean */
     if (is_ocean(src_tile->terrain)) {
       /* 5) */
-      if (!unit_type_flag(type, F_MARINES)
+      if (!unit_type_flag(punittype, F_MARINES)
          && is_enemy_city_tile(dst_tile, unit_owner)) {
        /* Most ground units can't move into cities from ships.  (Note this
         * check is only for movement, not attacking: most ground units
@@ -374,7 +374,7 @@ enum unit_move_result test_unit_move_to_
        return MR_BAD_TYPE_FOR_CITY_TAKE_OVER;
       }
     }
-  } else if (unit_types[type].move_type == SEA_MOVING) {
+  } else if (punittype->move_type == SEA_MOVING) {
     /* 6) */
     if (!is_ocean(dst_tile->terrain)
        && dst_tile->terrain != T_UNKNOWN
@@ -408,7 +408,7 @@ enum unit_move_result test_unit_move_to_
 
   /* 9) */
   zoc = igzoc
-    || can_step_taken_wrt_to_zoc(type, unit_owner, src_tile, dst_tile);
+    || can_step_taken_wrt_to_zoc(punittype, unit_owner, src_tile, dst_tile);
   if (!zoc) {
     /* The move is illegal because of zones of control. */
     return MR_ZOC;
@@ -429,14 +429,14 @@ bool can_unit_transport(const struct uni
 /**************************************************************************
   Return TRUE iff transporter type has ability to transport transported type.
 **************************************************************************/
-static bool can_unit_type_transport(Unit_type_id transporter,
-                                    Unit_type_id transported)
+static bool can_unit_type_transport(const struct unit_type *transporter,
+                                    const struct unit_type *transported)
 {
-  if (get_unit_type(transporter)->transport_capacity <= 0) {
+  if (transporter->transport_capacity <= 0) {
     return FALSE;
   }
 
-  if (get_unit_type(transported)->move_type == LAND_MOVING) {
+  if (transported->move_type == LAND_MOVING) {
     if ((unit_type_flag(transporter, F_CARRIER)
          || unit_type_flag(transporter, F_MISSILE_CARRIER))) {
       return FALSE;
@@ -454,13 +454,13 @@ static bool can_unit_type_transport(Unit
         && !unit_type_flag(transporter, F_CARRIER)) {
       return FALSE;
     }
-  } else if ((get_unit_type(transported)->move_type == AIR_MOVING
-              || get_unit_type(transported)->move_type == HELI_MOVING)
+  } else if ((transported->move_type == AIR_MOVING
+              || transported->move_type == HELI_MOVING)
              && !unit_type_flag(transporter, F_CARRIER)) {
     return FALSE;
   }
 
-  if (get_unit_type(transported)->move_type == SEA_MOVING) {
+  if (transported->move_type == SEA_MOVING) {
     /* No unit can transport sea units at the moment */
     return FALSE;
   }
Index: common/movement.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.h,v
retrieving revision 1.7
diff -p -u -r1.7 movement.h
--- common/movement.h   14 Jul 2005 19:25:45 -0000      1.7
+++ common/movement.h   19 Jul 2005 03:41:49 -0000
@@ -25,24 +25,24 @@ bool is_sailing_unit(const struct unit *
 bool is_air_unit(const struct unit *punit);
 bool is_heli_unit(const struct unit *punit);
 bool is_ground_unit(const struct unit *punit);
-bool is_sailing_unittype(Unit_type_id id);
-bool is_air_unittype(Unit_type_id id);
-bool is_heli_unittype(Unit_type_id id);
-bool is_ground_unittype(Unit_type_id id);
+bool is_sailing_unittype(const struct unit_type *punittype);
+bool is_air_unittype(const struct unit_type *punittype);
+bool is_heli_unittype(const struct unit_type *punittype);
+bool is_ground_unittype(const struct unit_type *punittype);
 
 bool is_native_terrain(const struct unit *punit,
                        const struct terrain *pterrain);
 bool can_unit_exist_at_tile(const struct unit *punit, const struct tile 
*ptile);
 bool can_unit_survive_at_tile(const struct unit *punit,
                              const struct tile *ptile);
-bool can_step_taken_wrt_to_zoc(Unit_type_id type,
+bool can_step_taken_wrt_to_zoc(const struct unit_type *punittype,
                               const struct player *unit_owner,
                               const struct tile *src_tile,
                               const struct tile *dst_tile);
 bool zoc_ok_move(const struct unit *punit, const struct tile *ptile);
 bool can_unit_move_to_tile(const struct unit *punit, const struct tile *ptile,
                           bool igzoc);
-enum unit_move_result test_unit_move_to_tile(Unit_type_id type,
+enum unit_move_result test_unit_move_to_tile(const struct unit_type *punittype,
                                             const struct player *unit_owner,
                                             enum unit_activity activity,
                                             const struct tile *src_tile,
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.53
diff -p -u -r1.53 nation.h
--- common/nation.h     18 Jul 2005 22:46:28 -0000      1.53
+++ common/nation.h     19 Jul 2005 03:41:49 -0000
@@ -17,7 +17,6 @@
 
 #include "fc_types.h"
 #include "terrain.h"           /* T_COUNT */
-#include "unittype.h"           /* Unit_type_id */
 
 #define MAX_NUM_TECH_GOALS 10
 
@@ -94,7 +93,7 @@ struct nation_type {
   int init_techs[MAX_NUM_TECH_LIST];
   int init_buildings[MAX_NUM_BUILDING_LIST];
   int init_government;
-  Unit_type_id init_units[MAX_NUM_UNIT_LIST];
+  struct unit_type *init_units[MAX_NUM_UNIT_LIST];
 
   /* Groups which this nation is assigned to */
   int num_groups;
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.30
diff -p -u -r1.30 requirements.c
--- common/requirements.c       18 Jul 2005 22:46:28 -0000      1.30
+++ common/requirements.c       19 Jul 2005 03:41:49 -0000
@@ -142,7 +142,7 @@ struct req_source req_source_from_str(co
     break;
   case REQ_UNITTYPE:
     source.value.unittype = find_unit_type_by_name(value);
-    if (source.value.unittype != U_LAST) {
+    if (source.value.unittype) {
       return source;
     }
     break;
@@ -210,7 +210,7 @@ struct req_source req_source_from_values
     source.value.nation = get_nation_by_idx(value);
     return source;
   case REQ_UNITTYPE:
-    source.value.unittype = value;
+    source.value.unittype = get_unit_type(value);
     return source;
   case REQ_UNITFLAG:
     source.value.unitflag = value;
@@ -266,7 +266,7 @@ void req_source_get_values(const struct 
     *value = source->value.nation->index;
     return;
   case REQ_UNITTYPE:
-    *value = source->value.unittype;
+    *value = source->value.unittype->index;
     return;
   case REQ_UNITFLAG:
     *value = source->value.unitflag;
@@ -716,11 +716,12 @@ static bool is_nation_in_range(const str
 ****************************************************************************/
 static bool is_unittype_in_range(const struct unit *target_unit,
                                 enum req_range range, bool survives,
-                                Unit_type_id unittype)
+                                struct unit_type *punittype)
 {
   return (range == REQ_RANGE_LOCAL
          && target_unit
-         && target_unit->type == unittype);
+         && punittype
+         && target_unit->type == punittype);
 }
 
 /****************************************************************************
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.21
diff -p -u -r1.21 requirements.h
--- common/requirements.h       18 Jul 2005 22:46:28 -0000      1.21
+++ common/requirements.h       19 Jul 2005 03:41:49 -0000
@@ -60,7 +60,7 @@ struct req_source {
     enum tile_special_type special;     /* source special */
     struct terrain *terrain;            /* source terrain type */
     struct nation_type *nation;         /* source nation type */
-    Unit_type_id unittype;              /* source unittype */
+    struct unit_type *unittype;         /* source unittype */
     enum unit_flag_id unitflag;         /* source unit flag */
     Output_type_id outputtype;          /* source output type */
     Specialist_type_id specialist;      /* specialist type */
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.245
diff -p -u -r1.245 unit.c
--- common/unit.c       14 Jul 2005 19:25:45 -0000      1.245
+++ common/unit.c       19 Jul 2005 03:41:50 -0000
@@ -437,7 +437,7 @@ bool can_unit_change_homecity(const stru
 **************************************************************************/
 int get_activity_rate(const struct unit *punit)
 {
-  int fact = get_unit_type(punit->type)->veteran[punit->veteran].power_fact;
+  int fact = punit->type->veteran[punit->veteran].power_fact;
 
   /* The speed of the settler depends on its base move_rate, not on
    * the number of moves actually remaining or the adjusted move rate.
@@ -1309,9 +1309,10 @@ bool is_my_zoc(const struct player *ppla
 /**************************************************************************
   Takes into account unit move_type as well as IGZOC
 **************************************************************************/
-bool unit_type_really_ignores_zoc(Unit_type_id type)
+bool unit_type_really_ignores_zoc(const struct unit_type *punittype)
 {
-  return (!is_ground_unittype(type)) || (unit_type_flag(type, F_IGZOC));
+  return (!is_ground_unittype(punittype)
+         || unit_type_flag(punittype, F_IGZOC));
 }
 
 /**************************************************************************
@@ -1430,11 +1431,13 @@ bool is_build_or_clean_activity(enum uni
   to set x, y and homecity yourself.
 **************************************************************************/
 struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity,
-                                 Unit_type_id type, int veteran_level)
+                                 struct unit_type *punittype,
+                                int veteran_level)
 {
   struct unit *punit = fc_calloc(1, sizeof(struct unit));
 
-  punit->type = type;
+  CHECK_UNIT_TYPE(punittype); /* No untyped units! */
+  punit->type = punittype;
   assert(pplayer != NULL); /* No unowned units! */
   punit->owner = pplayer;
   if (pcity) {
@@ -1552,11 +1555,11 @@ enum unit_upgrade_result test_unit_upgra
                                           bool is_free)
 {
   struct player *pplayer = unit_owner(punit);
-  Unit_type_id to_unittype = can_upgrade_unittype(pplayer, punit->type);
+  struct unit_type *to_unittype = can_upgrade_unittype(pplayer, punit->type);
   struct city *pcity;
   int cost;
 
-  if (to_unittype == -1) {
+  if (!to_unittype) {
     return UR_NO_UNITTYPE;
   }
 
@@ -1576,8 +1579,7 @@ enum unit_upgrade_result test_unit_upgra
     }
   }
 
-  if (get_transporter_occupancy(punit) >
-      unit_types[to_unittype].transport_capacity) {
+  if (get_transporter_occupancy(punit) > to_unittype->transport_capacity) {
     /* TODO: allow transported units to be reassigned.  Check for
      * ground_unit_transporter_capacity here and make changes to
      * upgrade_unit. */
@@ -1597,8 +1599,8 @@ enum unit_upgrade_result get_unit_upgrad
   struct player *pplayer = unit_owner(punit);
   enum unit_upgrade_result result = test_unit_upgrade(punit, FALSE);
   int upgrade_cost;
-  Unit_type_id from_unittype = punit->type;
-  Unit_type_id to_unittype = can_upgrade_unittype(pplayer,
+  struct unit_type *from_unittype = punit->type;
+  struct unit_type *to_unittype = can_upgrade_unittype(pplayer,
                                                  punit->type);
 
   switch (result) {
@@ -1607,20 +1609,20 @@ enum unit_upgrade_result get_unit_upgrad
     /* This message is targeted toward the GUI callers. */
     my_snprintf(buf, bufsz, _("Upgrade %s to %s for %d gold?\n"
                              "Treasury contains %d gold."),
-               unit_types[from_unittype].name, unit_types[to_unittype].name,
+               from_unittype->name, to_unittype->name,
                upgrade_cost, pplayer->economic.gold);
     break;
   case UR_NO_UNITTYPE:
     my_snprintf(buf, bufsz,
                _("Sorry, cannot upgrade %s (yet)."),
-               unit_types[from_unittype].name);
+               from_unittype->name);
     break;
   case UR_NO_MONEY:
     upgrade_cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
     my_snprintf(buf, bufsz,
                _("Upgrading %s to %s costs %d gold.\n"
                  "Treasury contains %d gold."),
-               unit_types[from_unittype].name, unit_types[to_unittype].name,
+               from_unittype->name, to_unittype->name,
                upgrade_cost, pplayer->economic.gold);
     break;
   case UR_NOT_IN_CITY:
@@ -1631,7 +1633,7 @@ enum unit_upgrade_result get_unit_upgrad
   case UR_NOT_ENOUGH_ROOM:
     my_snprintf(buf, bufsz,
                _("Upgrading this %s would strand units it transports."),
-               unit_types[from_unittype].name);
+               from_unittype->name);
     break;
   }
 
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.145
diff -p -u -r1.145 unit.h
--- common/unit.h       4 Jul 2005 17:48:37 -0000       1.145
+++ common/unit.h       19 Jul 2005 03:41:50 -0000
@@ -124,7 +124,7 @@ struct unit_ai {
 };
 
 struct unit {
-  Unit_type_id type;
+  struct unit_type *type;
   int id;
   struct player *owner; /* Cannot be NULL. */
   struct tile *tile;
@@ -318,12 +318,13 @@ int base_unsafe_terrain_loss_pct(const s
 
 bool is_my_zoc(const struct player *unit_owner, const struct tile *ptile);
 bool unit_being_aggressive(const struct unit *punit);
-bool unit_type_really_ignores_zoc(Unit_type_id type);
+bool unit_type_really_ignores_zoc(const struct unit_type *punittype);
 
 bool is_build_or_clean_activity(enum unit_activity activity);
 
 struct unit *create_unit_virtual(struct player *pplayer, struct city *pcity,
-                                 Unit_type_id type, int veteran_level);
+                                 struct unit_type *punittype,
+                                int veteran_level);
 void destroy_unit_virtual(struct unit *punit);
 void free_unit_orders(struct unit *punit);
 
Index: common/unittype.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.c,v
retrieving revision 1.61
diff -p -u -r1.61 unittype.c
--- common/unittype.c   8 Jul 2005 03:31:18 -0000       1.61
+++ common/unittype.c   19 Jul 2005 03:41:50 -0000
@@ -87,7 +87,7 @@ struct unit_type *get_unit_type(Unit_typ
 **************************************************************************/
 struct unit_type *unit_type(const struct unit *punit)
 {
-  return get_unit_type(punit->type);
+  return punit->type;
 }
 
 
@@ -117,10 +117,10 @@ int utype_happy_cost(const struct unit_t
 /**************************************************************************
   Return whether the given unit type (by ID) has the flag.
 **************************************************************************/
-bool unit_type_flag(Unit_type_id id, int flag)
+bool unit_type_flag(const struct unit_type *punittype, int flag)
 {
   assert(flag>=0 && flag<F_LAST);
-  return BV_ISSET(unit_types[id].flags, flag);
+  return BV_ISSET(punittype->flags, flag);
 }
 
 /**************************************************************************
@@ -135,26 +135,27 @@ bool unit_flag(const struct unit *punit,
   Return whether the given unit type (by ID) has the role.  Roles are like
   flags but have no meaning except to the AI.
 **************************************************************************/
-bool unit_has_role(Unit_type_id id, int role)
+bool unit_has_role(const struct unit_type *punittype, int role)
 {
   assert(role>=L_FIRST && role<L_LAST);
-  return BV_ISSET(unit_types[id].roles, role - L_FIRST);
+  return BV_ISSET(punittype->roles, role - L_FIRST);
 }
 
 /****************************************************************************
   Returns the number of shields it takes to build this unit.
 ****************************************************************************/
-int unit_build_shield_cost(Unit_type_id id)
+int unit_build_shield_cost(const struct unit_type *punittype)
 {
-  return unit_types[id].build_cost;
+  return punittype->build_cost;
 }
 
 /****************************************************************************
   Returns the amount of gold it takes to rush this unit.
 ****************************************************************************/
-int unit_buy_gold_cost(Unit_type_id id, int shields_in_stock)
+int unit_buy_gold_cost(const struct unit_type *punittype,
+                      int shields_in_stock)
 {
-  int cost = 0, missing = unit_types[id].build_cost - shields_in_stock;
+  int cost = 0, missing = punittype->build_cost - shields_in_stock;
 
   if (missing > 0) {
     cost = 2 * missing + (missing * missing) / 20;
@@ -168,52 +169,53 @@ int unit_buy_gold_cost(Unit_type_id id, 
 /****************************************************************************
   Returns the number of shields received when this unit is disbanded.
 ****************************************************************************/
-int unit_disband_shields(Unit_type_id id)
+int unit_disband_shields(const struct unit_type *punittype)
 {
-  return unit_types[id].build_cost / 2;
+  return punittype->build_cost / 2;
 }
 
 /**************************************************************************
 ...
 **************************************************************************/
-int unit_pop_value(Unit_type_id id)
+int unit_pop_value(const struct unit_type *punittype)
 {
-  return (unit_types[id].pop_cost);
+  return (punittype->pop_cost);
 }
 
 /**************************************************************************
   Return the (translated) name of the unit type.
 **************************************************************************/
-const char *unit_name(Unit_type_id id)
+const char *unit_name(const struct unit_type *punittype)
 {
-  return (unit_types[id].name);
+  return (punittype->name);
 }
 
 /**************************************************************************
   Return the original (untranslated) name of the unit type.
 **************************************************************************/
-const char *unit_name_orig(Unit_type_id id)
+const char *unit_name_orig(const struct unit_type *punittype)
 {
-  return unit_types[id].name_orig;
+  return punittype->name_orig;
 }
 
 /**************************************************************************
 ...
 **************************************************************************/
-const char *get_unit_name(Unit_type_id id)
+const char *get_unit_name(const struct unit_type *punittype)
 {
-  struct unit_type *ptype;
   static char buffer[256];
-  ptype =get_unit_type(id);
-  if (ptype->fuel > 0) {
+
+  if (punittype->fuel > 0) {
     my_snprintf(buffer, sizeof(buffer),
-               "%s [%d/%d/%d(%d)]", ptype->name, ptype->attack_strength,
-               ptype->defense_strength,
-               ptype->move_rate/3,(ptype->move_rate/3)*ptype->fuel);
+               "%s [%d/%d/%d(%d)]", punittype->name,
+               punittype->attack_strength,
+               punittype->defense_strength,
+               punittype->move_rate / 3,
+               punittype->move_rate / 3 * punittype->fuel);
   } else {
     my_snprintf(buffer, sizeof(buffer),
-               "%s [%d/%d/%d]", ptype->name, ptype->attack_strength,
-               ptype->defense_strength, ptype->move_rate/3);
+               "%s [%d/%d/%d]", punittype->name, punittype->attack_strength,
+               punittype->defense_strength, punittype->move_rate / 3);
   }
   return buffer;
 }
@@ -254,7 +256,7 @@ const char *get_units_with_flag_string(i
     astr.str[0] = 0;
 
     while ((count--) > 0) {
-      int u = get_role_unit(flag, count);
+      struct unit_type *u = get_role_unit(flag, count);
       const char *unitname = unit_name(u);
 
       /* there should be something like astr_append() */
@@ -283,19 +285,21 @@ const char *get_units_with_flag_string(i
 
 /**************************************************************************
   Return whether this player can upgrade this unit type (to any other
-  unit type).
+  unit type).  Returns NULL if no upgrade is possible.
 **************************************************************************/
-int can_upgrade_unittype(const struct player *pplayer, Unit_type_id id)
+struct unit_type *can_upgrade_unittype(const struct player *pplayer,
+                                      const struct unit_type *punittype)
 {
-  Unit_type_id best_upgrade = -1;
+  struct unit_type *best_upgrade = NULL, *upgrade;
 
-  if (!can_player_build_unit_direct(pplayer, id)) {
-    return -1;
+  if (!can_player_build_unit_direct(pplayer, punittype)) {
+    return NULL;
   }
-  while ((id = unit_types[id].obsoleted_by) != U_NOT_OBSOLETED) {
-    if (can_player_build_unit_direct(pplayer, id)) {
-      best_upgrade = id;
+  while ((upgrade = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
+    if (can_player_build_unit_direct(pplayer, upgrade)) {
+      best_upgrade = upgrade;
     }
+    punittype = upgrade; /* Hack to preserve const-ness */
   }
 
   return best_upgrade;
@@ -308,41 +312,42 @@ int can_upgrade_unittype(const struct pl
   belongs to.
 **************************************************************************/
 int unit_upgrade_price(const struct player *pplayer,
-                      Unit_type_id from, Unit_type_id to)
+                      const struct unit_type *from,
+                      const struct unit_type *to)
 {
   return unit_buy_gold_cost(to, unit_disband_shields(from));
 }
 
 /**************************************************************************
   Returns the unit type that has the given (translated) name.
-  Returns U_LAST if none match.
+  Returns NULL if none match.
 **************************************************************************/
-Unit_type_id find_unit_type_by_name(const char *name)
+struct unit_type *find_unit_type_by_name(const char *name)
 {
   /* Does a linear search of unit_types[].name */
-  unit_type_iterate(i) {
-    if (strcmp(unit_types[i].name, name) == 0) {
-      return i;
+  unit_type_iterate(punittype) {
+    if (strcmp(punittype->name, name) == 0) {
+      return punittype;
     }
   } unit_type_iterate_end;
 
-  return U_LAST;
+  return NULL;
 }
 
 /**************************************************************************
   Returns the unit type that has the given original (untranslated) name.
-  Returns U_LAST if none match.
+  Returns NULL if none match.
 **************************************************************************/
-Unit_type_id find_unit_type_by_name_orig(const char *name_orig)
+struct unit_type *find_unit_type_by_name_orig(const char *name_orig)
 {
   /* Does a linear search of unit_types[].name_orig. */
-  unit_type_iterate(i) {
-    if (mystrcasecmp(unit_types[i].name_orig, name_orig) == 0) {
-      return i;
+  unit_type_iterate(punittype) {
+    if (mystrcasecmp(punittype->name_orig, name_orig) == 0) {
+      return punittype;
     }
   } unit_type_iterate_end;
 
-  return U_LAST;
+  return NULL;
 }
 
 /**************************************************************************
@@ -412,31 +417,32 @@ Whether player can build given unit some
 ignoring whether unit is obsolete and assuming the
 player has a coastal city.
 **************************************************************************/
-bool can_player_build_unit_direct(const struct player *p, Unit_type_id id)
+bool can_player_build_unit_direct(const struct player *p,
+                                 const struct unit_type *punittype)
 {
   Impr_type_id impr_req;
 
-  CHECK_UNIT_TYPE(id);
-  if (unit_type_flag(id, F_NUCLEAR)
+  CHECK_UNIT_TYPE(punittype);
+  if (unit_type_flag(punittype, F_NUCLEAR)
       && !get_player_bonus(p, EFT_ENABLE_NUKE) > 0) {
     return FALSE;
   }
-  if (unit_type_flag(id, F_NOBUILD)) {
+  if (unit_type_flag(punittype, F_NOBUILD)) {
     return FALSE;
   }
-  if (unit_types[id].gov_requirement != G_MAGIC
-      && unit_types[id].gov_requirement != p->government) {
+  if (punittype->gov_requirement != G_MAGIC
+      && punittype->gov_requirement != p->government) {
     return FALSE;
   }
-  if (get_invention(p,unit_types[id].tech_requirement) != TECH_KNOWN) {
+  if (get_invention(p,punittype->tech_requirement) != TECH_KNOWN) {
     return FALSE;
   }
-  if (unit_type_flag(id, F_UNIQUE)) {
+  if (unit_type_flag(punittype, F_UNIQUE)) {
     /* FIXME: This could be slow if we have lots of units. We could
      * consider keeping an array of unittypes updated with this info 
      * instead. */
     unit_list_iterate(p->units, punit) {
-      if (punit->type == id) { 
+      if (punit->type == punittype) { 
         return FALSE;
       }
     } unit_list_iterate_end;
@@ -445,7 +451,7 @@ bool can_player_build_unit_direct(const 
   /* If the unit has a building requirement, we check to see if the player
    * can build that building.  Note that individual cities may not have
    * that building, so they still may not be able to build the unit. */
-  impr_req = unit_types[id].impr_requirement;
+  impr_req = punittype->impr_requirement;
   if (impr_req != B_LAST
       && !can_player_build_improvement_direct(p, impr_req)) {
     return FALSE;
@@ -458,13 +464,14 @@ bool can_player_build_unit_direct(const 
 Whether player can build given unit somewhere;
 returns 0 if unit is obsolete.
 **************************************************************************/
-bool can_player_build_unit(const struct player *p, Unit_type_id id)
+bool can_player_build_unit(const struct player *p,
+                          const struct unit_type *punittype)
 {
-  if (!can_player_build_unit_direct(p, id)) {
+  if (!can_player_build_unit_direct(p, punittype)) {
     return FALSE;
   }
-  while ((id = unit_types[id].obsoleted_by) != U_NOT_OBSOLETED) {
-    if (can_player_build_unit_direct(p, id)) {
+  while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
+    if (can_player_build_unit_direct(p, punittype)) {
        return FALSE;
     }
   }
@@ -477,15 +484,15 @@ returns 1 if unit is available with curr
 with future tech.  returns 0 if unit is obsolete.
 **************************************************************************/
 bool can_player_eventually_build_unit(const struct player *p,
-                                     Unit_type_id id)
+                                     const struct unit_type *punittype)
 {
-  CHECK_UNIT_TYPE(id);
-  if (unit_type_flag(id, F_NOBUILD)) {
+  CHECK_UNIT_TYPE(punittype);
+  if (unit_type_flag(punittype, F_NOBUILD)) {
     return FALSE;
   }
-  while ((id = unit_types[id].obsoleted_by) != U_NOT_OBSOLETED) {
-    if (can_player_build_unit_direct(p, id)) {
-       return FALSE;
+  while ((punittype = punittype->obsoleted_by) != U_NOT_OBSOLETED) {
+    if (can_player_build_unit_direct(p, punittype)) {
+      return FALSE;
     }
   }
   return TRUE;
@@ -500,12 +507,13 @@ Unit order is in terms of the order in t
 **************************************************************************/
 static bool first_init = TRUE;
 static int n_with_role[L_LAST];
-static Unit_type_id *with_role[L_LAST];
+static struct unit_type **with_role[L_LAST];
 
 /**************************************************************************
 Do the real work for role_unit_precalcs, for one role (or flag), given by i.
 **************************************************************************/
-static void precalc_one(int i, bool (*func_has)(Unit_type_id, int))
+static void precalc_one(int i,
+                       bool (*func_has)(const struct unit_type *, int))
 {
   int j;
 
@@ -568,7 +576,7 @@ int num_role_units(int role)
 Return index-th unit with specified role/flag.
 Index -1 means (n-1), ie last one.
 **************************************************************************/
-Unit_type_id get_role_unit(int role, int index)
+struct unit_type *get_role_unit(int role, int index)
 {
   assert((role>=0 && role<F_LAST) || (role>=L_FIRST && role<L_LAST));
   if (index==-1) index = n_with_role[role]-1;
@@ -577,12 +585,12 @@ Unit_type_id get_role_unit(int role, int
 }
 
 /**************************************************************************
-Return "best" unit this city can build, with given role/flag.
-Returns U_LAST if none match. "Best" means highest unit type id.
+  Return "best" unit this city can build, with given role/flag.
+  Returns NULL if none match. "Best" means highest unit type id.
 **************************************************************************/
-Unit_type_id best_role_unit(const struct city *pcity, int role)
+struct unit_type *best_role_unit(const struct city *pcity, int role)
 {
-  Unit_type_id u;
+  struct unit_type *u;
   int j;
   
   assert((role>=0 && role<F_LAST) || (role>=L_FIRST && role<L_LAST));
@@ -593,16 +601,16 @@ Unit_type_id best_role_unit(const struct
       return u;
     }
   }
-  return U_LAST;
+  return NULL;
 }
 
 /**************************************************************************
-Return "best" unit the player can build, with given role/flag.
-Returns U_LAST if none match. "Best" means highest unit type id.
+  Return "best" unit the player can build, with given role/flag.
+  Returns NULL if none match. "Best" means highest unit type id.
 
-TODO: Cache the result per player?
+  TODO: Cache the result per player?
 **************************************************************************/
-Unit_type_id best_role_unit_for_player(const struct player *pplayer,
+struct unit_type *best_role_unit_for_player(const struct player *pplayer,
                                       int role)
 {
   int j;
@@ -610,21 +618,21 @@ Unit_type_id best_role_unit_for_player(c
   assert((role >= 0 && role < F_LAST) || (role >= L_FIRST && role < L_LAST));
 
   for(j = n_with_role[role]-1; j >= 0; j--) {
-    Unit_type_id utype = with_role[role][j];
+    struct unit_type *utype = with_role[role][j];
 
     if (can_player_build_unit(pplayer, utype)) {
       return utype;
     }
   }
 
-  return U_LAST;
+  return NULL;
 }
 
 /**************************************************************************
   Return first unit the player can build, with given role/flag.
-  Returns U_LAST if none match.  Used eg when placing starting units.
+  Returns NULL if none match.  Used eg when placing starting units.
 **************************************************************************/
-Unit_type_id first_role_unit_for_player(const struct player *pplayer,
+struct unit_type *first_role_unit_for_player(const struct player *pplayer,
                                        int role)
 {
   int j;
@@ -632,14 +640,14 @@ Unit_type_id first_role_unit_for_player(
   assert((role >= 0 && role < F_LAST) || (role >= L_FIRST && role < L_LAST));
 
   for(j = 0; j < n_with_role[role]; j++) {
-    Unit_type_id utype = with_role[role][j];
+    struct unit_type *utype = with_role[role][j];
 
     if (can_player_build_unit(pplayer, utype)) {
       return utype;
     }
   }
 
-  return U_LAST;
+  return NULL;
 }
 
 /****************************************************************************
@@ -657,12 +665,10 @@ void unit_types_init(void)
 /**************************************************************************
   Frees the memory associated with this unit type.
 **************************************************************************/
-static void unit_type_free(Unit_type_id id)
+static void unit_type_free(struct unit_type *punittype)
 {
-  struct unit_type *p = get_unit_type(id);
-
-  free(p->helptext);
-  p->helptext = NULL;
+  free(punittype->helptext);
+  punittype->helptext = NULL;
 }
 
 /***************************************************************
@@ -670,15 +676,15 @@ static void unit_type_free(Unit_type_id 
 ***************************************************************/
 void unit_types_free(void)
 {
-  unit_type_iterate(i) {
-    unit_type_free(i);
+  unit_type_iterate(punittype) {
+    unit_type_free(punittype);
   } unit_type_iterate_end;
 }
 
 /***************************************************************
  Returns unit class structure
 ***************************************************************/
-struct unit_class *get_unit_class(Unit_type_id type)
+struct unit_class *get_unit_class(const struct unit_type *punittype)
 {
-  return &unit_classes[get_unit_type(type)->class];
+  return &unit_classes[punittype->class];
 }
Index: common/unittype.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unittype.h,v
retrieving revision 1.52
diff -p -u -r1.52 unittype.h
--- common/unittype.h   8 Jul 2005 03:31:18 -0000       1.52
+++ common/unittype.h   19 Jul 2005 03:41:50 -0000
@@ -17,28 +17,6 @@
 
 #include "fc_types.h"
 
-typedef int Unit_type_id;
-/*
-  Above typedef replaces old "enum unit_type_id" (since no longer
-  enumerate the unit types); keep as typedef to help code be
-  self-documenting.
-
-  It could potentially be some other type; "unsigned char" would be
-  natural, since there are already built-in assumptions that values
-  are not too large (less than U_LAST = MAX_NUM_ITEMS) since they must
-  fit in 8-bit unsigned int for packets; and normal values are always
-  non-negative.  But note sometimes use (-1) for obsoleted_by and some
-  related uses, though these use already plain int rather than
-  Unit_type_id?  (Ideally, these should probably have used U_LAST as
-  the flag value instead of (-1).)
-  
-  Decided to just use 'int' for several reasons:
-  - "natural integer type" may be faster on some platforms
-    (size advantage of using smaller type probably negligible);
-  - avoids any potential problems with (-1) values as mentioned above;
-  - avoids imposing any more limitations that there are already.
-*/
-  
 #define U_LAST MAX_NUM_ITEMS
 /*
   U_LAST is a value which is guaranteed to be larger than all
@@ -186,8 +164,8 @@ struct unit_type {
   int transport_capacity;
   int hp;
   int firepower;
-#define U_NOT_OBSOLETED ((Unit_type_id)(-1))
-  int obsoleted_by;
+#define U_NOT_OBSOLETED (NULL)
+  struct unit_type *obsoleted_by;
   int fuel;
 
   bv_flags flags;
@@ -213,39 +191,42 @@ struct unit_type {
 
 
 extern struct unit_type unit_types[U_LAST];
-#define CHECK_UNIT_TYPE(ut) (assert((ut) >= 0 && (ut) \
-                             < game.control.num_unit_types))
+#define CHECK_UNIT_TYPE(ut) (assert((ut) != NULL                           \
+                                   && (&unit_types[(ut)->index] == (ut))))
 
 struct unit_type *get_unit_type(Unit_type_id id);
 struct unit_type *unit_type(const struct unit *punit);
 
-bool unit_type_flag(Unit_type_id id, int flag);
+bool unit_type_flag(const struct unit_type *punittype, int flag);
 bool unit_flag(const struct unit *punit, enum unit_flag_id flag);
-bool unit_has_role(Unit_type_id id, int role);
+bool unit_has_role(const struct unit_type *punittype, int role);
 
-int unit_build_shield_cost(Unit_type_id id);
-int unit_buy_gold_cost(Unit_type_id id, int shields_in_stock);
-int unit_disband_shields(Unit_type_id id);
-int unit_pop_value(Unit_type_id id);
-
-struct unit_class *get_unit_class(Unit_type_id type);
-const char *unit_name(Unit_type_id id);
-const char *unit_name_orig(Unit_type_id id);
+int unit_build_shield_cost(const struct unit_type *punittype);
+int unit_buy_gold_cost(const struct unit_type *punittype,
+                      int shields_in_stock);
+int unit_disband_shields(const struct unit_type *punittype);
+int unit_pop_value(const struct unit_type *punittype);
+
+struct unit_class *get_unit_class(const struct unit_type *punittype);
+const char *unit_name(const struct unit_type *punittype);
+const char *unit_name_orig(const struct unit_type *punittype);
 const char *unit_class_name(Unit_Class_id id);
 
-const char *get_unit_name(Unit_type_id id);
+const char *get_unit_name(const struct unit_type *punittype);
 const char *get_units_with_flag_string(int flag);
 
 int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer,
                       const struct government *g, Output_type_id otype);
 int utype_happy_cost(const struct unit_type *ut, const struct government *g);
 
-int can_upgrade_unittype(const struct player *pplayer, Unit_type_id id);
+struct unit_type *can_upgrade_unittype(const struct player *pplayer,
+                                      const struct unit_type *punittype);
 int unit_upgrade_price(const struct player *pplayer,
-                      Unit_type_id from, Unit_type_id to);
+                      const struct unit_type *from,
+                      const struct unit_type *to);
 
-Unit_type_id find_unit_type_by_name(const char *name);
-Unit_type_id find_unit_type_by_name_orig(const char *name_orig);
+struct unit_type *find_unit_type_by_name(const char *name);
+struct unit_type *find_unit_type_by_name_orig(const char *name_orig);
 
 Unit_Class_id unit_class_from_str(const char *s);
 enum unit_flag_id unit_flag_from_str(const char *s);
@@ -253,30 +234,34 @@ enum unit_role_id unit_role_from_str(con
 
 const char *get_unit_flag_name(enum unit_flag_id id);
 
-bool can_player_build_unit_direct(const struct player *p, Unit_type_id id);
-bool can_player_build_unit(const struct player *p, Unit_type_id id);
+bool can_player_build_unit_direct(const struct player *p,
+                                 const struct unit_type *punittype);
+bool can_player_build_unit(const struct player *p,
+                          const struct unit_type *punittype);
 bool can_player_eventually_build_unit(const struct player *p,
-                                     Unit_type_id id);
+                                     const struct unit_type *punittype);
 
 void role_unit_precalcs(void);
 int num_role_units(int role);
-Unit_type_id get_role_unit(int role, int index);
-Unit_type_id best_role_unit(const struct city *pcity, int role);
-Unit_type_id best_role_unit_for_player(const struct player *pplayer,
-                                      int role);
-Unit_type_id first_role_unit_for_player(const struct player *pplayer,
-                                       int role);
+struct unit_type *get_role_unit(int role, int index);
+struct unit_type *best_role_unit(const struct city *pcity, int role);
+struct unit_type *best_role_unit_for_player(const struct player *pplayer,
+                                           int role);
+struct unit_type *first_role_unit_for_player(const struct player *pplayer,
+                                            int role);
 
 void unit_types_init(void);
 void unit_types_free(void);
 
-#define unit_type_iterate(m_i)                                                \
-{                                                                             \
-  Unit_type_id m_i;                                                           \
-  for (m_i = 0; m_i < game.control.num_unit_types; m_i++) {
+#define unit_type_iterate(punittype)                                       \
+{                                                                          \
+  int _index;                                                              \
+                                                                           \
+  for (_index = 0; _index < game.control.num_unit_types; _index++) {       \
+    struct unit_type *punittype = get_unit_type(_index);
 
-#define unit_type_iterate_end                                                 \
-  }                                                                           \
+#define unit_type_iterate_end                                               \
+  }                                                                         \
 }
 
 #endif  /* FC__UNITTYPE_H */
Index: common/aicore/aisupport.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/aisupport.c,v
retrieving revision 1.10
diff -p -u -r1.10 aisupport.c
--- common/aicore/aisupport.c   5 May 2005 18:32:52 -0000       1.10
+++ common/aicore/aisupport.c   19 Jul 2005 03:41:51 -0000
@@ -109,9 +109,9 @@ int city_gold_worth(struct city *pcity)
   worth = pcity->size * 150; /* reasonable base cost */
   unit_list_iterate(pcity->units_supported, punit) {
     if (same_pos(punit->tile, pcity->tile)) {
-      Unit_type_id id = unit_type(punit)->obsoleted_by;
+      struct unit_type *punittype = unit_type(punit)->obsoleted_by;
 
-      if (id >= 0 && can_build_unit_direct(pcity, id)) {
+      if (punittype && can_build_unit_direct(pcity, punittype)) {
         worth += unit_disband_shields(punit->type) / 2; /* obsolete */
       } else {
         worth += unit_disband_shields(punit->type); /* good stuff */
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.96
diff -p -u -r1.96 barbarian.c
--- server/barbarian.c  18 Jul 2005 22:46:28 -0000      1.96
+++ server/barbarian.c  19 Jul 2005 03:41:51 -0000
@@ -222,8 +222,7 @@ static bool is_free_sea(struct tile *pti
 bool unleash_barbarians(struct tile *ptile)
 {
   struct player *barbarians;
-  int unit, unit_cnt, land_cnt = 0, sea_cnt = 0;
-  int boat;
+  int unit_cnt, land_cnt = 0, sea_cnt = 0;
   int i;
   struct tile *utile = NULL;
   bool alive = TRUE;     /* explorer survived */
@@ -244,9 +243,11 @@ bool unleash_barbarians(struct tile *pti
 
   unit_cnt = 3 + myrand(4);
   for (i = 0; i < unit_cnt; i++) {
-    unit = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH);
-    (void) create_unit(barbarians, ptile, unit, 0, 0, -1);
-    freelog(LOG_DEBUG, "Created barbarian unit %s", unit_types[unit].name);
+    struct unit_type *punittype
+      = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH);
+
+    (void) create_unit(barbarians, ptile, punittype, 0, 0, -1);
+    freelog(LOG_DEBUG, "Created barbarian unit %s", punittype->name);
   }
 
   adjc_iterate(ptile, tile1) {
@@ -286,7 +287,7 @@ bool unleash_barbarians(struct tile *pti
               break;
            }
            if (is_free_sea(utile, barbarians)) {
-              boat = find_a_unit_type(L_BARBARIAN_BOAT, -1);
+              struct unit_type *boat = find_a_unit_type(L_BARBARIAN_BOAT, -1);
              (void) create_unit(barbarians, utile, boat, 0, 0, -1);
              btile = utile;
              break;
@@ -364,7 +365,8 @@ static struct tile *find_empty_tile_near
 static void try_summon_barbarians(void)
 {
   struct tile *ptile, *utile;
-  int i, boat, cap, dist, unit;
+  int i, cap, dist;
+  struct unit_type *boat, *unit;
   int uprise = 1;
   struct city *pc;
   struct player *barbarians, *victim;
@@ -427,9 +429,11 @@ static void try_summon_barbarians(void)
       uprise = 3;
     }
     for (i = 0; i < rand_factor + uprise * game.info.barbarianrate; i++) {
-      unit = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH);
-      (void) create_unit(barbarians, utile, unit, 0, 0, -1);
-      freelog(LOG_DEBUG, "Created barbarian unit %s", unit_types[unit].name);
+      struct unit_type *punittype
+       = find_a_unit_type(L_BARBARIAN, L_BARBARIAN_TECH);
+
+      (void) create_unit(barbarians, utile, punittype, 0, 0, -1);
+      freelog(LOG_DEBUG, "Created barbarian unit %s", unit->name);
     }
     (void) create_unit(barbarians, utile,
                       get_role_unit(L_BARBARIAN_LEADER, 0), 0, 0, -1);
@@ -444,7 +448,7 @@ static void try_summon_barbarians(void)
       unit = find_a_unit_type(L_BARBARIAN_SEA,L_BARBARIAN_SEA_TECH);
       (void) create_unit_full(barbarians, utile, unit, 0, 0, -1, -1,
                              ptrans);
-      freelog(LOG_DEBUG, "Created barbarian unit %s", unit_types[unit].name);
+      freelog(LOG_DEBUG, "Created barbarian unit %s", unit->name);
     }
     (void) create_unit_full(barbarians, utile,
                            get_role_unit(L_BARBARIAN_LEADER, 0), 0, 0,
Index: server/cityhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityhand.c,v
retrieving revision 1.147
diff -p -u -r1.147 cityhand.c
--- server/cityhand.c   5 May 2005 18:32:52 -0000       1.147
+++ server/cityhand.c   19 Jul 2005 03:41:51 -0000
@@ -245,7 +245,7 @@ void really_handle_city_buy(struct playe
 
   if (pcity->is_building_unit) {
     name = unit_types[pcity->currently_building].name;
-    total = unit_build_shield_cost(pcity->currently_building);
+    total = unit_build_shield_cost(get_unit_type(pcity->currently_building));
   } else {
     name = get_improvement_name(pcity->currently_building);
     total = impr_build_shield_cost(pcity->currently_building);
@@ -347,8 +347,10 @@ void handle_city_change(struct player *p
     return;
   }
 
-   if (is_build_id_unit_id && !can_build_unit(pcity, build_id))
-     return;
+  if (is_build_id_unit_id
+      && !can_build_unit(pcity, get_unit_type(build_id))) {
+    return;
+  }
    if (!is_build_id_unit_id && !can_build_improvement(pcity, build_id))
      return;
   if (pcity->did_buy && pcity->shield_stock > 0) {
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.335
diff -p -u -r1.335 citytools.c
--- server/citytools.c  18 Jul 2005 22:46:28 -0000      1.335
+++ server/citytools.c  19 Jul 2005 03:41:52 -0000
@@ -469,20 +469,22 @@ int build_points_left(struct city *pcity
 /**************************************************************************
   Will unit of this type be created as veteran?
 **************************************************************************/
-int do_make_unit_veteran(struct city *pcity, Unit_type_id id)
+int do_make_unit_veteran(struct city *pcity,
+                        const struct unit_type *punittype)
 {
   /* we current don't have any wonder or building that have influence on 
      settler/worker units */
-  if (unit_type_flag(id, F_SETTLERS) || unit_type_flag(id, F_CITIES)) {
+  if (unit_type_flag(punittype, F_SETTLERS)
+      || unit_type_flag(punittype, F_CITIES)) {
     return 0;
   }
   
-  if (unit_type_flag(id, F_DIPLOMAT)) {
+  if (unit_type_flag(punittype, F_DIPLOMAT)) {
     return (get_city_bonus(pcity, EFT_VETERAN_DIPLOMATS) ? 1 : 0);
-  } else if (is_ground_unittype(id)) {
+  } else if (is_ground_unittype(punittype)) {
     return (get_city_bonus(pcity, EFT_LAND_VETERAN) > 0) ? 1 : 0;
   } else {
-    if (is_sailing_unittype(id)) {
+    if (is_sailing_unittype(punittype)) {
       return (get_city_bonus(pcity, EFT_SEA_VETERAN) > 0) ? 1 : 0;
     } else {
       return (get_city_bonus(pcity, EFT_AIR_VETERAN) > 0) ? 1 : 0;
@@ -871,7 +873,8 @@ void transfer_city(struct player *ptaker
 
   /* Set production to something valid for pplayer, if not. */
   if ((pcity->is_building_unit
-       && !can_build_unit_direct(pcity, pcity->currently_building))
+       && !can_build_unit_direct(pcity,
+                                get_unit_type(pcity->currently_building)))
       || (!pcity->is_building_unit
           && !can_build_improvement(pcity, pcity->currently_building))) {
     advisor_choose_build(ptaker, pcity);
Index: server/citytools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.h,v
retrieving revision 1.64
diff -p -u -r1.64 citytools.h
--- server/citytools.h  30 Apr 2005 17:09:28 -0000      1.64
+++ server/citytools.h  19 Jul 2005 03:41:52 -0000
@@ -32,7 +32,8 @@
 #define COOLING_FACTOR WARMING_FACTOR
 
 int build_points_left(struct city *pcity);
-int do_make_unit_veteran(struct city *pcity, Unit_type_id id);
+int do_make_unit_veteran(struct city *pcity,
+                        const struct unit_type *punittype);
 
 void transfer_city_units(struct player *pplayer, struct player *pvictim, 
                         struct unit_list *units, struct city *pcity,
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.323
diff -p -u -r1.323 cityturn.c
--- server/cityturn.c   4 Jul 2005 17:48:38 -0000       1.323
+++ server/cityturn.c   19 Jul 2005 03:41:52 -0000
@@ -72,7 +72,8 @@ static bool city_build_unit(struct playe
 static bool city_build_stuff(struct player *pplayer, struct city *pcity);
 static Impr_type_id building_upgrades_to(struct city *pcity, Impr_type_id b);
 static void upgrade_building_prod(struct city *pcity);
-static Unit_type_id unit_upgrades_to(struct city *pcity, Unit_type_id id);
+static struct unit_type *unit_upgrades_to(struct city *pcity,
+                                         struct unit_type *id);
 static void upgrade_unit_prod(struct city *pcity);
 static void pay_for_buildings(struct player *pplayer, struct city *pcity);
 
@@ -625,9 +626,9 @@ static bool worklist_change_build_target
 
     /* Sanity checks */
     if (is_unit &&
-       !can_build_unit(pcity, target)) {
+       !can_build_unit(pcity, get_unit_type(target))) {
       struct unit_type *ptarget = get_unit_type(target);
-      Unit_type_id new_target = unit_upgrades_to(pcity, target);
+      struct unit_type *new_target = unit_upgrades_to(pcity, ptarget);
 
       /* Maybe we can just upgrade the target to what the city /can/ build. */
       if (new_target == U_NOT_OBSOLETED) {
@@ -667,10 +668,11 @@ static bool worklist_change_build_target
        /* Yep, we can go after new_target instead.  Joy! */
        notify_player_ex(pplayer, pcity->tile, E_WORKLIST,
                         _("Production of %s is upgraded to %s in %s."),
-                        get_unit_type(target)->name, 
-                        get_unit_type(new_target)->name,
+                        ptarget->name, 
+                        new_target->name,
                         pcity->name);
-       target = new_target;
+       ptarget = new_target;
+       target = new_target->index;
       }
     } else if (!is_unit && !can_build_improvement(pcity, target)) {
       Impr_type_id new_target = building_upgrades_to(pcity, target);
@@ -873,7 +875,7 @@ static void choose_build_target(struct p
    * call to change_build_target, so just return. */
   if (pcity->is_building_unit) {
     /* We can build a unit again unless it's unique. */
-    if (!unit_type_flag(pcity->currently_building, F_UNIQUE)) {
+    if (!unit_type_flag(get_unit_type(pcity->currently_building), F_UNIQUE)) {
       return;
     }
   } else if (can_build_improvement(pcity, pcity->currently_building)) {
@@ -938,19 +940,20 @@ static void upgrade_building_prod(struct
 
   FIXME: this function is a duplicate of can_upgrade_unittype.
 **************************************************************************/
-static Unit_type_id unit_upgrades_to(struct city *pcity, Unit_type_id id)
+static struct unit_type *unit_upgrades_to(struct city *pcity,
+                                         struct unit_type *punittype)
 {
-  Unit_type_id check = id, latest_ok = id;
+  struct unit_type *check = punittype, *latest_ok = punittype;
 
   if (!can_build_unit_direct(pcity, check)) {
     return U_NOT_OBSOLETED;
   }
-  while ((check = unit_types[check].obsoleted_by) != U_NOT_OBSOLETED) {
+  while ((check = check->obsoleted_by) != U_NOT_OBSOLETED) {
     if (can_build_unit_direct(pcity, check)) {
       latest_ok = check;
     }
   }
-  if (latest_ok == id) {
+  if (latest_ok == punittype) {
     return U_NOT_OBSOLETED; /* Can't upgrade */
   }
 
@@ -963,15 +966,14 @@ static Unit_type_id unit_upgrades_to(str
 static void upgrade_unit_prod(struct city *pcity)
 {
   struct player *pplayer = city_owner(pcity);
-  int id = pcity->currently_building;
-  int id2 = unit_upgrades_to(pcity, pcity->currently_building);
+  struct unit_type *id = get_unit_type(pcity->currently_building);
+  struct unit_type *id2 = unit_upgrades_to(pcity, id);
 
-  if (id2 != -1 && can_build_unit_direct(pcity, id2)) {
-    pcity->currently_building = id2;
+  if (id2 && can_build_unit_direct(pcity, id2)) {
+    pcity->currently_building = id2->index;
     notify_player_ex(pplayer, pcity->tile, E_UNIT_UPGRADED, 
                  _("Production of %s is upgraded to %s in %s."),
-                 get_unit_type(id)->name, 
-                 get_unit_type(id2)->name , 
+                 id->name, id2->name, 
                  pcity->name);
   }
 }
@@ -1167,22 +1169,21 @@ static bool city_build_unit(struct playe
   /* We must make a special case for barbarians here, because they are
      so dumb. Really. They don't know the prerequisite techs for units
      they build!! - Per */
-  if (!can_build_unit_direct(pcity, pcity->currently_building)
+  if (!can_build_unit_direct(pcity, utype)
       && !is_barbarian(pplayer)) {
     notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
         _("%s is building %s, which is no longer available."),
-        pcity->name, unit_name(pcity->currently_building));
+        pcity->name, unit_name(utype));
     script_signal_emit("unit_cant_be_built", 3,
                       API_TYPE_UNIT_TYPE, utype,
                       API_TYPE_CITY, pcity,
                       API_TYPE_STRING, "unavailable");
     freelog(LOG_VERBOSE, _("%s's %s tried build %s, which is not available"),
-            pplayer->name, pcity->name, unit_name(pcity->currently_building)); 
           
+            pplayer->name, pcity->name, unit_name(utype));
     return TRUE;
   }
-  if (pcity->shield_stock
-      >= unit_build_shield_cost(pcity->currently_building)) {
-    int pop_cost = unit_pop_value(pcity->currently_building);
+  if (pcity->shield_stock >= unit_build_shield_cost(utype)) {
+    int pop_cost = unit_pop_value(utype);
     struct unit *punit;
 
     /* Should we disband the city? -- Massimo */
@@ -1194,7 +1195,7 @@ static bool city_build_unit(struct playe
     if (pcity->size <= pop_cost) {
       notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
                       _("%s can't build %s yet."),
-                      pcity->name, unit_name(pcity->currently_building));
+                      pcity->name, unit_name(utype));
       script_signal_emit("unit_cant_be_built", 3,
                         API_TYPE_UNIT_TYPE, utype,
                         API_TYPE_CITY, pcity,
@@ -1207,9 +1208,8 @@ static bool city_build_unit(struct playe
     /* don't update turn_last_built if we returned above */
     pcity->turn_last_built = game.info.turn;
 
-    punit = create_unit(pplayer, pcity->tile, pcity->currently_building,
-                       do_make_unit_veteran(pcity,
-                                            pcity->currently_building),
+    punit = create_unit(pplayer, pcity->tile, utype,
+                       do_make_unit_veteran(pcity, utype),
                        pcity->id, 0);
 
     /* After we created the unit remove the citizen. This will also
@@ -1221,16 +1221,14 @@ static bool city_build_unit(struct playe
 
     /* to eliminate micromanagement, we only subtract the unit's
        cost */
-    pcity->before_change_shields
-      -= unit_build_shield_cost(pcity->currently_building);
-    pcity->shield_stock
-      -= unit_build_shield_cost(pcity->currently_building);
+    pcity->before_change_shields -= unit_build_shield_cost(utype);
+    pcity->shield_stock -= unit_build_shield_cost(utype);
 
     notify_player_ex(pplayer, pcity->tile, E_UNIT_BUILT,
                     /* TRANS: <city> is finished building <unit/building>. */
                     _("%s is finished building %s."),
                     pcity->name,
-                    unit_types[pcity->currently_building].name);
+                    get_unit_type(pcity->currently_building)->name);
 
     script_signal_emit("unit_built",
                       2, API_TYPE_UNIT, punit, API_TYPE_CITY, pcity);
@@ -1417,7 +1415,7 @@ static void define_orig_production_value
          "In %s, building %s.  Beg of Turn shields = %d",
          pcity->name,
          pcity->changed_from_is_unit ?
-           unit_types[pcity->changed_from_id].name :
+         get_unit_type(pcity->changed_from_id)->name :
            improvement_types[pcity->changed_from_id].name,
          pcity->before_change_shields
          );
@@ -1540,7 +1538,7 @@ static bool disband_city(struct city *pc
     notify_player_ex(pplayer, ptile, E_CITY_CANTBUILD,
                     _("%s can't build %s yet, "
                     "and we can't disband our only city."),
-                    pcity->name, unit_name(pcity->currently_building));
+                    pcity->name, unit_name(utype));
     script_signal_emit("unit_cant_be_built", 3,
                       API_TYPE_UNIT_TYPE, utype,
                       API_TYPE_CITY, pcity,
@@ -1548,8 +1546,8 @@ static bool disband_city(struct city *pc
     return FALSE;
   }
 
-  (void) create_unit(pplayer, ptile, pcity->currently_building,
-                    do_make_unit_veteran(pcity, pcity->currently_building),
+  (void) create_unit(pplayer, ptile, utype,
+                    do_make_unit_veteran(pcity, utype),
                     pcity->id, 0);
 
   /* Shift all the units supported by pcity (including the new unit)
@@ -1562,7 +1560,8 @@ static bool disband_city(struct city *pc
   notify_player_ex(pplayer, ptile, E_UNIT_BUILT,
                   /* TRANS: Settler production leads to disbanded city. */
                   _("%s is disbanded into %s."), 
-                  pcity->name, unit_types[pcity->currently_building].name);
+                  pcity->name,
+                  get_unit_type(pcity->currently_building)->name);
   gamelog(GAMELOG_DISBANDCITY, pcity);
 
   remove_city(pcity);
Index: server/diplomats.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.c,v
retrieving revision 1.86
diff -p -u -r1.86 diplomats.c
--- server/diplomats.c  12 Jul 2005 17:57:53 -0000      1.86
+++ server/diplomats.c  19 Jul 2005 03:41:53 -0000
@@ -928,7 +928,7 @@ void diplomat_sabotage(struct player *pp
 
     /* Report it. */
     if (pcity->is_building_unit)
-      prod = unit_name (pcity->currently_building);
+      prod = unit_name(get_unit_type(pcity->currently_building));
     else
       prod = get_improvement_name (pcity->currently_building);
     notify_player_ex(pplayer, pcity->tile, E_MY_DIPLOMAT_SABOTAGE,
Index: server/diplomats.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.h,v
retrieving revision 1.6
diff -p -u -r1.6 diplomats.h
--- server/diplomats.h  30 Apr 2005 17:09:28 -0000      1.6
+++ server/diplomats.h  19 Jul 2005 03:41:53 -0000
@@ -14,7 +14,6 @@
 #define FC__DIPLOMATS_H
 
 #include "fc_types.h"
-#include "unit.h"              /* Unit_type_id, enum unit_activity */
 
 #include "gotohand.h"          /* enum goto_move_restriction */
 
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.164
diff -p -u -r1.164 gamehand.c
--- server/gamehand.c   18 Jul 2005 22:46:28 -0000      1.164
+++ server/gamehand.c   19 Jul 2005 03:41:53 -0000
@@ -63,7 +63,7 @@ static void init_game_id(void)
 static void place_starting_unit(struct tile *ptile, struct player *pplayer,
                                char crole)
 {
-  Unit_type_id utype;
+  struct unit_type *utype;
   enum unit_flag_id role;
 
   assert(!is_non_allied_unit_tile(ptile, pplayer));
@@ -123,17 +123,17 @@ static void place_starting_unit(struct t
   /* Create the unit of an appropriate type, if it exists */
   if (num_role_units(role) > 0) {
     utype = first_role_unit_for_player(pplayer, role);
-    if (utype == U_LAST) {
+    if (utype == NULL) {
       utype = get_role_unit(role, 0);
     }
 
     /* We cannot currently handle sea units as start units.
      * TODO: remove this code block when we can. */
-    if (unit_types[utype].move_type == SEA_MOVING) {
+    if (utype->move_type == SEA_MOVING) {
       freelog(LOG_ERROR, _("Sea moving start units are not yet supported, "
-                           "%s not created."), unit_types[utype].name);
+                           "%s not created."), utype->name);
       notify_player(pplayer, _("Sea moving start units are not yet supported. "
-                               "Nobody gets %s."), unit_types[utype].name);
+                               "Nobody gets %s."), utype->name);
       return;
     }
 
@@ -270,7 +270,7 @@ void init_new_game(void)
 
     /* Place nation specific start units (not role based!) */
     i = 0;
-    while (nation->init_units[i] != U_LAST && i < MAX_NUM_UNIT_LIST) {
+    while (nation->init_units[i] != NULL && i < MAX_NUM_UNIT_LIST) {
       ptile = find_dispersed_position(pplayer, &p);
       create_unit(pplayer, ptile, nation->init_units[i], FALSE, 0, 0);
       i++;
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.195
diff -p -u -r1.195 gotohand.c
--- server/gotohand.c   14 Jul 2005 19:25:46 -0000      1.195
+++ server/gotohand.c   19 Jul 2005 03:41:53 -0000
@@ -912,7 +912,7 @@ static int find_a_direction(struct unit 
                            struct tile *dest_tile)
 {
 #define UNIT_DEFENSE(punit, ptile, defence_multiplier) \
-  ((get_virtual_defense_power(U_LAST, (punit)->type, (ptile), FALSE, 0) * \
+  ((get_virtual_defense_power(NULL, (punit)->type, (ptile), FALSE, 0) * \
     (defence_multiplier)) / 2)
 
 #define UNIT_RATING(punit, ptile, defence_multiplier) \
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.274
diff -p -u -r1.274 ruleset.c
--- server/ruleset.c    18 Jul 2005 22:46:29 -0000      1.274
+++ server/ruleset.c    19 Jul 2005 03:41:54 -0000
@@ -60,9 +60,11 @@ static int lookup_tech(struct section_fi
                       const char *description);
 static void lookup_tech_list(struct section_file *file, const char *prefix,
                             const char *entry, int *output, const char 
*filename);
-static int lookup_unit_type(struct section_file *file, const char *prefix,
-                           const char *entry, bool required, const char 
*filename,
-                           const char *description);
+static struct unit_type *lookup_unit_type(struct section_file *file,
+                                         const char *prefix,
+                                         const char *entry, bool required,
+                                         const char *filename,
+                                         const char *description);
 static Impr_type_id lookup_impr_type(struct section_file *file, const char 
*prefix,
                                     const char *entry, bool required,
                                     const char *filename, const char 
*description);
@@ -344,15 +346,15 @@ static int lookup_building(struct sectio
  we report it as an error, otherwise we just punt.
 **************************************************************************/
 static void lookup_unit_list(struct section_file *file, const char *prefix,
-                            const char *entry, int *output, 
+                            const char *entry, struct unit_type **output, 
                              const char *filename, bool required)
 {
   char **slist;
   int i, nval;
 
-  /* pre-fill with U_LAST: */
+  /* pre-fill with NULL: */
   for(i = 0; i < MAX_NUM_UNIT_LIST; i++) {
-    output[i] = A_LAST;
+    output[i] = NULL;
   }
   slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry);
   if (nval == 0) {
@@ -374,15 +376,16 @@ static void lookup_unit_list(struct sect
   }
   for (i = 0; i < nval; i++) {
     char *sval = slist[i];
-    Unit_type_id uid = find_unit_type_by_name(sval);
+    struct unit_type *punittype = find_unit_type_by_name(sval);
 
-    if (uid == U_LAST) {
+    if (!punittype) {
       freelog(LOG_FATAL, "For %s %s (%d) couldn't match unit \"%s\" (%s)",
              prefix, entry, i, sval, filename);
       exit(EXIT_FAILURE);
     }
-    output[i] = uid;
-    freelog(LOG_DEBUG, "%s.%s,%d %s %d", prefix, entry, i, sval, uid);
+    output[i] = punittype;
+    freelog(LOG_DEBUG, "%s.%s,%d %s %d", prefix, entry, i, sval,
+           punittype->index);
   }
   free(slist);
   return;
@@ -492,17 +495,19 @@ static void lookup_building_list(struct 
 
 /**************************************************************************
  Lookup a string prefix.entry in the file and return the corresponding
- unit_type id.  If (!required), return -1 if match "None" or can't match.
+ unit_type id.  If (!required), return NULL if match "None" or can't match.
  If (required), die if can't match.
  If description is not NULL, it is used in the warning message
  instead of prefix (eg pass unit->name instead of prefix="units2.u27")
 **************************************************************************/
-static int lookup_unit_type(struct section_file *file, const char *prefix,
-                           const char *entry, bool required, const char 
*filename,
-                           const char *description)
+static struct unit_type *lookup_unit_type(struct section_file *file,
+                                         const char *prefix,
+                                         const char *entry, bool required,
+                                         const char *filename,
+                                         const char *description)
 {
   char *sval;
-  int i;
+  struct unit_type *punittype;
   
   if (required) {
     sval = secfile_lookup_str(file, "%s.%s", prefix, entry);
@@ -511,21 +516,21 @@ static int lookup_unit_type(struct secti
   }
 
   if (strcmp(sval, "None")==0) {
-    i = -1;
+    punittype = NULL;
   } else {
-    i = find_unit_type_by_name(sval);
-    if (i==U_LAST) {
+    punittype = find_unit_type_by_name(sval);
+    if (!punittype) {
       freelog((required?LOG_FATAL:LOG_ERROR),
           "for %s %s couldn't match unit_type \"%s\" (%s)",
           (description?description:prefix), entry, sval, filename);
       if (required) {
        exit(EXIT_FAILURE);
       } else {
-       i = -1;
+       punittype = NULL;
       }
     }
   }
-  return i;
+  return punittype;
 }
 
 /**************************************************************************
@@ -878,7 +883,8 @@ static void load_unit_names(struct secti
 
   game.control.num_unit_types = nval;
 
-  unit_type_iterate(i) {
+  unit_type_iterate(punittype) {
+    const int i = punittype->index;
     char *name = secfile_lookup_str(file, "%s.name", sec[i]);
 
     name_strlcpy(unit_types[i].name_orig, name);
@@ -918,8 +924,8 @@ if (vet_levels_default > MAX_VET_LEVELS 
   def_vnlist = secfile_lookup_str_vec(file, &vet_levels_default,
                                "veteran_system.veteran_names");
 
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
 
     vnlist = secfile_lookup_str_vec(file, &vet_levels,
                                     "%s.veteran_names", sec[i]);
@@ -947,8 +953,9 @@ if (vet_levels_default > MAX_VET_LEVELS 
   /* power factor */
   def_vblist = secfile_lookup_int_vec(file, &vet_levels_default,
                                       "veteran_system.veteran_power_fact");
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     vblist = secfile_lookup_int_vec(file, &vet_levels,
                                     "%s.veteran_power_fact", sec[i]);
     CHECK_VETERAN_LIMIT
@@ -1011,8 +1018,9 @@ if (vet_levels_default > MAX_VET_LEVELS 
   /* move bonus */
   def_vblist = secfile_lookup_int_vec(file, &vet_levels_default,
                                       "veteran_system.veteran_move_bonus");
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     vblist = secfile_lookup_int_vec(file, &vet_levels,
                        "%s.veteran_move_bonus", sec[i]);
     CHECK_VETERAN_LIMIT
@@ -1032,8 +1040,9 @@ if (vet_levels_default > MAX_VET_LEVELS 
   }
 
   /* Tech and Gov requirements */  
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     u->tech_requirement = lookup_tech(file, sec[i], "tech_req",
                                      TRUE, filename, u->name);
     if (section_file_lookup(file, "%s.gov_req", sec[i])) {
@@ -1046,15 +1055,16 @@ if (vet_levels_default > MAX_VET_LEVELS 
     }
   } unit_type_iterate_end;
   
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     u->obsoleted_by = lookup_unit_type(file, sec[i], "obsolete_by",
                                       FALSE, filename, u->name);
   } unit_type_iterate_end;
 
   /* main stats: */
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
 
     u->impr_requirement = lookup_building(file, sec[i], "impr_req",
                                          FALSE, filename, u->name);
@@ -1141,10 +1151,11 @@ if (vet_levels_default > MAX_VET_LEVELS 
   } unit_type_iterate_end;
   
   /* flags */
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     BV_CLR_ALL(u->flags);
-    assert(!unit_type_flag(i, F_LAST-1));
+    assert(!unit_type_flag(u, F_LAST-1));
 
     slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec[i]);
     for(j=0; j<nval; j++) {
@@ -1158,14 +1169,15 @@ if (vet_levels_default > MAX_VET_LEVELS 
             u->name, sval, filename);
       }
       BV_SET(u->flags, ival);
-      assert(unit_type_flag(i, ival));
+      assert(unit_type_flag(u, ival));
     }
     free(slist);
   } unit_type_iterate_end;
     
   /* roles */
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
+    const int i = u->index;
+
     BV_CLR_ALL(u->roles);
     
     slist = secfile_lookup_str_vec(file, &nval, "%s.roles", sec[i] );
@@ -1180,14 +1192,13 @@ if (vet_levels_default > MAX_VET_LEVELS 
             u->name, sval, filename);
       }
       BV_SET(u->roles, ival - L_FIRST);
-      assert(unit_has_role(i, ival));
+      assert(unit_has_role(u, ival));
     }
     free(slist);
   } unit_type_iterate_end;
 
   /* Some more consistency checking: */
-  unit_type_iterate(i) {
-    u = &unit_types[i];
+  unit_type_iterate(u) {
     if (!tech_exists(u->tech_requirement)) {
       freelog(LOG_ERROR,
              "unit_type \"%s\" depends on removed tech \"%s\" (%s)",
@@ -1236,7 +1247,7 @@ if (vet_levels_default > MAX_VET_LEVELS 
     freelog(LOG_FATAL, "No role=barbarian ship units? (%s)", filename);
     exit(EXIT_FAILURE);
   } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
-    u = &unit_types[get_role_unit(L_BARBARIAN_BOAT,0)];
+    u = get_role_unit(L_BARBARIAN_BOAT,0);
     if(u->move_type != SEA_MOVING) {
       freelog(LOG_FATAL, "Barbarian boat (%s) needs to be a sea unit (%s)",
               u->name, filename);
@@ -2618,10 +2629,8 @@ static void send_ruleset_units(struct co
   struct packet_ruleset_unit packet;
   int i;
 
-  unit_type_iterate(utype_id) {
-    struct unit_type *u = get_unit_type(utype_id);
-
-    packet.id = u-unit_types;
+  unit_type_iterate(u) {
+    packet.id = u->index;
     sz_strlcpy(packet.name, u->name_orig);
     sz_strlcpy(packet.sound_move, u->sound_move);
     sz_strlcpy(packet.sound_move_alt, u->sound_move_alt);
@@ -2642,7 +2651,7 @@ static void send_ruleset_units(struct co
     packet.transport_capacity = u->transport_capacity;
     packet.hp = u->hp;
     packet.firepower = u->firepower;
-    packet.obsoleted_by = u->obsoleted_by;
+    packet.obsoleted_by = u->obsoleted_by ? u->obsoleted_by->index : -1;
     packet.fuel = u->fuel;
     packet.flags = u->flags;
     packet.roles = u->roles;
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.263
diff -p -u -r1.263 savegame.c
--- server/savegame.c   18 Jul 2005 22:46:29 -0000      1.263
+++ server/savegame.c   19 Jul 2005 03:41:55 -0000
@@ -1019,7 +1019,7 @@ const char* old_civ2_governments[] =
   unit_type_id.  This function tries to find the correct _old_ id for the
   unit's type.  It is used when the unit is saved.
 ****************************************************************************/
-static int old_unit_type_id(Unit_type_id type)
+static Unit_type_id old_unit_type_id(const struct unit_type *type)
 {
   const char** types;
   int num_types, i;
@@ -1040,7 +1040,7 @@ static int old_unit_type_id(Unit_type_id
 
   /* It's a new unit. Savegame cannot be forward compatible so we can
    * return anything */
-  return type;
+  return type->index;
 }
 
 /****************************************************************************
@@ -1079,7 +1079,8 @@ static int old_impr_type_id(Impr_type_id
   int i;
 
   for (i = 0; i < ARRAY_SIZE(old_impr_types); i++) {
-    if (mystrcasecmp(unit_name_orig(type), old_impr_types[i]) == 0) {
+    if (mystrcasecmp(get_improvement_name_orig(type),
+                    old_impr_types[i]) == 0) {
       return i;
     }
   }
@@ -1407,7 +1408,7 @@ static void worklist_load(struct section
       name = secfile_lookup_str_default(file, NULL, namepath, plrno, wlinx, i);
 
       if (pwl->wlefs[i] == WEF_UNIT) {
-       Unit_type_id type;
+       struct unit_type *type;
 
        if (!name) {
            /* before 1.15.0 unit types used to be saved by id */
@@ -1416,12 +1417,12 @@ static void worklist_load(struct section
        }
 
        type = find_unit_type_by_name_orig(name);
-       if (type == U_LAST) {
+       if (!type) {
          freelog(LOG_ERROR, _("Unknown unit type '%s' in worklist"),
                  name);
          exit(EXIT_FAILURE);
        }
-       pwl->wlids[i] = type;
+       pwl->wlids[i] = type->index;
       } else if (pwl->wlefs[i] == WEF_IMPR) {
        Impr_type_id type;
 
@@ -1477,7 +1478,7 @@ static void worklist_load_old(struct sec
       } else if (id >= 68) {           /* 68 was offset to unit ids */
        name = old_unit_type_name(id-68);
        pwl->wlefs[i] = WEF_UNIT;
-       pwl->wlids[i] = find_unit_type_by_name_orig(name);
+       pwl->wlids[i] = find_unit_type_by_name_orig(name)->index;
        end = (pwl->wlids[i] < 0 || pwl->wlids[i] >= 
game.control.num_unit_types);
       } else {                         /* must be an improvement id */
        name = old_impr_type_name(id);
@@ -1511,7 +1512,7 @@ static void load_player_units(struct pla
     struct city *pcity;
     int nat_x, nat_y;
     const char* type_name;
-    Unit_type_id type;
+    struct unit_type *type;
     
     type_name = secfile_lookup_str_default(file, NULL, 
                                            "player%d.u%d.type_by_name",
@@ -1530,7 +1531,7 @@ static void load_player_units(struct pla
     }
     
     type = find_unit_type_by_name_orig(type_name);
-    if (type == U_LAST) {
+    if (!type) {
       freelog(LOG_ERROR, _("Unknown unit type '%s' in player%d section"),
               type_name, plrno);
       exit(EXIT_FAILURE);
@@ -2159,7 +2160,7 @@ static void player_load(struct player *p
                                plrno, i);
        name = old_unit_type_name(id);
       }
-      pcity->currently_building = find_unit_type_by_name_orig(name);
+      pcity->currently_building = find_unit_type_by_name_orig(name)->index;
     } else {
       if (!name) {
        id = secfile_lookup_int(file, "player%d.c%d.currently_building",
@@ -2189,7 +2190,7 @@ static void player_load(struct player *p
                                plrno, i);
        name = old_unit_type_name(id);
       }
-      pcity->changed_from_id = find_unit_type_by_name_orig(name);
+      pcity->changed_from_id = find_unit_type_by_name_orig(name)->index;
     } else {
       if (!name) {
        id = secfile_lookup_int(file, "player%d.c%d.changed_from_id",
@@ -2586,9 +2587,13 @@ static void worklist_save(struct section
   for (i = 0; i < MAX_LEN_WORKLIST; i++) {
     secfile_insert_int(file, pwl->wlefs[i], efpath, plrno, wlinx, i);
     if (pwl->wlefs[i] == WEF_UNIT) {
-      secfile_insert_int(file, old_unit_type_id(pwl->wlids[i]), idpath,
+      secfile_insert_int(file,
+                        old_unit_type_id(get_unit_type(pwl->wlids[i])),
+                        idpath,
                         plrno, wlinx, i);
-      secfile_insert_str(file, unit_name_orig(pwl->wlids[i]), namepath, plrno,
+      secfile_insert_str(file,
+                        unit_name_orig(get_unit_type(pwl->wlids[i])),
+                        namepath, plrno,
                         wlinx, i);
     } else if (pwl->wlefs[i] == WEF_IMPR) {
       secfile_insert_int(file, pwl->wlids[i], idpath, plrno, wlinx, i);
@@ -2961,9 +2966,10 @@ static void player_save(struct player *p
     secfile_insert_bool(file, pcity->changed_from_is_unit,
                       "player%d.c%d.changed_from_is_unit", plrno, i);
     if (pcity->changed_from_is_unit) {
-      secfile_insert_int(file, old_unit_type_id(pcity->changed_from_id),
+      struct unit_type *punittype = get_unit_type(pcity->changed_from_id);
+      secfile_insert_int(file, old_unit_type_id(punittype),
                         "player%d.c%d.changed_from_id", plrno, i);
-      secfile_insert_str(file, unit_name_orig(pcity->changed_from_id),
+      secfile_insert_str(file, unit_name_orig(punittype),
                          "player%d.c%d.changed_from_name", plrno, i);
     } else {
       secfile_insert_int(file, old_impr_type_id(pcity->changed_from_id),
@@ -3028,9 +3034,10 @@ static void player_save(struct player *p
     secfile_insert_bool(file, pcity->is_building_unit, 
                       "player%d.c%d.is_building_unit", plrno, i);
     if (pcity->is_building_unit) {
-      secfile_insert_int(file, old_unit_type_id(pcity->currently_building), 
+      struct unit_type *punittype = get_unit_type(pcity->currently_building);
+      secfile_insert_int(file, old_unit_type_id(punittype),
                         "player%d.c%d.currently_building", plrno, i);
-      secfile_insert_str(file, unit_name_orig(pcity->currently_building),
+      secfile_insert_str(file, unit_name_orig(punittype),
                          "player%d.c%d.currently_building_name", plrno, i);
     } else {
       secfile_insert_int(file, old_impr_type_id(pcity->currently_building),
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.244
diff -p -u -r1.244 settlers.c
--- server/settlers.c   14 Jul 2005 19:25:46 -0000      1.244
+++ server/settlers.c   19 Jul 2005 03:41:55 -0000
@@ -1296,9 +1296,9 @@ void contemplate_new_city(struct city *p
 {
   struct player *pplayer = city_owner(pcity);
   struct unit *virtualunit;
-  Unit_type_id unit_type = best_role_unit(pcity, F_CITIES); 
+  struct unit_type *unit_type = best_role_unit(pcity, F_CITIES); 
 
-  if (unit_type == U_LAST) {
+  if (unit_type == NULL) {
     freelog(LOG_DEBUG, "No F_CITIES role unit available");
     return;
   }
@@ -1344,10 +1344,10 @@ void contemplate_terrain_improvements(st
   enum unit_activity best_act;
   struct tile *ptile = pcity->tile;
   struct ai_data *ai = ai_data_get(pplayer);
-  Unit_type_id unit_type = best_role_unit(pcity, F_SETTLERS);
+  struct unit_type *unit_type = best_role_unit(pcity, F_SETTLERS);
   int completion_time;
 
-  if (unit_type == U_LAST) {
+  if (unit_type == NULL) {
     freelog(LOG_DEBUG, "No F_SETTLERS role unit available");
     return;
   }
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.343
diff -p -u -r1.343 unithand.c
--- server/unithand.c   13 Jul 2005 16:49:39 -0000      1.343
+++ server/unithand.c   19 Jul 2005 03:41:56 -0000
@@ -86,15 +86,18 @@ void handle_unit_airlift(struct player *
 **************************************************************************/
 void handle_unit_type_upgrade(struct player *pplayer, Unit_type_id type)
 {
-  const Unit_type_id from_unittype = type;
-  const Unit_type_id to_unittype = can_upgrade_unittype(pplayer,
-                                                       from_unittype);
+  struct unit_type *from_unittype = get_unit_type(type), *to_unittype;
   int number_of_upgraded_units = 0;
 
-  if (to_unittype == -1) {
+  if (!from_unittype) {
+    return;
+  }
+
+  to_unittype = can_upgrade_unittype(pplayer, from_unittype);
+  if (!to_unittype) {
     notify_player(pplayer,
                  _("Illegal packet, can't upgrade %s (yet)."),
-                 unit_types[from_unittype].name);
+                 from_unittype->name);
     return;
   }
 
@@ -121,8 +124,8 @@ void handle_unit_type_upgrade(struct pla
   if (number_of_upgraded_units > 0) {
     const int cost = unit_upgrade_price(pplayer, from_unittype, to_unittype);
     notify_player(pplayer, _("%d %s upgraded to %s for %d gold."),
-                 number_of_upgraded_units, unit_types[from_unittype].name,
-                 unit_types[to_unittype].name,
+                 number_of_upgraded_units, from_unittype->name,
+                 to_unittype->name,
                  cost * number_of_upgraded_units);
     send_player_info(pplayer, pplayer);
   } else {
@@ -143,8 +146,8 @@ void handle_unit_upgrade(struct player *
   }
 
   if (get_unit_upgrade_info(buf, sizeof(buf), punit) == UR_OK) {
-    Unit_type_id from_unit = punit->type;
-    Unit_type_id to_unit = can_upgrade_unittype(pplayer, punit->type);
+    struct unit_type *from_unit = punit->type;
+    struct unit_type *to_unit = can_upgrade_unittype(pplayer, punit->type);
     int cost = unit_upgrade_price(pplayer, punit->type, to_unit);
 
     upgrade_unit(punit, to_unit, FALSE);
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.370
diff -p -u -r1.370 unittools.c
--- server/unittools.c  14 Jul 2005 19:25:46 -0000      1.370
+++ server/unittools.c  19 Jul 2005 03:41:56 -0000
@@ -110,15 +110,15 @@ static void change_vision_range(struct p
   It is an error if there are no available units.  This function will
   always return a valid unit.
 **************************************************************************/
-Unit_type_id find_a_unit_type(enum unit_role_id role,
-                             enum unit_role_id role_tech)
+struct unit_type *find_a_unit_type(enum unit_role_id role,
+                                  enum unit_role_id role_tech)
 {
-  int which[U_LAST];
+  struct unit_type *which[U_LAST];
   int i, num=0;
 
   if (role_tech != -1) {
     for(i=0; i<num_role_units(role_tech); i++) {
-      Unit_type_id iunit = get_role_unit(role_tech, i);
+      struct unit_type *iunit = get_role_unit(role_tech, i);
       const int minplayers = 2;
       int players = 0;
 
@@ -268,12 +268,13 @@ static void do_upgrade_effects(struct pl
      * available candidates. */
     int candidate_to_upgrade = myrand(unit_list_size(candidates));
     struct unit *punit = unit_list_get(candidates, candidate_to_upgrade);
-    Unit_type_id upgrade_type = can_upgrade_unittype(pplayer, punit->type);
+    struct unit_type *upgrade_type
+      = can_upgrade_unittype(pplayer, punit->type);
 
     notify_player(pplayer,
                  _("%s was upgraded for free to %s%s."),
                  unit_type(punit)->name,
-                 get_unit_type(upgrade_type)->name,
+                 upgrade_type->name,
                  get_location_str_in(pplayer, punit->tile));
 
     /* For historical reasons some veteran status may be lost while
@@ -1110,7 +1111,8 @@ enum goto_move_restriction get_activity_
 /**************************************************************************
 ...
 **************************************************************************/
-static bool find_a_good_partisan_spot(struct city *pcity, int u_type,
+static bool find_a_good_partisan_spot(struct city *pcity,
+                                     struct unit_type *u_type,
                                      struct tile **dst_tile)
 {
   int bestvalue = 0;
@@ -1124,7 +1126,7 @@ static bool find_a_good_partisan_spot(st
       continue;
     if (unit_list_size(ptile->units) > 0)
       continue;
-    value = get_virtual_defense_power(U_LAST, u_type, ptile, FALSE, 0);
+    value = get_virtual_defense_power(NULL, u_type, ptile, FALSE, 0);
     value *= 10;
 
     if (ptile->continent != tile_get_continent(pcity->tile)) {
@@ -1148,10 +1150,11 @@ static bool find_a_good_partisan_spot(st
 static void place_partisans(struct city *pcity, int count)
 {
   struct tile *ptile = NULL;
-  int u_type = get_role_unit(L_PARTISAN, 0);
+  struct unit_type *u_type = get_role_unit(L_PARTISAN, 0);
 
   while ((count--) > 0 && find_a_good_partisan_spot(pcity, u_type, &ptile)) {
     struct unit *punit;
+
     punit = create_unit(city_owner(pcity), ptile, u_type, 0, 0, -1);
     if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) {
       punit->activity = ACTIVITY_FORTIFIED; /* yes; directly fortified */
@@ -1385,7 +1388,8 @@ void remove_allied_visibility(struct pla
 ...
 **************************************************************************/
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
-                            Unit_type_id type, bool unit_is_on_tile)
+                            const struct unit_type *type,
+                            bool unit_is_on_tile)
 {
   struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
 
@@ -1419,7 +1423,8 @@ bool is_airunit_refuel_point(struct tile
 
   Note that this function is strongly tied to unit.c:test_unit_upgrade().
 **************************************************************************/
-void upgrade_unit(struct unit *punit, Unit_type_id to_unit, bool is_free)
+void upgrade_unit(struct unit *punit, struct unit_type *to_unit,
+                 bool is_free)
 {
   struct player *pplayer = unit_owner(punit);
   int range;
@@ -1454,7 +1459,7 @@ void upgrade_unit(struct unit *punit, Un
       && unit_profits_of_watchtower(punit)) {
     change_vision_range(pplayer, punit->tile, range, 
get_watchtower_vision(punit));
   } else {
-    change_vision_range(pplayer, punit->tile, range, 
get_unit_type(to_unit)->vision_range);
+    change_vision_range(pplayer, punit->tile, range, to_unit->vision_range);
   }
 
   send_unit_info(NULL, punit);
@@ -1465,7 +1470,7 @@ void upgrade_unit(struct unit *punit, Un
   Wrapper of the below
 *************************************************************************/
 struct unit *create_unit(struct player *pplayer, struct tile *ptile, 
-                         Unit_type_id type, int veteran_level, 
+                        struct unit_type *type, int veteran_level, 
                          int homecity_id, int moves_left)
 {
   return create_unit_full(pplayer, ptile, type, veteran_level, homecity_id, 
@@ -1477,7 +1482,7 @@ struct unit *create_unit(struct player *
   lists.
 **************************************************************************/
 struct unit *create_unit_full(struct player *pplayer, struct tile *ptile,
-                             Unit_type_id type, int veteran_level, 
+                             struct unit_type *type, int veteran_level, 
                               int homecity_id, int moves_left, int hp_left,
                              struct unit *ptrans)
 {
@@ -1849,7 +1854,7 @@ void package_unit(struct unit *punit, st
   packet->y = punit->tile->y;
   packet->homecity = punit->homecity;
   packet->veteran = punit->veteran;
-  packet->type = punit->type;
+  packet->type = punit->type->index;
   packet->movesleft = punit->moves_left;
   packet->hp = punit->hp;
   packet->activity = punit->activity;
@@ -1927,7 +1932,7 @@ void package_short_unit(struct unit *pun
   packet->x = punit->tile->x;
   packet->y = punit->tile->y;
   packet->veteran = punit->veteran;
-  packet->type = punit->type;
+  packet->type = punit->type->index;
   packet->hp = punit->hp;
   packet->occupied = (get_transporter_occupancy(punit) > 0);
   if (punit->activity == ACTIVITY_EXPLORE
@@ -2334,7 +2339,7 @@ static bool hut_get_barbarians(struct un
   } else {
     /* save coords and type in case unit dies */
     struct tile *unit_tile = punit->tile;
-    Unit_type_id type = punit->type;
+    struct unit_type *type = punit->type;
 
     ok = unleash_barbarians(unit_tile);
 
Index: server/unittools.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.h,v
retrieving revision 1.74
diff -p -u -r1.74 unittools.h
--- server/unittools.h  30 Apr 2005 17:09:30 -0000      1.74
+++ server/unittools.h  19 Jul 2005 03:41:57 -0000
@@ -20,15 +20,16 @@
 #include "gotohand.h"
 
 /* battle related */
-Unit_type_id find_a_unit_type(enum unit_role_id role,
-                             enum unit_role_id role_tech);
+struct unit_type *find_a_unit_type(enum unit_role_id role,
+                                  enum unit_role_id role_tech);
 bool maybe_make_veteran(struct unit *punit);
 void unit_versus_unit(struct unit *attacker, struct unit *defender,
                      bool bombard);
 
 /* move check related */
 bool is_airunit_refuel_point(struct tile *ptile, struct player *pplayer,
-                            Unit_type_id type, bool unit_is_on_tile);
+                            const struct unit_type *punittype,
+                            bool unit_is_on_tile);
 
 /* turn update related */
 void player_restore_units(struct player *pplayer);
@@ -51,11 +52,13 @@ void pay_for_units(struct player *pplaye
 void bounce_unit(struct unit *punit, bool verbose);
 
 /* creation/deletion/upgrading */
-void upgrade_unit(struct unit *punit, Unit_type_id to_unit, bool has_to_pay);
-struct unit *create_unit(struct player *pplayer, struct tile *ptile, 
Unit_type_id type,
+void upgrade_unit(struct unit *punit, struct unit_type *to_unit,
+                 bool has_to_pay);
+struct unit *create_unit(struct player *pplayer, struct tile *ptile,
+                        struct unit_type *punittype,
                         int veteran_level, int homecity_id, int moves_left);
 struct unit *create_unit_full(struct player *pplayer, struct tile *ptile,
-                             Unit_type_id type, int veteran_level,
+                             struct unit_type *punittype, int veteran_level,
                              int homecity_id, int moves_left, int hp_left,
                              struct unit *ptrans);
 void wipe_unit(struct unit *punit);
Index: server/scripting/api.pkg
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api.pkg,v
retrieving revision 1.12
diff -p -u -r1.12 api.pkg
--- server/scripting/api.pkg    18 Jul 2005 22:46:29 -0000      1.12
+++ server/scripting/api.pkg    19 Jul 2005 03:41:57 -0000
@@ -47,7 +47,7 @@ struct City {
 };
 
 struct Unit {
-  int type @ type_id;
+  Unit_Type *type;
   Player *owner;
   int homecity @ homecity_id;
   Tile *tile;
Index: server/scripting/api_actions.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api_actions.c,v
retrieving revision 1.5
diff -p -u -r1.5 api_actions.c
--- server/scripting/api_actions.c      1 Jul 2005 08:25:34 -0000       1.5
+++ server/scripting/api_actions.c      19 Jul 2005 03:41:57 -0000
@@ -30,7 +30,7 @@ Unit *api_actions_create_unit(Player *pp
                              int veteran_level, City *homecity,
                              int moves_left)
 {
-  return create_unit(pplayer, ptile, ptype->index, veteran_level,
+  return create_unit(pplayer, ptile, ptype, veteran_level,
                     homecity->id, moves_left);
 }
 
Index: server/scripting/api_find.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api_find.c,v
retrieving revision 1.8
diff -p -u -r1.8 api_find.c
--- server/scripting/api_find.c 18 Jul 2005 22:46:29 -0000      1.8
+++ server/scripting/api_find.c 19 Jul 2005 03:41:57 -0000
@@ -122,8 +122,7 @@ Unit_Type *api_find_unit_type(int unit_t
 **************************************************************************/
 Unit_Type *api_find_unit_type_by_name(const char *name_orig)
 {
-  Unit_type_id id = find_unit_type_by_name_orig(name_orig);
-  return api_find_unit_type(id);
+  return find_unit_type_by_name_orig(name_orig);
 }
 
 /**************************************************************************
Index: server/scripting/api_methods.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api_methods.c,v
retrieving revision 1.2
diff -p -u -r1.2 api_methods.c
--- server/scripting/api_methods.c      11 May 2005 00:53:22 -0000      1.2
+++ server/scripting/api_methods.c      19 Jul 2005 03:41:57 -0000
@@ -42,7 +42,7 @@ bool api_methods_unit_type_has_flag(Unit
   enum unit_flag_id id = unit_flag_from_str(flag);
 
   if (id != F_LAST) {
-    return unit_type_flag(punit_type->index, id);
+    return unit_type_flag(punit_type, id);
   } else {
     script_error("Unit flag \"%s\" does not exist", flag);
     return FALSE;
@@ -57,7 +57,7 @@ bool api_methods_unit_type_has_role(Unit
   enum unit_role_id id = unit_role_from_str(role);
 
   if (id != L_LAST) {
-    return unit_has_role(punit_type->index, id);
+    return unit_has_role(punit_type, id);
   } else {
     script_error("Unit role \"%s\" does not exist", role);
     return FALSE;

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] Re: (PR#13503) change unit types to use pointers, Jason Short <=