[Freeciv-Dev] (PR#12954) [PATCH] remove palace and city walls kludge
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] (PR#12954) [PATCH] remove palace and city walls kludge |
From: |
"Vasco Alexandre da Silva Costa" <vasc@xxxxxxxxxxxxxx> |
Date: |
Wed, 4 May 2005 13:45:48 -0700 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12954 >
> [vasc - Wed May 04 20:39:11 2005]:
>
> This patch fixes forward savedgame compatibility and renames a flag name.
> Bug reported by Mike Kaufman, fixes suggested by Jason Dorje.
Oops, included some generated files in the diff. This one is cleaner.
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.501
diff -u -u -r1.501 packhand.c
--- client/packhand.c 2 May 2005 15:42:52 -0000 1.501
+++ client/packhand.c 4 May 2005 20:17:19 -0000
@@ -312,24 +312,18 @@
/**************************************************************************
Updates a city's list of improvements from packet data. "impr" identifies
the improvement, and "have_impr" specifies whether the improvement should
- be added (TRUE) or removed (FALSE). "impr_changed" is set TRUE only if
- the existing improvement status was changed by this call.
+ be added (TRUE) or removed (FALSE).
**************************************************************************/
static void update_improvement_from_packet(struct city *pcity,
- Impr_type_id impr, bool have_impr,
- bool *impr_changed)
+ Impr_type_id impr, bool have_impr)
{
- if (have_impr && pcity->improvements[impr] == I_NONE) {
- city_add_improvement(pcity, impr);
-
- if (impr_changed) {
- *impr_changed = TRUE;
+ if (have_impr) {
+ if (pcity->improvements[impr] == I_NONE) {
+ city_add_improvement(pcity, impr);
}
- } else if (!have_impr && pcity->improvements[impr] != I_NONE) {
- city_remove_improvement(pcity, impr);
-
- if (impr_changed) {
- *impr_changed = TRUE;
+ } else {
+ if (pcity->improvements[impr] != I_NONE) {
+ city_remove_improvement(pcity, impr);
}
}
}
@@ -382,7 +376,7 @@
void handle_city_info(struct packet_city_info *packet)
{
int i;
- bool city_is_new, city_has_changed_owner = FALSE, need_effect_update = FALSE;
+ bool city_is_new, city_has_changed_owner = FALSE;
bool need_units_dialog_update = FALSE;
struct city *pcity;
bool popup, update_descriptions = FALSE, name_changed = FALSE;
@@ -507,13 +501,14 @@
}
impr_type_iterate(i) {
- if (pcity->improvements[i] == I_NONE && packet->improvements[i] == '1'
+ if (pcity->improvements[i] == I_NONE
+ && BV_ISSET(packet->improvements, i)
&& !city_is_new) {
audio_play_sound(get_improvement_type(i)->soundtag,
get_improvement_type(i)->soundtag_alt);
}
- update_improvement_from_packet(pcity, i, packet->improvements[i] == '1',
- &need_effect_update);
+ update_improvement_from_packet(pcity, i,
+ BV_ISSET(packet->improvements, i));
} impr_type_iterate_end;
/* We should be able to see units in the city. But for a diplomat
@@ -632,7 +627,7 @@
void handle_city_short_info(struct packet_city_short_info *packet)
{
struct city *pcity;
- bool city_is_new, city_has_changed_owner = FALSE, need_effect_update = FALSE;
+ bool city_is_new, city_has_changed_owner = FALSE;
bool update_descriptions = FALSE;
pcity=find_city_by_id(packet->id);
@@ -696,10 +691,10 @@
}
}
- update_improvement_from_packet(pcity, game.palace_building,
- packet->capital, &need_effect_update);
- update_improvement_from_packet(pcity, game.land_defend_building,
- packet->walls, &need_effect_update);
+ impr_type_iterate(i) {
+ update_improvement_from_packet(pcity, i,
+ BV_ISSET(packet->improvements, i));
+ } impr_type_iterate_end;
/* This sets dumb values for everything else. This is not really required,
but just want to be at the safe side. */
@@ -1362,20 +1357,6 @@
game.coolinglevel = pinfo->coolinglevel;
if (!can_client_change_view()) {
- /*
- * Hack to allow code that explicitly checks for Palace or City Walls
- * to work.
- */
- game.palace_building = get_building_for_effect(EFT_CAPITAL_CITY);
- if (game.palace_building == B_LAST) {
- freelog(LOG_FATAL, "Cannot find any palace building");
- }
-
- game.land_defend_building = get_building_for_effect(EFT_LAND_DEFEND);
- if (game.land_defend_building == B_LAST) {
- freelog(LOG_FATAL, "Cannot find any land defend building");
- }
-
game.player_idx = pinfo->player_idx;
game.player_ptr = &game.players[game.player_idx];
}
@@ -2254,6 +2235,7 @@
b->build_cost = p->build_cost;
b->upkeep = p->upkeep;
b->sabotage = p->sabotage;
+ b->flags = p->flags;
b->helptext = mystrdup(p->helptext);
sz_strlcpy(b->soundtag, p->soundtag);
sz_strlcpy(b->soundtag_alt, p->soundtag_alt);
@@ -2646,14 +2628,14 @@
...
**************************************************************************/
void handle_city_sabotage_list(int diplomat_id, int city_id,
- char *improvements)
+ bv_imprs improvements)
{
struct unit *punit = player_find_unit_by_id(game.player_ptr, diplomat_id);
struct city *pcity = find_city_by_id(city_id);
if (punit && pcity) {
impr_type_iterate(i) {
- pcity->improvements[i] = (improvements[i]=='1') ? I_ACTIVE : I_NONE;
+ pcity->improvements[i] = BV_ISSET(improvements, i) ? I_ACTIVE : I_NONE;
} impr_type_iterate_end;
popup_sabotage_dialog(pcity);
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.209
diff -u -u -r1.209 game.c
--- common/game.c 2 May 2005 08:56:26 -0000 1.209
+++ common/game.c 4 May 2005 20:17:19 -0000
@@ -266,9 +266,6 @@
game.default_government = G_MAGIC; /* flag */
game.government_when_anarchy = G_MAGIC; /* flag */
- game.palace_building = B_LAST;
- game.land_defend_building = B_LAST;
-
sz_strlcpy(game.demography, GAME_DEFAULT_DEMOGRAPHY);
sz_strlcpy(game.allow_take, GAME_DEFAULT_ALLOW_TAKE);
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.185
diff -u -u -r1.185 game.h
--- common/game.h 4 May 2005 06:18:07 -0000 1.185
+++ common/game.h 4 May 2005 20:17:20 -0000
@@ -175,9 +175,6 @@
char rulesetdir[MAX_LEN_NAME];
int firepower_factor; /* See README.rulesets */
- Impr_type_id palace_building;
- Impr_type_id land_defend_building;
-
/* values from game.ruleset */
struct {
int num_specialist_types;
Index: common/improvement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/improvement.c,v
retrieving revision 1.57
diff -u -u -r1.57 improvement.c
--- common/improvement.c 30 Apr 2005 17:09:27 -0000 1.57
+++ common/improvement.c 4 May 2005 20:17:20 -0000
@@ -27,21 +27,16 @@
#include "improvement.h"
-/* Names of impr ranges.
- * (These must correspond to enum impr_range_id in improvement.h.)
- * do not change these unless you know what you're doing! */
-static const char *impr_range_names[] = {
- "None",
- "City",
- "Island",
- "Player",
- "World"
-};
-
static const char *genus_names[IG_LAST] = {
"GreatWonder", "SmallWonder", "Improvement", "Special"
};
+static const char *flag_names[] = {
+ "VisibleByOthers", "SaveSmallWonder"
+};
+/* Note that these strings must correspond with the enums in impr_flag_id,
+ in common/improvement.h */
+
/**************************************************************************
All the city improvements:
Use get_improvement_type(id) to access the array.
@@ -52,39 +47,6 @@
struct impr_type improvement_types[B_LAST];
/**************************************************************************
- Convert impr range names to enum; case insensitive;
- returns IR_LAST if can't match.
-**************************************************************************/
-enum impr_range impr_range_from_str(const char *str)
-{
- enum impr_range ret_id;
-
- assert(ARRAY_SIZE(impr_range_names) == IR_LAST);
-
- for (ret_id = 0; ret_id < IR_LAST; ret_id++) {
- if (0 == mystrcasecmp(impr_range_names[ret_id], str)) {
- return ret_id;
- }
- }
-
- return IR_LAST;
-}
-
-/**************************************************************************
- Return impr range name; NULL if bad id.
-**************************************************************************/
-const char *impr_range_name(enum impr_range id)
-{
- assert(ARRAY_SIZE(impr_range_names) == IR_LAST);
-
- if (id < IR_LAST) {
- return impr_range_names[id];
- } else {
- return NULL;
- }
-}
-
-/**************************************************************************
Convert impr genus names to enum; case insensitive;
returns IG_LAST if can't match.
**************************************************************************/
@@ -266,6 +228,41 @@
}
/**************************************************************************
+ Return TRUE if the impr has this flag otherwise FALSE
+**************************************************************************/
+bool impr_flag(Impr_type_id id, enum impr_flag_id flag)
+{
+ assert(flag >= 0 && flag < IF_LAST);
+ return TEST_BIT(improvement_types[id].flags, flag);
+}
+
+/**************************************************************************
+ Convert flag names to enum; case insensitive;
+ returns IF_LAST if can't match.
+**************************************************************************/
+enum impr_flag_id impr_flag_from_str(const char *s)
+{
+ enum impr_flag_id i;
+
+ assert(ARRAY_SIZE(flag_names) == IF_LAST);
+
+ for(i = 0; i < IF_LAST; i++) {
+ if (mystrcasecmp(flag_names[i], s) == 0) {
+ return i;
+ }
+ }
+ return IF_LAST;
+}
+
+/**************************************************************************
+ Return TRUE if the improvement should be visible to others without spying
+**************************************************************************/
+bool is_improvement_visible(Impr_type_id id)
+{
+ return (is_wonder(id) || impr_flag(id, IF_VISIBLE_BY_OTHERS));
+}
+
+/**************************************************************************
Returns 1 if the improvement is obsolete, now also works for wonders
**************************************************************************/
bool improvement_obsolete(const struct player *pplayer, Impr_type_id id)
Index: common/improvement.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/improvement.h,v
retrieving revision 1.45
diff -u -u -r1.45 improvement.h
--- common/improvement.h 30 Apr 2005 17:09:27 -0000 1.45
+++ common/improvement.h 4 May 2005 20:17:21 -0000
@@ -43,15 +43,11 @@
* to hold full number of improvement types. */
#define B_LAST MAX_NUM_ITEMS
-/* Range of equivalence (used in equiv_range fields)
- * These must correspond to impr_range_names[] in improvement.c. */
-enum impr_range {
- IR_NONE,
- IR_CITY,
- IR_ISLAND,
- IR_PLAYER,
- IR_WORLD,
- IR_LAST /* keep this last */
+/* Changing these breaks network compatibility. */
+enum impr_flag_id {
+ IF_VISIBLE_BY_OTHERS, /* improvement should be visible to others without
spying */
+ IF_SAVE_SMALL_WONDER, /* this small wonder is moved to another city if
game.savepalace is on. */
+ IF_LAST
};
enum impr_genus_id {
@@ -62,6 +58,7 @@
IG_LAST
};
+BV_DEFINE(bv_imprs, B_LAST);
/* Type of improvement. (Read from buildings.ruleset file.) */
struct impr_type {
@@ -77,6 +74,7 @@
int build_cost; /* Use wrappers to access this. */
int upkeep;
int sabotage; /* Base chance of diplomat sabotage succeeding.
*/
+ unsigned int flags;
char *helptext;
char soundtag[MAX_LEN_NAME];
char soundtag_alt[MAX_LEN_NAME];
@@ -85,10 +83,6 @@
extern struct impr_type improvement_types[B_LAST];
-/* impr range id/string converters */
-enum impr_range impr_range_from_str(const char *str);
-const char *impr_range_name(enum impr_range id);
-
/* impr genus id/string converters */
enum impr_genus_id impr_genus_from_str(const char *s);
@@ -106,6 +100,11 @@
const char *get_improvement_name(Impr_type_id id);
const char *get_improvement_name_orig(Impr_type_id id);
+bool impr_flag(Impr_type_id id, enum impr_flag_id flag);
+enum impr_flag_id impr_flag_from_str(const char *s);
+
+bool is_improvement_visible(Impr_type_id id);
+
bool improvement_obsolete(const struct player *pplayer, 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);
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.113
diff -u -u -r1.113 packets.def
--- common/packets.def 2 May 2005 08:45:19 -0000 1.113
+++ common/packets.def 4 May 2005 20:17:21 -0000
@@ -437,7 +437,7 @@
WORKLIST worklist;
- BIT_STRING improvements[B_LAST+1];
+ bitvector(bv_imprs) improvements;
CITY_MAP city_map[CITY_MAP_SIZE * CITY_MAP_SIZE];
BOOL did_buy, did_sell, was_happy, airlift, diplomat_investigate;
@@ -455,8 +455,7 @@
UINT8 size;
BOOL happy;
BOOL unhappy;
- BOOL capital;
- BOOL walls;
+ bitvector(bv_imprs) improvements;
BOOL occupied;
UINT16 tile_trade;
end
@@ -537,7 +536,7 @@
PACKET_CITY_SABOTAGE_LIST=37;sc,lsend
UNIT diplomat_id;
CITY city_id;
- BIT_STRING improvements[B_LAST+1];
+ bitvector(bv_imprs) improvements;
end
/************** Player packets **********************/
@@ -1148,6 +1147,7 @@
IMPROVEMENT replaced_by;
UINT16 build_cost;
UINT8 upkeep, sabotage;
+ UINT16 flags;
STRING soundtag[MAX_LEN_NAME];
STRING soundtag_alt[MAX_LEN_NAME];
STRING helptext[MAX_LEN_PACKET];
Index: data/civ1/buildings.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/civ1/buildings.ruleset,v
retrieving revision 1.48
diff -u -u -r1.48 buildings.ruleset
--- data/civ1/buildings.ruleset 18 Apr 2005 06:52:50 -0000 1.48
+++ data/civ1/buildings.ruleset 4 May 2005 20:17:24 -0000
@@ -157,6 +157,7 @@
[building_city_walls]
name = _("City Walls")
genus = "Improvement"
+flags = "VisibleByOthers"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
@@ -408,6 +409,7 @@
[building_palace]
name = _("Palace")
genus = "SmallWonder"
+flags = "SaveSmallWonder"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
Index: data/civ2/buildings.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/civ2/buildings.ruleset,v
retrieving revision 1.52
diff -u -u -r1.52 buildings.ruleset
--- data/civ2/buildings.ruleset 2 May 2005 08:45:20 -0000 1.52
+++ data/civ2/buildings.ruleset 4 May 2005 20:17:24 -0000
@@ -188,6 +188,7 @@
[building_city_walls]
name = _("City Walls")
genus = "Improvement"
+flags = "VisibleByOthers"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
@@ -507,6 +508,7 @@
[building_palace]
name = _("Palace")
genus = "SmallWonder"
+flags = "SaveSmallWonder"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
Index: data/default/buildings.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/buildings.ruleset,v
retrieving revision 1.71
diff -u -u -r1.71 buildings.ruleset
--- data/default/buildings.ruleset 18 Apr 2005 23:33:03 -0000 1.71
+++ data/default/buildings.ruleset 4 May 2005 20:17:24 -0000
@@ -37,6 +37,7 @@
; build_cost = production shields required to build
; upkeep = monetary upkeep value
; sabotage = percent chance of diplomat sabotage being successful
+; flags = special flag strings
;
; */ <-- avoid gettext warnings
@@ -207,6 +208,7 @@
[building_city_walls]
name = _("City Walls")
genus = "Improvement"
+flags = "VisibleByOthers"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
@@ -535,6 +537,7 @@
[building_palace]
name = _("Palace")
genus = "SmallWonder"
+flags = "SaveSmallWonder"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
Index: data/history/buildings.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/history/buildings.ruleset,v
retrieving revision 1.23
diff -u -u -r1.23 buildings.ruleset
--- data/history/buildings.ruleset 18 Apr 2005 06:52:51 -0000 1.23
+++ data/history/buildings.ruleset 4 May 2005 20:17:24 -0000
@@ -190,6 +190,7 @@
[building_city_walls]
name = _("City Walls")
genus = "Improvement"
+flags = "VisibleByOthers"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
@@ -516,6 +517,7 @@
[building_palace]
name = _("Palace")
genus = "SmallWonder"
+flags = "SaveSmallWonder"
reqs =
{ "type", "name", "range"
"Tech", "Masonry", "Player"
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.319
diff -u -u -r1.319 citytools.c
--- server/citytools.c 3 May 2005 19:11:00 -0000 1.319
+++ server/citytools.c 4 May 2005 20:17:25 -0000
@@ -693,38 +693,43 @@
/**************************************************************************
Create a palace in a random city. Used when the capital was conquered.
**************************************************************************/
-static void build_free_palace(struct player *pplayer,
- const char *const old_capital_name)
+static void build_free_small_wonders(struct player *pplayer,
+ const char *const old_capital_name,
+ bv_imprs *had_small_wonders)
{
int size = city_list_size(pplayer->cities);
- struct city *pnew_capital;
if (size == 0) {
/* The last city was removed or transferred to the enemy. R.I.P. */
return;
}
- assert(find_palace(pplayer) == NULL);
+ impr_type_iterate(id) {
+ if (BV_ISSET(*had_small_wonders, id)) {
+ struct city *pnew_city;
- pnew_capital = city_list_get(pplayer->cities, myrand(size));
+ assert(find_city_from_small_wonder(pplayer, id) == NULL);
- city_add_improvement(pnew_capital, game.palace_building);
+ pnew_city = city_list_get(pplayer->cities, myrand(size));
- /*
- * send_player_cities will recalculate all cities and send them to
- * the client.
- */
- send_player_cities(pplayer);
+ city_add_improvement(pnew_city, id);
- notify_player(pplayer, _("You lost your capital %s. A new palace "
- "was built in %s."), old_capital_name,
- pnew_capital->name);
+ /*
+ * send_player_cities will recalculate all cities and send them to
+ * the client.
+ */
+ send_player_cities(pplayer);
- /*
- * The enemy want to see the new capital in his intelligence
- * report.
- */
- send_city_info(NULL, pnew_capital);
+ notify_player(pplayer, _("You lost %s. A new %s was built in %s."),
+ old_capital_name, get_improvement_name(id),
+ pnew_city->name);
+ /*
+ * The enemy want to see the new capital in his intelligence
+ * report.
+ */
+ send_city_info(NULL, pnew_city);
+ }
+ } impr_type_iterate_end;
}
/**********************************************************************
@@ -741,7 +746,7 @@
struct unit_list *old_city_units = unit_list_new();
struct player *pgiver = city_owner(pcity);
int old_trade_routes[NUM_TRADEROUTES];
- bool had_palace = is_capital(pcity);
+ bv_imprs had_small_wonders;
char old_city_name[MAX_LEN_NAME];
assert(pgiver != ptaker);
@@ -760,9 +765,13 @@
/* Remove all global improvement effects that this city confers (but
then restore the local improvement list - we need this to restore the
global effects for the new city owner) */
+ BV_CLR_ALL(had_small_wonders);
built_impr_iterate(pcity, i) {
city_remove_improvement(pcity, i);
- if (!is_small_wonder(i)) {
+
+ if (is_small_wonder(i)) {
+ BV_SET(had_small_wonders, i);
+ } else {
pcity->improvements[i] = I_ACTIVE;
}
} built_impr_iterate_end;
@@ -879,8 +888,8 @@
/* Build a new palace for free if the player lost her capital and
savepalace is on. */
- if (had_palace && game.savepalace) {
- build_free_palace(pgiver, pcity->name);
+ if (game.savepalace) {
+ build_free_small_wonders(pgiver, pcity->name, &had_small_wonders);
}
sanity_check_city(pcity);
@@ -1023,11 +1032,16 @@
int o;
struct player *pplayer = city_owner(pcity);
struct tile *ptile = pcity->tile;
- bool had_palace = is_capital(pcity);
+ bv_imprs had_small_wonders;
char *city_name = mystrdup(pcity->name);
+ BV_CLR_ALL(had_small_wonders);
built_impr_iterate(pcity, i) {
city_remove_improvement(pcity, i);
+
+ if (is_small_wonder(i)) {
+ BV_SET(had_small_wonders, i);
+ }
} built_impr_iterate_end;
/* Rehome units in other cities */
@@ -1130,8 +1144,8 @@
/* Build a new palace for free if the player lost her capital and
savepalace is on. */
- if (had_palace && game.savepalace) {
- build_free_palace(pplayer, city_name);
+ if (game.savepalace) {
+ build_free_small_wonders(pplayer, city_name, &had_small_wonders);
}
free(city_name);
@@ -1273,13 +1287,6 @@
packet->size = pdcity->size;
- if (pcity && pcity->id == pdcity->id && is_capital(pcity)) {
- packet->capital = TRUE;
- } else {
- packet->capital = FALSE;
- }
-
- packet->walls = pdcity->has_walls;
packet->occupied = pdcity->occupied;
packet->happy = pdcity->happy;
packet->unhappy = pdcity->unhappy;
@@ -1289,6 +1296,8 @@
} else {
packet->tile_trade = 0;
}
+
+ packet->improvements = pdcity->improvements;
}
/**************************************************************************
@@ -1501,7 +1510,7 @@
bool dipl_invest)
{
int x, y, i;
- char *p;
+
packet->id=pcity->id;
packet->owner=pcity->owner;
packet->x = pcity->tile->x;
@@ -1565,13 +1574,12 @@
}
}
- p = packet->improvements;
-
+ BV_CLR_ALL(packet->improvements);
impr_type_iterate(i) {
- *p++ = (city_got_building(pcity, i)) ? '1' : '0';
+ if (city_got_building(pcity, i)) {
+ BV_SET(packet->improvements, i);
+ }
} impr_type_iterate_end;
-
- *p = '\0';
}
/**************************************************************************
@@ -1594,16 +1602,24 @@
bool occupied =
(unit_list_size(pcity->tile->units) > 0);
bool happy = city_happy(pcity), unhappy = city_unhappy(pcity);
-
+ bv_imprs improvements;
+
+ BV_CLR_ALL(improvements);
+ impr_type_iterate(i) {
+ if (is_improvement_visible(i) && city_got_building(pcity, i)) {
+ BV_SET(improvements, i);
+ }
+ } impr_type_iterate_end;
+
if (pdcity
&& pdcity->id == pcity->id
&& strcmp(pdcity->name, pcity->name) == 0
&& pdcity->size == pcity->size
- && pdcity->has_walls == city_got_citywalls(pcity)
&& pdcity->occupied == occupied
&& pdcity->happy == happy
&& pdcity->unhappy == unhappy
- && pdcity->owner == pcity->owner) {
+ && pdcity->owner == pcity->owner
+ && BV_ARE_EQUAL(pdcity->improvements, improvements)) {
return FALSE;
}
@@ -1619,11 +1635,11 @@
}
sz_strlcpy(pdcity->name, pcity->name);
pdcity->size = pcity->size;
- pdcity->has_walls = city_got_citywalls(pcity);
pdcity->occupied = occupied;
pdcity->happy = happy;
pdcity->unhappy = unhappy;
pdcity->owner = pcity->owner;
+ pdcity->improvements = improvements;
return TRUE;
}
Index: server/diplomats.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/diplomats.c,v
retrieving revision 1.73
diff -u -u -r1.73 diplomats.c
--- server/diplomats.c 2 May 2005 19:05:15 -0000 1.73
+++ server/diplomats.c 4 May 2005 20:17:26 -0000
@@ -206,16 +206,14 @@
struct city *pcity)
{
struct packet_city_sabotage_list packet;
- char *p;
/* Send city improvements info to player. */
- p = packet.improvements;
+ BV_CLR_ALL(packet.improvements);
impr_type_iterate(i) {
- *p++=city_got_building(pcity,i)?'1':'0';
+ BV_SET(packet.improvements, city_got_building(pcity, i));
} impr_type_iterate_end;
- *p='\0';
packet.diplomat_id = pdiplomat->id;
packet.city_id = pcity->id;
lsend_packet_city_sabotage_list(player_reply_dest(pplayer), &packet);
Index: server/maphand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/maphand.h,v
retrieving revision 1.54
diff -u -u -r1.54 maphand.h
--- server/maphand.h 30 Apr 2005 20:59:50 -0000 1.54
+++ server/maphand.h 4 May 2005 20:17:26 -0000
@@ -29,12 +29,13 @@
/* Values in this struct are copied using a memcpy, so don't put any
* pointers in here. */
int id;
- bool has_walls;
bool occupied;
bool happy, unhappy;
char name[MAX_LEN_NAME];
unsigned short size;
unsigned char owner;
+
+ bv_imprs improvements;
};
struct player_tile {
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.251
diff -u -u -r1.251 ruleset.c
--- server/ruleset.c 2 May 2005 08:45:23 -0000 1.251
+++ server/ruleset.c 4 May 2005 20:17:27 -0000
@@ -2463,26 +2463,6 @@
section_file_check_unused(file, filename);
section_file_free(file);
-
- /*
- * Hack to allow code that explicitly checks for Palace or City Walls
- * to work.
- */
- game.palace_building = get_building_for_effect(EFT_CAPITAL_CITY);
- if (game.palace_building == B_LAST) {
- freelog(LOG_FATAL,
- /* TRANS: Obscure ruleset error */
- _("Cannot find any palace building"));
- exit(EXIT_FAILURE);
- }
-
- game.land_defend_building = get_building_for_effect(EFT_LAND_DEFEND);
- if (game.land_defend_building == B_LAST) {
- freelog(LOG_FATAL,
- /* TRANS: Obscure ruleset error */
- _("Cannot find any land defend building"));
- exit(EXIT_FAILURE);
- }
}
/**************************************************************************
@@ -2758,6 +2738,7 @@
packet.build_cost = b->build_cost;
packet.upkeep = b->upkeep;
packet.sabotage = b->sabotage;
+ packet.flags = b->flags;
sz_strlcpy(packet.soundtag, b->soundtag);
sz_strlcpy(packet.soundtag_alt, b->soundtag_alt);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.241
diff -u -u -r1.241 savegame.c
--- server/savegame.c 3 May 2005 19:42:48 -0000 1.241
+++ server/savegame.c 4 May 2005 20:17:28 -0000
@@ -2334,7 +2334,9 @@
The private map for fog of war
***********************************************************************/
static void player_map_load(struct player *plr, int plrno,
- struct section_file *file)
+ struct section_file *file,
+ char** improvement_order,
+ int improvement_order_size)
{
int i;
@@ -2404,6 +2406,8 @@
for (j = 0; j < i; j++) {
int nat_x, nat_y;
struct tile *ptile;
+ int k, id;
+ const char *p;
nat_x = secfile_lookup_int(file, "player%d.dc%d.x", plrno, j);
nat_y = secfile_lookup_int(file, "player%d.dc%d.y", plrno, j);
@@ -2413,7 +2417,6 @@
pdcity->id = secfile_lookup_int(file, "player%d.dc%d.id", plrno, j);
sz_strlcpy(pdcity->name, secfile_lookup_str(file, "player%d.dc%d.name",
plrno, j));
pdcity->size = secfile_lookup_int(file, "player%d.dc%d.size", plrno, j);
- pdcity->has_walls = secfile_lookup_bool(file,
"player%d.dc%d.has_walls", plrno, j);
pdcity->occupied = secfile_lookup_bool_default(file, FALSE,
"player%d.dc%d.occupied", plrno, j);
pdcity->happy = secfile_lookup_bool_default(file, FALSE,
@@ -2421,6 +2424,25 @@
pdcity->unhappy = secfile_lookup_bool_default(file, FALSE,
"player%d.dc%d.unhappy", plrno, j);
pdcity->owner = secfile_lookup_int(file, "player%d.dc%d.owner", plrno,
j);
+
+ /* Initialise list of improvements */
+ BV_CLR_ALL(pdcity->improvements);
+
+ p = secfile_lookup_str_default(file, NULL,
+ "player%d.dc%d.improvements", plrno, j);
+ if (!p) {
+ /* old savegames */
+ } else {
+ for (k = 0; k < improvement_order_size && p[k]; k++) {
+ if (p[k] == '1') {
+ id = find_improvement_by_name_orig(improvement_order[k]);
+ if (id != -1) {
+ BV_SET(pdcity->improvements, id);
+ }
+ }
+ }
+ }
+
map_get_player_tile(ptile, plr)->city = pdcity;
alloc_id(pdcity->id);
}
@@ -3001,6 +3023,7 @@
if (TRUE) {
struct dumb_city *pdcity;
i = 0;
+ char impr_buf[MAX_NUM_ITEMS + 1];
whole_map_iterate(ptile) {
if ((pdcity = map_get_player_tile(ptile, plr)->city)) {
@@ -3014,8 +3037,8 @@
plrno, i);
secfile_insert_int(file, pdcity->size, "player%d.dc%d.size",
plrno, i);
- secfile_insert_bool(file, pdcity->has_walls,
- "player%d.dc%d.has_walls", plrno, i);
+ secfile_insert_bool(file, FALSE,
+ "player%d.dc%d.has_walls", plrno, i);
secfile_insert_bool(file, pdcity->occupied,
"player%d.dc%d.occupied", plrno, i);
secfile_insert_bool(file, pdcity->happy,
@@ -3024,6 +3047,18 @@
"player%d.dc%d.unhappy", plrno, i);
secfile_insert_int(file, pdcity->owner, "player%d.dc%d.owner",
plrno, i);
+
+ /* Save improvement list as bitvector. Note that improvement order
+ * is saved in savefile.improvement_order.
+ */
+ impr_type_iterate(id) {
+ impr_buf[id] = BV_ISSET(pdcity->improvements, id) ? '1' : '0';
+ } impr_type_iterate_end;
+ impr_buf[game.num_impr_types] = '\0';
+ assert(strlen(impr_buf) < sizeof(impr_buf));
+ secfile_insert_str(file, impr_buf,
+ "player%d.dc%d.improvements", plrno, i);
+
i++;
}
} whole_map_iterate_end;
@@ -3612,7 +3647,8 @@
/* Since the cities must be placed on the map to put them on the
player map we do this afterwards */
for(i=0; i<game.nplayers; i++) {
- player_map_load(&game.players[i], i, file);
+ player_map_load(&game.players[i], i, file, improvement_order,
+ improvement_order_size);
}
/* We do this here since if the did it in player_load, player 1
|
|