Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2004:
[Freeciv-Dev] (PR#6941) Mission Orders 5
Home

[Freeciv-Dev] (PR#6941) Mission Orders 5

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#6941) Mission Orders 5
From: "Arnstein Lindgard" <a-l@xxxxxxx>
Date: Wed, 28 Jan 2004 07:49:28 -0800
Reply-to: rt@xxxxxxxxxxx

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

Introduces a union to encompass various enums.

The patch is big because of client interface modifications.
Areas particularly relevant to the new Orders patch is:

- the top of common/unit.h
- the bottom of server/unittools.c: execute_orders()

The graphics file was posted earlier.

In unithand.c: handle_unit_orders()
it seems unnecessary to check all valid orders. I'd also like to
remove the check for ACTIVITY_IDLE, so it'll be easier to send gotos
for many units at once.


Arnstein

? autom4te-2.53.cache
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.124
diff -u -p -r1.124 control.c
--- client/control.c    2004/01/20 21:52:06     1.124
+++ client/control.c    2004/01/28 13:25:02
@@ -55,6 +55,13 @@ static int previous_focus_id = -1;
 /* 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;
+
+/* Order to be executed on goto destination. */
+union composite_orders hover_mission = { ORDER_LAST };
+
+/* True when hover state is goto and client supports missions. */
+static bool mission_orders_phase = FALSE;
+
 /* 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;
@@ -83,12 +90,14 @@ void set_hover_state(struct unit *punit,
 {
   assert(punit != NULL || state == HOVER_NONE);
   draw_goto_line = TRUE;
-  if (punit)
-    hover_unit = punit->id;
-  else
-    hover_unit = 0;
+  hover_unit = punit ? punit->id : 0;
   hover_state = state;
+  hover_mission.order = ORDER_LAST;
   exit_goto_state();
+  mission_orders_phase =
+    state == HOVER_GOTO
+    && !is_air_unit(punit) && !is_heli_unit(punit)
+    && client_supports_mission_orders();
 }
 
 /**************************************************************************
@@ -125,9 +134,7 @@ void set_unit_focus(struct unit *punit)
 
   if(punit) {
     auto_center_on_focus_unit();
-
     punit->focus_status=FOCUS_AVAIL;
-    refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
 
     if (unit_has_orders(punit)) {
       /* Clear the focus unit's orders. */
@@ -139,6 +146,7 @@ void set_unit_focus(struct unit *punit)
       refresh_unit_city_dialogs(punit);
       request_new_unit_activity(punit, ACTIVITY_IDLE);
     }
+    refresh_tile_mapcanvas(punit->x, punit->y, FALSE);
   }
   
   /* avoid the old focus unit disappearing: */
@@ -148,7 +156,7 @@ void set_unit_focus(struct unit *punit)
     refresh_tile_mapcanvas(punit_old_focus->x, punit_old_focus->y, FALSE);
   }
 
-  update_unit_info_label(punit);
+  update_unit_info_label(punit);  /* This also clears hover state. */
   update_menus();
 }
 
@@ -594,6 +602,7 @@ void request_unit_goto(void)
   if (hover_state != HOVER_GOTO) {
     set_hover_state(punit, HOVER_GOTO);
     update_unit_info_label(punit);
+    update_menus();
     /* Not yet implemented for air units, including helicopters. */
     if (is_air_unit(punit) || is_heli_unit(punit)) {
       draw_goto_line = FALSE;
@@ -656,7 +665,7 @@ void request_unit_return(struct unit *pu
   }
 
   if ((path = path_to_nearest_allied_city(punit))) {
-    send_goto_path(punit, path);
+    send_goto_path(punit, path, NULL);
     pf_destroy_path(path);
   }
 }
@@ -706,9 +715,24 @@ void request_unit_build_city(struct unit
   if (can_unit_build_city(punit)) {
     dsend_packet_city_name_suggestion_req(&aconnection, punit->id);
     /* the reply will trigger a dialog to name the new city */
-  } else {
-    char name[] = "";
-    dsend_packet_unit_build_city(&aconnection, punit->id, name);
+  } else if (unit_flag(punit, F_CITIES)) {
+    /* The reply can trigger an error message. */
+    if (!punit->moves_left) {
+      struct packet_unit_orders p;
+      p.orders[0] = ACTION_BUILD_CITY;
+      p.dir[0] = -1;
+      p.length = 1;
+      p.unit_id = punit->id;
+      p.repeat = p.vigilant = FALSE;
+      p.dest_x = punit->x;
+      p.dest_y = punit->y;
+      send_packet_unit_orders(&aconnection, &p);
+
+      advance_unit_focus();
+    } else {
+      char name[] = "";
+      dsend_packet_unit_build_city(&aconnection, punit->id, name);
+    }
   }
 }
 
@@ -1259,6 +1283,7 @@ void do_map_click(int xtile, int ytile, 
   struct city *pcity = map_get_city(xtile, ytile);
   struct tile *ptile = map_get_tile(xtile, ytile);
   struct unit *punit = player_find_unit_by_id(game.player_ptr, hover_unit);
+  enum cursor_hover_state old_hover = hover_state;
   bool maybe_goto = FALSE;
 
   if (punit && hover_state != HOVER_NONE) {
@@ -1291,6 +1316,10 @@ void do_map_click(int xtile, int ytile, 
     }
     set_hover_state(NULL, HOVER_NONE);
     update_unit_info_label(punit);
+    if (old_hover == HOVER_GOTO) {
+      /* Rename Orders/Mission Orders. */
+      update_menus();
+    }
   }
 
   /* Bypass stack or city popup if quickselect is specified. */
@@ -1476,7 +1505,7 @@ void do_unit_goto(int x, int y)
       draw_line(x, y);
       get_line_dest(&dest_x, &dest_y);
       if (same_pos(dest_x, dest_y, x, y)) {
-       send_goto_route(punit);
+       send_goto_route(punit, &hover_mission);
       } else {
        append_output_window(_("Game: Didn't find a route to the 
destination!"));
       }
@@ -1542,6 +1571,7 @@ void key_cancel_action(void)
 
     set_hover_state(NULL, HOVER_NONE);
     update_unit_info_label(punit);
+    update_menus();
 
     keyboardless_goto_button_down = FALSE;
     keyboardless_goto_active = FALSE;
@@ -1592,10 +1622,13 @@ void key_recall_previous_focus_unit(void
 **************************************************************************/
 void key_unit_move(enum direction8 gui_dir)
 {
-  if (punit_focus) {
-    enum direction8 map_dir = gui_to_map_dir(gui_dir);
-    request_move_unit_direction(punit_focus, map_dir);
+  enum direction8 map_dir = gui_to_map_dir(gui_dir);
+
+  if (!punit_focus) {
+    return;
   }
+
+  request_move_unit_direction(punit_focus, map_dir);
 }
 
 /**************************************************************************
@@ -1603,7 +1636,13 @@ void key_unit_move(enum direction8 gui_d
 **************************************************************************/
 void key_unit_build_city(void)
 {
-  if (punit_focus) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_BUILD_CITY;
+  } else {
     request_unit_build_city(punit_focus);
   }
 }
@@ -1613,7 +1652,14 @@ void key_unit_build_city(void)
 **************************************************************************/
 void key_unit_build_wonder(void)
 {
-  if (punit_focus && unit_flag(punit_focus, F_HELP_WONDER)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_BUILD_WONDER;
+  }
+  else if (unit_can_help_build_wonder_here(punit_focus)) {
     request_unit_caravan_action(punit_focus, PACKET_UNIT_HELP_BUILD_WONDER);
   }
 }
@@ -1623,9 +1669,11 @@ handle user pressing key for 'Connect' c
 **************************************************************************/
 void key_unit_connect(void)
 {
-  if (punit_focus) {
-    request_unit_connect();
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_connect();
 }
 
 /**************************************************************************
@@ -1634,7 +1682,8 @@ void key_unit_connect(void)
 void key_unit_diplomat_actions(void)
 {
   struct city *pcity;          /* need pcity->id */
-  if (punit_focus
+
+  if(punit_focus
      && is_diplomat_unit(punit_focus)
      && (pcity = map_get_city(punit_focus->x, punit_focus->y))
      && !diplomat_dialog_is_open()    /* confusing otherwise? */
@@ -1648,9 +1697,11 @@ void key_unit_diplomat_actions(void)
 **************************************************************************/
 void key_unit_done(void)
 {
-  if (punit_focus) {
-    request_unit_move_done();
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_move_done();
 }
 
 /**************************************************************************
@@ -1658,9 +1709,11 @@ void key_unit_done(void)
 **************************************************************************/
 void key_unit_goto(void)
 {
-  if (punit_focus) {
-    request_unit_goto();
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_goto();
 }
 
 /**************************************************************************
@@ -1668,9 +1721,11 @@ Explode nuclear at a tile without enemy 
 **************************************************************************/
 void key_unit_nuke(void)
 {
-  if (punit_focus) {
-    request_unit_nuke(punit_focus);
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_nuke(punit_focus);
 }
 
 /**************************************************************************
@@ -1678,7 +1733,11 @@ void key_unit_nuke(void)
 **************************************************************************/
 void key_unit_paradrop(void)
 {
-  if (punit_focus && can_unit_paradrop(punit_focus)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (can_unit_paradrop(punit_focus)) {
     request_unit_paradrop(punit_focus);
   }
 }
@@ -1688,9 +1747,23 @@ void key_unit_paradrop(void)
 **************************************************************************/
 void key_unit_patrol(void)
 {
-  if (punit_focus) {
-    request_unit_patrol();
+  if (!punit_focus) {
+    return;
+  }
+
+  request_unit_patrol();
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+void key_unit_return(void)
+{
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_return(punit_focus);
 }
 
 /**************************************************************************
@@ -1698,7 +1771,14 @@ void key_unit_patrol(void)
 **************************************************************************/
 void key_unit_traderoute(void)
 {
-  if (punit_focus && unit_flag(punit_focus, F_TRADE_ROUTE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_TRADEROUTE;
+  }
+  else if (unit_can_est_traderoute_here(punit_focus)) {
     request_unit_caravan_action(punit_focus, PACKET_UNIT_ESTABLISH_TRADE);
   }
 }
@@ -1708,7 +1788,13 @@ void key_unit_traderoute(void)
 **************************************************************************/
 void key_unit_unload(void)
 {
-  if (punit_focus) {
+  if (!punit_focus || get_transporter_capacity(punit_focus) <= 0) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_UNLOAD;
+  } else {
     request_unit_unload(punit_focus);
   }
 }
@@ -1718,9 +1804,11 @@ void key_unit_unload(void)
 **************************************************************************/
 void key_unit_wait(void)
 {
-  if (punit_focus) {
-    request_unit_wait(punit_focus);
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_wait(punit_focus);
 }
 
 /**************************************************************************
@@ -1728,9 +1816,11 @@ void key_unit_wait(void)
 ***************************************************************************/
 void key_unit_wakeup_others(void)
 {
-  if (punit_focus) {
-    request_unit_wakeup(punit_focus);
+  if (!punit_focus) {
+    return;
   }
+
+  request_unit_wakeup(punit_focus);
 }
 
 /**************************************************************************
@@ -1738,8 +1828,14 @@ void key_unit_wakeup_others(void)
 **************************************************************************/
 void key_unit_airbase(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_AIRBASE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_AIRBASE;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_AIRBASE)) {
     request_new_unit_activity(punit_focus, ACTIVITY_AIRBASE);
   }
 }
@@ -1749,10 +1845,17 @@ void key_unit_airbase(void)
 **************************************************************************/
 void key_unit_auto_attack(void)
 {
-  if (punit_focus && !unit_flag(punit_focus, F_SETTLERS) &&
-      can_unit_do_auto(punit_focus)) {
-    request_unit_auto(punit_focus);
+  if (!punit_focus) {
+    return;
   }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_AUTO_ATTACK;
+  }
+  else if (!unit_flag(punit_focus, F_SETTLERS) &&
+           can_unit_do_auto(punit_focus)) {
+      request_unit_auto(punit_focus);
+  }
 }
 
 /**************************************************************************
@@ -1760,8 +1863,14 @@ void key_unit_auto_attack(void)
 **************************************************************************/
 void key_unit_auto_explore(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_EXPLORE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_EXPLORE;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_EXPLORE)) {
     request_new_unit_activity(punit_focus, ACTIVITY_EXPLORE);
   }
 }
@@ -1771,8 +1880,15 @@ void key_unit_auto_explore(void)
 **************************************************************************/
 void key_unit_auto_settle(void)
 {
-  if (punit_focus && unit_flag(punit_focus, F_SETTLERS) &&
-      can_unit_do_auto(punit_focus)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_AUTO_SETTLE;
+  }
+  else if (unit_flag(punit_focus, F_SETTLERS) &&
+           can_unit_do_auto(punit_focus)) {
     request_unit_auto(punit_focus);
   }
 }
@@ -1782,7 +1898,13 @@ void key_unit_auto_settle(void)
 **************************************************************************/
 void key_unit_disband(void)
 {
-  if (punit_focus) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_DISBAND;
+  } else {
     request_unit_disband(punit_focus);
   }
 }
@@ -1792,8 +1914,14 @@ void key_unit_disband(void)
 **************************************************************************/
 void key_unit_fallout(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_FALLOUT)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_FALLOUT;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_FALLOUT)) {
     request_new_unit_activity(punit_focus, ACTIVITY_FALLOUT);
   }
 }
@@ -1803,8 +1931,14 @@ void key_unit_fallout(void)
 **************************************************************************/
 void key_unit_fortify(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_FORTIFYING)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_FORTIFYING;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_FORTIFYING)) {
     request_new_unit_activity(punit_focus, ACTIVITY_FORTIFYING);
   }
 }
@@ -1814,8 +1948,14 @@ void key_unit_fortify(void)
 **************************************************************************/
 void key_unit_fortress(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_FORTRESS)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_FORTRESS;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_FORTRESS)) {
     request_new_unit_activity(punit_focus, ACTIVITY_FORTRESS);
   }
 }
@@ -1825,7 +1965,14 @@ void key_unit_fortress(void)
 **************************************************************************/
 void key_unit_homecity(void)
 {
-  if (punit_focus) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.action = ACTION_HOMECITY;
+  }
+  else if (can_unit_change_homecity(punit_focus)) {
     request_unit_change_homecity(punit_focus);
   }
 }
@@ -1835,8 +1982,14 @@ void key_unit_homecity(void)
 **************************************************************************/
 void key_unit_irrigate(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_IRRIGATE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_IRRIGATE;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_IRRIGATE)) {
     request_new_unit_activity(punit_focus, ACTIVITY_IRRIGATE);
   }
 }
@@ -1846,8 +1999,14 @@ void key_unit_irrigate(void)
 **************************************************************************/
 void key_unit_mine(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_MINE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_MINE;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_MINE)) {
     request_new_unit_activity(punit_focus, ACTIVITY_MINE);
   }
 }
@@ -1857,8 +2016,14 @@ void key_unit_mine(void)
 **************************************************************************/
 void key_unit_pillage(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_PILLAGE)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_PILLAGE;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_PILLAGE)) {
     request_unit_pillage(punit_focus);
   }
 }
@@ -1868,8 +2033,14 @@ void key_unit_pillage(void)
 **************************************************************************/
 void key_unit_pollution(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_POLLUTION)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_POLLUTION;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_POLLUTION)) {
     request_new_unit_activity(punit_focus, ACTIVITY_POLLUTION);
   }
 }
@@ -1879,11 +2050,18 @@ void key_unit_pollution(void)
 **************************************************************************/
 void key_unit_road(void)
 {
-  if (punit_focus) {
-    if(can_unit_do_activity(punit_focus, ACTIVITY_ROAD))
-      request_new_unit_activity(punit_focus, ACTIVITY_ROAD);
-    else if(can_unit_do_activity(punit_focus, ACTIVITY_RAILROAD))
-      request_new_unit_activity(punit_focus, ACTIVITY_RAILROAD);
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_ROAD;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_ROAD)) {
+    request_new_unit_activity(punit_focus, ACTIVITY_ROAD);
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_RAILROAD)) {
+    request_new_unit_activity(punit_focus, ACTIVITY_RAILROAD);
   }
 }
 
@@ -1892,8 +2070,14 @@ void key_unit_road(void)
 **************************************************************************/
 void key_unit_sentry(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_SENTRY)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_SENTRY;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_SENTRY)) {
     request_new_unit_activity(punit_focus, ACTIVITY_SENTRY);
   }
 }
