Complete.Org: Mailing Lists: Archives: freeciv-ai: August 2004:
[freeciv-ai] Re: Inprovements in settler.c
Home

[freeciv-ai] Re: Inprovements in settler.c

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-ai@xxxxxxxxxxx
Subject: [freeciv-ai] Re: Inprovements in settler.c
From: Jordi Negrevernis i Font <jorneg@xxxxxxxxxxx>
Date: Sat, 28 Aug 2004 20:39:40 +0200


   There are two patches there:

   settler -> introduces the bodyguard code for the settling activities.

hitpoint -> depends on settler.diff and modifies the function ai_manage_hitpoint_recovery ( or anything like that ) and tries to recover units in enemy territoty in hills or mountains.

Per Inge Mathisen wrote:

On Tue, 17 Aug 2004, Jordi Negrevernis i Font wrote:
 Will this enter in CVS?

Yes. I will look at and test when I get time.

If yes, i can extend to check for national border, and maybe distance to
enemies...

Good.

 Also, while debugging i notice that the settler or enginiers can
often do nothing - debug message 'could not go to ...' because they
select to improve terrain a tile in a diferent continent!!!!

Ooops. Can you see if you can fix this?

 Also, while looking to ai_manage_hitpoint_recovery - or something
like this - the damaged units that don't find a city to go to rest,
doesn't look for a hill or montain to cure. Can i make a patch to use
the function 'find_defending_spot' of the patch for this

I guess this is a good idea.

 - Per



diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore freeciv-cvs-Aug-06/ai/aitools.c 
freeciv-cvs-Aug-06-settler/ai/aitools.c
--- freeciv-cvs-Aug-06/ai/aitools.c     2004-08-06 07:14:59.000000000 +0200
+++ freeciv-cvs-Aug-06-settler/ai/aitools.c     2004-08-11 01:39:59.000000000 
+0200
@@ -456,7 +456,7 @@
   Repair incompletely referenced bodyguards. When the rest of the bodyguard
   mess is cleaned up, this repairing should be replaced with an assert.
 **************************************************************************/
-static bool has_bodyguard(struct unit *punit)
+bool has_bodyguard(struct unit *punit)
 {
   struct unit *guard;
   if (punit->ai.bodyguard > BODYGUARD_NONE) {
diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore freeciv-cvs-Aug-06/ai/aitools.h 
freeciv-cvs-Aug-06-settler/ai/aitools.h
--- freeciv-cvs-Aug-06/ai/aitools.h     2004-08-06 07:14:59.000000000 +0200
+++ freeciv-cvs-Aug-06-settler/ai/aitools.h     2004-08-11 01:39:49.000000000 
+0200
@@ -52,6 +52,7 @@
 bool ai_unit_make_homecity(struct unit *punit, struct city *pcity);
 bool ai_unit_attack(struct unit *punit, int x, int y);
 bool ai_unit_move(struct unit *punit, int x, int y);
+void ai_unit_bodyguard_move(int unitid, int x, int y);

 struct city *dist_nearest_city(struct player *pplayer, int x, int y,
                                bool everywhere, bool enemy);
@@ -70,4 +71,7 @@

 bool is_player_dangerous(struct player *pplayer, struct player *aplayer);

+bool has_bodyguard(struct unit *punit);
+
+
 #endif  /* FC__AITOOLS_H */
diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore freeciv-cvs-Aug-06/ai/aiunit.c 
freeciv-cvs-Aug-06-settler/ai/aiunit.c
--- freeciv-cvs-Aug-06/ai/aiunit.c      2004-08-07 07:15:05.000000000 +0200
+++ freeciv-cvs-Aug-06-settler/ai/aiunit.c      2004-08-15 19:48:43.000000000 
+0200
@@ -881,6 +881,34 @@
 }

 /*************************************************************************
+  Tries to find a land tile adjacent to a unit to defend from an attack
+  (dest_x, dest_y).  Prefers tiles which are more defensible.
+**************************************************************************/
+bool find_defending_spot(struct unit *punit, int *x, int *y)
+{
+  int ok, best = 0;
+  enum tile_terrain_type t;
+
+  CHECK_UNIT(punit);
+
+  adjc_iterate(punit->x, punit->y, x1, y1) {
+    ok = 0;
+    t = map_get_terrain(x1, y1);
+    if (!is_ocean(t) && is_my_zoc(unit_owner(punit), x1, y1)) {
+      /* accessible tile nearby */
+      ok = get_tile_type(t)->defense_bonus;
+      if (ok > best) {
+        best = ok;
+        *x = x1;
+        *y = y1;
+      }
+    }
+  } adjc_iterate_end;
+
+  return (best > 0);
+}
+
+/*************************************************************************
   Does the unit with the id given have the flag L_DEFEND_GOOD?
 **************************************************************************/
 static bool unit_role_defender(Unit_Type_id type)
diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore freeciv-cvs-Aug-06/ai/aiunit.h 
freeciv-cvs-Aug-06-settler/ai/aiunit.h
--- freeciv-cvs-Aug-06/ai/aiunit.h      2004-08-07 07:15:05.000000000 +0200
+++ freeciv-cvs-Aug-06-settler/ai/aiunit.h      2004-08-15 19:48:31.000000000 
+0200
@@ -66,6 +66,7 @@
                             int *x, int *y);
 bool find_beachhead(struct unit *punit, int dest_x, int dest_y, 
                     int *x, int *y);
