Complete.Org: Mailing Lists: Archives: freeciv-ai: July 2006:
[freeciv-ai] Re: [Freeciv-Dev] (PR#18476) [Patch] generate_warmap() and
Home

[freeciv-ai] Re: [Freeciv-Dev] (PR#18476) [Patch] generate_warmap() and

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [freeciv-ai] Re: [Freeciv-Dev] (PR#18476) [Patch] generate_warmap() and "TerrainSpeed"
From: "Marko Lindqvist" <cazfi74@xxxxxxxxx>
Date: Sun, 16 Jul 2006 17:53:11 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=18476 >

Marko Lindqvist wrote:
> 
>   Make really_generate_warmap() UCF_TERRAIN_SPEED aware. I had to 
> rewrite most of it. Old version did several things I don't understand 
> and I left those out of this new version. This may fix some old bugs but 
> more likely brings new ones.

  - Updated against svn
  - Takes advantage of new interfaces present in svn version and #18623 
(requires it)
  - Again couple of bugs fixed


  - ML

diff -Nurd -X.diff_ignore freeciv/server/gotohand.c freeciv/server/gotohand.c
--- freeciv/server/gotohand.c   2006-07-17 02:32:10.484375000 +0300
+++ freeciv/server/gotohand.c   2006-07-17 03:43:45.125000000 +0300
@@ -270,10 +270,12 @@
 {
   int move_cost;
   struct tile *orig_tile;
-  bool igter;
+  bool igter, terrain_speed;
   int maxcost = THRESHOLD * 6 + 2; /* should be big enough without being TOO 
big */
   struct tile *ptile;
   struct player *pplayer;
+  struct unit_class *pclass = NULL;
+  int unit_speed = SINGLE_MOVE;
 
   if (pcity) {
     orig_tile = pcity->tile;
@@ -286,10 +288,24 @@
   init_warmap(orig_tile, move_type);
   add_to_mapqueue(0, orig_tile);
 
-  if (punit && unit_flag(punit, F_IGTER))
-    igter = TRUE;
-  else
-    igter = FALSE;
+  igter = FALSE;
+  if (punit) {
+    pclass = get_unit_class(unit_type(punit));
+
+    terrain_speed = unit_class_flag(get_unit_class(unit_type(punit)), 
UCF_TERRAIN_SPEED);
+    if (!terrain_speed /* Igter meaningless without terrain_speed */
+        && unit_flag(punit, F_IGTER)) {
+      igter = TRUE;
+    }
+    unit_speed = unit_move_rate(punit);
+  } else {
+    /* Guess - can result in bad city warmaps with custom rulesets */
+    if (move_type == LAND_MOVING || move_type == SEA_MOVING) {
+      terrain_speed = TRUE;
+    } else {
+      terrain_speed = FALSE;
+    }
+  }
 
   /* FIXME: Should this apply only to F_CITIES units? -- jjm */
   if (punit
@@ -305,71 +321,100 @@
                          ? WARMAP_SEACOST(ptile) : WARMAP_COST(ptile));
 
     adjc_dir_iterate(ptile, tile1, dir) {
-      switch (move_type) {
-      case LAND_MOVING:
-       if (WARMAP_COST(tile1) <= cost)
-         continue; /* No need for all the calculations */
-
-        if (is_ocean(tile_get_terrain(tile1))) {
-          if (punit &&
-              unit_class_transporter_capacity(tile1, pplayer,
-                                              
get_unit_class(unit_type(punit))) > 0)
-           move_cost = SINGLE_MOVE;
-          else
-           continue;
-       } else if (is_ocean(ptile->terrain)) {
-         int base_cost
-           = tile_get_terrain(tile1)->movement_cost * SINGLE_MOVE;
-
-         move_cost = igter ? MOVE_COST_ROAD : MIN(base_cost, 
unit_move_rate(punit));
-        } else if (igter)
-         /* NOT c = 1 (Syela) [why not? - Thue] */
-         move_cost = (map_move_cost_ai(ptile, tile1) != 0
-                      ? SINGLE_MOVE : 0);
-        else if (punit) {
-         const int tmp1 = map_move_cost_ai(ptile, tile1);
-         const int tmp2 = unit_move_rate(punit);
-
-         move_cost = MIN(tmp1, tmp2);
-#if 0
-       } else {
-         c = ptile->move_cost[k]; 
-         /* This led to a bad bug where a unit in a swamp was considered
-          * too far away. */
-#endif
+      if ((move_type == LAND_MOVING && WARMAP_COST(tile1) <= cost)
+          || (move_type == SEA_MOVING && WARMAP_SEACOST(tile1) <= cost)) {
+        continue; /* No need for calculations */
+      }
+  
+      if (!terrain_speed) {
+        if (punit) {
+          if (!can_unit_exist_at_tile(punit, tile1)) {
+            if (move_type == SEA_MOVING) {
+              /* Bombardment allowed for sea units... */
+              if (!is_native_tile(unit_type(punit), ptile)) {
+                /* ...but not from land city */
+                continue;
+              }
+              move_cost = SINGLE_MOVE;
+            } else {
+              /* Land or air moving */
+              if (move_type == LAND_MOVING
+                  && unit_class_transporter_capacity(tile1, pplayer, pclass) > 
0) {
+                /* Enters transport */
+                move_cost = SINGLE_MOVE;
+              } else {
+                /* Can't enter tile */
+                continue;
+              }
+            }
+          } else {
+            /* Punit can_exist_at_tile() */
+            move_cost = SINGLE_MOVE;
+          }
         } else {
-         /* we have a city */
-         const int tmp1 = map_move_cost_ai(tile1, ptile);
-         const int tmp2 = map_move_cost_ai(ptile, tile1);
-
-          move_cost = (tmp2 + tmp1 + (tmp2 > tmp1 ? 1 : 0)) / 2;
+          /* No punit */
+          if ((move_type == SEA_MOVING && !is_ocean(tile1->terrain))
+              || (move_type == LAND_MOVING && is_ocean(tile1->terrain))) {
+            /* Can't enter tile */
+            continue;
+          }
+          move_cost = SINGLE_MOVE;
         }
-
-        move_cost += cost;
+      } else {
+  
+        /* Speed determined by terrain */
+        if (punit) {
+          if (!can_unit_exist_at_tile(punit, tile1)) {
+            if (move_type == LAND_MOVING
+                && unit_class_transporter_capacity(tile1, pplayer, pclass) > 
0) {
+              move_cost = SINGLE_MOVE;            /* Go on board */
+            } else if (move_type == SEA_MOVING) {
+              /* Bombardment allowed for sea units */
+              if (!is_native_tile(unit_type(punit), ptile)) {
+                /* But not from land city */
+                continue;
+              }
+              move_cost = SINGLE_MOVE;
+            } else {
+              continue;                           /* Can't enter tile */
+            }
+          } else if (is_native_tile(unit_type(punit), tile1)) {
+            /* can_exist_at_tile() */ 
+            int base_cost = map_move_cost(ptile, tile1);
+  
+            base_cost = base_cost > unit_speed ? unit_speed : base_cost;
+            move_cost = igter ? MIN(MOVE_COST_ROAD, base_cost) : base_cost;
+          } else {
+            /* can_exist_at_tile(), but !is_native_tile() -> entering port */
+            move_cost = SINGLE_MOVE;
+          }
+        } else if ((move_type == LAND_MOVING && is_ocean(tile1->terrain))
+                   || (move_type == SEA_MOVING && !is_ocean(tile1->terrain))) {
+          continue;     /* City warmap ignores possible transports */
+        } else {
+          move_cost = map_move_cost(ptile, tile1);
+        }
+      }
+  
+      move_cost += cost;
+ 
+      if (move_type != SEA_MOVING) {
         if (WARMAP_COST(tile1) > move_cost && move_cost < maxcost) {
           warmap.cost[tile1->index] = move_cost;
           add_to_mapqueue(move_cost, tile1);
         }
-       break;
-
-
-      case SEA_MOVING:
-        move_cost = SINGLE_MOVE;
-        move_cost += cost;
+      } else if (move_type == SEA_MOVING) {
         if (WARMAP_SEACOST(tile1) > move_cost && move_cost < maxcost) {
-         /* by adding the move_cost to the warmap regardless if we
-            can move between we allow for shore bombardment/transport
-            to inland positions/etc. */
+          /* by adding the move_cost to the warmap regardless if we
+           * can move between we allow for shore bombardment/transport
+           * to inland positions/etc. */
           warmap.seacost[tile1->index] = move_cost;
-         if (map_move_cost_ai(ptile, tile1)
-             == MOVE_COST_FOR_VALID_SEA_STEP) {
-           add_to_mapqueue(move_cost, tile1);
-         }
-       }
-       break;
-      default:
-       move_cost = 0; /* silence compiler warning */
-       die("Bad/unimplemented move_type in really_generate_warmap().");
+          if ((punit && can_unit_exist_at_tile(punit, tile1))
+              || (!punit && (is_ocean(tile1->terrain) || tile1->city))) {
+            /* Unit can actually move to tile */
+            add_to_mapqueue(move_cost, tile1);
+         }
+        }
       }
     } adjc_dir_iterate_end;
   }

[Prev in Thread] Current Thread [Next in Thread]
  • [freeciv-ai] Re: [Freeciv-Dev] (PR#18476) [Patch] generate_warmap() and "TerrainSpeed", Marko Lindqvist <=