@@ -1903,8 +2087,14 @@ void key_unit_sentry(void)
 **************************************************************************/
 void key_unit_transform(void)
 {
-  if (punit_focus &&
-      can_unit_do_activity(punit_focus, ACTIVITY_TRANSFORM)) {
+  if (!punit_focus) {
+    return;
+  }
+
+  if (mission_orders_phase) {
+    hover_mission.activity = ACTIVITY_TRANSFORM;
+  }
+  else if (can_unit_do_activity(punit_focus, ACTIVITY_TRANSFORM)) {
     request_new_unit_activity(punit_focus, ACTIVITY_TRANSFORM);
   }
 }
Index: client/control.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.h,v
retrieving revision 1.40
diff -u -p -r1.40 control.h
--- client/control.h    2003/12/16 15:07:52     1.40
+++ client/control.h    2004/01/28 13:25:03
@@ -31,6 +31,7 @@ enum quickselect_type {
 
 extern int hover_unit; /* unit hover_state applies to */
 extern enum cursor_hover_state hover_state;
+extern union composite_orders hover_mission;
 extern bool draw_goto_line;
 extern bool non_ai_unit_focus;
 
@@ -149,6 +150,7 @@ void key_unit_patrol(void);
 void key_unit_paradrop(void);
 void key_unit_pillage(void);
 void key_unit_pollution(void);
+void key_unit_return(void);
 void key_unit_road(void);
 void key_unit_sentry(void);
 void key_unit_traderoute(void);
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.66
diff -u -p -r1.66 goto.c
--- client/goto.c       2004/01/20 21:52:06     1.66
+++ client/goto.c       2004/01/28 13:25:10
@@ -486,7 +486,8 @@ void request_orders_cleared(struct unit 
   Send a path as a goto or patrol route to the server.
 **************************************************************************/
 static void send_path_orders(struct unit *punit, struct pf_path *path,
-                            bool repeat, bool vigilant)
+                            bool repeat, bool vigilant,
+                            union composite_orders *mission)
 {
   struct packet_unit_orders p;
   int i, old_x, old_y;
@@ -497,8 +498,17 @@ static void send_path_orders(struct unit
 
   freelog(PACKET_LOG_LEVEL, "Orders for unit %d:", punit->id);
 
-  /* We skip the start position. */
-  p.length = path->length - 1;
+  if (mission && mission->order != ORDER_LAST) {
+    /* The last order in the packet is a mission order. */
+    p.length = path->length;
+    p.orders[path->length - 1] = mission->order;
+    p.dir[path->length - 1] = -1;
+  } else {
+    /* The first order in the packet is the move from the start position
+     * to the second position. The last position in the generated path
+     * is skipped. */
+    p.length = path->length - 1;
+  }
   assert(p.length < MAX_LEN_ROUTE);
   old_x = path->positions[0].x;
   old_y = path->positions[0].y;
@@ -535,9 +545,10 @@ static void send_path_orders(struct unit
 /**************************************************************************
   Send an arbitrary goto path for the unit to the server.
 **************************************************************************/
-void send_goto_path(struct unit *punit, struct pf_path *path)
+void send_goto_path(struct unit *punit, struct pf_path *path,
+                   union composite_orders *mission)
 {
-  send_path_orders(punit, path, FALSE, FALSE);
+  send_path_orders(punit, path, FALSE, FALSE, mission);
 }
 
 /**************************************************************************
@@ -573,7 +584,7 @@ void send_patrol_route(struct unit *puni
   pf_destroy_map(map);
   pf_destroy_path(return_path);
 
-  send_path_orders(punit, path, TRUE, TRUE);
+  send_path_orders(punit, path, TRUE, TRUE, NULL);
 
   pf_destroy_path(path);
 }
@@ -583,7 +594,7 @@ void send_patrol_route(struct unit *puni
   HOVER_STATE) to the server.  The route might involve more than one
   part if waypoints were used.  FIXME: danger paths are not supported.
 **************************************************************************/
-void send_goto_route(struct unit *punit)
+void send_goto_route(struct unit *punit, union composite_orders *mission)
 {
   struct pf_path *path = NULL;
   int i;
@@ -595,7 +606,7 @@ void send_goto_route(struct unit *punit)
     path = pft_concat(path, goto_map.parts[i].path);
   }
 
-  send_goto_path(punit, path);
+  send_goto_path(punit, path, mission);
   pf_destroy_path(path);
 }
 
Index: client/goto.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.h,v
retrieving revision 1.11
diff -u -p -r1.11 goto.h
--- client/goto.h       2004/01/20 21:52:07     1.11
+++ client/goto.h       2004/01/28 13:25:10
@@ -30,9 +30,10 @@ void draw_line(int dest_x, int dest_y);
 int get_drawn(int x, int y, int dir);
 
 void request_orders_cleared(struct unit *punit);
-void send_goto_path(struct unit *punit, struct pf_path *path);
+void send_goto_path(struct unit *punit, struct pf_path *path,
+                   union composite_orders *mission);
 void send_patrol_route(struct unit *punit);
-void send_goto_route(struct unit *punit);
+void send_goto_route(struct unit *punit, union composite_orders *mission);
 
 struct pf_path *path_to_nearest_allied_city(struct unit *punit);
 
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.345
diff -u -p -r1.345 packhand.c
--- client/packhand.c   2004/01/20 21:52:07     1.345
+++ client/packhand.c   2004/01/28 13:25:36
@@ -119,6 +119,8 @@ static struct unit * unpackage_unit(stru
   punit->has_orders = packet->has_orders;
   punit->orders.repeat = packet->repeat;
   punit->orders.vigilant = packet->vigilant;
+  punit->orders.mission.order = packet->mission;
+  punit->orders.type = packet->orders_type;
   return punit;
 }
 
@@ -942,7 +944,10 @@ static bool handle_unit_packet_common(st
         || punit->activity_target != packet_unit->activity_target
        || punit->has_orders != packet_unit->has_orders
        || punit->orders.repeat != packet_unit->orders.repeat
-       || punit->orders.vigilant != packet_unit->orders.vigilant) {
+       || punit->orders.vigilant != packet_unit->orders.vigilant
+       || punit->orders.mission.order != packet_unit->orders.mission.order
+       || punit->orders.type != packet_unit->orders.type) {
+
       /*** Change in activity or activity's target. ***/
 
       /* May change focus if focus unit gets a new activity.
@@ -982,6 +987,8 @@ static bool handle_unit_packet_common(st
       punit->has_orders = packet_unit->has_orders;
       punit->orders.repeat = packet_unit->orders.repeat;
       punit->orders.vigilant = packet_unit->orders.vigilant;
+      punit->orders.mission.order = packet_unit->orders.mission.order;
+      punit->orders.type = packet_unit->orders.type;
 
       if (punit->owner == game.player_idx) {
         refresh_unit_city_dialogs(punit);
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.137
diff -u -p -r1.137 tilespec.c
--- client/tilespec.c   2004/01/20 21:52:07     1.137
+++ client/tilespec.c   2004/01/28 13:26:04
@@ -910,6 +910,7 @@ static void tilespec_lookup_sprite_tags(
   SET_SPRITE(unit.fortress,     "unit.fortress");
   SET_SPRITE(unit.airbase,      "unit.airbase");
   SET_SPRITE(unit.go_to,       "unit.goto");     
+  SET_SPRITE(unit.go_to_with_mission, "unit.goto_with_mission");
   SET_SPRITE(unit.irrigate,     "unit.irrigate");
   SET_SPRITE(unit.mine,                "unit.mine");
   SET_SPRITE(unit.pillage,     "unit.pillage");
@@ -920,6 +921,8 @@ static void tilespec_lookup_sprite_tags(
   SET_SPRITE(unit.transform,    "unit.transform");
   SET_SPRITE(unit.connect,      "unit.connect");
   SET_SPRITE(unit.patrol,       "unit.patrol");
+  SET_SPRITE(unit.build_city,   "unit.build_city");
+  SET_SPRITE(unit.build_wonder, "unit.build_wonder");
 
   for(i=0; i<NUM_TILES_HP_BAR; i++) {
     my_snprintf(buffer, sizeof(buffer), "unit.hp_%d", i*10);
@@ -1497,23 +1500,104 @@ int fill_unit_sprite_array(struct drawn_
     ADD_SPRITE_SIMPLE(s);
   }
 
-  if (punit->ai.control && punit->activity != ACTIVITY_EXPLORE) {
-    if (is_military_unit(punit)) {
-      ADD_SPRITE_SIMPLE(sprites.unit.auto_attack);
-    } else {
-      ADD_SPRITE_SIMPLE(sprites.unit.auto_settler);
+  if (hover_state == HOVER_GOTO && hover_mission.order != ORDER_LAST
+      && punit == find_unit_by_id(hover_unit)) {
+    /* Temporary mission indication during hover. */
+    struct Sprite *s = NULL;
+
+    switch (hover_mission.order) {
+    case ACTION_DISBAND:
+    case ACTION_HOMECITY:
+    case ACTION_UNLOAD:
+      /* No graphics. */
+      break;
+    case ACTION_AUTO_ATTACK:
+      s = sprites.unit.auto_attack;
+      break;
+    case ACTION_TRADEROUTE:
+      s = sprites.unit.road;
+      break;
+    case ACTION_AUTO_SETTLE:
+      s = sprites.unit.auto_settler;
+      break;
+    case ACTION_BUILD_CITY:
+      s = sprites.unit.build_city;
+      break;
+    case ACTION_BUILD_WONDER:
+      s = sprites.unit.build_wonder;
+      break;
+
+    case ACTIVITY_AIRBASE:
+      s = sprites.unit.airbase;
+      break;
+    case ACTIVITY_EXPLORE:
+      s = sprites.unit.auto_explore;
+      break;
+    case ACTIVITY_FALLOUT:
+      s = sprites.unit.fallout;
+      break;
+    case ACTIVITY_FORTIFYING:
+      s = sprites.unit.fortifying;
+      break;
+    case ACTIVITY_FORTRESS:
+      s = sprites.unit.fortress;
+      break;
+    case ACTIVITY_IRRIGATE:
+      s = sprites.unit.irrigate;
+      break;
+    case ACTIVITY_MINE:
+      s = sprites.unit.mine;
+      break;
+    case ACTIVITY_PILLAGE:
+      s = sprites.unit.pillage;
+      break;
+    case ACTIVITY_POLLUTION:
+      s = sprites.unit.pollution;
+      break;
+    case ACTIVITY_ROAD:
+      s = sprites.unit.road;
+      break;
+    case ACTIVITY_SENTRY:
+      s = sprites.unit.sentry;
+      break;
+    case ACTIVITY_TRANSFORM:
+      s = sprites.unit.transform;
+      break;
+
+    default:
+      break;
     }
-  }
+    if (s) {
+      ADD_SPRITE_SIMPLE(s);
+    }
+  } else {
+     /* Not hover unit. */
 
-  if (punit->connecting) {
-    ADD_SPRITE_SIMPLE(sprites.unit.connect);
-  }
+    if (punit->ai.control && punit->activity != ACTIVITY_EXPLORE) {
+      if (is_military_unit(punit)) {
+        ADD_SPRITE_SIMPLE(sprites.unit.auto_attack);
+      } else {
+        ADD_SPRITE_SIMPLE(sprites.unit.auto_settler);
+      }
+    }
 
-  if (unit_has_orders(punit)) {
-    if (punit->orders.repeat) {
-      ADD_SPRITE_SIMPLE(sprites.unit.patrol);
-    } else {
-      ADD_SPRITE_SIMPLE(sprites.unit.go_to);
+    if (punit->connecting) {
+      ADD_SPRITE_SIMPLE(sprites.unit.connect);
+    }
+
+    if (unit_has_orders(punit)) {
+      if (punit->orders.type == PATROL_ORDERS) {
+        ADD_SPRITE_SIMPLE(sprites.unit.patrol);
+      } else if (punit->orders.type == GOTO_ORDERS) {
+        ADD_SPRITE_SIMPLE(order_is_action(punit->orders.mission)
+          ? sprites.unit.go_to_with_mission : sprites.unit.go_to);
+      }
+      /* Build mission has an extra sprite, because it's neat. */
+      if (punit->orders.mission.action == ACTION_BUILD_CITY) {
+        ADD_SPRITE_SIMPLE(sprites.unit.build_city);
+      } else if (punit->orders.mission.action == ACTION_BUILD_WONDER) {
+        ADD_SPRITE_SIMPLE(sprites.unit.build_wonder);
+      }
     }
   }
 
Index: client/tilespec.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.h,v
retrieving revision 1.49
diff -u -p -r1.49 tilespec.h
--- client/tilespec.h   2004/01/11 17:45:03     1.49
+++ client/tilespec.h   2004/01/28 13:26:06
@@ -153,6 +153,7 @@ struct named_sprites {
       *fortress,
       *airbase,
       *go_to,                  /* goto is a C keyword :-) */
+      *go_to_with_mission,
       *irrigate,
       *mine,
       *pillage,
@@ -162,7 +163,9 @@ struct named_sprites {
       *stack,
       *transform,
       *connect,
-      *patrol;
+      *patrol,
+      *build_city,
+      *build_wonder;
   } unit;
   struct {
     struct Sprite
Index: client/gui-gtk/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/gui_main.c,v
retrieving revision 1.142
diff -u -p -r1.142 gui_main.c
--- client/gui-gtk/gui_main.c   2004/01/24 02:58:55     1.142
+++ client/gui-gtk/gui_main.c   2004/01/28 13:26:17
@@ -1197,3 +1197,11 @@ void remove_net_input(void)
   gdk_input_remove(gdk_input_id);
   gdk_window_set_cursor(root_window, NULL);
 }
+
+/**************************************************************************
+...
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return TRUE;
+}
Index: client/gui-gtk/menu.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/menu.c,v
retrieving revision 1.81
diff -u -p -r1.81 menu.c
--- client/gui-gtk/menu.c       2004/01/20 21:52:07     1.81
+++ client/gui-gtk/menu.c       2004/01/28 13:26:29
@@ -56,7 +56,6 @@
 #include "menu.h"
 
 static GtkItemFactory *item_factory = NULL;
-static enum unit_activity road_activity;
 
 static void menus_rename(const char *path, char *s);
 
@@ -311,116 +310,105 @@ static void view_menu_callback(gpointer 
 
 
 /****************************************************************
-...
+ Validity checking of the order for the unit is done in
+ control.c, sometimes in server. Here we only need check flags.
 *****************************************************************/
 static void orders_menu_callback(gpointer callback_data,
                                 guint callback_action, GtkWidget *widget)
 {
+  struct unit *punit = get_unit_in_focus();
+
+  if (!punit) {
+    return;
+  }
+
   switch(callback_action) {
-   case MENU_ORDER_BUILD_CITY:
-    if (get_unit_in_focus()) {
-      struct unit *punit = get_unit_in_focus();
-      /* Enable the button for adding to a city in all cases, so we
-        get an eventual error message from the server if we try. */
-      if (can_unit_add_or_build_city(punit)) {
-       key_unit_build_city();
-      } else {
-       key_unit_build_wonder();
-      }
-    }
+  case MENU_ORDER_BUILD_CITY:
+    unit_flag(punit, F_CITIES) ?
+    key_unit_build_city():
+    key_unit_build_wonder();
+    break;
+  case MENU_ORDER_ROAD:
+    unit_flag(punit, F_TRADE_ROUTE) ?
+    key_unit_traderoute():
+    key_unit_road();
     break;
-   case MENU_ORDER_ROAD:
-    if (get_unit_in_focus()) {
-      if (unit_can_est_traderoute_here(get_unit_in_focus()))
-       key_unit_traderoute();
-      else
-       key_unit_road();
-    }
-    break;
-   case MENU_ORDER_IRRIGATE:
+  case MENU_ORDER_IRRIGATE:
     key_unit_irrigate();
     break;
-   case MENU_ORDER_MINE:
+  case MENU_ORDER_MINE:
     key_unit_mine();
     break;
-   case MENU_ORDER_TRANSFORM:
+  case MENU_ORDER_TRANSFORM:
     key_unit_transform();
     break;
-   case MENU_ORDER_FORTRESS:
-    if (get_unit_in_focus()) {
-      if (can_unit_do_activity(get_unit_in_focus(), ACTIVITY_FORTRESS))
-       key_unit_fortress();
-      else
-       key_unit_fortify();
-    }
+  case MENU_ORDER_FORTRESS:
+    unit_flag(punit, F_SETTLERS) ?
+    key_unit_fortress():
+    key_unit_fortify();
     break;
-   case MENU_ORDER_AIRBASE:
+  case MENU_ORDER_AIRBASE:
     key_unit_airbase(); 
     break;
-   case MENU_ORDER_POLLUTION:
-    if (get_unit_in_focus()) {
-      if (can_unit_paradrop(get_unit_in_focus()))
-       key_unit_paradrop();
-      else
-       key_unit_pollution();
-    }
+  case MENU_ORDER_POLLUTION:
+    unit_flag(punit, F_PARATROOPERS) ?
+    key_unit_paradrop():
+    key_unit_pollution();
     break;
-   case MENU_ORDER_FALLOUT:
+  case MENU_ORDER_FALLOUT:
     key_unit_fallout();
     break;
-   case MENU_ORDER_SENTRY:
+  case MENU_ORDER_SENTRY:
     key_unit_sentry();
     break;
-   case MENU_ORDER_PILLAGE:
+  case MENU_ORDER_PILLAGE:
     key_unit_pillage();
     break;
-   case MENU_ORDER_HOMECITY:
+  case MENU_ORDER_HOMECITY:
     key_unit_homecity();
     break;
-   case MENU_ORDER_UNLOAD:
+  case MENU_ORDER_UNLOAD:
     key_unit_unload();
     break;
-   case MENU_ORDER_WAKEUP_OTHERS:
+  case MENU_ORDER_WAKEUP_OTHERS:
     key_unit_wakeup_others();
     break;
-   case MENU_ORDER_AUTO_SETTLER:
-    if(get_unit_in_focus())
-      request_unit_auto(get_unit_in_focus());
+  case MENU_ORDER_AUTO_SETTLER:
+    unit_flag(punit, F_SETTLERS) ?
+    key_unit_auto_settle():
+    key_unit_auto_attack();
     break;
-   case MENU_ORDER_AUTO_EXPLORE:
+  case MENU_ORDER_AUTO_EXPLORE:
     key_unit_auto_explore();
     break;
-   case MENU_ORDER_CONNECT:
+  case MENU_ORDER_CONNECT:
     key_unit_connect();
     break;
-   case MENU_ORDER_PATROL:
+  case MENU_ORDER_PATROL:
     key_unit_patrol();
     break;
-   case MENU_ORDER_GOTO:
+  case MENU_ORDER_GOTO:
     key_unit_goto();
     break;
-   case MENU_ORDER_GOTO_CITY:
-    if(get_unit_in_focus())
-      popup_goto_dialog();
-    break;
-   case MENU_ORDER_RETURN:
-    if (get_unit_in_focus()) {
-      request_unit_return(get_unit_in_focus());
-    }
+  case MENU_ORDER_GOTO_CITY:
+    popup_goto_dialog();
+    break;
+  case MENU_ORDER_RETURN:
+    key_unit_return();
     break;
-   case MENU_ORDER_DISBAND:
+  case MENU_ORDER_DISBAND:
     key_unit_disband();
     break;
-   case MENU_ORDER_DIPLOMAT_DLG:
+  case MENU_ORDER_DIPLOMAT_DLG:
     key_unit_diplomat_actions();
     break;
-   case MENU_ORDER_NUKE:
+  case MENU_ORDER_NUKE:
     key_unit_nuke();
     break;
-   case MENU_ORDER_WAIT:
+  case MENU_ORDER_WAIT:
     key_unit_wait();
     break;
-   case MENU_ORDER_DONE:
+  case MENU_ORDER_DONE:
     key_unit_done();
     break;
   }
@@ -667,6 +655,33 @@ static GtkItemFactoryEntry menu_items[]    
        NULL,                   0,                                      
"<Separator>"   },
   { "/" N_("View") "/" N_("_Center View"),             "c",
        view_menu_callback,     MENU_VIEW_CENTER_VIEW                           
        },
+  /* Reports menu ... */
+  { "/" N_("_Reports"),                                        NULL,
+       NULL,                   0,                                      
"<Branch>"      },
+  { "/" N_("Reports") "/tearoff1",                     NULL,
+       NULL,                   0,                                      
"<Tearoff>"     },
+  { "/" N_("Reports") "/" N_("_Cities"),               "F1",
+       reports_menu_callback,  MENU_REPORT_CITIES                              
        },
+  { "/" N_("Reports") "/" N_("_Units"),                        "F2",
+       reports_menu_callback,  MENU_REPORT_UNITS                               
        },
+  { "/" N_("Reports") "/" N_("_Players"),              "F3",
+       reports_menu_callback,  MENU_REPORT_PLAYERS                             
        },
+  { "/" N_("Reports") "/" N_("_Economy"),              "F5",
+       reports_menu_callback,  MENU_REPORT_ECONOMY                             
        },
+  { "/" N_("Reports") "/" N_("_Science"),              "F6",
+       reports_menu_callback,  MENU_REPORT_SCIENCE                             
        },
+  { "/" N_("Reports") "/sep1",                         NULL,
+       NULL,                   0,                                      
"<Separator>"   },
+  { "/" N_("Reports") "/" N_("_Wonders of the World"), "F7",
+       reports_menu_callback,  MENU_REPORT_WOW                                 
        },
+  { "/" N_("Reports") "/" N_("_Top Five Cities"),      "F8",
+       reports_menu_callback,  MENU_REPORT_TOP_CITIES                          
        },
+  { "/" N_("Reports") "/" N_("_Messages"),             "F10",
+       reports_menu_callback,  MENU_REPORT_MESSAGES                            
        },
+  { "/" N_("Reports") "/" N_("_Demographics"),         "F11",
+       reports_menu_callback,  MENU_REPORT_DEMOGRAPHIC                         
        },
+  { "/" N_("Reports") "/" N_("S_paceship"),            "F12",
+       reports_menu_callback,  MENU_REPORT_SPACESHIP                           
        },
   /* Orders menu ... */
   { "/" N_("_Orders"),                                 NULL,
        NULL,                   0,                                      
"<Branch>"      },
@@ -734,33 +749,6 @@ static GtkItemFactoryEntry menu_items[]    
        orders_menu_callback,   MENU_ORDER_WAIT                                 
        },
   { "/" N_("Orders") "/" N_("Done"),                   "space",
        orders_menu_callback,   MENU_ORDER_DONE                                 
        },
-  /* Reports menu ... */
-  { "/" N_("_Reports"),                                        NULL,
-       NULL,                   0,                                      
"<Branch>"      },
-  { "/" N_("Reports") "/tearoff1",                     NULL,
-       NULL,                   0,                                      
"<Tearoff>"     },
-  { "/" N_("Reports") "/" N_("_Cities"),               "F1",
-       reports_menu_callback,  MENU_REPORT_CITIES                              
        },
-  { "/" N_("Reports") "/" N_("_Units"),                        "F2",
-       reports_menu_callback,  MENU_REPORT_UNITS                               
        },
-  { "/" N_("Reports") "/" N_("_Players"),              "F3",
-       reports_menu_callback,  MENU_REPORT_PLAYERS                             
        },
-  { "/" N_("Reports") "/" N_("_Economy"),              "F5",
-       reports_menu_callback,  MENU_REPORT_ECONOMY                             
        },
-  { "/" N_("Reports") "/" N_("_Science"),              "F6",
-       reports_menu_callback,  MENU_REPORT_SCIENCE                             
        },
-  { "/" N_("Reports") "/sep1",                         NULL,
-       NULL,                   0,                                      
"<Separator>"   },
-  { "/" N_("Reports") "/" N_("_Wonders of the World"), "F7",
-       reports_menu_callback,  MENU_REPORT_WOW                                 
        },
-  { "/" N_("Reports") "/" N_("_Top Five Cities"),      "F8",
-       reports_menu_callback,  MENU_REPORT_TOP_CITIES                          
        },
-  { "/" N_("Reports") "/" N_("_Messages"),             "F10",
-       reports_menu_callback,  MENU_REPORT_MESSAGES                            
        },
-  { "/" N_("Reports") "/" N_("_Demographics"),         "F11",
-       reports_menu_callback,  MENU_REPORT_DEMOGRAPHIC                         
        },
-  { "/" N_("Reports") "/" N_("S_paceship"),            "F12",
-       reports_menu_callback,  MENU_REPORT_SPACESHIP                           
        },
   /* Help menu ... */
   { "/" N_("_Help"),                                   NULL,
        NULL,                   0,                                      
"<LastBranch>"  },
@@ -997,237 +985,304 @@ static void government_callback(GtkMenuI
 }
 
 /****************************************************************
-Note: the menu strings should contain underscores as in the
-menu_items struct. The underscores will be removed elsewhere if
-the string is used for a lookup via gtk_item_factory_get_widget()
+  Note: the menu strings should contain underscores as in the
+  menu_items struct. The underscores will be removed elsewhere
+  if the string is used for a lookup via
+  gtk_item_factory_get_widget().
+
+  To maintain this large function in gui GTK 1 and GTK 2, it is
+  worth noting that there are 3 differences between them:
+
+  1. The Governments menu stuff.
+  2. The spelling of item Diplomat / Spy Actions.
+  3. The spelling of item Go / Airlift to City.
+
+  The rest should be copy/paste.
 *****************************************************************/
 void update_menus(void)
 {
+  const char *path;
+  GtkWidget *parent;
+  struct unit *punit;
+
   if (!can_client_change_view()) {
     menus_set_sensitive("<main>/_Reports", FALSE);
     menus_set_sensitive("<main>/_Kingdom", FALSE);
     menus_set_sensitive("<main>/_View", FALSE);
     menus_set_sensitive("<main>/_Orders", FALSE);
-  } else {
-    struct unit *punit;
+    return;
+  }
+
+  /** Governments menu stuff **/
+
+  path = translate_menu_path("<main>/_Kingdom/_Government", TRUE);
+  parent = gtk_item_factory_get_widget(item_factory, path);
+
+  if (parent) {
+    int i;
+    GList *iter, *iter_next;
     GtkWidget *item;
-    const char *path =
-       translate_menu_path("<main>/_Kingdom/_Government", TRUE);
-    GtkWidget *parent = gtk_item_factory_get_widget(item_factory, path);
-
-    if (parent) {
-      int i;
-      GList *iter, *iter_next;
-
-      /* remove previous government entries. */
-      iter = gtk_container_children(GTK_CONTAINER(parent));
-      for (iter = g_list_nth(iter, 2); iter; iter = iter_next) {
-        iter_next = iter->next;
 
-        gtk_container_remove(GTK_CONTAINER(parent), GTK_WIDGET(iter->data));
-      }
+    /* remove previous government entries. */
+    iter = gtk_container_children(GTK_CONTAINER(parent));
+    for (iter = g_list_nth(iter, 2); iter; iter = iter_next) {
+      iter_next = iter->next;
+      gtk_container_remove(GTK_CONTAINER(parent), GTK_WIDGET(iter->data));
+    }
 
-      /* add new government entries. */
-      for (i = 0; i < game.government_count; i++) {
-        struct government *g = &governments[i];
-
-        if (i != game.government_when_anarchy) {
-          item = gtk_menu_item_new_with_label(g->name);
-          gtk_widget_show(item);
-
-          gtk_signal_connect(GTK_OBJECT(item), "activate",
-            GTK_SIGNAL_FUNC(government_callback), GINT_TO_POINTER(g->index));
-
-          if (!can_change_to_government(game.player_ptr, i)) {
-            gtk_widget_set_sensitive(item, FALSE);
-         }
+    /* add new government entries. */
+    for (i = 0; i < game.government_count; i++) {
+      struct government *g = &governments[i];
+
+      if (i != game.government_when_anarchy) {
+        item = gtk_menu_item_new_with_label(g->name);
+        gtk_widget_show(item);
 
-          gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
-          gtk_widget_show(item);
+        gtk_signal_connect(GTK_OBJECT(item), "activate",
+          GTK_SIGNAL_FUNC(government_callback), GINT_TO_POINTER(g->index));
+
+        if (!can_change_to_government(game.player_ptr, i)) {
+          gtk_widget_set_sensitive(item, FALSE);
         }
+
+        gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
+        gtk_widget_show(item);
       }
     }
+  }
+
+  /** End of Governments menu stuff **/
 
-    menus_set_sensitive("<main>/_Reports", TRUE);
-    menus_set_sensitive("<main>/_Kingdom", TRUE);
-    menus_set_sensitive("<main>/_View", TRUE);
-    menus_set_sensitive("<main>/_Orders", can_client_issue_orders());
-
-    menus_set_sensitive("<main>/_Kingdom/_Tax Rates",
-                       can_client_issue_orders());
-    menus_set_sensitive("<main>/_Kingdom/Work_lists",
-                       can_client_issue_orders());
-    menus_set_sensitive("<main>/_Kingdom/_Government",
-                       can_client_issue_orders());
-
-    menus_set_sensitive("<main>/_Reports/S_paceship",
-                       (game.player_ptr->spaceship.state!=SSHIP_NONE));
-
-    menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
-    menus_set_sensitive("<main>/_View/National _Borders", game.borders > 0);
-    menus_set_active("<main>/_View/National _Borders", draw_borders);
-    menus_set_active("<main>/_View/City _Names", draw_city_names);
-    menus_set_sensitive("<main>/_View/City G_rowth", draw_city_names);
-    menus_set_active("<main>/_View/City G_rowth", draw_city_growth);
-    menus_set_active("<main>/_View/City _Productions", draw_city_productions);
-    menus_set_active("<main>/_View/Terrain", draw_terrain);
-    menus_set_active("<main>/_View/Coastline", draw_coastline);
-    menus_set_sensitive("<main>/_View/Coastline", !draw_terrain);
-    menus_set_active("<main>/_View/Improvements/Roads & Rails", 
draw_roads_rails);
-    menus_set_active("<main>/_View/Improvements/Irrigation", draw_irrigation);
-    menus_set_active("<main>/_View/Improvements/Mines", draw_mines);
-    menus_set_active("<main>/_View/Improvements/Fortress & Airbase", 
draw_fortress_airbase);
-    menus_set_active("<main>/_View/Specials", draw_specials);
-    menus_set_active("<main>/_View/Pollution & Fallout", draw_pollution);
-    menus_set_active("<main>/_View/Cities", draw_cities);
-    menus_set_active("<main>/_View/Units", draw_units);
-    menus_set_active("<main>/_View/Focus Unit", draw_focus_unit);
-    menus_set_sensitive("<main>/_View/Focus Unit", !draw_units);
-    menus_set_active("<main>/_View/Fog of War", draw_fog_of_war);
+  menus_set_sensitive("<main>/_Reports", TRUE);
+  menus_set_sensitive("<main>/_Kingdom", TRUE);
+  menus_set_sensitive("<main>/_View", TRUE);
+  menus_set_sensitive("<main>/_Orders", can_client_issue_orders());
+
+  menus_set_sensitive("<main>/_Kingdom/_Tax Rates",
+                      can_client_issue_orders());
+  menus_set_sensitive("<main>/_Kingdom/Work_lists",
+                      can_client_issue_orders());
+  menus_set_sensitive("<main>/_Kingdom/_Government",
+                      can_client_issue_orders());
+
+  menus_set_sensitive("<main>/_Reports/S_paceship",
+                      (game.player_ptr->spaceship.state != SSHIP_NONE));
+
+  menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
+  menus_set_sensitive("<main>/_View/National _Borders", game.borders > 0);
+  menus_set_active("<main>/_View/National _Borders", draw_borders);
+  menus_set_active("<main>/_View/City _Names", draw_city_names);
+  menus_set_sensitive("<main>/_View/City G_rowth", draw_city_names);
+  menus_set_active("<main>/_View/City G_rowth", draw_city_growth);
+  menus_set_active("<main>/_View/City _Productions", draw_city_productions);
+  menus_set_active("<main>/_View/Terrain", draw_terrain);
+  menus_set_active("<main>/_View/Coastline", draw_coastline);
+  menus_set_sensitive("<main>/_View/Coastline", !draw_terrain);
+  menus_set_active("<main>/_View/Improvements/Roads & Rails",
+                   draw_roads_rails);
+  menus_set_active("<main>/_View/Improvements/Irrigation", draw_irrigation);
+  menus_set_active("<main>/_View/Improvements/Mines", draw_mines);
+  menus_set_active("<main>/_View/Improvements/Fortress & Airbase",
+                   draw_fortress_airbase);
+  menus_set_active("<main>/_View/Specials", draw_specials);
+  menus_set_active("<main>/_View/Pollution & Fallout", draw_pollution);
+  menus_set_active("<main>/_View/Cities", draw_cities);
+  menus_set_active("<main>/_View/Units", draw_units);
+  menus_set_active("<main>/_View/Focus Unit", draw_focus_unit);
+  menus_set_sensitive("<main>/_View/Focus Unit", !draw_units);
+  menus_set_active("<main>/_View/Fog of War", draw_fog_of_war);
 
-    /* Remaining part of this function: Update Orders menu */
+  /* Remaining part of this function: Update Orders menu */
+
+  if (!can_client_issue_orders()) {
+    return;
+  }
 
-    if (!can_client_issue_orders()) {
-      return;
+  punit = get_unit_in_focus();
+
+  if (punit) {
+    char *irrfmt = _("Change to %s (_I)");
+    char *minfmt = _("Change to %s (_M)");
+    char *transfmt = _("Transf_orm to %s");
+    char irrtext[128], mintext[128], transtext[128];
+    char *roadtext, *buildtext;
+    enum tile_terrain_type  ttype;
+    struct tile_type *      tinfo;
+
+    /* For readability. */
+    const bool worker  = unit_flag(punit, F_SETTLERS);
+    const bool mission = hover_state == HOVER_GOTO
+                         && !is_air_unit(punit) && !is_heli_unit(punit);
+
+    /* When hover state is goto, enable (only) all possible Mission
+     * Orders. The validity of the order is checked after the unit
+     * has arrived. The server may then send appropriate error
+     * message for that tile. I guess it's debatable whether the
+     * client should deny requests for Mission Orders that are
+     * illegal for the destination tile at the time of the start of
+     * the goto.  --ali.
+     */
+    menus_set_sensitive("<main>/_Orders/_Build City",
+            (unit_flag(punit, F_CITIES) ||
+             unit_can_help_build_wonder_here(punit) ||
+             (mission && unit_flag(punit, F_HELP_WONDER))));
+    menus_set_sensitive("<main>/_Orders/Build _Road",
+            (can_unit_do_activity(punit, ACTIVITY_ROAD) ||
+             can_unit_do_activity(punit, ACTIVITY_RAILROAD) ||
+             unit_can_est_traderoute_here(punit)) ||
+             (mission && (worker || unit_flag(punit, F_TRADE_ROUTE))));
+    menus_set_sensitive("<main>/_Orders/Build _Irrigation",
+            can_unit_do_activity(punit, ACTIVITY_IRRIGATE) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Build _Mine",
+            can_unit_do_activity(punit, ACTIVITY_MINE) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Transf_orm Terrain",
+            can_unit_do_activity(punit, ACTIVITY_TRANSFORM) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Build _Fortress",
+            (can_unit_do_activity(punit, ACTIVITY_FORTRESS) ||
+             can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) ||
+             (mission && is_ground_unit(punit) && (!worker ||
+              player_knows_techs_with_flag(game.player_ptr, TF_FORTRESS))));
+    menus_set_sensitive("<main>/_Orders/Build Airbas_e",
+            can_unit_do_activity(punit, ACTIVITY_AIRBASE) ||
+            (mission && unit_flag(punit, F_AIRBASE) &&
+             player_knows_techs_with_flag(game.player_ptr, TF_AIRBASE)));
+    menus_set_sensitive("<main>/_Orders/Clean _Pollution",
+             (can_unit_do_activity(punit, ACTIVITY_POLLUTION) ||
+              can_unit_paradrop(punit)) ||
+              (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Clean _Nuclear Fallout",
+            can_unit_do_activity(punit, ACTIVITY_FALLOUT) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/_Sentry",
+            can_unit_do_activity(punit, ACTIVITY_SENTRY) || mission);
+    menus_set_sensitive("<main>/_Orders/Pillage",
+            can_unit_do_activity(punit, ACTIVITY_PILLAGE) ||
+            (mission && is_ground_unit(punit)));
+    menus_set_sensitive("<main>/_Orders/Make _Homecity",
+            can_unit_change_homecity(punit) || mission);
+    menus_set_sensitive("<main>/_Orders/_Unload",
+            get_transporter_capacity(punit)>0);
+    menus_set_sensitive("<main>/_Orders/Wake up o_thers", 
+            is_unit_activity_on_tile(ACTIVITY_SENTRY,
+            punit->x, punit->y) && !mission);
+    menus_set_sensitive("<main>/_Orders/_Auto Settler",
+            can_unit_do_auto(punit) ||
+            (mission && (is_military_unit(punit) || worker)));
+    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) && !mission);
+    menus_set_sensitive("<main>/_Orders/Patrol (_Q)", !mission);
+    menus_set_sensitive("<main>/_Orders/Return to nearest city",
+            !(is_air_unit(punit) || is_heli_unit(punit)) && !mission);
+    menus_set_sensitive("<main>/_Orders/_Disband Unit",
+            !unit_flag(punit, F_UNDISBANDABLE));
+    menus_set_sensitive("<main>/_Orders/Diplomat|Spy Actions",
+            (is_diplomat_unit(punit) &&
+             diplomat_can_do_action(punit, DIPLOMAT_ANY_ACTION,
+             punit->x, punit->y)) && !mission);
+    menus_set_sensitive("<main>/_Orders/Explode Nuclear",
+            unit_flag(punit, F_NUCLEAR) && !mission);
+    menus_set_sensitive("<main>/_Orders/Go|Airlift to City", !mission);
+    menus_set_sensitive("<main>/_Orders/_Wait", !mission);
+    menus_set_sensitive("<main>/_Orders/Done", !mission);
+
+    /** Renaming Orders **/
+
+    /* Orders menu */
+    menus_rename("<main>/_Orders", mission ?
+                 _("Mission _Orders"):
+                 _("_Orders"));
+
+    /* Go to */
+    menus_rename("<main>/_Orders/_Go to", mission ?
+                 _("Add _Goto Waypoint"):
+                 _("_Go to"));
+
+    /* Build City / Wonder */
+    if (unit_flag(punit, F_HELP_WONDER)) {
+      buildtext = _("Help _Build Wonder");
+    }
+    else if (unit_flag(punit, F_CITIES) && !mission
+             && map_get_city(punit->x, punit->y)) {
+      buildtext = _("Add to City (_B)");
+    }
+    else {
+      buildtext = _("_Build City");
     }
+    menus_rename("<main>/_Orders/_Build City", buildtext);
 
-    if((punit=get_unit_in_focus())) {
-      char *irrfmt = _("Change to %s (_I)");
-      char *minfmt = _("Change to %s (_M)");
-      char *transfmt = _("Transf_orm to %s");
-      char irrtext[128], mintext[128], transtext[128];
-      char *roadtext;
-      enum tile_terrain_type  ttype;
-      struct tile_type *      tinfo;
-
-      sz_strlcpy(irrtext, _("Build _Irrigation"));
-      sz_strlcpy(mintext, _("Build _Mine"));
-      sz_strlcpy(transtext, _("Transf_orm Terrain"));
-      
-      /* Enable the button for adding to a city in all cases, so we
-        get an eventual error message from the server if we try. */
-      menus_set_sensitive("<main>/_Orders/_Build City",
-                         can_unit_add_or_build_city(punit) ||
-                         unit_can_help_build_wonder_here(punit));
-      menus_set_sensitive("<main>/_Orders/Build _Road",
-                          (can_unit_do_activity(punit, ACTIVITY_ROAD) ||
-                           can_unit_do_activity(punit, ACTIVITY_RAILROAD) ||
-                           unit_can_est_traderoute_here(punit)));
-      menus_set_sensitive("<main>/_Orders/Build _Irrigation",
-                          can_unit_do_activity(punit, ACTIVITY_IRRIGATE));
-      menus_set_sensitive("<main>/_Orders/Build _Mine",
-                          can_unit_do_activity(punit, ACTIVITY_MINE));
-      menus_set_sensitive("<main>/_Orders/Transf_orm Terrain",
-                         can_unit_do_activity(punit, ACTIVITY_TRANSFORM));
-      menus_set_sensitive("<main>/_Orders/Build _Fortress",
-                          (can_unit_do_activity(punit, ACTIVITY_FORTRESS) ||
-                           can_unit_do_activity(punit, ACTIVITY_FORTIFYING)));
-      menus_set_sensitive("<main>/_Orders/Build Airbas_e",
-                         can_unit_do_activity(punit, ACTIVITY_AIRBASE));
-      menus_set_sensitive("<main>/_Orders/Clean _Pollution",
-                          (can_unit_do_activity(punit, ACTIVITY_POLLUTION) ||
-                           can_unit_paradrop(punit)));
-      menus_set_sensitive("<main>/_Orders/Clean _Nuclear Fallout",
-                         can_unit_do_activity(punit, ACTIVITY_FALLOUT));
-      menus_set_sensitive("<main>/_Orders/_Sentry",
-                         can_unit_do_activity(punit, ACTIVITY_SENTRY));
-      menus_set_sensitive("<main>/_Orders/Pillage",
-                         can_unit_do_activity(punit, ACTIVITY_PILLAGE));
-      menus_set_sensitive("<main>/_Orders/Make _Homecity",
-                         can_unit_change_homecity(punit));
-      menus_set_sensitive("<main>/_Orders/_Unload",
-                         get_transporter_capacity(punit)>0);
-      menus_set_sensitive("<main>/_Orders/Wake up o_thers", 
-                         is_unit_activity_on_tile(ACTIVITY_SENTRY,
-                                                   punit->x, punit->y));
-      menus_set_sensitive("<main>/_Orders/_Auto Settler",
-                          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/Return to nearest city",
-                         !(is_air_unit(punit) || is_heli_unit(punit)));
-      menus_set_sensitive("<main>/_Orders/_Disband Unit",
-                          !unit_flag(punit, F_UNDISBANDABLE));
-      menus_set_sensitive("<main>/_Orders/Diplomat|Spy Actions",
-                          (is_diplomat_unit(punit)
-                           && diplomat_can_do_action(punit, 
DIPLOMAT_ANY_ACTION,
-                                                    punit->x, punit->y)));
-      menus_set_sensitive("<main>/_Orders/Explode Nuclear",
-                         unit_flag(punit, F_NUCLEAR));
-      if (unit_flag(punit, F_HELP_WONDER))
-       menus_rename("<main>/_Orders/_Build City", _("Help _Build Wonder"));
-      else if (unit_flag(punit, F_CITIES)) {
-       if (map_get_city(punit->x, punit->y))
-         menus_rename("<main>/_Orders/_Build City", _("Add to City (_B)"));
-       else
-         menus_rename("<main>/_Orders/_Build City", _("_Build City"));
-      }
-      else 
-       menus_rename("<main>/_Orders/_Build City", _("_Build City"));
- 
-      if (unit_flag(punit, F_TRADE_ROUTE))
-       menus_rename("<main>/_Orders/Build _Road", _("Make Trade _Route"));
-      else if (unit_flag(punit, F_SETTLERS)) {
-       if (map_has_special(punit->x, punit->y, S_ROAD)) {
-         roadtext = _("Build _Railroad");
-         road_activity=ACTIVITY_RAILROAD;  
-       } 
-       else {
-         roadtext = _("Build _Road");
-         road_activity=ACTIVITY_ROAD;  
-       }
-       menus_rename("<main>/_Orders/Build _Road", roadtext);
-      }
-      else
-       menus_rename("<main>/_Orders/Build _Road", _("Build _Road"));
+    /* Road / Traderoute */
+    if (unit_flag(punit, F_TRADE_ROUTE)) {
+      roadtext = _("Make Trade _Route");
+    }
+    else if (mission && worker) {
+      roadtext = _("Build _Road or Railroad");
+    }
+    else if (map_has_special(punit->x, punit->y, S_ROAD) && worker) {
+      roadtext = _("Build _Railroad");
+    }
+    else {
+      roadtext = _("Build _Road");
+    }
+    menus_rename("<main>/_Orders/Build _Road", roadtext);
+
+    /* Transform terrain */
+    ttype = map_get_tile(punit->x, punit->y)->terrain;
+    tinfo = get_tile_type(ttype);
+    sz_strlcpy(irrtext, _("Build _Irrigation"));
+    if (mission) {
+      /* Nothing. */
+    }
+    else if ((tinfo->irrigation_result != T_LAST) &&
+             (tinfo->irrigation_result != ttype)) {
+      my_snprintf (irrtext, sizeof(irrtext), irrfmt,
+          (get_tile_type(tinfo->irrigation_result))->terrain_name);
+    }
+    else if (map_has_special(punit->x, punit->y, S_IRRIGATION) &&
+             player_knows_techs_with_flag(game.player_ptr, TF_FARMLAND)) {
+      sz_strlcpy (irrtext, _("Bu_ild Farmland"));
+    }
+    menus_rename("<main>/_Orders/Build _Irrigation", irrtext);
 
-      ttype = map_get_tile(punit->x, punit->y)->terrain;
-      tinfo = get_tile_type(ttype);
-      if ((tinfo->irrigation_result != T_LAST) && (tinfo->irrigation_result != 
ttype))
-       {
-         my_snprintf (irrtext, sizeof(irrtext), irrfmt,
-                  (get_tile_type(tinfo->irrigation_result))->terrain_name);
-       }
-      else if (map_has_special(punit->x, punit->y, S_IRRIGATION) &&
-              player_knows_techs_with_flag(game.player_ptr, TF_FARMLAND))
-       {
-         sz_strlcpy (irrtext, _("Bu_ild Farmland"));
-       }
-      if ((tinfo->mining_result != T_LAST) && (tinfo->mining_result != ttype))
-       {
-         my_snprintf (mintext, sizeof(mintext), minfmt,
-                  (get_tile_type(tinfo->mining_result))->terrain_name);
-       }
-      if ((tinfo->transform_result != T_LAST) && (tinfo->transform_result != 
ttype))
-       {
-         my_snprintf (transtext, sizeof(transtext), transfmt,
-                  (get_tile_type(tinfo->transform_result))->terrain_name);
-       }
-
-      menus_rename("<main>/_Orders/Build _Irrigation", irrtext);
-      menus_rename("<main>/_Orders/Build _Mine", mintext);
-      menus_rename("<main>/_Orders/Transf_orm Terrain", transtext);
-
-      if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING))
-       menus_rename("<main>/_Orders/Build _Fortress", _("_Fortify"));
-      else
-       menus_rename("<main>/_Orders/Build _Fortress", _("Build _Fortress"));
-
-      if (unit_flag(punit, F_PARATROOPERS))
-       menus_rename("<main>/_Orders/Clean _Pollution", _("_Paradrop"));
-      else
-       menus_rename("<main>/_Orders/Clean _Pollution", _("Clean _Pollution"));
-
-      if (!unit_flag(punit, F_SETTLERS))
-       menus_rename("<main>/_Orders/_Auto Settler", _("_Auto Attack"));
-      else
-       menus_rename("<main>/_Orders/_Auto Settler", _("_Auto Settler"));
+    sz_strlcpy(mintext, _("Build _Mine"));
+    if ((tinfo->mining_result != T_LAST) &&
+        (tinfo->mining_result != ttype)  && !mission) {
+      my_snprintf (mintext, sizeof(mintext), minfmt,
+          (get_tile_type(tinfo->mining_result))->terrain_name);
+    }
+    menus_rename("<main>/_Orders/Build _Mine", mintext);
 
-      menus_set_sensitive("<main>/_Orders", TRUE);
+    sz_strlcpy(transtext, _("Transf_orm Terrain"));
+    if ((tinfo->transform_result != T_LAST) &&
+        (tinfo->transform_result != ttype) && !mission) {
+      my_snprintf (transtext, sizeof(transtext), transfmt,
+          (get_tile_type(tinfo->transform_result))->terrain_name);
     }
-    else
-      menus_set_sensitive("<main>/_Orders", FALSE);
+    menus_rename("<main>/_Orders/Transf_orm Terrain", transtext);
+
+    /* Fortify / Fortress */
+    menus_rename("<main>/_Orders/Build _Fortress", worker ?
+                 _("Build _Fortress"):
+                 _("_Fortify"));
+
+    /* Automate */
+    menus_rename("<main>/_Orders/_Auto Settler", worker ?
+                 _("_Auto Settler"):
+                 _("_Auto Attack"));
+
+    /* Paradrop / Pollution */
+    menus_rename("<main>/_Orders/Clean _Pollution",
+                 unit_flag(punit, F_PARATROOPERS) ?
+                 _("_Paradrop"):
+                 _("Clean _Pollution"));
+
+    menus_set_sensitive("<main>/_Orders", TRUE);
+  } else {
+    /* No focus unit. */
+    menus_set_sensitive("<main>/_Orders", FALSE);
   }
 }
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/gui_main.c,v
retrieving revision 1.64
diff -u -p -r1.64 gui_main.c
--- client/gui-gtk-2.0/gui_main.c       2004/01/24 02:58:55     1.64
+++ client/gui-gtk-2.0/gui_main.c       2004/01/28 13:26:43
@@ -1503,3 +1503,11 @@ void remove_net_input(void)
   gtk_input_remove(input_id);
   gdk_window_set_cursor(root_window, NULL);
 }
+
+/**************************************************************************
+...
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return TRUE;
+}
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.26
diff -u -p -r1.26 menu.c
--- client/gui-gtk-2.0/menu.c   2004/01/20 21:52:07     1.26
+++ client/gui-gtk-2.0/menu.c   2004/01/28 13:26:55
@@ -57,7 +57,6 @@
 
 static GtkItemFactory *item_factory = NULL;
 GtkAccelGroup *toplevel_accel = NULL;
-static enum unit_activity road_activity;
 
 static void menus_rename(const char *path, char *s);
 
@@ -312,116 +311,105 @@ static void view_menu_callback(gpointer 
 
 
 /****************************************************************
-...
+ Validity checking of the order for the unit is done in
+ control.c, sometimes in server. Here we only need check flags.
 *****************************************************************/
 static void orders_menu_callback(gpointer callback_data,
                                 guint callback_action, GtkWidget *widget)
 {
+  struct unit *punit = get_unit_in_focus();
+
+  if (!punit) {
+    return;
+  }
+
   switch(callback_action) {
-   case MENU_ORDER_BUILD_CITY:
-    if (get_unit_in_focus()) {
-      struct unit *punit = get_unit_in_focus();
-      /* Enable the button for adding to a city in all cases, so we
-        get an eventual error message from the server if we try. */
-      if (can_unit_add_or_build_city(punit)) {
-       key_unit_build_city();
-      } else {
-       key_unit_build_wonder();
-      }
-    }
-    break;
-   case MENU_ORDER_ROAD:
-    if (get_unit_in_focus()) {
-      if (unit_can_est_traderoute_here(get_unit_in_focus()))
-       key_unit_traderoute();
-      else
-       key_unit_road();
-    }
+  case MENU_ORDER_BUILD_CITY:
+    unit_flag(punit, F_CITIES) ?
+    key_unit_build_city():
+    key_unit_build_wonder();
+    break;
+  case MENU_ORDER_ROAD:
+    unit_flag(punit, F_TRADE_ROUTE) ?
+    key_unit_traderoute():
+    key_unit_road();
     break;
-   case MENU_ORDER_IRRIGATE:
+  case MENU_ORDER_IRRIGATE:
     key_unit_irrigate();
     break;
-   case MENU_ORDER_MINE:
+  case MENU_ORDER_MINE:
     key_unit_mine();
     break;
-   case MENU_ORDER_TRANSFORM:
+  case MENU_ORDER_TRANSFORM:
     key_unit_transform();
     break;
-   case MENU_ORDER_FORTRESS:
-    if (get_unit_in_focus()) {
-      if (can_unit_do_activity(get_unit_in_focus(), ACTIVITY_FORTRESS))
-       key_unit_fortress();
-      else
-       key_unit_fortify();
-    }
+  case MENU_ORDER_FORTRESS:
+    unit_flag(punit, F_SETTLERS) ?
+    key_unit_fortress():
+    key_unit_fortify();
     break;
-   case MENU_ORDER_AIRBASE:
+  case MENU_ORDER_AIRBASE:
     key_unit_airbase(); 
     break;
-   case MENU_ORDER_POLLUTION:
-    if (get_unit_in_focus()) {
-      if (can_unit_paradrop(get_unit_in_focus()))
-       key_unit_paradrop();
-      else
-       key_unit_pollution();
-    }
+  case MENU_ORDER_POLLUTION:
+    unit_flag(punit, F_PARATROOPERS) ?
+    key_unit_paradrop():
+    key_unit_pollution();
     break;
-   case MENU_ORDER_FALLOUT:
+  case MENU_ORDER_FALLOUT:
     key_unit_fallout();
     break;
-   case MENU_ORDER_SENTRY:
+  case MENU_ORDER_SENTRY:
     key_unit_sentry();
     break;
-   case MENU_ORDER_PILLAGE:
+  case MENU_ORDER_PILLAGE:
     key_unit_pillage();
     break;
-   case MENU_ORDER_HOMECITY:
+  case MENU_ORDER_HOMECITY:
     key_unit_homecity();
     break;
-   case MENU_ORDER_UNLOAD:
+  case MENU_ORDER_UNLOAD:
     key_unit_unload();
     break;
-   case MENU_ORDER_WAKEUP_OTHERS:
+  case MENU_ORDER_WAKEUP_OTHERS:
     key_unit_wakeup_others();
     break;
-   case MENU_ORDER_AUTO_SETTLER:
-    if(get_unit_in_focus())
-      request_unit_auto(get_unit_in_focus());
+  case MENU_ORDER_AUTO_SETTLER:
+    unit_flag(punit, F_SETTLERS) ?
+    key_unit_auto_settle():
+    key_unit_auto_attack();
     break;
-   case MENU_ORDER_AUTO_EXPLORE:
+  case MENU_ORDER_AUTO_EXPLORE:
     key_unit_auto_explore();
     break;
-   case MENU_ORDER_CONNECT:
+  case MENU_ORDER_CONNECT:
     key_unit_connect();
     break;
-   case MENU_ORDER_PATROL:
+  case MENU_ORDER_PATROL:
     key_unit_patrol();
     break;
-   case MENU_ORDER_GOTO:
+  case MENU_ORDER_GOTO:
     key_unit_goto();
     break;
-   case MENU_ORDER_GOTO_CITY:
-    if(get_unit_in_focus())
-      popup_goto_dialog();
-    break;
-   case MENU_ORDER_RETURN:
-    if (get_unit_in_focus()) {
-      request_unit_return(get_unit_in_focus());
-    }
+  case MENU_ORDER_GOTO_CITY:
+    popup_goto_dialog();
     break;
-   case MENU_ORDER_DISBAND:
+  case MENU_ORDER_RETURN:
+    key_unit_return();
+    break;
+  case MENU_ORDER_DISBAND:
     key_unit_disband();
     break;
-   case MENU_ORDER_DIPLOMAT_DLG:
+  case MENU_ORDER_DIPLOMAT_DLG:
     key_unit_diplomat_actions();
     break;
-   case MENU_ORDER_NUKE:
+  case MENU_ORDER_NUKE:
     key_unit_nuke();
     break;
-   case MENU_ORDER_WAIT:
+  case MENU_ORDER_WAIT:
     key_unit_wait();
     break;
-   case MENU_ORDER_DONE:
+  case MENU_ORDER_DONE:
     key_unit_done();
     break;
   }
@@ -666,6 +654,33 @@ static GtkItemFactoryEntry menu_items[]    
        NULL,                   0,                                      
"<Separator>"   },
   { "/" N_("View") "/" N_("_Center View"),             "c",
        view_menu_callback,     MENU_VIEW_CENTER_VIEW                           
        },
+  /* Reports menu ... */
+  { "/" N_("_Reports"),                                        NULL,
+       NULL,                   0,                                      
"<Branch>"      },
+  { "/" N_("Reports") "/tearoff1",                     NULL,
+       NULL,                   0,                                      
"<Tearoff>"     },
+  { "/" N_("Reports") "/" N_("_Cities"),               "F1",
+       reports_menu_callback,  MENU_REPORT_CITIES                              
        },
+  { "/" N_("Reports") "/" N_("_Units"),                        "F2",
+       reports_menu_callback,  MENU_REPORT_UNITS                               
        },
+  { "/" N_("Reports") "/" N_("_Players"),              "F3",
+       reports_menu_callback,  MENU_REPORT_PLAYERS                             
        },
+  { "/" N_("Reports") "/" N_("_Economy"),              "F5",
+       reports_menu_callback,  MENU_REPORT_ECONOMY                             
        },
+  { "/" N_("Reports") "/" N_("_Science"),              "F6",
+       reports_menu_callback,  MENU_REPORT_SCIENCE                             
        },
+  { "/" N_("Reports") "/sep1",                         NULL,
+       NULL,                   0,                                      
"<Separator>"   },
+  { "/" N_("Reports") "/" N_("_Wonders of the World"), "F7",
+       reports_menu_callback,  MENU_REPORT_WOW                                 
        },
+  { "/" N_("Reports") "/" N_("_Top Five Cities"),      "F8",
+       reports_menu_callback,  MENU_REPORT_TOP_CITIES                          
        },
+  { "/" N_("Reports") "/" N_("_Messages"),             "F9",
+       reports_menu_callback,  MENU_REPORT_MESSAGES                            
        },
+  { "/" N_("Reports") "/" N_("_Demographics"),         "F11",
+       reports_menu_callback,  MENU_REPORT_DEMOGRAPHIC                         
        },
+  { "/" N_("Reports") "/" N_("S_paceship"),            "F12",
+       reports_menu_callback,  MENU_REPORT_SPACESHIP                           
        },
   /* Orders menu ... */
   { "/" N_("_Orders"),                                 NULL,
        NULL,                   0,                                      
"<Branch>"      },
@@ -733,36 +748,9 @@ static GtkItemFactoryEntry menu_items[]    
        orders_menu_callback,   MENU_ORDER_WAIT                                 
        },
   { "/" N_("Orders") "/" N_("Done"),                   "space",
        orders_menu_callback,   MENU_ORDER_DONE                                 
        },
-  /* Reports menu ... */
-  { "/" N_("_Reports"),                                        NULL,
-       NULL,                   0,                                      
"<Branch>"      },
-  { "/" N_("Reports") "/tearoff1",                     NULL,
-       NULL,                   0,                                      
"<Tearoff>"     },
-  { "/" N_("Reports") "/" N_("_Cities"),               "F1",
-       reports_menu_callback,  MENU_REPORT_CITIES                              
        },
-  { "/" N_("Reports") "/" N_("_Units"),                        "F2",
-       reports_menu_callback,  MENU_REPORT_UNITS                               
        },
-  { "/" N_("Reports") "/" N_("_Players"),              "F3",
-       reports_menu_callback,  MENU_REPORT_PLAYERS                             
        },
-  { "/" N_("Reports") "/" N_("_Economy"),              "F5",
-       reports_menu_callback,  MENU_REPORT_ECONOMY                             
        },
-  { "/" N_("Reports") "/" N_("_Science"),              "F6",
-       reports_menu_callback,  MENU_REPORT_SCIENCE                             
        },
-  { "/" N_("Reports") "/sep1",                         NULL,
-       NULL,                   0,                                      
"<Separator>"   },
-  { "/" N_("Reports") "/" N_("_Wonders of the World"), "F7",
-       reports_menu_callback,  MENU_REPORT_WOW                                 
        },
-  { "/" N_("Reports") "/" N_("_Top Five Cities"),      "F8",
-       reports_menu_callback,  MENU_REPORT_TOP_CITIES                          
        },
-  { "/" N_("Reports") "/" N_("_Messages"),             "F9",
-       reports_menu_callback,  MENU_REPORT_MESSAGES                            
        },
-  { "/" N_("Reports") "/" N_("_Demographics"),         "F11",
-       reports_menu_callback,  MENU_REPORT_DEMOGRAPHIC                         
        },
-  { "/" N_("Reports") "/" N_("S_paceship"),            "F12",
-       reports_menu_callback,  MENU_REPORT_SPACESHIP                           
        },
   /* Help menu ... */
   { "/" N_("_Help"),                                   NULL,
-       NULL,                   0,                                      
"<Branch>"      },
+       NULL,                   0,                                      
"<LastBranch>"  },
   { "/" N_("Help") "/tearoff1",                                NULL,
        NULL,                   0,                                      
"<Tearoff>"     },
   { "/" N_("Help") "/" N_("Language_s"),               NULL,
@@ -1016,245 +1004,312 @@ static void government_callback(GtkMenuI
 }
 
 /****************************************************************
-Note: the menu strings should contain underscores as in the
-menu_items struct. The underscores will be removed elsewhere if
-the string is used for a lookup via gtk_item_factory_get_widget()
+  Note: the menu strings should contain underscores as in the
+  menu_items struct. The underscores will be removed elsewhere
+  if the string is used for a lookup via
+  gtk_item_factory_get_widget().
+
+  To maintain this large function in gui GTK 1 and GTK 2, it is
+  worth noting that there are 3 differences between them:
+
+  1. The Governments menu stuff.
+  2. The spelling of item Diplomat / Spy Actions.
+  3. The spelling of item Go / Airlift to City.
+
+  The rest should be copy/paste.
 *****************************************************************/
 void update_menus(void)
 {
+  const char *path;
+  GtkWidget *parent;
+  struct unit *punit;
+
   if (!can_client_change_view()) {
     menus_set_sensitive("<main>/_Reports", FALSE);
     menus_set_sensitive("<main>/_Kingdom", FALSE);
     menus_set_sensitive("<main>/_View", FALSE);
     menus_set_sensitive("<main>/_Orders", FALSE);
-  } else {
-    struct unit *punit;
-    const char *path =
-      menu_path_remove_uline("<main>/_Kingdom/_Government");
-    GtkWidget *parent = gtk_item_factory_get_widget(item_factory, path);
-
-    if (parent) {
-      int i;
-      GList *list, *iter, *iter_next;
-
-      /* remove previous government entries. */
-      list = gtk_container_get_children(GTK_CONTAINER(parent));
-      for (iter = g_list_nth(list, 2); iter; iter = iter_next) {
-       iter_next = iter->next;
-       gtk_widget_destroy(GTK_WIDGET(iter->data));
-      }
-      g_list_free(list);
+    return;
+  }
+
+  /** Governments menu stuff **/
 
-      /* add new government entries. */
-      for (i = 0; i < game.government_count; ++i) {
-        struct government *g = &governments[i];
+  path = menu_path_remove_uline("<main>/_Kingdom/_Government");
+  parent = gtk_item_factory_get_widget(item_factory, path);
 
-        if (i != game.government_when_anarchy) {
-          GtkWidget *item, *image;
-          struct Sprite *gsprite;
+  if (parent) {
+    int i;
+    GList *list, *iter, *iter_next;
+
+    /* remove previous government entries. */
+    list = gtk_container_get_children(GTK_CONTAINER(parent));
+    for (iter = g_list_nth(list, 2); iter; iter = iter_next) {
+      iter_next = iter->next;
+      gtk_widget_destroy(GTK_WIDGET(iter->data));
+    }
+    g_list_free(list);
 
-          item = gtk_image_menu_item_new_with_label(g->name);
+    /* add new government entries. */
+    for (i = 0; i < game.government_count; ++i) {
+      struct government *g = &governments[i];
 
-          gsprite = get_government(g->index)->sprite;
-          image = gtk_image_new_from_pixmap(gsprite->pixmap, gsprite->mask);
-          gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
+      if (i != game.government_when_anarchy) {
+        GtkWidget *item, *image;
+        struct Sprite *gsprite;
 
-          gtk_widget_show(image);
-          gtk_widget_show(item);
+        item = gtk_image_menu_item_new_with_label(g->name);
 
-          g_signal_connect(item, "activate",
-            G_CALLBACK(government_callback), GINT_TO_POINTER(g->index));
+        gsprite = get_government(g->index)->sprite;
+        image = gtk_image_new_from_pixmap(gsprite->pixmap, gsprite->mask);
+        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
 
-          if (!can_change_to_government(game.player_ptr, i)) {
-            gtk_widget_set_sensitive(item, FALSE);
-         }
+        gtk_widget_show(image);
+        gtk_widget_show(item);
 
-          gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
-          gtk_widget_show(item);
+        g_signal_connect(item, "activate",
+          G_CALLBACK(government_callback), GINT_TO_POINTER(g->index));
+
+        if (!can_change_to_government(game.player_ptr, i)) {
+          gtk_widget_set_sensitive(item, FALSE);
         }
+
+        gtk_menu_shell_append(GTK_MENU_SHELL(parent), item);
+        gtk_widget_show(item);
       }
     }
+  }
+
+  /** End of Governments menu stuff **/
 
-    menus_set_sensitive("<main>/_Reports", TRUE);
-    menus_set_sensitive("<main>/_Kingdom", TRUE);
-    menus_set_sensitive("<main>/_View", TRUE);
-    menus_set_sensitive("<main>/_Orders", can_client_issue_orders());
-
-    menus_set_sensitive("<main>/_Kingdom/_Tax Rates",
-                       can_client_issue_orders());
-    menus_set_sensitive("<main>/_Kingdom/Work_lists",
-                       can_client_issue_orders());
-    menus_set_sensitive("<main>/_Kingdom/_Government",
-                       can_client_issue_orders());
-
-    menus_set_sensitive("<main>/_Reports/S_paceship",
-                       (game.player_ptr->spaceship.state!=SSHIP_NONE));
-
-    menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
-    menus_set_sensitive("<main>/_View/National _Borders", game.borders > 0);
-    menus_set_active("<main>/_View/National _Borders", draw_borders);
-    menus_set_active("<main>/_View/City _Names", draw_city_names);
-    menus_set_sensitive("<main>/_View/City G_rowth", draw_city_names);
-    menus_set_active("<main>/_View/City G_rowth", draw_city_growth);
-    menus_set_active("<main>/_View/City _Productions", draw_city_productions);
-    menus_set_active("<main>/_View/Terrain", draw_terrain);
-    menus_set_active("<main>/_View/Coastline", draw_coastline);
-    menus_set_sensitive("<main>/_View/Coastline", !draw_terrain);
-    menus_set_active("<main>/_View/Improvements/Roads & Rails", 
draw_roads_rails);
-    menus_set_active("<main>/_View/Improvements/Irrigation", draw_irrigation);
-    menus_set_active("<main>/_View/Improvements/Mines", draw_mines);
-    menus_set_active("<main>/_View/Improvements/Fortress & Airbase", 
draw_fortress_airbase);
-    menus_set_active("<main>/_View/Specials", draw_specials);
-    menus_set_active("<main>/_View/Pollution & Fallout", draw_pollution);
-    menus_set_active("<main>/_View/Cities", draw_cities);
-    menus_set_active("<main>/_View/Units", draw_units);
-    menus_set_active("<main>/_View/Focus Unit", draw_focus_unit);
-    menus_set_sensitive("<main>/_View/Focus Unit", !draw_units);
-    menus_set_active("<main>/_View/Fog of War", draw_fog_of_war);
+  menus_set_sensitive("<main>/_Reports", TRUE);
+  menus_set_sensitive("<main>/_Kingdom", TRUE);
+  menus_set_sensitive("<main>/_View", TRUE);
+  menus_set_sensitive("<main>/_Orders", can_client_issue_orders());
+
+  menus_set_sensitive("<main>/_Kingdom/_Tax Rates",
+                      can_client_issue_orders());
+  menus_set_sensitive("<main>/_Kingdom/Work_lists",
+                      can_client_issue_orders());
+  menus_set_sensitive("<main>/_Kingdom/_Government",
+                      can_client_issue_orders());
+
+  menus_set_sensitive("<main>/_Reports/S_paceship",
+                      (game.player_ptr->spaceship.state != SSHIP_NONE));
+
+  menus_set_active("<main>/_View/Map _Grid", draw_map_grid);
+  menus_set_sensitive("<main>/_View/National _Borders", game.borders > 0);
+  menus_set_active("<main>/_View/National _Borders", draw_borders);
+  menus_set_active("<main>/_View/City _Names", draw_city_names);
+  menus_set_sensitive("<main>/_View/City G_rowth", draw_city_names);
+  menus_set_active("<main>/_View/City G_rowth", draw_city_growth);
+  menus_set_active("<main>/_View/City _Productions", draw_city_productions);
+  menus_set_active("<main>/_View/Terrain", draw_terrain);
+  menus_set_active("<main>/_View/Coastline", draw_coastline);
+  menus_set_sensitive("<main>/_View/Coastline", !draw_terrain);
+  menus_set_active("<main>/_View/Improvements/Roads & Rails",
+                   draw_roads_rails);
+  menus_set_active("<main>/_View/Improvements/Irrigation", draw_irrigation);
+  menus_set_active("<main>/_View/Improvements/Mines", draw_mines);
+  menus_set_active("<main>/_View/Improvements/Fortress & Airbase",
+                   draw_fortress_airbase);
+  menus_set_active("<main>/_View/Specials", draw_specials);
+  menus_set_active("<main>/_View/Pollution & Fallout", draw_pollution);
+  menus_set_active("<main>/_View/Cities", draw_cities);
+  menus_set_active("<main>/_View/Units", draw_units);
+  menus_set_active("<main>/_View/Focus Unit", draw_focus_unit);
+  menus_set_sensitive("<main>/_View/Focus Unit", !draw_units);
+  menus_set_active("<main>/_View/Fog of War", draw_fog_of_war);
 
-    /* Remaining part of this function: Update Orders menu */
+  /* Remaining part of this function: Update Orders menu */
+
+  if (!can_client_issue_orders()) {
+    return;
+  }
 
-    if (!can_client_issue_orders()) {
-      return;
+  punit = get_unit_in_focus();
+
+  if (punit) {
+    char *irrfmt = _("Change to %s (_I)");
+    char *minfmt = _("Change to %s (_M)");
+    char *transfmt = _("Transf_orm to %s");
+    char irrtext[128], mintext[128], transtext[128];
+    char *roadtext, *buildtext;
+    enum tile_terrain_type  ttype;
+    struct tile_type *      tinfo;
+
+    /* For readability. */
+    const bool worker  = unit_flag(punit, F_SETTLERS);
+    const bool mission = hover_state == HOVER_GOTO;
+
+    /* When hover state is goto, enable (only) all possible Mission
+     * Orders. The validity of the order is checked after the unit
+     * has arrived. The server may then send appropriate error
+     * message for that tile. I guess it's debatable whether the
+     * client should deny requests for Mission Orders that are
+     * illegal for the destination tile at the time of the start of
+     * the goto.  --ali.
+     */
+    menus_set_sensitive("<main>/_Orders/_Build City",
+            (unit_flag(punit, F_CITIES) ||
+             unit_can_help_build_wonder_here(punit) ||
+             (mission && unit_flag(punit, F_HELP_WONDER))));
+    menus_set_sensitive("<main>/_Orders/Build _Road",
+            (can_unit_do_activity(punit, ACTIVITY_ROAD) ||
+             can_unit_do_activity(punit, ACTIVITY_RAILROAD) ||
+             unit_can_est_traderoute_here(punit)) ||
+             (mission && (worker || unit_flag(punit, F_TRADE_ROUTE))));
+    menus_set_sensitive("<main>/_Orders/Build _Irrigation",
+            can_unit_do_activity(punit, ACTIVITY_IRRIGATE) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Build _Mine",
+            can_unit_do_activity(punit, ACTIVITY_MINE) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Transf_orm Terrain",
+            can_unit_do_activity(punit, ACTIVITY_TRANSFORM) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Build _Fortress",
+            (can_unit_do_activity(punit, ACTIVITY_FORTRESS) ||
+             can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) ||
+             (mission && is_ground_unit(punit) && (!worker ||
+              player_knows_techs_with_flag(game.player_ptr, TF_FORTRESS))));
+    menus_set_sensitive("<main>/_Orders/Build Airbas_e",
+            can_unit_do_activity(punit, ACTIVITY_AIRBASE) ||
+            (mission && unit_flag(punit, F_AIRBASE) &&
+             player_knows_techs_with_flag(game.player_ptr, TF_AIRBASE)));
+    menus_set_sensitive("<main>/_Orders/Clean _Pollution",
+             (can_unit_do_activity(punit, ACTIVITY_POLLUTION) ||
+              can_unit_paradrop(punit)) ||
+              (mission && worker));
+    menus_set_sensitive("<main>/_Orders/Clean _Nuclear Fallout",
+            can_unit_do_activity(punit, ACTIVITY_FALLOUT) ||
+            (mission && worker));
+    menus_set_sensitive("<main>/_Orders/_Sentry",
+            can_unit_do_activity(punit, ACTIVITY_SENTRY) || mission);
+    menus_set_sensitive("<main>/_Orders/Pillage",
+            can_unit_do_activity(punit, ACTIVITY_PILLAGE) ||
+            (mission && is_ground_unit(punit)));
+    menus_set_sensitive("<main>/_Orders/Make _Homecity",
+            can_unit_change_homecity(punit) || mission);
+    menus_set_sensitive("<main>/_Orders/_Unload",
+            get_transporter_capacity(punit)>0);
+    menus_set_sensitive("<main>/_Orders/Wake up o_thers", 
+            is_unit_activity_on_tile(ACTIVITY_SENTRY,
+            punit->x, punit->y) && !mission);
+    menus_set_sensitive("<main>/_Orders/_Auto Settler",
+            can_unit_do_auto(punit) ||
+            (mission && (is_military_unit(punit) || worker)));
+    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) && !mission);
+    menus_set_sensitive("<main>/_Orders/Patrol (_Q)", !mission);
+    menus_set_sensitive("<main>/_Orders/Return to nearest city",
+            !(is_air_unit(punit) || is_heli_unit(punit)) && !mission);
+    menus_set_sensitive("<main>/_Orders/_Disband Unit",
+            !unit_flag(punit, F_UNDISBANDABLE));
+    menus_set_sensitive("<main>/_Orders/Diplomat\\/Spy Actions",
+            (is_diplomat_unit(punit) &&
+             diplomat_can_do_action(punit, DIPLOMAT_ANY_ACTION,
+             punit->x, punit->y)) && !mission);
+    menus_set_sensitive("<main>/_Orders/Explode Nuclear",
+            unit_flag(punit, F_NUCLEAR) && !mission);
+    menus_set_sensitive("<main>/_Orders/Go\\/Airlift to City", !mission);
+    menus_set_sensitive("<main>/_Orders/_Wait", !mission);
+    menus_set_sensitive("<main>/_Orders/Done", !mission);
+
+    /** Renaming Orders **/
+
+    /* Orders menu */
+    menus_rename("<main>/_Orders", mission ?
+                 _("Mission _Orders"):
+                 _("_Orders"));
+
+    /* Go to */
+    menus_rename("<main>/_Orders/_Go to", mission ?
+                 _("Add _Goto Waypoint"):
+                 _("_Go to"));
+
+    /* Build City / Wonder */
+    if (unit_flag(punit, F_HELP_WONDER)) {
+      buildtext = _("Help _Build Wonder");
+    }
+    else if (unit_flag(punit, F_CITIES) && !mission
+             && map_get_city(punit->x, punit->y)) {
+      buildtext = _("Add to City (_B)");
+    }
+    else {
+      buildtext = _("_Build City");
     }
+    menus_rename("<main>/_Orders/_Build City", buildtext);
 
-    if((punit=get_unit_in_focus())) {
-      char *irrfmt = _("Change to %s (_I)");
-      char *minfmt = _("Change to %s (_M)");
-      char *transfmt = _("Transf_orm to %s");
-      char irrtext[128], mintext[128], transtext[128];
-      char *roadtext;
-      enum tile_terrain_type  ttype;
-      struct tile_type *      tinfo;
-
-      sz_strlcpy(irrtext, _("Build _Irrigation"));
-      sz_strlcpy(mintext, _("Build _Mine"));
-      sz_strlcpy(transtext, _("Transf_orm Terrain"));
-      
-      /* Enable the button for adding to a city in all cases, so we
-        get an eventual error message from the server if we try. */
-      menus_set_sensitive("<main>/_Orders/_Build City",
-                         can_unit_add_or_build_city(punit) ||
-                         unit_can_help_build_wonder_here(punit));
-      menus_set_sensitive("<main>/_Orders/Build _Road",
-                          (can_unit_do_activity(punit, ACTIVITY_ROAD) ||
-                           can_unit_do_activity(punit, ACTIVITY_RAILROAD) ||
-                           unit_can_est_traderoute_here(punit)));
-      menus_set_sensitive("<main>/_Orders/Build _Irrigation",
-                          can_unit_do_activity(punit, ACTIVITY_IRRIGATE));
-      menus_set_sensitive("<main>/_Orders/Build _Mine",
-                          can_unit_do_activity(punit, ACTIVITY_MINE));
-      menus_set_sensitive("<main>/_Orders/Transf_orm Terrain",
-                         can_unit_do_activity(punit, ACTIVITY_TRANSFORM));
-      menus_set_sensitive("<main>/_Orders/Build _Fortress",
-                          (can_unit_do_activity(punit, ACTIVITY_FORTRESS) ||
-                           can_unit_do_activity(punit, ACTIVITY_FORTIFYING)));
-      menus_set_sensitive("<main>/_Orders/Build Airbas_e",
-                         can_unit_do_activity(punit, ACTIVITY_AIRBASE));
-      menus_set_sensitive("<main>/_Orders/Clean _Pollution",
-                          (can_unit_do_activity(punit, ACTIVITY_POLLUTION) ||
-                           can_unit_paradrop(punit)));
-      menus_set_sensitive("<main>/_Orders/Clean _Nuclear Fallout",
-                         can_unit_do_activity(punit, ACTIVITY_FALLOUT));
-      menus_set_sensitive("<main>/_Orders/_Sentry",
-                         can_unit_do_activity(punit, ACTIVITY_SENTRY));
-      menus_set_sensitive("<main>/_Orders/Pillage",
-                         can_unit_do_activity(punit, ACTIVITY_PILLAGE));
-      menus_set_sensitive("<main>/_Orders/_Disband Unit",
-                         !unit_flag(punit, F_UNDISBANDABLE));
-      menus_set_sensitive("<main>/_Orders/Make _Homecity",
-                         can_unit_change_homecity(punit));
-      menus_set_sensitive("<main>/_Orders/_Unload",
-                         get_transporter_capacity(punit)>0);
-      menus_set_sensitive("<main>/_Orders/Wake up o_thers", 
-                         is_unit_activity_on_tile(ACTIVITY_SENTRY,
-                                                   punit->x, punit->y));
-      menus_set_sensitive("<main>/_Orders/_Auto Settler",
-                          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/Return to nearest city",
-                         !(is_air_unit(punit) || is_heli_unit(punit)));
-      menus_set_sensitive("<main>/_Orders/Diplomat\\/Spy Actions",
-                          (is_diplomat_unit(punit)
-                           && diplomat_can_do_action(punit, 
DIPLOMAT_ANY_ACTION,
-                                                    punit->x, punit->y)));
-      menus_set_sensitive("<main>/_Orders/Explode Nuclear",
-                         unit_flag(punit, F_NUCLEAR));
-      if (unit_flag(punit, F_HELP_WONDER))
-       menus_rename("<main>/_Orders/_Build City", _("Help _Build Wonder"));
-      else if (unit_flag(punit, F_CITIES)) {
-       if (map_get_city(punit->x, punit->y))
-         menus_rename("<main>/_Orders/_Build City", _("Add to City (_B)"));
-       else
-         menus_rename("<main>/_Orders/_Build City", _("_Build City"));
-      }
-      else 
-       menus_rename("<main>/_Orders/_Build City", _("_Build City"));
- 
-      if (unit_flag(punit, F_TRADE_ROUTE))
-       menus_rename("<main>/_Orders/Build _Road", _("Make Trade _Route"));
-      else if (unit_flag(punit, F_SETTLERS)) {
-       if (map_has_special(punit->x, punit->y, S_ROAD)) {
-         roadtext = _("Build _Railroad");
-         road_activity=ACTIVITY_RAILROAD;  
-       } 
-       else {
-         roadtext = _("Build _Road");
-         road_activity=ACTIVITY_ROAD;  
-       }
-       menus_rename("<main>/_Orders/Build _Road", roadtext);
-      }
-      else
-       menus_rename("<main>/_Orders/Build _Road", _("Build _Road"));
+    /* Road / Traderoute */
+    if (unit_flag(punit, F_TRADE_ROUTE)) {
+      roadtext = _("Make Trade _Route");
+    }
+    else if (mission && worker) {
+      roadtext = _("Build _Road or Railroad");
+    }
+    else if (map_has_special(punit->x, punit->y, S_ROAD) && worker) {
+      roadtext = _("Build _Railroad");
+    }
+    else {
+      roadtext = _("Build _Road");
+    }
+    menus_rename("<main>/_Orders/Build _Road", roadtext);
+
+    /* Transform terrain */
+    ttype = map_get_tile(punit->x, punit->y)->terrain;
+    tinfo = get_tile_type(ttype);
+    sz_strlcpy(irrtext, _("Build _Irrigation"));
+    if (mission) {
+      /* Nothing. */
+    }
+    else if ((tinfo->irrigation_result != T_LAST) &&
+             (tinfo->irrigation_result != ttype)) {
+      my_snprintf (irrtext, sizeof(irrtext), irrfmt,
+          (get_tile_type(tinfo->irrigation_result))->terrain_name);
+    }
+    else if (map_has_special(punit->x, punit->y, S_IRRIGATION) &&
+             player_knows_techs_with_flag(game.player_ptr, TF_FARMLAND)) {
+      sz_strlcpy (irrtext, _("Bu_ild Farmland"));
+    }
+    menus_rename("<main>/_Orders/Build _Irrigation", irrtext);
 
-      ttype = map_get_tile(punit->x, punit->y)->terrain;
-      tinfo = get_tile_type(ttype);
-      if ((tinfo->irrigation_result != T_LAST) && (tinfo->irrigation_result != 
ttype))
-       {
-         my_snprintf (irrtext, sizeof(irrtext), irrfmt,
-                  (get_tile_type(tinfo->irrigation_result))->terrain_name);
-       }
-      else if (map_has_special(punit->x, punit->y, S_IRRIGATION) &&
-              player_knows_techs_with_flag(game.player_ptr, TF_FARMLAND))
-       {
-         sz_strlcpy (irrtext, _("Bu_ild Farmland"));
-       }
-      if ((tinfo->mining_result != T_LAST) && (tinfo->mining_result != ttype))
-       {
-         my_snprintf (mintext, sizeof(mintext), minfmt,
-                  (get_tile_type(tinfo->mining_result))->terrain_name);
-       }
-      if ((tinfo->transform_result != T_LAST) && (tinfo->transform_result != 
ttype))
-       {
-         my_snprintf (transtext, sizeof(transtext), transfmt,
-                  (get_tile_type(tinfo->transform_result))->terrain_name);
-       }
-
-      menus_rename("<main>/_Orders/Build _Irrigation", irrtext);
-      menus_rename("<main>/_Orders/Build _Mine", mintext);
-      menus_rename("<main>/_Orders/Transf_orm Terrain", transtext);
-
-      if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING))
-       menus_rename("<main>/_Orders/Build _Fortress", _("_Fortify"));
-      else
-       menus_rename("<main>/_Orders/Build _Fortress", _("Build _Fortress"));
-
-      if (unit_flag(punit, F_PARATROOPERS))
-       menus_rename("<main>/_Orders/Clean _Pollution", _("_Paradrop"));
-      else
-       menus_rename("<main>/_Orders/Clean _Pollution", _("Clean _Pollution"));
-
-      if (!unit_flag(punit, F_SETTLERS))
-       menus_rename("<main>/_Orders/_Auto Settler", _("_Auto Attack"));
-      else
-       menus_rename("<main>/_Orders/_Auto Settler", _("_Auto Settler"));
+    sz_strlcpy(mintext, _("Build _Mine"));
+    if ((tinfo->mining_result != T_LAST) &&
+        (tinfo->mining_result != ttype)  && !mission) {
+      my_snprintf (mintext, sizeof(mintext), minfmt,
+          (get_tile_type(tinfo->mining_result))->terrain_name);
+    }
+    menus_rename("<main>/_Orders/Build _Mine", mintext);
 
-      menus_set_sensitive("<main>/_Orders", TRUE);
+    sz_strlcpy(transtext, _("Transf_orm Terrain"));
+    if ((tinfo->transform_result != T_LAST) &&
+        (tinfo->transform_result != ttype) && !mission) {
+      my_snprintf (transtext, sizeof(transtext), transfmt,
+          (get_tile_type(tinfo->transform_result))->terrain_name);
     }
-    else
-      menus_set_sensitive("<main>/_Orders", FALSE);
+    menus_rename("<main>/_Orders/Transf_orm Terrain", transtext);
+
+    /* Fortify / Fortress */
+    menus_rename("<main>/_Orders/Build _Fortress", worker ?
+                 _("Build _Fortress"):
+                 _("_Fortify"));
+
+    /* Automate */
+    menus_rename("<main>/_Orders/_Auto Settler", worker ?
+                 _("_Auto Settler"):
+                 _("_Auto Attack"));
+
+    /* Paradrop / Pollution */
+    menus_rename("<main>/_Orders/Clean _Pollution",
+                 unit_flag(punit, F_PARATROOPERS) ?
+                 _("_Paradrop"):
+                 _("Clean _Pollution"));
+
+    menus_set_sensitive("<main>/_Orders", TRUE);
+  } else {
+    /* No focus unit. */
+    menus_set_sensitive("<main>/_Orders", FALSE);
   }
 }
Index: client/gui-mui/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-mui/gui_main.c,v
retrieving revision 1.81
diff -u -p -r1.81 gui_main.c
--- client/gui-mui/gui_main.c   2004/01/24 02:58:55     1.81
+++ client/gui-mui/gui_main.c   2004/01/28 13:27:10
@@ -1454,3 +1454,11 @@ void set_unit_icon(int idx, struct unit 
 void set_unit_icons_more_arrow(bool onoff)
 {
 }
+
+/**************************************************************************
+ Porting from GTK requires updating the "Orders" menu.
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return FALSE;
+}
Index: client/gui-sdl/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-sdl/gui_main.c,v
retrieving revision 1.44
diff -u -p -r1.44 gui_main.c
--- client/gui-sdl/gui_main.c   2004/01/24 02:58:55     1.44
+++ client/gui-sdl/gui_main.c   2004/01/28 13:27:18
@@ -955,3 +955,11 @@ void remove_net_input(void)
     pStoreAnimCursor = NULL;
   }
 }
+
+/**************************************************************************
+ Porting from GTK requires updating the "Orders" menu.
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return FALSE;
+}
Index: client/gui-stub/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-stub/gui_main.c,v
retrieving revision 1.10
diff -u -p -r1.10 gui_main.c
--- client/gui-stub/gui_main.c  2003/05/03 20:20:16     1.10
+++ client/gui-stub/gui_main.c  2004/01/28 13:27:20
@@ -94,3 +94,11 @@ void set_unit_icons_more_arrow(bool onof
 {
   /* PORTME */
 }
+
+/**************************************************************************
+ Porting from GTK requires updating the "Orders" menu.
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return FALSE;
+}
Index: client/gui-win32/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/gui_main.c,v
retrieving revision 1.24
diff -u -p -r1.24 gui_main.c
--- client/gui-win32/gui_main.c 2004/01/24 02:58:55     1.24
+++ client/gui-win32/gui_main.c 2004/01/28 13:27:26
@@ -613,3 +613,11 @@ set_unit_icons_more_arrow(bool onoff)
 {
        /* PORTME */
 }
+
+/**************************************************************************
+ Porting from GTK requires updating the "Orders" menu.
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return FALSE;
+}
Index: client/gui-xaw/gui_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/gui_main.c,v
retrieving revision 1.85
diff -u -p -r1.85 gui_main.c
--- client/gui-xaw/gui_main.c   2004/01/24 02:58:55     1.85
+++ client/gui-xaw/gui_main.c   2004/01/28 13:27:34
@@ -882,3 +882,11 @@ void set_unit_icons_more_arrow(bool onof
     showing = FALSE;
   }
 }
+
+/**************************************************************************
+ Porting from GTK requires updating the "Orders" menu.
+**************************************************************************/
+bool client_supports_mission_orders(void)
+{
+  return FALSE;
+}
Index: client/include/gui_main_g.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/include/gui_main_g.h,v
retrieving revision 1.9
diff -u -p -r1.9 gui_main_g.h
--- client/include/gui_main_g.h 2003/05/03 20:20:16     1.9
+++ client/include/gui_main_g.h 2004/01/28 13:27:35
@@ -27,6 +27,8 @@ void remove_net_input(void);
 void set_unit_icon(int idx, struct unit *punit);
 void set_unit_icons_more_arrow(bool onoff);
 
+bool client_supports_mission_orders(void);
+
 extern const char *client_string;
 
 #endif  /* FC__GUI_MAIN_G_H */
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.153
diff -u -p -r1.153 capstr.c
--- common/capstr.c     2004/01/22 23:52:20     1.153
+++ common/capstr.c     2004/01/28 13:27:37
@@ -75,7 +75,7 @@ const char * const our_capability = our_
  */
 
 #define CAPABILITY "+1.14.delta +last_turns_shield_surplus veteran +orders " \
-                   "+starter"
+                   "+starter +mission_orders"
 
 /* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
  *
@@ -88,6 +88,9 @@ const char * const our_capability = our_
  * "veteran" means the extended veteran system.
  *
  * "starter" means the Starter terrain flag is supported.
+ *
+ * "mission_orders" means some clients can assign an Order to a goto,
+ * which will be executed on the destination.
  */
 
 void init_our_capability(void)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.172
diff -u -p -r1.172 map.h
--- common/map.h        2004/01/27 06:48:12     1.172
+++ common/map.h        2004/01/28 13:27:44
@@ -550,8 +550,8 @@ enum direction8 {
 BV_DEFINE(dir_vector, 8);
 
 struct unit_order {
-  enum unit_orders order;
-  enum direction8 dir;         /* Only valid for ORDER_MOVE. */
+  union composite_orders composite;
+  enum direction8 dir;                 /* Only valid for ORDER_MOVE. */
 };
 
 /* return the reverse of the direction */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.7
diff -u -p -r1.7 packets.def
--- common/packets.def  2004/01/20 21:52:08     1.7
+++ common/packets.def  2004/01/28 13:27:53
@@ -176,6 +176,7 @@ type AUTH_TYPE              = uint8(enum authenticat
 type IMPR_RANGE                = uint8(enum impr_range)
 type DIRECTION         = uint8(enum direction8)
 type ORDERS            = uint8(enum unit_orders)
+type ORDERS_TYPE       = uint8(enum orders_type)
 
 # typedefs for IDs
 type PLAYER            = UINT8
@@ -599,6 +600,8 @@ PACKET_UNIT_INFO=49; is-info,sc
   BOOL veteran_old; remove-cap(veteran)
   BOOL ai, paradropped, connecting, carried, done_moving;
   BOOL has_orders, repeat, vigilant;
+  ORDERS mission;
+  ORDERS_TYPE orders_type;
 
   UNIT_TYPE type;
   UINT8 movesleft, hp, fuel, activity_count;
Index: common/packets_gen.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_gen.c,v
retrieving revision 1.8
diff -u -p -r1.8 packets_gen.c
--- common/packets_gen.c        2004/01/20 21:52:08     1.8
+++ common/packets_gen.c        2004/01/28 13:30:45
@@ -9779,7 +9779,7 @@ static int cmp_packet_unit_info_100(cons
   return 0;
 }
 
-BV_DEFINE(packet_unit_info_100_fields, 27);
+BV_DEFINE(packet_unit_info_100_fields, 29);
 
 static struct packet_unit_info *receive_packet_unit_info_100(struct connection 
*pc, enum packet_type type)
 {
@@ -9832,45 +9832,51 @@ static struct packet_unit_info *receive_
   real_packet->repeat = BV_ISSET(fields, 11);
   real_packet->vigilant = BV_ISSET(fields, 12);
   if (BV_ISSET(fields, 13)) {
-    dio_get_uint8(&din, (int *) &real_packet->type);
+    dio_get_uint8(&din, (int *) &real_packet->mission);
   }
   if (BV_ISSET(fields, 14)) {
-    dio_get_uint8(&din, (int *) &real_packet->movesleft);
+    dio_get_uint8(&din, (int *) &real_packet->orders_type);
   }
   if (BV_ISSET(fields, 15)) {
-    dio_get_uint8(&din, (int *) &real_packet->hp);
+    dio_get_uint8(&din, (int *) &real_packet->type);
   }
   if (BV_ISSET(fields, 16)) {
-    dio_get_uint8(&din, (int *) &real_packet->fuel);
+    dio_get_uint8(&din, (int *) &real_packet->movesleft);
   }
   if (BV_ISSET(fields, 17)) {
-    dio_get_uint8(&din, (int *) &real_packet->activity_count);
+    dio_get_uint8(&din, (int *) &real_packet->hp);
   }
   if (BV_ISSET(fields, 18)) {
-    dio_get_uint8(&din, (int *) &real_packet->unhappiness);
+    dio_get_uint8(&din, (int *) &real_packet->fuel);
   }
   if (BV_ISSET(fields, 19)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep);
+    dio_get_uint8(&din, (int *) &real_packet->activity_count);
   }
   if (BV_ISSET(fields, 20)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep_food);
+    dio_get_uint8(&din, (int *) &real_packet->unhappiness);
   }
   if (BV_ISSET(fields, 21)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep_gold);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep);
   }
   if (BV_ISSET(fields, 22)) {
-    dio_get_uint8(&din, (int *) &real_packet->occupy);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep_food);
   }
   if (BV_ISSET(fields, 23)) {
-    dio_get_uint8(&din, (int *) &real_packet->goto_dest_x);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep_gold);
   }
   if (BV_ISSET(fields, 24)) {
-    dio_get_uint8(&din, (int *) &real_packet->goto_dest_y);
+    dio_get_uint8(&din, (int *) &real_packet->occupy);
   }
   if (BV_ISSET(fields, 25)) {
-    dio_get_uint8(&din, (int *) &real_packet->activity);
+    dio_get_uint8(&din, (int *) &real_packet->goto_dest_x);
   }
   if (BV_ISSET(fields, 26)) {
+    dio_get_uint8(&din, (int *) &real_packet->goto_dest_y);
+  }
+  if (BV_ISSET(fields, 27)) {
+    dio_get_uint8(&din, (int *) &real_packet->activity);
+  }
+  if (BV_ISSET(fields, 28)) {
     dio_get_uint16(&din, (int *) &real_packet->activity_target);
   }
 
@@ -9959,62 +9965,70 @@ static int send_packet_unit_info_100(str
   if(differ) {different++;}
   if(packet->vigilant) {BV_SET(fields, 12);}
 
-  differ = (old->type != real_packet->type);
+  differ = (old->mission != real_packet->mission);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 13);}
 
-  differ = (old->movesleft != real_packet->movesleft);
+  differ = (old->orders_type != real_packet->orders_type);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 14);}
 
