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

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

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#7282) connect as orders
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 16 May 2004 21:59:01 -0700
Reply-to: rt@xxxxxxxxxxx

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

Here's an updated version of the patch.  It may actually now be 
complete.  Certainly it's now ready for testing and review.

Greg said I should set the MC (move cost) to 1 and put the construction 
time into the EC (extra cost).  This would choose the path with the 
shortest number of moves, which is ideal for roads (but not for rail, 
and certainly not for irrigation).  The EC is used only as a tiebreaker 
for equal-MC paths, so the shortest-construction-time would be the 
secondary consideration.

The problem with this is that the construction time includes the move 
time, and there is no way to reliably calculate the move time as part of 
the EC since the extra cost is calculated only per-tile, not per-move. 
(That is to say, the EC function is given only a single tile, not a 
source and destination tile.)

The alternative is to add the construction time directly onto the MC, as 
I had originally planned to do.  However this breaks PF's turn mode if 
you use TM_WORST_TIME.  The reason is that PF "knows" that a unit gets 
to move at least one tile per turn.  So even if the MC is 18 (for 
connect-road on a typical forest) this will only take 1 turn (rather 
than 5 [not 6] as it should).  It would work better if we could just 
give an "extra turns" callback to PF, which is added onto the MC and 
otherwise works as you'd expect it to.  But I digress.  The immediate 
solution is to disable PF's turn mode by setting it to TM_NONE.  Now we 
just calculate the total "moves" required.

jason


? eff
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.314
diff -u -r1.314 aiunit.c
--- ai/aiunit.c 4 May 2004 17:40:25 -0000       1.314
+++ ai/aiunit.c 17 May 2004 04:56:49 -0000
@@ -198,7 +198,7 @@
 
   result =
       test_unit_move_to_tile(punit->type, unit_owner(punit),
-                             ACTIVITY_IDLE, FALSE, punit->x, punit->y, 
+                             ACTIVITY_IDLE, punit->x, punit->y, 
                              dest_x, dest_y, unit_flag(punit, F_IGZOC));
   if (result == MR_OK) {
     return 1;
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.135
diff -u -r1.135 control.c
--- client/control.c    17 May 2004 01:29:46 -0000      1.135
+++ client/control.c    17 May 2004 04:56:49 -0000
@@ -634,6 +634,12 @@
     /* Enter or change the hover connect state. */
     set_hover_state(punit_focus, HOVER_CONNECT, activity);
     update_unit_info_label(punit_focus);
+
+    enter_goto_state(punit_focus);
+    create_line_at_mouse_pos();
+  } else {
+    assert(goto_is_active());
+    goto_add_waypoint();
   }
 }
 