+bool find_defending_spot(struct unit *punit, int *x, int *y);
 
 int build_cost_balanced(Unit_Type_id type);
 int unittype_att_rating(Unit_Type_id type, int veteran,
diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore 
freeciv-cvs-Aug-06/server/settlers.c 
freeciv-cvs-Aug-06-settler/server/settlers.c
--- freeciv-cvs-Aug-06/server/settlers.c        2004-08-07 07:15:21.000000000 
+0200
+++ freeciv-cvs-Aug-06-settler/server/settlers.c        2004-08-28 
13:58:14.000000000 +0200
@@ -63,6 +63,8 @@
 {
   int x = punit->x, y = punit->y;
   struct city *pcity;
+  int bodyguard = punit->ai.bodyguard;
+  struct unit *pbody = find_unit_by_id(bodyguard);

   handle_unit_activity_request(punit, ACTIVITY_IDLE);

@@ -73,11 +75,19 @@
                         city_name_suggestion(pplayer, x, y));
   pcity = map_get_city(x, y);
   if (!pcity) {
     freelog(LOG_ERROR, "%s: Failed to build city at (%d, %d)",
             pplayer->name, x, y);
     return FALSE;
   }

+  /* If we carried a bodyguard just use it!.
+   *  Its the new defender of the city */
+  if (pbody) {
+    if (ai_unit_make_homecity(pbody, pcity)) {
+      ai_unit_new_role(pbody, AIUNIT_ESCORT, -1, -1);
+    }
+  }
+
   return TRUE;
 }
 
@@ -137,20 +147,45 @@
   Manages settlers.
 **************************************************************************/
 void ai_manage_settler(struct player *pplayer, struct unit *punit)