-  differ = (old->hp != real_packet->hp);
+  differ = (old->type != real_packet->type);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 15);}
 
-  differ = (old->fuel != real_packet->fuel);
+  differ = (old->movesleft != real_packet->movesleft);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 16);}
 
-  differ = (old->activity_count != real_packet->activity_count);
+  differ = (old->hp != real_packet->hp);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 17);}
 
-  differ = (old->unhappiness != real_packet->unhappiness);
+  differ = (old->fuel != real_packet->fuel);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 18);}
 
-  differ = (old->upkeep != real_packet->upkeep);
+  differ = (old->activity_count != real_packet->activity_count);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 19);}
 
-  differ = (old->upkeep_food != real_packet->upkeep_food);
+  differ = (old->unhappiness != real_packet->unhappiness);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 20);}
 
-  differ = (old->upkeep_gold != real_packet->upkeep_gold);
+  differ = (old->upkeep != real_packet->upkeep);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 21);}
 
-  differ = (old->occupy != real_packet->occupy);
+  differ = (old->upkeep_food != real_packet->upkeep_food);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 22);}
 
-  differ = (old->goto_dest_x != real_packet->goto_dest_x);
+  differ = (old->upkeep_gold != real_packet->upkeep_gold);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 23);}
 
-  differ = (old->goto_dest_y != real_packet->goto_dest_y);
+  differ = (old->occupy != real_packet->occupy);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 24);}
 