@@ -1634,13 +1640,23 @@
 void do_unit_connect(struct unit *punit, int x, int y,
                     enum unit_activity activity)
 {
-  struct packet_unit_connect req;
+  if (is_air_unit(punit)) {
+    append_output_window(_("Game: Sorry, airunit connect "
+                          "not yet implemented."));
+  } else {
+    int dest_x, dest_y;
 
-  req.activity_type = activity;
-  req.unit_id = punit->id;
-  req.dest_x = x;
-  req.dest_y = y;
-  send_packet_unit_connect(&aconnection, &req);
+    draw_line(x, y);
+    get_line_dest(&dest_x, &dest_y);
+    if (same_pos(dest_x, dest_y, x, y)) {
+      send_connect_route(punit, activity);
+    } else {
+      append_output_window(_("Game: Didn't find a route to "
+                            "the destination!"));
+    }
+  }
+
+  set_hover_state(NULL, HOVER_NONE, ACTIVITY_LAST);
 }
  
 /**************************************************************************
Index: client/goto.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.c,v
retrieving revision 1.69
diff -u -r1.69 goto.c
--- client/goto.c       11 May 2004 17:40:06 -0000      1.69
+++ client/goto.c       17 May 2004 04:56:49 -0000
@@ -365,6 +365,84 @@
   return TB_NORMAL;
 }
 
+static int (*original_MC) (int from_x, int from_y, enum direction8 dir,
+                          int to_x, int to_y, struct pf_parameter *param);
+
+/****************************************************************************
+  PF callback for the cost of a connect (including "extra" cost).  In
+  connect mode we may (or may not) be concerned with number of steps but are
+  secondarily worried about build time.
+****************************************************************************/
+static int get_connect_MC(int from_x, int from_y, enum direction8 dir,
+                         int to_x, int to_y, struct pf_parameter *param)
+{
+  int base_mc = original_MC(from_x, from_y, dir, to_x, to_y, param);
+  struct tile *ptile = map_get_tile(to_x, to_y);
+  int activity_mc = 0;
+  struct tile_type *ttype = get_tile_type(map_get_terrain(to_x, to_y));
+
+  if (base_mc == PF_IMPOSSIBLE_MC) {
+    return base_mc;
+  }
+
+  /* The move will never take more than one turn. */
+  base_mc = MIN(base_mc, param->move_rate);
+
+  if (hover_state == HOVER_CONNECT) {
+    switch (connect_activity) {
+    case ACTIVITY_IRRIGATE:
+      if (!DIR_IS_CARDINAL(dir)) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      if (tile_has_special(ptile, S_IRRIGATION)) {
+       break;
+      }
+
+      activity_mc = ttype->irrigation_time;
+      if (activity_mc == 0) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      break;
+    case ACTIVITY_ROAD:
+      assert(terrain_control.may_road);
+      if (tile_has_special(ptile, S_ROAD)) {
+       break;
+      }
+      if (ttype->road_time == 0
+         || (map_has_special(to_x, to_y, S_RIVER)
+             && !player_knows_techs_with_flag(param->owner, TF_BRIDGE))) {
+       return PF_IMPOSSIBLE_MC;
+      }
+      activity_mc = ttype->road_time;
+      break;
+    case ACTIVITY_RAILROAD:
+      assert(terrain_control.may_road);
+      if (tile_has_special(ptile, S_RAILROAD)) {
+       break;
+      } else {
+       if (ttype->road_time == 0
+           || (map_has_special(to_x, to_y, S_RIVER)
+               && !player_knows_techs_with_flag(param->owner, TF_BRIDGE))) {
+         return PF_IMPOSSIBLE_MC;
+       }
+       if (!tile_has_special(ptile, S_ROAD)) {
+         /* Have to build road first. */
+         activity_mc += ttype->road_time;
+       }
+       activity_mc += ttype->road_time;
+      }
+      break;
+    default:
+      die("Invalid connect activity.");
+    }
+  }
+
+  activity_mc *= SINGLE_MOVE;
+  base_mc += activity_mc;
+
+  return base_mc;
+}
+
 /********************************************************************** 
   Fill the PF parameter with the correct client-goto values.
 ***********************************************************************/
@@ -375,6 +453,11 @@
   assert(parameter->get_EC == NULL);
   parameter->get_EC = get_EC;
   assert(parameter->get_TB == NULL);
+  assert(parameter->get_MC != NULL);
+  if (hover_state == HOVER_CONNECT) {
+    original_MC = parameter->get_MC;
+    parameter->get_MC = get_connect_MC;
+  }
   if (is_attack_unit(punit) || is_diplomat_unit(punit)) {
     parameter->get_TB = get_TB_aggr;
   } else if (unit_flag(punit, F_TRADE_ROUTE)
@@ -383,7 +466,15 @@
   } else {
     parameter->get_TB = no_fights_or_unknown;
   }
-  parameter->turn_mode = TM_WORST_TIME;
+  if (hover_state == HOVER_CONNECT) {
+    /* In connect mode the "time" includes extra moves needed for the
+     * construction.  PF can't figure out the turns involved here since
+     * we just give it one value.  So we should just look at the total
+     * number of moves required, which will be an excellent approximation. */
+    parameter->turn_mode = TM_NONE;
+  } else {
+    parameter->turn_mode = TM_WORST_TIME;
+  }
   parameter->start_x = punit->x;
   parameter->start_y = punit->y;
 
@@ -523,6 +614,7 @@
       p.dir[i] = get_direction_for_step(old_x, old_y, new_x, new_y);
       freelog(PACKET_LOG_LEVEL, "  packet[%d] = move %s: %d,%d => %d,%d",
              i, dir_get_name(p.dir[i]), old_x, old_y, new_x, new_y);
+      p.activity[i] = ACTIVITY_LAST;
     }
     old_x = new_x;
     old_y = new_y;
