Complete.Org: Mailing Lists: Archives: freeciv-ai: September 2003:
[freeciv-ai] Re: Possible bug in ai_military_gothere
Home

[freeciv-ai] Re: Possible bug in ai_military_gothere

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Freeciv AI List <freeciv-ai@xxxxxxxxxxx>
Subject: [freeciv-ai] Re: Possible bug in ai_military_gothere
From: Jordi Negrevernis i Font <jorneg@xxxxxxxxxxx>
Date: Thu, 04 Sep 2003 18:22:20 +0200


En/na Per I. Mathisen ha escrit:

On Thu, 28 Aug 2003, Jordi Negrevernis i Font wrote:
 Hi, while looking at the code to try to resolve the problem reported
in the previous message i found it.

 Do you remember to say very often barbarian galleons not disembarking?
...
 So, if the city is inland at 5 tiles of the coast the barbarians or
the AI will not disembarc troups.

Can you make a patch?

   Yep! Here you have it!

   Its against cvs Aug 24, but i think it will apply.

   I tried to clean up de patch but maybe it has garbage...

I just touched the ai_military_gothere() function to make sure that the unit get off the boat where it has arrived, and just touched the clients of find_beachhead and find_city_beach...

I played two autogames and the server did not crash, and i think it does what is suposed to do.

diff -Nur -Xfreeciv-cvs-Aug-24/diff_ignore freeciv-cvs-Aug-24/ai/aiunit.c 
freeciv-cvs-Aug-24-ferryboat/ai/aiunit.c
--- freeciv-cvs-Aug-24/ai/aiunit.c      Thu Sep  4 11:24:41 2003
+++ freeciv-cvs-Aug-24-ferryboat/ai/aiunit.c    Thu Sep  4 15:25:08 2003
@@ -1426,7 +1426,7 @@
 }

 /**************************************************************************
   Return values:
   -1: died
   0: didn't move
   1: moved
@@ -1440,6 +1440,7 @@
   struct unit *def;
   struct city *dcity = map_get_city(dest_x, dest_y);
   struct tile *ptile;
+  int boat_x = -1, boat_y = -1, boat_arrived = 0;

   CHECK_UNIT(punit);

@@ -1474,9 +1475,9 @@
     ptile = map_get_tile(punit->x, punit->y);
     ferryboat = unit_list_find(&ptile->units, punit->ai.ferryboat);

     if (ferryboat && (ferryboat->ai.passenger == 0
                       || ferryboat->ai.passenger == punit->id)) {
-      int boat_x, boat_y;
+

       freelog(LOG_DEBUG, "We have FOUND BOAT, %d ABOARD %d@(%d,%d)->(%d, %d).",
               punit->id, ferryboat->id, punit->x, punit->y, dest_x, dest_y);
@@ -1484,7 +1485,16 @@
       ferryboat->ai.passenger = punit->id;

       /* Last ingredient: a beachhead. */
-      if (find_beachhead(punit, dest_x, dest_y, &boat_x, &boat_y)) {
+      if (!find_beachhead(punit, dest_x, dest_y, &boat_x, &boat_y)) {
+        /* we try the other function */
+        if (dcity) {
+          find_city_beach(dcity, punit, &boat_x, &boat_y);
+        } else {
+          /* the previous function failed, so... */
+          boat_x = punit->x; boat_y = punit->y;
+        }
+      }
+      if (!same_pos(punit->x, punit->y, boat_x, boat_y)) {
        set_goto_dest(ferryboat, boat_x, boat_y);
        set_goto_dest(punit, dest_x, dest_y);
         if (ground_unit_transporter_capacity(punit->x, punit->y, pplayer)
@@ -1501,36 +1511,45 @@
               }
             }
           } unit_list_iterate_end; /* passengers are safely stowed away */
           if (!ai_unit_goto(ferryboat, boat_x, boat_y)) {
             return -1; /* died */
           }
           handle_unit_activity_request(punit, ACTIVITY_IDLE);
         } /* else wait, we can GOTO when more passengers come. */
       }