-  differ = (old->activity != real_packet->activity);
+  differ = (old->goto_dest_x != real_packet->goto_dest_x);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 25);}
 
-  differ = (old->activity_target != real_packet->activity_target);
+  differ = (old->goto_dest_y != real_packet->goto_dest_y);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 26);}
 
+  differ = (old->activity != real_packet->activity);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 27);}
+
+  differ = (old->activity_target != real_packet->activity_target);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 28);}
+
   if (different == 0 && !force_send_of_unchanged) {
     return 0;
   }
@@ -10046,45 +10060,51 @@ static int send_packet_unit_info_100(str
   /* field 11 is folded into the header */
   /* field 12 is folded into the header */
   if (BV_ISSET(fields, 13)) {
-    dio_put_uint8(&dout, real_packet->type);
+    dio_put_uint8(&dout, real_packet->mission);
   }
   if (BV_ISSET(fields, 14)) {
-    dio_put_uint8(&dout, real_packet->movesleft);
+    dio_put_uint8(&dout, real_packet->orders_type);
   }
   if (BV_ISSET(fields, 15)) {
-    dio_put_uint8(&dout, real_packet->hp);
+    dio_put_uint8(&dout, real_packet->type);
   }
   if (BV_ISSET(fields, 16)) {
-    dio_put_uint8(&dout, real_packet->fuel);
+    dio_put_uint8(&dout, real_packet->movesleft);
   }
   if (BV_ISSET(fields, 17)) {
-    dio_put_uint8(&dout, real_packet->activity_count);
+    dio_put_uint8(&dout, real_packet->hp);
   }
   if (BV_ISSET(fields, 18)) {
-    dio_put_uint8(&dout, real_packet->unhappiness);
+    dio_put_uint8(&dout, real_packet->fuel);
   }
   if (BV_ISSET(fields, 19)) {
-    dio_put_uint8(&dout, real_packet->upkeep);
+    dio_put_uint8(&dout, real_packet->activity_count);
   }
   if (BV_ISSET(fields, 20)) {
-    dio_put_uint8(&dout, real_packet->upkeep_food);
+    dio_put_uint8(&dout, real_packet->unhappiness);
   }
   if (BV_ISSET(fields, 21)) {
-    dio_put_uint8(&dout, real_packet->upkeep_gold);
+    dio_put_uint8(&dout, real_packet->upkeep);
   }
   if (BV_ISSET(fields, 22)) {
-    dio_put_uint8(&dout, real_packet->occupy);
+    dio_put_uint8(&dout, real_packet->upkeep_food);
   }
   if (BV_ISSET(fields, 23)) {
-    dio_put_uint8(&dout, real_packet->goto_dest_x);
+    dio_put_uint8(&dout, real_packet->upkeep_gold);
   }
   if (BV_ISSET(fields, 24)) {
-    dio_put_uint8(&dout, real_packet->goto_dest_y);
+    dio_put_uint8(&dout, real_packet->occupy);
   }
   if (BV_ISSET(fields, 25)) {
-    dio_put_uint8(&dout, real_packet->activity);
+    dio_put_uint8(&dout, real_packet->goto_dest_x);
   }
   if (BV_ISSET(fields, 26)) {
+    dio_put_uint8(&dout, real_packet->goto_dest_y);
+  }
+  if (BV_ISSET(fields, 27)) {
+    dio_put_uint8(&dout, real_packet->activity);
+  }
+  if (BV_ISSET(fields, 28)) {
     dio_put_uint16(&dout, real_packet->activity_target);
   }
 
@@ -10121,7 +10141,7 @@ static int cmp_packet_unit_info_101(cons
   return 0;
 }
 
-BV_DEFINE(packet_unit_info_101_fields, 27);
+BV_DEFINE(packet_unit_info_101_fields, 29);
 
 static struct packet_unit_info *receive_packet_unit_info_101(struct connection 
*pc, enum packet_type type)
 {
@@ -10172,45 +10192,51 @@ static struct packet_unit_info *receive_
   real_packet->repeat = BV_ISSET(fields, 11);
   real_packet->vigilant = BV_ISSET(fields, 12);
   if (BV_ISSET(fields, 13)) {
-    dio_get_uint8(&din, (int *) &real_packet->type);
+    dio_get_uint8(&din, (int *) &real_packet->mission);
   }
   if (BV_ISSET(fields, 14)) {
-    dio_get_uint8(&din, (int *) &real_packet->movesleft);
+    dio_get_uint8(&din, (int *) &real_packet->orders_type);
   }
   if (BV_ISSET(fields, 15)) {
-    dio_get_uint8(&din, (int *) &real_packet->hp);
+    dio_get_uint8(&din, (int *) &real_packet->type);
   }
   if (BV_ISSET(fields, 16)) {
-    dio_get_uint8(&din, (int *) &real_packet->fuel);
+    dio_get_uint8(&din, (int *) &real_packet->movesleft);
   }
   if (BV_ISSET(fields, 17)) {
-    dio_get_uint8(&din, (int *) &real_packet->activity_count);
+    dio_get_uint8(&din, (int *) &real_packet->hp);
   }
   if (BV_ISSET(fields, 18)) {
-    dio_get_uint8(&din, (int *) &real_packet->unhappiness);
+    dio_get_uint8(&din, (int *) &real_packet->fuel);
   }
   if (BV_ISSET(fields, 19)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep);
+    dio_get_uint8(&din, (int *) &real_packet->activity_count);
   }
   if (BV_ISSET(fields, 20)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep_food);
+    dio_get_uint8(&din, (int *) &real_packet->unhappiness);
   }
   if (BV_ISSET(fields, 21)) {
-    dio_get_uint8(&din, (int *) &real_packet->upkeep_gold);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep);
   }
   if (BV_ISSET(fields, 22)) {
-    dio_get_uint8(&din, (int *) &real_packet->occupy);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep_food);
   }
   if (BV_ISSET(fields, 23)) {
-    dio_get_uint8(&din, (int *) &real_packet->goto_dest_x);
+    dio_get_uint8(&din, (int *) &real_packet->upkeep_gold);
   }
   if (BV_ISSET(fields, 24)) {
-    dio_get_uint8(&din, (int *) &real_packet->goto_dest_y);
+    dio_get_uint8(&din, (int *) &real_packet->occupy);
   }
   if (BV_ISSET(fields, 25)) {
-    dio_get_uint8(&din, (int *) &real_packet->activity);
+    dio_get_uint8(&din, (int *) &real_packet->goto_dest_x);
   }
   if (BV_ISSET(fields, 26)) {
+    dio_get_uint8(&din, (int *) &real_packet->goto_dest_y);
+  }
+  if (BV_ISSET(fields, 27)) {
+    dio_get_uint8(&din, (int *) &real_packet->activity);
+  }
+  if (BV_ISSET(fields, 28)) {
     dio_get_uint16(&din, (int *) &real_packet->activity_target);
   }
 
