stratagus-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Stratagus-CVS] stratagus/src/ai ai_plan.c


From: address@hidden
Subject: [Stratagus-CVS] stratagus/src/ai ai_plan.c
Date: 14 Dec 2003 21:46:33 +1100

CVSROOT:        /home/strat
Module name:    stratagus
Changes by:      <address@hidden>       03/12/14 21:46:33

Modified files:
        src/ai         : ai_plan.c 

Log message:
        Tabs, Cleanup

Patches:
Index: stratagus/src/ai/ai_plan.c
diff -u stratagus/src/ai/ai_plan.c:1.25 stratagus/src/ai/ai_plan.c:1.26
--- stratagus/src/ai/ai_plan.c:1.25     Mon Dec  1 07:03:31 2003
+++ stratagus/src/ai/ai_plan.c  Sun Dec 14 21:46:33 2003
@@ -1,16 +1,16 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
-//             \/                  \/          \//_____/            \/ 
+//             \/                  \/          \//_____/            \/
 //  ______________________                           ______________________
 //                        T H E   W A R   B E G I N S
 //         Stratagus - A free fantasy real time strategy game engine
 //
-/address@hidden ai_plan.c      -       AI planning functions. */
+/address@hidden ai_plan.c - AI planning functions. */
 //
-//      (c) Copyright 2002-2003 by Lutz Sammer and Jimmy Salmon
+//      (c) Copyright 2002-2004 by Lutz Sammer and Jimmy Salmon
 //
 //      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
@@ -26,19 +26,18 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_plan.c,v 1.25 2003/11/30 20:03:31 jsalmon3 Exp $
+//      $Id: ai_plan.c,v 1.26 2003/12/14 10:46:33 wizzard Exp $
 
 //@{
 
 /*----------------------------------------------------------------------------
---     Includes
+--  Includes
 ----------------------------------------------------------------------------*/
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "stratagus.h"
-
 #include "missile.h"
 #include "unittype.h"
 #include "map.h"
@@ -47,688 +46,693 @@
 #include "ai_local.h"
 
 /*----------------------------------------------------------------------------
---     Variables
+--  Variables
 ----------------------------------------------------------------------------*/
 
 /*----------------------------------------------------------------------------
---     Functions
+--  Functions
 ----------------------------------------------------------------------------*/
 
 /**
-**     Choose enemy on map tile.
+**  Choose enemy on map tile.
 **
-**     @param source   Unit which want to attack.
-**     @param tx       X position on map, tile-based.
-**     @param ty       Y position on map, tile-based.
+**  @param source  Unit which want to attack.
+**  @param tx      X position on map, tile-based.
+**  @param ty      Y position on map, tile-based.
 **
-**     @return         Returns ideal target on map tile.
+**  @return        Returns ideal target on map tile.
 */