@@ -581,6 +673,87 @@
 }
 
 /**************************************************************************
+  Send the current connect route (i.e., the one generated via HOVER_STATE)
+  to the server.
+**************************************************************************/
+void send_connect_route(struct unit *punit, enum unit_activity activity)
+{
+  struct pf_path *path = NULL;
+  int i;
+  struct packet_unit_orders p;
+  int old_x, old_y;
+
+  assert(is_active);
+  assert(punit->id == goto_map.unit_id);
+
+  memset(&p, 0, sizeof(p));
+
+  for (i = 0; i < goto_map.num_parts; i++) {
+    path = pft_concat(path, goto_map.parts[i].path);
+  }
+
+  p.unit_id = punit->id;
+  p.repeat = FALSE;
+  p.vigilant = FALSE; /* Should be TRUE? */
+
+  p.length = 0;
+  old_x = path->positions[0].x;
+  old_y = path->positions[0].y;
+
+  for (i = 0; i < path->length; i++) {
+    switch (activity) {
+    case ACTIVITY_IRRIGATE:
+      if (!map_has_special(old_x, old_y, S_IRRIGATION)) {
+       /* Assume the unit can irrigate or we wouldn't be here. */
+       p.orders[p.length] = ORDER_ACTIVITY;
+       p.activity[p.length] = ACTIVITY_IRRIGATE;
+       p.length++;
+      }
+      break;
+    case ACTIVITY_ROAD:
+    case ACTIVITY_RAILROAD:
+      if (!map_has_special(old_x, old_y, S_ROAD)) {
+       /* Assume the unit can build the road or we wouldn't be here. */
+       p.orders[p.length] = ORDER_ACTIVITY;
+       p.activity[p.length] = ACTIVITY_ROAD;
+       p.length++;
+      }
+      if (activity == ACTIVITY_RAILROAD) {
+       if (!map_has_special(old_x, old_y, S_RAILROAD)) {
+         /* Assume the unit can build the rail or we wouldn't be here. */
+         p.orders[p.length] = ORDER_ACTIVITY;
+         p.activity[p.length] = ACTIVITY_RAILROAD;
+         p.length++;
+       }
+      }
+      break;
+    default:
+      die("Invalid connect activity.");
+      break;
+    }
+
+    if (i != path->length - 1) {
+      int new_x = path->positions[i + 1].x;
+      int new_y = path->positions[i + 1].y;
+
+      assert(!same_pos(new_x, new_y, old_x, old_y));
+
+      p.orders[p.length] = ORDER_MOVE;
+      p.dir[p.length] = get_direction_for_step(old_x, old_y, new_x, new_y);
+      p.length++;
+
+      old_x = new_x;
+      old_y = new_y;
+    }
+  }
+
+  p.dest_x = old_x;
+  p.dest_y = old_y;
+
+  send_packet_unit_orders(&aconnection, &p);
+}
+
+/**************************************************************************
   Send the current goto route (i.e., the one generated via
   HOVER_STATE) to the server.  The route might involve more than one
   part if waypoints were used.  FIXME: danger paths are not supported.
Index: client/goto.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/goto.h,v
retrieving revision 1.12
diff -u -r1.12 goto.h
--- client/goto.h       11 May 2004 17:40:06 -0000      1.12
+++ client/goto.h       17 May 2004 04:56:49 -0000
@@ -33,6 +33,7 @@
 void send_goto_path(struct unit *punit, struct pf_path *path);
 void send_patrol_route(struct unit *punit);
 void send_goto_route(struct unit *punit);
+void send_connect_route(struct unit *punit, enum unit_activity activity);
 
 struct pf_path *path_to_nearest_allied_city(struct unit *punit);
 
Index: client/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.36
diff -u -r1.36 mapctrl_common.c
--- client/mapctrl_common.c     17 May 2004 01:29:46 -0000      1.36
+++ client/mapctrl_common.c     17 May 2004 04:56:50 -0000
@@ -603,7 +603,9 @@
 **************************************************************************/
 void update_line(int canvas_x, int canvas_y)
 {
-  if ((hover_state == HOVER_GOTO || hover_state == HOVER_PATROL)
+  if ((hover_state == HOVER_GOTO
+       || hover_state == HOVER_PATROL
+       || hover_state == HOVER_CONNECT)
       && draw_goto_line) {
     int x, y, old_x, old_y;
 
@@ -623,7 +625,9 @@
 ****************************************************************************/
 void overview_update_line(int overview_x, int overview_y)
 {
-  if ((hover_state == HOVER_GOTO || hover_state == HOVER_PATROL)
+  if ((hover_state == HOVER_GOTO
+       || hover_state == HOVER_PATROL
+       || hover_state == HOVER_CONNECT)
       && draw_goto_line) {
     int x, y, old_x, old_y;
 
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.365
diff -u -r1.365 packhand.c
--- client/packhand.c   15 May 2004 16:33:42 -0000      1.365
+++ client/packhand.c   17 May 2004 04:56:50 -0000
@@ -109,7 +109,6 @@
   }
   punit->activity_target = packet->activity_target;
   punit->paradropped = packet->paradropped;
-  punit->connecting = packet->connecting;
   punit->done_moving = packet->done_moving;
   punit->occupy = packet->occupy;
   if (packet->transported) {
@@ -130,6 +129,7 @@
     for (i = 0; i < punit->orders.length; i++) {
       punit->orders.list[i].order = packet->orders[i];
       punit->orders.list[i].dir = packet->orders_dirs[i];
+      punit->orders.list[i].activity = packet->orders_activities[i];
     }
   }
   return punit;
@@ -1171,7 +1171,6 @@
       clear_goto_dest(punit);
     }
     punit->paradropped = packet_unit->paradropped;
-    punit->connecting = packet_unit->connecting;
     if (punit->done_moving != packet_unit->done_moving) {
       punit->done_moving = packet_unit->done_moving;
       check_focus = TRUE;
Index: client/tilespec.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/tilespec.c,v
retrieving revision 1.167
diff -u -r1.167 tilespec.c
--- client/tilespec.c   5 May 2004 20:39:15 -0000       1.167
+++ client/tilespec.c   17 May 2004 04:56:51 -0000
@@ -1599,13 +1599,11 @@
     }
   }
 
-  if (punit->connecting) {
-    ADD_SPRITE_FULL(sprites.unit.connect);
-  }
-
   if (unit_has_orders(punit)) {
     if (punit->orders.repeat) {
       ADD_SPRITE_FULL(sprites.unit.patrol);
+    } else if (punit->activity != ACTIVITY_IDLE) {
+      ADD_SPRITE_SIMPLE(sprites.unit.connect);
     } else {
       ADD_SPRITE_FULL(sprites.unit.go_to);
     }
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.165
diff -u -r1.165 capstr.c
--- common/capstr.c     11 May 2004 17:18:19 -0000      1.165
+++ common/capstr.c     17 May 2004 04:56:51 -0000
@@ -77,7 +77,7 @@
 #define CAPABILITY "+1.14.delta +last_turns_shield_surplus veteran +orders " \
                    "+starter +union +iso_maps +orders2client " \
                    "+change_production +tilespec1 +no_earth +trans " \
-                   "+want_hack invasions bombard +killstack2"
+                   "+want_hack invasions bombard +killstack2 +connect"
 
 /* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
  *
@@ -115,6 +115,8 @@
  * it's a boolean.
  *
  * "bombard" means units support the bombard ability.
+ *
+ * "connect" means the 'connect' function is done with client orders.
  */
 
 void init_our_capability(void)
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.183
diff -u -r1.183 map.h
--- common/map.h        16 May 2004 19:07:35 -0000      1.183
+++ common/map.h        17 May 2004 04:56:51 -0000
@@ -586,6 +586,7 @@
 struct unit_order {
   enum unit_orders order;
   enum direction8 dir;         /* Only valid for ORDER_MOVE. */
+  enum unit_activity activity; /* Only valid for ORDER_ACTIVITY. */
 };
 
 /* return the reverse of the direction */
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.22
diff -u -r1.22 packets.def
--- common/packets.def  11 May 2004 17:18:19 -0000      1.22
+++ common/packets.def  17 May 2004 04:56:51 -0000
@@ -595,7 +595,7 @@
 
   UINT8 veteran; add-cap(veteran)
   BOOL veteran_old; remove-cap(veteran)
-  BOOL ai, paradropped, connecting, transported, done_moving;
+  BOOL ai, paradropped, transported, done_moving;
 
   UNIT_TYPE type;
   UNIT transported_by; /* Only valid if transported is set. */
@@ -610,6 +610,7 @@
   BOOL orders_repeat, orders_vigilant;
   ORDERS orders[MAX_LEN_ROUTE:orders_length];
   DIRECTION orders_dirs[MAX_LEN_ROUTE:orders_length];
+  ACTIVITY orders_activities[MAX_LEN_ROUTE:orders_length];
 end
 
 PACKET_UNIT_SHORT_INFO=50; is-info,sc,lsend
@@ -681,6 +682,7 @@
   BOOL repeat, vigilant;
   ORDERS orders[MAX_LEN_ROUTE:length];
   DIRECTION dir[MAX_LEN_ROUTE:length];
+  ACTIVITY activity[MAX_LEN_ROUTE:length];
   COORD dest_x, dest_y;
 end
 
@@ -716,13 +718,6 @@
   CITY city_id;
 end
 
-PACKET_UNIT_CONNECT=66;cs
-  UNIT unit_id;
-  ACTIVITY activity_type;
-  COORD dest_x;
-  COORD dest_y;
-end
-
 PACKET_UNIT_BRIBE_INQ=67;cs,handle-per-conn,dsend
   UNIT unit_id;
 end
Index: common/unit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.c,v
retrieving revision 1.209
diff -u -r1.209 unit.c
--- common/unit.c       6 May 2004 21:28:03 -0000       1.209
+++ common/unit.c       17 May 2004 04:56:53 -0000
@@ -748,9 +748,6 @@
               (current == ACTIVITY_FORTIFIED) ? ACTIVITY_FORTIFYING : current;
   bool result;
 
-  if (punit->connecting)
-    return can_unit_do_connect(punit, current);
-
   punit->activity = ACTIVITY_IDLE;
   punit->activity_target = S_NO_SPECIAL;
 
@@ -975,7 +972,6 @@
   punit->activity=new_activity;
   punit->activity_count=0;
   punit->activity_target = S_NO_SPECIAL;
-  punit->connecting = FALSE;
   if (new_activity == ACTIVITY_IDLE && punit->moves_left > 0) {
     /* No longer done. */
     punit->done_moving = FALSE;
@@ -1465,14 +1461,14 @@
                           bool igzoc)
 {
   return MR_OK == test_unit_move_to_tile(punit->type, unit_owner(punit),
-                                        punit->activity, punit->connecting,
+                                        punit->activity,
                                         punit->x, punit->y, dest_x, dest_y,
                                         igzoc);
 }
 
 /**************************************************************************
   unit can be moved if:
-  1) the unit is idle or on goto or connecting.
+  1) the unit is idle or on server goto.
   2) the target location is on the map
   3) the target location is next to the unit
   4) there are no non-allied units on the target tile
@@ -1487,9 +1483,9 @@
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
                                             struct player *unit_owner,
                                             enum unit_activity activity,
-                                            bool connecting, int src_x,
-                                            int src_y, int dest_x,
-                                            int dest_y, bool igzoc)
+                                            int src_x, int src_y,
+                                            int dest_x, int dest_y,
+                                            bool igzoc)
 {
   struct tile *pfromtile, *ptotile;
   bool zoc;
@@ -1497,8 +1493,7 @@
 
   /* 1) */
   if (activity != ACTIVITY_IDLE
-      && activity != ACTIVITY_GOTO
-      && !connecting) {
+      && activity != ACTIVITY_GOTO) {
     return MR_BAD_ACTIVITY;
   }
 
@@ -1679,7 +1674,6 @@
   punit->moves_left = unit_move_rate(punit);
   punit->moved = FALSE;
   punit->paradropped = FALSE;
-  punit->connecting = FALSE;
   punit->done_moving = FALSE;
   if (is_barbarian(pplayer)) {
     punit->fuel = BARBARIAN_LIFE;
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.117
diff -u -r1.117 unit.h
--- common/unit.h       6 May 2004 21:28:03 -0000       1.117
+++ common/unit.h       17 May 2004 04:56:53 -0000
@@ -41,7 +41,7 @@
 
 /* Changing this enum will break savegame and network compatability. */
 enum unit_orders {
-  ORDER_MOVE, ORDER_FINISH_TURN,
+  ORDER_MOVE, ORDER_FINISH_TURN, ORDER_ACTIVITY,
   ORDER_LAST
 };
 
@@ -161,7 +161,6 @@
   bool debug;
   bool moved;
   bool paradropped;
-  bool connecting;
 
   /* This value is set if the unit is done moving for this turn. This
    * information is used by the client.  The invariant is:
@@ -328,9 +327,9 @@
 enum unit_move_result test_unit_move_to_tile(Unit_Type_id type,
                                             struct player *unit_owner,
                                             enum unit_activity activity,
-                                            bool connecting, int src_x,
-                                            int src_y, int dest_x,
-                                            int dest_y, bool igzoc);
+                                            int src_x, int src_y,
+                                            int dest_x, int dest_y,
+                                            bool igzoc);
 bool unit_type_really_ignores_zoc(Unit_Type_id type);
 bool zoc_ok_move(struct unit *punit, int x, int y);
 
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.178
diff -u -r1.178 gotohand.c
--- server/gotohand.c   20 Jan 2004 21:52:09 -0000      1.178
+++ server/gotohand.c   17 May 2004 04:56:53 -0000
@@ -1288,7 +1288,6 @@
   if (same_pos(punit->x, punit->y, dest_x, dest_y) ||
       !goto_is_sane(punit, dest_x, dest_y, FALSE)) {
     punit->activity = ACTIVITY_IDLE;
-    punit->connecting = FALSE;
     send_unit_info(NULL, punit);
     if (same_pos(punit->x, punit->y, dest_x, dest_y)) {
       return GR_ARRIVED;
@@ -1316,7 +1315,6 @@
              pplayer->name, unit_type(punit)->name,
              punit->x, punit->y, dest_x, dest_y);
       punit->activity = ACTIVITY_IDLE;
-      punit->connecting = FALSE;
       send_unit_info(NULL, punit);
       return GR_FAILED;
     }
@@ -1380,13 +1378,6 @@
        return GR_OUT_OF_MOVEPOINTS;
       }
 
-      /* single step connecting unit when it can do it's activity */
-      if (punit->connecting
-         && can_unit_do_activity(punit, punit->activity)) {
-       /* for connecting unit every step is a destination */
-       return GR_ARRIVED;
-      }
-
       freelog(LOG_DEBUG, "Moving on.");
     } while(!same_pos(x, y, waypoint_x, waypoint_y));
   } else {
@@ -1395,17 +1386,11 @@
            pplayer->name, unit_type(punit)->name,
            punit->x, punit->y, dest_x, dest_y);
     handle_unit_activity_request(punit, ACTIVITY_IDLE);
-    punit->connecting = FALSE;
     send_unit_info(NULL, punit);
     return GR_FAILED;
   }
   /** Finished moving the unit for this turn **/
 
-  /* ensure that the connecting unit will perform it's activity
-     on the destination file too. */
-  if (punit->connecting && can_unit_do_activity(punit, punit->activity))
-    return GR_ARRIVED;
-
   /* normally we would just do this unconditionally, but if we had an
      airplane goto we might not be finished even if the loop exited */
   if (same_pos(punit->x, punit->y, dest_x, dest_y)) {
@@ -1416,7 +1401,6 @@
     status = GR_OUT_OF_MOVEPOINTS;
   }
 
-  punit->connecting = FALSE;
   send_unit_info(NULL, punit);
   return status;
 }
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.150
diff -u -r1.150 savegame.c
--- server/savegame.c   15 May 2004 22:41:37 -0000      1.150
+++ server/savegame.c   17 May 2004 04:56:53 -0000
@@ -1110,9 +1110,6 @@
        secfile_lookup_int_default(file, (int) S_NO_SPECIAL,
                                   "player%d.u%d.activity_target", plrno, i);
 
-    punit->connecting=secfile_lookup_bool_default(file, FALSE,
-                                               "player%d.u%d.connecting",
-                                               plrno, i);
     punit->done_moving = secfile_lookup_bool_default(file,
        (punit->moves_left == 0), "player%d.u%d.done_moving", plrno, i);
     /* Load the goto information.  Older savegames will not have the
@@ -1152,7 +1149,7 @@
       int len = secfile_lookup_int_default(file, 0,
                        "player%d.u%d.orders_length", plrno, i);
       if (len > 0) {
-       char *orders_buf, *dir_buf;
+       char *orders_buf, *dir_buf, *act_buf;
 
        punit->orders.list = fc_malloc(len * sizeof(*(punit->orders.list)));
        punit->orders.length = len;
@@ -1167,14 +1164,18 @@
                        "player%d.u%d.orders_list", plrno, i);
        dir_buf = secfile_lookup_str_default(file, "",
                        "player%d.u%d.dir_list", plrno, i);
+       act_buf = secfile_lookup_str_default(file, "",
+                       "player%d.u%d.activity_list", plrno, i);
        for (j = 0; j < len; j++) {
-         if (orders_buf[j] == '\0' || dir_buf == '\0') {
+         if (orders_buf[j] == '\0' || dir_buf[j] == '\0'
+             || act_buf[j] == '\0') {
            freelog(LOG_ERROR, _("Savegame error: invalid unit orders."));
            free_unit_orders(punit);
            break;
          }
          punit->orders.list[j].order = orders_buf[j] - 'a';
          punit->orders.list[j].dir = dir_buf[j] - 'a';
+         punit->orders.list[j].activity = act_buf[j] - 'a';
        }
        punit->has_orders = TRUE;
       } else {
@@ -1570,9 +1571,6 @@
     secfile_insert_int(file, punit->activity_target, 
                                "player%d.u%d.activity_target",
                                plrno, i);
-    secfile_insert_bool(file, punit->connecting, 
-                               "player%d.u%d.connecting",
-                               plrno, i);
     secfile_insert_bool(file, punit->done_moving,
                        "player%d.u%d.done_moving", plrno, i);
     secfile_insert_int(file, punit->moves_left, "player%d.u%d.moves",
@@ -1602,7 +1600,7 @@
                       "player%d.u%d.transported_by", plrno, i);
     if (punit->has_orders) {
       int len = punit->orders.length, j;
-      char orders_buf[len + 1], dir_buf[len + 1];
+      char orders_buf[len + 1], dir_buf[len + 1], act_buf[len + 1];
 
       secfile_insert_int(file, len, "player%d.u%d.orders_length", plrno, i);
       secfile_insert_int(file, punit->orders.index,
@@ -1615,13 +1613,16 @@
       for (j = 0; j < len; j++) {
        orders_buf[j] = 'a' + punit->orders.list[j].order;
        dir_buf[j] = 'a' + punit->orders.list[j].dir;
+       act_buf[j] = 'a' + punit->orders.list[j].activity;
       }
-      orders_buf[len] = dir_buf[len] = '\0';
+      orders_buf[len] = dir_buf[len] = act_buf[len] = '\0';
 
       secfile_insert_str(file, orders_buf,
                         "player%d.u%d.orders_list", plrno, i);
       secfile_insert_str(file, dir_buf,
                         "player%d.u%d.dir_list", plrno, i);
+      secfile_insert_str(file, act_buf,
+                        "player%d.u%d.activity_list", plrno, i);
     } else {
       /* Put all the same fields into the savegame.  Otherwise the
        * registry code gets confused (although it still works). */
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.298
diff -u -r1.298 unithand.c
--- server/unithand.c   13 May 2004 16:38:19 -0000      1.298
+++ server/unithand.c   17 May 2004 04:56:53 -0000
@@ -101,44 +101,6 @@
 }
 
 /**************************************************************************
-Handler for PACKET_UNIT_CONNECT request. The unit is send on way and will 
-build something (roads only for now) along the way, using server-side
-path-finding. 
-
-FIXME: This should be rewritten to use client-side path finding along so 
-that we can show in the client where the road-to-be-built will be and 
-enable the use of waypoints to alter this route. - Per
-**************************************************************************/
-void handle_unit_connect(struct player *pplayer, int unit_id,
-                        enum unit_activity activity_type, int dest_x,
-                        int dest_y)
-{
-  struct unit *punit = player_find_unit_by_id(pplayer, unit_id);
-
-  if (!is_normal_map_pos(dest_x, dest_y) || !punit
-      || !can_unit_do_connect(punit, activity_type)) {
-    return;
-  }
-
-  set_goto_dest(punit, dest_x, dest_y);
-
-  set_unit_activity(punit, activity_type);
-  punit->connecting = TRUE;
-
-  send_unit_info(NULL, punit);
-
-  /* 
-   * Avoid wasting first turn if unit cannot do the activity on the
-   * starting tile.
-   */
-  if (!can_unit_do_activity(punit, activity_type)) {
-    (void) do_unit_goto(punit,
-                       get_activity_move_restriction(activity_type),
-                       FALSE);
-  }
-}
-
-/**************************************************************************
  Upgrade all units of a given type.
 **************************************************************************/
 void handle_unit_type_upgrade(struct player *pplayer, Unit_Type_id type)
