Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2004:
[Freeciv-Dev] Re: (PR#7282) connect as orders
Home

[Freeciv-Dev] Re: (PR#7282) connect as orders

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#7282) connect as orders
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 Apr 2004 22:06:05 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=7282 >

Here's an updated connect-as-orders patch.

Changes and non-changes:

- Updated for current CVS.

- Better tilespec sprite choosing.

- Savegame support added.

- Finding the route is still a bit sketchy.

- Still only road, rail, irrigation are supported.

- Still only gui-gtk-2.0 is supported.

Within the limitations it gives very nice behavior.

jason


? cma_weirdness
? client/gui-qpe
? data/civ3
? data/womoks
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.311
diff -u -r1.311 aiunit.c
--- ai/aiunit.c 25 Feb 2004 20:23:49 -0000      1.311
+++ ai/aiunit.c 21 Apr 2004 05:01:03 -0000
@@ -196,7 +196,7 @@
 
   result =
       test_unit_move_to_tile(punit->type, unit_owner(punit),
-                             ACTIVITY_IDLE, FALSE, punit->x, punit->y, 
+                             ACTIVITY_IDLE, punit->x, punit->y, 
                              dest_x, dest_y, unit_flag(punit, F_IGZOC));
   if (result == MR_OK) {
     return 1;
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.134
diff -u -r1.134 control.c
--- client/control.c    16 Apr 2004 17:27:08 -0000      1.134
+++ client/control.c    21 Apr 2004 05:01:03 -0000
@@ -55,6 +55,7 @@
 /* These should be set via set_hover_state() */
 int hover_unit = 0; /* id of unit hover_state applies to */
 enum cursor_hover_state hover_state = HOVER_NONE;
+enum unit_activity connect_activity;
 /* This may only be here until client goto is fully implemented.
    It is reset each time the hower_state is reset. */
 bool draw_goto_line = TRUE;
@@ -79,15 +80,18 @@
 /**************************************************************************
 ...
 **************************************************************************/
-void set_hover_state(struct unit *punit, enum cursor_hover_state state)
+void set_hover_state(struct unit *punit, enum cursor_hover_state state,
+                    enum unit_activity activity)
 {
   assert(punit != NULL || state == HOVER_NONE);
+  assert(state == HOVER_CONNECT || activity == ACTIVITY_LAST);
   draw_goto_line = TRUE;
   if (punit)
     hover_unit = punit->id;
   else
     hover_unit = 0;
   hover_state = state;
+  connect_activity = activity;
   exit_goto_state();
 }
 
@@ -220,7 +224,7 @@
   struct unit *punit_old_focus = punit_focus;
   struct unit *candidate = find_best_focus_candidate(FALSE);
 
-  set_hover_state(NULL, HOVER_NONE);
+  set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
   if (!can_client_change_view()) {
     return;
   }
@@ -601,7 +605,7 @@
     return;
 
   if (hover_state != HOVER_GOTO) {
-    set_hover_state(punit, HOVER_GOTO);
+    set_hover_state(punit, HOVER_GOTO, ACTIVITY_LAST);
     update_unit_info_label(punit);
     /* Not yet implemented for air units, including helicopters. */
     if (is_air_unit(punit) || is_heli_unit(punit)) {
@@ -620,11 +624,21 @@
 prompt player for entering destination point for unit connect
 (e.g. connecting with roads)
 **************************************************************************/
-void request_unit_connect(void)
+void request_unit_connect(enum unit_activity activity)
 {
-  if (punit_focus && can_unit_do_connect (punit_focus, ACTIVITY_IDLE)) {
-    set_hover_state(punit_focus, HOVER_CONNECT);
+  if (!punit_focus || !can_unit_do_connect(punit_focus, activity)) {
+    return;
+  }
+
+  if (hover_state != HOVER_GOTO && connect_activity != activity) {
+    set_hover_state(punit_focus, HOVER_CONNECT, activity);
     update_unit_info_label(punit_focus);
+
+    enter_goto_state(punit_focus);
+    create_line_at_mouse_pos();
+  } else {
+    assert(goto_is_active());
+    goto_add_waypoint();
   }
 }
 
@@ -926,7 +940,7 @@
   if(punit->moves_left == 0)
     do_unit_nuke(punit);
   else {
-    set_hover_state(punit, HOVER_NUKE);
+    set_hover_state(punit, HOVER_NUKE, ACTIVITY_LAST);
     update_unit_info_label(punit);
   }
 }
@@ -943,7 +957,7 @@
   if(!can_unit_paradrop(punit))
     return;
 
-  set_hover_state(punit, HOVER_PARADROP);
+  set_hover_state(punit, HOVER_PARADROP, ACTIVITY_LAST);
   update_unit_info_label(punit);
 }
 
@@ -958,7 +972,7 @@
     return;
 
   if (hover_state != HOVER_PATROL) {
-    set_hover_state(punit, HOVER_PATROL);
+    set_hover_state(punit, HOVER_PATROL, ACTIVITY_LAST);
     update_unit_info_label(punit);
     /* Not yet implemented for air units, including helicopters. */
     if (is_air_unit(punit) || is_heli_unit(punit)) {
@@ -1378,13 +1392,13 @@
       do_unit_paradrop_to(punit, xtile, ytile);
       break;
     case HOVER_CONNECT:
-      popup_unit_connect_dialog(punit, xtile, ytile);
+      do_unit_connect(punit, xtile, ytile, connect_activity);
       break;
     case HOVER_PATROL:
       do_unit_patrol_to(punit, xtile, ytile);
       break;   
     }
-    set_hover_state(NULL, HOVER_NONE);
+    set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
     update_unit_info_label(punit);
   }
 
@@ -1578,7 +1592,7 @@
     }
   }
 
-  set_hover_state(NULL, HOVER_NONE);
+  set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
 }
 
 /**************************************************************************
@@ -1616,7 +1630,32 @@
     }
   }
 
-  set_hover_state(NULL, HOVER_NONE);
+  set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
+}
+ 
+/**************************************************************************
+  "Connect" to the given location.
+**************************************************************************/
+void do_unit_connect(struct unit *punit, int x, int y,
+                    enum unit_activity activity)
+{
+  if (is_air_unit(punit)) {
+    append_output_window(_("Game: Sorry, airunit connect "
+                          "not yet implemented."));
+  } else {
+    int dest_x, dest_y;
+
+    draw_line(x, y);
+    get_line_dest(&dest_x, &dest_y);
+    if (same_pos(dest_x, dest_y, x, y)) {
+      send_connect_route(punit, activity);
+    } else {
+      append_output_window(_("Game: Didn't find a route to "
+                            "the destination!"));
+    }
+  }
+
+  set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
 }
  
 /**************************************************************************
@@ -1635,7 +1674,7 @@
   if (hover_state != HOVER_NONE && !popped) {
     struct unit *punit = player_find_unit_by_id(game.player_ptr, hover_unit);
 
-    set_hover_state(NULL, HOVER_NONE);
+    set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
     update_unit_info_label(punit);
 
     keyboardless_goto_button_down = FALSE;
@@ -1716,10 +1755,10 @@
 /**************************************************************************
 handle user pressing key for 'Connect' command
 **************************************************************************/
-void key_unit_connect(void)
+void key_unit_connect(enum unit_activity activity)
 {
   if (punit_focus) {
-    request_unit_connect();
+    request_unit_connect(activity);
   }
 }
 
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.42
diff -u -r1.42 control.h
--- client/control.h    1 Apr 2004 23:46:25 -0000       1.42
+++ client/control.h    21 Apr 2004 05:01:03 -0000
@@ -31,6 +31,7 @@
 
 extern int hover_unit; /* unit hover_state applies to */
 extern enum cursor_hover_state hover_state;
+extern enum unit_activity connect_activity;
 extern bool draw_goto_line;
 extern bool non_ai_unit_focus;
 
@@ -39,9 +40,12 @@
 void do_unit_nuke(struct unit *punit);
 void do_unit_paradrop_to(struct unit *punit, int x, int y);
 void do_unit_patrol_to(struct unit *punit, int x, int y);
+void do_unit_connect(struct unit *punit, int x, int y,
+                    enum unit_activity activity);
 void do_map_click(int xtile, int ytile, enum quickselect_type qtype);
 
-void set_hover_state(struct unit *punit, enum cursor_hover_state state);
+void set_hover_state(struct unit *punit, enum cursor_hover_state state,
+                    enum unit_activity activity);
 void request_center_focus_unit(void);
 void request_move_unit_direction(struct unit *punit, int dir);
 void request_new_unit_activity(struct unit *punit, enum unit_activity act);
@@ -54,7 +58,7 @@
 void request_unit_build_city(struct unit *punit);
 void request_unit_caravan_action(struct unit *punit, enum packet_type action);
 void request_unit_change_homecity(struct unit *punit);
-void request_unit_connect(void);
+void request_unit_connect(enum unit_activity activity);
 void request_unit_disband(struct unit *punit);
 void request_unit_fortify(struct unit *punit);
 void request_unit_goto(void);
@@ -135,7 +139,7 @@
 void key_unit_auto_settle(void);
 void key_unit_build_city(void);
 void key_unit_build_wonder(void);
-void key_unit_connect(void);
+void key_unit_connect(enum unit_activity activity);
 void key_unit_diplomat_actions(void);
 void key_unit_disband(void);
 void key_unit_done(void);
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.68
diff -u -r1.68 goto.c
--- client/goto.c       18 Feb 2004 02:26:35 -0000      1.68
+++ client/goto.c       21 Apr 2004 05:01:04 -0000
@@ -365,6 +365,78 @@
   return TB_NORMAL;
 }
 
