Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] (PR#13482) track nations by pointer
Home

[Freeciv-Dev] (PR#13482) track nations by pointer

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13482) track nations by pointer
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 15 Jul 2005 22:26:27 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This patch changes just about all nation variables to be struct
nation_type * instead of Nation_type_id values.  It is straightforward
but lengthy.  I fixed a couple of buglets while editing the code and
probably introduced a couple of new ones in their place.

-jason

Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.533
diff -p -u -r1.533 packhand.c
--- client/packhand.c   16 Jul 2005 03:54:12 -0000      1.533
+++ client/packhand.c   16 Jul 2005 05:24:34 -0000
@@ -1422,7 +1422,7 @@ void handle_player_info(struct packet_pl
   sz_strlcpy(pplayer->name, pinfo->name);
 
   pplayer->is_observer = pinfo->is_observer;
-  pplayer->nation=pinfo->nation;
+  pplayer->nation = get_nation_by_idx(pinfo->nation);
   pplayer->is_male=pinfo->is_male;
   team_add_player(pplayer, team_get_by_id(pinfo->team));
   pplayer->score.game = pinfo->score;
@@ -2261,7 +2261,7 @@ void handle_ruleset_government_ruler_tit
            p->id, gov->name);
     return;
   }
-  gov->ruler_titles[p->id].nation = p->nation;
+  gov->ruler_titles[p->id].nation = get_nation_by_idx(p->nation);
   sz_strlcpy(gov->ruler_titles[p->id].male_title_orig, p->male_title);
   gov->ruler_titles[p->id].male_title
     = gov->ruler_titles[p->id].male_title_orig;
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.314
diff -p -u -r1.314 tilespec.c
--- client/tilespec.c   14 Jul 2005 19:25:44 -0000      1.314
+++ client/tilespec.c   16 Jul 2005 05:24:35 -0000
@@ -2663,12 +2663,12 @@ struct sprite *get_city_flag_sprite(cons
 static struct sprite *get_unit_nation_flag_sprite(const struct tileset *t,
                                                  const struct unit *punit)
 {
-  Nation_type_id nation = unit_owner(punit)->nation;
+  struct nation_type *pnation = unit_owner(punit)->nation;
 
   if (draw_unit_shields) {
-    return t->sprites.nation_shield.p[nation];
+    return t->sprites.nation_shield.p[pnation->index];
   } else {
-    return t->sprites.nation_flag.p[nation];
+    return t->sprites.nation_flag.p[pnation->index];
   }
 }
 
@@ -4329,13 +4329,9 @@ struct sprite *get_citizen_sprite(const 
   Return the sprite for the nation.
 **************************************************************************/
 struct sprite *get_nation_flag_sprite(const struct tileset *t,
-                                     Nation_type_id nation)
+                                     const struct nation_type *pnation)
 {
-  if (nation < 0 || nation >= game.control.nation_count) {
-    assert(0);
-    return NULL;
-  }
-  return t->sprites.nation_flag.p[nation];
+  return t->sprites.nation_flag.p[pnation->index];
 }
 
 /**************************************************************************
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.155
diff -p -u -r1.155 tilespec.h
--- client/tilespec.h   14 Jul 2005 19:25:44 -0000      1.155
+++ client/tilespec.h   16 Jul 2005 05:24:35 -0000
@@ -190,7 +190,7 @@ struct sprite *get_citizen_sprite(const 
 struct sprite *get_city_flag_sprite(const struct tileset *t,
                                    const struct city *pcity);
 struct sprite *get_nation_flag_sprite(const struct tileset *t,
-                                     Nation_type_id nation);
+                                     const struct nation_type *nation);
 struct sprite *get_tech_sprite(const struct tileset *t, Tech_type_id tech);
 struct sprite *get_building_sprite(const struct tileset *t, Impr_type_id b);
 struct sprite *get_government_sprite(const struct tileset *t,
Index: client/gui-gtk-2.0/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/dialogs.c,v
retrieving revision 1.111
diff -p -u -r1.111 dialogs.c
--- client/gui-gtk-2.0/dialogs.c        13 Jul 2005 15:29:13 -0000      1.111
+++ client/gui-gtk-2.0/dialogs.c        16 Jul 2005 05:24:36 -0000
@@ -1597,7 +1597,7 @@ static GtkWidget* create_list_of_nations
     GtkTreeIter it;
     GValue value = { 0, };
 
-    if (!is_nation_playable(pnation->index) || pnation->is_unavailable) {
+    if (!is_nation_playable(pnation) || pnation->is_unavailable) {
       continue;
     }
 
@@ -1607,7 +1607,7 @@ static GtkWidget* create_list_of_nations
 
     gtk_list_store_append(store, &it);
 
-    s = crop_blankspace(get_nation_flag_sprite(tileset, pnation->index));
+    s = crop_blankspace(get_nation_flag_sprite(tileset, pnation));
     img = sprite_get_pixbuf(s);
     used = pnation->is_used;
     gtk_list_store_set(store, &it, 0, pnation->index, 1, used, 2, img, -1);
@@ -1924,7 +1924,8 @@ static void select_random_leader(void)
     unique = TRUE;
   }
 
-  leaders = get_nation_leaders(selected_nation, &nleaders);
+  leaders
+    = get_nation_leaders(get_nation_by_idx(selected_nation), &nleaders);
   for (i = 0; i < nleaders; i++) {
     items = g_list_prepend(items, leaders[i].name);
   }
@@ -2045,7 +2046,7 @@ static void races_nation_callback(GtkTre
       select_random_leader();
       
       /* Select city style for chosen nation. */
-      cs = get_nation_city_style(selected_nation);
+      cs = get_nation_city_style(get_nation_by_idx(selected_nation));
       for (i = 0, j = 0; i < game.control.styles_count; i++) {
         if (city_style_has_requirements(&city_styles[i])) {
          continue;
@@ -2082,8 +2083,9 @@ static void races_leader_callback(void)
 
   name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(races_leader)->entry));
 
-  if (check_nation_leader_name(selected_nation, name)) {
-    selected_sex = get_nation_leader_sex(selected_nation, name);
+  if (check_nation_leader_name(get_nation_by_idx(selected_nation), name)) {
+    selected_sex = get_nation_leader_sex(get_nation_by_idx(selected_nation),
+                                        name);
     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(races_sex[selected_sex]),
                                 TRUE);
   }
@@ -2138,8 +2140,7 @@ static void races_response(GtkWidget *w,
     if (selected_nation == -1) {
       dsend_packet_nation_select_req(&aconnection,
                                     races_player->player_no,
-                                    NO_NATION_SELECTED,
-                                    FALSE, "", 0);
+                                    -1, FALSE, "", 0);
       popdown_races_dialog();
       return;
     }
@@ -2169,8 +2170,7 @@ static void races_response(GtkWidget *w,
   } else if (response == GTK_RESPONSE_CANCEL) {
     dsend_packet_nation_select_req(&aconnection,
                                   races_player->player_no,
-                                  NO_NATION_SELECTED,
-                                  FALSE, "", 0);
+                                  -1, FALSE, "", 0);
   }
   popdown_races_dialog();
 }
