Re: Two patches not applied!

Jordi Negrevernis i Font <[email protected]>
Newsgroups gmane.games.freeciv.ai
Message-ID <[email protected]>
    Also, this...
paratroop4.diff (text/plain, 18.8 KB)
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/advmilitary.c freeciv-cvs-Feb-27-paratroop/ai/advmilitary.c
--- freeciv-cvs-Feb-27/ai/advmilitary.c	2004-02-26 07:01:21.000000000 +0100
+++ freeciv-cvs-Feb-27-paratroop/ai/advmilitary.c	2004-03-18 02:37:15.000000000 +0100
@@ -35,6 +35,7 @@
 #include "aidiplomat.h"
 #include "aihand.h"
 #include "ailog.h"
+#include "aiparatrooper.h"
 #include "aitools.h"
 #include "aiunit.h"
 
@@ -1306,6 +1307,9 @@
   /* Consider making an airplane */
   (void) ai_choose_attacker_air(pplayer, pcity, choice);
 
+  /* Consider making a paratrooper */
+  ai_choose_paratrooper(pplayer, pcity, choice);
+
   /* Check if we want a sailing attacker. Have to put sailing first
      before we mung the seamap */
   unit_type = ai_choose_attacker(pcity, SEA_MOVING);
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/aiparatrooper.c freeciv-cvs-Feb-27-paratroop/ai/aiparatrooper.c
--- freeciv-cvs-Feb-27/ai/aiparatrooper.c	1970-01-01 01:00:00.000000000 +0100
+++ freeciv-cvs-Feb-27-paratroop/ai/aiparatrooper.c	2004-04-05 16:37:53.000000000 +0200
@@ -0,0 +1,389 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "city.h"
+#include "citytools.h"
+#include "log.h"
+#include "pf_tools.h"
+#include "player.h"
+#include "unit.h"
+#include "unittools.h"
+
+#include "ailog.h"
+#include "aiparatrooper.h"
+#include "aiunit.h"
+#include "aitools.h"
+
+#define LOGLEVEL_PARATROOPER LOG_NORMAL
+
+/**********************************************************************
+  Find own city to go there to recover and paradroop.
+
+  TODO: Actually check how safe the city is. This is a difficult
+  decision not easily taken, since we also want to protect unsafe
+  cities, at least most of the time.
+**********************************************************************/
+static struct city *find_nearest_own_city_at(struct player *pplayer,
+                                             int x, int y)
+{ int best = 0, cur = 100;
+  int continent = map_get_continent(x, y);
+  struct city *acity = NULL;
+
+  city_list_iterate(pplayer->cities, pcity) {
+    cur = real_map_distance(pcity->x, pcity->y, x ,y);
+    if (city_got_building(pcity, B_BARRACKS)
+       || city_got_building(pcity, B_BARRACKS2)
+       || city_got_building(pcity, B_BARRACKS3)) {
+      cur /= 3;
+    }
+    if (continent != map_get_continent(pcity->x, pcity->y)) {
+      /* it must be in the same continent */
+      cur = 0;
+    }
+    if (cur < best && (cur > 0) ) {
+      best = cur;
+      acity = pcity;
+    }
+  } city_list_iterate_end;
+
+  return acity;
+}
+
+/**********************************************************************
+ This function does manage the paratrooper units of the AI.
+ 1st.- checks for cities left alone without defenders
+ 2nd.- checks for enemy cities left alone
+ 3th.- checks for enemy units in range
+**********************************************************************/
+void ai_manage_paratrooper(struct player *pplayer, struct unit *punit)
+{
+  struct city *pcity = map_get_city(punit->x, punit->y);
+  struct city *acity = NULL;
+  int sanity = punit->id;
+  int x_dest = 0, y_dest = 0, best = 0;
+
+  CHECK_UNIT(punit);
+
+  /* defend attacking (and be opportunistic too)*/
+  if (!ai_military_rampage(punit, RAMPAGE_ANYTHING,
+                           RAMPAGE_FREE_CITY_OR_BETTER)) {
+    /* dead */
+    return;
+  }
+
+  /* check to recover hit points */
+  if ((punit->hp < unit_type(punit)->hp) && pcity) {
+    UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "recovering hit points.",
+             pplayer->name, unit_type(punit)->name,
+             punit->id, punit->x, punit->y);
+    return;
+  }
+
+  /* nothing to do! */
+  if (punit->moves_left == 0) {
+    return;
+  }
+
+  /* we must defend the city! */
+  if (stay_and_defend(punit)) {
+    UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "defending the city.",
+             pplayer->name, unit_type(punit)->name,
+	     punit->id, punit->x, punit->y);
+    return;
+  }
+
+  if (can_unit_paradrop(punit)) {
+    /* unit can paradrop, so use it! */
+    int range = unit_type(punit)->paratroopers_range;
+
+    /* first, we search for undefended cities in danger */
+    square_iterate(punit->x, punit->y, range, x, y) {
+      acity = map_get_city(x,y);
+      if ((acity) && (city_owner(acity) == pplayer) &&
+          (unit_list_size(&(map_get_tile(x, y)->units)) == 0)) {
+        /* own city and empty! */
+        if ((acity->size * acity->ai.urgency) > best) {
+          best = acity->size * acity->ai.urgency;
+          x_dest = acity->x; y_dest = acity->y;
+        }
+      }
+    } square_iterate_end;
+
+    /* second, we search for undefended enemy cities near us */
+    if (best == 0) {
+      square_iterate(punit->x, punit->y, range, x, y) {
+        acity = map_get_city(x,y);
+        if ((acity) && pplayers_at_war(pplayer, city_owner(acity)) &&
+            (unit_list_size(&(map_get_tile(x, y)->units)) == 0)) {
+          /* enemy empty city! */
+          if (acity->size > best) {
+            best = acity->size;
+            x_dest = acity->x; y_dest = acity->y;
+          }
+        }
+      } square_iterate_end;
+    }
+
+    /* third, we search for enemy units near us,
+       if we don't find any own empty city */
+    if (best == 0) {
+      square_iterate(punit->x, punit->y, range, x, y) {
+        struct tile *ptile = map_get_tile(x, y);
+        if (unit_list_size(&(ptile->units)) > 0) {
+          struct unit *pdef = unit_list_get(&ptile->units, 0);
+	  if (pplayers_at_war(pplayer, unit_owner(pdef))) {
+	    int benefit = stack_cost(pdef);
+            benefit = (benefit * punit->hp) / unit_type(punit)->hp;
+            if (benefit > best) {
+              /* best enemy unit to kill! */
+	      best = benefit;
+	      x_dest = x; y_dest = y;
+	    }
+	  }
+        }
+      } square_iterate_end;
+
+      if (best > 0) {
+        /* now we have the location of the enemy unit,
+	   we find the best tile around it,
+	   to attack him */
+	struct city *acity = find_nearest_own_city_at(unit_owner(punit),
+	                                              x_dest, y_dest);
+	int xd = 0, yd = 0, dist = 0;
+
+	if (acity) {
+	  /* we continue if we find a city in that continent */
+	  dist = real_map_distance(x_dest, y_dest, acity->x, acity->y);
+	  best = 0;
+	  square_iterate(x_dest, y_dest, 1, x, y) {
+	    int rating = 0;
+	    if (is_ocean(map_get_terrain(x, y))) {
+	      /*  do not paradroop to ocean! */
+	      continue;
+	    }
+            if (is_non_allied_unit_tile(map_get_tile(x, y), pplayer)) {
+	      /* do not paradroop on an enemy unit! */
+	      continue;
+            }
+	    if (real_map_distance(punit->x, punit->y, x, y) > range) {
+	      /* do not paradroop outside the range */
+	      continue;
+	    }
+
+	    switch(map_get_terrain(x, y)) {
+	      case T_FOREST:
+	      case T_HILLS:
+	      case T_JUNGLE:
+	        rating = 2; break;
+	      case T_MOUNTAINS:
+	        rating = 4; break;
+	      default:
+	        rating = 0; break;
+	    };
+	    rating += (dist - real_map_distance(x, y, acity->x, acity->y));
+
+	    if (rating > best) {
+	      /* we assign the best location to attack the unit */
+	      best = rating;
+	      xd = x; yd = y;
+	    }
+
+	  } square_iterate_end;
+
+          /* we assign the last best values */
+	  if (best) {
+	    x_dest = xd; y_dest = yd;
+	  }
+	} else {
+	  best = 0;
+	  x_dest = 0; y_dest = 0;
+	}
+      }
+    }
+
+    if (best) {
+      /* we move the unit */
+      set_goto_dest(punit, x_dest, y_dest);
+      UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "paradroping.",
+               pplayer->name, unit_type(punit)->name,
+	       punit->id, punit->x, punit->y);
+      if (do_paradrop(punit, x_dest, y_dest)) {
+        /* successfull! */
+        if (!find_unit_by_id(sanity)) {
+          /* the unit did not survive the move */
+          return;
+        }
+        /* and we attack the target */
+        (void)ai_military_rampage(punit, RAMPAGE_ANYTHING, RAMPAGE_ANYTHING);
+      }
+      if (find_unit_by_id(sanity)) {
+        clear_goto_dest(punit);
+      }
+    } else {
+      UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "dind't find objective to paradrop to.",
+               pplayer->name, unit_type(punit)->name,
+	       punit->id, punit->x, punit->y);
+      /* go to zones in danger */
+      square_iterate(punit->x, punit->y, range, x, y) {
+        struct city *acity = map_get_city(x, y);
+        if (acity && pplayers_allied(city_owner(acity), pplayer)) {
+          if (acity->ai.danger > best) {
+            best = acity->ai.danger;
+            x_dest = acity->x; y_dest = acity->y;
+          }
+        }
+      } square_iterate_end;
+
+      if (best && ((punit->x != x_dest) && (punit->y != y_dest))) {
+        set_goto_dest(punit, x_dest, y_dest);
+        UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "moving to zones in danger.",
+                 pplayer->name, unit_type(punit)->name,
+		 punit->id, punit->x, punit->y);
+        (void)do_paradrop(punit, x_dest, y_dest);
+        if (find_unit_by_id(sanity)) {
+          clear_goto_dest(punit);
+        }
+      }
+    }
+  } else {
+    /* we can't paradrop :-(  */
+    struct city *acity = NULL;
+
+    /* we are in a city, so don't try to find another */
+    if (pcity) {
+      UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "waiting in a city for next turn.",
+               pplayer->name, unit_type(punit)->name,
+	       punit->id, punit->x, punit->y);
+      return;
+    }
+
+    /* find a city to go to recover and paradrop from */
+    acity = find_nearest_own_city_at(unit_owner(punit), punit->x, punit->y);
+
+    if (acity) {
+      if (!ai_unit_goto(punit, acity->x, acity->y)) {
+        /* die or unsuccessfull move */
+	return;
+      }
+    } else {
+        UNIT_LOG(LOGLEVEL_PARATROOPER, punit, "didn't find city to go and recover.",
+                 pplayer->name, unit_type(punit)->name,
+		 punit->id, punit->x, punit->y);
+	/* TODO: decide what to do now! */
+    }
+  }
+}
+
+/*******************************************************************
+  Computes the want for an operation
+ ******************************************************************/
+static int find_something_to_paradrop(struct unit *punit, int x, int y)
+{ int profit = 0;
+  int range = unit_type(punit)->paratroopers_range;
+  struct city *acity = NULL;
+  struct player *pplayer = unit_owner(punit);
+
+  /* first, we search for undefended cities */
+  square_iterate(punit->x, punit->y, range, x, y) {
+    acity = map_get_city(x,y);
+    if ((acity) && (city_owner(acity) == pplayer) &&
+        (unit_list_size(&(map_get_tile(x, y)->units)) == 0)) {
+      /* own city and empty! */
+      if ((acity->size *
+           (acity->trade_prod + acity->shield_prod + acity->food_prod) *
+           acity->ai.urgency) > profit) {
+        profit = (acity->size *
+	          (acity->trade_prod + acity->shield_prod + acity->food_prod) *
+                  acity->ai.urgency);
+      }
+    }
+  } square_iterate_end;
+
+  /* second, we search for undefended enemy cities near us */
+  square_iterate(punit->x, punit->y, range, x, y) {
+    acity = map_get_city(x,y);
+    if ((acity) && pplayers_at_war(city_owner(acity), pplayer) &&
+        (unit_list_size(&(map_get_tile(x, y)->units)) == 0)) {
+      /* enemy city and empty! */
+      if ((acity->size *
+           (acity->trade_prod + acity->shield_prod + acity->food_prod)) > profit) {
+        profit = (acity->size *
+	          (acity->trade_prod + acity->shield_prod + acity->food_prod));
+      }
+    }
+  } square_iterate_end;
+
+  /* third, we search for enemy units near us */
+  square_iterate(punit->x, punit->y, range, x, y) {
+    struct tile *ptile = map_get_tile(x, y);
+    if (unit_list_size(&(ptile->units)) > 0) {
+      struct unit *pdef = unit_list_get(&ptile->units, 0);
+      if (pplayers_at_war(pplayer, unit_owner(pdef))) {
+        int benefit = stack_cost(pdef);
+        benefit = (benefit * punit->hp) / unit_type(punit)->hp;
+        if (benefit > profit) {
+          /* best enemy unit to kill! */
+          profit = benefit;
+        }
+      }
+    }
+  } square_iterate_end;
+
+  return profit;
+}
+
+/*******************************************************************
+ * Chooses to build a paratroop if necessary
+ ******************************************************************/
+void ai_choose_paratrooper(struct player *pplayer, struct city *pcity,
+                           struct ai_choice *choice)
+{
+
+  /* military_advisor_choose_build does something idiotic,
+   * this function should not be called if there is danger... */
+  if (choice->want >= 100 && choice->type != CT_ATTACKER) {
+    return;
+  }
+
+  unit_type_iterate(u_type) {
+    if (!unit_type_flag(u_type, F_PARATROOPERS)) {
+      continue;
+    }
+
+    if (!can_build_unit(pcity, u_type)) {
+      continue;
+    }
+
+    struct unit *virtual_unit =
+      create_unit_virtual(pplayer, pcity, u_type,
+                          do_make_unit_veteran(pcity, u_type));
+    int profit = find_something_to_paradrop(virtual_unit, pcity->x, pcity->y);
+    if (profit > choice->want){
+      /* Update choice */
+      choice->want = profit;
+      choice->choice = u_type;
+      choice->type = CT_ATTACKER;
+      freelog(LOGLEVEL_PARATROOPER, "%s wants to build %s (want=%d)",
+              pcity->name, get_unit_type(u_type)->name, profit);
+    }
+    destroy_unit_virtual(virtual_unit);
+  } unit_type_iterate_end;
+
+  return;
+}
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/aiparatrooper.h freeciv-cvs-Feb-27-paratroop/ai/aiparatrooper.h
--- freeciv-cvs-Feb-27/ai/aiparatrooper.h	1970-01-01 01:00:00.000000000 +0100
+++ freeciv-cvs-Feb-27-paratroop/ai/aiparatrooper.h	2004-03-18 02:34:36.000000000 +0100
@@ -0,0 +1,25 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__AIPARATROOPER_H
+#define FC__AIPARATROOPER_H
+
+struct ai_choice;
+struct city;
+struct player;
+struct unit;
+
+void ai_manage_paratrooper(struct player *pplayer, struct unit *punit);
+void ai_choose_paratrooper(struct player *pplayer, struct city *pcity,
+			   struct ai_choice *choice);
+
+#endif /* FC__AIPARATROOPER_H */
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/aiunit.c freeciv-cvs-Feb-27-paratroop/ai/aiunit.c
--- freeciv-cvs-Feb-27/ai/aiunit.c	2004-02-26 07:01:21.000000000 +0100
+++ freeciv-cvs-Feb-27-paratroop/ai/aiunit.c	2004-03-30 14:26:38.000000000 +0200
@@ -55,6 +55,7 @@
 #include "aidiplomat.h"
 #include "aihand.h"
 #include "ailog.h"