@@ -10299,62 +10325,70 @@ static int send_packet_unit_info_101(str
   if(differ) {different++;}
   if(packet->vigilant) {BV_SET(fields, 12);}
 
-  differ = (old->type != real_packet->type);
+  differ = (old->mission != real_packet->mission);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 13);}
 
-  differ = (old->movesleft != real_packet->movesleft);
+  differ = (old->orders_type != real_packet->orders_type);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 14);}
 
-  differ = (old->hp != real_packet->hp);
+  differ = (old->type != real_packet->type);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 15);}
 
-  differ = (old->fuel != real_packet->fuel);
+  differ = (old->movesleft != real_packet->movesleft);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 16);}
 
-  differ = (old->activity_count != real_packet->activity_count);
+  differ = (old->hp != real_packet->hp);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 17);}
 
-  differ = (old->unhappiness != real_packet->unhappiness);
+  differ = (old->fuel != real_packet->fuel);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 18);}
 
-  differ = (old->upkeep != real_packet->upkeep);
+  differ = (old->activity_count != real_packet->activity_count);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 19);}
 
-  differ = (old->upkeep_food != real_packet->upkeep_food);
+  differ = (old->unhappiness != real_packet->unhappiness);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 20);}
 
-  differ = (old->upkeep_gold != real_packet->upkeep_gold);
+  differ = (old->upkeep != real_packet->upkeep);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 21);}
 
