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

 This allows editing what tiles player knows.


 - ML

diff -Nurd -X.diff_ignore freeciv/client/editor.c freeciv/client/editor.c
--- freeciv/client/editor.c	2007-02-26 14:16:19.000000000 +0200
+++ freeciv/client/editor.c	2007-03-02 04:43:03.000000000 +0200
@@ -39,6 +39,8 @@
 static enum editor_paint_type selected_paint_type = EPAINT_LAST;
 static struct unit *selected_unit;
 static struct city *selected_city;
+static struct player *selected_player;
+static enum editor_vision_mode selected_vision_mode;
 
 /****************************************************************************
   Initialize the editor tools data.
@@ -64,6 +66,8 @@
   selected_special = S_LAST;
   selected_paint_type = EPAINT_LAST;
   selected_terrain = NULL;
+  selected_player = NULL;
+  selected_vision_mode = EVISION_LAST;
 }
 
 /****************************************************************************
@@ -99,6 +103,22 @@
 }
 
 /****************************************************************************
+  Sets the selected editor player.
+****************************************************************************/
+void editor_set_selected_player(struct player *pplayer)
+{
+  selected_player = pplayer;
+}
+
+/****************************************************************************
+  Sets the selected editor vision modifying tool.
+****************************************************************************/
+void editor_set_vision_mode(enum editor_vision_mode mode)
+{
+  selected_vision_mode = mode;
+}
+
+/****************************************************************************
   Returns the selected unit.
 ****************************************************************************/
 struct unit *editor_get_selected_unit(void)
@@ -174,6 +194,21 @@
   return CURSOR_EDIT_ADD;
 }
 
+/****************************************************************************
+  Edit vision
+****************************************************************************/
+static enum cursor_type editor_vision(struct tile *ptile, bool testing)
+{
+  if (!testing) {
+    if (selected_player) {
+      dsend_packet_edit_vision(&aconnection, selected_player->player_no,
+                               ptile->x, ptile->y, selected_vision_mode);
+    }
+  }
+
+  return CURSOR_EDIT_PAINT;
+}
+
 #if 0
 /****************************************************************************
  basically package_city in citytools.c
@@ -243,7 +278,8 @@
 {
   /* Editing tiles that we can't see (or are fogged) will only lead to
    * problems. */
-  if (client_tile_get_known(ptile) != TILE_KNOWN) {
+  if (selected_tool != ETOOL_VISION &&
+      client_tile_get_known(ptile) != TILE_KNOWN) {
     return CURSOR_INVALID;
   }
 
@@ -261,6 +297,8 @@
     }
     return editor_city(ptile, testing);
   case ETOOL_PLAYER:
+  case ETOOL_VISION:
+    return editor_vision(ptile, testing);
   case ETOOL_DELETE:
   case ETOOL_LAST:
     break;
diff -Nurd -X.diff_ignore freeciv/client/editor.h freeciv/client/editor.h
--- freeciv/client/editor.h	2007-02-26 14:16:19.000000000 +0200
+++ freeciv/client/editor.h	2007-03-02 04:39:08.000000000 +0200
@@ -21,6 +21,7 @@
   ETOOL_UNIT,
   ETOOL_CITY,
   ETOOL_PLAYER,
+  ETOOL_VISION,
   ETOOL_DELETE,
   ETOOL_LAST
 };
@@ -40,6 +41,8 @@
 void editor_set_selected_paint_type(enum editor_paint_type type);
 void editor_set_selected_terrain(struct terrain *pterrain);
 void editor_set_selected_special(enum tile_special_type special);
+void editor_set_selected_player(struct player *pplayer);
+void editor_set_vision_mode(enum editor_vision_mode mode);
 
 struct unit *editor_get_selected_unit(void);
 struct city *editor_get_selected_city(void);
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/editdlg.c freeciv/client/gui-gtk-2.0/editdlg.c
--- freeciv/client/gui-gtk-2.0/editdlg.c	2007-02-26 14:16:16.000000000 +0200
+++ freeciv/client/gui-gtk-2.0/editdlg.c	2007-03-02 04:41:50.000000000 +0200
@@ -70,8 +70,14 @@
   { NULL, S_FALLOUT }
 };
 
+static paint_item vision_items[] = {
+  { N_("Known"),   EVISION_ADD },
+  { N_("Unknown"), EVISION_REMOVE },
+  { N_("Toggle"),  EVISION_TOGGLE }
+};
+
 static char *tool_names[ETOOL_LAST] = {
-  N_("Paint"), N_("Unit"), N_("City"), N_("Player"), N_("Delete")
+  N_("Paint"), N_("Unit"), N_("City"), N_("Player"), N_("Vision"), N_("Delete")
 };
 
 #define SPECIALS_NUM ARRAY_SIZE(specials)
