stratagus-cvs
[Top][All Lists]
Advanced

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

[Stratagus-CVS] stratagus/src action/action_attack.c action/act...


From: Crestez Leonard
Subject: [Stratagus-CVS] stratagus/src action/action_attack.c action/act...
Date: Thu, 20 Nov 2003 15:35:51 -0500

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/11/20 15:35:49

Modified files:
        src/action     : action_attack.c action_move.c action_resource.c 
                         actions.c 
        src/ai         : ai_plan.c ai_resource.c new_ai.c 
        src/clone      : mainloop.c unit.c unit_draw.c unit_find.c 
        src/include    : map.h unit.h 
        src/map        : map.c map_fog.c minimap.c 
        src/ui         : mouse.c 
        src/unit       : ccl_unit.c 

Log message:
        Try to fix Seen problems.

Patches:
Index: stratagus/src/action/action_attack.c
diff -u stratagus/src/action/action_attack.c:1.89 
stratagus/src/action/action_attack.c:1.90
--- stratagus/src/action/action_attack.c:1.89   Sun Nov  9 17:13:56 2003
+++ stratagus/src/action/action_attack.c        Thu Nov 20 15:35:40 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_attack.c,v 1.89 2003/11/09 22:13:56 n0body Exp $
+//     $Id: action_attack.c,v 1.90 2003/11/20 20:35:40 n0body Exp $
 
 //@{
 
@@ -77,7 +77,7 @@
 
     flags = UnitShowAnimation(unit, attack);
 
-    if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) || 
ReplayRevealMap)) {
+    if (flags & AnimationSound) {
        PlayUnitSound(unit, VoiceAttacking);
     }
 
Index: stratagus/src/action/action_move.c
diff -u stratagus/src/action/action_move.c:1.74 
stratagus/src/action/action_move.c:1.75
--- stratagus/src/action/action_move.c:1.74     Wed Nov 19 21:23:40 2003
+++ stratagus/src/action/action_move.c  Thu Nov 20 15:35:41 2003
@@ -21,7 +21,7 @@
 //     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 //     GNU General Public License for more details.
 //
-//     $Id: action_move.c,v 1.74 2003/11/20 02:23:40 pludov Exp $
+//     $Id: action_move.c,v 1.75 2003/11/20 20:35:41 n0body Exp $
 
 //@{
 
@@ -171,11 +171,6 @@
        uninside = unit->UnitInside;
        for (i = unit->InsideCount; i; uninside = uninside->NextContained, --i) 
{
            MapMarkUnitOnBoardSight(uninside, unit);
-       }
-
-       //  Reveal cloaked units.
-       if (unit->Type->DetectCloak) {
-           MapDetectCloakedUnits(unit);
        }
 
        unit->IX = -xd * TileSizeX;
Index: stratagus/src/action/action_resource.c
diff -u stratagus/src/action/action_resource.c:1.69 
stratagus/src/action/action_resource.c:1.70
--- stratagus/src/action/action_resource.c:1.69 Mon Nov 10 22:06:52 2003
+++ stratagus/src/action/action_resource.c      Thu Nov 20 15:35:41 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_resource.c,v 1.69 2003/11/11 03:06:52 n0body Exp $
+//     $Id: action_resource.c,v 1.70 2003/11/20 20:35:41 n0body Exp $
 
 //@{
 
@@ -254,7 +254,7 @@
        DebugCheck(!unit->Type->Animations->Harvest[unit->CurrentResource]);
        flags = UnitShowAnimation(unit,
            unit->Type->Animations->Harvest[unit->CurrentResource]);
-       if ((flags & AnimationSound) && (UnitVisibleOnMap(unit) || 
ReplayRevealMap)) {
+       if (flags & AnimationSound) {
            PlayUnitSound(unit, VoiceHarvesting);
        }
     }
Index: stratagus/src/action/actions.c
diff -u stratagus/src/action/actions.c:1.107 
stratagus/src/action/actions.c:1.108
--- stratagus/src/action/actions.c:1.107        Mon Nov 10 22:06:53 2003
+++ stratagus/src/action/actions.c      Thu Nov 20 15:35:41 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: actions.c,v 1.107 2003/11/11 03:06:53 n0body Exp $
+//     $Id: actions.c,v 1.108 2003/11/20 20:35:41 n0body Exp $
 
 //@{
 
@@ -95,10 +95,6 @@
            if (goal->Invisible) {
                return 1;
            }
-           //  Goal is cloaked for this player
-           if (!(goal->Visible & (1 << p))) {
-               return 1;
-           }
            //
            //  Check if under fog of war.
            //  Don't bother for goals visible under fog.
@@ -693,35 +689,6 @@
        SyncHash ^= unit->State << 12;
        SyncHash ^= unit->SubAction << 6;
        SyncHash ^= unit->Refs << 3;
-    }
-}
-
-/**
-**     Handle Marking and Unmarking of Cloak
-**
-**     @note Must be handled outside the drawing fucntions and
-**     @note all at once.
-*/
-global void HandleCloak(void)
-{
-    Unit* unit;
-    int i;
-
-    for (i = 0; i < NumUnits; ++i) {
-       unit = Units[i]; 
-       if (unit->Type->PermanentCloak) {
-           if ((unit->Visible & (1 << ThisPlayer->Player))) {
-               CheckUnitToBeDrawn(unit);
-           }
-           unit->Visible = 0;
-       }
-    }
-    for (i = 0; i < NumUnits; ++i) {
-       unit = Units[i];
-       if (unit->Type->DetectCloak && !unit->Removed &&
-               unit->Orders[0].Action != UnitActionBuilded) {
-           MapDetectCloakedUnits(unit);
-       }
     }
 }
 
Index: stratagus/src/ai/ai_plan.c
diff -u stratagus/src/ai/ai_plan.c:1.23 stratagus/src/ai/ai_plan.c:1.24
--- stratagus/src/ai/ai_plan.c:1.23     Thu Nov 20 11:48:12 2003
+++ stratagus/src/ai/ai_plan.c  Thu Nov 20 15:35:42 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_plan.c,v 1.23 2003/11/20 16:48:12 pludov Exp $
+//      $Id: ai_plan.c,v 1.24 2003/11/20 20:35:42 n0body Exp $
 
 //@{
 
@@ -49,6 +49,552 @@
 /*----------------------------------------------------------------------------
 --     Variables
 ----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+--     Functions
+----------------------------------------------------------------------------*/
+
+/**
+**     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.
+**
+**     @return         Returns ideal target on map tile.
+*/
+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->VisCount[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;
+}
+
+/**
+**     Mark all by transporter reachable water tiles.
+**
+**     @param unit     Transporter
+**     @param matrix   Water matrix.
+**
+**     @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.
+       //
+       if (rp == wp) {                 // unreachable, no more points available
+           break;
+       }
+       ep = wp;
+    }
+
+    free(points);
+}
+
+/**
+**     Find possible targets.
+**
+**     @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.
+*/
+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;
+                           }
+                       }
+                       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;
+                   }
+               }
+           }
+
+           if (++rp >= size) {         // round about
+               rp = 0;
+           }
+       }
+
+       //
+       //      Continue with next frame.
+       //
+       if (rp == wp) {                 // unreachable, no more points available
+           break;
+       }
+       ep = wp;
+    }
+    free(points);
+    return 0;
+}
+
+/**
+**     Find possible walls to target.
+**
+**     @param force    Attack force.
+**
+**     @return         True if wall found.
+*/
+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;
+               }
+
+               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;
+    }
+    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;
+       }
+       return 1;
+    }
+
+    return 0;
+}
+
+/**
+**     Plan an attack with a force.
+**     We know, that we must use a transporter.
+**
+**     @param force    Pointer on the force.
+**
+**     @return         True if target found, false otherwise.
+**
+**     @todo   Perfect planning.
+**             Only works for water transporter!
+*/
+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;
+       }
+       aiunit = aiunit->Next;
+    }
+
+    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
Index: stratagus/src/ai/ai_resource.c
diff -u stratagus/src/ai/ai_resource.c:1.80 stratagus/src/ai/ai_resource.c:1.81
--- stratagus/src/ai/ai_resource.c:1.80 Sun Nov 16 01:49:25 2003
+++ stratagus/src/ai/ai_resource.c      Thu Nov 20 15:35:42 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_resource.c,v 1.80 2003/11/16 06:49:25 mr-russ Exp $
+//      $Id: ai_resource.c,v 1.81 2003/11/20 20:35:42 n0body Exp $
 
 //@{
 
