[Freeciv-Dev] (PR#10575) city dialog tooltips
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=10575 >
Here's a new version of the patch. It has support for food, shields,
trade, gold, science, luxury, and pollution.
You'll note immediately that this is a lot of code! A lot of code
duplicated from city.c, and a lot of code duplicated within the
different functions here. This means there's a reasonable chance of
bugs. I've tested it in some situations, but not all. It also should
make us wonder if there's a way to merge these functions. This is a big
reason why I'd like to start some work on gen-output.
jason
Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.50
diff -u -r1.50 citydlg_common.c
--- client/citydlg_common.c 16 Oct 2004 00:00:10 -0000 1.50
+++ client/citydlg_common.c 22 Oct 2004 03:45:53 -0000
@@ -380,6 +380,298 @@
}
/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_food_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int total = 0;
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Farmers\n"), pcity->food_prod);
+ total += pcity->food_prod;
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Consumed by citizens\n"), -2 * pcity->size);
+ total -= 2 * pcity->size;
+
+ if (pcity->food_upkeep > 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Unit upkeep\n"), -pcity->food_upkeep);
+ total -= pcity->food_upkeep;
+ }
+
+ if (city_unhappy(pcity)) {
+ cat_snprintf(buf, bufsz, _("%+4d : Disorder\n"), -MAX(total, 0));
+ }
+
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), pcity->food_surplus);
+}
+
+/**************************************************************************
+ Return text describing the shield output.
+**************************************************************************/
+void get_city_dialog_shield_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int total = 0, base, bonus = 100;
+ struct effect_source_vector sources;
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Workers\n"), pcity->shield_prod);
+ total += pcity->shield_prod;
+
+ if (pcity->shield_waste != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Waste\n"), -pcity->shield_waste);
+ total -= pcity->shield_waste;
+ }
+
+ base = total;
+ sources = get_city_bonus_sources(pcity, EFT_PROD_BONUS);
+ effect_source_vector_iterate(&sources, s) {
+ int new_total;
+
+ bonus += s->effect_value;
+ new_total = bonus * base / 100;
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Bonus from %s\n"),
+ (new_total - total), get_improvement_name(s->building));
+ total = new_total;
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
+
+ if (pcity->shield_upkeep > 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Unit upkeep\n"), -pcity->shield_upkeep);
+ total -= pcity->shield_upkeep;
+ }
+
+ if (city_unhappy(pcity)) {
+ cat_snprintf(buf, bufsz, _("%+4d : Disorder\n"), -MAX(total, 0));
+ }
+
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), pcity->shield_surplus);
+}
+
+/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_trade_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int intercity_trade
+ = pcity->trade_prod - pcity->tile_trade + pcity->corruption;
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Tile trade\n"), pcity->tile_trade);
+ if (intercity_trade != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Trade routes\n"), -2 * pcity->size);
+ }
+ if (pcity->corruption != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Corruption\n"), -pcity->corruption);
+ }
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), pcity->trade_prod);
+}
+
+/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_gold_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int sci, lux, gold;
+ int total, surplus, bonus = 100, sp;
+ struct effect_source_vector sources;
+
+ get_tax_income(city_owner(pcity), pcity->trade_prod, &sci, &lux, &gold);
+ surplus = city_gold_surplus(pcity, pcity->tax_total);
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Gold from trade\n"), gold);
+
+ sp = (pcity->specialists[SP_TAXMAN]
+ * game.rgame.specialists[SP_TAXMAN].bonus);
+ if (sp != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : From %s\n"),
+ sp, game.rgame.specialists[SP_TAXMAN].name);
+ gold += sp;
+ }
+
+ if (city_unhappy(pcity)) {
+ cat_snprintf(buf, bufsz, _("%+4d : Disorder\n"), -gold);
+ gold = 0;
+ }
+
+ total = gold;
+ sources = get_city_bonus_sources(pcity, EFT_TAX_BONUS);
+ effect_source_vector_iterate(&sources, s) {
+ int new_total;
+
+ bonus += s->effect_value;
+ new_total = bonus * lux / 100;
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Bonus from %s\n"),
+ (new_total - total), get_improvement_name(s->building));
+ total = new_total;
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
+
+ if (pcity->gold_unit_upkeep != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Unit upkeep\n"), -pcity->gold_unit_upkeep);
+ }
+ if (pcity->gold_building_upkeep != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Building upkeep\n"), -pcity->gold_building_upkeep);
+ }
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), surplus);
+}
+
+/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_science_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int sci, lux, gold;
+ int surplus = pcity->science_total, total, bonus = 100, sp;
+ struct effect_source_vector sources;
+
+ get_tax_income(city_owner(pcity), pcity->trade_prod, &sci, &lux, &gold);
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%4d : Science from trade\n"), sci);
+
+ sp = (pcity->specialists[SP_SCIENTIST]
+ * game.rgame.specialists[SP_SCIENTIST].bonus);
+ if (sp != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : From %s\n"),
+ sp, game.rgame.specialists[SP_SCIENTIST].name);
+ sci += sp;
+ }
+
+ if (city_unhappy(pcity)) {
+ cat_snprintf(buf, bufsz, _("%+4d : Disorder\n"), -sci);
+ sci = 0;
+ }
+
+ total = sci;
+ sources = get_city_bonus_sources(pcity, EFT_SCIENCE_BONUS);
+ effect_source_vector_iterate(&sources, s) {
+ int new_total;
+
+ bonus += s->effect_value;
+ new_total = bonus * sci / 100;
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Bonus from %s\n"),
+ (new_total - total), get_improvement_name(s->building));
+ total = new_total;
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
+
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), surplus);
+}
+
+/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_luxury_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int sci, lux, gold;
+ int surplus = pcity->luxury_total, total, bonus = 100, sp;
+ struct effect_source_vector sources;
+
+ get_tax_income(city_owner(pcity), pcity->trade_prod, &sci, &lux, &gold);
+
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Luxury from trade\n"), lux);
+
+ sp = pcity->specialists[SP_ELVIS] * game.rgame.specialists[SP_ELVIS].bonus;
+ if (sp != 0) {
+ cat_snprintf(buf, bufsz,
+ _("%+4d : From %s\n"),
+ sp, game.rgame.specialists[SP_ELVIS].name);
+ lux += sp;
+ }
+
+ total = lux;
+ sources = get_city_bonus_sources(pcity, EFT_LUXURY_BONUS);
+ effect_source_vector_iterate(&sources, s) {
+ int new_total;
+
+ bonus += s->effect_value;
+ new_total = bonus * lux / 100;
+ cat_snprintf(buf, bufsz,
+ _("%+4d : Bonus from %s\n"),
+ (new_total - total), get_improvement_name(s->building));
+ total = new_total;
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
+
+ cat_snprintf(buf, bufsz,
+ _("==== : Adds up to\n"));
+ cat_snprintf(buf, bufsz,
+ _("%4d : Total surplus"), surplus);
+}
+
+/**************************************************************************
+ Return text describing the food output.
+**************************************************************************/
+void get_city_dialog_pollution_text(const struct city *pcity,
+ char *buf, size_t bufsz)
+{
+ int pollu, prod, pop, mod;
+
+ pollu = city_pollution_types(pcity, pcity->shield_prod,
+ &prod, &pop, &mod);
+ buf[0] = '\0';
+
+ cat_snprintf(buf, bufsz,
+ "%+4d : Pollution from shields\n", prod);
+ cat_snprintf(buf, bufsz,
+ "%+4d : Pollution from citizens\n", pop);
+ cat_snprintf(buf, bufsz,
+ "%+4d : Pollution modifier\n", mod);
+ cat_snprintf(buf, bufsz,
+ "==== : Adds up to\n");
+ cat_snprintf(buf, bufsz,
+ "%4d : Total surplus", pollu);
+}
+
+/**************************************************************************
Provide a list of all citizens in the city, in order. "index"
should be the happiness index (currently [0..4]; 4 = final
happiness). "citizens" should be an array large enough to hold all
Index: client/citydlg_common.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.h,v
retrieving revision 1.27
diff -u -r1.27 citydlg_common.h
--- client/citydlg_common.h 29 Sep 2004 02:24:18 -0000 1.27
+++ client/citydlg_common.h 22 Oct 2004 03:45:53 -0000
@@ -54,6 +54,21 @@
void get_city_dialog_production_row(char *buf[], size_t column_size, int id,
bool is_unit, struct city *pcity);
+void get_city_dialog_food_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_shield_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_trade_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_gold_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_science_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_luxury_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+void get_city_dialog_pollution_text(const struct city *pcity,
+ char *buffer, size_t bufsz);
+
void get_city_citizen_types(struct city *pcity, int index,
struct citizen_type *citizens);
void city_rotate_specialist(struct city *pcity, int citizen_index);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.411
diff -u -r1.411 packhand.c
--- client/packhand.c 21 Oct 2004 20:27:28 -0000 1.411
+++ client/packhand.c 22 Oct 2004 03:45:54 -0000
@@ -456,7 +456,12 @@
pcity->tile_trade=packet->tile_trade;
pcity->corruption=packet->corruption;
pcity->shield_waste=packet->shield_waste;
-
+
+ pcity->food_upkeep = packet->food_upkeep;
+ pcity->shield_upkeep = packet->shield_upkeep;
+ pcity->gold_unit_upkeep = packet->gold_unit_upkeep;
+ pcity->gold_building_upkeep = packet->gold_building_upkeep;
+
pcity->luxury_total=packet->luxury_total;
pcity->tax_total=packet->tax_total;
pcity->science_total=packet->science_total;
@@ -730,6 +735,8 @@
pcity->shield_surplus = 0;
pcity->trade_prod = 0;
pcity->corruption = 0;
+ pcity->food_upkeep = 0;
+ pcity->shield_upkeep = 0;
pcity->luxury_total = 0;
pcity->tax_total = 0;
pcity->science_total = 0;
Index: client/text.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/text.c,v
retrieving revision 1.13
diff -u -r1.13 text.c
--- client/text.c 18 Oct 2004 22:40:02 -0000 1.13
+++ client/text.c 22 Oct 2004 03:45:54 -0000
@@ -703,17 +703,17 @@
const char *get_happiness_buildings(const struct city *pcity)
{
int faces = 0;
- struct building_vector sources;
+ struct effect_source_vector sources;
INIT;
add_line(_("Buildings: "));
sources = get_city_bonus_sources(pcity, EFT_MAKE_CONTENT);
- building_vector_iterate(&sources, pbldg) {
+ effect_source_vector_iterate(&sources, src) {
faces++;
- add(_("%s. "), get_improvement_name(*pbldg));
- } building_vector_iterate_end;
- building_vector_free(&sources);
+ add(_("%s. "), get_improvement_name(src->building));
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
if (faces == 0) {
add(_("None. "));
@@ -728,31 +728,31 @@
const char *get_happiness_wonders(const struct city *pcity)
{
int faces = 0;
- struct building_vector sources;
+ struct effect_source_vector sources;
INIT;
add_line(_("Wonders: "));
sources = get_city_bonus_sources(pcity, EFT_MAKE_HAPPY);
- building_vector_iterate(&sources, pbldg) {
+ effect_source_vector_iterate(&sources, src) {
faces++;
- add(_("%s. "), get_improvement_name(*pbldg));
- } building_vector_iterate_end;
- building_vector_free(&sources);
+ add(_("%s. "), get_improvement_name(src->building));
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
sources = get_city_bonus_sources(pcity, EFT_FORCE_CONTENT);
- building_vector_iterate(&sources, pbldg) {
+ effect_source_vector_iterate(&sources, src) {
faces++;
- add(_("%s. "), get_improvement_name(*pbldg));
- } building_vector_iterate_end;
- building_vector_free(&sources);
+ add(_("%s. "), get_improvement_name(src->building));
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
sources = get_city_bonus_sources(pcity, EFT_NO_UNHAPPY);
- building_vector_iterate(&sources, pbldg) {
+ effect_source_vector_iterate(&sources, src) {
faces++;
- add(_("%s. "), get_improvement_name(*pbldg));
- } building_vector_iterate_end;
- building_vector_free(&sources);
+ add(_("%s. "), get_improvement_name(src->building));
+ } effect_source_vector_iterate_end;
+ effect_source_vector_free(&sources);
if (faces == 0) {
add(_("None. "));
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.96
diff -u -r1.96 citydlg.c
--- client/gui-gtk-2.0/citydlg.c 19 Oct 2004 16:35:33 -0000 1.96
+++ client/gui-gtk-2.0/citydlg.c 22 Oct 2004 03:45:54 -0000
@@ -127,6 +127,7 @@
struct unit_node_vector supported_units;
struct unit_node_vector present_units;
+ GtkWidget *info_ebox[NUM_INFO_FIELDS];
GtkWidget *info_label[NUM_INFO_FIELDS];
} overview;
@@ -140,6 +141,7 @@
GtkWidget *map_canvas;
GtkWidget *map_canvas_pixmap;
GtkWidget *widget;
+ GtkWidget *info_ebox[NUM_INFO_FIELDS];
GtkWidget *info_label[NUM_INFO_FIELDS];
} happiness;
@@ -185,7 +187,9 @@
static gboolean keyboard_handler(GtkWidget * widget, GdkEventKey * event,
struct city_dialog *pdialog);
-static GtkWidget *create_city_info_table(GtkWidget **info_label);
+static GtkWidget *create_city_info_table(struct city_dialog *pdialog,
+ GtkWidget **info_ebox,
+ GtkWidget **info_label);
static void create_and_append_overview_page(struct city_dialog *pdialog);
static void create_and_append_worklist_page(struct city_dialog *pdialog);
static void create_and_append_happiness_page(struct city_dialog *pdialog);
@@ -198,7 +202,8 @@
static void city_dialog_update_title(struct city_dialog *pdialog);
static void city_dialog_update_citizens(struct city_dialog *pdialog);
-static void city_dialog_update_information(GtkWidget **info_label,
+static void city_dialog_update_information(GtkWidget **info_ebox,
+ GtkWidget **info_label,
struct city_dialog *pdialog);
static void city_dialog_update_map(struct city_dialog *pdialog);
static void city_dialog_update_building(struct city_dialog *pdialog);
@@ -357,7 +362,8 @@
city_dialog_update_title(pdialog);
city_dialog_update_citizens(pdialog);
- city_dialog_update_information(pdialog->overview.info_label, pdialog);
+ city_dialog_update_information(pdialog->overview.info_ebox,
+ pdialog->overview.info_label, pdialog);
city_dialog_update_map(pdialog);
city_dialog_update_building(pdialog);
city_dialog_update_improvement_list(pdialog);
@@ -372,7 +378,8 @@
refresh_worklist(pdialog->production.worklist);
- city_dialog_update_information(pdialog->happiness.info_label, pdialog);
+ city_dialog_update_information(pdialog->happiness.info_ebox,
+ pdialog->happiness.info_label, pdialog);
refresh_happiness_dialog(pdialog->pcity);
refresh_cma_dialog(pdialog->pcity, REFRESH_ALL);
@@ -482,14 +489,90 @@
return FALSE;
}
+/**************************************************************************
+...
+**************************************************************************/
+static gboolean show_info_button_release(GtkWidget *w, GdkEventButton *ev,
+ gpointer data)
+{
+ gtk_grab_remove(w);
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ gtk_widget_destroy(w);
+ return FALSE;
+}
+
+enum { FIELD_FOOD, FIELD_SHIELD, FIELD_TRADE, FIELD_GOLD, FIELD_LUXURY,
+ FIELD_SCIENCE, FIELD_GRANARY, FIELD_GROWTH, FIELD_CORRUPTION,
+ FIELD_WASTE, FIELD_POLLUTION
+};
+
+/****************************************************************
+...
+*****************************************************************/
+static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev,
+ gpointer data)
+{
+ struct city_dialog *pdialog = g_object_get_data(G_OBJECT(w), "pdialog");
+
+ if (ev->button == 1) {
+ GtkWidget *p, *label;
+ char buf[1024];
+
+ switch (GPOINTER_TO_UINT(data)) {
+ case FIELD_FOOD:
+ get_city_dialog_food_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_SHIELD:
+ get_city_dialog_shield_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_TRADE:
+ get_city_dialog_trade_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_GOLD:
+ get_city_dialog_gold_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_SCIENCE:
+ get_city_dialog_science_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_LUXURY:
+ get_city_dialog_luxury_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ case FIELD_POLLUTION:
+ get_city_dialog_pollution_text(pdialog->pcity, buf, sizeof(buf));
+ break;
+ default:
+ return TRUE;
+ }
+
+ p = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_widget_set_name(p, "Freeciv");
+ gtk_container_set_border_width(GTK_CONTAINER(p), 4);
+ gtk_window_set_position(GTK_WINDOW(p), GTK_WIN_POS_MOUSE);
+
+ label = gtk_label_new(buf);
+ gtk_widget_set_name(label, "city info label");
+ gtk_container_add(GTK_CONTAINER(p), label);
+ gtk_widget_show_all(p);
+
+ gdk_pointer_grab(p->window, TRUE, GDK_BUTTON_RELEASE_MASK,
+ NULL, NULL, ev->time);
+ gtk_grab_add(p);
+
+ g_signal_connect_after(p, "button_release_event",
+ G_CALLBACK(show_info_button_release), NULL);
+ }
+ return TRUE;
+}
/****************************************************************
used once in the overview page and once in the happiness page
**info_label points to the info_label in the respective struct
****************************************************************/
-static GtkWidget *create_city_info_table(GtkWidget **info_label)
+static GtkWidget *create_city_info_table(struct city_dialog *pdialog,
+ GtkWidget **info_ebox,
+ GtkWidget **info_label)
{
int i;
- GtkWidget *hbox, *table, *label;
+ GtkWidget *hbox, *table, *label, *ebox;
static const char *output_label[NUM_INFO_FIELDS] = { N_("Food:"),
N_("Prod:"),
@@ -523,12 +606,20 @@
gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, GTK_FILL, 0,
0, 0);
+ ebox = gtk_event_box_new();
+ g_object_set_data(G_OBJECT(ebox), "pdialog", pdialog);
+ g_signal_connect(ebox, "button_press_event",
+ G_CALLBACK(show_info_popup), GUINT_TO_POINTER(i));
+ info_ebox[i] = ebox;
+
label = gtk_label_new("");
info_label[i] = label;
gtk_widget_set_name(label, "city label"); /* ditto */
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_table_attach(GTK_TABLE(table), label, 1, 2, i, i + 1, GTK_FILL, 0,
+ gtk_container_add(GTK_CONTAINER(ebox), label);
+
+ gtk_table_attach(GTK_TABLE(table), ebox, 1, 2, i, i + 1, GTK_FILL, 0,
0, 0);
}
@@ -577,7 +668,9 @@
frame = gtk_frame_new(_("Info"));
gtk_box_pack_start(GTK_BOX(top), frame, FALSE, FALSE, 0);
- table = create_city_info_table(pdialog->overview.info_label);
+ table = create_city_info_table(pdialog,
+ pdialog->overview.info_ebox,
+ pdialog->overview.info_label);
gtk_container_add(GTK_CONTAINER(frame), table);
frame = gtk_frame_new(_("City map"));
@@ -864,7 +957,9 @@
align = gtk_alignment_new(0.5, 0.5, 0, 0);
gtk_container_add(GTK_CONTAINER(vbox), align);
- table = create_city_info_table(pdialog->happiness.info_label);
+ table = create_city_info_table(pdialog,
+ pdialog->happiness.info_ebox,
+ pdialog->happiness.info_label);
gtk_container_add(GTK_CONTAINER(align), table);
gtk_widget_show_all(page);
@@ -1072,6 +1167,9 @@
}
}
+
+
+
/****************************************************************
...
*****************************************************************/
@@ -1299,54 +1397,52 @@
/****************************************************************
...
*****************************************************************/
-static void city_dialog_update_information(GtkWidget **info_label,
+static void city_dialog_update_information(GtkWidget **info_ebox,
+ GtkWidget **info_label,
struct city_dialog *pdialog)
{
int i, style;
char buf[NUM_INFO_FIELDS][512];
struct city *pcity = pdialog->pcity;
int granaryturns;
- enum { FOOD, SHIELD, TRADE, GOLD, LUXURY, SCIENCE,
- GRANARY, GROWTH, CORRUPTION, WASTE, POLLUTION
- };
/* fill the buffers with the necessary info */
- my_snprintf(buf[FOOD], sizeof(buf[FOOD]), "%2d (%+2d)",
+ my_snprintf(buf[FIELD_FOOD], sizeof(buf[FIELD_FOOD]), "%2d (%+2d)",
pcity->food_prod, pcity->food_surplus);
- my_snprintf(buf[SHIELD], sizeof(buf[SHIELD]), "%2d (%+2d)",
+ my_snprintf(buf[FIELD_SHIELD], sizeof(buf[FIELD_SHIELD]), "%2d (%+2d)",
pcity->shield_prod + pcity->shield_waste,
pcity->shield_surplus);
- my_snprintf(buf[TRADE], sizeof(buf[TRADE]), "%2d (%+2d)",
+ my_snprintf(buf[FIELD_TRADE], sizeof(buf[FIELD_TRADE]), "%2d (%+2d)",
pcity->trade_prod + pcity->corruption, pcity->trade_prod);
- my_snprintf(buf[GOLD], sizeof(buf[GOLD]), "%2d (%+2d)",
+ my_snprintf(buf[FIELD_GOLD], sizeof(buf[FIELD_GOLD]), "%2d (%+2d)",
pcity->tax_total, city_gold_surplus(pcity, pcity->tax_total));
- my_snprintf(buf[LUXURY], sizeof(buf[LUXURY]), "%2d ",
+ my_snprintf(buf[FIELD_LUXURY], sizeof(buf[FIELD_LUXURY]), "%2d ",
pcity->luxury_total);
- my_snprintf(buf[SCIENCE], sizeof(buf[SCIENCE]), "%2d",
+ my_snprintf(buf[FIELD_SCIENCE], sizeof(buf[FIELD_SCIENCE]), "%2d",
pcity->science_total);
- my_snprintf(buf[GRANARY], sizeof(buf[GRANARY]), "%d/%-d",
+ my_snprintf(buf[FIELD_GRANARY], sizeof(buf[FIELD_GRANARY]), "%d/%-d",
pcity->food_stock, city_granary_size(pcity->size));
-
+
granaryturns = city_turns_to_grow(pcity);
if (granaryturns == 0) {
- my_snprintf(buf[GROWTH], sizeof(buf[GROWTH]), _("blocked"));
+ my_snprintf(buf[FIELD_GROWTH], sizeof(buf[FIELD_GROWTH]), _("blocked"));
} else if (granaryturns == FC_INFINITY) {
- my_snprintf(buf[GROWTH], sizeof(buf[GROWTH]), _("never"));
+ my_snprintf(buf[FIELD_GROWTH], sizeof(buf[FIELD_GROWTH]), _("never"));
} else {
/* A negative value means we'll have famine in that many turns.
But that's handled down below. */
- my_snprintf(buf[GROWTH], sizeof(buf[GROWTH]),
+ my_snprintf(buf[FIELD_GROWTH], sizeof(buf[FIELD_GROWTH]),
PL_("%d turn", "%d turns", abs(granaryturns)),
abs(granaryturns));
}
- my_snprintf(buf[CORRUPTION], sizeof(buf[CORRUPTION]), "%2d",
+ my_snprintf(buf[FIELD_CORRUPTION], sizeof(buf[FIELD_CORRUPTION]), "%2d",
pcity->corruption);
- my_snprintf(buf[WASTE], sizeof(buf[WASTE]), "%2d",
+ my_snprintf(buf[FIELD_WASTE], sizeof(buf[FIELD_WASTE]), "%2d",
pcity->shield_waste);
- my_snprintf(buf[POLLUTION], sizeof(buf[POLLUTION]), "%2d",
+ my_snprintf(buf[FIELD_POLLUTION], sizeof(buf[FIELD_POLLUTION]), "%2d",
pcity->pollution);
/* stick 'em in the labels */
@@ -1360,16 +1456,17 @@
* "4" below is arbitrary. 3 turns should be enough of a warning.
*/
style = (granaryturns > -4 && granaryturns < 0) ? RED : NORMAL;
- gtk_widget_modify_style(info_label[GRANARY], info_label_style[style]);
+ gtk_widget_modify_style(info_label[FIELD_GRANARY], info_label_style[style]);
style = (granaryturns == 0 || pcity->food_surplus < 0) ? RED : NORMAL;
- gtk_widget_modify_style(info_label[GROWTH], info_label_style[style]);
+ gtk_widget_modify_style(info_label[FIELD_GROWTH], info_label_style[style]);
/* someone could add the info_label_style[ORANGE]
* style for better granularity here */
style = (pcity->pollution >= 10) ? RED : NORMAL;
- gtk_widget_modify_style(info_label[POLLUTION], info_label_style[style]);
+ gtk_widget_modify_style(info_label[FIELD_POLLUTION],
+ info_label_style[style]);
}
/****************************************************************
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.252
diff -u -r1.252 city.c
--- common/city.c 19 Oct 2004 06:46:57 -0000 1.252
+++ common/city.c 22 Oct 2004 03:45:55 -0000
@@ -1908,30 +1908,47 @@
}
/**************************************************************************
- Calculate pollution for the city. The shield_total must be passed in
- (most callers will want to pass pcity->shield_prod).
+ Calculate the pollution from production and population in the city.
**************************************************************************/
-int city_pollution(struct city *pcity, int shield_total)
+int city_pollution_types(const struct city *pcity, int shield_total,
+ int *pollu_prod, int *pollu_pop, int *pollu_mod)
{
struct player *pplayer = city_owner(pcity);
- int mod, pollution;
+ int prod, pop, mod;
/* Add one one pollution per shield, multipled by the bonus. */
mod = 100 + get_city_bonus(pcity, EFT_POLLU_PROD_PCT);
mod = MAX(0, mod);
- pollution = shield_total * mod / 100;
+ prod = shield_total * mod / 100;
/* Add one 1/4 pollution per citizen per tech, multiplied by the bonus. */
mod = 100 + get_city_bonus(pcity, EFT_POLLU_POP_PCT);
mod = MAX(0, mod);
- pollution += (pcity->size
- * num_known_tech_with_flag(pplayer,
- TF_POPULATION_POLLUTION_INC)
- * mod) / (4 * 100);
+ pop = (pcity->size
+ * num_known_tech_with_flag(pplayer, TF_POPULATION_POLLUTION_INC)
+ * mod) / (4 * 100);
- pollution = MAX(0, pollution - 20);
+ mod = -20;
- return pollution;
+ if (pollu_prod) {
+ *pollu_prod = prod;
+ }
+ if (pollu_pop) {
+ *pollu_pop = pop;
+ }
+ if (pollu_mod) {
+ *pollu_mod = -20;
+ }
+ return MAX(prod + pop + mod, 0);
+}
+
+/**************************************************************************
+ Calculate pollution for the city. The shield_total must be passed in
+ (most callers will want to pass pcity->shield_prod).
+**************************************************************************/
+int city_pollution(struct city *pcity, int shield_total)
+{
+ return city_pollution_types(pcity, shield_total, NULL, NULL, NULL);
}
/**************************************************************************
@@ -2038,6 +2055,10 @@
/* loop over units, subtracting appropriate amounts of food, shields,
* gold etc -- SKi */
+ pcity->food_upkeep = 0;
+ pcity->shield_upkeep = 0;
+ pcity->gold_unit_upkeep = 0;
+ pcity->gold_building_upkeep = 0;
unit_list_iterate(pcity->units_supported, this_unit) {
struct unit_type *ut = unit_type(this_unit);
int shield_cost = utype_shield_cost(ut, g);
@@ -2086,6 +2107,7 @@
if (shield_cost > 0) {
adjust_city_free_cost(&free_shield, &shield_cost);
if (shield_cost > 0) {
+ pcity->shield_upkeep += shield_cost;
pcity->shield_surplus -= shield_cost;
this_unit->upkeep = shield_cost;
}
@@ -2093,6 +2115,7 @@
if (food_cost > 0) {
adjust_city_free_cost(&free_food, &food_cost);
if (food_cost > 0) {
+ pcity->food_upkeep += food_cost;
pcity->food_surplus -= food_cost;
this_unit->upkeep_food = food_cost;
}
@@ -2102,6 +2125,7 @@
if (gold_cost > 0) {
/* FIXME: This is not implemented -- SKi */
this_unit->upkeep_gold = gold_cost;
+ pcity->gold_unit_upkeep += gold_cost;
}
}
@@ -2115,6 +2139,10 @@
}
}
unit_list_iterate_end;
+
+ built_impr_iterate(pcity, i) {
+ pcity->gold_building_upkeep += improvement_upkeep(pcity, i);
+ } built_impr_iterate_end;
}
/**************************************************************************
@@ -2391,7 +2419,8 @@
int i;
struct city *pcity;
- pcity = fc_malloc(sizeof(struct city));
+ pcity = fc_malloc(sizeof(*pcity));
+ memset(pcity, 0, sizeof(*pcity));
pcity->id = 0;
pcity->owner = pplayer->player_no;
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.165
diff -u -r1.165 city.h
--- common/city.h 20 Oct 2004 18:20:53 -0000 1.165
+++ common/city.h 22 Oct 2004 03:45:55 -0000
@@ -243,6 +243,9 @@
int shield_prod, shield_surplus, shield_waste;
int trade_prod, corruption, tile_trade;
+ /* Upkeeps (gold upkeep is done globally, not per-city). */
+ int food_upkeep, shield_upkeep, gold_unit_upkeep, gold_building_upkeep;
+
/* Cached values for CPU savings. */
int shield_bonus, luxury_bonus, tax_bonus, science_bonus;
@@ -522,6 +525,8 @@
void get_tax_income(struct player *pplayer, int trade, int *sci,
int *lux, int *tax);
int get_city_tithes_bonus(const struct city *pcity);
+int city_pollution_types(const struct city *pcity, int shield_total,
+ int *pollu_prod, int *pollu_pop, int *pollu_mod);
int city_pollution(struct city *pcity, int shield_total);
/*
Index: common/effects.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.c,v
retrieving revision 1.14
diff -u -r1.14 effects.c
--- common/effects.c 10 Oct 2004 21:14:11 -0000 1.14
+++ common/effects.c 22 Oct 2004 03:45:55 -0000
@@ -1149,13 +1149,13 @@
source gives the source type of the effect
effect_type gives the effect type to be considered
**************************************************************************/
-static int get_effect_value(enum target_type target,
- const struct player *target_player,
- const struct city *target_city,
- Impr_Type_id target_building,
- const struct tile *target_tile,
- Impr_Type_id source,
- enum effect_type effect_type)
+int get_effect_value(enum target_type target,
+ const struct player *target_player,
+ const struct city *target_city,
+ Impr_Type_id target_building,
+ const struct tile *target_tile,
+ Impr_Type_id source,
+ enum effect_type effect_type)
{
int value = 0;
@@ -1249,20 +1249,24 @@
The returned vector must be freed (building_vector_free) when the caller
is done with it.
**************************************************************************/
-struct building_vector get_city_bonus_sources(const struct city *pcity,
- enum effect_type effect_type)
+struct effect_source_vector get_city_bonus_sources(const struct city *pcity,
+ enum effect_type effect_type)
{
struct player *pplayer = city_owner(pcity);
- struct building_vector sources;
+ struct effect_source_vector sources;
- building_vector_init(&sources);
+ effect_source_vector_init(&sources);
building_vector_iterate(get_buildings_with_effect(effect_type), pbldg) {
- if (get_effect_value(TARGET_CITY, pplayer, pcity,
- B_LAST, NULL, *pbldg, effect_type) > 0) {
- building_vector_append(&sources, pbldg);
+ struct effect_source e;
+
+ e.building = *pbldg;
+ e.effect_value = get_effect_value(TARGET_CITY, pplayer, pcity,
+ B_LAST, NULL, *pbldg, effect_type);
+ if (e.effect_value != 0) {
+ effect_source_vector_append(&sources, &e);
}
- } building_vector_iterate_end;
+ } effect_source_vector_iterate_end;
return sources;
}
Index: common/effects.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.h,v
retrieving revision 1.9
diff -u -r1.9 effects.h
--- common/effects.h 22 Sep 2004 15:42:28 -0000 1.9
+++ common/effects.h 22 Oct 2004 03:45:55 -0000
@@ -199,6 +199,17 @@
TYPED_LIST_ITERATE(struct effect, effect_list, peffect)
#define effect_list_iterate_end LIST_ITERATE_END
+struct effect_source {
+ Impr_Type_id building;
+ int effect_value;
+};
+#define SPECVEC_TAG effect_source
+#define SPECVEC_TYPE struct effect_source
+#include "specvec.h"
+#define effect_source_vector_iterate(vector, psource) \
+ TYPED_VECTOR_ITERATE(struct effect_source, vector, psource)
+#define effect_source_vector_iterate_end VECTOR_ITERATE_END
+
/* ruleset cache creation and communication functions */
void ruleset_cache_init(void);
void ruleset_cache_free(void);
@@ -239,6 +250,13 @@
Impr_Type_id target_building,
const struct tile *target_tile,
Impr_Type_id source, const struct effect *effect);
+int get_effect_value(enum target_type target,
+ const struct player *target_player,
+ const struct city *target_city,
+ Impr_Type_id target_building,
+ const struct tile *target_tile,
+ Impr_Type_id source,
+ enum effect_type effect_type);
bool is_building_replaced(const struct city *pcity, Impr_Type_id building);
@@ -255,8 +273,8 @@
enum effect_type effect_type);
struct effect_type_vector *get_building_effect_types(Impr_Type_id building);
-struct building_vector get_city_bonus_sources(const struct city *pcity,
- enum effect_type effect_type);
+struct effect_source_vector get_city_bonus_sources(const struct city *pcity,
+ enum effect_type effect_type);
bool building_has_effect(Impr_Type_id building,
enum effect_type effect_type);
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.57
diff -u -r1.57 packets.def
--- common/packets.def 21 Oct 2004 20:27:28 -0000 1.57
+++ common/packets.def 22 Oct 2004 03:45:56 -0000
@@ -398,6 +398,7 @@
UINT8 specialists[SP_COUNT];
UINT16 food_prod, shield_prod, trade_prod;
+ UINT16 food_upkeep, shield_upkeep, gold_unit_upkeep, gold_building_upkeep;
SINT16 food_surplus, shield_surplus, tile_trade;
UINT16 food_stock, shield_stock, corruption;
Index: data/freeciv.rc-2.0
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/freeciv.rc-2.0,v
retrieving revision 1.20
diff -u -r1.20 freeciv.rc-2.0
--- data/freeciv.rc-2.0 18 Oct 2004 23:49:27 -0000 1.20
+++ data/freeciv.rc-2.0 22 Oct 2004 03:45:56 -0000
@@ -1,3 +1,8 @@
+style "city_info_label"
+{
+ font_name = "Monospace 8"
+}
+
style "city_label"
{
font_name = "Monospace 8"
@@ -75,6 +80,7 @@
font_name = "Serif 10"
}
+widget "Freeciv*.city info label" style "city_info_label"
widget "Freeciv*.city label" style "city_label"
widget "Freeciv*.notify label" style "notify_label"
widget "Freeciv*.spaceship label" style "spaceship_label"
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.277
diff -u -r1.277 citytools.c
--- server/citytools.c 19 Oct 2004 06:46:57 -0000 1.277
+++ server/citytools.c 22 Oct 2004 03:45:56 -0000
@@ -1588,7 +1588,12 @@
packet->trade_prod=pcity->trade_prod;
packet->tile_trade=pcity->tile_trade;
packet->corruption=pcity->corruption;
-
+
+ packet->food_upkeep = pcity->food_upkeep;
+ packet->shield_upkeep = pcity->shield_upkeep;
+ packet->gold_unit_upkeep = pcity->gold_unit_upkeep;
+ packet->gold_building_upkeep = pcity->gold_building_upkeep;
+
packet->shield_waste=pcity->shield_waste;
packet->luxury_total=pcity->luxury_total;
|
|