<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40704 >

Patch implements a feature to be able to buy directly from the
main map in multiple cities at once. The buying function is
activated by pressing 'b' when the target cities are selected.
The selected cities are sorted in order of increasing buy cost
so that as many productions are bought for the least amount of
gold as possible.


-----------------------------------------------------------------------
買え!買え!買え!
 client/climisc.c              |   58 +++++++++++++++++++++++++++++++++++++++++
 client/climisc.h              |    2 +
 client/gui-gtk-2.0/gui_main.c |    7 +++++
 3 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/client/climisc.c b/client/climisc.c
index 9518bf7..ccb5856 100644
--- a/client/climisc.c
+++ b/client/climisc.c
@@ -53,6 +53,7 @@ used throughout the client.
 #include "climap.h"
 #include "climisc.h"
 #include "control.h"
+#include "mapctrl_common.h"
 #include "messagewin_common.h"
 #include "packhand.h"
 #include "plrdlg_common.h"
@@ -1140,3 +1141,60 @@ enum unit_bg_color_type unit_color_type(const struct unit_type *punittype)
 
   return UNIT_BG_FLYING;
 }
+
+/****************************************************************************
+  Comparison function used by qsort in buy_production_in_selected_cities().
+****************************************************************************/
+static int city_buy_cost_compare(const void *a, const void *b)
+{
+  const struct city *ca, *cb;
+  ca = *((const struct city **) a);
+  cb = *((const struct city **) b);
+  return (city_production_buy_gold_cost(ca)
+          - city_production_buy_gold_cost(cb));
+}
+
+/****************************************************************************
+  For each selected city, buy the current production. The selected cities
+  are sorted so production is bought in the cities with lowest cost first.
+****************************************************************************/
+void buy_production_in_selected_cities(void)
+{
+  const struct player *pplayer = client_player();
+  if (!pplayer || !pplayer->cities
+      || city_list_size(pplayer->cities) < 1) {
+    return;
+  }
+
+  int gold = pplayer->economic.gold;
+  if (gold < 1) {
+    return;
+  }
+
+  const int n = city_list_size(pplayer->cities);
+  struct city *cities[n];
+  int i, count = 0;
+
+  city_list_iterate(pplayer->cities, pcity) {
+    if (!is_city_hilited(pcity) || !city_can_buy(pcity)) {
+      continue;
+    }
+    cities[count++] = pcity;
+  } city_list_iterate_end;
+
+  if (count < 1) {
+    return;
+  }
+
+  qsort(cities, count, sizeof(*cities), city_buy_cost_compare);
+
+  struct connection *pconn = &client.conn;
+  connection_do_buffer(pconn);
+
+  for (i = 0; i < count && gold > 0; i++) {
+    gold -= city_production_buy_gold_cost(cities[i]);
+    city_buy_production(cities[i]);
+  }
+
+  connection_do_unbuffer(pconn);
+}
diff --git a/client/climisc.h b/client/climisc.h
index 5c87b69..6c77a0e 100644
--- a/client/climisc.h
+++ b/client/climisc.h
@@ -124,4 +124,6 @@ enum unit_bg_color_type { UNIT_BG_HP_LOSS,
 
 enum unit_bg_color_type unit_color_type(const struct unit_type *punittype);
 
+void buy_production_in_selected_cities(void);
+
 #endif  /* FC__CLIMISC_H */
diff --git a/client/gui-gtk-2.0/gui_main.c b/client/gui-gtk-2.0/gui_main.c
index 6448d26..16fa289 100644
--- a/client/gui-gtk-2.0/gui_main.c
+++ b/client/gui-gtk-2.0/gui_main.c
@@ -643,6 +643,13 @@ static gboolean key_press_map_canvas(GtkWidget *w, GdkEventKey *ev,
     key_cancel_action();
     return TRUE;
 
+  case GDK_b:
+    if (tiles_hilited_cities) {
+      buy_production_in_selected_cities();
+      return TRUE;
+    }
+    break;
+
   default:
     break;
   };
 client/climisc.c              |   57 +++++++++++++++++++++++++++++++++++++++++
 client/climisc.h              |    2 +
 client/gui-gtk-2.0/gui_main.c |    7 +++++
 3 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/client/climisc.c b/client/climisc.c
index 1df843f..db6c7e0 100644
--- a/client/climisc.c
+++ b/client/climisc.c
@@ -51,6 +51,7 @@ used throughout the client.
 #include "climisc.h"
 #include "clinet.h"
 #include "control.h"
+#include "mapctrl_common.h"
 #include "messagewin_common.h"
 #include "packhand.h"
 #include "plrdlg_common.h"
@@ -1103,3 +1104,59 @@ bool can_units_do_connect(struct unit_list *punits,
 
   return FALSE;
 }
+
+/****************************************************************************
+  Comparison function used by qsort in buy_production_in_selected_cities().
+****************************************************************************/
+static int city_buy_cost_compare(const void *a, const void *b)
+{
+  const struct city *ca, *cb;
+  ca = *((const struct city **) a);
+  cb = *((const struct city **) b);
+  return city_buy_cost(ca) - city_buy_cost(cb);
+}
+
+/****************************************************************************
+  For each selected city, buy the current production. The selected cities
+  are sorted so production is bought in the cities with lowest cost first.
+****************************************************************************/
+void buy_production_in_selected_cities(void)
+{
+  const struct player *pplayer = game.player_ptr;
+  if (!pplayer || !pplayer->cities
+      || city_list_size(pplayer->cities) < 1) {
+    return;
+  }
+
+  int gold = pplayer->economic.gold;
+  if (gold < 1) {
+    return;
+  }
+
+  const int n = city_list_size(pplayer->cities);
+  struct city *cities[n];
+  int i, count = 0;
+
+  city_list_iterate(pplayer->cities, pcity) {
+    if (!is_city_hilited(pcity) || !city_can_buy(pcity)) {
+      continue;
+    }
+    cities[count++] = pcity;
+  } city_list_iterate_end;
+
+  if (count < 1) {
+    return;
+  }
+
+  qsort(cities, count, sizeof(*cities), city_buy_cost_compare);
+
+  struct connection *pconn = &aconnection;
+  connection_do_buffer(pconn);
+
+  for (i = 0; i < count && gold > 0; i++) {
+    gold -= city_buy_cost(cities[i]);
+    city_buy_production(cities[i]);
+  }
+
+  connection_do_unbuffer(pconn);
+}
diff --git a/client/climisc.h b/client/climisc.h
index 1803b10..d52702b 100644
--- a/client/climisc.h
+++ b/client/climisc.h
@@ -118,4 +118,6 @@ void common_taxrates_callback(int i);
 bool can_units_do_connect(struct unit_list *punits,
 			  enum unit_activity activity);
 
+void buy_production_in_selected_cities(void);
+
 #endif  /* FC__CLIMISC_H */
diff --git a/client/gui-gtk-2.0/gui_main.c b/client/gui-gtk-2.0/gui_main.c
index 93ce820..9e6bdf1 100644
--- a/client/gui-gtk-2.0/gui_main.c
+++ b/client/gui-gtk-2.0/gui_main.c
@@ -561,6 +561,13 @@ static gboolean keyboard_map_canvas(GtkWidget *w, GdkEventKey *ev, gpointer data
     key_cancel_action();
     return TRUE;
 
+  case GDK_b:
+    if (tiles_hilited_cities) {
+      buy_production_in_selected_cities();
+      return TRUE;
+    }
+    break;
+
   default:
     break;
   };
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to