Freeciv-3.3
Loading...
Searching...
No Matches
text.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdarg.h>
19#include <string.h>
20#include <math.h> /* ceil */
21
22/* utility */
23#include "astring.h"
24#include "bitvector.h"
25#include "fcintl.h"
26#include "log.h"
27#include "support.h"
28
29/* common */
30#include "calendar.h"
31#include "citizens.h"
32#include "clientutils.h"
33#include "combat.h"
34#include "culture.h"
35#include "fc_types.h" /* LINE_BREAK */
36#include "game.h"
37#include "government.h"
38#include "map.h"
39#include "nation.h"
40#include "research.h"
41#include "traderoutes.h"
42#include "unitlist.h"
43
44/* client */
45#include "client_main.h"
46#include "climap.h"
47#include "climisc.h"
48#include "control.h"
49#include "goto.h"
50#include "helpdata.h"
51
52#include "text.h"
53
54
55static int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs);
56static const char *format_duration(int duration);
57
58/************************************************************************/
63const char *get_tile_output_text(const struct tile *ptile)
64{
65 static struct astring str = ASTRING_INIT;
66 int i;
67 char output_text[O_LAST][16];
68
69 for (i = 0; i < O_LAST; i++) {
70 int before_penalty = 0;
71 int x = city_tile_output(NULL, ptile, FALSE, i);
72
73 if (NULL != client.conn.playing) {
77 }
78
79 if (before_penalty > 0 && x > before_penalty) {
80 fc_snprintf(output_text[i], sizeof(output_text[i]), "%d(-1)", x);
81 } else {
82 fc_snprintf(output_text[i], sizeof(output_text[i]), "%d", x);
83 }
84 }
85
86 astr_set(&str, "%s/%s/%s", output_text[O_FOOD],
88
89 return astr_str(&str);
90}
91
92/************************************************************************/
96static inline void get_full_username(char *buf, int buflen,
97 const struct player *pplayer)
98{
99 if (!buf || buflen < 1) {
100 return;
101 }
102
103 if (!pplayer) {
104 buf[0] = '\0';
105 return;
106 }
107
108 if (is_ai(pplayer)) {
109 /* TRANS: "AI <player name>" */
110 fc_snprintf(buf, buflen, _("AI %s"), pplayer->name);
111 } else {
112 fc_strlcpy(buf, pplayer->username, buflen);
113 }
114}
115
116/************************************************************************/
120static inline void get_full_nation(char *buf, int buflen,
121 const struct player *pplayer)
122{
123 if (!buf || buflen < 1) {
124 return;
125 }
126
127 if (!pplayer) {
128 buf[0] = '\0';
129 return;
130 }
131
132 if (pplayer->team) {
133 /* TRANS: "<nation adjective>, team <team name>" */
134 fc_snprintf(buf, buflen, _("%s, team %s"),
136 team_name_translation(pplayer->team));
137 } else {
139 }
140}
141
142/************************************************************************/
147const char *popup_info_text(struct tile *ptile)
148{
149 const char *activity_text;
150 struct city *pcity = tile_city(ptile);
151 struct unit *punit = find_visible_unit(ptile);
153 {"" /* unused, DS_ARMISTICE */, Q_("?nation:Hostile"),
154 "" /* unused, DS_CEASEFIRE */,
155 Q_("?nation:Peaceful"), Q_("?nation:Friendly"),
156 Q_("?nation:Mysterious"), Q_("?nation:Friendly(team)")};
157 const char *diplo_city_adjectives[DS_LAST] =
158 {"" /* unused, DS_ARMISTICE */, Q_("?city:Hostile"),
159 "" /* unused, DS_CEASEFIRE */,
160 Q_("?city:Peaceful"), Q_("?city:Friendly"), Q_("?city:Mysterious"),
161 Q_("?city:Friendly(team)")};
162 static struct astring str = ASTRING_INIT;
163 char username[MAX_LEN_NAME + 32];
164 char nation[2 * MAX_LEN_NAME + 32];
165 int tile_x, tile_y, nat_x, nat_y;
166 bool first;
167 struct player *plr = client_player();
168 bool flaggy_unit = (punit != nullptr
169 && !is_flagless_to_player(punit, plr));
170 Continent_id cont = tile_continent(ptile);
171
172 astr_clear(&str);
174 astr_add_line(&str, _("Location: (%d, %d) [%d]"),
175 tile_x, tile_y, cont);
177 astr_add_line(&str, _("Native coordinates: (%d, %d)"),
178 nat_x, nat_y);
179
180 if (cont > 0) {
181 int size = get_continent_size(cont);
183
184 if (is_whole_continent_known(cont)) {
185 astr_add_line(&str, _("Continent size: %d"), size);
186 if (surrounder < 0) {
187 astr_add_line(&str, _("Surrounded by ocean %d"), -surrounder);
188 }
189 } else {
190 astr_add_line(&str, _("Continent size: at least %d"), size);
191 if (surrounder < 0) {
192 astr_add_line(&str, _("Maybe surrounded by ocean %d"), -surrounder);
193 }
194 }
195 } else if (cont < 0) {
196 int size = get_ocean_size(-cont);
198
199 if (is_whole_ocean_known(-cont)) {
200 astr_add_line(&str, _("Ocean size: %d"), size);
201 if (surrounder > 0) {
202 astr_add_line(&str, _("Surrounded by continent %d"), surrounder);
203 }
204 } else {
205 astr_add_line(&str, _("Ocean size: at least %d"), size);
206 if (surrounder > 0) {
207 astr_add_line(&str, _("Maybe surrounded by continent %d"),
208 surrounder);
209 }
210 }
211 }
212 astr_add_line(&str, _("Latitude: %d"),
213 map_signed_latitude(ptile));
214
215 if (client_tile_get_known(ptile) == TILE_UNKNOWN) {
216 astr_add(&str, _("Unknown"));
217 return astr_str(&str);
218 }
219 astr_add_line(&str, _("Terrain: %s"), tile_get_info_text(ptile, TRUE, 0));
220 astr_add_line(&str, _("Food/Prod/Trade: %s"),
221 get_tile_output_text(ptile));
222 first = TRUE;
223 extra_type_iterate(pextra) {
224 if (pextra->category == ECAT_BONUS && tile_has_visible_extra(ptile, pextra)) {
225 if (!first) {
226 astr_add(&str, ",%s", extra_name_translation(pextra));
227 } else {
229 first = FALSE;
230 }
231 }
233
235 struct player *owner = tile_owner(ptile);
236
239
240 if (plr != nullptr && owner == plr) {
241 astr_add_line(&str, _("Our territory"));
242 } else if (owner != nullptr && plr == nullptr) {
243 /* TRANS: "Territory of <username> (<nation + team>)" */
244 astr_add_line(&str, _("Territory of %s (%s)"), username, nation);
245 } else if (owner != nullptr) {
247
248 if (ds->type == DS_CEASEFIRE) {
249 int turns = ds->turns_left;
250
252 /* TRANS: "Territory of <username> (<nation + team>)
253 * (<number> turn cease-fire)" */
254 PL_("Territory of %s (%s) (%d turn cease-fire)",
255 "Territory of %s (%s) (%d turn cease-fire)",
256 turns),
257 username, nation, turns);
258 } else if (ds->type == DS_ARMISTICE) {
259 int turns = ds->turns_left;
260
262 /* TRANS: "Territory of <username> (<nation + team>)
263 * (<number> turn armistice)" */
264 PL_("Territory of %s (%s) (%d turn armistice)",
265 "Territory of %s (%s) (%d turn armistice)",
266 turns),
267 username, nation, turns);
268 } else {
269 int type = ds->type;
270
271 /* TRANS: "Territory of <username>
272 * (<nation + team> | <diplomatic state>)" */
273 astr_add_line(&str, _("Territory of %s (%s | %s)"),
274 username, nation,
276 }
277 } else {
278 astr_add_line(&str, _("Unclaimed territory"));
279 }
280 }
281
282 if (pcity != nullptr) {
283 /* Look at city owner, not tile owner (the two should be the same, if
284 * borders are in use). */
285 struct player *owner = city_owner(pcity);
286 const char *improvements[improvement_count()];
287 int has_improvements = 0;
288
291
292 if (plr == nullptr || owner == plr) {
293 /* TRANS: "City: <city name> | <username> (<nation + team>)" */
294 astr_add_line(&str, _("City: %s | %s (%s)"),
296 } else {
298
299 if (ds->type == DS_CEASEFIRE) {
300 int turns = ds->turns_left;
301
302 /* TRANS: "City: <city name> | <username>
303 * (<nation + team>, <number> turn cease-fire)" */
304 astr_add_line(&str, PL_("City: %s | %s (%s, %d turn cease-fire)",
305 "City: %s | %s (%s, %d turn cease-fire)",
306 turns),
307 city_name_get(pcity), username, nation, turns);
308 } else if (ds->type == DS_ARMISTICE) {
309 int turns = ds->turns_left;
310
311 /* TRANS: "City: <city name> | <username>
312 * (<nation + team>, <number> turn armistice)" */
313 astr_add_line(&str, PL_("City: %s | %s (%s, %d turn armistice)",
314 "City: %s | %s (%s, %d turn armistice)",
315 turns),
316 city_name_get(pcity), username, nation, turns);
317 } else {
318 /* TRANS: "City: <city name> | <username>
319 * (<nation + team>, <diplomatic state>)" */
320 astr_add_line(&str, _("City: %s | %s (%s, %s)"),
321 city_name_get(pcity), username, nation,
323 }
324 }
325
327 int count = unit_list_size(ptile->units);
328
329 if (count > 0) {
330 /* TRANS: preserve leading space */
331 astr_add(&str, PL_(" | Occupied with %d unit.",
332 " | Occupied with %d units.", count), count);
333 } else {
334 /* TRANS: preserve leading space */
335 astr_add(&str, _(" | Not occupied."));
336 }
337 } else {
338 if (city_is_occupied(pcity)) {
339 /* TRANS: preserve leading space */
340 astr_add(&str, _(" | Occupied."));
341 } else {
342 /* TRANS: preserve leading space */
343 astr_add(&str, _(" | Not occupied."));
344 }
345 }
346
347 improvement_iterate(pimprove) {
348 if (is_improvement_visible(pimprove)
349 && city_has_building(pcity, pimprove)) {
350 improvements[has_improvements++] =
352 }
354
355 if (0 < has_improvements) {
356 struct astring list = ASTRING_INIT;
357
359 /* TRANS: %s is a list of "and"-separated improvements. */
360 astr_add_line(&str, _(" with %s."), astr_str(&list));
361 astr_free(&list);
362 }
363
365 struct city *hcity = game_city_by_number(pfocus_unit->homecity);
366
371 hcity)->replace_priority)) {
372 /* TRANS: "Trade from Warsaw: 5" */
373 astr_add_line(&str, _("Trade from %s: %d"),
376 }
378 }
379 {
380 const char *infratext = get_infrastructure_text(ptile->extras);
381
382 if (*infratext != '\0') {
383 astr_add_line(&str, _("Infrastructure: %s"), infratext);
384 }
385 }
387 if (strlen(activity_text) > 0) {
388 astr_add_line(&str, _("Activity: %s"), activity_text);
389 }
390
391 if (punit != nullptr && pcity == nullptr) {
392 struct player *owner = unit_owner(punit);
393 const struct unit_type *ptype = unit_type_get(punit);
394
395 if (flaggy_unit) {
396 get_full_username(username, sizeof(username), owner);
397 get_full_nation(nation, sizeof(nation), owner);
398
399 if (plr == nullptr || owner == plr) {
401
402 /* TRANS: "Unit: <unit type> | <username> (<nation + team>)" */
403 astr_add_line(&str, _("Unit: %s | %s (%s)"),
404 utype_name_translation(ptype), username, nation);
405
408 if (hcity != nullptr) {
409 /* TRANS: on own line immediately following \n, "from <city> |
410 * <nationality> people" */
411 astr_add_line(&str, _("from %s | %s people"), city_name_get(hcity),
413 } else {
414 /* TRANS: Nationality of the people comprising a unit, if
415 * different from owner. */
416 astr_add_line(&str, _("%s people"),
418 }
419 } else if (hcity != nullptr) {
420 /* TRANS: on own line immediately following \n, ... <city> */
421 astr_add_line(&str, _("from %s"), city_name_get(hcity));
422 }
423 if (punit->carrying
425 /* TRANS: on own line immediately following \n, from ... */
426 astr_add_line(&str, _("carrying %s"),
428 }
429 } else if (owner != nullptr) {
431
432 if (ds->type == DS_CEASEFIRE) {
433 int turns = ds->turns_left;
434
435 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
436 * <number> turn cease-fire)" */
437 astr_add_line(&str, PL_("Unit: %s | %s (%s, %d turn cease-fire)",
438 "Unit: %s | %s (%s, %d turn cease-fire)",
439 turns),
441 username, nation, turns);
442 } else if (ds->type == DS_ARMISTICE) {
443 int turns = ds->turns_left;
444
445 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
446 * <number> turn armistice)" */
447 astr_add_line(&str, PL_("Unit: %s | %s (%s, %d turn armistice)",
448 "Unit: %s | %s (%s, %d turn armistice)",
449 turns),
451 username, nation, turns);
452 } else {
453 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
454 * <diplomatic state>)" */
455 astr_add_line(&str, _("Unit: %s | %s (%s, %s)"),
456 utype_name_translation(ptype), username, nation,
458 }
459 }
460 } else {
462 }
463
465
466 if (owner == plr || client_is_global_observer()) {
467 /* Show bribe cost for own units. */
468 astr_add_line(&str, _("Probable bribe cost: %d"),
469 unit_bribe_cost(punit, nullptr, nullptr));
470 } else {
471 /* We can only give an (lower) boundary for units of other players. */
472 astr_add_line(&str, _("Estimated bribe cost: > %d"),
473 unit_bribe_cost(punit, plr, nullptr));
474 }
475
476 if ((plr == nullptr || owner == plr)
477 && unit_list_size(ptile->units) >= 2) {
478 /* TRANS: "5 more" units on this tile */
479 astr_add(&str, _(" (%d more)"), unit_list_size(ptile->units) - 1);
480 }
481 }
482
484
485 return astr_str(&str);
486}
487
488#define FAR_CITY_SQUARE_DIST (2*(6*6))
489/************************************************************************/
494const char *get_nearest_city_text(struct city *pcity, int sq_dist)
495{
496 static struct astring str = ASTRING_INIT;
497
498 astr_clear(&str);
499
500 /* Just to be sure */
501 if (!pcity) {
502 sq_dist = -1;
503 }
504
506 /* TRANS: on own line immediately following \n, ... <city> */
507 ? _("far from %s")
508 : (sq_dist > 0)
509 /* TRANS: on own line immediately following \n, ... <city> */
510 ? _("near %s")
511 : (sq_dist == 0)
512 /* TRANS: on own line immediately following \n, ... <city> */
513 ? _("in %s")
514 : "%s",
515 pcity
517 : "");
518
519 return astr_str(&str);
520}
521
522/************************************************************************/
528const char *unit_description(struct unit *punit)
529{
530 int pcity_near_dist;
531 struct player *owner = unit_owner(punit);
532 struct player *nationality = unit_nationality(punit);
533 struct city *pcity
536 const struct unit_type *ptype = unit_type_get(punit);
537 static struct astring str = ASTRING_INIT;
538 const struct player *pplayer = client_player();
539
540 astr_clear(&str);
541
543
544 {
545 const char *veteran_name =
547 if (veteran_name) {
548 astr_add(&str, " (%s)", veteran_name);
549 }
550 }
551
552 if (pplayer == owner) {
554 } else {
555 astr_add(&str, "\n");
556 }
558
559 if (pcity) {
560 /* TRANS: on own line immediately following \n, ... <city> */
561 astr_add_line(&str, _("from %s"), city_name_get(pcity));
562 } else {
563 astr_add(&str, "\n");
564 }
566 if (nationality != NULL && owner != nationality) {
567 /* TRANS: Nationality of the people comprising a unit, if
568 * different from owner. */
569 astr_add_line(&str, _("%s people"),
570 nation_adjective_for_player(nationality));
571 } else {
572 astr_add(&str, "\n");
573 }
574 }
575
576 astr_add_line(&str, "%s",
578#ifdef FREECIV_DEBUG
579 astr_add_line(&str, "Unit ID: %d", punit->id);
580#endif
581
582 return astr_str(&str);
583}
584
585/************************************************************************/
598const char *get_airlift_text(const struct unit_list *punits,
599 const struct city *pdest)
600{
601 static struct astring str = ASTRING_INIT;
602 bool src = (pdest == NULL);
604 best = AL_IMPOSSIBLE;
605 int cur = 0, max = 0;
606
608 enum texttype this = AL_IMPOSSIBLE;
609 enum unit_airlift_result result;
610
611 /* NULL will tell us about the capability of airlifting from source */
613
614 switch (result) {
615 case AR_NO_MOVES:
617 case AR_OCCUPIED:
618 case AR_NOT_IN_CITY:
619 case AR_BAD_SRC_CITY:
620 case AR_BAD_DST_CITY:
621 /* No chance of an airlift. */
622 this = AL_IMPOSSIBLE;
623 break;
624 case AR_OK:
629 /* May or may not be able to airlift now, but there's a chance we could
630 * later */
631 {
632 const struct city *pcity = src ? tile_city(unit_tile(punit)) : pdest;
633
637 /* No restrictions on destination (and we can infer this even for
638 * other players' cities). */
639 this = AL_INFINITE;
642 this = AL_INFINITE;
643 } else if (client_player() == city_owner(pcity)) {
644 /* A city we know about. */
645 int this_cur = pcity->airlift, this_max = city_airlift_max(pcity);
646
647 if (this_max <= 0) {
648 /* City known not to be airlift-capable. */
649 this = AL_IMPOSSIBLE;
650 } else {
651 if (src
653 /* Unlimited capacity. */
654 this = AL_INFINITE;
655 } else if (!src
657 this = AL_INFINITE;
658 } else {
659 /* Limited capacity (possibly zero right now). */
660 this = AL_FINITE;
661 /* Store the numbers. This whole setup assumes that numeric
662 * capacity isn't unit-dependent. */
663 if (best == AL_FINITE) {
664 fc_assert(cur == this_cur && max == this_max);
665 }
666 cur = this_cur;
667 max = this_max;
668 }
669 }
670 } else {
671 /* Unknown capacity. */
672 this = AL_UNKNOWN;
673 }
674 }
675 break;
676 }
677
678 /* Now take the most optimistic view. */
679 best = MAX(best, this);
681
682 switch (best) {
683 case AL_IMPOSSIBLE:
684 return NULL;
685 case AL_UNKNOWN:
686 astr_set(&str, "?");
687 break;
688 case AL_FINITE:
689 astr_set(&str, "%d/%d", cur, max);
690 break;
691 case AL_INFINITE:
692 astr_set(&str, _("Yes"));
693 break;
694 }
695
696 return astr_str(&str);
697}
698
699/************************************************************************/
702static int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs)
703{
704 const struct research *presearch;
705 int ours = 0, theirs = 0;
706 bool team = FALSE;
707
708 if (!client_has_player()) {
709 return 0;
710 }
712
713 /* Sum up science */
715 if (pplayer == client_player()) {
716 city_list_iterate(pplayer->cities, pcity) {
717 ours += pcity->surplus[O_SCIENCE];
719 } else {
720 team = TRUE;
721 theirs -= pplayer->client.tech_upkeep;
722 }
724
725 if (team) {
726 theirs += presearch->client.total_bulbs_prod - ours;
727 }
728 ours -= client_player()->client.tech_upkeep;
729
730 if (pours) {
731 *pours = ours;
732 }
733 if (pteam) {
734 *pteam = team;
735 }
736 if (ptheirs) {
737 *ptheirs = theirs;
738 }
739
740 return ours + theirs;
741}
742
743/************************************************************************/
747 int per_turn)
748{
749 if (per_turn > 0) {
750 return ceil((double)(presearch->client.researching_cost
751 - presearch->bulbs_researched) / per_turn);
752 } else {
753 return -1;
754 }
755}
756
757/************************************************************************/
761static int turns_per_advance(const struct research *presearch, int per_turn)
762{
763 if (per_turn > 0) {
764 return MAX(1, ceil((double)presearch->client.researching_cost) / per_turn);
765 } else {
766 return -1;
767 }
768}
769
770/************************************************************************/
774static int turns_to_tech_loss(const struct research *presearch, int per_turn)
775{
776 if (per_turn >= 0 || game.info.techloss_forgiveness == -1) {
777 /* With techloss_forgiveness == -1, we'll never lose a tech, just
778 * get further into debt. */
779 return -1;
780 } else {
781 int bulbs_to_loss = presearch->bulbs_researched
782 + (presearch->client.researching_cost
784
785 return ceil((double)bulbs_to_loss / -per_turn);
786 }
787}
788
789/************************************************************************/
794const char *science_dialog_text(void)
795{
796 bool team;
797 int ours, theirs, perturn, upkeep;
798 static struct astring str = ASTRING_INIT;
800 struct research *research;
801
802 astr_clear(&str);
803
805
807 upkeep = client_player()->client.tech_upkeep;
808
809 if (NULL == client.conn.playing || (ours == 0 && theirs == 0
810 && upkeep == 0)) {
811 return _("Progress: no research");
812 }
813
814 if (A_UNSET == research->researching) {
815 astr_add(&str, _("Progress: no research"));
816 } else {
817 int turns;
818
819 if ((turns = turns_per_advance(research, perturn)) >= 0) {
820 astr_add(&str, PL_("Progress: %d turn/advance",
821 "Progress: %d turns/advance",
822 turns), turns);
823 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
824 /* FIXME: turns to next loss is not a good predictor of turns to
825 * following loss, due to techloss_restore etc. But it'll do. */
826 astr_add(&str, PL_("Progress: %d turn/advance loss",
827 "Progress: %d turns/advance loss",
828 turns), turns);
829 } else {
830 /* no forward progress -- no research, or tech loss disallowed */
831 if (perturn < 0) {
832 astr_add(&str, _("Progress: decreasing!"));
833 } else {
834 astr_add(&str, _("Progress: none"));
835 }
836 }
837 }
838 astr_set(&ourbuf, PL_("%d bulb/turn", "%d bulbs/turn", ours), ours);
839 if (team) {
840 /* Techpool version */
842 /* TRANS: This is appended to "%d bulb/turn" text */
843 PL_(", %d bulb/turn from team",
844 ", %d bulbs/turn from team", theirs), theirs);
845 } else {
847 }
848 astr_add(&str, " (%s%s)", astr_str(&ourbuf), astr_str(&theirbuf));
851
853 /* perturn is defined as: (bulbs produced) - upkeep */
854 astr_add_line(&str, _("Bulbs produced per turn: %d"), perturn + upkeep);
855 /* TRANS: keep leading space; appended to "Bulbs produced per turn: %d" */
856 astr_add(&str, _(" (needed for technology upkeep: %d)"), upkeep);
857 }
858
859 return astr_str(&str);
860}
861
862/************************************************************************/
874{
876 static struct astring str = ASTRING_INIT;
877
878 if (!research) {
879 return "-";
880 }
881
882 astr_clear(&str);
883 if (research->researching == A_UNSET) {
884 astr_add(&str, _("%d/- (never)"), research->bulbs_researched);
885 if (percent) {
886 *percent = 0.0;
887 }
888 } else {
889 int total = research->client.researching_cost;
890 int done = research->bulbs_researched;
892 int turns;
893
894 if ((turns = turns_to_research_done(research, perturn)) >= 0) {
895 astr_add(&str, PL_("%d/%d (%d turn)", "%d/%d (%d turns)", turns),
896 done, total, turns);
897 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
898 astr_add(&str, PL_("%d/%d (%d turn to loss)",
899 "%d/%d (%d turns to loss)", turns),
900 done, total, turns);
901 } else {
902 /* no forward progress -- no research, or tech loss disallowed */
903 astr_add(&str, _("%d/%d (never)"), done, total);
904 }
905 if (percent) {
906 *percent = (double)done / (double)total;
907 *percent = CLIP(0.0, *percent, 1.0);
908 }
909 }
910
911 return astr_str(&str);
912}
913
914/************************************************************************/
920{
921 const struct research *research = research_get(client_player());
922 int steps = research_goal_unknown_techs(research, goal);
924 int turns;
926 static struct astring str = ASTRING_INIT;
927 struct astring buf1 = ASTRING_INIT,
930
931 if (!research) {
932 return "-";
933 }
934
935 astr_clear(&str);
936
938 || research->researching == goal) {
940 }
941
942 astr_set(&buf1,
943 PL_("%d step", "%d steps", steps), steps);
944 astr_set(&buf2,
945 PL_("%d bulb", "%d bulbs", bulbs_needed), bulbs_needed);
946 if (perturn > 0) {
947 turns = (bulbs_needed + perturn - 1) / perturn;
948 astr_set(&buf3,
949 PL_("%d turn", "%d turns", turns), turns);
950 } else {
951 astr_set(&buf3, _("never"));
952 }
953 astr_add_line(&str, "(%s - %s - %s)",
955 astr_free(&buf1);
956 astr_free(&buf2);
957 astr_free(&buf3);
958
959 return astr_str(&str);
960}
961
962/************************************************************************/
971{
972 static struct astring str = ASTRING_INIT;
973
974 astr_clear(&str);
975
976 if (NULL != client.conn.playing) {
977 astr_add_line(&str, _("Population: %s"),
979 }
980 astr_add_line(&str, _("Year: %s (T%d)"),
982
983 if (NULL != client.conn.playing) {
984 astr_add_line(&str, _("Gold: %d (%+d)"),
987 astr_add_line(&str, _("Tax: %d Lux: %d Sci: %d"),
991 }
993 if (game.info.phase < 0 || game.info.phase >= player_count()) {
994 astr_add_line(&str, _("Moving: Nobody"));
995 } else {
996 astr_add_line(&str, _("Moving: %s"),
998 }
999 } else if (game.info.phase_mode == PMT_TEAMS_ALTERNATE) {
1000 if (game.info.phase < 0 || game.info.phase >= team_count()) {
1001 astr_add_line(&str, _("Moving: Nobody"));
1002 } else {
1003 astr_add_line(&str, _("Moving: %s"),
1005 }
1006 }
1007
1008 if (moreinfo) {
1009 astr_add_line(&str, _("(Click for more info)"));
1010 }
1011
1012 return astr_str(&str);
1013}
1014
1015/************************************************************************/
1023{
1024 static struct astring str = ASTRING_INIT;
1025
1026 astr_clear(&str);
1027
1028 if (NULL != client.conn.playing) {
1029 astr_add_line(&str, _("%s People"),
1031 }
1032 astr_add_line(&str, _("Year: %s"), calendar_text());
1033 astr_add_line(&str, _("Turn: %d"), game.info.turn);
1034
1035 if (NULL != client.conn.playing) {
1036 const struct research *presearch = research_get(client_player());
1038 int upkeep = client_player()->client.tech_upkeep;
1039
1040 astr_add_line(&str, _("Gold: %d"),
1042 astr_add_line(&str, _("Net Income: %d"),
1044 /* TRANS: Gold, luxury, and science rates are in percentage values. */
1045 astr_add_line(&str, _("Tax rates: Gold:%d%% Luxury:%d%% Science:%d%%"),
1049 astr_add_line(&str, _("Researching %s: %s"),
1051 presearch->researching),
1053 /* perturn is defined as: (bulbs produced) - upkeep */
1055 astr_add_line(&str, _("Bulbs per turn: %d - %d = %d"), perturn + upkeep,
1056 upkeep, perturn);
1057 } else {
1058 fc_assert(upkeep == 0);
1059 astr_add_line(&str, _("Bulbs per turn: %d"), perturn);
1060 }
1061 {
1063
1067 astr_add_line(&str, _("Culture: %d (%+d/turn)"),
1069 }
1070 }
1071
1072 /* See also get_global_warming_tooltip() and get_nuclear_winter_tooltip(). */
1073
1074 if (game.info.global_warming) {
1075 int chance, rate;
1077 astr_add_line(&str, _("Global warming chance: %d%% (%+d%%/turn)"),
1078 chance, rate);
1079 } else {
1080 astr_add_line(&str, _("Global warming deactivated."));
1081 }
1082
1083 if (game.info.nuclear_winter) {
1084 int chance, rate;
1086 astr_add_line(&str, _("Nuclear winter chance: %d%% (%+d%%/turn)"),
1087 chance, rate);
1088 } else {
1089 astr_add_line(&str, _("Nuclear winter deactivated."));
1090 }
1091
1092 if (NULL != client.conn.playing) {
1093 astr_add_line(&str, _("Government: %s"),
1095 }
1096
1097 return astr_str(&str);
1098}
1099
1100/************************************************************************/
1107const char *get_unit_info_label_text1(struct unit_list *punits)
1108{
1109 static struct astring str = ASTRING_INIT;
1110
1111 astr_clear(&str);
1112
1113 if (punits) {
1114 int count = unit_list_size(punits);
1115
1116 if (count == 1) {
1118 } else {
1119 astr_add(&str, PL_("%d unit", "%d units", count), count);
1120 }
1121 }
1122 return astr_str(&str);
1123}
1124
1125/************************************************************************/
1132const char *get_unit_info_label_text2(struct unit_list *punits, int linebreaks)
1133{
1134 static struct astring str = ASTRING_INIT;
1135 int count;
1136
1137 astr_clear(&str);
1138
1139 if (!punits) {
1140 return "";
1141 }
1142
1143 count = unit_list_size(punits);
1144
1145 /* This text should always have the same number of lines if
1146 * 'linebreaks' has no flags at all. Otherwise the GUI widgets may be
1147 * confused and try to resize themselves. If caller asks for
1148 * conditional 'linebreaks', it should take care of these problems
1149 * itself. */
1150
1151 /* Line 1. Goto or activity text. */
1152 if (count > 0 && hover_state != HOVER_NONE) {
1153 int min, max;
1154
1155 if (!goto_get_turns(&min, &max)) {
1156 /* TRANS: Impossible to reach goto target tile */
1157 astr_add_line(&str, "%s", Q_("?goto:Unreachable"));
1158 } else if (min == max) {
1159 astr_add_line(&str, _("Turns to target: %d"), max);
1160 } else {
1161 astr_add_line(&str, _("Turns to target: %d to %d"), min, max);
1162 }
1163 } else if (count == 1) {
1164 struct astring addition = ASTRING_INIT;
1165
1169 } else if (count > 1) {
1170 astr_add_line(&str, PL_("%d unit selected",
1171 "%d units selected",
1172 count),
1173 count);
1174 } else {
1175 astr_add_line(&str, _("No units selected."));
1176 }
1177
1178 /* Lines 2, 3, 4, and possible 5 vary. */
1179 if (count == 1) {
1180 struct unit *punit = unit_list_get(punits, 0);
1181 struct player *owner = unit_owner(punit);
1183 punit->homecity);
1184
1186 linebreaks));
1187 {
1189
1190 if (*infratext != '\0') {
1191 astr_add_line(&str, "%s", infratext);
1192 } else {
1193 astr_add_line(&str, " ");
1194 }
1195 }
1196 if (pcity) {
1198 } else {
1199 astr_add_line(&str, " ");
1200 }
1201
1203 struct player *nationality = unit_nationality(punit);
1204
1205 /* Line 5, nationality text */
1206 if (nationality != NULL && owner != nationality) {
1207 /* TRANS: Nationality of the people comprising a unit, if
1208 * different from owner. */
1209 astr_add_line(&str, _("%s people"),
1210 nation_adjective_for_player(nationality));
1211 } else {
1212 astr_add_line(&str, " ");
1213 }
1214 }
1215
1216 } else if (count > 1) {
1217 int mil = 0, nonmil = 0;
1218 int types_count[U_LAST], i;
1219 struct unit_type *top[3];
1220
1221 memset(types_count, 0, sizeof(types_count));
1224 nonmil++;
1225 } else {
1226 mil++;
1227 }
1230
1231 top[0] = top[1] = top[2] = NULL;
1232 unit_type_iterate(utype) {
1233 if (!top[2]
1234 || types_count[utype_index(top[2])] < types_count[utype_index(utype)]) {
1235 top[2] = utype;
1236
1237 if (!top[1]
1238 || types_count[utype_index(top[1])] < types_count[utype_index(top[2])]) {
1239 top[2] = top[1];
1240 top[1] = utype;
1241
1242 if (!top[0]
1243 || types_count[utype_index(top[0])] < types_count[utype_index(utype)]) {
1244 top[1] = top[0];
1245 top[0] = utype;
1246 }
1247 }
1248 }
1250
1251 for (i = 0; i < 2; i++) {
1252 if (top[i] && types_count[utype_index(top[i])] > 0) {
1253 if (utype_has_flag(top[i], UTYF_CIVILIAN)) {
1254 nonmil -= types_count[utype_index(top[i])];
1255 } else {
1256 mil -= types_count[utype_index(top[i])];
1257 }
1258 astr_add_line(&str, "%d: %s",
1259 types_count[utype_index(top[i])],
1261 } else {
1262 astr_add_line(&str, " ");
1263 }
1264 }
1265
1266 if (top[2] && types_count[utype_index(top[2])] > 0
1267 && types_count[utype_index(top[2])] == nonmil + mil) {
1268 astr_add_line(&str, "%d: %s", types_count[utype_index(top[2])],
1269 utype_name_translation(top[2]));
1270 } else if (nonmil > 0 && mil > 0) {
1271 astr_add_line(&str, _("Others: %d civil; %d military"), nonmil, mil);
1272 } else if (nonmil > 0) {
1273 astr_add_line(&str, _("Others: %d civilian"), nonmil);
1274 } else if (mil > 0) {
1275 astr_add_line(&str, _("Others: %d military"), mil);
1276 } else {
1277 astr_add_line(&str, " ");
1278 }
1279
1281 astr_add_line(&str, " ");
1282 }
1283 } else {
1284 astr_add_line(&str, " ");
1285 astr_add_line(&str, " ");
1286 astr_add_line(&str, " ");
1287
1289 astr_add_line(&str, " ");
1290 }
1291 }
1292
1293 /* Line 5/6. Debug text. */
1294#ifdef FREECIV_DEBUG
1295 if (count == 1) {
1296 astr_add_line(&str, "(Unit ID %d)", unit_list_get(punits, 0)->id);
1297 } else {
1298 astr_add_line(&str, " ");
1299 }
1300#endif /* FREECIV_DEBUG */
1301
1302 return astr_str(&str);
1303}
1304
1305/************************************************************************/
1311 struct unit_list *punits)
1312{
1313 if (unit_list_size(punits) == 0) {
1314 fc_snprintf(buf, bufsz, _("No units to upgrade!"));
1315 return FALSE;
1316 } else if (unit_list_size(punits) == 1) {
1318 } else {
1319 int upgrade_cost = 0;
1320 int num_upgraded = 0;
1322
1325 && UU_OK == unit_upgrade_test(&(wld.map), punit, FALSE)) {
1326 const struct unit_type *from_unittype = unit_type_get(punit);
1331
1332 num_upgraded++;
1333 upgrade_cost += cost;
1335 }
1337 if (num_upgraded == 0) {
1338 fc_snprintf(buf, bufsz, _("None of these units may be upgraded."));
1339 return FALSE;
1340 } else {
1341 /* This may trigger sometimes if you don't have enough money for
1342 * a full upgrade. If you have enough to upgrade at least one, it
1343 * will do it. */
1344 /* Construct prompt in several parts to allow separate pluralisation
1345 * by localizations */
1347
1348 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1349 "Treasury contains %d gold.",
1350 client_player()->economic.gold),
1351 client_player()->economic.gold);
1352 /* TRANS: this whole string is a sentence fragment that is only ever
1353 * used by including it in another string (search comments for this
1354 * string to find it) */
1355 fc_snprintf(ubuf, ARRAY_SIZE(ubuf), PL_("Upgrade %d unit",
1356 "Upgrade %d units",
1357 num_upgraded),
1358 num_upgraded);
1359 /* TRANS: This is complicated. The first %s is a pre-pluralised
1360 * sentence fragment "Upgrade %d unit(s)"; the second is pre-pluralised
1361 * "Treasury contains %d gold." So the whole thing reads
1362 * "Upgrade 13 units for 1000 gold?\nTreasury contains 2000 gold." */
1363 fc_snprintf(buf, bufsz, PL_("%s for %d gold?\n%s",
1364 "%s for %d gold?\n%s", upgrade_cost),
1366 return TRUE;
1367 }
1368 }
1369}
1370
1371/************************************************************************/
1377 struct unit_list *punits)
1378{
1379 if (unit_list_size(punits) == 0) {
1380 fc_snprintf(buf, bufsz, _("No units to disband!"));
1381 return FALSE;
1382 } else if (unit_list_size(punits) == 1) {
1385 fc_snprintf(buf, bufsz, _("%s refuses to disband!"),
1387 return FALSE;
1388 } else {
1389 /* TRANS: %s is a unit type */
1390 fc_snprintf(buf, bufsz, _("Disband %s?"),
1392 return TRUE;
1393 }
1394 } else {
1395 int count = 0;
1396
1399 count++;
1400 }
1402 if (count == 0) {
1403 fc_snprintf(buf, bufsz, _("None of these units may be disbanded."));
1404 return FALSE;
1405 } else {
1406 /* TRANS: %d is never 0 or 1 */
1407 fc_snprintf(buf, bufsz, PL_("Disband %d unit?",
1408 "Disband %d units?", count), count);
1409 return TRUE;
1410 }
1411 }
1412}
1413
1414/************************************************************************/
1420const char *get_bulb_tooltip(void)
1421{
1422 static struct astring str = ASTRING_INIT;
1423
1424 astr_clear(&str);
1425
1426 astr_add_line(&str, _("Shows your progress in "
1427 "researching the current technology."));
1428
1429 if (NULL != client.conn.playing) {
1431
1432 if (research->researching == A_UNSET) {
1433 astr_add_line(&str, _("No research target."));
1434 } else {
1435 int turns;
1438
1439 if ((turns = turns_to_research_done(research, perturn)) >= 0) {
1440 astr_set(&buf1, PL_("%d turn", "%d turns", turns), turns);
1441 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
1442 astr_set(&buf1, PL_("%d turn to loss", "%d turns to loss", turns),
1443 turns);
1444 } else {
1445 if (perturn < 0) {
1446 astr_set(&buf1, _("Decreasing"));
1447 } else {
1448 astr_set(&buf1, _("No progress"));
1449 }
1450 }
1451
1452 /* TRANS: <perturn> bulbs/turn */
1453 astr_set(&buf2, PL_("%d bulb/turn", "%d bulbs/turn", perturn), perturn);
1454
1455 /* TRANS: <tech>: <amount>/<total bulbs> */
1456 astr_add_line(&str, _("%s: %d/%d (%s, %s)."),
1461 astr_str(&buf1), astr_str(&buf2));
1462
1463 astr_free(&buf1);
1464 astr_free(&buf2);
1465 }
1466 }
1467
1468 return astr_str(&str);
1469}
1470
1471/************************************************************************/
1478{
1479 static struct astring str = ASTRING_INIT;
1480
1481 astr_clear(&str);
1482
1483 if (!game.info.global_warming) {
1484 astr_add_line(&str, _("Global warming deactivated."));
1485 } else {
1486 int chance, rate;
1487
1489 astr_add_line(&str, _("Shows the progress of global warming:"));
1490 astr_add_line(&str, _("Pollution rate: %d%%"), rate);
1491 astr_add_line(&str, _("Chance of catastrophic warming each turn: %d%%"),
1492 chance);
1493 }
1494
1495 return astr_str(&str);
1496}
1497
1498/************************************************************************/
1505{
1506 static struct astring str = ASTRING_INIT;
1507
1508 astr_clear(&str);
1509
1510 if (!game.info.nuclear_winter) {
1511 astr_add_line(&str, _("Nuclear winter deactivated."));
1512 } else {
1513 int chance, rate;
1514
1516 astr_add_line(&str, _("Shows the progress of nuclear winter:"));
1517 astr_add_line(&str, _("Fallout rate: %d%%"), rate);
1518 astr_add_line(&str, _("Chance of catastrophic winter each turn: %d%%"),
1519 chance);
1520 }
1521
1522 return astr_str(&str);
1523}
1524
1525/************************************************************************/
1531const char *get_government_tooltip(void)
1532{
1533 static struct astring str = ASTRING_INIT;
1534
1535 astr_clear(&str);
1536
1537 astr_add_line(&str, _("Shows your current government:"));
1538
1539 if (NULL != client.conn.playing) {
1540 astr_add_line(&str, "%s",
1542 }
1543
1544 return astr_str(&str);
1545}
1546
1547/************************************************************************/
1554{
1555 struct player_spaceship ship;
1556 static struct astring str = ASTRING_INIT;
1557
1558 astr_clear(&str);
1559
1560 if (!pship) {
1561 pship = &ship;
1562 memset(&ship, 0, sizeof(ship));
1563 }
1564
1565 /* TRANS: spaceship text; should have constant width. */
1566 astr_add_line(&str, _("Population: %5d"), pship->population);
1567
1568 /* TRANS: spaceship text; should have constant width. */
1569 astr_add_line(&str, _("Support: %5d %%"),
1570 (int) (pship->support_rate * 100.0));
1571
1572 /* TRANS: spaceship text; should have constant width. */
1573 astr_add_line(&str, _("Energy: %5d %%"),
1574 (int) (pship->energy_rate * 100.0));
1575
1576 /* TRANS: spaceship text; should have constant width. */
1577 astr_add_line(&str, PL_("Mass: %5d ton",
1578 "Mass: %5d tons",
1579 pship->mass), pship->mass);
1580
1581 if (pship->propulsion > 0) {
1582 /* TRANS: spaceship text; should have constant width. */
1583 astr_add_line(&str, _("Travel time: %5.1f years"),
1584 (float) (0.1 * ((int) (pship->travel_time * 10.0))));
1585 } else {
1586 /* TRANS: spaceship text; should have constant width. */
1587 astr_add_line(&str, "%s", _("Travel time: N/A "));
1588 }
1589
1590 /* TRANS: spaceship text; should have constant width. */
1591 astr_add_line(&str, _("Success prob.: %5d %%"),
1592 (int) (pship->success_rate * 100.0));
1593
1594 /* TRANS: spaceship text; should have constant width. */
1595 astr_add_line(&str, _("Year of arrival: %8s"),
1596 (pship->state == SSHIP_LAUNCHED)
1597 ? textyear((int) (pship->launch_year +
1598 (int) pship->travel_time))
1599 : "- ");
1600
1601 return astr_str(&str);
1602}
1603
1604/************************************************************************/
1610const char *get_timeout_label_text(void)
1611{
1612 static struct astring str = ASTRING_INIT;
1613
1614 astr_clear(&str);
1615
1618
1619 if (wt <= 0) {
1620 astr_add(&str, "%s", Q_("?timeout:wait"));
1621 } else {
1622 astr_add(&str, "%s: %s", Q_("?timeout:eta"), format_duration(wt));
1623 }
1624 } else {
1625 if (current_turn_timeout() <= 0) {
1626 astr_add(&str, "%s", Q_("?timeout:off"));
1627 } else {
1629 }
1630 }
1631
1632 return astr_str(&str);
1633}
1634
1635/************************************************************************/
1643static const char *format_duration(int duration)
1644{
1645 static struct astring str = ASTRING_INIT;
1646
1647 astr_clear(&str);
1648
1649 if (duration < 0) {
1650 duration = 0;
1651 }
1652 if (duration < 60) {
1653 astr_add(&str, Q_("?seconds:%02ds"), duration);
1654 } else if (duration < 3600) { /* < 60 minutes */
1655 astr_add(&str, Q_("?mins/secs:%02dm %02ds"), duration / 60, duration % 60);
1656 } else if (duration < 360000) { /* < 100 hours */
1657 astr_add(&str, Q_("?hrs/mns:%02dh %02dm"), duration / 3600, (duration / 60) % 60);
1658 } else if (duration < 8640000) { /* < 100 days */
1659 astr_add(&str, Q_("?dys/hrs:%02dd %02dh"), duration / 86400,
1660 (duration / 3600) % 24);
1661 } else {
1662 astr_add(&str, "%s", Q_("?duration:overflow"));
1663 }
1664
1665 return astr_str(&str);
1666}
1667
1668/************************************************************************/
1674const char *get_ping_time_text(const struct player *pplayer)
1675{
1676 static struct astring str = ASTRING_INIT;
1677
1678 astr_clear(&str);
1679
1681 if (!pconn->observer
1682 /* Certainly not needed, but safer. */
1683 && 0 == strcmp(pconn->username, pplayer->username)) {
1684 if (pconn->ping_time >= 0) {
1685 double ping_time_in_ms = 1000 * pconn->ping_time;
1686
1687 astr_add(&str, _("%6d.%02d ms"), (int) ping_time_in_ms,
1688 ((int) (ping_time_in_ms * 100.0)) % 100);
1689 }
1690 break;
1691 }
1693
1694 return astr_str(&str);
1695}
1696
1697/************************************************************************/
1703const char *get_score_text(const struct player *pplayer)
1704{
1705 static struct astring str = ASTRING_INIT;
1706
1707 astr_clear(&str);
1708
1709 if (pplayer->score.game >= 0) {
1710 astr_add(&str, "%d", pplayer->score.game);
1711 } else {
1712 astr_add(&str, "?");
1713 }
1714
1715 return astr_str(&str);
1716}
1717
1718/************************************************************************/
1725const char *get_report_title(const char *report_name)
1726{
1727 static struct astring str = ASTRING_INIT;
1728 const struct player *pplayer = client_player();
1729
1730 astr_clear(&str);
1731
1732 astr_add_line(&str, "%s", report_name);
1733
1734 if (pplayer != NULL) {
1735 char buf[4 * MAX_LEN_NAME];
1736
1737 /* TRANS: <nation adjective> <government name>.
1738 * E.g. "Polish Republic". */
1739 astr_add_line(&str, Q_("?nationgovernment:%s %s"),
1742
1743 /* TRANS: Just appending 2 strings, using the correct localized
1744 * syntax. */
1745 astr_add_line(&str, _("%s - %s"),
1746 ruler_title_for_player(pplayer, buf, sizeof(buf)),
1747 calendar_text());
1748 } else {
1749 /* TRANS: "Observer - 1985 AD" */
1750 astr_add_line(&str, _("Observer - %s"),
1751 calendar_text());
1752 }
1753
1754 return astr_str(&str);
1755}
1756
1757/**********************************************************************/
1764 const struct act_prob prob,
1765 const struct unit *actor_unit,
1766 const struct city *target_city)
1767{
1768 static struct astring custom = ASTRING_INIT;
1769
1771
1772 if (!action_prob_possible(prob)) {
1773 /* No info since impossible. */
1774 return NULL;
1775 }
1776
1778 || target_city != NULL),
1779 NULL);
1780
1786 TRUE);
1787
1788 if (revenue > 0) {
1790 /* TRANS: Estimated one time bonus and recurring revenue for
1791 * the Establish Trade _Route action. */
1792 _("%d one time bonus + %d trade"),
1793 revenue,
1795 } else {
1797 /* TRANS: Estimated recurring revenue for
1798 * the Establish Trade _Route action. */
1799 _("%d trade"),
1801 }
1807 FALSE);
1808
1809 if (revenue > 0) {
1811 /* TRANS: Estimated one time bonus for the Enter Marketplace
1812 * action. */
1813 _("%d one time bonus"), revenue);
1814 } else {
1815 /* No info to add. */
1816 return NULL;
1817 }
1821 /* Can only give remaining production for domestic and existing
1822 * cities. */
1824
1825 astr_set(&custom, _("%d remaining"), cost - target_city->shield_stock);
1826 } else {
1827 /* No info to add. */
1828 return NULL;
1829 }
1830
1831 return astr_str(&custom);
1832}
1833
1834/**********************************************************************/
1842const char *act_sel_action_tool_tip(const struct action *paction,
1843 const struct act_prob prob)
1844{
1845 return action_prob_explain(prob);
1846}
1847
1848/************************************************************************/
1853const char *text_happiness_buildings(const struct city *pcity)
1854{
1855 struct effect_list *plist = effect_list_new();
1856 static struct astring str = ASTRING_INIT;
1857
1859 if (0 < effect_list_size(plist)) {
1860 struct astring effects = ASTRING_INIT;
1861
1863 astr_set(&str, _("Buildings: %s."), astr_str(&effects));
1865 } else {
1866 astr_set(&str, _("Buildings: None."));
1867 }
1869
1870 /* Add line breaks after 80 characters. */
1871 astr_break_lines(&str, 80);
1872
1873 return astr_str(&str);
1874}
1875
1876/************************************************************************/
1881const char *text_happiness_nationality(const struct city *pcity)
1882{
1883 static struct astring str = ASTRING_INIT;
1884 int enemies = 0;
1885
1886 astr_clear(&str);
1887
1888 astr_add_line(&str, _("Nationality: "));
1889
1892 struct player *owner = city_owner(pcity);
1893
1894 citizens_foreign_iterate(pcity, pslot, nationality) {
1896 enemies += nationality;
1897 }
1899
1900 if (enemies > 0) {
1901 astr_add(&str, PL_("%d enemy nationalist", "%d enemy nationalists", enemies),
1902 enemies);
1903 }
1904 }
1905
1906 if (enemies == 0) {
1907 /* TRANS: No enemy nationalities, as there's no enemies present. */
1908 astr_add(&str, _("None."));
1909 }
1910 } else {
1911 /* TRANS: No nationalities present. */
1912 astr_add(&str, _("Disabled."));
1913 }
1914
1915 return astr_str(&str);
1916}
1917
1918/************************************************************************/
1923const char *text_happiness_wonders(const struct city *pcity)
1924{
1925 struct effect_list *plist = effect_list_new();
1926 static struct astring str = ASTRING_INIT;
1927
1931 if (0 < effect_list_size(plist)) {
1932 struct astring effects = ASTRING_INIT;
1933
1935 astr_set(&str, _("Wonders: %s."), astr_str(&effects));
1937 } else {
1938 astr_set(&str, _("Wonders: None."));
1939 }
1940
1941 /* Add line breaks after 80 characters. */
1942 astr_break_lines(&str, 80);
1944
1945 return astr_str(&str);
1946}
1947
1948/************************************************************************/
1953const char *text_happiness_cities(const struct city *pcity)
1954{
1955 struct player *pplayer = city_owner(pcity);
1956 int cities = city_list_size(pplayer->cities);
1957 int content = get_player_bonus(pplayer, EFT_CITY_UNHAPPY_SIZE);
1960 static struct astring str = ASTRING_INIT;
1961
1962 astr_clear(&str);
1963
1964 if (basis+step <= 0) {
1965 /* Special case where penalty is disabled; see
1966 * player_content_citizens(). */
1968 PL_("Cities: %d total, but no penalty for empire size.",
1969 "Cities: %d total, but no penalty for empire size.",
1970 cities),
1971 cities);
1973 /* TRANS: %d is number of citizens */
1974 PL_("%d content per city.",
1975 "%d content per city.", content),
1976 content);
1977 } else {
1978 /* Can have up to and including 'basis' cities without penalty */
1979 int excess = MAX(cities - basis, 0);
1980 int penalty;
1981 int unhappy, angry;
1982 int last, next;
1983
1984 if (excess > 0) {
1985 if (step > 0) {
1986 penalty = 1 + (excess - 1) / step;
1987 } else {
1988 penalty = 1;
1989 }
1990 } else {
1991 penalty = 0;
1992 }
1993
1994 unhappy = MIN(penalty, content);
1995 angry = game.info.angrycitizen ? MAX(penalty-content, 0) : 0;
1996 if (penalty >= 1) {
1997 /* 'last' is when last actual malcontent appeared, will saturate
1998 * if no angry citizens */
1999 last = basis + (unhappy+angry-1)*step;
2000 if (!game.info.angrycitizen && unhappy == content) {
2001 /* Maxed out unhappy citizens, so no more penalties */
2002 next = 0;
2003 } else {
2004 /* Angry citizens can continue appearing indefinitely */
2005 next = last + step;
2006 }
2007 } else {
2008 last = 0;
2009 next = basis;
2010 }
2011
2013 /* TRANS: sentence fragment, will have text appended */
2014 PL_("Cities: %d total:",
2015 "Cities: %d total:", cities),
2016 cities);
2017 if (excess > 0) {
2018 astr_add(&str,
2019 /* TRANS: appended to "Cities: %d total:"; preserve leading
2020 * space. Pluralized in "nearest threshold of %d cities". */
2021 PL_(" %d over nearest threshold of %d city.",
2022 " %d over nearest threshold of %d cities.", last),
2023 cities - last, last);
2025 /* TRANS: Number of content [citizen(s)] ... */
2026 PL_("%d content before penalty.",
2027 "%d content before penalty.", content),
2028 content);
2030 PL_("%d additional unhappy citizen.",
2031 "%d additional unhappy citizens.", unhappy),
2032 unhappy);
2033 if (angry > 0) {
2035 PL_("%d angry citizen.",
2036 "%d angry citizens.", angry),
2037 angry);
2038 }
2039 } else {
2040 astr_add(&str,
2041 /* TRANS: appended to "Cities: %d total:"; preserve leading
2042 * space. */
2043 PL_(" not more than %d, so no empire size penalty.",
2044 " not more than %d, so no empire size penalty.", next),
2045 next);
2047 /* TRANS: %d is number of citizens */
2048 PL_("%d content per city.",
2049 "%d content per city.", content),
2050 content);
2051 }
2052 if (next >= cities && penalty < content) {
2054 PL_("With %d more city, another citizen will become "
2055 "unhappy.",
2056 "With %d more cities, another citizen will become "
2057 "unhappy.",
2058 next + 1 - cities),
2059 next + 1 - cities);
2060 } else if (next >= cities) {
2061 /* We maxed out the number of unhappy citizens, but they can get
2062 * angry instead. */
2065 PL_("With %d more city, another citizen will become "
2066 "angry.",
2067 "With %d more cities, another citizen will become "
2068 "angry.",
2069 next + 1 - cities),
2070 next + 1 - cities);
2071 } else {
2072 /* Either no Empire_Size_Step, or we maxed out on unhappy citizens
2073 * and ruleset doesn't allow angry ones. */
2075 _("More cities will not cause more unhappy citizens."));
2076 }
2077 }
2078
2079 return astr_str(&str);
2080}
2081
2082/************************************************************************/
2087const char *text_happiness_units(const struct city *pcity)
2088{
2091 static struct astring str = ASTRING_INIT;
2092
2093 astr_clear(&str);
2094
2095 if (mlmax > 0) {
2097
2098 if (mlmax == 100) {
2099 astr_add_line(&str, "%s", _("Unlimited martial law in effect."));
2100 } else {
2101 astr_add_line(&str, PL_("%d military unit may impose martial law.",
2102 "Up to %d military units may impose martial "
2103 "law.", mlmax), mlmax);
2104 }
2105 astr_add_line(&str, PL_("Each military unit makes %d "
2106 "unhappy citizen content.",
2107 "Each military unit makes %d "
2108 "unhappy citizens content.",
2109 mleach), mleach);
2110 } else if (uhcfac > 0) {
2112 _("Military units in the field may cause unhappiness. "));
2113 } else {
2115 _("Military units have no happiness effect. "));
2116 }
2117
2118 return astr_str(&str);
2119}
2120
2121/************************************************************************/
2126const char *text_happiness_luxuries(const struct city *pcity)
2127{
2128 static struct astring str = ASTRING_INIT;
2129
2130 astr_clear(&str);
2131
2133 _("Luxury: %d total."),
2134 pcity->prod[O_LUXURY]);
2135
2136 return astr_str(&str);
2137}
2138
2139/************************************************************************/
2143const char *production_help(const struct universal *uni, char *buf,
2144 size_t bufsize)
2145{
2146 buf[0] = '\0';
2147 int segments = 0;
2148
2149 if (uni->kind == VUT_UTYPE) {
2150 if (uni->value.utype->helptext != NULL) {
2151 strvec_iterate(uni->value.utype->helptext, text) {
2152 if (segments++) {
2153 cat_snprintf(buf, bufsize, "\n\n");
2154 }
2155 cat_snprintf(buf, bufsize, "%s", _(text));
2157 }
2158 } else {
2160
2161 if (uni->value.building->helptext != NULL) {
2162 strvec_iterate(uni->value.building->helptext, text) {
2163 if (segments++) {
2164 cat_snprintf(buf, bufsize, "\n\n");
2165 }
2166 cat_snprintf(buf, bufsize, "%s", _(text));
2168 }
2169 }
2170
2171 return buf;
2172}
2173
2174/************************************************************************/
2180const char *score_tooltip(const struct player *pplayer, int score)
2181{
2182 static char buf[1024];
2183 char *relation;
2184
2185 if (client.conn.playing != NULL) {
2186 if (pplayer == client.conn.playing) {
2187 relation = _(" (us)");
2188 } else if (pplayers_allied(pplayer, client.conn.playing)) {
2189 relation = _(" (an ally)");
2190 } else if (player_diplstate_get(pplayer, client.conn.playing)->type == DS_WAR) {
2191 /* Actual enemy; don't want to use pplayers_at_war() that considers also
2192 * never met players enemies. */
2193 relation = _(" (an enemy)");
2194 } else {
2195 relation = "";
2196 }
2197 } else {
2198 relation = "";
2199 }
2200
2201 if (score >= 0) {
2202 /* TRANS: %s is a Nation */
2203 fc_snprintf(buf, sizeof(buf), _("%s%s: score %d"),
2205 score);
2206 } else {
2207 fc_snprintf(buf, sizeof(buf), "%s%s",
2209 }
2210
2211 return buf;
2212}
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:1423
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5068
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1108
#define action_has_result(_act_, _res_)
Definition actions.h:184
void astr_free(struct astring *astr)
Definition astring.c:148
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:251
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:351
void astr_add_line(struct astring *astr, const char *format,...)
Definition astring.c:283
void astr_clear(struct astring *astr)
Definition astring.c:201
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:271
#define str
Definition astring.c:76
void astr_break_lines(struct astring *astr, size_t desired_len)
Definition astring.c:302
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
#define ASTRING_INIT
Definition astring.h:44
const char * calendar_text(void)
Definition calendar.c:142
const char * textyear(int year)
Definition calendar.c:121
#define citizens_foreign_iterate_end
Definition citizens.h:63
#define citizens_foreign_iterate(_pcity, _pslot, _nationality)
Definition citizens.h:58
int city_production_build_shield_cost(const struct city *pcity)
Definition city.c:737
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
int city_airlift_max(const struct city *pcity)
Definition city.c:2942
struct output_type * get_output_type(Output_type_id output)
Definition city.c:638
bool city_is_occupied(const struct city *pcity)
Definition city.c:1665
int city_tile_output(const struct city *pcity, const struct tile *ptile, bool is_celebrating, Output_type_id otype)
Definition city.c:1283
#define city_list_iterate(citylist, pcity)
Definition city.h:505
#define city_owner(_pcity_)
Definition city.h:560
#define city_list_iterate_end
Definition city.h:507
bool client_is_global_observer(void)
int get_seconds_to_new_turn(void)
int get_seconds_to_turndone(void)
struct civclient client
bool is_waiting_turn_change(void)
bool client_has_player(void)
#define client_player()
void combat_odds_to_astr(struct astring *str, struct unit_list *punits, const struct tile *ptile, const struct unit *punit, const char *pct_str)
const char * concat_tile_activity_text(struct tile *ptile)
enum known_type client_tile_get_known(const struct tile *ptile)
Definition climap.c:36
void nuclear_winter_scaled(int *chance, int *rate, int max)
Definition climisc.c:344
void global_warming_scaled(int *chance, int *rate, int max)
Definition climisc.c:334
struct city * get_nearest_city(const struct unit *punit, int *sq_dist)
Definition climisc.c:1119
static struct fc_sockaddr_list * list
Definition clinet.c:102
char * incite_cost
Definition comments.c:76
#define MAX_LEN_MSG
Definition conn_types.h:37
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
struct unit_list * get_units_in_focus(void)
Definition control.c:177
enum cursor_hover_state hover_state
Definition control.c:89
struct unit * find_visible_unit(struct tile *ptile)
Definition control.c:822
@ HOVER_NONE
Definition control.h:26
int city_history_gain(const struct city *pcity)
Definition culture.c:39
int nation_history_gain(const struct player *pplayer)
Definition culture.c:66
struct unit * actor_unit
Definition dialogs_g.h:55
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct unit struct city * target_city
Definition dialogs_g.h:56
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
struct effect_list * effects[EFT_COUNT]
Definition effects.c:127
int get_player_output_bonus(const struct player *pplayer, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:957
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:1151
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:824
void get_effect_list_req_text(const struct effect_list *plist, struct astring *astr)
Definition effects.c:1301
static struct extra_type extras[MAX_EXTRA_TYPES]
Definition extras.c:31
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:194
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_iterate_end
Definition extras.h:321
int Tech_type_id
Definition fc_types.h:236
#define MAX_LEN_NAME
Definition fc_types.h:66
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_TRADE
Definition fc_types.h:101
@ O_SCIENCE
Definition fc_types.h:101
@ O_LUXURY
Definition fc_types.h:101
@ O_LAST
Definition fc_types.h:101
signed short Continent_id
Definition fc_types.h:231
#define LINE_BREAK
Definition fc_types.h:77
@ BORDERS_DISABLED
Definition fc_types.h:745
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * population_to_text(int thousand_citizen)
Definition game.c:739
struct civ_game game
Definition game.c:61
int current_turn_timeout(void)
Definition game.c:853
struct world wld
Definition game.c:62
int civ_population(const struct player *pplayer)
Definition game.c:73
struct city * game_city_by_number(int id)
Definition game.c:106
bool goto_get_turns(int *min, int *max)
Definition goto.c:1079
const char * ruler_title_for_player(const struct player *pplayer, char *buf, size_t buf_len)
Definition government.c:391
const char * government_name_for_player(const struct player *pplayer)
Definition government.c:154
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
static const int bufsz
Definition helpdlg.c:70
bool is_improvement_visible(const struct impr_type *pimprove)
const char * improvement_name_translation(const struct impr_type *pimprove)
Impr_type_id improvement_count(void)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
int get_continent_size(Continent_id id)
Definition map.c:819
#define nat_x
#define nat_y
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1692
int get_ocean_size(Continent_id id)
Definition map.c:830
int get_island_surrounder(Continent_id id)
Definition map.c:842
int get_lake_surrounder(Continent_id id)
Definition map.c:875
#define is_whole_continent_known(cont)
Definition map.h:78
#define is_whole_ocean_known(ocean)
Definition map.h:82
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:161
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:229
#define fc_strdup(str)
Definition mem.h:43
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:169
struct city_list * cities
Definition packhand.c:119
struct player * player_by_number(const int player_id)
Definition player.c:849
int player_count(void)
Definition player.c:817
int player_get_expected_income(const struct player *pplayer)
Definition player.c:1286
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1203
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1409
bool can_player_see_units_in_city(const struct player *pplayer, const struct city *pcity)
Definition player.c:1133
struct player * player_slot_get_player(const struct player_slot *pslot)
Definition player.c:437
#define is_ai(plr)
Definition player.h:232
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:750
bool research_goal_tech_req(const struct research *presearch, Tech_type_id goal, Tech_type_id tech)
Definition research.c:807
int research_goal_bulbs_required(const struct research *presearch, Tech_type_id goal)
Definition research.c:772
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:273
struct research * research_get(const struct player *pplayer)
Definition research.c:128
#define research_players_iterate(_presearch, _pplayer)
Definition research.h:166
#define research_players_iterate_end
Definition research.h:170
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
@ SSHIP_LAUNCHED
Definition spaceship.h:85
int step
Definition specpq.h:92
size_t size
Definition specvec.h:72
struct sprite int x
Definition sprite_g.h:31
#define strvec_iterate(psv, str)
#define strvec_iterate_end
Definition city.h:317
struct packet_game_info info
Definition game.h:89
struct packet_timeout_info tinfo
Definition game.h:91
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:151
struct strvec * helptext
Definition improvement.h:65
enum borders_mode borders
enum tech_upkeep_style tech_upkeep_style
enum airlifting_style airlifting_style
enum phase_mode_type phase_mode
bool airlift_from_always_enabled
bool airlift_to_always_enabled
enum diplstate_type type
Definition player.h:199
struct city_list * cities
Definition player.h:281
char username[MAX_LEN_NAME]
Definition player.h:252
struct team * team
Definition player.h:261
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
int culture
Definition player.h:367
char name[MAX_LEN_NAME]
Definition player.h:251
struct player_score score
Definition player.h:283
struct nation_type * nation
Definition player.h:260
struct player::@73::@76 client
Tech_type_id researching
Definition research.h:52
struct research::@79::@81 client
int researching_cost
Definition research.h:96
int bulbs_researched
Definition research.h:53
Definition team.c:40
Definition tile.h:50
bv_extras extras
Definition tile.h:55
struct unit_list * units
Definition tile.h:58
struct strvec * helptext
Definition unittype.h:576
Definition unit.h:140
int id
Definition unit.h:147
int homecity
Definition unit.h:148
struct goods_type * carrying
Definition unit.h:189
int veteran
Definition unit.h:154
enum universals_n kind
Definition fc_types.h:608
universals_u value
Definition fc_types.h:607
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
int team_count(void)
Definition team.c:375
struct team * team_by_number(const int team_id)
Definition team.c:400
const char * team_name_translation(const struct team *pteam)
Definition team.c:420
#define A_UNSET
Definition tech.h:48
const char * get_infrastructure_text(bv_extras extras)
Definition terrain.c:508
const char * get_government_tooltip(void)
Definition text.c:1531
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1953
static const char * format_duration(int duration)
Definition text.c:1643
static void get_full_username(char *buf, int buflen, const struct player *pplayer)
Definition text.c:96
const char * text_happiness_nationality(const struct city *pcity)
Definition text.c:1881
#define FAR_CITY_SQUARE_DIST
Definition text.c:488
const char * score_tooltip(const struct player *pplayer, int score)
Definition text.c:2180
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1923
bool get_units_upgrade_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1310
bool get_units_disband_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1376
static int turns_to_research_done(const struct research *presearch, int per_turn)
Definition text.c:746
const char * get_airlift_text(const struct unit_list *punits, const struct city *pdest)
Definition text.c:598
const char * get_info_label_text_popup(void)
Definition text.c:1022
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2087
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2126
const char * science_dialog_text(void)
Definition text.c:794
static int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs)
Definition text.c:702
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1853
const char * get_ping_time_text(const struct player *pplayer)
Definition text.c:1674
const char * get_report_title(const char *report_name)
Definition text.c:1725
static int turns_to_tech_loss(const struct research *presearch, int per_turn)
Definition text.c:774
const char * get_nuclear_winter_tooltip(void)
Definition text.c:1504
const char * get_score_text(const struct player *pplayer)
Definition text.c:1703
const char * get_science_target_text(double *percent)
Definition text.c:873
const char * get_bulb_tooltip(void)
Definition text.c:1420
const char * get_timeout_label_text(void)
Definition text.c:1610
const char * get_nearest_city_text(struct city *pcity, int sq_dist)
Definition text.c:494
const char * get_act_sel_action_custom_text(struct action *paction, const struct act_prob prob, const struct unit *actor_unit, const struct city *target_city)
Definition text.c:1763
const char * popup_info_text(struct tile *ptile)
Definition text.c:147
const char * unit_description(struct unit *punit)
Definition text.c:528
static void get_full_nation(char *buf, int buflen, const struct player *pplayer)
Definition text.c:120
const char * get_global_warming_tooltip(void)
Definition text.c:1477
const char * get_tile_output_text(const struct tile *ptile)
Definition text.c:63
const char * get_info_label_text(bool moreinfo)
Definition text.c:970
const char * production_help(const struct universal *uni, char *buf, size_t bufsize)
Definition text.c:2143
static int turns_per_advance(const struct research *presearch, int per_turn)
Definition text.c:761
const char * get_science_goal_text(Tech_type_id goal)
Definition text.c:919
const char * get_unit_info_label_text2(struct unit_list *punits, int linebreaks)
Definition text.c:1132
const char * get_unit_info_label_text1(struct unit_list *punits)
Definition text.c:1107
const char * get_spaceship_descr(struct player_spaceship *pship)
Definition text.c:1553
const char * act_sel_action_tool_tip(const struct action *paction, const struct act_prob prob)
Definition text.c:1842
bool tile_has_visible_extra(const struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:917
const char * tile_get_info_text(const struct tile *ptile, bool include_nuisances, int linebreaks)
Definition tile.c:771
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:89
@ TILE_UNKNOWN
Definition tile.h:36
#define tile_continent(_tile)
Definition tile.h:93
#define tile_owner(_tile)
Definition tile.h:97
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
int trade_base_between_cities(const struct city *pc1, const struct city *pc2)
struct goods_type * unit_current_goods(const struct unit *punit, const struct city *homecity)
const char * goods_name_translation(struct goods_type *pgood)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2, int priority)
int get_caravan_enter_city_trade_bonus(const struct city *pc1, const struct city *pc2, const struct unit_type *ut, struct goods_type *pgood, const bool establish_trade)
const struct unit_type * utype
Definition fc_types.h:553
const struct impr_type * building
Definition fc_types.h:546
enum unit_upgrade_result unit_upgrade_info(const struct civ_map *nmap, const struct unit *punit, char *buf, size_t bufsz)
Definition unit.c:2114
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1300
int unit_bribe_cost(const struct unit *punit, const struct player *briber, const struct unit *briber_unit)
Definition unit.c:2370
enum unit_airlift_result test_unit_can_airlift_to(const struct civ_map *nmap, const struct player *restriction, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:85
void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1286
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:401
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1210
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:2051
bool is_flagless_to_player(const struct unit *punit, const struct player *pplayer)
Definition unit.c:381
#define unit_tile(_pu)
Definition unit.h:407
#define unit_owner(_pu)
Definition unit.h:406
@ UU_OK
Definition unit.h:62
#define unit_home(_pu_)
Definition unit.h:404
unit_airlift_result
Definition unit.h:73
@ AR_SRC_NO_FLIGHTS
Definition unit.h:85
@ AR_OK_SRC_UNKNOWN
Definition unit.h:76
@ AR_OK_DST_UNKNOWN
Definition unit.h:77
@ AR_NO_MOVES
Definition unit.h:79
@ AR_BAD_DST_CITY
Definition unit.h:84
@ AR_NOT_IN_CITY
Definition unit.h:82
@ AR_OCCUPIED
Definition unit.h:81
@ AR_OK
Definition unit.h:75
@ AR_DST_NO_FLIGHTS
Definition unit.h:86
@ AR_WRONG_UNITTYPE
Definition unit.h:80
@ AR_BAD_SRC_CITY
Definition unit.h:83
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2614
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
const char * unit_name_translation(const struct unit *punit)
Definition unittype.c:1573
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1707
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:194
Unit_type_id utype_index(const struct unit_type *punittype)
Definition unittype.c:91
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1564
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:375
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1735
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:622
#define unit_type_iterate(_p)
Definition unittype.h:860
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:867