@@ -81,6 +87,7 @@
 
 static GList *tool_group;
 static GList *map_group;
+static GList *vision_group;
 
 /****************************************************************************
   handle the toggle buttons' toggle events
@@ -178,6 +185,13 @@
   }
 }
 
+static void set_selected_vision_paint(GtkWidget *w, gpointer data)
+{
+  enum editor_vision_mode edit_type = GPOINTER_TO_INT(data);
+
+  editor_set_vision_mode(edit_type);
+}
+
 /****************************************************************************
   FIXME: this is for demonstration purposes only (and not demonstration of
           coding goodness to be sure!)
@@ -237,6 +251,16 @@
   pcity->owner = get_player(to);
 }
 
+/****************************************************************************
+  Set whose vision we are editing.
+****************************************************************************/
+static void vision_callback(GtkWidget *button, gpointer data)
+{
+  size_t to = (size_t) data;
+
+  editor_set_selected_player(get_player(to));
+}
+
 #if 0
 /****************************************************************************
  FIXME: this is for demonstration purposes only (and not demonstration of
@@ -458,7 +482,6 @@
   return vbox;
 }
 
-#if 0
 /****************************************************************************
   Create the tab for the player editor tool.
 ****************************************************************************/
@@ -470,7 +493,75 @@
 
   return vbox;
 }
-#endif
+
+/****************************************************************************
+  Create the tab for the vision editor tool.
+****************************************************************************/
+static GtkWidget *create_vision_palette(void)
+{
+  GtkWidget *vbox, *hbox, *bbox, *label, *button;
+  GtkWidget *playermenu, *popupmenu;
+  int i, sig;
+
+  vbox = gtk_vbox_new(FALSE, 5);
+  hbox = gtk_hbox_new(FALSE, 5);
+  bbox = gtk_hbox_new(FALSE, 5);
+
+  label = gtk_label_new(_("Player"));
+  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+
+  playermenu = gtk_option_menu_new();
+  popupmenu = gtk_menu_new();
+  gtk_option_menu_set_menu(GTK_OPTION_MENU(playermenu), popupmenu);
+  players_iterate(pplayer) {
+    char data[1024];
+    GtkWidget *item;
+
+    if (pplayer->nation) {
+      my_snprintf(data, sizeof(data), "%s (%s)",
+		  pplayer->name, pplayer->nation->name);
+    } else {
+      my_snprintf(data, sizeof(data), "%s", pplayer->name);
+
+    }
+    item = gtk_menu_item_new_with_label(data);
+
+    g_signal_connect(item, "activate",
+                     G_CALLBACK(vision_callback),
+                     GINT_TO_POINTER(pplayer->player_no));
+    gtk_menu_shell_append(GTK_MENU_SHELL(popupmenu), item);
+  } players_iterate_end;
+  gtk_box_pack_start(GTK_BOX(hbox), playermenu, TRUE, TRUE, 0);
+
+  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+  for(i = 0; i < EVISION_LAST; i++) {
+    paint_item *item = &vision_items[i];
+
+    button = gtk_toggle_button_new_with_label(item->name);
+
+    gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button),
+                                (i == EVISION_ADD) ? TRUE : FALSE);
+    sig = g_signal_connect(button, "toggled",
+                           G_CALLBACK(set_selected_vision_paint),
+                           GINT_TO_POINTER(i));
+
+    /* add this button to a group */
+    vision_group = g_list_append(vision_group, button);
+
+    /* add this group and the signal id to widget internal data */
+    g_signal_connect(button, "toggled", G_CALLBACK(toggle_group_callback),
+                     (gpointer)vision_group);
+    g_object_set_data(G_OBJECT(button), "sigid", GINT_TO_POINTER(sig));
+
+    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
+  }
+
+  gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+  return vbox;
+}
 
 /****************************************************************************
   Create the tools dialog.
@@ -516,10 +607,10 @@
 			   create_units_palette(), NULL);
   gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
 			   create_city_palette(), NULL);
-#if 0
   gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
 			   create_player_palette(), NULL);
-#endif
+  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+                           create_vision_palette(), NULL);
 
   gtk_widget_show_all(toolwin);
 }
diff -Nurd -X.diff_ignore freeciv/common/fc_types.h freeciv/common/fc_types.h
--- freeciv/common/fc_types.h	2007-02-12 17:40:06.000000000 +0200
+++ freeciv/common/fc_types.h	2007-03-02 04:37:36.000000000 +0200
@@ -173,4 +173,11 @@
 
 #define AI_LEVEL_DEFAULT AI_LEVEL_NOVICE
 
+enum editor_vision_mode {
+  EVISION_ADD,
+  EVISION_REMOVE,
+  EVISION_TOGGLE,
+  EVISION_LAST
+};
+
 #endif /* FC__FC_TYPES_H */