-local Unit *EnemyOnMapTile(const Unit * source, int tx, int ty)
+local Unit* EnemyOnMapTile(const Unit* source, int tx, int ty)
 {
-    Unit *table[UnitMax];
-    Unit *unit;
-    Unit *best;
-    const UnitType *type;
-    int n;
-    int i;
-
-    n = SelectUnitsOnTile(tx, ty, table);
-    best = NoUnitP;
-    for (i = 0; i < n; ++i) {
-       unit = table[i];
-       // unusable unit ?
-       // if( UnitUnusable(unit) ) can't attack constructions
-       // FIXME: did SelectUnitsOnTile already filter this?
-       // Invisible and not Visible
-       if (unit->Removed || unit->Invisible || !unit->HP
-           || !(unit->Visible & (1 << source->Player->Player))
-           || unit->Orders[0].Action == UnitActionDie) {
-           continue;
-       }
-       type = unit->Type;
-       if (tx < unit->X || tx >= unit->X + type->TileWidth
-           || ty < unit->Y || ty >= unit->Y + type->TileHeight) {
-           continue;
-       }
-       if (!CanTarget(source->Type, unit->Type)) {
-           continue;
-       }
-       if (!IsEnemy(source->Player, unit)) {   // a friend or neutral
-           continue;
-       }
-       //
-       //      Choose the best target.
-       //
-       if (!best || best->Type->Priority < unit->Type->Priority) {
-           best = unit;
+       Unit* table[UnitMax];
+       Unit* unit;
+       Unit* best;
+       const UnitType* type;
+       int n;
+       int i;
+
+       n = SelectUnitsOnTile(tx, ty, table);
+       best = NoUnitP;
+       for (i = 0; i < n; ++i) {
+               unit = table[i];
+               // unusable unit ?
+               // if( UnitUnusable(unit) ) can't attack constructions
+               // FIXME: did SelectUnitsOnTile already filter this?
+               // Invisible and not Visible
+               if (unit->Removed || unit->Invisible || !unit->HP
+                       || !(unit->Visible & (1 << source->Player->Player))
+                       || unit->Orders[0].Action == UnitActionDie) {
+                       continue;
+               }
+               type = unit->Type;
+               if (tx < unit->X || tx >= unit->X + type->TileWidth
+                       || ty < unit->Y || ty >= unit->Y + type->TileHeight) {
+                       continue;
+               }
+               if (!CanTarget(source->Type, unit->Type)) {
+                       continue;
+               }
+               if (!IsEnemy(source->Player, unit)) { // a friend or neutral
+                       continue;
+               }
+               //
+               // Choose the best target.
+               //
+               if (!best || best->Type->Priority < unit->Type->Priority) {
+                       best = unit;
+               }
        }
-    }
-    return best;
+       return best;
 }
 
 /**
-**     Mark all by transporter reachable water tiles.
+**  Mark all by transporter reachable water tiles.
 **
-**     @param unit     Transporter
-**     @param matrix   Water matrix.
+**  @param unit    Transporter
+**  @param matrix  Water matrix.
 **
-**     @note only works for water transporters!
+**  @note only works for water transporters!
 */
 local void AiMarkWaterTransporter(const Unit * unit, unsigned char *matrix)
 {
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-       unsigned short X;
-       unsigned short Y;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    unsigned char *m;
-
-    x = unit->X;
-    y = unit->Y;
-    w = TheMap.Width + 2;
-    matrix += w + w + 2;
-    if (matrix[x + y * w]) {           // already marked
-       DebugLevel0("Done\n");
-       return;
-    }
-
-    points = malloc(TheMap.Width * TheMap.Height);
-    size = TheMap.Width * TheMap.Height / sizeof (*points);
-
-    //
-    //  Make movement matrix.
-    //
-    mask = UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
-
-    points[0].X = x;
-    points[0].Y = y;
-    rp = 0;
-    matrix[x + y * w] = 66;            // mark start point
-    ep = wp = 1;                       // start with one point
-
-    //
-    //  Pop a point from stack, push all neightbors which could be entered.
-    //
-    for (;;) {
-       while (rp != ep) {
-           rx = points[rp].X;
-           ry = points[rp].Y;
-           for (i = 0; i < 8; ++i) {   // mark all neighbors
-               x = rx + xoffset[i];
-               y = ry + yoffset[i];
-               m = matrix + x + y * w;
-               if (*m) {               // already checked
-                   continue;
-               }
-
-               if (CanMoveToMask(x, y, mask)) {        // reachable
-
-                   *m = 66;
-                   points[wp].X = x;   // push the point
-                   points[wp].Y = y;
-                   if (++wp >= size) { // round about
-                       wp = 0;
-                   }
-                   /*      Must be checked multiple
-                      } else {                     // unreachable
-                      *m=99;
-                    */
-               }
-           }
-
-           if (++rp >= size) {         // round about
-               rp = 0;
-           }
-       }
-
-       //
-       //      Continue with next frame.
+       static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+       static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+       struct {
+               unsigned short X;
+               unsigned short Y;
+       } *points;
+       int size;
+       int x;
+       int y;
+       int rx;
+       int ry;
+       int mask;
+       int wp;
+       int rp;
+       int ep;
+       int i;
+       int w;
+       unsigned char *m;
+
+       x = unit->X;
+       y = unit->Y;
+       w = TheMap.Width + 2;
+       matrix += w + w + 2;
+       if (matrix[x + y * w]) { // already marked
+               DebugLevel0("Done\n");
+               return;
+       }
+
+       points = malloc(TheMap.Width * TheMap.Height);
+       size = TheMap.Width * TheMap.Height / sizeof (*points);
+
+       //
+       // Make movement matrix.
+       //
+       mask = UnitMovementMask(unit);
+       // Ignore all possible mobile units.
+       mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
+
+       points[0].X = x;
+       points[0].Y = y;
+       rp = 0;
+       matrix[x + y * w] = 66; // mark start point
+       ep = wp = 1; // start with one point
+
+       //
+       // Pop a point from stack, push all neightbors which could be entered.
        //
-       if (rp == wp) {                 // unreachable, no more points available
-           break;
+       for (;;) {
+               while (rp != ep) {
+                       rx = points[rp].X;
+                       ry = points[rp].Y;
+                       for (i = 0; i < 8; ++i) { // mark all neighbors
+                               x = rx + xoffset[i];
+                               y = ry + yoffset[i];
+                               m = matrix + x + y * w;
+                               if (*m) { // already checked
+                                       continue;
+                               }
+
+                               if (CanMoveToMask(x, y, mask)) { // reachable
+                                       *m = 66;
+                                       points[wp].X = x; // push the point
+                                       points[wp].Y = y;
+                                       if (++wp >= size) { // round about
+                                               wp = 0;
+                                       }
+                                       /* Must be checked multiple
+                                          } else { // unreachable
+                                          *m=99;
+                                        */
+                               }
+                       }
+
+                       if (++rp >= size) { // round about
+                               rp = 0;
+                       }
+               }
+
+               //
+               // Continue with next frame.
+               //
+               if (rp == wp) { // unreachable, no more points available
+                       break;
+               }
+               ep = wp;
        }
-       ep = wp;
-    }
 
-    free(points);
+       free(points);
 }
 
 /**
-**     Find possible targets.
+**  Find possible targets.
 **
-**     @param unit     Attack.
-**     @param matrix   Water matrix.
-**     @param dx       Attack point X.
-**     @param dy       Attack point Y.
-**     @param ds       Attack state.
+**  @param unit    Attack.
+**  @param matrix  Water matrix.
+**  @param dx      Attack point X.
+**  @param dy      Attack point Y.
+**  @param ds      Attack state.
 **
-**     @return         True if target found.
+**  @return        True if target found.
 */
-local int AiFindTarget(const Unit * unit, unsigned char *matrix, int *dx, int 
*dy,
-    int *ds)
+local int AiFindTarget(const Unit* unit, unsigned char* matrix, int* dx, int* 
dy,
+       int* ds)
 {
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-       unsigned short X;
-       unsigned short Y;
-       unsigned char State;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    enum { OnWater, OnLand, OnIsle } state;
-    unsigned char *m;
-
-    size = TheMap.Width * TheMap.Height / 2;
-    points = malloc(size * sizeof (*points));
-
-    x = unit->X;
-    y = unit->Y;
-
-    w = TheMap.Width + 2;
-    mask = UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
-
-    points[0].X = x;
-    points[0].Y = y;
-    points[0].State = OnLand;
-    matrix += w + w + 2;
-    rp = 0;
-    matrix[x + y * w] = 1;             // mark start point
-    ep = wp = 1;                       // start with one point
-
-    //
-    //  Pop a point from stack, push all neightbors which could be entered.
-    //
-    for (;;) {
-       while (rp != ep) {
-           rx = points[rp].X;
-           ry = points[rp].Y;
-           state = points[rp].State;
-           for (i = 0; i < 8; ++i) {   // mark all neighbors
-               x = rx + xoffset[i];
-               y = ry + yoffset[i];
-               m = matrix + x + y * w;
-
-               if (state != OnWater) {
-                   if (*m) {           // already checked
-                       if (state == OnLand && *m == 66) {      // tansporter?
-                           DebugLevel0Fn("->Water\n");
-                           *m = 6;
-                           points[wp].X = x;   // push the point
-                           points[wp].Y = y;
-                           points[wp].State = OnWater;
-                           if (++wp >= size) { // round about
-                               wp = 0;
-                           }
-                       }
-                       continue;
-                   }
-                   // Check targets on tile?
-                   // FIXME: the move code didn't likes a shore building as
-                   //          target
-                   if (EnemyOnMapTile(unit, x, y)) {
-                       DebugLevel0Fn("Target found %d,%d-%d\n" _C_ x _C_ y _C_ 
state);
-                       *dx = x;
-                       *dy = y;
-                       *ds = state;
-                       free(points);
-                       return 1;
-                   }
-
-                   if (CanMoveToMask(x, y, mask)) {    // reachable
-
-                       *m = 1;
-                       points[wp].X = x;       // push the point
-                       points[wp].Y = y;
-                       points[wp].State = state;
-                       if (++wp >= size) {     // round about
-                           wp = 0;
-                       }
-                   } else {            // unreachable
-                       *m = 99;
-                   }
-               } else {                // On water
-                   if (*m) {           // already checked 
-                       if (*m == 66) { // tansporter?
-                           *m = 6;
-                           points[wp].X = x;   // push the point
-                           points[wp].Y = y;
-                           points[wp].State = OnWater;
-                           if (++wp >= size) { // round about
-                               wp = 0;
-                           }
+       static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+       static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+       struct {
+               unsigned short X;
+               unsigned short Y;
+               unsigned char State;
+       } *points;
+       int size;
+       int x;
+       int y;
+       int rx;
+       int ry;
+       int mask;
+       int wp;
+       int rp;
+       int ep;
+       int i;
+       int w;
+       enum { 
+               OnWater,
+               OnLand,
+               OnIsle
+       } state;
+       unsigned char* m;
+
+       size = TheMap.Width * TheMap.Height / 2;
+       points = malloc(size * sizeof (*points));
+
+       x = unit->X;
+       y = unit->Y;
+
+       w = TheMap.Width + 2;
+       mask = UnitMovementMask(unit);
+       // Ignore all possible mobile units.
+       mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
+
+       points[0].X = x;
+       points[0].Y = y;
+       points[0].State = OnLand;
+       matrix += w + w + 2;
+       rp = 0;
+       matrix[x + y * w] = 1; // mark start point
+       ep = wp = 1; // start with one point
+
+       //
+       // Pop a point from stack, push all neightbors which could be entered.
+       //
+       for (;;) {
+               while (rp != ep) {
+                       rx = points[rp].X;
+                       ry = points[rp].Y;
+                       state = points[rp].State;
+                       for (i = 0; i < 8; ++i) { // mark all neighbors
+                               x = rx + xoffset[i];
+                               y = ry + yoffset[i];
+                               m = matrix + x + y * w;
+
+                               if (state != OnWater) {
+                                       if (*m) { // already checked
+                                               if (state == OnLand && *m == 
66) { // tansporter?
+                                                       
DebugLevel0Fn("->Water\n");
+                                                       *m = 6;
+                                                       points[wp].X = x; // 
push the point
+                                                       points[wp].Y = y;
+                                                       points[wp].State = 
OnWater;
+                                                       if (++wp >= size) { // 
round about
+                                                               wp = 0;
+                                                       }
+                                               }
+                                               continue;
+                                       }
+                                       // Check targets on tile?
+                                       // FIXME: the move code didn't likes a 
shore building as
+                                       //  target
+                                       if (EnemyOnMapTile(unit, x, y)) {
+                                               DebugLevel0Fn("Target found 
%d,%d-%d\n" _C_ x _C_ y _C_ state);
+                                               *dx = x;
+                                               *dy = y;
+                                               *ds = state;
+                                               free(points);
+                                               return 1;
+                                       }
+
+                                       if (CanMoveToMask(x, y, mask)) { // 
reachable
+
+                                               *m = 1;
+                                               points[wp].X = x; // push the 
point
+                                               points[wp].Y = y;
+                                               points[wp].State = state;
+                                               if (++wp >= size) { // round 
about
+                                                       wp = 0;
+                                               }
+                                       } else { // unreachable
+                                               *m = 99;
+                                       }
+                               } else { // On water
+                                       if (*m) { // already checked
+                                               if (*m == 66) { // tansporter?
+                                                       *m = 6;
+                                                       points[wp].X = x; // 
push the point
+                                                       points[wp].Y = y;
+                                                       points[wp].State = 
OnWater;
+                                                       if (++wp >= size) { // 
round about
+                                                               wp = 0;
+                                                       }
+                                               }
+                                               continue;
+                                       }
+                                       if (CanMoveToMask(x, y, mask)) { // 
reachable
+                                               DebugLevel0Fn("->Land\n");
+                                               *m = 1;
+                                               points[wp].X = x; // push the 
point
+                                               points[wp].Y = y;
+                                               points[wp].State = OnIsle;
+                                               if (++wp >= size) { // round 
about
+                                                       wp = 0;
+                                               }
+                                       } else { // unreachable
+                                               *m = 99;
+                                       }
+                               }
                        }
-                       continue;
-                   }
-                   if (CanMoveToMask(x, y, mask)) {    // reachable
-                       DebugLevel0Fn("->Land\n");
-                       *m = 1;
-                       points[wp].X = x;       // push the point
-                       points[wp].Y = y;
-                       points[wp].State = OnIsle;
-                       if (++wp >= size) {     // round about
-                           wp = 0;
+
+                       if (++rp >= size) { // round about
+                               rp = 0;
                        }
-                   } else {            // unreachable
-                       *m = 99;
-                   }
                }
-           }
-
-           if (++rp >= size) {         // round about
-               rp = 0;
-           }
-       }
 
-       //
-       //      Continue with next frame.
-       //
-       if (rp == wp) {                 // unreachable, no more points available
-           break;
+               //
+               // Continue with next frame.
+               //
+               if (rp == wp) { // unreachable, no more points available
+                       break;
+               }
+               ep = wp;
        }
-       ep = wp;
-    }
-    free(points);
-    return 0;
+       free(points);
+       return 0;
 }
 
 /**
-**     Find possible walls to target.
+**  Find possible walls to target.
 **
-**     @param force    Attack force.
+**  @param force  Attack force.
 **
-**     @return         True if wall found.
+**  @return       True if wall found.
 */
-global int AiFindWall(AiForce * force)
+global int AiFindWall(AiForce* force)
 {
-    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
-    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
-    struct {
-       unsigned short X;
-       unsigned short Y;
-    }     *points;
-    int size;
-    int x;
-    int y;
-    int rx;
-    int ry;
-    int mask;
-    int wp;
-    int rp;
-    int ep;
-    int i;
-    int w;
-    unsigned char *m;
-    unsigned char *matrix;
-    int destx;
-    int desty;
-    AiUnit *aiunit;
-    Unit *unit;
-
-    // Find a unit to use.  Best choice is a land unit with range 1.
-    // Next best choice is any land unit.  Otherwise just use the first.
-    aiunit = force->Units;
-    unit = aiunit->Unit;
-    while (aiunit) {
-       if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
-           unit = aiunit->Unit;
-           if (aiunit->Unit->Type->Missile.Missile->Range == 1) {
-               break;
-           }
-       }
-       aiunit = aiunit->Next;
-    }
-
-    x = unit->X;
-    y = unit->Y;
-    size = TheMap.Width * TheMap.Height / 4;
-    points = malloc(size * sizeof (*points));
-
-    destx = -1;
-    desty = -1;
-
-    matrix = CreateMatrix();
-    w = TheMap.Width + 2;
-    matrix += w + w + 2;
-
-    points[0].X = x;
-    points[0].Y = y;
-    rp = 0;
-    matrix[x + y * w] = 1;             // mark start point
-    ep = wp = 1;                       // start with one point
-
-    mask = UnitMovementMask(unit);
-
-    //
-    //  Pop a point from stack, push all neighbors which could be entered.
-    //
-    for (; destx == -1;) {
-       while (rp != ep && destx == -1) {
-           rx = points[rp].X;
-           ry = points[rp].Y;
-           for (i = 0; i < 8; ++i) {   // mark all neighbors
-               x = rx + xoffset[i];
-               y = ry + yoffset[i];
-               m = matrix + x + y * w;
-               if (*m) {
-                   continue;
-               }
-               // 
-               //      Check for a wall
-               //
-               if (WallOnMap(x, y)) {
-                   DebugLevel0Fn("Wall found %d,%d\n" _C_ x _C_ y);
-                   destx = x;
-                   desty = y;
-                   break;
-               }
+       static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+       static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+       struct {
+               unsigned short X;
+               unsigned short Y;
+       } *points;
+       int size;
+       int x;
+       int y;
+       int rx;
+       int ry;
+       int mask;
+       int wp;
+       int rp;
+       int ep;
+       int i;
+       int w;
+       unsigned char *m;
+       unsigned char *matrix;
+       int destx;
+       int desty;
+       AiUnit *aiunit;
+       Unit *unit;
 
-               if (CanMoveToMask(x, y, mask)) {        // reachable
-                   *m = 1;
-                   points[wp].X = x;   // push the point
-                   points[wp].Y = y;
-                   if (++wp >= size) { // round about
-                       wp = 0;
-                   }
-               } else {                // unreachable
-                   *m = 99;
+       // Find a unit to use.  Best choice is a land unit with range 1.
+       // Next best choice is any land unit.  Otherwise just use the first.
+       aiunit = force->Units;
+       unit = aiunit->Unit;
+       while (aiunit) {
+               if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
+                       unit = aiunit->Unit;
+                       if (aiunit->Unit->Type->Missile.Missile->Range == 1) {
+                               break;
+                       }
                }
-           }
-           if (++rp >= size) {         // round about
-               rp = 0;
-           }
+               aiunit = aiunit->Next;
        }
 
+       x = unit->X;
+       y = unit->Y;
+       size = TheMap.Width * TheMap.Height / 4;
+       points = malloc(size * sizeof (*points));
+
+       destx = -1;
+       desty = -1;
+
+       matrix = CreateMatrix();
+       w = TheMap.Width + 2;
+       matrix += w + w + 2;
+
+       points[0].X = x;
+       points[0].Y = y;
+       rp = 0;
+       matrix[x + y * w] = 1; // mark start point
+       ep = wp = 1; // start with one point
+
+       mask = UnitMovementMask(unit);
+
        //
-       //      Continue with next frame.
+       // Pop a point from stack, push all neighbors which could be entered.
        //
-       if (rp == wp) {                 // unreachable, no more points available
-           break;
+       for (; destx == -1;) {
+               while (rp != ep && destx == -1) {
+                       rx = points[rp].X;
+                       ry = points[rp].Y;
+                       for (i = 0; i < 8; ++i) { // mark all neighbors
+                               x = rx + xoffset[i];
+                               y = ry + yoffset[i];
+                               m = matrix + x + y * w;
+                               if (*m) {
+                                       continue;
+                               }
+                               //
+                               // Check for a wall
+                               //
+                               if (WallOnMap(x, y)) {
+                                       DebugLevel0Fn("Wall found %d,%d\n" _C_ 
x _C_ y);
+                                       destx = x;
+                                       desty = y;
+                                       break;
+                               }
+
+                               if (CanMoveToMask(x, y, mask)) { // reachable
+                                       *m = 1;
+                                       points[wp].X = x; // push the point
+                                       points[wp].Y = y;
+                                       if (++wp >= size) { // round about
+                                               wp = 0;
+                                       }
+                               } else { // unreachable
+                                       *m = 99;
+                               }
+                       }
+                       if (++rp >= size) { // round about
+                               rp = 0;
+                       }
+               }
+
+               //
+               // Continue with next frame.
+               //
+               if (rp == wp) { // unreachable, no more points available
+                       break;
+               }
+               ep = wp;
        }
-       ep = wp;
-    }
-    free(points);
+       free(points);
 
-    if (destx != -1) {
-       force->State = 0;
-       aiunit = force->Units;
-       while (aiunit) {
-           if (aiunit->Unit->Type->CanAttack) {
-               CommandAttack(aiunit->Unit, destx, desty, NULL, FlushCommands);
-           } else {
-               CommandMove(aiunit->Unit, destx, desty, FlushCommands);
-           }
-           aiunit = aiunit->Next;
+       if (destx != -1) {
+               force->State = 0;
+               aiunit = force->Units;
+               while (aiunit) {
+                       if (aiunit->Unit->Type->CanAttack) {
+                               CommandAttack(aiunit->Unit, destx, desty, NULL, 
FlushCommands);
+                       } else {
+                               CommandMove(aiunit->Unit, destx, desty, 
FlushCommands);
+                       }
+                       aiunit = aiunit->Next;
+               }
+               return 1;
        }
-       return 1;
-    }
 
-    return 0;
+       return 0;
 }
 
 /**
-**     Plan an attack with a force.
-**     We know, that we must use a transporter.
+**  Plan an attack with a force.
+**  We know, that we must use a transporter.
 **
-**     @param force    Pointer on the force.
+**  @param force  Pointer on the force.
 **
-**     @return         True if target found, false otherwise.
+**  @return       True if target found, false otherwise.
 **
-**     @todo   Perfect planning.
-**             Only works for water transporter!
+**  @todo         Perfect planning.
+**                Only works for water transporter!
 */
-global int AiPlanAttack(AiForce * force)
+global int AiPlanAttack(AiForce* force)
 {
-    char *watermatrix;
-    const AiUnit *aiunit;
-    int x;
-    int y;
-    int i;
-    int state;
-    Unit *transporter;
-
-    DebugLevel0Fn("Planning for force #%d of player #%d\n"
-       _C_ force - AiPlayer->Force _C_ AiPlayer->Player->Player);
-
-    watermatrix = CreateMatrix();
-
-    //
-    //  Transporter must be already assigned to the force.
-    //  NOTE: finding free transportes was too much work for me.
-    //
-    aiunit = force->Units;
-    state = 1;
-    while (aiunit) {
-       if (aiunit->Unit->Type->Transporter) {
-           DebugLevel0Fn("Transporter #%d\n" _C_ UnitNumber(aiunit->Unit));
-           AiMarkWaterTransporter(aiunit->Unit, watermatrix);
-           state = 0;
-       }
-       aiunit = aiunit->Next;
-    }
-
-    //
-    //  No transport that belongs to the force.
-    //
-    transporter = NULL;
-    if (state) {
-       for (i = 0; i < AiPlayer->Player->TotalNumUnits; ++i) {
-           Unit *unit;
-
-           unit = AiPlayer->Player->Units[i];
-           if (unit->Type->Transporter && UnitIdle(unit)) {
-               DebugLevel0Fn("Assign any transporter\n");
-               AiMarkWaterTransporter(unit, watermatrix);
-               // FIXME: can be the wrong transporter.
-               transporter = unit;
-               state = 0;
-           }
-       }
-    }
-
-    if (state) {                       // Absolute no transporter
-       DebugLevel0Fn("No transporter available\n");
-       // FIXME: should tell the resource manager we need a transporter!
-       return 0;
-    }
-    //
-    //  Find a land unit of the force.
-    //          FIXME: if force is split over different places -> broken
-    //
-    aiunit = force->Units;
-    while (aiunit) {
-       if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
-           DebugLevel0Fn("Landunit %d\n" _C_ UnitNumber(aiunit->Unit));
-           break;
+       char* watermatrix;
+       const AiUnit* aiunit;
+       int x;
+       int y;
+       int i;
+       int state;
+       Unit* transporter;
+
+       DebugLevel0Fn("Planning for force #%d of player #%d\n"
+               _C_ force - AiPlayer->Force _C_ AiPlayer->Player->Player);
+
+       watermatrix = CreateMatrix();
+
+       //
+       // Transporter must be already assigned to the force.
+       // NOTE: finding free transportes was too much work for me.
+       //
+       aiunit = force->Units;
+       state = 1;
+       while (aiunit) {
+               if (aiunit->Unit->Type->Transporter) {
+                       DebugLevel0Fn("Transporter #%d\n" _C_ 
UnitNumber(aiunit->Unit));
+                       AiMarkWaterTransporter(aiunit->Unit, watermatrix);
+                       state = 0;
+               }
+               aiunit = aiunit->Next;
        }
-       aiunit = aiunit->Next;
-    }
 
-    if (!aiunit) {
-       DebugLevel0Fn("No land unit in force\n");
-       return 0;
-    }
+       //
+       // No transport that belongs to the force.
+       //
+       transporter = NULL;
+       if (state) {
+               for (i = 0; i < AiPlayer->Player->TotalNumUnits; ++i) {
+                       Unit *unit;
+
+                       unit = AiPlayer->Player->Units[i];
+                       if (unit->Type->Transporter && UnitIdle(unit)) {
+                               DebugLevel0Fn("Assign any transporter\n");
+                               AiMarkWaterTransporter(unit, watermatrix);
+                               // FIXME: can be the wrong transporter.
+                               transporter = unit;
+                               state = 0;
+                       }
+               }
+       }
 
-    if (AiFindTarget(aiunit->Unit, watermatrix, &x, &y, &state)) {
-       AiUnit *aiunit;
+       if (state) { // Absolute no transporter
+               DebugLevel0Fn("No transporter available\n");
+               // FIXME: should tell the resource manager we need a 
transporter!
+               return 0;
+       }
+       //
+       // Find a land unit of the force.
+       // FIXME: if force is split over different places -> broken
+       //
+       aiunit = force->Units;
+       while (aiunit) {
+               if (aiunit->Unit->Type->UnitType == UnitTypeLand) {
+                       DebugLevel0Fn("Landunit %d\n" _C_ 
UnitNumber(aiunit->Unit));
+                       break;
+               }
+               aiunit = aiunit->Next;
+       }
 
-       if (transporter) {
-           aiunit = malloc(sizeof (*aiunit));
-           aiunit->Next = force->Units;
-           force->Units = aiunit;
-           aiunit->Unit = transporter;
-           RefsIncrease(transporter);
-       }
-
-       DebugLevel0Fn("Can attack\n");
-       force->GoalX = x;
-       force->GoalY = y;
-       force->MustTransport = state == 2;
-
-       force->State = 1;
-       return 1;
-    }
-    return 0;
+       if (!aiunit) {
+               DebugLevel0Fn("No land unit in force\n");
+               return 0;
+       }
+
+       if (AiFindTarget(aiunit->Unit, watermatrix, &x, &y, &state)) {
+               AiUnit *aiunit;
+
+               if (transporter) {
+                       aiunit = malloc(sizeof (*aiunit));
+                       aiunit->Next = force->Units;
+                       force->Units = aiunit;
+                       aiunit->Unit = transporter;
+                       RefsIncrease(transporter);
+               }
+
+               DebugLevel0Fn("Can attack\n");
+               force->GoalX = x;
+               force->GoalY = y;
+               force->MustTransport = state == 2;
+
+               force->State = 1;
+               return 1;
+       }
+       return 0;
 }
 
 /**
-**     Respond to ExplorationRequests
+**  Respond to ExplorationRequests
 */
 void AiSendExplorers(void)
 {
-    AiExplorationRequest* request;
-    int requestcount;
-    int requestid;
-    int centerx,centery;
-    int x,y;
-    int i;
-    int targetok;
-    int ray;
-    int trycount;
-    int outtrycount;
-    
-    Unit** unit;
-    UnitType * type;
-    Unit* bestunit;
-    int distance;
-    int bestdistance;
-    int flyeronly;
-    
-    // Count requests...
-    request = AiPlayer->FirstExplorationRequest;
-    requestcount = 0;
-
-    while (request) {
-       requestcount ++;
-       
-       request = request->Next;
-    }
-
-    // Nothing => abort
-    if (!requestcount) {
-       return;
-    }
-
-    outtrycount = 0;
-    do {
-       bestunit = 0;
-       outtrycount++;
-
-       // Choose a request
-       requestid = SyncRand() % requestcount;
+       AiExplorationRequest* request;
+       int requestcount;
+       int requestid;
+       int centerx;
+       int centery;
+       int x;
+       int y;
+       int i;
+       int targetok;
+       int ray;
+       int trycount;
+       int outtrycount;
+
+       Unit** unit;
+       UnitType* type;
+       Unit* bestunit;
+       int distance;
+       int bestdistance;
+       int flyeronly;
 
+       // Count requests...
        request = AiPlayer->FirstExplorationRequest;
-       while (requestid) {
-           request = request->Next;
-           requestid--;
-       }
-       // Choose a target, "near"
-       centerx = request->X;
-       centery = request->Y;
-       ray = 3;
-       trycount = 0;
+       requestcount = 0;
+
+       while (request) {
+               requestcount ++;
 
+               request = request->Next;
+       }
+
+       // Nothing => abort
+       if (!requestcount) {
+               return;
+       }
+
+       outtrycount = 0;
        do {
-           targetok = 0;
+               bestunit = 0;
+               outtrycount++;
+
+               // Choose a request
+               requestid = SyncRand() % requestcount;
+
+               request = AiPlayer->FirstExplorationRequest;
+               while (requestid) {
+                       request = request->Next;
+                       requestid--;
+               }
+               // Choose a target, "near"
+               centerx = request->X;
+               centery = request->Y;
+               ray = 3;
+               trycount = 0;
+
+               do {
+                       targetok = 0;
+
+                       x = centerx + SyncRand() % (2 * ray + 1) - ray;
+                       y = centery + SyncRand() % (2 * ray + 1) - ray;
+
+                       if (x >= 0 && y >= 0 && x < TheMap.Width && y < 
TheMap.Height) {
+                               targetok = 
!IsMapFieldExplored(AiPlayer->Player, x, y);
+                       }
+
+                       ray = 3 * ray / 2;
+                       trycount ++;
+               } while (trycount < 8 && !targetok);
+
+               if (!targetok) {
+                       continue;
+               }
 
-           x = centerx + SyncRand() % (2 * ray + 1) - ray;
-           y = centery + SyncRand() % (2 * ray + 1) - ray;
+               // We have an unexplored tile in sight (x,y)
 
-           if (x >= 0 && y >= 0 && x < TheMap.Width && y < TheMap.Height) {
-               targetok = !IsMapFieldExplored(AiPlayer->Player, x, y);
-           }
-
-           ray = 3 * ray / 2;
-           trycount ++;
-       } while (trycount < 8 && !targetok);
-
-       if (!targetok) {
-           continue;
-       }
-
-       // We have an unexplored tile in sight (x,y)
-
-       // Find an idle unit, responding to the mask
-       flyeronly = 0;
-       bestdistance = -1;
-
-       unit = AiPlayer->Player->Units;
-       for (i = AiPlayer->Player->TotalNumUnits; i > 0; unit++) {
-           i--;
-
-           if (!UnitIdle((*unit))) {
-               continue;
-           }
-           
-           if ((*unit)->X == -1 || (*unit)->Y == -1) {
-               continue;
-           }
-
-           type = (*unit)->Type;
-
-           if (type->Building) {
-               continue;
-           }
-           
-           if (type->UnitType != UnitTypeFly) {
-               if (flyeronly) {
-                   continue;
-               }
-               if ((request->Mask & MapFieldLandUnit) && (type->UnitType != 
UnitTypeLand)) {
-                   continue;
-               }
-               if ((request->Mask & MapFieldSeaUnit) && (type->UnitType != 
UnitTypeNaval)) {
-                   continue;
-               }
-           } else {
-               flyeronly = 1;
-           }
-
-           distance = ((*unit)->X - x) * ((*unit)->X - x) + ((*unit)->Y - y) * 
((*unit)->Y - y);
-           if (bestdistance == -1 || distance <= bestdistance || 
-                   (bestunit->Type->UnitType != UnitTypeFly && type->UnitType 
== UnitTypeFly)) {
-               bestdistance = distance;
-               bestunit = (*unit);
-           }
-       }
-    } while(outtrycount <= 4 && !bestunit);
-    
-    if (bestunit) {
-       CommandMove(bestunit, x, y, FlushCommands);
-       AiPlayer->LastExplorationGameCycle=GameCycle;
-    }
-
-    // Remove all requests
-    while (AiPlayer->FirstExplorationRequest) {
-       request = AiPlayer->FirstExplorationRequest->Next;
-       free(AiPlayer->FirstExplorationRequest);
-       AiPlayer->FirstExplorationRequest = request;
-    }
+               // Find an idle unit, responding to the mask
+               flyeronly = 0;
+               bestdistance = -1;
+
+               unit = AiPlayer->Player->Units;
+               for (i = AiPlayer->Player->TotalNumUnits; i > 0; ++unit) {
+                       --i;
+
+                       if (!UnitIdle((*unit))) {
+                               continue;
+                       }
+
+                       if ((*unit)->X == -1 || (*unit)->Y == -1) {
+                               continue;
+                       }
+
+                       type = (*unit)->Type;
+
+                       if (type->Building) {
+                               continue;
+                       }
+
+                       if (type->UnitType != UnitTypeFly) {
+                               if (flyeronly) {
+                                       continue;
+                               }
+                               if ((request->Mask & MapFieldLandUnit) && 
(type->UnitType != UnitTypeLand)) {
+                                       continue;
+                               }
+                               if ((request->Mask & MapFieldSeaUnit) && 
(type->UnitType != UnitTypeNaval)) {
+                                       continue;
+                               }
+                       } else {
+                               flyeronly = 1;
+                       }
+
+                       distance = ((*unit)->X - x) * ((*unit)->X - x) + 
((*unit)->Y - y) * ((*unit)->Y - y);
+                       if (bestdistance == -1 || distance <= bestdistance ||
+                                       (bestunit->Type->UnitType != 
UnitTypeFly && type->UnitType == UnitTypeFly)) {
+                               bestdistance = distance;
+                               bestunit = (*unit);
+                       }
+               }
+       } while(outtrycount <= 4 && !bestunit);
+
+       if (bestunit) {
+               CommandMove(bestunit, x, y, FlushCommands);
+               AiPlayer->LastExplorationGameCycle=GameCycle;
+       }
+
+       // Remove all requests
+       while (AiPlayer->FirstExplorationRequest) {
+               request = AiPlayer->FirstExplorationRequest->Next;
+               free(AiPlayer->FirstExplorationRequest);
+               AiPlayer->FirstExplorationRequest = request;
+       }
 }
 
 //@}




reply via email to

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