Index: client/gui-gtk-2.0/pages.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/pages.c,v
retrieving revision 1.35
diff -p -u -r1.35 pages.c
--- client/gui-gtk-2.0/pages.c  14 Jun 2005 18:49:08 -0000      1.35
+++ client/gui-gtk-2.0/pages.c  16 Jul 2005 05:24:36 -0000
@@ -1602,11 +1602,12 @@ static void update_nation_page(struct pa
   for (i = 0; i < packet->nplayers; i++) {
     GtkTreeIter iter;
     const char *nation_name;
+    struct nation_type *pnation = get_nation_by_idx(packet->nations[i]);
 
-    if (packet->nations[i] == NO_NATION_SELECTED) {
+    if (pnation == NO_NATION_SELECTED) {
       nation_name = "";
     } else {
-      nation_name = get_nation_name(packet->nations[i]);
+      nation_name = get_nation_name(pnation);
     }
 
     gtk_list_store_append(nation_store, &iter);
@@ -1617,8 +1618,8 @@ static void update_nation_page(struct pa
        4, packet->is_ai[i] ? _("AI") : _("Human"), -1);
 
     /* set flag if we've got one to set. */
-    if (packet->nations[i] != NO_NATION_SELECTED) {
-      GdkPixbuf *flag = get_flag(packet->nations[i]);
+    if (pnation != NO_NATION_SELECTED) {
+      GdkPixbuf *flag = get_flag(pnation);
 
       if (flag) {
        gtk_list_store_set(nation_store, &iter, 1, flag, -1);
Index: client/gui-gtk-2.0/plrdlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/plrdlg.c,v
retrieving revision 1.65
diff -p -u -r1.65 plrdlg.c
--- client/gui-gtk-2.0/plrdlg.c 11 Jun 2005 19:07:30 -0000      1.65
+++ client/gui-gtk-2.0/plrdlg.c 16 Jul 2005 05:24:36 -0000
@@ -536,7 +536,7 @@ void create_players_dialog(void)
 /**************************************************************************
  Builds the flag pixmap.
 **************************************************************************/
-GdkPixbuf *get_flag(Nation_type_id nation)
+GdkPixbuf *get_flag(const struct nation_type *nation)
 {
   int x0, y0, x1, y1, w, h;
   GdkPixbuf *im, *im2;
Index: client/gui-gtk-2.0/plrdlg.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/plrdlg.h,v
retrieving revision 1.6
diff -p -u -r1.6 plrdlg.h
--- client/gui-gtk-2.0/plrdlg.h 30 Apr 2005 17:09:26 -0000      1.6
+++ client/gui-gtk-2.0/plrdlg.h 16 Jul 2005 05:24:36 -0000
@@ -18,6 +18,6 @@
 void popdown_players_dialog(void);
 
 /* Misc helper functions */
-GdkPixbuf *get_flag(Nation_type_id nation);
+GdkPixbuf *get_flag(const struct nation_type *pnation);
 
 #endif  /* FC__PLRDLG_H */
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.59
diff -p -u -r1.59 government.c
--- common/government.c 11 May 2005 14:11:20 -0000      1.59
+++ common/government.c 16 Jul 2005 05:24:36 -0000
@@ -92,7 +92,8 @@ struct government *get_gov_pcity(const s
 /***************************************************************
 ...
 ***************************************************************/
-const char *get_ruler_title(int gov, bool male, int nation)
+const char *get_ruler_title(int gov, bool male,
+                           const struct nation_type *nation)
 {
   struct government *g = get_government(gov);
   struct ruler_title *best_match = NULL;
@@ -100,6 +101,7 @@ const char *get_ruler_title(int gov, boo
 
   for(i=0; i<g->num_ruler_titles; i++) {
     struct ruler_title *title = &g->ruler_titles[i];
+
     if (title->nation == DEFAULT_TITLE && !best_match) {
       best_match = title;
     } else if (title->nation == nation) {
@@ -113,7 +115,7 @@ const char *get_ruler_title(int gov, boo
   } else {
     freelog(LOG_ERROR,
            "get_ruler_title: found no title for government %d (%s) nation %d",
-           gov, g->name, nation);
+           gov, g->name, nation->index);
     return male ? "Mr." : "Ms.";
   }
 }
@@ -155,7 +157,7 @@ bool can_change_to_government(struct pla
 /***************************************************************
 ...
 ***************************************************************/
-void set_ruler_title(struct government *gov, int nation,
+void set_ruler_title(struct government *gov, struct nation_type *pnation,
                      const char *male, const char *female)
 {
   struct ruler_title *title;
@@ -166,7 +168,7 @@ void set_ruler_title(struct government *
       gov->num_ruler_titles*sizeof(struct ruler_title));
   title = &(gov->ruler_titles[gov->num_ruler_titles-1]);
 
-  title->nation = nation;
+  title->nation = pnation; /* A valid nation or DEFAULT_NATION */
 
   sz_strlcpy(title->male_title_orig, male);
   title->male_title = title->male_title_orig;
Index: common/government.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.h,v
retrieving revision 1.46
diff -p -u -r1.46 government.h
--- common/government.h 11 May 2005 14:11:21 -0000      1.46
+++ common/government.h 16 Jul 2005 05:24:36 -0000
@@ -26,11 +26,11 @@
 /* each government has a list of ruler titles, where at least
  * one entry should have nation=DEFAULT_TITLE.
  */
-#define DEFAULT_TITLE  MAX_NUM_ITEMS
+#define DEFAULT_TITLE NULL
 
 struct ruler_title
 {
-  int  nation;
+  struct nation_type *nation;
   const char *male_title; /* Translated string - doesn't need freeing. */
   const char *female_title; /* Translated string - doesn't need freeing. */
   
@@ -97,11 +97,12 @@ struct government *find_government_by_na
 struct government *find_government_by_name_orig(const char *name);
 
 const char *get_government_name(int type);
-const char *get_ruler_title(int gov, bool male, int nation);
+const char *get_ruler_title(int gov, bool male,
+                           const struct nation_type *pnation);
 
 bool can_change_to_government(struct player *pplayer, int government);
 
-void set_ruler_title(struct government *gov, int nation, 
+void set_ruler_title(struct government *gov, struct nation_type *pnation,
                      const char *male, const char *female);
 void governments_alloc(int num);
 void governments_free(void);
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.250
diff -p -u -r1.250 map.h
--- common/map.h        7 Jun 2005 06:17:11 -0000       1.250
+++ common/map.h        16 Jul 2005 05:24:36 -0000
@@ -67,7 +67,7 @@ struct civ_map {
   /* Only used by server. */
   struct start_position {
     struct tile *tile;
-    Nation_type_id nation; /* May be NO_NATION_SELECTED. */
+    struct nation_type *nation; /* May be NO_NATION_SELECTED. */
   } *start_positions;  /* allocated at runtime */
 };
 
Index: common/nation.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.c,v
retrieving revision 1.55
diff -p -u -r1.55 nation.c
--- common/nation.c     16 Jul 2005 03:54:12 -0000      1.55
+++ common/nation.c     16 Jul 2005 05:24:36 -0000
@@ -42,16 +42,18 @@ static struct nation_group nation_groups
   If returning 0, prints log message with given loglevel
   quoting given func name, explaining problem.
 ***************************************************************/
-static bool bounds_check_nation_id(Nation_type_id nid, int loglevel,
-                                 const char *func_name)
+static bool bounds_check_nation(const struct nation_type *pnation,
+                               int loglevel, const char *func_name)
 {
-  if (game.control.nation_count==0) {
+  if (game.control.nation_count == 0) {
     freelog(loglevel, "%s before nations setup", func_name);
     return FALSE;
   }
-  if (nid < 0 || nid >= game.control.nation_count) {
+  if (pnation->index < 0
+      || pnation->index >= game.control.nation_count
+      || &nations[pnation->index] != pnation) {
     freelog(loglevel, "Bad nation id %d (count %d) in %s",
-           nid, game.control.nation_count, func_name);
+           pnation->index, game.control.nation_count, func_name);
     return FALSE;
   }
   return TRUE;
@@ -60,13 +62,13 @@ static bool bounds_check_nation_id(Natio
 /***************************************************************
 Find nation by (translated) name
 ***************************************************************/
-Nation_type_id find_nation_by_name(const char *name)
+struct nation_type *find_nation_by_name(const char *name)
 {
-  int i;
-
-  for (i = 0; i < game.control.nation_count; i++)
-     if(mystrcasecmp(name, get_nation_name (i)) == 0)
-       return i;
+  nations_iterate(pnation) {
+    if (mystrcasecmp(name, get_nation_name(pnation)) == 0) {
+      return pnation;
+    }
+  } nations_iterate_end;
 
   return NO_NATION_SELECTED;
 }
@@ -74,13 +76,13 @@ Nation_type_id find_nation_by_name(const
 /***************************************************************
 Find nation by (untranslated) original name
 ***************************************************************/
-Nation_type_id find_nation_by_name_orig(const char *name)
+struct nation_type *find_nation_by_name_orig(const char *name)
 {
-  int i;
-
-  for(i = 0; i < game.control.nation_count; i++)
-     if(mystrcasecmp(name, get_nation_name_orig (i)) == 0)
-       return i;
+  nations_iterate(pnation) {
+    if (mystrcasecmp(name, get_nation_name_orig(pnation)) == 0) {
+      return pnation;
+    }
+  } nations_iterate_end;
 
   return NO_NATION_SELECTED;
 }
@@ -88,23 +90,23 @@ Nation_type_id find_nation_by_name_orig(
 /***************************************************************
 Returns (translated) name of the nation
 ***************************************************************/
-const char *get_nation_name(Nation_type_id nation)
+const char *get_nation_name(const struct nation_type *pnation)
 {
-  if (!bounds_check_nation_id(nation, LOG_ERROR, "get_nation_name")) {
+  if (!bounds_check_nation(pnation, LOG_ERROR, "get_nation_name")) {
     return "";
   }
-  return nations[nation].name;
+  return pnation->name;
 }
 
 /***************************************************************
 Returns (untranslated) original name of the nation
 ***************************************************************/
-const char *get_nation_name_orig(Nation_type_id nation)
+const char *get_nation_name_orig(const struct nation_type *pnation)
 {
-  if (!bounds_check_nation_id(nation, LOG_ERROR, "get_nation_name_orig")) {
+  if (!bounds_check_nation(pnation, LOG_ERROR, "get_nation_name_orig")) {
     return "";
   }
-  return nations[nation].name_orig;
+  return pnation->name_orig;
 }
 
 /****************************************************************************
@@ -113,12 +115,12 @@ const char *get_nation_name_orig(Nation_
 
   This does not check whether a nation is "used" or "available".
 ****************************************************************************/
-bool is_nation_playable(Nation_type_id nation)
+bool is_nation_playable(const struct nation_type *nation)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "is_nation_playable")) {
-    die("wrong nation %d", nation);
+  if (!bounds_check_nation(nation, LOG_FATAL, "is_nation_playable")) {
+    die("wrong nation %d", nation->index);
   }
-  return nations[nation].is_playable;
+  return nation->is_playable;
 }
 
 /****************************************************************************
@@ -127,12 +129,12 @@ bool is_nation_playable(Nation_type_id n
 
   This does not check whether a nation is "used" or "available".
 ****************************************************************************/
-bool is_nation_observer(Nation_type_id nation)
+bool is_nation_observer(const struct nation_type *nation)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "is_nation_observer")) {
-    die("wrong nation %d", nation);
+  if (!bounds_check_nation(nation, LOG_FATAL, "is_nation_observer")) {
+    die("wrong nation %d", nation->index);
   }
-  return nations[nation].is_observer;
+  return nation->is_observer;
 }
 
 /****************************************************************************
@@ -141,50 +143,50 @@ bool is_nation_observer(Nation_type_id n
 
   This does not check whether a nation is "used" or "available".
 ****************************************************************************/
-bool is_nation_barbarian(Nation_type_id nation)
+bool is_nation_barbarian(const struct nation_type *nation)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "is_nation_barbarian")) {
-    die("wrong nation %d", nation);
+  if (!bounds_check_nation(nation, LOG_FATAL, "is_nation_barbarian")) {
+    die("wrong nation %d", nation->index);
   }
-  return nations[nation].is_barbarian;
+  return nation->is_barbarian;
 }
 
 /***************************************************************
 Returns pointer to the array of the nation leader names, and
 sets dim to number of leaders.
 ***************************************************************/
-struct leader *get_nation_leaders(Nation_type_id nation, int *dim)
+struct leader *get_nation_leaders(const struct nation_type *nation, int *dim)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "get_nation_leader_names")) {
-    die("wrong nation %d", nation);
+  if (!bounds_check_nation(nation, LOG_FATAL, "get_nation_leader_names")) {
+    die("wrong nation %d", nation->index);
   }
-  *dim = nations[nation].leader_count;
-  return nations[nation].leaders;
+  *dim = nation->leader_count;
+  return nation->leaders;
 }
 
 /****************************************************************************
   Returns pointer to the preferred set of nations that can fork from the
   nation.  The array is terminated by a NO_NATION_SELECTED value.
 ****************************************************************************/
-Nation_type_id* get_nation_civilwar(Nation_type_id nation)
+struct nation_type **get_nation_civilwar(const struct nation_type *nation)
 {
-  return nations[nation].civilwar_nations;
+  return nation->civilwar_nations;
 }
 
 /***************************************************************
 Returns sex of given leader name. If names is not found,
 return 1 (meaning male).
 ***************************************************************/
-bool get_nation_leader_sex(Nation_type_id nation, const char *name)
+bool get_nation_leader_sex(const struct nation_type *nation, const char *name)
 {
   int i;
   
-  if (!bounds_check_nation_id(nation, LOG_ERROR, "get_nation_leader_sex")) {
+  if (!bounds_check_nation(nation, LOG_ERROR, "get_nation_leader_sex")) {
     return FALSE;
   }
-  for (i = 0; i < nations[nation].leader_count; i++) {
-    if (strcmp(nations[nation].leaders[i].name, name) == 0) {
-      return nations[nation].leaders[i].is_male;
+  for (i = 0; i < nation->leader_count; i++) {
+    if (strcmp(nation->leaders[i].name, name) == 0) {
+      return nation->leaders[i].is_male;
     }
   }
   return TRUE;
@@ -193,15 +195,16 @@ bool get_nation_leader_sex(Nation_type_i
 /***************************************************************
 checks if given leader name exist for given nation.
 ***************************************************************/
-bool check_nation_leader_name(Nation_type_id nation, const char *name)
+bool check_nation_leader_name(const struct nation_type *pnation,
+                             const char *name)
 {
   int i;
   
-  if (!bounds_check_nation_id(nation, LOG_ERROR, "check_nation_leader_name")) {
+  if (!bounds_check_nation(pnation, LOG_ERROR, "check_nation_leader_name")) {
     return TRUE;                       /* ? */
   }
-  for (i = 0; i < nations[nation].leader_count; i++) {
-    if (strcmp(name, nations[nation].leaders[i].name) == 0) {
+  for (i = 0; i < pnation->leader_count; i++) {
+    if (strcmp(name, pnation->leaders[i].name) == 0) {
       return TRUE;
     }
   }
@@ -211,12 +214,12 @@ bool check_nation_leader_name(Nation_typ
 /***************************************************************
 Returns plural name of the nation.
 ***************************************************************/
-const char *get_nation_name_plural(Nation_type_id nation)
+const char *get_nation_name_plural(const struct nation_type *pnation)
 {
-  if (!bounds_check_nation_id(nation, LOG_ERROR, "get_nation_name_plural")) {
+  if (!bounds_check_nation(pnation, LOG_ERROR, "get_nation_name_plural")) {
     return "";
   }
-  return nations[nation].name_plural;
+  return pnation->name_plural;
 }
 
 /***************************************************************
@@ -225,10 +228,10 @@ Returns pointer to a nation 
 struct nation_type *get_nation_by_plr(const struct player *plr)
 {
   assert(plr != NULL);
-  if (!bounds_check_nation_id(plr->nation, LOG_FATAL, "get_nation_by_plr")) {
-    die("wrong nation %d", plr->nation);
+  if (!bounds_check_nation(plr->nation, LOG_FATAL, "get_nation_by_plr")) {
+    die("wrong nation %d", plr->nation->index);
   }
-  return &nations[plr->nation];
+  return plr->nation;
 }
 
 /***************************************************************
@@ -236,8 +239,8 @@ struct nation_type *get_nation_by_plr(co
 ***************************************************************/
 struct nation_type *get_nation_by_idx(Nation_type_id nation)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "get_nation_by_idx")) {
-    die("wrong nation %d", nation);
+  if (nation < 0 || nation >= game.control.nation_count) {
+    return NULL;
   }
   return &nations[nation];
 }
@@ -260,58 +263,55 @@ void nations_alloc(int num)
 /***************************************************************
  De-allocate resources associated with the given nation.
 ***************************************************************/
-static void nation_free(Nation_type_id nation)
+static void nation_free(struct nation_type *pnation)
 {
   int i;
-  struct nation_type *p = get_nation_by_idx(nation);
 
-  for (i = 0; i < p->leader_count; i++) {
-    free(p->leaders[i].name);
+  for (i = 0; i < pnation->leader_count; i++) {
+    free(pnation->leaders[i].name);
   }
-  if (p->leaders) {
-    free(p->leaders);
-    p->leaders = NULL;
+  if (pnation->leaders) {
+    free(pnation->leaders);
+    pnation->leaders = NULL;
   }
   
-  if (p->legend) {
-    free(p->legend);
-    p->legend = NULL;
+  if (pnation->legend) {
+    free(pnation->legend);
+    pnation->legend = NULL;
   }
 
-  if (p->civilwar_nations) {
-    free(p->civilwar_nations);
-    p->civilwar_nations = NULL;
+  if (pnation->civilwar_nations) {
+    free(pnation->civilwar_nations);
+    pnation->civilwar_nations = NULL;
   }
 
-  if (p->parent_nations) {
-    free(p->parent_nations);
-    p->parent_nations = NULL;
+  if (pnation->parent_nations) {
+    free(pnation->parent_nations);
+    pnation->parent_nations = NULL;
   }
   
-  if (p->groups) {
-    free(p->groups);
-    p->groups = NULL;
+  if (pnation->groups) {
+    free(pnation->groups);
+    pnation->groups = NULL;
   }
 
-  nation_city_names_free(p->city_names);
-  p->city_names = NULL;
+  nation_city_names_free(pnation->city_names);
+  pnation->city_names = NULL;
 }
 
 /***************************************************************
  De-allocate the currently allocated nations and remove all
  nation groups
 ***************************************************************/
-void nations_free()
+void nations_free(void)
 {
-  Nation_type_id nation;
-
   if (!nations) {
     return;
   }
 
-  for (nation = 0; nation < game.control.nation_count; nation++) {
-    nation_free(nation);
-  }
+  nations_iterate(pnation) {
+    nation_free(pnation);
+  } nations_iterate_end;
 
   free(nations);
   nations = NULL;
@@ -343,12 +343,12 @@ void nation_city_names_free(struct city_
 /***************************************************************
 Returns nation's city style
 ***************************************************************/
-int get_nation_city_style(Nation_type_id nation)
+int get_nation_city_style(const struct nation_type *pnation)
 {
-  if (!bounds_check_nation_id(nation, LOG_FATAL, "get_nation_city_style")) {
-    die("wrong nation %d", nation);
+  if (!bounds_check_nation(pnation, LOG_FATAL, "get_nation_city_style")) {
+    die("wrong nation %d", pnation->index);
   }
-  return nations[nation].city_style;
+  return pnation->city_style;
 }
 
 /***************************************************************
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.52
diff -p -u -r1.52 nation.h
--- common/nation.h     16 Jul 2005 03:54:12 -0000      1.52
+++ common/nation.h     16 Jul 2005 05:24:36 -0000
@@ -22,7 +22,7 @@
 #define MAX_NUM_TECH_GOALS 10
 
 /* Changing this value will break network compatibility. */
-#define NO_NATION_SELECTED (Nation_type_id)(-1)
+#define NO_NATION_SELECTED (NULL)
 
 /* 
  * Purpose of this constant is to catch invalid ruleset and network
@@ -83,8 +83,8 @@ struct nation_type {
   /* civilwar_nations is a NO_NATION_SELECTED-terminated list of index of
    * the nations that can fork from this one.  parent_nations is the inverse
    * of this array.  Server only. */
-  Nation_type_id *civilwar_nations;
-  Nation_type_id *parent_nations;
+  struct nation_type **civilwar_nations;
+  struct nation_type **parent_nations;
 
   /* untranslated copies: */
   char name_orig[MAX_LEN_NAME];
@@ -105,24 +105,26 @@ struct nation_type {
   bool is_unavailable, is_used;
 };
 
-Nation_type_id find_nation_by_name(const char *name);
-Nation_type_id find_nation_by_name_orig(const char *name);
-const char *get_nation_name(Nation_type_id nation);
-const char *get_nation_name_plural(Nation_type_id nation);
-const char *get_nation_name_orig(Nation_type_id nation);
-bool is_nation_playable(Nation_type_id nation);
-bool is_nation_observer(Nation_type_id nation);
-bool is_nation_barbarian(Nation_type_id nation);
-struct leader *get_nation_leaders(Nation_type_id nation, int *dim);
-Nation_type_id *get_nation_civilwar(Nation_type_id nation);
-bool get_nation_leader_sex(Nation_type_id nation, const char *name);
+struct nation_type *find_nation_by_name(const char *name);
+struct nation_type *find_nation_by_name_orig(const char *name);
+const char *get_nation_name(const struct nation_type *nation);
+const char *get_nation_name_plural(const struct nation_type *nation);
+const char *get_nation_name_orig(const struct nation_type *nation);
+bool is_nation_playable(const struct nation_type *nation);
+bool is_nation_observer(const struct nation_type *nation);
+bool is_nation_barbarian(const struct nation_type *nation);
+struct leader *get_nation_leaders(const struct nation_type *nation, int *dim);
+struct nation_type **get_nation_civilwar(const struct nation_type *nation);
+bool get_nation_leader_sex(const struct nation_type *nation,
+                          const char *name);
 struct nation_type *get_nation_by_plr(const struct player *plr);
 struct nation_type *get_nation_by_idx(Nation_type_id nation);
-bool check_nation_leader_name(Nation_type_id nation, const char *name);
+bool check_nation_leader_name(const struct nation_type *nation,
+                             const char *name);
 void nations_alloc(int num);
 void nations_free(void);
 void nation_city_names_free(struct city_name *city_names);
-int get_nation_city_style(Nation_type_id nation);
+int get_nation_city_style(const struct nation_type *nation);
 
 struct nation_group* add_new_nation_group(const char* name);
 int get_nation_groups_count(void);
@@ -135,14 +137,14 @@ bool can_conn_edit_players_nation(const 
 
 /* Iterate over nations.  This iterates over all nations, including
  * unplayable ones (use is_nation_playable to filter if necessary). */
-#define nations_iterate(nation)                                                
    \
+#define nations_iterate(pnation)                                           \
 {                                                                          \
   int NI_index;                                                                
    \
                                                                            \
   for (NI_index = 0;                                                       \
        NI_index < game.control.nation_count;                               \
        NI_index++) {                                                       \
-    struct nation_type *nation = get_nation_by_idx(NI_index);
+    struct nation_type *pnation = get_nation_by_idx(NI_index);
 
 #define nations_iterate_end                                                \
   }                                                                        \
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.158
diff -p -u -r1.158 player.h
--- common/player.h     7 Jul 2005 08:34:38 -0000       1.158
+++ common/player.h     16 Jul 2005 05:24:37 -0000
@@ -204,7 +204,7 @@ struct player {
   bool is_male;
   int government;
   int target_government;
-  Nation_type_id nation;
+  struct nation_type *nation;
   struct team *team;
   bool is_ready; /* Did the player click "start" yet? */
   bool phase_done;
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.29
diff -p -u -r1.29 requirements.c
--- common/requirements.c       14 Jul 2005 19:25:45 -0000      1.29
+++ common/requirements.c       16 Jul 2005 05:24:37 -0000
@@ -207,7 +207,7 @@ struct req_source req_source_from_values
     source.value.terrain = get_terrain(value);
     return source;
   case REQ_NATION:
-    source.value.nation = value;
+    source.value.nation = get_nation_by_idx(value);
     return source;
   case REQ_UNITTYPE:
     source.value.unittype = value;
@@ -263,7 +263,7 @@ void req_source_get_values(const struct 
     *value = source->value.terrain->index;
     return;
   case REQ_NATION:
-    *value = source->value.nation;
+    *value = source->value.nation->index;
     return;
   case REQ_UNITTYPE:
     *value = source->value.unittype;
@@ -686,7 +686,7 @@ static bool is_terrain_in_range(const st
 ****************************************************************************/
 static bool is_nation_in_range(const struct player *target_player,
                               enum req_range range, bool survives,
-                              Nation_type_id nation)
+                              const struct nation_type *nation)
 {
   switch (range) {
   case REQ_RANGE_PLAYER:
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.20
diff -p -u -r1.20 requirements.h
--- common/requirements.h       14 Jul 2005 19:25:45 -0000      1.20
+++ common/requirements.h       16 Jul 2005 05:24:37 -0000
@@ -16,6 +16,7 @@
 
 #include "fc_types.h"
 #include "tech.h"
+#include "terrain.h"
 #include "unittype.h"
 
 /* The type of a requirement source.  This must correspond to req_type_names[]
@@ -58,7 +59,7 @@ struct req_source {
     Impr_type_id building;              /* source building */
     enum tile_special_type special;     /* source special */
     struct terrain *terrain;            /* source terrain type */
-    Nation_type_id nation;              /* source nation type */
+    struct nation_type *nation;         /* source nation type */
     Unit_type_id unittype;              /* source unittype */
     enum unit_flag_id unitflag;         /* source unit flag */
     Output_type_id outputtype;          /* source output type */
Index: common/tech.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.h,v
retrieving revision 1.57
diff -p -u -r1.57 tech.h
--- common/tech.h       8 Jul 2005 03:31:18 -0000       1.57
+++ common/tech.h       16 Jul 2005 05:24:37 -0000
@@ -16,7 +16,6 @@
 #include "shared.h"
 
 #include "fc_types.h"
-#include "nation.h" /* Nation_type_id */
 
 typedef int Tech_type_id;
 /*
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.95
diff -p -u -r1.95 barbarian.c
--- server/barbarian.c  16 Jul 2005 03:54:13 -0000      1.95
+++ server/barbarian.c  16 Jul 2005 05:24:39 -0000
@@ -83,11 +83,11 @@ static bool is_sea_barbarian(struct play
   available nation, or the first nation already in use by another barbarian
   player.
 ****************************************************************************/
-static Nation_type_id pick_barbarian_nation(void)
+struct nation_type *pick_barbarian_nation(void)
 {
   nations_iterate(pnation) {
-    if (is_nation_barbarian(pnation->index) && !pnation->is_used) {
-      return pnation->index;
+    if (is_nation_barbarian(pnation) && !pnation->is_used) {
+      return pnation;
     }
   } nations_iterate_end;
 
@@ -113,7 +113,7 @@ static struct player *create_barbarian_p
 {
   int newplayer = game.info.nplayers;
   struct player *barbarians;
-  Nation_type_id nation = pick_barbarian_nation();
+  struct nation_type *nation = pick_barbarian_nation();
 
   players_iterate(barbarians) {
     if ((land && is_land_barbarian(barbarians))
Index: server/barbarian.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.h,v
retrieving revision 1.11
diff -p -u -r1.11 barbarian.h
--- server/barbarian.h  29 Sep 2004 02:24:23 -0000      1.11
+++ server/barbarian.h  16 Jul 2005 05:24:39 -0000
@@ -27,6 +27,7 @@
 
 #define MAP_FACTOR     2000  /* adjust this to get a good uprising frequency */
 
+struct nation_type *pick_barbarian_nation(void);
 bool unleash_barbarians(struct tile *ptile);
 void summon_barbarians(void);
 bool is_land_barbarian(struct player *pplayer);
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.334
diff -p -u -r1.334 citytools.c
--- server/citytools.c  14 Jul 2005 19:25:46 -0000      1.334
+++ server/citytools.c  16 Jul 2005 05:24:39 -0000
@@ -349,7 +349,7 @@ char *city_name_suggestion(struct player
 {
   int i = 0, j;
   bool nations_selected[game.control.nation_count];
-  Nation_type_id nation_list[game.control.nation_count], n;
+  struct nation_type *nation_list[game.control.nation_count];
   int queue_size;
 
   static const int num_tiles = MAP_MAX_WIDTH * MAP_MAX_HEIGHT; 
@@ -382,23 +382,23 @@ char *city_name_suggestion(struct player
 
   queue_size = 1;
   nation_list[0] = pplayer->nation;
-  nations_selected[pplayer->nation] = TRUE;
+  nations_selected[pplayer->nation->index] = TRUE;
 
   while (i < game.control.nation_count) {
     for (; i < queue_size; i++) {
-      struct nation_type *nation;
       char *name;
+      struct nation_type *nation;
 
       {
        /* Pick a random nation from the queue. */
        const int which = i + myrand(queue_size - i);
-       const Nation_type_id tmp = nation_list[i];
+       struct nation_type *tmp = nation_list[i];
 
        nation_list[i] = nation_list[which];
        nation_list[which] = tmp;
       }
 
-      nation = get_nation_by_idx(nation_list[i]);
+      nation = nation_list[i];
       name = search_for_city_name(ptile, nation->city_names, pplayer);
 
       freelog(LOG_DEBUG, "Looking through %s.", nation->name);
@@ -409,36 +409,38 @@ char *city_name_suggestion(struct player
 
       /* Append the nation's parent nations into the search tree. */
       for (j = 0; nation->parent_nations[j] != NO_NATION_SELECTED; j++) {
-       n = nation->parent_nations[j];
-       if (!nations_selected[n]) {
+       struct nation_type *n = nation->parent_nations[j];
+
+       if (!nations_selected[n->index]) {
          nation_list[queue_size] = n;
-         nations_selected[n] = TRUE;
+         nations_selected[n->index] = TRUE;
          queue_size++;
-         freelog(LOG_DEBUG, "Parent %s.", get_nation_by_idx(n)->name);
+         freelog(LOG_DEBUG, "Parent %s.", n->name);
        }
       }
 
       /* Append the nation's civil war nations into the search tree. */
       for (j = 0; nation->civilwar_nations[j] != NO_NATION_SELECTED; j++) {
-       n = nation->civilwar_nations[j];
-       if (!nations_selected[n]) {
+       struct nation_type *n = nation->civilwar_nations[j];
+
+       if (!nations_selected[n->index]) {
          nation_list[queue_size] = n;
-         nations_selected[n] = TRUE;
+         nations_selected[n->index] = TRUE;
          queue_size++;
-         freelog(LOG_DEBUG, "Child %s.", get_nation_by_idx(n)->name);
+         freelog(LOG_DEBUG, "Child %s.", n->name);
        }
       }
     }
 
     /* Append all remaining nations. */
-    for (n = 0; n < game.control.nation_count; n++) {
-      if (!nations_selected[n]) {
+    nations_iterate(n) {
+      if (!nations_selected[n->index]) {
        nation_list[queue_size] = n;
-       nations_selected[n] = TRUE;
+       nations_selected[n->index] = TRUE;
        queue_size++;
-       freelog(LOG_DEBUG, "Misc nation %s.", get_nation_by_idx(n)->name);
+       freelog(LOG_DEBUG, "Misc nation %s.", n->name);
       }
-    }
+    } nations_iterate_end;
   }
 
   for (i = 1; i <= num_tiles; i++ ) {
@@ -1199,7 +1201,7 @@ void handle_unit_enter_city(struct unit 
       && civil_war_triggered(cplayer)) {
     /* Do a civil war only if there's an available unused nation. */
     nations_iterate(pnation) {
-      if (is_nation_playable(pnation->index)
+      if (is_nation_playable(pnation)
          && !pnation->is_unavailable && !pnation->is_used) {
        do_civil_war = TRUE;
        break;
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.163
diff -p -u -r1.163 gamehand.c
--- server/gamehand.c   5 May 2005 18:32:52 -0000       1.163
+++ server/gamehand.c   16 Jul 2005 05:24:39 -0000
@@ -181,13 +181,14 @@ void init_new_game(void)
   /* First set up some data fields. */
   freelog(LOG_VERBOSE, "Placing players at start positions.");
   for (i = 0; i < map.num_start_positions; i++) {
-    Nation_type_id n = map.start_positions[i].nation;
+    struct nation_type *n = map.start_positions[i].nation;
 
     pos_used[i] = FALSE;
     freelog(LOG_VERBOSE, "%3d : (%2d,%2d) : %d : %s",
            i, map.start_positions[i].tile->x,
            map.start_positions[i].tile->y,
-           n, (n >= 0 ? get_nation_name(n) : ""));
+           n ? n->index : -1,
+           n ? n->name : "");
   }
   players_iterate(pplayer) {
     start_pos[pplayer->player_no] = NO_START_POS;
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.399
diff -p -u -r1.399 plrhand.c
--- server/plrhand.c    16 Jul 2005 03:54:13 -0000      1.399
+++ server/plrhand.c    16 Jul 2005 05:24:40 -0000
@@ -881,7 +881,7 @@ static void package_player_common(struct
   packet->playerno=plr->player_no;
   sz_strlcpy(packet->name, plr->name);
   sz_strlcpy(packet->username, plr->username);
-  packet->nation=plr->nation;
+  packet->nation = plr->nation ? plr->nation->index : -1;
   packet->is_male=plr->is_male;
   packet->is_observer=plr->is_observer;
   packet->team = plr->team ? plr->team->index : -1;
@@ -1317,7 +1317,7 @@ static int nations_match(struct nation_t
 
   choices may be NULL; if so it's ignored.
 ****************************************************************************/
-Nation_type_id pick_available_nation(Nation_type_id *choices)
+struct nation_type *pick_available_nation(struct nation_type **choices)
 {
   enum {
     UNAVAILABLE, AVAILABLE, PREFERRED
@@ -1330,7 +1330,7 @@ Nation_type_id pick_available_nation(Nat
    * 1: available
    * 2: preferred choice */
   nations_iterate(pnation) {
-    if (!is_nation_playable(pnation->index)
+    if (!is_nation_playable(pnation)
        || pnation->is_used || pnation->is_unavailable) {
       /* Nation is unplayable or already used: don't consider it. */
       nations_used[pnation->index] = UNAVAILABLE;
@@ -1343,9 +1343,8 @@ Nation_type_id pick_available_nation(Nat
     match[pnation->index] = 1;
     players_iterate(pplayer) {
       if (pplayer->nation != NO_NATION_SELECTED) {
-       struct nation_type *pnation2 = get_nation_by_idx(pplayer->nation);
-
-       match[pnation->index] += nations_match(pnation2, pnation) * 100;
+       match[pnation->index]
+         += nations_match(pplayer->nation, pnation) * 100;
       }
     } players_iterate_end;
 
@@ -1353,9 +1352,9 @@ Nation_type_id pick_available_nation(Nat
   } nations_iterate_end;
 
   for (; choices && *choices != NO_NATION_SELECTED; choices++) {
-    if (nations_used[*choices] == AVAILABLE) {
-      pref_nations_avail += match[*choices];
-      nations_used[*choices] = PREFERRED;
+    if (nations_used[(*choices)->index] == AVAILABLE) {
+      pref_nations_avail += match[(*choices)->index];
+      nations_used[(*choices)->index] = PREFERRED;
     }
   }
 
@@ -1375,7 +1374,7 @@ Nation_type_id pick_available_nation(Nat
       pick -= match[pnation->index];
 
       if (pick < 0) {
-       return pnation->index;
+       return pnation;
       }
     }
   } nations_iterate_end;
@@ -1388,11 +1387,11 @@ Nation_type_id pick_available_nation(Nat
   Return an available observer nation.  This simply returns the first
   such nation.  If no nation is available NO_NATION_SELECTED is returned.
 ****************************************************************************/
-static Nation_type_id pick_observer_nation(void)
+static struct nation_type *pick_observer_nation(void)
 {
   nations_iterate(pnation) {
-    if (is_nation_observer(pnation->index) && !pnation->is_used) {
-      return pnation->index;
+    if (is_nation_observer(pnation) && !pnation->is_used) {
+      return pnation;
     }
   } nations_iterate_end;
 
@@ -1409,7 +1408,7 @@ static Nation_type_id pick_observer_nati
 struct player *create_global_observer(void)
 {
   struct player *pplayer = NULL;
-  Nation_type_id nation;
+  struct nation_type *nation;
 
   /* Check if a global observer already exists. If so, return it.  Note the
    * observer may exist at any position in the array. */
@@ -1502,7 +1501,8 @@ static struct player *split_player(struc
 {
   int newplayer = game.info.nplayers;
   struct player *cplayer = &game.players[newplayer];
-  Nation_type_id *civilwar_nations = get_nation_civilwar(pplayer->nation);
+  struct nation_type **civilwar_nations
+    = get_nation_civilwar(pplayer->nation);
   struct player_research *new_research, *old_research;
 
   /* make a new player */
Index: server/plrhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.h,v
retrieving revision 1.79
diff -p -u -r1.79 plrhand.h
--- server/plrhand.h    13 Jul 2005 15:29:13 -0000      1.79
+++ server/plrhand.h    16 Jul 2005 05:24:40 -0000
@@ -36,7 +36,7 @@ void kill_player(struct player *pplayer)
 void kill_dying_players(void);
 void update_revolution(struct player *pplayer);
 
-Nation_type_id pick_available_nation(Nation_type_id *choices);
+struct nation_type *pick_available_nation(struct nation_type **choices);
 
 void check_player_government_rates(struct player *pplayer);
 void make_contact(struct player *pplayer1, struct player *pplayer2,
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.273
diff -p -u -r1.273 ruleset.c
--- server/ruleset.c    16 Jul 2005 03:54:13 -0000      1.273
+++ server/ruleset.c    16 Jul 2005 05:24:40 -0000
@@ -1873,8 +1873,10 @@ static void load_nation_names(struct sec
 
     /* Check if nation name is already defined. */
     for(j = 0; j < i; j++) {
-      if (0 == strcmp(get_nation_name(j), pl->name)
-         || 0 == strcmp(get_nation_name_plural(j), pl->name_plural)) {
+      struct nation_type *n2 = get_nation_by_idx(j);
+
+      if (0 == strcmp(get_nation_name(n2), pl->name)
+         || 0 == strcmp(get_nation_name_plural(n2), pl->name_plural)) {
         freelog(LOG_FATAL,
                "Nation %s (the %s) defined twice; "
                "in section nation%d and section nation%d",
@@ -2146,7 +2148,7 @@ static void load_ruleset_nations(struct 
        check_name(male_name);
        check_name(female_name);
        /* Truncation is handled by set_ruler_title(). */
-       set_ruler_title(gov, i, male_name, female_name);
+       set_ruler_title(gov, pl, male_name, female_name);
       } else {
        /* LOG_VERBOSE rather than LOG_ERROR so that can use single nation
           ruleset file with variety of government ruleset files: */
@@ -2237,27 +2239,24 @@ static void load_ruleset_nations(struct 
   }
 
   /* Calculate parent nations.  O(n^2) algorithm. */
-  for (i = 0; i < game.control.nation_count; i++) {
-    Nation_type_id parents[game.control.nation_count];
+  nations_iterate(pl) {
+    struct nation_type *parents[game.control.nation_count];
     int count = 0;
 
-    pl = get_nation_by_idx(i);
-    for (j = 0; j < game.control.nation_count; j++) {
-      struct nation_type *p2 = get_nation_by_idx(j);
-
+    nations_iterate(p2) {
       for (k = 0; p2->civilwar_nations[k] != NO_NATION_SELECTED; k++) {
-       if (p2->civilwar_nations[k] == i) {
-         parents[count] = j;
+       if (p2->civilwar_nations[k] == pl) {
+         parents[count] = p2;
          count++;
        }
       }
-    }
+    } nations_iterate_end;
 
     assert(sizeof(parents[0]) == sizeof(*pl->parent_nations));
     pl->parent_nations = fc_malloc((count + 1) * sizeof(parents[0]));
     memcpy(pl->parent_nations, parents, count * sizeof(parents[0]));
     pl->parent_nations[count] = NO_NATION_SELECTED;
-  }
+  } nations_iterate_end;
 
   free(sec);
   section_file_check_unused(file, filename);
@@ -2901,7 +2900,7 @@ static void send_ruleset_governments(str
 
       title.gov = g->index;
       title.id = j;
-      title.nation = p_title->nation;
+      title.nation = p_title->nation ? p_title->nation->index : -1;
       sz_strlcpy(title.male_title, p_title->male_title);
       sz_strlcpy(title.female_title, p_title->female_title);
     
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.262
diff -p -u -r1.262 savegame.c
--- server/savegame.c   14 Jul 2005 19:25:46 -0000      1.262
+++ server/savegame.c   16 Jul 2005 05:24:41 -0000
@@ -45,6 +45,7 @@
 
 #include "script.h"
 
+#include "barbarian.h"
 #include "citytools.h"
 #include "cityturn.h"
 #include "diplhand.h"
@@ -513,7 +514,6 @@ static void map_startpos_load(struct sec
 {
   int savegame_start_positions;
   int i, j;
-  int nation_id;
   int nat_x, nat_y;
   
   for (savegame_start_positions = 0;
@@ -528,21 +528,21 @@ static void map_startpos_load(struct sec
     struct start_position start_positions[savegame_start_positions];
     
     for (i = j = 0; i < savegame_start_positions; i++) {
-      char *nation = secfile_lookup_str_default(file, NULL, "map.r%dsnation",
-                                                i);
+      char *nation_name = secfile_lookup_str_default(file, NULL,
+                                                    "map.r%dsnation", i);
+      struct nation_type *pnation;
 
-      if (nation == NULL) {
+      if (!nation_name) {
         /* Starting positions in normal games are saved without nation.
           Just ignore it */
        continue;
       }
-      
-      nation_id = find_nation_by_name_orig(nation);
-      if (nation_id == NO_NATION_SELECTED) {
+
+      pnation = find_nation_by_name_orig(nation_name);
+      if (pnation == NO_NATION_SELECTED) {
        freelog(LOG_NORMAL,
                _("Warning: Unknown nation %s for starting position no %d"),
-               nation,
-               i);
+               nation_name, i);
        continue;
       }
       
@@ -550,7 +550,7 @@ static void map_startpos_load(struct sec
       nat_y = secfile_lookup_int(file, "map.r%dsy", i);
 
       start_positions[j].tile = native_pos_to_tile(nat_x, nat_y);
-      start_positions[j].nation = nation_id;
+      start_positions[j].nation = pnation;
       j++;
     }
     map.num_start_positions = j;
@@ -1799,8 +1799,8 @@ static void player_load(struct player *p
     team_add_player(plr, pteam);
   }
 
-  if (is_barbarian(plr)) {
-    plr->nation = game.control.nation_count - 1;
+  if (is_barbarian(plr) && plr->nation == NO_NATION_SELECTED) {
+    plr->nation = pick_barbarian_nation();
   }
 
   /* government */
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.278
diff -p -u -r1.278 srv_main.c
--- server/srv_main.c   13 Jul 2005 15:29:13 -0000      1.278
+++ server/srv_main.c   16 Jul 2005 05:24:41 -0000
@@ -1080,10 +1080,8 @@ void check_for_full_turn_done(void)
   particular player.
 **************************************************************************/
 static bool is_default_nation_name(const char *name,
-                                  Nation_type_id nation_id)
+                                  const struct nation_type *nation)
 {
-  const struct nation_type *nation = get_nation_by_idx(nation_id);
-
   int choice;
 
   for (choice = 0; choice < nation->leader_count; choice++) {
@@ -1100,7 +1098,7 @@ static bool is_default_nation_name(const
   (a translated string to be sent to the client) if not.
 **************************************************************************/
 static bool is_allowed_player_name(struct player *pplayer,
-                                  Nation_type_id nation,
+                                  const struct nation_type *nation,
                                   const char *name,
                                   char *error_buf, size_t bufsz)
 {
@@ -1207,15 +1205,14 @@ void init_available_nations(void)
       nation->is_unavailable = TRUE;
     } nations_iterate_end;
     for (i = 0; i < map.num_start_positions; i++) {
-      Nation_type_id nation_no = map.start_positions[i].nation;
-      struct nation_type *nation = get_nation_by_idx(nation_no);
-
-      nation->is_unavailable = FALSE;
+      map.start_positions[i].nation->is_unavailable = FALSE;
     }
   } else {
     nations_iterate(nation) {
       /* We preemptively mark unplayable nations as unavailable. */
-      nation->is_unavailable = !is_nation_playable(nation->index);
+      /* FIXME: this may not be right since barbarians need them to be
+       * available (for instance). */
+      nation->is_unavailable = !is_nation_playable(nation);
     } nations_iterate_end;
   }
   nations_iterate(nation) {
@@ -1232,11 +1229,10 @@ void handle_nation_select_req(struct pla
                              Nation_type_id nation_no, bool is_male,
                              char *name, int city_style)
 {
-  Nation_type_id old_nation_no;
+  struct nation_type *old_nation, *new_nation;
   struct player *pplayer = get_player(player_no);
 
-  if (server_state != PRE_GAME_STATE
-      || !pplayer) {
+  if (server_state != PRE_GAME_STATE || !pplayer) {
     return;
   }
 
@@ -1244,36 +1240,34 @@ void handle_nation_select_req(struct pla
     return;
   }
 
-  old_nation_no = pplayer->nation;
+  old_nation = pplayer->nation;
+  new_nation = get_nation_by_idx(nation_no);
 
-  if (nation_no != NO_NATION_SELECTED) {
+  if (new_nation != NO_NATION_SELECTED) {
     char message[1024];
-    struct nation_type *nation;
 
     /* check sanity of the packet sent by client */
-    if (nation_no < 0 || nation_no >= game.control.nation_count
-       || city_style < 0 || city_style >= game.control.styles_count
+    if (city_style < 0 || city_style >= game.control.styles_count
        || city_style_has_requirements(&city_styles[city_style])) {
       return;
     }
 
-    nation = get_nation_by_idx(nation_no);
-    if (nation->is_unavailable) {
+    if (new_nation->is_unavailable) {
       notify_conn_ex(pplayer->connections, NULL, E_NATION_SELECTED,
                     _("%s nation is not available in this scenario."),
-                    nation->name);
+                    new_nation->name);
       return;
     }
-    if (nation->is_unavailable) {
+    if (new_nation->is_unavailable) {
       notify_conn_ex(pplayer->connections, NULL, E_NATION_SELECTED,
                     _("%s nation is already in use."),
-                    nation->name);
+                    new_nation->name);
       return;
     }
 
     remove_leading_trailing_spaces(name);
 
-    if (!is_allowed_player_name(pplayer, nation_no, name,
+    if (!is_allowed_player_name(pplayer, new_nation, name,
                                message, sizeof(message))) {
       notify_conn_ex(pplayer->connections, NULL, E_NATION_SELECTED,
                     "%s", message);
@@ -1284,22 +1278,20 @@ void handle_nation_select_req(struct pla
 
     notify_conn_ex(game.game_connections, NULL, E_NATION_SELECTED,
                   _("%s is the %s ruler %s."), pplayer->username,
-                  get_nation_name(nation_no), name);
+                  new_nation->name, name);
 
     sz_strlcpy(pplayer->name, name);
     pplayer->is_male = is_male;
     pplayer->city_style = city_style;
 
-    nation->is_used = TRUE;
-    send_nation_available(nation);
+    new_nation->is_used = TRUE;
+    send_nation_available(new_nation);
   }
 
-  pplayer->nation = nation_no;
+  pplayer->nation = new_nation; /* May be NULL (NO_NATION_SELECTED) */
   send_player_info_c(pplayer, game.est_connections);
 
-  if (old_nation_no != NO_NATION_SELECTED) {
-    struct nation_type *old_nation = get_nation_by_idx(old_nation_no);
-
+  if (old_nation != NO_NATION_SELECTED) {
     old_nation->is_used = FALSE;
     send_nation_available(old_nation);
   }
@@ -1463,13 +1455,12 @@ static void generate_players(void)
 
     /* See if the player name matches a known leader name. */
     nations_iterate(pnation) {
-      if (is_nation_playable(pnation->index)
+      if (is_nation_playable(pnation)
          && !pnation->is_unavailable && !pnation->is_used
-         && check_nation_leader_name(pnation->index, pplayer->name)) {
-       pplayer->nation = pnation->index;
-       pplayer->city_style = get_nation_city_style(pnation->index);
-       pplayer->is_male = get_nation_leader_sex(pnation->index,
-                                                pplayer->name);
+         && check_nation_leader_name(pnation, pplayer->name)) {
+       pplayer->nation = pnation;
+       pplayer->city_style = get_nation_city_style(pnation);
+       pplayer->is_male = get_nation_leader_sex(pnation, pplayer->name);
        break;
       }
     } nations_iterate_end;
@@ -1481,7 +1472,7 @@ static void generate_players(void)
     pplayer->nation = pick_available_nation(NULL);
     assert(pplayer->nation != NO_NATION_SELECTED);
 
-    get_nation_by_idx(pplayer->nation)->is_used = TRUE;
+    pplayer->nation->is_used = TRUE;
     pplayer->city_style = get_nation_city_style(pplayer->nation);
 
     pick_random_player_name(pplayer->nation, player_name);
@@ -1518,7 +1509,7 @@ static bool good_name(char *ptry, char *
      is found.
  newname should point to a buffer of size at least MAX_LEN_NAME.
 *************************************************************************/
-void pick_random_player_name(Nation_type_id nation, char *newname) 
+void pick_random_player_name(const struct nation_type *nation, char *newname) 
 {
    int i, names_count;
    struct leader *leaders;
Index: server/srv_main.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.h,v
retrieving revision 1.35
diff -p -u -r1.35 srv_main.h
--- server/srv_main.h   21 Jun 2005 10:17:03 -0000      1.35
+++ server/srv_main.h   16 Jul 2005 05:24:41 -0000
@@ -59,7 +59,8 @@ bool is_game_over(void);
 bool handle_packet_input(struct connection *pconn, void *packet, int type);
 void start_game(void);
 void save_game(char *orig_filename, const char *save_reason);
-void pick_random_player_name(Nation_type_id nation, char *newname);
+void pick_random_player_name(const struct nation_type *pnation,
+                            char *newname);
 void send_all_info(struct conn_list *dest);
 void check_for_full_turn_done(void);
 
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.426
diff -p -u -r1.426 stdinhand.c
--- server/stdinhand.c  7 Jul 2005 08:34:40 -0000       1.426
+++ server/stdinhand.c  16 Jul 2005 05:24:42 -0000
@@ -3118,10 +3118,10 @@ static void send_load_game_info(bool loa
 
       sz_strlcpy(packet.name[i], pplayer->name);
       sz_strlcpy(packet.username[i], pplayer->username);
-      if (game.control.nation_count) {
-       packet.nations[i] = pplayer->nation;
+      if (pplayer->nation != NO_NATION_SELECTED) {
+       packet.nations[i] = pplayer->nation->index;
       } else { /* No nations picked */
-       packet.nations[i] = NO_NATION_SELECTED;
+       packet.nations[i] = -1;
       }
       packet.is_alive[i] = pplayer->is_alive;
       packet.is_ai[i] = pplayer->ai.control;
Index: server/scripting/api.pkg
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api.pkg,v
retrieving revision 1.11
diff -p -u -r1.11 api.pkg
--- server/scripting/api.pkg    14 Jul 2005 19:25:47 -0000      1.11
+++ server/scripting/api.pkg    16 Jul 2005 05:24:42 -0000
@@ -31,7 +31,7 @@ struct Player_ai {
 
 struct Player {
   const char *name;
-  int nation @ nation_id;
+  Nation_Type *nation;
 
   Player_ai ai;
 
@@ -131,10 +131,6 @@ function Player:is_human()
   return not self.ai.control
 end
 
-function Player:nation()
-  return find.nation(self.nation_id)
-end
-
 function Player:num_cities()
   return methods_player_num_cities(self)
 end
Index: server/scripting/api_find.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/scripting/api_find.c,v
retrieving revision 1.7
diff -p -u -r1.7 api_find.c
--- server/scripting/api_find.c 14 Jul 2005 19:25:47 -0000      1.7
+++ server/scripting/api_find.c 16 Jul 2005 05:24:42 -0000
@@ -89,8 +89,7 @@ Nation_Type *api_find_nation_type(int na
 **************************************************************************/
 Nation_Type *api_find_nation_type_by_name(const char *name_orig)
 {
-  Nation_type_id id = find_nation_by_name_orig(name_orig);
-  return api_find_nation_type(id);
+  return find_nation_by_name_orig(name_orig);
 }
 
 /**************************************************************************

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13482) track nations by pointer, Jason Short <=