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

[Freeciv-Dev] Re: (PR#7282) Patch: 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) Patch: connect as orders
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 9 Aug 2004 15:00:57 -0700
Reply-to: rt@xxxxxxxxxxx

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

Jason Short wrote:

> One problem is the move time does not take into account the activity 
> time at the current tile.  This is left out of the PF calculation.  We 
> only look at the time at the destination tile, never the source tile. 
> But I guess there should be a check for if(same_pos(src_x, src_y, 
> param->src_x, src_y)) in both get_connect_MC and get_connect_moveEC...

Here's a patch that solves this.  A new function get_activity_MC is 
created.  It is called:

- in get_connect_MC, to determine if the activity / first activity is 
possible.
- In get_connect_moveEC, to determine the activity's MC.
- In update_last_part, to add the time onto the path's time.

It's kindof ugly but better than anything else that came to mind.

I also fixed problems with move_rate versus SINGLE_MOVE.  The EC is now 
the number of _moves_ needed to do the connect, so it gets divided by 
the unit's move_rate.

There are still however some problems with the time.  Getting this right 
will take some tweaking.  If this patch is going to take longer perhaps 
the server and common parts should be committed (since they conflict 
with Ali's extended orders patch).

jason

? diff
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.325
diff -u -r1.325 aiunit.c
--- ai/aiunit.c 7 Aug 2004 17:53:50 -0000       1.325
+++ ai/aiunit.c 9 Aug 2004 21:57:37 -0000
@@ -196,7 +196,7 @@
 
   result =
       test_unit_move_to_tile(punit->type, unit_owner(punit),
-                             ACTIVITY_IDLE, FALSE, punit->x, punit->y, 
+                             ACTIVITY_IDLE, punit->x, punit->y, 
                              dest_x, dest_y, unit_flag(punit, F_IGZOC));
   if (result == MR_OK) {
     return 1;
Index: client/control.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/control.c,v
retrieving revision 1.139
diff -u -r1.139 control.c
--- client/control.c    2 Aug 2004 16:59:14 -0000       1.139
+++ client/control.c    9 Aug 2004 21:57:37 -0000
@@ -633,6 +633,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();
   }
 }
 
@@ -1632,13 +1638,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.70
diff -u -r1.70 goto.c
--- client/goto.c       21 Jun 2004 15:14:43 -0000      1.70
+++ client/goto.c       9 Aug 2004 21:57:37 -0000
@@ -75,6 +75,9 @@
 static void decrement_drawn(int src_x, int src_y, enum direction8 dir);
 static void reset_last_part(void);
 
+static int get_activity_MC(int map_x, int map_y, struct pf_parameter *param);
+
+
 /**************************************************************************
   Various stuff for the goto routes
 **************************************************************************/
@@ -196,7 +199,16 @@
   p->end_x = x;
   p->end_y = y;
   p->end_moves_left = pf_last_position(p->path)->moves_left;
-  p->time = pf_last_position(p->path)->turn;
+
+  if (hover_state == HOVER_CONNECT) {
+    int move_rate = goto_map.template.move_rate;
+    int moves = pf_last_position(p->path)->total_EC
+      + get_activity_MC(p->start_x, p->start_y, &goto_map.template);
+
+    p->time = (moves + move_rate - 1) / move_rate;
+  } else {
+    p->time = pf_last_position(p->path)->turn;
+  }
 
   /* Refresh tiles so turn information is shown. */
   refresh_tile_mapcanvas(old_x, old_y, FALSE);
@@ -375,6 +387,148 @@
   return TB_NORMAL;
 }
 
