Stop sharing requirement_unit_state_ereq().
[freeciv.git] / client / plrdlg_common.c
blobb48d530c9e09e0bb56b18ba4cc6661d6be46ef86
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)
6 any later version.
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 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <string.h>
20 /* utility */
21 #include "fcintl.h"
22 #include "log.h"
23 #include "support.h"
25 /* common */
26 #include "connection.h"
27 #include "game.h"
29 /* client */
30 #include "client_main.h"
31 #include "climisc.h"
32 #include "options.h"
33 #include "text.h"
35 /* client/include */
36 #include "plrdlg_g.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,
89 * do that. */
90 return is_ai(plr);
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) {
112 return "-";
113 } else {
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),
118 pds->turns_left);
119 return buf;
120 } else {
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] = {
137 [DS_TEAM] = 1 << 16,
138 [DS_ALLIANCE] = 2 << 16,
139 [DS_PEACE] = 3 << 16,
140 [DS_ARMISTICE] = 4 << 16,
141 [DS_CEASEFIRE] = 5 << 16,
142 [DS_WAR] = 6 << 16,
143 [DS_NO_CONTACT] = 7 << 16
146 const struct player_diplstate *pds;
147 int ds_value;
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 */
152 return 0;
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;
162 return ds_value;
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)) {
181 return "-";
182 } else {
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)
193 int love1, love2;
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;
201 } else {
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;
207 } else {
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 */
231 return _("R.I.P.");
232 } else if (!plr->is_connected) {
233 struct option *opt;
234 bool consider_tb = FALSE;
236 if (is_ai(plr)) {
237 return "";
240 opt = optset_option_by_name(server_optset, "turnblock");
241 if (opt != NULL) {
242 consider_tb = option_bool_get(opt);
245 if (!consider_tb) {
246 /* TRANS: No connection */
247 return _("noconn");
250 if (!is_player_phase(plr, game.info.phase)) {
251 return _("waiting");
252 } else if (plr->phase_done) {
253 return _("done");
254 } else {
255 /* TRANS: Turnblocking & player not connected */
256 return _("blocking");
258 } else {
259 if (!is_player_phase(plr, game.info.phase)) {
260 return _("waiting");
261 } else if (plr->phase_done) {
262 return _("done");
263 } else {
264 return _("moving");
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)
283 int idle;
284 static char buf[100];
286 if (plr->nturns_idle > 3) {
287 idle = plr->nturns_idle - 1;
288 } else {
289 idle = 0;
291 fc_snprintf(buf, sizeof(buf), "%d", idle);
292 return buf;
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,
319 "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)
334 return 3;
337 /****************************************************************************
338 Translate all titles
339 ****************************************************************************/
340 void init_player_dlg_common()
342 int i;
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
357 observers.
358 **************************************************************************/
359 const char *player_addr_hack(const struct player *pplayer)
361 conn_list_iterate(pplayer->connections, pconn) {
362 if (!pconn->observer) {
363 return pconn->addr;
365 } conn_list_iterate_end;
367 return blank_addr_str;