+static int (*original_MC) (int from_x, int from_y, enum direction8 dir,
+                     int to_x, int to_y, struct pf_parameter *param);
+
+/********************************************************************** 
+  PF callback for move cost. Caravans doesn't go into the unknown and
+  don't attack enemy units but enter enemy cities.
+***********************************************************************/
+static int get_MC(int from_x, int from_y, enum direction8 dir,
+                 int to_x, int to_y, struct pf_parameter *param)
+{
+  int base_mc = original_MC(from_x, from_y, dir, to_x, to_y, param);
+  struct tile *ptile = map_get_tile(to_x, to_y);
+  int activity_mc = 0;
+  struct tile_type *ttype = get_tile_type(map_get_terrain(to_x, to_y));
+
+  if (base_mc == PF_IMPOSSIBLE_MC) {
+    return base_mc;
+  }
+
+  if (hover_state == HOVER_CONNECT) {
+    switch (connect_activity) {
+    case ACTIVITY_IRRIGATE:
+      if (!DIR_IS_CARDINAL(dir)) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      if (tile_has_special(ptile, S_IRRIGATION)) {
+       break;
+      }
+
+      activity_mc = ttype->irrigation_time;
+      if (activity_mc == 0) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      break;
+    case ACTIVITY_ROAD:
+      if (tile_has_special(ptile, S_ROAD)) {
+       break;
+      }
+      activity_mc = ttype->road_time;
+      if (activity_mc == 0
+         || !terrain_control.may_road
+         || (map_has_special(to_x, to_y, S_RIVER)
+             && !player_knows_techs_with_flag(param->owner, TF_BRIDGE))) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      break;
+    case ACTIVITY_RAILROAD:
+      if (!terrain_control.may_road || ttype->road_time == 0) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      if (tile_has_special(ptile, S_RAILROAD)) {
+       break;
+      } else {
+       if (map_has_special(to_x, to_y, S_RIVER)
+           && !player_knows_techs_with_flag(param->owner, TF_BRIDGE)) {
+         return PF_IMPOSSIBLE_MC;
+       }
+       if (!tile_has_special(ptile, S_ROAD)) {
+         activity_mc += ttype->road_time;
+       }
+       activity_mc += ttype->road_time;
+      }
+      break;
+    default:
+      die("Invalid connect activity.");
+    }
+  }
+
+  base_mc += activity_mc * param->move_rate;
+  return base_mc;
+}
+
 /********************************************************************** 
   Fill the PF parameter with the correct client-goto values.
 ***********************************************************************/
@@ -375,6 +447,9 @@
   assert(parameter->get_EC == NULL);
   parameter->get_EC = get_EC;
   assert(parameter->get_TB == NULL);
+  assert(parameter->get_MC != NULL);
+  original_MC = parameter->get_MC;
+  parameter->get_MC = get_MC;
   if (is_attack_unit(punit) || is_diplomat_unit(punit)) {
     parameter->get_TB = get_TB_aggr;
   } else if (unit_flag(punit, F_TRADE_ROUTE)
@@ -523,6 +598,7 @@
       p.dir[i] = get_direction_for_step(old_x, old_y, new_x, new_y);
       freelog(PACKET_LOG_LEVEL, "  packet[%d] = move %s: %d,%d => %d,%d",
              i, dir_get_name(p.dir[i]), old_x, old_y, new_x, new_y);
+      p.activity[i] = ACTIVITY_LAST;
     }
     old_x = new_x;
     old_y = new_y;
@@ -578,6 +654,87 @@
   send_path_orders(punit, path, TRUE, TRUE);
 
   pf_destroy_path(path);
