stratagus-cvs
[Top][All Lists]
Advanced

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

[Stratagus-CVS] stratagus data/ccl/stratagus.ccl data/ccl/units...


From: Russell Smith
Subject: [Stratagus-CVS] stratagus data/ccl/stratagus.ccl data/ccl/units...
Date: Mon, 25 Aug 2003 07:21:19 -0400

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Russell Smith <address@hidden>  03/08/25 07:21:18

Modified files:
        data/ccl       : stratagus.ccl units.ccl 
        data/ccl/human : units.ccl 
        data/ccl/orc   : units.ccl 
        src/action     : action_attack.c action_build.c action_die.c 
                         action_harvest.c action_move.c command.c 
        src/clone      : spells.c unit.c unit_draw.c unit_find.c 
                         unitcache.c 
        src/game       : game.c 
        src/include    : map.h pathfinder.h unit.h 
        src/map        : ccl_map.c map_fog.c 
        src/missile    : missile.c 
        src/pathfinder : astar.c pathfinder.c 
        src/unit       : ccl_unit.c upgrade.c 
        src/video      : video.c 

Log message:
        Rewrote Vision and Goals to be circular.
        They still require a circular generating function, but with one of 
those you can have circle or the current square
        vision.

Patches:
Index: stratagus/data/ccl/human/units.ccl
diff -u stratagus/data/ccl/human/units.ccl:1.26 
stratagus/data/ccl/human/units.ccl:1.27
--- stratagus/data/ccl/human/units.ccl:1.26     Thu Aug 21 17:55:44 2003
+++ stratagus/data/ccl/human/units.ccl  Mon Aug 25 07:21:14 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: units.ccl,v 1.26 2003/08/21 21:55:44 n0body Exp $
+;;     $Id: units.ccl,v 1.27 2003/08/25 11:21:14 mr-russ Exp $
 
 ;;=============================================================================
 ;;     Define unit-types.
@@ -896,7 +896,7 @@
   'hit-points 400
   'draw-level 20
   'tile-size '(2 2) 'box-size '(63 63)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 20 'annoy-computer-factor 45
   'points 100
@@ -924,7 +924,7 @@
   'hit-points 800
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 30 'annoy-computer-factor 35
   'points 160
@@ -951,7 +951,7 @@
   'hit-points 700
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 35
   'points 240
@@ -1007,7 +1007,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 15
   'points 210
@@ -1034,7 +1034,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 230
@@ -1061,7 +1061,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 280
@@ -1088,7 +1088,7 @@
   'hit-points 1100
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 30 'annoy-computer-factor 20
   'points 170
@@ -1118,7 +1118,7 @@
   'hit-points 600
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 25 'annoy-computer-factor 15
   'points 150
@@ -1146,7 +1146,7 @@
   'hit-points 750
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 200
@@ -1174,7 +1174,7 @@
   'hit-points 1200
   'draw-level 20
   'tile-size '(4 4) 'box-size '(126 126)
-  'sight-range 4
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 35 'annoy-computer-factor 45
   'points 200
@@ -1203,7 +1203,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 35 'annoy-computer-factor 20
   'points 240
@@ -1230,7 +1230,7 @@
   'hit-points 775
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 170
@@ -1257,7 +1257,7 @@
   'hit-points 600
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 25 'annoy-computer-factor 20
   'points 200
@@ -1287,7 +1287,7 @@
   'hit-points 650
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 20 'annoy-computer-factor 20
   'points 160
@@ -1316,7 +1316,7 @@
   'hit-points 1400
   'draw-level 20
   'tile-size '(4 4) 'box-size '(127 127)
-  'sight-range 6
+  'sight-range 3
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 37 'annoy-computer-factor 40
   'points 600
@@ -1345,7 +1345,7 @@
   'hit-points 1600
   'draw-level 20
   'tile-size '(4 4) 'box-size '(127 127)
-  'sight-range 9
+  'sight-range 6
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 40 'annoy-computer-factor 50
   'points 1500
Index: stratagus/data/ccl/orc/units.ccl
diff -u stratagus/data/ccl/orc/units.ccl:1.30 
stratagus/data/ccl/orc/units.ccl:1.31
--- stratagus/data/ccl/orc/units.ccl:1.30       Thu Aug 21 17:55:44 2003
+++ stratagus/data/ccl/orc/units.ccl    Mon Aug 25 07:21:14 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: units.ccl,v 1.30 2003/08/21 21:55:44 n0body Exp $
+;;     $Id: units.ccl,v 1.31 2003/08/25 11:21:14 mr-russ Exp $
 
 ;;=============================================================================
 ;;     Define unit-types.
@@ -986,7 +986,7 @@
   'hit-points 400
   'draw-level 20
   'tile-size '(2 2) 'box-size '(63 63)
-  'sight-range 3
+  'sight-range 2
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 20 'annoy-computer-factor 45
   'points 100
@@ -1014,7 +1014,7 @@
   'hit-points 800
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 30 'annoy-computer-factor 35
   'points 160
@@ -1041,7 +1041,7 @@
   'hit-points 700
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 35
   'points 240
@@ -1097,7 +1097,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 15
   'points 210
@@ -1124,7 +1124,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 230
@@ -1151,7 +1151,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 280
@@ -1178,7 +1178,7 @@
   'hit-points 1100
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 30 'annoy-computer-factor 20
   'points 170
@@ -1207,7 +1207,7 @@
   'hit-points 1200
   'draw-level 20
   'tile-size '(4 4) 'box-size '(127 127)
-  'sight-range 4
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 35 'annoy-computer-factor 45
   'points 200
@@ -1215,6 +1215,7 @@
   'corpse '(unit-destroyed-4x4-place 0)
   'type-land
   'building 