@@ -947,7 +909,7 @@
 
   reason =
       test_unit_move_to_tile(punit->type, unit_owner(punit),
-                            punit->activity, punit->connecting,
+                            punit->activity,
                             punit->x, punit->y, dest_x, dest_y, igzoc);
   if (reason == MR_OK)
     return TRUE;
@@ -1599,6 +1561,7 @@
     return;
   }
 
+
   for (i = 0; i < packet->length; i++) {
     switch (packet->orders[i]) {
     case ORDER_MOVE:
@@ -1606,6 +1569,16 @@
        return;
       }
       break;
+    case ORDER_ACTIVITY:
+      switch (packet->activity[i]) {
+      case ACTIVITY_ROAD:
+      case ACTIVITY_RAILROAD:
+      case ACTIVITY_IRRIGATE:
+       break;
+      default:
+       return;
+      }
+      break;
     case ORDER_FINISH_TURN:
       break;
     default:
@@ -1633,6 +1606,7 @@
   for (i = 0; i < packet->length; i++) {
     punit->orders.list[i].order = packet->orders[i];
     punit->orders.list[i].dir = packet->dir[i];
+    punit->orders.list[i].activity = packet->activity[i];
   }
 
   if (!packet->repeat) {
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.292
diff -u -r1.292 unittools.c
--- server/unittools.c  10 May 2004 22:29:20 -0000      1.292
+++ server/unittools.c  17 May 2004 04:56:54 -0000
@@ -593,20 +593,6 @@
 
   unit_restore_movepoints(pplayer, punit);
 
-  if (punit->connecting && !can_unit_do_activity(punit, activity)) {
-    punit->activity_count = 0;
-    if (do_unit_goto(punit, get_activity_move_restriction(activity), FALSE)
-       == GR_DIED) {
-      return;
-    }
-  }
-
-  /* if connecting, automagically build prerequisities first */
-  if (punit->connecting && activity == ACTIVITY_RAILROAD &&
-      !map_has_special(punit->x, punit->y, S_ROAD)) {
-    activity = ACTIVITY_ROAD;
-  }
-
   if (activity == ACTIVITY_EXPLORE) {
     bool more_to_explore = ai_manage_explorer(punit);
 
@@ -779,18 +765,8 @@
     send_tile_info(NULL, punit->x, punit->y);
     unit_list_iterate (map_get_tile(punit->x, punit->y)->units, punit2) {
       if (punit2->activity == activity) {
-       bool alive = TRUE;
-       if (punit2->connecting) {
-         punit2->activity_count = 0;
-         alive = (do_unit_goto(punit2,
-                               get_activity_move_restriction(activity),
-                               FALSE) != GR_DIED);
-       } else {
-         set_unit_activity(punit2, ACTIVITY_IDLE);
-       }
-       if (alive) {
-         send_unit_info(NULL, punit2);
-       }
+       set_unit_activity(punit2, ACTIVITY_IDLE);
+       send_unit_info(NULL, punit2);
       }
     } unit_list_iterate_end;
   }
@@ -1832,7 +1808,6 @@
   }
   packet->activity_target = punit->activity_target;
   packet->paradropped = punit->paradropped;
-  packet->connecting = punit->connecting;
   packet->done_moving = punit->done_moving;
   if (punit->transported_by == -1) {
     packet->transported = FALSE;
@@ -1853,6 +1828,7 @@
     for (i = 0; i < punit->orders.length; i++) {
       packet->orders[i] = punit->orders.list[i].order;
       packet->orders_dirs[i] = punit->orders.list[i].dir;
+      packet->orders_activities[i] = punit->orders.list[i].activity;
     }
   } else {
     packet->orders_length = packet->orders_index = 0;
@@ -2625,8 +2601,7 @@
   if (punit->activity != ACTIVITY_IDLE
       && punit->activity != ACTIVITY_SENTRY
       && punit->activity != ACTIVITY_EXPLORE
-      && punit->activity != ACTIVITY_GOTO
-      && !punit->connecting) {
+      && punit->activity != ACTIVITY_GOTO) {
     set_unit_activity(punit, ACTIVITY_IDLE);
   }
 }
@@ -2910,9 +2885,15 @@
   int unitid = punit->id;
   struct player *pplayer = unit_owner(punit);
   int moves_made = 0;
+  enum unit_activity activity;
 
   assert(unit_has_orders(punit));
 
+  if (punit->activity != ACTIVITY_IDLE) {
+    punit->done_moving = TRUE;
+    return TRUE;
+  }
+
   freelog(LOG_DEBUG, "Executing orders for %s %d",
          unit_name(punit->type), punit->id);   
 
@@ -2972,6 +2953,19 @@
       freelog(LOG_DEBUG, "  waiting this turn");
       send_unit_info(NULL, punit);
       break;
+    case ORDER_ACTIVITY:
+      activity = order.activity;
+      if (!can_unit_do_activity(punit, activity)) {
+       cancel_orders(punit, "  orders canceled because of failed activity");
+       notify_player_ex(pplayer, punit->x, punit->y, E_UNIT_ORDERS,
+                        _("Game: Orders for %s aborted since they "
+                          "give an invalid activity."),
+                        unit_name(punit->type));
+       return TRUE;
+      }
+      set_unit_activity(punit, activity);
+      punit->done_moving = TRUE;
+      break;
     case ORDER_MOVE:
       /* Move unit */
       if (!MAPSTEP(dest_x, dest_y, punit->x, punit->y, order.dir)) {

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