+}
+
+/**************************************************************************
+  Send the current connect route (i.e., the one generated via HOVER_STATE)
+  to the server.
+**************************************************************************/
+void send_connect_route(struct unit *punit, enum unit_activity activity)
+{
+  struct pf_path *path = NULL;
+  int i;
+  struct packet_unit_orders p;
+  int old_x, old_y;
+
+  assert(is_active);
+  assert(punit->id == goto_map.unit_id);
+
+  memset(&p, 0, sizeof(p));
+
+  for (i = 0; i < goto_map.num_parts; i++) {
+    path = pft_concat(path, goto_map.parts[i].path);
+  }
+
+  p.unit_id = punit->id;
+  p.repeat = FALSE;
+  p.vigilant = FALSE; /* Should be TRUE? */
+
+  p.length = 0;
+  old_x = path->positions[0].x;
+  old_y = path->positions[0].y;
+
+  for (i = 0; i < path->length; i++) {
+    switch (activity) {
+    case ACTIVITY_IRRIGATE:
+      if (!map_has_special(old_x, old_y, S_IRRIGATION)
+         /* and unit can irrigate here */) {
+       p.orders[p.length] = ORDER_ACTIVITY;
+       p.activity[p.length] = ACTIVITY_IRRIGATE;
+       p.length++;
+      }
+      break;
+    case ACTIVITY_ROAD:
+    case ACTIVITY_RAILROAD:
+      if (!map_has_special(old_x, old_y, S_ROAD)
+         /* and unit can build road here */) {
+       p.orders[p.length] = ORDER_ACTIVITY;
+       p.activity[p.length] = ACTIVITY_ROAD;
+       p.length++;
+      }
+      if (activity == ACTIVITY_RAILROAD) {
+       if (!map_has_special(old_x, old_y, S_RAILROAD)
+           /* and unit can build rail here */) {
+         p.orders[p.length] = ORDER_ACTIVITY;
+         p.activity[p.length] = ACTIVITY_RAILROAD;
+         p.length++;
+       }
+      }
+      break;
+    default:
+      die("Invalid connect activity.");
+      break;
+    }
+
+    if (i != path->length - 1) {
+      int new_x = path->positions[i + 1].x;
+      int new_y = path->positions[i + 1].y;
+
+      assert(!same_pos(new_x, new_y, old_x, old_y));
+
+      p.orders[p.length] = ORDER_MOVE;
+      p.dir[p.length] = get_direction_for_step(old_x, old_y, new_x, new_y);
+      p.length++;
+
+      old_x = new_x;
+      old_y = new_y;
+    }
+  }
+
+  p.dest_x = old_x;
+  p.dest_y = old_y;
+
+  send_packet_unit_orders(&aconnection, &p);
 }
 
 /**************************************************************************
Index: client/goto.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.h,v
retrieving revision 1.11
diff -u -r1.11 goto.h
--- client/goto.h       20 Jan 2004 21:52:07 -0000      1.11
+++ client/goto.h       21 Apr 2004 05:01:04 -0000
@@ -33,6 +33,7 @@
 void send_goto_path(struct unit *punit, struct pf_path *path);
 void send_patrol_route(struct unit *punit);
 void send_goto_route(struct unit *punit);
+void send_connect_route(struct unit *punit, enum unit_activity activity);
 
 struct pf_path *path_to_nearest_allied_city(struct unit *punit);
 
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.33
diff -u -r1.33 mapctrl_common.c
--- client/mapctrl_common.c     10 Apr 2004 01:40:16 -0000      1.33
+++ client/mapctrl_common.c     21 Apr 2004 05:01:04 -0000
@@ -411,7 +411,7 @@
     struct unit *punit =
         player_find_unit_by_id(game.player_ptr, hover_unit);
     do_unit_goto(tile_x, tile_y);
-    set_hover_state(NULL, HOVER_NONE);
+    set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
     update_unit_info_label(punit);
   }
   keyboardless_goto_active = FALSE;
@@ -599,7 +599,9 @@
 **************************************************************************/
 void update_line(int canvas_x, int canvas_y)
 {
-  if ((hover_state == HOVER_GOTO || hover_state == HOVER_PATROL)
+  if ((hover_state == HOVER_GOTO
+       || hover_state == HOVER_PATROL
+       || hover_state == HOVER_CONNECT)
       && draw_goto_line) {
     int x, y, old_x, old_y;
 
@@ -619,7 +621,9 @@
 ****************************************************************************/
 void overview_update_line(int overview_x, int overview_y)
 {
-  if ((hover_state == HOVER_GOTO || hover_state == HOVER_PATROL)
+  if ((hover_state == HOVER_GOTO
+       || hover_state == HOVER_PATROL
+       || hover_state == HOVER_CONNECT)
       && draw_goto_line) {
     int x, y, old_x, old_y;
 
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.103
diff -u -r1.103 mapview_common.c
--- client/mapview_common.c     20 Apr 2004 19:56:16 -0000      1.103
+++ client/mapview_common.c     21 Apr 2004 05:01:04 -0000
@@ -1763,7 +1763,7 @@
   anim_timer = renew_timer_start(anim_timer, TIMER_USER, TIMER_ACTIVE);
 
   if (punit == get_unit_in_focus() && hover_state != HOVER_NONE) {
-    set_hover_state(NULL, HOVER_NONE);
+    set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
     update_unit_info_label(punit);
   }
 
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.362
diff -u -r1.362 packhand.c
--- client/packhand.c   14 Apr 2004 17:18:36 -0000      1.362
+++ client/packhand.c   21 Apr 2004 05:01:05 -0000
@@ -109,7 +109,6 @@
   }
   punit->activity_target = packet->activity_target;
   punit->paradropped = packet->paradropped;
-  punit->connecting = packet->connecting;
   punit->done_moving = packet->done_moving;
   punit->occupy = packet->occupy;
   if (packet->transported) {
@@ -130,6 +129,7 @@
     for (i = 0; i < punit->orders.length; i++) {
       punit->orders.list[i].order = packet->orders[i];
       punit->orders.list[i].dir = packet->orders_dirs[i];
+      punit->orders.list[i].activity = packet->orders_activities[i];
     }
   }
   return punit;
@@ -1164,7 +1164,6 @@
       clear_goto_dest(punit);
     }
     punit->paradropped = packet_unit->paradropped;
-    punit->connecting = packet_unit->connecting;
     if (punit->done_moving != packet_unit->done_moving) {
       punit->done_moving = packet_unit->done_moving;
       check_focus = TRUE;
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.159
diff -u -r1.159 tilespec.c
--- client/tilespec.c   20 Apr 2004 06:30:31 -0000      1.159
+++ client/tilespec.c   21 Apr 2004 05:01:05 -0000
@@ -1587,7 +1587,7 @@
 
   ADD_SPRITE_SIMPLE(unit_type(punit)->sprite);
 
-  if(punit->activity!=ACTIVITY_IDLE) {
+  if (punit->activity!=ACTIVITY_IDLE) {
     struct Sprite *s = NULL;
     switch(punit->activity) {
     case ACTIVITY_MINE:
@@ -1648,13 +1648,11 @@
     }
   }
 
-  if (punit->connecting) {
-    ADD_SPRITE_SIMPLE(sprites.unit.connect);
-  }
-
   if (unit_has_orders(punit)) {
     if (punit->orders.repeat) {
       ADD_SPRITE_SIMPLE(sprites.unit.patrol);
+    } else if (punit->activity != ACTIVITY_IDLE) {
+      ADD_SPRITE_SIMPLE(sprites.unit.connect);
     } else {
       ADD_SPRITE_SIMPLE(sprites.unit.go_to);
     }
Index: client/gui-gtk-2.0/dialogs.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/dialogs.c,v
retrieving revision 1.62
diff -u -r1.62 dialogs.c
--- client/gui-gtk-2.0/dialogs.c        10 Apr 2004 03:47:48 -0000      1.62
+++ client/gui-gtk-2.0/dialogs.c        21 Apr 2004 05:01:07 -0000
@@ -119,11 +119,6 @@
 
 static GtkWidget *caravan_dialog;
 
-static int is_showing_unit_connect_dialog = FALSE;
-static int unit_to_use_to_connect;
-static int connect_unit_x;
-static int connect_unit_y;
-
 /****************************************************************
 ...
 *****************************************************************/
@@ -1208,77 +1203,6 @@
     g_signal_connect(shl, "destroy", G_CALLBACK(pillage_destroy_callback),
                     NULL);   
   }
-}
-
-/****************************************************************
-handle buttons in unit connect dialog
-*****************************************************************/
-static void unit_connect_callback(GtkWidget *w, gpointer data)
-{
-  struct unit *punit;
-  int activity = GPOINTER_TO_INT(data);
-
-  punit = find_unit_by_id(unit_to_use_to_connect);
-
-  if (punit) {
-    if (activity != ACTIVITY_IDLE) {
-      struct packet_unit_connect req;
-      req.activity_type = activity;
-      req.unit_id = punit->id;
-      req.dest_x = connect_unit_x;
-      req.dest_y = connect_unit_y;
-      send_packet_unit_connect(&aconnection, &req);
-    }
-    else {
-      update_unit_info_label(punit);
-    }
-  }
-}
-
-/****************************************************************
-...
-*****************************************************************/
-static void unit_connect_destroy_callback(GtkWidget *w, gpointer data)
-{
-  is_showing_unit_connect_dialog = FALSE;
-}
-
-/****************************************************************
-popup dialog which prompts for activity type (unit connect)
-*****************************************************************/
-void popup_unit_connect_dialog(struct unit *punit, int dest_x, int dest_y)
-{
-  GtkWidget *shl;
-  int activity;
-
-  if (is_showing_unit_connect_dialog) 
-    return;
-
-  is_showing_unit_connect_dialog = TRUE;
-  unit_to_use_to_connect = punit->id;
-  connect_unit_x = dest_x;
-  connect_unit_y = dest_y;
-
-  shl = message_dialog_start(GTK_WINDOW(toplevel),
-                            _("Connect"),
-                            _("Choose unit activity:"));
-
-  for (activity = ACTIVITY_IDLE + 1; activity < ACTIVITY_LAST; activity++) {
-    if (! can_unit_do_connect (punit, activity)) continue;
-
-    message_dialog_add(shl, get_activity_text(activity),
-                      G_CALLBACK(unit_connect_callback),
-                      GINT_TO_POINTER(activity));
-  }
-
-  message_dialog_add(shl, GTK_STOCK_CANCEL, 
-                    G_CALLBACK(unit_connect_callback),
-                    GINT_TO_POINTER(ACTIVITY_IDLE));
-
-  message_dialog_end(shl);
-
-  g_signal_connect(shl, "destroy",
-                  G_CALLBACK(unit_connect_destroy_callback), NULL);
 }
 
 /****************************************************************
Index: client/gui-gtk-2.0/mapview.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapview.c,v
retrieving revision 1.119
diff -u -r1.119 mapview.c
--- client/gui-gtk-2.0/mapview.c        15 Apr 2004 19:36:01 -0000      1.119
+++ client/gui-gtk-2.0/mapview.c        21 Apr 2004 05:01:07 -0000
@@ -248,7 +248,7 @@
     gtk_label_set_text(GTK_LABEL(unit_info_label), buffer);
 
     if (hover_unit != punit->id)
-      set_hover_state(NULL, HOVER_NONE);
+      set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
 
     switch (hover_state) {
     case HOVER_NONE:
Index: client/gui-gtk-2.0/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/menu.c,v
retrieving revision 1.28
diff -u -r1.28 menu.c
--- client/gui-gtk-2.0/menu.c   10 Apr 2004 03:47:48 -0000      1.28
+++ client/gui-gtk-2.0/menu.c   21 Apr 2004 05:01:07 -0000
@@ -124,7 +124,9 @@
   MENU_ORDER_WAKEUP_OTHERS,
   MENU_ORDER_AUTO_SETTLER,   /* shared with AUTO_ATTACK */
   MENU_ORDER_AUTO_EXPLORE,
-  MENU_ORDER_CONNECT,
+  MENU_ORDER_CONNECT_ROAD,
+  MENU_ORDER_CONNECT_RAIL,
+  MENU_ORDER_CONNECT_IRRIGATE,
   MENU_ORDER_PATROL,
   MENU_ORDER_GOTO,
   MENU_ORDER_GOTO_CITY,
@@ -420,8 +422,14 @@
    case MENU_ORDER_AUTO_EXPLORE:
     key_unit_auto_explore();
     break;
-   case MENU_ORDER_CONNECT:
-    key_unit_connect();
+   case MENU_ORDER_CONNECT_ROAD:
+    key_unit_connect(ACTIVITY_ROAD);
+    break;
+   case MENU_ORDER_CONNECT_RAIL:
+    key_unit_connect(ACTIVITY_RAILROAD);
+    break;
+   case MENU_ORDER_CONNECT_IRRIGATE:
+    key_unit_connect(ACTIVITY_IRRIGATE);
     break;
    case MENU_ORDER_PATROL:
     key_unit_patrol();
@@ -748,8 +756,12 @@
        orders_menu_callback,   MENU_ORDER_AUTO_SETTLER                         
        },
   { "/" N_("Orders") "/" N_("Auto E_xplore"),          "x",
        orders_menu_callback,   MENU_ORDER_AUTO_EXPLORE                         
        },
-  { "/" N_("Orders") "/" N_("_Connect"),               "<shift>c",
-       orders_menu_callback,   MENU_ORDER_CONNECT                              
        },
+  {"/" N_("Orders") "/" N_("_Connect") "/" N_("_Road"), "<ctrl>r",
+   orders_menu_callback, MENU_ORDER_CONNECT_ROAD},
+  {"/" N_("Orders") "/" N_("_Connect") "/" N_("Rai_l"), "<ctrl>l",
+   orders_menu_callback, MENU_ORDER_CONNECT_RAIL},
+  {"/" N_("Orders") "/" N_("_Connect") "/" N_("_Irrigate"), "<ctrl>i",
+   orders_menu_callback, MENU_ORDER_CONNECT_IRRIGATE},
   { "/" N_("Orders") "/" N_("Patrol (_Q)"),            "q",
        orders_menu_callback,   MENU_ORDER_PATROL                               
        },
   { "/" N_("Orders") "/" N_("_Go to"),                 "g",
@@ -1231,8 +1243,12 @@
                           can_unit_do_auto(punit));
       menus_set_sensitive("<main>/_Orders/Auto E_xplore",
                           can_unit_do_activity(punit, ACTIVITY_EXPLORE));
-      menus_set_sensitive("<main>/_Orders/_Connect",
-                          can_unit_do_connect(punit, ACTIVITY_IDLE));
+      menus_set_sensitive("<main>/_Orders/_Connect/_Road",
+                          can_unit_do_connect(punit, ACTIVITY_ROAD));
+      menus_set_sensitive("<main>/_Orders/_Connect/_Rail",
+                          can_unit_do_connect(punit, ACTIVITY_RAILROAD));
+      menus_set_sensitive("<main>/_Orders/_Connect/_Irrigate",
+                          can_unit_do_connect(punit, ACTIVITY_IRRIGATE));
       menus_set_sensitive("<main>/_Orders/Return to nearest city",
                          !(is_air_unit(punit) || is_heli_unit(punit)));
       menus_set_sensitive("<main>/_Orders/Diplomat\\/Spy Actions",
Index: client/include/dialogs_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/dialogs_g.h,v
retrieving revision 1.15
diff -u -r1.15 dialogs_g.h
--- client/include/dialogs_g.h  2 Feb 2004 07:23:45 -0000       1.15
+++ client/include/dialogs_g.h  21 Apr 2004 05:01:07 -0000
@@ -47,7 +47,6 @@
 void popup_sabotage_dialog(struct city *pcity);
 void popup_pillage_dialog(struct unit *punit,
                          enum tile_special_type may_pillage);
-void popup_unit_connect_dialog (struct unit *punit, int dest_x, int dest_y);
 
 void popdown_all_game_dialogs(void);
 
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.164
diff -u -r1.164 capstr.c
--- common/capstr.c     14 Apr 2004 11:19:44 -0000      1.164
+++ common/capstr.c     21 Apr 2004 05:01:07 -0000
@@ -77,7 +77,7 @@
 #define CAPABILITY "+1.14.delta +last_turns_shield_surplus veteran +orders " \
                    "+starter +union +iso_maps +orders2client " \
                    "+change_production +tilespec1 +no_earth +trans " \
-                   "+want_hack invasions killstack bombard"
+                   "+want_hack invasions killstack bombard +connect"
 
 /* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
  *
@@ -114,6 +114,8 @@
  * "killstack" means ruleset option to ignore unit killstack effect
  *
  * "bombard" means units support the bombard ability.
+ *
+ * "connect" means the 'connect' function is done with client orders.
  */
 
 void init_our_capability(void)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.178
diff -u -r1.178 map.h
--- common/map.h        20 Apr 2004 20:10:37 -0000      1.178
+++ common/map.h        21 Apr 2004 05:01:07 -0000
@@ -544,6 +544,7 @@
 struct unit_order {
   enum unit_orders order;
   enum direction8 dir;         /* Only valid for ORDER_MOVE. */
+  enum unit_activity activity; /* Only valid for ORDER_ACTIVITY. */
 };
 
 /* return the reverse of the direction */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.20
diff -u -r1.20 packets.def
--- common/packets.def  14 Apr 2004 11:19:44 -0000      1.20
+++ common/packets.def  21 Apr 2004 05:01:07 -0000
@@ -594,7 +594,7 @@
 
   UINT8 veteran; add-cap(veteran)
   BOOL veteran_old; remove-cap(veteran)
-  BOOL ai, paradropped, connecting, transported, done_moving;
+  BOOL ai, paradropped, transported, done_moving;
 
   UNIT_TYPE type;
   UNIT transported_by; /* Only valid if transported is set. */
@@ -609,6 +609,7 @@
   BOOL orders_repeat, orders_vigilant;
   ORDERS orders[MAX_LEN_ROUTE:orders_length];
   DIRECTION orders_dirs[MAX_LEN_ROUTE:orders_length];
+  ACTIVITY orders_activities[MAX_LEN_ROUTE:orders_length];
 end
 
 PACKET_UNIT_SHORT_INFO=50; is-info,sc,lsend
@@ -680,6 +681,7 @@
   BOOL repeat, vigilant;
   ORDERS orders[MAX_LEN_ROUTE:length];
   DIRECTION dir[MAX_LEN_ROUTE:length];
+  ACTIVITY activity[MAX_LEN_ROUTE:length];
   COORD dest_x, dest_y;
 end
 
@@ -713,13 +715,6 @@
 PACKET_UNIT_AIRLIFT=65;cs,dsend
   UNIT unit_id;
   CITY city_id;
-end
-
-PACKET_UNIT_CONNECT=66;cs
-  UNIT unit_id;
-  ACTIVITY activity_type;
-  COORD dest_x;
-  COORD dest_y;
 end
 
 PACKET_UNIT_BRIBE_INQ=67;cs,handle-per-conn,dsend
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.204
diff -u -r1.204 unit.c
--- common/unit.c       20 Apr 2004 16:17:39 -0000      1.204
+++ common/unit.c       21 Apr 2004 05:01:07 -0000
@@ -733,9 +733,6 @@
               (current == ACTIVITY_FORTIFIED) ? ACTIVITY_FORTIFYING : current;
   bool result;
 
-  if (punit->connecting)
-    return can_unit_do_connect(punit, current);
-
   punit->activity = ACTIVITY_IDLE;
   punit->activity_target = S_NO_SPECIAL;
 
@@ -756,21 +753,32 @@
 }
 
 /**************************************************************************
-Note that if you make changes here you should also change the code for
-autosettlers in server/settler.c. The code there does not use this function
-as it would be a ajor CPU hog.
+  Return whether the unit can do the targeted activity at its current
+  location.
 **************************************************************************/
 bool can_unit_do_activity_targeted(struct unit *punit,
                                   enum unit_activity activity,
                                   enum tile_special_type target)
 {
-  struct player *pplayer;
-  struct tile *ptile;
-  struct tile_type *type;
-
-  pplayer = unit_owner(punit);
-  ptile = map_get_tile(punit->x, punit->y);
-  type = get_tile_type(ptile->terrain);
+  return can_unit_do_activity_targeted_at(punit, activity, target,
+                                         punit->x, punit->y);
+}
+
+/****************************************************************************
+  Return TRUE if the unit can do the targeted activity at the given location.
+
+  Note that if you make changes here you should also change the code for
+  autosettlers in server/settler.c. The code there does not use this function
+  as it would be a ajor CPU hog.
+****************************************************************************/
+bool can_unit_do_activity_targeted_at(struct unit *punit,
+                                     enum unit_activity activity,
+                                     enum tile_special_type target,
+                                     int x, int y)
+{
+  struct player *pplayer = unit_owner(punit);
+  struct tile *ptile = map_get_tile(x, y);
+  struct tile_type *type = get_tile_type(ptile->terrain);
 
   switch(activity) {
   case ACTIVITY_IDLE:
@@ -800,11 +808,11 @@
          (ptile->terrain!=type->mining_result &&
           type->mining_result!=T_LAST &&
           (!is_ocean(ptile->terrain) || is_ocean(type->mining_result) ||
-           can_reclaim_ocean(punit->x, punit->y)) &&
+           can_reclaim_ocean(x, y)) &&
           (is_ocean(ptile->terrain) || !is_ocean(type->mining_result) ||
-           can_channel_land(punit->x, punit->y)) &&
+           can_channel_land(x, y)) &&
           (!is_ocean(type->mining_result) ||
-           !(map_get_city(punit->x, punit->y)))) )) {
+           !(map_get_city(x, y)))) )) {
       unit_list_iterate(ptile->units, tunit) {
        if(tunit->activity==ACTIVITY_IRRIGATE) return FALSE;
       }
@@ -821,15 +829,15 @@
         (!tile_has_special(ptile, S_FARMLAND) &&
          player_knows_techs_with_flag(pplayer, TF_FARMLAND))) &&
        ( (ptile->terrain==type->irrigation_result && 
-          is_water_adjacent_to_tile(punit->x, punit->y)) ||
+          is_water_adjacent_to_tile(x, y)) ||
          (ptile->terrain!=type->irrigation_result &&
           type->irrigation_result!=T_LAST &&
           (!is_ocean(ptile->terrain) || is_ocean(type->irrigation_result) ||
-           can_reclaim_ocean(punit->x, punit->y)) &&
+           can_reclaim_ocean(x, y)) &&
           (is_ocean(ptile->terrain) || !is_ocean(type->irrigation_result) ||
-           can_channel_land(punit->x, punit->y)) &&
+           can_channel_land(x, y)) &&
           (!is_ocean(type->irrigation_result) ||
-           !(map_get_city(punit->x, punit->y)))) )) {
+           !(map_get_city(x, y)))) )) {
       unit_list_iterate(ptile->units, tunit) {
        if(tunit->activity==ACTIVITY_MINE) return FALSE;
       }
@@ -848,7 +856,7 @@
 
   case ACTIVITY_FORTRESS:
     return (unit_flag(punit, F_SETTLERS) &&
-           !map_get_city(punit->x, punit->y) &&
+           !map_get_city(x, y) &&
            player_knows_techs_with_flag(pplayer, TF_FORTRESS) &&
            !tile_has_special(ptile, S_FORTRESS) && !is_ocean(ptile->terrain));
 
@@ -864,11 +872,7 @@
     /* if the tile has road, the terrain must be ok.. */
     return (terrain_control.may_road &&
            unit_flag(punit, F_SETTLERS) &&
-           (tile_has_special(ptile, S_ROAD) ||
-            (punit->connecting &&
-             (type->road_time != 0 &&
-              (!tile_has_special(ptile, S_RIVER)
-               || player_knows_techs_with_flag(pplayer, TF_BRIDGE))))) &&
+           tile_has_special(ptile, S_ROAD) &&
            !tile_has_special(ptile, S_RAILROAD) &&
            player_knows_techs_with_flag(pplayer, TF_RAILROAD));
 
@@ -878,7 +882,7 @@
       enum tile_special_type psworking;
 
       if (pspresent != S_NO_SPECIAL && is_ground_unit(punit)) {
-       psworking = get_unit_tile_pillage_set(punit->x, punit->y);
+       psworking = get_unit_tile_pillage_set(x, y);
        if (ptile->city && (contains_special(target, S_ROAD) ||
                            contains_special(target, S_RAILROAD))) {
          return FALSE;
@@ -909,18 +913,22 @@
            (type->transform_result!=T_LAST) &&
            (ptile->terrain!=type->transform_result) &&
            (!is_ocean(ptile->terrain) || is_ocean(type->transform_result) ||
-            can_reclaim_ocean(punit->x, punit->y)) &&
+            can_reclaim_ocean(x, y)) &&
            (is_ocean(ptile->terrain) || !is_ocean(type->transform_result) ||
-            can_channel_land(punit->x, punit->y)) &&
+            can_channel_land(x, y)) &&
            (!is_ocean(type->transform_result) ||
-            !(map_get_city(punit->x, punit->y))) &&
+            !(map_get_city(x, y))) &&
            unit_flag(punit, F_TRANSFORM));
 