+  'builder-outside
   'can-store '(gold wood)
   'sounds '(
     selected "great-hall-selected"
@@ -1237,7 +1238,7 @@
   'hit-points 600
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 25 'annoy-computer-factor 15
   'points 150
@@ -1265,7 +1266,7 @@
   'hit-points 750
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 200
@@ -1293,7 +1294,7 @@
   'hit-points 500
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 35 'annoy-computer-factor 20
   'points 240
@@ -1320,7 +1321,7 @@
   'hit-points 775
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 15 'annoy-computer-factor 20
   'points 170
@@ -1347,7 +1348,7 @@
   'hit-points 600
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 25 'annoy-computer-factor 20
   'points 200
@@ -1377,7 +1378,7 @@
   'hit-points 650
   'draw-level 20
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 20 'annoy-computer-factor 20
   'points 160
@@ -1406,7 +1407,7 @@
   'hit-points 1400
   'draw-level 20
   'tile-size '(4 4) 'box-size '(127 127)
-  'sight-range 6
+  'sight-range 2
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 37 'annoy-computer-factor 40
   'points 600
@@ -1435,7 +1436,7 @@
   'hit-points 1600
   'draw-level 20
   'tile-size '(4 4) 'box-size '(127 127)
-  'sight-range 9
+  'sight-range 6
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 40 'annoy-computer-factor 50
   'points 1500
Index: stratagus/data/ccl/stratagus.ccl
diff -u stratagus/data/ccl/stratagus.ccl:1.7 
stratagus/data/ccl/stratagus.ccl:1.8
--- stratagus/data/ccl/stratagus.ccl:1.7        Wed Aug 13 10:55:44 2003
+++ stratagus/data/ccl/stratagus.ccl    Mon Aug 25 07:21:13 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: stratagus.ccl,v 1.7 2003/08/13 14:55:44 martinxyz Exp $
+;;     $Id: stratagus.ccl,v 1.8 2003/08/25 11:21:13 mr-russ Exp $
 
 (cond ((equal? *scheme* 'guile)
        (load "guile.ccl"))
@@ -77,6 +77,7 @@
 
 ;;     FIXME: documentation
 (set-game-name! "wc2")
+(set-default-map! "puds/default2.pud")
 
 ;;-----------------------------------------------------------------------------
 ;;     Music play list -       Insert your titles here
@@ -132,7 +133,7 @@
 ;;
 (set-show-sight-range! #f)
 ;(set-show-sight-range! #t)
-
+;(set-show-sight-range! 'circle)
 ;;     Enable/disable display of attack range of the selected unit on map.
 (set-show-attack-range! #f)
 ;(set-show-attack-range! #t)
Index: stratagus/data/ccl/units.ccl
diff -u stratagus/data/ccl/units.ccl:1.42 stratagus/data/ccl/units.ccl:1.43
--- stratagus/data/ccl/units.ccl:1.42   Sun Aug 24 14:48:02 2003
+++ stratagus/data/ccl/units.ccl        Mon Aug 25 07:21:14 2003
@@ -26,7 +26,7 @@
 ;;      along with this program; if not, write to the Free Software
 ;;      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA
 ;;
-;;     $Id: units.ccl,v 1.42 2003/08/24 18:48:02 n0body Exp $
+;;     $Id: units.ccl,v 1.43 2003/08/25 11:21:14 mr-russ Exp $
 
 ;; Load the animations for the units.
 (ccl:load "ccl/anim.ccl")
@@ -192,7 +192,7 @@
   'hit-points 25500
   'draw-level 40
   'tile-size '(3 3) 'box-size '(95 95)
-  'sight-range 3
+  'sight-range 1
   'armor 20 'basic-damage 0 'piercing-damage 0 'missile 'missile-none
   'priority 0
   'corpse '(unit-destroyed-3x3-place 0)
Index: stratagus/src/action/action_attack.c
diff -u stratagus/src/action/action_attack.c:1.78 
stratagus/src/action/action_attack.c:1.79
--- stratagus/src/action/action_attack.c:1.78   Thu Aug 21 03:12:03 2003
+++ stratagus/src/action/action_attack.c        Mon Aug 25 07:21:14 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_attack.c,v 1.78 2003/08/21 07:12:03 n0body Exp $
+//     $Id: action_attack.c,v 1.79 2003/08/25 11:21:14 mr-russ Exp $
 
 //@{
 
@@ -357,16 +357,14 @@
                if( goal ) {
                    DebugLevel3(", target %d range %d\n" _C_ UnitNumber(goal) 
_C_ unit->Orders[0].RangeX);
                } else {
-                   DebugLevel3(", (%d,%d) Tring with more range...\n" _C_ 
unit->Orders[0].X _C_ unit->Orders[0].Y);
-               }
-               if( unit->Orders[0].RangeX < TheMap.Width 
-                   || unit->Orders[0].RangeY < TheMap.Height ) {
-                   // Try again later and with a bigger range.
-                   // FIXME: does the range ever decrease?
-                   unit->Wait=10;
-                   unit->Orders[0].RangeX++;
-                   unit->Orders[0].RangeY++;
-                   return;
+                   DebugLevel0(", (%d,%d) Tring with more range...\n" _C_ 
unit->Orders[0].X _C_ unit->Orders[0].Y);
+                   if( unit->Orders[0].RangeX < TheMap.Width 
+                       || unit->Orders[0].RangeY < TheMap.Height ) {
+                       // Try again with more range
+                       unit->Orders[0].RangeX++;
+                       unit->Orders[0].RangeY++;
+                       return;
+                   }
                }
            }
            if( unit->Orders[0].Goal ) {
Index: stratagus/src/action/action_build.c
diff -u stratagus/src/action/action_build.c:1.90 
stratagus/src/action/action_build.c:1.91
--- stratagus/src/action/action_build.c:1.90    Sun Aug 24 14:48:03 2003
+++ stratagus/src/action/action_build.c Mon Aug 25 07:21:15 2003
@@ -1,4 +1,4 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_build.c,v 1.90 2003/08/24 18:48:03 n0body Exp $
+//     $Id: action_build.c,v 1.91 2003/08/25 11:21:15 mr-russ Exp $
 
 //@{
 
@@ -102,6 +102,14 @@
 
     type=unit->Orders[0].Type;
 
+    // Create the building to find a valid path to any part of it.
+    // Only create if we didn't already.
+    if ( unit->Orders[0].Goal == NoUnitP ) {
+       unit->Orders[0].Goal=MakeUnit(type,NULL);
+       unit->Orders[0].Goal->X=unit->Orders[0].X;
+       unit->Orders[0].Goal->Y=unit->Orders[0].Y;
+    }
+
     switch( DoActionMove(unit) ) {     // reached end-point?
        case PF_UNREACHABLE:
            //
@@ -121,6 +129,9 @@
            }
 
            unit->Orders[0].Action=UnitActionStill;
+           // Release Temporary Building
+            UnitClearOrders(unit->Orders[0].Goal);
+            ReleaseUnit(unit->Orders[0].Goal);
            unit->SubAction=0;
            if( unit->Selected ) {      // update display for new action
                SelectedUnitChanged();
@@ -135,15 +146,8 @@
            return;
     }
 
-    //
-    // Building place must be reached!
-    //
     x=unit->Orders[0].X;
     y=unit->Orders[0].Y;
-    if( type->ShoreBuilding ) {                // correct coordinates.
-       ++x;
-       ++y;
-    }
 
     //
     // Check if the building could be build there.
@@ -166,6 +170,9 @@
        }
 
        unit->Orders[0].Action=UnitActionStill;
+       // Release Temporary Building
+        UnitClearOrders(unit->Orders[0].Goal);
+        ReleaseUnit(unit->Orders[0].Goal);
        unit->SubAction=0;
        if( unit->Selected ) {  // update display for new action
            SelectedUnitChanged();
@@ -195,6 +202,9 @@
        }
 
        unit->Orders[0].Action=UnitActionStill;
+       // Release Temporary Building
+        UnitClearOrders(unit->Orders[0].Goal);
+        ReleaseUnit(unit->Orders[0].Goal);
        unit->SubAction=0;
        if( unit->Selected ) {  // update display for new action
            SelectedUnitChanged();
@@ -213,6 +223,9 @@
        }
 
        unit->Orders[0].Action=UnitActionStill;
+       // Release Temporary Building
+        UnitClearOrders(unit->Orders[0].Goal);
+        ReleaseUnit(unit->Orders[0].Goal);
        unit->SubAction=0;
        if( unit->Selected ) {  // update display for new action
            SelectedUnitChanged();
@@ -221,12 +234,16 @@
     }
     PlayerSubUnitType(unit->Player,type);
 
-    build=MakeUnit(type,unit->Player);
+    
+    build=unit->Orders[0].Goal;
+    unit->Orders[0].Goal = NoUnitP;
+    AssignUnitToPlayer(build,unit->Player);
     build->Constructed=1;
     build->CurrentSightRange=0;
     PlaceUnit(build,x,y);
-    build->CurrentSightRange=build->Type->TileWidth < build->Type->TileHeight
-                               ? build->Type->TileHeight : 
build->Type->TileWidth;
+    if( !type->BuilderOutside ) {
+       build->CurrentSightRange=1;
+    }
 
     // Building on top of something, must remove what is beneath it
     if( type->MustBuildOnTop ) {
@@ -285,7 +302,7 @@
        build->Refs++;
        UnitMarkSeen(unit);
        //  Mark the new building seen.
-       
MapMarkSight(build->Player,x+build->Type->TileWidth/2,y+build->Type->TileHeight/2,build->CurrentSightRange);
+       MapMarkUnitSight(build);
     }
     UpdateConstructionFrame(build);
     UnitMarkSeen(build);
@@ -422,9 +439,7 @@
            SelectedUnitChanged();
        }
        unit->CurrentSightRange=unit->Stats->SightRange;
-       MapMarkSight(unit->Player,unit->X+unit->Type->TileWidth/2,
-                           unit->Y+unit->Type->TileWidth/2,
-                           unit->CurrentSightRange);
+       MapMarkUnitSight(unit);
         CheckUnitToBeDrawn(unit);
        return;
     }
Index: stratagus/src/action/action_die.c
diff -u stratagus/src/action/action_die.c:1.50 
stratagus/src/action/action_die.c:1.51
--- stratagus/src/action/action_die.c:1.50      Fri Jul 11 10:35:29 2003
+++ stratagus/src/action/action_die.c   Mon Aug 25 07:21:15 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_die.c,v 1.50 2003/07/11 14:35:29 n0body Exp $
+//     $Id: action_die.c,v 1.51 2003/08/25 11:21:15 mr-russ Exp $
 
 //@{
 
@@ -78,7 +78,7 @@
        }
 
        //Fixes sight from death
-       MapUnmarkSight(unit->Player,unit->X,unit->Y,unit->CurrentSightRange);
+       MapUnmarkUnitSight(unit);
        //unit->CurrentSightRange=unit->Type->Stats->SightRange;
 
        unit->State=unit->Type->CorpseScript;
Index: stratagus/src/action/action_harvest.c
diff -u stratagus/src/action/action_harvest.c:1.76 
stratagus/src/action/action_harvest.c:1.77
--- stratagus/src/action/action_harvest.c:1.76  Sun Aug 10 22:14:45 2003
+++ stratagus/src/action/action_harvest.c       Mon Aug 25 07:21:15 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: action_harvest.c,v 1.76 2003/08/11 02:14:45 n0body Exp $
+//     $Id: action_harvest.c,v 1.77 2003/08/25 11:21:15 mr-russ Exp $
 
 //@{
 
@@ -278,6 +278,7 @@
     int i;
 
     destu=unit->Orders[0].Goal;
+    unit->Orders[0].RangeX=unit->Orders[0].RangeY=1;
     DebugCheck( !destu );
 
     i=DoActionMove(unit);
Index: stratagus/src/action/action_move.c
diff -u stratagus/src/action/action_move.c:1.62 
stratagus/src/action/action_move.c:1.63
--- stratagus/src/action/action_move.c:1.62     Thu Aug 21 03:12:03 2003
+++ stratagus/src/action/action_move.c  Mon Aug 25 07:21:15 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.62 2003/08/21 07:12:03 n0body Exp $
+//     $Id: action_move.c,v 1.63 2003/08/25 11:21:15 mr-russ Exp $
 
 //@{
 
@@ -131,20 +131,23 @@
        TheMap.Fields[unit->X+unit->Y*TheMap.Width].Flags&=~i;
 
        UnitCacheRemove(unit);
+
+       MapUnmarkUnitSight(unit);
+       //  ummark sight for units inside too.
+       uninside=unit->UnitInside;
+       for( i=unit->InsideCount; i; uninside=uninside->NextContained,i-- ) {
+           MapUnmarkUnitOnBoardSight(uninside,unit);
+       }
+
        x=unit->X+=xd;
        y=unit->Y+=yd;
        UnitCacheInsert(unit);
 
-       TheMap.Fields[x+y*TheMap.Width].Flags|=i;
+       TheMap.Fields[x+y*TheMap.Width].Flags|=unit->Type->FieldFlags;
 
        MustRedraw|=RedrawMinimap;
-       //
-       //      Update visible area.
-       //
-       x+=unit->Type->TileWidth/2;
-       y+=unit->Type->TileHeight/2;
 
-       MapMarkNewSight(unit->Player,x,y,unit->CurrentSightRange,xd,yd);
+       MapMarkUnitSight(unit);
        //  Remove unit from the current selection
        if( unit->Selected && !IsMapFieldVisible(ThisPlayer,unit->X,unit->Y)) {
 #ifndef NEW_UI
@@ -157,11 +160,9 @@
        }
 
        //  Remark sight for units inside too.
-       if ( unit->Type->Transporter ) {
-           uninside=unit->UnitInside;
-           for( i=unit->InsideCount; i; uninside=uninside->NextContained,i-- ) 
{
-               
MapMarkNewSight(uninside->Player,x,y,uninside->CurrentSightRange,xd,yd);
-           }
+       uninside=unit->UnitInside;
+       for( i=unit->InsideCount; i; uninside=uninside->NextContained,i-- ) {
+           MapMarkUnitOnBoardSight(uninside,unit);
        }
 
        //  Reveal Submarines and stuff.
Index: stratagus/src/action/command.c
diff -u stratagus/src/action/command.c:1.100 
stratagus/src/action/command.c:1.101
--- stratagus/src/action/command.c:1.100        Thu Aug 21 17:55:45 2003
+++ stratagus/src/action/command.c      Mon Aug 25 07:21:15 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: command.c,v 1.100 2003/08/21 21:55:45 n0body Exp $
+//     $Id: command.c,v 1.101 2003/08/25 11:21:15 mr-russ Exp $
 
 //@{
 
@@ -666,23 +666,16 @@
 
        order->Action=UnitActionBuild;
        order->Goal=NoUnitP;
-       if( what->ShoreBuilding ) {
-           order->RangeX=what->TileWidth+1;
-           order->RangeY=what->TileHeight+1;
-           order->X=x-1;
-           order->Y=y-1;
-       } else {
-           // FIXME: -1 read note in pathfinder, some old wired code.
-           order->RangeX=what->TileWidth-1;
-           order->RangeY=what->TileHeight-1;
-           order->X=x;
-           order->Y=y;
-       }
+       order->IsRect=1;
+       order->X=x;
+       order->Y=y;
        if(what->BuilderOutside) {
-           // FIXME: n0body: brain damage. Walk around buggy moving to
-           // FIXME: the building position.
-           order->RangeX=what->TileWidth*10;
-           order->RangeY=what->TileWidth*10;
+           order->RangeX=REPAIR_RANGE;
+           order->RangeY=REPAIR_RANGE;
+       } else {
+           // If building inside, but be next to stop
+           order->RangeX=1;
+           order->RangeY=1;
        }
        order->Type=what;
        order->Arg1=NULL;
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.93 stratagus/src/clone/spells.c:1.94
--- stratagus/src/clone/spells.c:1.93   Thu Aug 21 17:55:45 2003
+++ stratagus/src/clone/spells.c        Mon Aug 25 07:21:15 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.93 2003/08/21 21:55:45 n0body Exp $
+//     $Id: spells.c,v 1.94 2003/08/25 11:21:15 mr-russ Exp $
 
 /*
 **     And when we cast our final spell
@@ -1548,7 +1548,7 @@
     target->CurrentSightRange=target->Stats->SightRange;
 
     target->Removed=1;
-    MapMarkSight(target->Player,x,y,target->CurrentSightRange);
+    MapMarkUnitSight(target);
 
     target->TTL=GameCycle+target->Type->DecayRate*6*CYCLES_PER_SECOND;
     CheckUnitToBeDrawn(target);
Index: stratagus/src/clone/unit.c
diff -u stratagus/src/clone/unit.c:1.289 stratagus/src/clone/unit.c:1.290
--- stratagus/src/clone/unit.c:1.289    Sun Aug 24 14:48:03 2003
+++ stratagus/src/clone/unit.c  Mon Aug 25 07:21:17 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit.c,v 1.289 2003/08/24 18:48:03 n0body Exp $
+//     $Id: unit.c,v 1.290 2003/08/25 11:21:17 mr-russ Exp $
 
 //@{
 
@@ -413,6 +413,8 @@
     unit->Player=player;
     unit->Stats=&type->Stats[unit->Player->Player];
     unit->Colors=&player->UnitColors;
+    unit->HP = unit->Stats->HitPoints;
+
 }
 
 /**
@@ -427,17 +429,15 @@
 {
     Unit* unit;
 
-    DebugCheck(!player);               // Current code didn't support no player
+    //DebugCheck(!player);             // Current code didn't support no player
 
     unit = AllocUnit();
     InitUnit(unit, type);
-    AssignUnitToPlayer(unit, player);
 
-    /* now we can finish the player-specific initialization of our unit */
-    /* NOTE: this used to be a part of AssignUnitToPlayer() but had to be
-     * moved out since it clobbered HP read from a saved file during game
-     * load. */
-    unit->HP = unit->Stats->HitPoints;
+    // Only Assign if a Player was specified
+    if ( player ) {
+       AssignUnitToPlayer(unit, player);
+    }
 
     return unit;
 }
@@ -504,15 +504,13 @@
        //      Update fog of war, if unit belongs to player on this computer
        //
        if( unit->Container && unit->Removed ) {
-           
MapUnmarkSight(unit->Player,unit->Container->X+unit->Container->Type->TileWidth/2
-                   ,unit->Container->Y+unit->Container->Type->TileHeight/2
-                   ,unit->CurrentSightRange);
+           MapUnmarkUnitOnBoardSight(unit,unit->Container);
        }
        if (unit->Container) {
            RemoveUnitFromContainer(unit);
        }
        unit->CurrentSightRange=unit->Stats->SightRange;
-       MapMarkSight(unit->Player,x,y,unit->CurrentSightRange);
+       MapMarkUnitSight(unit);
 
        if( type->CanSeeSubmarine ) {
            MarkSubmarineSeen(unit->Player,x,y,unit->Stats->SightRange);
@@ -629,19 +627,13 @@
     unsigned flags;
 
     if( unit->Removed && unit->Container ) {
-       
MapUnmarkSight(unit->Player,unit->Container->X+unit->Container->Type->TileWidth/2
-               ,unit->Container->Y+unit->Container->Type->TileHeight/2
-               ,unit->CurrentSightRange);
+       MapUnmarkUnitOnBoardSight(unit,unit->Container);
     } else {
-       MapUnmarkSight(unit->Player,unit->X+unit->Type->TileWidth/2
-               ,unit->Y+unit->Type->TileHeight/2
-               ,unit->CurrentSightRange);
+       MapUnmarkUnitSight(unit);
     }
     if( host ) {
        unit->CurrentSightRange=host->CurrentSightRange;
-       MapMarkSight(unit->Player,host->X+host->Type->TileWidth/2,
-               host->Y+host->Type->TileWidth/2,
-               unit->CurrentSightRange);
+       MapMarkUnitOnBoardSight(unit,host);
        AddUnitInContainer(unit,host);
     }
 
@@ -1728,22 +1720,14 @@
     }
     *unit->PlayerSlot=unit;
 
-    unit->Player=newplayer;
-
     if ( unit->Removed && unit->Container ) {
-       
MapUnmarkSight(oldplayer,unit->Container->X+unit->Container->Type->TileWidth/2
-               ,unit->Container->Y+unit->Container->Type->TileHeight/2
-               ,unit->CurrentSightRange);
-       
MapMarkSight(unit->Player,unit->Container->X+unit->Container->Type->TileWidth/2
-               ,unit->Container->Y+unit->Container->Type->TileHeight/2
-               ,unit->CurrentSightRange);
+       MapUnmarkUnitOnBoardSight(unit,unit->Next);
+       unit->Player=newplayer;
+       MapMarkUnitOnBoardSight(unit,unit->Next);
     } else {
-       MapUnmarkSight(oldplayer,unit->X+unit->Type->TileWidth/2
-               ,unit->Y+unit->Type->TileHeight/2
-               ,unit->CurrentSightRange);
-       MapMarkSight(unit->Player,unit->X+unit->Type->TileWidth/2
-               ,unit->Y+unit->Type->TileHeight/2
-               ,unit->CurrentSightRange);
+       MapUnmarkUnitSight(unit);
+       unit->Player=newplayer;
+       MapMarkUnitSight(unit);
     }
 
     unit->Stats=&unit->Type->Stats[newplayer->Player];
@@ -2369,7 +2353,7 @@
     // Remove unit that is building!
     //
     IfDebug( j=0; );
-    if( unit&&!type->BuilderOutside ) {
+    if( unit ) {
        // FIXME: This only works with 1x1 big units
        DebugCheck( unit->Type->TileWidth!=1 || unit->Type->TileHeight!=1 );
        j=unit->Type->FieldFlags;
@@ -2463,7 +2447,7 @@
            }
        }
     }
-    if( unit&&!type->BuilderOutside ) {
+    if( unit ) {
        TheMap.Fields[unit->X+unit->Y*TheMap.Width].Flags|=j;
     }
 
@@ -2794,7 +2778,7 @@
 
     for( i=0; i<nunits; i++ ) {
        unit=units[i];
-       if( unit->Type->Harvester && !unit->Removed ) {
+       if( unit->Type->Coward && !unit->Removed ) {
            if( unit->Orders[0].Action==UnitActionStill ) {
                if( SelectNextUnit && !IsOnlySelected(unit) ) {
                    return unit;
@@ -2993,18 +2977,18 @@
            unit->Visible = 0xffff;
            DeadBuildingCacheInsert(unit);      //Insert into corpse list
            // FIXME: (mr-russ) Hack to make sure we see our own building 
destroyed
-           MapMarkSight(unit->Player,unit->X,unit->Y,1);
+           MapMarkUnitSight(unit);
            UnitMarkSeen(unit);
-           MapUnmarkSight(unit->Player,unit->X,unit->Y,1);
+           MapUnmarkUnitSight(unit);
            UnitMarkSeen(unit);
            return;
        }
 
        // no corpse available
        // FIXME: (mr-russ) Hack to make sure we see our own building destroyed
-       MapMarkSight(unit->Player,unit->X,unit->Y,1);
+       MapMarkUnitSight(unit);
        UnitMarkSeen(unit);
-       MapUnmarkSight(unit->Player,unit->X,unit->Y,1);
+       MapUnmarkUnitSight(unit);
        ReleaseUnit(unit);
        return;
     }
@@ -3038,7 +3022,7 @@
     } else {
        unit->CurrentSightRange=0;
     }
-    MapMarkSight(unit->Player,unit->X,unit->Y,unit->CurrentSightRange);
+    MapMarkUnitSight(unit);
 }
 
 /**
@@ -3050,6 +3034,8 @@
     int i;
 
     // FIXME: n0b0dy: No corpses, is that correct behaviour?
+    // No Corpses, we are inside something, and we can't be seen
+    // FIXME: mr-russ: support for units inside units/buildings?
     unit=source->UnitInside;
     for( i=source->InsideCount; i; --i,unit=unit->NextContained ) {
        RemoveUnit(unit,NULL);
@@ -3278,7 +3264,7 @@
  */
 global int MapDistance(int x1,int y1,int x2,int y2)
 {
-    return max(abs(x1-x2),abs(y1-y2));
+    return isqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
 }
 
 /**
@@ -3318,7 +3304,7 @@
     DebugLevel3("\tDistance %d,%d -> %d,%d = %d\n"
            _C_ x1 _C_ y1 _C_ x2 _C_ y2 _C_ (dy<dx) ? dx : dy );
 
-    return (dy<dx) ? dx : dy;
+    return isqrt(dy*dy+dx*dx);
 }
 
 /**
@@ -3378,7 +3364,7 @@
        }
     }
 
-    return (dy<dx) ? dx : dy;
+    return isqrt(dy*dy+dx*dx);
 }
 
 /**
@@ -3704,10 +3690,14 @@
        CLprintf(file," 'rescued-from %d",unit->RescuedFrom->Player);
     }
     // n0b0dy: How is this usefull?
+    // mr-russ: You can't always load units in order, it saved the information
+    // so you can load a unit who's Container hasn't been loaded yet.
+    // SEE unit loading code.
     if( unit->Container && unit->Removed ) {
-       CLprintf(file," 'host-tile '(%d %d) ",
-               unit->Container->X+unit->Container->Type->TileWidth/2,
-               unit->Container->Y+unit->Container->Type->TileHeight/2);
+       CLprintf(file," 'host-info '(%d %d %d %d) ",
+           unit->Next->X,unit->Next->Y,
+           unit->Next->Type->TileWidth,
+           unit->Next->Type->TileHeight);
     }
     CLprintf(file," 'visible \"");
     for( i=0; i<PlayerMax; ++i ) {
@@ -3871,7 +3861,7 @@
     int InRun, RunStart;
 
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: units $Id: unit.c,v 1.289 2003/08/24 18:48:03 
n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: units $Id: unit.c,v 1.290 2003/08/25 11:21:17 
mr-russ Exp $\n\n");
 
     //
     // Local variables
Index: stratagus/src/clone/unit_draw.c
diff -u stratagus/src/clone/unit_draw.c:1.154 
stratagus/src/clone/unit_draw.c:1.155
--- stratagus/src/clone/unit_draw.c:1.154       Sun Aug 24 14:48:03 2003
+++ stratagus/src/clone/unit_draw.c     Mon Aug 25 07:21:17 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit_draw.c,v 1.154 2003/08/24 18:48:03 n0body Exp $
+//     $Id: unit_draw.c,v 1.155 2003/08/25 11:21:17 mr-russ Exp $
 
 //@{
 
@@ -577,7 +577,7 @@
 global void SaveDecorations(CLFile* file)
 {
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: decorations $Id: unit_draw.c,v 1.154 2003/08/24 
18:48:03 n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: decorations $Id: unit_draw.c,v 1.155 2003/08/25 
11:21:17 mr-russ Exp $\n\n");
 
     CLprintf(file,"(mana-sprite \"%s\"  %d %d  %d %d)\n",
        ManaSprite.File,ManaSprite.HotX,ManaSprite.HotY,
@@ -1589,14 +1589,13 @@
                VideoFill75TransCircleClip(ColorGreen
                        ,x+type->TileWidth*TileSizeX/2
                        ,y+type->TileHeight*TileSizeY/2
-                       ,min(stats->SightRange*TileSizeX
-                           ,stats->SightRange*TileSizeY));
+                       ,min((stats->SightRange+(type->TileWidth-1)/2)*TileSizeX
+                           
,(stats->SightRange+(type->TileHeight-1)/2)*TileSizeY));
            } else {
-               VideoDrawRectangleClip(ColorGreen
-                   ,x+type->TileWidth*TileSizeX/2-stats->SightRange*TileSizeX
-                   ,y+type->TileHeight*TileSizeY/2-stats->SightRange*TileSizeY
-                   ,stats->SightRange*TileSizeX*2
-                   ,stats->SightRange*TileSizeY*2);
+               VideoDrawCircleClip(ColorGreen
+                   ,x+type->TileWidth*TileSizeX/2
+                   ,y+type->TileHeight*TileSizeY/2
+                   ,(stats->SightRange+(type->TileWidth-1)/2)*TileSizeX*2);
            }
        }
        if( type->CanAttack || type->Tower ) {
@@ -1605,19 +1604,17 @@
                        ? type->ReactRangePerson
                        : type->ReactRangeComputer;
                if( r ) {
-                   VideoDrawRectangleClip(ColorBlue
-                       ,x+type->TileWidth*TileSizeX/2-r*TileSizeX
-                       ,y+TileSizeY/2-r*TileSizeY
-                       ,r*TileSizeX*2
-                       ,r*TileSizeY*2);
+                   VideoDrawCircleClip(ColorBlue
+                       ,x+type->TileWidth*TileSizeX/2
+                       ,y+type->TileHeight*TileSizeY/2
+                       ,r*TileSizeX);
                }
            }
            if( ShowAttackRange && stats->AttackRange ) {
-               VideoDrawRectangleClip(ColorRed
-                   ,x+type->TileWidth*TileSizeX/2-stats->AttackRange*TileSizeX
-                   ,y+type->TileHeight*TileSizeY/2-stats->AttackRange*TileSizeY
-                   ,stats->AttackRange*TileSizeX*2
-                   ,stats->AttackRange*TileSizeY*2);
+               VideoDrawCircleClip(ColorRed
+                   ,x+type->TileWidth*TileSizeX/2
+                   ,y+type->TileHeight*TileSizeY/2
+                   ,stats->AttackRange*TileSizeX);
            }
        }
     }
@@ -1897,7 +1894,7 @@
        drawlevel2 = c2->Type->DrawLevel;
     }
     if( drawlevel1 == drawlevel2 ) {
-        return c1->Y*MaxMapWidth+c1->X < c2->Y*MaxMapWidth+c2->X ? -1 : 1;
+       return c1->Y*MaxMapWidth+c1->X < c2->Y*MaxMapWidth+c2->X ? -1 : 1;
     } else {
        return drawlevel1 <= drawlevel2 ? -1 : 1;
     }
Index: stratagus/src/clone/unit_find.c
diff -u stratagus/src/clone/unit_find.c:1.54 
stratagus/src/clone/unit_find.c:1.55
--- stratagus/src/clone/unit_find.c:1.54        Thu Aug 21 03:12:03 2003
+++ stratagus/src/clone/unit_find.c     Mon Aug 25 07:21:17 2003
@@ -10,7 +10,7 @@
 //
 /address@hidden unit_find.c    -       The find/select for units. */
 //
-//     (c) Copyright 1998-2003 by Lutz Sammer
+//     (c) Copyright 1998-2003 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,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit_find.c,v 1.54 2003/08/21 07:12:03 n0body Exp $
+//     $Id: unit_find.c,v 1.55 2003/08/25 11:21:17 mr-russ Exp $
 
 //@{
 
@@ -67,6 +67,12 @@
 #define CANATTACK_BONUS                0x01000000
 
 /*----------------------------------------------------------------------------
+--     Local Data
+----------------------------------------------------------------------------*/
+//FIXME: mr-russ  Really bad hack to improve UnitsInDistance calculation
+local Unit* localunit;
+
+/*----------------------------------------------------------------------------
 --     Functions
 ----------------------------------------------------------------------------*/
 
@@ -212,15 +218,15 @@
 }
 
 /**
-**     Choose target on map tile.
+**     Choose targe on a map
 **
-**     @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 wants to attack.
+**     @param tx       X position to attack.
+**     @param ty       Y position to attack.
 **
 **     @return         Returns ideal target on map tile.
 */
-global Unit* TargetOnMapTile(const Unit* source,int tx,int ty)
+global Unit* TargetOnMapTile(const Unit* source, int tx, int ty)
 {
     Unit* table[UnitMax];
     Unit* unit;
@@ -252,6 +258,57 @@
        if( !CanTarget(source->Type,unit->Type) ) {
            continue;
        }
+       //
+       //      Choose the best target.
+       //
+       if( !best || best->Type->Priority<unit->Type->Priority ) {
+           best=unit;
+       }
+    }
+    return best;
+}
+
+/**
+**     Choose target on map area.
+**
+**     @param source   Unit which want to attack.
+**     @param x1       X position on map, tile-based.
+**     @param y1       Y position on map, tile-based.
+**     @param x2       X position on map, tile-based.
+**     @param y2       Y position on map, tile-based.
+**
+**     @return         Returns ideal target on map tile.
+*/
+global Unit* TargetOnMap(const Unit* source,int x1,int y1,int x2,int y2)
+{
+    Unit* table[UnitMax];
+    Unit* unit;
+    Unit* best;
+    const UnitType* type;
+    int n;
+    int i;
+
+    n=SelectUnits(x1,y1,x2,y2,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( x2<unit->X || x1>=unit->X+type->TileWidth
+               || y2<unit->Y || y1>=unit->Y+type->TileHeight ) {
+           continue;
+       }
+       if( !CanTarget(source->Type,unit->Type) ) {
+           continue;
+       }
 
        //
        //      Choose the best target.
@@ -397,6 +454,21 @@
     return NoUnitP;
 }
 
+/**
+**     Compare distance from me to a unit
+**
+**     @param v1       item to compare
+**     @param v2       item to compare with
+**
+**     @return         which unit should be sorted first
+**
+**/
+local int InDistanceCompare(const void* v1, const void* v2)
+{
+    return MapDistanceBetweenUnits(*(Unit**)v1,localunit) <
+       MapDistanceBetweenUnits(*(Unit**)v2,localunit);
+}
+                       
 /*----------------------------------------------------------------------------
 --     Finding units for attack
 ----------------------------------------------------------------------------*/
@@ -462,6 +534,9 @@
     }
 
     enemy_count=0;
+    // FIXME: (mr-russ) Breaks all good coding rules...
+    localunit=u;
+    qsort((void *)table,n,sizeof(Unit*),InDistanceCompare);
     // FILL good/bad...
     for (i = 0; i < n; i++) {
        dest = table[i];
@@ -554,10 +629,10 @@
            d=MapDistanceBetweenUnits(u,dest);
 
             // FIXME: we don't support moving away!
-            if((d<type->MinAttackRange)||(!UnitReachable(u,dest,attackrange))) 
{
-               table[i]=0;
-           } else {
+           
if((d>=type->MinAttackRange)&&(d<=range)&&UnitReachable(u,dest,attackrange)) {
                enemy_count++;
+           } else {
+               table[i]=0;
            }
        }
 
@@ -666,11 +741,10 @@
 **
 **     @return         Unit to be attacked.
 **
-**     @note   This could be improved, for better performance.
 */
 global Unit* AttackUnitsInDistance(Unit* unit,int range)
 {
-    const Unit* dest;
+    Unit* dest;
     const UnitType* type;
     const UnitType* dtype;
     Unit* table[UnitMax];
@@ -681,11 +755,10 @@
     int d;
     int attackrange;
     int cost;
-    const Player* player;
-    const Unit* best_unit;
     int best_cost;
     int tried_units;
-    int reachable;
+    const Player* player;
+    Unit* best_unit;
 
     DebugLevel3Fn("(%d)%s\n" _C_ UnitNumber(unit) _C_ unit->Type->Ident);
 
@@ -700,19 +773,23 @@
     //
     x=unit->X;
     y=unit->Y;
-    n=SelectUnits(x-range,y-range,x+range+1,y+range+1,table);
+    type=unit->Type;
+    
n=SelectUnits(x-range,y-range,x+range+type->TileWidth-1,y+range+type->TileHeight-1,table);
 
     best_unit=NoUnitP;
     best_cost=INT_MAX;
     tried_units=0;
 
     player=unit->Player;
-    type=unit->Type;
     attackrange=unit->Stats->AttackRange;
 
     //
     // Find the best unit to attack
     //
+
+    // FIXME: (mr-russ) Breaks all good coding rules...
+    localunit=unit;
+    qsort((void *)table,n,sizeof(Unit*),InDistanceCompare);
     for( i=0; i<n; ++i ) {
        dest=table[i];
        //
@@ -754,6 +831,10 @@
        if( d<type->MinAttackRange ) {  // FIXME: we don't support moving away!
            continue;
        }
+       // Use Circle, not square :)
+       if( d>range ) {
+           continue;
+       }
        if( d<attackrange && d>type->MinAttackRange ) {
            cost+=d*INRANGE_FACTOR;
            cost-=INRANGE_BONUS;
@@ -771,19 +852,16 @@
        //
        //      Take this target?
        //
-       // If we failed 5 times, we probably can't get anything
+       // If we failed 5 closest units, we probably can't get anything
        if( tried_units >= 5 && best_cost == INT_MAX ) {
            best_unit=NULL;
            break;
        }
-       if( cost<best_cost ) {
-           reachable = UnitReachable(unit,dest,attackrange);
-           if( d<attackrange || reachable ) {
-               best_unit=dest;
-               best_cost=cost;
-           } else {
-               tried_units++;
-           }
+       if( cost<best_cost && d>attackrange && 
!UnitReachable(unit,dest,attackrange)) {
+           tried_units++;
+       } else {
+           best_unit=dest;
+           best_cost=cost;
        }
     }
 
@@ -794,8 +872,7 @@
     }
 */
 
-    // FIXME: No idea how to make this correct, without cast!!
-    return (Unit*)best_unit;
+    return best_unit;
 }
 
 /**
Index: stratagus/src/clone/unitcache.c
diff -u stratagus/src/clone/unitcache.c:1.35 
stratagus/src/clone/unitcache.c:1.36
--- stratagus/src/clone/unitcache.c:1.35        Fri Jul 11 10:35:30 2003
+++ stratagus/src/clone/unitcache.c     Mon Aug 25 07:21:17 2003
@@ -33,7 +33,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unitcache.c,v 1.35 2003/07/11 14:35:30 n0body Exp $
+//     $Id: unitcache.c,v 1.36 2003/08/25 11:21:17 mr-russ Exp $
 
 //@{
 
@@ -979,16 +979,20 @@
 */
 global Unit* UnitCacheOnXY(int x,int y,unsigned type)
 {
-    Unit* unit;
+    Unit* table[UnitMax];
+    int n;
 
-    unit=TheMap.Fields[y*TheMap.Width+x].Here.Units;
-    while( unit ) {
-       if( (unsigned)unit->Type->UnitType==type ) {
+    n = UnitCacheOnTile(x,y,table);
+    while( n-- ) {
+       if( (unsigned)table[n]->Type->UnitType==type ) {
            break;
        }
-       unit=unit->Next;
     }
-    return unit;
+    if( n > -1 ) {
+       return table[n];
+    } else {
+       return NoUnitP;
+    }
 }
 
 /**
Index: stratagus/src/game/game.c
diff -u stratagus/src/game/game.c:1.99 stratagus/src/game/game.c:1.100
--- stratagus/src/game/game.c:1.99      Sat Aug  2 09:34:25 2003
+++ stratagus/src/game/game.c   Mon Aug 25 07:21:17 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: game.c,v 1.99 2003/08/02 13:34:25 grumbel Exp $
+//     $Id: game.c,v 1.100 2003/08/25 11:21:17 mr-russ Exp $
 
 //@{
 
@@ -282,6 +282,8 @@
        return;
     }
 
+    InitMapFogOfWar();                 // build tables for fog of war
+    
     if( filename ) {
        s = NULL;
        // FIXME: LibraryFile here?
@@ -425,7 +427,6 @@
 
     CreateMinimap();                   // create minimap for pud
     InitMap();                         // setup draw functions
-    InitMapFogOfWar();                 // build tables for fog of war
     PreprocessMap();                   // Adjust map for use
     MapColorCycle();                   // Setup color cycle
 
Index: stratagus/src/include/map.h
diff -u stratagus/src/include/map.h:1.97 stratagus/src/include/map.h:1.98
--- stratagus/src/include/map.h:1.97    Sun Aug 17 11:57:07 2003
+++ stratagus/src/include/map.h Mon Aug 25 07:21:17 2003
@@ -1,4 +1,4 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: map.h,v 1.97 2003/08/17 15:57:07 n0body Exp $
+//     $Id: map.h,v 1.98 2003/08/25 11:21:17 mr-russ Exp $
 
 #ifndef __MAP_H__
 #define __MAP_H__
@@ -340,6 +340,11 @@
     /// Draws tiles display and video mode independ
 extern void (*MapDrawTile)(int,int,int);
 
+    /// Vision Table to see where to locate goals and vision
+extern unsigned char *VisionTable[3];
+    /// Companion table for fast lookups
+extern int *VisionLookup;
+
 #ifdef NEW_DECODRAW
     /// FIXME: docu
 extern void InitMapDecoration(void);
@@ -396,12 +401,10 @@
 //
 //     in map_fog.c
 //
-    /// Mark the sight in range
-extern void MapMarkSight(const Player*,int,int,int);
-    /// Mark the new sight in range
-extern void MapMarkNewSight(const Player*,int,int,int,int,int);
-    /// Unmark the sight in range
-extern void MapUnmarkSight(const Player*,int,int,int);
+extern void MapUnmarkTileSight(const Player* player,int x,int y,unsigned char 
*v);
+extern void MapMarkTileSight(const Player* player,int x,int y,unsigned char 
*v);
+    /// 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,unsigned char*));
     /// Find if a tile is visible (With shared vision)
 extern int IsTileVisible(const Player* player, int x, int y);
     /// Mark tiles with fog of war to be redrawn
@@ -543,7 +546,16 @@
 #define CanMoveToMask(x,y,mask) \
        !(TheMap.Fields[(x)+(y)*TheMap.Width].Flags&(mask))
 
-
+#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 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, \
+       
(host)->Type->TileWidth,(host)->Type->TileHeight,(unit)->CurrentSightRange,MapUnmarkTileSight)
     /// Check if a field for the user is explored
 #define IsMapFieldExplored(player,x,y) \
     (IsTileVisible((player),(x),(y)))
Index: stratagus/src/include/pathfinder.h
diff -u stratagus/src/include/pathfinder.h:1.31 
stratagus/src/include/pathfinder.h:1.32
--- stratagus/src/include/pathfinder.h:1.31     Fri Jul 11 10:35:30 2003
+++ stratagus/src/include/pathfinder.h  Mon Aug 25 07:21:17 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: pathfinder.h,v 1.31 2003/07/11 14:35:30 n0body Exp $
+//     $Id: pathfinder.h,v 1.32 2003/08/25 11:21:17 mr-russ Exp $
 
 #ifndef        __PATH_FINDER_H__
 #define        __PATH_FINDER_H__
@@ -100,9 +100,9 @@
     /// Get next element of the way to goal.
 extern int NewPath(Unit* unit);
     /// Return distance to place.
-extern int PlaceReachable(Unit* unit,int x,int y,int range);
+extern int PlaceReachable(Unit* src,int x,int y,int w, int h, int range);
     /// Return distance to unit.
-extern int UnitReachable(Unit* unit,const Unit* dest,int range);
+extern int UnitReachable(Unit* unit,Unit* dst,int range);
 
 //
 //     in astar.c
@@ -117,7 +117,7 @@
 extern void FreeAStar(void);
 
     /// Find and a* path for a unit
-extern int AStarFindPath(Unit* unit, int x1, int y1, int x2, int y2, char* 
path);
+extern int AStarFindPath(Unit* unit, int gx, int gy, int gw, int gh, int 
range, char* path);
 //
 //     in ccl_pathfinder.c
 //
Index: stratagus/src/include/unit.h
diff -u stratagus/src/include/unit.h:1.208 stratagus/src/include/unit.h:1.209
--- stratagus/src/include/unit.h:1.208  Sun Aug 24 14:48:03 2003
+++ stratagus/src/include/unit.h        Mon Aug 25 07:21:17 2003
@@ -10,7 +10,7 @@
 //
 /address@hidden unit.h         -       The unit headerfile. */
 //
-//     (c) Copyright 1998-2003 by Lutz Sammer
+//     (c) Copyright 1998-2003 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,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit.h,v 1.208 2003/08/24 18:48:03 n0body Exp $
+//     $Id: unit.h,v 1.209 2003/08/25 11:21:17 mr-russ Exp $
 
 #ifndef __UNIT_H__
 #define __UNIT_H__
@@ -433,8 +433,9 @@
 typedef struct _order_ {
     unsigned char      Action;         /// global action
     unsigned char      Flags;          /// Order flags (unused)
-    unsigned char      RangeX;         /// How near in X direction
-    unsigned char      RangeY;         /// How near in Y direction
+    unsigned int       RangeX;         /// How near in X direction
+    unsigned int       RangeY;         /// How near in Y direction
+    unsigned char      IsRect:1;       /// For goal as a square, not circle
 
     Unit*              Goal;           /// goal of the order (if any)
     int                        X;              /// or X tile coordinate of 
destination
@@ -946,8 +947,10 @@
 extern Unit* UnitOnMapTile(int tx,int ty);
     /// Return repairable unit on that map tile
 extern Unit* RepairableOnMapTile(int tx,int ty);
-    /// Return possible attack target on that map tile
-extern Unit* TargetOnMapTile(const Unit* unit,int tx,int ty);
+    /// Return possible attack target on a tile
+extern Unit* TargetOnMapTile(const Unit* soruce, int tx, int ty);
+    /// Return possible attack target on that map area
+extern Unit* TargetOnMap(const Unit* unit,int x1,int y1,int x2,int y2);
     /// Return transporter unit on that map tile
 extern Unit* TransporterOnMapTile(int tx,int ty);
 
Index: stratagus/src/map/ccl_map.c
diff -u stratagus/src/map/ccl_map.c:1.35 stratagus/src/map/ccl_map.c:1.36
--- stratagus/src/map/ccl_map.c:1.35    Sat Aug  2 09:34:25 2003
+++ stratagus/src/map/ccl_map.c Mon Aug 25 07:21:18 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_map.c,v 1.35 2003/08/02 13:34:25 grumbel Exp $
+//     $Id: ccl_map.c,v 1.36 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -296,7 +296,7 @@
     target->Y = gh_scm2int(y);
     target->TTL=GameCycle+gh_scm2int(cycle);
     target->CurrentSightRange=gh_scm2int(radius);
-    
MapMarkSight(target->Player,gh_scm2int(x),gh_scm2int(y),target->CurrentSightRange);
+    MapMarkUnitSight(target);
     return SCM_UNSPECIFIED;
 }
 /**
Index: stratagus/src/map/map_fog.c
diff -u stratagus/src/map/map_fog.c:1.96 stratagus/src/map/map_fog.c:1.97
--- stratagus/src/map/map_fog.c:1.96    Thu Jul 24 15:27:33 2003
+++ stratagus/src/map/map_fog.c Mon Aug 25 07:21:18 2003
@@ -1,4 +1,4 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: map_fog.c,v 1.96 2003/07/24 19:27:33 n0body Exp $
+//     $Id: map_fog.c,v 1.97 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -118,23 +118,41 @@
      0,11,10, 2,  13, 6, 0, 3,  12, 0, 4, 1,  8, 9, 7, 0,
 };
 
-/**
-**     Pythagorus table tree for use in fow calculations
+/*
+global const unsigned char VisionTable[][3] = {
+      {2,0,0}, {1,1,1},
+      {3,0,0}, {1,1,1}, {1,1,0}, {1,0,1},
+      {4,0,0}, {1,1,1}, {1,1,0}, {1,1,1}, {1,0,1},
+      {5,0,0}, {1,1,1}, {2,1,0}, {1,0,1}, {1,1,0}, {2,0,1},
+      {6,0,0}, {1,1,1}, {2,1,0}, {2,1,1}, {2,0,1},
+      {7,0,0}, {1,1,1}, {2,1,0}, {3,1,1}, {2,0,1},
+      {8,0,0}, {1,1,1}, {2,1,0}, {1,1,1}, {1,1,0}, {1,0,1}, {1,1,0}, 
{1,0,1},{1,1,1},{2,0,1},
+      {9,0,0}, {1,1,1}, {3,1,0}, {1,0,1}, {1,1,0}, {2,1,1}, {1,0,1}, {1,1,0}, 
{3,0,1},
+      {10,0,0}, {1,1,1}, {3,1,0}, {1,1,1}, {1,1,0}, {1,0,1}, {1,1,0}, 
{1,0,1},{1,1,0}, {1,0,1},{1,1,1},{3,0,1},
+      {11,0,0}, {1,1,1}, 
{3,1,0},{1,1,1},{1,1,0},{3,1,1},{1,0,1},{1,1,1},{3,0,1},
+      {12,0,0}
+    };
+local const int VisionLookup[6] = { 0,0,2,6,11,17 };
+
+global const unsigned char VisionTable[][3] = {
+       {1,0,0}, {1,1,0},
+       {2,0,0}, {2,1,0}, {1,0,1},
+       {3,0,0}, {3,1,0}, {2,0,1},
+       {4,0,0}, {4,1,0}, {3,0,1},
+       {5,0,0}, {5,1,0}, {4,0,1},
+       {6,0,0}, {6,1,0}, {5,0,1},
+       {7,0,0}, {7,1,0}, {6,0,1},
+       {8,0,0}, {8,1,0}, {7,0,1},
+       {9,0,0}, {9,1,0}, {8,0,1},
+       {10,0,0}, {10,1,0}, {9,0,1},
+       {11,0,0}, {11,1,0}, {10,0,1},
+       {12,0,0}
+       };
+
+local const int VisionLookup[14] = { 0,0,3,6,9,12,15,18,21,24,27,30,33,36 };
 */
-local const int PythagTree[13][13] = {
-    {   0,   1,   4,   9,  16,  25,  36,  49,  64,  81, 100, 121, 144},
-    {   1,   2,   5,  10,  17,  26,  37,  50,  65,  82, 101, 122, 145},
-    {   4,   5,   8,  13,  20,  29,  40,  53,  68,  85, 104, 125, 148},
-    {   9,  10,  13,  18,  25,  34,  45,  58,  73,  90, 109, 130, 153},
-    {  16,  17,  20,  25,  32,  41,  52,  65,  80,  97, 116, 137, 160},
-    {  25,  26,  29,  34,  41,  50,  61,  74,  89, 106, 125, 146, 169},
-    {  36,  37,  40,  45,  52,  61,  72,  85, 100, 117, 136, 157, 180},
-    {  49,  50,  53,  58,  65,  74,  85,  98, 113, 130, 149, 170, 193},
-    {  64,  65,  68,  73,  80,  89, 100, 113, 128, 145, 164, 185, 208},
-    {  81,  82,  85,  90,  97, 106, 117, 130, 145, 162, 181, 202, 225},
-    { 100, 101, 104, 109, 116, 125, 136, 149, 164, 181, 200, 221, 244},
-    { 121, 122, 125, 130, 137, 146, 157, 170, 185, 202, 221, 242, 265},
-    { 144, 145, 148, 153, 160, 169, 180, 193, 208, 225, 244, 265, 288}};
+global unsigned char *VisionTable[3];
+global int *VisionLookup;
 /**
 **     Draw unexplored area function pointer. (display and video mode independ)
 */
@@ -173,21 +191,22 @@
 {
     int i;
     int visiblecount;
-    int x;
-    int y;
     int range;
+    int mapdistance;
     Unit* unit;
 
     visiblecount=0;
-    // FIXME: Speedup can be done by only selecting unit possibly in range
     for( i=0; i<player->TotalNumUnits; ++i ) {
        unit=player->Units[i];
-       range=(unit->CurrentSightRange+1)*(unit->CurrentSightRange+1);
-       x=unit->X+unit->Type->TileWidth/2;
-       y=unit->Y+unit->Type->TileHeight/2;
-       if( PythagTree[abs(x-tx)][abs(y-ty)]<=range ) {
+       range=unit->CurrentSightRange;
+       mapdistance=MapDistanceToUnit(tx,ty,unit);
+       if( mapdistance <= range) {
            ++visiblecount;
        }
+       if( (tx >= unit->X && tx < unit->X+unit->Type->TileWidth && mapdistance 
== range+1) ||
+           (ty >= unit->Y && ty < unit->Y+unit->Type->TileHeight && 
mapdistance == range+1)) {
+           --visiblecount;
+       }
        if( visiblecount >= 255 ) {
            return 255;
        }
@@ -231,266 +250,189 @@
 }
 
 /**
-**     Mark the sight of unit. (Explore and make visible.)
+**     Mark a tile's sight. (Explore and make visible.)
 **
 **     @param player   Player to mark sight.
-**     @param tx       X center position.
-**     @param ty       Y center position.
-**     @param range    Radius to mark.
+**     @param x        X tile to mark.
+**     @param y        Y tile to mark.
+**     @param v        Pointer to visible value.
 */
-global void MapMarkSight(const Player* player,int tx,int ty,int range)
+global void MapMarkTileSight(const Player* player, int x, int y, unsigned char 
*v)
 {
-    int i;
-    int x;
-    int y;
-    int height;
-    int width;
-    int v;
-    int p;
-    int w;
-    int h;
-    Unit** corpses;
     Unit* unit;
     Unit* remove;
+    Unit** corpses;
+    int w;
+    int h;
 
-    // Mark as seen
-    if( !range ) {                     // zero sight range is zero sight range
-       DebugLevel0Fn("Zero sight range\n");
-       return;
-    }
-
-    x=tx-range;
-    y=ty-range;
-    width=height=range+range;
-
-    // Clipping
-    if( y<0 ) {
-       height+=y;
-       y=0;
-    }
-    if( x<0 ) {
-       width+=x;
-       x=0;
-    }
-    if( y+height>=TheMap.Height ) {
-       height=TheMap.Height-y-1;
-    }
-    if( x+width>=TheMap.Width ) {
-       width=TheMap.Width-x-1;
+    switch( *v ) {
+    case 0:            // Unexplored
+    case 1:            // Unseen
+    // FIXME: mark for screen update
+       *v=2;
+       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);
+               }
+           }
+        }
+       if( IsTileVisible(ThisPlayer,x,y) > 1) {
+           MapMarkSeenTile(x,y);
+           UnitsMarkSeen(x,y);
+       }
+
+       break;
+    case 255:          // Overflow
+       DebugLevel0Fn("Visible overflow (Player): %d\n" _C_ player->Player);
+       break;
+
+    default:           // seen -> seen
+       *v=*v+1;
+       break;
     }
+}
 
-    p=player->Player;
-    ++range;
-    range = range*range;
-    // FIXME: Can be speed optimized, no * += ...
-    while( height-->=0 ) {
-       for( i=x; i<=x+width; ++i ) {
-           if( PythagTree[abs(i-tx)][abs(y-ty)]<=range ) {
-               v=TheMap.Fields[i+y*TheMap.Width].Visible[p];
-               switch( v ) {
-                   case 0:             // Unexplored
-                   case 1:             // Unseen
-                       // FIXME: mark for screen update
-                       TheMap.Fields[i+y*TheMap.Width].Visible[p]=2;
-                       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( i >= unit->X && y >= unit->Y
-                                       && i < 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);
-                               }
-                           }
-                        }
-                       if( IsTileVisible(ThisPlayer,i,y) > 1) {
-                           MapMarkSeenTile(i,y);
-                           UnitsMarkSeen(i,y);
-                       }
-                        
-                       break;
-                   case 255:           // Overflow
-                       DebugLevel0Fn("Visible overflow (Player): %d\n" _C_ p);
-                       break;
-
-                   default:            // seen -> seen
-                       TheMap.Fields[i+y*TheMap.Width].Visible[p]=v+1;
-                       break;
-               }
+global void MapUnmarkTileSight(const Player* player,int x,int y,unsigned char 
*v)
+{
+    switch( *v ) {
+       case 255:
+           // FIXME: (mr-russ) Lookupsight is broken :(
+           DebugCheck( 1 );
+           *v = LookupSight(player,x,y);
+           DebugCheck( *v < 254 );
+           break;
+       case 0:         // Unexplored
+       case 1:
+           // We are at minimum, don't do anything shouldn't happen.
+           DebugCheck( 1 );
+           break;
+       case 2:
+           // Check visible Tile, then deduct...
+           if( IsTileVisible(ThisPlayer,x,y) > 1) {
+               MapMarkSeenTile(x,y);
+               UnitsMarkSeen(x,y);
            }
-       }
-       ++y;
+       default:                // seen -> seen
+           *v=*v-1;
+           break;
     }
 }
 
 /**
-**     Unmark the sight of unit. (Dies, Boards a unit.)
+**     Mark the sight of unit. (Explore and make visible.)
 **
-**     @param player   Player to mark sight.
-**     @param tx       X center position.
-**     @param ty       Y center position.
-**     @param range    Radius to unmark.
+**     @param player   player to mark the sight for (not unit owner)
+**     @param x        x location to mark
+**     @param y        y location to mark
+**
+**     @param range    Radius to mark.
+**     @param marker   Function to mark or unmark sight
 */
-global void MapUnmarkSight(const Player* player,int tx,int ty,int range)
+global void MapSight(const Player* player, int x, int y, int w, int h, int 
range, void (*marker)(const Player*,int,int,unsigned char*))
 {
-    int i;
-    int x;
-    int y;
-    int height;
-    int width;
-    int v;
+    int mx;
+    int my;
+    int cx[4];
+    int cy[4];
+    int steps;
+    int cycle;
     int p;
 
-    // zero sight range is zero sight range
-    if( !range ) {
+    // Mark as seen
+    if( !range ) {                     // zero sight range is zero sight range
        DebugLevel0Fn("Zero sight range\n");
        return;
     }
 
-    x=tx-range;
-    y=ty-range;
-    width=height=range+range;
-
-    // Clipping
-    if( y<0 ) {
-       height+=y;
-       y=0;
-    }
-    if( x<0 ) {
-       width+=x;
-       x=0;
-    }
-    if( y+height>=TheMap.Height ) {
-       height=TheMap.Height-y-1;
-    }
-    if( x+width>=TheMap.Width ) {
-       width=TheMap.Width-x-1;
-    }
-
     p=player->Player;
-    ++range;
-    range=range*range;
-    while( height-->=0 ) {
-       for( i=x; i<=x+width; ++i ) {
-           if( PythagTree[abs(i-tx)][abs(y-ty)]<=range ) {
-               v=TheMap.Fields[i+y*TheMap.Width].Visible[p];
-               switch( v ) {
-                   case 255:
-                       TheMap.Fields[i+y*TheMap.Width].Visible[p] =
-                           LookupSight(player,i,y);
-                       DebugCheck( TheMap.Fields[i+y*TheMap.Width].Visible[p] 
< 254 );
-                   case 0:             // Unexplored
-                   case 1:
-                       // We are at minimum, don't do anything shouldn't 
happen.
-                       //DebugCheck( 1 );
-                       break;
-                   case 2:
-                       // Check visible Tile, then deduct...
-                       if( IsTileVisible(ThisPlayer,i,y) > 1) {
-                           MapMarkSeenTile(i,y);
-                           UnitsMarkSeen(i,y);
-                       }
-                   default:            // seen -> seen
-                       TheMap.Fields[i+y*TheMap.Width].Visible[p]=v-1;
-                       break;
-               }
+
+    // Mark Horizontal sight for unit
+    for(mx=x-range; mx < x+range+w; mx++) {
+        for(my=y; my < y+h; my++) {
+           if( mx >= 0 && mx < TheMap.Width ) {
+               
marker(player,mx,my,&TheMap.Fields[mx+my*TheMap.Width].Visible[p]);
            }
        }
-       ++y;
     }
-}
-
-    
-/**
-**     Mark the new sight of unit. (Explore and make visible.)
-**
-**     @param player   Player to mark sight.
-**     @param tx       X center position.
-**     @param ty       Y center position.
-**     @param range    Radius to mark.
-**     @param dx       Delta in tiles in X direction.
-**     @param dy       Delta in tiles in Y direction.
-*/
-global void MapMarkNewSight(const Player* player,int tx,int ty,int range
-       ,int dx,int dy)
-{
-    /// It's faster to mark then unmark.
-    MapMarkSight(player,tx,ty,range);
-    MapUnmarkSight(player,tx-dx,ty-dy,range);
-}
-
-/**
-**     Update the fog of war, for the view point. Called from UpdateDisplay.
-**
-**     @param x        Viewpoint X map tile position
-**     @param y        Viewpoint Y map tile position
-**
-**     @todo   FIXME: should be handled complete in UpdateDisplay.
-*/
-global void MapUpdateFogOfWar(int x,int y)
-{
-    x=y=0;
-#if 0
-    Unit* unit;
-    Unit* table[UnitMax];
-    char *redraw_row;
-    char *redraw_tile;
-    int n;
-    int i;
-    int sx,sy,ex,ey,dx,dy;
-    int vis;
-    int last;
-
-    // Tiles not visible last frame but are this frame must be redrawn.
-    redraw_row=MustRedrawRow;
-    redraw_tile=MustRedrawTile;
-
-    ex=TheUI.MapEndX;
-    sy=y*TheMap.Width;
-    dy=TheUI.MapY;
-    ey=TheUI.MapEndY;
-
-    while( dy<=ey ) {
-       sx=x+sy;
-       dx=TheUI.MapX;
-       while( dx<=ex ) {
-#ifdef NEW_MAPDRAW
-           *redraw_row=NEW_MAPDRAW;
-           *redraw_tile=NEW_MAPDRAW;
-#else
-           *redraw_row=*redraw_tile=1;
-#endif
 
-           ++redraw_tile;
-           ++sx;
-           dx+=TileSizeX;
+    // Mark vertical sight for unit (don't remark self) (above unit)
+    for(my=y-range; my < y; my++) {
+        for(mx=x; mx < x+w; mx++) {
+           if( my >= 0 && my < TheMap.Width ) {
+               
marker(player,mx,my,&TheMap.Fields[mx+my*TheMap.Width].Visible[p]);
+           }
        }
-       ++redraw_row;
-       sy+=TheMap.Width;
-       dy+=TileSizeY;
     }
 
-    // Buildings under fog of war must be redrawn
-    n=SelectUnits(MapX,MapY,MapX+MapWidth,MapY+MapHeight,table);
+    // Mark vertical sight for unit (don't remark self) (below unit)
+    for(my=y+h; my < y+range+h; my++) {
+        for(mx=x; mx < x+w; mx++) {
+       if( my >= 0 && my < TheMap.Width ) {
+           marker(player,mx,my,&TheMap.Fields[mx+my*TheMap.Width].Visible[p]);
+       }
+       }
+    }
 
-    for( i=0; i<n; ++i ) {
-       unit=table[i];
-       if( unit->Type->Building && !unit->Removed
-               && UnitVisibleOnScreen(unit) ) {
-           CheckUnitToBeDrawn(unit);
+    // Now the cross has been marked, need to use loop to mark in circle
+    steps=0;
+    while(VisionTable[0][steps] <= range) {
+       // 0 - Top right Quadrant
+       cx[0] = x+w-1;
+       cy[0] = y-VisionTable[0][steps];
+       // 1 - Top left Quadrant
+       cx[1] = x;
+       cy[1] = y-VisionTable[0][steps];
+       // 2 - Bottom Left Quadrant
+       cx[2] = x;
+       cy[2] = y+VisionTable[0][steps]+h-1;
+       // 3 - Bottom Right Quadrant
+       cx[3] = x+w-1;
+       cy[3] = y+VisionTable[0][steps]+h-1;
+       // loop for steps
+       steps++;        // Increment past info pointer
+       while(VisionTable[1][steps] != 0 || VisionTable[2][steps] != 0 ) {
+           // Loop through for repeat cycle
+           cycle=0;
+           while( cycle++ < VisionTable[0][steps] ) {
+               cx[0]+=VisionTable[1][steps];
+               cy[0]+=VisionTable[2][steps];
+               cx[1]-=VisionTable[1][steps];
+               cy[1]+=VisionTable[2][steps];
+               cx[2]-=VisionTable[1][steps];
+               cy[2]-=VisionTable[2][steps];
+               cx[3]+=VisionTable[1][steps];
+               cy[3]-=VisionTable[2][steps];
+               if( cx[0] < TheMap.Width && cy[0] >= 0) {
+                   
marker(player,cx[0],cy[0],&TheMap.Fields[cx[0]+cy[0]*TheMap.Width].Visible[p]);
+               }
+               if( cx[1] >= 0 && cy[1] < TheMap.Height) {
+                   
marker(player,cx[1],cy[1],&TheMap.Fields[cx[1]+cy[1]*TheMap.Width].Visible[p]);
+               }
+               if( cx[2] >= 0 && cy[2] >= 0 ) {
+                   
marker(player,cx[2],cy[2],&TheMap.Fields[cx[2]+cy[2]*TheMap.Width].Visible[p]);
+               }
+               if( cx[3] < TheMap.Width && cy[3] < TheMap.Height ) {
+                   
marker(player,cx[3],cy[3],&TheMap.Fields[cx[3]+cy[3]*TheMap.Width].Visible[p]);
+               }
+           }
+           steps++;
        }
     }
-#endif
 }
 
 /**
@@ -2511,6 +2453,11 @@
     //
     // Which Tile to draw for fog
     //
+    // Investigate tiles around current tile
+    // 1 2 3
+    // 4 * 5
+    // 6 7 8
+
     if( sy ) {
        if( sx!=sy ) {
            if( !IsMapFieldExplored(ThisPlayer,x-1,y-1) ) {
@@ -2750,6 +2697,14 @@
 */
 global void InitMapFogOfWar(void)
 {
+    int maxsize;
+    int *visionlist;
+    int sizex;
+    int sizey;
+    int maxsearchsize;
+    int i;
+    int VisionTablePosition;
+
 #ifdef USE_OPENGL
     VideoDrawFog=VideoDrawFogAlphaOpenGL;
     VideoDrawOnlyFog=VideoDrawOnlyFogAlphaOpenGL;
@@ -3025,6 +2980,61 @@
        }
     }
 #endif
+
+       visionlist=malloc(MaxMapWidth*MaxMapWidth*sizeof(int));
+       //*2 as diagonal distance is longer
+
+       maxsize = MaxMapWidth;
+    // Fill in table of map size
+    for(sizex=0; sizex < maxsize; sizex++) {
+       for(sizey=0; sizey < maxsize; sizey++) {
+           visionlist[sizey*maxsize+sizex]=isqrt(sizex*sizex+sizey*sizey);
+       }
+    }
+    // Find maximum distance in corner of map.
+    maxsearchsize=isqrt(maxsize/2);
+    // 1 for 0 and one for end redundant point
+    VisionLookup=malloc((maxsearchsize+2)*sizeof(int));
+
+    // Initialize Visiontable to large size, can't be more entries than tiles.
+    VisionTable[0]=malloc(maxsize*maxsize*sizeof(int));
+    VisionTable[1]=malloc(maxsize*maxsize*sizeof(int));
+    VisionTable[2]=malloc(maxsize*maxsize*sizeof(int));
+
+    // Mark 1, It's a special case
+    // Only Horizontal is marked
+    VisionTable[0][0]=1;
+    VisionTable[1][0]=0;
+    VisionTable[2][0]=0;
+    VisionTable[0][1]=1;
+    VisionTable[1][1]=1;
+    VisionTable[2][1]=0;
+
+    // Mark VisionLookup
+    VisionLookup[0]=0;
+    VisionLookup[1]=0;
+    i=2;
+    VisionTablePosition=1;
+    while( i <= maxsearchsize ) {
+       VisionTablePosition++;
+       VisionLookup[i]=VisionTablePosition;
+       // Setup Vision Start
+        VisionTable[0][VisionTablePosition]=i;
+       VisionTable[1][VisionTablePosition]=0;
+       VisionTable[2][VisionTablePosition]=0;
+       // Do Horizontal
+       VisionTablePosition++;
+       VisionTable[0][VisionTablePosition]=i;
+       VisionTable[1][VisionTablePosition]=1;
+       VisionTable[2][VisionTablePosition]=0;
+       // Do Vertical
+       VisionTablePosition++;
+       VisionTable[0][VisionTablePosition]=i-1;
+       VisionTable[1][VisionTablePosition]=0;
+       VisionTable[2][VisionTablePosition]=1;
+       i++;
+    }
+    free(visionlist);
 }
 
 /**
@@ -3035,6 +3045,23 @@
     if( FogOfWarAlphaTable ) {
        free(FogOfWarAlphaTable);
        FogOfWarAlphaTable=NULL;
+    }
+    // Free Vision Data
+    if( VisionTable[0] ) {
+       free(VisionTable[0]);
+       VisionTable[0]=NULL;
+    }
+    if( VisionTable[1] ) {
+       free(VisionTable[1]);
+       VisionTable[1]=NULL;
+    }
+    if( VisionTable[2] ) {
+       free(VisionTable[2]);
+       VisionTable[2]=NULL;
+    }
+    if( VisionLookup ) {
+       free(VisionLookup);
+       VisionLookup=NULL;
     }
 }
 
Index: stratagus/src/missile/missile.c
diff -u stratagus/src/missile/missile.c:1.76 
stratagus/src/missile/missile.c:1.77
--- stratagus/src/missile/missile.c:1.76        Sun Aug 17 11:57:07 2003
+++ stratagus/src/missile/missile.c     Mon Aug 25 07:21:18 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: missile.c,v 1.76 2003/08/17 15:57:07 n0body Exp $
+//     $Id: missile.c,v 1.77 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -531,14 +531,15 @@
     if( goal && RevealAttacker ) {     // attacking units are seen
        Unit* target;
        // FIXME: Don't use UnitTypeByIdent during runtime.
-       target = MakeUnit(UnitTypeByIdent("unit-reveal-attacker"), 
unit->Player);
+       target = MakeUnit(UnitTypeByIdent("unit-reveal-attacker"), 
goal->Player);
        target->Orders[0].Action = UnitActionStill;
        target->HP = 0;
        target->X = unit->X;
        target->Y = unit->Y;
        target->TTL=GameCycle+CYCLES_PER_SECOND+CYCLES_PER_SECOND/2;
        target->CurrentSightRange=target->Stats->SightRange;
-       MapMarkSight(target->Player,unit->X,unit->Y,target->CurrentSightRange);
+       // Little hack for the way the macro works :)
+       MapMarkUnitOnBoardSight(goal,unit);
        CheckUnitToBeDrawn(target);
     }
 
@@ -1524,7 +1525,7 @@
     int i;
 
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: missile-types $Id: missile.c,v 1.76 2003/08/17 
15:57:07 n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: missile-types $Id: missile.c,v 1.77 2003/08/25 
11:21:18 mr-russ Exp $\n\n");
 
     //
     // Original number to internal missile-type name.
@@ -1619,7 +1620,7 @@
     Missile* const* missiles;
 
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: missiles $Id: missile.c,v 1.76 2003/08/17 
15:57:07 n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: missiles $Id: missile.c,v 1.77 2003/08/25 
11:21:18 mr-russ Exp $\n\n");
 
     for( missiles=GlobalMissiles; *missiles; ++missiles ) {
        SaveMissile(*missiles,file);
Index: stratagus/src/pathfinder/astar.c
diff -u stratagus/src/pathfinder/astar.c:1.44 
stratagus/src/pathfinder/astar.c:1.45
--- stratagus/src/pathfinder/astar.c:1.44       Fri Jul 11 10:35:33 2003
+++ stratagus/src/pathfinder/astar.c    Mon Aug 25 07:21:18 2003
@@ -1,4 +1,4 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: astar.c,v 1.44 2003/07/11 14:35:33 n0body Exp $
+//     $Id: astar.c,v 1.45 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -126,11 +126,13 @@
 */
 global void FreeAStar(void)
 {
-    if( AStarMatrix ) {
-       free(AStarMatrix);
-       AStarMatrix=NULL;
-       free(CloseSet);
-       free(OpenSet);
+    if( AStarOn ) {
+       if( AStarMatrix ) {
+           free(AStarMatrix);
+           AStarMatrix=NULL;
+           free(CloseSet);
+           free(OpenSet);
+       }
     }
 }
 
@@ -164,10 +166,13 @@
 **     Returns the position of this node in the open node set (always 0 in the
 **     current heap based implementation)
 */
+#define AStarFindMinimum() 0
+#if 0
 local int AStarFindMinimum()
 {
     return 0;
 }
+#endif
 
 /**
 **     Remove the minimum from the open node set (and update the heap)
@@ -314,9 +319,11 @@
            if( goal->Moving ) {
                // moving unit are crossable
                cost+=AStarMovingUnitCrossingCost;
+           } else {
+               // for non moving unit
+               cost+=AStarFixedUnitCrossingCost;
+               return -1;
            }
-           // for non moving unit
-           cost+=AStarFixedUnitCrossingCost;
        }
     }
     // empty tile
@@ -328,20 +335,166 @@
 }
 
 /**
+**     MarkAStarGoal
+*/
+local int AStarMarkGoal(Unit* unit, int gx, int gy, int gw, int gh, int range, 
int mask, int* num_in_close)
+{
+    int cx[4]; 
+    int cy[4];
+    int steps;
+    int cycle;
+    int x;
+    int y;
+    int goal_reachable;
+    int quad;
+    int eo;
+    int filler;
+
+    goal_reachable=0;
+
+    if( range == 0 && gw == 0 && gh == 0 ) {
+       if( CostMoveTo(unit,gx,gy,mask,AStarFixedUnitCrossingCost)>=0 ) {
+           AStarMatrix[gx+gy*TheMap.Width].InGoal=1;
+           return 1;
+       } else {
+           return 0;
+       }
+    }
+
+    // Mark top, bottom, left, right
+
+    // Mark Top and Bottom of Goal
+    for(x=gx;x<=gx+gw;x++) {
+       if( x >= 0 && x < TheMap.Width) {
+           if( gy-range >= 0 && 
CostMoveTo(unit,x,gy-range,mask,AStarFixedUnitCrossingCost)>=0 ) {
+               AStarMatrix[(gy-range)*TheMap.Width+x].InGoal=1;
+               goal_reachable=1;
+               if( *num_in_close<Threshold ) {
+                   CloseSet[(*num_in_close)++]=(gy-range)*TheMap.Width+x;
+               }                                                   
+           }
+           if( gy+range+gh < TheMap.Height && 
CostMoveTo(unit,x,gy+range,mask,AStarFixedUnitCrossingCost)>=0 ) {
+               AStarMatrix[(gy+range+gh)*TheMap.Width+x].InGoal=1;
+               if( *num_in_close<Threshold ) {
+                   CloseSet[(*num_in_close)++]=(gy+range+gh)*TheMap.Width+x;
+               }
+               goal_reachable=1;
+           }
+       }
+    }
+
+    for(y=gy;y<=gy+gh;y++) {
+       if( y >= 0 && y < TheMap.Height) {
+           if( gx-range >=0 && 
CostMoveTo(unit,gx-range,y,mask,AStarFixedUnitCrossingCost)>=0 ) {
+               AStarMatrix[y*TheMap.Width+gx-range].InGoal=1;
+               if( *num_in_close<Threshold ) {
+                   CloseSet[(*num_in_close)++]=y*TheMap.Width+gx-range;
+               }
+               goal_reachable=1;
+           }
+           if( gx+gw+range < TheMap.Width && 
CostMoveTo(unit,gx+gw+range,y,mask,AStarFixedUnitCrossingCost)>=0 ) {
+               AStarMatrix[y*TheMap.Width+gx+gw+range].InGoal=1;
+               if( *num_in_close<Threshold ) {
+                   CloseSet[(*num_in_close)++]=y*TheMap.Width+gx+gw+range;
+               }
+               goal_reachable=1;
+           }
+       }
+    }
+
+    // Mark Goal Border in Matrix
+
+    // Mark Edges of goal
+
+    steps=0;
+    // Find place to start. (for marking curves)
+    while(VisionTable[0][steps] != range && VisionTable[1][steps] == 0 && 
VisionTable[2][steps] == 0) {
+       steps++;
+    }
+    // 0 - Top right Quadrant
+    cx[0] = gx+gw;
+    cy[0] = gy-VisionTable[0][steps];
+    // 1 - Top left Quadrant
+    cx[1] = gx;
+    cy[1] = gy-VisionTable[0][steps];
+    // 2 - Bottom Left Quadrant
+    cx[2] = gx;
+    cy[2] = gy+VisionTable[0][steps]+gh;
+    // 3 - Bottom Right Quadrant
+    cx[3] = gx+gw;
+    cy[3] = gy+VisionTable[0][steps]+gh;
+
+    steps++;  // Move past blank marker
+    while(VisionTable[1][steps] != 0 || VisionTable[2][steps] != 0 ) {
+       // Loop through for repeat cycle
+       cycle=0;
+       while( cycle++ < VisionTable[0][steps] ) {
+           // If we travelled on an angle, mark down as well.
+           if( VisionTable[1][steps] == VisionTable[2][steps] ) {
+               // do down
+               quad = 0;
+               while( quad < 4 ) {
+                   if( quad < 2 ) {
+                       filler=1;
+                   } else {
+                       filler=-1;
+                   }
+                   if( cx[quad] >= 0 && cx[quad] < TheMap.Width && 
cy[quad]+filler >= 0 && 
+                       cy[quad]+filler < TheMap.Height &&
+                       
CostMoveTo(unit,cx[quad],cy[quad]+filler,mask,AStarFixedUnitCrossingCost)>=0 ) {
+                       eo=(cy[quad]+filler)*TheMap.Width+cx[quad];
+                       AStarMatrix[eo].InGoal=1;
+                       if( *num_in_close<Threshold ) {
+                           CloseSet[(*num_in_close)++]=eo;
+                       }
+                       goal_reachable=1;
+                   }
+                   quad++;
+               }
+           }
+               
+           cx[0]+=VisionTable[1][steps];
+           cy[0]+=VisionTable[2][steps];
+           cx[1]-=VisionTable[1][steps];
+           cy[1]+=VisionTable[2][steps];
+           cx[2]-=VisionTable[1][steps];
+           cy[2]-=VisionTable[2][steps];
+           cx[3]+=VisionTable[1][steps];
+           cy[3]-=VisionTable[2][steps];
+           
+           // Mark Actually Goal curve change
+           quad = 0;
+           while( quad < 4 ) {
+               if( cx[quad] >= 0 && cx[quad] < TheMap.Width && cy[quad] >= 0 &&
+                   cy[quad] < TheMap.Height &&
+                   
CostMoveTo(unit,cx[quad],cy[quad],mask,AStarFixedUnitCrossingCost)>=0 ) {
+                   eo=cy[quad]*TheMap.Width+cx[quad];
+                   AStarMatrix[eo].InGoal=1;
+                   if( *num_in_close<Threshold ) {
+                       CloseSet[(*num_in_close)++]=eo;
+                   }
+                   goal_reachable=1;
+               }
+               quad++;
+           }
+       }
+       steps++;
+    }
+    return goal_reachable;
+}
+/**
 **     Find path.
 */
-global int AStarFindPath(Unit* unit, int x1, int y1, int x2, int y2, char* 
path)
+global int AStarFindPath(Unit* unit, int gx, int gy, int gw, int gh, int 
range, char* path)
 {
     int i;
     int j;
     int o;
-    int x;
-    int y;
     int ex;
     int ey;
     int eo;
-    int gx;
-    int gy;
+    int x;
+    int y;
     int px;
     int py;
     int shortest;
@@ -351,77 +504,19 @@
     int path_length;
     int num_in_close;
     int mask;
-    int goal_reachable;
 
     DebugLevel3Fn("%d %d,%d->%d,%d\n" _C_
            UnitNumber(unit) _C_
-           unit->X _C_ unit->Y _C_ unit->Orders[0].X _C_ unit->Orders[0].Y);
+           unit->X _C_ unit->Y _C_ x _C_ y);
 
     OpenSetSize=0;
     num_in_close=0;
+    mask=UnitMovementMask(unit);
     x=unit->X;
     y=unit->Y;
-    mask=UnitMovementMask(unit);
-    goal_reachable=0;
-
-    // Let's first mark goal
-    gx=(x1+x2)/2;
-    gy=(y1+y2)/2;
-
-    if( y1<0 ) {
-       y1=0;
-    }
-    if( y2>=TheMap.Height ) {
-       y2=TheMap.Height-1;
-    }
-    if( x1<0 ) {
-       x1=0;
-    }
-    if( x2>=TheMap.Width ) {
-       x2=TheMap.Width-1;
-    }
 
-    // Mark Goal Border in Matrix
-    for( ey=y1; ey<=y2; ++ey ){
-       if( CostMoveTo(unit,x1,ey,mask,AStarFixedUnitCrossingCost)>=0 ) {
-           eo=ey*TheMap.Width+x1;
-           AStarMatrix[eo].InGoal=1;
-           if( num_in_close<Threshold ) {
-               CloseSet[num_in_close++]=eo;
-           }
-           goal_reachable=1;
-       }
-       if( CostMoveTo(unit,x2,ey,mask,AStarFixedUnitCrossingCost)>=0 ) {
-           eo=ey*TheMap.Width+x2;
-           AStarMatrix[eo].InGoal=1;
-           if( num_in_close<Threshold ) {
-               CloseSet[num_in_close++]=eo;
-           }
-           goal_reachable=1;
-       }
-    }
-    
-    for( ex=x1; ex<=x2; ++ex ){
-       if( CostMoveTo(unit,ex,y1,mask,AStarFixedUnitCrossingCost)>=0 ) {
-           eo=y1*TheMap.Width+ex;
-           AStarMatrix[eo].InGoal=1;
-           if( num_in_close<Threshold ) {
-               CloseSet[num_in_close++]=eo;
-           }
-           goal_reachable=1;
-       }
-       if( CostMoveTo(unit,x2,y2,mask,AStarFixedUnitCrossingCost)>=0 ) {
-           eo=y2*TheMap.Width+ex;
-           AStarMatrix[eo].InGoal=1;
-           if( num_in_close<Threshold ) {
-               CloseSet[num_in_close++]=eo;
-           }
-           goal_reachable=1;
-       }
-    }
-                                                                               
                
     // if goal is not directory reachable, punch out
-    if( !goal_reachable ) {
+    if( !AStarMarkGoal(unit, gx, gy, gw, gh, range, mask, &num_in_close) ) {
        AStarCleanUp(num_in_close);
        return PF_UNREACHABLE;
     }
@@ -441,6 +536,10 @@
     if( num_in_close<Threshold ) {
        CloseSet[num_in_close++]=OpenSet[0].O;
     }
+    if( AStarMatrix[eo].InGoal ) {
+       AStarCleanUp(num_in_close);
+       return PF_REACHED;
+    }
 
     counter=TheMap.Width*TheMap.Height;        
 
@@ -585,21 +684,21 @@
     }
 
     // Now we have the length, calculate the cached path.
-    while( ex!=x || ey!=y ) {
+    while( (ex!=x || ey!=y) && path!=NULL ) {
        eo=ey*TheMap.Width+ex;
        i=AStarMatrix[eo].Direction;
        DebugLevel3("%d %d %d %d (%d,%d)\n" _C_ x _C_ y _C_ ex _C_ ey _C_ 
Heading2X[i] _C_ Heading2Y[i]);
        ex-=Heading2X[i];
        ey-=Heading2Y[i];
        --gx;
-        if( gx<gy && path!=NULL) {
+        if( gx<gy ) {
            path[gy-gx-1]=i;
        } 
     }
 
     // let's clean up the matrix now
     AStarCleanUp(num_in_close);
-    DebugLevel3Fn("Tiles Visited: %d\n" _C_ 
(TheMap.Height*TheMap.Width)-counter);
+    DebugLevel1Fn("Tiles Visited: %d\n" _C_ 
(TheMap.Height*TheMap.Width)-counter);
     return path_length;
 }
 
@@ -615,33 +714,17 @@
 */
 global int NextPathElement(Unit* unit,int* pxd,int *pyd)
 {
-    static unsigned long last_game_cycle;
-    static int unreachable_counter;
     int result;
 
-
-    //
-    // Reduce the load, stop handling paths if too many UNREACHABLE results.
-    //
-    if( GameCycle!=last_game_cycle ) {
-       last_game_cycle=GameCycle;
-       unreachable_counter=3;
-    }
-    // FIXME: Can use the time left in frame.
-    if( !unreachable_counter ) {
-       DebugLevel0Fn("Done too much, can't do path for %d.\n" _C_ 
UnitNumber(unit));
-       return PF_WAIT;
-    }
-
     // Attempt to use path cache
     // FIXME: If there is a goal, it may have moved, ruining the cache
     *pxd=0;
     *pyd=0;
-    if( unit->Data.Move.Length<=0 ) {
+
+    if( unit->Data.Move.Length <= 0 ) {
         result=NewPath(unit);
         if( result==PF_UNREACHABLE ) {
            unit->Data.Move.Length=0;
-           // --unreachable_counter;
            return result;
        }
        if( result==PF_REACHED ) {
@@ -659,10 +742,13 @@
            
*pyd=Heading2Y[(int)unit->Data.Move.Path[(int)unit->Data.Move.Length-1]];
            if( 
!CheckedCanMoveToMask(*pxd+unit->X,*pyd+unit->Y,UnitMovementMask(unit)) ) {
                // There may be unit in the way, Astar may allow you to walk 
onto it.
-               return PF_UNREACHABLE;
+               result=PF_UNREACHABLE;
+               *pxd=0;
+               *pyd=0;
+           } else {
+               result=unit->Data.Move.Length;
+               unit->Data.Move.Length--;
            }
-           result=unit->Data.Move.Length;
-           unit->Data.Move.Length--;
        }
     }
     return result;
Index: stratagus/src/pathfinder/pathfinder.c
diff -u stratagus/src/pathfinder/pathfinder.c:1.52 
stratagus/src/pathfinder/pathfinder.c:1.53
--- stratagus/src/pathfinder/pathfinder.c:1.52  Sun Aug 24 14:48:03 2003
+++ stratagus/src/pathfinder/pathfinder.c       Mon Aug 25 07:21:18 2003
@@ -1,4 +1,4 @@
-//       _________ __                 __                               
+//       _________ __                 __
 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
@@ -28,7 +28,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: pathfinder.c,v 1.52 2003/08/24 18:48:03 n0body Exp $
+//     $Id: pathfinder.c,v 1.53 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -153,66 +153,123 @@
 /**
 **     Mark place in matrix.
 **
-**     @param x1       X1 position of target area
-**     @param y1       Y1 position of target area
-**     @param x2       X2 position of target area, range is [x1,x2]
-**     @param y2       Y2 position of target area, range is [y1,y2]
+**     @param gx       X position of target area
+**     @param gy       Y position of target area
+**     @param gw       Width of target area
+**     @param gh       Height of target area
+**     @param rnage    Range to search at
 **     @param matrix   Target area marked in matrix
 **
 **     @returns        depth, -1 unreachable
 */
-local int CheckPlaceInMatrix(int x1,int y1,int x2,int y2,unsigned int* matrix)
+local int CheckPlaceInMatrix(int gx,int gy,int gw,int gh,int range,unsigned 
int* matrix)
 {
+    int cx[4]; 
+    int cy[4];
+    int steps;
+    int cycle;
     int x;
     int y;
+    int quad;
+    int filler;
 
-    for( y=y1; y<=y2; y++) {
-       if( matrix[y*TheMap.Width+x1] ) {
-           return matrix[y*TheMap.Width+x1];
-       }
-       if( matrix[y*TheMap.Width+x2] ) {
-           return matrix[y*TheMap.Width+x2];
-       }
+    if( range == 0 && gw == 0 && gh == 0 ) {
+       return matrix[gx+gy*TheMap.Width];
     }
-    for( x=x1; x<=x2; ++x ) {
-       if( matrix[y1*TheMap.Width+x] ) {
-           return matrix[y1*TheMap.Width+x];
-       }
-       if( matrix[y2*TheMap.Width+x] ) {
-           return matrix[y2*TheMap.Width+x];
+
+    // Mark top, bottom, left, right
+
+    // Mark Top and Bottom of Goal
+    for(x=gx;x<=gx+gw;x++) {
+       if( x >= 0 && x < TheMap.Width) {
+           if( gy-range >= 0 && matrix[(gy-range)*TheMap.Width+x] ) {
+               return 1;
+           }
+           if( gy+range+gh < TheMap.Height && 
matrix[(gy+range+gh)*TheMap.Width+x] ) {
+               return 1;
+           }
        }
     }
-    return -1;
-}
 
-/**
-**     Make goal in matrix.
-**     'range' is how near we must reach.
-**
-**            rrrr
-**            rggr
-**            rggr
-**            rrrr
-**
-**     @param unit     Goal to reach.
-**     @param range    How near we must come.
-**     @param matrix   Target goal and area around is marked in matrix
-*/
-local int CheckGoalInMatrix(const Unit* unit,int range,unsigned int* matrix)
-{
-    int x;
-    int y;
-    int w;
-    int h;
-    UnitType* type;
+    for(y=gy;y<=gy+gh;y++) {
+       if( y >= 0 && y < TheMap.Height) {
+           if( gx-range >=0 && matrix[y*TheMap.Width+gx-range] ) {
+               return 1;
+           }
+           if( gx+gw+range < TheMap.Width && 
matrix[y*TheMap.Width+gx+gw+range] ) {
+               return 1;
+           }
+       }
+    }
 
-    x=unit->X-range;
-    y=unit->Y-range;
-    type=unit->Type;
-    w=type->TileWidth+range*2;
-    h=type->TileHeight+range*2;
+    // Mark Goal Border in Matrix
 
-    return CheckPlaceInMatrix(x,y,w,h,matrix);
+    // Mark Edges of goal
+   
+    steps=0;
+    // Find place to start. (for marking curves)
+    while(VisionTable[0][steps] != range && VisionTable[1][steps] == 0 && 
VisionTable[2][steps] == 0) {
+       steps++;
+    }
+    // 0 - Top right Quadrant
+    cx[0] = gx+gw;
+    cy[0] = gy-VisionTable[0][steps];
+    // 1 - Top left Quadrant
+    cx[1] = gx;
+    cy[1] = gy-VisionTable[0][steps];
+    // 2 - Bottom Left Quadrant
+    cx[2] = gx;
+    cy[2] = gy+VisionTable[0][steps]+gh;
+    // 3 - Bottom Right Quadrant
+    cx[3] = gx+gw;
+    cy[3] = gy+VisionTable[0][steps]+gh;
+    
+    steps++;  // Move past blank marker
+    while(VisionTable[1][steps] != 0 || VisionTable[2][steps] != 0 ) {
+       // Loop through for repeat cycle
+       cycle=0;
+       while( cycle++ < VisionTable[0][steps] ) {
+           // If we travelled on an angle, mark down as well.
+           if( VisionTable[1][steps] == VisionTable[2][steps] ) {
+               // do down
+               quad = 0;
+               while( quad < 4 ) {
+                   if( quad < 2 ) {
+                       filler=1;
+                   } else {
+                       filler=-1;
+                   }
+                   if( cx[quad] >= 0 && cx[quad] < TheMap.Width && 
cy[quad]+filler >= 0 && 
+                       cy[quad]+filler < TheMap.Height && 
matrix[(cy[quad]+filler)*TheMap.Width+cx[quad]] ) {
+                       return 1;
+                   }
+                   quad++;
+               }
+           }
+               
+           cx[0]+=VisionTable[1][steps];
+           cy[0]+=VisionTable[2][steps];
+           cx[1]-=VisionTable[1][steps];
+           cy[1]+=VisionTable[2][steps];
+           cx[2]-=VisionTable[1][steps];
+           cy[2]-=VisionTable[2][steps];
+           cx[3]+=VisionTable[1][steps];
+           cy[3]-=VisionTable[2][steps];
+           
+           // Mark Actually Goal curve change
+           quad = 0;
+           while( quad < 4 ) {
+               if( cx[quad] >= 0 && cx[quad] < TheMap.Width && cy[quad] >= 0 &&
+                   cy[quad] < TheMap.Height &&
+                   matrix[cy[quad]*TheMap.Width+cx[quad]] ) {
+                   return 1;
+               }
+               quad++;
+           }
+       }
+       steps++;
+    }
+    return 0;
 }
 
 /**
@@ -323,66 +380,24 @@
 **     @param src      Unit for the path.
 **     @param x        Map X tile position.
 **     @param y        Map Y tile position.
+**     @param w        Width of Goal
+**     @param h        Height of Goal
 **     @param range    Range to the tile.
 **
 **     @return         Distance to place.
 */
-global int PlaceReachable(Unit* src,int x,int y,int range)
+global int PlaceReachable(Unit* src,int x,int y,int w,int h,int range)
 {
     int depth;
-    int x1;
-    int x2;
-    int y1;
-    int y2;
-    int reachable;
     static unsigned long LastGameCycle;
     static unsigned mask;
 
     DebugLevel3Fn("%p -> %d,%d\n" _C_ src _C_ x _C_ y);
 
     //
-    // Find a path to the place.
-    //
-    x1 = x;
-    if( x1 < 0 ) {
-       x1 = 0;
-    }
-    x2 = x + range;
-    if( x2 > TheMap.Width ) {
-       x2 = TheMap.Width;
-    }
-    y1 = y;
-    if( y1 < 0 ) {
-       y1 = 0;
-    }
-    y2 = y+range;
-    if( y2 > TheMap.Height ) {
-       y2 = TheMap.Height;
-    }
-    // Find a reachable target, otherwise, don't search
-    reachable=0;
-    for( x=x1;x<=x2;x++ ) {
-       if( CheckedCanMoveToMask(x,y1,UnitMovementMask(src)) ||
-           CheckedCanMoveToMask(x,y2,UnitMovementMask(src)) ) {
-           reachable=1;
-       }
-    }
-    for( y=y1;y<y2;y++ ) {
-       if( CheckedCanMoveToMask(x1,y,UnitMovementMask(src)) ||
-           CheckedCanMoveToMask(x2,y,UnitMovementMask(src)) ) {
-           reachable=1;
-       }
-    }
-
-    if( !reachable ) {
-       DebugLevel3("Can't move to destination, goal unreachable\n");
-       return 0;
-    }
-
-    //
     //  Setup movement.
     //
-    if( src->Type->MovementMask != mask || LastGameCycle != GameCycle 
+    if( src->Type->MovementMask != mask || LastGameCycle != GameCycle
        || LocalMatrix[src->X+src->Y*TheMap.Width] == 0 ) {
        InitLocalMatrix();
        FillMatrix(src,LocalMatrix);
@@ -393,13 +408,13 @@
     //
     //  Find a path to the place.
     //
-    if( (depth=CheckPlaceInMatrix(x1,y1,x2,y2,LocalMatrix)) < 0 ) {
-       DebugLevel3("Can't move to destination, not route to goal\n");
+    if( (depth=CheckPlaceInMatrix(x,y,w,h,range,LocalMatrix)) < 0 ) {
+       DebugLevel1("Can't move to destination, not route to goal\n");
        return 0;
     }
 
     return depth;
-                                                               
+
 }
 
 /**
@@ -411,10 +426,9 @@
 **
 **     @return         Distance to place.
 */
-global int UnitReachable(Unit* src,const Unit* dst,int range)
+global int UnitReachable(Unit* src,Unit* dst,int range)
 {
     int depth;
-    int realrange;
 
     DebugLevel3Fn("%d(%d,%d,%s)->%d(%d,%d,%s)+%d "
        _C_ UnitNumber(src) _C_ src->X _C_ src->Y _C_ src->Type->Ident
@@ -423,8 +437,7 @@
     //
     // Find a path to the goal.
     //
-    realrange = range + range + 
max(dst->Type->TileHeight,dst->Type->TileWidth);
-    depth=PlaceReachable(src,dst->X-range,dst->Y-range,realrange);
+    
depth=PlaceReachable(src,dst->X,dst->Y,dst->Type->TileWidth,dst->Type->TileHeight,range);
     if( depth <= 0 ) {
        DebugLevel3("NO WAY\n");
        return 0;
@@ -887,6 +900,7 @@
 */
 global int NewPath(Unit* unit)
 {
+#if 0
     int x;
     int y;
     const Unit* goal;
@@ -897,10 +911,17 @@
     int y2;
     int rx;
     int ry;
-    int i;
     int reachable;
+#endif
+    int i;
+    int gw;
+    int gh;
+    int gx;
+    int gy;
+    int range;
     char* path;
 
+#if 0
     x=unit->X;
     y=unit->Y;
     goal=unit->Orders[0].Goal;
@@ -910,11 +931,6 @@
     ry=unit->Orders[0].RangeY;
     unit->Data.Move.Length=0;
 
-#if 0
-    DebugLevel1Fn("%d: -> %s %p | %dx%d-%dx%d\n"
-       _C_ UnitNumber(unit) _C_ unit->Data.Move.Fast ? "F" : "C"
-       _C_ goal _C_ x1 _C_ y1 _C_ x2 _C_ y2);
-#endif
     //
     // Check if goal is already reached.
     //
@@ -1003,14 +1019,41 @@
     //
     // Fall back to slow complex method.
     //
+#endif
+    if( unit->Orders[0].Goal ) {
+       gw=unit->Orders[0].Goal->Type->TileWidth-1;
+       gh=unit->Orders[0].Goal->Type->TileHeight-1;
+       gx=unit->Orders[0].Goal->X;
+       gy=unit->Orders[0].Goal->Y;
+       range=unit->Orders[0].RangeX;
+       DebugCheck( unit->Orders[0].RangeX != unit->Orders[0].RangeY );
+    } else {
+       // Take care of non square goals :)
+       // If goal is non square, range states a non-existant goal rather
+       // than a tile.
+       if( unit->Orders[0].IsRect ) {
+           gw = unit->Orders[0].RangeX;
+           gh = unit->Orders[0].RangeY;
+           range=0;
+       } else {
+           gw=0;
+           gh=0;
+           range=unit->Orders[0].RangeX;
+       }
+       gx=unit->Orders[0].X;
+       gy=unit->Orders[0].Y;
+    }
     path = unit->Data.Move.Path;
+    i=0;
     if( AStarOn ) {
-       i=AStarFindPath(unit,x1,y1,x2,y2,path);
+       i=AStarFindPath(unit,gx,gy,gw,gh,range,path);
        if( i == PF_FAILED ) {
            i = PF_UNREACHABLE;
        }
+#if 0  
     } else {
        i=ComplexNewPath(unit,x1,y1,x2,y2,path);
+#endif
     }
 
     // Update path if it was requested. Otherwise we may only want
Index: stratagus/src/unit/ccl_unit.c
diff -u stratagus/src/unit/ccl_unit.c:1.64 stratagus/src/unit/ccl_unit.c:1.65
--- stratagus/src/unit/ccl_unit.c:1.64  Sun Aug 24 14:48:04 2003
+++ stratagus/src/unit/ccl_unit.c       Mon Aug 25 07:21:18 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_unit.c,v 1.64 2003/08/24 18:48:04 n0body Exp $
+//     $Id: ccl_unit.c,v 1.65 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -46,6 +46,7 @@
 #include "spells.h"
 #include "pathfinder.h"
 #include "trigger.h"
+#include "actions.h"
 
 /*----------------------------------------------------------------------------
 --     Variables
@@ -557,11 +558,12 @@
        } else if( gh_eq_p(value,gh_symbol2scm("current-sight-range")) ) {
            unit->CurrentSightRange=gh_scm2int(gh_car(list));
            list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("host-tile")) ) {          
+       } else if( gh_eq_p(value,gh_symbol2scm("host-info")) ) {          
            value=gh_car(list);
            list=gh_cdr(list);
-           MapMarkSight(player,gh_scm2int(gh_car(value)),
-                               gh_scm2int(gh_cadr(value)),
+           
MapMarkSight(player,gh_scm2int(gh_car(value)),gh_scm2int(gh_cadr(value)),
+                               gh_scm2int(gh_cadr(gh_cdr(value))),
+                               gh_scm2int(gh_cadr(gh_cdr(gh_cdr(value)))),
                                unit->CurrentSightRange);   
        } else if( gh_eq_p(value,gh_symbol2scm("tile")) ) {
            value=gh_car(list);
@@ -722,11 +724,14 @@
            unit->OrderFlush=gh_scm2int(gh_car(list));
            list=gh_cdr(list);
        } else if( gh_eq_p(value,gh_symbol2scm("orders")) ) {
+           int hp;
            sublist=gh_car(list);
            list=gh_cdr(list);
            CclParseOrders(unit,sublist);
            // now we know unit's action so we can assign it to a player
+           hp = unit->HP;
            AssignUnitToPlayer (unit, player);
+           unit->HP = hp;
            if( unit->Orders[0].Action==UnitActionBuilded ) {
                // HACK: the building is not ready yet
                unit->Player->UnitTypesCount[type->Type]--;
@@ -738,12 +743,12 @@
            } else if( unit->Orders[0].Action==UnitActionDie ) {
                CorpseCacheInsert(unit);
            }
+#if 0
            if( unit->Orders[0].Action==UnitActionDie &&
                unit->Type->CorpseScript ) {
-               MapMarkSight(unit->Player,unit->X+unit->Type->TileWidth/2,
-                                       unit->Y+unit->Type->TileHeight/2,
-                                       unit->CurrentSightRange);
+               MapMarkUnitSight(unit);
            }
+#endif
        } else if( gh_eq_p(value,gh_symbol2scm("saved-order")) ) {
            value=gh_car(list);
            list=gh_cdr(list);
@@ -794,7 +799,7 @@
 
     //  Revealers are units that can see while removed
     if ( unit->Removed && unit->Type->Revealer ) {
-       MapMarkSight(unit->Player,unit->X,unit->Y,unit->CurrentSightRange);
+       MapMarkUnitSight(unit);
     }
     
     // Place on map
@@ -889,6 +894,78 @@
 }
 
 /**
+**     Order a unit
+**
+**     (order-unit player unit-type sloc dloc order)
+*/
+local SCM CclOrderUnit(SCM list)
+{
+    int plynr;
+    int x1;
+    int y1;
+    int x2;
+    int y2;
+    int dx1;
+    int dy1;
+    int dx2;
+    int dy2;
+    const UnitType* unittype;
+    Unit* table[UnitMax];
+    Unit* unit;
+    int an;
+    int j;
+    char* order;
+
+    plynr=TriggerGetPlayer(gh_car(list));
+    list=gh_cdr(list);
+    unittype=TriggerGetUnitType(gh_car(list));
+    list=gh_cdr(list);
+    x1=gh_scm2int(gh_car(gh_car(list)));
+    y1=gh_scm2int(gh_car(gh_cdr(gh_car(list))));
+    x2=gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_car(list)))));
+    y2=gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_cdr(gh_car(list))))));
+    list=gh_cdr(list);
+    dx1=gh_scm2int(gh_car(gh_car(list)));
+    dy1=gh_scm2int(gh_car(gh_cdr(gh_car(list))));
+    if( !gh_null_p(gh_cdr(gh_cdr(gh_car(list)))) ) {
+       dx2=gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_car(list)))));
+       dy2=gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_cdr(gh_car(list))))));
+    } else {
+       dx2=dx1;
+       dy2=dy1;
+    }
+    list=gh_cdr(list);
+    order=gh_scm2newstr(gh_car(list),NULL);
+
+    an=SelectUnits(x1,y1,x2+1,y2+1,table);
+    for( j=0; j<an; ++j ) {
+       unit=table[j];
+       if( unittype==ANY_UNIT
+               || (unittype==ALL_FOODUNITS && !unit->Type->Building)
+               || (unittype==ALL_BUILDINGS && unit->Type->Building)
+               || unittype==unit->Type ) {
+           if( plynr==-1 || plynr==unit->Player->Player ) {
+               if( !strcmp(order,"move") ) {
+                   CommandMove(unit,(dx1+dx2)/2,(dy1+dy2)/2,1);
+               } else if( !strcmp(order,"attack") ) {
+                   Unit* attack;
+
+                   attack=TargetOnMap(unit,dx1,dy1,dx2,dy2);
+                   CommandAttack(unit,(dx1+dx2)/2,(dy1+dy2)/2,attack,1);
+               } else if( !strcmp(order,"patrol") ) {
+                   CommandPatrolUnit(unit,(dx1+dx2)/2,(dy1+dy2)/2,1);
+               } else {
+                   errl("Unsupported order",gh_car(list));
+               }
+           }
+       }
+    }
+
+    free(order);
+    return SCM_UNSPECIFIED;
+}
+
+/**
 **     Kill a unit
 **
 **     @param type     Unit-type of the unit,
@@ -939,7 +1016,7 @@
 **
 **     @return         Returns the number of units killed.
 */
-local SCM CclKillUnitAt(SCM type,SCM player,SCM quantity,SCM loc1,SCM loc2)
+local SCM CclKillUnitAt(SCM type,SCM player,SCM quantity,SCM loc)
 {
     int plynr;
     int q;
@@ -957,10 +1034,10 @@
     plynr=TriggerGetPlayer(player);
     q=gh_scm2int(quantity);
     unittype=TriggerGetUnitType(type);
-    x1=gh_scm2int(gh_car(loc1));
-    y1=gh_scm2int(gh_car(gh_cdr(loc1)));
-    x2=gh_scm2int(gh_car(loc2));
-    y2=gh_scm2int(gh_car(gh_cdr(loc2)));
+    x1=gh_scm2int(gh_car(loc));
+    y1=gh_scm2int(gh_car(gh_cdr(loc)));
+    x2=gh_scm2int(gh_car(gh_cdr(gh_cdr(loc))));
+    y2=gh_scm2int(gh_car(gh_cdr(gh_cdr(gh_cdr(loc)))));
 
     an=SelectUnits(x1,y1,x2+1,y2+1,table);
     for( j=s=0; j<an && s<q; ++j ) {
@@ -1077,8 +1154,9 @@
     gh_new_procedure2_0("make-unit",CclMakeUnit);
     gh_new_procedure3_0("place-unit",CclPlaceUnit);
     gh_new_procedure4_0("create-unit",CclCreateUnit);
+    gh_new_procedureN("order-unit",CclOrderUnit);
     gh_new_procedure2_0("kill-unit",CclKillUnit);
-    gh_new_procedure5_0("kill-unit-at",CclKillUnitAt);
+    gh_new_procedure4_0("kill-unit-at",CclKillUnitAt);
 
     // unit member access functions
     gh_new_procedure1_0("get-unit-unholy-armor",CclGetUnitUnholyArmor);
Index: stratagus/src/unit/upgrade.c
diff -u stratagus/src/unit/upgrade.c:1.58 stratagus/src/unit/upgrade.c:1.59
--- stratagus/src/unit/upgrade.c:1.58   Sun Aug 17 11:57:08 2003
+++ stratagus/src/unit/upgrade.c        Mon Aug 25 07:21:18 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: upgrade.c,v 1.58 2003/08/17 15:57:08 n0body Exp $
+//     $Id: upgrade.c,v 1.59 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -550,7 +550,7 @@
     int p;
 
     CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: upgrades $Id: upgrade.c,v 1.58 2003/08/17 
15:57:08 n0body Exp $\n\n");
+    CLprintf(file,";;; MODULE: upgrades $Id: upgrade.c,v 1.59 2003/08/25 
11:21:18 mr-russ Exp $\n\n");
 
     /* remove?
     //
@@ -1301,10 +1301,7 @@
            if ((unit->CurrentSightRange != 
dst->Stats[player->Player].SightRange ||
                src->TileWidth != dst->TileWidth ||
                src->TileHeight != dst->TileHeight) && !unit->Removed) {
-               MapUnmarkSight(player,
-                       unit->X+unit->Type->TileWidth/2,
-                       unit->Y+unit->Type->TileHeight/2,
-                       unit->CurrentSightRange);
+               MapUnmarkUnitSight(unit);
            }
            unit->Type=dst;
            unit->Stats=&dst->Stats[player->Player];
@@ -1318,10 +1315,7 @@
                src->TileWidth != dst->TileWidth ||
                src->TileHeight != dst->TileHeight) && !unit->Removed) {
                unit->CurrentSightRange=dst->Stats[player->Player].SightRange;
-               MapMarkSight(player,
-                       unit->X+unit->Type->TileWidth/2,
-                       unit->Y+unit->Type->TileHeight/2,
-                       unit->CurrentSightRange);
+               MapMarkUnitSight(unit);
            }
            
            CheckUnitToBeDrawn(unit);
@@ -1417,16 +1411,9 @@
                while (numunits >= 0) {
                    if (sightupgrade[numunits]->Player->Player == 
player->Player &&
                        !sightupgrade[numunits]->Removed) {
-                       /// Marking First is faster
-                       MapMarkSight(player,
-                                       
sightupgrade[numunits]->X+UnitTypes[z]->TileWidth/2,
-                                       
sightupgrade[numunits]->Y+UnitTypes[z]->TileHeight/2,
-                                       UnitTypes[z]->Stats[pn].SightRange);
-                       MapUnmarkSight(player,
-                                       
sightupgrade[numunits]->X+UnitTypes[z]->TileWidth/2,
-                                       
sightupgrade[numunits]->Y+UnitTypes[z]->TileHeight/2,
-                                       
sightupgrade[numunits]->CurrentSightRange);
+                       MapUnmarkUnitSight(sightupgrade[numunits]);
                        
sightupgrade[numunits]->CurrentSightRange=UnitTypes[z]->Stats[pn].SightRange;
+                       MapMarkUnitSight(sightupgrade[numunits]);
                    }                                   
                    numunits--;
                }
Index: stratagus/src/video/video.c
diff -u stratagus/src/video/video.c:1.63 stratagus/src/video/video.c:1.64
--- stratagus/src/video/video.c:1.63    Sun Aug 17 11:57:08 2003
+++ stratagus/src/video/video.c Mon Aug 25 07:21:18 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: video.c,v 1.63 2003/08/17 15:57:08 n0body Exp $
+//     $Id: video.c,v 1.64 2003/08/25 11:21:18 mr-russ Exp $
 
 //@{
 
@@ -318,13 +318,11 @@
 */
 global void SetClipping(int left, int top, int right, int bottom)
 {
-    IfDebug(
        if( left>right || top>bottom || left<0 || left>=VideoWidth
                || top<0 || top>=VideoHeight || right<0
                || right>=VideoWidth || bottom<0 || bottom>=VideoHeight ) {
            DebugLevel0Fn("Wrong clipping, write cleaner code.\n");
        }
-    );
 
     // Note this swaps the coordinates, if wrong ordered
     if (left > right) {




reply via email to

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