diff -Nurd -X.diff_ignore freeciv/common/packets.def freeciv/common/packets.def
--- freeciv/common/packets.def	2007-03-01 22:59:22.000000000 +0200
+++ freeciv/common/packets.def	2007-03-02 04:37:50.000000000 +0200
@@ -1455,3 +1455,9 @@
 
 PACKET_EDIT_RECALCULATE_BORDERS=131;cs,handle-per-conn
 end
+
+PACKET_EDIT_VISION=132;cs,handle-per-conn,dsend
+  PLAYER player;
+  COORD x, y;
+  UINT8 mode;
+end
diff -Nurd -X.diff_ignore freeciv/server/citytools.c freeciv/server/citytools.c
--- freeciv/server/citytools.c	2007-02-28 23:02:37.000000000 +0200
+++ freeciv/server/citytools.c	2007-03-02 04:25:58.000000000 +0200
@@ -945,7 +945,7 @@
    * to some players, but we don't want to make any special handling for
    * those cases.  The network code may prevent asecond packet from being
    * sent anyway. */
-  send_tile_info(NULL, ptile);
+  send_tile_info(NULL, ptile, FALSE);
 
   pcity = create_city_virtual(pplayer, ptile, name);
   pcity->ai.trade_want = TRADE_WEIGHTING;
diff -Nurd -X.diff_ignore freeciv/server/edithand.c freeciv/server/edithand.c
--- freeciv/server/edithand.c	2007-02-26 14:15:28.000000000 +0200
+++ freeciv/server/edithand.c	2007-03-02 04:39:32.000000000 +0200
@@ -28,6 +28,7 @@
 #include "map.h"
 #include "movement.h"
 #include "terrain.h"
+#include "unitlist.h"
 
 #include "citytools.h"
 #include "cityturn.h"
@@ -98,7 +99,7 @@
 
   /* update playertiles and send updates to the clients */
   update_tile_knowledge(ptile);
-  send_tile_info(NULL, ptile);
+  send_tile_info(NULL, ptile, FALSE);
 }
 
 /****************************************************************************
@@ -406,6 +407,53 @@
 }
 
 /****************************************************************************
+  Handles vision editing requests from client
+****************************************************************************/
+void handle_edit_vision(struct connection *pc, int plr_no, int x, int y,
+                        int mode)
+{
+  struct player *pplayer = get_player(plr_no);
+  struct tile *ptile = map_pos_to_tile(x, y);
+  bool remove_knowledge = FALSE;
+
+  if (!can_conn_edit(pc) || !pplayer || !ptile) {
+    return;
+  }
+
+  if (mode == EVISION_REMOVE
+      || (mode == EVISION_TOGGLE && map_is_known(ptile, pplayer))) {
+    remove_knowledge = TRUE;
+  }
+
+  if (remove_knowledge) {
+    struct city *pcity = tile_get_city(ptile);
+
+    if (pcity && pcity->owner == pplayer) {
+      notify_conn(pc->self, NULL, E_BAD_COMMAND,
+                  _("Cannot remove knowledde about own city."));
+      return;
+    }
+
+    unit_list_iterate(ptile->units, punit) {
+      if (punit->owner == pplayer) {
+        notify_conn(pc->self, NULL, E_BAD_COMMAND,
+                    _("Cannot remove knowledde about own unit."));
+        return;
+      }
+    } unit_list_iterate_end;
+  }
+
+  if (!remove_knowledge) {
+    map_set_known(ptile, pplayer);
+    update_player_tile_knowledge(pplayer, ptile);
+  } else {
+    map_clear_known(ptile, pplayer);
+  }
+
+  send_tile_info(pplayer->connections, ptile, TRUE);
+}
+
+/****************************************************************************
   Client editor requests us to recalculate borders. Note that this does
   not necessarily extend borders to their maximum due to the way the
   borders code is written. This may be considered a feature or limitation.
diff -Nurd -X.diff_ignore freeciv/server/maphand.c freeciv/server/maphand.c
--- freeciv/server/maphand.c	2007-02-12 15:27:37.000000000 +0200
+++ freeciv/server/maphand.c	2007-03-02 04:27:54.000000000 +0200
@@ -422,7 +422,7 @@
       conn_list_do_buffer(dest);
     }
 
-    send_tile_info(dest, ptile);
+    send_tile_info(dest, ptile, FALSE);
   } whole_map_iterate_end;
 
   conn_list_do_unbuffer(dest);
@@ -437,7 +437,8 @@
   Note that this function does not update the playermap.  For that call
   update_tile_knowledge().
 **************************************************************************/