-  default:
-    freelog(LOG_ERROR, "Unknown activity %d in 
can_unit_do_activity_targeted()",
-           activity);
-    return FALSE;
-  }
+  case ACTIVITY_PATROL_UNUSED:
+  case ACTIVITY_LAST:
+  case ACTIVITY_UNKNOWN:
+    break;
+  }
+  freelog(LOG_ERROR,
+         "Unknown activity %d in can_unit_do_activity_targeted()",
+         activity);
+  return FALSE;
 }
 
 /**************************************************************************
@@ -931,7 +939,6 @@
   punit->activity=new_activity;
   punit->activity_count=0;
   punit->activity_target = S_NO_SPECIAL;
-  punit->connecting = FALSE;
   if (new_activity == ACTIVITY_IDLE && punit->moves_left > 0) {
     /* No longer done. */
     punit->done_moving = FALSE;
@@ -1421,14 +1428,14 @@
                           bool igzoc)
 {
   return MR_OK == test_unit_move_to_tile(punit->type, unit_owner(punit),
-                                        punit->activity, punit->connecting,
+                                        punit->activity,
                                         punit->x, punit->y, dest_x, dest_y,
                                         igzoc);
 }
 
 /**************************************************************************
   unit can be moved if:
-  1) the unit is idle or on goto or connecting.
+  1) the unit is idle or on server goto.
   2) the target location is on the map
   3) the target location is next to the unit
   4) there are no non-allied units on the target tile
@@ -1443,9 +1450,9 @@
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
                                             struct player *unit_owner,
                                             enum unit_activity activity,
-                                            bool connecting, int src_x,
-                                            int src_y, int dest_x,
-                                            int dest_y, bool igzoc)
+                                            int src_x, int src_y,
+                                            int dest_x, int dest_y,
+                                            bool igzoc)
 {
   struct tile *pfromtile, *ptotile;
   bool zoc;
@@ -1453,8 +1460,7 @@
 
   /* 1) */
   if (activity != ACTIVITY_IDLE
-      && activity != ACTIVITY_GOTO
-      && !connecting) {
+      && activity != ACTIVITY_GOTO) {
     return MR_BAD_ACTIVITY;
   }
 