-  differ = (old->occupy != real_packet->occupy);
+  differ = (old->upkeep_food != real_packet->upkeep_food);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 22);}
 
-  differ = (old->goto_dest_x != real_packet->goto_dest_x);
+  differ = (old->upkeep_gold != real_packet->upkeep_gold);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 23);}
 
-  differ = (old->goto_dest_y != real_packet->goto_dest_y);
+  differ = (old->occupy != real_packet->occupy);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 24);}
 
-  differ = (old->activity != real_packet->activity);
+  differ = (old->goto_dest_x != real_packet->goto_dest_x);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 25);}
 
-  differ = (old->activity_target != real_packet->activity_target);
+  differ = (old->goto_dest_y != real_packet->goto_dest_y);
   if(differ) {different++;}
   if(differ) {BV_SET(fields, 26);}
 
+  differ = (old->activity != real_packet->activity);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 27);}
+
+  differ = (old->activity_target != real_packet->activity_target);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 28);}
+
   if (different == 0 && !force_send_of_unchanged) {
     return 0;
   }
@@ -10384,45 +10418,51 @@ static int send_packet_unit_info_101(str
   /* field 11 is folded into the header */
   /* field 12 is folded into the header */
   if (BV_ISSET(fields, 13)) {
-    dio_put_uint8(&dout, real_packet->type);
+    dio_put_uint8(&dout, real_packet->mission);
   }
   if (BV_ISSET(fields, 14)) {
-    dio_put_uint8(&dout, real_packet->movesleft);
+    dio_put_uint8(&dout, real_packet->orders_type);
   }
   if (BV_ISSET(fields, 15)) {
-    dio_put_uint8(&dout, real_packet->hp);
+    dio_put_uint8(&dout, real_packet->type);
   }
   if (BV_ISSET(fields, 16)) {
-    dio_put_uint8(&dout, real_packet->fuel);
+    dio_put_uint8(&dout, real_packet->movesleft);
   }
   if (BV_ISSET(fields, 17)) {
-    dio_put_uint8(&dout, real_packet->activity_count);
+    dio_put_uint8(&dout, real_packet->hp);
   }
   if (BV_ISSET(fields, 18)) {
-    dio_put_uint8(&dout, real_packet->unhappiness);
+    dio_put_uint8(&dout, real_packet->fuel);
   }
   if (BV_ISSET(fields, 19)) {
-    dio_put_uint8(&dout, real_packet->upkeep);
+    dio_put_uint8(&dout, real_packet->activity_count);
   }
   if (BV_ISSET(fields, 20)) {
-    dio_put_uint8(&dout, real_packet->upkeep_food);
+    dio_put_uint8(&dout, real_packet->unhappiness);
   }
   if (BV_ISSET(fields, 21)) {
-    dio_put_uint8(&dout, real_packet->upkeep_gold);
+    dio_put_uint8(&dout, real_packet->upkeep);
   }
   if (BV_ISSET(fields, 22)) {
-    dio_put_uint8(&dout, real_packet->occupy);
+    dio_put_uint8(&dout, real_packet->upkeep_food);
   }
   if (BV_ISSET(fields, 23)) {
-    dio_put_uint8(&dout, real_packet->goto_dest_x);
+    dio_put_uint8(&dout, real_packet->upkeep_gold);
   }
   if (BV_ISSET(fields, 24)) {
-    dio_put_uint8(&dout, real_packet->goto_dest_y);
+    dio_put_uint8(&dout, real_packet->occupy);
   }
   if (BV_ISSET(fields, 25)) {
-    dio_put_uint8(&dout, real_packet->activity);
+    dio_put_uint8(&dout, real_packet->goto_dest_x);
   }
   if (BV_ISSET(fields, 26)) {
+    dio_put_uint8(&dout, real_packet->goto_dest_y);
+  }
+  if (BV_ISSET(fields, 27)) {
+    dio_put_uint8(&dout, real_packet->activity);
+  }
+  if (BV_ISSET(fields, 28)) {
     dio_put_uint16(&dout, real_packet->activity_target);
   }
 
Index: common/packets_gen.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets_gen.h,v
retrieving revision 1.5
diff -u -p -r1.5 packets_gen.h
--- common/packets_gen.h        2004/01/20 21:52:08     1.5
+++ common/packets_gen.h        2004/01/28 13:31:01
@@ -393,6 +393,8 @@ struct packet_unit_info {
   bool has_orders;
   bool repeat;
   bool vigilant;
+  enum unit_orders mission;
+  enum orders_type orders_type;
   Unit_Type_id type;
   int movesleft;
   int hp;
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.197
diff -u -p -r1.197 unit.c
--- common/unit.c       2004/01/25 08:04:52     1.197
+++ common/unit.c       2004/01/28 13:31:16
@@ -222,6 +222,17 @@ bool unit_has_orders(struct unit *punit)
   return punit->has_orders;
 }
 
+/****************************************************************************
+  TRUE if the order is an action or activity. Determines sprites in the
+  client and helpful for server to examine the orders list.
+****************************************************************************/
+bool order_is_action(union composite_orders comp)
+{
+  return (comp.order != ORDER_LAST &&
+         comp.order != ORDER_MOVE &&
+         comp.order != ORDER_FINISH_TURN);
+}
+
 /**************************************************************************
 ...
 **************************************************************************/
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.110
diff -u -p -r1.110 unit.h
--- common/unit.h       2004/01/25 08:04:53     1.110
+++ common/unit.h       2004/01/28 13:31:20
@@ -24,6 +24,9 @@ struct unit_order;
 
 #define BARBARIAN_LIFE    5
 
+/* The items in the following 4 enums need distinct individual
+ * assigned numbers, as they may be used together in a union. */
+
 /* Changing this enum will break savegame and network compatability. */
 enum unit_activity {
   ACTIVITY_IDLE, ACTIVITY_POLLUTION, ACTIVITY_ROAD, ACTIVITY_MINE,
@@ -36,22 +39,46 @@ enum unit_activity {
 };
 
 /* Changing this enum will break savegame and network compatability. */
+enum unit_actions {
+  ACTION_AUTO_ATTACK = (ACTIVITY_LAST + 1),
+  ACTION_AUTO_SETTLE, ACTION_BUILD_CITY, ACTION_BUILD_WONDER,
+  ACTION_DISBAND, ACTION_HOMECITY, ACTION_TRADEROUTE, ACTION_UNLOAD,
+  ACTION_LAST   /* leave this one last */
+};
+
+/* Changing this enum will break savegame and network compatability. */
+enum diplomat_actions {
+  DIPLOMAT_BRIBE = (ACTION_LAST + 1),
+  DIPLOMAT_EMBASSY, DIPLOMAT_SABOTAGE, DIPLOMAT_STEAL,
+  DIPLOMAT_INCITE, SPY_POISON,  DIPLOMAT_INVESTIGATE,
+  SPY_SABOTAGE_UNIT, SPY_GET_SABOTAGE_LIST,
+  DIPLOMAT_MOVE,       /* move onto city square - only for allied cities */
+  DIPLOMAT_ANY_ACTION   /* leave this one last */
+};
+
+/* Changing this enum will break savegame and network compatability. */
+/* Also update function order_is_action() if changing this. */
 enum unit_orders {
-  ORDER_MOVE, ORDER_FINISH_TURN,
+  ORDER_MOVE = (DIPLOMAT_ANY_ACTION + 1),
+  ORDER_FINISH_TURN,
   ORDER_LAST
 };
 
-enum unit_focus_status {
-  FOCUS_AVAIL, FOCUS_WAIT, FOCUS_DONE  
+/* This make up a unit's orders list. */
+union composite_orders {
+  enum unit_orders     order;
+  enum unit_activity   activity;
+  enum unit_actions    action;
+  enum diplomat_actions        diplomat;
 };
 
-enum diplomat_actions {
-  DIPLOMAT_BRIBE, DIPLOMAT_EMBASSY, DIPLOMAT_SABOTAGE,
-  DIPLOMAT_STEAL, DIPLOMAT_INCITE, SPY_POISON, 
-  DIPLOMAT_INVESTIGATE, SPY_SABOTAGE_UNIT,
-  SPY_GET_SABOTAGE_LIST,
-  DIPLOMAT_MOVE,       /* move onto city square - only for allied cities */
-  DIPLOMAT_ANY_ACTION   /* leave this one last */
+/* For client to determine which sprite to display. */
+enum orders_type {
+  GOTO_ORDERS, PATROL_ORDERS, STATIONARY_ORDERS
+};
+
+enum unit_focus_status {
+  FOCUS_AVAIL, FOCUS_WAIT, FOCUS_DONE  
 };
 
 enum ai_unit_task { AIUNIT_NONE, AIUNIT_AUTO_SETTLER, AIUNIT_BUILD_CITY,
@@ -65,10 +92,6 @@ enum goto_move_restriction {
   GOTO_MOVE_STRAIGHTEST
 };
 
-enum goto_route_type {
-  ROUTE_GOTO, ROUTE_PATROL
-};
-
 enum unit_move_result {
   MR_OK, MR_BAD_TYPE_FOR_CITY_TAKE_OVER, MR_NO_WAR, MR_ZOC,
   MR_BAD_ACTIVITY, MR_BAD_DESTINATION, MR_BAD_MAP_POSITION,
@@ -168,6 +191,9 @@ struct unit {
     bool repeat;       /* The path is to be repeated on completion. */
     bool vigilant;     /* Orders should be cleared if an enemy is met. */
     struct unit_order *list; /* server only */
+    /* Information for client to display sprites correctly. */
+    union composite_orders mission;   /* The last order in the list. */
+    enum orders_type type;    /* Goto, Patrol, Stationary.   */
   } orders;
 };
 
@@ -238,6 +264,7 @@ bool unit_can_est_traderoute_here(struct
 bool unit_can_defend_here(struct unit *punit);
 bool unit_can_airlift_to(struct unit *punit, struct city *pcity);
 bool unit_has_orders(struct unit *punit);
+bool order_is_action(union composite_orders comp);
 
 bool can_unit_paradrop(struct unit *punit);
 bool can_unit_change_homecity(struct unit *punit);
Index: data/isotrident/tiles.png
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident/tiles.png,v
retrieving revision 1.2
diff -u -p -r1.2 tiles.png
Binary files /tmp/cvsYAA02ai7X and tiles.png differ
Index: data/isotrident/tiles.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/isotrident/tiles.spec,v
retrieving revision 1.2
diff -u -p -r1.2 tiles.spec
--- data/isotrident/tiles.spec  2003/10/13 21:24:54     1.2
+++ data/isotrident/tiles.spec  2004/01/28 13:31:48
@@ -32,6 +32,7 @@ tiles = { "row", "column", "tag"
   2, 12, "unit.transform"
   2, 13, "unit.sentry"
   2, 14, "unit.goto"
+  3, 14, "unit.goto_with_mission"
   2, 15, "unit.mine"
   2, 16, "unit.pollution"
   2, 17, "unit.road"
@@ -43,6 +44,11 @@ tiles = { "row", "column", "tag"
   3, 18, "unit.fortified"
   3, 19, "unit.fallout"
   4, 19, "unit.patrol"
+
+; Mission Orders indication:
+
+  3, 15, "unit.build_city",
+         "unit.build_wonder"
 
 ; Unit hit-point bars: approx percent of hp remaining
 
Index: data/trident/auto_ll.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/auto_ll.spec,v
retrieving revision 1.1
diff -u -p -r1.1 auto_ll.spec
--- data/trident/auto_ll.spec   2000/01/18 19:42:52     1.1
+++ data/trident/auto_ll.spec   2004/01/28 13:31:49
@@ -29,4 +29,9 @@ tiles = { "row", "column", "tag"
   4, 18, "unit.connect"
   4, 19, "unit.auto_explore"
 
+; Mission Orders indication:
+
+  4, 16, "unit.build_city",
+         "unit.build_wonder"
+
 }
Index: data/trident/tiles.png
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/tiles.png,v
retrieving revision 1.3
diff -u -p -r1.3 tiles.png
Binary files /tmp/cvsBBA32ai7X and tiles.png differ
Index: data/trident/tiles.spec
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/trident/tiles.spec,v
retrieving revision 1.13
diff -u -p -r1.13 tiles.spec
--- data/trident/tiles.spec     2003/11/20 22:05:26     1.13
+++ data/trident/tiles.spec     2004/01/28 13:32:06
@@ -393,6 +393,7 @@ tiles = { "row", "column", "tag"
  11, 12, "unit.transform"
  11, 13, "unit.sentry"
  11, 14, "unit.goto"
+  2, 16, "unit.goto_with_mission"
  11, 15, "unit.mine"
  11, 16, "unit.pollution"
  11, 17, "unit.road"
@@ -404,6 +405,11 @@ tiles = { "row", "column", "tag"
  12, 18, "unit.fortified"
  12, 19, "unit.fallout"
  13, 19, "unit.patrol"
+
+; Mission Orders indication:
+
+  3, 16, "unit.build_city",
+         "unit.build_wonder"
 
 ; Unit hit-point bars: approx percent of hp remaining
 
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.145
diff -u -p -r1.145 savegame.c
--- server/savegame.c   2004/01/20 21:52:09     1.145
+++ server/savegame.c   2004/01/28 13:32:40
@@ -1128,9 +1128,13 @@ static void player_load(struct player *p
            free_unit_orders(punit);
            break;
          }
-         punit->orders.list[j].order = orders_buf[j] - 'a';
+         punit->orders.list[j].composite.order = orders_buf[j] - 'a';
          punit->orders.list[j].dir = dir_buf[j] - 'a';
        }
+       punit->orders.mission.order = secfile_lookup_int_default(file,
+           (int) ORDER_LAST, "player%d.u%d.orders_mission", plrno, i);
+       punit->orders.type = secfile_lookup_int_default(file,
+           (int) STATIONARY_ORDERS, "player%d.u%d.orders_type", plrno, i);
        punit->has_orders = TRUE;
       } else {
        punit->has_orders = FALSE;
@@ -1552,7 +1556,7 @@ static void player_save(struct player *p
                          "player%d.u%d.orders_vigilant", plrno, i);
 
       for (j = 0; j < len; j++) {
-       orders_buf[j] = 'a' + punit->orders.list[j].order;
+       orders_buf[j] = 'a' + punit->orders.list[j].composite.order;
        dir_buf[j] = 'a' + punit->orders.list[j].dir;
       }
       orders_buf[len] = dir_buf[len] = '\0';
@@ -1561,6 +1565,11 @@ static void player_save(struct player *p
                         "player%d.u%d.orders_list", plrno, i);
       secfile_insert_str(file, dir_buf,
                         "player%d.u%d.dir_list", plrno, i);
+
+      secfile_insert_int(file, punit->orders.mission.order,
+                        "player%d.u%d.orders_mission", plrno, i);
+      secfile_insert_int(file, punit->orders.type,
+                        "player%d.u%d.orders_type", plrno, i);
     } else {
       secfile_insert_int(file, 0, "player%d.u%d.orders_length", plrno, i);
     }
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.287
diff -u -p -r1.287 unithand.c
--- server/unithand.c   2004/01/28 06:02:44     1.287
+++ server/unithand.c   2004/01/28 13:32:55
@@ -1509,6 +1509,26 @@ void handle_unit_orders(struct player *p
       }
       break;
     case ORDER_FINISH_TURN:
+    case ACTION_AUTO_ATTACK:
+    case ACTION_AUTO_SETTLE:
+    case ACTION_BUILD_CITY:
+    case ACTION_BUILD_WONDER:
+    case ACTION_DISBAND:
+    case ACTION_HOMECITY:
+    case ACTION_TRADEROUTE:
+    case ACTION_UNLOAD:
+    case ACTIVITY_AIRBASE:
+    case ACTIVITY_EXPLORE:
+    case ACTIVITY_FALLOUT:
+    case ACTIVITY_FORTIFYING:
+    case ACTIVITY_FORTRESS:
+    case ACTIVITY_IRRIGATE:
+    case ACTIVITY_MINE:
+    case ACTIVITY_PILLAGE:
+    case ACTIVITY_POLLUTION:
+    case ACTIVITY_ROAD:
+    case ACTIVITY_SENTRY:
+    case ACTIVITY_TRANSFORM:
       break;
     default:
       /* An invalid order.  This is handled in execute_orders. */
@@ -1533,9 +1553,12 @@ void handle_unit_orders(struct player *p
   punit->orders.list
     = fc_malloc(packet->length * sizeof(*(punit->orders.list)));
   for (i = 0; i < packet->length; i++) {
-    punit->orders.list[i].order = packet->orders[i];
+    punit->orders.list[i].composite.order = packet->orders[i];
     punit->orders.list[i].dir = packet->dir[i];
   }
+  /* For client to display correct sprites. */
+  punit->orders.mission.order = packet->orders[packet->length - 1];
+  punit->orders.type = packet->repeat ? PATROL_ORDERS : GOTO_ORDERS;
 
   if (!packet->repeat) {
     set_goto_dest(punit, packet->dest_x, packet->dest_y);
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.273
diff -u -p -r1.273 unittools.c
--- server/unittools.c  2004/01/28 06:02:44     1.273
+++ server/unittools.c  2004/01/28 13:33:27
@@ -1898,8 +1898,12 @@ void package_unit(struct unit *punit, st
   if (punit->has_orders) {
     packet->repeat = punit->orders.repeat;
     packet->vigilant = punit->orders.vigilant;
+    packet->mission = punit->orders.mission.order;
+    packet->orders_type = punit->orders.type;
   } else {
     packet->repeat = packet->vigilant = FALSE;
+    packet->mission = ORDER_LAST;
+    packet->orders_type = STATIONARY_ORDERS;
   }
 }
 
@@ -3178,10 +3182,12 @@ static bool maybe_cancel_patrol_due_to_e
 bool execute_orders(struct unit *punit)
 {
   int dest_x, dest_y;
-  bool res, last_order;
   int unitid = punit->id;
-  struct player *pplayer = unit_owner(punit);
   int moves_made = 0;
+  bool res, is_last_order, is_last_and_action;
+  enum unit_activity activity;
+  struct player *pplayer = unit_owner(punit);
+  struct city *pcity;
 
   assert(unit_has_orders(punit));
 
@@ -3192,19 +3198,39 @@ bool execute_orders(struct unit *punit)
 
   while (TRUE) {
     struct unit_order order;
+
+    order = punit->orders.list[punit->orders.index];
 
-    if (punit->moves_left == 0) {
-      /* FIXME: this check won't work when actions take 0 MP. */
+    is_last_order = (!punit->orders.repeat &&
+                    punit->orders.index + 1 == punit->orders.length);
+
+    is_last_and_action = (is_last_order &&
+                         order_is_action(order.composite));
+
+    if (is_last_and_action) {
+      /* Don't display goto/patrol sprite any more. In practice, this is
+       * only for exhausted settlers with Mission Order: Build city. */
+      punit->orders.type = STATIONARY_ORDERS;
+
+      if (punit->moves_left == 0
+         && order.composite.action == ACTION_BUILD_CITY) {
+       freelog(LOG_DEBUG, "  ran out of MPs and will build city later.");
+       return TRUE;
+      }
+    }
+
+    else if (punit->moves_left == 0) {
       freelog(LOG_DEBUG, "  stopping because of no more move points");
       return TRUE;
     }
 
-    if (punit->done_moving) {
+    else if (punit->done_moving) {
       freelog(LOG_DEBUG, "  stopping because we're done this turn");
       return TRUE;
     }
 
-    if (punit->orders.vigilant && maybe_cancel_patrol_due_to_enemy(punit)) {
+    else if (punit->orders.vigilant
+            && maybe_cancel_patrol_due_to_enemy(punit)) {
       /* "Patrol" orders are stopped if an enemy is near. */
       freelog(LOG_DEBUG, "  stopping because of nearby enemy");               
       free_unit_orders(punit);
@@ -3215,17 +3241,13 @@ bool execute_orders(struct unit *punit)
       return TRUE;
     }
 
-    if (moves_made == punit->orders.length) {
+    else if (moves_made == punit->orders.length) {
       /* For repeating orders, don't repeat more than once per turn. */
       freelog(LOG_DEBUG, "  stopping because we ran a round");
       return TRUE;
     }
 
-    last_order = (!punit->orders.repeat
-                 && punit->orders.index + 1 == punit->orders.length);
-
-    order = punit->orders.list[punit->orders.index];
-    if (last_order) {
+    if (is_last_order) {
       /* Clear the orders before we engage in the move.  That way any
        * has_orders checks will yield FALSE and this will be treated as
        * a normal move.  This is important: for instance a caravan goto
@@ -3233,7 +3255,8 @@ bool execute_orders(struct unit *punit)
       free_unit_orders(punit);
     }
 
-    switch (order.order) {
+    activity = ACTIVITY_LAST;
+    switch (order.composite.order) {
     case ORDER_FINISH_TURN:
       punit->done_moving = TRUE;
       freelog(LOG_DEBUG, "  waiting this turn");
@@ -3251,7 +3274,7 @@ bool execute_orders(struct unit *punit)
        return TRUE;
       }
 
-      if (!last_order
+      if (!is_last_order
          && maybe_cancel_goto_due_to_enemy(punit, dest_x, dest_y)) {
        freelog(LOG_DEBUG, "  orders canceled because of enemy");
        free_unit_orders(punit);
@@ -3264,7 +3287,7 @@ bool execute_orders(struct unit *punit)
 
       freelog(LOG_DEBUG, "  moving to %d,%d", dest_x, dest_y);
       res = handle_unit_move_request(punit, dest_x, dest_y,
-                                    FALSE, !last_order);
+                                    FALSE, !is_last_order);
       if (!player_find_unit_by_id(pplayer, unitid)) {
        freelog(LOG_DEBUG, "  unit died while moving.");
        /* A player notification should already have been sent. */
@@ -3287,9 +3310,63 @@ bool execute_orders(struct unit *punit)
                         unit_name(punit->type));
        return TRUE;
       }
-
+      break;
+    case ACTION_AUTO_ATTACK:
+    case ACTION_AUTO_SETTLE:
+      freelog(LOG_DEBUG, "  entering auto mode.");
+      handle_unit_auto(pplayer, unitid);
+      break;
+    case ACTION_BUILD_CITY:
+      /* We don't need extra 2-way communication about city names,
+       * since this function may be called when sniff_packets() is
+       * not active. Player will just have to accept that
+       * Build Missions take default city name. */
+      freelog(LOG_DEBUG, "  founding new city.");
+      handle_unit_build_city(pplayer, unitid,
+        city_name_suggestion(pplayer, punit->x, punit->y));
+      break;
+    case ACTION_BUILD_WONDER:
+      freelog(LOG_DEBUG, "  building wonder.");
+      handle_unit_help_build_wonder(pplayer, unitid);
       break;
-    case ORDER_LAST:
+    case ACTION_DISBAND:
+      freelog(LOG_DEBUG, "  disbanding unit.");
+      handle_unit_disband(pplayer, unitid);
+      break;
+    case ACTION_HOMECITY:
+      freelog(LOG_DEBUG, "  changing homecity.");
+      pcity = map_get_city(punit->x, punit->y);
+      handle_unit_change_homecity(pplayer, unitid, pcity ? pcity->id : -1);
+      break;
+    case ACTION_TRADEROUTE:
+      freelog(LOG_DEBUG, "  establishing a trade route.");
+      handle_unit_establish_trade(pplayer, unitid);
+      break;
+    case ACTION_UNLOAD:
+      freelog(LOG_DEBUG, "  unloading.");
+      handle_unit_unload(pplayer, unitid);
+      break;
+    case ACTIVITY_AIRBASE:
+    case ACTIVITY_EXPLORE:
+    case ACTIVITY_FALLOUT:
+    case ACTIVITY_FORTIFYING:
+    case ACTIVITY_FORTRESS:
+    case ACTIVITY_IRRIGATE:
+    case ACTIVITY_MINE:
+    case ACTIVITY_PILLAGE:
+    case ACTIVITY_POLLUTION:
+    case ACTIVITY_SENTRY:
+    case ACTIVITY_TRANSFORM:
+      activity = order.composite.activity;
+      break;
+    case ACTIVITY_ROAD:
+      activity = map_has_special(punit->x, punit->y, S_ROAD)
+                 ? ACTIVITY_RAILROAD : ACTIVITY_ROAD;
+      break;
+    /*
+     *  Add DIPLOMAT_INVESTIGATE, DIPLOMAT_EMBASSY, etc ?
+     */
+    default:
       freelog(LOG_DEBUG, "  client sent invalid order!");
       free_unit_orders(punit);
       notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_ORDERS,
@@ -3297,8 +3374,26 @@ bool execute_orders(struct unit *punit)
                       unit_name(punit->type));
       return TRUE;
     }
+
+    if (activity == ACTIVITY_EXPLORE) {
+      /* This generates new orders. */
+      free_unit_orders(punit);
+      freelog(LOG_DEBUG, "  entering explore mode.");
+      handle_unit_change_activity(pplayer, unitid, activity, S_NO_SPECIAL);
+      return player_find_unit_by_id(pplayer, unitid) ? TRUE : FALSE;
+    }
+
+    if (activity != ACTIVITY_LAST) {
+      freelog(LOG_DEBUG, "  setting new activity.");
+      handle_unit_change_activity(pplayer, unitid, activity, S_NO_SPECIAL);
+    }
+
+    if (!player_find_unit_by_id(pplayer, unitid)) {
+      freelog(LOG_DEBUG, "  unit died from executing order.");
+      return FALSE;
+    }
 
-    if (last_order) {
+    if (is_last_order) {
       assert(punit->has_orders == FALSE);
       freelog(LOG_DEBUG, "  stopping because orders are complete");
       return TRUE;

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