Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2004:
[Freeciv-Dev] (PR#9712) Governments saved by name
Home

[Freeciv-Dev] (PR#9712) Governments saved by name

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#9712) Governments saved by name
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Wed, 18 Aug 2004 00:16:59 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=9712 >

> [jdorje - Tue Aug 17 15:42:34 2004]:
> 
> Just one other minor ugliness: the "id" value you use is declared as a 
> Tech_type_id, but of course you're using it as a government id.  I think 
> a new integer (or Government_type_id, if there is such a thing) should 
> be declared within the block where id is used.
> 
> jason

It is used also by units and improvements. I think it will be enough to
change the type to int. Savegame.c is the place where conversion is
taking place, so I don't see problem here.
--
mateusz
? client/civgame-3650.sav.gz
? client/civgame-3750.sav.gz
? client/civgame-3950.sav.gz
? client/core.25993
? client/core.26163
? server/civgame+0001.sav.gz
? server/civgame+0200.sav
? server/civgame-0250.sav
? server/civgame-0500.sav.gz
? server/civgame-0750.sav.gz
? server/civgame-1000.sav.gz
? server/civgame-1500.sav.gz
? server/civgame-2000.sav.gz
? server/civgame-2500.sav.gz
? server/civgame-3000.sav.gz
? server/civgame-3500.sav.gz
? server/core.7881
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.43
diff -u -r1.43 government.c
--- common/government.c 25 Jun 2004 23:43:01 -0000      1.43
+++ common/government.c 18 Aug 2004 07:15:21 -0000
@@ -143,6 +143,20 @@
 /***************************************************************
 ...
 ***************************************************************/
+struct government *find_government_by_name_orig(const char *name)
+{
+  government_iterate(gov) {
+    if (mystrcasecmp(gov->name_orig, name) == 0) {
+      return gov;
+    }
+  } government_iterate_end;
+
+  return NULL;
+}
+
+/***************************************************************
+...
+***************************************************************/
 struct government *get_government(int gov)
 {
   assert(game.government_count > 0 && gov >= 0
Index: common/government.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.h,v
retrieving revision 1.28
diff -u -r1.28 government.h
--- common/government.h 14 Jun 2004 23:43:08 -0000      1.28
+++ common/government.h 18 Aug 2004 07:15:21 -0000
@@ -177,6 +177,7 @@
 struct government *get_gov_pcity(const struct city *pcity);
 
 struct government *find_government_by_name(const char *name);
+struct government *find_government_by_name_orig(const char *name);
 
 enum government_flag_id government_flag_from_str(const char *s);
 bool government_has_flag(const struct government *gov,
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.175
diff -u -r1.175 savegame.c
--- server/savegame.c   8 Aug 2004 15:09:12 -0000       1.175
+++ server/savegame.c   18 Aug 2004 07:16:05 -0000
@@ -24,6 +24,7 @@
 #include "city.h"
 #include "fcintl.h"
 #include "game.h"
+#include "government.h"
 #include "idex.h"
 #include "log.h"
 #include "map.h"
@@ -687,6 +688,19 @@
   "Writing"
 };
 
+/* old (~1.14.1) government order in default, civ1, history ruleset */
+const char* old_default_governments[] = 
+{
+  "Anarchy", "Despotism", "Monarchy", "Communism", "Republic", "Democracy"
+};
+
+/* old (~1.14.1) government order in civ2 rulesetes */
+const char* old_civ2_governments[] =
+{
+  "Anarchy", "Despotism", "Monarchy", "Communism", "Fundamentalism",
+  "Republic", "Democracy"
+};
+
 /****************************************************************************
   Nowadays unit types are saved by name, but old servers need the
   unit_type_id.  This function tries to find the correct _old_ id for the
@@ -990,6 +1004,62 @@
   secfile_insert_int(file, old_tech_id(tech), path, plrno);
 }
 
+/****************************************************************************
+  Nowadays governments are saved by name, but old servers need the
+  index .  This function tries to find the correct _old_ id for the
+  government. It is used when the government is saved.
+****************************************************************************/
+static int old_government_id(struct government* gov)
+{
+  const char** names;
+  int num_names, i;
+
+  if (strcmp(game.rulesetdir, "civ2") == 0) {
+    names = old_civ2_governments;
+    num_names = ARRAY_SIZE(old_civ2_governments);
+  } else {
+    names = old_default_governments;
+    num_names = ARRAY_SIZE(old_default_governments);
+  }
+
+  for (i = 0; i < num_names; i++) {
+    if (mystrcasecmp(gov->name_orig, names[i]) == 0) {
+      return i;
+    }
+  }
+
+  /* It's a new government. Savegame cannot be forward compatible so we can
+   * return anything */
+  return gov->index;
+}
+
+/****************************************************************************
+  Convert an old-style government index into a government name.
+****************************************************************************/
+static const char* old_government_name(int id)
+{
+  /* before 1.15.0 governments used to be saved by index */
+  if (id < 0) {
+    freelog(LOG_ERROR, _("Wrong government type id value (%d)"), id);
+    exit(EXIT_FAILURE);
+  }
+  /* Different rulesets had different governments. */
+  if (strcmp(game.rulesetdir, "civ2") == 0) {
+    if (id >= ARRAY_SIZE(old_civ2_governments)) {
+      freelog(LOG_ERROR, _("Wrong government type id value (%d)"), id);
+      exit(EXIT_FAILURE);
+    }
+    return old_civ2_governments[id];
+  } else {
+    if (id >= ARRAY_SIZE(old_default_governments)) {
+      freelog(LOG_ERROR, _("Wrong government type id value (%d)"), id);
+      exit(EXIT_FAILURE);
+    }
+    return old_default_governments[id];
+  }
+}
+
+
 /***************************************************************
 Load the worklist elements specified by path, given the arguments
 plrno and wlinx, into the worklist pointed to by pwl.
@@ -1330,7 +1400,8 @@
   const char *name;
   char *savefile_options = secfile_lookup_str(file, "savefile.options");
   struct ai_data *ai;
-  Tech_Type_id id;
+  struct government* gov;
+  int id;
 
   server_player_init(plr, TRUE);
   ai_data_init(plr);
@@ -1397,7 +1468,22 @@
   if (is_barbarian(plr)) {
     plr->nation=game.nation_count-1;
   }
-  plr->government=secfile_lookup_int(file, "player%d.government", plrno);
+
+  /* government */
+  name = secfile_lookup_str_default(file, NULL, "player%d.government_name",
+                                    plrno);
+  if (!name) {
+    /* old servers used to save government by id */
+    id = secfile_lookup_int(file, "player%d.government", plrno);
+    name = old_government_name(id);
+  }
+  gov = find_government_by_name_orig(name);
+  if (gov == NULL) {
+    freelog(LOG_ERROR, _("Unsupported government found (%s)"), name);
+    exit(EXIT_FAILURE);
+  }
+  plr->government = gov->index;
+  
   plr->embassy=secfile_lookup_int(file, "player%d.embassy", plrno);
 
   p = secfile_lookup_str_default(file, NULL, "player%d.city_style_by_name",
@@ -2083,6 +2169,7 @@
   char invs[A_LAST+1];
   struct player_spaceship *ship = &plr->spaceship;
   struct ai_data *ai = ai_data_get(plr);
+  struct government* gov;
 
   secfile_insert_str(file, plr->name, "player%d.name", plrno);
   secfile_insert_str(file, plr->username, "player%d.username", plrno);
@@ -2094,7 +2181,14 @@
     secfile_insert_str(file, (char *) team_get_by_id(plr->team)->name, 
                        "player%d.team", plrno);
   }
-  secfile_insert_int(file, plr->government, "player%d.government", plrno);
+
+  gov = get_government(plr->government);
+  secfile_insert_str(file, gov->name_orig, "player%d.government_name", plrno);
+  /* 1.15 and later won't use "government" field, kept for forward 
+   * compatibility */
+  secfile_insert_int(file, old_government_id(gov),
+                     "player%d.government", plrno);
+  
   secfile_insert_int(file, plr->embassy, "player%d.embassy", plrno);
 
   /* This field won't be used; it's kept only for forward compatibility. 

[Prev in Thread] Current Thread [Next in Thread]