@@ -221,7 +221,7 @@
        //
        // FIXME: did SelectUnits already filter this.
        if (dest->Removed || dest->Invisible || !unit->HP
-           || !(dest->Visible & (1 << player->Player))
+           || (!dest->VisCount[1 << player->Player])
            || dest->Orders[0].Action == UnitActionDie) {
            DebugLevel0Fn("NO\n");
            continue;
@@ -764,7 +764,7 @@
            //  Check limits, AI should be broken if reached.
            //
            if (PlayerCheckLimits(AiPlayer->Player, type) < 0) {
-               DebugLevel2Fn("Unit limits reached, or Need Supply\n");
+               DebugLevel3Fn("Unit limits reached, or Need Supply\n");
                continue;
            }
            //
Index: stratagus/src/ai/new_ai.c
diff -u stratagus/src/ai/new_ai.c:1.94 stratagus/src/ai/new_ai.c:1.95
--- stratagus/src/ai/new_ai.c:1.94      Thu Nov 20 06:31:01 2003
+++ stratagus/src/ai/new_ai.c   Thu Nov 20 15:35:43 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: new_ai.c,v 1.94 2003/11/20 11:31:01 pludov Exp $
+//      $Id: new_ai.c,v 1.95 2003/11/20 20:35:43 n0body Exp $
 
 
 //@{
@@ -784,7 +784,7 @@
 {
     CLprintf(file, "\n;;; -----------------------------------------\n");
     CLprintf(file,
-       ";;; MODULE: AI $Id: new_ai.c,v 1.94 2003/11/20 11:31:01 pludov Exp 
$\n\n");
+       ";;; MODULE: AI $Id: new_ai.c,v 1.95 2003/11/20 20:35:43 n0body Exp 
$\n\n");
 
     SaveAiTypesWcName(file);
     SaveAiHelper(file);
@@ -1371,7 +1371,8 @@
 
     movablenb = 0;
 
-    
+    DebugLevel3Fn("AiCanNotMove : %s at %d %d\n" _C_ unittype->Ident _C_ ux0 
_C_ uy0);
+
     // Try to make some unit moves around it
     for (i = 0; i < NumUnits; ++i) {
        blocker = Units[i];
Index: stratagus/src/clone/mainloop.c
diff -u stratagus/src/clone/mainloop.c:1.163 
stratagus/src/clone/mainloop.c:1.164
--- stratagus/src/clone/mainloop.c:1.163        Thu Nov 20 12:56:36 2003
+++ stratagus/src/clone/mainloop.c      Thu Nov 20 15:35:44 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: mainloop.c,v 1.163 2003/11/20 17:56:36 jsalmon3 Exp $
+//     $Id: mainloop.c,v 1.164 2003/11/20 20:35:44 n0body Exp $
 
 //@{
 
@@ -417,6 +417,9 @@
        //
        nunits = FindAndSortUnits(vp, table);
        nmissiles = FindAndSortMissiles(vp, missiletable);
+/*     if (Units[170]) {
+           DebugLevel0Fn("Unit 170: %s ref %d\n" _C_ Units[170]->Type->Name 
_C_ Units[170]->Refs);
+       }*/
 
        i = 0;
        j = 0;
@@ -830,10 +833,7 @@
                    // Clear scheme heap each second
                    // FIXME: this is too slow to call during the game
                    CclGarbageCollect(1);
-                   break;
-               case 1:
-                   HandleCloak();
-                   break;
+                   break;                  
                case 2:
                    break;
                case 3:                         // minimap update
Index: stratagus/src/clone/unit.c
diff -u stratagus/src/clone/unit.c:1.341 stratagus/src/clone/unit.c:1.342
--- stratagus/src/clone/unit.c:1.341    Thu Nov 20 07:52:06 2003
+++ stratagus/src/clone/unit.c  Thu Nov 20 15:35:44 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit.c,v 1.341 2003/11/20 12:52:06 pludov Exp $
+//     $Id: unit.c,v 1.342 2003/11/20 20:35:44 n0body Exp $
 
 //@{
 
@@ -76,7 +76,6 @@
 
 global Unit* Units[MAX_UNIT_SLOTS];    /// Array of used slots
 global int NumUnits;                   /// Number of slots used
-global Unit* DestroyedBuildings;       /// List of DestroyedBuildings
 global Unit* CorpseList;               /// List of Corpses On Map
 
 global int XpDamage;                   /// Hit point regeneration for all units
@@ -111,7 +110,6 @@
 
     ReleasedTail = &ReleasedHead;              // list of unfreed units.
     NumUnits = 0;
-    DestroyedBuildings = NULL;
     CorpseList = NULL;
 }
 
@@ -201,37 +199,6 @@
        //
        unit->Destroyed = 1;            // mark as destroyed
 
-       // Mark building as can't be destroyed, since it's still seen
-       if (unit->Type->Building) {
-           int i;
-           int x;
-           int y;
-           int w;
-           int w0;
-           int h;
-
-           // Mark the Destroyed building, with who has seen it destroyed.
-           x = unit->X;
-           y = unit->Y;
-           unit->Visible = 0x0000;
-           for (i = 0; i < PlayerMax; ++i) {
-               w = w0 = unit->Type->TileWidth;
-               h = unit->Type->TileHeight;
-               for (; h-- > 0;) {
-                   for (w = w0; w-- > 0;) {
-                       if (!IsMapFieldVisible(&Players[i], x + w, y + h) &&
-                               IsMapFieldExplored(&Players[i], x + w, y + h) &&
-                               Players[i].Type == PlayerPerson) {
-                           unit->Visible |= (1 << i);
-                       }
-                   }
-               }
-           }
-       }
-
-       if (unit->Type->Building && unit->Visible != 0x0000) {
-           return;
-       }
        RefsDebugCheck(!unit->Refs);
        if (--unit->Refs > 0) {
            DebugLevel2Fn("%lu:More references of %d #%d\n" _C_ GameCycle _C_
@@ -245,11 +212,7 @@
 
     // Update Corpse Cache
     if (unit->Orders[0].Action == UnitActionDie) {
-       if (unit->Type->Building) {
-           DeadBuildingCacheRemove(unit);
-       } else {
-           CorpseCacheRemove(unit);
-       }
+       CorpseCacheRemove(unit);
     }
 
     RefsDebugCheck(unit->Refs);
@@ -388,11 +351,6 @@
     unit->Reset = 1;
     unit->Removed = 1;
 
-    // Invisible as default for submarines
-    if (!type->PermanentCloak) {
-       unit->Visible = -1;             // Visible as default
-    }
-
     unit->Rs = MyRand() % 100;         // used for fancy buildings and others
 
     unit->OrderCount = 1;              // No orders
@@ -547,10 +505,6 @@
        }
        unit->CurrentSightRange = unit->Stats->SightRange;
        MapMarkUnitSight(unit);
-
-       if (type->DetectCloak) {
-           MapDetectCloakedUnits(unit);
-       }
     }
 
     unit->Removed = 0;
@@ -978,79 +932,54 @@
 */
 global int UnitVisibleOnMap(const Unit* unit)
 {
-    int x;
-    int y;
-    int w;
-    int w0;
-    int h;
-
     DebugCheck(!unit->Type);   // FIXME: Can this happen, if yes it is a bug
 
-    //
-    // Unit invisible (by spell), removed or submarine.
-    //
-    if (unit->Invisible || unit->Removed ||
-           !(unit->Visible & (1 << ThisPlayer->Player))) {
+    // Removed unit
+    if (unit->Removed) {
        return 0;
     }
-
-    x = unit->X;
-    y = unit->Y;
-    w = w0 = unit->Type->TileWidth;
-    h = unit->Type->TileHeight;
-
-    //
-    // Check if visible, not under fog of war.
-    //         FIXME: need only check the boundary, not the complete rectangle.
-    //
-    for (; h-- > 0;) {
-       for (w = w0; w-- > 0;) {
-           if (IsMapFieldVisible(ThisPlayer, x + w, y + h)) {
-               return 1;
-           }
-       }
+    //  If it's your own unit, of course you can see it, right?
+    //  WRONG, it can have a vision range of 0.
+    // Invisible by spell
+    if (unit->Invisible) {
+       return 0;
     }
-
-    return 0;
+    // If units are watching it... what do you think?
+    return (unit->VisCount[ThisPlayer->Player] != 0);
 }
 
 /**
-**     Returns true, if unit is visible for this player on the map.
-**     An unit is visible, if any field could be seen.
+**     Returns true if the unit should be drawn on map.
+**     Unlike UnitVisibleOnMap this will return true for corpses and
+**     buildings under fog of war. Only for ThisPlayer
 **
-**     @warning        This is only true for ::ThisPlayer.
-**
-**     @param unit     Unit to be checked.
-**     @return         True if visible, false otherwise.
+**     @param unit     The unit to check.
 */
-global int BuildingVisibleOnMap(const Unit* unit)
+global int UnitDrawableOnMap(const Unit* unit)
 {
-    int x;
-    int y;
-    int w;
-    int w0;
-    int h;
-
     DebugCheck(!unit->Type);   // FIXME: Can this happen, if yes it is a bug
-    
-    x = unit->X;
-    y = unit->Y;
-    w = w0 = unit->Type->TileWidth;
-    h = unit->Type->TileHeight;
 
-    //
-    // Check if visible, not under fog of war.
-    //         FIXME: need only check the boundary, not the complete rectangle.
-    //
-    for (; h-- > 0;) {
-       for (w = w0; w-- > 0;) {
-           if (IsMapFieldVisible(ThisPlayer, x + w, y + h)) {
-               return 1;
-           }
+    //  If it's your own unit, of course you can see it, right?
+    //  WRONG, it can have a vision range of 0.
+    // Invisible by spell
+    if (unit->Invisible) {
+       return 0;
+    }
+    // If units are watching it... what do you think?
+    if (unit->VisCount[ThisPlayer->Player]) {
+       return 1;
+    } else { // Not watched by any units.
+       // Cloaked, sorry, not known
+       if (unit->Type->PermanentCloak) {
+           return 0;
        }
+       
+       // Unit is visible under fog and was already discovered once.
+       if (unit->Type->VisibleUnderFog && unit->SeenFrame!=UnitNotSeen) {
+           return 1;
+       }
+       return 0;
     }
-
-    return 0;
 }
 
 /**
@@ -1059,7 +988,7 @@
 ** 
 **     @param unit     The unit to work on
 */
-global void UnitFillSeenValues(Unit* unit)
+local void UnitFillSeenValues(Unit* unit)
 {
     // Seen values are undefined for visible units.
     unit->SeenIY = unit->IY;
@@ -1077,13 +1006,64 @@
 }
 
 /**
+**     This function should get called when an unit goes out of fog of war.
+**
+**     @param unit     The unit that goes out of fog.
+**     @param p        The player the unit goes out of fog for.
+**
+**     @note For units that are visible under fog (mostly buildings)
+**     we use reference counts, from the players that know about
+**     the building. When an building goes under fog it gets a refs
+**     increase, and when it shows up it gets a decrease. It must
+**     not get an decrease the first time it's seen, so we have to
+**     keep track of what player saw what units, with SeenByPlayer.
+*/
+local void UnitGoesOutOfFog(Unit* unit, int p)
+{
+    if (unit->Type->VisibleUnderFog) {
+       if (unit->SeenByPlayer & (1<<p)) {
+           DebugLevel3Fn("unit %d(%s): cleaned a ref from player %d\n" _C_
+                   unit->Slot _C_ unit->Type->Name _C_ p);
+           if (Players[p].Type == PlayerPerson) {
+               RefsDecrease(unit);
+           }
+       } else {
+           unit->SeenByPlayer |= (1<<p);
+       }
+    }
+}
+
+/**
+**     This function should get called when an unit goes under fog of war.
+**
+**     @param unit     The unit that goes under fog.
+**     @param p        The player the unit goes out of fog for.
+*/
+global void UnitGoesUnderFog(Unit* unit, int p)
+{
+    if (unit->Type->VisibleUnderFog) {
+       DebugLevel3Fn("unit %d(%s): got a ref from player %d\n" _C_
+               unit->Slot _C_ unit->Type->Name _C_ p);
+       if (Players[p].Type == PlayerPerson) {
+           RefsIncrease(unit);
+       }
+       if (p == ThisPlayer->Player) {
+           UnitFillSeenValues(unit);
+       }
+    }
+}
+
+/**
 **     This function marks units on x, y as seen. It uses a reference count.
 **
+**     @param player   The player to mark for.
 **     @param x        x location to check if building is on, and mark as seen
 **     @param y        y location to check if building is on, and mark as seen
+**     @param cloak    If this is for cloaked units. 
 */
-global void UnitsMarkSeen(const Player* player, int x, int y)
+global void UnitsMarkSeen(const Player* player, int x, int y, int cloak)
 {
+    int p;
     int n;
     Unit* units[UnitMax];
     Unit* unit;
@@ -1091,24 +1071,32 @@
     n = SelectUnitsOnTile(x, y,units);
     DebugLevel3Fn("I can see %d units from here.\n" _C_ n);
     while (n) {
-       unit = units[n - 1];
-       if (unit->SeenFrame == UnitNotSeen) {
-           DebugLevel3Fn("unit %d at %d,%d first seen at %lu.\n" _C_
-               unit->Slot _C_ unit->X _C_ unit->Y _C_ GameCycle);
+       unit = units[--n];
+       if (cloak != unit->Type->PermanentCloak) {
+           continue;
+       }
+       for (p = 0; p < PlayerMax ; ++p) {
+           if ((player->SharedVision & (1 << p)) || (p == player->Player)) {
+               if (!unit->VisCount[p]) {
+                   UnitGoesOutOfFog(unit,p);
+               }
+               unit->VisCount[p]++;
+           }
        }
-       unit->VisCount[player->Player]++;
-       --n;
     }
 }
 
 /**
 **     This function unmarks units on x, y as seen. It uses a reference count.
 **
+**     @param player   The player to mark for.
 **     @param x        x location to check if building is on, and mark as seen
 **     @param y        y location to check if building is on, and mark as seen
+**     @param cloak    If this is for cloaked units.
 */
-global void UnitsUnmarkSeen(const Player* player, int x, int y)
+global void UnitsUnmarkSeen(const Player* player, int x, int y, int cloak)
 {
+    int p;
     int n;
     Unit* units[UnitMax];
     Unit* unit;
@@ -1116,20 +1104,19 @@
     n = SelectUnitsOnTile(x, y,units);
     DebugLevel3Fn("I can see %d units from here.\n" _C_ n);
     while (n) {
-       unit = units[n - 1];
-       DebugCheck(!unit->VisCount[player->Player]);
-       unit->VisCount[player->Player]--;
-       //
-       //      Check if building goes under FOW.
-       //
-       if (!unit->VisCount[player->Player]) {
-           DebugLevel3Fn("unit %d at %d,%d is now under fog time %lu.\n" _C_
-               unit->Slot _C_ unit->X _C_ unit->Y _C_ GameCycle);
-           if (player == ThisPlayer) {
-               UnitFillSeenValues(unit);
+       unit = units[--n];
+       if (cloak != unit->Type->PermanentCloak) {
+           continue;
+       }
+       for (p = 0; p < PlayerMax ; ++p) {
+           if (player->SharedVision & (1 << p) || (p == player->Player)) {
+               DebugCheck(!unit->VisCount[p]);
+               unit->VisCount[p]--;
+               if (!unit->VisCount[p]) {
+                   UnitGoesUnderFog(unit,p);
+               }
            }
        }
-       --n;
     }
 }
 
@@ -1152,6 +1139,9 @@
     // FIXME: optimize, only work on certain players?
     // This is for instance good for updating shared vision...
     for (p = 0; p < PlayerMax; ++p) {
+       if (Players[p].Type == PlayerNobody) {
+           continue;
+       }
        //
        //      First calculate the new visibility count.
        //
@@ -1159,26 +1149,22 @@
        newv = 0;
        for (x = 0; x < unit->Type->TileWidth; ++x) {
            for (y = 0; y < unit->Type->TileHeight; ++y) {
-               if (IsMapFieldVisible(&Players[p], unit->X + x, unit->Y + y)) {
-                   newv++;
+               if (unit->Type->PermanentCloak) {
+                   if (TileDetectCloak(&Players[p], unit->X + x, unit->Y + y)) 
{
+                       newv++;
+                   }
+               } else {
+                   if (IsMapFieldVisible(&Players[p], unit->X + x, unit->Y + 
y)) {
+                       newv++;
+                   }
                }
            }
        }
-#ifdef DEBUG
        if ((oldv == 0) && (newv)) {
-           DebugLevel3Fn("unit %d(%s) at %d,%d popped into player %d's sight 
at cycle %lu.\n" _C_
-                   unit->Slot _C_ unit->Type->Name _C_ unit->X _C_ unit->Y _C_ 
p _C_ GameCycle);
+           UnitGoesOutOfFog(unit,p);
        }
-#endif
-       //
-       //      If the unit goes out of sight we have to fill in seen data.
-       //
        if ((oldv) && (newv == 0)) {
-           DebugLevel3Fn("unit %d(%s) at %d,%d got out of player %d's sight at 
cycle %lu.\n" _C_
-                   unit->Slot _C_ unit->Type->Name _C_ unit->X _C_ unit->Y _C_ 
p _C_ GameCycle);
-           if (p == ThisPlayer->Player) {
-               UnitFillSeenValues(unit);
-           }
+           UnitGoesUnderFog(unit,p);
        }
        //  Now set the new visibility count
        unit->VisCount[p] = newv;
@@ -1186,61 +1172,6 @@
 }
 
 /**
-**     Returns true, if unit is known on the map. Special case for buildings.
-**
-**     @param unit     Unit to be checked.
-**     @return         True if known, false otherwise.
-*/
-global int UnitKnownOnMap(const Unit* unit)
-{
-    int x;
-    int y;
-    int w;
-    int w0;
-    int h;
-
-    DebugCheck(!unit->Type);   // FIXME: Can this happen, if yes it is a bug
-
-    if (unit->Player != ThisPlayer) {
-       //FIXME: vladi: should handle teams and shared vision
-       // Invisible by spell
-       if (unit->Invisible) {
-           return 0;
-       }
-       // Visible submarine
-       if (!(unit->Visible & (1 << ThisPlayer->Player))) {
-           return 0;
-       }
-    }
-
-    //
-    // Check if visible on screen.
-    //         FIXME: This could be better checked, tells to much!
-    //         FIXME: This is needed to show moving units.
-    //         FIXME: flyers disappears to fast.
-    //
-    x = unit->X;
-    y = unit->Y;
-    w = w0 = unit->Type->TileWidth;
-    h = unit->Type->TileHeight;
-    //
-    // Check explored or if visible (building) under fog of war.
-    //         FIXME: need only check the boundary, not the complete rectangle.
-    //
-    for (; h-- > 0;) {
-       for (w = w0; w-- > 0;) {
-           if (IsMapFieldVisible(ThisPlayer, x + w, y + h) ||
-                   (unit->Type->Building && unit->SeenFrame != UnitNotSeen
-                       && IsMapFieldExplored(ThisPlayer, x + w, y + h))) {
-               return 1;
-           }
-       }
-    }
-
-    return 0;
-}
-
-/**
 **     Returns true, if unit is visible in viewport.
 **
 **     @param vp       Viewport number.
@@ -1252,63 +1183,21 @@
     int x;
     int y;
     int w;
-    int w0;
     int h;
 
-    DebugCheck(!unit->Type);   // FIXME: Can this happen, if yes it is a bug
-
-    if (!ThisPlayer) {
-       //FIXME: ARI: Added here for early game setup state by
-       //      MakeAndPlaceUnit() from LoadMap(). ThisPlayer not yet set,
-       //      so don't show anything until first real map-draw.
-       return 0;
-    }
-
-    // FIXME: Need to be able to see enemy submarines seen by my shared vision
-    //         partners
-    if (ThisPlayer != unit->Player &&
-           !(unit->Player->SharedVision & (1 << ThisPlayer->Player) &&
-               ThisPlayer->SharedVision & (1 << unit->Player->Player))) {
-       // Invisible by spell
-       if (unit->Invisible) {
-           return 0;
-       }
-       // Visible submarine
-       if (!(unit->Visible & (1 << ThisPlayer->Player)) && 
!unit->Type->Building) {
-           return 0;
-       }
-    }
-
     //
     // Check if visible on screen.
-    //         FIXME: This could be better checked, tells to much!
-    //         FIXME: This is needed to show moving units.
-    //         FIXME: flyers disappears to fast.
     //
     x = unit->X;
     y = unit->Y;
-    w = w0 = unit->Type->TileWidth;
+    w = unit->Type->TileWidth;
     h = unit->Type->TileHeight;
     if ((x + w) < vp->MapX || x > (vp->MapX + vp->MapWidth) ||
            (y + h) < vp->MapY || y > (vp->MapY + vp->MapHeight)) {
        return 0;
     }
 
-    //
-    // Check explored or if visible (building) under fog of war.
-    //         FIXME: need only check the boundary, not the complete rectangle.
-    //
-    for (; h-- > 0;) {
-       for (w = w0; w-- > 0;) {
-           if (IsMapFieldVisible(ThisPlayer, x + w, y + h) || ReplayRevealMap 
||
-                   (unit->Type->VisibleUnderFog && unit->SeenFrame != 
UnitNotSeen &&
-                       IsMapFieldExplored(ThisPlayer, x + w, y + h))) {
-               return 1;
-           }
-       }
-    }
-
-    return 0;
+    return UnitDrawableOnMap(unit);
 }
 
 /**
@@ -1368,23 +1257,6 @@
 }
 
 /**
-**     Decoration redraw function that will redraw a building for
-**     set clip rectangle by decoration mechanism.
-**
-**     @param data     Unit pointer to be drawn
-*/
-local void DecoBuildingDraw(void* data)
-{
-    Unit *unit;
-
-    unit = (Unit*)data;
-    DebugCheck(unit->Removed);
-    //DebugCheck(!UnitVisibleOnScreen(unit));
-
-    DrawBuilding(unit);
-}
-
-/**
 **     Create decoration for any unit-type
 **
 **     @param u        an unit which is visible on screen
@@ -1395,21 +1267,7 @@
 */
 local void AddUnitDeco(Unit* u, int x, int y, int w, int h)
 {
-#if 0//SEVERE_BRAINDAMAGE
-    if (u->Type->Building) {
-       u->deco = DecorationAdd(u, DecoBuildingDraw, LevBuilding, x, y, w, h);
-    } else if (u->Type->UnitType == UnitTypeFly) {
-       u->deco = DecorationAdd(u, DecoUnitDraw, LevSkylow, x, y, w, h);
-    } else {
-       u->deco = DecorationAdd(u, DecoUnitDraw, LevCarLow, x, y, w, h);
-    }
-#else
-    if (u->Type->Building) {
-       u->Decoration = DecorationAdd(u, DecoBuildingDraw, 1, x, y, w, h);
-    } else {
-       u->Decoration = DecorationAdd(u, DecoUnitDraw, 2, x, y, w, h);
-    }
-#endif
+    u->Decoration = DecorationAdd(u, DecoUnitDraw, 1, x, y, w, h);
 }
 #endif
 
@@ -2942,8 +2800,7 @@
                !unit->Type->Animations->Die);
            UnitShowAnimation(unit, unit->Type->Animations->Die);
            DebugLevel0Fn("Frame %d\n" _C_ unit->Frame);
-           unit->Visible = 0xffff;
-           DeadBuildingCacheInsert(unit);      //Insert into corpse list
+           CorpseCacheInsert(unit);    //Insert into corpse list
            // FIXME: (mr-russ) Hack to make sure we see our own building 
destroyed
            MapMarkUnitSight(unit);
            UnitCountSeen(unit);
@@ -3132,7 +2989,7 @@
        CommandStopUnit(attacker);      // Attacker shouldn't continue attack!
     }
 
-    if ((UnitVisibleOnMap(target) || ReplayRevealMap) && DamageMissile) {
+    if (UnitVisibleOnMap(target) && DamageMissile) {
        MakeLocalMissile(MissileTypeByIdent(DamageMissile),
                target->X * TileSizeX + target->Type->TileWidth * TileSizeX / 2,
                target->Y * TileSizeY + target->Type->TileHeight * TileSizeY / 
2,
@@ -3663,11 +3520,6 @@
            unit->Container->Type->TileWidth,
            unit->Container->Type->TileHeight);
     }
-    CLprintf(file, " 'visible \"");
-    for (i = 0; i < PlayerMax; ++i) {
-       CLprintf(file, "%c", (unit->Visible & (1 << i)) ? 'X' : '_');
-    }
-    CLprintf(file, "\"\n ");
     if (unit->Constructed) {
        CLprintf(file, " 'constructed");
     }
@@ -3873,7 +3725,7 @@
     int RunStart;
 
     CLprintf(file, "\n;;; -----------------------------------------\n");
-    CLprintf(file, ";;; MODULE: units $Id: unit.c,v 1.341 2003/11/20 12:52:06 
pludov Exp $\n\n");
+    CLprintf(file, ";;; MODULE: units $Id: unit.c,v 1.342 2003/11/20 20:35:44 
n0body Exp $\n\n");
 
     //
     // Local variables
Index: stratagus/src/clone/unit_draw.c
diff -u stratagus/src/clone/unit_draw.c:1.187 
stratagus/src/clone/unit_draw.c:1.188
--- stratagus/src/clone/unit_draw.c:1.187       Thu Nov 20 15:00:28 2003
+++ stratagus/src/clone/unit_draw.c     Thu Nov 20 15:35:45 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit_draw.c,v 1.187 2003/11/20 20:00:28 jsalmon3 Exp $
+//     $Id: unit_draw.c,v 1.188 2003/11/20 20:35:45 n0body Exp $
 
 //@{
 
@@ -943,7 +943,7 @@
 global void SaveDecorations(CLFile* file)
 {
     CLprintf(file, "\n;;; -----------------------------------------\n");
-    CLprintf(file, ";;; MODULE: decorations $Id: unit_draw.c,v 1.187 
2003/11/20 20:00:28 jsalmon3 Exp $\n\n");
+    CLprintf(file, ";;; MODULE: decorations $Id: unit_draw.c,v 1.188 
2003/11/20 20:35:45 n0body Exp $\n\n");
 
     CLprintf(file, "(mana-sprite \"%s\"  %d %d  %d %d)\n",
        ManaSprite.File, ManaSprite.HotX, ManaSprite.HotY,
@@ -1921,9 +1921,9 @@
     const UnitStats* stats;
     int r;
 
-#if 0 // This is for showing vis counts.
+#if 0 // This is for showing vis counts and refs.
     char buf[10];
-    sprintf(buf, "%d", unit->VisCount[ThisPlayer->Player]);
+    sprintf(buf, "%d/%d", unit->VisCount[ThisPlayer->Player], unit->Refs);
     VideoDrawTextClip(x + 10, y + 10, 1, buf);
 #endif
 
@@ -2172,14 +2172,14 @@
     //
     // This should be obviousely false.
     //
-/*    DebugCheck(unit->VisCount[ThisPlayer->Player] >
+    DebugCheck(unit->VisCount[ThisPlayer->Player] >
            unit->Type->TileWidth * unit->Type->TileHeight);
-*/
 
     //
     // If we are in replay reveal map or the unit is visible(not under fog).
     //
     if (ReplayRevealMap || TheMap.NoFogOfWar ||
+//         !unit->SeenType || // UGLY STUPID HACK
            unit->VisCount[ThisPlayer->Player]) {
        type = unit->Type;
        frame = unit->Frame;
@@ -2341,22 +2341,11 @@
     while (*corpses) {
        if (UnitVisibleInViewport(vp,*corpses) && !(*corpses)->Destroyed) {
            table[n++] = *corpses;
+           DebugLevel3Fn("Yay we have a corpse\n");
        }
        corpses = &(*corpses)->Next;
     }
 
-    //
-    //  Add Destroyed Buildings
-    //
-    corpses = &DestroyedBuildings;
-    while (*corpses) {
-       if (UnitVisibleInViewport(vp, *corpses) && !(*corpses)->SeenDestroyed &&
-               (((*corpses)->Visible & 1 << ThisPlayer->Player) ||
-                   !(*corpses)->Destroyed)) {
-           table[n++] = *corpses;
-       }
-       corpses = &(*corpses)->Next;
-    }
     // Only draw if there are units to draw :)
     if (n) {
        qsort((void *)table, n, sizeof(Unit*), DrawLevelCompare);
Index: stratagus/src/clone/unit_find.c
diff -u stratagus/src/clone/unit_find.c:1.63 
stratagus/src/clone/unit_find.c:1.64
--- stratagus/src/clone/unit_find.c:1.63        Thu Oct 23 14:38:35 2003
+++ stratagus/src/clone/unit_find.c     Thu Nov 20 15:35:45 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit_find.c,v 1.63 2003/10/23 18:38:35 n0body Exp $
+//     $Id: unit_find.c,v 1.64 2003/11/20 20:35:45 n0body Exp $
 
 //@{
 
@@ -242,7 +242,7 @@
        // FIXME: did SelectUnitsOnTile already filter this?
        // Invisible and not Visible
        if (unit->Removed || unit->Invisible || !unit->HP ||
-               !(unit->Visible & (1 << source->Player->Player)) ||
+               !(unit->VisCount[source->Player->Player]) ||
                unit->Orders[0].Action == UnitActionDie) {
            continue;
        }
@@ -295,7 +295,7 @@
        // FIXME: did SelectUnitsOnTile already filter this?
        // Invisible and not Visible
        if (unit->Removed || unit->Invisible || !unit->HP ||
-               !(unit->Visible & (1 << source->Player->Player)) ||
+               !(unit->VisCount[source->Player->Player]) ||
                unit->Orders[0].Action == UnitActionDie) {
            continue;
        }
@@ -542,7 +542,7 @@
        //
        // FIXME: did SelectUnits already filter this.
        if (dest->Removed || dest->Invisible || !u->HP ||
-               !(dest->Visible & (1 << player->Player)) ||
+               !(dest->VisCount[player->Player]) ||
                dest->Orders[0].Action == UnitActionDie) {
            table[i] = 0;
            continue;
@@ -789,7 +789,7 @@
        //
        // FIXME: did SelectUnits already filter this.
        if (dest->Removed || dest->Invisible || !unit->HP ||
-               !(dest->Visible & (1 << player->Player)) ||
+               !(dest->VisCount[player->Player]) ||
                dest->Orders[0].Action == UnitActionDie) {
            continue;
        }
Index: stratagus/src/include/map.h
diff -u stratagus/src/include/map.h:1.102 stratagus/src/include/map.h:1.103
--- stratagus/src/include/map.h:1.102   Mon Nov 17 14:14:32 2003
+++ stratagus/src/include/map.h Thu Nov 20 15:35:46 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: map.h,v 1.102 2003/11/17 19:14:32 nehalmistry Exp $
+//     $Id: map.h,v 1.103 2003/11/20 20:35:46 n0body Exp $
 
 #ifndef __MAP_H__
 #define __MAP_H__
@@ -197,8 +197,8 @@
 //     1024x1024:        8 MB  12 MB
 //     2048*2048:       32 MB  48 MB
 //     4096*4096:      128 MB 192 MB
-#define MaxMapWidth    1024            /// maximal map width supported
-#define MaxMapHeight   1024            /// maximal map height supported
+#define MaxMapWidth    256             ///  maximal map width supported
+#define MaxMapHeight   256             /// maximal map height supported
 
 /*----------------------------------------------------------------------------
 --     Map - field
@@ -227,6 +227,7 @@
     //       different.
     unsigned char      Value;          /// HP for walls/ Wood Regeneration
     unsigned char Visible[PlayerMax];  /// Seen counter 0 unexplored
+    unsigned char VisCloak[PlayerMax]; /// Seen counter 0 unexplored
 #ifdef UNIT_ON_MAP
     union {
        Unit*           Units;          /// An unit on the map field
@@ -420,12 +421,18 @@
 extern void MapMarkTileSight(const Player* player,int x,int y);
     /// Unmark a tile for normal sight
 extern void MapUnmarkTileSight(const Player* player,int x,int y);
+    /// Mark a tile for cloak detection
+extern void MapMarkTileDetectCloak(const Player* player,int x,int y);
+    /// Unmark a tile for cloak detection
+extern void MapUnmarkTileDetectCloak(const Player* player,int x,int y);
     /// Mark Cloaked units on a tile as detected.
 extern void MapDetectUnitsOnTile(const Player* player,int x,int y);
     /// Mark sight changes
 extern void MapSight(const Player* player, int x, int y, int w, int h, int 
range, void (*marker)(const Player*,int,int));
     /// Find if a tile is visible (With shared vision)
 extern int IsTileVisible(const Player* player, int x, int y);
+    /// Find if cloak detection is available on a tile.
+extern int TileDetectCloak(const Player* player, int x, int y);
     /// Mark tiles with fog of war to be redrawn
 extern void MapUpdateFogOfWar(int x,int y);
     ///        Update fog of war
@@ -569,14 +576,29 @@
 #define CanMoveToMask(x,y,mask) \
        !(TheMap.Fields[(x)+(y)*TheMap.Width].Flags&(mask))
 
-#define MapDetectCloakedUnits(unit) 
MapSight((unit)->Player,(unit)->X,(unit)->Y, \
-       
(unit)->Type->TileWidth,(unit)->Type->TileHeight,(unit)->CurrentSightRange,MapDetectUnitsOnTile)
 #define MapMarkSight(player,x,y,w,h,range) 
MapSight((player),(x),(y),(w),(h),(range),MapMarkTileSight)
 #define MapUnmarkSight(player,x,y,w,h,range) 
MapSight((player),(x),(y),(w),(h),(range),MapUnmarkTileSight)
-#define MapMarkUnitSight(unit) MapSight((unit)->Player,(unit)->X,(unit)->Y, \
-       
(unit)->Type->TileWidth,(unit)->Type->TileHeight,(unit)->CurrentSightRange,MapMarkTileSight)
-#define MapUnmarkUnitSight(unit) MapSight((unit)->Player,(unit)->X,(unit)->Y, \
-       
(unit)->Type->TileWidth,(unit)->Type->TileHeight,(unit)->CurrentSightRange,MapUnmarkTileSight)
+
+#define MapMarkUnitSight(unit) \
+{ \
+    MapSight((unit)->Player, (unit)->X,(unit)->Y, (unit)->Type->TileWidth,\
+           (unit)->Type->TileHeight, (unit)->CurrentSightRange, 
MapMarkTileSight); \
+    if (unit->Type->DetectCloak) { \
+       MapSight((unit)->Player, (unit)->X,(unit)->Y, (unit)->Type->TileWidth,\
+               (unit)->Type->TileHeight, (unit)->CurrentSightRange, 
MapMarkTileDetectCloak); \
+    }\
+}
+
+#define MapUnmarkUnitSight(unit) \
+{ \
+    MapSight((unit)->Player,(unit)->X,(unit)->Y, (unit)->Type->TileWidth,\
+           
(unit)->Type->TileHeight,(unit)->CurrentSightRange,MapUnmarkTileSight); \
+    if (unit->Type->DetectCloak) { \
+       MapSight((unit)->Player, (unit)->X,(unit)->Y, (unit)->Type->TileWidth,\
+               (unit)->Type->TileHeight, (unit)->CurrentSightRange, 
MapUnmarkTileDetectCloak); \
+    }\
+}
+
 #define MapMarkUnitOnBoardSight(unit,host) 
MapSight((unit)->Player,(host)->X,(host)->Y, \
        
(host)->Type->TileWidth,(host)->Type->TileHeight,(unit)->CurrentSightRange,MapMarkTileSight)
 #define MapUnmarkUnitOnBoardSight(unit,host) 
MapSight((unit)->Player,(host)->X,(host)->Y, \
Index: stratagus/src/include/unit.h
diff -u stratagus/src/include/unit.h:1.236 stratagus/src/include/unit.h:1.237
--- stratagus/src/include/unit.h:1.236  Mon Nov 17 14:14:33 2003
+++ stratagus/src/include/unit.h        Thu Nov 20 15:35:46 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit.h,v 1.236 2003/11/17 19:14:33 nehalmistry Exp $
+//     $Id: unit.h,v 1.237 2003/11/20 20:35:46 n0body Exp $
 
 #ifndef __UNIT_H__
 #define __UNIT_H__
@@ -200,18 +200,18 @@
 **
 **             If Burning is non-zero, the unit is burning.
 **
-**     Unit::Visible
-**
-**             Used for submarines. It is a bit field for all players. If
-**             Unit::Visible&(1<<player-nr) is non-zero, the unit could be
-**             seen on the map.
-**
 **     Unit::VisCount[PlayerMax]
 **
 **             Used to keep track of visible units on the map, it counts the
 **             Number of seen tiles for each player. This is only modified
 **             in UnitsMarkSeen and UnitsUnmarkSeen, from fow.
 **
+**     Unit::SeenByPlayer
+**
+**             This is a bitmask of 1 and 0 values. SeenByPlayer & (1<<p) is 0
+**             If p never saw the unit and 1 if it did. This is important for
+**             keeping track of dead units under fog.
+**
 **     Unit::Destroyed
 **
 **     FIXME: @todo
@@ -545,7 +545,7 @@
     unsigned   Selected : 1;           /// unit is selected
 
     unsigned char VisCount[PlayerMax];  /// Unit visibility counts.
-    unsigned   Visible : 16;           /// Unit is visible (submarine)
+    unsigned   SeenByPlayer : 16;      /// Unit seen mask. (as in explored.)
     unsigned   Constructed : 1;        /// Unit is in construction
     unsigned   Active : 1;             /// Unit is active for AI
     Player*     RescuedFrom;            /// The original owner of a rescued 
unit.
@@ -705,7 +705,6 @@
 
 extern Unit* Units[MAX_UNIT_SLOTS];    /// Units used
 extern int NumUnits;                   /// Number of units used
-extern Unit* DestroyedBuildings;       /// List of DestroyedBuildings
 extern Unit* CorpseList;               /// List of Corpses On Map
 
 //     in unit_draw.c (FIXME: could be moved into the user interface?)
@@ -780,19 +779,17 @@
 extern void NearestOfUnit(const Unit* unit, int tx, int ty, int *dx, int *dy);
     /// Returns true, if unit is visible on the map
 extern int UnitVisibleOnMap(const Unit* unit);
-    /// Returns true, if building is known on the map
-extern int BuildingVisibleOnMap(const Unit* unit);
+    /// Returns true, if unit is visible for drawing on the map
+extern int UnitDrawableOnMap(const Unit* unit);
 
-    /// Fill in values, considering the unit was just recently seen.
-extern void UnitFillSeenValues(Unit* unit);
+    /// To be called when an unit goes under fog.
+extern void UnitGoesUnderFog(Unit* unit, int p);
     /// Marks unit seen. (increases visibility count)
-extern void UnitsMarkSeen(const Player* player, int x, int y);
+extern void UnitsMarkSeen(const Player* player, int x, int y, int cloak);
     /// Unmarks unit seen. (decreases visibility count)
-extern void UnitsUnmarkSeen(const Player* player, int x, int y);
+extern void UnitsUnmarkSeen(const Player* player, int x, int y, int cloak);
     /// Calculated an unit's seen information itself
 extern void UnitCountSeen(Unit* unit);
-    /// Returns true, if unit is known on the map
-extern int UnitKnownOnMap(const Unit* unit);
 
     /// To be called when the look of the unit changes.
 extern int CheckUnitToBeDrawn(Unit* unit);
@@ -912,14 +909,8 @@
 #define CorpseCacheInsert(unit) \
        (DeadCacheInsert((unit),&CorpseList))
 
-#define DeadBuildingCacheInsert(unit) \
-       (DeadCacheInsert((unit),&DestroyedBuildings))
-
 #define CorpseCacheRemove(unit) \
        (DeadCacheRemove((unit),&CorpseList))
-
-#define DeadBuildingCacheRemove(unit) \
-       (DeadCacheRemove((unit),&DestroyedBuildings))
 
 //     in unit_draw.c
 //--------------------
Index: stratagus/src/map/map.c
diff -u stratagus/src/map/map.c:1.65 stratagus/src/map/map.c:1.66
--- stratagus/src/map/map.c:1.65        Mon Nov 17 14:14:34 2003
+++ stratagus/src/map/map.c     Thu Nov 20 15:35:46 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: map.c,v 1.65 2003/11/17 19:14:34 nehalmistry Exp $
+//     $Id: map.c,v 1.66 2003/11/20 20:35:46 n0body Exp $
 
 //@{
 
@@ -134,6 +134,7 @@
 {
     int x;
     int y;
+    int p;
 
     DebugLevel1Fn("\n");
     for (x = 0; x < TheMap.Width; ++x) {
@@ -149,9 +150,18 @@
     }
     //
     // Start a global unit seen recount. It's the best way.
+    // We also have to copy seen values for every unit, and thus mark those 
units as
+    // dicovered.
     //
     for (x = 0; x < NumUnits; ++x) {
-       UnitFillSeenValues(Units[x]);
+       for (p = 0; p < PlayerMax; ++p) {
+           if (Players[p].Type == PlayerPerson && (!(Units[x]->SeenByPlayer & 
(1 << p))) &&
+                   Units[x]->Type->VisibleUnderFog && !Units[x]->VisCount[p]) {
+               DebugLevel0Fn("unit %d first seen by %d\n" _C_ Units[x]->Slot 
_C_ p);
+               UnitGoesUnderFog(Units[x], p);
+               Units[x]->SeenByPlayer |= (1 << p);
+           }
+       }
     }
 }
 
Index: stratagus/src/map/map_fog.c
diff -u stratagus/src/map/map_fog.c:1.116 stratagus/src/map/map_fog.c:1.117
--- stratagus/src/map/map_fog.c:1.116   Tue Nov 18 13:37:50 2003
+++ stratagus/src/map/map_fog.c Thu Nov 20 15:35:46 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: map_fog.c,v 1.116 2003/11/18 18:37:50 nehalmistry Exp $
+//     $Id: map_fog.c,v 1.117 2003/11/20 20:35:46 n0body Exp $
 
 //@{
 
@@ -234,6 +234,41 @@
 }
 
 /**
+**     Find out if units on a field are uncloaked (By player or shared vision.)
+**
+**     @param player   Player to check for.
+**     @param x        X tile to check.
+**     @param y        Y tile to check.
+**
+**     @return         0 not detect, 1 detect
+*/
+global int TileDetectCloak(const Player* player, int x, int y)
+{
+    int i;
+    unsigned char visiontype;
+    unsigned char* visible;
+
+    visible = TheMap.Fields[y * TheMap.Width + x].VisCloak;
+    visiontype = visible[player->Player];
+
+    if (visiontype > 0) {
+       return 1;
+    }
+    if (!player->SharedVision) {
+       return visiontype > 0;
+    }
+    for (i = 0; i < PlayerMax ; ++i) {
+       if (player->SharedVision & (1 << i) &&
+               (Players[i].SharedVision & (1 << player->Player))) {
+           if (visible[i]) {
+               return 1;
+           }
+       }
+    }
+    return 0;
+}
+
+/**
 **     Mark a tile's sight. (Explore and make visible.)
 **
 **     @param player   Player to mark sight.
@@ -243,51 +278,21 @@
 global void MapMarkTileSight(const Player* player, int x, int y)
 {
     unsigned char v;
-    Unit* unit;
-    Unit* remove;
-    Unit** corpses;
-    int w;
-    int h;
- 
     v = TheMap.Fields[x + y * TheMap.Width].Visible[player->Player];
-
     switch (v) {
        case 0:         // Unexplored
        case 1:         // Unseen
-       // FIXME: mark for screen update
-           v = 2;
-           UnitsMarkSeen(player, x, y);
-           if (player->Type == PlayerPerson) {
-               corpses = &DestroyedBuildings;
-               while (*corpses) {
-                   unit = *corpses;
-                   if ((unit->Visible & 1 << player->Player)) {
-                       w = unit->Type->TileWidth;
-                       h = unit->Type->TileHeight;
-                       if (x >= unit->X && y >= unit->Y &&
-                               x < unit->X+w && y < unit->Y+h) {
-                           unit->Visible &= ~(1 << player->Player);
-//                         UnitMarkSeen(unit);
-                       }
-                   }
-                   remove = unit;
-                   unit = unit->Next;
-                   corpses = &unit;
-                   if (remove->Visible == 0x0000 && !remove->Refs) {
-                       ReleaseUnit(remove);
-                   }
-               }
+           //  When there is NoFogOfWar only unexplored tiles are marked.
+           if ((!TheMap.NoFogOfWar) || (v == 0)) {
+               UnitsMarkSeen(player, x, y, 0);
            }
+           v = 2;
            TheMap.Fields[x + y * TheMap.Width].Visible[player->Player] = v;
-           if (IsTileVisible(ThisPlayer, x, y) > 1) {
-               MapMarkSeenTile(x, y);
-           }
-
+           MapMarkSeenTile(x, y);
            return;
        case 255:               // Overflow
            DebugLevel0Fn("Visible overflow (Player): %d\n" _C_ player->Player);
            break;
-
        default:                // seen -> seen
            ++v;
            break;
@@ -320,11 +325,13 @@
            DebugCheck(1);
            break;
        case 2:
-           UnitsUnmarkSeen(player, x, y);
+           //  When there is NoFogOfWar units never get unmarked.
+           if (!TheMap.NoFogOfWar) {
+               UnitsUnmarkSeen(player, x, y, 0);
+           }
            // Check visible Tile, then deduct...
            if (IsTileVisible(ThisPlayer, x, y) > 1) {
                MapMarkSeenTile(x, y);
-               //UnitsMarkSeen(x, y);
            }
        default:                // seen -> seen
            v--;
@@ -334,26 +341,44 @@
 }
 
 /**
-**     Mark cloacked units on a tile as detected.
+**     Mark a tile for cloak detection.
 **
 **     @param player   Player to mark sight.
 **     @param x        X tile to mark.
 **     @param y        Y tile to mark.
 */
-global void MapDetectUnitsOnTile(const Player* player, int x, int y)
+global void MapMarkTileDetectCloak(const Player* player, int x, int y)
 {
-    Unit* table[UnitMax];
-    int n;
-    int i;
-    int pm;
+    unsigned char v;
+    v = TheMap.Fields[x + y * TheMap.Width].VisCloak[player->Player];
+    if (v == 0) {
+       UnitsMarkSeen(player, x, y, 1);
+    }
+    DebugCheck(v == 255);
+    ++v;
+    TheMap.Fields[x + y * TheMap.Width].VisCloak[player->Player] = v;
+}
 
-    n = SelectUnitsOnTile(x, y, table);
-    pm = ((1 << player->Player) | player->SharedVision);
-    for (i = 0; i < n; ++i) {
-       table[i]->Visible |= pm;
+/**
+**     Unmark a tile for cloak detection.
+**
+**     @param player   Player to mark sight.
+**     @param x        X tile to mark.
+**     @param y        Y tile to mark.
+*/
+global void MapUnmarkTileDetectCloak(const Player* player, int x, int y)
+{
+    unsigned char v;
+    v = TheMap.Fields[x + y * TheMap.Width].VisCloak[player->Player];
+    DebugCheck(v == 0);
+    if (v == 1) {
+       UnitsUnmarkSeen(player, x, y, 1);
     }
+    --v;
+    TheMap.Fields[x + y * TheMap.Width].VisCloak[player->Player] = v;
 }
 
+
 /**
 **     Mark the sight of unit. (Explore and make visible.)
 **
@@ -467,6 +492,7 @@
     int y;
     int w;
 
+    DebugLevel1Fn("\n");
     //
     // Mark all explored fields as visible.
     //
Index: stratagus/src/map/minimap.c
diff -u stratagus/src/map/minimap.c:1.74 stratagus/src/map/minimap.c:1.75
--- stratagus/src/map/minimap.c:1.74    Mon Nov 17 14:14:36 2003
+++ stratagus/src/map/minimap.c Thu Nov 20 15:35:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: minimap.c,v 1.74 2003/11/17 19:14:36 nehalmistry Exp $
+//     $Id: minimap.c,v 1.75 2003/11/20 20:35:47 n0body Exp $
 
 //@{
 
@@ -383,17 +383,22 @@
     // FIXME: and other changes
     //
 
-    // Draw Destroyed Buildings On Map
-    table = &DestroyedBuildings;
+    table = &CorpseList;
 
 #ifdef USE_SDL_SURFACE
     // FIXME: todo
     (int)type = (int)unit = w = h = h0 = 0;
 #else
+
     while (*table) {
        VMemType color;
 
-       if (!BuildingVisibleOnMap(*table) && (*table)->SeenState != 3
+       // Only for buildings?
+       if (!(*table)->Type->Building) {
+           table = &(*table)->Next;
+           continue;
+       }
+       if (!UnitDrawableOnMap(*table) && (*table)->SeenState != 3
                && !(*table)->SeenDestroyed && (type = (*table)->SeenType) ) {
            if( (*table)->Player->Player == PlayerNumNeutral ) {
                color = 
VideoMapRGB((*table)->Type->NeutralMinimapColorRGB.D24.a,
@@ -428,21 +433,13 @@
 
        unit = *table;
 
-       if (unit->Removed) {            // Removed, inside another building
-           continue;
-       }
-       if (unit->Invisible) {          // Can't be seen
-           continue;
-       }
-       if (!(unit->Visible & (1 << ThisPlayer->Player))) {
-           continue;                   // Cloaked unit not visible
-       }
-
-       if (!UnitKnownOnMap(unit) && !ReplayRevealMap) {
+       //
+       //      If the unit is not known on map don't draw it.
+       //      This function should cover shared vision and stuff.
+       //
+       if (!UnitDrawableOnMap(unit) && !ReplayRevealMap) {
            continue;
        }
-
-       // FIXME: submarine not visible
 
        type = unit->Type;
        //
Index: stratagus/src/ui/mouse.c
diff -u stratagus/src/ui/mouse.c:1.163 stratagus/src/ui/mouse.c:1.164
--- stratagus/src/ui/mouse.c:1.163      Thu Nov 13 21:26:54 2003
+++ stratagus/src/ui/mouse.c    Thu Nov 20 15:35:47 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: mouse.c,v 1.163 2003/11/14 02:26:54 jsalmon3 Exp $
+//     $Id: mouse.c,v 1.164 2003/11/20 20:35:47 n0body Exp $
 
 //@{
 
@@ -753,7 +753,7 @@
     //NOTE: vladi: if unit is invisible, no cursor hint should be allowed
     // FIXME: johns: not corrrect? Should I get informations about
     // buildings under fog of war?
-    if (UnitUnderCursor && !UnitKnownOnMap(UnitUnderCursor) &&
+    if (UnitUnderCursor && !UnitVisibleOnMap(UnitUnderCursor) &&
            !ReplayRevealMap) {
        UnitUnderCursor = NULL;
     }
Index: stratagus/src/unit/ccl_unit.c
diff -u stratagus/src/unit/ccl_unit.c:1.79 stratagus/src/unit/ccl_unit.c:1.80
--- stratagus/src/unit/ccl_unit.c:1.79  Thu Nov 20 14:19:25 2003
+++ stratagus/src/unit/ccl_unit.c       Thu Nov 20 15:35:48 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_unit.c,v 1.79 2003/11/20 19:19:25 jsalmon3 Exp $
+//     $Id: ccl_unit.c,v 1.80 2003/11/20 20:35:48 n0body Exp $
 
 //@{
 
@@ -583,7 +583,6 @@
     int i;
     int insidecount;
     char* str;
-    char* s;
 
     insidecount = -1;
     slot = gh_scm2int(gh_car(list));
@@ -727,17 +726,6 @@
        } else if (gh_eq_p(value, gh_symbol2scm("rescued-from"))) {
            unit->RescuedFrom = &Players[gh_scm2int(gh_car(list))];
            list = gh_cdr(list);
-       } else if (gh_eq_p(value, gh_symbol2scm("visible"))) {
-           str=s = gh_scm2newstr(gh_car(list), NULL);
-           list = gh_cdr(list);
-           for (i = 0; i < PlayerMax && *s; ++i, ++s) {
-               if (*s == '-' || *s == '_' || *s == ' ') {
-                   unit->Visible &= ~(1 << i);
-               } else {
-                   unit->Visible |= (1 << i);
-               }
-           }
-           free(str);
        } else if (gh_eq_p(value, gh_symbol2scm("constructed"))) {
            unit->Constructed = 1;
        } else if (gh_eq_p(value, gh_symbol2scm("active"))) {
@@ -847,10 +835,7 @@
                unit->Player->UnitTypesCount[type->Type]--;
            }
            // FIXME: (mr-russ) Does not load CorpseList Properly
-           if (unit->Type->Building &&
-                   (unit->Orders[0].Action == UnitActionDie || 
unit->Destroyed)) {
-               DeadBuildingCacheInsert(unit);
-           } else if (unit->Orders[0].Action == UnitActionDie) {
+           if (unit->Orders[0].Action == UnitActionDie) {
                CorpseCacheInsert(unit);
            }
 #if 0




reply via email to

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