Freeciv-3.2
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
168 astr_clear(&str);
170 astr_add_line(&str, _("Location: (%d, %d) [%d]"),
171 tile_x, tile_y, tile_continent(ptile));
173 astr_add_line(&str, _("Native coordinates: (%d, %d)"),
174 nat_x, nat_y);
175 astr_add_line(&str, _("Latitude: %d"),
176 map_signed_latitude(ptile));
177
178 if (client_tile_get_known(ptile) == TILE_UNKNOWN) {
179 astr_add(&str, _("Unknown"));
180 return astr_str(&str);
181 }
182 astr_add_line(&str, _("Terrain: %s"), tile_get_info_text(ptile, TRUE, 0));
183 astr_add_line(&str, _("Food/Prod/Trade: %s"),
184 get_tile_output_text(ptile));
185 first = TRUE;
186 extra_type_iterate(pextra) {
187 if (pextra->category == ECAT_BONUS && tile_has_visible_extra(ptile, pextra)) {
188 if (!first) {
189 astr_add(&str, ",%s", extra_name_translation(pextra));
190 } else {
192 first = FALSE;
193 }
194 }
196 if (BORDERS_DISABLED != game.info.borders && !pcity) {
197 struct player *owner = tile_owner(ptile);
198
201
203 astr_add_line(&str, _("Our territory"));
204 } else if (NULL != owner && NULL == client.conn.playing) {
205 /* TRANS: "Territory of <username> (<nation + team>)" */
206 astr_add_line(&str, _("Territory of %s (%s)"), username, nation);
207 } else if (NULL != owner) {
209 owner);
210
211 if (ds->type == DS_CEASEFIRE) {
212 int turns = ds->turns_left;
213
215 /* TRANS: "Territory of <username> (<nation + team>)
216 * (<number> turn cease-fire)" */
217 PL_("Territory of %s (%s) (%d turn cease-fire)",
218 "Territory of %s (%s) (%d turn cease-fire)",
219 turns),
220 username, nation, turns);
221 } else if (ds->type == DS_ARMISTICE) {
222 int turns = ds->turns_left;
223
225 /* TRANS: "Territory of <username> (<nation + team>)
226 * (<number> turn armistice)" */
227 PL_("Territory of %s (%s) (%d turn armistice)",
228 "Territory of %s (%s) (%d turn armistice)",
229 turns),
230 username, nation, turns);
231 } else {
232 int type = ds->type;
233
234 /* TRANS: "Territory of <username>
235 * (<nation + team> | <diplomatic state>)" */
236 astr_add_line(&str, _("Territory of %s (%s | %s)"),
237 username, nation,
239 }
240 } else {
241 astr_add_line(&str, _("Unclaimed territory"));
242 }
243 }
244 if (pcity) {
245 /* Look at city owner, not tile owner (the two should be the same, if
246 * borders are in use). */
247 struct player *owner = city_owner(pcity);
248 const char *improvements[improvement_count()];
249 int has_improvements = 0;
250
253
255 /* TRANS: "City: <city name> | <username> (<nation + team>)" */
256 astr_add_line(&str, _("City: %s | %s (%s)"),
257 city_name_get(pcity), username, nation);
258 } else {
259 struct player_diplstate *ds
261 if (ds->type == DS_CEASEFIRE) {
262 int turns = ds->turns_left;
263
264 /* TRANS: "City: <city name> | <username>
265 * (<nation + team>, <number> turn cease-fire)" */
266 astr_add_line(&str, PL_("City: %s | %s (%s, %d turn cease-fire)",
267 "City: %s | %s (%s, %d turn cease-fire)",
268 turns),
269 city_name_get(pcity), username, nation, turns);
270 } else if (ds->type == DS_ARMISTICE) {
271 int turns = ds->turns_left;
272
273 /* TRANS: "City: <city name> | <username>
274 * (<nation + team>, <number> turn armistice)" */
275 astr_add_line(&str, PL_("City: %s | %s (%s, %d turn armistice)",
276 "City: %s | %s (%s, %d turn armistice)",
277 turns),
278 city_name_get(pcity), username, nation, turns);
279 } else {
280 /* TRANS: "City: <city name> | <username>
281 * (<nation + team>, <diplomatic state>)" */
282 astr_add_line(&str, _("City: %s | %s (%s, %s)"),
283 city_name_get(pcity), username, nation,
285 }
286 }
288 int count = unit_list_size(ptile->units);
289
290 if (count > 0) {
291 /* TRANS: preserve leading space */
292 astr_add(&str, PL_(" | Occupied with %d unit.",
293 " | Occupied with %d units.", count), count);
294 } else {
295 /* TRANS: preserve leading space */
296 astr_add(&str, _(" | Not occupied."));
297 }
298 } else {
299 if (city_is_occupied(pcity)) {
300 /* TRANS: preserve leading space */
301 astr_add(&str, _(" | Occupied."));
302 } else {
303 /* TRANS: preserve leading space */
304 astr_add(&str, _(" | Not occupied."));
305 }
306 }
307 improvement_iterate(pimprove) {
308 if (is_improvement_visible(pimprove)
309 && city_has_building(pcity, pimprove)) {
310 improvements[has_improvements++] =
312 }
314
315 if (0 < has_improvements) {
316 struct astring list = ASTRING_INIT;
317
319 /* TRANS: %s is a list of "and"-separated improvements. */
320 astr_add_line(&str, _(" with %s."), astr_str(&list));
321 astr_free(&list);
322 }
323
325 struct city *hcity = game_city_by_number(pfocus_unit->homecity);
326
328 && can_cities_trade(hcity, pcity)
329 && can_establish_trade_route(hcity, pcity)) {
330 /* TRANS: "Trade from Warsaw: 5" */
331 astr_add_line(&str, _("Trade from %s: %d"),
334 }
336 }
337 {
338 const char *infratext = get_infrastructure_text(ptile->extras);
339
340 if (*infratext != '\0') {
341 astr_add_line(&str, _("Infrastructure: %s"), infratext);
342 }
343 }
345 if (strlen(activity_text) > 0) {
346 astr_add_line(&str, _("Activity: %s"), activity_text);
347 }
348 if (punit && !pcity) {
349 struct player *owner = unit_owner(punit);
350 const struct unit_type *ptype = unit_type_get(punit);
351
352 get_full_username(username, sizeof(username), owner);
353 get_full_nation(nation, sizeof(nation), owner);
354
355 if (!client_player() || owner == client_player()) {
357
358 /* TRANS: "Unit: <unit type> | <username> (<nation + team>)" */
359 astr_add_line(&str, _("Unit: %s | %s (%s)"),
360 utype_name_translation(ptype), username, nation);
361
364 if (hcity != NULL) {
365 /* TRANS: on own line immediately following \n, "from <city> |
366 * <nationality> people" */
367 astr_add_line(&str, _("from %s | %s people"), city_name_get(hcity),
369 } else {
370 /* TRANS: Nationality of the people comprising a unit, if
371 * different from owner. */
372 astr_add_line(&str, _("%s people"),
374 }
375 } else if (hcity != NULL) {
376 /* TRANS: on own line immediately following \n, ... <city> */
377 astr_add_line(&str, _("from %s"), city_name_get(hcity));
378 }
379 if (punit->carrying
381 /* TRANS: on own line immediately following \n, from ... */
382 astr_add_line(&str, _("carrying %s"),
384 }
385 } else if (NULL != owner) {
387 owner);
388 if (ds->type == DS_CEASEFIRE) {
389 int turns = ds->turns_left;
390
391 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
392 * <number> turn cease-fire)" */
393 astr_add_line(&str, PL_("Unit: %s | %s (%s, %d turn cease-fire)",
394 "Unit: %s | %s (%s, %d turn cease-fire)",
395 turns),
397 username, nation, turns);
398 } else if (ds->type == DS_ARMISTICE) {
399 int turns = ds->turns_left;
400
401 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
402 * <number> turn armistice)" */
403 astr_add_line(&str, PL_("Unit: %s | %s (%s, %d turn armistice)",
404 "Unit: %s | %s (%s, %d turn armistice)",
405 turns),
407 username, nation, turns);
408 } else {
409 /* TRANS: "Unit: <unit type> | <username> (<nation + team>,
410 * <diplomatic state>)" */
411 astr_add_line(&str, _("Unit: %s | %s (%s, %s)"),
412 utype_name_translation(ptype), username, nation,
414 }
415 }
416
418
421 /* Show bribe cost for own units. */
422 astr_add_line(&str, _("Probable bribe cost: %d"),
424 } else {
425 /* We can only give an (lower) boundary for units of other players. */
426 astr_add_line(&str, _("Estimated bribe cost: > %d"),
428 }
429
431 && unit_list_size(ptile->units) >= 2) {
432 /* TRANS: "5 more" units on this tile */
433 astr_add(&str, _(" (%d more)"), unit_list_size(ptile->units) - 1);
434 }
435 }
436
438 return astr_str(&str);
439}
440
441#define FAR_CITY_SQUARE_DIST (2*(6*6))
442/************************************************************************/
447const char *get_nearest_city_text(struct city *pcity, int sq_dist)
448{
449 static struct astring str = ASTRING_INIT;
450
451 astr_clear(&str);
452
453 /* Just to be sure */
454 if (!pcity) {
455 sq_dist = -1;
456 }
457
459 /* TRANS: on own line immediately following \n, ... <city> */
460 ? _("far from %s")
461 : (sq_dist > 0)
462 /* TRANS: on own line immediately following \n, ... <city> */
463 ? _("near %s")
464 : (sq_dist == 0)
465 /* TRANS: on own line immediately following \n, ... <city> */
466 ? _("in %s")
467 : "%s",
468 pcity
469 ? city_name_get(pcity)
470 : "");
471
472 return astr_str(&str);
473}
474
475/************************************************************************/
481const char *unit_description(struct unit *punit)
482{
483 int pcity_near_dist;
484 struct player *owner = unit_owner(punit);
485 struct player *nationality = unit_nationality(punit);
486 struct city *pcity =
489 const struct unit_type *ptype = unit_type_get(punit);
490 static struct astring str = ASTRING_INIT;
491 const struct player *pplayer = client_player();
492
493 astr_clear(&str);
494
496
497 {
498 const char *veteran_name =
500 if (veteran_name) {
501 astr_add(&str, " (%s)", veteran_name);
502 }
503 }
504
505 if (pplayer == owner) {
507 } else {
508 astr_add(&str, "\n");
509 }
511
512 if (pcity) {
513 /* TRANS: on own line immediately following \n, ... <city> */
514 astr_add_line(&str, _("from %s"), city_name_get(pcity));
515 } else {
516 astr_add(&str, "\n");
517 }
519 if (nationality != NULL && owner != nationality) {
520 /* TRANS: Nationality of the people comprising a unit, if
521 * different from owner. */
522 astr_add_line(&str, _("%s people"),
523 nation_adjective_for_player(nationality));
524 } else {
525 astr_add(&str, "\n");
526 }
527 }
528
529 astr_add_line(&str, "%s",
531#ifdef FREECIV_DEBUG
532 astr_add_line(&str, "Unit ID: %d", punit->id);
533#endif
534
535 return astr_str(&str);
536}
537
538/************************************************************************/
551const char *get_airlift_text(const struct unit_list *punits,
552 const struct city *pdest)
553{
554 static struct astring str = ASTRING_INIT;
555 bool src = (pdest == NULL);
557 best = AL_IMPOSSIBLE;
558 int cur = 0, max = 0;
559
561 enum texttype this = AL_IMPOSSIBLE;
562 enum unit_airlift_result result;
563
564 /* NULL will tell us about the capability of airlifting from source */
566
567 switch (result) {
568 case AR_NO_MOVES:
570 case AR_OCCUPIED:
571 case AR_NOT_IN_CITY:
572 case AR_BAD_SRC_CITY:
573 case AR_BAD_DST_CITY:
574 /* No chance of an airlift. */
575 this = AL_IMPOSSIBLE;
576 break;
577 case AR_OK:
582 /* May or may not be able to airlift now, but there's a chance we could
583 * later */
584 {
585 const struct city *pcity = src ? tile_city(unit_tile(punit)) : pdest;
586
587 fc_assert_ret_val(pcity != NULL, fc_strdup("-"));
590 /* No restrictions on destination (and we can infer this even for
591 * other players' cities). */
592 this = AL_INFINITE;
595 this = AL_INFINITE;
596 } else if (client_player() == city_owner(pcity)) {
597 /* A city we know about. */
598 int this_cur = pcity->airlift, this_max = city_airlift_max(pcity);
599
600 if (this_max <= 0) {
601 /* City known not to be airlift-capable. */
602 this = AL_IMPOSSIBLE;
603 } else {
604 if (src
606 /* Unlimited capacity. */
607 this = AL_INFINITE;
608 } else if (!src
610 this = AL_INFINITE;
611 } else {
612 /* Limited capacity (possibly zero right now). */
613 this = AL_FINITE;
614 /* Store the numbers. This whole setup assumes that numeric
615 * capacity isn't unit-dependent. */
616 if (best == AL_FINITE) {
617 fc_assert(cur == this_cur && max == this_max);
618 }
619 cur = this_cur;
620 max = this_max;
621 }
622 }
623 } else {
624 /* Unknown capacity. */
625 this = AL_UNKNOWN;
626 }
627 }
628 break;
629 }
630
631 /* Now take the most optimistic view. */
632 best = MAX(best, this);
634
635 switch (best) {
636 case AL_IMPOSSIBLE:
637 return NULL;
638 case AL_UNKNOWN:
639 astr_set(&str, "?");
640 break;
641 case AL_FINITE:
642 astr_set(&str, "%d/%d", cur, max);
643 break;
644 case AL_INFINITE:
645 astr_set(&str, _("Yes"));
646 break;
647 }
648
649 return astr_str(&str);
650}
651
652/************************************************************************/
655static int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs)
656{
657 const struct research *presearch;
658 int ours = 0, theirs = 0;
659 bool team = FALSE;
660
661 if (!client_has_player()) {
662 return 0;
663 }
665
666 /* Sum up science */
668 if (pplayer == client_player()) {
669 city_list_iterate(pplayer->cities, pcity) {
670 ours += pcity->surplus[O_SCIENCE];
672 } else {
673 team = TRUE;
674 theirs -= pplayer->client.tech_upkeep;
675 }
677
678 if (team) {
679 theirs += presearch->client.total_bulbs_prod - ours;
680 }
681 ours -= client_player()->client.tech_upkeep;
682
683 if (pours) {
684 *pours = ours;
685 }
686 if (pteam) {
687 *pteam = team;
688 }
689 if (ptheirs) {
690 *ptheirs = theirs;
691 }
692
693 return ours + theirs;
694}
695
696/************************************************************************/
700 int per_turn)
701{
702 if (per_turn > 0) {
703 return ceil((double)(presearch->client.researching_cost
704 - presearch->bulbs_researched) / per_turn);
705 } else {
706 return -1;
707 }
708}
709
710/************************************************************************/
714static int turns_per_advance(const struct research *presearch, int per_turn)
715{
716 if (per_turn > 0) {
717 return MAX(1, ceil((double)presearch->client.researching_cost) / per_turn);
718 } else {
719 return -1;
720 }
721}
722
723/************************************************************************/
727static int turns_to_tech_loss(const struct research *presearch, int per_turn)
728{
729 if (per_turn >= 0 || game.info.techloss_forgiveness == -1) {
730 /* With techloss_forgiveness == -1, we'll never lose a tech, just
731 * get further into debt. */
732 return -1;
733 } else {
734 int bulbs_to_loss = presearch->bulbs_researched
735 + (presearch->client.researching_cost
737
738 return ceil((double)bulbs_to_loss / -per_turn);
739 }
740}
741
742/************************************************************************/
747const char *science_dialog_text(void)
748{
749 bool team;
750 int ours, theirs, perturn, upkeep;
751 static struct astring str = ASTRING_INIT;
753 struct research *research;
754
755 astr_clear(&str);
756
758
760 upkeep = client_player()->client.tech_upkeep;
761
762 if (NULL == client.conn.playing || (ours == 0 && theirs == 0
763 && upkeep == 0)) {
764 return _("Progress: no research");
765 }
766
767 if (A_UNSET == research->researching) {
768 astr_add(&str, _("Progress: no research"));
769 } else {
770 int turns;
771
772 if ((turns = turns_per_advance(research, perturn)) >= 0) {
773 astr_add(&str, PL_("Progress: %d turn/advance",
774 "Progress: %d turns/advance",
775 turns), turns);
776 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
777 /* FIXME: turns to next loss is not a good predictor of turns to
778 * following loss, due to techloss_restore etc. But it'll do. */
779 astr_add(&str, PL_("Progress: %d turn/advance loss",
780 "Progress: %d turns/advance loss",
781 turns), turns);
782 } else {
783 /* no forward progress -- no research, or tech loss disallowed */
784 if (perturn < 0) {
785 astr_add(&str, _("Progress: decreasing!"));
786 } else {
787 astr_add(&str, _("Progress: none"));
788 }
789 }
790 }
791 astr_set(&ourbuf, PL_("%d bulb/turn", "%d bulbs/turn", ours), ours);
792 if (team) {
793 /* Techpool version */
795 /* TRANS: This is appended to "%d bulb/turn" text */
796 PL_(", %d bulb/turn from team",
797 ", %d bulbs/turn from team", theirs), theirs);
798 } else {
800 }
801 astr_add(&str, " (%s%s)", astr_str(&ourbuf), astr_str(&theirbuf));
804
806 /* perturn is defined as: (bulbs produced) - upkeep */
807 astr_add_line(&str, _("Bulbs produced per turn: %d"), perturn + upkeep);
808 /* TRANS: keep leading space; appended to "Bulbs produced per turn: %d" */
809 astr_add(&str, _(" (needed for technology upkeep: %d)"), upkeep);
810 }
811
812 return astr_str(&str);
813}
814
815/************************************************************************/
827{
829 static struct astring str = ASTRING_INIT;
830
831 if (!research) {
832 return "-";
833 }
834
835 astr_clear(&str);
836 if (research->researching == A_UNSET) {
837 astr_add(&str, _("%d/- (never)"), research->bulbs_researched);
838 if (percent) {
839 *percent = 0.0;
840 }
841 } else {
842 int total = research->client.researching_cost;
843 int done = research->bulbs_researched;
845 int turns;
846
847 if ((turns = turns_to_research_done(research, perturn)) >= 0) {
848 astr_add(&str, PL_("%d/%d (%d turn)", "%d/%d (%d turns)", turns),
849 done, total, turns);
850 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
851 astr_add(&str, PL_("%d/%d (%d turn to loss)",
852 "%d/%d (%d turns to loss)", turns),
853 done, total, turns);
854 } else {
855 /* no forward progress -- no research, or tech loss disallowed */
856 astr_add(&str, _("%d/%d (never)"), done, total);
857 }
858 if (percent) {
859 *percent = (double)done / (double)total;
860 *percent = CLIP(0.0, *percent, 1.0);
861 }
862 }
863
864 return astr_str(&str);
865}
866
867/************************************************************************/
873{
874 const struct research *research = research_get(client_player());
875 int steps = research_goal_unknown_techs(research, goal);
877 int turns;
879 static struct astring str = ASTRING_INIT;
880 struct astring buf1 = ASTRING_INIT,
883
884 if (!research) {
885 return "-";
886 }
887
888 astr_clear(&str);
889
891 || research->researching == goal) {
893 }
894
895 astr_set(&buf1,
896 PL_("%d step", "%d steps", steps), steps);
897 astr_set(&buf2,
898 PL_("%d bulb", "%d bulbs", bulbs_needed), bulbs_needed);
899 if (perturn > 0) {
900 turns = (bulbs_needed + perturn - 1) / perturn;
901 astr_set(&buf3,
902 PL_("%d turn", "%d turns", turns), turns);
903 } else {
904 astr_set(&buf3, _("never"));
905 }
906 astr_add_line(&str, "(%s - %s - %s)",
908 astr_free(&buf1);
909 astr_free(&buf2);
910 astr_free(&buf3);
911
912 return astr_str(&str);
913}
914
915/************************************************************************/
924{
925 static struct astring str = ASTRING_INIT;
926
927 astr_clear(&str);
928
929 if (NULL != client.conn.playing) {
930 astr_add_line(&str, _("Population: %s"),
932 }
933 astr_add_line(&str, _("Year: %s (T%d)"),
935
936 if (NULL != client.conn.playing) {
937 astr_add_line(&str, _("Gold: %d (%+d)"),
940 astr_add_line(&str, _("Tax: %d Lux: %d Sci: %d"),
944 }
946 if (game.info.phase < 0 || game.info.phase >= player_count()) {
947 astr_add_line(&str, _("Moving: Nobody"));
948 } else {
949 astr_add_line(&str, _("Moving: %s"),
951 }
952 } else if (game.info.phase_mode == PMT_TEAMS_ALTERNATE) {
953 if (game.info.phase < 0 || game.info.phase >= team_count()) {
954 astr_add_line(&str, _("Moving: Nobody"));
955 } else {
956 astr_add_line(&str, _("Moving: %s"),
958 }
959 }
960
961 if (moreinfo) {
962 astr_add_line(&str, _("(Click for more info)"));
963 }
964
965 return astr_str(&str);
966}
967
968/************************************************************************/
976{
977 static struct astring str = ASTRING_INIT;
978
979 astr_clear(&str);
980
981 if (NULL != client.conn.playing) {
982 astr_add_line(&str, _("%s People"),
984 }
985 astr_add_line(&str, _("Year: %s"), calendar_text());
986 astr_add_line(&str, _("Turn: %d"), game.info.turn);
987
988 if (NULL != client.conn.playing) {
989 const struct research *presearch = research_get(client_player());
991 int upkeep = client_player()->client.tech_upkeep;
992
993 astr_add_line(&str, _("Gold: %d"),
995 astr_add_line(&str, _("Net Income: %d"),
997 /* TRANS: Gold, luxury, and science rates are in percentage values. */
998 astr_add_line(&str, _("Tax rates: Gold:%d%% Luxury:%d%% Science:%d%%"),
1002 astr_add_line(&str, _("Researching %s: %s"),
1004 presearch->researching),
1006 /* perturn is defined as: (bulbs produced) - upkeep */
1008 astr_add_line(&str, _("Bulbs per turn: %d - %d = %d"), perturn + upkeep,
1009 upkeep, perturn);
1010 } else {
1011 fc_assert(upkeep == 0);
1012 astr_add_line(&str, _("Bulbs per turn: %d"), perturn);
1013 }
1014 {
1016
1020 astr_add_line(&str, _("Culture: %d (%+d/turn)"),
1022 }
1023 }
1024
1025 /* See also get_global_warming_tooltip() and get_nuclear_winter_tooltip(). */
1026
1027 if (game.info.global_warming) {
1028 int chance, rate;
1030 astr_add_line(&str, _("Global warming chance: %d%% (%+d%%/turn)"),
1031 chance, rate);
1032 } else {
1033 astr_add_line(&str, _("Global warming deactivated."));
1034 }
1035
1036 if (game.info.nuclear_winter) {
1037 int chance, rate;
1039 astr_add_line(&str, _("Nuclear winter chance: %d%% (%+d%%/turn)"),
1040 chance, rate);
1041 } else {
1042 astr_add_line(&str, _("Nuclear winter deactivated."));
1043 }
1044
1045 if (NULL != client.conn.playing) {
1046 astr_add_line(&str, _("Government: %s"),
1048 }
1049
1050 return astr_str(&str);
1051}
1052
1053/************************************************************************/
1060const char *get_unit_info_label_text1(struct unit_list *punits)
1061{
1062 static struct astring str = ASTRING_INIT;
1063
1064 astr_clear(&str);
1065
1066 if (punits) {
1067 int count = unit_list_size(punits);
1068
1069 if (count == 1) {
1071 } else {
1072 astr_add(&str, PL_("%d unit", "%d units", count), count);
1073 }
1074 }
1075 return astr_str(&str);
1076}
1077
1078/************************************************************************/
1085const char *get_unit_info_label_text2(struct unit_list *punits, int linebreaks)
1086{
1087 static struct astring str = ASTRING_INIT;
1088 int count;
1089
1090 astr_clear(&str);
1091
1092 if (!punits) {
1093 return "";
1094 }
1095
1096 count = unit_list_size(punits);
1097
1098 /* This text should always have the same number of lines if
1099 * 'linebreaks' has no flags at all. Otherwise the GUI widgets may be
1100 * confused and try to resize themselves. If caller asks for
1101 * conditional 'linebreaks', it should take care of these problems
1102 * itself. */
1103
1104 /* Line 1. Goto or activity text. */
1105 if (count > 0 && hover_state != HOVER_NONE) {
1106 int min, max;
1107
1108 if (!goto_get_turns(&min, &max)) {
1109 /* TRANS: Impossible to reach goto target tile */
1110 astr_add_line(&str, "%s", Q_("?goto:Unreachable"));
1111 } else if (min == max) {
1112 astr_add_line(&str, _("Turns to target: %d"), max);
1113 } else {
1114 astr_add_line(&str, _("Turns to target: %d to %d"), min, max);
1115 }
1116 } else if (count == 1) {
1117 struct astring addition = ASTRING_INIT;
1118
1122 } else if (count > 1) {
1123 astr_add_line(&str, PL_("%d unit selected",
1124 "%d units selected",
1125 count),
1126 count);
1127 } else {
1128 astr_add_line(&str, _("No units selected."));
1129 }
1130
1131 /* Lines 2, 3, 4, and possible 5 vary. */
1132 if (count == 1) {
1133 struct unit *punit = unit_list_get(punits, 0);
1134 struct player *owner = unit_owner(punit);
1135 struct city *pcity = player_city_by_number(owner,
1136 punit->homecity);
1137
1139 linebreaks));
1140 {
1142
1143 if (*infratext != '\0') {
1144 astr_add_line(&str, "%s", infratext);
1145 } else {
1146 astr_add_line(&str, " ");
1147 }
1148 }
1149 if (pcity) {
1150 astr_add_line(&str, "%s", city_name_get(pcity));
1151 } else {
1152 astr_add_line(&str, " ");
1153 }
1154
1156 struct player *nationality = unit_nationality(punit);
1157
1158 /* Line 5, nationality text */
1159 if (nationality != NULL && owner != nationality) {
1160 /* TRANS: Nationality of the people comprising a unit, if
1161 * different from owner. */
1162 astr_add_line(&str, _("%s people"),
1163 nation_adjective_for_player(nationality));
1164 } else {
1165 astr_add_line(&str, " ");
1166 }
1167 }
1168
1169 } else if (count > 1) {
1170 int mil = 0, nonmil = 0;
1171 int types_count[U_LAST], i;
1172 struct unit_type *top[3];
1173
1174 memset(types_count, 0, sizeof(types_count));
1177 nonmil++;
1178 } else {
1179 mil++;
1180 }
1183
1184 top[0] = top[1] = top[2] = NULL;
1185 unit_type_iterate(utype) {
1186 if (!top[2]
1187 || types_count[utype_index(top[2])] < types_count[utype_index(utype)]) {
1188 top[2] = utype;
1189
1190 if (!top[1]
1191 || types_count[utype_index(top[1])] < types_count[utype_index(top[2])]) {
1192 top[2] = top[1];
1193 top[1] = utype;
1194
1195 if (!top[0]
1196 || types_count[utype_index(top[0])] < types_count[utype_index(utype)]) {
1197 top[1] = top[0];
1198 top[0] = utype;
1199 }
1200 }
1201 }
1203
1204 for (i = 0; i < 2; i++) {
1205 if (top[i] && types_count[utype_index(top[i])] > 0) {
1206 if (utype_has_flag(top[i], UTYF_CIVILIAN)) {
1207 nonmil -= types_count[utype_index(top[i])];
1208 } else {
1209 mil -= types_count[utype_index(top[i])];
1210 }
1211 astr_add_line(&str, "%d: %s",
1212 types_count[utype_index(top[i])],
1214 } else {
1215 astr_add_line(&str, " ");
1216 }
1217 }
1218
1219 if (top[2] && types_count[utype_index(top[2])] > 0
1220 && types_count[utype_index(top[2])] == nonmil + mil) {
1221 astr_add_line(&str, "%d: %s", types_count[utype_index(top[2])],
1222 utype_name_translation(top[2]));
1223 } else if (nonmil > 0 && mil > 0) {
1224 astr_add_line(&str, _("Others: %d civil; %d military"), nonmil, mil);
1225 } else if (nonmil > 0) {
1226 astr_add_line(&str, _("Others: %d civilian"), nonmil);
1227 } else if (mil > 0) {
1228 astr_add_line(&str, _("Others: %d military"), mil);
1229 } else {
1230 astr_add_line(&str, " ");
1231 }
1232
1234 astr_add_line(&str, " ");
1235 }
1236 } else {
1237 astr_add_line(&str, " ");
1238 astr_add_line(&str, " ");
1239 astr_add_line(&str, " ");
1240
1242 astr_add_line(&str, " ");
1243 }
1244 }
1245
1246 /* Line 5/6. Debug text. */
1247#ifdef FREECIV_DEBUG
1248 if (count == 1) {
1249 astr_add_line(&str, "(Unit ID %d)", unit_list_get(punits, 0)->id);
1250 } else {
1251 astr_add_line(&str, " ");
1252 }
1253#endif /* FREECIV_DEBUG */
1254
1255 return astr_str(&str);
1256}
1257
1258/************************************************************************/
1264 struct unit_list *punits)
1265{
1266 if (unit_list_size(punits) == 0) {
1267 fc_snprintf(buf, bufsz, _("No units to upgrade!"));
1268 return FALSE;
1269 } else if (unit_list_size(punits) == 1) {
1271 } else {
1272 int upgrade_cost = 0;
1273 int num_upgraded = 0;
1275
1278 && UU_OK == unit_upgrade_test(&(wld.map), punit, FALSE)) {
1279 const struct unit_type *from_unittype = unit_type_get(punit);
1284
1285 num_upgraded++;
1286 upgrade_cost += cost;
1288 }
1290 if (num_upgraded == 0) {
1291 fc_snprintf(buf, bufsz, _("None of these units may be upgraded."));
1292 return FALSE;
1293 } else {
1294 /* This may trigger sometimes if you don't have enough money for
1295 * a full upgrade. If you have enough to upgrade at least one, it
1296 * will do it. */
1297 /* Construct prompt in several parts to allow separate pluralisation
1298 * by localizations */
1300
1301 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1302 "Treasury contains %d gold.",
1303 client_player()->economic.gold),
1304 client_player()->economic.gold);
1305 /* TRANS: this whole string is a sentence fragment that is only ever
1306 * used by including it in another string (search comments for this
1307 * string to find it) */
1308 fc_snprintf(ubuf, ARRAY_SIZE(ubuf), PL_("Upgrade %d unit",
1309 "Upgrade %d units",
1310 num_upgraded),
1311 num_upgraded);
1312 /* TRANS: This is complicated. The first %s is a pre-pluralised
1313 * sentence fragment "Upgrade %d unit(s)"; the second is pre-pluralised
1314 * "Treasury contains %d gold." So the whole thing reads
1315 * "Upgrade 13 units for 1000 gold?\nTreasury contains 2000 gold." */
1316 fc_snprintf(buf, bufsz, PL_("%s for %d gold?\n%s",
1317 "%s for %d gold?\n%s", upgrade_cost),
1319 return TRUE;
1320 }
1321 }
1322}
1323
1324/************************************************************************/
1330 struct unit_list *punits)
1331{
1332 if (unit_list_size(punits) == 0) {
1333 fc_snprintf(buf, bufsz, _("No units to disband!"));
1334 return FALSE;
1335 } else if (unit_list_size(punits) == 1) {
1338 fc_snprintf(buf, bufsz, _("%s refuses to disband!"),
1340 return FALSE;
1341 } else {
1342 /* TRANS: %s is a unit type */
1343 fc_snprintf(buf, bufsz, _("Disband %s?"),
1345 return TRUE;
1346 }
1347 } else {
1348 int count = 0;
1349
1352 count++;
1353 }
1355 if (count == 0) {
1356 fc_snprintf(buf, bufsz, _("None of these units may be disbanded."));
1357 return FALSE;
1358 } else {
1359 /* TRANS: %d is never 0 or 1 */
1360 fc_snprintf(buf, bufsz, PL_("Disband %d unit?",
1361 "Disband %d units?", count), count);
1362 return TRUE;
1363 }
1364 }
1365}
1366
1367/************************************************************************/
1373const char *get_bulb_tooltip(void)
1374{
1375 static struct astring str = ASTRING_INIT;
1376
1377 astr_clear(&str);
1378
1379 astr_add_line(&str, _("Shows your progress in "
1380 "researching the current technology."));
1381
1382 if (NULL != client.conn.playing) {
1384
1385 if (research->researching == A_UNSET) {
1386 astr_add_line(&str, _("No research target."));
1387 } else {
1388 int turns;
1391
1392 if ((turns = turns_to_research_done(research, perturn)) >= 0) {
1393 astr_set(&buf1, PL_("%d turn", "%d turns", turns), turns);
1394 } else if ((turns = turns_to_tech_loss(research, perturn)) >= 0) {
1395 astr_set(&buf1, PL_("%d turn to loss", "%d turns to loss", turns),
1396 turns);
1397 } else {
1398 if (perturn < 0) {
1399 astr_set(&buf1, _("Decreasing"));
1400 } else {
1401 astr_set(&buf1, _("No progress"));
1402 }
1403 }
1404
1405 /* TRANS: <perturn> bulbs/turn */
1406 astr_set(&buf2, PL_("%d bulb/turn", "%d bulbs/turn", perturn), perturn);
1407
1408 /* TRANS: <tech>: <amount>/<total bulbs> */
1409 astr_add_line(&str, _("%s: %d/%d (%s, %s)."),
1414 astr_str(&buf1), astr_str(&buf2));
1415
1416 astr_free(&buf1);
1417 astr_free(&buf2);
1418 }
1419 }
1420
1421 return astr_str(&str);
1422}
1423
1424/************************************************************************/
1431{
1432 static struct astring str = ASTRING_INIT;
1433
1434 astr_clear(&str);
1435
1436 if (!game.info.global_warming) {
1437 astr_add_line(&str, _("Global warming deactivated."));
1438 } else {
1439 int chance, rate;
1440
1442 astr_add_line(&str, _("Shows the progress of global warming:"));
1443 astr_add_line(&str, _("Pollution rate: %d%%"), rate);
1444 astr_add_line(&str, _("Chance of catastrophic warming each turn: %d%%"),
1445 chance);
1446 }
1447
1448 return astr_str(&str);
1449}
1450
1451/************************************************************************/
1458{
1459 static struct astring str = ASTRING_INIT;
1460
1461 astr_clear(&str);
1462
1463 if (!game.info.nuclear_winter) {
1464 astr_add_line(&str, _("Nuclear winter deactivated."));
1465 } else {
1466 int chance, rate;
1467
1469 astr_add_line(&str, _("Shows the progress of nuclear winter:"));
1470 astr_add_line(&str, _("Fallout rate: %d%%"), rate);
1471 astr_add_line(&str, _("Chance of catastrophic winter each turn: %d%%"),
1472 chance);
1473 }
1474
1475 return astr_str(&str);
1476}
1477
1478/************************************************************************/
1484const char *get_government_tooltip(void)
1485{
1486 static struct astring str = ASTRING_INIT;
1487
1488 astr_clear(&str);
1489
1490 astr_add_line(&str, _("Shows your current government:"));
1491
1492 if (NULL != client.conn.playing) {
1493 astr_add_line(&str, "%s",
1495 }
1496
1497 return astr_str(&str);
1498}
1499
1500/************************************************************************/
1507{
1508 struct player_spaceship ship;
1509 static struct astring str = ASTRING_INIT;
1510
1511 astr_clear(&str);
1512
1513 if (!pship) {
1514 pship = &ship;
1515 memset(&ship, 0, sizeof(ship));
1516 }
1517
1518 /* TRANS: spaceship text; should have constant width. */
1519 astr_add_line(&str, _("Population: %5d"), pship->population);
1520
1521 /* TRANS: spaceship text; should have constant width. */
1522 astr_add_line(&str, _("Support: %5d %%"),
1523 (int) (pship->support_rate * 100.0));
1524
1525 /* TRANS: spaceship text; should have constant width. */
1526 astr_add_line(&str, _("Energy: %5d %%"),
1527 (int) (pship->energy_rate * 100.0));
1528
1529 /* TRANS: spaceship text; should have constant width. */
1530 astr_add_line(&str, PL_("Mass: %5d ton",
1531 "Mass: %5d tons",
1532 pship->mass), pship->mass);
1533
1534 if (pship->propulsion > 0) {
1535 /* TRANS: spaceship text; should have constant width. */
1536 astr_add_line(&str, _("Travel time: %5.1f years"),
1537 (float) (0.1 * ((int) (pship->travel_time * 10.0))));
1538 } else {
1539 /* TRANS: spaceship text; should have constant width. */
1540 astr_add_line(&str, "%s", _("Travel time: N/A "));
1541 }
1542
1543 /* TRANS: spaceship text; should have constant width. */
1544 astr_add_line(&str, _("Success prob.: %5d %%"),
1545 (int) (pship->success_rate * 100.0));
1546
1547 /* TRANS: spaceship text; should have constant width. */
1548 astr_add_line(&str, _("Year of arrival: %8s"),
1549 (pship->state == SSHIP_LAUNCHED)
1550 ? textyear((int) (pship->launch_year +
1551 (int) pship->travel_time))
1552 : "- ");
1553
1554 return astr_str(&str);
1555}
1556
1557/************************************************************************/
1563const char *get_timeout_label_text(void)
1564{
1565 static struct astring str = ASTRING_INIT;
1566
1567 astr_clear(&str);
1568
1571
1572 if (wt <= 0) {
1573 astr_add(&str, "%s", Q_("?timeout:wait"));
1574 } else {
1575 astr_add(&str, "%s: %s", Q_("?timeout:eta"), format_duration(wt));
1576 }
1577 } else {
1578 if (current_turn_timeout() <= 0) {
1579 astr_add(&str, "%s", Q_("?timeout:off"));
1580 } else {
1582 }
1583 }
1584
1585 return astr_str(&str);
1586}
1587
1588/************************************************************************/
1596static const char *format_duration(int duration)
1597{
1598 static struct astring str = ASTRING_INIT;
1599
1600 astr_clear(&str);
1601
1602 if (duration < 0) {
1603 duration = 0;
1604 }
1605 if (duration < 60) {
1606 astr_add(&str, Q_("?seconds:%02ds"), duration);
1607 } else if (duration < 3600) { /* < 60 minutes */
1608 astr_add(&str, Q_("?mins/secs:%02dm %02ds"), duration / 60, duration % 60);
1609 } else if (duration < 360000) { /* < 100 hours */
1610 astr_add(&str, Q_("?hrs/mns:%02dh %02dm"), duration / 3600, (duration / 60) % 60);
1611 } else if (duration < 8640000) { /* < 100 days */
1612 astr_add(&str, Q_("?dys/hrs:%02dd %02dh"), duration / 86400,
1613 (duration / 3600) % 24);
1614 } else {
1615 astr_add(&str, "%s", Q_("?duration:overflow"));
1616 }
1617
1618 return astr_str(&str);
1619}
1620
1621/************************************************************************/
1627const char *get_ping_time_text(const struct player *pplayer)
1628{
1629 static struct astring str = ASTRING_INIT;
1630
1631 astr_clear(&str);
1632
1634 if (!pconn->observer
1635 /* Certainly not needed, but safer. */
1636 && 0 == strcmp(pconn->username, pplayer->username)) {
1637 if (pconn->ping_time >= 0) {
1638 double ping_time_in_ms = 1000 * pconn->ping_time;
1639
1640 astr_add(&str, _("%6d.%02d ms"), (int) ping_time_in_ms,
1641 ((int) (ping_time_in_ms * 100.0)) % 100);
1642 }
1643 break;
1644 }
1646
1647 return astr_str(&str);
1648}
1649
1650/************************************************************************/
1656const char *get_score_text(const struct player *pplayer)
1657{
1658 static struct astring str = ASTRING_INIT;
1659
1660 astr_clear(&str);
1661
1662 if (pplayer->score.game >= 0) {
1663 astr_add(&str, "%d", pplayer->score.game);
1664 } else {
1665 astr_add(&str, "?");
1666 }
1667
1668 return astr_str(&str);
1669}
1670
1671/************************************************************************/
1678const char *get_report_title(const char *report_name)
1679{
1680 static struct astring str = ASTRING_INIT;
1681 const struct player *pplayer = client_player();
1682
1683 astr_clear(&str);
1684
1685 astr_add_line(&str, "%s", report_name);
1686
1687 if (pplayer != NULL) {
1688 char buf[4 * MAX_LEN_NAME];
1689
1690 /* TRANS: <nation adjective> <government name>.
1691 * E.g. "Polish Republic". */
1692 astr_add_line(&str, Q_("?nationgovernment:%s %s"),
1695
1696 /* TRANS: Just appending 2 strings, using the correct localized
1697 * syntax. */
1698 astr_add_line(&str, _("%s - %s"),
1699 ruler_title_for_player(pplayer, buf, sizeof(buf)),
1700 calendar_text());
1701 } else {
1702 /* TRANS: "Observer - 1985 AD" */
1703 astr_add_line(&str, _("Observer - %s"),
1704 calendar_text());
1705 }
1706
1707 return astr_str(&str);
1708}
1709
1710/**********************************************************************/
1717 const struct act_prob prob,
1718 const struct unit *actor_unit,
1719 const struct city *target_city)
1720{
1721 static struct astring custom = ASTRING_INIT;
1722
1724
1725 if (!action_prob_possible(prob)) {
1726 /* No info since impossible. */
1727 return NULL;
1728 }
1729
1731 || target_city != NULL),
1732 NULL);
1733
1739 TRUE);
1740
1741 if (revenue > 0) {
1743 /* TRANS: Estimated one time bonus and recurring revenue for
1744 * the Establish Trade _Route action. */
1745 _("%d one time bonus + %d trade"),
1746 revenue,
1748 } else {
1750 /* TRANS: Estimated recurring revenue for
1751 * the Establish Trade _Route action. */
1752 _("%d trade"),
1754 }
1760 FALSE);
1761
1762 if (revenue > 0) {
1764 /* TRANS: Estimated one time bonus for the Enter Marketplace
1765 * action. */
1766 _("%d one time bonus"), revenue);
1767 } else {
1768 /* No info to add. */
1769 return NULL;
1770 }
1774 /* Can only give remaining production for domestic and existing
1775 * cities. */
1777
1778 astr_set(&custom, _("%d remaining"), cost - target_city->shield_stock);
1779 } else {
1780 /* No info to add. */
1781 return NULL;
1782 }
1783
1784 return astr_str(&custom);
1785}
1786
1787/**********************************************************************/
1795const char *act_sel_action_tool_tip(const struct action *paction,
1796 const struct act_prob prob)
1797{
1798 return action_prob_explain(prob);
1799}
1800
1801/************************************************************************/
1806const char *text_happiness_buildings(const struct city *pcity)
1807{
1808 struct effect_list *plist = effect_list_new();
1809 static struct astring str = ASTRING_INIT;
1810
1812 if (0 < effect_list_size(plist)) {
1813 struct astring effects = ASTRING_INIT;
1814
1816 astr_set(&str, _("Buildings: %s."), astr_str(&effects));
1818 } else {
1819 astr_set(&str, _("Buildings: None."));
1820 }
1822
1823 /* Add line breaks after 80 characters. */
1824 astr_break_lines(&str, 80);
1825
1826 return astr_str(&str);
1827}
1828
1829/************************************************************************/
1834const char *text_happiness_nationality(const struct city *pcity)
1835{
1836 static struct astring str = ASTRING_INIT;
1837 int enemies = 0;
1838
1839 astr_clear(&str);
1840
1841 astr_add_line(&str, _("Nationality: "));
1842
1845 struct player *owner = city_owner(pcity);
1846
1847 citizens_foreign_iterate(pcity, pslot, nationality) {
1849 enemies += nationality;
1850 }
1852
1853 if (enemies > 0) {
1854 astr_add(&str, PL_("%d enemy nationalist", "%d enemy nationalists", enemies),
1855 enemies);
1856 }
1857 }
1858
1859 if (enemies == 0) {
1860 /* TRANS: No enemy nationalities, as there's no enemies present. */
1861 astr_add(&str, _("None."));
1862 }
1863 } else {
1864 /* TRANS: No nationalities present. */
1865 astr_add(&str, _("Disabled."));
1866 }
1867
1868 return astr_str(&str);
1869}
1870
1871/************************************************************************/
1876const char *text_happiness_wonders(const struct city *pcity)
1877{
1878 struct effect_list *plist = effect_list_new();
1879 static struct astring str = ASTRING_INIT;
1880
1884 if (0 < effect_list_size(plist)) {
1885 struct astring effects = ASTRING_INIT;
1886
1888 astr_set(&str, _("Wonders: %s."), astr_str(&effects));
1890 } else {
1891 astr_set(&str, _("Wonders: None."));
1892 }
1893
1894 /* Add line breaks after 80 characters. */
1895 astr_break_lines(&str, 80);
1897
1898 return astr_str(&str);
1899}
1900
1901/************************************************************************/
1906const char *text_happiness_cities(const struct city *pcity)
1907{
1908 struct player *pplayer = city_owner(pcity);
1909 int cities = city_list_size(pplayer->cities);
1910 int content = get_player_bonus(pplayer, EFT_CITY_UNHAPPY_SIZE);
1913 static struct astring str = ASTRING_INIT;
1914
1915 astr_clear(&str);
1916
1917 if (basis+step <= 0) {
1918 /* Special case where penalty is disabled; see
1919 * player_content_citizens(). */
1921 PL_("Cities: %d total, but no penalty for empire size.",
1922 "Cities: %d total, but no penalty for empire size.",
1923 cities),
1924 cities);
1926 /* TRANS: %d is number of citizens */
1927 PL_("%d content per city.",
1928 "%d content per city.", content),
1929 content);
1930 } else {
1931 /* Can have up to and including 'basis' cities without penalty */
1932 int excess = MAX(cities - basis, 0);
1933 int penalty;
1934 int unhappy, angry;
1935 int last, next;
1936
1937 if (excess > 0) {
1938 if (step > 0) {
1939 penalty = 1 + (excess - 1) / step;
1940 } else {
1941 penalty = 1;
1942 }
1943 } else {
1944 penalty = 0;
1945 }
1946
1947 unhappy = MIN(penalty, content);
1948 angry = game.info.angrycitizen ? MAX(penalty-content, 0) : 0;
1949 if (penalty >= 1) {
1950 /* 'last' is when last actual malcontent appeared, will saturate
1951 * if no angry citizens */
1952 last = basis + (unhappy+angry-1)*step;
1953 if (!game.info.angrycitizen && unhappy == content) {
1954 /* Maxed out unhappy citizens, so no more penalties */
1955 next = 0;
1956 } else {
1957 /* Angry citizens can continue appearing indefinitely */
1958 next = last + step;
1959 }
1960 } else {
1961 last = 0;
1962 next = basis;
1963 }
1964
1966 /* TRANS: sentence fragment, will have text appended */
1967 PL_("Cities: %d total:",
1968 "Cities: %d total:", cities),
1969 cities);
1970 if (excess > 0) {
1971 astr_add(&str,
1972 /* TRANS: appended to "Cities: %d total:"; preserve leading
1973 * space. Pluralized in "nearest threshold of %d cities". */
1974 PL_(" %d over nearest threshold of %d city.",
1975 " %d over nearest threshold of %d cities.", last),
1976 cities - last, last);
1978 /* TRANS: Number of content [citizen(s)] ... */
1979 PL_("%d content before penalty.",
1980 "%d content before penalty.", content),
1981 content);
1983 PL_("%d additional unhappy citizen.",
1984 "%d additional unhappy citizens.", unhappy),
1985 unhappy);
1986 if (angry > 0) {
1988 PL_("%d angry citizen.",
1989 "%d angry citizens.", angry),
1990 angry);
1991 }
1992 } else {
1993 astr_add(&str,
1994 /* TRANS: appended to "Cities: %d total:"; preserve leading
1995 * space. */
1996 PL_(" not more than %d, so no empire size penalty.",
1997 " not more than %d, so no empire size penalty.", next),
1998 next);
2000 /* TRANS: %d is number of citizens */
2001 PL_("%d content per city.",
2002 "%d content per city.", content),
2003 content);
2004 }
2005 if (next >= cities && penalty < content) {
2007 PL_("With %d more city, another citizen will become "
2008 "unhappy.",
2009 "With %d more cities, another citizen will become "
2010 "unhappy.",
2011 next + 1 - cities),
2012 next + 1 - cities);
2013 } else if (next >= cities) {
2014 /* We maxed out the number of unhappy citizens, but they can get
2015 * angry instead. */
2018 PL_("With %d more city, another citizen will become "
2019 "angry.",
2020 "With %d more cities, another citizen will become "
2021 "angry.",
2022 next + 1 - cities),
2023 next + 1 - cities);
2024 } else {
2025 /* Either no Empire_Size_Step, or we maxed out on unhappy citizens
2026 * and ruleset doesn't allow angry ones. */
2028 _("More cities will not cause more unhappy citizens."));
2029 }
2030 }
2031
2032 return astr_str(&str);
2033}
2034
2035/************************************************************************/
2040const char *text_happiness_units(const struct city *pcity)
2041{
2044 static struct astring str = ASTRING_INIT;
2045
2046 astr_clear(&str);
2047
2048 if (mlmax > 0) {
2050 if (mlmax == 100) {
2051 astr_add_line(&str, "%s", _("Unlimited martial law in effect."));
2052 } else {
2053 astr_add_line(&str, PL_("%d military unit may impose martial law.",
2054 "Up to %d military units may impose martial "
2055 "law.", mlmax), mlmax);
2056 }
2057 astr_add_line(&str, PL_("Each military unit makes %d "
2058 "unhappy citizen content.",
2059 "Each military unit makes %d "
2060 "unhappy citizens content.",
2061 mleach), mleach);
2062 } else if (uhcfac > 0) {
2064 _("Military units in the field may cause unhappiness. "));
2065 } else {
2067 _("Military units have no happiness effect. "));
2068 }
2069
2070 return astr_str(&str);
2071}
2072
2073/************************************************************************/
2078const char *text_happiness_luxuries(const struct city *pcity)
2079{
2080 static struct astring str = ASTRING_INIT;
2081
2082 astr_clear(&str);
2083
2085 _("Luxury: %d total."),
2086 pcity->prod[O_LUXURY]);
2087
2088 return astr_str(&str);
2089}
2090
2091/************************************************************************/
2095const char *production_help(const struct universal *uni, char *buf,
2096 size_t bufsize)
2097{
2098 buf[0] = '\0';
2099 int segments = 0;
2100
2101 if (uni->kind == VUT_UTYPE) {
2102 if (uni->value.utype->helptext != NULL) {
2103 strvec_iterate(uni->value.utype->helptext, text) {
2104 if (segments++) {
2105 cat_snprintf(buf, bufsize, "\n\n");
2106 }
2107 cat_snprintf(buf, bufsize, "%s", _(text));
2109 }
2110 } else {
2112
2113 if (uni->value.building->helptext != NULL) {
2114 strvec_iterate(uni->value.building->helptext, text) {
2115 if (segments++) {
2116 cat_snprintf(buf, bufsize, "\n\n");
2117 }
2118 cat_snprintf(buf, bufsize, "%s", _(text));
2120 }
2121 }
2122
2123 return buf;
2124}
2125
2126/************************************************************************/
2132const char *score_tooltip(const struct player *pplayer, int score)
2133{
2134 static char buf[1024];
2135 char *relation;
2136
2137 if (client.conn.playing != NULL) {
2138 if (pplayer == client.conn.playing) {
2139 relation = _(" (us)");
2140 } else if (pplayers_allied(pplayer, client.conn.playing)) {
2141 relation = _(" (an ally)");
2142 } else if (player_diplstate_get(pplayer, client.conn.playing)->type == DS_WAR) {
2143 /* Actual enemy; don't want to use pplayers_at_war() that considers also
2144 * never met players enemies. */
2145 relation = _(" (an enemy)");
2146 } else {
2147 relation = "";
2148 }
2149 } else {
2150 relation = "";
2151 }
2152
2153 if (score >= 0) {
2154 /* TRANS: %s is a Nation */
2155 fc_snprintf(buf, sizeof(buf), _("%s%s: score %d"),
2157 score);
2158 } else {
2159 fc_snprintf(buf, sizeof(buf), "%s%s",
2161 }
2162
2163 return buf;
2164}
const char * action_prob_explain(const struct act_prob prob)
Definition actions.c:2184
bool action_prob_possible(const struct act_prob probability)
Definition actions.c:5821
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1869
#define action_has_result(_act_, _res_)
Definition actions.h:431
void astr_free(struct astring *astr)
Definition astring.c:153
void astr_set(struct astring *astr, const char *format,...)
Definition astring.c:267
const char * astr_build_and_list(struct astring *astr, const char *const *items, size_t number)
Definition astring.c:367
void astr_add_line(struct astring *astr, const char *format,...)
Definition astring.c:299
void astr_clear(struct astring *astr)
Definition astring.c:205
void astr_add(struct astring *astr, const char *format,...)
Definition astring.c:287
#define str
Definition astring.c:76
void astr_break_lines(struct astring *astr, size_t desired_len)
Definition astring.c:318
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:141
const char * textyear(int year)
Definition calendar.c:120
#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:508
#define city_owner(_pcity_)
Definition city.h:563
#define city_list_iterate_end
Definition city.h:510
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:1118
static struct fc_sockaddr_list * list
Definition clinet.c:102
char * incite_cost
Definition comments.c:75
#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:37
int nation_history_gain(const struct player *pplayer)
Definition culture.c:61
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 * 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:961
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:846
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:1153
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
void get_effect_list_req_text(const struct effect_list *plist, struct astring *astr)
Definition effects.c:1303
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:377
#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
#define LINE_BREAK
Definition fc_types.h:77
@ BORDERS_DISABLED
Definition fc_types.h:1037
#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:734
struct civ_game game
Definition game.c:62
int current_turn_timeout(void)
Definition game.c:848
struct world wld
Definition game.c:63
int civ_population(const struct player *pplayer)
Definition game.c:74
struct city * game_city_by_number(int id)
Definition game.c:107
bool goto_get_turns(int *min, int *max)
Definition goto.c:1068
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:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define nat_x
#define nat_y
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1550
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:157
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:233
#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:1405
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:230
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
struct sprite int x
Definition sprite_g.h:31
#define strvec_iterate(psv, str)
#define strvec_iterate_end
Definition city.h:320
int airlift
Definition city.h:378
int prod[O_LAST]
Definition city.h:358
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:197
struct city_list * cities
Definition player.h:279
char username[MAX_LEN_NAME]
Definition player.h:250
struct team * team
Definition player.h:259
struct conn_list * connections
Definition player.h:296
struct player::@70::@73 client
struct player_economic economic
Definition player.h:282
int culture
Definition player.h:365
char name[MAX_LEN_NAME]
Definition player.h:249
struct player_score score
Definition player.h:281
struct nation_type * nation
Definition player.h:258
Tech_type_id researching
Definition research.h:52
struct research::@76::@78 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:571
Definition unit.h:138
int id
Definition unit.h:145
int homecity
Definition unit.h:146
struct goods_type * carrying
Definition unit.h:186
int veteran
Definition unit.h:152
enum universals_n kind
Definition fc_types.h:902
universals_u value
Definition fc_types.h:901
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
#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:1484
const char * text_happiness_cities(const struct city *pcity)
Definition text.c:1906
static const char * format_duration(int duration)
Definition text.c:1596
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:1834
#define FAR_CITY_SQUARE_DIST
Definition text.c:441
const char * score_tooltip(const struct player *pplayer, int score)
Definition text.c:2132
const char * text_happiness_wonders(const struct city *pcity)
Definition text.c:1876
bool get_units_upgrade_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1263
bool get_units_disband_info(char *buf, size_t bufsz, struct unit_list *punits)
Definition text.c:1329
static int turns_to_research_done(const struct research *presearch, int per_turn)
Definition text.c:699
const char * get_airlift_text(const struct unit_list *punits, const struct city *pdest)
Definition text.c:551
const char * get_info_label_text_popup(void)
Definition text.c:975
const char * text_happiness_units(const struct city *pcity)
Definition text.c:2040
const char * text_happiness_luxuries(const struct city *pcity)
Definition text.c:2078
const char * science_dialog_text(void)
Definition text.c:747
static int get_bulbs_per_turn(int *pours, bool *pteam, int *ptheirs)
Definition text.c:655
const char * text_happiness_buildings(const struct city *pcity)
Definition text.c:1806
const char * get_ping_time_text(const struct player *pplayer)
Definition text.c:1627
const char * get_report_title(const char *report_name)
Definition text.c:1678
static int turns_to_tech_loss(const struct research *presearch, int per_turn)
Definition text.c:727
const char * get_nuclear_winter_tooltip(void)
Definition text.c:1457
const char * get_score_text(const struct player *pplayer)
Definition text.c:1656
const char * get_science_target_text(double *percent)
Definition text.c:826
const char * get_bulb_tooltip(void)
Definition text.c:1373
const char * get_timeout_label_text(void)
Definition text.c:1563
const char * get_nearest_city_text(struct city *pcity, int sq_dist)
Definition text.c:447
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:1716
const char * popup_info_text(struct tile *ptile)
Definition text.c:147
const char * unit_description(struct unit *punit)
Definition text.c:481
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:1430
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:923
const char * production_help(const struct universal *uni, char *buf, size_t bufsize)
Definition text.c:2095
static int turns_per_advance(const struct research *presearch, int per_turn)
Definition text.c:714
const char * get_science_goal_text(Tech_type_id goal)
Definition text.c:872
const char * get_unit_info_label_text2(struct unit_list *punits, int linebreaks)
Definition text.c:1085
const char * get_unit_info_label_text1(struct unit_list *punits)
Definition text.c:1060
const char * get_spaceship_descr(struct player_spaceship *pship)
Definition text.c:1506
const char * act_sel_action_tool_tip(const struct action *paction, const struct act_prob prob)
Definition text.c:1795
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:88
@ TILE_UNKNOWN
Definition tile.h:36
#define tile_continent(_tile)
Definition tile.h:92
#define tile_owner(_tile)
Definition tile.h:96
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)
const char * goods_name_translation(struct goods_type *pgood)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
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:721
const struct impr_type * building
Definition fc_types.h:714
enum unit_upgrade_result unit_upgrade_info(const struct civ_map *nmap, const struct unit *punit, char *buf, size_t bufsz)
Definition unit.c:2059
struct player * unit_nationality(const struct unit *punit)
Definition unit.c:1253
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
int unit_bribe_cost(struct unit *punit, struct player *briber)
Definition unit.c:2312
void unit_upkeep_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1239
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:367
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1163
enum unit_upgrade_result unit_upgrade_test(const struct civ_map *nmap, const struct unit *punit, bool is_free)
Definition unit.c:1996
#define unit_tile(_pu)
Definition unit.h:397
#define unit_owner(_pu)
Definition unit.h:396
@ UU_OK
Definition unit.h:61
#define unit_home(_pu_)
Definition unit.h:394
unit_airlift_result
Definition unit.h:72
@ AR_SRC_NO_FLIGHTS
Definition unit.h:84
@ AR_OK_SRC_UNKNOWN
Definition unit.h:75
@ AR_OK_DST_UNKNOWN
Definition unit.h:76
@ AR_NO_MOVES
Definition unit.h:78
@ AR_BAD_DST_CITY
Definition unit.h:83
@ AR_NOT_IN_CITY
Definition unit.h:81
@ AR_OCCUPIED
Definition unit.h:80
@ AR_OK
Definition unit.h:74
@ AR_DST_NO_FLIGHTS
Definition unit.h:85
@ AR_WRONG_UNITTYPE
Definition unit.h:79
@ AR_BAD_SRC_CITY
Definition unit.h:82
#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:2610
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:1569
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1703
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
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:1560
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
int unit_upgrade_price(const struct player *pplayer, const struct unit_type *from, const struct unit_type *to)
Definition unittype.c:1731
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_type_iterate(_p)
Definition unittype.h:855
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:862