[Freeciv-Dev] (PR#13878) redesign observers
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13878 >
This patch fixes the remaining problems and is probably ready to be
committed.
The bug in v3 of the patch was simply in detach_command, which would
just return and do nothing for observing players (since pconn->player
was NULL).
-jason
Index: client/attribute.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/attribute.c,v
retrieving revision 1.22
diff -p -u -r1.22 attribute.c
--- client/attribute.c 23 Sep 2005 19:23:31 -0000 1.22
+++ client/attribute.c 26 Sep 2005 22:19:29 -0000
@@ -257,6 +257,10 @@ void attribute_flush(void)
{
struct player *pplayer = game.player_ptr;
+ if (!pplayer) {
+ return;
+ }
+
assert(attribute_hash != NULL);
if (hash_num_entries(attribute_hash) == 0)
@@ -280,6 +284,10 @@ void attribute_restore(void)
{
struct player *pplayer = game.player_ptr;
+ if (!pplayer) {
+ return;
+ }
+
assert(attribute_hash != NULL);
if (!unserialize_hash(attribute_hash, pplayer->attribute_block.data,
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.85
diff -p -u -r1.85 citydlg_common.c
--- client/citydlg_common.c 1 Aug 2005 23:09:35 -0000 1.85
+++ client/citydlg_common.c 26 Sep 2005 22:19:29 -0000
@@ -318,7 +318,7 @@ void get_city_dialog_production_row(char
}
my_snprintf(buf[2], column_size, "%d", unit_build_shield_cost(ptype));
} else {
- struct player *pplayer = game.player_ptr;
+ struct player *pplayer = pcity->owner;
/* Total & turns left meaningless on capitalization */
if (building_has_effect(target.value, EFT_PROD_TO_GOLD)) {
Index: client/civclient.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/civclient.c,v
retrieving revision 1.234
diff -p -u -r1.234 civclient.c
--- client/civclient.c 5 Sep 2005 15:55:45 -0000 1.234
+++ client/civclient.c 26 Sep 2005 22:19:30 -0000
@@ -724,8 +724,9 @@ bool can_client_issue_orders(void)
**************************************************************************/
bool can_meet_with_player(const struct player *pplayer)
{
- return (could_meet_with_player(game.player_ptr, pplayer)
- && can_client_issue_orders());
+ return (can_client_issue_orders()
+ && game.player_ptr
+ && could_meet_with_player(game.player_ptr, pplayer));
}
/**************************************************************************
@@ -734,7 +735,9 @@ bool can_meet_with_player(const struct p
**************************************************************************/
bool can_intel_with_player(const struct player *pplayer)
{
- return could_intel_with_player(game.player_ptr, pplayer);
+ return (client_is_observer()
+ || (game.player_ptr
+ && could_intel_with_player(game.player_ptr, pplayer)));
}
/**************************************************************************
@@ -744,7 +747,7 @@ bool can_intel_with_player(const struct
**************************************************************************/
bool can_client_change_view(void)
{
- return (game.player_ptr
+ return ((game.player_ptr || client_is_observer())
&& (get_client_state() == CLIENT_GAME_RUNNING_STATE
|| get_client_state() == CLIENT_GAME_OVER_STATE));
}
Index: client/climap.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climap.c,v
retrieving revision 1.10
diff -p -u -r1.10 climap.c
--- client/climap.c 5 May 2005 18:32:46 -0000 1.10
+++ client/climap.c 26 Sep 2005 22:19:30 -0000
@@ -19,9 +19,9 @@
#include "map.h"
#include "shared.h"
-#include "tilespec.h" /* tileset_is_isometric(tileset) */
-
+#include "civclient.h"
#include "climap.h"
+#include "tilespec.h" /* tileset_is_isometric(tileset) */
/************************************************************************
A tile's "known" field is used by the server to store whether _each_
@@ -35,6 +35,9 @@
*************************************************************************/
enum known_type client_tile_get_known(const struct tile *ptile)
{
+ if (!game.player_ptr && client_is_observer()) {
+ return TILE_KNOWN;
+ }
return tile_get_known(ptile, game.player_ptr);
}
Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.181
diff -p -u -r1.181 climisc.c
--- client/climisc.c 13 Sep 2005 08:13:10 -0000 1.181
+++ client/climisc.c 26 Sep 2005 22:19:30 -0000
@@ -111,12 +111,15 @@ void client_remove_unit(struct unit *pun
TILE_XY(pcity->tile));
}
- pcity = player_find_city_by_id(game.player_ptr, hc);
- if (pcity) {
- refresh_city_dialog(pcity);
- freelog(LOG_DEBUG, "home city %s, %s, (%d %d)", pcity->name,
- get_nation_name(city_owner(pcity)->nation),
- TILE_XY(pcity->tile));
+ /* FIXME: this can cause two refreshes to be done? */
+ if (game.player_ptr) {
+ pcity = player_find_city_by_id(game.player_ptr, hc);
+ if (pcity) {
+ refresh_city_dialog(pcity);
+ freelog(LOG_DEBUG, "home city %s, %s, (%d %d)", pcity->name,
+ get_nation_name(city_owner(pcity)->nation),
+ TILE_XY(pcity->tile));
+ }
}
refresh_unit_mapcanvas(&old_unit, ptile, TRUE, FALSE);
@@ -162,6 +165,10 @@ void client_change_all(struct city_produ
{
int last_request_id = 0;
+ if (!can_client_issue_orders()) {
+ return;
+ }
+
create_event(NULL, E_CITY_PRODUCTION_CHANGED,
_("Changing production of every %s into %s."),
from.is_unit ? get_unit_type(from.value)->name
@@ -191,7 +198,8 @@ void client_change_all(struct city_produ
const char *get_embassy_status(const struct player *me,
const struct player *them)
{
- if (me == them
+ if (!me || !them
+ || me == them
|| !them->is_alive
|| !me->is_alive) {
return "-";
@@ -218,13 +226,13 @@ const char *get_embassy_status(const str
const char *get_vision_status(const struct player *me,
const struct player *them)
{
- if (gives_shared_vision(me, them)) {
+ if (me && them && gives_shared_vision(me, them)) {
if (gives_shared_vision(them, me)) {
return Q_("?vision:Both");
} else {
return Q_("?vision:To Them");
}
- } else if (gives_shared_vision(them, me)) {
+ } else if (me && them && gives_shared_vision(them, me)) {
return Q_("?vision:To Us");
} else {
return "";
@@ -373,7 +381,8 @@ struct sprite *client_cooling_sprite(voi
**************************************************************************/
struct sprite *client_government_sprite(void)
{
- if (can_client_change_view() && game.control.government_count > 0) {
+ if (can_client_change_view() && game.player_ptr
+ && game.control.government_count > 0) {
struct government *gov = game.player_ptr->government;
return get_government_sprite(tileset, gov);
@@ -402,15 +411,15 @@ void center_on_something(void)
can_slide = FALSE;
if ((punit = get_unit_in_focus())) {
center_tile_mapcanvas(punit->tile);
- } else if ((pcity = find_palace(game.player_ptr))) {
+ } else if (game.player_ptr && (pcity = find_palace(game.player_ptr))) {
/* Else focus on the capital. */
center_tile_mapcanvas(pcity->tile);
- } else if (city_list_size(game.player_ptr->cities) > 0) {
+ } else if (game.player_ptr && city_list_size(game.player_ptr->cities) > 0) {
/* Just focus on any city. */
pcity = city_list_get(game.player_ptr->cities, 0);
assert(pcity != NULL);
center_tile_mapcanvas(pcity->tile);
- } else if (unit_list_size(game.player_ptr->units) > 0) {
+ } else if (game.player_ptr && unit_list_size(game.player_ptr->units) > 0) {
/* Just focus on any unit. */
punit = unit_list_get(game.player_ptr->units, 0);
assert(punit != NULL);
@@ -633,7 +642,9 @@ void name_and_sort_items(struct city_pro
}
/**************************************************************************
-...
+ Return possible production targets for the current player's cities.
+
+ FIXME: this should probably take a pplayer argument.
**************************************************************************/
int collect_production_targets(struct city_production *targets,
struct city **selected_cities,
@@ -648,6 +659,10 @@ int collect_production_targets(struct ci
cid cid;
int items_used = 0;
+ if (!game.player_ptr) {
+ return 0;
+ }
+
for (cid = first; cid < last; cid++) {
bool append = FALSE;
struct city_production target = cid_decode(cid);
@@ -681,6 +696,8 @@ int collect_production_targets(struct ci
/**************************************************************************
Collect the cids of all targets (improvements and units) which are
currently built in a city.
+
+ FIXME: this should probably take a pplayer argument.
**************************************************************************/
int collect_currently_building_targets(struct city_production *targets)
{
@@ -688,6 +705,10 @@ int collect_currently_building_targets(s
int cids_used = 0;
cid cid;
+ if (!game.player_ptr) {
+ return 0;
+ }
+
memset(mapping, 0, sizeof(mapping));
city_list_iterate(game.player_ptr->cities, pcity) {
mapping[cid_encode_from_city(pcity)] = TRUE;
@@ -706,11 +727,17 @@ int collect_currently_building_targets(s
/**************************************************************************
Collect the cids of all targets (improvements and units) which can
be build in a city.
+
+ FIXME: this should probably take a pplayer argument.
**************************************************************************/
int collect_buildable_targets(struct city_production *targets)
{
int cids_used = 0;
+ if (!game.player_ptr) {
+ return 0;
+ }
+
impr_type_iterate(id) {
if (can_player_build_improvement(game.player_ptr, id)) {
targets[cids_used].is_unit = FALSE;
@@ -733,6 +760,8 @@ int collect_buildable_targets(struct cit
/**************************************************************************
Collect the cids of all targets which can be build by this city or
in general.
+
+ FIXME: this should probably take a pplayer argument.
**************************************************************************/
int collect_eventually_buildable_targets(struct city_production *targets,
struct city *pcity,
@@ -740,6 +769,10 @@ int collect_eventually_buildable_targets
{
int cids_used = 0;
+ if (!game.player_ptr) {
+ return 0;
+ }
+
impr_type_iterate(id) {
bool can_build = can_player_build_improvement(game.player_ptr, id);
bool can_eventually_build =
@@ -809,7 +842,8 @@ int num_supported_units_in_city(struct c
{
struct unit_list *plist;
- if (pcity->owner != game.player_ptr) {
+ if (can_player_see_city_internals(game.player_ptr, pcity)) {
+ /* Other players don't see inside the city (but observers do). */
plist = pcity->info_units_supported;
} else {
plist = pcity->units_supported;
@@ -825,7 +859,8 @@ int num_present_units_in_city(struct cit
{
struct unit_list *plist;
- if (pcity->owner != game.player_ptr) {
+ if (can_player_see_units_in_city(game.player_ptr, pcity)) {
+ /* Other players don't see inside the city (but observers do). */
plist = pcity->info_units_present;
} else {
plist = pcity->tile->units;
@@ -855,8 +890,8 @@ void handle_event(char *message, struct
if (BOOL_VAL(where & MW_MESSAGES)) {
add_notify_window(message, ptile, event);
}
- if (BOOL_VAL(where & MW_POPUP) &&
- (!game.player_ptr->ai.control)) {
+ if (BOOL_VAL(where & MW_POPUP)
+ && (!game.player_ptr || !game.player_ptr->ai.control)) {
popup_notify_goto_dialog(_("Popup Request"), message, ptile);
}
@@ -999,7 +1034,7 @@ void cityrep_buy(struct city *pcity)
return;
}
- if (game.player_ptr->economic.gold >= value) {
+ if (pcity->owner->economic.gold >= value) {
city_buy_production(pcity);
} else {
const char *name;
@@ -1012,7 +1047,7 @@ void cityrep_buy(struct city *pcity)
create_event(NULL, E_BAD_COMMAND,
_("%s costs %d gold and you only have %d gold."),
- name, value, game.player_ptr->economic.gold);
+ name, value, pcity->owner->economic.gold);
}
}
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.187
diff -p -u -r1.187 control.c
--- client/control.c 13 Sep 2005 08:13:10 -0000 1.187
+++ client/control.c 26 Sep 2005 22:19:31 -0000
@@ -145,10 +145,8 @@ void set_unit_focus(struct unit *punit)
{
struct unit *punit_old_focus = punit_focus;
- if (punit && punit->owner != game.player_ptr) {
+ if (punit && game.player_ptr && punit->owner != game.player_ptr) {
/* Callers should make sure this never happens. */
- freelog(LOG_ERROR, "Trying to focus on another player's unit!");
- assert(0);
return;
}
@@ -227,7 +225,7 @@ at the end of the goto, then they are st
**************************************************************************/
void update_unit_focus(void)
{
- if (!can_client_change_view()) {
+ if (!game.player_ptr || !can_client_change_view()) {
return;
}
if (!punit_focus
@@ -261,7 +259,10 @@ void advance_unit_focus(void)
struct unit *punit_old_focus = punit_focus;
struct unit *candidate = find_best_focus_candidate(FALSE);
- assert(can_client_change_view());
+ if (!game.player_ptr || !can_client_change_view()) {
+ set_unit_focus(NULL);
+ return;
+ }
set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST, ORDER_LAST);
if (!can_client_change_view()) {
@@ -315,7 +316,8 @@ static struct unit *find_best_focus_cand
int best_dist = 99999;
struct tile *ptile;
- if (!is_player_phase(game.player_ptr, game.info.phase)) {
+ if (!game.player_ptr
+ || !is_player_phase(game.player_ptr, game.info.phase)) {
/* No focus unit wanted. */
return NULL;
}
@@ -457,7 +459,8 @@ double blink_turn_done_button(void)
static struct timer *blink_timer = NULL;
const double blink_time = 0.5; /* half-second blink interval */
- if (game.player_ptr && game.player_ptr->is_alive
+ if (game.player_ptr
+ && game.player_ptr->is_alive
&& !game.player_ptr->phase_done) {
if (!blink_timer || read_timer_seconds(blink_timer) > blink_time) {
int is_waiting = 0, is_moving = 0;
@@ -588,13 +591,16 @@ void process_caravan_arrival(struct unit
id = *p_id;
free(p_id);
p_id = NULL;
- punit = player_find_unit_by_id(game.player_ptr, id);
+ punit = find_unit_by_id(id);
if (punit && (unit_can_help_build_wonder_here(punit)
|| unit_can_est_traderoute_here(punit))
- && (!game.player_ptr->ai.control)) {
+ && (!game.player_ptr
+ || (game.player_ptr == punit->owner
+ && !game.player_ptr->ai.control))) {
struct city *pcity_dest = tile_get_city(punit->tile);
struct city *pcity_homecity = find_city_by_id(punit->homecity);
+
if (pcity_dest && pcity_homecity) {
popup_caravan_dialog(punit, pcity_homecity, pcity_dest);
return;
@@ -794,7 +800,7 @@ void request_unit_unload_all(struct unit
request_new_unit_activity(pcargo, ACTIVITY_IDLE);
}
- if (pcargo->owner == game.player_ptr) {
+ if (pcargo->owner == punit->owner) {
plast = pcargo;
}
}
@@ -867,6 +873,9 @@ void request_diplomat_action(enum diplom
void wakeup_sentried_units(struct tile *ptile)
{
+ if (!can_client_issue_orders()) {
+ return;
+ }
unit_list_iterate(ptile->units, punit) {
if (punit->activity == ACTIVITY_SENTRY
&& game.player_ptr == punit->owner) {
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.91
diff -p -u -r1.91 goto.c
--- client/goto.c 20 Aug 2005 19:53:40 -0000 1.91
+++ client/goto.c 26 Sep 2005 22:19:31 -0000
@@ -1152,7 +1152,7 @@ struct pf_path *path_to_nearest_allied_c
struct pf_map *map;
struct pf_path *path = NULL;
- if ((pcity = is_allied_city_tile(punit->tile, game.player_ptr))) {
+ if ((pcity = is_allied_city_tile(punit->tile, punit->owner))) {
/* We're already on a city - don't go anywhere. */
return NULL;
}
@@ -1165,7 +1165,7 @@ struct pf_path *path_to_nearest_allied_c
pf_next_get_position(map, &pos);
- if ((pcity = is_allied_city_tile(pos.tile, game.player_ptr))) {
+ if ((pcity = is_allied_city_tile(pos.tile, punit->owner))) {
break;
}
}
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.62
diff -p -u -r1.62 mapctrl_common.c
--- client/mapctrl_common.c 13 Sep 2005 08:13:11 -0000 1.62
+++ client/mapctrl_common.c 26 Sep 2005 22:19:31 -0000
@@ -324,6 +324,10 @@ void clipboard_copy_production(struct ti
{
struct city *pcity = ptile->city;
+ if (!can_client_issue_orders()) {
+ return;
+ }
+
if (pcity) {
if (pcity->owner != game.player_ptr) {
return;
@@ -402,6 +406,9 @@ static void clipboard_send_production_pa
**************************************************************************/
void upgrade_canvas_clipboard(void)
{
+ if (!can_client_issue_orders()) {
+ return;
+ }
if (clipboard.is_unit) {
struct unit_type *u
= can_upgrade_unittype(game.player_ptr, get_unit_type(clipboard.value));
@@ -589,7 +596,9 @@ void update_turn_done_button_state()
if (turn_done_state) {
if (waiting_for_end_turn
- || (game.player_ptr->ai.control && !ai_manual_turn_done)) {
+ || (game.player_ptr
+ && game.player_ptr->ai.control
+ && !ai_manual_turn_done)) {
send_turn_done();
} else {
update_turn_done_button(TRUE);
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.245
diff -p -u -r1.245 mapview_common.c
--- client/mapview_common.c 26 Sep 2005 20:52:38 -0000 1.245
+++ client/mapview_common.c 26 Sep 2005 22:19:32 -0000
@@ -1217,7 +1217,8 @@ static void show_full_citybar(struct can
const struct citybar_sprites *citybar = get_citybar_sprites(tileset);
const bool line1 = draw_city_names;
const bool line2 = ((draw_city_productions || draw_city_growth)
- && pcity->owner == game.player_ptr);
+ && (!game.player_ptr
+ || pcity->owner == game.player_ptr));
static char name[512], growth[32], prod[512], size[32];
enum color_std growth_color;
struct color *owner_color;
@@ -1432,7 +1433,8 @@ static void show_small_citybar(struct ca
*width = MAX(*width, total_width);
*height += total_height + 3;
}
- if (draw_city_productions && pcity->owner == game.player_ptr) {
+ if (draw_city_productions
+ && (pcity->owner == game.player_ptr || !game.player_ptr)) {
get_city_mapview_production(pcity, prod, sizeof(prod));
get_text_size(&prod_rect.w, &prod_rect.h, FONT_CITY_PROD, prod);
@@ -1818,7 +1820,7 @@ struct city *find_city_or_settler_near_t
}
if (pcity) {
- if (pcity->owner == game.player_ptr) {
+ if (!game.player_ptr || pcity->owner == game.player_ptr) {
/* rule a */
return pcity;
} else {
@@ -1832,7 +1834,8 @@ struct city *find_city_or_settler_near_t
city_map_checked_iterate(ptile, city_x, city_y, tile1) {
pcity = tile_get_city(tile1);
- if (pcity && pcity->owner == game.player_ptr
+ if (pcity
+ && (!game.player_ptr || pcity->owner == game.player_ptr)
&& get_worker_city(pcity, CITY_MAP_SIZE - 1 - city_x,
CITY_MAP_SIZE - 1 - city_y) == C_TILE_EMPTY) {
/*
@@ -1862,7 +1865,7 @@ struct city *find_city_or_settler_near_t
if (tile1) {
unit_list_iterate(tile1->units, psettler) {
- if (psettler->owner == game.player_ptr
+ if ((!game.player_ptr || psettler->owner == game.player_ptr)
&& unit_flag(psettler, F_CITIES)
&& city_can_be_built_here(psettler->tile, psettler)) {
if (!closest_settler) {
@@ -2134,7 +2137,7 @@ void get_city_mapview_name_and_growth(st
{
my_snprintf(name_buffer, name_buffer_len, pcity->name);
- if (pcity->owner == game.player_ptr) {
+ if (!game.player_ptr || pcity->owner == game.player_ptr) {
int turns = city_turns_to_grow(pcity);
if (turns == 0) {
Index: client/messagewin_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/messagewin_common.c,v
retrieving revision 1.24
diff -p -u -r1.24 messagewin_common.c
--- client/messagewin_common.c 25 Aug 2005 20:36:12 -0000 1.24
+++ client/messagewin_common.c 26 Sep 2005 22:19:32 -0000
@@ -75,8 +75,10 @@ void update_meswin_dialog(void)
return;
}
- if (!is_meswin_open() && messages_total > 0 &&
- (!game.player_ptr->ai.control)) {
+ if (!is_meswin_open() && messages_total > 0
+ && !client_is_observer()
+ && game.player_ptr
+ && !game.player_ptr->ai.control) {
popup_meswin_dialog(FALSE);
change = FALSE;
return;
@@ -144,7 +146,9 @@ void add_notify_window(char *message, st
if (messages[i].location_ok) {
struct city *pcity = tile_get_city(messages[i].tile);
- messages[i].city_ok = (pcity && city_owner(pcity) == game.player_ptr);
+ messages[i].city_ok
+ = (pcity
+ && can_player_see_city_internals(game.player_ptr, pcity));
} else {
messages[i].city_ok = FALSE;
}
@@ -193,7 +197,8 @@ void meswin_popup_city(int message_index
center_tile_mapcanvas(ptile);
}
- if (pcity && city_owner(pcity) == game.player_ptr) {
+ if (pcity
+ && can_player_see_units_in_city(game.player_ptr, pcity)) {
/* If the event was the city being destroyed, pcity will be NULL
* and we'd better not try to pop it up. It's also possible that
* events will happen on enemy cities; we generally don't want to pop
Index: client/overview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/overview_common.c,v
retrieving revision 1.18
diff -p -u -r1.18 overview_common.c
--- client/overview_common.c 31 Aug 2005 20:18:52 -0000 1.18
+++ client/overview_common.c 26 Sep 2005 22:19:32 -0000
@@ -112,7 +112,7 @@ static struct color *overview_tile_color
struct city *pcity = tile_get_city(ptile);
if (pcity) {
- if (pcity->owner == game.player_ptr) {
+ if (!game.player_ptr || pcity->owner == game.player_ptr) {
return get_color(tileset, COLOR_OVERVIEW_MY_CITY);
} else if (pplayers_allied(city_owner(pcity), game.player_ptr)) {
/* Includes teams. */
@@ -126,7 +126,7 @@ static struct color *overview_tile_color
struct unit *punit = find_visible_unit(ptile);
if (punit) {
- if (punit->owner == game.player_ptr) {
+ if (!game.player_ptr || punit->owner == game.player_ptr) {
return get_color(tileset, COLOR_OVERVIEW_MY_UNIT);
} else if (pplayers_allied(unit_owner(punit), game.player_ptr)) {
/* Includes teams. */
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.550
diff -p -u -r1.550 packhand.c
--- client/packhand.c 26 Sep 2005 22:03:09 -0000 1.550
+++ client/packhand.c 26 Sep 2005 22:19:32 -0000
@@ -600,15 +600,17 @@ static void handle_city_packet_common(st
}
if (popup
- && (!game.player_ptr->ai.control)
- && can_client_issue_orders()) {
+ && can_client_issue_orders()
+ && game.player_ptr
+ && !game.player_ptr->ai.control) {
update_menus();
if (!city_dialog_is_open(pcity)) {
popup_city_dialog(pcity);
}
}
- if (!is_new && (pcity->owner==game.player_ptr || popup)) {
+ if (!is_new
+ && (can_player_see_city_internals(game.player_ptr, pcity) || popup)) {
refresh_city_dialog(pcity);
}
@@ -774,14 +776,16 @@ void handle_new_year(int year, int turn)
#if 0
/* This information shouldn't be needed, but if it is this is the only
* way we can get it. */
- turn_gold_difference=game.player_ptr->economic.gold-last_turn_gold_amount;
- last_turn_gold_amount=game.player_ptr->economic.gold;
+ if (game.player_ptr) {
+ turn_gold_difference
+ = game.player_ptr->economic.gold - last_turn_gold_amount;
+ last_turn_gold_amount = game.player_ptr->economic.gold;
+ }
#endif
update_city_descriptions();
- if (sound_bell_at_new_turn &&
- (!game.player_ptr->ai.control || ai_manual_turn_done)) {
+ if (sound_bell_at_new_turn) {
create_event(NULL, E_TURN_BELL, _("Start of turn %d"), game.info.turn);
}
@@ -912,11 +916,6 @@ void handle_unit_info(struct packet_unit
{
struct unit *punit;
- if (packet->owner != game.info.player_idx) {
- freelog(LOG_ERROR, "Got packet_unit_info for unit of %s.",
- game.players[packet->owner].name);
- }
-
punit = unpackage_unit(packet);
if (handle_unit_packet_common(punit)) {
free(punit);
@@ -1001,6 +1000,7 @@ static bool handle_unit_packet_common(st
/* Wakeup Focus */
if (wakeup_focus
+ && game.player_ptr
&& !game.player_ptr->ai.control
&& punit->owner == game.player_ptr
&& punit->activity == ACTIVITY_SENTRY
@@ -1045,7 +1045,7 @@ static bool handle_unit_packet_common(st
punit->orders.list = packet_unit->orders.list;
packet_unit->orders.list = NULL;
- if (punit->owner == game.player_ptr) {
+ if (!game.player_ptr || punit->owner == game.player_ptr) {
refresh_unit_city_dialogs(punit);
}
} /*** End of Change in activity or activity's target. ***/
@@ -1149,7 +1149,8 @@ static bool handle_unit_packet_common(st
refresh_city_dialog(pcity);
if((unit_flag(punit, F_TRADE_ROUTE) || unit_flag(punit, F_HELP_WONDER))
- && (!game.player_ptr->ai.control)
+ && game.player_ptr
+ && !game.player_ptr->ai.control
&& punit->owner == game.player_ptr
&& !unit_has_orders(punit)
&& can_client_issue_orders()
@@ -1238,6 +1239,7 @@ static bool handle_unit_packet_common(st
}
if ((check_focus || get_unit_in_focus() == NULL)
+ && game.player_ptr
&& !game.player_ptr->ai.control
&& is_player_phase(game.player_ptr, game.info.phase)) {
update_unit_focus();
@@ -1322,6 +1324,10 @@ void handle_unit_short_info(struct packe
****************************************************************************/
void handle_map_info(int xsize, int ysize, int topology_id)
{
+ if (!map_is_empty()) {
+ map_free();
+ }
+
map.xsize = xsize;
map.ysize = ysize;
map.topology_id = topology_id;
@@ -1407,8 +1413,9 @@ static bool read_player_info_techs(struc
**************************************************************************/
void set_government_choice(struct government *government)
{
- if (government != game.player_ptr->government
- && can_client_issue_orders()) {
+ if (can_client_issue_orders()
+ && game.player_ptr
+ && government != game.player_ptr->government) {
dsend_packet_player_change_government(&aconnection, government->index);
}
}
@@ -1437,7 +1444,6 @@ void handle_player_info(struct packet_pl
sz_strlcpy(pplayer->name, pinfo->name);
- pplayer->is_observer = pinfo->is_observer;
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));
@@ -1514,7 +1520,7 @@ void handle_player_info(struct packet_pl
science_dialog_update();
}
if (poptechup) {
- if (!game.player_ptr->ai.control) {
+ if (game.player_ptr && !game.player_ptr->ai.control) {
popup_science_dialog(FALSE);
}
}
@@ -1919,21 +1925,23 @@ void handle_tile_info(struct packet_tile
if (old_known != packet->known) {
known_changed = TRUE;
}
- BV_CLR(ptile->tile_known, game.info.player_idx);
- BV_CLR(ptile->tile_seen, game.info.player_idx);
- switch (packet->known) {
- case TILE_KNOWN:
- BV_SET(ptile->tile_known, game.info.player_idx);
- BV_SET(ptile->tile_seen, game.info.player_idx);
- break;
- case TILE_KNOWN_FOGGED:
- BV_SET(ptile->tile_known, game.info.player_idx);
- break;
- case TILE_UNKNOWN:
- break;
- default:
- freelog(LOG_NORMAL, "Unknown tile value %d.", packet->known);
- break;
+ if (game.player_ptr) {
+ BV_CLR(ptile->tile_known, game.info.player_idx);
+ BV_CLR(ptile->tile_seen, game.info.player_idx);
+ switch (packet->known) {
+ case TILE_KNOWN:
+ BV_SET(ptile->tile_known, game.info.player_idx);
+ BV_SET(ptile->tile_seen, game.info.player_idx);
+ break;
+ case TILE_KNOWN_FOGGED:
+ BV_SET(ptile->tile_known, game.info.player_idx);
+ break;
+ case TILE_UNKNOWN:
+ break;
+ default:
+ freelog(LOG_NORMAL, "Unknown tile value %d.", packet->known);
+ break;
+ }
}
if (packet->spec_sprite[0] != '\0') {
@@ -2371,7 +2379,6 @@ void handle_ruleset_nation(struct packet
pl->city_style = p->city_style;
pl->is_playable = p->is_playable;
- pl->is_observer = p->is_observer;
pl->is_barbarian = p->is_barbarian;
memcpy(pl->init_techs, p->init_techs, sizeof(pl->init_techs));
@@ -2483,7 +2490,7 @@ void handle_unit_bribe_info(int unit_id,
if (punit) {
punit->bribe_cost = cost;
- if (!game.player_ptr->ai.control) {
+ if (game.player_ptr && !game.player_ptr->ai.control) {
popup_bribe_dialog(punit);
}
}
@@ -2498,7 +2505,7 @@ void handle_city_incite_info(int city_id
if (pcity) {
pcity->incite_revolt_cost = cost;
- if (!game.player_ptr->ai.control) {
+ if (game.player_ptr && !game.player_ptr->ai.control) {
popup_incite_dialog(pcity);
}
}
@@ -2532,7 +2539,7 @@ void handle_unit_diplomat_popup_dialog(i
struct unit *pdiplomat =
player_find_unit_by_id(game.player_ptr, diplomat_id);
- if (pdiplomat) {
+ if (pdiplomat && can_client_issue_orders()) {
process_diplomat_arrival(pdiplomat, target_id);
}
}
@@ -2546,7 +2553,7 @@ void handle_city_sabotage_list(int diplo
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) {
+ if (punit && pcity && can_client_issue_orders()) {
impr_type_iterate(i) {
pcity->improvements[i] = BV_ISSET(improvements, i) ? I_ACTIVE : I_NONE;
} impr_type_iterate_end;
@@ -2568,6 +2575,9 @@ void handle_endgame_report(struct packet
**************************************************************************/
void handle_player_attribute_chunk(struct packet_player_attribute_chunk
*packet)
{
+ if (!game.player_ptr) {
+ return;
+ }
generic_handle_player_attribute_chunk(game.player_ptr, packet);
if (packet->offset + packet->chunk_length == packet->total_length) {
Index: client/plrdlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/plrdlg_common.c,v
retrieving revision 1.23
diff -p -u -r1.23 plrdlg_common.c
--- client/plrdlg_common.c 18 Aug 2005 06:53:29 -0000 1.23
+++ client/plrdlg_common.c 26 Sep 2005 22:19:32 -0000
@@ -126,7 +126,7 @@ static const char *col_diplstate(const s
static char buf[100];
const struct player_diplstate *pds;
- if (player == game.player_ptr) {
+ if (!game.player_ptr || player == game.player_ptr) {
return "-";
} else {
pds = pplayer_get_diplstate(game.player_ptr, player);
@@ -145,7 +145,7 @@ static const char *col_diplstate(const s
*******************************************************************/
static const char *col_love(const struct player *player)
{
- if (player == game.player_ptr || !player->ai.control) {
+ if (!game.player_ptr || player == game.player_ptr || !player->ai.control) {
return "-";
} else {
return love_text(player->ai.love[game.player_ptr->player_no]);
@@ -159,6 +159,11 @@ static int cmp_love(const struct player
const struct player *player2)
{
int love1, love2;
+
+ if (!game.player_ptr) {
+ return player1->player_no - player2->player_no;
+ }
+
if (player1 == game.player_ptr || !player1->ai.control) {
love1 = MAX_AI_LOVE + 999;
} else {
Index: client/repodlgs_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/repodlgs_common.c,v
retrieving revision 1.29
diff -p -u -r1.29 repodlgs_common.c
--- client/repodlgs_common.c 18 Aug 2005 06:44:27 -0000 1.29
+++ client/repodlgs_common.c 26 Sep 2005 22:19:32 -0000
@@ -47,6 +47,10 @@ void get_economy_report_data(struct impr
*num_entries_used = 0;
*total_cost = 0;
+ if (!game.player_ptr) {
+ return;
+ }
+
impr_type_iterate(impr_id) {
if (is_improvement(impr_id)) {
int count = 0, cost = 0;
@@ -96,6 +100,13 @@ void get_economy_report_units_data(struc
{
int count, cost, partial_cost;
+ *num_entries_used = 0;
+ *total_cost = 0;
+
+ if (!game.player_ptr) {
+ return;
+ }
+
unit_type_iterate(unittype) {
cost = utype_upkeep_cost(unittype, game.player_ptr,
get_gov_pplayer(game.player_ptr), O_GOLD);
Index: client/reqtree.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/reqtree.c,v
retrieving revision 1.11
diff -p -u -r1.11 reqtree.c
--- client/reqtree.c 25 Sep 2005 14:06:02 -0000 1.11
+++ client/reqtree.c 26 Sep 2005 22:19:33 -0000
@@ -836,6 +836,11 @@ static enum color_std node_color(struct
{
if (!node->is_dummy) {
struct player_research* research = get_player_research(game.player_ptr);
+
+ if (!game.player_ptr || !research) {
+ return COLOR_REQTREE_KNOWN;
+ }
+
if (research->researching == node->tech) {
return COLOR_REQTREE_RESEARCHING;
}
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.53
diff -p -u -r1.53 text.c
--- client/text.c 15 Sep 2005 18:05:51 -0000 1.53
+++ client/text.c 26 Sep 2005 22:19:33 -0000
@@ -101,11 +101,16 @@ const char *popup_info_text(struct tile
}
if (game.info.borders > 0 && !pcity) {
struct player *owner = tile_get_owner(ptile);
- struct player_diplstate *ds = game.player_ptr->diplstates;
- if (owner == game.player_ptr){
+ if (game.player_ptr && owner == game.player_ptr){
astr_add_line(&str, _("Our Territory"));
+ } else if (owner && !game.player_ptr) {
+ /* TRANS: "Territory of the Polish" */
+ astr_add_line(&str, _("Territory of the %s"),
+ get_nation_name_plural(owner->nation));
} else if (owner) {
+ struct player_diplstate *ds = game.player_ptr->diplstates;
+
if (ds[owner->player_no].type == DS_CEASEFIRE) {
int turns = ds[owner->player_no].turns_left;
@@ -131,13 +136,14 @@ const char *popup_info_text(struct tile
/* Look at city owner, not tile owner (the two should be the same, if
* borders are in use). */
struct player *owner = city_owner(pcity);
- struct player_diplstate *ds = game.player_ptr->diplstates;
- if (owner == game.player_ptr){
+ if (!game.player_ptr || owner == game.player_ptr){
/* TRANS: "City: Warsaw (Polish)" */
astr_add_line(&str, _("City: %s (%s)"), pcity->name,
get_nation_name(owner->nation));
- } else if (owner) {
+ } else {
+ struct player_diplstate *ds = game.player_ptr->diplstates;
+
if (ds[owner->player_no].type == DS_CEASEFIRE) {
int turns = ds[owner->player_no].turns_left;
@@ -183,14 +189,13 @@ const char *popup_info_text(struct tile
}
if (punit && !pcity) {
struct player *owner = unit_owner(punit);
- struct player_diplstate *ds = game.player_ptr->diplstates;
struct unit_type *ptype = unit_type(punit);
- if (owner == game.player_ptr){
+ if (!game.player_ptr || owner == game.player_ptr){
struct city *pcity;
char tmp[64] = {0};
- pcity = player_find_city_by_id(game.player_ptr, punit->homecity);
+ pcity = player_find_city_by_id(owner, punit->homecity);
if (pcity) {
my_snprintf(tmp, sizeof(tmp), "/%s", pcity->name);
}
@@ -199,6 +204,10 @@ const char *popup_info_text(struct tile
get_nation_name(owner->nation),
tmp);
} else if (owner) {
+ struct player_diplstate *ds = game.player_ptr->diplstates;
+
+ assert(owner != NULL && game.player_ptr != NULL);
+
if (ds[owner->player_no].type == DS_CEASEFIRE) {
int turns = ds[owner->player_no].turns_left;
@@ -249,7 +258,7 @@ const char *popup_info_text(struct tile
ptype->hp,
_(ptype->veteran[punit->veteran].name));
- if (owner == game.player_ptr
+ if ((!game.player_ptr || owner == game.player_ptr)
&& unit_list_size(ptile->units) >= 2) {
/* TRANS: "5 more" units on this tile */
astr_add(&str, _(" (%d more)"), unit_list_size(ptile->units) - 1);
@@ -334,7 +343,7 @@ const char *unit_description(struct unit
{
int pcity_near_dist;
struct city *pcity =
- player_find_city_by_id(game.player_ptr, punit->homecity);
+ player_find_city_by_id(punit->owner, punit->homecity);
struct city *pcity_near = get_nearest_city(punit, &pcity_near_dist);
struct unit_type *ptype = unit_type(punit);
static struct astring str = ASTRING_INIT;
@@ -373,6 +382,10 @@ static int get_bulbs_per_turn(int *pours
struct player *plr = game.player_ptr;
int ours = 0, theirs = 0;
+ if (!game.player_ptr) {
+ return 0;
+ }
+
/* Sum up science */
players_iterate(pplayer) {
enum diplstate_type ds = pplayer_get_diplstate(plr, pplayer)->type;
@@ -409,9 +422,8 @@ const char *science_dialog_text(void)
get_bulbs_per_turn(&ours, &theirs);
- if (ours == 0 && theirs == 0) {
- astr_add(&str, _("Progress: no research"));
- return str.str;
+ if (!game.player_ptr || (ours == 0 && theirs == 0)) {
+ return _("Progress: no research");
}
assert(ours >= 0 && theirs >= 0);
if (get_player_research(plr)->researching == A_UNSET) {
@@ -451,6 +463,10 @@ const char *get_science_target_text(doub
struct player_research *research = get_player_research(game.player_ptr);
static struct astring str = ASTRING_INIT;
+ if (!game.player_ptr) {
+ return "-";
+ }
+
astr_clear(&str);
if (research->researching == A_UNSET) {
astr_add(&str, _("%d/- (never)"), research->bulbs_researched);
@@ -492,6 +508,10 @@ const char *get_science_goal_text(Tech_t
struct player_research* research = get_player_research(game.player_ptr);
static struct astring str = ASTRING_INIT;
+ if (!game.player_ptr) {
+ return "-";
+ }
+
astr_clear(&str);
if (is_tech_a_req_for_goal(game.player_ptr,
@@ -561,21 +581,25 @@ const char *get_info_label_text_popup(vo
astr_clear(&str);
- astr_add_line(&str, _("%s People"),
- population_to_text(civ_population(game.player_ptr)));
+ if (game.player_ptr) {
+ astr_add_line(&str, _("%s People"),
+ population_to_text(civ_population(game.player_ptr)));
+ }
astr_add_line(&str, _("Year: %s"), textyear(game.info.year));
astr_add_line(&str, _("Turn: %d"), game.info.turn);
- astr_add_line(&str, _("Gold: %d"), game.player_ptr->economic.gold);
- astr_add_line(&str, _("Net Income: %d"),
- player_get_expected_income(game.player_ptr));
- /* TRANS: Gold, luxury, and science rates are in percentage values. */
- astr_add_line(&str, _("Tax rates: Gold:%d%% Luxury:%d%% Science:%d%%"),
- game.player_ptr->economic.tax,
- game.player_ptr->economic.luxury,
- game.player_ptr->economic.science);
- astr_add_line(&str, _("Researching %s: %s"),
- get_tech_name(game.player_ptr, research->researching),
- get_science_target_text(NULL));
+ if (game.player_ptr) {
+ astr_add_line(&str, _("Gold: %d"), game.player_ptr->economic.gold);
+ astr_add_line(&str, _("Net Income: %d"),
+ player_get_expected_income(game.player_ptr));
+ /* TRANS: Gold, luxury, and science rates are in percentage values. */
+ astr_add_line(&str, _("Tax rates: Gold:%d%% Luxury:%d%% Science:%d%%"),
+ game.player_ptr->economic.tax,
+ game.player_ptr->economic.luxury,
+ game.player_ptr->economic.science);
+ astr_add_line(&str, _("Researching %s: %s"),
+ get_tech_name(game.player_ptr, research->researching),
+ get_science_target_text(NULL));
+ }
/* These mirror the code in get_global_warming_tooltip and
* get_nuclear_winter_tooltip. */
@@ -586,8 +610,10 @@ const char *get_info_label_text_popup(vo
CLIP(0, (game.info.nuclearwinter + 1) / 2, 100),
DIVIDE(game.info.cooling - game.info.coolinglevel + 1, 2));
- astr_add_line(&str, _("Government: %s"),
- get_government_name(game.player_ptr->government));
+ if (game.player_ptr) {
+ astr_add_line(&str, _("Government: %s"),
+ get_government_name(game.player_ptr->government));
+ }
return str.str;
}
@@ -626,7 +652,7 @@ const char *get_unit_info_label_text2(st
* GUI widgets may be confused and try to resize themselves. */
if (punit) {
struct city *pcity =
- player_find_city_by_id(game.player_ptr, punit->homecity);
+ player_find_city_by_id(punit->owner, punit->homecity);
int infracount;
bv_special infrastructure =
get_tile_infrastructure_set(punit->tile, &infracount);
@@ -877,7 +903,9 @@ const char *get_score_text(const struct
astr_clear(&str);
- if (pplayer->score.game > 0 || pplayer == game.player_ptr) {
+ if (pplayer->score.game > 0
+ || !game.player_ptr
+ || pplayer == game.player_ptr) {
astr_add(&str, "%d", pplayer->score.game);
} else {
astr_add(&str, "?");
@@ -899,17 +927,23 @@ const char *get_report_title(const char
astr_add_line(&str, "%s", report_name);
- /* TRANS: "Republic of the Polish" */
- astr_add_line(&str, _("%s of the %s"),
- get_government_name(game.player_ptr->government),
- get_nation_name_plural(game.player_ptr->nation));
-
- astr_add_line(&str, "%s %s: %s",
- get_ruler_title(game.player_ptr->government,
- game.player_ptr->is_male,
- game.player_ptr->nation),
- game.player_ptr->name,
- textyear(game.info.year));
+ if (game.player_ptr) {
+ /* TRANS: "Republic of the Polish" */
+ astr_add_line(&str, _("%s of the %s"),
+ get_government_name(game.player_ptr->government),
+ get_nation_name_plural(game.player_ptr->nation));
+
+ astr_add_line(&str, "%s %s: %s",
+ get_ruler_title(game.player_ptr->government,
+ game.player_ptr->is_male,
+ game.player_ptr->nation),
+ game.player_ptr->name,
+ textyear(game.info.year));
+ } else {
+ /* TRANS: "Observer: 1985" */
+ astr_add_line(&str, _("Observer: %s"),
+ textyear(game.info.year));
+ }
return str.str;
}
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.324
diff -p -u -r1.324 tilespec.c
--- client/tilespec.c 22 Sep 2005 04:50:51 -0000 1.324
+++ client/tilespec.c 26 Sep 2005 22:19:34 -0000
@@ -3643,8 +3643,10 @@ static int fill_grid_sprite_array(const
&& base_map_to_city_map(&dummy_x, &dummy_y, pfocus->tile, tile);
worked[i] = FALSE;
- city[i] = tile && (powner == NULL || powner == game.player_ptr)
- && player_in_city_radius(game.player_ptr, tile);
+ city[i] = (tile
+ && (!powner || !game.player_ptr || powner == game.player_ptr)
+ && (!game.player_ptr
+ || player_in_city_radius(game.player_ptr, tile)));
if (city[i]) {
if (citymode) {
int cx, cy;
@@ -4252,7 +4254,7 @@ struct unit *get_drawable_unit(const str
if (!punit)
return NULL;
- if (citymode && punit->owner == game.player_ptr)
+ if (citymode && punit->owner == citymode->owner)
return NULL;
if (punit != pfocus
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.140
diff -p -u -r1.140 citydlg.c
--- client/gui-gtk-2.0/citydlg.c 8 Aug 2005 16:15:29 -0000 1.140
+++ client/gui-gtk-2.0/citydlg.c 26 Sep 2005 22:19:35 -0000
@@ -375,7 +375,7 @@ void refresh_city_dialog(struct city *pc
city_dialog_update_supported_units(pdialog);
city_dialog_update_present_units(pdialog);
- if (city_owner(pcity) == game.player_ptr) {
+ if (!game.player_ptr || city_owner(pcity) == game.player_ptr) {
bool have_present_units =
(unit_list_size(pcity->tile->units) > 0);
refresh_worklist(pdialog->production.worklist);
@@ -870,7 +870,7 @@ target_drag_data_received(GtkWidget *w,
GtkTreeModel *model;
GtkTreePath *path;
- if (pdialog->pcity->owner != game.player_ptr) {
+ if (game.player_ptr && pdialog->pcity->owner != game.player_ptr) {
gtk_drag_finish(context, FALSE, FALSE, time);
}
@@ -1224,7 +1224,7 @@ static struct city_dialog *create_city_d
create_and_append_worklist_page(pdialog);
/* only create these tabs if not a spy */
- if (pcity->owner == game.player_ptr) {
+ if (!game.player_ptr || pcity->owner == game.player_ptr) {
create_and_append_happiness_page(pdialog);
create_and_append_cma_page(pdialog);
}
@@ -1263,7 +1263,7 @@ static struct city_dialog *create_city_d
gtk_dialog_add_action_widget(GTK_DIALOG(pdialog->shell),
pdialog->next_command, 2);
- if (pcity->owner != game.player_ptr) {
+ if (!game.player_ptr || pcity->owner != game.player_ptr) {
gtk_widget_set_sensitive(pdialog->prev_command, FALSE);
gtk_widget_set_sensitive(pdialog->next_command, FALSE);
}
@@ -1633,7 +1633,7 @@ static void city_dialog_update_supported
int n, m, i;
char buf[30];
- if (pdialog->pcity->owner != game.player_ptr) {
+ if (game.player_ptr && pdialog->pcity->owner != game.player_ptr) {
units = pdialog->pcity->info_units_supported;
} else {
units = pdialog->pcity->units_supported;
@@ -1752,7 +1752,7 @@ static void city_dialog_update_present_u
int n, m, i;
char buf[30];
- if (pdialog->pcity->owner != game.player_ptr) {
+ if (game.player_ptr && pdialog->pcity->owner != game.player_ptr) {
units = pdialog->pcity->info_units_present;
} else {
units = pdialog->pcity->tile->units;
@@ -1866,7 +1866,13 @@ static void city_dialog_update_present_u
static void city_dialog_update_prev_next()
{
int count = 0;
- int city_number = city_list_size(game.player_ptr->cities);
+ int city_number;
+
+ if (game.player_ptr) {
+ city_number = city_list_size(game.player_ptr->cities);
+ } else {
+ city_number = FC_INFINITY; /* ? */
+ }
/* the first time, we see if all the city dialogs are open */
@@ -2105,7 +2111,8 @@ static gboolean present_unit_callback(Gt
GINT_TO_POINTER(punit->id));
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
- if (can_upgrade_unittype(game.player_ptr, punit->type) == NULL) {
+ if (!can_client_issue_orders()
+ || can_upgrade_unittype(game.player_ptr, punit->type) == NULL) {
gtk_widget_set_sensitive(item, FALSE);
}
@@ -2411,12 +2418,14 @@ static void buy_callback_response(GtkWid
*****************************************************************/
static void buy_callback(GtkWidget *w, gpointer data)
{
- struct city_dialog *pdialog;
+ struct city_dialog *pdialog = data;
int value;
const char *name;
GtkWidget *shell;
- pdialog = (struct city_dialog *) data;
+ if (!can_client_issue_orders()) {
+ return;
+ }
if (pdialog->pcity->production.is_unit) {
name = get_unit_type(pdialog->pcity->production.value)->name;
@@ -2718,10 +2727,8 @@ static void city_destroy_callback(GtkWid
gtk_widget_hide(pdialog->shell);
- if (pdialog->pcity->owner == game.player_ptr) {
- close_happiness_dialog(pdialog->pcity);
- close_cma_dialog(pdialog->pcity);
- }
+ close_happiness_dialog(pdialog->pcity);
+ close_cma_dialog(pdialog->pcity);
citydialog_height = pdialog->shell->allocation.height;
citydialog_width = pdialog->shell->allocation.width;
@@ -2787,9 +2794,14 @@ static void close_city_dialog(struct cit
static void switch_city_callback(GtkWidget *w, gpointer data)
{
struct city_dialog *pdialog = (struct city_dialog *) data;
- int i, j, dir, size = city_list_size(game.player_ptr->cities);
+ int i, j, dir, size;
struct city *new_pcity = NULL;
+ if (!game.player_ptr) {
+ return;
+ }
+ size = city_list_size(game.player_ptr->cities);
+
assert(city_dialogs_have_been_initialised);
assert(size >= 1);
assert(pdialog->pcity->owner == game.player_ptr);
Index: client/gui-gtk-2.0/cityrep.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/cityrep.c,v
retrieving revision 1.79
diff -p -u -r1.79 cityrep.c
--- client/gui-gtk-2.0/cityrep.c 8 Aug 2005 16:15:29 -0000 1.79
+++ client/gui-gtk-2.0/cityrep.c 26 Sep 2005 22:19:35 -0000
@@ -535,6 +535,9 @@ static void append_cma_to_menu_item(GtkM
GtkWidget *w;
gtk_menu_item_remove_submenu(parent_item);
+ if (!can_client_issue_orders()) {
+ return;
+ }
menu = gtk_menu_new();
gtk_menu_item_set_submenu(parent_item, menu);
@@ -1099,8 +1102,7 @@ static void update_row(GtkTreeIter *row,
*****************************************************************/
static void city_model_init(void)
{
- if (city_dialog_shell && !is_report_dialogs_frozen()) {
-
+ if (city_dialog_shell && !is_report_dialogs_frozen() && game.player_ptr) {
city_list_iterate(game.player_ptr->cities, pcity) {
GtkTreeIter it;
@@ -1138,14 +1140,16 @@ void city_report_dialog_update(void)
/* update. */
gtk_list_store_clear(city_model);
- city_list_iterate(game.player_ptr->cities, pcity) {
- gtk_list_store_append(city_model, &it);
- update_row(&it, pcity);
+ if (game.player_ptr) {
+ city_list_iterate(game.player_ptr->cities, pcity) {
+ gtk_list_store_append(city_model, &it);
+ update_row(&it, pcity);
- if (g_hash_table_remove(copy, pcity)) {
- gtk_tree_selection_select_iter(city_selection, &it);
- }
- } city_list_iterate_end;
+ if (g_hash_table_remove(copy, pcity)) {
+ gtk_tree_selection_select_iter(city_selection, &it);
+ }
+ } city_list_iterate_end;
+ }
/* free the selection. */
g_hash_table_destroy(copy);
Index: client/gui-gtk-2.0/diplodlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/diplodlg.c,v
retrieving revision 1.35
diff -p -u -r1.35 diplodlg.c
--- client/gui-gtk-2.0/diplodlg.c 16 Sep 2005 06:59:54 -0000 1.35
+++ client/gui-gtk-2.0/diplodlg.c 26 Sep 2005 22:19:35 -0000
@@ -20,28 +20,30 @@
#include <gtk/gtk.h>
+#include "mem.h"
+#include "shared.h"
+#include "support.h"
+
+#include "diptreaty.h"
#include "fcintl.h"
#include "game.h"
#include "government.h"
#include "map.h"
-#include "mem.h"
#include "packets.h"
#include "player.h"
-#include "shared.h"
-#include "support.h"
#include "chatline.h"
+#include "civclient.h"
#include "climisc.h"
#include "clinet.h"
-#include "diptreaty.h"
+#include "options.h"
+
+#include "diplodlg.h"
#include "gui_main.h"
#include "gui_stuff.h"
#include "mapview.h"
-#include "options.h"
#include "plrdlg.h"
-#include "diplodlg.h"
-
#define MAX_NUM_CLAUSES 64
struct Diplomacy_dialog {
@@ -170,6 +172,10 @@ static void popup_diplomacy_dialog(int o
{
struct Diplomacy_dialog *pdialog = find_diplomacy_dialog(other_player_id);
+ if (!can_client_issue_orders()) {
+ return;
+ }
+
if (game.player_ptr->ai.control) {
return; /* Don't show if we are AI controlled. */
}
Index: client/gui-gtk-2.0/gamedlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gamedlgs.c,v
retrieving revision 1.30
diff -p -u -r1.30 gamedlgs.c
--- client/gui-gtk-2.0/gamedlgs.c 2 May 2005 08:45:19 -0000 1.30
+++ client/gui-gtk-2.0/gamedlgs.c 26 Sep 2005 22:19:35 -0000
@@ -22,23 +22,25 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include "shared.h"
+#include "support.h"
+
#include "events.h"
#include "fcintl.h"
#include "game.h"
#include "government.h"
#include "packets.h"
#include "player.h"
-#include "shared.h"
-#include "support.h"
+
+#include "civclient.h"
+#include "clinet.h"
+#include "options.h"
#include "chatline.h"
#include "cityrep.h"
#include "dialogs.h"
-#include "clinet.h"
#include "gui_main.h"
#include "gui_stuff.h"
-#include "options.h"
-
#include "ratesdlg.h"
#include "optiondlg.h"
@@ -73,7 +75,11 @@ static void rates_set_values(int tax, in
lux_lock = GTK_TOGGLE_BUTTON(rates_lux_toggle)->active;
sci_lock = GTK_TOGGLE_BUTTON(rates_sci_toggle)->active;
- maxrate = get_player_bonus(game.player_ptr, EFT_MAX_RATES);
+ if (game.player_ptr) {
+ maxrate = get_player_bonus(game.player_ptr, EFT_MAX_RATES);
+ } else {
+ maxrate = 100;
+ }
/* This's quite a simple-minded "double check".. */
tax=MIN(tax, maxrate);
lux=MIN(lux, maxrate);
@@ -213,6 +219,10 @@ static GtkWidget *create_rates_dialog(vo
GtkWidget *frame, *hbox;
GtkWidget *scale;
+
+ if (!can_client_issue_orders()) {
+ return NULL;
+ }
shell = gtk_dialog_new_with_buttons(_("Select tax, luxury and science
rates"),
NULL,
@@ -330,8 +340,16 @@ void popup_rates_dialog(void)
{
char buf[64];
- if (!rates_dialog_shell)
+ if (!can_client_issue_orders()) {
+ return;
+ }
+
+ if (!rates_dialog_shell) {
rates_dialog_shell = create_rates_dialog();
+ }
+ if (!rates_dialog_shell) {
+ return;
+ }
my_snprintf(buf, sizeof(buf), _("%s max rate: %d%%"),
get_government_name(game.player_ptr->government),
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.137
diff -p -u -r1.137 gui_main.c
--- client/gui-gtk-2.0/gui_main.c 29 Aug 2005 13:56:49 -0000 1.137
+++ client/gui-gtk-2.0/gui_main.c 26 Sep 2005 22:19:35 -0000
@@ -384,7 +384,7 @@ static gboolean keyboard_handler(GtkWidg
return TRUE;
}
- if (!client_is_observer()) {
+ if (!client_is_observer()) { /* FIXME: is this check right? */
if ((ev->state & GDK_SHIFT_MASK)) {
switch (ev->keyval) {
case GDK_Left:
@@ -1260,9 +1260,6 @@ void update_conn_list_dialog(void)
players_iterate(pplayer) {
enum cmdlevel_id access_level = ALLOW_NONE;
- if (pplayer->is_observer) {
- continue; /* Connections are listed individually. */
- }
conn_list_iterate(pplayer->connections, pconn) {
access_level = MAX(pconn->access_level, access_level);
} conn_list_iterate_end;
@@ -1309,7 +1306,7 @@ void update_conn_list_dialog(void)
-1);
} players_iterate_end;
conn_list_iterate(game.est_connections, pconn) {
- if (pconn->player && !pconn->observer && !pconn->player->is_observer) {
+ if (pconn->player && !pconn->observer) {
continue; /* Already listed above. */
}
sz_strlcpy(name, pconn->username);
Index: client/gui-gtk-2.0/happiness.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/happiness.c,v
retrieving revision 1.23
diff -p -u -r1.23 happiness.c
--- client/gui-gtk-2.0/happiness.c 4 Jul 2005 17:48:37 -0000 1.23
+++ client/gui-gtk-2.0/happiness.c 26 Sep 2005 22:19:35 -0000
@@ -224,8 +224,8 @@ static void happiness_dialog_update_citi
int cities = city_list_size(pplayer->cities);
int content = game.info.unhappysize;
int basis = game.info.cityfactor
- + get_player_bonus(game.player_ptr, EFT_EMPIRE_SIZE_MOD);
- int step = get_player_bonus(game.player_ptr, EFT_EMPIRE_SIZE_STEP);
+ + get_player_bonus(pcity->owner, EFT_EMPIRE_SIZE_MOD);
+ int step = get_player_bonus(pcity->owner, EFT_EMPIRE_SIZE_STEP);
int excess = cities - basis;
int penalty = 0;
Index: client/gui-gtk-2.0/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/menu.c,v
retrieving revision 1.84
diff -p -u -r1.84 menu.c
--- client/gui-gtk-2.0/menu.c 18 Aug 2005 06:44:27 -0000 1.84
+++ client/gui-gtk-2.0/menu.c 26 Sep 2005 22:19:36 -0000
@@ -553,8 +553,10 @@ static void reports_menu_callback(gpoint
case MENU_REPORT_DEMOGRAPHIC:
send_report_request(REPORT_DEMOGRAPHIC);
break;
- case MENU_REPORT_SPACESHIP:
- popup_spaceship_dialog(game.player_ptr);
+ case MENU_REPORT_SPACESHIP:
+ if (game.player_ptr) {
+ popup_spaceship_dialog(game.player_ptr);
+ }
break;
}
}
@@ -1246,7 +1248,8 @@ void update_menus(void)
can_client_issue_orders());
menus_set_sensitive("<main>/_Reports/S_paceship",
- (game.player_ptr->spaceship.state!=SSHIP_NONE));
+ (game.player_ptr
+ && game.player_ptr->spaceship.state != SSHIP_NONE));
menus_set_active("<main>/_View/City Outlines", draw_city_outlines);
menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
@@ -1385,7 +1388,7 @@ void update_menus(void)
get_tile_change_menu_text(punit->tile,
ACTIVITY_IRRIGATE));
} else if (tile_has_special(punit->tile, S_IRRIGATION)
- && player_knows_techs_with_flag(game.player_ptr,
+ && player_knows_techs_with_flag(punit->owner,
TF_FARMLAND)) {
sz_strlcpy(irrtext, _("Bu_ild Farmland"));
}
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.42
diff -p -u -r1.42 pages.c
--- client/gui-gtk-2.0/pages.c 26 Sep 2005 18:59:11 -0000 1.42
+++ client/gui-gtk-2.0/pages.c 26 Sep 2005 22:19:36 -0000
@@ -942,7 +942,9 @@ static void start_start_callback(GtkWidg
**************************************************************************/
static void pick_nation_callback(GtkWidget *w, gpointer data)
{
- popup_races_dialog(game.player_ptr);
+ if (game.player_ptr) {
+ popup_races_dialog(game.player_ptr);
+ }
}
/**************************************************************************
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.68
diff -p -u -r1.68 plrdlg.c
--- client/gui-gtk-2.0/plrdlg.c 1 Aug 2005 06:44:44 -0000 1.68
+++ client/gui-gtk-2.0/plrdlg.c 26 Sep 2005 22:19:36 -0000
@@ -146,15 +146,20 @@ static void update_players_menu(void)
gtk_widget_set_sensitive(players_sship_command, FALSE);
}
- switch (pplayer_get_diplstate(game.player_ptr, get_player(plrno))->type) {
- case DS_WAR:
- case DS_NO_CONTACT:
+ if (game.player_ptr) {
+ switch (pplayer_get_diplstate(game.player_ptr,
+ get_player(plrno))->type) {
+ case DS_WAR:
+ case DS_NO_CONTACT:
+ gtk_widget_set_sensitive(players_war_command, FALSE);
+ break;
+ default:
+ gtk_widget_set_sensitive(players_war_command,
+ can_client_issue_orders()
+ && game.info.player_idx != plrno);
+ }
+ } else {
gtk_widget_set_sensitive(players_war_command, FALSE);
- break;
- default:
- gtk_widget_set_sensitive(players_war_command,
- can_client_issue_orders()
- && game.info.player_idx != plrno);
}
gtk_widget_set_sensitive(players_vision_command,
@@ -576,7 +581,7 @@ static void build_row(GtkTreeIter *it, i
{
struct player *plr = get_player(i);
GdkPixbuf *pixbuf;
- gint style, weight;
+ gint style = PANGO_STYLE_NORMAL, weight = PANGO_WEIGHT_NORMAL;
int k;
gchar *p;
@@ -610,21 +615,29 @@ static void build_row(GtkTreeIter *it, i
-1);
/* now add some eye candy ... */
- switch (pplayer_get_diplstate(game.player_ptr, plr)->type) {
- case DS_WAR:
- weight = PANGO_WEIGHT_NORMAL;
- style = PANGO_STYLE_ITALIC;
- break;
- case DS_ALLIANCE:
- case DS_TEAM:
- weight = PANGO_WEIGHT_BOLD;
- style = PANGO_STYLE_NORMAL;
- break;
- default:
- weight = PANGO_WEIGHT_NORMAL;
- style = PANGO_STYLE_NORMAL;
- break;
- }
+ if (game.player_ptr) {
+ switch (pplayer_get_diplstate(game.player_ptr, plr)->type) {
+ case DS_WAR:
+ weight = PANGO_WEIGHT_NORMAL;
+ style = PANGO_STYLE_ITALIC;
+ break;
+ case DS_ALLIANCE:
+ case DS_TEAM:
+ weight = PANGO_WEIGHT_BOLD;
+ style = PANGO_STYLE_NORMAL;
+ break;
+ case DS_NEUTRAL:
+ case DS_CEASEFIRE:
+ case DS_PEACE:
+ case DS_NO_CONTACT:
+ weight = PANGO_WEIGHT_NORMAL;
+ style = PANGO_STYLE_NORMAL;
+ break;
+ case DS_LAST:
+ assert(0);
+ break;
+ }
+ }
gtk_list_store_set(store, it,
num_player_dlg_columns, style,
num_player_dlg_columns + 1, weight,
Index: client/gui-gtk-2.0/repodlgs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/repodlgs.c,v
retrieving revision 1.97
diff -p -u -r1.97 repodlgs.c
--- client/gui-gtk-2.0/repodlgs.c 16 Aug 2005 06:54:53 -0000 1.97
+++ client/gui-gtk-2.0/repodlgs.c 26 Sep 2005 22:19:38 -0000
@@ -145,7 +145,8 @@ void popup_science_dialog(bool raise)
create_science_dialog(FALSE);
}
- if (get_player_research(game.player_ptr)->tech_goal == A_UNSET
+ if (can_client_issue_orders()
+ && get_player_research(game.player_ptr)->tech_goal == A_UNSET
&& get_player_research(game.player_ptr)->researching == A_UNSET) {
gui_dialog_alert(science_dialog_shell);
} else {
@@ -182,7 +183,7 @@ static void button_release_event_callbac
if (tech == A_NONE) {
return;
}
- if (event->button == 1) {
+ if (event->button == 1 && can_client_issue_orders()) {
/* LMB: set research or research goal */
switch (get_invention(game.player_ptr, tech)) {
case TECH_REACHABLE:
@@ -227,6 +228,7 @@ static GtkWidget *create_reqtree_diagram
GtkAdjustment* adjustment;
int width, height;
int x;
+ Tech_type_id researching;
get_reqtree_dimensions(reqtree, &width, &height);
@@ -252,8 +254,12 @@ static GtkWidget *create_reqtree_diagram
adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(sw));
/* Center on currently researched node */
- if (find_tech_on_reqtree(reqtree,
- get_player_research(game.player_ptr)->researching,
+ if (game.player_ptr) {
+ researching = get_player_research(game.player_ptr)->researching;
+ } else {
+ researching = A_UNSET;
+ }
+ if (find_tech_on_reqtree(reqtree, researching,
&x, NULL, NULL, NULL)) {
/* FIXME: this is just an approximation */
gtk_adjustment_set_value(adjustment, x - 100);
@@ -397,26 +403,10 @@ void science_goal_callback(GtkWidget *wi
static gint cmp_func(gconstpointer a_p, gconstpointer b_p)
{
const gchar *a_str, *b_str;
- gchar text_a[512], text_b[512];
gint a = GPOINTER_TO_INT(a_p), b = GPOINTER_TO_INT(b_p);
- /* FIXME: future techs aren't counted this way but are handled by
- * get_tech_name() when given a player parameter. */
- if (!is_future_tech(a)) {
- a_str = get_tech_name(game.player_ptr, a);
- } else {
- my_snprintf(text_a,sizeof(text_a), _("Future Tech. %d"),
- a - game.control.num_tech_types);
- a_str=text_a;
- }
-
- if(!is_future_tech(b)) {
- b_str = get_tech_name(game.player_ptr, b);
- } else {
- my_snprintf(text_b,sizeof(text_b), _("Future Tech. %d"),
- b - game.control.num_tech_types);
- b_str=text_b;
- }
+ a_str = get_tech_name(game.player_ptr, a);
+ b_str = get_tech_name(game.player_ptr, b);
return strcmp(a_str,b_str);
}
@@ -434,7 +424,7 @@ void science_dialog_update(void)
GtkSizeGroup *group1, *group2;
struct player_research *research = get_player_research(game.player_ptr);
- if (is_report_dialogs_frozen()) {
+ if (!game.player_ptr || !research || is_report_dialogs_frozen()) {
return;
}
@@ -1069,14 +1059,10 @@ static void activeunits_selection_callba
ACTIVEUNITS_NEAREST,
can_client_issue_orders());
- if (can_upgrade_unittype(game.player_ptr, utype) != NULL) {
- gui_dialog_set_response_sensitive(activeunits_dialog_shell,
- ACTIVEUNITS_UPGRADE,
- can_client_issue_orders());
- } else {
- gui_dialog_set_response_sensitive(activeunits_dialog_shell,
- ACTIVEUNITS_UPGRADE, FALSE);
- }
+ gui_dialog_set_response_sensitive(activeunits_dialog_shell,
+ ACTIVEUNITS_UPGRADE,
+ (can_client_issue_orders()
+ && can_upgrade_unittype(game.player_ptr, utype) != NULL));
}
}
@@ -1087,9 +1073,12 @@ static struct unit *find_nearest_unit(co
struct tile *ptile)
{
struct unit *best_candidate;
- int best_dist = 99999;
+ int best_dist = FC_INFINITY;
best_candidate = NULL;
+ if (!game.player_ptr) {
+ return NULL;
+ }
unit_list_iterate(game.player_ptr->units, punit) {
if (punit->type == type) {
if (punit->focus_status==FOCUS_AVAIL
@@ -1153,7 +1142,7 @@ static void activeunits_command_callback
}
}
}
- } else {
+ } else if (can_client_issue_orders()) {
GtkWidget *shell;
struct unit_type *ut2 = can_upgrade_unittype(game.player_ptr, utype1);
@@ -1189,10 +1178,12 @@ void activeunits_report_dialog_update(vo
int building_count;
};
- if (is_report_dialogs_frozen())
+ if (is_report_dialogs_frozen() || !activeunits_dialog_shell) {
return;
+ }
- if (activeunits_dialog_shell) {
+ gtk_list_store_clear(activeunits_store);
+ if (game.player_ptr) {
int k, can;
struct repoinfo unitarray[U_LAST];
struct repoinfo unittotals;
Index: client/gui-gtk-2.0/wldlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/wldlg.c,v
retrieving revision 1.52
diff -p -u -r1.52 wldlg.c
--- client/gui-gtk-2.0/wldlg.c 8 Aug 2005 16:15:29 -0000 1.52
+++ client/gui-gtk-2.0/wldlg.c 26 Sep 2005 22:19:38 -0000
@@ -117,7 +117,11 @@ void update_worklist_report_dialog(void)
plr = game.player_ptr;
gtk_list_store_clear(worklists_store);
-
+
+ if (!game.player_ptr) {
+ return;
+ }
+
for (i = 0; i < MAX_NUM_WORKLISTS; i++) {
if (plr->worklists[i].is_valid) {
gtk_list_store_append(worklists_store, &it);
@@ -143,6 +147,10 @@ static void worklists_response(GtkWidget
plr = game.player_ptr;
+ if (!game.player_ptr) {
+ return;
+ }
+
for (i = 0; i < MAX_NUM_WORKLISTS; i++) {
if (!plr->worklists[i].is_valid) {
break;
@@ -209,13 +217,12 @@ static void cell_edited(GtkCellRendererT
GtkTreePath *path;
GtkTreeIter it;
int pos;
- struct player *plr;
+ struct player *plr = game.player_ptr;
path = gtk_tree_path_new_from_string(spath);
gtk_tree_model_get_iter(GTK_TREE_MODEL(worklists_store), &it, path);
gtk_tree_model_get(GTK_TREE_MODEL(worklists_store), &it, 1, &pos, -1);
- plr = game.player_ptr;
sz_strlcpy(plr->worklists[pos].name, text);
gtk_list_store_set(worklists_store, &it, 0, text, -1);
@@ -473,6 +480,10 @@ static void menu_item_callback(GtkMenuIt
gint pos;
struct worklist *pwl;
+ if (!game.player_ptr) {
+ return;
+ }
+
plr = game.player_ptr;
pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(item), "pos"));
@@ -508,6 +519,10 @@ static void popup_add_menu(GtkMenuShell
(GtkCallback) gtk_widget_destroy, NULL);
plr = game.player_ptr;
+ if (!game.player_ptr) {
+ return;
+ }
+
for (i = 0; i < MAX_NUM_WORKLISTS; i++) {
if (plr->worklists[i].is_valid) {
item = gtk_menu_item_new_with_label(plr->worklists[i].name);
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.200
diff -p -u -r1.200 game.h
--- common/game.h 26 Sep 2005 18:59:11 -0000 1.200
+++ common/game.h 26 Sep 2005 22:19:38 -0000
@@ -70,7 +70,7 @@ struct civ_game {
* take effect until the next turn. */
bool simultaneous_phases_stored;
char *startmessage;
- struct player *player_ptr;
+ struct player *player_ptr; /* Client-only; may be NULL */
struct player players[MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS];
struct conn_list *all_connections; /* including not yet established */
struct conn_list *est_connections; /* all established client conns */
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.61
diff -p -u -r1.61 government.c
--- common/government.c 18 Aug 2005 06:44:28 -0000 1.61
+++ common/government.c 26 Sep 2005 22:19:38 -0000
@@ -137,12 +137,17 @@ const char *get_government_name(const st
- no required tech (required is A_NONE)
- player has required tech
- we have an appropriate wonder
+ Returns FALSE if pplayer is NULL (used for observers).
***************************************************************/
bool can_change_to_government(struct player *pplayer,
const struct government *gov)
{
CHECK_GOVERNMENT(gov);
+ if (!pplayer) {
+ return FALSE;
+ }
+
if (get_player_bonus(pplayer, EFT_ANY_GOVERNMENT) > 0) {
/* Note, this may allow govs that are on someone else's "tech tree". */
return TRUE;
Index: common/nation.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.c,v
retrieving revision 1.57
diff -p -u -r1.57 nation.c
--- common/nation.c 21 Sep 2005 06:45:24 -0000 1.57
+++ common/nation.c 26 Sep 2005 22:19:38 -0000
@@ -124,20 +124,6 @@ bool is_nation_playable(const struct nat
}
/****************************************************************************
- Return whether a nation is usable as an observer. If true then observers
- can use this nation.
-
- This does not check whether a nation is "used" or "available".
-****************************************************************************/
-bool is_nation_observer(const struct nation_type *nation)
-{
- if (!bounds_check_nation(nation, LOG_FATAL, "is_nation_observer")) {
- die("wrong nation %d", nation->index);
- }
- return nation->is_observer;
-}
-
-/****************************************************************************
Return whether a nation is usable as a barbarian. If true then barbarians
can use this nation.
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.57
diff -p -u -r1.57 nation.h
--- common/nation.h 21 Sep 2005 06:45:24 -0000 1.57
+++ common/nation.h 26 Sep 2005 22:19:38 -0000
@@ -77,7 +77,7 @@ struct nation_type {
struct city_name *city_names; /* The default city names. */
char *legend; /* may be empty */
- bool is_playable, is_barbarian, is_observer;
+ bool is_playable, is_barbarian;
/* 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
@@ -116,7 +116,6 @@ const char *get_nation_name(const struct
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);
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.158
diff -p -u -r1.158 packets.def
--- common/packets.def 26 Sep 2005 18:59:11 -0000 1.158
+++ common/packets.def 26 Sep 2005 22:19:40 -0000
@@ -638,7 +638,6 @@ PACKET_PLAYER_INFO=39; sc
STRING username[MAX_LEN_NAME];
UINT32 score;
- BOOL is_observer;
BOOL is_male;
GOVERNMENT government;
GOVERNMENT target_government;
@@ -1180,7 +1179,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_available, is_playable, is_observer, is_barbarian;
+ BOOL is_available, is_playable, 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.193
diff -p -u -r1.193 player.c
--- common/player.c 17 Sep 2005 15:50:10 -0000 1.193
+++ common/player.c 26 Sep 2005 22:19:40 -0000
@@ -127,7 +127,6 @@ void player_init(struct player *plr)
plr->connections = conn_list_new();
plr->current_conn = NULL;
plr->is_connected = FALSE;
- plr->is_observer = FALSE;
plr->was_created = FALSE;
plr->is_alive=TRUE;
plr->is_dying = FALSE;
@@ -338,11 +337,15 @@ bool can_player_see_unit(const struct pl
Note that can_player_see_city_internals => can_player_see_units_in_city.
Otherwise the player would not know anything about the city's units at
all, since the full city packet has no "occupied" flag.
+
+ Returns TRUE if given a NULL player. This is used by the client when in
+ observer mode.
****************************************************************************/
bool can_player_see_units_in_city(const struct player *pplayer,
const struct city *pcity)
{
- return (can_player_see_city_internals(pplayer, pcity)
+ return (!pplayer
+ || can_player_see_city_internals(pplayer, pcity)
|| pplayers_allied(pplayer, city_owner(pcity)));
}
@@ -350,17 +353,22 @@ bool can_player_see_units_in_city(const
Return TRUE iff the player can see the city's internals. This means the
full city packet is sent to the client, who should then be able to popup
a dialog for it.
+
+ Returns TRUE if given a NULL player. This is used by the client when in
+ observer mode.
****************************************************************************/
bool can_player_see_city_internals(const struct player *pplayer,
const struct city *pcity)
{
- return (pplayer == city_owner(pcity));
+ return (!pplayer || pplayer == city_owner(pcity));
}
/***************************************************************
If the specified player owns the city with the specified id,
return pointer to the city struct. Else return NULL.
Now always uses fast idex_lookup_city.
+
+ pplayer may be NULL in which case all cities will be considered.
***************************************************************/
struct city *player_find_city_by_id(const struct player *pplayer,
int city_id)
@@ -374,6 +382,8 @@ struct city *player_find_city_by_id(cons
If the specified player owns the unit with the specified id,
return pointer to the unit struct. Else return NULL.
Uses fast idex_lookup_city.
+
+ pplayer may be NULL in which case all units will be considered.
***************************************************************/
struct unit *player_find_unit_by_id(const struct player *pplayer,
int unit_id)
@@ -501,6 +511,10 @@ Locate the city where the players palace
**************************************************************************/
struct city *find_palace(const struct player *pplayer)
{
+ if (!pplayer) {
+ /* The client depends on this behavior in some places. */
+ return NULL;
+ }
city_list_iterate(pplayer->cities, pcity) {
if (is_capital(pcity)) {
return pcity;
@@ -765,6 +779,9 @@ bool is_valid_username(const char *name)
****************************************************************************/
struct player_research *get_player_research(const struct player *plr)
{
- assert((plr != NULL) && (plr->team != NULL));
+ if (!plr || !plr->team) {
+ /* Some client users depend on this behavior. */
+ return NULL;
+ }
return &(plr->team->research);
}
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.165
diff -p -u -r1.165 player.h
--- common/player.h 17 Sep 2005 15:50:10 -0000 1.165
+++ common/player.h 26 Sep 2005 22:19:40 -0000
@@ -29,7 +29,6 @@
#define ANON_PLAYER_NAME "noname"
#define ANON_USER_NAME "Unassigned"
-#define OBSERVER_NAME "Observer"
/*
* pplayer->ai.barbarian_type uses this enum. Note that the values
@@ -162,7 +161,6 @@ struct player {
bool phase_done;
int nturns_idle;
bool is_alive;
- bool is_observer; /* is the player a global observer */
bool is_dying; /* set once the player is in the process of dying */
bool surrendered; /* has indicated willingness to surrender */
@@ -182,7 +180,7 @@ struct player {
struct player_spaceship spaceship;
struct player_ai ai;
bool was_created; /* if the player was /created */
- bool is_connected; /* observers don't count */
+ bool is_connected;
struct connection *current_conn; /* non-null while handling packet */
struct conn_list *connections; /* will replace conn */
struct worklist worklists[MAX_NUM_WORKLISTS];
Index: common/tech.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/tech.c,v
retrieving revision 1.100
diff -p -u -r1.100 tech.c
--- common/tech.c 2 Sep 2005 23:12:40 -0000 1.100
+++ common/tech.c 26 Sep 2005 22:19:40 -0000
@@ -52,6 +52,8 @@ static const char *flag_names[] = {
Returns state of the tech for current pplayer.
This can be: TECH_KNOW, TECH_UNKNOWN or TECH_REACHABLE
Should be called with existing techs or A_FUTURE
+
+ If pplayer is NULL this simply returns TECH_KNOWN (used by the client).
**************************************************************************/
enum tech_state get_invention(const struct player *pplayer,
Tech_type_id tech)
@@ -59,7 +61,11 @@ enum tech_state get_invention(const stru
assert(tech == A_FUTURE
|| (tech >= 0 && tech < game.control.num_tech_types));
- return get_player_research(pplayer)->inventions[tech].state;
+ if (!pplayer) {
+ return TECH_KNOWN;
+ } else {
+ return get_player_research(pplayer)->inventions[tech].state;
+ }
}
/**************************************************************************
@@ -84,12 +90,18 @@ void set_invention(struct player *pplaye
/**************************************************************************
Returns if the given tech has to be researched to reach the
goal. The goal itself isn't a requirement of itself.
+
+ pplayer may be NULL; however the function will always return FALSE in
+ that case.
**************************************************************************/
bool is_tech_a_req_for_goal(const struct player *pplayer, Tech_type_id tech,
Tech_type_id goal)
{
if (tech == goal) {
return FALSE;
+ } else if (!pplayer) {
+ /* FIXME: We need a proper implementation here! */
+ return FALSE;
} else {
return
BV_ISSET(get_player_research(pplayer)->inventions[goal].required_techs,
@@ -177,6 +189,9 @@ static void build_required_techs(struct
/**************************************************************************
Returns TRUE iff the given tech is ever reachable by the given player
by checking tech tree limitations.
+
+ pplayer may be NULL in which case a simplified result is returned
+ (used by the client).
**************************************************************************/
bool tech_is_available(const struct player *pplayer, Tech_type_id id)
{
@@ -390,6 +405,9 @@ int total_bulbs_required(const struct pl
At the end we multiply by the sciencebox value, as a percentage. The
cost can never be less than 1.
+
+ pplayer may be NULL in which case a simplified result is returned (used
+ by client and manual code).
****************************************************************************/
int base_total_bulbs_required(const struct player *pplayer,
Tech_type_id tech)
@@ -397,7 +415,9 @@ int base_total_bulbs_required(const stru
int tech_cost_style = game.info.tech_cost_style;
double base_cost;
- if (!is_future_tech(tech) && get_invention(pplayer, tech) == TECH_KNOWN) {
+ if (pplayer
+ && !is_future_tech(tech)
+ && get_invention(pplayer, tech) == TECH_KNOWN) {
/* A non-future tech which is already known costs nothing. */
return 0;
}
@@ -414,8 +434,12 @@ int base_total_bulbs_required(const stru
switch (tech_cost_style) {
case 0:
- base_cost = get_player_research(pplayer)->techs_researched
- * game.info.base_tech_cost;
+ if (pplayer) {
+ base_cost = get_player_research(pplayer)->techs_researched
+ * game.info.base_tech_cost;
+ } else {
+ base_cost = 0;
+ }
break;
case 1:
base_cost = techcoststyle1[tech];
@@ -447,7 +471,7 @@ int base_total_bulbs_required(const stru
players_iterate(other) {
players++;
if (get_invention(other, tech) == TECH_KNOWN
- && player_has_embassy(pplayer, other)) {
+ && pplayer && player_has_embassy(pplayer, other)) {
players_with_tech_and_embassy++;
}
} players_iterate_end;
@@ -500,7 +524,7 @@ int base_total_bulbs_required(const stru
* can also be adpoted to create an extra-hard AI skill level where the AI
* gets science benefits */
- if (pplayer->ai.control) {
+ if (pplayer && pplayer->ai.control) {
assert(pplayer->ai.science_cost > 0);
base_cost *= (double)pplayer->ai.science_cost / 100.0;
}
@@ -514,10 +538,16 @@ int base_total_bulbs_required(const stru
Returns the number of technologies the player need to research to get
the goal technology. This includes the goal technology. Technologies
are only counted once.
+
+ pplayer may be NULL; however the wrong value will be return in this case.
**************************************************************************/
int num_unknown_techs_for_goal(const struct player *pplayer,
Tech_type_id goal)
{
+ if (!pplayer) {
+ /* FIXME: need an implementation for this! */
+ return 0;
+ }
return get_player_research(pplayer)->inventions[goal].num_required_techs;
}
@@ -525,10 +555,16 @@ int num_unknown_techs_for_goal(const str
Function to determine cost (in bulbs) of reaching goal
technology. These costs _include_ the cost for researching the goal
technology itself.
+
+ pplayer may be NULL; however the wrong value will be return in this case.
**************************************************************************/
int total_bulbs_required_for_goal(const struct player *pplayer,
Tech_type_id goal)
{
+ if (!pplayer) {
+ /* FIXME: need an implementation for this! */
+ return 0;
+ }
return get_player_research(pplayer)->inventions[goal].bulbs_required;
}
@@ -583,14 +619,15 @@ bool is_future_tech(Tech_type_id tech)
#include "specvec.h"
/**************************************************************************
- Return the name of the given tech. You don't have to free the return
- pointer.
+ Return the name of the given tech. You don't have to free the return
+ pointer.
+
+ pplayer may be NULL. In this case we won't know the "number" of a
+ future technology.
**************************************************************************/
const char *get_tech_name(const struct player *pplayer, Tech_type_id tech)
{
- static struct string_vector future;
int i;
- struct player_research *research;
/* We don't return a static buffer because that would break anything that
* needed to work with more than one name at a time. */
@@ -602,22 +639,27 @@ const char *get_tech_name(const struct p
/* TRANS: "None" tech */
return _("None");
case A_FUTURE:
- research = get_player_research(pplayer);
+ if (pplayer) {
+ struct player_research *research = get_player_research(pplayer);
+ static struct string_vector future;
+
+ /* pplayer->future_tech == 0 means "Future Tech. 1". */
+ for (i = future.size; i <= research->future_tech; i++) {
+ char *ptr = NULL;
- /* pplayer->future_tech == 0 means "Future Tech. 1". */
- for (i = future.size; i <= research->future_tech; i++) {
- char *ptr = NULL;
-
- string_vector_append(&future, &ptr);
- }
- if (!future.p[research->future_tech]) {
- char buffer[1024];
+ string_vector_append(&future, &ptr);
+ }
+ if (!future.p[research->future_tech]) {
+ char buffer[1024];
- my_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"),
- research->future_tech + 1);
- future.p[research->future_tech] = mystrdup(buffer);
+ my_snprintf(buffer, sizeof(buffer), _("Future Tech. %d"),
+ research->future_tech + 1);
+ future.p[research->future_tech] = mystrdup(buffer);
+ }
+ return future.p[research->future_tech];
+ } else {
+ return _("Future Tech.");
}
- return future.p[research->future_tech];
default:
/* Includes A_NONE */
if (!tech_exists(tech)) {
Index: data/civ1/nations.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/civ1/nations.ruleset,v
retrieving revision 1.4
diff -p -u -r1.4 nations.ruleset
--- data/civ1/nations.ruleset 29 Aug 2004 19:03:32 -0000 1.4
+++ data/civ1/nations.ruleset 26 Sep 2005 22:19:40 -0000
@@ -61,8 +61,4 @@ options="1.9"
*include "nation/english.ruleset"
*include "nation/mongol.ruleset"
-;
-; observer and barbarians MUST go last in THIS order
-;
-*include "nation/observer.ruleset"
*include "nation/barbarian.ruleset"
Index: data/default/nations.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/nations.ruleset,v
retrieving revision 1.83
diff -p -u -r1.83 nations.ruleset
--- data/default/nations.ruleset 13 Sep 2005 00:59:25 -0000 1.83
+++ data/default/nations.ruleset 26 Sep 2005 22:19:40 -0000
@@ -160,8 +160,4 @@ match=2
*include "nation/tibetan.ruleset"
*include "nation/tunisian.ruleset"
*include "nation/uyghur.ruleset"
-;
-; observer and barbarians MUST go last in THIS order
-;
-*include "nation/observer.ruleset"
*include "nation/barbarian.ruleset"
Index: data/nation/Makefile.am
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/nation/Makefile.am,v
retrieving revision 1.25
diff -p -u -r1.25 Makefile.am
--- data/nation/Makefile.am 13 Sep 2005 00:59:25 -0000 1.25
+++ data/nation/Makefile.am 26 Sep 2005 22:19:40 -0000
@@ -78,7 +78,6 @@ pkgdata_DATA = \
mordor.ruleset \
newzealand.ruleset \
nigerian.ruleset \
- observer.ruleset \
persian.ruleset \
phoenician.ruleset \
polish.ruleset \
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.169
diff -p -u -r1.169 gamehand.c
--- server/gamehand.c 5 Sep 2005 15:55:46 -0000 1.169
+++ server/gamehand.c 26 Sep 2005 22:19:41 -0000
@@ -239,11 +239,6 @@ void init_new_game(void)
struct start_position pos
= map.start_positions[start_pos[pplayer->player_no]];
- /* don't give any units to observer */
- if (pplayer->is_observer) {
- continue;
- }
-
/* Place the first unit. */
place_starting_unit(pos.tile, pplayer, game.info.start_units[0]);
} players_iterate_end;
@@ -256,11 +251,6 @@ void init_new_game(void)
struct start_position p
= map.start_positions[start_pos[pplayer->player_no]];
- /* don't give any units to observer */
- if (pplayer->is_observer) {
- continue;
- }
-
/* Place global start units */
for (i = 1; i < strlen(game.info.start_units); i++) {
ptile = find_dispersed_position(pplayer, &p);
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.425
diff -p -u -r1.425 plrhand.c
--- server/plrhand.c 21 Sep 2005 06:45:25 -0000 1.425
+++ server/plrhand.c 26 Sep 2005 22:19:41 -0000
@@ -844,7 +844,7 @@ void send_player_info_c(struct player *s
package_player_common(pplayer, &info);
conn_list_iterate(dest, pconn) {
- if (pconn->player && pconn->player->is_observer) {
+ if (!pconn->player && pconn->observer) {
/* Global observer. */
package_player_info(pplayer, &info, pconn->player, INFO_FULL);
} else if (pconn->player) {
@@ -885,7 +885,6 @@ static void package_player_common(struct
sz_strlcpy(packet->username, plr->username);
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;
packet->is_ready = plr->is_ready;
packet->city_style=plr->city_style;
@@ -1426,102 +1425,6 @@ struct nation_type *pick_available_natio
}
/****************************************************************************
- Return an available observer nation. This simply returns the first
- such nation. If no nation is available NO_NATION_SELECTED is returned.
-****************************************************************************/
-static struct nation_type *pick_observer_nation(void)
-{
- nations_iterate(pnation) {
- if (is_nation_observer(pnation) && !pnation->player) {
- return pnation;
- }
- } nations_iterate_end;
-
- return NO_NATION_SELECTED;
-}
-
-/****************************************************************************
- Create a player with is_observer = TRUE and return it.
- If a global observer has already been created, return that player.
- If there are no player slots available return NULL.
-
- (Could be called ensure_global_observer instead.)
-****************************************************************************/
-struct player *create_global_observer(void)
-{
- struct player *pplayer = NULL;
- 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. */
- players_iterate(aplayer) {
- if (aplayer->is_observer) {
- return aplayer;
- }
- } players_iterate_end
-
- /* If we're here we couldn't find an observer, so check if we have
- * a slot available to create one. Observers are taken from the slots of
- * normal civs (barbarians are reserved separately). */
- if (game.info.nplayers - game.info.nbarbarians >= MAX_NUM_PLAYERS) {
- notify_conn(NULL, NULL, E_CONNECTION,
- _("A global observer cannot be created: too "
- "many regular players."));
- return NULL;
- }
-
- nation = pick_observer_nation();
- if (nation == NO_NATION_SELECTED) {
- notify_conn(NULL, NULL, E_CONNECTION,
- _("A global observer cannot be created: there's "
- "no observer nation in the ruleset."));
- return NULL;
- }
-
- /* alright, we can create an observer. go for it. */
- pplayer = &game.players[game.info.nplayers];
-
- /* only allocate a player map is the game is running or a game is loaded
- * in pregame. This is because a game map might not be created otherwise.
- *
- * FIXME: could we use map_is_empty here? */
- server_player_init(pplayer,
- (server_state == RUN_GAME_STATE ||
!game.info.is_new_game),
- TRUE);
-
- sz_strlcpy(pplayer->name, OBSERVER_NAME);
- sz_strlcpy(pplayer->username, ANON_USER_NAME);
- pplayer->is_connected = FALSE;
- pplayer->is_observer = TRUE;
- pplayer->capital = TRUE; /* is this necessary? maybe for client... */
- pplayer->phase_done = TRUE;
- BV_CLR_ALL(pplayer->embassy); /* no embassies */
- pplayer->is_alive = FALSE;
- pplayer->was_created = FALSE; /* doesn't really matter */
-
- /* don't do this otherwise, because a game map might
- * not have been created.
- *
- * FIXME: could we use map_is_empty here? */
- if (server_state == RUN_GAME_STATE || !game.info.is_new_game) {
- pplayer->nation = nation;
- init_tech(pplayer);
- give_initial_techs(pplayer);
- map_know_and_see_all(pplayer);
- }
-
- game.info.nplayers++;
-
- /* tell everyone that game.info.nplayers has been updated */
- send_game_info(NULL);
- send_player_info(pplayer, NULL);
- notify_conn(NULL, NULL, E_CONNECTION,
- _("A global observer has been created"));
-
- return pplayer;
-}
-
-/****************************************************************************
Called when something is changed; this resets everyone's readiness.
****************************************************************************/
void reset_all_start_commands(void)
Index: server/plrhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.h,v
retrieving revision 1.87
diff -p -u -r1.87 plrhand.h
--- server/plrhand.h 21 Sep 2005 06:45:25 -0000 1.87
+++ server/plrhand.h 26 Sep 2005 22:19:41 -0000
@@ -74,7 +74,6 @@ void send_player_turn_notifications(stru
void shuffle_players(void);
void set_shuffled_players(int *shuffled_players);
struct player *shuffled_player(int i);
-struct player *create_global_observer(void);
void reset_all_start_commands(void);
#define shuffled_players_iterate(pplayer) \
Index: server/report.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/report.c,v
retrieving revision 1.71
diff -p -u -r1.71 report.c
--- server/report.c 5 Sep 2005 15:55:47 -0000 1.71
+++ server/report.c 26 Sep 2005 22:19:42 -0000
@@ -97,7 +97,7 @@ static const char *science_to_text(int v
static const char *mil_service_to_text(int value);
static const char *pollution_to_text(int value);
-#define GOOD_PLAYER(p) ((p)->is_alive && !is_barbarian(p) && !(p)->is_observer)
+#define GOOD_PLAYER(p) ((p)->is_alive && !is_barbarian(p))
/*
* Describes a row.
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.285
diff -p -u -r1.285 ruleset.c
--- server/ruleset.c 21 Sep 2005 06:45:25 -0000 1.285
+++ server/ruleset.c 26 Sep 2005 22:19:42 -0000
@@ -2137,8 +2137,6 @@ static void load_ruleset_nations(struct
pl->is_playable = secfile_lookup_bool_default(file, TRUE,
"%s.is_playable", sec[i]);
- pl->is_observer = secfile_lookup_bool_default(file, FALSE,
- "%s.is_observer", sec[i]);
pl->is_barbarian = secfile_lookup_bool_default(file, FALSE,
"%s.is_barbarian", sec[i]);
@@ -2969,7 +2967,6 @@ void send_ruleset_nations(struct conn_li
packet.city_style = n->city_style;
packet.is_playable = n->is_playable;
packet.is_available = n->is_available;
- packet.is_observer = n->is_observer;
packet.is_barbarian = n->is_barbarian;
memcpy(packet.init_techs, n->init_techs, sizeof(packet.init_techs));
memcpy(packet.init_buildings, n->init_buildings,
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.278
diff -p -u -r1.278 savegame.c
--- server/savegame.c 26 Sep 2005 18:59:12 -0000 1.278
+++ server/savegame.c 26 Sep 2005 22:19:43 -0000
@@ -1762,8 +1762,7 @@ static void player_load(struct player *p
plr->nturns_idle=0;
plr->is_male=secfile_lookup_bool_default(file, TRUE, "player%d.is_male",
plrno);
plr->is_alive=secfile_lookup_bool(file, "player%d.is_alive", plrno);
- plr->is_observer=secfile_lookup_bool_default(file, FALSE,
- "player%d.is_observer", plrno);
+ /* "Old" observer players will still be loaded but are considered dead. */
plr->ai.control = secfile_lookup_bool(file, "player%d.ai.control", plrno);
for (i = 0; i < MAX_NUM_PLAYERS; i++) {
plr->ai.love[i]
@@ -2513,7 +2512,6 @@ static void player_save(struct player *p
secfile_insert_bool(file, plr->is_male, "player%d.is_male", plrno);
secfile_insert_bool(file, plr->is_alive, "player%d.is_alive", plrno);
- secfile_insert_bool(file, plr->is_observer, "player%d.is_observer", plrno);
secfile_insert_bool(file, plr->ai.control, "player%d.ai.control", plrno);
for (i = 0; i < MAX_NUM_PLAYERS; i++) {
secfile_insert_int(file, plr->ai.love[i],
Index: server/score.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/score.c,v
retrieving revision 1.24
diff -p -u -r1.24 score.c
--- server/score.c 4 Jul 2005 17:48:38 -0000 1.24
+++ server/score.c 26 Sep 2005 22:19:43 -0000
@@ -392,7 +392,7 @@ void calc_civ_score(struct player *pplay
pplayer->score.literacy = 0;
pplayer->score.spaceship = 0;
- if (is_barbarian(pplayer) || pplayer->is_observer) {
+ if (is_barbarian(pplayer)) {
return;
}
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.294
diff -p -u -r1.294 srv_main.c
--- server/srv_main.c 21 Sep 2005 06:45:25 -0000 1.294
+++ server/srv_main.c 26 Sep 2005 22:19:44 -0000
@@ -204,7 +204,7 @@ void srv_init(void)
**************************************************************************/
bool is_game_over(void)
{
- int barbs = 0, alive = 0, observers = 0;
+ int barbs = 0, alive = 0;
bool all_allied;
struct player *victor = NULL;
@@ -222,9 +222,6 @@ bool is_game_over(void)
if (is_barbarian(pplayer)) {
barbs++;
}
- if (pplayer->is_observer) {
- observers++;
- }
} players_iterate_end;
/* count the living */
@@ -238,7 +235,7 @@ bool is_game_over(void)
} players_iterate_end;
/* the game does not quit if we are playing solo */
- if (game.info.nplayers == (observers + barbs + 1)
+ if (game.info.nplayers == (barbs + 1)
&& alive >= 1) {
return FALSE;
}
@@ -1336,8 +1333,7 @@ void handle_player_ready(struct player *
****************************************************************************/
void aifill(int amount)
{
- int observers = 0, remove;
- int filled = 0;
+ int remove, filled = 0;
if (server_state != PRE_GAME_STATE || !game.info.is_new_game) {
return;
@@ -1350,18 +1346,7 @@ void aifill(int amount)
amount = MIN(amount, game.info.max_players);
- /* we don't want aifill to count global observers unless
- * aifill = MAX_NUM_PLAYERS */
- players_iterate(pplayer) {
- if (pplayer->is_observer) {
- observers++;
- }
- } players_iterate_end;
- if (amount == game.info.max_players) {
- observers = 0;
- }
-
- while (game.info.nplayers < amount + observers) {
+ while (game.info.nplayers < amount) {
const int old_nplayers = game.info.nplayers;
struct player *pplayer = get_player(old_nplayers);
char player_name[ARRAY_SIZE(pplayer->name)];
@@ -1394,11 +1379,10 @@ void aifill(int amount)
}
remove = game.info.nplayers - 1;
- while (game.info.nplayers > amount + observers && remove >= 0) {
+ while (game.info.nplayers > amount && remove >= 0) {
struct player *pplayer = get_player(remove);
- if (!pplayer->is_observer && !pplayer->is_connected
- && !pplayer->was_created) {
+ if (!pplayer->is_connected && !pplayer->was_created) {
server_remove_player(pplayer);
}
remove--;
@@ -1890,13 +1874,6 @@ static void srv_loop(void)
if(game.info.is_new_game) {
init_new_game();
-
- /* give global observers the entire map */
- players_iterate(pplayer) {
- if (pplayer->is_observer) {
- map_know_and_see_all(pplayer);
- }
- } players_iterate_end;
}
send_game_state(game.est_connections, CLIENT_GAME_RUNNING_STATE);
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.439
diff -p -u -r1.439 stdinhand.c
--- server/stdinhand.c 26 Sep 2005 18:59:12 -0000 1.439
+++ server/stdinhand.c 26 Sep 2005 22:19:45 -0000
@@ -142,7 +142,8 @@ static PlayerNameStatus test_player_name
return PNameTooLong;
} else if (mystrcasecmp(name, ANON_PLAYER_NAME) == 0) {
return PNameIllegal;
- } else if (mystrcasecmp(name, OBSERVER_NAME) == 0) {
+ } else if (mystrcasecmp(name, "Observer") == 0) {
+ /* "Observer" used to be illegal and we keep it that way for now. */
return PNameIllegal;
}
@@ -833,23 +834,6 @@ static bool toggle_ai_player(struct conn
return TRUE;
}
-/****************************************************************************
- Return the number of non-observer players. game.info.nplayers includes
- observers so in some places this function should be called instead.
-****************************************************************************/
-static int get_num_nonobserver_players(void)
-{
- int nplayers = 0;
-
- players_iterate(pplayer) {
- if (!pplayer->is_observer) {
- nplayers++;
- }
- } players_iterate_end;
-
- return nplayers;
-}
-
/**************************************************************************
...
**************************************************************************/
@@ -868,13 +852,11 @@ static bool create_ai_player(struct conn
/* game.info.max_players is a limit on the number of non-observer players.
* MAX_NUM_PLAYERS is a limit on all players. */
- if (get_num_nonobserver_players() >= game.info.max_players
- || game.info.nplayers >= MAX_NUM_PLAYERS) {
+ if (game.info.nplayers >= MAX_NUM_PLAYERS) {
/* Try emptying a slot if there is an ai player
* created through the /aifill command */
players_iterate(eplayer) {
- if (eplayer->is_observer || eplayer->is_connected
- || eplayer->was_created) {
+ if (eplayer->is_connected || eplayer->was_created) {
continue;
}
ai_player_should_be_removed = TRUE;
@@ -924,8 +906,7 @@ static bool create_ai_player(struct conn
if (ai_player_should_be_removed) {
players_iterate(eplayer) {
- if (eplayer->is_observer || eplayer->is_connected
- || eplayer->was_created) {
+ if (eplayer->is_connected || eplayer->was_created) {
continue;
}
server_remove_player(eplayer);
@@ -2135,7 +2116,7 @@ static bool vote_command(struct connecti
if (caller == NULL || caller->player == NULL) {
cmd_reply(CMD_VOTE, caller, C_FAIL, _("This command is client only."));
return FALSE;
- } else if (caller->player->is_observer || caller->observer) {
+ } else if (caller->observer) {
cmd_reply(CMD_VOTE, caller, C_FAIL, _("Observers cannot vote."));
return FALSE;
} else if (server_state != RUN_GAME_STATE) {
@@ -2572,7 +2553,8 @@ static bool is_allowed_to_take(struct pl
{
const char *allow;
- if (pplayer->is_observer) {
+ if (!pplayer) {
+ /* Observer */
if (!(allow = strchr(game.allow_take, (game.info.is_new_game ? 'O' :
'o')))) {
if (will_obs) {
mystrlcpy(msg, _("Sorry, one can't observe globally in this game."),
@@ -2716,11 +2698,6 @@ static bool observe_command(struct conne
}
/* if we have no pplayer, it means that we want to be a global observer */
- if (!pplayer) {
- if (!(pplayer = create_global_observer())) {
- goto end; /* couldn't create an observer */
- }
- }
/******** PART II: do the observing ********/
@@ -2731,8 +2708,11 @@ static bool observe_command(struct conne
}
/* observing your own player (during pregame) makes no sense. */
- if (pconn->player == pplayer && !pconn->observer
- && is_newgame && !pplayer->was_created) {
+ if (pplayer
+ && pconn->player == pplayer
+ && !pconn->observer
+ && is_newgame
+ && !pplayer->was_created) {
cmd_reply(CMD_OBSERVE, caller, C_FAIL,
_("%s already controls %s. Using 'observe' would remove %s"),
pconn->username, pplayer->name, pplayer->name);
@@ -2741,9 +2721,15 @@ static bool observe_command(struct conne
/* attempting to observe a player you're already observing should fail. */
if (pconn->player == pplayer && pconn->observer) {
- cmd_reply(CMD_OBSERVE, caller, C_FAIL,
- _("%s is already observing %s."),
- pconn->username, pplayer->name);
+ if (pplayer) {
+ cmd_reply(CMD_OBSERVE, caller, C_FAIL,
+ _("%s is already observing %s."),
+ pconn->username, pplayer->name);
+ } else {
+ cmd_reply(CMD_OBSERVE, caller, C_FAIL,
+ _("%s is already observing."),
+ pconn->username);
+ }
goto end;
}
@@ -2757,13 +2743,17 @@ static bool observe_command(struct conne
if (pconn->player) {
char name[MAX_LEN_NAME];
- /* if a pconn->player is removed, we'll lose pplayer */
- sz_strlcpy(name, pplayer->name);
-
+ if (pplayer) {
+ /* if a pconn->player is removed, we'll lose pplayer */
+ sz_strlcpy(name, pplayer->name);
+ }
+
detach_command(NULL, pconn->username, FALSE);
- /* find pplayer again, the pointer might have been changed */
- pplayer = find_player_by_name(name);
+ if (pplayer) {
+ /* find pplayer again, the pointer might have been changed */
+ pplayer = find_player_by_name(name);
+ }
}
/* we don't want the connection's username on another player */
@@ -2775,7 +2765,11 @@ static bool observe_command(struct conne
/* attach pconn to new player as an observer */
pconn->observer = TRUE; /* do this before attach! */
- attach_connection_to_player(pconn, pplayer);
+ if (pplayer) {
+ attach_connection_to_player(pconn, pplayer);
+ } else {
+ unattach_connection_from_player(pconn);
+ }
send_conn_info(pconn->self, game.est_connections);
if (server_state == RUN_GAME_STATE) {
@@ -2788,8 +2782,13 @@ static bool observe_command(struct conne
dsend_packet_start_phase(pconn, game.info.phase);
}
- cmd_reply(CMD_OBSERVE, caller, C_OK, _("%s now observes %s"),
- pconn->username, pplayer->name);
+ if (pplayer) {
+ cmd_reply(CMD_OBSERVE, caller, C_OK, _("%s now observes %s"),
+ pconn->username, pplayer->name);
+ } else {
+ cmd_reply(CMD_OBSERVE, caller, C_OK, _("%s now observes"),
+ pconn->username);
+ }
end:;
/* free our args */
@@ -2867,13 +2866,6 @@ static bool take_command(struct connecti
goto end;
}
- /* you may not take over a global observer */
- if (pplayer->is_observer) {
- cmd_reply(CMD_TAKE, caller, C_FAIL, _("%s cannot be taken."),
- pplayer->name);
- goto end;
- }
-
/* taking your own player makes no sense. */
if (pconn->player == pplayer && !pconn->observer) {
cmd_reply(CMD_TAKE, caller, C_FAIL, _("%s already controls %s"),
@@ -2988,7 +2980,7 @@ static bool detach_command(struct connec
struct connection *pconn = NULL;
struct player *pplayer = NULL;
bool is_newgame = server_state == PRE_GAME_STATE && game.info.is_new_game;
- bool one_obs_among_many = FALSE, res = FALSE;
+ bool res = FALSE;
sz_strlcpy(buf, str);
ntokens = get_tokens(buf, arg, 1, TOKEN_DELIMITERS);
@@ -3022,18 +3014,12 @@ static bool detach_command(struct connec
pplayer = pconn->player;
/* must have someone to detach from... */
- if (!pplayer) {
+ if (!pplayer && !pconn->observer) {
cmd_reply(CMD_DETACH, caller, C_FAIL,
_("%s is not attached to any player."), pconn->username);
goto end;
}
- /* a special case for global observers: we don't want to remove the
- * observer player in pregame if someone else is also observing it */
- if (pplayer->is_observer && conn_list_size(pplayer->connections) > 1) {
- one_obs_among_many = TRUE;
- }
-
res = TRUE;
if (check) {
goto end;
@@ -3050,16 +3036,23 @@ static bool detach_command(struct connec
}
/* actually do the detaching */
- unattach_connection_from_player(pconn);
+ if (pplayer) {
+ unattach_connection_from_player(pconn);
+ cmd_reply(CMD_DETACH, caller, C_COMMENT,
+ _("%s detaching from %s"), pconn->username, pplayer->name);
+ } else {
+ pconn->observer = FALSE;
+ cmd_reply(CMD_DETACH, caller, C_COMMENT,
+ _("%s no longer observing."), pconn->username);
+ }
send_conn_info(pconn->self, game.est_connections);
- cmd_reply(CMD_DETACH, caller, C_COMMENT,
- _("%s detaching from %s"), pconn->username, pplayer->name);
/* only remove the player if the game is new and in pregame,
* the player wasn't /created, and no one is controlling it
* and we were observing but no one else was... */
- if (!pplayer->is_connected && !pplayer->was_created && is_newgame
- && !one_obs_among_many) {
+ if (pplayer
+ && !pplayer->is_connected
+ && !pplayer->was_created && is_newgame) {
/* detach any observers */
conn_list_iterate(pplayer->connections, aconn) {
if (aconn->observer) {
@@ -3076,7 +3069,7 @@ static bool detach_command(struct connec
reset_all_start_commands();
}
- if (!pplayer->is_connected) {
+ if (pplayer && !pplayer->is_connected) {
/* aitoggle the player if no longer connected. */
if (game.info.auto_ai_toggle && !pplayer->ai.control) {
toggle_ai_player_direct(NULL, pplayer);
@@ -3369,7 +3362,6 @@ bool handle_stdin_input(struct connectio
if (caller
&& caller->player
&& !check
- && !caller->player->is_observer
&& caller->access_level == ALLOW_INFO
&& commands[cmd].level == ALLOW_CTRL) {
int idx = caller->player->player_no;
@@ -3602,10 +3594,10 @@ static bool start_command(struct connect
game.info.max_players = map.num_start_positions;
}
- if (get_num_nonobserver_players() > game.info.max_players) {
+ if (game.info.nplayers > game.info.max_players) {
/* Because of the way player ids are renumbered during
server_remove_player() this is correct */
- while (get_num_nonobserver_players() > game.info.max_players) {
+ while (game.info.nplayers > game.info.max_players) {
/* This may erronously remove observer players sometimes. This
* is a bug but non-fatal. */
server_remove_player(get_player(game.info.max_players));
@@ -3620,7 +3612,7 @@ static bool start_command(struct connect
}
/* check min_players */
- if (get_num_nonobserver_players() < game.info.min_players) {
+ if (game.info.nplayers < game.info.min_players) {
cmd_reply(CMD_START_GAME, caller, C_FAIL,
_("Not enough players, game will not start."));
return FALSE;
|
|