-void send_tile_info(struct conn_list *dest, struct tile *ptile)
+void send_tile_info(struct conn_list *dest, struct tile *ptile,
+                    bool send_unknown)
 {
   struct packet_tile_info info;
 
@@ -482,6 +483,15 @@
       info.resource = plrtile->resource ? plrtile->resource->index : -1;
       info.continent = ptile->continent;
       send_packet_tile_info(pconn, &info);
+    } else if (send_unknown) {
+      info.known = TILE_UNKNOWN;
+      info.type  = -1;
+      for (spe = 0; spe < S_LAST; spe++) {
+        info.special[spe] = FALSE;
+      }
+      info.resource  = -1;
+      info.continent = 0;
+      send_packet_tile_info(pconn, &info);
     }
   }
   conn_list_iterate_end;
@@ -517,7 +527,7 @@
      * continent number before it can handle following packets
      */
     update_player_tile_knowledge(pplayer, ptile);
-    send_tile_info(pplayer->connections, ptile);
+    send_tile_info(pplayer->connections, ptile, FALSE);
     /* NOTE: because the V_INVIS case doesn't fall into this if statement,
      * changes to V_INVIS fogging won't send a new info packet to the client
      * and the client's tile_seen[V_INVIS] bitfield may end up being out
@@ -598,7 +608,7 @@
 
   if (vlayer == V_MAIN) {
     update_player_tile_last_seen(pplayer, ptile);
-    send_tile_info(pplayer->connections, ptile);
+    send_tile_info(pplayer->connections, ptile, FALSE);
   }
 }
 
@@ -706,7 +716,7 @@
 	update_player_tile_knowledge(pplayer, ptile);
 	update_player_tile_last_seen(pplayer, ptile);
 
-	send_tile_info(pplayer->connections, ptile);
+	send_tile_info(pplayer->connections, ptile, FALSE);
 
 	/* remove old cities that exist no more */
 	reality_check_city(pplayer, ptile);
@@ -1018,7 +1028,7 @@
   players_iterate(pplayer) {
     if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
       if (update_player_tile_knowledge(pplayer, ptile)) {
-        send_tile_info(pplayer->connections, ptile);
+        send_tile_info(pplayer->connections, ptile, FALSE);
       }
     }
   } players_iterate_end;
@@ -1027,7 +1037,7 @@
   conn_list_iterate(game.est_connections, pconn) {
     struct player *pplayer = pconn->player;
     if (!pplayer && pconn->observer) {
-      send_tile_info(pconn->self, ptile);
+      send_tile_info(pconn->self, ptile, FALSE);
     }
   } conn_list_iterate_end;
 }
@@ -1069,7 +1079,7 @@
       dest_tile->special = from_tile->special;
       dest_tile->resource = from_tile->resource;
       dest_tile->last_updated = from_tile->last_updated;
-      send_tile_info(pdest->connections, ptile);
+      send_tile_info(pdest->connections, ptile, FALSE);
 	
       /* update and send city knowledge */
       /* remove outdated cities */
@@ -1501,7 +1511,7 @@
 {
   ptile->owner_source = source;
   tile_set_owner(ptile, owner);
-  send_tile_info(NULL, ptile);
+  send_tile_info(NULL, ptile, FALSE);
   tile_update_owner(ptile);
 }
 
diff -Nurd -X.diff_ignore freeciv/server/maphand.h freeciv/server/maphand.h
--- freeciv/server/maphand.h	2007-02-12 15:27:37.000000000 +0200
+++ freeciv/server/maphand.h	2007-03-02 04:25:32.000000000 +0200
@@ -59,7 +59,8 @@
 void give_citymap_from_player_to_player(struct city *pcity,
 					struct player *pfrom, struct player *pdest);
 void send_all_known_tiles(struct conn_list *dest);
-void send_tile_info(struct conn_list *dest, struct tile *ptile);
+void send_tile_info(struct conn_list *dest, struct tile *ptile,
+                    bool send_unknown);
 void upgrade_city_rails(struct player *pplayer, bool discovery);
 void send_map_info(struct conn_list *dest);
 
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to