61 int min_x = 0, max_x = 0, min_y = 0, max_y = 0;
67 float canvas_x, canvas_y;
72 min_x =
MIN(canvas_x, min_x);
73 max_x =
MAX(canvas_x, max_x);
74 min_y =
MIN(canvas_y, min_y);
75 max_y =
MAX(canvas_y, max_y);
89 static char cost_str[50];
102 if (build_slots > num_units) {
104 fc_snprintf(cost_str,
sizeof(cost_str),
"{%d*%d}", num_units, cost);
107 fc_snprintf(cost_str,
sizeof(cost_str),
"[%d*%d]", num_units, cost);
111 fc_snprintf(cost_str,
sizeof(cost_str),
"%3d", cost);
126 char time_str[50], *cost_str;
129 if (pcity ==
nullptr) {
139 fc_strlcpy(buffer,
Q_(
"?filler:XXX/XXX XXX turns"), buffer_len);
147 PL_(
"%3d gold per turn",
"%3d gold per turn", gold), gold);
157 fc_snprintf(time_str,
sizeof(time_str),
"%3d", turns);
160 PL_(
"%3d turn",
"%3d turns", turns), turns);
168 fc_snprintf(buffer, buffer_len,
_(
"%3d/%s:%s"), stock, cost_str,
171 fc_snprintf(buffer, buffer_len,
_(
"%3d/%s %s"), stock, cost_str,
180 QString html_pre(
const QString &content)
182 return QStringLiteral(
"<pre>") + content + QStringLiteral(
"</pre>");
196 QString posdesc, negdesc;
198 bool suppress_if_zero;
217 struct city_sum *city_sum_new(
const char *format)
219 struct city_sum *sum =
new city_sum();
221 sum->format = format;
233 void city_sum_add_real(
struct city_sum *sum,
double value,
234 bool suppress_if_zero,
const QString &auxfmt,
235 double aux,
const QString &posdesc,
236 const QString &negdesc)
241 for (i = 0; i < sum->n; i++) {
242 if (sum->sums[i].posdesc == posdesc && sum->sums[i].negdesc == negdesc
243 && sum->sums[i].auxfmt == auxfmt
244 && sum->sums[i].suppress_if_zero == suppress_if_zero) {
246 sum->sums[i].value += value;
247 sum->sums[i].aux += aux;
254 sum->sums.resize(sum->n + 1);
255 sum->sums[sum->n].value = value;
256 sum->sums[sum->n].posdesc = posdesc;
257 sum->sums[sum->n].negdesc = negdesc;
258 sum->sums[sum->n].suppress_if_zero = suppress_if_zero;
259 sum->sums[sum->n].aux = aux;
260 sum->sums[sum->n].auxfmt = auxfmt;
278 city_sum_add_full(struct city_sum *sum,
double value,
279 bool suppress_if_zero, const
char *auxfmt,
280 double aux, const
char *posfmt,
281 const
char *negfmt, ...)
286 va_start(args, negfmt);
287 auto posdesc = QString::vasprintf(posfmt, args);
290 va_start(args, negfmt);
291 auto negdesc = QString::vasprintf(negfmt, args);
294 city_sum_add_real(sum, value, suppress_if_zero, auxfmt, aux, posdesc,
307 city_sum_add(struct city_sum *sum,
double value, const
char *descfmt,
313 va_start(args, descfmt);
314 auto desc = QString::vasprintf(descfmt, args);
318 city_sum_add_real(sum, value,
false,
nullptr, 0, desc, desc);
330 city_sum_add_if_nonzero(struct city_sum *sum,
double value,
331 const
char *descfmt, ...)
336 va_start(args, descfmt);
337 auto desc = QString::vasprintf(descfmt, args);
341 city_sum_add_real(sum, value,
true,
nullptr, 0, desc, desc);
347 double city_sum_total(
struct city_sum *sum)
352 for (i = 0; i < sum->n; i++) {
353 total += sum->sums[i].value;
364 inline int city_sum_compare(
double val1,
double val2)
368 if (fabs(val1 - val2) < 0.0000001) {
371 return (val1 > val2 ? +1 : -1);
383 city_sum_print(struct city_sum *sum,
bool account_for_unknown,
384 const
char *totalfmt, ...)
393 if (account_for_unknown) {
394 double total = city_sum_total(sum);
397 va_start(args, totalfmt);
398 actual_total = va_arg(args,
double);
401 if (city_sum_compare(total, actual_total) != 0) {
402 city_sum_add(sum, actual_total - total,
405 Q_(
"?city_sum:(unknown)"));
410 for (i = 0; i < sum->n; i++) {
411 if (!sum->sums[i].suppress_if_zero
412 || city_sum_compare(sum->sums[i].value, 0) != 0) {
413 result += QString::asprintf(
414 qUtf8Printable(sum->format), sum->sums[i].value,
415 (sum->sums[i].value < 0) ? qUtf8Printable(sum->sums[i].negdesc)
416 : qUtf8Printable(sum->sums[i].posdesc));
417 if (!sum->sums[i].auxfmt.isEmpty()) {
418 result += QString::asprintf(qUtf8Printable(sum->sums[i].auxfmt),
421 result += QStringLiteral(
"\n");
425 va_start(args, totalfmt);
426 result += QString::vasprintf(totalfmt, args);
430 return html_pre(result);
445 struct city_sum *sum = city_sum_new(
Q_(
"?city_surplus:%+4.0f : %s"));
448 Q_(
"?city_surplus:Citizens"));
451 memset(tax, 0,
O_LAST *
sizeof(*tax));
453 city_sum_add_if_nonzero(sum, tax[otype],
454 Q_(
"?city_surplus:Taxed from trade"));
467 int value = proute->value
470 switch (proute->dir) {
471 case RDIR_BIDIRECTIONAL:
472 city_sum_add(sum, value,
Q_(
"?city_surplus:Trading %s with %s"),
476 city_sum_add(sum, value,
Q_(
"?city_surplus:Trading %s to %s"),
480 city_sum_add(sum, value,
Q_(
"?city_surplus:Trading %s from %s"),
486 }
else if (otype ==
O_GOLD) {
489 city_sum_add_if_nonzero(sum, tithes,
490 Q_(
"?city_surplus:Building tithes"));
494 enum effect_type eft[] = {EFT_OUTPUT_BONUS, EFT_OUTPUT_BONUS_2};
497 int base = city_sum_total(sum),
bonus = 100;
498 struct effect_list *plist = effect_list_new();
510 if (peffect->multiplier) {
512 peffect->multiplier);
520 delta = (peffect->value * mul) / 100;
522 delta = peffect->value;
525 new_total = bonus *
base / 100;
526 city_sum_add_full(sum, new_total - city_sum_total(sum),
true,
529 Q_(
"?city_surplus: (%+.0f%%)"), delta,
530 Q_(
"?city_surplus:Bonus from %s"),
531 Q_(
"?city_surplus:Loss from %s"), buf2);
534 effect_list_destroy(plist);
538 if (pcity->
waste[otype] != 0) {
547 if (
city_waste(pcity, otype, city_sum_total(sum), wastetypes,
549 == pcity->
waste[otype]) {
551 city_sum_add_if_nonzero(sum, -wastetypes[
OLOSS_SIZE],
552 Q_(
"?city_surplus:Size penalty"));
558 regular_waste = pcity->
waste[otype];
559 breakdown_ok =
false;
561 if (regular_waste > 0) {
568 fmt =
Q_(
"?city_surplus:Waste%s");
573 fmt =
Q_(
"?city_surplus:Corruption%s");
576 city_sum_add(sum, -regular_waste, fmt, breakdown_ok ?
"" :
"?");
581 Q_(
"?city_surplus:Disorder"));
583 if (pcity->
usage[otype] > 0) {
584 city_sum_add(sum, -pcity->
usage[otype],
Q_(
"?city_surplus:Used"));
587 return city_sum_print(sum,
true,
589 "==== : Adds up to\n"
590 "%4.0f : Total surplus"),
591 static_cast<double>(pcity->
surplus[otype]));
599 int illness, ill_base, ill_size, ill_trade, ill_pollution;
600 struct effect_list *plist;
601 struct city_sum *sum;
604 return _(
"Illness deactivated in ruleset.");
607 sum = city_sum_new(
Q_(
"?city_plague:%+5.1f%% : %s"));
612 city_sum_add(sum,
static_cast<float>(ill_size) / 10.0,
613 Q_(
"?city_plague:Risk from overcrowding"));
614 city_sum_add(sum,
static_cast<float>(ill_trade) / 10.0,
615 Q_(
"?city_plague:Risk from trade"));
616 city_sum_add(sum,
static_cast<float>(ill_pollution) / 10.0,
617 Q_(
"?city_plague:Risk from pollution"));
619 plist = effect_list_new();
630 if (peffect->multiplier) {
632 peffect->multiplier);
640 delta = (peffect->value * mul) / 100;
642 delta = peffect->value;
645 city_sum_add_full(sum, -(0.1 * ill_base * delta / 100),
true,
646 Q_(
"?city_plague: (%+.0f%%)"), -delta,
647 Q_(
"?city_plague:Risk from %s"),
648 Q_(
"?city_plague:Bonus from %s"), buf2);
651 effect_list_destroy(plist);
657 return city_sum_print(sum,
false,
659 "====== : Adds up to\n"
660 "%5.1f%% : Plague chance per turn"),
661 (
static_cast<double>(illness) / 10.0));
669 int pollu, prod, trade, pop, mod;
670 struct city_sum *sum = city_sum_new(
Q_(
"?city_pollution:%+4.0f : %s"));
679 city_sum_add(sum, prod,
Q_(
"?city_pollution:Pollution from shields"));
680 city_sum_add(sum, trade,
Q_(
"?city_pollution:Pollution from trade"));
681 city_sum_add(sum, pop,
Q_(
"?city_pollution:Pollution from citizens"));
682 city_sum_add(sum, mod,
Q_(
"?city_pollution:Pollution modifier"));
683 return city_sum_print(sum,
false,
684 Q_(
"?city_pollution:"
685 "==== : Adds up to\n"
686 "%4.0f : Total surplus"),
687 static_cast<double>(pollu));
695 struct effect_list *plist;
696 struct city_sum *sum = city_sum_new(
Q_(
"?city_culture:%4.0f : %s"));
699 city_sum_add(sum, pcity->
history,
Q_(
"?city_culture:History (%+d/turn)"),
702 plist = effect_list_new();
714 if (peffect->multiplier) {
716 peffect->multiplier);
726 value = (peffect->value * mul) / 100;
728 city_sum_add_if_nonzero(sum, value,
Q_(
"?city_culture:%s"), buf2);
731 effect_list_destroy(plist);
733 return city_sum_print(sum,
true,
735 "==== : Adds up to\n"
736 "%4.0f : Total culture"),
737 static_cast<double>(pcity->
client.culture));
749 if (
game.
info.airlifting_style & AIRLIFTING_UNLIMITED_SRC
760 fc_snprintf(src,
sizeof(src),
_(
"unlimited take offs%s"),
761 game.
info.airlifting_style & AIRLIFTING_UNLIMITED_DEST
765 :
PL_(
" (until the landing has been spent)",
766 " (until all landings have been spent)",
772 PL_(
"%d take off",
"%d take offs", pcity->
airlift),
776 if (
game.
info.airlifting_style & AIRLIFTING_UNLIMITED_DEST) {
783 fc_snprintf(dest,
sizeof(dest),
_(
"unlimited landings"));
788 PL_(
"%d landing",
"%d landings", pcity->
airlift),
795 return _(
"unlimited take offs and landings");
800 return QString::asprintf(
_(
"%s and %s"), src, dest);
803 return QString::asprintf(
806 PL_(
"%d take off or landing",
"%d take offs or landings",
818 auto text = QString();
820 text += QString(
_(
"Happy: %1\n"))
823 text += QString(
_(
"Content: %1\n"))
826 text += QString(
_(
"Unhappy: %1\n"))
829 text += QString(
_(
"Angry: %1\n"))
834 text += QStringLiteral(
"%1: %2\n")
840 return html_pre(text.trimmed());
850 return _(
"Disorder");
853 return _(
"Celebrating");
869 if (granaryturns == 0) {
877 return QString::asprintf(
PL_(
"%3d turn",
"%3d turns", abs(granaryturns)),
891 if (
game.
info.airlifting_style & AIRLIFTING_UNLIMITED_SRC
902 game.
info.airlifting_style & AIRLIFTING_UNLIMITED_DEST
913 if (
game.
info.airlifting_style & AIRLIFTING_UNLIMITED_DEST) {
934 return QString::asprintf(
_(
" s: %s d: %s"), src, dest);
938 return QString::asprintf(
_(
" %s"), src);
971 for (n = 0; n < pcity->
specialists[sp]; n++, i++) {
979 qCritical(
"get_city_citizen_types() %d citizens "
980 "not equal %d city size in \"%s\".",
996 if (citizen_index < 0 || citizen_index >= num_citizens
1031 return dsend_packet_city_worklist(&
client.
conn, pcity->
id, pworklist);
1045 if (position == 0) {
1058 }
else if (position >= 1
1102 bool success =
false;
1197 && pcity->
client.buy_cost > 0);
1205 return dsend_packet_city_sell(&
client.
conn, pcity->
id, sell_id);
1222 return dsend_packet_city_change_specialist(&
client.
conn, pcity->
id, from,
int rs_max_city_radius_sq()
Maximum city radius in this ruleset.
int city_production_build_shield_cost(const struct city *pcity)
Return the number of shields it takes to build current city production.
int city_build_slots(const struct city *pcity)
The maximum number of units a city can build per turn.
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Returns TRUE iff the given city can use this kind of specialist.
bool city_production_has_flag(const struct city *pcity, enum impr_flag_id flag)
Return TRUE when the current production has this flag.
void add_tax_income(const struct player *pplayer, int trade, int *output)
Add the incomes of a city according to the taxrates (ignore # of specialists).
int get_city_tithes_bonus(const struct city *pcity)
Return the amount of gold generated by buildings under "tithe" attribute governments.
const char * city_name_get(const struct city *pcity)
Return the name of the city.
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Calculates the turns which are needed to build the requested production in the city.
bool city_unhappy(const struct city *pcity)
Return TRUE iff the city is unhappy.
bool city_celebrating(const struct city *pcity)
cities celebrate only after consecutive happy turns
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Calculate city's illness in tenth of percent:
bool city_happy(const struct city *pcity)
Return TRUE iff the city is happy.
bool can_city_build_direct(const struct city *pcity, const struct universal *target)
Returns whether city can immediately build given target, unit or improvement.
int city_waste(const struct city *pcity, Output_type_id otype, int total, int *breakdown, const std::vector< city * > &gov_centers, const cached_waste *pcwaste)
Give corruption/waste generated by city.
bool can_city_build_later(const struct city *pcity, const struct universal *target)
Returns whether city can ever build given target, unit or improvement.
int city_pollution_types(const struct city *pcity, int shield_total, int trade_total, int *pollu_prod, int *pollu_trade, int *pollu_pop, int *pollu_mod)
Calculate the pollution from production and population in the city.
bool city_production_build_units(const struct city *pcity, bool add_production, int *num_units)
Return TRUE if the city could use the additional build slots provided by the effect City_Build_Slots.
int city_turns_to_grow(const struct city *pcity)
Calculates the turns which are needed for the city to grow.
citizens city_size_get(const struct city *pcity)
Get the city size.
struct output_type output_types[O_LAST]
bool city_can_change_build(const struct city *pcity)
Returns TRUE iff the given city can change what it is building.
#define city_map_iterate_without_index_end
#define CITY_ABS2REL(_coor)
#define city_map_iterate_without_index(_radius_sq, _x, _y)
QString get_city_dialog_airlift_value(const struct city *pcity)
Return airlift capacity.
QString get_city_dialog_status_text(const struct city *pcity)
Return text describing the city's status: disorder/celebrating/...
int get_citydlg_canvas_height()
Return the height of the city dialog canvas.
QString get_city_dialog_culture_text(const struct city *pcity)
Return text describing the culture output.
QString get_city_dialog_output_text(const struct city *pcity, Output_type_id otype)
Return text describing the production output.
void get_city_dialog_production(struct city *pcity, char *buffer, size_t buffer_len)
Find the city dialog city production text for the given city, and place it into the buffer.
int city_set_worklist(struct city *pcity, const struct worklist *pworklist)
Set the worklist for a given city.
int city_rename(struct city *pcity, const char *name)
Tell the server to rename the city.
char * city_production_cost_str(const struct city *pcity)
Return a string describing the cost for the production of the city considerung several build slots fo...
int get_city_citizen_types(struct city *pcity, enum citizen_feeling idx, enum citizen_category *categories)
Provide a list of all citizens in the city, in order.
int city_buy_production(struct city *pcity)
Buy the current production item in a given city.
bool city_queue_insert(struct city *pcity, int position, struct universal *item)
Insert an item into the city's queue.
bool city_queue_insert_worklist(struct city *pcity, int position, const struct worklist *worklist)
Insert the worklist into the city's queue at the given position.
QString get_city_dialog_growth_value(const struct city *pcity)
Return time until next growth.
bool city_set_queue(struct city *pcity, const struct worklist *pqueue)
Set the city current production and the worklist, like it should be.
QString get_city_dialog_size_text(const struct city *pcity)
Return text describing the city's citizens.
QString get_city_dialog_pollution_text(const struct city *pcity)
Return text describing the pollution output.
int city_change_production(struct city *pcity, struct universal *target)
Change the production of a given city.
void city_rotate_specialist(struct city *pcity, int citizen_index)
Rotate the given specialist citizen to the next type of citizen.
static bool base_city_queue_insert(struct city *pcity, int position, struct universal *item)
Insert an item into the city's queue.
QString get_city_dialog_airlift_text(const struct city *pcity)
Return text describing airlift capacity.
static int citydlg_map_height
int get_citydlg_canvas_width()
Return the width of the city dialog canvas.
void city_get_queue(struct city *pcity, struct worklist *pqueue)
Get the city current production and the worklist, like it should be.
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
Change the production of a given city.
void generate_citydlg_dimensions()
Calculate the citydlg width and height.
int city_change_specialist(struct city *pcity, Specialist_type_id from, Specialist_type_id to)
Change a specialist in the given city.
QString get_city_dialog_illness_text(const struct city *pcity)
Return text describing the chance for a plague.
bool city_can_buy(const struct city *pcity)
Return TRUE iff the city can buy.
static int citydlg_map_width
void refresh_city_dialog(struct city *pcity)
bool can_client_issue_orders()
Returns TRUE iff the client can issue orders (such as giving unit commands).
int city_history_gain(const struct city *pcity)
How much history city gains this turn.
static void base(QVariant data1, QVariant data2)
Action "Build Base" for choice dialog.
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Returns the effect sources of this type currently active at the city.
void get_effect_req_text(const struct effect *peffect, char *buf, size_t buf_len)
Make user-friendly text for the source.
int get_city_bonus(const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
Returns the effect bonus at a city.
#define effect_list_iterate_end
#define effect_list_iterate(effect_list, peffect)
enum output_type_id Output_type_id
#define PL_(String1, String2, n)
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Return TRUE if the impr has this flag otherwise FALSE.
#define fc_assert(condition)
client_options * gui_options
int player_multiplier_effect_value(const struct player *pplayer, const struct multiplier *pmul)
Return the multiplier value currently in effect for pplayer, scaled from display units to the units u...
std::vector< city * > player_gov_centers(const struct player *pplayer)
Locate the player's government centers.
bool are_universals_equal(const struct universal *psource1, const struct universal *psource2)
Return TRUE iff the two sources are equivalent.
int universal_number(const struct universal *source)
Return the universal number of the constituent.
struct specialist * specialist_by_number(const Specialist_type_id id)
Return the specialist pointer for the given number.
Specialist_type_id specialist_count()
Return the number of specialist_types.
const char * specialist_plural_translation(const struct specialist *sp)
Return the (translated, plural) name of the specialist type.
#define specialist_type_iterate_end
#define specialist_type_iterate(sp)
SPECPQ_PRIORITY_TYPE priority
struct city::@15::@18 client
struct universal production
int unhappy_penalty[O_LAST]
citizens feel[CITIZEN_LAST][FEELING_LAST]
citizens specialists[SP_MAX]
struct packet_game_info info
bool concise_city_production
int fc_snprintf(char *str, size_t n, const char *format,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
int fc__attribute((nonnull(1, 3)))
int tileset_tile_height(const struct tileset *t)
Return the tile height of the current tileset.
int tileset_tile_width(const struct tileset *t)
Return the tile width of the current tileset.
const char * goods_name_translation(struct goods_type *pgood)
Return translated name of this goods type.
#define trade_routes_iterate_end
#define trade_routes_iterate(c, proute)
const struct impr_type * building
void map_to_gui_vector(const struct tileset *t, float *gui_dx, float *gui_dy, int map_dx, int map_dy)
Translate from a cartesian system to the GUI system.
void worklist_advance(struct worklist *pwl)
Remove first element from worklist.
bool worklist_peek(const struct worklist *pwl, struct universal *prod)
Fill in the id and is_unit values for the head of the worklist if the worklist is non-empty.
void worklist_copy(struct worklist *dst, const struct worklist *src)
Copy contents from worklist src to worklist dst.
bool worklist_is_empty(const struct worklist *pwl)
Returns whether worklist has no elements.
bool worklist_append(struct worklist *pwl, const struct universal *prod)
Adds the id to the next available slot in the worklist.
bool worklist_insert(struct worklist *pwl, const struct universal *prod, int idx)
Inserts the production at the location idx in the worklist, thus moving all subsequent entries down.
void worklist_remove(struct worklist *pwl, int idx)
Remove element from position idx.
int worklist_length(const struct worklist *pwl)
Returns the number of entries in the worklist.
#define worklist_iterate_end
#define worklist_iterate(_list, _p)