@@ -1635,7 +1641,6 @@
   punit->moves_left = unit_move_rate(punit);
   punit->moved = FALSE;
   punit->paradropped = FALSE;
-  punit->connecting = FALSE;
   punit->done_moving = FALSE;
   if (is_barbarian(pplayer)) {
     punit->fuel = BARBARIAN_LIFE;
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.114
diff -u -r1.114 unit.h
--- common/unit.h       14 Apr 2004 11:19:45 -0000      1.114
+++ common/unit.h       21 Apr 2004 05:01:07 -0000
@@ -37,7 +37,7 @@
 
 /* Changing this enum will break savegame and network compatability. */
 enum unit_orders {
-  ORDER_MOVE, ORDER_FINISH_TURN,
+  ORDER_MOVE, ORDER_FINISH_TURN, ORDER_ACTIVITY,
   ORDER_LAST
 };
 
@@ -150,7 +150,6 @@
   bool debug;
   bool moved;
   bool paradropped;
-  bool connecting;
 
   /* This value is set if the unit is done moving for this turn. This
    * information is used by the client.  The invariant is:
@@ -251,6 +250,10 @@
 bool can_unit_do_activity_targeted(struct unit *punit,
                                   enum unit_activity activity,
                                   enum tile_special_type target);
+bool can_unit_do_activity_targeted_at(struct unit *punit,
+                                     enum unit_activity activity,
+                                     enum tile_special_type target,
+                                     int map_x, int map_y);
 void set_unit_activity(struct unit *punit, enum unit_activity new_activity);
 void set_unit_activity_targeted(struct unit *punit,
                                enum unit_activity new_activity,
@@ -313,9 +316,9 @@
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
                                             struct player *unit_owner,
                                             enum unit_activity activity,
-                                            bool connecting, int src_x,
-                                            int src_y, int dest_x,
-                                            int dest_y, bool igzoc);
+                                            int src_x, int src_y,
+                                            int dest_x, int dest_y,
+                                            bool igzoc);
 bool unit_type_really_ignores_zoc(Unit_Type_id type);
 bool zoc_ok_move(struct unit *punit, int x, int y);
 
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.178
diff -u -r1.178 gotohand.c
--- server/gotohand.c   20 Jan 2004 21:52:09 -0000      1.178
+++ server/gotohand.c   21 Apr 2004 05:01:08 -0000
@@ -1288,7 +1288,6 @@
   if (same_pos(punit->x, punit->y, dest_x, dest_y) ||
       !goto_is_sane(punit, dest_x, dest_y, FALSE)) {
     punit->activity = ACTIVITY_IDLE;
-    punit->connecting = FALSE;
     send_unit_info(NULL, punit);
     if (same_pos(punit->x, punit->y, dest_x, dest_y)) {
       return GR_ARRIVED;
@@ -1316,7 +1315,6 @@
              pplayer->name, unit_type(punit)->name,
              punit->x, punit->y, dest_x, dest_y);
       punit->activity = ACTIVITY_IDLE;
-      punit->connecting = FALSE;
       send_unit_info(NULL, punit);
       return GR_FAILED;
     }
@@ -1380,13 +1378,6 @@
        return GR_OUT_OF_MOVEPOINTS;
       }
 
-      /* single step connecting unit when it can do it's activity */
-      if (punit->connecting
-         && can_unit_do_activity(punit, punit->activity)) {
-       /* for connecting unit every step is a destination */
-       return GR_ARRIVED;
-      }
-
       freelog(LOG_DEBUG, "Moving on.");
     } while(!same_pos(x, y, waypoint_x, waypoint_y));
   } else {
@@ -1395,17 +1386,11 @@
            pplayer->name, unit_type(punit)->name,
            punit->x, punit->y, dest_x, dest_y);
     handle_unit_activity_request(punit, ACTIVITY_IDLE);
