[Freeciv-Dev] (PR#13776) Deleting a player does not make their nation av
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13776 >
Here is a kindof complicated patch that should fix it (untested).
-jason
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.179
diff -p -u -r1.179 climisc.c
--- client/climisc.c 18 Aug 2005 06:44:27 -0000 1.179
+++ client/climisc.c 26 Aug 2005 21:37:32 -0000
@@ -63,6 +63,7 @@ void client_remove_player(int plrno)
game_remove_player(get_player(plrno));
game_renumber_players(plrno);
update_conn_list_dialog();
+ races_toggles_set_sensitive();
}
/**************************************************************************
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.543
diff -p -u -r1.543 packhand.c
--- client/packhand.c 25 Aug 2005 20:36:12 -0000 1.543
+++ client/packhand.c 26 Aug 2005 21:37:33 -0000
@@ -1419,11 +1419,12 @@ void handle_player_info(struct packet_pl
char msg[MAX_LEN_MSG];
struct player *pplayer = &game.players[pinfo->playerno];
struct player_research* research;
+ bool is_new_nation;
sz_strlcpy(pplayer->name, pinfo->name);
pplayer->is_observer = pinfo->is_observer;
- pplayer->nation = get_nation_by_idx(pinfo->nation);
+ is_new_nation = player_set_nation(pplayer, 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;
@@ -1557,6 +1558,9 @@ void handle_player_info(struct packet_pl
sz_strlcpy(pplayer->username, pinfo->username);
+ if (is_new_nation) {
+ races_toggles_set_sensitive();
+ }
if (can_client_change_view()) {
/* Just about any changes above require an update to the intelligence
* dialog. */
@@ -2004,30 +2008,6 @@ void handle_player_remove(int player_id)
}
/**************************************************************************
- Mark a nation as available or unavailable, in pregame.
-**************************************************************************/
-void handle_nation_available(Nation_type_id nation_no,
- bool is_unavailable, bool is_used)
-{
- if (get_client_state() == CLIENT_PRE_GAME_STATE
- && nation_no >= 0 && nation_no < game.control.nation_count) {
- struct nation_type *nation = get_nation_by_idx(nation_no);
- const bool changed = (nation->is_unavailable != is_unavailable
- || nation->is_used != is_used);
-
- nation->is_unavailable = is_unavailable;
- nation->is_used = is_used;
-
- if (changed) {
- races_toggles_set_sensitive();
- }
- } else {
- freelog(LOG_ERROR,
- "got a select nation packet in an incompatible state");
- }
-}
-
-/**************************************************************************
Take arrival of ruleset control packet to indicate that
current allocated governments should be free'd, and new
memory allocated for new size. The same for nations.
@@ -2398,6 +2378,8 @@ void handle_ruleset_nation(struct packet
pl->groups[i] = add_new_nation_group(p->group_name[i]);
}
+ pl->is_available = p->is_available;
+
tileset_setup_nation_flag(tileset, p->id);
}
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.116
diff -p -u -r1.116 dialogs.c
--- client/gui-gtk-2.0/dialogs.c 19 Aug 2005 07:40:16 -0000 1.116
+++ client/gui-gtk-2.0/dialogs.c 26 Aug 2005 21:37:34 -0000
@@ -1598,7 +1598,7 @@ static GtkWidget* create_list_of_nations
GtkTreeIter it;
GValue value = { 0, };
- if (!is_nation_playable(pnation) || pnation->is_unavailable) {
+ if (!is_nation_playable(pnation) || !pnation->is_available) {
continue;
}
@@ -1610,7 +1610,7 @@ static GtkWidget* create_list_of_nations
s = crop_blankspace(get_nation_flag_sprite(tileset, pnation));
img = sprite_get_pixbuf(s);
- used = pnation->is_used;
+ used = (pnation->player != NULL);
gtk_list_store_set(store, &it, 0, pnation->index, 1, used, 2, img, -1);
free_sprite(s);
@@ -1976,7 +1976,7 @@ void races_toggles_set_sensitive(void)
gtk_tree_model_get(model, &it, 0, &nation_no, -1);
nation = get_nation_by_idx(nation_no);
- chosen = nation->is_unavailable || nation->is_used;
+ chosen = !nation->is_available || nation->player;
gtk_list_store_set(GTK_LIST_STORE(model), &it, 1, chosen, -1);
Index: common/game.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.c,v
retrieving revision 1.236
diff -p -u -r1.236 game.c
--- common/game.c 18 Aug 2005 06:44:27 -0000 1.236
+++ common/game.c 26 Aug 2005 21:37:34 -0000
@@ -435,6 +435,7 @@ void game_advance_year(void)
****************************************************************************/
void game_remove_player(struct player *pplayer)
{
+ player_set_nation(pplayer, NULL);
if (pplayer->attribute_block.data) {
free(pplayer->attribute_block.data);
pplayer->attribute_block.data = NULL;
@@ -488,6 +489,9 @@ void game_renumber_players(int plrno)
conn_list_iterate(game.players[i].connections, pconn) {
pconn->player = &game.players[i];
} conn_list_iterate_end;
+ if (game.players[i].nation) {
+ game.players[i].nation->player = &game.players[i];
+ }
/* We could renumber players in-game if we updated the unit and
* city owners. But for now we just make sure these lists are empty. */
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.55
diff -p -u -r1.55 nation.h
--- common/nation.h 18 Aug 2005 06:44:28 -0000 1.55
+++ common/nation.h 26 Aug 2005 21:37:34 -0000
@@ -99,9 +99,10 @@ struct nation_type {
int num_groups;
struct nation_group **groups;
- /* Unavailable nations aren't allowed in the scenario. Used nations are
- * those in use by another player. */
- bool is_unavailable, is_used;
+ /* Unavailable nations aren't allowed in the scenario. */
+ bool is_available;
+
+ struct player *player; /* Who's using the nation, or NULL. */
};
struct nation_type *find_nation_by_name(const char *name);
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.153
diff -p -u -r1.153 packets.def
--- common/packets.def 20 Aug 2005 19:53:40 -0000 1.153
+++ common/packets.def 26 Aug 2005 21:37:35 -0000
@@ -293,13 +293,6 @@ end
PACKET_SERVER_SHUTDOWN=8;sc,lsend
end
-PACKET_NATION_AVAILABLE=9;sc,lsend
- NATION id; key
-
- BOOL is_unavailable;
- BOOL is_used;
-end
-
PACKET_NATION_SELECT_REQ=10;cs,dsend
PLAYER player_no;
NATION nation_no;
@@ -1165,7 +1158,7 @@ PACKET_RULESET_TERRAIN_CONTROL=101;sc,ls
UINT8 fallout_tile_penalty[O_MAX]; /* % taken from output if polluted */
end
-PACKET_RULESET_NATION=102;sc,lsend
+PACKET_RULESET_NATION=102;sc,lsend,is-info
NATION id; key
STRING name[MAX_LEN_NAME];
@@ -1184,7 +1177,7 @@ PACKET_RULESET_NATION=102;sc,lsend
STRING leader_name[MAX_NUM_LEADERS:leader_count][MAX_LEN_NAME];
BOOL leader_sex[MAX_NUM_LEADERS:leader_count];
- BOOL is_playable, is_observer, is_barbarian;
+ BOOL is_available, is_playable, is_observer, is_barbarian;
UINT8 group_count;
STRING group_name[MAX_NUM_NATION_GROUPS:group_count][MAX_LEN_NAME];
Index: common/player.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.c,v
retrieving revision 1.191
diff -p -u -r1.191 player.c
--- common/player.c 22 Aug 2005 21:15:48 -0000 1.191
+++ common/player.c 26 Aug 2005 21:37:35 -0000
@@ -164,6 +164,25 @@ void player_init(struct player *plr)
BV_CLR_ALL(plr->debug);
}
+/****************************************************************************
+ Set the player's nation to the given nation (may be NULL). Returns TRUE
+ iff there was a change.
+****************************************************************************/
+bool player_set_nation(struct player *pplayer, struct nation_type *pnation)
+{
+ if (pplayer->nation != pnation) {
+ if (pplayer->nation) {
+ pplayer->nation->player = NULL;
+ }
+ if (pnation) {
+ pnation->player = pplayer;
+ }
+ pplayer->nation = pnation;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/***************************************************************
...
***************************************************************/
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.163
diff -p -u -r1.163 player.h
--- common/player.h 18 Aug 2005 06:44:28 -0000 1.163
+++ common/player.h 26 Aug 2005 21:37:35 -0000
@@ -204,6 +204,7 @@ struct player *find_player_by_name(const
struct player *find_player_by_name_prefix(const char *name,
enum m_pre_result *result);
struct player *find_player_by_user(const char *name);
+bool player_set_nation(struct player *pplayer, struct nation_type *pnation);
void player_set_unit_focus_status(struct player *pplayer);
bool player_has_embassy(const struct player *pplayer,
const struct player *pplayer2);
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.100
diff -p -u -r1.100 barbarian.c
--- server/barbarian.c 22 Aug 2005 20:46:00 -0000 1.100
+++ server/barbarian.c 26 Aug 2005 21:37:35 -0000
@@ -86,7 +86,7 @@ static bool is_sea_barbarian(struct play
struct nation_type *pick_barbarian_nation(void)
{
nations_iterate(pnation) {
- if (is_nation_barbarian(pnation) && !pnation->is_used) {
+ if (is_nation_barbarian(pnation) && !pnation->player) {
return pnation;
}
} nations_iterate_end;
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.344
diff -p -u -r1.344 citytools.c
--- server/citytools.c 26 Aug 2005 19:40:26 -0000 1.344
+++ server/citytools.c 26 Aug 2005 21:37:36 -0000
@@ -1210,7 +1210,8 @@ void handle_unit_enter_city(struct unit
/* Do a civil war only if there's an available unused nation. */
nations_iterate(pnation) {
if (is_nation_playable(pnation)
- && !pnation->is_unavailable && !pnation->is_used) {
+ && pnation->is_available
+ && !pnation->player) {
do_civil_war = TRUE;
break;
}
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.416
diff -p -u -r1.416 plrhand.c
--- server/plrhand.c 26 Aug 2005 19:40:26 -0000 1.416
+++ server/plrhand.c 26 Aug 2005 21:37:36 -0000
@@ -1320,7 +1320,8 @@ struct nation_type *pick_available_natio
* 2: preferred choice */
nations_iterate(pnation) {
if (!is_nation_playable(pnation)
- || pnation->is_used || pnation->is_unavailable) {
+ || pnation->player
+ || !pnation->is_available) {
/* Nation is unplayable or already used: don't consider it. */
nations_used[pnation->index] = UNAVAILABLE;
match[pnation->index] = 0;
@@ -1379,7 +1380,7 @@ struct nation_type *pick_available_natio
static struct nation_type *pick_observer_nation(void)
{
nations_iterate(pnation) {
- if (is_nation_observer(pnation) && !pnation->is_used) {
+ if (is_nation_observer(pnation) && !pnation->player) {
return pnation;
}
} nations_iterate_end;
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.280
diff -p -u -r1.280 ruleset.c
--- server/ruleset.c 18 Aug 2005 06:53:31 -0000 1.280
+++ server/ruleset.c 26 Aug 2005 21:37:37 -0000
@@ -101,8 +101,6 @@ static void send_ruleset_units(struct co
static void send_ruleset_buildings(struct conn_list *dest);
static void send_ruleset_terrain(struct conn_list *dest);
static void send_ruleset_governments(struct conn_list *dest);
-static void send_ruleset_nations(struct conn_list *dest);
-static void send_ruleset_nations_availability(struct conn_list *dest);
static void send_ruleset_cities(struct conn_list *dest);
static void send_ruleset_game(struct conn_list *dest);
@@ -2245,8 +2243,8 @@ static void load_ruleset_nations(struct
pl->legend[MAX_LEN_MSG - 1] = '\0';
}
- pl->is_unavailable = FALSE;
- pl->is_used = FALSE;
+ pl->is_available = TRUE;
+ pl->player = NULL;
}
/* Calculate parent nations. O(n^2) algorithm. */
@@ -2935,7 +2933,7 @@ static void send_ruleset_governments(str
Send the nations ruleset information (info on each nation) to the
specified connections.
**************************************************************************/
-static void send_ruleset_nations(struct conn_list *dest)
+void send_ruleset_nations(struct conn_list *dest)
{
struct packet_ruleset_nation packet;
struct nation_type *n;
@@ -2980,22 +2978,6 @@ static void send_ruleset_nations(struct
}
/**************************************************************************
- Send nations availability information
-**************************************************************************/
-static void send_ruleset_nations_availability(struct conn_list *dest)
-{
- int i;
- for (i = 0; i < game.control.nation_count; i++) {
- struct nation_type *nation = get_nation_by_idx(i);
- struct packet_nation_available packet;
- packet.id = i;
- packet.is_unavailable = nation->is_unavailable;
- packet.is_used = nation->is_used;
- lsend_packet_nation_available(dest, &packet);
- }
-}
-
-/**************************************************************************
Send the city-style ruleset information (each style) to the specified
connections.
**************************************************************************/
@@ -3145,7 +3127,6 @@ void send_rulesets(struct conn_list *des
send_ruleset_terrain(dest);
send_ruleset_buildings(dest);
send_ruleset_nations(dest);
- send_ruleset_nations_availability(dest);
send_ruleset_cities(dest);
send_ruleset_cache(dest);
Index: server/ruleset.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.h,v
retrieving revision 1.9
diff -p -u -r1.9 ruleset.h
--- server/ruleset.h 18 Dec 2002 17:36:20 -0000 1.9
+++ server/ruleset.h 26 Aug 2005 21:37:37 -0000
@@ -18,4 +18,6 @@ struct conn_list;
void load_rulesets(void);
void send_rulesets(struct conn_list *dest);
+void send_ruleset_nations(struct conn_list *dest);
+
#endif /* FC__RULESET_H */
Index: server/sanitycheck.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sanitycheck.c,v
retrieving revision 1.73
diff -p -u -r1.73 sanitycheck.c
--- server/sanitycheck.c 25 Aug 2005 19:21:20 -0000 1.73
+++ server/sanitycheck.c 26 Aug 2005 21:37:37 -0000
@@ -464,6 +464,10 @@ static void check_players(void)
/* Dying players shouldn't be left around. But they are. */
SANITY_CHECK(!pplayer->is_dying);
}
+
+ nations_iterate(pnation) {
+ SANITY_CHECK(!pnation->player || pnation->player->nation == pnation);
+ } nations_iterate_end;
}
/****************************************************************************
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.288
diff -p -u -r1.288 srv_main.c
--- server/srv_main.c 26 Aug 2005 19:40:26 -0000 1.288
+++ server/srv_main.c 26 Aug 2005 21:37:37 -0000
@@ -1164,20 +1164,6 @@ static bool is_allowed_player_name(struc
}
/****************************************************************************
- Send unavailable/used information for this nation out to everyone.
-****************************************************************************/
-static void send_nation_available(struct nation_type *nation)
-{
- struct packet_nation_available packet;
-
- packet.id = nation->index;
- packet.is_unavailable = nation->is_unavailable;
- packet.is_used = nation->is_used;
-
- lsend_packet_nation_available(game.est_connections, &packet);
-}
-
-/****************************************************************************
Initialize the list of available nations.
Call this on server start, or when loading a scenario.
@@ -1202,23 +1188,16 @@ void init_available_nations(void)
if (start_nations) {
nations_iterate(nation) {
- nation->is_unavailable = TRUE;
+ nation->is_available = FALSE;
} nations_iterate_end;
for (i = 0; i < map.num_start_positions; i++) {
- map.start_positions[i].nation->is_unavailable = FALSE;
+ map.start_positions[i].nation->is_available = TRUE;
}
- } else {
- nations_iterate(nation) {
- /* We preemptively mark unplayable nations as unavailable. */
- /* 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) {
- nation->is_used = FALSE;
- send_nation_available(nation);
+ nation->player = NULL;
} nations_iterate_end;
+ send_ruleset_nations(game.est_connections);
}
/**************************************************************************
@@ -1252,13 +1231,13 @@ void handle_nation_select_req(struct pla
return;
}
- if (new_nation->is_unavailable) {
+ if (!new_nation->is_available) {
notify_conn_ex(pplayer->connections, NULL, E_NATION_SELECTED,
_("%s nation is not available in this scenario."),
new_nation->name);
return;
}
- if (new_nation->is_unavailable) {
+ if (new_nation->player && new_nation->player != pplayer) {
notify_conn_ex(pplayer->connections, NULL, E_NATION_SELECTED,
_("%s nation is already in use."),
new_nation->name);
@@ -1283,17 +1262,13 @@ void handle_nation_select_req(struct pla
sz_strlcpy(pplayer->name, name);
pplayer->is_male = is_male;
pplayer->city_style = city_style;
-
- new_nation->is_used = TRUE;
- send_nation_available(new_nation);
}
- pplayer->nation = new_nation; /* May be NULL (NO_NATION_SELECTED) */
+ (void) player_set_nation(pplayer, new_nation);
send_player_info_c(pplayer, game.est_connections);
if (old_nation != NO_NATION_SELECTED) {
- old_nation->is_used = FALSE;
- send_nation_available(old_nation);
+ old_nation->player = NULL;
}
}
@@ -1387,7 +1362,7 @@ void aifill(int amount)
char player_name[ARRAY_SIZE(pplayer->name)];
server_player_init(pplayer, FALSE, TRUE);
- pplayer->nation = NO_NATION_SELECTED;
+ player_set_nation(pplayer, NULL);
do {
my_snprintf(player_name, sizeof(player_name),
"AI%d", ++filled);
@@ -1454,9 +1429,10 @@ static void generate_players(void)
/* See if the player name matches a known leader name. */
nations_iterate(pnation) {
if (is_nation_playable(pnation)
- && !pnation->is_unavailable && !pnation->is_used
+ && pnation->is_available
+ && !pnation->player
&& check_nation_leader_name(pnation, pplayer->name)) {
- pplayer->nation = pnation;
+ player_set_nation(pplayer, pnation);
pplayer->city_style = get_nation_city_style(pnation);
pplayer->is_male = get_nation_leader_sex(pnation, pplayer->name);
break;
@@ -1467,10 +1443,9 @@ static void generate_players(void)
continue;
}
- pplayer->nation = pick_available_nation(NULL);
+ player_set_nation(pplayer, pick_available_nation(NULL));
assert(pplayer->nation != NO_NATION_SELECTED);
- pplayer->nation->is_used = TRUE;
pplayer->city_style = get_nation_city_style(pplayer->nation);
pick_random_player_name(pplayer->nation, player_name);
|
|