[Freeciv-Dev] (PR#9123) Save unit types by names. Part2
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: |
undisclosed-recipients: ; |
Subject: |
[Freeciv-Dev] (PR#9123) Save unit types by names. Part2 |
From: |
"Mateusz Stefek" <mstefek@xxxxxxxxx> |
Date: |
Sat, 3 Jul 2004 12:16:10 -0700 |
Reply-to: |
rt@xxxxxxxxxxx |
<URL: http://rt.freeciv.org/Ticket/Display.html?id=9123 >
On 2004-07-01 07:59:15, Jason Short wrote:
> Thanks. How about this?
>
> 1. Pikeman => Pikemen
> 2. Removed comma from civ1 array.
> 3. Use mystrcasecmp instead of strcmp in
> find_unit_type_by_name_orig.
>
> The third one is actually a change but I think ignoring case is safer
> here. At least looking at all the capitalization in these arrays
> made
> me think so...
>
> Unless there are more problems I will commit it soon.
>
> jason
>
>
With attached patch worklists and city productions are no more
dependent on the order in which improvements or units are read from
ruleset.
I changed old_type_id(struct unit* punit) into old_unit_type_id
(Unit_Type_id) and moved the code before worklist_load.
You have to use Jason's patch first
TODO:
-city improvements
-research
-technology
-destroyed_wonders
--
mateusz
diff -ur -Xdiff_ignore freeorig/common/improvement.c
freeciv/common/improvement.c
--- freeorig/common/improvement.c 2004-06-22 08:28:12.000000000 +0200
+++ freeciv/common/improvement.c 2004-06-30 13:36:52.000000000 +0200
@@ -154,6 +154,14 @@
return get_improvement_type(id)->name;
}
+/**************************************************************************
+...
+**************************************************************************/
+const char *get_improvement_name_orig(Impr_Type_id id)
+{
+ return get_improvement_type(id)->name_orig;
+}
+
/****************************************************************************
Returns the number of shields it takes to build this improvement.
****************************************************************************/
@@ -211,6 +219,20 @@
}
/**************************************************************************
+Does a linear search of improvement_types[].name_orig
+Returns B_LAST if none match.
+**************************************************************************/
+Impr_Type_id find_improvement_by_name_orig(const char *s)
+{
+ impr_type_iterate(i) {
+ if (strcmp(improvement_types[i].name_orig, s)==0)
+ return i;
+ } impr_type_iterate_end;
+
+ return B_LAST;
+}
+
+/**************************************************************************
FIXME: remove when gen-impr obsoletes
**************************************************************************/
int improvement_variant(Impr_Type_id id)
diff -ur -Xdiff_ignore freeorig/common/improvement.h
freeciv/common/improvement.h
--- freeorig/common/improvement.h 2004-06-22 08:28:12.000000000 +0200
+++ freeciv/common/improvement.h 2004-06-30 13:36:11.000000000 +0200
@@ -139,6 +139,7 @@
bool is_wonder(Impr_Type_id id);
const char *get_improvement_name(Impr_Type_id id);
+const char *get_improvement_name_orig(Impr_Type_id id);
/* FIXME: remove improvement_variant() when gen-impr obsoletes */
int improvement_variant(Impr_Type_id id);
@@ -149,6 +150,7 @@
bool wonder_obsolete(Impr_Type_id id);
bool is_wonder_useful(Impr_Type_id id);
Impr_Type_id find_improvement_by_name(const char *s);
+Impr_Type_id find_improvement_by_name_orig(const char *s);
void improvement_status_init(Impr_Status * improvements, size_t elements);
/* player related improvement and unit functions */
diff -ur -Xdiff_ignore freeorig/server/savegame.c freeciv/server/savegame.c
--- freeorig/server/savegame.c 2004-07-01 10:41:54.000000000 +0200
+++ freeciv/server/savegame.c 2004-07-01 11:38:39.000000000 +0200
@@ -566,84 +566,6 @@
} whole_map_iterate_end;
}
-/***************************************************************
-Load the worklist elements specified by path, given the arguments
-plrno and wlinx, into the worklist pointed to by pwl.
-***************************************************************/
-static void worklist_load(struct section_file *file,
- const char *path, int plrno, int wlinx,
- struct worklist *pwl)
-{
- char efpath[64];
- char idpath[64];
- int i;
- bool end = FALSE;
-
- sz_strlcpy(efpath, path);
- sz_strlcat(efpath, ".wlef%d");
- sz_strlcpy(idpath, path);
- sz_strlcat(idpath, ".wlid%d");
-
- for (i = 0; i < MAX_LEN_WORKLIST; i++) {
- if (end) {
- pwl->wlefs[i] = WEF_END;
- pwl->wlids[i] = 0;
- (void) section_file_lookup(file, efpath, plrno, wlinx, i);
- (void) section_file_lookup(file, idpath, plrno, wlinx, i);
- } else {
- pwl->wlefs[i] =
- secfile_lookup_int_default(file, WEF_END, efpath, plrno, wlinx, i);
- pwl->wlids[i] =
- secfile_lookup_int_default(file, 0, idpath, plrno, wlinx, i);
-
- if ((pwl->wlefs[i] <= WEF_END) || (pwl->wlefs[i] >= WEF_LAST) ||
- ((pwl->wlefs[i] == WEF_UNIT) && !unit_type_exists(pwl->wlids[i])) ||
- ((pwl->wlefs[i] == WEF_IMPR) && !improvement_exists(pwl->wlids[i]))) {
- pwl->wlefs[i] = WEF_END;
- pwl->wlids[i] = 0;
- end = TRUE;
- }
- }
- }
-}
-
-/***************************************************************
-Load the worklist elements specified by path, given the arguments
-plrno and wlinx, into the worklist pointed to by pwl.
-Assumes original save-file format. Use for backward compatibility.
-***************************************************************/
-static void worklist_load_old(struct section_file *file,
- const char *path, int plrno, int wlinx,
- struct worklist *pwl)
-{
- int i, id;
- bool end = FALSE;
-
- for (i = 0; i < MAX_LEN_WORKLIST; i++) {
- if (end) {
- pwl->wlefs[i] = WEF_END;
- pwl->wlids[i] = 0;
- (void) section_file_lookup(file, path, plrno, wlinx, i);
- } else {
- id = secfile_lookup_int_default(file, -1, path, plrno, wlinx, i);
-
- if ((id < 0) || (id >= 284)) { /* 284 was flag value for end of list */
- pwl->wlefs[i] = WEF_END;
- pwl->wlids[i] = 0;
- end = TRUE;
- } else if (id >= 68) { /* 68 was offset to unit ids */
- pwl->wlefs[i] = WEF_UNIT;
- pwl->wlids[i] = id - 68;
- end = !unit_type_exists(pwl->wlids[i]);
- } else { /* must be an improvement id */
- pwl->wlefs[i] = WEF_IMPR;
- pwl->wlids[i] = id;
- end = !improvement_exists(pwl->wlids[i]);
- }
- }
- }
-}
-
/*
* Previously (with 1.14.1 and earlier) units had their type saved by ID.
* This meant any time a unit was added (unless it was added at the end)
@@ -694,12 +616,40 @@
"Caravan", "Freight", "Explorer", "Barbarian Leader"
};
+/* old (1.14.1) improvement order in default ruleset */
+const char* old_impr_types[] =
+{
+ "Airport", "Aqueduct", "Bank",
+ "Barracks", "Barracks II", "Barracks III",
+ "Cathedral", "City Walls", "Coastal Defense",
+ "Colosseum", "Courthouse", "Factory",
+ "Granary", "Harbour", "Hydro Plant",
+ "Library", "Marketplace", "Mass Transit",
+ "Mfg. Plant", "Nuclear Plant", "Offshore Platform",
+ "Palace", "Police Station", "Port Facility",
+ "Power Plant", "Recycling Center", "Research Lab",
+ "SAM Battery", "SDI Defense", "Sewer System",
+ "Solar Plant", "Space Component", "Space Module",
+ "Space Structural", "Stock Exchange", "Super Highways",
+ "Supermarket", "Temple", "University",
+ "Apollo Program", "A.Smith's Trading Co.","Colossus",
+ "Copernicus' Observatory", "Cure For Cancer", "Darwin's Voyage",
+ "Eiffel Tower", "Great Library", "Great Wall",
+ "Hanging Gardens", "Hoover Dam", "Isaac Newton's College",
+ "J.S. Bach's Cathedral","King Richard's Crusade", "Leonardo's Workshop",
+ "Lighthouse", "Magellan's Expedition","Manhattan Project",
+ "Marco Polo's Embassy","Michelangelo's Chapel","Oracle",
+ "Pyramids", "SETI Program", "Shakespeare's Theatre",
+ "Statue of Liberty", "Sun Tzu's War Academy","United Nations",
+ "Women's Suffrage", "Coinage"
+};
+
/****************************************************************************
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
unit's type. It is used when the unit is saved.
****************************************************************************/
-static int old_type_id(struct unit* punit)
+static int old_unit_type_id(Unit_Type_id type)
{
const char** types;
int num_types, i;
@@ -713,14 +663,190 @@
}
for (i = 0; i < num_types; i++) {
- if (strcmp(unit_name_orig(punit->type), types[i]) == 0) {
+ if (strcmp(unit_name_orig(type), types[i]) == 0) {
return i;
}
}
/* It's a new unit. Savegame cannot be backward compatible so we can
* return anything */
- return punit->type;
+ return type;
+}
+
+/***************************************************************
+ Convert old-style unit type id into unit type name
+***************************************************************/
+static const char* old_unit_type_name(int id)
+{
+ /* before 1.15.0 unit types used to be saved by id */
+ if (id < 0) {
+ freelog(LOG_ERROR, _("Wrong unit type id value (%d)"), id);
+ exit(EXIT_FAILURE);
+ }
+ /* Different rulesets had different unit names. */
+ if (strcmp(game.rulesetdir, "civ1") == 0) {
+ if (id >= ARRAY_SIZE(old_civ1_unit_types)) {
+ freelog(LOG_ERROR, _("Wrong unit type id value (%d)"), id);
+ exit(EXIT_FAILURE);
+ }
+ return old_civ1_unit_types[id];
+ } else {
+ if (id >= ARRAY_SIZE(old_default_unit_types)) {
+ freelog(LOG_ERROR, _("Wrong unit type id value (%d)"), id);
+ exit(EXIT_FAILURE);
+ }
+ return old_default_unit_types[id];
+ }
+}
+
+/****************************************************************************
+ Nowadays improvement types are saved by name, but old servers need the
+ Impr_type_id. This function tries to find the correct _old_ id for the
+ improvements's type. It is used when the improvement is saved.
+****************************************************************************/
+static int old_impr_type_id(Impr_Type_id type)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(old_impr_types); i++) {
+ if (strcmp(unit_name_orig(type), old_impr_types[i]) == 0) {
+ return i;
+ }
+ }
+
+ /* It's a new improvement. Savegame cannot be backward compatible so we can
+ * return anything */
+ return type;
+}
+
+/***************************************************************
+ Convert old-style improvement type id into improvement type name
+***************************************************************/
+static const char* old_impr_type_name(int id)
+{
+ /* before 1.15.0 improvement types used to be saved by id */
+ if (id < 0 || id >= ARRAY_SIZE(old_impr_types)) {
+ freelog(LOG_ERROR, _("Wrong improvement type id value (%d)"), id);
+ exit(EXIT_FAILURE);
+ }
+ return old_impr_types[id];
+}
+
+/***************************************************************
+Load the worklist elements specified by path, given the arguments
+plrno and wlinx, into the worklist pointed to by pwl.
+***************************************************************/
+static void worklist_load(struct section_file *file,
+ const char *path, int plrno, int wlinx,
+ struct worklist *pwl)
+{
+ char efpath[64];
+ char idpath[64];
+ char namepath[64];
+ int i;
+ bool end = FALSE;
+ const char* name;
+
+ sz_strlcpy(efpath, path);
+ sz_strlcat(efpath, ".wlef%d");
+ sz_strlcpy(idpath, path);
+ sz_strlcat(idpath, ".wlid%d");
+ sz_strlcpy(namepath, path);
+ sz_strlcat(namepath, ".wlname%d");
+
+ for (i = 0; i < MAX_LEN_WORKLIST; i++) {
+ if (end) {
+ pwl->wlefs[i] = WEF_END;
+ pwl->wlids[i] = 0;
+ (void) section_file_lookup(file, efpath, plrno, wlinx, i);
+ (void) section_file_lookup(file, idpath, plrno, wlinx, i);
+ } else {
+ pwl->wlefs[i] =
+ secfile_lookup_int_default(file, WEF_END, efpath, plrno, wlinx, i);
+ name = secfile_lookup_str_default(file, NULL, namepath, plrno, wlinx, i);
+
+ if (pwl->wlefs[i] == WEF_UNIT) {
+ Unit_Type_id type;
+
+ if (!name) {
+ /* before 1.15.0 unit types used to be saved by id */
+ name = old_unit_type_name(secfile_lookup_int(file, idpath,
+ plrno, wlinx, i));
+ }
+
+ type = find_unit_type_by_name_orig(name);
+ if (type == U_LAST) {
+ freelog(LOG_ERROR, _("Unknown unit type '%s' in worklist"),
+ name);
+ exit(EXIT_FAILURE);
+ }
+ pwl->wlids[i] = type;
+ } else if (pwl->wlefs[i] == WEF_IMPR) {
+ Impr_Type_id type;
+
+ if (!name) {
+ name = old_impr_type_name(secfile_lookup_int(file, idpath,
+ plrno, wlinx, i));
+ }
+
+ type = find_improvement_by_name_orig(name);
+ if (type == B_LAST) {
+ freelog(LOG_ERROR, _("Unknown improvement type '%s' in worklist"),
+ name);
+ }
+ pwl->wlids[i] = type;
+ }
+
+ if ((pwl->wlefs[i] <= WEF_END) || (pwl->wlefs[i] >= WEF_LAST) ||
+ ((pwl->wlefs[i] == WEF_UNIT) && !unit_type_exists(pwl->wlids[i])) ||
+ ((pwl->wlefs[i] == WEF_IMPR) && !improvement_exists(pwl->wlids[i]))) {
+ pwl->wlefs[i] = WEF_END;
+ pwl->wlids[i] = 0;
+ end = TRUE;
+ }
+ }
+ }
+}
+
+/***************************************************************
+Load the worklist elements specified by path, given the arguments
+plrno and wlinx, into the worklist pointed to by pwl.
+Assumes original save-file format. Use for backward compatibility.
+***************************************************************/
+static void worklist_load_old(struct section_file *file,
+ const char *path, int plrno, int wlinx,
+ struct worklist *pwl)
+{
+ int i, id;
+ bool end = FALSE;
+ const char* name;
+
+ for (i = 0; i < MAX_LEN_WORKLIST; i++) {
+ if (end) {
+ pwl->wlefs[i] = WEF_END;
+ pwl->wlids[i] = 0;
+ (void) section_file_lookup(file, path, plrno, wlinx, i);
+ } else {
+ id = secfile_lookup_int_default(file, -1, path, plrno, wlinx, i);
+
+ if ((id < 0) || (id >= 284)) { /* 284 was flag value for end of list */
+ pwl->wlefs[i] = WEF_END;
+ pwl->wlids[i] = 0;
+ end = TRUE;
+ } 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);
+ end = !unit_type_exists(pwl->wlids[i]);
+ } else { /* must be an improvement id */
+ name = old_impr_type_name(id);
+ pwl->wlefs[i] = WEF_IMPR;
+ pwl->wlids[i] = find_improvement_by_name_orig(name);
+ end = !improvement_exists(pwl->wlids[i]);
+ }
+ }
+ }
+
}
/****************************************************************************
@@ -758,23 +884,8 @@
plrno, i, t);
exit(EXIT_FAILURE);
}
+ type_name = old_unit_type_name(t);
- /* Different rulesets had different unit names. */
- if (strcmp(game.rulesetdir, "civ1") == 0) {
- if (t >= ARRAY_SIZE(old_civ1_unit_types)) {
- freelog(LOG_ERROR, _("Wrong player%d.u%d.type value (%d)"),
- plrno, i, t);
- exit(EXIT_FAILURE);
- }
- type_name = old_civ1_unit_types[t];
- } else {
- if (t >= ARRAY_SIZE(old_default_unit_types)) {
- freelog(LOG_ERROR, _("Wrong player%d.u%d.type value (%d)"),
- plrno, i, t);
- exit(EXIT_FAILURE);
- }
- type_name = old_default_unit_types[t];
- }
}
type = find_unit_type_by_name_orig(type_name);
@@ -1228,6 +1339,8 @@
int nat_x = secfile_lookup_int(file, "player%d.c%d.x", plrno, i);
int nat_y = secfile_lookup_int(file, "player%d.c%d.y", plrno, i);
int map_x, map_y;
+ const char* name;
+ int id;
native_to_map_pos(&map_x, &map_y, nat_x, nat_y);
pcity = create_city_virtual(plr, map_x, map_y,
@@ -1267,9 +1380,25 @@
pcity->is_building_unit=
secfile_lookup_bool(file,
"player%d.c%d.is_building_unit", plrno, i);
- pcity->currently_building=
- secfile_lookup_int(file,
- "player%d.c%d.currently_building", plrno, i);
+ name = secfile_lookup_str_default(file, NULL,
+ "player%d.c%d.currently_building_name",
+ plrno, i);
+ if (pcity->is_building_unit) {
+ if (!name) {
+ id = secfile_lookup_int(file, "player%d.c%d.currently_building",
+ plrno, i);
+ name = old_unit_type_name(id);
+ }
+ pcity->currently_building = find_unit_type_by_name_orig(name);
+ } else {
+ if (!name) {
+ id = secfile_lookup_int(file, "player%d.c%d.currently_building",
+ plrno, i);
+ name = old_impr_type_name(id);
+ }
+ pcity->currently_building = find_improvement_by_name_orig(name);
+ }
+
pcity->turn_last_built=
secfile_lookup_int_default(file, GAME_START_YEAR,
"player%d.c%d.turn_last_built", plrno, i);
@@ -1589,16 +1718,31 @@
{
char efpath[64];
char idpath[64];
+ char namepath[64];
int i;
sz_strlcpy(efpath, path);
sz_strlcat(efpath, ".wlef%d");
sz_strlcpy(idpath, path);
sz_strlcat(idpath, ".wlid%d");
+ sz_strlcpy(namepath, path);
+ sz_strlcat(namepath, ".wlname%d");
for (i = 0; i < MAX_LEN_WORKLIST; i++) {
secfile_insert_int(file, pwl->wlefs[i], efpath, plrno, wlinx, i);
- secfile_insert_int(file, pwl->wlids[i], idpath, plrno, wlinx, i);
+ if (pwl->wlefs[i] == WEF_UNIT) {
+ secfile_insert_int(file, old_unit_type_id(pwl->wlids[i]), idpath,
+ plrno, wlinx, i);
+ secfile_insert_str(file, unit_name_orig(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);
+ secfile_insert_str(file, get_improvement_name_orig(pwl->wlids[i]),
+ namepath, plrno, wlinx, i);
+ } else {
+ secfile_insert_int(file, 0, idpath, plrno, wlinx, i);
+ secfile_insert_str(file, "", namepath, plrno, wlinx, i);
+ }
if (pwl->wlefs[i] == WEF_END) {
break;
}
@@ -1609,7 +1753,9 @@
/* These values match what worklist_load fills in for unused entries. */
secfile_insert_int(file, WEF_END, efpath, plrno, wlinx, i);
secfile_insert_int(file, 0, idpath, plrno, wlinx, i);
+ secfile_insert_str(file, "", namepath, plrno, wlinx, i);
}
+
}
/***************************************************************
@@ -1766,7 +1912,7 @@
secfile_insert_int(file, punit->homecity, "player%d.u%d.homecity",
plrno, i);
/* .type is actually kept only for backward compatibility */
- secfile_insert_int(file, old_type_id(punit), "player%d.u%d.type",
+ secfile_insert_int(file, old_unit_type_id(punit->type),
"player%d.u%d.type",
plrno, i);
secfile_insert_str(file, unit_name_orig(punit->type),
"player%d.u%d.type_by_name",
@@ -1928,8 +2074,18 @@
secfile_insert_bool(file, pcity->is_building_unit,
"player%d.c%d.is_building_unit", plrno, i);
- secfile_insert_int(file, pcity->currently_building,
- "player%d.c%d.currently_building", plrno, i);
+ if (pcity->is_building_unit) {
+ secfile_insert_int(file, old_unit_type_id(pcity->currently_building),
+ "player%d.c%d.currently_building", plrno, i);
+ secfile_insert_str(file, unit_name_orig(pcity->currently_building),
+ "player%d.c%d.currently_building_name", plrno, i);
+ } else {
+ secfile_insert_int(file, old_impr_type_id(pcity->currently_building),
+ "player%d.c%d.currently_building", plrno, i);
+ secfile_insert_str(file, get_improvement_name_orig(
+ pcity->currently_building),
+ "player%d.c%d.currently_building_name", plrno, i);
+ }
impr_type_iterate(id) {
buf[id] = (pcity->improvements[id] != I_NONE) ? '1' : '0';
|
|