-    punit->connecting = FALSE;
     send_unit_info(NULL, punit);
     return GR_FAILED;
   }
   /** Finished moving the unit for this turn **/
 
-  /* ensure that the connecting unit will perform it's activity
-     on the destination file too. */
-  if (punit->connecting && can_unit_do_activity(punit, punit->activity))
-    return GR_ARRIVED;
-
   /* normally we would just do this unconditionally, but if we had an
      airplane goto we might not be finished even if the loop exited */
   if (same_pos(punit->x, punit->y, dest_x, dest_y)) {
@@ -1416,7 +1401,6 @@
     status = GR_OUT_OF_MOVEPOINTS;
   }
 
-  punit->connecting = FALSE;
   send_unit_info(NULL, punit);
   return status;
 }
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.149
diff -u -r1.149 savegame.c
--- server/savegame.c   26 Mar 2004 17:31:55 -0000      1.149
+++ server/savegame.c   21 Apr 2004 05:01:08 -0000
@@ -1112,9 +1112,6 @@
        secfile_lookup_int_default(file, (int) S_NO_SPECIAL,
                                   "player%d.u%d.activity_target", plrno, i);
 
-    punit->connecting=secfile_lookup_bool_default(file, FALSE,
-                                               "player%d.u%d.connecting",
-                                               plrno, i);
     punit->done_moving = secfile_lookup_bool_default(file,
        (punit->moves_left == 0), "player%d.u%d.done_moving", plrno, i);
     /* Load the goto information.  Older savegames will not have the
@@ -1154,7 +1151,7 @@
       int len = secfile_lookup_int_default(file, 0,
                        "player%d.u%d.orders_length", plrno, i);
       if (len > 0) {
-       char *orders_buf, *dir_buf;
+       char *orders_buf, *dir_buf, *act_buf;
 
        punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
        punit->orders.length = len;
@@ -1169,14 +1166,18 @@
                        "player%d.u%d.orders_list", plrno, i);
        dir_buf = secfile_lookup_str_default(file, "",
                        "player%d.u%d.dir_list", plrno, i);
+       act_buf = secfile_lookup_str_default(file, "",
+                       "player%d.u%d.activity_list", plrno, i);
        for (j = 0; j < len; j++) {
-         if (orders_buf[j] == '\0' || dir_buf == '\0') {
+         if (orders_buf[j] == '\0' || dir_buf[j] == '\0'
+             || act_buf[j] == '\0') {
            freelog(LOG_ERROR, _("Savegame error: invalid unit orders."));
            free_unit_orders(punit);
            break;
          }
          punit->orders.list[j].order = orders_buf[j] - 'a';
          punit->orders.list[j].dir = dir_buf[j] - 'a';
+         punit->orders.list[j].activity = act_buf[j] - 'a';
        }
        punit->has_orders = TRUE;
       } else {
@@ -1573,9 +1574,6 @@
     secfile_insert_int(file, punit->activity_target, 
                                "player%d.u%d.activity_target",
                                plrno, i);
-    secfile_insert_bool(file, punit->connecting, 
-                               "player%d.u%d.connecting",
-                               plrno, i);
     secfile_insert_bool(file, punit->done_moving,
                        "player%d.u%d.done_moving", plrno, i);
     secfile_insert_int(file, punit->moves_left, "player%d.u%d.moves",
@@ -1605,7 +1603,7 @@
                       "player%d.u%d.transported_by", plrno, i);
     if (punit->has_orders) {
       int len = punit->orders.length, j;
-      char orders_buf[len + 1], dir_buf[len + 1];
+      char orders_buf[len + 1], dir_buf[len + 1], act_buf[len + 1];
 
       secfile_insert_int(file, len, "player%d.u%d.orders_length", plrno, i);
       secfile_insert_int(file, punit->orders.index,
@@ -1618,13 +1616,16 @@
       for (j = 0; j < len; j++) {
        orders_buf[j] = 'a' + punit->orders.list[j].order;
        dir_buf[j] = 'a' + punit->orders.list[j].dir;
+       act_buf[j] = 'a' + punit->orders.list[j].activity;
       }
-      orders_buf[len] = dir_buf[len] = '\0';
+      orders_buf[len] = dir_buf[len] = act_buf[len] = '\0';
 
       secfile_insert_str(file, orders_buf,
                         "player%d.u%d.orders_list", plrno, i);
       secfile_insert_str(file, dir_buf,
                         "player%d.u%d.dir_list", plrno, i);
+      secfile_insert_str(file, act_buf,
+                        "player%d.u%d.activity_list", plrno, i);
     } else {
       /* Put all the same fields into the savegame.  Otherwise the
        * registry code gets confused (although it still works). */
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.295
diff -u -r1.295 unithand.c
--- server/unithand.c   16 Apr 2004 17:27:09 -0000      1.295
+++ server/unithand.c   21 Apr 2004 05:01:09 -0000
@@ -101,44 +101,6 @@
 }
 
 /**************************************************************************
-Handler for PACKET_UNIT_CONNECT request. The unit is send on way and will 
-build something (roads only for now) along the way, using server-side
-path-finding. 
-
-FIXME: This should be rewritten to use client-side path finding along so 
-that we can show in the client where the road-to-be-built will be and 
-enable the use of waypoints to alter this route. - Per
-**************************************************************************/
-void handle_unit_connect(struct player *pplayer, int unit_id,
-                        enum unit_activity activity_type, int dest_x,
-                        int dest_y)
-{
-  struct unit *punit = player_find_unit_by_id(pplayer, unit_id);
-
-  if (!is_normal_map_pos(dest_x, dest_y) || !punit
-      || !can_unit_do_connect(punit, activity_type)) {
-    return;
-  }
-
-  set_goto_dest(punit, dest_x, dest_y);
-
-  set_unit_activity(punit, activity_type);
-  punit->connecting = TRUE;
-
-  send_unit_info(NULL, punit);
-
-  /* 
-   * Avoid wasting first turn if unit cannot do the activity on the
-   * starting tile.
-   */
-  if (!can_unit_do_activity(punit, activity_type)) {
-    (void) do_unit_goto(punit,
-                       get_activity_move_restriction(activity_type),
-                       FALSE);
-  }
-}
-
-/**************************************************************************
  Upgrade all units of a given type.
 **************************************************************************/
 void handle_unit_type_upgrade(struct player *pplayer, Unit_Type_id type)