-{
+{ bool pos_dangerous = 0;
+#define LOG_SETTLER LOG_NORMAL
+
   punit->ai.control = TRUE;
   /* if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler */
   if (punit->ai.ai_role == AIUNIT_NONE) {
     ai_unit_new_role(punit, AIUNIT_AUTO_SETTLER, -1, -1);
   }
+
+  /* we check for a bodyguard if our settler unit is in danger */
+
+  /* if goto is set we check for a dangerous position */
+  if (is_goto_dest_set(punit)) {
+    pos_dangerous = enemies_at(punit, goto_dest_x(punit), goto_dest_y(punit)) 
||
+                    (map_get_owner(goto_dest_x(punit), goto_dest_y(punit)) != 
pplayer);
+  } else {
+    /* otherwise we check for the current location */
+    pos_dangerous = enemies_at(punit, punit->x, punit->y);
+  }
+
+  if (pos_dangerous > 0) {
+    if (!has_bodyguard(punit)) {
+      punit->ai.bodyguard = BODYGUARD_WANTED;
+    }
+  }
+
+  if (has_bodyguard(punit)) {
+    UNIT_LOG(LOG_SETTLER, punit, "with a bodyguard!");
+    ai_unit_bodyguard_move(punit->ai.bodyguard, punit->x, punit->y);
+  }
+
   return;
 }

 /**************************************************************************
  return 1 if there is already a unit on this square or one destined for it
  (via goto)
 **************************************************************************/
 static bool is_already_assigned(struct unit *myunit, struct player *pplayer,
     int x, int y)
 {
   if (same_pos(myunit->x, myunit->y, x, y)
@@ -1052,7 +1087,6 @@
 /**************************************************************************
   Find some work for our settlers and/or workers.
 **************************************************************************/
-#define LOG_SETTLER LOG_DEBUG
 static void auto_settler_findwork(struct player *pplayer, struct unit *punit)
 {
   struct cityresult result;
@@ -1080,23 +1114,38 @@
       ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
       return; /* avoid recursion at all cost */
     } else {
-      /* Go there */
-      if ((!ai_gothere(pplayer, punit, x, y) && !find_unit_by_id(sanity))
-          || punit->moves_left <= 0) {
+      if (enemies_at(punit, punit->x, punit->y) && !has_bodyguard(punit)) {
+        /* there are enemies at current location! so scatter and hide */
+        UNIT_LOG(LOG_SETTLER, punit, "enemies side by side settler!");
+        if (find_defending_spot(punit, &gx, &gy)) {
+         ai_unit_goto(punit, gx, gy);
+       }
         return;
-      }
-      if (same_pos(punit->x, punit->y, x, y)) {
-        if (!ai_do_build_city(pplayer, punit)) {
-          UNIT_LOG(LOG_ERROR, punit, "could not make city on %s",
-                   map_get_tile_info_text(punit->x, punit->y));
-          ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
-        } else {
-          return; /* We came, we saw, we built... */
-        }
       } else {
-        UNIT_LOG(LOG_SETTLER, punit, "could not go to target");
-        /* ai_unit_new_role(punit, AIUNIT_NONE, -1, -1); */
-        return;
+        if (enemies_at(punit, x, y) && !has_bodyguard(punit)) {
+          /* there are enemies at destination! */
+          UNIT_LOG(LOG_SETTLER, punit, "enemies at city founding location!");
+          return;
+       } else {
+          /* Go there */
+          if ((!ai_gothere(pplayer, punit, x, y) && !find_unit_by_id(sanity))
+              || punit->moves_left <= 0) {
+            return;
+          }
+          if (same_pos(punit->x, punit->y, x, y)) {
+            if (!ai_do_build_city(pplayer, punit)) {
+              UNIT_LOG(LOG_ERROR, punit, "could not make city on %s",
+                       map_get_tile_info_text(punit->x, punit->y));
+              ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
+            } else {
+              return; /* We came, we saw, we built... */
+            }
+          } else {
+            UNIT_LOG(LOG_SETTLER, punit, "could not go to build target city or 
en route");
+            /* ai_unit_new_role(punit, AIUNIT_NONE, -1, -1); */
+            return;
+          }
+        }
       }
     }
   }
diff -u -r -Xfreeciv-cvs-Aug-06/diff_ignore 
freeciv-cvs-Aug-06-settler/ai/aiunit.c 
freeciv-cvs-Aug-06-settler-hitpoint/ai/aiunit.c
--- freeciv-cvs-Aug-06-settler/ai/aiunit.c      2004-08-15 19:48:43.000000000 
+0200
+++ freeciv-cvs-Aug-06-settler-hitpoint/ai/aiunit.c     2004-08-28 
18:32:59.000000000 +0200
@@ -1957,6 +1957,7 @@
   struct city *pcity = map_get_city(punit->x, punit->y);
   struct city *safe = NULL;
   struct unit_type *punittype = get_unit_type(punit->type);
+  int gx = 0, gy = 0;

   CHECK_UNIT(punit);

@@ -1989,7 +1990,23 @@
       }
     } else {
       /* oops */
-      UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
+      if (is_ground_unit(punit)) {
+        if (find_defending_spot(punit, &gx, &gy)) {
+          UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover 
in, so fortyfing in a hill!");
+          if (ai_unit_goto(punit, gx, gy)) {
+            if (same_pos(punit->x, punit->y, gx, gy)) {
+              if ((punit->activity != ACTIVITY_FORTIFYING) && (punit->activity 
!= ACTIVITY_FORTIFIED)) {
+               handle_unit_activity_request(punit, ACTIVITY_FORTIFYING);
+             }
+            }
+          } else {
+           /* we die */
+           return;
+         }
+        }
+      }
+
+      UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in, so 
attacking!");
       ai_unit_new_role(punit, AIUNIT_NONE, -1, -1);
       ai_military_attack(pplayer, punit);
       return;

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