1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
26 #include "connection.h"
30 #include "client_main.h"
38 #include "plrdlg_common.h"
41 /******************************************************************
42 The player-name (aka nation leader) column of the plrdlg.
43 *******************************************************************/
44 static const char *col_name(const struct player
*player
)
46 return player_name(player
);
49 /****************************************************************************
50 Compares the names of two players in players dialog.
51 ****************************************************************************/
52 static int cmp_name(const struct player
*pplayer1
,
53 const struct player
*pplayer2
)
55 return fc_stricoll(player_name(pplayer1
), player_name(pplayer2
));
58 /******************************************************************
59 The username (connection name) column of the plrdlg.
60 *******************************************************************/
61 static const char *col_username(const struct player
*player
)
63 return player
->username
;
66 /******************************************************************
67 The name of the player's nation for the plrdlg.
68 *******************************************************************/
69 static const char *col_nation(const struct player
*player
)
71 return nation_adjective_for_player(player
);
74 /******************************************************************
75 The name of the player's team (or empty) for the plrdlg.
76 *******************************************************************/
77 static const char *col_team(const struct player
*player
)
79 return team_name_translation(player
->team
);
82 /******************************************************************
83 TRUE if the player is AI-controlled.
84 *******************************************************************/
85 static bool col_ai(const struct player
*plr
)
87 /* TODO: Currently is_ai() is a macro so we can't have it
88 * directly as this callback, but once it's a function,
93 /******************************************************************
94 Returns a translated string giving the embassy status
95 (none/with us/with them/both).
96 *******************************************************************/
97 static const char *col_embassy(const struct player
*player
)
99 return get_embassy_status(client
.conn
.playing
, player
);
102 /******************************************************************
103 Returns a translated string giving the diplomatic status
104 ("war" or "ceasefire (5)").
105 *******************************************************************/
106 static const char *col_diplstate(const struct player
*player
)
108 static char buf
[100];
109 const struct player_diplstate
*pds
;
111 if (NULL
== client
.conn
.playing
|| player
== client
.conn
.playing
) {
114 pds
= player_diplstate_get(client
.conn
.playing
, player
);
115 if (pds
->type
== DS_CEASEFIRE
|| pds
->type
== DS_ARMISTICE
) {
116 fc_snprintf(buf
, sizeof(buf
), "%s (%d)",
117 diplstate_type_translated_name(pds
->type
),
121 return diplstate_type_translated_name(pds
->type
);
126 /******************************************************************
127 Return a numerical value suitable for ordering players by
128 their diplomatic status in the players dialog
130 A lower value stands for more friendly diplomatic status.
131 *******************************************************************/
132 static int diplstate_value(const struct player
*plr
)
134 /* these values are scaled so that adding/subtracting
135 the number of turns left makes sense */
136 static const int diplstate_cmp_lookup
[DS_LAST
] = {
138 [DS_ALLIANCE
] = 2 << 16,
139 [DS_PEACE
] = 3 << 16,
140 [DS_ARMISTICE
] = 4 << 16,
141 [DS_CEASEFIRE
] = 5 << 16,
143 [DS_NO_CONTACT
] = 7 << 16
146 const struct player_diplstate
*pds
;
149 if (NULL
== client
.conn
.playing
|| plr
== client
.conn
.playing
) {
150 /* current global player is as close as players get
151 -> return value smaller than for DS_TEAM */
155 pds
= player_diplstate_get(client
.conn
.playing
, plr
);
156 ds_value
= diplstate_cmp_lookup
[pds
->type
];
158 if (pds
->type
== DS_ARMISTICE
|| pds
->type
== DS_CEASEFIRE
) {
159 ds_value
+= pds
->turns_left
;
165 /******************************************************************
166 Compares diplomatic status of two players in players dialog
167 *******************************************************************/
168 static int cmp_diplstate(const struct player
*player1
,
169 const struct player
*player2
)
171 return diplstate_value(player1
) - diplstate_value(player2
);
174 /******************************************************************
175 Return a string displaying the AI's love (or not) for you...
176 *******************************************************************/
177 static const char *col_love(const struct player
*player
)
179 if (NULL
== client
.conn
.playing
|| player
== client
.conn
.playing
180 || is_human(player
)) {
183 return love_text(player
->ai_common
.love
[player_index(client
.conn
.playing
)]);
187 /******************************************************************
188 Compares ai's attitude toward the player
189 ******************************************************************/
190 static int cmp_love(const struct player
*player1
,
191 const struct player
*player2
)
195 if (NULL
== client
.conn
.playing
) {
196 return player_number(player1
) - player_number(player2
);
199 if (player1
== client
.conn
.playing
|| is_human(player1
)) {
200 love1
= MAX_AI_LOVE
+ 999;
202 love1
= player1
->ai_common
.love
[player_index(client
.conn
.playing
)];
205 if (player2
== client
.conn
.playing
|| is_human(player2
)) {
206 love2
= MAX_AI_LOVE
+ 999;
208 love2
= player2
->ai_common
.love
[player_index(client
.conn
.playing
)];
211 return love1
- love2
;
214 /******************************************************************
215 Returns a translated string giving our shared-vision status.
216 *******************************************************************/
217 static const char *col_vision(const struct player
*player
)
219 return get_vision_status(client
.conn
.playing
, player
);
222 /******************************************************************
223 Returns a translated string giving the player's "state".
225 FIXME: These terms aren't very intuitive for new players.
226 *******************************************************************/
227 const char *plrdlg_col_state(const struct player
*plr
)
229 if (!plr
->is_alive
) {
230 /* TRANS: Dead -- Rest In Peace -- Reqia In Pace */
232 } else if (!plr
->is_connected
) {
234 bool consider_tb
= FALSE
;
240 opt
= optset_option_by_name(server_optset
, "turnblock");
242 consider_tb
= option_bool_get(opt
);
246 /* TRANS: No connection */
250 if (!is_player_phase(plr
, game
.info
.phase
)) {
252 } else if (plr
->phase_done
) {
255 /* TRANS: Turnblocking & player not connected */
256 return _("blocking");
259 if (!is_player_phase(plr
, game
.info
.phase
)) {
261 } else if (plr
->phase_done
) {
269 /******************************************************************
270 Returns a string telling the player's client's hostname (the
271 machine from which he is connecting).
272 *******************************************************************/
273 static const char *col_host(const struct player
*player
)
275 return player_addr_hack(player
);
278 /******************************************************************
279 Returns a string telling how many turns the player has been idle.
280 *******************************************************************/
281 static const char *col_idle(const struct player
*plr
)
284 static char buf
[100];
286 if (plr
->nturns_idle
> 3) {
287 idle
= plr
->nturns_idle
- 1;
291 fc_snprintf(buf
, sizeof(buf
), "%d", idle
);
295 /******************************************************************
296 Compares score of two players in players dialog
297 *******************************************************************/
298 static int cmp_score(const struct player
* player1
,
299 const struct player
* player2
)
301 return player1
->score
.game
- player2
->score
.game
;
304 /******************************************************************
306 *******************************************************************/
307 struct player_dlg_column player_dlg_columns
[] = {
308 {TRUE
, COL_TEXT
, N_("?Player:Name"), col_name
, NULL
, cmp_name
, "name"},
309 {FALSE
, COL_TEXT
, N_("Username"), col_username
, NULL
, NULL
, "username"},
310 {TRUE
, COL_FLAG
, N_("Flag"), NULL
, NULL
, NULL
, "flag"},
311 {TRUE
, COL_TEXT
, N_("Nation"), col_nation
, NULL
, NULL
, "nation"},
312 {TRUE
, COL_COLOR
, N_("Border"), NULL
, NULL
, NULL
, "border"},
313 {TRUE
, COL_RIGHT_TEXT
, N_("Score"), get_score_text
, NULL
, cmp_score
, "score"},
314 {TRUE
, COL_TEXT
, N_("Team"), col_team
, NULL
, NULL
, "team"},
315 {TRUE
, COL_BOOLEAN
, N_("AI"), NULL
, col_ai
, NULL
, "ai"},
316 {TRUE
, COL_TEXT
, N_("Attitude"), col_love
, NULL
, cmp_love
, "attitude"},
317 {TRUE
, COL_TEXT
, N_("Embassy"), col_embassy
, NULL
, NULL
, "embassy"},
318 {TRUE
, COL_TEXT
, N_("Dipl.State"), col_diplstate
, NULL
, cmp_diplstate
,
320 {TRUE
, COL_TEXT
, N_("Vision"), col_vision
, NULL
, NULL
, "vision"},
321 {TRUE
, COL_TEXT
, N_("State"), plrdlg_col_state
, NULL
, NULL
, "state"},
322 {FALSE
, COL_TEXT
, N_("?Player_dlg:Host"), col_host
, NULL
, NULL
, "host"},
323 {FALSE
, COL_RIGHT_TEXT
, N_("?Player_dlg:Idle"), col_idle
, NULL
, NULL
, "idle"},
324 {FALSE
, COL_RIGHT_TEXT
, N_("Ping"), get_ping_time_text
, NULL
, NULL
, "ping"}
327 const int num_player_dlg_columns
= ARRAY_SIZE(player_dlg_columns
);
329 /******************************************************************
330 Return default player dlg sorting column.
331 *******************************************************************/
332 int player_dlg_default_sort_column(void)
337 /****************************************************************************
339 ****************************************************************************/
340 void init_player_dlg_common()
344 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
345 player_dlg_columns
[i
].title
= Q_(player_dlg_columns
[i
].title
);
349 /**************************************************************************
350 The only place where this is used is the player dialog.
351 Eventually this should go the way of the dodo with everything here
352 moved into col_host above, but some of the older clients (+win32) still
353 use this function directly.
355 This code in this function is only really needed so that the host is
356 kept as a blank address if no one is controlling a player, but there are
358 **************************************************************************/
359 const char *player_addr_hack(const struct player
*pplayer
)
361 conn_list_iterate(pplayer
->connections
, pconn
) {
362 if (!pconn
->observer
) {
365 } conn_list_iterate_end
;
367 return blank_addr_str
;