Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2003:
[Freeciv-Dev] (PR#3524) another look at the goto_dest problem
Home

[Freeciv-Dev] (PR#3524) another look at the goto_dest problem

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] (PR#3524) another look at the goto_dest problem
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 1 Mar 2003 14:24:22 -0800
Reply-to: rt@xxxxxxxxxxxxxx

[jdorje - Wed Feb 26 08:50:45 2003]:

> Finally, I ran into what could end up being a big problem in the network 
> code.  The network sends the goto_dest coordinates as an unsigned 8-bit 
> integer.  Initially this meant sending (-1,-1) was translated into 
> (255,255) and caused a client error.  To avoid this I changed it to a 
> signed 16-bit integer value.  In the general case, the use of uint8 
> could be a major problem since it places an unreasonable limitation on 
> the size of the map - a 200x100 iso-rectangular map will exceed these 
> bounds.  If the uint8 is used everywhere when sending coordinates (as I 
> expect it is), then we'll have another set of problems. (I've tried 
> running the corecleanups on large maps in the past, with very bad 
> results.  Perhaps this is one of the reasons.)

Looks like I'm completely wrong - (255,255) is never a normal position
given the current constraints.

Here's a new patch, with the network changes removed and updated for
CVS.  I get no errors with this one (which isn't to say there aren't any
out there somewhere).

jason

Index: ai/aiair.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiair.c,v
retrieving revision 1.12
diff -u -r1.12 aiair.c
--- ai/aiair.c  2003/02/17 22:49:27     1.12
+++ ai/aiair.c  2003/03/01 22:19:50
@@ -165,7 +165,7 @@
 /**********************************************************************
  * Find something to bomb
  * Air-units specific victim search
- * Returns the want for the best target, records target in goto_dest_x,y
+ * Returns the want for the best target, records target in punit's goto_dest
  * TODO: take counterattack dangers into account
  * TODO: make separate handicaps for air units seeing targets
  *       IMO should be more restrictive than general H_MAP, H_FOG
@@ -208,8 +208,7 @@
        && (air_can_move_between (max_dist, x, y, x1, y1, pplayer) >= 0)){
       int new_best = ai_evaluate_tile_for_air_attack(punit, x1, y1);
       if (new_best > best) {
-       punit->goto_dest_x = x1;
-       punit->goto_dest_y = y1;
+       set_goto_dest(punit, x1, y1);
        best = new_best;
        freelog(LOG_DEBUG, "%s wants to attack tile (%d, %d)", 
                unit_type(punit)->name, x1, y1);
@@ -305,19 +304,18 @@
 
     if (punit->activity == ACTIVITY_GOTO
       /* We are on a GOTO.  Check if it will get us anywhere */
-       && is_airunit_refuel_point(punit->goto_dest_x, punit->goto_dest_y, 
+       && is_airunit_refuel_point(goto_dest_x(punit), goto_dest_y(punit), 
                                   pplayer, punit->type, FALSE)
        && air_can_move_between (punit->moves_left/SINGLE_MOVE, 
                                  punit->x, punit->y, 
-                                punit->goto_dest_x, punit->goto_dest_y,
+                                goto_dest_x(punit), goto_dest_y(punit),
                                 pplayer) >= 0) {
       /* It's an ok GOTO, just go there */
       result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
     } else if (find_nearest_airbase(punit->x, punit->y, punit, 
                             &refuel_x, &refuel_y)) {
       /* Go refuelling */
-      punit->goto_dest_x = refuel_x;
-      punit->goto_dest_y = refuel_y;
+      set_goto_dest(punit, refuel_x, refuel_y);
       freelog(LOG_DEBUG, "Sent %s to refuel", unit_type(punit)->name);
       set_unit_activity(punit, ACTIVITY_GOTO);
       result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
@@ -338,9 +336,10 @@
   } else if (punit->fuel == unit_type(punit)->fuel
             && find_something_to_bomb(punit, punit->x, punit->y) > 0) {
 
-    /* Found target, coordinates are in punit->goto_dest_[xy]
+    /* Found target, coordinates are in punit's goto_dest.
      * TODO: separate attacking into a function, check for the best 
      * tile to attack from */
+    assert(is_goto_dest_set(punit));
     set_unit_activity(punit, ACTIVITY_GOTO);
     if (!ai_unit_gothere(punit)) {
       return; /* died */
@@ -350,11 +349,12 @@
 
     /* We could use ai_military_findvictim here, but I don't trust it... */
     set_unit_activity(punit, ACTIVITY_IDLE);
-    if (is_tiles_adjacent(punit->x, punit->y, 
-                         punit->goto_dest_x, punit->goto_dest_y)) {
+    if (is_goto_dest_set(punit)
+       && is_tiles_adjacent(punit->x, punit->y, 
+                            goto_dest_x(punit), goto_dest_y(punit))) {
       int id = punit->id;
-      (void) handle_unit_move_request(punit, punit->goto_dest_x,
-                                     punit->goto_dest_y, TRUE, FALSE);
+      (void) handle_unit_move_request(punit, goto_dest_x(punit),
+                                     goto_dest_y(punit), TRUE, FALSE);
       if ((punit = find_unit_by_id(id)) != NULL && punit->moves_left > 0) {
        /* Fly home now */
        ai_manage_airunit(pplayer, punit);
@@ -372,8 +372,7 @@
               unit_type(punit)->name, dest_x, dest_y, 
               (map_get_city(dest_x, dest_y) ? 
                map_get_city(dest_x, dest_y)->name : ""));
-      punit->goto_dest_x = dest_x;
-      punit->goto_dest_y = dest_y;
+      set_goto_dest(punit, dest_x, dest_y);
       set_unit_activity(punit, ACTIVITY_GOTO);
       result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
     } else {
Index: ai/aidiplomat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aidiplomat.c,v
retrieving revision 1.14
diff -u -r1.14 aidiplomat.c
--- ai/aidiplomat.c     2003/02/27 22:14:37     1.14
+++ ai/aidiplomat.c     2003/03/01 22:19:50
@@ -576,7 +576,8 @@
   /* If we have a role, we have a valid goto. Check if we have a valid city. */
   if (punit->ai.ai_role == AIUNIT_ATTACK
       || punit->ai.ai_role == AIUNIT_DEFEND_HOME) {
-    ctarget = map_get_city(punit->goto_dest_x, punit->goto_dest_y);
+    assert(is_goto_dest_set(punit));
+    ctarget = map_get_city(goto_dest_x(punit), goto_dest_y(punit));
   }
 
   /* Check if existing target still makes sense */
@@ -651,12 +652,12 @@
   /* Check if we can do something with our destination now. */
   if (punit->ai.ai_role == AIUNIT_ATTACK) {
     int dist = real_map_distance(punit->x, punit->y,
-                                 punit->goto_dest_x,
-                                 punit->goto_dest_y);
+                                 goto_dest_x(punit),
+                                 goto_dest_y(punit));
     UNIT_LOG(LOG_DIPLOMAT, punit, "attack, dist %d to %s (%s goto)"
              "[%d mc]", dist, ctarget ? ctarget->name : "(none)", 
              punit->activity == ACTIVITY_GOTO ? "has" : "no",
-             WARMAP_COST(punit->goto_dest_x, punit->goto_dest_y));
+             WARMAP_COST(goto_dest_x(punit), goto_dest_y(punit)));
     if (dist == 1) {
       /* Do our stuff */
       ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
Index: ai/ailog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/ailog.c,v
retrieving revision 1.6
diff -u -r1.6 ailog.c
--- ai/ailog.c  2003/02/17 22:49:27     1.6
+++ ai/ailog.c  2003/03/01 22:19:50
@@ -68,15 +68,23 @@
   char buffer2[500];
   va_list ap;
   int minlevel = MIN(LOGLEVEL_UNIT, level);
+  int gx, gy;
 
   if (minlevel > fc_log_level) {
     return;
   }
 
+  if (is_goto_dest_set(punit)) {
+    gx = goto_dest_x(punit);
+    gy = goto_dest_y(punit);
+  } else {
+    gx = gy = -1;
+  }
+  
   my_snprintf(buffer, sizeof(buffer), "%s's %s[%d] (%d,%d)->(%d,%d){%d} ",
               unit_owner(punit)->name, unit_type(punit)->name,
               punit->id, punit->x, punit->y,
-              punit->goto_dest_x, punit->goto_dest_y, 
+             gx, gy,
               punit->ai.bodyguard);
 
   va_start(ap, msg);
@@ -100,12 +108,20 @@
     char buffer[500];
     char buffer2[500];
     va_list ap;
+    int gx, gy;
+
+    if (is_goto_dest_set(punit)) {
+      gx = goto_dest_x(punit);
+      gy = goto_dest_y(punit);
+    } else {
+      gx = gy = -1;
+    }
 
     my_snprintf(buffer, sizeof(buffer),
                 "%s's %s[%d] on GOTO (%d,%d)->(%d,%d) %s : ",
                 unit_owner(punit)->name, unit_type(punit)->name,
                 punit->id, punit->x, punit->y,
-                punit->goto_dest_x, punit->goto_dest_y,
+               gx, gy,
                (result == GR_FAILED) ? "failed" : "fought");
 
     va_start(ap, msg);
Index: ai/aitools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aitools.c,v
retrieving revision 1.81
diff -u -r1.81 aitools.c
--- ai/aitools.c        2003/02/27 22:14:37     1.81
+++ ai/aitools.c        2003/03/01 22:19:51
@@ -87,8 +87,7 @@
   CHECK_MAP_POS(pcity->x, pcity->y);
   punit->x = pcity->x;
   punit->y = pcity->y;
-  punit->goto_dest_x = 0;
-  punit->goto_dest_y = 0;
+  clear_goto_dest(punit);
   punit->veteran = make_veteran;
   punit->homecity = pcity->id;
   punit->upkeep = 0;
@@ -144,8 +143,8 @@
 bool ai_unit_gothere(struct unit *punit)
 {
   CHECK_UNIT(punit);
-  assert(punit->goto_dest_x != -1 && punit->goto_dest_y != -1);
-  if (ai_unit_goto(punit, punit->goto_dest_x, punit->goto_dest_y)) {
+  assert(is_goto_dest_set(punit));
+  if (ai_unit_goto(punit, goto_dest_x(punit), goto_dest_y(punit))) {
     return TRUE; /* ... and survived */
   } else {
     return FALSE; /* we died */
@@ -161,19 +160,27 @@
 bool ai_unit_goto(struct unit *punit, int x, int y)
 {
   enum goto_result result;
-  int oldx = punit->goto_dest_x, oldy = punit->goto_dest_y;
+  int oldx = -1, oldy = -1;
   enum unit_activity activity = punit->activity;
+  bool is_set = is_goto_dest_set(punit);
 
+  if (is_set) {
+    oldx = goto_dest_x(punit);
+    oldy = goto_dest_y(punit);
+  }
+
   CHECK_UNIT(punit);
   /* TODO: log error on same_pos with punit->x|y */
-  punit->goto_dest_x = x;
-  punit->goto_dest_y = y;
+  set_goto_dest(punit, x, y);
   handle_unit_activity_request(punit, ACTIVITY_GOTO);
   result = do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
   if (result != GR_DIED) {
     handle_unit_activity_request(punit, activity);
-    punit->goto_dest_x = oldx;
-    punit->goto_dest_y = oldy;
+    if (is_set) {
+      set_goto_dest(punit, oldx, oldy);
+    } else {
+      clear_goto_dest(punit);
+    }
     return TRUE;
   }
   return FALSE;
@@ -195,8 +202,8 @@
   }
 
   if (punit->ai.ai_role == AIUNIT_BUILD_CITY) {
-    assert(is_normal_map_pos(punit->goto_dest_x, punit->goto_dest_y));
-    remove_city_from_minimap(punit->goto_dest_x, punit->goto_dest_y);
+    assert(is_goto_dest_set(punit));
+    remove_city_from_minimap(goto_dest_x(punit), goto_dest_y(punit));
   }
 
   if (charge && (charge->ai.bodyguard == punit->id)) {
@@ -211,12 +218,9 @@
    * stringent, but for now we don't want to break things too badly. */
   if (x == -1 && y == -1) {
     /* No goto_dest. */
-    punit->goto_dest_x = 0;
-    punit->goto_dest_y = 0;
+    clear_goto_dest(punit);
   } else {
-    assert(is_normal_map_pos(x, y));
-    punit->goto_dest_x = x;
-    punit->goto_dest_y = y;
+    set_goto_dest(punit, x, y);
   }
 
   if (punit->ai.ai_role == AIUNIT_NONE && bodyguard) {
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.267
diff -u -r1.267 aiunit.c
--- ai/aiunit.c 2003/02/27 22:28:41     1.267
+++ ai/aiunit.c 2003/03/01 22:19:53
@@ -1373,10 +1373,10 @@
         handle_unit_activity_request(punit, ACTIVITY_SENTRY);
         ferryboat->ai.passenger = punit->id;
 /* the code that worked for settlers wasn't good for piles of cannons */
-        if (find_beachhead(punit, dest_x, dest_y, &ferryboat->goto_dest_x,
-               &ferryboat->goto_dest_y) != 0) {
-          punit->goto_dest_x = dest_x;
-          punit->goto_dest_y = dest_y;
+        if (is_goto_dest_set(punit)
+           && find_beachhead(punit, dest_x, dest_y, &goto_dest_x(ferryboat),
+                             &goto_dest_y(ferryboat)) != 0) {
+         set_goto_dest(punit, dest_x, dest_y);
           handle_unit_activity_request(punit, ACTIVITY_SENTRY);
          if (ground_unit_transporter_capacity(punit->x, punit->y, pplayer)
              <= 0) {
@@ -1411,8 +1411,7 @@
 bodyguard, or 3) we are going to an empty city.  Previously, cannons
 would disembark before the cruisers arrived and die. -- Syela */
 
-      punit->goto_dest_x = dest_x;
-      punit->goto_dest_y = dest_y;
+      set_goto_dest(punit, dest_x, dest_y);
 
 /* The following code block is supposed to stop units from running away from 
their
 bodyguards, and not interfere with those that don't have bodyguards nearby -- 
Syela */
@@ -1809,8 +1808,9 @@
   CHECK_UNIT(punit);
 
   if (dest) {
-    x = punit->goto_dest_x;
-    y = punit->goto_dest_y;
+    assert(is_goto_dest_set(punit));
+    x = goto_dest_x(punit);
+    y = goto_dest_y(punit);
   } else {
     x = punit->x;
     y = punit->y;
@@ -1915,8 +1915,9 @@
     /* dealing with invasion stuff */
     if (IS_ATTACKER(aunit)) {
       if (aunit->activity == ACTIVITY_GOTO) {
+       assert(is_goto_dest_set(aunit));
         invasion_funct(aunit, TRUE, 0, (COULD_OCCUPY(aunit) ? 1 : 2));
-        if ((pcity = map_get_city(aunit->goto_dest_x, aunit->goto_dest_y))) {
+        if ((pcity = map_get_city(goto_dest_x(aunit), goto_dest_y(aunit)))) {
           pcity->ai.attack += unit_belligerence_basic(aunit);
           pcity->ai.bcost += unit_type(aunit)->build_cost;
         } 
@@ -2472,7 +2473,11 @@
       }
       p++;
       bodyguard = unit_list_find(&map_get_tile(punit->x, punit->y)->units, 
aunit->ai.bodyguard);
-      pcity = map_get_city(aunit->goto_dest_x, aunit->goto_dest_y);
+      if (is_goto_dest_set(aunit)) {
+       pcity = map_get_city(goto_dest_x(aunit), goto_dest_y(aunit));
+      } else {
+       pcity = NULL;
+      }
       if (aunit->ai.bodyguard == BODYGUARD_NONE || bodyguard ||
          (pcity && pcity->ai.invasion >= 2)) {
        if (pcity) {
@@ -2501,15 +2506,13 @@
   if (p != 0) {
     freelog(LOG_DEBUG, "%s#%d@(%d,%d), p=%d, n=%d",
                  unit_name(punit->type), punit->id, punit->x, punit->y, p, n);
-    if (punit->moves_left > 0 && n != 0) {
+    if (is_goto_dest_set(punit) && punit->moves_left > 0 && n != 0) {
       (void) ai_unit_gothere(punit);
     } else if (n == 0 && !map_get_city(punit->x, punit->y)) { /* rest in a 
city, for unhap */
-      x = punit->goto_dest_x; y = punit->goto_dest_y;
       port = find_nearest_safe_city(punit);
       if (port && !ai_unit_goto(punit, port->x, port->y)) {
         return; /* oops! */
       }
-      punit->goto_dest_x = x; punit->goto_dest_y = y;
       send_unit_info(pplayer, punit); /* to get the crosshairs right -- Syela 
*/
     } else {
       UNIT_LOG(LOG_DEBUG, punit, "Ferryboat %d@(%d,%d) stalling.",
@@ -2567,8 +2570,7 @@
   } unit_list_iterate_end;
   if (best < 4 * unit_type(punit)->move_rate) {
     /* Pickup is within 4 turns to grab, so move it! */
-    punit->goto_dest_x = x;
-    punit->goto_dest_y = y;
+    set_goto_dest(punit, x, y);
     UNIT_LOG(LOG_DEBUG, punit, "Found a friend and going to him @(%d, %d)",
              x, y);
     (void) ai_unit_gothere(punit);
@@ -2583,8 +2585,7 @@
   if (pcity) {
     if (!ai_handicap(pplayer, H_TARGETS) ||
         unit_move_turns(punit, pcity->x, pcity->y) < p) {
-      punit->goto_dest_x = pcity->x;
-      punit->goto_dest_y = pcity->y;
+      set_goto_dest(punit, pcity->x, pcity->y);
       UNIT_LOG(LOG_DEBUG, punit, "No friends.  Going home.");
       (void) ai_unit_gothere(punit);
       return;
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.293
diff -u -r1.293 packhand.c
--- client/packhand.c   2003/02/20 23:00:55     1.293
+++ client/packhand.c   2003/03/01 22:19:55
@@ -97,8 +97,11 @@
   punit->upkeep_gold = packet->upkeep_gold;
   punit->ai.control = packet->ai;
   punit->fuel = packet->fuel;
-  punit->goto_dest_x = packet->goto_dest_x;
-  punit->goto_dest_y = packet->goto_dest_y;
+  if (is_normal_map_pos(packet->goto_dest_x, packet->goto_dest_y)) {
+    set_goto_dest(punit, packet->goto_dest_x, packet->goto_dest_y);
+  } else {
+    clear_goto_dest(punit);
+  }
   punit->activity_target = packet->activity_target;
   punit->paradropped = packet->paradropped;
   punit->connecting = packet->connecting;
@@ -1006,7 +1009,7 @@
           && (!game.player_ptr->ai.control || ai_popup_windows)
           && punit->owner==game.player_idx
           && (punit->activity!=ACTIVITY_GOTO ||
-              same_pos(punit->goto_dest_x, punit->goto_dest_y,
+              same_pos(goto_dest_x(punit), goto_dest_y(punit),
                        pcity->x, pcity->y))
           && (unit_can_help_build_wonder_here(punit)
               || unit_can_est_traderoute_here(punit))) {
@@ -1042,8 +1045,11 @@
     punit->moves_left=packet->movesleft;
     punit->bribe_cost=0;
     punit->fuel=packet->fuel;
-    punit->goto_dest_x=packet->goto_dest_x;
-    punit->goto_dest_y=packet->goto_dest_y;
+    if (is_normal_map_pos(packet->goto_dest_x, packet->goto_dest_y)) {
+      set_goto_dest(punit, packet->goto_dest_x, packet->goto_dest_y);
+    } else {
+      clear_goto_dest(punit);
+    }
     punit->paradropped=packet->paradropped;
     punit->connecting=packet->connecting;
   
Index: client/gui-gtk/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/mapctrl.c,v
retrieving revision 1.76
diff -u -r1.76 mapctrl.c
--- client/gui-gtk/mapctrl.c    2003/02/17 22:49:27     1.76
+++ client/gui-gtk/mapctrl.c    2003/03/01 22:19:55
@@ -158,8 +158,9 @@
                    ptype->hp, punit->veteran ? _(" V") : "", uc);
 
         if(punit->activity == ACTIVITY_GOTO || punit->connecting)  {
-         cross_head->x = punit->goto_dest_x;
-         cross_head->y = punit->goto_dest_y;
+         assert(is_goto_dest_set(punit));
+         cross_head->x = goto_dest_x(punit);
+         cross_head->y = goto_dest_y(punit);
          cross_head++;
         }
       } else {
Index: client/gui-gtk-2.0/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/mapctrl.c,v
retrieving revision 1.17
diff -u -r1.17 mapctrl.c
--- client/gui-gtk-2.0/mapctrl.c        2003/02/17 22:49:27     1.17
+++ client/gui-gtk-2.0/mapctrl.c        2003/03/01 22:19:55
@@ -167,8 +167,9 @@
                    ptype->hp, punit->veteran ? _(" V") : "", uc);
 
         if(punit->activity == ACTIVITY_GOTO || punit->connecting)  {
-         cross_head->x = punit->goto_dest_x;
-         cross_head->y = punit->goto_dest_y;
+         assert(is_goto_dest_set(punit));
+         cross_head->x = goto_dest_x(punit);
+         cross_head->y = goto_dest_y(punit);
          cross_head++;
         }
       } else {
Index: client/gui-win32/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-win32/mapctrl.c,v
retrieving revision 1.20
diff -u -r1.20 mapctrl.c
--- client/gui-win32/mapctrl.c  2003/02/17 22:49:27     1.20
+++ client/gui-win32/mapctrl.c  2003/03/01 22:19:56
@@ -193,8 +193,9 @@
                  ptype->hp, punit->veteran?_(" V"):"", uc);
       
       if(punit->activity==ACTIVITY_GOTO || punit->connecting)  {
-       cross_head->x = punit->goto_dest_x;
-       cross_head->y = punit->goto_dest_y;
+       assert(is_goto_dest_set(punit));
+       cross_head->x = goto_dest_x(punit);
+       cross_head->y = goto_dest_y(punit);
        cross_head++;
       }
     } else {
Index: client/gui-xaw/mapctrl.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-xaw/mapctrl.c,v
retrieving revision 1.64
diff -u -r1.64 mapctrl.c
--- client/gui-xaw/mapctrl.c    2003/02/17 22:49:27     1.64
+++ client/gui-xaw/mapctrl.c    2003/03/01 22:19:56
@@ -167,8 +167,9 @@
                ptype->hp, punit->veteran?_(" V"):"", uc);
 
         if(punit->activity==ACTIVITY_GOTO)  {
-         cross_head->x = punit->goto_dest_x;
-         cross_head->y = punit->goto_dest_y;
+         assert(is_goto_dest_set(punit));
+         cross_head->x = goto_dest_x(punit);
+         cross_head->y = goto_dest_y(punit);
          cross_head++;
         }
       } else {
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.126
diff -u -r1.126 capstr.c
--- common/capstr.c     2003/02/17 22:49:27     1.126
+++ common/capstr.c     2003/03/01 22:19:56
@@ -76,7 +76,7 @@
 
 #define CAPABILITY "+1.14.0 conn_info +occupied team tech_impr_gfx " \
                    "city_struct_minor_cleanup obsolete_last class_legend " \
-                   "+impr_req +waste +fastfocus +continent"
+                   "+impr_req +waste +fastfocus +continent +goto_dest"
   
 /* "+1.14.0" is protocol for 1.14.0 release.
  *
@@ -109,6 +109,9 @@
  * "fastfocus" removes the server from client unit focus.
  *
  * +continent": the server gives the client continent information
+ *
+ * +goto_dest: send a non-normal position (currently 255,255) when a unit has
+ * no goto_dest.
  */
 
 void init_our_capability(void)
Index: common/unit.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/unit.h,v
retrieving revision 1.95
diff -u -r1.95 unit.h
--- common/unit.h       2003/02/17 22:49:28     1.95
+++ common/unit.h       2003/03/01 22:19:58
@@ -121,7 +121,9 @@
   int bribe_cost;
   struct unit_ai ai;
   enum unit_activity activity;
-  int goto_dest_x, goto_dest_y;
+  struct {
+    int x, y;
+  } goto_dest;
   int activity_count;
   enum tile_special_type activity_target;
   enum unit_focus_status focus_status;
@@ -135,6 +137,17 @@
   struct goto_route *pgr;
 };
 
+/* Wrappers for accessing the goto destination of a unit.  This goto_dest
+ * is used by client goto as well as by the AI. */
+#define is_goto_dest_set(punit) ((punit)->goto_dest.x != -1    \
+                                 || (punit)->goto_dest.y != -1)
+#define goto_dest_x(punit) ((punit)->goto_dest.x)
+#define goto_dest_y(punit) ((punit)->goto_dest.y)
+#define set_goto_dest(punit, map_x, map_y) (CHECK_MAP_POS(map_x, map_y),  \
+                                            (punit)->goto_dest.x = map_x, \
+                                            (punit)->goto_dest.y = map_y)
+#define clear_goto_dest(punit) ((punit)->goto_dest.x = -1, \
+                                (punit)->goto_dest.y = -1)
 
 /* get 'struct unit_list' and related functions: */
 #define SPECLIST_TAG unit
Index: server/autoattack.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/autoattack.c,v
retrieving revision 1.42
diff -u -r1.42 autoattack.c
--- server/autoattack.c 2003/02/17 22:49:28     1.42
+++ server/autoattack.c 2003/03/01 22:20:00
@@ -166,8 +166,7 @@
                   unit_owner(enemy)->name, unit_name(enemy->type));
   
   set_unit_activity(punit, ACTIVITY_GOTO);
-  punit->goto_dest_x=enemy->x;
-  punit->goto_dest_y=enemy->y;
+  set_goto_dest(punit, enemy->x, enemy->y);
   
   send_unit_info(NULL, punit);
   (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
@@ -176,8 +175,7 @@
   
   if (punit) {
     set_unit_activity(punit, ACTIVITY_GOTO);
-    punit->goto_dest_x=pcity->x;
-    punit->goto_dest_y=pcity->y;
+    set_goto_dest(punit, pcity->x, pcity->y);
     send_unit_info(NULL, punit);
     
     (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
Index: server/gotohand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gotohand.c,v
retrieving revision 1.168
diff -u -r1.168 gotohand.c
--- server/gotohand.c   2003/02/20 09:45:21     1.168
+++ server/gotohand.c   2003/03/01 22:20:01
@@ -745,8 +745,7 @@
          total_cost += unit_type(punit)->move_rate;
          freelog(LOG_DEBUG, "%s#%d@(%d,%d) dissuaded from (%d,%d) -> (%d,%d)",
                  unit_type(punit)->name, punit->id,
-                 punit->x, punit->y, x1, y1,
-                 punit->goto_dest_x, punit->goto_dest_y);
+                 punit->x, punit->y, x1, y1, dest_x, dest_y);
        }
        break;
 
@@ -1278,8 +1277,9 @@
   }
 
   unit_id = punit->id;
-  dest_x = waypoint_x = punit->goto_dest_x;
-  dest_y = waypoint_y = punit->goto_dest_y;
+  assert(is_goto_dest_set(punit));
+  dest_x = waypoint_x = goto_dest_x(punit);
+  dest_y = waypoint_y = goto_dest_y(punit);
 
   if (same_pos(punit->x, punit->y, dest_x, dest_y) ||
       !goto_is_sane(punit, dest_x, dest_y, FALSE)) {
@@ -1342,7 +1342,7 @@
       penemy = is_enemy_unit_tile(map_get_tile(x, y), unit_owner(punit));
       assert(punit->moves_left > 0);
 
-      last_tile = same_pos(x, y, punit->goto_dest_x, punit->goto_dest_y);
+      last_tile = same_pos(x, y, goto_dest_x(punit), goto_dest_y(punit));
 
       /* Call handle_unit_move_request for humans and ai_unit_move for AI */
       success = (!pplayer->ai.control 
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.114
diff -u -r1.114 savegame.c
--- server/savegame.c   2003/02/17 22:49:28     1.114
+++ server/savegame.c   2003/03/01 22:20:03
@@ -980,11 +980,17 @@
     punit->connecting=secfile_lookup_bool_default(file, FALSE,
                                                "player%d.u%d.connecting",
                                                plrno, i);
+    /* Load the goto information.  Older savegames will not have the
+     * "go" field, so we just load the goto destination by default. */
+    if (secfile_lookup_bool_default(file, TRUE,
+                                   "player%d.u%d.go", plrno, i)) {
+      int x = secfile_lookup_int(file, "player%d.u%d.goto_x", plrno, i);
+      int y = secfile_lookup_int(file, "player%d.u%d.goto_y", plrno, i);
+      set_goto_dest(punit, x, y);
+    } else {
+      clear_goto_dest(punit);
+    }
 
-    punit->goto_dest_x=secfile_lookup_int(file, 
-                                         "player%d.u%d.goto_x", plrno,i);
-    punit->goto_dest_y=secfile_lookup_int(file, 
-                                         "player%d.u%d.goto_y", plrno,i);
     punit->ai.control=secfile_lookup_bool(file, "player%d.u%d.ai", plrno,i);
     punit->ai.ai_role = AIUNIT_NONE;
     punit->ai.ferryboat = 0;
@@ -1409,9 +1415,20 @@
                                plrno, i);
     secfile_insert_int(file, punit->fuel, "player%d.u%d.fuel",
                                plrno, i);
+
+    if (is_goto_dest_set(punit)) {
+      secfile_insert_bool(file, TRUE, "player%d.u%d.go", plrno, i);
+      secfile_insert_int(file, goto_dest_x(punit),
+                        "player%d.u%d.goto_x", plrno, i);
+      secfile_insert_int(file, goto_dest_y(punit), "player%d.u%d.goto_y",
+                        plrno, i);
+    } else {
+      secfile_insert_bool(file, FALSE, "player%d.u%d.go", plrno, i);
+      /* for compatility with older servers */
+      secfile_insert_int(file, 0, "player%d.u%d.goto_x", plrno, i);
+      secfile_insert_int(file, 0, "player%d.u%d.goto_y", plrno, i);
+    }
 
-    secfile_insert_int(file, punit->goto_dest_x, "player%d.u%d.goto_x", plrno, 
i);
-    secfile_insert_int(file, punit->goto_dest_y, "player%d.u%d.goto_y", plrno, 
i);
     secfile_insert_bool(file, punit->ai.control, "player%d.u%d.ai", plrno, i);
     secfile_insert_int(file, punit->ord_map, "player%d.u%d.ord_map", plrno, i);
     secfile_insert_int(file, punit->ord_city, "player%d.u%d.ord_city", plrno, 
i);
Index: server/settlers.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/settlers.c,v
retrieving revision 1.165
diff -u -r1.165 settlers.c
--- server/settlers.c   2003/02/17 22:49:28     1.165
+++ server/settlers.c   2003/03/01 22:20:04
@@ -459,7 +459,8 @@
     int x, int y)
 {
   if (same_pos(myunit->x, myunit->y, x, y) ||
-      same_pos(myunit->goto_dest_x, myunit->goto_dest_y, x, y)) {
+      (is_goto_dest_set(myunit)
+       && same_pos(goto_dest_x(myunit), goto_dest_y(myunit), x, y))) {
 /* I'm still not sure this is exactly right -- Syela */
     unit_list_iterate(map_get_tile(x, y)->units, punit)
       if (myunit==punit) continue;
@@ -1222,8 +1223,7 @@
     }
     ferryboat = unit_list_find(&(map_get_tile(punit->x, punit->y)->units),
                                punit->ai.ferryboat);
-    punit->goto_dest_x = gx;
-    punit->goto_dest_y = gy;
+    set_goto_dest(punit, gx, gy);
 
     if (ferryboat && (ferryboat->ai.passenger == 0
                       || ferryboat->ai.passenger == punit->id)) {
@@ -1231,8 +1231,7 @@
                ferryboat->id);
       handle_unit_activity_request(punit, ACTIVITY_SENTRY);
       ferryboat->ai.passenger = punit->id;
-      ferryboat->goto_dest_x = gx;
-      ferryboat->goto_dest_y = gy;
+      set_goto_dest(ferryboat, gx, gy);
       if (!ai_unit_goto(ferryboat, gx, gy)) {
         return FALSE; /* died */
       }
@@ -1249,8 +1248,7 @@
       && (!ferryboat
           || (is_tiles_adjacent(punit->x, punit->y, gx, gy)
               && could_unit_move_to_tile(punit, gx, gy) != 0))) {
-    punit->goto_dest_x = gx;
-    punit->goto_dest_y = gy;
+    set_goto_dest(punit, gx, gy);
     if (!ai_unit_goto(punit, gx, gy)) {
       return FALSE; /* died */
     }
@@ -1426,7 +1424,8 @@
     if (unit_flag(punit, F_SETTLERS)
        || unit_flag(punit, F_CITIES)) {
       if (punit->activity == ACTIVITY_GOTO) {
-        ptile = map_get_tile(punit->goto_dest_x, punit->goto_dest_y);
+       assert(is_goto_dest_set(punit));
+        ptile = map_get_tile(goto_dest_x(punit), goto_dest_y(punit));
         ptile->assigned = ptile->assigned | i; /* assigned for us only */
       } else {
         ptile = map_get_tile(punit->x, punit->y);
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.255
diff -u -r1.255 unithand.c
--- server/unithand.c   2003/02/17 22:49:28     1.255
+++ server/unithand.c   2003/03/01 22:20:06
@@ -76,8 +76,7 @@
     return;
   }
 
-  punit->goto_dest_x = req->x;
-  punit->goto_dest_y = req->y;
+  set_goto_dest(punit, req->x, req->y);
 
   set_unit_activity(punit, ACTIVITY_GOTO);
 
@@ -133,8 +132,7 @@
     return;
   }
 
-  punit->goto_dest_x = req->dest_x;
-  punit->goto_dest_y = req->dest_y;
+  set_goto_dest(punit, req->dest_x, req->dest_y);
 
   set_unit_activity(punit, req->activity_type);
   punit->connecting = TRUE;
@@ -1034,7 +1032,7 @@
      * human players the server-side goto implementation should be
      * obsoleted for client usage. So in time, remove the code below. */
     if (punit->activity == ACTIVITY_GOTO && 
-        !same_pos(punit->goto_dest_x, punit->goto_dest_y, dest_x, dest_y)) {
+        !same_pos(goto_dest_x(punit), goto_dest_y(punit), dest_x, dest_y)) {
       notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
                       _("Game: %s aborted GOTO as there are units in the 
way."),
                       unit_type(punit)->name);
@@ -1445,8 +1443,8 @@
 #endif
 
   if (punit->activity == ACTIVITY_GOTO) {
-    punit->goto_dest_x = pgr->pos[pgr->last_index-1].x;
-    punit->goto_dest_y = pgr->pos[pgr->last_index-1].y;
+    set_goto_dest(punit, pgr->pos[pgr->last_index-1].x,
+                 pgr->pos[pgr->last_index-1].y);
     send_unit_info(pplayer, punit);
   }
 
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.214
diff -u -r1.214 unittools.c
--- server/unittools.c  2003/02/18 18:10:15     1.214
+++ server/unittools.c  2003/03/01 22:20:09
@@ -520,8 +520,7 @@
              (air_can_move_between
               (punit->moves_left / 3, punit->x, punit->y, x_itr, y_itr,
                unit_owner(punit)) >= 0)) {
-           punit->goto_dest_x = x_itr;
-           punit->goto_dest_y = y_itr;
+           set_goto_dest(punit, x_itr, y_itr);
            set_unit_activity(punit, ACTIVITY_GOTO);
            (void) do_unit_goto(punit, GOTO_MOVE_ANY, FALSE);
            notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT, 
@@ -1569,8 +1568,7 @@
   punit->x = x;
   punit->y = y;
 
-  punit->goto_dest_x=0;
-  punit->goto_dest_y=0;
+  clear_goto_dest(punit);
   
   pcity=find_city_by_id(homecity_id);
   punit->veteran=make_veteran;
@@ -1924,8 +1922,14 @@
   packet->upkeep_gold = punit->upkeep_gold;
   packet->ai = punit->ai.control;
   packet->fuel = punit->fuel;
-  packet->goto_dest_x = punit->goto_dest_x;
-  packet->goto_dest_y = punit->goto_dest_y;
+  if (is_goto_dest_set(punit)) {
+    packet->goto_dest_x = goto_dest_x(punit);
+    packet->goto_dest_y = goto_dest_y(punit);
+  } else {
+    packet->goto_dest_x = 255;
+    packet->goto_dest_y = 255;
+    assert(!is_normal_map_pos(255, 255));
+  }
   packet->activity_target = punit->activity_target;
   packet->paradropped = punit->paradropped;
   packet->connecting = punit->connecting;
@@ -2934,7 +2938,7 @@
   }
   /* A transporter should not take units with it when on an attack goto -- 
fisch */
   if ((punit->activity == ACTIVITY_GOTO) &&
-      get_defender(punit, punit->goto_dest_x, punit->goto_dest_y) &&
+      get_defender(punit, goto_dest_x(punit), goto_dest_y(punit)) &&
       !is_ocean(psrctile->terrain)) {
     transport_units = FALSE;
   }
@@ -3005,14 +3009,15 @@
   check_unit_activity(punit);
 
   /* set activity to sentry if boarding a ship unless the unit is just 
-     passing through the ship on its way somewhere else */
+   * passing through the ship on its way somewhere else.  If the unit is
+   * GOTOing and the ship isn't the final destination, then don't go
+   * to sleep. */
   if (is_ground_unit(punit)
       && is_ocean(pdesttile->terrain)
       && !(pplayer->ai.control)
-      && !(punit->activity == ACTIVITY_GOTO      /* if unit is GOTOing and the 
ship */ 
-          && (dest_x != punit->goto_dest_x      /* isn't the final destination 
*/
-              || dest_y != punit->goto_dest_y)) /* then don't go to sleep */
-      ) {
+      && !(punit->activity == ACTIVITY_GOTO
+          && !same_pos(goto_dest_x(punit), goto_dest_y(punit),
+                       dest_x, dest_y))) {
     set_unit_activity(punit, ACTIVITY_SENTRY);
   }
   send_unit_info_to_onlookers(NULL, punit, src_x, src_y, FALSE);

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#3524) another look at the goto_dest problem, Jason Short <=