+/****************************************************************************
+  Return the number of MP needed to do the connect activity at this
+  position.  A negative number means it's impossible.
+****************************************************************************/
+static int get_activity_MC(int map_x, int map_y, struct pf_parameter *param)
+{
+  struct tile *ptile = map_get_tile(map_x, map_y);
+  struct tile_type *ttype = get_tile_type(ptile->terrain);
+  int activity_mc = 0;
+
+  assert(hover_state == HOVER_CONNECT);
+
+  switch (connect_activity) {
+  case ACTIVITY_IRRIGATE:
+    if (ttype->irrigation_time == 0) {
+      return -1;
+    }
+    if (map_has_special(map_x, map_y, S_MINE)) {
+      /* Don't overwrite mines. */
+      return -1;
+    }
+
+    if (tile_has_special(ptile, S_IRRIGATION)) {
+      break;
+    }
+
+    activity_mc = ttype->irrigation_time;
+    break;
+  case ACTIVITY_ROAD:
+    if (!map_has_special(map_x, map_y, S_ROAD)
+       && (ttype->road_time == 0
+           || (map_has_special(map_x, map_y, S_RIVER)
+               && !player_knows_techs_with_flag(param->owner,
+                                                TF_BRIDGE)))) {
+      return PF_IMPOSSIBLE_MC;
+    }
+    assert(terrain_control.may_road);
+    if (tile_has_special(ptile, S_ROAD)) {
+      break;
+    }
+    activity_mc = ttype->road_time;
+    break;
+  case ACTIVITY_RAILROAD:
+    assert(terrain_control.may_road);
+    if (!map_has_special(map_x, map_y, S_RAILROAD)
+       && (ttype->road_time == 0
+           || (map_has_special(map_x, map_y, S_RIVER)
+               && !player_knows_techs_with_flag(param->owner,
+                                                TF_BRIDGE)))) {
+      return PF_IMPOSSIBLE_MC;
+    }
+
+    if (tile_has_special(ptile, S_RAILROAD)) {
+      break;
+    } else {
+      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.");
+  }
+
+  return activity_mc * param->move_rate;
+}
+
+/****************************************************************************
+  PF callback for the cost of a connect.  In connect mode we are primarily
+  concerned with number of steps.
+****************************************************************************/
+static int get_connect_MC(int src_x, int src_y, enum direction8 dir,
+                         int dest_x, int dest_y, struct pf_parameter *param)
+{
+  int (*original_MC) (int src_x, int src_y, enum direction8 dir,
+                     int dest_x, int dest_y,
+                     struct pf_parameter *param) = param->data;
+  int base_mc = original_MC(src_x, src_y, dir, dest_x, dest_y, param);
+  int activity_mc = get_activity_MC(dest_x, dest_y, param);
+  int activity_mc2 = 0;
+
+  if (same_pos(src_x, src_y, param->start_x, param->start_y)) {
+    activity_mc2 = get_activity_MC(src_x, src_y, param);
+  }
+
+  if (base_mc == PF_IMPOSSIBLE_MC || activity_mc < 0 || activity_mc2 < 0) {
+    return PF_IMPOSSIBLE_MC;
+  }
+
+  assert(hover_state == HOVER_CONNECT);
+  switch (connect_activity) {
+  case ACTIVITY_IRRIGATE:
+    if (!is_cardinal_dir(dir)) {
+      /* Only cardinal moves allowed. */
+      return PF_IMPOSSIBLE_MC;
+    }
+
+    /* Otherwise distance doesn't matter. */
+    return 0;
+  case ACTIVITY_ROAD:
+    /* We just want a minimal distance path. */
+    return SINGLE_MOVE;
+  case ACTIVITY_RAILROAD:
+    /* We don't care about distance, just build time. */
+    return 0;
+  default:
+    break;
+  }
+
+  assert(0);
+  return 0;
+}
+
+/****************************************************************************
+  PF callback for the cost of a connect.  In connect mode we are secondarily
+  concerned with build time (including travel and activity time).
+****************************************************************************/
+static int get_connect_moveEC(int src_x, int src_y, enum direction8 dir,
+                             int dest_x, int dest_y,
+                             struct pf_parameter *param)
+{
+  int base_mc;
+  int activity_mc = get_activity_MC(dest_x, dest_y, param);
+
+  if (activity_mc > 0) {
+    /* Assume it takes one turn to get to this tile. */
+    base_mc = param->move_rate;
+  } else {
+    int (*original_MC) (int src_x, int src_y, enum direction8 dir,
+                       int dest_x, int dest_y,
+                       struct pf_parameter *param) = param->data;
+
+    /* No activity; just moving through. */
+    base_mc = original_MC(src_x, src_y, dir, dest_x, dest_y, param);
+    base_mc = MIN(base_mc, param->move_rate);
+  }
+
+  return base_mc + activity_mc;
+}
+
 /********************************************************************** 
   Fill the PF parameter with the correct client-goto values.
 ***********************************************************************/
@@ -385,6 +539,13 @@
   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) {
+    parameter->data = parameter->get_MC;
+    parameter->get_MC = get_connect_MC;
+    parameter->get_moveEC = get_connect_moveEC;
+    parameter->is_pos_dangerous = NULL;
+  }
   if (is_attack_unit(punit) || is_diplomat_unit(punit)) {
     parameter->get_TB = get_TB_aggr;
   } else if (unit_flag(punit, F_TRADE_ROUTE)
@@ -393,7 +554,11 @@
   } else {
     parameter->get_TB = no_fights_or_unknown;
   }
+
+  /* Note that in connect mode the "time" does not correspond to any actual
+   * move rate. */
   parameter->turn_mode = TM_WORST_TIME;
+
   parameter->start_x = punit->x;
   parameter->start_y = punit->y;
 
@@ -550,6 +715,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;
@@ -608,6 +774,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.13
diff -u -r1.13 goto.h
--- client/goto.h       21 Jun 2004 15:14:43 -0000      1.13
+++ client/goto.h       9 Aug 2004 21:57:37 -0000
@@ -36,6 +36,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.39
diff -u -r1.39 mapctrl_common.c
--- client/mapctrl_common.c     2 Aug 2004 16:59:14 -0000       1.39
+++ client/mapctrl_common.c     9 Aug 2004 21:57:37 -0000
@@ -625,7 +625,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;
 