+#include "aiparatrooper.h"
 #include "aitools.h"
 
 #include "aiunit.h"
@@ -67,11 +68,6 @@
 static void ai_manage_barbarian_leader(struct player *pplayer,
 				       struct unit *leader);
 
-#define RAMPAGE_ANYTHING                 1
-#define RAMPAGE_HUT_OR_BETTER        99998
-#define RAMPAGE_FREE_CITY_OR_BETTER  99999
-static bool ai_military_rampage(struct unit *punit, int thresh_adj, 
-                                int thresh_move);
 static void ai_military_findjob(struct player *pplayer,struct unit *punit);
 static void ai_military_gohome(struct player *pplayer,struct unit *punit);
 static void ai_military_attack(struct player *pplayer,struct unit *punit);
@@ -665,7 +661,7 @@
 
   FIXME: We should check for fortresses here.
 **************************************************************************/
-static bool stay_and_defend(struct unit *punit)
+bool stay_and_defend(struct unit *punit)
 {
   struct city *pcity = map_get_city(punit->x, punit->y);
   bool has_defense = FALSE;
@@ -1052,7 +1048,7 @@
 
   Returns TRUE if survived the rampage session.
 **************************************************************************/
-static bool ai_military_rampage(struct unit *punit, int thresh_adj, 
+bool ai_military_rampage(struct unit *punit, int thresh_adj,
                                 int thresh_move)
 {
   int count = punit->moves_left + 1; /* break any infinite loops */
@@ -2653,6 +2649,9 @@
   } else if (unit_has_role(punit->type, L_BARBARIAN_LEADER)) {
     ai_manage_barbarian_leader(pplayer, punit);
     return;
+  } else if (unit_flag(punit, F_PARATROOPERS)) {
+    ai_manage_paratrooper(pplayer, punit);
+    return;
   } else if (get_transporter_capacity(punit) > 0) {
     ai_manage_ferryboat(pplayer, punit);
     return;
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/aiunit.h freeciv-cvs-Feb-27-paratroop/ai/aiunit.h
--- freeciv-cvs-Feb-27/ai/aiunit.h	2004-01-12 07:16:15.000000000 +0100
+++ freeciv-cvs-Feb-27-paratroop/ai/aiunit.h	2004-03-30 14:27:31.000000000 +0200
@@ -46,6 +46,11 @@
 
 extern Unit_Type_id simple_ai_types[U_LAST];
 
+#define RAMPAGE_ANYTHING                 1
+#define RAMPAGE_HUT_OR_BETTER        99998
+#define RAMPAGE_FREE_CITY_OR_BETTER  99999
+bool ai_military_rampage(struct unit *punit, int thresh_adj,
+                         int thresh_move);
 void ai_manage_units(struct player *pplayer); 
 int could_unit_move_to_tile(struct unit *punit, int dest_x, int dest_y);
 int look_for_charge(struct player *pplayer, struct unit *punit,
@@ -64,6 +69,7 @@
                     int *x, int *y);
 
 int build_cost_balanced(Unit_Type_id type);
+bool stay_and_defend(struct unit *punit);
 int unittype_att_rating(Unit_Type_id type, int veteran,
                         int moves_left, int hp);
 int unit_att_rating(struct unit *punit);
diff -NurEbB -Xfreeciv-cvs-Feb-27/diff_ignore freeciv-cvs-Feb-27/ai/Makefile.am freeciv-cvs-Feb-27-paratroop/ai/Makefile.am
--- freeciv-cvs-Feb-27/ai/Makefile.am	2003-09-22 07:00:04.000000000 +0200
+++ freeciv-cvs-Feb-27-paratroop/ai/Makefile.am	2004-03-18 01:07:19.000000000 +0100
@@ -25,6 +25,8 @@
 		aihand.h	\
 		ailog.c		\
 		ailog.h		\
+		aiparatrooper.c \
+		aiparatrooper.h \
 		aitech.c	\
 		aitech.h	\
 		aitools.c	\
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.