@@ -947,7 +909,7 @@
 
   reason =
       test_unit_move_to_tile(punit->type, unit_owner(punit),
-                            punit->activity, punit->connecting,
+                            punit->activity,
                             punit->x, punit->y, dest_x, dest_y, igzoc);
   if (reason == MR_OK)
     return TRUE;
@@ -1599,6 +1561,7 @@
     return;
   }
 
+
   for (i = 0; i < packet->length; i++) {
     switch (packet->orders[i]) {
     case ORDER_MOVE:
@@ -1606,6 +1569,16 @@
        return;
       }
       break;
+    case ORDER_ACTIVITY:
+      switch (packet->activity[i]) {
+      case ACTIVITY_ROAD:
+      case ACTIVITY_RAILROAD:
+      case ACTIVITY_IRRIGATE:
+       break;
+      default:
+       return;
+      }
+      break;
     case ORDER_FINISH_TURN:
       break;
     default:
@@ -1633,6 +1606,7 @@
   for (i = 0; i < packet->length; i++) {
     punit->orders.list[i].order = packet->orders[i];
     punit->orders.list[i].dir = packet->dir[i];
+    punit->orders.list[i].activity = packet->activity[i];
   }
 
   if (!packet->repeat) {
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.290
diff -u -r1.290 unittools.c
--- server/unittools.c  20 Apr 2004 17:21:57 -0000      1.290
+++ server/unittools.c  21 Apr 2004 05:01:09 -0000
@@ -711,20 +711,6 @@
 
   unit_restore_movepoints(pplayer, punit);
 
-  if (punit->connecting && !can_unit_do_activity(punit, activity)) {
-    punit->activity_count = 0;
-    if (do_unit_goto(punit, get_activity_move_restriction(activity), FALSE)
-       == GR_DIED) {
-      return;
-    }
-  }
-
-  /* if connecting, automagically build prerequisities first */
-  if (punit->connecting && activity == ACTIVITY_RAILROAD &&
-      !map_has_special(punit->x, punit->y, S_ROAD)) {
-    activity = ACTIVITY_ROAD;
-  }
-
   if (activity == ACTIVITY_EXPLORE) {
     bool more_to_explore = ai_manage_explorer(punit);
 
@@ -897,18 +883,8 @@
     send_tile_info(NULL, punit->x, punit->y);
     unit_list_iterate (map_get_tile(punit->x, punit->y)->units, punit2) {
       if (punit2->activity == activity) {
-       bool alive = TRUE;
-       if (punit2->connecting) {
-         punit2->activity_count = 0;
-         alive = (do_unit_goto(punit2,
-                               get_activity_move_restriction(activity),
-                               FALSE) != GR_DIED);
-       } else {
-         set_unit_activity(punit2, ACTIVITY_IDLE);
-       }
-       if (alive) {
-         send_unit_info(NULL, punit2);
-       }
+       set_unit_activity(punit2, ACTIVITY_IDLE);
+       send_unit_info(NULL, punit2);
       }
     } unit_list_iterate_end;
   }
@@ -1950,7 +1926,6 @@
   }
   packet->activity_target = punit->activity_target;
   packet->paradropped = punit->paradropped;
-  packet->connecting = punit->connecting;
   packet->done_moving = punit->done_moving;
   if (punit->transported_by == -1) {
     packet->transported = FALSE;
@@ -1971,6 +1946,7 @@
     for (i = 0; i < punit->orders.length; i++) {
       packet->orders[i] = punit->orders.list[i].order;
       packet->orders_dirs[i] = punit->orders.list[i].dir;
+      packet->orders_activities[i] = punit->orders.list[i].activity;
     }
   } else {
     packet->orders_length = packet->orders_index = 0;
@@ -2738,8 +2714,7 @@
   if (punit->activity != ACTIVITY_IDLE
       && punit->activity != ACTIVITY_SENTRY
       && punit->activity != ACTIVITY_EXPLORE
-      && punit->activity != ACTIVITY_GOTO
-      && !punit->connecting) {
+      && punit->activity != ACTIVITY_GOTO) {
     set_unit_activity(punit, ACTIVITY_IDLE);
   }
 }
@@ -3023,9 +2998,15 @@
   int unitid = punit->id;
   struct player *pplayer = unit_owner(punit);
   int moves_made = 0;
+  enum unit_activity activity;
 
   assert(unit_has_orders(punit));
 
+  if (punit->activity != ACTIVITY_IDLE) {
+    punit->done_moving = TRUE;
+    return TRUE;
+  }
+
   freelog(LOG_DEBUG, "Executing orders for %s %d",
          unit_name(punit->type), punit->id);   
 
@@ -3084,6 +3065,19 @@
       punit->done_moving = TRUE;
       freelog(LOG_DEBUG, "  waiting this turn");
       send_unit_info(NULL, punit);
+      break;
+    case ORDER_ACTIVITY:
+      activity = order.activity;
+      if (!can_unit_do_activity(punit, activity)) {
+       cancel_orders(punit, "  orders canceled because of failed activity");
+       notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_ORDERS,
+                        _("Game: Orders for %s aborted since they "
+                          "give an invalid activity."),
+                        unit_name(punit->type));
+       return TRUE;
+      }
+      set_unit_activity(punit, activity);
+      punit->done_moving = TRUE;
       break;
     case ORDER_MOVE:
       /* Move unit */

[Prev in Thread] Current Thread [Next in Thread]