@@ -645,7 +647,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.393
diff -u -r1.393 packhand.c
--- client/packhand.c   2 Aug 2004 16:59:14 -0000       1.393
+++ client/packhand.c   9 Aug 2004 21:57:38 -0000
@@ -105,7 +105,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) {
@@ -126,6 +125,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;
@@ -1183,7 +1183,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.194
diff -u -r1.194 tilespec.c
--- client/tilespec.c   3 Aug 2004 00:09:44 -0000       1.194
+++ client/tilespec.c   9 Aug 2004 21:57:38 -0000
@@ -2001,13 +2001,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.175
diff -u -r1.175 capstr.c
--- common/capstr.c     30 Jul 2004 20:40:49 -0000      1.175
+++ common/capstr.c     9 Aug 2004 21:57:40 -0000
@@ -78,7 +78,7 @@
                    "+change_production +tilespec1 +no_earth +trans " \
                    "+want_hack invasions bombard +killstack2 spec +spec2 " \
                    "+city_map startunits +turn_last_built +happyborders " \
-                   "+connid +love"
+                   "+connid +love +connect"
 
 /* "+1.14.delta" is the new delta protocol for 1.14.0-dev.
  *
@@ -136,6 +136,8 @@
  * info sent to clients.
  * 
  * "love" means that we show the AI love for you in the client
+ *
+ * "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.203
diff -u -r1.203 map.h
--- common/map.h        5 Aug 2004 10:41:34 -0000       1.203
+++ common/map.h        9 Aug 2004 21:57:40 -0000
@@ -575,6 +575,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.36
diff -u -r1.36 packets.def
--- common/packets.def  30 Jul 2004 20:40:49 -0000      1.36
+++ common/packets.def  9 Aug 2004 21:57:40 -0000
@@ -606,7 +606,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. */
@@ -621,6 +621,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
@@ -692,6 +693,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
 
@@ -727,13 +729,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.214
diff -u -r1.214 unit.c
--- common/unit.c       2 Aug 2004 16:59:14 -0000       1.214
+++ common/unit.c       9 Aug 2004 21:57:40 -0000
@@ -784,9 +784,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;
 
@@ -1011,7 +1008,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;
@@ -1501,14 +1497,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
@@ -1523,9 +1519,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;
@@ -1533,8 +1529,7 @@
 
   /* 1) */
   if (activity != ACTIVITY_IDLE
-      && activity != ACTIVITY_GOTO
-      && !connecting) {
+      && activity != ACTIVITY_GOTO) {
     return MR_BAD_ACTIVITY;
   }
 
@@ -1743,7 +1738,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.121
diff -u -r1.121 unit.h
--- common/unit.h       2 Aug 2004 16:59:14 -0000       1.121
+++ common/unit.h       9 Aug 2004 21:57:40 -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:
@@ -336,9 +335,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.181
diff -u -r1.181 gotohand.c
--- server/gotohand.c   9 Aug 2004 05:24:35 -0000       1.181
+++ server/gotohand.c   9 Aug 2004 21:57:41 -0000
@@ -1315,7 +1315,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;
@@ -1343,7 +1342,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;
     }
@@ -1407,13 +1405,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 {
@@ -1422,17 +1413,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)) {
@@ -1443,7 +1428,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.175
diff -u -r1.175 savegame.c
--- server/savegame.c   8 Aug 2004 15:09:12 -0000       1.175
+++ server/savegame.c   9 Aug 2004 21:57:41 -0000
@@ -1200,9 +1200,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);
 
@@ -1252,7 +1249,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;
@@ -1267,14 +1264,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 {
@@ -2253,9 +2254,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",
@@ -2286,7 +2284,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,
@@ -2299,13 +2297,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.301
diff -u -r1.301 unithand.c
--- server/unithand.c   8 Aug 2004 14:15:14 -0000       1.301
+++ server/unithand.c   9 Aug 2004 21:57:41 -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;
@@ -1619,6 +1581,7 @@
     return;
   }
 
+
   for (i = 0; i < packet->length; i++) {
     switch (packet->orders[i]) {
     case ORDER_MOVE:
@@ -1626,6 +1589,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:
@@ -1653,6 +1626,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.297
diff -u -r1.297 unittools.c
--- server/unittools.c  6 Aug 2004 14:46:28 -0000       1.297
+++ server/unittools.c  9 Aug 2004 21:57:42 -0000
@@ -594,20 +594,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);
 
@@ -780,18 +766,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;
   }
@@ -1833,7 +1809,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;
@@ -1854,6 +1829,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;
@@ -2626,8 +2602,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);
   }
 }
@@ -2927,9 +2902,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);   
 
@@ -2989,6 +2970,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]