Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2003:
[Freeciv-Dev] (PR#6132) New function can_unit_attack_all_at_tile
Home

[Freeciv-Dev] (PR#6132) New function can_unit_attack_all_at_tile

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#6132) New function can_unit_attack_all_at_tile
From: "Gregory Berkolaiko" <Gregory.Berkolaiko@xxxxxxxxxxxx>
Date: Wed, 10 Sep 2003 15:50:54 -0700
Reply-to: rt@xxxxxxxxxxxxxx

It checks whether a unit can attack all units at the target tile, which is 
the rule now for a successful attack.

It should also be used in almost all cases instead of the direct call to 
can_unit_attack_unit_at_tile, which is done in the patch.

One direct call is still left, where we are checking wheter a unit, which 
is not there yet, can be attacked.

As a side effect, the loop in ai_manage_airunit (6123) would be prevented.


G.

? ai_activities.diff
Index: ai/aiair.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiair.c,v
retrieving revision 1.19
diff -u -r1.19 aiair.c
--- ai/aiair.c  2003/08/01 15:58:07     1.19
+++ ai/aiair.c  2003/09/10 22:49:09
@@ -98,7 +98,7 @@
 #define PROB_MULTIPLIER 100 /* should unify with those in combat.c */
 
   if ((pdefender == NULL) 
-      || !can_unit_attack_unit_at_tile(punit, pdefender, dest_x, dest_y)) {
+      || !can_unit_attack_all_at_tile(punit, dest_x, dest_y)) {
     return 0;
   }
 
Index: ai/aiunit.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aiunit.c,v
retrieving revision 1.285
diff -u -r1.285 aiunit.c
--- ai/aiunit.c 2003/08/31 17:21:03     1.285
+++ ai/aiunit.c 2003/09/10 22:49:10
@@ -1008,7 +1008,7 @@
     unit_list_iterate(ptile->units, aunit) {
       if (aunit == punit || aunit->owner != punit->owner)
        continue;
-      if (!can_unit_attack_unit_at_tile(aunit, pdef, pdef->x, pdef->y))
+      if (!can_unit_attack_all_at_tile(aunit, pdef->x, pdef->y))
        continue;
       d = get_virtual_defense_power(aunit->type, pdef->type, pdef->x,
                                    pdef->y, FALSE, FALSE);
@@ -1049,8 +1049,7 @@
   
   if (pdef) {
     
-    if (!can_player_attack_tile(pplayer, x, y)
-        || !can_unit_attack_unit_at_tile(punit, pdef, x, y)) {
+    if (!can_unit_attack_tile(punit, x, y)) {
       return 0;
     }
     
@@ -2284,7 +2283,10 @@
         continue;
       }
 
-      if (!can_unit_attack_unit_at_tile(punit, aunit, aunit->x, aunit->y)
+      /* We have to assume the attack is diplomatically ok.
+       * We cannot use can_player_attack_tile, because we might not
+       * be at war with aplayer yet */
+      if (!can_unit_attack_all_at_tile(punit, aunit->x, aunit->y)
           || !(aunit == get_defender(punit, aunit->x, aunit->y))) {
         /* We cannot attack it, or it is not the main defender. */
         continue;
Index: common/combat.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.c,v
retrieving revision 1.32
diff -u -r1.32 combat.c
--- common/combat.c     2003/08/27 16:27:32     1.32
+++ common/combat.c     2003/09/10 22:49:11
@@ -117,24 +117,30 @@
 }
 
 /***********************************************************************
+  To attack a stack, unit must be able to attack every unit there
+************************************************************************/
+bool can_unit_attack_all_at_tile(struct unit *punit, int x, int y)
+{
+  unit_list_iterate(map_get_tile(x, y)->units, aunit) {
+    if (!can_unit_attack_unit_at_tile(punit, aunit, x, y)) {
+      return FALSE;
+    }
+  } unit_list_iterate_end;
+
+  return TRUE;
+}
+
+/***********************************************************************
   Is unit (1) diplomatically allowed to attack and (2) physically able
   to do so?
 ***********************************************************************/
 bool can_unit_attack_tile(struct unit *punit, int dest_x, int dest_y)
 {
-  struct unit *pdefender;
-
   if (!can_player_attack_tile(unit_owner(punit), dest_x, dest_y)) {
     return FALSE;
   }
-
-  pdefender = get_defender(punit, dest_x, dest_y);
-  if (!pdefender) {
-    /* It must be the empty city! */
-    return TRUE;
-  }
 
-  return can_unit_attack_unit_at_tile(punit, pdefender, dest_x, dest_y);
+  return can_unit_attack_all_at_tile(punit, dest_x, dest_y);
 }
 
 /***********************************************************************
Index: common/combat.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/combat.h,v
retrieving revision 1.9
diff -u -r1.9 combat.h
--- common/combat.h     2003/06/04 20:05:40     1.9
+++ common/combat.h     2003/09/10 22:49:11
@@ -29,6 +29,7 @@
 bool can_player_attack_tile(struct player *pplayer, int x, int y);
 bool can_unit_attack_unit_at_tile(struct unit *punit, struct unit *pdefender,
                                   int dest_x, int dest_y);
+bool can_unit_attack_all_at_tile(struct unit *punit, int x, int y);
 bool can_unit_attack_tile(struct unit *punit, int dest_x, int dest_y);
 
 double win_chance(int as, int ahp, int afp, int ds, int dhp, int dfp);
Index: server/autoattack.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/autoattack.c,v
retrieving revision 1.47
diff -u -r1.47 autoattack.c
--- server/autoattack.c 2003/08/09 15:34:19     1.47
+++ server/autoattack.c 2003/09/10 22:49:11
@@ -129,22 +129,13 @@
     }
 
     /*
-     * c_u_a_u_a_t() seems to assume that attacker is in an adjacent tile but I
-     * do not think it matters.
-     *
-     * On the other hand, we already checked everything that this function
-     * checks, except for missiles trying to attack air units, so perhaps we
-     * should just do that check here?  But doing a final sanity check to make
-     * sure our attacker can engage the enemy at all seems safest.
-     *
      * Without this check, missiles are made useless for auto-attack as they
      * get triggered by fighters and bombers and end up being wasted when they
      * cannot engage.
      */
-    if (!can_unit_attack_unit_at_tile(punit, enemy, x, y)) {
-      freelog(LOG_DEBUG, "%s at (%d,%d) cannot attack %s at (%d,%d)",
-             unit_name(punit->type), punit->x, punit->y,
-             unit_name(enemy->type), x, y);
+    if (!can_unit_attack_all_at_tile(punit, x, y)) {
+      freelog(LOG_DEBUG, "%s at (%d,%d) cannot attack at (%d,%d)",
+             unit_name(punit->type), punit->x, punit->y, x, y);
       continue;
     }
 
Index: server/unithand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unithand.c,v
retrieving revision 1.269
diff -u -r1.269 unithand.c
--- server/unithand.c   2003/09/09 20:10:28     1.269
+++ server/unithand.c   2003/09/10 22:49:12
@@ -1067,13 +1067,11 @@
 
     if (victim) {
       /* Must be physically able to attack EVERY unit there */
-      unit_list_iterate(pdesttile->units, aunit) {
-        if (!can_unit_attack_unit_at_tile(punit, aunit, x, y)) {
-          notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
-                           _("Game: You can't attack there."));
-          return FALSE;
-        }
-      } unit_list_iterate_end;
+      if (!can_unit_attack_all_at_tile(punit, x, y)) {
+        notify_player_ex(pplayer, punit->x, punit->y, E_NOEVENT,
+                         _("Game: You can't attack there."));
+        return FALSE;
+      }
       
       handle_unit_attack_request(punit, victim);
       return TRUE;
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.249
diff -u -r1.249 unittools.c
--- server/unittools.c  2003/09/10 16:50:18     1.249
+++ server/unittools.c  2003/09/10 22:49:13
@@ -1260,8 +1260,9 @@
       continue;
     }
     unit_list_iterate(map_get_tile(x1, y1)->units, enemy) {
-      if (pplayers_at_war(unit_owner(enemy), unit_owner(punit)) &&
-         can_unit_attack_unit_at_tile(enemy, punit, x, y)) {
+      if (pplayers_at_war(unit_owner(enemy), unit_owner(punit)) 
+          && can_unit_attack_unit_at_tile(enemy, punit, x, y)
+          && can_unit_attack_all_at_tile(enemy, x, y)) {
        a += unit_att_rating(enemy);
        if ((a * a * 10) >= d) {
           /* The enemies combined strength is too big! */

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