-    }
+
+    }
+  }
+
+  if (ferryboat) {
+    /* we go on a ferry! did we arrive? */
+    boat_arrived = same_pos(ferryboat->x, ferryboat->y, 
ferryboat->goto_dest.x, ferryboat->goto_dest.y) ||
+                   is_tiles_adjacent(ferryboat->x, ferryboat->y, 
ferryboat->goto_dest.x, ferryboat->goto_dest.y);
+  } else {
+    boat_arrived = FALSE;
   }

-  if (goto_is_sane(punit, dest_x, dest_y, TRUE) && punit->moves_left > 0
-      && (!ferryboat
-          || (real_map_distance(punit->x, punit->y, dest_x, dest_y) < 3
-              && (punit->ai.bodyguard == BODYGUARD_NONE
+  if (goto_is_sane(punit, dest_x, dest_y, TRUE) && punit->moves_left > 0
+      && (!ferryboat
+          || ( boat_arrived
+              && (punit->ai.bodyguard == BODYGUARD_NONE
                   || unit_list_find(&(map_get_tile(punit->x, punit->y)->units),
                                     punit->ai.bodyguard)
                   || (dcity && !has_defense(dcity)))))) {
     /* if we are on a boat, disembark only if we are within two tiles of
-     * our target, and either 1) we don't need a bodyguard, 2) we have a
-     * bodyguard, or 3) we are going to an empty city.  Previously, cannons
-     * would disembark before the cruisers arrived and die. -- Syela */
+     * our beach head near the target, and either 1) we don't need a bodyguard,
+     * 2) we have a bodyguard, or 3) we are going to an empty city. Previously,
+     * cannons would disembark before the cruisers arrived and die. -- Syela */

     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 */
     /* The case where the bodyguard has moves left and could meet us en route
      * is not handled properly.  There should be a way to do it with dir_ok
      * but I'm tired now. -- Syela */
     if (punit->ai.bodyguard == BODYGUARD_WANTED) {
       adjc_iterate(punit->x, punit->y, i, j) {
         unit_list_iterate(map_get_tile(i, j)->units, aunit) {
           if (aunit->ai.charge != punit->id || punit->owner != aunit->owner) {
@@ -2230,25 +2249,34 @@
                 acity->name, acity->x, acity->y,
                 go_by_boat, move_time, want, best);
       }

       if (want > best && ai_fuzzy(pplayer, TRUE)) {
         /* Yes, we like this target */
         if (punit->id != 0 && is_ground_unit(punit)
             && !unit_flag(punit, F_MARINES)
             && map_get_continent(acity->x, acity->y) != con) {
           /* a non-virtual ground unit is trying to attack something on
            * another continent.  Need a beachhead which is adjacent
            * to the city and an available ocean tile */
           int xx, yy;

           if (find_beachhead(punit, acity->x, acity->y, &xx, &yy)) {
             best = want;
             *x = acity->x;
             *y = acity->y;
-            /* the ferryboat needs to target the beachhead, but the unit
-             * needs to target the city itself.  This is a little weird,
+            /* the ferryboat needs to target the beachhead, but the unit
+             * needs to target the city itself.  This is a little weird,
              * but it's the best we can do. -- Syela */
-          } /* else do nothing, since we have no beachhead */
+          } else {
+            /* try to use find_city_beach */
+            find_city_beach(acity, punit, &xx, &yy);
+            if (!same_pos(punit->x, punit->y, xx, yy)) {
+              /* we find beach head, same comment as above! */
+              best = want;
+              *x = acity->x;
+              *y = acity->y;
+            }
+          }
         } else {
           best = want;
           *x = acity->x;
@@ -2475,9 +2503,9 @@
         /* sometimes find_beachhead is not enough */
         if (!find_beachhead(punit, pc->x, pc->y, &fx, &fy)) {
           find_city_beach(pc, punit, &fx, &fy);
-          freelog(LOG_DEBUG, "Barbarian sailing to city");
-          ai_military_gothere(pplayer, punit, fx, fy);
-       }
+        }
+        freelog(LOG_DEBUG, "Barbarian sailing to city");
+        ai_military_gothere(pplayer, punit, fx, fy);
       }
     }
   }

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