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 return plr
->ai_controlled
;
90 /******************************************************************
91 Returns a translated string giving the embassy status
92 (none/with us/with them/both).
93 *******************************************************************/
94 static const char *col_embassy(const struct player
*player
)
96 return get_embassy_status(client
.conn
.playing
, player
);
99 /******************************************************************
100 Returns a translated string giving the diplomatic status
101 ("war" or "ceasefire (5)").
102 *******************************************************************/
103 static const char *col_diplstate(const struct player
*player
)
105 static char buf
[100];
106 const struct player_diplstate
*pds
;
108 if (NULL
== client
.conn
.playing
|| player
== client
.conn
.playing
) {
111 pds
= player_diplstate_get(client
.conn
.playing
, player
);
112 if (pds
->type
== DS_CEASEFIRE
|| pds
->type
== DS_ARMISTICE
) {
113 fc_snprintf(buf
, sizeof(buf
), "%s (%d)",
114 diplstate_type_translated_name(pds
->type
),
118 return diplstate_type_translated_name(pds
->type
);
123 /******************************************************************
124 Return a numerical value suitable for ordering players by
125 their diplomatic status in the players dialog
127 A lower value stands for more friendly diplomatic status.
128 *******************************************************************/
129 static int diplstate_value(const struct player
*plr
)
131 /* these values are scaled so that adding/subtracting
132 the number of turns left makes sense */
133 static const int diplstate_cmp_lookup
[DS_LAST
] = {
135 [DS_ALLIANCE
] = 2 << 16,
136 [DS_PEACE
] = 3 << 16,
137 [DS_ARMISTICE
] = 4 << 16,
138 [DS_CEASEFIRE
] = 5 << 16,
140 [DS_NO_CONTACT
] = 7 << 16
143 const struct player_diplstate
*pds
;
146 if (NULL
== client
.conn
.playing
|| plr
== client
.conn
.playing
) {
147 /* current global player is as close as players get
148 -> return value smaller than for DS_TEAM */
152 pds
= player_diplstate_get(client
.conn
.playing
, plr
);
153 ds_value
= diplstate_cmp_lookup
[pds
->type
];
155 if (pds
->type
== DS_ARMISTICE
|| pds
->type
== DS_CEASEFIRE
) {
156 ds_value
+= pds
->turns_left
;
162 /******************************************************************
163 Compares diplomatic status of two players in players dialog
164 *******************************************************************/
165 static int cmp_diplstate(const struct player
*player1
,
166 const struct player
*player2
)
168 return diplstate_value(player1
) - diplstate_value(player2
);
171 /******************************************************************
172 Return a string displaying the AI's love (or not) for you...
173 *******************************************************************/
174 static const char *col_love(const struct player
*player
)
176 if (NULL
== client
.conn
.playing
|| player
== client
.conn
.playing
177 || !player
->ai_controlled
) {
180 return love_text(player
->ai_common
.love
[player_index(client
.conn
.playing
)]);
184 /******************************************************************
185 Compares ai's attitude toward the player
186 ******************************************************************/
187 static int cmp_love(const struct player
*player1
,
188 const struct player
*player2
)
192 if (NULL
== client
.conn
.playing
) {
193 return player_number(player1
) - player_number(player2
);
196 if (player1
== client
.conn
.playing
|| !player1
->ai_controlled
) {
197 love1
= MAX_AI_LOVE
+ 999;
199 love1
= player1
->ai_common
.love
[player_index(client
.conn
.playing
)];
202 if (player2
== client
.conn
.playing
|| !player2
->ai_controlled
) {
203 love2
= MAX_AI_LOVE
+ 999;
205 love2
= player2
->ai_common
.love
[player_index(client
.conn
.playing
)];
208 return love1
- love2
;
211 /******************************************************************
212 Returns a translated string giving our shared-vision status.
213 *******************************************************************/
214 static const char *col_vision(const struct player
*player
)
216 return get_vision_status(client
.conn
.playing
, player
);
219 /******************************************************************
220 Returns a translated string giving the player's "state".
222 FIXME: These terms aren't very intuitive for new players.
223 *******************************************************************/
224 const char *plrdlg_col_state(const struct player
*plr
)
226 if (!plr
->is_alive
) {
227 /* TRANS: Dead -- Rest In Peace -- Reqia In Pace */
229 } else if (!plr
->is_connected
) {
231 bool consider_tb
= FALSE
;
233 if (plr
->ai_controlled
) {
237 opt
= optset_option_by_name(server_optset
, "turnblock");
239 consider_tb
= option_bool_get(opt
);
243 /* TRANS: No connection */
247 if (!is_player_phase(plr
, game
.info
.phase
)) {
249 } else if (plr
->phase_done
) {
252 /* TRANS: Turnblocking & player not connected */
253 return _("blocking");
256 if (!is_player_phase(plr
, game
.info
.phase
)) {
258 } else if (plr
->phase_done
) {
266 /******************************************************************
267 Returns a string telling the player's client's hostname (the
268 machine from which he is connecting).
269 *******************************************************************/
270 static const char *col_host(const struct player
*player
)
272 return player_addr_hack(player
);
275 /******************************************************************
276 Returns a string telling how many turns the player has been idle.
277 *******************************************************************/
278 static const char *col_idle(const struct player
*plr
)
281 static char buf
[100];
283 if (plr
->nturns_idle
> 3) {
284 idle
= plr
->nturns_idle
- 1;
288 fc_snprintf(buf
, sizeof(buf
), "%d", idle
);
292 /******************************************************************
293 Compares score of two players in players dialog
294 *******************************************************************/
295 static int cmp_score(const struct player
* player1
,
296 const struct player
* player2
)
298 return player1
->score
.game
- player2
->score
.game
;
301 /******************************************************************
303 *******************************************************************/
304 struct player_dlg_column player_dlg_columns
[] = {
305 {TRUE
, COL_TEXT
, N_("?Player:Name"), col_name
, NULL
, cmp_name
, "name"},
306 {FALSE
, COL_TEXT
, N_("Username"), col_username
, NULL
, NULL
, "username"},
307 {TRUE
, COL_FLAG
, N_("Flag"), NULL
, NULL
, NULL
, "flag"},
308 {TRUE
, COL_TEXT
, N_("Nation"), col_nation
, NULL
, NULL
, "nation"},
309 {TRUE
, COL_COLOR
, N_("Border"), NULL
, NULL
, NULL
, "border"},
310 {TRUE
, COL_RIGHT_TEXT
, N_("Score"), get_score_text
, NULL
, cmp_score
, "score"},
311 {TRUE
, COL_TEXT
, N_("Team"), col_team
, NULL
, NULL
, "team"},
312 {TRUE
, COL_BOOLEAN
, N_("AI"), NULL
, col_ai
, NULL
, "ai"},
313 {TRUE
, COL_TEXT
, N_("Attitude"), col_love
, NULL
, cmp_love
, "attitude"},
314 {TRUE
, COL_TEXT
, N_("Embassy"), col_embassy
, NULL
, NULL
, "embassy"},
315 {TRUE
, COL_TEXT
, N_("Dipl.State"), col_diplstate
, NULL
, cmp_diplstate
,
317 {TRUE
, COL_TEXT
, N_("Vision"), col_vision
, NULL
, NULL
, "vision"},
318 {TRUE
, COL_TEXT
, N_("State"), plrdlg_col_state
, NULL
, NULL
, "state"},
319 {FALSE
, COL_TEXT
, N_("?Player_dlg:Host"), col_host
, NULL
, NULL
, "host"},
320 {FALSE
, COL_RIGHT_TEXT
, N_("?Player_dlg:Idle"), col_idle
, NULL
, NULL
, "idle"},
321 {FALSE
, COL_RIGHT_TEXT
, N_("Ping"), get_ping_time_text
, NULL
, NULL
, "ping"}
324 const int num_player_dlg_columns
= ARRAY_SIZE(player_dlg_columns
);
326 /******************************************************************
327 Return default player dlg sorting column.
328 *******************************************************************/
329 int player_dlg_default_sort_column(void)
334 /****************************************************************************
336 ****************************************************************************/
337 void init_player_dlg_common()
341 for (i
= 0; i
< num_player_dlg_columns
; i
++) {
342 player_dlg_columns
[i
].title
= Q_(player_dlg_columns
[i
].title
);
346 /**************************************************************************
347 The only place where this is used is the player dialog.
348 Eventually this should go the way of the dodo with everything here
349 moved into col_host above, but some of the older clients (+win32) still
350 use this function directly.
352 This code in this function is only really needed so that the host is
353 kept as a blank address if no one is controlling a player, but there are
355 **************************************************************************/
356 const char *player_addr_hack(const struct player
*pplayer
)
358 conn_list_iterate(pplayer
->connections
, pconn
) {
359 if (!pconn
->observer
) {
362 } conn_list_iterate_end
;
364 return blank_addr_str
;