stratagus-cvs
[Top][All Lists]
Advanced

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

[Stratagus-CVS] stratagus data/ccl/ai.ccl data/ccl/spells.ccl d...


From: Crestez Leonard
Subject: [Stratagus-CVS] stratagus data/ccl/ai.ccl data/ccl/spells.ccl d...
Date: Thu, 23 Oct 2003 18:40:32 -0000

CVSROOT:        /cvsroot/stratagus
Module name:    stratagus
Branch:         
Changes by:     Crestez Leonard <address@hidden>        03/10/23 14:38:37

Modified files:
        data/ccl       : ai.ccl spells.ccl 
        data/ccl/human : buttons.ccl units.ccl 
        doc            : ChangeLog.html 
        src/ai         : Module.make ai_building.c ai_force.c ai_local.h 
                         ai_magic.c ai_plan.c ai_resource.c ccl_ai.c 
                         new_ai.c 
        src/clone      : Module.make ccl.c ccl_spell.c mainloop.c 
                         player.c spells.c unit_find.c 
        src/game       : savegame.c 
        src/include    : pathfinder.h player.h spells.h unit.h 
        src/pathfinder : pathfinder.c 
        src/sound      : ccl_sound.c 
        src/video      : sdl.c 

Log message:
        Applied ai patch. Started work on demolish spell.

Patches:
Index: stratagus/data/ccl/ai.ccl
diff -u stratagus/data/ccl/ai.ccl:1.55 stratagus/data/ccl/ai.ccl:1.56
--- stratagus/data/ccl/ai.ccl:1.55      Thu Sep 11 06:49:07 2003
+++ stratagus/data/ccl/ai.ccl   Thu Oct 23 14:38:32 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: ai.ccl,v 1.55 2003/09/11 10:49:07 n0body Exp $
+;;     $Id: ai.ccl,v 1.56 2003/10/23 18:38:32 n0body Exp $
 
 ;(define (ai:sleep) () #t)
 
@@ -136,7 +136,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;     * Race orc.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 (define-ai-helper
     ;;
     ;; Unit can build which buildings.
@@ -309,6 +308,405 @@
 ;;
 
 
+(define-ai-action '(defense attack)
+    '(
+       (
+           availables-orc-units
+           ai:send-all:get-needs
+           ai:default-defend
+       )
+       (
+               unit-ogre-mage
+               unit-ogre
+               unit-catapult   
+               unit-axethrower 
+               unit-berserker
+               unit-grunt
+               unit-death-knight
+               unit-dragon))
+)
+
+(define-ai-action '(defense attack)
+    '(
+       (
+           availables-human-units
+           ai:send-all:get-needs
+           ai:default-defend
+       )
+       (
+               unit-paladin    
+               unit-knight     
+               unit-ballista
+               unit-ranger
+               unit-archer
+               unit-footman
+               unit-mage
+               unit-gryphon-rider))
+)
+
+;; Define the script's properties ( rules used to choose a script... ) 
+(define-ai-action '(defense attack)
+  '(
+    (  
+     ;; name
+     soldier-only 
+     ;; lambda for getting needs
+     ai:ground-get-needs
+     ;; Ai Script to execute when ready
+     ai:default-defend
+     )
+    
+    ;; gauge which must be 0..     
+    (zero-gauges enemy-hotspot-air-force  enemy-hotspot-sea-force)
+    
+    ;; Global force requirement ( percentages ).
+    ;; Must send unit of at least this force... ( can remove allied force ... )
+    (force-minimum (enemy-hotspot-ground-force 100) )
+    
+    ;; force requirements in units ( percentages )
+    ((ai:soldier) (enemy-hotspot-ground-force 110))
+    ))
+
+;; Same, but send only peont ( as last chance defense... )
+(define-ai-action '(defense)
+  '(
+    (
+     ;; name
+     last-chance-defense
+     ;; lambda for getting needs
+     ai:ground-get-needs
+     ;; Ai Script to execute when ready
+     ai:default-defend
+     )
+    ;; gauge which must be 0..     
+    (zero-gauges enemy-hotspot-air-force  enemy-hotspot-sea-force)
+    
+    ;; Global force requirement ( percentages ).
+    ;; Must send unit of at least this force... ( can remove allied force ... )
+    (force-minimum (enemy-hotspot-ground-force 200) )
+
+    ;; force requirements in units ( percentages )
+    ((ai:worker) (enemy-hotspot-ground-force 110))))
+
+(define-ai-action '(defense attack)
+  '(
+    (  
+     ;; name
+     air-rush 
+     ;; lambda for getting needs
+     ai:default-get-needs
+     ;; Ai Script to execute when ready
+     ai:default-defend
+     )
+    
+    ;; gauge which must be 0 ( none )..            
+    (zero-gauges )
+    
+    ;; Global force requirement ( percentages ).
+    ;; Must send unit of at least this force... ( can remove allied force ... )
+    (force-minimum (enemy-hotspot-air-fire 110)        )
+    
+    ;; force requirements in units ( percentages )
+    ((ai:flyer) 
+       (enemy-hotspot-air-fire     80) 
+       (enemy-hotspot-air-force    30)
+       (enemy-hotspot-ground-force 30)
+       (enemy-hotspot-sea-force    30)  )
+    ))
+  
+(define-ai-action '(defense attack)
+    '(
+       ;; use battleship &  destroyer
+       (
+           ship-rush
+           ai:sea-get-needs
+           ai:default-defend
+       )
+       (zero-gauges)
+       (force-minimum (enemy-hotspot-sea-force 100) )
+       ((ai:battleship)
+           (enemy-hotspot-sea-fire 70)
+           (enemy-hotspot-ground-force 30) (enemy-hotspot-sea-force 30))
+       ((ai:destroyer)
+           (enemy-hotspot-sea-fire 70)
+           (enemy-hotspot-ground-force 20) (enemy-hotspot-sea-force 20) 
(enemy-hotspot-air-force 80))
+       ))
+
+(define-ai-action '(defense attack)
+    '(
+       ;; use submarine against blind units
+       (
+           submarine-rush
+           ai:sea-only-get-needs
+           ai:default-defend
+       )
+       (zero-gauges enemy-hotspot-detectors)
+       (force-minimum (enemy-hotspot-sea-force 50))
+       ((ai:submarine) (enemy-hotspot-sea-force 50))
+       ))
+
+(define-ai-action '(defense attack)
+    '(
+       (       ;; name
+           cavalrie-rush 
+           ;; lambda for getting needs
+           ai:ground-get-needs
+           ;; Ai Script to execute when ready
+           ai:default-defend
+       )
+       
+       ;; gauge which must be 0..          
+       (zero-gauges enemy-hotspot-air-force enemy-hotspot-sea-force)
+    
+       ;; Global force requirement ( percentages ).
+       ;; Must send unit of at least this force... ( can remove allied force 
... )
+       (force-minimum (enemy-hotspot-ground-force 100) )
+       
+       ;; force requirements in units ( percentages )
+       ((ai:cavalrie) (enemy-hotspot-ground-force 130))    
+    ))
+
+(define-ai-action '(defense attack)
+    '(
+       (       ;; name
+           ground-mixed-rush 
+           ;; lambda for getting needs
+           ai:ground-get-needs
+           ;; Ai Script to execute when ready
+           ai:default-defend
+       )
+       ;; gauge which must be 0..          
+       (zero-gauges enemy-hotspot-sea-force)
+    
+       ;; Global force requirement ( percentages ).
+       ;; Must send unit of at least this force... ( can remove allied force 
... )
+       (force-minimum (enemy-hotspot-ground-force 100) 
(enemy-hotspot-air-force 100) )
+    
+       ;; force requirements in units ( percentages )
+       ((ai:cavalrie)  (enemy-hotspot-ground-force 75))
+       ((ai:soldier)   (enemy-hotspot-ground-force 20))
+       ((ai:shooter)   (enemy-hotspot-ground-force 25)
+                       (enemy-hotspot-air-force 120))
+    ))
+
+(define-ai-action '(defense attack)    
+    '(
+       (       ;; name
+           soldier-shooter-rush 
+           ;; lambda for getting needs
+           ai:ground-get-needs
+           ;; Ai Script to execute when ready
+           ai:default-defend
+       )
+       (zero-gauges enemy-hotspot-sea-force)
+       (force-minimum  (enemy-hotspot-ground-force 100) 
(enemy-hotspot-air-force 100) )
+       ((ai:soldier)   (enemy-hotspot-ground-force 80))
+       ((ai:shooter)   (enemy-hotspot-ground-force 40)
+                       (enemy-hotspot-air-force 120))
+    ))
+
+;;
+;; Check if a list of gauges is 0...
+;;
+(define ai:check-gauges
+    (lambda (gauges) 
+       (cond 
+           ((null? gauges)         #t)
+           ((> (ai:get-gauge (car gauges)) 0) #f)
+           (#t (ai:check-gauges (cdr gauges)))
+)))        
+
+;;
+;; Sum a list of gauges pcts
+;;
+(define ai:sum-gauges-pcts
+    (lambda (lst)
+       (cond
+           ((null? lst)        0)
+           (#t
+               (let(
+                   (gauge      (car(car lst)))
+                   (pct        (car (cdr(car lst))))
+                   (left       (cdr lst)))
+                   (+  (* (ai:get-gauge gauge) pct)
+                       (ai:sum-gauges-pcts left))
+)))))
+
+;;
+;; sum the force of units in a list ( unittype count unittype count ... )
+;;
+(define ai:unit-list-force
+    (lambda (list)
+       (cond
+           ((null? list)       0)
+           (#t 
+               (+      
+                   (* 
+                       (ai:get-unittype-force (car list)) (cadr list))
+                       (ai:unit-list-force (cddr list))
+)))))
+
+;;
+;; From a pct list of gauge, return number of wanted units.
+;; ( ( unittype1 (gauge %) (gauge %) (gauge %) ) 
+;;   ( unittype2 (gauge %) (gauge %) (gauge %) ) ... )
+;; => ( unittype1 count1 unittype2 count2 ... )
+;;
+;; % can be negative.
+;;                     
+(define ai:units_pct_to_wants
+    (lambda (pcts)
+       (cond
+           ((null? pcts)       '())
+           (#t 
+               (let* ( (unittype (eval (caar pcts) ))
+                       (gauges_pcts (cdar pcts))
+                       (want_pct (ai:sum-gauges-pcts gauges_pcts))
+                       (unit_force (ai:get-unittype-force unittype))
+                       (wanted (quotient want_pct (* unit_force 100))))
+               (if (< wanted 1)
+                   (ai:units_pct_to_wants (cdr pcts))
+                   (cons unittype (cons wanted (ai:units_pct_to_wants (cdr 
pcts))))                
+))))))
+
+;;
+;; Add unit to unitlist, until it get the "to" force
+;;
+;; Only the first unit is incremented
+;;
+(define complete-force-to
+    (lambda (units to)
+       (if (< (ai:unit-list-force units) to)
+           (complete-force-to (cons (car units) (cons (+ 1 (cadr units)) (cddr 
units))) to)
+           units)))
+
+;;
+;; Get the list of units required by the script 
+;;
+(define ai:get-script-unit-list
+    (lambda (script)
+       (let*
+           ((force-mini-gauges (cdr(caddr script)))
+            (units_pct (cdddr script))
+            (result 0)
+            (force-mini (quotient (ai:sum-gauges-pcts force-mini-gauges) 100))
+            (units (ai:units_pct_to_wants units_pct)))
+               
+           ;; Build at least one of the first type.
+           (if (null? units)
+               (set! units (list (eval (caar units_pct) ) 1)))
+           
+           ;; Complete if necessary to achieve minimum force ...
+           (set! units (complete-force-to units force-mini))
+           units)))                    
+
+;;
+;; Evaluate a script.
+;; It tries to send as much unit as possible ( from force 0 )
+;; script content is : (unittype max) (unittype max) (unittype max) ...
+;;     foce is incremented until it reaches the hotspot enemy-force...
+(define ai:send-all:get-needs
+    (lambda (script)
+       (begin
+           (if (ai:adhoc-force (list 
+                       (ai:get-gauge 'enemy-hotspot-ground-force)
+                       (ai:get-gauge 'enemy-hotspot-sea-force)
+                       (ai:get-gauge 'enemy-hotspot-air-force))
+               (car (cdr script)))
+               0
+               -1
+))))
+
+  
+;;
+;; Evaluate a script; returns :
+;; - nil if nothing possible
+;; - a value from 0 (go/ready) to ~(will take eternity to achieve)
+;;   ( in this case, the tmp force is filled with script requirements. )
+;;
+(define ai:default-get-needs
+    (lambda (script)
+       (let
+           ((gauges (cdadr script)))
+           ;; (force-mini-gauges (cdadr script))       
+           ;; (units_pct (cddr script)))
+           
+           (if (ai:check-gauges gauges)        
+               (let
+                   ((result 0))
+                  
+                   ;; clear tmp-force
+                   (ai:clear-force (ai:own-force))
+                   ;; set tmp-force to this script requirement
+                   (ai:force-list (cons (ai:own-force) 
(ai:get-script-unit-list script)))
+                   
+                   ;; take units from pool force to tmp...
+                   (ai:force-complete (ai:own-force))
+                   ;; compute cost to complete the tmp force
+                   (set! result (ai:evaluate-force-cost (ai:own-force)))
+                                   
+                   ;; return the computed value
+                   result
+               )
+               ;; can't, return -1
+               -1
+           )
+)))
+
+(define ai:ground-get-needs
+    (lambda (script)
+       ;; Check if hotspot is accessible by ground 
+       (if (ai:can-reach-hotspot 'ground)
+           (ai:default-get-needs script)
+           -1)))
+
+(define ai:sea-get-needs
+    (lambda (script)
+       ;; Check if hotspot is accessible by ground 
+       (if (ai:can-reach-hotspot 'sea)
+           (ai:default-get-needs script)
+           -1)))
+
+(define ai:sea-only-get-needs
+    (lambda (script)
+       (if (> (ai:get-gauge 'enemy-hotspot-sea-force) 0)
+           ;; Check if hotspot is accessible by ground 
+           (ai:sea-get-needs script)
+           -1)))
+    
+;;
+;; This script is used in the simplest case when : 
+;;     - a force ( defend-force ) is ready
+;;     - a hotspot is set
+;;     - the AI need only to send the defend force there...
+;;
+(define ai:default-defend
+'(
+    ;; group the force     
+    (begin     
+           (writes nil "Force will defend/attack now\n")
+           (ai:group-force (ai:own-force))         
+    )
+
+    ;; wait for grouping complete.     
+    (if (ai:force-active (ai:own-force)) 
+       ;; hang...
+       (ai:idle)           
+        ;; else attack the hotspot
+       (ai:hotspot-attack-with-force (ai:own-force)))  
+    
+    ;; The send units back to home (?)
+    ;; Fixme : if unit is on ground & no combat => go home 
+    (if (ai:force-active (ai:own-force)) (ai:idle))
+    
+    (begin
+       ;; Send units home,
+       ;; and forget about them.
+       (ai:force-go-home (ai:own-force))
+       (ai:clear-force (ai:own-force)))        
+))
+
+              
 ;;=============================================================================
 ;;
 ;;     Define an AI engine.
@@ -336,10 +734,10 @@
 (define ai:orc-land-rush-endloop
   '((writes nil "Looping !\n")
     (ai:force 0 'unit-grunt 15 'unit-ogre-mage 9 'unit-catapult 3)
-    (ai:force 1 'unit-grunt 20)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
+;;    (ai:force 1 'unit-grunt 20)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+    (ai:sleep 5000)
     (ai:script ai:orc-land-rush-endloop) ) )
 
 (define-ai 'rush race2 "gruntrush"
@@ -355,11 +753,10 @@
     (ai:set  'unit-pig-farm 2)
     (ai:need 'unit-mythical-barracks)
     (ai:need 'unit-mythical-blacksmith)
-    (ai:force 1 'unit-grunt 1)
+;;    (ai:force 1 'unit-grunt 1)
     (ai:force 0 'unit-grunt 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
     (ai:force 0 'unit-grunt 2)
     (ai:research 'upgrade-battle-axe1)
@@ -367,144 +764,146 @@
     (ai:research 'upgrade-battle-axe2)
     (ai:research 'upgrade-orc-shield2)
     (ai:set  'unit-peon 20)
-    (ai:force 1 'unit-grunt 6)
-    (ai:wait-force 1)          ;; wait until attack party is completed
+    (ai:force 0 'unit-grunt 6)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
     (ai:set 'unit-mythical-barracks 3)
-    (ai:force 1 'unit-grunt 20)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 20)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
     (ai:set 'unit-mythical-barracks 6)
-    (ai:force 1 'unit-grunt 40)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 40)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
     (ai:set  'unit-pig-farm 25)
 
 
-    (ai:force 0 'unit-grunt 9)
-    (ai:force 2 'unit-grunt 20)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-
-    (ai:force 0 'unit-grunt 15)
-    (ai:force 1 'unit-grunt 20)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 0 'unit-grunt )
+;;    (ai:force 2 'unit-grunt 20)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+
+;;    (ai:force 0 'unit-grunt 15)
+;;   (ai:force 1 'unit-grunt 20)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
     (ai:need (unit-type 'unit-great-hall))
 
-    (ai:force 0 'unit-grunt 15)
-    (ai:force 2 'unit-grunt 80)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+;;    (ai:force 0 'unit-grunt 15)
+;;    (ai:force 2 'unit-grunt 80)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
 
-    (ai:force 1 'unit-grunt 20)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 1 'unit-grunt 20)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
-    (ai:force 2 'unit-grunt 20)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+;;    (ai:force 2 'unit-grunt 20)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
 
-    (ai:force 1 'unit-grunt 20)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 1 'unit-grunt 20)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
-    (ai:force 2 'unit-grunt 20)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+;;    (ai:force 2 'unit-grunt 20)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
 
 
 
 
 
-    (ai:force 1 'unit-grunt 9)
-    (ai:force 2 'unit-grunt 4)
-    (ai:force 3 'unit-grunt 5)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+;;    (ai:force 1 'unit-grunt 9)
+;;    (ai:force 2 'unit-grunt 4)
+;;    (ai:force 3 'unit-grunt 5)
+;;    (ai:wait-force 3)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 3)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
 
     (ai:set 'unit-ogre-mound 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:force 0 'unit-grunt 9)
-    (ai:force 4 'unit-grunt 9)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:force 0 'unit-grunt 9)
+;;    (ai:force 4 'unit-grunt 9)
 
     (ai:set  'unit-peon 25)
 
     (ai:set  'unit-pig-farm 20)
     (ai:force 0 'unit-grunt 9 'unit-ogre 1)
-    (ai:force 1 'unit-grunt 9)
-    (ai:force 2 'unit-grunt 9)
-    (ai:force 3 'unit-grunt 12)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:wait-force 2)          ;; wait until attack party is completed
+;;    (ai:force 1 'unit-grunt 9)
+;;    (ai:force 2 'unit-grunt 9)
+;;    (ai:force 3 'unit-grunt 12)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
     (ai:set 'unit-mythical-barracks 9)
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 2)
 
     (ai:force 0 'unit-grunt 9 'unit-ogre 3)
-    (ai:force 1 'unit-grunt 14)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 3)
-
-    (ai:force 0 'unit-grunt 14 'unit-axethrower 2 'unit-ogre 5 'unit-catapult 
1)
-    (ai:force 1 'unit-grunt 9)
-    (ai:force 2 'unit-grunt 9)
-    (ai:force 3 'unit-grunt 9)
-    (ai:force 4 'unit-grunt 4)
-    (ai:force 5 'unit-grunt 9 'unit-ogre 3)
-    (ai:wait-force 4)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
-    (ai:attack-with-force 4)
-
-    (ai:force 6 'unit-grunt 19)
-    (ai:force 7 'unit-grunt 19)
-
-    (ai:force 0 'unit-grunt 9 'unit-axethrower 9 'unit-ogre 9 'unit-catapult 2)
-    (ai:force 1 'unit-grunt 9 'unit-ogre 3)
-    (ai:wait-force 5)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 5)
-    (ai:attack-with-force 6)
-    (ai:attack-with-force 7)
-
-    (ai:force 1 'unit-grunt 9 'unit-ogre 2)
-    (ai:force 2 'unit-grunt 9)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
-
-    (ai:force 1 'unit-grunt 11 'unit-ogre 4)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:force 1 'unit-grunt 15)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:force 1 'unit-grunt 11 'unit-ogre 4)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:force 1 'unit-grunt 15)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 1 'unit-grunt 14)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 3)
+
+    (ai:sleep 5000)
+
+    (ai:force 0 'unit-grunt 50 'unit-axethrower 2 'unit-ogre 10 'unit-catapult 
1)
+;;    (ai:force 1 'unit-grunt 9)
+;;    (ai:force 2 'unit-grunt 9)
+;;    (ai:force 3 'unit-grunt 9)
+;;    (ai:force 4 'unit-grunt 4)
+;;    (ai:force 5 'unit-grunt 9 'unit-ogre 3)
+;;    (ai:wait-force 4)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
+;;    (ai:attack-with-force 4)
+
+;;    (ai:force 6 'unit-grunt 19)
+;;    (ai:force 7 'unit-grunt 19)
+
+;;    (ai:force 0 'unit-grunt 9 'unit-axethrower 9 'unit-ogre 9 'unit-catapult 
2)
+;;    (ai:force 1 'unit-grunt 9 'unit-ogre 3)
+;;    (ai:wait-force 5)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 5)
+;;    (ai:attack-with-force 6)
+;;    (ai:attack-with-force 7)
+
+;;    (ai:force 1 'unit-grunt 9 'unit-ogre 2)
+;;    (ai:force 2 'unit-grunt 9)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 2)
+
+;;    (ai:force 1 'unit-grunt 11 'unit-ogre 4)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+
+;;    (ai:force 1 'unit-grunt 15)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+
+;;    (ai:force 1 'unit-grunt 11 'unit-ogre 4)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+
+;;    (ai:force 1 'unit-grunt 15)
+;;    (ai:wait-force 1)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
        (ai:sleep 500)
     (ai:force 0 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
        'unit-ogre-mage 6 'unit-catapult 1 'unit-death-knight 5)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
-       'unit-ogre-mage 2 'unit-catapult 1 'unit-death-knight 1)
-    (ai:force 2 'unit-dragon 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+;;    (ai:force 1 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
+;;     'unit-ogre-mage 2 'unit-catapult 1 'unit-death-knight 1)
+;;    (ai:force 2 'unit-dragon 1)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 2)
 
     ;;(ai:sleep 500)
     (ai:need 'unit-mythical-watch-tower)
@@ -966,150 +1365,165 @@
 ;;
 (define ai:air-attack-endloop
   '((writes nil "Looping !\n")
-    (ai:force 1 (ai:flyer) 2)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:force 3 (ai:flyer) 2)
-    (ai:force 4 (ai:flyer) 2)
-    (ai:force 5 (ai:flyer) 2)
-    (ai:force 6 (ai:flyer) 1)
-    (ai:wait-force 5)
-    (ai:wait-force 6)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
-    (ai:attack-with-force 4)
-    (ai:attack-with-force 5)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:force 3 (ai:flyer) 2)
+;;    (ai:force 4 (ai:flyer) 2)
+;;    (ai:force 5 (ai:flyer) 2)
+;;    (ai:force 6 (ai:flyer) 1)
+;;    (ai:wait-force 5)
+;;    (ai:wait-force 6)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
+;;    (ai:attack-with-force 4)
+;;    (ai:attack-with-force 5)
     (ai:sleep 500)
     (ai:script ai:air-attack-endloop) ))
 
 (define-ai "wc2-air-attack" "*" "air-attack"
   '(
     ;; Define the main AI script.
-    (begin (ai:debug #f) (ai:sleep (ai:get-sleep-cycles)))
+    (begin (ai:debug #f) (ai:set-auto-attack #f) (ai:sleep 
(ai:get-sleep-cycles)))
     (ai:set-reserve! #( 0  0 0 0  0 0 0))
     (ai:need (ai:city-center))
     (ai:set  (ai:worker) 1)
     (ai:wait (ai:city-center))
     (ai:wait (ai:worker))      ;; start hangs if nothing is available
 
-    (ai:set  (ai:worker) 9)
+    (ai:set  (ai:worker) 12)     
+    
     (ai:need (ai:lumber-mill))
+    (ai:wait (ai:lumber-mill))
+    
     (ai:need (ai:barracks))
+    (ai:wait (ai:barracks))
     (ai:force 0 (ai:soldier) 2)
-    (ai:wait-force 0)          ;; wait until defence is ready
+;;    (ai:wait-force 0)                ;; wait until defence is ready
 
     (ai:need (ai:blacksmith))
+    (ai:wait (ai:blacksmith))
     (ai:upgrade-to (ai:better-city-center))
-    (ai:set  (ai:worker) 15)
+    (ai:set  (ai:worker) 20)
     (ai:force 0 (ai:soldier) 2 (ai:shooter) 3)
     (ai:wait (ai:better-city-center))
 
     (ai:need (ai:cavalry))
+    
     (ai:need (ai:tower))
-    (ai:upgrade-to (ai:guard-tower))
+    (ai:wait (ai:tower))
+    
+    (ai:upgrade-to (ai:guard-tower))    
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:upgrade-to (ai:best-city-center))
     (ai:wait (ai:best-city-center))    ;; need this for airport!
 
     (ai:need (ai:airport))
-    (ai:force 2 (ai:flyer) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+    
+    ;; Force 1 is attack reserve.
+    (ai:force 1 (ai:flyer) 2)
+    (ai:wait-force 1)
+    
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
 
+    (ai:set-auto-attack #t)
     (ai:sleep 500)
     (ai:need (ai:city-center))
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:airport))
-    (ai:force 2 (ai:flyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
+    (ai:force 0 (ai:flyer) 3)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
 
     (ai:need (ai:city-center))
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:airport))
     (ai:set  (ai:worker) 20)
-    (ai:force 1 (ai:flyer) 2)
-    (ai:attack-with-force 2)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:attack-with-force 2)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:cannon-tower))
-    (ai:force 2 (ai:flyer) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 2 (ai:flyer) 1)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
-    (ai:force 1 (ai:flyer) 2)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:wait-force 2)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
-    (ai:force 1 (ai:flyer) 1)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:force 3 (ai:flyer) 2)
-    (ai:wait-force 2)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
+    (ai:force 0 (ai:flyer) 6)
+;;    (ai:force 1 (ai:flyer) 1)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:force 3 (ai:flyer) 2)
+;;    (ai:wait-force 2)
+;;    (ai:wait-force 3)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
-    (ai:force 1 (ai:flyer) 2)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:force 3 (ai:flyer) 2)
-    (ai:wait-force 2)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:force 3 (ai:flyer) 2)
+;;    (ai:wait-force 2)
+;;    (ai:wait-force 3)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
-    (ai:force 1 (ai:flyer) 2)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:force 3 (ai:flyer) 3)
-    (ai:wait-force 2)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:force 3 (ai:flyer) 3)
+;;    (ai:wait-force 2)
+;;    (ai:wait-force 3)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
 
     (ai:sleep 500)
     (ai:need (ai:tower))
     (ai:upgrade-to (ai:guard-tower))
     (ai:need (ai:tower))
-    (ai:force 1 (ai:flyer) 2)
-    (ai:force 2 (ai:flyer) 3)
-    (ai:force 3 (ai:flyer) 3)
-    (ai:wait-force 2)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
-
-    (ai:sleep 500)
-    (ai:force 1 (ai:flyer) 1)
-    (ai:force 2 (ai:flyer) 2)
-    (ai:force 3 (ai:flyer) 2)
-    (ai:force 4 (ai:flyer) 2)
-    (ai:force 5 (ai:flyer) 2)
-    (ai:wait-force 5)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:attack-with-force 3)
-    (ai:attack-with-force 4)
-    (ai:attack-with-force 5)
+;;    (ai:force 1 (ai:flyer) 2)
+;;    (ai:force 2 (ai:flyer) 3)
+;;    (ai:force 3 (ai:flyer) 3)
+;;    (ai:wait-force 2)
+;;    (ai:wait-force 3)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
+
+    (ai:sleep 500)
+    (ai:force 0 (ai:flyer) 10)
+;;    (ai:force 1 (ai:flyer) 1)
+;;    (ai:force 2 (ai:flyer) 2)
+;;    (ai:force 3 (ai:flyer) 2)
+;;    (ai:force 4 (ai:flyer) 2)
+;;    (ai:force 5 (ai:flyer) 2)
+;;    (ai:wait-force 5)                ;; wait until attack party is completed
+;;    (ai:attack-with-force 2)
+;;    (ai:attack-with-force 3)
+;;    (ai:attack-with-force 4)
+;;    (ai:attack-with-force 5)
 
     (ai:sleep 500)
     (ai:script ai:air-attack-endloop) ))
@@ -1126,44 +1540,55 @@
 ;;
 (define ai:sea-attack-endloop
   '((writes nil "Looping !\n")
-    (ai:force 1 (ai:destroyer) 6 (ai:battleship) 7 (ai:scout) 1)
-    (ai:force 2 (ai:soldier) 4 (ai:cavalrie) 4 (ai:catapult) 4
-       (ai:transporter) 2)
-    (ai:wait-force 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 
+             (ai:destroyer) 6 (ai:battleship) 7 (ai:scout) 1
+             (ai:soldier) 4 (ai:cavalrie) 4 (ai:catapult) 4
+             (ai:transporter) 2)
     (ai:sleep 500)
     (ai:script ai:sea-attack-endloop) ))
 
 (define-ai "wc2-sea-attack" "*" "sea-attack"
   '(
     ;; Define the main AI script.
-    (begin (ai:debug #f) (ai:sleep (ai:get-sleep-cycles)))
+    (begin (ai:debug #f) (ai:set-auto-attack #f) (ai:sleep 
(ai:get-sleep-cycles)))
     (ai:need (ai:city-center))
     (ai:set  (ai:worker) 1)
     (ai:wait (ai:city-center))
     (ai:wait (ai:worker))      ;; start hangs if nothing is available
 
-    (ai:set  (ai:worker) 9)
+    (ai:set  (ai:worker) 12)    
     (ai:need (ai:lumber-mill))
+    (ai:wait (ai:lumber-mill))
+    
     (ai:need (ai:barracks))
-    (ai:force 0 (ai:soldier) 3)
-    (ai:wait-force 0)          ;; wait until defence is ready
+    (ai:wait (ai:barracks))
 
+    ;;    (ai:wait-force 0)            ;; wait until defence is ready
+    (ai:set  (ai:worker) 15)
+    
+    (ai:sleep 1000)
+    
     (ai:need (ai:harbor))
+    (ai:wait (ai:harbor))
+    
     (ai:upgrade-to (ai:better-city-center))
     (ai:need (ai:refinery))
+    (ai:wait (ai:refinery))
+    
     (ai:need (ai:scientific))
-    (ai:set  (ai:worker) 15)
+    
+    (ai:set  (ai:worker) 20)
+    
     (ai:set  (ai:tanker) 1)
     (ai:need (ai:platform))
     (ai:wait (ai:better-city-center))
 
     (ai:set  (ai:tanker) 3)
-    (ai:force 1 (ai:submarine) 3)
+    (ai:force 0 (ai:soldier) 3 (ai:submarine) 2)
+    (ai:force 1 (ai:submarine) 2)
     (ai:wait-force 1)          ;; wait until attack force is ready
-    (ai:attack-with-force 1)
+    
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:need (ai:foundry))
@@ -1171,81 +1596,58 @@
     (ai:research (ai:upgrade-ship-armor-2))
     (ai:set  (ai:tanker) 4)
     (ai:force 1 (ai:submarine) 4)
-    (ai:wait-force 1)          ;; wait until attack force is ready
-    (ai:attack-with-force 1)
+    (ai:wait-force 1)    
+    
+    (ai:set-auto-attack #t)
+;;    (ai:wait-force 1)                ;; wait until attack force is ready
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:need (ai:harbor))
     (ai:need (ai:blacksmith))
-    (ai:force 1 (ai:submarine) 5 (ai:scout) 1)
-    (ai:wait-force 1)          ;; wait until attack force is ready
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:submarine) 5 (ai:scout) 1)
+;;    (ai:wait-force 1)                ;; wait until attack force is ready
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:research (ai:upgrade-catapult-1))
     (ai:need (ai:cavalry))
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 2 (ai:battleship) 1
-       (ai:scout) 2)
+    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1 (ai:submarine) 1 
(ai:destroyer) 2 (ai:battleship) 1 )    
+    (ai:force 1 (ai:scout) 1 (ai:destroyer) 2 (ai:battleship) 2)
+    
     (ai:sleep 3000)
-    (ai:wait-force  1)
-    (ai:attack-with-force 1)
+;;    (ai:wait-force  1)
+;;    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 3 (ai:destroyer) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 2 (ai:battleship) 2
-       (ai:scout) 2)
-    (ai:force 2 (ai:catapult) 2 (ai:transporter) 1)
-    (ai:wait-force  1)
-    (ai:attack-with-force 1)
+    (ai:force 0 
+             (ai:soldier) 3 (ai:catapult) 2 (ai:scout) 3 (ai:submarine) 1 
(ai:destroyer) 2 (ai:battleship) 2 (ai:transporter) 1)
+    (ai:force 1 (ai:scout) 2 (ai:destroyer) 3 (ai:battleship) 3)
+;;    (ai:force 2 (ai:catapult) 2 )
+;;    (ai:wait-force  1)
+;;    (ai:attack-with-force 1)
 
     (ai:sleep 500)
     (ai:research (ai:upgrade-catapult-2))
     (ai:research (ai:upgrade-ship-cannon-1))
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 2 (ai:battleship) 3
-       (ai:scout) 1)
-    (ai:force 2 (ai:cavalrie) 1 (ai:catapult) 3 (ai:transporter) 1)
-    (ai:wait-force  1)
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:cavalrie) 1 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 2 
(ai:destroyer) 4 (ai:battleship) 5 (ai:submarine) 3 (ai:transporter) 1)
 
     (ai:sleep 500)
     (ai:research (ai:upgrade-ship-cannon-2))
     (ai:need (ai:city-center))
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 3 (ai:battleship) 4
-       (ai:scout) 1)
-    (ai:force 2 (ai:cavalrie) 3 (ai:catapult) 3 (ai:transporter) 1)
-    (ai:wait-force  1)
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:cavalrie) 2 (ai:soldier) 5 (ai:catapult) 3 (ai:scout) 3 
(ai:destroyer) 6 (ai:battleship) 6 (ai:submarine) 3 (ai:transporter) 2)
 
     (ai:sleep 500)
     (ai:need (ai:harbor))
     (ai:research (ai:upgrade-weapon-1))
+    (ai:sleep 500)
     (ai:research (ai:upgrade-armor-1))
+    (ai:sleep 500)
     (ai:research (ai:upgrade-weapon-2))
+    (ai:sleep 500)
     (ai:research (ai:upgrade-armor-2))
     (ai:set  (ai:tanker) 5)
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 4 (ai:battleship) 5
-       (ai:scout) 1)
-    (ai:force 2 (ai:cavalrie) 3 (ai:catapult) 3 (ai:transporter) 1)
-    (ai:wait-force  1)
-    (ai:attack-with-force 1)
 
     (ai:sleep 500)
-    (ai:force 0 (ai:soldier) 3 (ai:catapult) 1 (ai:scout) 1)
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:scout) 1)
-    (ai:force 1 (ai:submarine) 1 (ai:destroyer) 5 (ai:battleship) 6
-       (ai:scout) 1)
-    (ai:force 2 (ai:cavalrie) 4 (ai:catapult) 2 (ai:transporter) 1)
-    (ai:wait-force  1)
-    (ai:wait-force  2)
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
 
     (ai:sleep 500)
     (ai:script ai:sea-attack-endloop) ))
@@ -1262,14 +1664,8 @@
 ;;
 (define ai:human-land-attack-endloop
   '((writes nil "Looping !\n")
-    (ai:force 0 'unit-footman 1 'unit-ranger 2 'unit-paladin 4 'unit-ballista 1
-       'unit-mage 4)
-    (ai:force 1 'unit-footman 1 'unit-ranger 2 'unit-paladin 4 'unit-ballista 1
-       'unit-mage 2)
-    (ai:force 2 'unit-gryphon-rider 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 'unit-footman 2 'unit-ranger 4 'unit-paladin 8 'unit-ballista 2
+       'unit-mage 6 'unit-gryphon-rider 3)
 
     (ai:sleep 500)
     (ai:script ai:human-land-attack-endloop) ) )
@@ -1286,18 +1682,12 @@
     (ai:set  'unit-peasant 4)
     (ai:need 'unit-elven-lumber-mill)
     (ai:need 'unit-alliance-barracks)
-    (ai:force 0  'unit-footman 2)
-    (ai:force 1  'unit-footman 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0  'unit-footman 3)
 
     (ai:set  'unit-peasant 9)
     (ai:sleep  500)
     (ai:need 'unit-alliance-blacksmith)
-    (ai:force 0 'unit-footman 2 'unit-archer 1)
-    (ai:force 1 'unit-footman 2 'unit-archer 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 4 'unit-archer 2)
 
     (ai:sleep  500)
     (ai:research 'upgrade-sword1)
@@ -1308,33 +1698,20 @@
     (ai:research 'upgrade-arrow2)
     (ai:need 'unit-alliance-barracks)
 
-    (ai:force 0 'unit-footman 3 'unit-archer 2)
-    (ai:force 1 'unit-footman 3 'unit-archer 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 6 'unit-archer 3)
 
     (ai:sleep  500)
     (ai:set  'unit-peasant 15)
-    (ai:force 0 'unit-footman 3 'unit-archer 2)
-    (ai:force 1 'unit-footman 3 'unit-archer 1 'unit-ballista 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 6 'unit-archer 3 'unit-ballista 1)
 
     (ai:sleep  500)
     (ai:upgrade-to 'unit-keep)
     (ai:wait 'unit-keep)
 
-    (ai:force 1 'unit-footman 3 'unit-archer 1 'unit-ballista 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
     (ai:sleep  500)
     (ai:need 'unit-town-hall)
     (ai:need 'unit-stables)
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-knight 6 'unit-ballista 1)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-knight 2 'unit-ballista 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 1 'unit-archer 4 'unit-knight 6 'unit-ballista 2)
 
     (ai:sleep  500)
     (ai:need 'unit-alliance-watch-tower)
@@ -1346,10 +1723,7 @@
     (ai:set  'unit-peasant 19)
     (ai:wait 'unit-castle)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-knight 6 'unit-ballista 1)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-knight 2 'unit-ballista 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-knight 10 'unit-ballista 
2)
 
     (ai:sleep  500)
     (ai:need 'unit-alliance-watch-tower)
@@ -1361,12 +1735,7 @@
     (ai:research 'upgrade-healing)
     (ai:research 'upgrade-exorcism)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-knight 0 'unit-paladin 5
-       'unit-ballista 1)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-knight 0 'unit-paladin 3
-       'unit-ballista 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-knight 0 'unit-paladin 5 
'unit-ballista 1)
 
     (ai:sleep  500)
     (ai:need 'unit-alliance-watch-tower)
@@ -1377,12 +1746,8 @@
     (ai:research 'upgrade-polymorph)
     (ai:research 'upgrade-blizzard)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-paladin 6 'unit-ballista 1
-       'unit-mage 2)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-paladin 2 'unit-ballista 1
-       'unit-mage 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-footman 1 'unit-archer 3 'unit-paladin 10 'unit-ballista 
3
+       'unit-mage 3)
 
     (ai:sleep  500)
     (ai:research 'upgrade-slow)
@@ -1392,37 +1757,22 @@
     (ai:upgrade-to 'unit-alliance-guard-tower)
     (ai:research 'upgrade-invisibility)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-paladin 6 'unit-ballista 1
+    (ai:force 0 'unit-footman 1 'unit-archer 4 'unit-paladin 12 'unit-ballista 
4
        'unit-mage 5)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-paladin 2 'unit-ballista 1
-       'unit-mage 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  500)
     (ai:need 'unit-gryphon-aviary)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 2 'unit-paladin 6 'unit-ballista 1
-       'unit-mage 5)
-    (ai:force 1 'unit-footman 1 'unit-archer 2 'unit-paladin 2 'unit-ballista 1
-       'unit-mage 1)
-    (ai:force 2 'unit-gryphon-rider 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 'unit-footman 1 'unit-archer 5 'unit-paladin 14 'unit-ballista 
4
+       'unit-mage 6 'unit-gryphon-rider 1)
 
     (ai:sleep  500)
     (ai:research 'upgrade-ranger)
     (ai:research 'upgrade-ranger-scouting)
     (ai:research 'upgrade-flame-shield)
-    (ai:force 0 'unit-footman 1 'unit-archer 0 'unit-ranger 2 'unit-paladin 6
-       'unit-ballista 1 'unit-mage 5)
-    (ai:force 1 'unit-footman 1 'unit-archer 0 'unit-ranger 2 'unit-paladin 2
-       'unit-ballista 1 'unit-mage 1)
-    (ai:force 2 'unit-gryphon-rider 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 'unit-footman 1 'unit-archer 0 'unit-ranger 5 'unit-paladin 14 
'unit-ballista 4
+       'unit-mage 6 'unit-gryphon-rider 3)
+
 
     (ai:sleep  500)
     (ai:need 'unit-town-hall)
@@ -1433,15 +1783,6 @@
     (ai:need 'unit-inventor)
     (ai:research 'upgrade-longbow)
 
-    (ai:force 0 'unit-footman 1 'unit-archer 0 'unit-ranger 2 'unit-paladin 6
-       'unit-ballista 1 'unit-mage 5)
-    (ai:force 1 'unit-footman 1 'unit-archer 0 'unit-ranger 2 'unit-paladin 2
-       'unit-ballista 1 'unit-mage 1)
-    (ai:force 2 'unit-gryphon-rider 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
-
     (ai:sleep  500)
     (ai:need 'unit-alliance-watch-tower)
     (ai:upgrade-to 'unit-alliance-cannon-tower)
@@ -1475,14 +1816,6 @@
 ;;
 (define ai:orc-land-attack-endloop
   '((writes nil "Looping !\n")
-    (ai:force 0 'unit-grunt 1 'unit-berserker 2 'unit-ogre-mage 4
-       'unit-catapult 1 'unit-death-knight 4)
-    (ai:force 1 'unit-grunt 1 'unit-berserker 2 'unit-ogre-mage 4
-       'unit-catapult 1 'unit-death-knight 2)
-    (ai:force 2 'unit-dragon 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
 
     (ai:sleep 500)
     (ai:script ai:orc-land-attack-endloop) ) )
@@ -1499,18 +1832,12 @@
     (ai:set  'unit-peon 4)
     (ai:need 'unit-troll-lumber-mill)
     (ai:need 'unit-mythical-barracks)
-    (ai:force 0 'unit-grunt 2)
-    (ai:force 1 'unit-grunt 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 3)
 
     (ai:set  'unit-peon 9)
     (ai:sleep  500)
     (ai:need 'unit-mythical-blacksmith)
-    (ai:force 0 'unit-grunt 2 'unit-axethrower 1)
-    (ai:force 1 'unit-grunt 2 'unit-axethrower 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 4 'unit-axethrower 2)
 
     (ai:sleep  500)
     (ai:research 'upgrade-battle-axe1)
@@ -1521,33 +1848,22 @@
     (ai:research 'upgrade-throwing-axe2)
     (ai:need 'unit-mythical-barracks)
 
-    (ai:force 0 'unit-grunt 3 'unit-axethrower 2)
-    (ai:force 1 'unit-grunt 3 'unit-axethrower 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 6 'unit-axethrower 4)
 
     (ai:sleep  500)
     (ai:set  'unit-peon 15)
-    (ai:force 0 'unit-grunt 3 'unit-axethrower 2)
-    (ai:force 1 'unit-grunt 3 'unit-axethrower 1 'unit-catapult 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 6 'unit-axethrower 2 'unit-catapult 1)
 
     (ai:sleep  500)
     (ai:upgrade-to 'unit-stronghold)
     (ai:wait 'unit-stronghold)
 
-    (ai:force 1 'unit-grunt 3 'unit-axethrower 1 'unit-catapult 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 7 'unit-axethrower 3 'unit-catapult 1)
 
     (ai:sleep  500)
     (ai:need 'unit-great-hall)
     (ai:need 'unit-ogre-mound)
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 6 'unit-catapult 1)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 2 'unit-catapult 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 7 'unit-ogre 10 'unit-catapult 
2)
 
     (ai:sleep  500)
     (ai:need 'unit-mythical-watch-tower)
@@ -1559,11 +1875,6 @@
     (ai:set  'unit-peon 19)
     (ai:wait 'unit-fortress)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 6 'unit-catapult 1)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 2 'unit-catapult 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
     (ai:sleep  500)
     (ai:need 'unit-mythical-watch-tower)
     (ai:upgrade-to 'unit-mythical-guard-tower)
@@ -1574,12 +1885,7 @@
     (ai:research 'upgrade-bloodlust)
     (ai:research 'upgrade-runes)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 0 'unit-ogre-mage 5
-       'unit-catapult 1)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 0 'unit-ogre-mage 3
-       'unit-catapult 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre 0 'unit-ogre-mage 
10       'unit-catapult 1)
 
     (ai:sleep  500)
     (ai:need 'unit-mythical-watch-tower)
@@ -1590,12 +1896,7 @@
     (ai:research 'upgrade-unholy-armor)
     (ai:research 'upgrade-death-and-decay)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 6
-       'unit-catapult 1 'unit-death-knight 2)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 2
-       'unit-catapult 1 'unit-death-knight 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 10 
'unit-catapult 2 'unit-death-knight 2)
 
     (ai:sleep  500)
     (ai:research 'upgrade-haste)
@@ -1605,37 +1906,21 @@
     (ai:upgrade-to 'unit-mythical-guard-tower)
     (ai:research 'upgrade-whirlwind)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 6
-       'unit-catapult 1 'unit-death-knight 5)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 2
-       'unit-catapult 1 'unit-death-knight 1)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 5 'unit-ogre-mage 16 
'unit-catapult 3 'unit-death-knight 5)
+
     (ai:wait-force 1)          ;; wait until attack party is completed
     (ai:attack-with-force 1)
 
     (ai:sleep  500)
     (ai:need 'unit-dragon-roost)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 6
-       'unit-catapult 1 'unit-death-knight 5)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 2 'unit-ogre-mage 2
-       'unit-catapult 1 'unit-death-knight 1)
-    (ai:force 2 'unit-dragon 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 4 'unit-ogre-mage 16 
'unit-catapult 3 'unit-death-knight 6)
 
     (ai:sleep  500)
     (ai:research 'upgrade-berserker)
     (ai:research 'upgrade-berserker-scouting)
     (ai:research 'upgrade-raise-dead)
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
-       'unit-ogre-mage 6 'unit-catapult 1 'unit-death-knight 5)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
-       'unit-ogre-mage 2 'unit-catapult 1 'unit-death-knight 1)
-    (ai:force 2 'unit-dragon 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
+    (ai:force 0 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 4        
'unit-ogre-mage 16 'unit-catapult 3 'unit-death-knight 6 'unit-dragon 4)
 
     (ai:sleep  500)
     (ai:need 'unit-great-hall)
@@ -1646,15 +1931,6 @@
     (ai:need 'unit-alchemist)
     (ai:research 'upgrade-light-axes)
 
-    (ai:force 0 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
-       'unit-ogre-mage 6 'unit-catapult 1 'unit-death-knight 5)
-    (ai:force 1 'unit-grunt 1 'unit-axethrower 0 'unit-ranger 2
-       'unit-ogre-mage 2 'unit-catapult 1 'unit-death-knight 1)
-    (ai:force 2 'unit-dragon 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-    (ai:attack-with-force 2)
-
     (ai:sleep  500)
     (ai:need 'unit-mythical-watch-tower)
     (ai:upgrade-to 'unit-mythical-cannon-tower)
@@ -1705,12 +1981,7 @@
 (define ai:hum-04-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep 25000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:sleep 22000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    
     (ai:script ai:hum-04-attack-endloop) ) )
 
 (define-ai 'hum-04 "*" "hum-04"
@@ -1723,45 +1994,17 @@
 
     (ai:need (ai:platform))
 
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 3 (ai:shooter) 4)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1 (ai:transporter) 1)
+    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 3 (ai:shooter) 4 
(ai:transporter) 1)
     (ai:sleep 27000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:set  (ai:transporter) 2)
     (ai:sleep 22000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 22000)
-    (ai:force 0 (ai:destroyer) 0 (ai:soldier) 3 (ai:shooter) 3)
-    (ai:force 2 (ai:destroyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:sleep 22000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 3 (ai:shooter) 3)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 2 (ai:transporter) 1)
-    (ai:force 2 (ai:destroyer) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 18000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 3 (ai:shooter) 4)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-
-    (ai:sleep 27000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 2 (ai:shooter) 3)
-    (ai:force 1 (ai:soldier) 3 (ai:shooter) 2 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-
-    (ai:sleep 24000)
-    (ai:force 0 (ai:destroyer) 0 (ai:soldier) 2 (ai:shooter) 3)
-    (ai:force 1 (ai:soldier) 3 (ai:shooter) 2 (ai:transporter) 1)
-    (ai:force 2 (ai:destroyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
 
     (ai:script ai:hum-04-attack-endloop) ))
 
@@ -1773,12 +2016,6 @@
 (define ai:orc-04-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep 10500)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:sleep 10500)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
     (ai:script ai:orc-04-attack-endloop) ) )
 
 (define-ai 'orc-04 "*" "orc-04"
@@ -1793,41 +2030,19 @@
     (ai:force 0 (ai:soldier) 3 (ai:shooter) 4 (ai:destroyer) 2)
     (ai:need (ai:platform))
 
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1)
-    (ai:sleep 27000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:set  (ai:transporter) 2)
     (ai:sleep 15000)
-    (ai:force 0 (ai:soldier) 3 (ai:shooter) 3 (ai:destroyer) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 6 (ai:shooter) 5 (ai:destroyer) 2)
 
     (ai:sleep 15000)
-    (ai:force 0 (ai:soldier) 3 (ai:shooter) 3 (ai:destroyer) 0)
-    (ai:force 2 (ai:destroyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:sleep 19500)
-    (ai:force 0 (ai:soldier) 4 (ai:shooter) 4 (ai:destroyer) 0)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 10 (ai:shooter) 8 (ai:destroyer) 2)
 
     (ai:sleep 12000)
-    (ai:force 0 (ai:soldier) 4 (ai:shooter) 4 (ai:destroyer) 1)
-    (ai:force 2 (ai:destroyer) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:sleep 13500)
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 3 (ai:destroyer) 1)
-    (ai:force 1 (ai:soldier) 3 (ai:shooter) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 30500)
 
@@ -1841,26 +2056,12 @@
 (define ai:hum-05-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep 18000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 12000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 1 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 24000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 0 (ai:shooter) 1)
-    (ai:force 1 (ai:soldier) 3 (ai:shooter) 2 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 14000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 0 (ai:shooter) 1)
-    (ai:force 2 (ai:destroyer) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:script ai:hum-05-attack-endloop) ) )
 
@@ -1875,43 +2076,22 @@
 
     (ai:need (ai:platform))
 
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 2 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:force 2 (ai:destroyer) 1)
-    (ai:sleep 6000)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+    (ai:force 0 (ai:destroyer) 3 (ai:soldier) 4 (ai:shooter) 3 
(ai:transporter) 1)
 
     (ai:sleep 3000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 4000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 4000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 12000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 1 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:destroyer) 4 (ai:soldier) 6 (ai:shooter) 4 
(ai:transporter) 1)
+
 
     (ai:sleep 14000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 12000)
-    (ai:force 0 (ai:destroyer) 2 (ai:soldier) 2 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-05-attack-endloop) ))
 
@@ -1924,34 +2104,18 @@
 (define ai:hum-06-attack-endloop
   '((writes nil "Looping !\n")
     (ai:force 0 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 1 )
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 3 (ai:cavalrie) 2 )
     (ai:sleep 14000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:force 0 (ai:soldier) 1 (ai:shooter) 3 (ai:cavalrie) 2 )
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 1 )
     (ai:sleep 11000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:force 0 (ai:soldier) 0 (ai:shooter) 3 (ai:cavalrie) 2 )
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 )
     (ai:sleep 8000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:force 0 (ai:soldier) 0 (ai:shooter) 2 (ai:cavalrie) 2 )
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 2 (ai:cavalrie) 1 )
     (ai:sleep 11000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 1 (ai:shooter) 4 (ai:cavalrie) 1 )
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 2 )
     (ai:sleep 9000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-06-attack-endloop) ) )
 
@@ -1963,43 +2127,24 @@
     (ai:wait (ai:worker))      ;; start hangs if nothing available
 
     (ai:force 0 (ai:soldier) 3 (ai:shooter) 3)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1)
     (ai:sleep 4000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 3000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 4000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:need (ai:blacksmith))
     (ai:research (ai:upgrade-missile-1))
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 2)
-    (ai:sleep 9000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 4 (ai:shooter) 4)
 
     (ai:research (ai:upgrade-weapon-1))
 
-    (ai:force 0 (ai:soldier) 1 (ai:shooter) 2)
-    (ai:force 1 (ai:soldier) 3 (ai:shooter) 2)
+    (ai:force 0 (ai:soldier) 6 (ai:shooter) 4)
     (ai:sleep 13000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 1 (ai:shooter) 3 (ai:cavalrie) 1 )
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 2 )
+    (ai:force 0 (ai:soldier) 1 (ai:shooter) 3 (ai:cavalrie) 3 )
     (ai:sleep 14000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:upgrade-armor-1))
 
@@ -2026,22 +2171,11 @@
 (define ai:hum-08-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep 16000)
-    (ai:force 0 (ai:soldier) 1 (ai:shooter) 4 (ai:cavalrie) 2)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 1 (ai:shooter) 4 (ai:cavalrie) 3 (ai:catapult) 1)
 
     (ai:sleep 14000)
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 4 (ai:cavalrie) 1 (ai:catapult) 1)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 2 (ai:catapult) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 12000)
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 4 (ai:cavalrie) 0 (ai:catapult) 0)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 3 (ai:catapult) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-08-attack-endloop) ) )
 
@@ -2053,45 +2187,27 @@
     (ai:set  (ai:worker) 3)
     (ai:wait (ai:worker))      ;; start hangs if nothing available
 
-    (ai:force 0 (ai:soldier) 3 (ai:shooter) 3)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1)
+    (ai:force 0 (ai:soldier) 5 (ai:shooter) 4)
     (ai:sleep 14000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 5 (ai:shooter) 5 (ai:cavalrie) 0)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 2)
+    (ai:force 0 (ai:soldier) 5 (ai:shooter) 5 (ai:cavalrie) 3)
     (ai:sleep 10000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 4 (ai:cavalrie) 1)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 2)
     (ai:sleep 15000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:upgrade-cavalrie-mage))
     (ai:research (ai:cavalrie-mage-spell-1))
     (ai:research (ai:upgrade-missile-1))
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 5 (ai:cavalrie) 1)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 2 (ai:catapult) 1)
+    (ai:force 0 (ai:soldier) 2 (ai:shooter) 5 (ai:cavalrie) 4 (ai:catapult) 1)
     (ai:sleep 15000)
+
     (ai:research (ai:upgrade-weapon-1))
     (ai:research (ai:upgrade-armor-1))
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep 21000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:upgrade-elite-shooter))
     (ai:sleep 12000)
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 5 (ai:cavalrie) 2)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 1 (ai:catapult) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-08-attack-endloop) ))
 
@@ -2115,30 +2231,12 @@
 (define ai:hum-10-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep  5000)
-    (ai:force 0 (ai:soldier) 3 (ai:shooter) 3 (ai:cavalrie) 2 (ai:catapult) 1)
-    (ai:force 2 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 2 (ai:catapult) 1
-       (ai:transporter) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+    (ai:force 0 (ai:soldier) 4 (ai:shooter) 4 (ai:cavalrie) 4 (ai:catapult) 1 
(ai:transporter) 1)
 
     (ai:sleep  6000)
-    (ai:force 1 (ai:destroyer) 1 (ai:battleship) 0)
-    (ai:force 3 (ai:destroyer) 2 (ai:battleship) 1)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
+    (ai:force 0 (ai:destroyer) 3 (ai:battleship) 1)
 
     (ai:sleep  5000)
-    (ai:force 1 (ai:destroyer) 3 (ai:battleship) 1)
-    (ai:force 3 (ai:destroyer) 0 (ai:battleship) 0)
-    (ai:force 0 (ai:soldier) 4 (ai:shooter) 2 (ai:cavalrie) 2 (ai:catapult) 2)
-    (ai:force 2 (ai:soldier) 0 (ai:shooter) 2 (ai:cavalrie) 2 (ai:catapult) 0)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-
-    (ai:force 1 (ai:destroyer) 1 (ai:battleship) 1)
-    (ai:force 3 (ai:destroyer) 2 (ai:battleship) 0)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
 
     (ai:script ai:hum-10-attack-endloop) ) )
 
@@ -2154,13 +2252,10 @@
     (ai:wait (ai:worker))      ;; Wait for the workers
 
     (ai:set  (ai:transporter) 1)
-    (ai:force 0 (ai:destroyer) 2)
-    (ai:force 2 (ai:transporter) 1)
+    (ai:force 0 (ai:destroyer) 2 (ai:transporter) 1)
     (ai:sleep  6000)
-    (ai:force 2 (ai:transporter) 0)
     (ai:force 0 (ai:soldier) 4 (ai:shooter) 4
-      (ai:destroyer) 0 (ai:transporter) 1)
-    (ai:force 1 (ai:destroyer) 2)
+      (ai:destroyer) 2 (ai:transporter) 1)
 
     (ai:research (ai:upgrade-cavalrie-mage))
     (ai:research (ai:cavalrie-mage-spell-1))
@@ -2168,34 +2263,22 @@
     (ai:research (ai:mage-spell-2))
     (ai:research (ai:upgrade-missile-1))
 
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 2 (ai:transporter) 0)
-    (ai:force 2 (ai:soldier) 2 (ai:shooter) 2 (ai:transporter) 1)
-    (ai:force 1 (ai:destroyer) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
+    (ai:force 0 (ai:soldier) 4 (ai:shooter) 4 (ai:transporter) 1 
(ai:destroyer) 2)
 
     (ai:research (ai:upgrade-weapon-1))
     (ai:sleep  4000)
     (ai:research (ai:upgrade-armor-1))
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:sleep  5000)
-    (ai:force 1 (ai:destroyer) 3 (ai:battleship) 1)
+    (ai:force 0 (ai:destroyer) 3 (ai:battleship) 1)
     (ai:research (ai:upgrade-missile-2))
     (ai:research (ai:upgrade-weapon-2))
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:research (ai:upgrade-ship-cannon-1))
     (ai:sleep  3000)
     (ai:research (ai:upgrade-armor-2))
     (ai:research (ai:upgrade-ship-armor-1))
     (ai:research (ai:upgrade-elite-shooter))
-    (ai:force 0 (ai:soldier) 2 (ai:shooter) 3)
-    (ai:force 2 (ai:soldier) 2 (ai:shooter) 1 (ai:transporter) 1)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
     (ai:research (ai:upgrade-catapult-1))
     (ai:research (ai:upgrade-ship-cannon-2))
@@ -2205,17 +2288,9 @@
     (ai:sleep  5000)
     (ai:research (ai:upgrade-elite-shooter-2))
     (ai:research (ai:upgrade-elite-shooter-3))
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
 
-    (ai:force 0 (ai:soldier) 4 (ai:shooter) 3 (ai:cavalrie) 2 (ai:catapult) 1)
-    (ai:force 2 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 2 (ai:catapult) 1
-       (ai:transporter) 1)
     (ai:sleep  5000)
 
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-
     (ai:script ai:hum-10-attack-endloop) ))
 
 ;;=============================================================================
@@ -2226,28 +2301,14 @@
 (define ai:hum-11-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep  12000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 0)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
+    (ai:force 0 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
        (ai:mage) 3)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  8000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 1)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
+       (ai:mage) 3)
 
     (ai:sleep  13000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 0)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 3)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-11-attack-endloop) ) )
 
@@ -2255,65 +2316,34 @@
   '(
     ;; Define the main AI script.
     (begin (ai:debug #f)
-      (ai:force-role 0 'defend) (ai:force-role 1 'attack)
-      (ai:force-role 2 'attack)
       (ai:sleep (ai:get-sleep-cycles)))
     (ai:set  (ai:worker) 8)
     (ai:wait (ai:worker))      ;; Wait for the workers
 
     (ai:sleep  6000)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 2 (ai:cavalrie) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 0 (ai:cavalrie) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 2 (ai:shooter) 2 (ai:cavalrie) 2)
 
     (ai:sleep  6000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  7000)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 1 (ai:cavalrie) 2)
-    (ai:force 1 (ai:soldier) 2 (ai:shooter) 1 (ai:cavalrie) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 2 (ai:shooter) 2 (ai:cavalrie) 2)
 
     (ai:sleep  5000)
-    (ai:force 1 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0)
     (ai:force 0 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 2 (ai:catapult) 1)
     (ai:research (ai:upgrade-missile-1))
     (ai:research (ai:upgrade-weapon-1))
     (ai:research (ai:upgrade-armor-1))
 
     (ai:sleep  6000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 3)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1  
(ai:mage) 3)
 
     (ai:sleep  9000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 1)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  7000)
     (ai:research (ai:upgrade-elite-shooter))
     (ai:research (ai:upgrade-elite-shooter-1))
     (ai:sleep  13000)
 
-    (ai:force 2 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 1)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 1)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 2)
-    (ai:wait-force 2)          ;; wait until attack party is completed
-    (ai:attack-with-force 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:upgrade-elite-shooter-2))
     (ai:research (ai:mage-spell-1))
@@ -2324,37 +2354,18 @@
     (ai:research (ai:mage-spell-2))
     (ai:research (ai:upgrade-weapon-2))
     (ai:sleep  12000)
-    (ai:force 2 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 0)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 2)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+
     (ai:research (ai:upgrade-armor-2))
     (ai:research (ai:mage-spell-3))
     (ai:research (ai:mage-spell-4))
     (ai:research (ai:upgrade-catapult-1))
 
     (ai:sleep  8000)
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 1)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:cavalrie-mage-spell-1))
     (ai:research (ai:mage-spell-5))
     (ai:sleep  13000)
 
-    (ai:force 1 (ai:soldier) 1 (ai:shooter) 1 (ai:cavalrie) 1 (ai:catapult) 1
-       (ai:mage) 0)
-    (ai:force 0 (ai:soldier) 0 (ai:shooter) 0 (ai:cavalrie) 0 (ai:catapult) 0
-       (ai:mage) 3)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-11-attack-endloop) ))
 
@@ -2366,22 +2377,13 @@
 (define ai:hum-12-attack-endloop
   '((writes nil "Looping !\n")
     (ai:sleep  10000)
-    (ai:force 0 (ai:soldier) 1 (ai:cavalrie) 7 (ai:mage) 1)
-    (ai:force 1 (ai:soldier) 1 (ai:cavalrie) 3 (ai:mage) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:soldier) 2 (ai:cavalrie) 10 (ai:mage) 2)
 
     (ai:sleep  5000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  7000)
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 4
-       (ai:scout) 1) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 1
-       (ai:scout) 1) 
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
+    (ai:force 0 (ai:destroyer) 2 (ai:battleship) 2 (ai:submarine) 5
+       (ai:scout) 2) 
 
     (ai:script ai:hum-12-attack-endloop) ) )
 
@@ -2400,22 +2402,15 @@
     (ai:need (ai:platform))
     (ai:set  (ai:transporter) 2)
 
-    (ai:force 1 (ai:soldier) 2)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
     (ai:force 0 (ai:soldier) 2)
+
     (ai:sleep  2000)
 
-    (ai:force 2 (ai:destroyer) 2 (ai:battleship) 1 (ai:submarine) 3) 
-    (ai:force 3 (ai:destroyer) 0 (ai:battleship) 1 (ai:submarine) 1) 
+    (ai:force 0 (ai:destroyer) 2 (ai:battleship) 2 (ai:submarine) 4) 
 
     (ai:sleep  3000)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
-
+    
     (ai:force 0 (ai:soldier) 1 (ai:cavalrie) 10 (ai:mage) 2)
-    (ai:force 1 (ai:soldier) 1 )
 
     (ai:research (ai:mage-spell-1))
     (ai:research (ai:upgrade-cavalrie-mage))
@@ -2429,10 +2424,7 @@
     (ai:research (ai:upgrade-ship-armor-1))
     (ai:sleep  4000)
 
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 3) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 1) 
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
+    (ai:force 0 (ai:destroyer) 2 (ai:battleship) 2 (ai:submarine) 4) 
 
     (ai:research (ai:upgrade-ship-cannon-2))
     (ai:research (ai:upgrade-ship-armor-2))
@@ -2440,30 +2432,15 @@
     (ai:research (ai:upgrade-catapult-2))
     (ai:sleep  6000)
 
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 3) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 2) 
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
+    (ai:force 0 (ai:destroyer) 2 (ai:battleship) 2 (ai:submarine) 5) 
 
     (ai:sleep  7000)
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 2) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 1 (ai:submarine) 3) 
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
 
     (ai:sleep  5000)
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 0 (ai:submarine) 2) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 2 (ai:submarine) 3) 
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
-
-    (ai:force 0 (ai:soldier) 1 (ai:cavalrie) 10 (ai:mage) 2 (ai:catapult) 1)
-    (ai:force 1 (ai:soldier) 1 (ai:catapult) 1)
-
-    (ai:force 2 (ai:destroyer) 1 (ai:battleship) 0 (ai:submarine) 2
-       (ai:scout) 1) 
-    (ai:force 3 (ai:destroyer) 1 (ai:battleship) 2 (ai:submarine) 3
-       (ai:scout) 1) 
+
+    (ai:force 0
+             (ai:soldier) 1 (ai:cavalrie) 10 (ai:mage) 2 (ai:catapult) 1
+             (ai:destroyer) 2 (ai:battleship) 2 (ai:submarine) 5 (ai:scout) 2) 
 
     (ai:research (ai:upgrade-missile-1))
     (ai:research (ai:upgrade-weapon-1))
@@ -2488,29 +2465,18 @@
   '((writes nil "Looping !\n")
 
     (ai:sleep  12000)
-    (ai:force 0 (ai:cavalrie) 1 (ai:mage) 1 (ai:catapult) 2)
-    (ai:force 1 (ai:cavalrie) 2 (ai:shooter) 1 (ai:mage) 1 (ai:catapult) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
+    (ai:force 0 (ai:cavalrie) 3 (ai:mage) 2 (ai:shooter) 1 (ai:catapult) 2)
 
     (ai:sleep  14000)
-    (ai:force 2 (ai:flyer) 1)
-    (ai:force 3 (ai:flyer) 3)
+    (ai:force 0 (ai:flyer) 4)
     (ai:sleep  14000)
 
-    (ai:force 0 (ai:cavalrie) 1 (ai:mage) 2 (ai:catapult) 1)
-    (ai:force 1 (ai:cavalrie) 2 (ai:shooter) 1 (ai:mage) 0 (ai:catapult) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
     (ai:script ai:hum-13-attack-endloop) ) )
 
 (define-ai 'hum-13 "*" "hum-13"
   '(
     ;; Define the main AI script.
-    (begin (ai:debug #f)
-      (ai:force-role 0 'defend) (ai:force-role 1 'attack)
-      (ai:force-role 2 'defend) (ai:force-role 3 'attack)
+    (begin (ai:debug #f)      
       (ai:sleep (ai:get-sleep-cycles)))
 
     (ai:set  (ai:tanker) 2)
@@ -2532,49 +2498,25 @@
 
     (ai:sleep  4000)
 
-    (ai:force 0 (ai:cavalrie) 1 (ai:mage) 1)
-    (ai:force 1 (ai:cavalrie) 2 (ai:mage) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
-
-    (ai:force 0 (ai:cavalrie) 1 (ai:mage) 1)
-    (ai:force 1 (ai:cavalrie) 2 (ai:shooter) 1 (ai:mage) 1)
+    (ai:force 0 (ai:cavalrie) 4 (ai:mage) 2 (ai:shooter) 1)
     (ai:sleep  12000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  15000)
-    (ai:force 0 (ai:cavalrie) 0 (ai:mage) 1)
-    (ai:force 1 (ai:cavalrie) 3 (ai:shooter) 1 (ai:mage) 1)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:mage-spell-5))
     (ai:research (ai:upgrade-ship-cannon-1))
     (ai:research (ai:upgrade-ship-armor-1))
     (ai:research (ai:upgrade-ship-cannon-2))
     (ai:research (ai:upgrade-ship-armor-2))
-    (ai:force 0 (ai:cavalrie) 2 (ai:mage) 2 (ai:catapult) 1)
-    (ai:force 1 (ai:cavalrie) 1 (ai:shooter) 1 (ai:mage) 0 (ai:catapult) 1)
+    (ai:force 0 (ai:cavalrie) 3 (ai:shooter) 1 (ai:mage) 2 (ai:catapult) 1)
     (ai:sleep  15000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 2 (ai:flyer) 1)
-    (ai:force 3 (ai:flyer) 3)
+    (ai:force 0 (ai:flyer) 4)
     (ai:sleep  20000)
-    (ai:wait-force 3)          ;; wait until attack party is completed
-    (ai:attack-with-force 3)
 
     (ai:sleep  14000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  18000)
-    (ai:force 0 (ai:cavalrie) 2 (ai:mage) 2 (ai:catapult) 2)
-    (ai:force 1 (ai:cavalrie) 1 (ai:shooter) 1 (ai:mage) 0 (ai:catapult) 0)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:research (ai:upgrade-catapult-1))
     (ai:research (ai:upgrade-catapult-2))
@@ -2603,8 +2545,7 @@
     (ai:set  (ai:worker) 5)
     (ai:wait (ai:worker))      ;; Wait for the workers
 
-    (ai:force 0 (ai:cavalrie) 8)
-    (ai:force 1 (ai:cavalrie) 7)
+    (ai:force 0 (ai:cavalrie) 15)
 
     (ai:script ai:hum-14-orange-attack-endloop) ))
 
@@ -2641,29 +2582,16 @@
 ;;
 (define ai:hum-14-white-attack-endloop
   '((writes nil "Looping !\n")
-    (ai:force 0 (ai:flyer) 8)
-    (ai:force 1 (ai:flyer) 2)
+    (ai:force 0 (ai:flyer) 10)
     (ai:sleep  19000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:flyer) 5)
-    (ai:force 1 (ai:flyer) 4)
     (ai:sleep  20000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:flyer) 6)
-    (ai:force 1 (ai:flyer) 3)
+    (ai:force 0 (ai:flyer) 12)
+
     (ai:sleep  21000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
-    (ai:force 0 (ai:flyer) 3)
-    (ai:force 1 (ai:flyer) 6)
     (ai:sleep  20000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-14-white-attack-endloop) ) )
 
@@ -2677,20 +2605,13 @@
     (ai:set  (ai:worker) 9)
     (ai:wait (ai:worker))      ;; Wait for the workers
 
-    (ai:force 0 (ai:flyer) 9)
-    (ai:force 1 (ai:flyer) 1)
+    (ai:force 0 (ai:flyer) 10)
 
     (ai:sleep  64000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  12000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:sleep  18000)
-    (ai:wait-force 1)          ;; wait until attack party is completed
-    (ai:attack-with-force 1)
 
     (ai:script ai:hum-14-white-attack-endloop) ))
 
Index: stratagus/data/ccl/human/buttons.ccl
diff -u stratagus/data/ccl/human/buttons.ccl:1.26 
stratagus/data/ccl/human/buttons.ccl:1.27
--- stratagus/data/ccl/human/buttons.ccl:1.26   Fri Sep  5 14:10:54 2003
+++ stratagus/data/ccl/human/buttons.ccl        Thu Oct 23 14:38:33 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: buttons.ccl,v 1.26 2003/09/05 18:10:54 n0body Exp $
+;;     $Id: buttons.ccl,v 1.27 2003/10/23 18:38:33 n0body Exp $
 
 ;;----------------------------------------------------------------------------
 ;;     Define unit-button.
@@ -219,6 +219,7 @@
 
 (define-button 'pos 8 'level 0 'icon 'icon-polymorph
   'action 'cast-spell 'value 'spell-polymorph
+;  'action 'cast-spell 'value 'spell-suicide-bomber
   'allowed 'check-upgrade 'allow-arg '(upgrade-polymorph)
   'key "p" 'hint "~!POLYMORPH"
   'for-unit '(unit-mage unit-white-mage))
Index: stratagus/data/ccl/human/units.ccl
diff -u stratagus/data/ccl/human/units.ccl:1.43 
stratagus/data/ccl/human/units.ccl:1.44
--- stratagus/data/ccl/human/units.ccl:1.43     Mon Oct 13 19:01:25 2003
+++ stratagus/data/ccl/human/units.ccl  Thu Oct 23 14:38:33 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.43 2003/10/13 23:01:25 jsalmon3 Exp $
+;;     $Id: units.ccl,v 1.44 2003/10/23 18:38:33 n0body Exp $
 
 ;;=============================================================================
 ;;     Define unit-types.
@@ -231,7 +231,8 @@
       spell-flame-shield
       spell-invisibility
       spell-polymorph
-      spell-blizzard)
+      spell-blizzard
+      spell-suicide-bomber)
   'land-unit
   'coward
   'organic
Index: stratagus/data/ccl/spells.ccl
diff -u stratagus/data/ccl/spells.ccl:1.12 stratagus/data/ccl/spells.ccl:1.13
--- stratagus/data/ccl/spells.ccl:1.12  Wed Oct 22 15:28:04 2003
+++ stratagus/data/ccl/spells.ccl       Thu Oct 23 14:38:32 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: spells.ccl,v 1.12 2003/10/22 19:28:04 n0body Exp $

+;;     $Id: spells.ccl,v 1.13 2003/10/23 18:38:32 n0body Exp $

 

 ;; For documentation see stratagus/doc/ccl/ccl.html ;; FIXME write and move 
doc.

 

@@ -92,6 +92,15 @@
 (define-unit-type 'unit-skeleton)

 (define-unit-type 'unit-circle-of-power)

 

+(define-spell "spell-suicide-bomber"

+       'showname "Demolish"

+       'manacost 0

+       'range 10

+       'target 'position

+       'action '((demolish range 1 damage 400))

+       'sound-when-cast "holy vision"

+       'missile-when-cast "missile-normal-spell"

+)

 (define-spell "spell-holy-vision"

        'showname "Holy Vision"

        'manacost 70

Index: stratagus/doc/ChangeLog.html
diff -u stratagus/doc/ChangeLog.html:1.558 stratagus/doc/ChangeLog.html:1.559
--- stratagus/doc/ChangeLog.html:1.558  Wed Oct 22 15:28:05 2003
+++ stratagus/doc/ChangeLog.html        Thu Oct 23 14:38:33 2003
@@ -2,7 +2,7 @@
 <html>
 <head>
 <!--
-----   $Id: ChangeLog.html,v 1.558 2003/10/22 19:28:05 n0body Exp $
+----   $Id: ChangeLog.html,v 1.559 2003/10/23 18:38:33 n0body Exp $
 
 ----   (c) Copyright 1998-2003 by Lutz Sammer
 
@@ -36,6 +36,8 @@
 <li>Future 2.00 Release<p>
     <ul>
     <li>++
+    <li>Applied patch #1969 (AI enhancement) (from Ludovic Pollet).
+    <li>Added the demolish spell, though not complete (from Crestez Leonard).
     <li>Added the spawn-missile action, removed fireball death-coil whirlwind 
runes flame-shield (from Crestez Leonard).
     <li>Applied missile smoke patch #2133, fixed task #2786. (from Jarod 
Dauphin).
     <li>Made lots of missile changes, removed Missile::Controller. (from 
Crestez Leonard).
Index: stratagus/src/ai/Module.make
diff -u stratagus/src/ai/Module.make:1.3 stratagus/src/ai/Module.make:1.4
--- stratagus/src/ai/Module.make:1.3    Thu Sep 25 02:58:34 2003
+++ stratagus/src/ai/Module.make        Thu Oct 23 14:38:34 2003
@@ -1,3 +1,3 @@
-SRC += src/ai/ai_building.c src/ai/ai_force.c src/ai/ai_magic.c 
src/ai/ai_plan.c src/ai/ai_resource.c src/ai/ccl_ai.c src/ai/new_ai.c 
+SRC += src/ai/ai_building.c src/ai/ai_force.c src/ai/ai_magic.c 
src/ai/ai_plan.c src/ai/ai_resource.c src/ai/ccl_ai.c src/ai/new_ai.c 
src/ai/ai_rules.c
 HDRS += src/ai/ai_local.h
-OBJ += src/ai/$(OBJDIR)/ai_building.o src/ai/$(OBJDIR)/ai_force.o 
src/ai/$(OBJDIR)/ai_magic.o src/ai/$(OBJDIR)/ai_plan.o 
src/ai/$(OBJDIR)/ai_resource.o src/ai/$(OBJDIR)/ccl_ai.o 
src/ai/$(OBJDIR)/new_ai.o 
+OBJ += src/ai/$(OBJDIR)/ai_building.o src/ai/$(OBJDIR)/ai_force.o 
src/ai/$(OBJDIR)/ai_magic.o src/ai/$(OBJDIR)/ai_plan.o 
src/ai/$(OBJDIR)/ai_resource.o src/ai/$(OBJDIR)/ccl_ai.o 
src/ai/$(OBJDIR)/new_ai.o src/ai/$(OBJDIR)/ai_rules.o
Index: stratagus/src/ai/ai_building.c
diff -u stratagus/src/ai/ai_building.c:1.40 stratagus/src/ai/ai_building.c:1.41
--- stratagus/src/ai/ai_building.c:1.40 Mon Oct 13 22:47:35 2003
+++ stratagus/src/ai/ai_building.c      Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_building.c  -       AI building functions. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_building.c,v 1.40 2003/10/14 02:47:35 jsalmon3 Exp $
+//      $Id: ai_building.c,v 1.41 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -64,8 +64,7 @@
 **
 **     @note           Can be faster written.
 */
-local int AiCheckSurrounding(const Unit* worker,const UnitType* type,
-    int x, int y)
+local int AiCheckSurrounding( const Unit * worker, const UnitType * type, int 
x, int y )
 {
     int i;
     int h;
@@ -76,36 +75,48 @@
     --x;
     --y;
 
-    for (i = 0; i < w; ++i) {          // Top row
-       if ((x + i) < 0 || (x + i) > TheMap.Width) {    // FIXME: slow, 
worse,...
+    for ( i = 0; i < w; ++i ) {        // Top row
+       if ( ( x + i ) < 0 || ( x + i ) > TheMap.Width ) {      // FIXME: slow, 
worse,...
            continue;
        }
-       if (!((x + i) == worker->X && y == worker->Y) && y >= 0 &&
-               TheMap.Fields[x + i + y * TheMap.Width].Flags & 
(MapFieldUnpassable |
-                   MapFieldWall | MapFieldRocks | MapFieldForest | 
MapFieldBuilding)) {
+       if ( !( ( x + i ) == worker->X && y == worker->Y ) && y >= 0 &&
+            TheMap.Fields[x + i + y * TheMap.Width].Flags & ( 
MapFieldUnpassable |
+                                                              MapFieldWall | 
MapFieldRocks |
+                                                              MapFieldForest |
+                                                              MapFieldBuilding 
) ) {
            return 0;
-       }                               // Bot row
-       if (!((x + i) == worker->X && (y + h) == worker->Y) && (y + h) < 
TheMap.Height &&
-               TheMap.Fields[x + i + (y + h) * TheMap.Width].Flags & 
(MapFieldUnpassable |
-                   MapFieldWall | MapFieldRocks | MapFieldForest | 
MapFieldBuilding)) {
+       }                       // Bot row
+       if ( !( ( x + i ) == worker->X && ( y + h ) == worker->Y ) && ( y + h ) 
< TheMap.Height
+            && TheMap.Fields[x + i +
+                             ( y +
+                               h ) *
+                             TheMap.Width].
+            Flags & ( MapFieldUnpassable | MapFieldWall | MapFieldRocks | 
MapFieldForest |
+                      MapFieldBuilding ) ) {
            return 0;
        }
     }
 
     ++y;
     h -= 2;
-    for (i = 0; i < h; ++i) {          // Left row
-       if ((y + i) < 0 || (y + i) > TheMap.Height) {   // FIXME: slow, 
worse,...
+    for ( i = 0; i < h; ++i ) {        // Left row
+       if ( ( y + i ) < 0 || ( y + i ) > TheMap.Height ) {     // FIXME: slow, 
worse,...
            continue;
        }
-       if (!(x == worker->X && (y + i) == worker->Y) && x >= 0 &&
-               TheMap.Fields[x + (y + i) * TheMap.Width].Flags & 
(MapFieldUnpassable |
-                   MapFieldWall | MapFieldRocks | MapFieldForest | 
MapFieldBuilding)) {
+       if ( !( x == worker->X && ( y + i ) == worker->Y ) && x >= 0 &&
+            TheMap.Fields[x + ( y + i ) * TheMap.Width].Flags & ( 
MapFieldUnpassable |
+                                                                  MapFieldWall 
| MapFieldRocks
+                                                                  | 
MapFieldForest |
+                                                                  
MapFieldBuilding ) ) {
            return 0;
-       }                               // Right row
-       if (!((x + w) == worker->X && (y + i) == worker->Y) && (x + w) < 
TheMap.Width &&
-               TheMap.Fields[x + w + (y + i) * TheMap.Width].Flags & 
(MapFieldUnpassable |
-                   MapFieldWall | MapFieldRocks | MapFieldForest | 
MapFieldBuilding)) {
+       }                       // Right row
+       if ( !( ( x + w ) == worker->X && ( y + i ) == worker->Y ) && ( x + w ) 
< TheMap.Width
+            && TheMap.Fields[x + w +
+                             ( y +
+                               i ) *
+                             TheMap.Width].
+            Flags & ( MapFieldUnpassable | MapFieldWall | MapFieldRocks | 
MapFieldForest |
+                      MapFieldBuilding ) ) {
            return 0;
        }
     }
@@ -125,8 +136,8 @@
 **
 **     @note   This can be done faster, use flood fill.
 */
-local int AiFindBuildingPlace2(const Unit* worker, const UnitType* type,
-    int* dx, int* dy, int flag)
+local int AiFindBuildingPlace2( const Unit * worker, const UnitType * type,
+                               int *dx, int *dy, int flag )
 {
     int wx;
     int wy;
@@ -146,44 +157,44 @@
 
     state = 0;
     end = y + addy - 1;
-    for (;;) {                         // test rectangles around the place
-       switch (state) {
-           case 0:
-               if (y++ == end) {
-                   ++state;
-                   end = x + addx++;
-               }
-               break;
-           case 1:
-               if (x++ == end) {
-                   ++state;
-                   end = y - addy++;
-               }
-               break;
-           case 2:
-               if (y-- == end) {
-                   ++state;
-                   end = x - addx++;
-               }
-               break;
-           case 3:
-               if (x-- == end) {
-                   state = 0;
-                   end = y + addy++;
-                   if (addx >= TheMap.Width && addy >= TheMap.Height) {
-                       return 0;
-                   }
+    for ( ;; ) {               // test rectangles around the place
+       switch ( state ) {
+       case 0:
+           if ( y++ == end ) {
+               ++state;
+               end = x + addx++;
+           }
+           break;
+       case 1:
+           if ( x++ == end ) {
+               ++state;
+               end = y - addy++;
+           }
+           break;
+       case 2:
+           if ( y-- == end ) {
+               ++state;
+               end = x - addx++;
+           }
+           break;
+       case 3:
+           if ( x-- == end ) {
+               state = 0;
+               end = y + addy++;
+               if ( addx >= TheMap.Width && addy >= TheMap.Height ) {
+                   return 0;
                }
-               break;
+           }
+           break;
        }
 
-       // FIXME: this check outside the map could be speeded up.
-       if (y < 0 || x < 0 || y >= TheMap.Height || x >= TheMap.Width) {
+       // FIXME: this check outside the map could be speeded up.
+       if ( y < 0 || x < 0 || y >= TheMap.Height || x >= TheMap.Width ) {
            continue;
        }
-       if (CanBuildUnitType(worker, type, x, y) &&
-               (!flag || AiCheckSurrounding(worker, type, x, y)) &&
-               PlaceReachable(worker, x, y, 1)) {
+       if ( CanBuildUnitType( worker, type, x, y ) &&
+            ( !flag || AiCheckSurrounding( worker, type, x, y ) ) &&
+            PlaceReachable( worker, x, y, 1 ) ) {
            *dx = x;
            *dy = y;
            return 1;
@@ -206,15 +217,17 @@
 **     @param flag     Flag if surrounding must be free.
 **     @return         True if place found, false if no found.
 */
-local int AiFindBuildingPlace2(const Unit* worker, const UnitType* type,
-    int ox, int oy, int* dx, int* dy, int flag)
+local int AiFindBuildingPlace2( const Unit * worker, const UnitType * type,
+                               int ox, int oy, int *dx, int *dy, int flag )
 {
-    static const int xoffset[] = {  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[] = { -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
-    } *points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -226,107 +239,106 @@
     int ep;
     int i;
     int w;
-    unsigned char* m;
-    unsigned char* matrix;
+    unsigned char *m;
+    unsigned char *matrix;
 
-    points = malloc(TheMap.Width * TheMap.Height);
-    size = TheMap.Width * TheMap.Height / sizeof(*points);
+    points = malloc( TheMap.Width * TheMap.Height );
+    size = TheMap.Width * TheMap.Height / sizeof ( *points );
 
     x = ox;
     y = oy;
-    //
-    // Look if we can build at current place.
-    //
-    if (CanBuildUnitType(worker, type, x, y) &&
-           (!flag || AiCheckSurrounding(worker, type, x, y))) {
+   //
+   //  Look if we can build at current place.
+   //
+    if ( CanBuildUnitType( worker, type, x, y ) &&
+        ( !flag || AiCheckSurrounding( worker, type, x, y ) ) ) {
        *dx = x;
        *dy = y;
-       free(points);
+       free( points );
        return 1;
     }
-
-    //
-    // Make movement matrix.
-    //
+   //
+   //  Make movement matrix.
+   //
     matrix = CreateMatrix();
     w = TheMap.Width + 2;
 
-    mask = UnitMovementMask(worker);
-    // Ignore all possible mobile units.
-    mask &= ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
+    mask = UnitMovementMask( worker );
+   // Ignore all possible mobile units.
+    mask &= ~( MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit );
 
     points[0].X = x;
     points[0].Y = y;
-    // also use the bottom right
-    if (type->TileWidth>1 && x + type->TileWidth - 1 < TheMap.Width &&
-           y + type->TileHeight - 1 < TheMap.Height) {
+   // also use the bottom right
+    if ( type->TileWidth > 1 && x + type->TileWidth - 1 < TheMap.Width &&
+        y + type->TileHeight - 1 < TheMap.Height ) {
        points[1].X = x + type->TileWidth - 1;
        points[1].Y = y + type->TileWidth - 1;
-       ep = wp = 2;                            // start with two points
+       ep = wp = 2;            // start with two points
     } else {
-       ep = wp = 1;                            // start with one point
+       ep = wp = 1;            // start with one point
     }
     matrix += w + w + 2;
     rp = 0;
-    matrix[x + y * w] = 1;                             // mark start point
+    matrix[x + y * w] = 1;     // mark start point
 
-    //
-    // Pop a point from stack, push all neighbours which could be entered.
-    //
-    for (;;) {
-       while (rp != ep) {
+   //
+   //  Pop a point from stack, push all neighbours which could be entered.
+   //
+    for ( ;; ) {
+       while ( rp != ep ) {
            rx = points[rp].X;
            ry = points[rp].Y;
-           for (i = 0; i < 8; ++i) {           // mark all neighbors
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
                x = rx + xoffset[i];
                y = ry + yoffset[i];
                m = matrix + x + y * w;
-               if (*m) {                       // already checked
+               if ( *m ) {     // already checked
                    continue;
                }
 
-               DebugLevel3Fn("Checking to build %s(%s) at %d,%d\n" _C_
-                   type->Ident _C_ type->Name _C_ x _C_ y);
+               DebugLevel3Fn( "Checking to build %s(%s) at %d,%d\n" _C_
+                              type->Ident _C_ type->Name _C_ x _C_ y );
 
-               //
-               //      Look if we can build here.
-               //
-               if (CanBuildUnitType(worker, type, x, y) &&
-                       (!flag || AiCheckSurrounding(worker, type, x, y))) {
+              //
+              //      Look if we can build here.
+              //
+               if ( CanBuildUnitType( worker, type, x, y ) &&
+                    ( !flag || AiCheckSurrounding( worker, type, x, y ) ) ) {
                    *dx = x;
                    *dy = y;
-                   free(points);
-                   DebugLevel3Fn("Found a building place!!!\n");
+                   free( points );
+                   DebugLevel3Fn( "Found a building place!!!\n" );
                    return 1;
                }
 
-               if (CanMoveToMask(x, y, mask)) {        // reachable
+               if ( CanMoveToMask( x, y, mask ) ) {    // reachable
                    *m = 1;
-                   points[wp].X = x;           // push the point
+                   points[wp].X = x;   // push the point
                    points[wp].Y = y;
-                   if (++wp >= size) {         // round about
+                   if ( ++wp >= size ) {       // round about
                        wp = 0;
                    }
-               } else {                        // unreachable
+               } else {        // unreachable
                    *m = 99;
                }
            }
 
-           if (++rp >= size) {                 // round about
+           if ( ++rp >= size ) {       // round about
                rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if (rp == wp) {                 // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
        ep = wp;
     }
 
-    free(points);
+    free( points );
 
     return 0;
 }
@@ -352,15 +364,16 @@
 **     @todo   FIXME: This is slow really slow, using two flood fills, is not
 **             a perfect solution.
 */
-local int AiFindHallPlace(const Unit* worker, const UnitType* type,
-    int* dx, int* dy)
+local int AiFindHallPlace( const Unit * worker, const UnitType * type, int 
*dx, int *dy )
 {
-    static const int xoffset[] = {  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[] = { -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
-    } *points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -372,21 +385,21 @@
     int ep;
     int i;
     int w;
-    unsigned char* m;
-    unsigned char* morg;
-    unsigned char* matrix;
-    Unit* mine;
+    unsigned char *m;
+    unsigned char *morg;
+    unsigned char *matrix;
+    Unit *mine;
     int destx;
     int desty;
 
     destx = x = worker->X;
     desty = y = worker->Y;
     size = TheMap.Width * TheMap.Height / 4;
-    points = malloc(size * sizeof(*points));
+    points = malloc( size * sizeof ( *points ) );
 
-    //
-    // Make movement matrix. FIXME: can create smaller matrix.
-    //
+   //
+   //  Make movement matrix. FIXME: can create smaller matrix.
+   //
     morg = MakeMatrix();
     w = TheMap.Width + 2;
     matrix = morg + w + w + 2;
@@ -394,30 +407,29 @@
     points[0].X = x;
     points[0].Y = y;
     rp = 0;
-    matrix[x + y * w] = 1;                     // mark start point
-    ep = wp = 1;                               // start with one point
+    matrix[x + y * w] = 1;     // mark start point
+    ep = wp = 1;               // start with one point
 
-    mask = UnitMovementMask(worker);
+    mask = UnitMovementMask( worker );
 
-    //
-    // Pop a point from stack, push all neighbors which could be entered.
-    //
-    for (;;) {
-       while (rp!=ep) {
+   //
+   //  Pop a point from stack, push all neighbors which could be entered.
+   //
+    for ( ;; ) {
+       while ( rp != ep ) {
            rx = points[rp].X;
            ry = points[rp].Y;
-           for (i = 0; i < 8; ++i) {           // mark all neighbors
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
                x = rx + xoffset[i];
                y = ry + yoffset[i];
                m = matrix + x + y * w;
-               if (*m) {                       // already checked
+               if ( *m ) {     // already checked
                    continue;
                }
-
-               //
-               //      Look if there is a mine
-               //
-               if ((mine = ResourceOnMap(x, y, GoldCost))) {
+              //
+              //      Look if there is a mine
+              //
+               if ( ( mine = ResourceOnMap( x, y, GoldCost ) ) ) {
                    int buildings;
                    int j;
                    int minx;
@@ -425,86 +437,86 @@
                    int miny;
                    int maxy;
                    int nunits;
-                   Unit* units[UnitMax];
+                   Unit *units[UnitMax];
 
                    buildings = 0;
 
-                   //
-                   //  Check units around mine
-                   //
+                  //
+                  //  Check units around mine
+                  //
                    minx = mine->X - 5;
-                   if (minx < 0) {
+                   if ( minx < 0 ) {
                        minx = 0;
                    }
                    miny = mine->Y - 5;
-                   if (miny < 0) {
+                   if ( miny < 0 ) {
                        miny = 0;
                    }
                    maxx = mine->X + mine->Type->TileWidth + 5;
-                   if (maxx > TheMap.Width) {
+                   if ( maxx > TheMap.Width ) {
                        maxx = TheMap.Width;
                    }
                    maxy = mine->Y + mine->Type->TileHeight + 5;
-                   if (maxy > TheMap.Height) {
+                   if ( maxy > TheMap.Height ) {
                        maxy = TheMap.Height;
                    }
 
-                   nunits = SelectUnits(minx, miny, maxx, maxy, units);
-                   for (j = 0; j < nunits; ++j) {
-                       // Enemy near mine
-                       if (AiPlayer->Player->Enemy & (1 << 
units[j]->Player->Player)) {
+                   nunits = SelectUnits( minx, miny, maxx, maxy, units );
+                   for ( j = 0; j < nunits; ++j ) {
+                      // Enemy near mine
+                       if ( AiPlayer->Player->Enemy & ( 1 << 
units[j]->Player->Player ) ) {
                            break;
                        }
-                       // Town hall near mine
-                       if (units[j]->Type->CanStore[GoldCost]) {
+                      // Town hall near mine
+                       if ( units[j]->Type->CanStore[GoldCost] ) {
                            break;
                        }
-                       // Town hall may not be near but we may be using it, 
check
-                       // for 2 buildings near it and assume it's been used
-                       if (units[j]->Type->Building &&
-                               !units[j]->Type->GivesResource == GoldCost) {
+                      // Town hall may not be near but we may be using it, 
check
+                      // for 2 buildings near it and assume it's been used
+                       if ( units[j]->Type->Building &&
+                            !units[j]->Type->GivesResource == GoldCost ) {
                            ++buildings;
-                           if (buildings == 2) {
+                           if ( buildings == 2 ) {
                                break;
                            }
                        }
                    }
-                   if (j == nunits) {
-                       if (AiFindBuildingPlace2(worker, type, x, y, dx, dy, 
0)) {
-                           free(morg);
-                           free(points);
+                   if ( j == nunits ) {
+                       if ( AiFindBuildingPlace2( worker, type, x, y, dx, dy, 
0 ) ) {
+                           free( morg );
+                           free( points );
                            return 1;
                        }
                    }
                }
 
-               if (CanMoveToMask(x, y, mask)) {        // reachable
+               if ( CanMoveToMask( x, y, mask ) ) {    // reachable
                    *m = 1;
-                   points[wp].X = x;           // push the point
+                   points[wp].X = x;   // push the point
                    points[wp].Y = y;
-                   if (++wp >= size) {         // round about
+                   if ( ++wp >= size ) {       // round about
                        wp = 0;
                    }
-               } else {                        // unreachable
+               } else {        // unreachable
                    *m = 99;
                }
            }
-           if (++rp >= size) {                 // round about
+           if ( ++rp >= size ) {       // round about
                rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if (rp == wp) {                 // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
        ep = wp;
     }
 
-    free(morg);
-    free(points);
+    free( morg );
+    free( points );
     return 0;
 }
 
@@ -520,15 +532,16 @@
 **     @todo   FIXME: This is slow really slow, using two flood fills, is not
 **             a perfect solution.
 */
-local int AiFindLumberMillPlace(const Unit* worker, const UnitType* type,
-    int* dx, int* dy)
+local int AiFindLumberMillPlace( const Unit * worker, const UnitType * type, 
int *dx, int *dy )
 {
-    static const int xoffset[] = {  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[] = { -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
-    } *points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -540,18 +553,18 @@
     int ep;
     int i;
     int w;
-    unsigned char* m;
-    unsigned char* morg;
-    unsigned char* matrix;
+    unsigned char *m;
+    unsigned char *morg;
+    unsigned char *matrix;
 
     x = worker->X;
     y = worker->Y;
     size = TheMap.Width * TheMap.Height / 4;
-    points = malloc(size * sizeof(*points));
+    points = malloc( size * sizeof ( *points ) );
 
-    //
-    // Make movement matrix.
-    //
+   //
+   //  Make movement matrix.
+   //
     morg = MakeMatrix();
     w = TheMap.Width + 2;
     matrix = morg + w + w + 2;
@@ -559,65 +572,64 @@
     points[0].X = x;
     points[0].Y = y;
     rp = 0;
-    matrix[x + y * w] = 1;                     // mark start point
-    ep = wp = 1;                               // start with one point
+    matrix[x + y * w] = 1;     // mark start point
+    ep = wp = 1;               // start with one point
 
-    mask = UnitMovementMask(worker);
+    mask = UnitMovementMask( worker );
 
-    //
-    // Pop a point from stack, push all neightbors which could be entered.
-    //
-    for (;;) {
-       while (rp != ep) {
+   //
+   //  Pop a point from stack, push all neightbors which could be entered.
+   //
+    for ( ;; ) {
+       while ( rp != ep ) {
            rx = points[rp].X;
            ry = points[rp].Y;
-           for (i = 0; i < 8; ++i) {           // mark all neighbors
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
                x = rx + xoffset[i];
                y = ry + yoffset[i];
                m = matrix + x + y * w;
-               if (*m) {                       // already checked
+               if ( *m ) {     // already checked
                    continue;
                }
-
-               //
-               //      Look if there is wood
-               //
-               if (ForestOnMap(x, y)) {
-                   if (AiFindBuildingPlace2(worker, type, x, y, dx, dy, 1)) {
-                       free(morg);
-                       free(points);
+              //
+              //      Look if there is wood
+              //
+               if ( ForestOnMap( x, y ) ) {
+                   if ( AiFindBuildingPlace2( worker, type, x, y, dx, dy, 1 ) 
) {
+                       free( morg );
+                       free( points );
                        return 1;
                    }
                }
 
-               if (CanMoveToMask(x, y, mask)) {        // reachable
+               if ( CanMoveToMask( x, y, mask ) ) {    // reachable
                    *m = 1;
-                   points[wp].X = x;           // push the point
+                   points[wp].X = x;   // push the point
                    points[wp].Y = y;
-                   if (++wp >= size) {         // round about
+                   if ( ++wp >= size ) {       // round about
                        wp = 0;
                    }
-               } else {                        // unreachable
+               } else {        // unreachable
                    *m = 99;
                }
            }
 
-           if (++rp >= size) {                 // round about
+           if ( ++rp >= size ) {       // round about
                rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if (rp == wp) {                 // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
        ep = wp;
     }
 
-    free(morg);
-    free(points);
+    free( morg );
+    free( points );
     return 0;
 }
 
@@ -633,39 +645,34 @@
 **     @todo   Better and faster way to find building place of oil platforms
 **             Special routines for special buildings.
 */
-global int AiFindBuildingPlace(const Unit* worker, const UnitType* type,
-    int* dx, int* dy)
+global int AiFindBuildingPlace( const Unit * worker, const UnitType * type, 
int *dx, int *dy )
 {
 
-    //
-    // Find a good place for a new hall
-    //
-    DebugLevel0Fn("Want to build a %s(%s)\n" _C_ type->Ident _C_ type->Name);
-    if (type->CanStore[GoldCost] && AiFindHallPlace(worker, type, dx, dy)) {
-       DebugLevel0Fn("Found place for town hall (%s,%s)\n" _C_
-           type->Ident _C_ type->Name);
+   //
+   //  Find a good place for a new hall
+   //
+    DebugLevel0Fn( "Want to build a %s(%s)\n" _C_ type->Ident _C_ type->Name );
+    if ( type->CanStore[GoldCost] && AiFindHallPlace( worker, type, dx, dy ) ) 
{
+       DebugLevel0Fn( "Found place for town hall (%s,%s)\n" _C_ type->Ident 
_C_ type->Name );
        return 1;
     }
-
-    //
-    // Find a place near wood for a lumber mill
-    //
-    if (type->CanStore[WoodCost] && AiFindLumberMillPlace(worker, type, dx, 
dy)) {
+   //
+   //  Find a place near wood for a lumber mill
+   //
+    if ( type->CanStore[WoodCost] && AiFindLumberMillPlace( worker, type, dx, 
dy ) ) {
        return 1;
     }
-
-    //
-    // Platforms can only be built on oil patches
-    //
-    if (type->GivesResource != OilCost &&
-           AiFindBuildingPlace2(worker, type, worker->X, worker->Y, dx, dy, 
1)) {
+   //
+   //  Platforms can only be built on oil patches
+   //
+    if ( type->GivesResource != OilCost &&
+        AiFindBuildingPlace2( worker, type, worker->X, worker->Y, dx, dy, 1 ) 
) {
        return 1;
     }
+   // FIXME: Should do this if all units can't build better!
+    return AiFindBuildingPlace2( worker, type, worker->X, worker->Y, dx, dy, 0 
);
 
-    // FIXME: Should do this if all units can't build better!
-    return AiFindBuildingPlace2(worker, type, worker->X, worker->Y, dx, dy, 0);
-
-    // return 0;
+   // return 0;
 }
 
 //@}
Index: stratagus/src/ai/ai_force.c
diff -u stratagus/src/ai/ai_force.c:1.34 stratagus/src/ai/ai_force.c:1.35
--- stratagus/src/ai/ai_force.c:1.34    Mon Oct 13 22:47:35 2003
+++ stratagus/src/ai/ai_force.c Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_force.c     -       AI force functions. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_force.c,v 1.34 2003/10/14 02:47:35 jsalmon3 Exp $
+//      $Id: ai_force.c,v 1.35 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -54,153 +54,257 @@
 --     Functions
 ----------------------------------------------------------------------------*/
 
+
+/**
+**     Count available units by type in a force.
+**
+**     The returned array will map UnitType=>number of unit
+** 
+**     @param force            the force to count unit
+**     @param countByType      array[UnitTypeMax+1] of int
+*/
+global void AiForceCountUnits( int force, int *countByType )
+{
+    int type;
+    AiUnit *aiunit;
+    memset( countByType, 0, sizeof ( int ) * ( UnitTypeMax + 1 ) );
+
+   // FIXME: Should I use equivalent unit types?
+    aiunit = AiPlayer->Force[force].Units;
+    while ( aiunit ) {
+       if ( ( !aiunit->Unit->Destroyed ) &&
+            ( aiunit->Unit->HP ) && ( aiunit->Unit->Orders[0].Action != 
UnitActionDie ) ) {
+           type = aiunit->Unit->Type->Type;
+
+           DebugCheck( ( type < 0 ) || ( type > UnitTypeMax ) );
+           countByType[type]++;
+       }
+       aiunit = aiunit->Next;
+    }
+}
+
+/**
+**     Substract wanted unit in a force. ( from the result of 
AiForceCountUnits )
+**
+**     @param force            the force to count unit
+**     @param countByType      array[UnitTypeMax+1] of int
+**     @return                 The number of missing unit
+*/
+global int AiForceSubstractWant( int force, int *countByType )
+{
+    int missing;
+    const AiUnitType *aitype;
+
+    missing = 0;
+    aitype = AiPlayer->Force[force].UnitTypes;
+    while ( aitype ) {
+       countByType[aitype->Type->Type] -= aitype->Want;
+       if ( countByType[aitype->Type->Type] < 0 ) {
+           missing -= countByType[aitype->Type->Type];
+       }
+       aitype = aitype->Next;
+    }
+
+    return missing;
+}
+
+/**
+**     Complete dst force with units from src force.
+**
+**     @param src the force from which units are taken
+**     @param dst the force into which units go
+*/
+global void AiForceTransfert( int src, int dst )
+{
+    AiUnit **prev;
+    AiUnit *aiunit;
+
+    int counter[UnitTypeMax + 1];
+
+   //
+   //  Count units in dest force.
+   //
+    AiForceCountUnits( dst, counter );
+
+   //
+   //  Check the dest force requirements.
+   //    
+    if ( AiForceSubstractWant( dst, counter ) == 0 ) {
+       // Nothing missing => abort.
+       return;
+    }
+   // Iterate the source force, moving needed units into dest...
+    prev = &AiPlayer->Force[src].Units;
+    while ( *prev ) {
+       aiunit = ( *prev );
+       if ( counter[aiunit->Unit->Type->Type] < 0 ) {
+          // move in dest force...
+           *prev = aiunit->Next;
+
+           aiunit->Next = AiPlayer->Force[dst].Units;
+           AiPlayer->Force[dst].Units = aiunit;
+
+           counter[aiunit->Unit->Type->Type]++;
+       } else {
+          // Just iterate
+           prev = &aiunit->Next;
+       }
+    }
+}
+
 /**
 **     Ai clean units in a force.
 **
 **     @param force    Force number.
 */
-local void AiCleanForce(int force)
+global void AiCleanForce( int force )
 {
-    AiUnit** prev;
-    AiUnit* aiunit;
-    const AiUnitType* aitype;
-    int counter[UnitTypeMax];
-
-    //
-    // Release all killed units.
-    //
+    AiUnit **prev;
+    AiUnit *aiunit;
+    int counter[UnitTypeMax + 1];
+    int unit_released;
+
+   //
+   //  Release all killed units.
+   //
     prev = &AiPlayer->Force[force].Units;
-    while ((aiunit = *prev)) {
-       if (aiunit->Unit->Destroyed) {
-           RefsDebugCheck(!aiunit->Unit->Refs);
-           if (!--aiunit->Unit->Refs) {
-               ReleaseUnit(aiunit->Unit);
+    while ( ( aiunit = *prev ) ) {
+       if ( aiunit->Unit->Destroyed ) {
+           RefsDebugCheck( !aiunit->Unit->Refs );
+           if ( !--aiunit->Unit->Refs ) {
+               ReleaseUnit( aiunit->Unit );
            }
            *prev = aiunit->Next;
-           free(aiunit);
+           free( aiunit );
            continue;
-       } else if (!aiunit->Unit->HP ||
-               aiunit->Unit->Orders[0].Action == UnitActionDie) {
-           RefsDebugCheck(!aiunit->Unit->Refs);
+       } else if ( !aiunit->Unit->HP || aiunit->Unit->Orders[0].Action == 
UnitActionDie ) {
+           RefsDebugCheck( !aiunit->Unit->Refs );
            --aiunit->Unit->Refs;
-           RefsDebugCheck(!aiunit->Unit->Refs);
+           RefsDebugCheck( !aiunit->Unit->Refs );
            *prev = aiunit->Next;
-           free(aiunit);
+           free( aiunit );
            continue;
        }
        prev = &aiunit->Next;
     }
 
-    //
-    // Count units in force.
-    //
-    memset(counter, 0, sizeof(counter));
-    aiunit = AiPlayer->Force[force].Units;
-    while (aiunit) {
-       // FIXME: Should I use equivalent unit types?
-       counter[aiunit->Unit->Type->Type]++;
-       aiunit = aiunit->Next;
-    }
-
-    //
-    // Look if the force is complete.
-    //
-    AiPlayer->Force[force].Completed = 1;
-    aitype = AiPlayer->Force[force].UnitTypes;
-    while (aitype) {
-       if (aitype->Want > counter[aitype->Type->Type]) {
-           DebugLevel3Fn("%d: missing %s.\n" _C_ force _C_ 
aitype->Type->Ident);
-           AiPlayer->Force[force].Completed = 0;
-       }
-       counter[aitype->Type->Type] -= aitype->Want;
-       aitype = aitype->Next;
-    }
-
-    //
-    // Release units too much in force.
-    //
-    if (!AiPlayer->Force[force].Attacking) {
-       prev = &AiPlayer->Force[force].Units;
-       while ((aiunit = *prev)) {
-           if (counter[aiunit->Unit->Type->Type] > 0) {
-               DebugLevel0Fn("Release unit %s\n" _C_
-                   aiunit->Unit->Type->Ident);
+   //
+   //  Count units in force.
+   //
+    AiForceCountUnits( force, counter );
+
+   //
+   //  Look if the force is complete.
+   //
+    AiPlayer->Force[force].Completed = ( AiForceSubstractWant( force, counter 
) == 0 );
+
+   // Don't prune the 0 force in any case 
+    if ( force > 0 ) {
+       //
+       //      Release units too much in force.
+       //
+       unit_released = 0;
+       prev = ( &AiPlayer->Force[force].Units );
+       while ( ( aiunit = ( *prev ) ) ) {
+           if ( counter[aiunit->Unit->Type->Type] > 0 ) {
+               DebugLevel0Fn( "Release unit %s\n" _C_ 
aiunit->Unit->Type->Ident );
                counter[aiunit->Unit->Type->Type]--;
-               RefsDebugCheck(!aiunit->Unit->Refs);
+               RefsDebugCheck( !aiunit->Unit->Refs );
                --aiunit->Unit->Refs;
-               RefsDebugCheck(!aiunit->Unit->Refs);
+               RefsDebugCheck( !aiunit->Unit->Refs );
                *prev = aiunit->Next;
-               free(aiunit);
+
+              // Move this unit somewhere else...             
+               AiAssignToForce( aiunit->Unit );
+               free( aiunit );
+
                continue;
            }
            prev = &aiunit->Next;
        }
     }
 
-    DebugLevel3Fn("%d complete %d\n" _C_ force _C_
-       AiPlayer->Force[force].Completed);
+    DebugLevel3Fn( "%d complete %d\n" _C_ force _C_ 
AiPlayer->Force[force].Completed );
+}
+
+/**
+**
+**     Remove everything in the given force
+**
+**     @param force    the force to erase
+*/
+global void AiEraseForce( int force )
+{
+    AiUnitType *aiut, *next;
+    AiUnit *aiu, *next_u;
+
+    aiut = AiPlayer->Force[force].UnitTypes;
+    while ( aiut ) {
+       next = aiut->Next;
+       free( aiut );
+       aiut = next;
+    }
+    AiPlayer->Force[force].UnitTypes = 0;
+
+    aiu = AiPlayer->Force[force].Units;
+    while ( aiu ) {
+       next_u = aiu->Next;
+       free( aiu );
+       aiu = next_u;
+    }
+    AiPlayer->Force[force].Units = 0;
+
+    AiAssignFreeUnitsToForce();
 }
 
 /**
 **     Cleanup units in forces.
 */
-global void AiCleanForces(void)
+global void AiCleanForces( void )
 {
     int force;
 
-    //
-    // Release all killed units.
-    //
-    for (force = 0; force < AI_MAX_ATTACKING_FORCES; ++force) {
-       AiCleanForce(force);
+   //
+   //  Release all killed units.
+   //
+    for ( force = 0; force < AI_MAX_FORCES; ++force ) {
+       AiCleanForce( force );
     }
 }
 
 /**
 **     Check if the units belongs to the force.
+**     If ok, update the completed flag
 **
 **     @param force    Force to be checked.
 **     @param type     Type to check.
-**     @return         Returns true if it fits, false otherwise.
+**     @return         Returns true if it fits & update completed flag, false 
otherwise.
 */
-local int AiCheckBelongsToForce(int force, const UnitType* type)
+local int AiCheckBelongsToForce( int force, const UnitType * type )
 {
-    AiUnit* aiunit;
-    AiUnitType* aitype;
-    int counter[UnitTypeMax];
-    int flag;
-
-    memset(counter, 0, sizeof(counter));
-    //
-    // Count units in force.
-    //
-    aiunit = AiPlayer->Force[force].Units;
-    while (aiunit) {
-       // FIXME: Should I use equivalent unit types?
-       counter[aiunit->Unit->Type->Type]++;
-       aiunit = aiunit->Next;
-    }
+    int counter[UnitTypeMax + 1];
+    int missing;
 
-    //
-    // Look what should be in the force.
-    //
-    flag = 0;
-    AiPlayer->Force[force].Completed = 1;
-    aitype = AiPlayer->Force[force].UnitTypes;
-    while (aitype) {
-       if (aitype->Want > counter[aitype->Type->Type]) {
-           if (type == aitype->Type) {
-               if (aitype->Want - 1 > counter[aitype->Type->Type]) {
-                   AiPlayer->Force[force].Completed = 0;
-               }
-               flag = 1;
-           } else {
-               AiPlayer->Force[force].Completed = 0;
-           }
+   //
+   //  Count units in force.
+   //
+    AiForceCountUnits( force, counter );
+
+   //
+   //  Look what should be in the force.
+   //
+    missing = AiForceSubstractWant( force, counter );
+    AiPlayer->Force[force].Completed = ( missing == 0 );
+
+    if ( counter[type->Type] < 0 ) {
+       // Ok we will put this unit in this force !
+       // Just one missing...
+       if ( ( counter[type->Type] == -1 ) && ( missing == 1 ) ) {
+           AiPlayer->Force[force].Completed = 1;
        }
-       aitype = aitype->Next;
+       return 1;
     }
-    return flag;
+    return 0;
 }
 
 /**
@@ -208,60 +312,239 @@
 **
 **     @param unit     Unit to assign to force.
 */
-global void AiAssignToForce(Unit* unit)
+global void AiAssignToForce( Unit * unit )
 {
+    AiUnit *aiunit;
     int force;
 
-    //
-    // Check to which force it belongs
-    //
-    for (force = 0; force < AI_MAX_FORCES; ++force) {
-       // No troops for attacking force
-       if (!AiPlayer->Force[force].Defending &&
-               AiPlayer->Force[force].Attacking) {
+   //
+   //  Check to which force it belongs
+   //
+    for ( force = 0; force < AI_MAX_FORCES; ++force ) {
+       // care of populate from scratch only.
+       if ( AiPlayer->Force[force].PopulateMode != AiForcePopulateFromScratch 
) {
            continue;
        }
 
-       if (AiCheckBelongsToForce(force, unit->Type)) {
-           AiUnit* aiunit;
-
-           aiunit = malloc(sizeof(*aiunit));
+       if ( AiCheckBelongsToForce( force, unit->Type ) ) {
+           aiunit = malloc( sizeof ( *aiunit ) );
            aiunit->Next = AiPlayer->Force[force].Units;
            AiPlayer->Force[force].Units = aiunit;
            aiunit->Unit = unit;
-           RefsDebugCheck(unit->Destroyed || !unit->Refs);
+           RefsDebugCheck( unit->Destroyed || !unit->Refs );
            ++unit->Refs;
+           return;
+       }
+    }
+
+   // Add to the 0 force !
+   // ( we overflow the 0 force here, so completed does not need update )
+    aiunit = malloc( sizeof ( *aiunit ) );
+    aiunit->Next = AiPlayer->Force[0].Units;
+    AiPlayer->Force[0].Units = aiunit;
+    aiunit->Unit = unit;
+    RefsDebugCheck( unit->Destroyed || !unit->Refs );
+    ++unit->Refs;
+}
+
+/**
+**     Try to complete a force, using all available units
+**
+**     @param force    the force to complete
+*/
+global void AiForceComplete( int force )
+{
+    int j;
+
+    for ( j = 0; j < AI_MAX_FORCES; ++j ) {
+       // Don't complete with self ...
+       if ( j == force ) {
+           continue;
+       }
+       // Complete only with "reusable" forces.
+       if ( !AiPlayer->Force[j].UnitsReusable ) {
+           continue;
+       }
+       // Honor "populate from attack" 
+       if ( ( AiPlayer->Force[force].PopulateMode == AiForcePopulateFromAttack 
) &&
+            ( !AiPlayer->Force[j].Role == AiForceRoleAttack ) ) {
+           continue;
+       }
+       // Complete the force automatically...
+       AiForceTransfert( j, force );
+
+       if ( AiPlayer->Force[force].Completed ) {
            break;
        }
     }
 }
 
 /**
+**     Enrole a unit in the specific force.
+**     FIXME : should take units which are closer to the hotspot.
+**     FIXME : should ensure that units can move to the hotspot.
+**
+**     @param force    the force to put units on
+**     @param ut       the searched unittype
+**     @param count    the number of unit to add
+**     @return         the number of unit still missing ( or 0 if successfull )
+*/
+global int AiEnroleSpecificUnitType( int force, UnitType * ut, int count )
+{
+    AiForce *dstForce;
+    int src_force;
+    AiUnit *aiUnit, **prev;;
+
+    dstForce = AiPlayer->Force + force;
+    for ( src_force = 0; src_force < AI_MAX_FORCES; src_force++ ) {
+       if ( src_force == force ) {
+           continue;
+       }
+       // Only populate with reserve 
+       if ( !AiPlayer->Force[src_force].UnitsReusable ) {
+           continue;
+       }
+       // Don't populate attack force with defend reserve.
+       if ( ( AiPlayer->Force[src_force].Role == AiForceRoleDefend ) &&
+            ( AiPlayer->Force[force].PopulateMode == AiForcePopulateFromAttack 
) ) {
+           continue;
+       }
+
+       aiUnit = AiPlayer->Force[src_force].Units;
+       prev = &AiPlayer->Force[src_force].Units;
+       while ( aiUnit ) {
+          // FIXME : comparaison should match equivalent unit as well
+           if ( aiUnit->Unit->Type == ut ) {
+               *prev = aiUnit->Next;
+
+              // Move to dstForce 
+               AiPlayer->Force[src_force].Completed = 0;
+               aiUnit->Next = dstForce->Units;
+               dstForce->Units = aiUnit;
+
+               count--;
+               if ( !count ) {
+                   return 0;
+               }
+           }
+           prev = &aiUnit->Next;
+           aiUnit = aiUnit->Next;
+       }
+    }
+    return count;
+}
+
+/**
+**     Make sure that current force requirement are superior to actual 
assigned unit count
+**
+*/
+local void AiFinalizeForce( int force )
+{
+    int i;
+    int unitcount[UnitTypeMax + 1];
+    AiUnitType *aitype;
+
+    AiForceCountUnits( force, unitcount );
+    aitype = AiPlayer->Force[force].UnitTypes;
+    while ( aitype ) {
+       if ( unitcount[aitype->Type->Type] > aitype->Want ) {
+           aitype->Want = unitcount[aitype->Type->Type];
+           unitcount[aitype->Type->Type] = 0;
+       }
+       aitype = aitype->Next;
+    }
+
+    for ( i = 0; i <= UnitTypeMax; i++ ) {
+       if ( unitcount[i] > 0 ) {
+           aitype = ( AiUnitType * ) malloc( sizeof ( AiUnitType ) );
+           aitype->Want = unitcount[i];
+           aitype->Type = UnitTypes[i];
+
+          // Insert into force.
+           aitype->Next = AiPlayer->Force[force].UnitTypes;
+           AiPlayer->Force[force].UnitTypes = aitype;
+       }
+    }
+}
+
+/**
+**     Create a force full of available units, responding to the powers.
+**
+**     @param power    Land/Sea/Air power to match
+**     @param utypes   array of unittypes to use
+**     @param ucount   Size of the utypes array        
+**     @return         -1 if not possible, 0 if force ready.
+*/
+global int AiCreateSpecificForce( int *power, int *unittypes, int 
unittypescount )
+{
+    int id, maxPower, forceUpdated;
+    UnitType *ut;
+    int curpower[3];
+
+    curpower[0] = power[0];
+    curpower[1] = power[1];
+    curpower[2] = power[2];
+    AiEraseForce( AiScript->ownForce );
+
+    do {
+       forceUpdated = 0;
+       maxPower = ( curpower[0] > curpower[1] ?
+                    ( curpower[0] > curpower[2] ? 0 : 2 ) :
+                    ( curpower[1] > curpower[2] ? 1 : 2 ) );
+
+       for ( id = 0; id < unittypescount; id++ ) {
+           ut = UnitTypes[unittypes[id]];
+           if ( !( ut->CanTarget & ( 1 << maxPower ) ) ) {
+               continue;
+           }
+          // Try to respond to the most important power ...
+           if ( AiEnroleSpecificUnitType( AiScript->ownForce, ut, 1 ) == 1 ) {
+               continue;
+           }
+
+           curpower[maxPower] -= AiUnittypeForce( ut );
+           forceUpdated = 1;
+           maxPower = ( curpower[0] > curpower[1] ?
+                        ( curpower[0] > curpower[2] ? 0 : 2 ) :
+                        ( curpower[1] > curpower[2] ? 1 : 2 ) );
+           if ( curpower[maxPower] <= 0 ) {
+               AiFinalizeForce( AiScript->ownForce );
+               return 0;
+           }
+       }
+    } while ( forceUpdated );
+   // Sth missing...
+    AiFinalizeForce( AiScript->ownForce );
+    return -1;
+}
+
+
+/**
 **     Assign free units to force.
 */
-global void AiAssignFreeUnitsToForce(void)
+global void AiAssignFreeUnitsToForce( void )
 {
-    Unit* table[UnitMax];
+    Unit *table[UnitMax];
     int n;
     int f;
     int i;
-    Unit* unit;
-    const AiUnit* aiunit;
+    Unit *unit;
+    const AiUnit *aiunit;
 
     AiCleanForces();
 
     n = AiPlayer->Player->TotalNumUnits;
-    memcpy(table, AiPlayer->Player->Units, sizeof(*AiPlayer->Player->Units) * 
n);
+    memcpy( table, AiPlayer->Player->Units, sizeof ( *AiPlayer->Player->Units 
) * n );
 
-    //
-    // Remove all units already in forces.
-    //
-    for (f = 0; f < AI_MAX_ATTACKING_FORCES; ++f) {
+   //
+   //  Remove all units already in forces.
+   //
+    for ( f = 0; f < AI_MAX_FORCES; ++f ) {
        aiunit = AiPlayer->Force[f].Units;
-       while (aiunit) {
+       while ( aiunit ) {
            unit = aiunit->Unit;
-           for (i = 0; i < n; ++i) {
-               if (table[i] == unit) {
+           for ( i = 0; i < n; ++i ) {
+               if ( table[i] == unit ) {
                    table[i] = table[--n];
                }
            }
@@ -269,12 +552,12 @@
        }
     }
 
-    //
-    // Try to assign the remaining units.
-    //
-    for (i = 0; i < n; ++i) {
-       if (table[i]->Active) {
-           AiAssignToForce(table[i]);
+   //
+   //  Try to assign the remaining units.
+   //
+    for ( i = 0; i < n; ++i ) {
+       if ( table[i]->Active ) {
+           AiAssignToForce( table[i] );
        }
     }
 }
@@ -286,24 +569,25 @@
 **     @param x        X tile map position to be attacked.
 **     @param y        Y tile map position to be attacked.
 */
-global void AiAttackWithForceAt(int force, int x, int y)
+global void AiAttackWithForceAt( int force, int x, int y )
 {
-    const AiUnit* aiunit;
+    const AiUnit *aiunit;
 
-    AiCleanForce(force);
+    AiCleanForce( force );
 
-    if ((aiunit = AiPlayer->Force[force].Units)) {
+    if ( ( aiunit = AiPlayer->Force[force].Units ) ) {
        AiPlayer->Force[force].Attacking = 1;
 
-       //
-       //      Send all units in the force to enemy.
-       //
-       while (aiunit) {
-           if (aiunit->Unit->Type->CanAttack) {
-               CommandAttack(aiunit->Unit, x, y, NULL, FlushCommands);
+       //
+       //      Send all units in the force to enemy.
+       //
+       while ( aiunit ) {
+           if ( aiunit->Unit->Type->CanAttack ) {
+               CommandAttack( aiunit->Unit, x, y, NULL, FlushCommands );
            } else {
-               CommandMove(aiunit->Unit, x, y, FlushCommands);
+               CommandMove( aiunit->Unit, x, y, FlushCommands );
            }
+
            aiunit = aiunit->Next;
        }
     }
@@ -314,73 +598,33 @@
 **
 **     @param force    Force number to attack with.
 */
-global void AiAttackWithForce(int force)
+global void AiAttackWithForce( int force )
 {
-    const AiUnit* aiunit;
-    const Unit* enemy;
+    const AiUnit *aiunit;
+    const Unit *enemy;
     int x;
     int y;
-    int f;
 
-    // Move the force to a free position so it can be used for a new
-    // attacking party
-    if (force < AI_MAX_FORCES) {
-       AiUnitType* aiut;
-       AiUnitType* temp;
-       AiUnitType** aiut2;
-
-       f = AI_MAX_FORCES;
-       while (AiPlayer->Force[f].Attacking) {
-           ++f;
-           if (f == AI_MAX_ATTACKING_FORCES) {
-               DebugLevel0Fn("No free attacking forces\n");
-               f = force;
-               break;
-           }
-       }
-       if (f != AI_MAX_ATTACKING_FORCES) {
-           for (aiut = AiPlayer->Force[f].UnitTypes; aiut; aiut = temp) {
-               temp = aiut->Next;
-               free(aiut);
-           }
-
-           AiPlayer->Force[f] = AiPlayer->Force[force];
-           memset(&AiPlayer->Force[force], 0, sizeof(AiForce));
-           aiut = AiPlayer->Force[force].UnitTypes;
-           aiut2 = &AiPlayer->Force[force].UnitTypes;
-           while (aiut) {
-               *aiut2 = malloc(sizeof(**aiut2));
-               (*aiut2)->Next = NULL;
-               (*aiut2)->Want = aiut->Want;
-               (*aiut2)->Type = aiut->Type;
-               aiut = aiut->Next;
-               aiut2 = &(*aiut2)->Next;
-           }
-       }
-
-       force = f;
-    }
-
-    AiCleanForce(force);
+    AiCleanForce( force );
 
     AiPlayer->Force[force].Attacking = 0;
-    if ((aiunit = AiPlayer->Force[force].Units)) {
+    if ( ( aiunit = AiPlayer->Force[force].Units ) ) {
        AiPlayer->Force[force].Attacking = 1;
+       DebugLevel3Fn( "FORCE %d started ( AiAttackWithForce )\n" _C_ force );
 
        enemy = NoUnitP;
-       while (aiunit && !enemy) {      // Use an unit that can attack
-           if (aiunit->Unit->Type->CanAttack) {
-               enemy = AttackUnitsInDistance(aiunit->Unit, MaxMapWidth);
+       while ( aiunit && !enemy ) {    // Use an unit that can attack
+           if ( aiunit->Unit->Type->CanAttack ) {
+               enemy = AttackUnitsInDistance( aiunit->Unit, MaxMapWidth );
            }
            aiunit = aiunit->Next;
        }
 
-       if (!enemy) {
-           DebugLevel0Fn("Need to plan an attack with transporter\n");
-           if (!AiPlayer->Force[force].State &&
-                   !AiPlanAttack(&AiPlayer->Force[force])) {
-               DebugLevel0Fn("Can't transport, look for walls\n");
-               if (!AiFindWall(&AiPlayer->Force[force])) {
+       if ( !enemy ) {
+           DebugLevel0Fn( "Need to plan an attack with transporter\n" );
+           if ( !AiPlayer->Force[force].State && !AiPlanAttack( 
&AiPlayer->Force[force] ) ) {
+               DebugLevel0Fn( "Can't transport, look for walls\n" );
+               if ( !AiFindWall( &AiPlayer->Force[force] ) ) {
                    AiPlayer->Force[force].Attacking = 0;
                }
            }
@@ -390,23 +634,123 @@
        x = enemy->X;
        y = enemy->Y;
 
-       //
-       //      Send all units in the force to enemy.
-       //
+       //
+       //      Send all units in the force to enemy.
+       //
        aiunit = AiPlayer->Force[force].Units;
-       while (aiunit) {
-           if (aiunit->Unit->Type->CanAttack) {
-               CommandAttack(aiunit->Unit, x, y, NULL, FlushCommands);
+       while ( aiunit ) {
+           if ( aiunit->Unit->Type->CanAttack ) {
+               CommandAttack( aiunit->Unit, x, y, NULL, FlushCommands );
            } else {
-               CommandMove(aiunit->Unit, x, y, FlushCommands);
+               CommandMove( aiunit->Unit, x, y, FlushCommands );
            }
            aiunit = aiunit->Next;
        }
     }
 }
 
+/**
+**     Try to group units in a force. Units are grouped arround the closest 
units of the hotspot. 
+**
+**     @param  force   the force to send home.
+*/
+global void AiGroupForceNear( int force, int targetX, int targetY )
+{
+    const AiUnit *aiunit;
+    const AiUnit *groupunit;
+    int unitdst, groupdst;
+
+   // Step 1 : find the unit closest to the force hotspot
+    AiCleanForce( force );
+
+    groupdst = -1;
+
+    groupunit = 0;
+
+    aiunit = AiPlayer->Force[force].Units;
+
+   // Sanity : don't group force with only one unit !
+    if ( ( !aiunit ) || ( !aiunit->Next ) ) {
+       return;
+    }
+
+    while ( aiunit ) {
+       unitdst = abs( aiunit->Unit->X - targetX ) + abs( aiunit->Unit->Y - 
targetY );
+       if ( ( unitdst < groupdst ) || ( !groupunit ) ) {
+           groupunit = aiunit;
+           groupdst = unitdst;
+       }
+
+       aiunit = aiunit->Next;
+    }
+
+    AiPlayer->Force[force].Attacking = 1;
+
+   // Order units to attack near the "group" unit...
+    aiunit = AiPlayer->Force[force].Units;
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->CanAttack ) {
+           CommandAttack( aiunit->Unit, groupunit->Unit->X, 
groupunit->Unit->Y, NULL,
+                          FlushCommands );
+       } else {
+           CommandMove( aiunit->Unit, groupunit->Unit->X, groupunit->Unit->Y, 
FlushCommands );
+       }
+       aiunit = aiunit->Next;
+    }
+}
+
+/**
+**     Find the closest home batiment.
+**     ground is 0 : land, 1 : air, 2 : water ( as UnitType::UnitType )
+**
+**     @param ground   ground type ( land/air/water )
+**     @param x        X start position
+**     @param y        Y start position
+**     @param rsltx    X destination
+**     @param rslyx    Y destination
+*/
+local void AiFindHome( int ground, int x, int y, int *rsltx, int *rslty )
+{
+   // Find in the player unit's the closer to
+   // FIXME : TODO
+    *rsltx = AiPlayer->Player->StartX;
+    *rslty = AiPlayer->Player->StartY;
+}
+
+/**
+**     Try to send this force home 
+**
+**     @param  force   the force to send home.
+*/
+global void AiSendForceHome( int force )
+{
+    const AiUnit *aiunit;
+    int i, type;
+    int x[3], y[3];
+
+    AiCleanForce( force );
+    aiunit = AiPlayer->Force[force].Units;
+
+    for ( i = 0; i < 3; i++ ) {
+       x[i] = -1;
+       y[i] = -1;
+    }
+
+    while ( aiunit ) {
+       type = aiunit->Unit->Type->UnitType;
+
+       if ( x[type] == -1 ) {
+           AiFindHome( type, aiunit->Unit->X, aiunit->Unit->Y, &x[type], 
&y[type] );
+       }
+
+       CommandMove( aiunit->Unit, x[type], y[type], FlushCommands );
+
+       aiunit = aiunit->Next;
+    }
+}
+
 //----------------------------------------------------------------------------
-//     Handle attack of force with transporter.
+//      Handle attack of force with transporter.
 //----------------------------------------------------------------------------
 
 /**
@@ -419,58 +763,55 @@
 **             We must the transporter land on a new position.
 **             Or the board action will be better written.
 */
-local void AiLoadForce(AiForce* force)
+local void AiLoadForce( AiForce * force )
 {
-    AiUnit* aiunit;
-    Unit* table[UnitMax];
+    AiUnit *aiunit;
+    Unit *table[UnitMax];
     int n;
     int i;
     int o;
     int f;
 
-    //
-    // Find all transporters.
-    //
+   //
+   //  Find all transporters.
+   //
     n = 0;
     aiunit = force->Units;
-    while (aiunit) {
-       if (aiunit->Unit->Type->Transporter) {
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->Transporter ) {
            table[n++] = aiunit->Unit;
        }
        aiunit = aiunit->Next;
     }
 
-    if (!n) {
-       DebugLevel0Fn("No transporter, lost or error in code?\n");
+    if ( !n ) {
+       DebugLevel0Fn( "No transporter, lost or error in code?\n" );
        force->MustTransport = 0;
        force->State = 0;
        return;
     }
-
-    //
-    // Load all on transporter.
-    //
+   //
+   //  Load all on transporter.
+   //
     f = o = i = 0;
     aiunit = force->Units;
-    while (aiunit) {
-       Unit* unit;
+    while ( aiunit ) {
+       Unit *unit;
 
        unit = aiunit->Unit;
-       if (!unit->Type->Transporter &&
-               unit->Type->UnitType == UnitTypeLand) {
-           if (!unit->Removed) {
+       if ( !unit->Type->Transporter && unit->Type->UnitType == UnitTypeLand ) 
{
+           if ( !unit->Removed ) {
                f = 1;
-               if (unit->Orders[0].Action != UnitActionBoard) {
-                   if (table[i]->Orders[0].Action == UnitActionStill &&
-                           table[i]->OrderCount == 1) {
-                       DebugLevel0Fn("Send transporter %d\n" _C_ i);
-                       CommandFollow(table[i], unit, FlushCommands);
+               if ( unit->Orders[0].Action != UnitActionBoard ) {
+                   if ( UnitIdle( table[i] ) ) {
+                       DebugLevel0Fn( "Send transporter %d\n" _C_ i );
+                       CommandFollow( table[i], unit, FlushCommands );
                    }
-                   CommandBoard(unit, table[i], FlushCommands);
+                   CommandBoard( unit, table[i], FlushCommands );
                    ++o;
-                   // FIXME
-                   if (o == table[i]->Type->MaxOnBoard) {
-                       DebugLevel0Fn("FIXME: next transporter for AI 
boarding\n");
+                  // FIXME
+                   if ( o == table[i]->Type->MaxOnBoard ) {
+                       DebugLevel0Fn( "FIXME: next transporter for AI 
boarding\n" );
                        return;
                    }
                }
@@ -479,8 +820,8 @@
        aiunit = aiunit->Next;
     }
 
-    if (!f) {
-       DebugLevel0Fn("All are loaded\n");
+    if ( !f ) {
+       DebugLevel0Fn( "All are loaded\n" );
        ++force->State;
     }
 }
@@ -495,25 +836,23 @@
 **             at an unfortified coast. If we send more transporters they
 **             should land on different positions.
 */
-local void AiSendTransporter(AiForce* force)
+local void AiSendTransporter( AiForce * force )
 {
-    AiUnit* aiunit;
+    AiUnit *aiunit;
 
-    //
-    // Find all transporters.
-    //
+   //
+   //  Find all transporters.
+   //
     aiunit = force->Units;
-    while (aiunit) {
-       //      Transporter to unload units
-       if (aiunit->Unit->Type->Transporter) {
-           CommandUnload(aiunit->Unit, force->GoalX, force->GoalY, NoUnitP,
-               FlushCommands);
-       //      Ships to defend transporter
-       } else if (aiunit->Unit->Type->UnitType == UnitTypeNaval) {
-           CommandAttack(aiunit->Unit, force->GoalX, force->GoalY, NoUnitP,
-               FlushCommands);
+    while ( aiunit ) {
+       //      Transporter to unload units
+       if ( aiunit->Unit->Type->Transporter ) {
+           CommandUnload( aiunit->Unit, force->GoalX, force->GoalY, NoUnitP, 
FlushCommands );
+          //      Ships to defend transporter
+       } else if ( aiunit->Unit->Type->UnitType == UnitTypeNaval ) {
+           CommandAttack( aiunit->Unit, force->GoalX, force->GoalY, NoUnitP, 
FlushCommands );
        }
-       aiunit=aiunit->Next;
+       aiunit = aiunit->Next;
     }
     ++force->State;
 }
@@ -525,25 +864,25 @@
 **     @param force    Force pointer.
 **
 */
-local void AiWaitLanded(AiForce* force)
+local void AiWaitLanded( AiForce * force )
 {
-    AiUnit* aiunit;
+    AiUnit *aiunit;
     int i;
 
-    DebugLevel0Fn("Waiting\n");
-    //
-    // Find all transporters.
-    //
+    DebugLevel0Fn( "Waiting\n" );
+   //
+   //  Find all transporters.
+   //
     i = 1;
     aiunit = force->Units;
-    while (aiunit) {
-       if (aiunit->Unit->Type->Transporter) {
-           if (aiunit->Unit->Orders[0].Action == UnitActionStill) {
-               DebugLevel0Fn("Unloading\n");
-               // Don't tell empty transporters to unload.
-               if (aiunit->Unit->InsideCount) {
-                   CommandUnload(aiunit->Unit, force->GoalX, force->GoalY,
-                       NoUnitP, FlushCommands);
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->Transporter ) {
+           if ( UnitIdle( aiunit->Unit ) ) {
+               DebugLevel0Fn( "Unloading\n" );
+              // Don't tell empty transporters to unload.
+               if ( aiunit->Unit->InsideCount ) {
+                   CommandUnload( aiunit->Unit, force->GoalX, force->GoalY,
+                                  NoUnitP, FlushCommands );
                    i = 0;
                }
            } else {
@@ -552,8 +891,8 @@
        }
        aiunit = aiunit->Next;
     }
-    if (i) {
-       ++force->State;                 // all unloaded
+    if ( i ) {
+       ++force->State;         // all unloaded
     }
 }
 
@@ -563,97 +902,129 @@
 **
 **     @param force    Force pointer.
 */
-local void AiForceAttacks(AiForce* force)
+local void AiForceAttacks( AiForce * force )
 {
-    const AiUnit* aiunit;
+    const AiUnit *aiunit;
 
-    if ((aiunit = force->Units)) {
-       while (aiunit) {
-           // Still some action
-           if (aiunit->Unit->Orders[0].Action != UnitActionStill) {
+    if ( ( aiunit = force->Units ) ) {
+       while ( aiunit ) {
+          // Still some action
+           if ( !UnitIdle( aiunit->Unit ) ) {
                break;
            }
            aiunit = aiunit->Next;
        }
-       if (!aiunit) {
-           AiAttackWithForce(force - AiPlayer->Force);
+       // Must mark the attack as terminated 
+       if ( !aiunit ) {
+           DebugLevel3Fn( "FORCE stopped ( AiForceAttacks, unitactionstill 
)\n" );
+           DebugLevel3Fn( "force target was %d %d\n" _C_ force->GoalX _C_ 
force->GoalY );
+           DebugLevel3Fn( "unit pos was %d %d\n" _C_ force->Units->Unit->X _C_ 
force->Units->
+                          Unit->Y );
+
+           force->Attacking = 0;
+          // AiAttackWithForce(force-AiPlayer->Force);
        }
     } else {
+       DebugLevel3Fn( "FORCE stopped ( AiAttackWithForce, no unit )\n" );
        force->Attacking = 0;
     }
 }
 
+global void AiForceHelpMe( int force, const Unit * attacker, Unit * defender )
+{
+    AiForce *aiForce;
+    AiUnit *rescue;
+
+    aiForce = AiPlayer->Force + force;
+
+   // Don't handle special cases
+    if ( aiForce->State > 0 ) {
+       return;
+    }
+
+    switch ( aiForce->HelpMode ) {
+    case AiForceDontHelp:
+       // Don't react (easy)
+       return;
+
+    case AiForceHelpForce:
+       // Send all idles units to help
+       rescue = aiForce->Units;
+       while ( rescue ) {
+          // TODO : check that dead units does appear there
+           if ( UnitIdle( rescue->Unit ) ) {
+              // This unit attack !
+               if ( rescue->Unit->Type->CanAttack ) {
+                   CommandAttack( rescue->Unit, attacker->X, attacker->Y, NULL,
+                                  FlushCommands );
+               } else {
+                   CommandMove( rescue->Unit, attacker->X, attacker->Y, 
FlushCommands );
+               }
+              // Now the force is attacking ( again )
+               aiForce->Attacking = 1;
+           }
+           rescue = rescue->Next;
+       }
+       break;
+
+    default:
+       // the usual way : create a defense force, send it, ...
+       AiFindDefendScript( attacker->X, attacker->Y );
+       break;
+    }
+}
+
 /**
 **     Handle an attack force.
 **
 **     @param force    Force pointer.
 */
-local void AiGuideAttackForce(AiForce* force)
+local void AiGuideAttackForce( AiForce * force )
 {
-    enum { StartState = 1, TransporterLoaded, WaitLanded, AttackNow };
+    enum
+    { StartState = 1, TransporterLoaded, WaitLanded, AttackNow };
 
-    switch (force->State) {
-           //
-           //  Load units on transporters.
-           //
-       case StartState:
-           AiLoadForce(force);
-           break;
-       case TransporterLoaded:
-           AiSendTransporter(force);
-           break;
-       case WaitLanded:
-           AiWaitLanded(force);
-           break;
-       case AttackNow:
-           force->State = 0;
-           AiAttackWithForce(force - AiPlayer->Force);
-           break;
+    switch ( force->State ) {
+       //
+       //  Load units on transporters.
+       //
+    case StartState:
+       AiLoadForce( force );
+       break;
+    case TransporterLoaded:
+       AiSendTransporter( force );
+       break;
+    case WaitLanded:
+       AiWaitLanded( force );
+       break;
+    case AttackNow:
+       force->State = 0;
+       AiAttackWithForce( force - AiPlayer->Force );
+       break;
 
-           //
-           //  Attacking!
-           //
-       case 0:
-           AiForceAttacks(force);
-           break;
+       //
+       //  Attacking!
+       //
+    case 0:
+       AiForceAttacks( force );
+       break;
     }
 }
 
 /**
 **     Entry point of force manager, perodic called.
 */
-global void AiForceManager(void)
+global void AiForceManager( void )
 {
     int force;
 
-    //
-    // Look if our defenders still have enemies in range.
-    //
-    for (force = 0; force < AI_MAX_ATTACKING_FORCES; ++force) {
-       if (AiPlayer->Force[force].Defending) {
-           const AiUnit* aiunit;
-
-           AiCleanForce(force);
-           //
-           //  Look if still enemies in attack range.
-           //
-           aiunit = AiPlayer->Force[force].Units;
-           while (aiunit) {
-               if (aiunit->Unit->Type->CanAttack &&
-                       AttackUnitsInReactRange(aiunit->Unit)) {
-                   break;
-               }
-               aiunit = aiunit->Next;
-           }
-           if (!aiunit) {              // No enemies go home.
-               DebugLevel0Fn("FIXME: not written, should send force home\n");
-               AiPlayer->Force[force].Defending = 0;
-               AiPlayer->Force[force].Attacking = 0;
-           }
-       }
-       if (AiPlayer->Force[force].Attacking) {
-           AiCleanForce(force);
-           AiGuideAttackForce(&AiPlayer->Force[force]);
+   //
+   //  Look if our defenders still have enemies in range.
+   //
+    for ( force = 0; force < AI_MAX_FORCES; ++force ) {
+       if ( AiPlayer->Force[force].Attacking ) {
+           AiCleanForce( force );
+           AiGuideAttackForce( &AiPlayer->Force[force] );
        }
     }
     AiAssignFreeUnitsToForce();
Index: stratagus/src/ai/ai_local.h
diff -u stratagus/src/ai/ai_local.h:1.36 stratagus/src/ai/ai_local.h:1.37
--- stratagus/src/ai/ai_local.h:1.36    Thu Sep 25 02:58:35 2003
+++ stratagus/src/ai/ai_local.h Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_local.h     -       The local AI header file. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_local.h,v 1.36 2003/09/25 06:58:35 mr-russ Exp $
+//      $Id: ai_local.h,v 1.37 2003/10/23 18:38:34 n0body Exp $
 
 #ifndef __AI_LOCAL_H__
 #define __AI_LOCAL_H__
@@ -54,27 +54,30 @@
 /**
 **     Ai Type structure.
 */
-struct _ai_type_ {
-    AiType*            Next;                   /// Next ai type
+struct _ai_type_
+{
+    AiType *Next;              /// Next ai type
+
+    char *Name;                        /// Name of this ai
+    char *Race;                        /// for this race
+    char *Class;               /// class of this ai
+
+   // nice flags
+   //unsigned char     AllExplored : 1;        /// Ai sees unexplored area
+   //unsigned char     AllVisibile : 1;        /// Ai sees invisibile area
 
-    char*              Name;                   /// Name of this ai
-    char*              Race;                   /// for this race
-    char*              Class;                  /// class of this ai
-
-    // nice flags
-    //unsigned char    AllExplored : 1;        /// Ai sees unexplored area
-    //unsigned char    AllVisibile : 1;        /// Ai sees invisibile area
-
-    SCM                        Script;                 /// Main script 
(gc-protected!)
+    SCM Script;                        /// Main script (gc-protected!)
 };
 
 /**
 **     AI unit-type table with counter in front.
 */
-typedef struct _ai_unittype_table_ {
-    int                Count;                  /// elements in table
-    UnitType*  Table[1];               /// the table
-} AiUnitTypeTable;
+typedef struct _ai_unittype_table_
+{
+    int Count;                 /// elements in table
+    UnitType *Table[1];                /// the table
+}
+AiUnitTypeTable;
 
 /**
 **     Ai unit-type typedef.
@@ -84,10 +87,11 @@
 /**
 **     Ai unit-type in a force.
 */
-struct _ai_unit_type_ {
-    AiUnitType*        Next;                   /// next unit-type
-    int                Want;                   /// number of this unit-type 
wanted
-    UnitType*  Type;                   /// unit-type self
+struct _ai_unit_type_
+{
+    AiUnitType *Next;          /// next unit-type
+    int Want;                  /// number of this unit-type wanted
+    UnitType *Type;            /// unit-type self
 };
 
 /**
@@ -98,17 +102,41 @@
 /**
 **     Ai unit in a force.
 */
-struct _ai_unit_ {
-    AiUnit*    Next;                   /// next unit
-    Unit*      Unit;                   /// unit self
+struct _ai_unit_
+{
+    AiUnit *Next;              /// next unit
+    Unit *Unit;                        /// unit self
 };
 
 /**
 **     Roles for forces
 */
-enum _ai_force_role_ {
-    AiForceRoleAttack,                 /// Force should attack
-    AiForceRoleDefend,                 /// Force should defend
+enum _ai_force_role_
+{
+    AiForceRoleAttack,         /// Force should attack
+    AiForceRoleDefend,         /// Force should defend
+};
+
+
+/**
+**     Ways to populate a force 
+*/
+enum _ai_force_populate_mode_
+{
+    AiForceDontPopulate,       /// Force won't receive any unit
+    AiForcePopulateFromScratch,        /// Force unit's will be builded
+    AiForcePopulateFromAttack, /// Force will receive units from idle attack 
force only - nothing builded
+    AiForcePopulateAny         /// Force will receive units from any idle 
force - nothing builded
+};
+
+/**
+**     How to react when an unit is attacked in a force
+*/
+enum _ai_force_help_mode_
+{
+    AiForceDontHelp,           /// Don't react to attack on this force
+    AiForceHelpForce,          /// Send idle units to defend
+    AiForceHelpFull            /// Create a defend force, send it, ...
 };
 
 /**
@@ -121,22 +149,25 @@
 **
 **     A force is a group of units belonging together.
 */
-struct _ai_force_ {
-    char               Completed;      /// Flag saying force is complete build
-    char               Defending;      /// Flag saying force is defending
-    char               Attacking;      /// Flag saying force is attacking
-
-    char               Role;           /// Role of the force
-
-    AiUnitType*                UnitTypes;      /// Count and types of unit-type
-    AiUnit*            Units;          /// Units in the force
-       //
-       // If attacking
-       //
-    int                        State;          /// Attack state
-    int                        GoalX;          /// Attack point X tile map 
position
-    int                        GoalY;          /// Attack point Y tile map 
position
-    int                        MustTransport;  /// Flag must use transporter
+struct _ai_force_
+{
+    char Completed;            /// Flag saying force is complete build
+    char Attacking;            /// Is this force attacking ( aka not idle )
+    char Role;                 /// Role of the force
+    char PopulateMode;         /// Which forces can be used to fill this force 
?
+    char UnitsReusable;                /// Indicate moving units of this force 
into others is allowed.    
+    char HelpMode;             /// How to react to treat in this force ?
+
+    AiUnitType *UnitTypes;     /// Count and types of unit-type
+    AiUnit *Units;             /// Units in the force
+
+   //
+   // If attacking
+   //
+    int State;                 /// Attack state
+    int GoalX;                 /// Attack point X tile map position
+    int GoalY;                 /// Attack point Y tile map position
+    int MustTransport;         /// Flag must use transporter
 };
 
 /**
@@ -149,63 +180,148 @@
 **
 **     List of orders for the resource manager to handle
 */
-struct _ai_build_queue_ {
-       AiBuildQueue*   Next;           /// next request
-       int             Want;           /// requested number
-       int             Made;           /// builded number
-       UnitType*       Type;           /// unit-type
+struct _ai_build_queue_
+{
+    AiBuildQueue *Next;                /// next request
+    int Want;                  /// requested number
+    int Made;                  /// builded number
+    UnitType *Type;            /// unit-type
 };
 
+
+typedef struct _ai_running_script_ AiRunningScript;
+
 /**
-**     AI variables.
+**     AI running script ( with state, ... )
 */
-typedef struct _player_ai_ {
-    Player*     Player;                 /// Engine player structure
+struct _ai_running_script_
+{
+    SCM Script;                        /// Script executed
+    unsigned long SleepCycles; /// Cycles to sleep
+    char ident[10];            /// Debugging !
+    int HotSpot_X;             /// Hot spot ( for defense, attack, ... )
+    int HotSpot_Y;
+    int HotSpot_Ray;
 
-    AiType*    AiType;                 /// AI type of this player AI
+    int ownForce;              /// A force ID ( the n° of the script... )
 
-    // controller
-    SCM                Script;                 /// Script executed
-    int                ScriptDebug;            /// Flag script debuging on/off
-    unsigned long      SleepCycles;    /// Cycles to sleep
-
-    // forces
-#define AI_MAX_FORCES  10              /// How many forces are supported
-#define AI_MAX_ATTACKING_FORCES        30      /// Attacking forces

-    AiForce    Force[AI_MAX_ATTACKING_FORCES]; /// Forces controlled by AI
-
-    // resource manager
-
-    int                Reserve[MaxCosts];      /// Resources to keep in reserve
-    int                Used[MaxCosts];         /// Used resources
-    int                Needed[MaxCosts];       /// Needed resources
-    int                Collect[MaxCosts];      /// Collect % of resources
-    int                NeededMask;             /// Mask for needed resources
-
-    int                NeedFood;               /// Flag need food
-
-       /// number of elements in UnitTypeRequests
-    int                        UnitTypeRequestsCount;
-       /// unit-types to build/train requested and priority list
-    AiUnitTypeTable*   UnitTypeRequests;
-       /// number of elements in UpgradeRequests
-    int                        UpgradeToRequestsCount;
-       /// Upgrade to unit-type requested and priority list
-    UnitType**         UpgradeToRequests;
-       /// number of elements in ResearchRequests
-    int                        ResearchRequestsCount;
-       /// Upgrades requested and priority list
-    Upgrade**          ResearchRequests;
-
-       /// What the resource manager should build
-    AiBuildQueue*      UnitTypeBuilded;
-
-       /// Last building checked for repair in this turn
-    int                        LastRepairBuilding;
-       /// Number of workers that unsuccessfully tried to repair a building
-    unsigned           TriedRepairWorkers[UnitMax];
+   // Total number of ressource gauges
+#define RESSOURCE_COUNT 3
+   // Total number of forces gauges
+#define FORCE_COUNT    11
 
-} PlayerAi;
+#define GAUGE_NB (3+(RESSOURCE_COUNT*2)+(FORCE_COUNT*6))
+    int *gauges;               /// Gauges values ( initially 0 )               
+};
+
+/**
+**     Ai script action 
+**
+**     Describe each different attack/defend scheme.
+**
+**     Linked list.
+*/
+typedef struct _ai_script_action_ AiScriptAction;
+
+struct _ai_script_action_
+{
+    SCM Action;                        /// Scheme description, in the form : 
+   /// '((name evaluate-lambda run-script) ... )
+
+    int Defensive;             /// Is this action usable for defense
+    int Offensive;             /// Is this action usable for attack
+
+   /// TODO : hotspot_kind : set if the hotspot should contain path from base  
    
+};
+
+/**
+**     Ai action evaluation 
+**
+**     Each AiPlayer periodically evaluation an attack action.
+**
+**     If it is ready, the attack is fired. Else, it is keept for a while.
+**     From time to time, the best unfired try is fired.
+**     
+*/
+typedef struct _ai_action_evaluation_ AiActionEvaluation;
+
+struct _ai_action_evaluation_
+{
+    AiScriptAction *aiScriptAction;
+
+    int hotSpotX;
+    int hotSpotY;
+
+   // Value of the hotspot ( total points to get... )
+    int hotSpotValue;
+
+   // Evaluation of the script ( ressources needed... )
+    int value;
+
+    AiActionEvaluation *Next;
+};
+
+/**
+**     AI variables.
+*/
+typedef struct _player_ai_
+{
+    Player *Player;            /// Engine player structure
+
+    AiType *AiType;            /// AI type of this player AI
+
+   // controller
+#define AI_MAX_RUNNING_SCRIPTS 5       /// ( generic, attack, defend, ... )
+#define AI_MAIN_SCRIPT 0
+    AiRunningScript Scripts[AI_MAX_RUNNING_SCRIPTS];
+
+   // Ai "memory"
+#define AI_MEMORY_SIZE 30      /// Max number of keept evaluation ( => 30 sec )
+    AiActionEvaluation *FirstEvaluation;
+    AiActionEvaluation *LastEvaluation;
+    int EvaluationCount;
+
+    int ScriptDebug;           /// Flag script debuging on/off
+
+    int AutoAttack;            /// Are attack started automatically ?
+
+   // forces
+#define AI_MAX_FORCES  10      /// How many forces are supported
+#define AI_GENERIC_FORCES      (AI_MAX_FORCES-AI_MAX_RUNNING_SCRIPTS)  /// How 
many forces are useable in the main script
+    AiForce Force[AI_MAX_FORCES];      /// Forces controlled by AI
+
+   // resource manager
+    int Reserve[MaxCosts];     /// Resources to keep in reserve
+    int Used[MaxCosts];                /// Used resources
+    int Needed[MaxCosts];      /// Needed resources
+    int Collect[MaxCosts];     /// Collect % of resources
+    int NeededMask;            /// Mask for needed resources
+
+    int NeedFood;              /// Flag need food
+
+   /// number of elements in UnitTypeRequests
+    int UnitTypeRequestsCount;
+   /// unit-types to build/train requested and priority list
+    AiUnitTypeTable *UnitTypeRequests;
+   /// number of elements in UpgradeRequests
+    int UpgradeToRequestsCount;
+   /// Upgrade to unit-type requested and priority list
+    UnitType **UpgradeToRequests;
+   /// number of elements in ResearchRequests
+    int ResearchRequestsCount;
+   /// Upgrades requested and priority list
+    Upgrade **ResearchRequests;
+
+   /// What the resource manager should build
+    AiBuildQueue *UnitTypeBuilded;
+
+   /// Last building checked for repair in this turn
+    int LastRepairBuilding;
+   /// Number of workers that unsuccessfully tried to repair a building
+    unsigned TriedRepairWorkers[UnitMax];
+
+}
+PlayerAi;
 
 /**
 **     AI Helper.
@@ -214,113 +330,177 @@
 **     building or upgrade or spell, it could lookup in this tables to find
 **     where it could be trained, builded or researched.
 */
-typedef struct _ai_helper_ {
+typedef struct _ai_helper_
+{
     /**
     ** The index is the unit that should be trained, giving a table of all
     ** units/buildings which could train this unit.
     */
-    int                        TrainCount;
-    AiUnitTypeTable**  Train;
+    int TrainCount;
+    AiUnitTypeTable **Train;
     /**
     ** The index is the unit that should be build, giving a table of all
     ** units/buildings which could build this unit.
     */
-    int                        BuildCount;
-    AiUnitTypeTable**  Build;
+    int BuildCount;
+    AiUnitTypeTable **Build;
     /**
     ** The index is the upgrade that should be made, giving a table of all
     ** units/buildings which could do the upgrade.
     */
-    int                        UpgradeCount;
-    AiUnitTypeTable**  Upgrade;
+    int UpgradeCount;
+    AiUnitTypeTable **Upgrade;
     /**
     ** The index is the research that should be made, giving a table of all
     ** units/buildings which could research this upgrade.
     */
-    int                        ResearchCount;
-    AiUnitTypeTable**  Research;
+    int ResearchCount;
+    AiUnitTypeTable **Research;
     /**
     ** The index is the unit that should be repaired, giving a table of all
     ** units/buildings which could repair this unit.
     */
-    int                        RepairCount;
-    AiUnitTypeTable**  Repair;
+    int RepairCount;
+    AiUnitTypeTable **Repair;
     /**
     ** The index is the unit-limit that should be solved, giving a table of all
     ** units/buildings which could reduce this unit-limit.
     */
-    int                        UnitLimitCount;
-    AiUnitTypeTable**  UnitLimit;
+    int UnitLimitCount;
+    AiUnitTypeTable **UnitLimit;
     /**
     ** The index is the unit that should be made, giving a table of all
     ** units/buildings which are equivalent.
     */
-    int                        EquivCount;
-    AiUnitTypeTable**  Equiv;
-} AiHelper;
+    int EquivCount;
+    AiUnitTypeTable **Equiv;
+}
+AiHelper;
 
 /*----------------------------------------------------------------------------
 --     Variables
 ----------------------------------------------------------------------------*/
 
-extern AiType* AiTypes;                        /// List of all AI types
-extern AiHelper AiHelpers;             /// AI helper variables
+extern AiType *AiTypes;                /// List of all AI types
+extern AiHelper AiHelpers;     /// AI helper variables
 
-extern PlayerAi* AiPlayer;             /// Current AI player
-extern char** AiTypeWcNames;           /// pud num to internal string mapping
+#define MaxAiScriptActions     64      /// How many AiScriptActions are 
supported
+extern int AiScriptActionNum;  /// Current number of AiScriptAction
+extern AiScriptAction AiScriptActions[MaxAiScriptActions];     /// All 
availables AI script actions   
+
+extern PlayerAi *AiPlayer;     /// Current AI player
+extern AiRunningScript *AiScript;
+extern char **AiTypeWcNames;   /// pud num to internal string mapping
 
 /*----------------------------------------------------------------------------
 --     Functions
 ----------------------------------------------------------------------------*/
 
 //
-//     Resource manager
+//      Resource manager
 //
     /// Add unit-type request to resource manager
-extern void AiAddUnitTypeRequest(UnitType* type,int count);
+extern void AiAddUnitTypeRequest( UnitType * type, int count );
     /// Add upgrade-to request to resource manager
-extern void AiAddUpgradeToRequest(UnitType* type);
+extern void AiAddUpgradeToRequest( UnitType * type );
     /// Add research request to resource manager
-extern void AiAddResearchRequest(Upgrade* upgrade);
+extern void AiAddResearchRequest( Upgrade * upgrade );
     /// Periodic called resource manager handler
-extern void AiResourceManager(void);
+extern void AiResourceManager( void );
+    /// Count the number of builder unit available for the given unittype
+extern int AiCountUnitBuilders( UnitType * type );
 
 //
-//     Buildings
+//      Buildings
 //
     /// Find nice building place
-extern int AiFindBuildingPlace(const Unit*, const UnitType * , int *, int *);
+extern int AiFindBuildingPlace( const Unit *, const UnitType *, int *, int * );
 
 //
-//     Forces
+//      Forces
 //
     /// Cleanup units in force
-extern void AiCleanForces(void);
+extern void AiCleanForces( void );
+    /// Cleanup units in the given force
+extern void AiCleanForce( int force );
+    /// Remove everything in the given force
+extern void AiEraseForce( int force );
     /// Assign a new unit to a force
-extern void AiAssignToForce(Unit* unit);
+extern void AiAssignToForce( Unit * unit );
     /// Assign a free units to a force
-extern void AiAssignFreeUnitsToForce(void);
+extern void AiAssignFreeUnitsToForce( void );
+    /// Complete a force with units form another
+extern void AiForceTransfert( int src, int dst );
+    /// Group a force on the nearest unit to target
+extern void AiGroupForceNear( int force, int targetx, int targety );
     /// Attack with force at position
-extern void AiAttackWithForceAt(int force,int x,int y);
+extern void AiAttackWithForceAt( int force, int x, int y );
     /// Attack with force
-extern void AiAttackWithForce(int force);
+extern void AiAttackWithForce( int force );
+    /// Send force home
+extern void AiSendForceHome( int force );
+    /// Evaluate the cost to build a force (time to build + ressources)
+extern int AiEvaluateForceCost( int force, int total );
+    /// Complete a force from existing units.
+extern void AiForceComplete( int force );
+    /// Enrole one or more units of a type in a force
+extern int AiEnroleSpecificUnitType( int force, UnitType * ut, int count );
+    /// Create a force from existing units, ready to respond to the powers
+extern int AiCreateSpecificForce( int *power, int *unittypes, int 
unittypescount );
+    /// Force's unit is attacked.
+extern void AiForceHelpMe( int force, const Unit * attacker, Unit * defender );
     /// Periodic called force manager handler
-extern void AiForceManager(void);
-
+extern void AiForceManager( void );
+    /// Calculate the number of unit produced for each wanted unittype   
+extern void AiForceCountUnits( int force, int *unittypeCount );
+    /// Substract the number of unit wanted for each unittype
+extern int AiForceSubstractWant( int force, int *unittypeCount );
 //
-//     Plans
+//      Plans
 //
     /// Find a wall to attack
-extern int AiFindWall(AiForce* force);
+extern int AiFindWall( AiForce * force );
     /// Plan the an attack
-extern int AiPlanAttack(AiForce* force);
+extern int AiPlanAttack( AiForce * force );
+
+//
+//      Scripts
+//
+       /// Run a script ( for the current AiPlayer )
+extern void AiRunScript( int script, SCM list, int hotSpotX, int hotSpotY, int 
hotSpotRay );
+       /// Find a script for defense.
+extern void AiFindDefendScript( int attackX, int attackY );
+       /// Check if attack is possible
+extern void AiPeriodicAttack();
+//
+//      Gauges
+//
+    /// Compute gauges for the current RunningScript
+extern void AiComputeCurrentScriptGauges();
+    /// Output gauges values
+extern void AiDebugGauges();
+    /// Give the value of a specific gauge, for the current RunningScript
+extern int AiGetGaugeValue( int gauge );
+    /// Find a gauge given its identifier. 
+extern int AiFindGaugeId( SCM id );
+    /// return the force of the unittype.
+extern int AiUnittypeForce( UnitType * unitType );
 
 //
-//     Magic
+//      Magic
 //
     /// Check for magic
-extern void AiCheckMagic(void);
+extern void AiCheckMagic( void );
+
+
+//
+//      Ccl helpers
+//
+
+    /// Save/Load a PlayerAi structure ( see ccl_helpers.h for details )
+extern void IOPlayerAiFullPtr( SCM form, void *binaryform, void *para );
+
 
 //@}
 
-#endif // !__AI_LOCAL_H__
+#endif                         // !__AI_LOCAL_H__
Index: stratagus/src/ai/ai_magic.c
diff -u stratagus/src/ai/ai_magic.c:1.20 stratagus/src/ai/ai_magic.c:1.21
--- stratagus/src/ai/ai_magic.c:1.20    Mon Oct 13 22:47:35 2003
+++ stratagus/src/ai/ai_magic.c Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_magic.c     -       AI magic functions. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_magic.c,v 1.20 2003/10/14 02:47:35 jsalmon3 Exp $
+//      $Id: ai_magic.c,v 1.21 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -54,36 +54,35 @@
 **     Check what computer units can do with magic.
 **     In fact, turn on autocast for AI.
 */
-global void AiCheckMagic(void)
+global void AiCheckMagic( void )
 {
     int i, j;
     int n;
-    Unit** units;
-    Unit* unit;
-    const Player* player;
+    Unit **units;
+    Unit *unit;
+    const Player *player;
 #ifdef DEBUG
     int success;
 #endif
 
     n = AiPlayer->Player->TotalNumUnits;
     units = AiPlayer->Player->Units;
-    player = AiPlayer->Player;/*units[0]->Player*/
-    for (i = 0; i < n; ++i) {
+    player = AiPlayer->Player; /*units[0]->Player */
+    for ( i = 0; i < n; ++i ) {
        unit = units[i];
-       //  Check only magic units
-       if (unit->Type->CanCastSpell) {
-           for (j = 0; j < SpellTypeCount; ++j) {
-               //  Check if we can cast this spell. SpellIsAvailable checks 
for upgrades.
-               if (unit->Type->CanCastSpell[j] && SpellIsAvailable(player, j) 
&&
-                       (SpellTypeById(j)->AutoCast || 
SpellTypeById(j)->AICast)) {
+       //  Check only magic units
+       if ( unit->Type->CanCastSpell ) {
+           for ( j = 0; j < SpellTypeCount; ++j ) {
+              //  Check if we can cast this spell. SpellIsAvailable checks for 
upgrades.
+               if ( unit->Type->CanCastSpell[j] && SpellIsAvailable( player, j 
) &&
+                    ( SpellTypeById( j )->AutoCast || SpellTypeById( j 
)->AICast ) ) {
 #ifdef DEBUG
-                   success = // Follow on next line (AutoCastSpell).
+                   success =   // Follow on next line (AutoCastSpell).
 #endif
-                   AutoCastSpell(unit, SpellTypeById(j));
-                   DebugLevel3Fn("Mage '%s' cast '%s' : %s\n" _C_
-                       unit->Type->Ident _C_
-                       SpellTypeById(j)->Ident _C_
-                       success ? "success" : "fail");
+                       AutoCastSpell( unit, SpellTypeById( j ) );
+                   DebugLevel3Fn( "Mage '%s' cast '%s' : %s\n" _C_
+                                  unit->Type->Ident _C_
+                                  SpellTypeById( j )->Ident _C_ success ? 
"success" : "fail" );
                }
            }
        }
Index: stratagus/src/ai/ai_plan.c
diff -u stratagus/src/ai/ai_plan.c:1.17 stratagus/src/ai/ai_plan.c:1.18
--- stratagus/src/ai/ai_plan.c:1.17     Thu Sep 25 02:58:35 2003
+++ stratagus/src/ai/ai_plan.c  Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_plan.c      -       AI planning functions. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_plan.c,v 1.17 2003/09/25 06:58:35 mr-russ Exp $
+//      $Id: ai_plan.c,v 1.18 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -63,45 +63,44 @@
 **
 **     @return         Returns ideal target on map tile.
 */
-local Unit* EnemyOnMapTile(const Unit* source,int tx,int ty)
+local Unit *EnemyOnMapTile( const Unit * source, int tx, int ty )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
-    Unit* best;
-    const UnitType* type;
+    Unit *table[UnitMax];
+    Unit *unit;
+    Unit *best;
+    const UnitType *type;
     int n;
     int i;
 
-    n=SelectUnitsOnTile(tx,ty,table);
-    best=NoUnitP;
-    for( i=0; i<n; ++i ) {
-       unit=table[i];
-       // unusable unit ?
-       // if( UnitUnusable(unit) ) can't attack constructions
-       // FIXME: did SelectUnitsOnTile already filter this?
-       // Invisible and not Visible
-       if( unit->Removed || unit->Invisible || !unit->HP
-               || !(unit->Visible&(1<<source->Player->Player))
-               || unit->Orders[0].Action==UnitActionDie ) {
+    n = SelectUnitsOnTile( tx, ty, table );
+    best = NoUnitP;
+    for ( i = 0; i < n; ++i ) {
+       unit = table[i];
+       // unusable unit ?
+       // if( UnitUnusable(unit) ) can't attack constructions
+       // FIXME: did SelectUnitsOnTile already filter this?
+       // Invisible and not Visible
+       if ( unit->Removed || unit->Invisible || !unit->HP
+            || !( unit->Visible & ( 1 << source->Player->Player ) )
+            || unit->Orders[0].Action == UnitActionDie ) {
            continue;
        }
-       type=unit->Type;
-       if( tx<unit->X || tx>=unit->X+type->TileWidth
-               || ty<unit->Y || ty>=unit->Y+type->TileHeight ) {
+       type = unit->Type;
+       if ( tx < unit->X || tx >= unit->X + type->TileWidth
+            || ty < unit->Y || ty >= unit->Y + type->TileHeight ) {
            continue;
        }
-       if( !CanTarget(source->Type,unit->Type) ) {
+       if ( !CanTarget( source->Type, unit->Type ) ) {
            continue;
        }
-       if( !IsEnemy(source->Player,unit) ) {   // a friend or neutral
+       if ( !IsEnemy( source->Player, unit ) ) {       // a friend or neutral
            continue;
        }
-
-       //
-       //      Choose the best target.
-       //
-       if( !best || best->Type->Priority<unit->Type->Priority ) {
-           best=unit;
+       //
+       //      Choose the best target.
+       //
+       if ( !best || best->Type->Priority < unit->Type->Priority ) {
+           best = unit;
        }
     }
     return best;
@@ -115,14 +114,16 @@
 **
 **     @note only works for water transporters!
 */
-local void AiMarkWaterTransporter(const Unit* unit,unsigned char* matrix)
+local void AiMarkWaterTransporter( const Unit * unit, unsigned char *matrix )
 {
-    static const int xoffset[]={  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[]={ -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
-    } * points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -134,78 +135,78 @@
     int ep;
     int i;
     int w;
-    unsigned char* m;
+    unsigned char *m;
 
-    x=unit->X;
-    y=unit->Y;
-    w=TheMap.Width+2;
-    matrix+=w+w+2;
-    if( matrix[x+y*w] ) {              // already marked
-       DebugLevel0("Done\n");
+    x = unit->X;
+    y = unit->Y;
+    w = TheMap.Width + 2;
+    matrix += w + w + 2;
+    if ( matrix[x + y * w] ) { // already marked
+       DebugLevel0( "Done\n" );
        return;
     }
 
-    points=malloc(TheMap.Width*TheMap.Height);
-    size=TheMap.Width*TheMap.Height/sizeof(*points);
+    points = malloc( TheMap.Width * TheMap.Height );
+    size = TheMap.Width * TheMap.Height / sizeof ( *points );
 
-    //
-    // Make movement matrix.
-    //
-    mask=UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask&=~(MapFieldLandUnit|MapFieldAirUnit|MapFieldSeaUnit);
-
-    points[0].X=x;
-    points[0].Y=y;
-    rp=0;
-    matrix[x+y*w]=66;                          // mark start point
-    ep=wp=1;                                   // start with one point
-
-    //
-    // Pop a point from stack, push all neightbors which could be entered.
-    //
-    for( ;; ) {
-       while( rp!=ep ) {
-           rx=points[rp].X;
-           ry=points[rp].Y;
-           for( i=0; i<8; ++i ) {              // mark all neighbors
-               x=rx+xoffset[i];
-               y=ry+yoffset[i];
-               m=matrix+x+y*w;
-               if( *m ) {                      // already checked
+   //
+   //  Make movement matrix.
+   //
+    mask = UnitMovementMask( unit );
+   // Ignore all possible mobile units.
+    mask &= ~( MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit );
+
+    points[0].X = x;
+    points[0].Y = y;
+    rp = 0;
+    matrix[x + y * w] = 66;    // mark start point
+    ep = wp = 1;               // start with one point
+
+   //
+   //  Pop a point from stack, push all neightbors which could be entered.
+   //
+    for ( ;; ) {
+       while ( rp != ep ) {
+           rx = points[rp].X;
+           ry = points[rp].Y;
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
+               x = rx + xoffset[i];
+               y = ry + yoffset[i];
+               m = matrix + x + y * w;
+               if ( *m ) {     // already checked
                    continue;
                }
 
-               if( CanMoveToMask(x,y,mask) ) { // reachable
-                       
-                   *m=66;
-                   points[wp].X=x;             // push the point
-                   points[wp].Y=y;
-                   if( ++wp>=size ) {          // round about
-                       wp=0;
+               if ( CanMoveToMask( x, y, mask ) ) {    // reachable
+
+                   *m = 66;
+                   points[wp].X = x;   // push the point
+                   points[wp].Y = y;
+                   if ( ++wp >= size ) {       // round about
+                       wp = 0;
                    }
-               /*      Must be checked multiple
-               } else {                        // unreachable
-                   *m=99;
-               */
+                  /*      Must be checked multiple
+                     } else {                     // unreachable
+                     *m=99;
+                   */
                }
            }
 
-           if( ++rp>=size ) {                  // round about
-               rp=0;
+           if ( ++rp >= size ) {       // round about
+               rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if( rp==wp ) {                  // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
-       ep=wp;
+       ep = wp;
     }
 
-    free(points);
+    free( points );
 }
 
 /**
@@ -219,16 +220,17 @@
 **
 **     @return         True if target found.
 */
-local int AiFindTarget(const Unit* unit,unsigned char* matrix,
-       int* dx,int* dy,int* ds)
+local int AiFindTarget( const Unit * unit, unsigned char *matrix, int *dx, int 
*dy, int *ds )
 {
-    static const int xoffset[]={  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[]={ -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
        unsigned char State;
-    } * points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -240,123 +242,123 @@
     int ep;
     int i;
     int w;
-    enum { OnWater, OnLand, OnIsle } state;
-    unsigned char* m;
-
-    size=TheMap.Width*TheMap.Height/2;
-    points=malloc(size*sizeof(*points));
-
-    x=unit->X;
-    y=unit->Y;
-
-    w=TheMap.Width+2;
-    mask=UnitMovementMask(unit);
-    // Ignore all possible mobile units.
-    mask&=~(MapFieldLandUnit|MapFieldAirUnit|MapFieldSeaUnit);
-
-    points[0].X=x;
-    points[0].Y=y;
-    points[0].State=OnLand;
-    matrix+=w+w+2;
-    rp=0;
-    matrix[x+y*w]=1;                           // mark start point
-    ep=wp=1;                                   // start with one point
-
-    //
-    // Pop a point from stack, push all neightbors which could be entered.
-    //
-    for( ;; ) {
-       while( rp!=ep ) {
-           rx=points[rp].X;
-           ry=points[rp].Y;
-           state=points[rp].State;
-           for( i=0; i<8; ++i ) {              // mark all neighbors
-               x=rx+xoffset[i];
-               y=ry+yoffset[i];
-               m=matrix+x+y*w;
-
-               if( state!=OnWater ) {
-                   if( *m ) {                  // already checked
-                       if( state==OnLand && *m==66 ) { // tansporter?
-                           DebugLevel0Fn("->Water\n");
-                           *m=6;
-                           points[wp].X=x;     // push the point
-                           points[wp].Y=y;
-                           points[wp].State=OnWater;
-                           if( ++wp>=size ) {  // round about
-                               wp=0;
+    enum
+    { OnWater, OnLand, OnIsle }
+    state;
+    unsigned char *m;
+
+    size = TheMap.Width * TheMap.Height / 2;
+    points = malloc( size * sizeof ( *points ) );
+
+    x = unit->X;
+    y = unit->Y;
+
+    w = TheMap.Width + 2;
+    mask = UnitMovementMask( unit );
+   // Ignore all possible mobile units.
+    mask &= ~( MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit );
+
+    points[0].X = x;
+    points[0].Y = y;
+    points[0].State = OnLand;
+    matrix += w + w + 2;
+    rp = 0;
+    matrix[x + y * w] = 1;     // mark start point
+    ep = wp = 1;               // start with one point
+
+   //
+   //  Pop a point from stack, push all neightbors which could be entered.
+   //
+    for ( ;; ) {
+       while ( rp != ep ) {
+           rx = points[rp].X;
+           ry = points[rp].Y;
+           state = points[rp].State;
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
+               x = rx + xoffset[i];
+               y = ry + yoffset[i];
+               m = matrix + x + y * w;
+
+               if ( state != OnWater ) {
+                   if ( *m ) { // already checked
+                       if ( state == OnLand && *m == 66 ) {    // tansporter?
+                           DebugLevel0Fn( "->Water\n" );
+                           *m = 6;
+                           points[wp].X = x;   // push the point
+                           points[wp].Y = y;
+                           points[wp].State = OnWater;
+                           if ( ++wp >= size ) {       // round about
+                               wp = 0;
                            }
                        }
                        continue;
                    }
-
-                   // Check targets on tile?
-                   // FIXME: the move code didn't likes a shore building as
-                   //          target
-                   if( EnemyOnMapTile(unit,x,y) ) {
-                       DebugLevel0Fn("Target found %d,%d-%d\n"
-                               _C_ x _C_ y _C_ state);
-                       *dx=x;
-                       *dy=y;
-                       *ds=state;
-                       free(points);
+                  // Check targets on tile?
+                  // FIXME: the move code didn't likes a shore building as
+                  //          target
+                   if ( EnemyOnMapTile( unit, x, y ) ) {
+                       DebugLevel0Fn( "Target found %d,%d-%d\n" _C_ x _C_ y 
_C_ state );
+                       *dx = x;
+                       *dy = y;
+                       *ds = state;
+                       free( points );
                        return 1;
                    }
 
-                   if( CanMoveToMask(x,y,mask) ) {     // reachable
-                           
-                       *m=1;
-                       points[wp].X=x;         // push the point
-                       points[wp].Y=y;
-                       points[wp].State=state;
-                       if( ++wp>=size ) {      // round about
-                           wp=0;
+                   if ( CanMoveToMask( x, y, mask ) ) {        // reachable
+
+                       *m = 1;
+                       points[wp].X = x;       // push the point
+                       points[wp].Y = y;
+                       points[wp].State = state;
+                       if ( ++wp >= size ) {   // round about
+                           wp = 0;
                        }
-                   } else {                    // unreachable
-                       *m=99;
+                   } else {    // unreachable
+                       *m = 99;
                    }
-               } else {                        // On water
-                   if( *m ) {                  // already checked 
-                       if( *m==66 ) {          // tansporter?
-                           *m=6;
-                           points[wp].X=x;     // push the point
-                           points[wp].Y=y;
-                           points[wp].State=OnWater;
-                           if( ++wp>=size ) {  // round about
-                               wp=0;
+               } else {        // On water
+                   if ( *m ) { // already checked 
+                       if ( *m == 66 ) {       // tansporter?
+                           *m = 6;
+                           points[wp].X = x;   // push the point
+                           points[wp].Y = y;
+                           points[wp].State = OnWater;
+                           if ( ++wp >= size ) {       // round about
+                               wp = 0;
                            }
                        }
                        continue;
                    }
-                   if( CanMoveToMask(x,y,mask) ) {     // reachable
-                       DebugLevel0Fn("->Land\n");
-                       *m=1;
-                       points[wp].X=x;         // push the point
-                       points[wp].Y=y;
-                       points[wp].State=OnIsle;
-                       if( ++wp>=size ) {      // round about
-                           wp=0;
+                   if ( CanMoveToMask( x, y, mask ) ) {        // reachable
+                       DebugLevel0Fn( "->Land\n" );
+                       *m = 1;
+                       points[wp].X = x;       // push the point
+                       points[wp].Y = y;
+                       points[wp].State = OnIsle;
+                       if ( ++wp >= size ) {   // round about
+                           wp = 0;
                        }
-                   } else {                    // unreachable
-                       *m=99;
+                   } else {    // unreachable
+                       *m = 99;
                    }
                }
            }
 
-           if( ++rp>=size ) {                  // round about
-               rp=0;
+           if ( ++rp >= size ) {       // round about
+               rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if( rp==wp ) {                  // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
-       ep=wp;
+       ep = wp;
     }
-    free(points);
+    free( points );
     return 0;
 }
 
@@ -367,14 +369,16 @@
 **
 **     @return         True if wall found.
 */
-global int AiFindWall(AiForce* force)
+global int AiFindWall( AiForce * force )
 {
-    static const int xoffset[]={  0,-1,+1, 0, -1,+1,-1,+1 };
-    static const int yoffset[]={ -1, 0, 0,+1, -1,-1,+1,+1 };
-    struct {
+    static const int xoffset[] = { 0, -1, +1, 0, -1, +1, -1, +1 };
+    static const int yoffset[] = { -1, 0, 0, +1, -1, -1, +1, +1 };
+    struct
+    {
        unsigned short X;
        unsigned short Y;
-    } * points;
+    }
+    *points;
     int size;
     int x;
     int y;
@@ -386,108 +390,107 @@
     int ep;
     int i;
     int w;
-    unsigned char* m;
-    unsigned char* matrix;
+    unsigned char *m;
+    unsigned char *matrix;
     int destx;
     int desty;
-    AiUnit* aiunit;
-    Unit* unit;
+    AiUnit *aiunit;
+    Unit *unit;
 
-    // Find a unit to use.  Best choice is a land unit with range 1.
-    // Next best choice is any land unit.  Otherwise just use the first.
-    aiunit=force->Units;
-    unit=aiunit->Unit;
-    while( aiunit ) {
-       if( aiunit->Unit->Type->UnitType==UnitTypeLand ) {
-           unit=aiunit->Unit;
-           if( aiunit->Unit->Type->Missile.Missile->Range==1 ) {
+   // Find a unit to use.  Best choice is a land unit with range 1.
+   // Next best choice is any land unit.  Otherwise just use the first.
+    aiunit = force->Units;
+    unit = aiunit->Unit;
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->UnitType == UnitTypeLand ) {
+           unit = aiunit->Unit;
+           if ( aiunit->Unit->Type->Missile.Missile->Range == 1 ) {
                break;
            }
        }
-       aiunit=aiunit->Next;
+       aiunit = aiunit->Next;
     }
 
-    x=unit->X;
-    y=unit->Y;
-    size=TheMap.Width*TheMap.Height/4;
-    points=malloc(size*sizeof(*points));
-
-    destx=-1;
-    desty=-1;
-
-    matrix=CreateMatrix();
-    w=TheMap.Width+2;
-    matrix+=w+w+2;
-
-    points[0].X=x;
-    points[0].Y=y;
-    rp=0;
-    matrix[x+y*w]=1;                           // mark start point
-    ep=wp=1;                                   // start with one point
-
-    mask=UnitMovementMask(unit);
-
-    //
-    // Pop a point from stack, push all neighbors which could be entered.
-    //
-    for( ; destx==-1; ) {
-       while( rp!=ep && destx==-1 ) {
-           rx=points[rp].X;
-           ry=points[rp].Y;
-           for( i=0; i<8; ++i ) {              // mark all neighbors
-               x=rx+xoffset[i];
-               y=ry+yoffset[i];
-               m=matrix+x+y*w;
-               if( *m ) {
+    x = unit->X;
+    y = unit->Y;
+    size = TheMap.Width * TheMap.Height / 4;
+    points = malloc( size * sizeof ( *points ) );
+
+    destx = -1;
+    desty = -1;
+
+    matrix = CreateMatrix();
+    w = TheMap.Width + 2;
+    matrix += w + w + 2;
+
+    points[0].X = x;
+    points[0].Y = y;
+    rp = 0;
+    matrix[x + y * w] = 1;     // mark start point
+    ep = wp = 1;               // start with one point
+
+    mask = UnitMovementMask( unit );
+
+   //
+   //  Pop a point from stack, push all neighbors which could be entered.
+   //
+    for ( ; destx == -1; ) {
+       while ( rp != ep && destx == -1 ) {
+           rx = points[rp].X;
+           ry = points[rp].Y;
+           for ( i = 0; i < 8; ++i ) { // mark all neighbors
+               x = rx + xoffset[i];
+               y = ry + yoffset[i];
+               m = matrix + x + y * w;
+               if ( *m ) {
                    continue;
                }
-
-               // 
-               //      Check for a wall
-               //
-               if( WallOnMap(x,y) ) {
-                   DebugLevel0Fn("Wall found %d,%d\n" _C_ x _C_ y);
-                   destx=x;
-                   desty=y;
+              // 
+              //      Check for a wall
+              //
+               if ( WallOnMap( x, y ) ) {
+                   DebugLevel0Fn( "Wall found %d,%d\n" _C_ x _C_ y );
+                   destx = x;
+                   desty = y;
                    break;
                }
 
-               if( CanMoveToMask(x,y,mask) ) { // reachable
-                   *m=1;
-                   points[wp].X=x;             // push the point
-                   points[wp].Y=y;
-                   if( ++wp>=size ) {          // round about
-                       wp=0;
+               if ( CanMoveToMask( x, y, mask ) ) {    // reachable
+                   *m = 1;
+                   points[wp].X = x;   // push the point
+                   points[wp].Y = y;
+                   if ( ++wp >= size ) {       // round about
+                       wp = 0;
                    }
-               } else {                        // unreachable
-                   *m=99;
+               } else {        // unreachable
+                   *m = 99;
                }
            }
-           if( ++rp>=size ) {                  // round about
-               rp=0;
+           if ( ++rp >= size ) {       // round about
+               rp = 0;
            }
        }
 
-       //
-       //      Continue with next frame.
-       //
-       if( rp==wp ) {                  // unreachable, no more points available
+       //
+       //      Continue with next frame.
+       //
+       if ( rp == wp ) {       // unreachable, no more points available
            break;
        }
-       ep=wp;
+       ep = wp;
     }
-    free(points);
+    free( points );
 
-    if( destx!=-1 ) {
-       force->State=0;
-       aiunit=force->Units;
-       while( aiunit ) {
-           if( aiunit->Unit->Type->CanAttack ) {
-               CommandAttack(aiunit->Unit,destx,desty,NULL,FlushCommands);
+    if ( destx != -1 ) {
+       force->State = 0;
+       aiunit = force->Units;
+       while ( aiunit ) {
+           if ( aiunit->Unit->Type->CanAttack ) {
+               CommandAttack( aiunit->Unit, destx, desty, NULL, FlushCommands 
);
            } else {
-               CommandMove(aiunit->Unit,destx,desty,FlushCommands);
+               CommandMove( aiunit->Unit, destx, desty, FlushCommands );
            }
-           aiunit=aiunit->Next;
+           aiunit = aiunit->Next;
        }
        return 1;
     }
@@ -506,99 +509,96 @@
 **     @todo   Perfect planning.
 **             Only works for water transporter!
 */
-global int AiPlanAttack(AiForce* force)
+global int AiPlanAttack( AiForce * force )
 {
-    char* watermatrix;
-    const AiUnit* aiunit;
+    char *watermatrix;
+    const AiUnit *aiunit;
     int x;
     int y;
     int i;
     int state;
-    Unit* transporter;
+    Unit *transporter;
 
-    DebugLevel0Fn("Planning for force #%d of player #%d\n"
-       _C_ force-AiPlayer->Force _C_ AiPlayer->Player->Player);
+    DebugLevel0Fn( "Planning for force #%d of player #%d\n"
+                  _C_ force - AiPlayer->Force _C_ AiPlayer->Player->Player );
 
-    watermatrix=CreateMatrix();
+    watermatrix = CreateMatrix();
 
-    //
-    // Transporter must be already assigned to the force.
-    // NOTE: finding free transportes was too much work for me.
-    //
-    aiunit=force->Units;
-    state=1;
-    while( aiunit ) {
-       if( aiunit->Unit->Type->Transporter ) {
-           DebugLevel0Fn("Transporter #%d\n" _C_ UnitNumber(aiunit->Unit));
-           AiMarkWaterTransporter(aiunit->Unit,watermatrix);
-           state=0;
-       }
-       aiunit=aiunit->Next;
-    }
-
-    //
-    // No transport that belongs to the force.
-    //
-    transporter=NULL;
-    if( state ) {
-       for( i=0; i<AiPlayer->Player->TotalNumUnits; ++i ) { 
-           Unit* unit;
-
-           unit=AiPlayer->Player->Units[i];
-           if( unit->Type->Transporter 
-                   && unit->Orders[0].Action==UnitActionStill
-                   && unit->OrderCount==1 ) {
-               DebugLevel0Fn("Assign any transporter\n");
-               AiMarkWaterTransporter(unit,watermatrix);
-               // FIXME: can be the wrong transporter.
-               transporter=unit;
-               state=0;
+   //
+   //  Transporter must be already assigned to the force.
+   //  NOTE: finding free transportes was too much work for me.
+   //
+    aiunit = force->Units;
+    state = 1;
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->Transporter ) {
+           DebugLevel0Fn( "Transporter #%d\n" _C_ UnitNumber( aiunit->Unit ) );
+           AiMarkWaterTransporter( aiunit->Unit, watermatrix );
+           state = 0;
+       }
+       aiunit = aiunit->Next;
+    }
+
+   //
+   //  No transport that belongs to the force.
+   //
+    transporter = NULL;
+    if ( state ) {
+       for ( i = 0; i < AiPlayer->Player->TotalNumUnits; ++i ) {
+           Unit *unit;
+
+           unit = AiPlayer->Player->Units[i];
+           if ( unit->Type->Transporter && UnitIdle( unit ) ) {
+               DebugLevel0Fn( "Assign any transporter\n" );
+               AiMarkWaterTransporter( unit, watermatrix );
+              // FIXME: can be the wrong transporter.
+               transporter = unit;
+               state = 0;
            }
        }
     }
 
-    if( state ) {                      // Absolute no transporter
-       DebugLevel0Fn("No transporter available\n");
-       // FIXME: should tell the resource manager we need a transporter!
+    if ( state ) {             // Absolute no transporter
+       DebugLevel0Fn( "No transporter available\n" );
+       // FIXME: should tell the resource manager we need a transporter!
        return 0;
     }
-
-    //
-    // Find a land unit of the force.
-    //         FIXME: if force is split over different places -> broken
-    //
-    aiunit=force->Units;
-    while( aiunit ) {
-       if( aiunit->Unit->Type->UnitType==UnitTypeLand ) {
-           DebugLevel0Fn("Landunit %d\n" _C_ UnitNumber(aiunit->Unit));
+   //
+   //  Find a land unit of the force.
+   //          FIXME: if force is split over different places -> broken
+   //
+    aiunit = force->Units;
+    while ( aiunit ) {
+       if ( aiunit->Unit->Type->UnitType == UnitTypeLand ) {
+           DebugLevel0Fn( "Landunit %d\n" _C_ UnitNumber( aiunit->Unit ) );
            break;
        }
-       aiunit=aiunit->Next;
+       aiunit = aiunit->Next;
     }
 
-    if( !aiunit ) {
-       DebugLevel0Fn("No land unit in force\n");
+    if ( !aiunit ) {
+       DebugLevel0Fn( "No land unit in force\n" );
        return 0;
     }
 
-    if( AiFindTarget(aiunit->Unit,watermatrix,&x,&y,&state) ) {
-       AiUnit* aiunit;
+    if ( AiFindTarget( aiunit->Unit, watermatrix, &x, &y, &state ) ) {
+       AiUnit *aiunit;
 
-       if( transporter ) {
-           aiunit=malloc(sizeof(*aiunit));
-           aiunit->Next=force->Units;
-           force->Units=aiunit;
-           aiunit->Unit=transporter;
+       if ( transporter ) {
+           aiunit = malloc( sizeof ( *aiunit ) );
+           aiunit->Next = force->Units;
+           force->Units = aiunit;
+           aiunit->Unit = transporter;
            RefsDebugCheck( transporter->Destroyed || !transporter->Refs );
            ++transporter->Refs;
        }
 
-       DebugLevel0Fn("Can attack\n");
-       force->GoalX=x;
-       force->GoalY=y;
-       force->MustTransport= state==2 ;
+       DebugLevel0Fn( "Can attack\n" );
+       force->GoalX = x;
+       force->GoalY = y;
+       force->MustTransport = state == 2;
 
-       force->State=1;
+       force->State = 1;
        return 1;
     }
     return 0;
Index: stratagus/src/ai/ai_resource.c
diff -u stratagus/src/ai/ai_resource.c:1.71 stratagus/src/ai/ai_resource.c:1.72
--- stratagus/src/ai/ai_resource.c:1.71 Fri Sep 26 21:58:59 2003
+++ stratagus/src/ai/ai_resource.c      Thu Oct 23 14:38:34 2003
@@ -5,8 +5,8 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ai_resource.c  -       AI resource manager. */
 //
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: ai_resource.c,v 1.71 2003/09/27 01:58:59 n0body Exp $
+//      $Id: ai_resource.c,v 1.72 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -46,7 +46,7 @@
 #include "ai_local.h"
 #include "actions.h"
 
-local int AiMakeUnit(UnitType* type);
+local int AiMakeUnit( UnitType * type );
 
 /*----------------------------------------------------------------------------
 --     Variables
@@ -65,46 +65,47 @@
 **
 **     @return         A bit field of the missing costs.
 */
-local int AiCheckCosts(const int* costs)
+local int AiCheckCosts( const int *costs )
 {
     int i;
     int j;
     int k;
     int err;
-    const int* resources;
-    const int* reserve;
-    int* used;
+    const int *resources;
+    const int *reserve;
+    int *used;
     int nunits;
-    Unit** units;
-    const int* building_costs;
+    Unit **units;
+    const int *building_costs;
 
 
-    // FIXME: the used costs shouldn't be calculated here
-    used=AiPlayer->Used;
-    for( j=1; j<MaxCosts; ++j ) {
-       used[j]=0;
-    }
-
-    nunits=AiPlayer->Player->TotalNumUnits;
-    units=AiPlayer->Player->Units;
-    for( i=0; i<nunits; ++i ) {
-       for( k=0; k<units[i]->OrderCount; ++k ) {
-           if( units[i]->Orders[k].Action==UnitActionBuild ) {
-               
building_costs=units[i]->Orders[k].Type->Stats[AiPlayer->Player->Player].Costs;
-               for( j=1; j<MaxCosts; ++j ) {
-                   used[j]+=building_costs[j];
+   // FIXME: the used costs shouldn't be calculated here
+    used = AiPlayer->Used;
+    for ( j = 1; j < MaxCosts; ++j ) {
+       used[j] = 0;
+    }
+
+    nunits = AiPlayer->Player->TotalNumUnits;
+    units = AiPlayer->Player->Units;
+    for ( i = 0; i < nunits; ++i ) {
+       for ( k = 0; k < units[i]->OrderCount; ++k ) {
+           if ( units[i]->Orders[k].Action == UnitActionBuild ) {
+               building_costs =
+                   
units[i]->Orders[k].Type->Stats[AiPlayer->Player->Player].Costs;
+               for ( j = 1; j < MaxCosts; ++j ) {
+                   used[j] += building_costs[j];
                }
            }
        }
     }
 
 
-    err=0;
-    resources=AiPlayer->Player->Resources;
-    reserve=AiPlayer->Reserve;
-    for( i=1; i<MaxCosts; ++i ) {
-       if( resources[i]-used[i]<costs[i]-reserve[i] ) {
-           err|=1<<i;
+    err = 0;
+    resources = AiPlayer->Player->Resources;
+    reserve = AiPlayer->Reserve;
+    for ( i = 1; i < MaxCosts; ++i ) {
+       if ( resources[i] - used[i] < costs[i] - reserve[i] ) {
+           err |= 1 << i;
        }
     }
 
@@ -123,43 +124,40 @@
 **     @todo   The number of food currently trained can be stored global
 **             for faster use.
 */
-local int AiCheckFood(const PlayerAi* pai,const UnitType* type)
+local int AiCheckFood( const PlayerAi * pai, const UnitType * type )
 {
     int remaining;
-    const AiBuildQueue* queue;
+    const AiBuildQueue *queue;
 
-    DebugLevel3Fn(" for player %d\n" _C_ pai->Player->Player);
-    //
-    // Count food supplies under construction.
-    //
-    remaining=0;
-    for( queue=pai->UnitTypeBuilded; queue; queue=queue->Next ) {
-       if( queue->Type->Supply ) {
-           DebugLevel3Fn("Builded %d remain %d\n"
-               _C_ queue->Made _C_ remaining);
-           remaining+=queue->Made*queue->Type->Supply;
-       }
-    }
-    DebugLevel3Fn("Remain %d" _C_ remaining);
-    //
-    // We are already out of food.
-    //
-    remaining+=pai->Player->Food-pai->Player->NumFoodUnits-type->Demand;
-    DebugLevel3Fn("-Demand %d\n" _C_ remaining);
-    if( remaining<0 ) {
-       DebugLevel3Fn(" player %d needs more food\n" _C_ pai->Player->Player);
+    DebugLevel3Fn( " for player %d\n" _C_ pai->Player->Player );
+   //
+   //  Count food supplies under construction.
+   //
+    remaining = 0;
+    for ( queue = pai->UnitTypeBuilded; queue; queue = queue->Next ) {
+       if ( queue->Type->Supply ) {
+           DebugLevel3Fn( "Builded %d remain %d\n" _C_ queue->Made _C_ 
remaining );
+           remaining += queue->Made * queue->Type->Supply;
+       }
+    }
+    DebugLevel3Fn( "Remain %d" _C_ remaining );
+   //
+   //  We are already out of food.
+   //
+    remaining += pai->Player->Food - pai->Player->NumFoodUnits - type->Demand;
+    DebugLevel3Fn( "-Demand %d\n" _C_ remaining );
+    if ( remaining < 0 ) {
+       DebugLevel3Fn( " player %d needs more food\n" _C_ pai->Player->Player );
        return 0;
     }
-
-    //
-    // Count what we train.
-    //
-    for( queue=pai->UnitTypeBuilded; queue; queue=queue->Next ) {
-       if( !queue->Type->Building ) {
-           DebugLevel3Fn("Trained %d remain %d\n"
-               _C_ queue->Made _C_ remaining);
-           if( (remaining-=queue->Made*queue->Type->Demand)<0 ) {
-               DebugLevel3Fn(" player %d needs more food\n" _C_ 
pai->Player->Player);
+   //
+   //  Count what we train.
+   //
+    for ( queue = pai->UnitTypeBuilded; queue; queue = queue->Next ) {
+       if ( !queue->Type->Building ) {
+           DebugLevel3Fn( "Trained %d remain %d\n" _C_ queue->Made _C_ 
remaining );
+           if ( ( remaining -= queue->Made * queue->Type->Demand ) < 0 ) {
+               DebugLevel3Fn( " player %d needs more food\n" _C_ 
pai->Player->Player );
                return 0;
            }
        }
@@ -176,9 +174,9 @@
 **
 **     @return         A bit field of the missing costs.
 */
-local int AiCheckUnitTypeCosts(const UnitType* type)
+local int AiCheckUnitTypeCosts( const UnitType * type )
 {
-    return AiCheckCosts(type->Stats[AiPlayer->Player->Player].Costs);
+    return AiCheckCosts( type->Stats[AiPlayer->Player->Player].Costs );
 }
 
 /**
@@ -189,54 +187,53 @@
 **
 **     @return         Number of enemy units.
 */
-global int EnemyUnitsInDistance(const Unit* unit,unsigned range)
+global int EnemyUnitsInDistance( const Unit * unit, unsigned range )
 {
-    const Unit* dest;
-    const UnitType* type;
-    Unit* table[UnitMax];
+    const Unit *dest;
+    const UnitType *type;
+    Unit *table[UnitMax];
     unsigned x;
     unsigned y;
     unsigned n;
     unsigned i;
     int e;
-    const Player* player;
+    const Player *player;
 
-    DebugLevel3Fn("(%d)%s\n" _C_ UnitNumber(unit) _C_ unit->Type->Ident);
+    DebugLevel3Fn( "(%d)%s\n" _C_ UnitNumber( unit ) _C_ unit->Type->Ident );
 
-    //
-    // Select all units in range.
-    //
-    x=unit->X;
-    y=unit->Y;
-    n=SelectUnits(x-range,y-range,x+range+1,y+range+1,table);
-
-    player=unit->Player;
-    type=unit->Type;
-
-    //
-    // Find the enemy units which can attack
-    //
-    for( e=i=0; i<n; ++i ) {
-       dest=table[i];
-       //
-       //      unusable unit
-       //
-       // FIXME: did SelectUnits already filter this.
-       if( dest->Removed || dest->Invisible || !unit->HP
-               || !(dest->Visible&(1<<player->Player))
-               || dest->Orders[0].Action==UnitActionDie ) {
-           DebugLevel0Fn("NO\n");
+   //
+   //  Select all units in range.
+   //
+    x = unit->X;
+    y = unit->Y;
+    n = SelectUnits( x - range, y - range, x + range + 1, y + range + 1, table 
);
+
+    player = unit->Player;
+    type = unit->Type;
+
+   //
+   //  Find the enemy units which can attack
+   //
+    for ( e = i = 0; i < n; ++i ) {
+       dest = table[i];
+       //
+       //      unusable unit
+       //
+       // FIXME: did SelectUnits already filter this.
+       if ( dest->Removed || dest->Invisible || !unit->HP
+            || !( dest->Visible & ( 1 << player->Player ) )
+            || dest->Orders[0].Action == UnitActionDie ) {
+           DebugLevel0Fn( "NO\n" );
            continue;
        }
 
-       if( !IsEnemy(player,dest) ) {   // a friend or neutral
+       if ( !IsEnemy( player, dest ) ) {       // a friend or neutral
            continue;
        }
-
-       //
-       //      Unit can attack back?
-       //
-       if( CanTarget(dest->Type,type) ) {
+       //
+       //      Unit can attack back?
+       //
+       if ( CanTarget( dest->Type, type ) ) {
            ++e;
        }
     }
@@ -253,51 +250,52 @@
 **
 **     @note   We must check if the dependencies are fulfilled.
 */
-local int AiBuildBuilding(const UnitType* type,UnitType* building)
+local int AiBuildBuilding( const UnitType * type, UnitType * building )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
+    Unit *table[UnitMax];
+    Unit *unit;
     int nunits;
     int i;
     int num;
     int x;
     int y;
 
-    DebugLevel3Fn("%s can made %s\n" _C_ type->Ident _C_ building->Ident);
+    DebugLevel3Fn( "%s can made %s\n" _C_ type->Ident _C_ building->Ident );
 
-    IfDebug( unit=NoUnitP; );
-    //
-    //  Remove all workers on the way building something
-    //
-    nunits = FindPlayerUnitsByType(AiPlayer->Player,type,table);
-    for (num = i = 0; i < nunits; i++) {
+    IfDebug( unit = NoUnitP; );
+   //
+   //  Remove all workers on the way building something
+   //
+    nunits = FindPlayerUnitsByType( AiPlayer->Player, type, table );
+    for ( num = i = 0; i < nunits; i++ ) {
        unit = table[i];
-       for (x=0;x<unit->OrderCount;x++) {
-           if (unit->Orders[x].Action == UnitActionBuild
-                   || unit->Orders[x].Action == UnitActionRepair ) {
+       for ( x = 0; x < unit->OrderCount; x++ ) {
+           if ( unit->Orders[x].Action == UnitActionBuild
+                || unit->Orders[x].Action == UnitActionRepair ) {
                break;
            }
        }
-       if (x==unit->OrderCount) {
+       if ( x == unit->OrderCount ) {
            table[num++] = unit;
        }
     }
 
-    for( i=0; i<num; ++i ) {
+    for ( i = 0; i < num; ++i ) {
 
-       unit=table[i];
-       DebugLevel3Fn("Have an unit to build %d :)\n" _C_ UnitNumber(unit));
+       unit = table[i];
+       DebugLevel3Fn( "Have an unit to build %d :)\n" _C_ UnitNumber( unit ) );
 
-       //
-       //  Find place on that could be build.
-       //
-       if ( !AiFindBuildingPlace(unit,building,&x,&y) ) {
+       //
+       //  Find place on that could be build.
+       //
+       if ( !AiFindBuildingPlace( unit, building, &x, &y ) ) {
            continue;
        }
 
-       DebugLevel3Fn("Have a building place %d,%d for %s:)\n" _C_ x _C_ y _C_ 
building->Name);
+       DebugLevel3Fn( "Have a building place %d,%d for %s:)\n" _C_ x _C_ y _C_ 
building->
+                      Name );
 
-       CommandBuildBuilding(unit, x, y, building,FlushCommands);
+       CommandBuildBuilding( unit, x, y, building, FlushCommands );
 
        return 1;
     }
@@ -308,50 +306,50 @@
 /**
 **     Build new units to reduce the food shortage.
 */
-local void AiRequestFarms(void)
+local void AiRequestFarms( void )
 {
     int i;
     int n;
     int c;
-    UnitType* type;
-    AiBuildQueue* queue;
+    UnitType *type;
+    AiBuildQueue *queue;
     int counter[UnitTypeMax];
 
-    //
-    // Count the already made build requests.
-    //
-    memset(counter,0,sizeof(counter));
-    for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
-       counter[queue->Type->Type]+=queue->Want;
+   //
+   //  Count the already made build requests.
+   //
+    memset( counter, 0, sizeof ( counter ) );
+    for ( queue = AiPlayer->UnitTypeBuilded; queue; queue = queue->Next ) {
+       counter[queue->Type->Type] += queue->Want;
     }
 
-    //
-    // Check if we can build this?
-    //
-    n=AiHelpers.UnitLimit[0]->Count;
-    for( i=0; i<n; ++i ) {
-       type=AiHelpers.UnitLimit[0]->Table[i];
-       if( counter[type->Type] ) {     // Already ordered.
+   //
+   //  Check if we can build this?
+   //
+    n = AiHelpers.UnitLimit[0]->Count;
+    for ( i = 0; i < n; ++i ) {
+       type = AiHelpers.UnitLimit[0]->Table[i];
+       if ( counter[type->Type] ) {    // Already ordered.
            return;
        }
 
-       DebugLevel3Fn("Must build: %s\n" _C_ type->Ident);
-       //
-       //      Check if resources available.
-       //
-       if( (c=AiCheckUnitTypeCosts(type)) ) {
-           DebugLevel3("- no resources\n");
-           AiPlayer->NeededMask|=c;
+       DebugLevel3Fn( "Must build: %s\n" _C_ type->Ident );
+       //
+       //      Check if resources available.
+       //
+       if ( ( c = AiCheckUnitTypeCosts( type ) ) ) {
+           DebugLevel3( "- no resources\n" );
+           AiPlayer->NeededMask |= c;
            return;
        } else {
-           DebugLevel3("- enough resources\n");
-           if( AiMakeUnit(type) ) {
-               queue=malloc(sizeof(*AiPlayer->UnitTypeBuilded));
-               queue->Next=AiPlayer->UnitTypeBuilded;
-               queue->Type=type;
-               queue->Want=1;
-               queue->Made=1;
-               AiPlayer->UnitTypeBuilded=queue;
+           DebugLevel3( "- enough resources\n" );
+           if ( AiMakeUnit( type ) ) {
+               queue = malloc( sizeof ( *AiPlayer->UnitTypeBuilded ) );
+               queue->Next = AiPlayer->UnitTypeBuilded;
+               queue->Type = type;
+               queue->Want = 1;
+               queue->Made = 1;
+               AiPlayer->UnitTypeBuilded = queue;
            }
        }
     }
@@ -366,34 +364,34 @@
 **
 **     @note   We must check if the dependencies are fulfilled.
 */
-local int AiTrainUnit(const UnitType* type,UnitType* what)
+local int AiTrainUnit( const UnitType * type, UnitType * what )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
+    Unit *table[UnitMax];
+    Unit *unit;
     int nunits;
     int i;
     int num;
 
-    DebugLevel3Fn("%s can made %s\n" _C_ type->Ident _C_ what->Ident);
+    DebugLevel3Fn( "%s can made %s\n" _C_ type->Ident _C_ what->Ident );
 
-    IfDebug( unit=NoUnitP; );
-    //
-    //  Remove all units already doing something.
-    //
-    nunits = FindPlayerUnitsByType(AiPlayer->Player,type,table);
-    for (num = i = 0; i < nunits; i++) {
+    IfDebug( unit = NoUnitP; );
+   //
+   //  Remove all units already doing something.
+   //
+    nunits = FindPlayerUnitsByType( AiPlayer->Player, type, table );
+    for ( num = i = 0; i < nunits; i++ ) {
        unit = table[i];
-       if (unit->Orders[0].Action==UnitActionStill && unit->OrderCount==1 ) {
+       if ( UnitIdle( unit ) ) {
            table[num++] = unit;
        }
     }
 
-    for( i=0; i<num; ++i ) {
+    for ( i = 0; i < num; ++i ) {
 
-       unit=table[i];
-       DebugLevel3Fn("Have an unit to train %d :)\n" _C_ UnitNumber(unit));
+       unit = table[i];
+       DebugLevel3Fn( "Have an unit to train %d :)\n" _C_ UnitNumber( unit ) );
 
-       CommandTrainUnit(unit, what,FlushCommands);
+       CommandTrainUnit( unit, what, FlushCommands );
 
        return 1;
     }
@@ -402,6 +400,56 @@
 }
 
 /**
+**     Return the number of unit which can produce the given unittype. 
+**
+**     @param type the unittype we wan't to build
+*/
+global int AiCountUnitBuilders( UnitType * type )
+{
+    int result;
+    int i;
+    int n;
+    const int *unit_count;
+    AiUnitTypeTable *const *tablep;
+    const AiUnitTypeTable *table;
+
+    if ( !UnitIdAllowed( AiPlayer->Player, type->Type ) ) {
+       DebugLevel0Fn( "Can't build `%s' now\n" _C_ type->Ident );
+       return 0;
+    }
+   //
+   //  Check if we have a place for building or an unit to build.
+   //
+    if ( type->Building ) {
+       n = AiHelpers.BuildCount;
+       tablep = AiHelpers.Build;
+    } else {
+       n = AiHelpers.TrainCount;
+       tablep = AiHelpers.Train;
+    }
+    if ( type->Type > n ) {    // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
+       return 0;
+    }
+    table = tablep[type->Type];
+    if ( !table ) {            // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
+       return 0;
+    }
+    n = table->Count;
+
+    unit_count = AiPlayer->Player->UnitTypesCount;
+    result = 0;
+    for ( i = 0; i < n; ++i ) {
+       //
+       //      The type for builder/trainer is available
+       //
+       result += unit_count[table->Table[i]->Type];
+    }
+    return result;
+}
+
+/**
 **     Check if we can make an unit-type.
 **
 **     @param type     Unit-type that must be made.
@@ -409,50 +457,50 @@
 **
 **     @note   We must check if the dependencies are fulfilled.
 */
-local int AiMakeUnit(UnitType* type)
+local int AiMakeUnit( UnitType * type )
 {
     int i;
     int n;
-    const int* unit_count;
-    AiUnitTypeTable* const* tablep;
-    const AiUnitTypeTable* table;
-
-    DebugLevel3Fn(":%s\n" _C_ type->Name);
-
-    //
-    // Check if we have a place for building or an unit to build.
-    //
-    if( type->Building ) {
-       n=AiHelpers.BuildCount;
-       tablep=AiHelpers.Build;
+    const int *unit_count;
+    AiUnitTypeTable *const *tablep;
+    const AiUnitTypeTable *table;
+
+    DebugLevel3Fn( ":%s\n" _C_ type->Name );
+
+   //
+   //  Check if we have a place for building or an unit to build.
+   //
+    if ( type->Building ) {
+       n = AiHelpers.BuildCount;
+       tablep = AiHelpers.Build;
     } else {
-       n=AiHelpers.TrainCount;
-       tablep=AiHelpers.Train;
+       n = AiHelpers.TrainCount;
+       tablep = AiHelpers.Train;
     }
-    if( type->Type>n ) {               // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    if ( type->Type > n ) {    // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return 0;
     }
-    table=tablep[type->Type];
-    if( !table ) {                     // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    table = tablep[type->Type];
+    if ( !table ) {            // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return 0;
     }
-    n=table->Count;
+    n = table->Count;
 
-    unit_count=AiPlayer->Player->UnitTypesCount;
-    for( i=0; i<n; ++i ) {
-       //
-       //      The type for builder/trainer is available
-       //
-       if( unit_count[table->Table[i]->Type] ) {
-           DebugLevel3("Found a builder for a %s.\n" _C_ type->ident);
-           if( type->Building ) {
-               if( AiBuildBuilding(table->Table[i],type) ) {
+    unit_count = AiPlayer->Player->UnitTypesCount;
+    for ( i = 0; i < n; ++i ) {
+       //
+       //      The type for builder/trainer is available
+       //
+       if ( unit_count[table->Table[i]->Type] ) {
+           DebugLevel3( "Found a builder for a %s.\n" _C_ type->ident );
+           if ( type->Building ) {
+               if ( AiBuildBuilding( table->Table[i], type ) ) {
                    return 1;
                }
            } else {
-               if( AiTrainUnit(table->Table[i],type) ) {
+               if ( AiTrainUnit( table->Table[i], type ) ) {
                    return 1;
                }
            }
@@ -471,34 +519,34 @@
 **
 **     @note   We must check if the dependencies are fulfilled.
 */
-local int AiResearchUpgrade(const UnitType* type,Upgrade* what)
+local int AiResearchUpgrade( const UnitType * type, Upgrade * what )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
+    Unit *table[UnitMax];
+    Unit *unit;
     int nunits;
     int i;
     int num;
 
-    DebugLevel3Fn("%s can research %s\n" _C_ type->Ident _C_ what->Ident);
+    DebugLevel3Fn( "%s can research %s\n" _C_ type->Ident _C_ what->Ident );
 
-    IfDebug( unit=NoUnitP; );
-    //
-    //  Remove all units already doing something.
-    //
-    nunits = FindPlayerUnitsByType(AiPlayer->Player,type,table);
-    for (num = i = 0; i < nunits; i++) {
+    IfDebug( unit = NoUnitP; );
+   //
+   //  Remove all units already doing something.
+   //
+    nunits = FindPlayerUnitsByType( AiPlayer->Player, type, table );
+    for ( num = i = 0; i < nunits; i++ ) {
        unit = table[i];
-       if (unit->Orders[0].Action==UnitActionStill && unit->OrderCount==1 ) {
+       if ( UnitIdle( unit ) ) {
            table[num++] = unit;
        }
     }
 
-    for( i=0; i<num; ++i ) {
+    for ( i = 0; i < num; ++i ) {
 
-       unit=table[i];
-       DebugLevel3Fn("Have an unit to research %d :)\n" _C_ UnitNumber(unit));
+       unit = table[i];
+       DebugLevel3Fn( "Have an unit to research %d :)\n" _C_ UnitNumber( unit 
) );
 
-       CommandResearch(unit, what,FlushCommands);
+       CommandResearch( unit, what, FlushCommands );
 
        return 1;
     }
@@ -509,46 +557,45 @@
 /**
 **     Check if the research can be done.
 */
-global void AiAddResearchRequest(Upgrade* upgrade)
+global void AiAddResearchRequest( Upgrade * upgrade )
 {
     int i;
     int n;
-    const int* unit_count;
-    AiUnitTypeTable* const* tablep;
-    const AiUnitTypeTable* table;
-
-    //
-    // Check if resources are available.
-    //
-    if( (i=AiCheckCosts(upgrade->Costs)) ) {
-       AiPlayer->NeededMask|=i;
+    const int *unit_count;
+    AiUnitTypeTable *const *tablep;
+    const AiUnitTypeTable *table;
+
+   //
+   //  Check if resources are available.
+   //
+    if ( ( i = AiCheckCosts( upgrade->Costs ) ) ) {
+       AiPlayer->NeededMask |= i;
        return;
     }
+   //
+   //  Check if we have a place for the upgrade to research
+   //
+    n = AiHelpers.ResearchCount;
+    tablep = AiHelpers.Research;
 
-    //
-    // Check if we have a place for the upgrade to research
-    //
-    n=AiHelpers.ResearchCount;
-    tablep=AiHelpers.Research;
-
-    if( upgrade-Upgrades>n ) {         // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ upgrade->Ident);
+    if ( upgrade - Upgrades > n ) {    // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ upgrade->Ident );
        return;
     }
-    table=tablep[upgrade-Upgrades];
-    if( !table ) {                     // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ upgrade->Ident);
+    table = tablep[upgrade - Upgrades];
+    if ( !table ) {            // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ upgrade->Ident );
        return;
     }
-    n=table->Count;
+    n = table->Count;
 
-    unit_count=AiPlayer->Player->UnitTypesCount;
-    for( i=0; i<n; ++i ) {
-       //
-       //      The type is available
-       //
-       if( unit_count[table->Table[i]->Type] ) {
-           if( AiResearchUpgrade(table->Table[i],upgrade) ) {
+    unit_count = AiPlayer->Player->UnitTypesCount;
+    for ( i = 0; i < n; ++i ) {
+       //
+       //      The type is available
+       //
+       if ( unit_count[table->Table[i]->Type] ) {
+           if ( AiResearchUpgrade( table->Table[i], upgrade ) ) {
                return;
            }
        }
@@ -566,35 +613,34 @@
 **
 **     @note   We must check if the dependencies are fulfilled.
 */
-local int AiUpgradeTo(const UnitType* type,UnitType* what)
+local int AiUpgradeTo( const UnitType * type, UnitType * what )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
+    Unit *table[UnitMax];
+    Unit *unit;
     int nunits;
     int i;
     int num;
 
-    DebugLevel3Fn("%s can upgrade-to %s\n" _C_ type->Ident _C_ what->Ident);
+    DebugLevel3Fn( "%s can upgrade-to %s\n" _C_ type->Ident _C_ what->Ident );
 
-    IfDebug( unit=NoUnitP; );
-    //
-    //  Remove all units already doing something.
-    //
-    nunits = FindPlayerUnitsByType(AiPlayer->Player,type,table);
-    for (num = i = 0; i < nunits; i++) {
+    IfDebug( unit = NoUnitP; );
+   //
+   //  Remove all units already doing something.
+   //
+    nunits = FindPlayerUnitsByType( AiPlayer->Player, type, table );
+    for ( num = i = 0; i < nunits; i++ ) {
        unit = table[i];
-       if (unit->Orders[0].Action==UnitActionStill && unit->OrderCount==1 ) {
+       if ( UnitIdle( unit ) ) {
            table[num++] = unit;
        }
     }
 
-    for( i=0; i<num; ++i ) {
+    for ( i = 0; i < num; ++i ) {
 
-       unit=table[i];
-       DebugLevel3Fn("Have an unit to upgrade-to %d :)\n" _C_
-               UnitNumber(unit));
+       unit = table[i];
+       DebugLevel3Fn( "Have an unit to upgrade-to %d :)\n" _C_ UnitNumber( 
unit ) );
 
-       CommandUpgradeTo(unit, what,FlushCommands);
+       CommandUpgradeTo( unit, what, FlushCommands );
 
        return 1;
     }
@@ -605,46 +651,45 @@
 /**
 **     Check if the upgrade-to can be done.
 */
-global void AiAddUpgradeToRequest(UnitType* type)
+global void AiAddUpgradeToRequest( UnitType * type )
 {
     int i;
     int n;
-    const int* unit_count;
-    AiUnitTypeTable* const* tablep;
-    const AiUnitTypeTable* table;
-
-    //
-    // Check if resources are available.
-    //
-    if( (i=AiCheckUnitTypeCosts(type)) ) {
-       AiPlayer->NeededMask|=i;
+    const int *unit_count;
+    AiUnitTypeTable *const *tablep;
+    const AiUnitTypeTable *table;
+
+   //
+   //  Check if resources are available.
+   //
+    if ( ( i = AiCheckUnitTypeCosts( type ) ) ) {
+       AiPlayer->NeededMask |= i;
        return;
     }
+   //
+   //  Check if we have a place for the upgrade to.
+   //
+    n = AiHelpers.UpgradeCount;
+    tablep = AiHelpers.Upgrade;
 
-    //
-    // Check if we have a place for the upgrade to.
-    //
-    n=AiHelpers.UpgradeCount;
-    tablep=AiHelpers.Upgrade;
-
-    if( type->Type>n ) {               // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    if ( type->Type > n ) {    // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return;
     }
-    table=tablep[type->Type];
-    if( !table ) {                     // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    table = tablep[type->Type];
+    if ( !table ) {            // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return;
     }
-    n=table->Count;
+    n = table->Count;
 
-    unit_count=AiPlayer->Player->UnitTypesCount;
-    for( i=0; i<n; ++i ) {
-       //
-       //      The type is available
-       //
-       if( unit_count[table->Table[i]->Type] ) {
-           if( AiUpgradeTo(table->Table[i],type) ) {
+    unit_count = AiPlayer->Player->UnitTypesCount;
+    for ( i = 0; i < n; ++i ) {
+       //
+       //      The type is available
+       //
+       if ( unit_count[table->Table[i]->Type] ) {
+           if ( AiUpgradeTo( table->Table[i], type ) ) {
                return;
            }
        }
@@ -656,74 +701,70 @@
 /**
 **     Check what must be builded / trained.
 */
-local void AiCheckingWork(void)
+local void AiCheckingWork( void )
 {
     int c;
-    UnitType* type;
-    AiBuildQueue* queue;
+    UnitType *type;
+    AiBuildQueue *queue;
 
-    DebugLevel3Fn("%d:%d %d %d\n" _C_ AiPlayer->Player->Player _C_
-           AiPlayer->Player->Resources[1] _C_
-           AiPlayer->Player->Resources[2] _C_
-           AiPlayer->Player->Resources[3]);
-
-    // Food has the highest priority
-    if( AiPlayer->NeedFood ) {
-       DebugLevel3Fn("player %d needs food.\n" _C_ AiPlayer->Player->Player);
-       if( !(AiPlayer->UnitTypeBuilded && 
AiPlayer->UnitTypeBuilded->Type->Supply) ) {
-           AiPlayer->NeedFood=0;
+    DebugLevel3Fn( "%d:%d %d %d\n" _C_ AiPlayer->Player->Player _C_
+                  AiPlayer->Player->Resources[1] _C_
+                  AiPlayer->Player->Resources[2] _C_ 
AiPlayer->Player->Resources[3] );
+
+   // Food has the highest priority
+    if ( AiPlayer->NeedFood ) {
+       DebugLevel3Fn( "player %d needs food.\n" _C_ AiPlayer->Player->Player );
+       if ( !( AiPlayer->UnitTypeBuilded && 
AiPlayer->UnitTypeBuilded->Type->Supply ) ) {
+           AiPlayer->NeedFood = 0;
            AiRequestFarms();
        }
     }
-
-    //
-    // Look to the build requests, what can be done.
-    //
-    for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
-       if( queue->Want>queue->Made ) {
-           type=queue->Type;
-           DebugLevel3Fn("Must build: %s\n" _C_ type->Ident);
-
-           //
-           //  FIXME: must check if requirements are fulfilled.
-           //          Buildings can be destructed.
-
-           //
-           //  Check limits, AI should be broken if reached.
-           //
-           if( !PlayerCheckLimits(AiPlayer->Player,type) ) {
-               DebugLevel2Fn("Unit limits reached\n");
+   //
+   //  Look to the build requests, what can be done.
+   //
+    for ( queue = AiPlayer->UnitTypeBuilded; queue; queue = queue->Next ) {
+       if ( queue->Want > queue->Made ) {
+           type = queue->Type;
+           DebugLevel3Fn( "Must build: %s\n" _C_ type->Ident );
+
+          //
+          //  FIXME: must check if requirements are fulfilled.
+          //          Buildings can be destructed.
+
+          //
+          //  Check limits, AI should be broken if reached.
+          //
+           if ( !PlayerCheckLimits( AiPlayer->Player, type ) ) {
+               DebugLevel2Fn( "Unit limits reached\n" );
                continue;
            }
-
-           //
-           //  Check if we have enough food.
-           //
-           if( !type->Building ) {
-               // Count future
-               if(  !AiCheckFood(AiPlayer,type) ) {
-                   AiPlayer->NeedFood=1;
+          //
+          //  Check if we have enough food.
+          //
+           if ( !type->Building ) {
+              // Count future
+               if ( !AiCheckFood( AiPlayer, type ) ) {
+                   AiPlayer->NeedFood = 1;
                    AiRequestFarms();
                }
-               // Current limit
-               if( !PlayerCheckFood(AiPlayer->Player,type) ) {
+              // Current limit
+               if ( !PlayerCheckFood( AiPlayer->Player, type ) ) {
                    continue;
                }
            }
-
-           //
-           //  Check if resources available.
-           //
-           if( (c=AiCheckUnitTypeCosts(type)) ) {
-               DebugLevel3("- no resources\n");
-               AiPlayer->NeededMask|=c;
-               //
-               //      NOTE: we can continue and build things with lesser
-               //              resource or other resource need!
+          //
+          //  Check if resources available.
+          //
+           if ( ( c = AiCheckUnitTypeCosts( type ) ) ) {
+               DebugLevel3( "- no resources\n" );
+               AiPlayer->NeededMask |= c;
+              //
+              //      NOTE: we can continue and build things with lesser
+              //              resource or other resource need!
                continue;
            } else {
-               DebugLevel3("- enough resources\n");
-               if( AiMakeUnit(type) ) {
+               DebugLevel3( "- enough resources\n" );
+               if ( AiMakeUnit( type ) ) {
                    ++queue->Made;
                }
            }
@@ -743,36 +784,36 @@
 **
 **     @return 1 if the worker was assigned, 0 otherwise.
 */
-local int AiAssignHarvester(Unit * unit,int resource)
+local int AiAssignHarvester( Unit * unit, int resource )
 {
-    ResourceInfo * resinfo;
-    //  These will hold the coordinates of the forest.
+    ResourceInfo *resinfo;
+   //  These will hold the coordinates of the forest.
     int forestx;
     int foresty;
-    //  This will hold the resulting gather destination.
-    Unit* dest;
-    
-    resinfo=unit->Type->ResInfo[resource];
-    DebugCheck(!resinfo);
-    if (resinfo->TerrainHarvester) {
-       //
-       //      Code for terrain harvesters. Search for piece of terrain to 
mine.
-       //
-       if (FindTerrainType(UnitMovementMask(unit),MapFieldForest,0,1000,
-               unit->Player,unit->X,unit->Y,&forestx,&foresty)) {
-           CommandResourceLoc(unit, forestx, foresty,FlushCommands);
+   //  This will hold the resulting gather destination.
+    Unit *dest;
+
+    resinfo = unit->Type->ResInfo[resource];
+    DebugCheck( !resinfo );
+    if ( resinfo->TerrainHarvester ) {
+       //
+       //      Code for terrain harvesters. Search for piece of terrain to 
mine.
+       //
+       if ( FindTerrainType( UnitMovementMask( unit ), MapFieldForest, 0, 1000,
+                             unit->Player, unit->X, unit->Y, &forestx, 
&foresty ) ) {
+           CommandResourceLoc( unit, forestx, foresty, FlushCommands );
            return 1;
        }
     } else {
-       //
-       //      Find a resource to ravest from.
-       //
-       if ((dest=FindResource(unit,unit->X,unit->Y,1000,resource))) {
-           CommandResource(unit,dest,FlushCommands);
+       //
+       //      Find a resource to ravest from.
+       //
+       if ( ( dest = FindResource( unit, unit->X, unit->Y, 1000, resource ) ) 
) {
+           CommandResource( unit, dest, FlushCommands );
            return 1;
        }
     }
-    //  Failed.
+   //  Failed.
     return 0;
 }
 
@@ -782,127 +823,125 @@
 **     If we have a shortage of a resource, let many workers collecting this.
 **     If no shortage, split workers to all resources.
 */
-local void AiCollectResources(void)
+local void AiCollectResources( void )
 {
-    Unit* units_with_resource[UnitMax][MaxCosts];   // Worker with resource
+    Unit *units_with_resource[UnitMax][MaxCosts];      // Worker with resource
     int num_units_with_resource[MaxCosts];
-    Unit* units_assigned[UnitMax][MaxCosts];       // Worker assigned to 
resource
+    Unit *units_assigned[UnitMax][MaxCosts];   // Worker assigned to resource
     int num_units_assigned[MaxCosts];
-    Unit* units_unassigned[UnitMax][MaxCosts];     // Unassigned workers
+    Unit *units_unassigned[UnitMax][MaxCosts]; // Unassigned workers
     int num_units_unassigned[MaxCosts];
-    int total;                                     // Total of workers
+    int total;                 // Total of workers
     int c;
     int i;
     int n;
     int o;
-    Unit** units;
-    Unit* unit;
+    Unit **units;
+    Unit *unit;
     int percent[MaxCosts];
     int percent_total;
 
-    //
-    // Collect statistics about the current assignment
-    //
+   //
+   //  Collect statistics about the current assignment
+   //
     percent_total = 100;
-    for( c=0; c<MaxCosts; c++ ) {
-       num_units_with_resource[c]=0;
-       num_units_assigned[c]=0;
-       num_units_unassigned[c]=0;
-       percent[c]=AiPlayer->Collect[c];
-       if( (AiPlayer->NeededMask&(1<<c)) ) {   // Double percent if needed
-           percent_total+=percent[c];
-           percent[c]<<=1;
+    for ( c = 0; c < MaxCosts; c++ ) {
+       num_units_with_resource[c] = 0;
+       num_units_assigned[c] = 0;
+       num_units_unassigned[c] = 0;
+       percent[c] = AiPlayer->Collect[c];
+       if ( ( AiPlayer->NeededMask & ( 1 << c ) ) ) {  // Double percent if 
needed
+           percent_total += percent[c];
+           percent[c] <<= 1;
        }
     }
 
-    n=AiPlayer->Player->TotalNumUnits;
-    units=AiPlayer->Player->Units;
-    for( i=0; i<n; i++ ) {
-       unit=units[i];
-       if( (!unit->Type->Harvester) || (unit->Removed )) {
+    n = AiPlayer->Player->TotalNumUnits;
+    units = AiPlayer->Player->Units;
+    for ( i = 0; i < n; i++ ) {
+       unit = units[i];
+       if ( ( !unit->Type->Harvester ) || ( unit->Removed ) ) {
            continue;
        }
 
-       c=unit->CurrentResource;
-       //
-       //      See if it's assigned already
-       //
-       if (unit->Orders[0].Action==UnitActionResource&&c) {
-           units_assigned[num_units_assigned[c]++][c]=unit;
+       c = unit->CurrentResource;
+       //
+       //      See if it's assigned already
+       //
+       if ( unit->Orders[0].Action == UnitActionResource && c ) {
+           units_assigned[num_units_assigned[c]++][c] = unit;
            continue;
        }
-
-       //
-       //      Ignore busy units.
-       //      
-       if (unit->Orders->Action != UnitActionStill || unit->OrderCount!=1 ) {
+       //
+       //      Ignore busy units.
+       //      
+       if ( !UnitIdle( unit ) ) {
            continue;
        }
-
-       //
-       //      Send workers with resources back home.
-       //
-       if (unit->Value&&c) {
-           units_with_resource[num_units_with_resource[c]++][c]=unit;
-           CommandReturnGoods(unit,0,FlushCommands);
+       //
+       //      Send workers with resources back home.
+       //
+       if ( unit->Value && c ) {
+           units_with_resource[num_units_with_resource[c]++][c] = unit;
+           CommandReturnGoods( unit, 0, FlushCommands );
            continue;
        }
-       
-       //
-       //      Look what the unit can do
-       //
-       for( c=0; c<MaxCosts; ++c ) {
-           if (unit->Type->ResInfo[c]) {
-               units_unassigned[num_units_unassigned[c]++][c]=unit;
+       //
+       //      Look what the unit can do
+       //
+       for ( c = 0; c < MaxCosts; ++c ) {
+           if ( unit->Type->ResInfo[c] ) {
+               units_unassigned[num_units_unassigned[c]++][c] = unit;
            }
        }
     }
 
-    total=0;
-    for( c=0; c<MaxCosts; ++c ) {
-       total+=num_units_assigned[c]+num_units_with_resource[c];
-       DebugLevel3Fn("Assigned %d = %d\n" _C_ c _C_ num_units_assigned[c]);
-       DebugLevel3Fn("Resource %d = %d\n" _C_ c _C_ 
num_units_with_resource[c]);
+    total = 0;
+    for ( c = 0; c < MaxCosts; ++c ) {
+       total += num_units_assigned[c] + num_units_with_resource[c];
+       DebugLevel3Fn( "Assigned %d = %d\n" _C_ c _C_ num_units_assigned[c] );
+       DebugLevel3Fn( "Resource %d = %d\n" _C_ c _C_ 
num_units_with_resource[c] );
     }
 #ifdef DEBUG
-    DebugLevel3Fn("Unassigned %d of total %d\n" _C_ num_units_unassigned[c] 
_C_ total);
-    if (AiPlayer->Player==ThisPlayer) {
-       DebugLevel3Fn("Percent Assignment:");
-       for( c=0; c<MaxCosts; ++c ) {
-           if (percent[c]) {
-               DebugLevel3(" %s:%d%%" _C_ DefaultResourceNames[c] _C_ 
percent[c]);
+    DebugLevel3Fn( "Unassigned %d of total %d\n" _C_ num_units_unassigned[c] 
_C_ total );
+    if ( AiPlayer->Player == ThisPlayer ) {
+       DebugLevel3Fn( "Percent Assignment:" );
+       for ( c = 0; c < MaxCosts; ++c ) {
+           if ( percent[c] ) {
+               DebugLevel3( " %s:%d%%" _C_ DefaultResourceNames[c] _C_ 
percent[c] );
            }
        }
-       DebugLevel3("\n");
+       DebugLevel3( "\n" );
     }
- 
 #endif
 
-    //
-    // Reassign free workers
-    //
-    for( c=0; c<MaxCosts; ++c ) {
-       if( num_units_unassigned[c]==0 ) {
-           if( percent[c] == 0 ) {
+   //
+   //  Reassign free workers
+   //
+    for ( c = 0; c < MaxCosts; ++c ) {
+       if ( num_units_unassigned[c] == 0 ) {
+           if ( percent[c] == 0 ) {
                continue;
            }
-           for( i=0; i<MaxCosts; ++i ) {
-               if( i==c ) {
+           for ( i = 0; i < MaxCosts; ++i ) {
+               if ( i == c ) {
                    continue;
                }
-               //  FIXME: Shouldn't this turn into a while? currently max one 
worker is transfered.
-               if( (percent[i] < percent[c] &&
-                   
((num_units_assigned[c]+num_units_with_resource[c]-1)*percent_total > 
total*percent[c] || 
-                     num_units_assigned[c]+num_units_with_resource[c]==0)) ||
-                   
(num_units_assigned[i]+num_units_with_resource[i]-1)*percent_total > 
total*percent[i] ) {
-                   //  We take workers from resource i and move them to 
resource c
+              //  FIXME: Shouldn't this turn into a while? currently max one 
worker is transfered.
+               if ( ( percent[i] < percent[c] &&
+                      ( ( num_units_assigned[c] + num_units_with_resource[c] -
+                          1 ) * percent_total > total * percent[c]
+                        || num_units_assigned[c] + num_units_with_resource[c] 
== 0 ) )
+                    || ( num_units_assigned[i] + num_units_with_resource[i] -
+                         1 ) * percent_total > total * percent[i] ) {
+                  //  We take workers from resource i and move them to 
resource c
                    int j;
-                   for( j=num_units_assigned[i]-1; j>=0; --j ) {
-                       unit=units_assigned[j][i];
-                       if( unit && unit->SubAction < 50 ) {
+                   for ( j = num_units_assigned[i] - 1; j >= 0; --j ) {
+                       unit = units_assigned[j][i];
+                       if ( unit && unit->SubAction < 50 ) {
                            units_assigned[j][i] = 
units_assigned[--num_units_assigned[i]][i];
                            --total;
-                           units_unassigned[num_units_unassigned[c]++][c]=unit;
+                           units_unassigned[num_units_unassigned[c]++][c] = 
unit;
                            break;
                        }
                    }
@@ -910,66 +949,68 @@
            }
        }
     }
-    
-    //
-    // Now assign the free workers.
-    //
-    for( n=0; n<MaxCosts; ++n ) {
-       for( i=0; i<num_units_unassigned[n]; i++ ) {
+
+   //
+   //  Now assign the free workers.
+   //
+    for ( n = 0; n < MaxCosts; ++n ) {
+       for ( i = 0; i < num_units_unassigned[n]; i++ ) {
            int t;
            int max;
 
-           //
-           //  Loop through all of the workers.
-           //
-           unit=units_unassigned[i][n];
-
-           //
-           //  Here we determine what to assign the worker to first. 
-           //
-           for( max=o=c=0; c<MaxCosts; ++c ) {
-               DebugLevel3Fn("%d, %d, %d\n" _C_
-                   
(num_units_assigned[c]+num_units_with_resource[c])*percent_total _C_
-                   percent[c] _C_
-                   total*percent[c]);
-               
t=(num_units_assigned[c]+num_units_with_resource[c])*percent_total;
-               if( t < total*percent[c] ) {
-                   if( total*percent[c]-t > max ) {
-                       max=total*percent[c]-t;
-                       o=c;
+          //
+          //  Loop through all of the workers.
+          //
+           unit = units_unassigned[i][n];
+
+          //
+          //  Here we determine what to assign the worker to first. 
+          //
+           for ( max = o = c = 0; c < MaxCosts; ++c ) {
+               DebugLevel3Fn( "%d, %d, %d\n" _C_
+                              ( num_units_assigned[c] +
+                                num_units_with_resource[c] ) *
+                              percent_total _C_ percent[c] _C_ total * 
percent[c] );
+               t = ( num_units_assigned[c] + num_units_with_resource[c] ) * 
percent_total;
+               if ( t < total * percent[c] ) {
+                   if ( total * percent[c] - t > max ) {
+                       max = total * percent[c] - t;
+                       o = c;
                    }
                }
            }
 
-           //
-           //  Look what the unit can do
-           //
-           for( t=0; t<MaxCosts; ++t ) {
-               //
-               //  Now we have to assign it to resource c
-               //  
-               c=(t+o)%MaxCosts;
-               if (!unit->Type->ResInfo[c]) {
-                   continue; //        Alas, we can't mine c
+          //
+          //  Look what the unit can do
+          //
+           for ( t = 0; t < MaxCosts; ++t ) {
+              //
+              //  Now we have to assign it to resource c
+              //  
+               c = ( t + o ) % MaxCosts;
+               if ( !unit->Type->ResInfo[c] ) {
+                   continue;   //        Alas, we can't mine c
                }
-               //
-               //  Look if it is a worker for this resource
-               //
-               if( AiAssignHarvester(unit,c) ) {
-                   int n1,n2;
-                   DebugLevel3Fn("Assigned %d to %s\n" _C_ unit->Slot _C_ 
DefaultResourceNames[c]);
-                   units_assigned[num_units_assigned[c]++][c]=unit;
+              //
+              //  Look if it is a worker for this resource
+              //
+               if ( AiAssignHarvester( unit, c ) ) {
+                   int n1, n2;
+                   DebugLevel3Fn( "Assigned %d to %s\n" _C_ unit->
+                                  Slot _C_ DefaultResourceNames[c] );
+                   units_assigned[num_units_assigned[c]++][c] = unit;
                    units_unassigned[i][c] = 
units_unassigned[--num_units_unassigned[c]][c];
-                   for( n1=0; n1<MaxCosts; ++n1 ) {
-                       for( n2=0; n2<num_units_unassigned[n1]; ++n2 ) {
-                           if( units_unassigned[n2][n1]==unit ) {
-                               
units_unassigned[n2][n1]=units_unassigned[--num_units_unassigned[n1]][n1];
+                   for ( n1 = 0; n1 < MaxCosts; ++n1 ) {
+                       for ( n2 = 0; n2 < num_units_unassigned[n1]; ++n2 ) {
+                           if ( units_unassigned[n2][n1] == unit ) {
+                               units_unassigned[n2][n1] =
+                                   
units_unassigned[--num_units_unassigned[n1]][n1];
                                break;
                            }
                        }
                    }
                    ++total;
-                   //  We assigned this worker to something already.
+                  //  We assigned this worker to something already.
                    break;
                }
            }
@@ -988,11 +1029,11 @@
 **     @param building Building to be repaired.
 **     @return         True if can repair, false if can't repair..
 */
-local int AiRepairBuilding(const UnitType* type,Unit* building)
+local int AiRepairBuilding( const UnitType * type, Unit * building )
 {
-    Unit* table[UnitMax];
-    Unit* unit;
-    Unit* unit_temp;
+    Unit *table[UnitMax];
+    Unit *unit;
+    Unit *unit_temp;
     int distance[UnitMax];
     int rX;
     int rY;
@@ -1004,54 +1045,55 @@
     int k;
     int num;
 
-    DebugLevel3Fn("%s can repair %s\n" _C_ type->Ident _C_
-           building->Type->Ident);
+    DebugLevel3Fn( "%s can repair %s\n" _C_ type->Ident _C_ 
building->Type->Ident );
 
-    IfDebug( unit=NoUnitP; );
-    //
-    //  Remove all workers not mining. on the way building something
-    // FIXME: It is not clever to use workers with gold
-    //  Idea: Antonis: Put the rest of the workers in a table in case
-    //  miners can't reach but others can. This will be useful if AI becomes
-    //  more flexible (e.g.: transports workers to an island)
-    // FIXME: too hardcoded, not nice, needs improvement.
-    //  FIXME: too many workers repair the same building!
-
-    // Selection of mining workers.
-    nunits = FindPlayerUnitsByType(AiPlayer->Player,type,table);
-    for (num = i = 0; i < nunits; i++) {
+    IfDebug( unit = NoUnitP; );
+   //
+   //  Remove all workers not mining. on the way building something
+   //  FIXME: It is not clever to use workers with gold
+   //  Idea: Antonis: Put the rest of the workers in a table in case
+   //  miners can't reach but others can. This will be useful if AI becomes
+   //  more flexible (e.g.: transports workers to an island)
+   //  FIXME: too hardcoded, not nice, needs improvement.
+   //  FIXME: too many workers repair the same building!
+
+   // Selection of mining workers.
+    nunits = FindPlayerUnitsByType( AiPlayer->Player, type, table );
+    for ( num = i = 0; i < nunits; i++ ) {
        unit = table[i];
        if ( unit->Type->RepairRange &&
-               (unit->Orders[0].Action==UnitActionResource ||
-               unit->Orders[0].Action==UnitActionStill) &&
-               unit->OrderCount==1 ) {
+            ( unit->Orders[0].Action == UnitActionResource ||
+              unit->Orders[0].Action == UnitActionStill ) && unit->OrderCount 
== 1 ) {
            table[num++] = unit;
        }
     }
 
-    // Sort by distance loops -Antonis-
-    for (i=0; i<num; ++i) {
+   // Sort by distance loops -Antonis-
+    for ( i = 0; i < num; ++i ) {
        unit = table[i];
-       //      FIXME: Probably calculated from top left corner of building
-       if ((rX = unit->X - building->X) < 0) { rX = -rX; }
-       if ((rY = unit->Y - building->Y) < 0) { rY = -rY; }
-       if (rX<rY) {
-           distance[i] = rX;
+       //      FIXME: Probably calculated from top left corner of building
+       if ( ( rX = unit->X - building->X ) < 0 ) {
+           rX = -rX;
        }
-       else {
+       if ( ( rY = unit->Y - building->Y ) < 0 ) {
+           rY = -rY;
+       }
+       if ( rX < rY ) {
+           distance[i] = rX;
+       } else {
            distance[i] = rY;
        }
     }
-    for (i=0; i<num; ++i) {
+    for ( i = 0; i < num; ++i ) {
        r_temp = distance[i];
        index_temp = i;
-       for (j=i; j<num; ++j) {
-           if (distance[j] < r_temp) {
+       for ( j = i; j < num; ++j ) {
+           if ( distance[j] < r_temp ) {
                r_temp = distance[j];
                index_temp = j;
            }
        }
-       if (index_temp > i) {
+       if ( index_temp > i ) {
            unit_temp = table[index_temp];
            table[index_temp] = table[i];
            distance[index_temp] = distance[i];
@@ -1060,24 +1102,24 @@
        }
     }
 
-    // Check if building is reachable and try next trio of workers
+   // Check if building is reachable and try next trio of workers
 
-    if ( (j=AiPlayer->TriedRepairWorkers[UnitNumber(building)]) > num) {
-       j=AiPlayer->TriedRepairWorkers[UnitNumber(building)]=0;
+    if ( ( j = AiPlayer->TriedRepairWorkers[UnitNumber( building )] ) > num ) {
+       j = AiPlayer->TriedRepairWorkers[UnitNumber( building )] = 0;
     }
 
-    for( k=i=j; i<num && i<j+3; ++i ) {
+    for ( k = i = j; i < num && i < j + 3; ++i ) {
 
-       unit=table[i];
-       DebugLevel2Fn("Have an unit to repair %d :)\n" _C_ UnitNumber(unit));
+       unit = table[i];
+       DebugLevel2Fn( "Have an unit to repair %d :)\n" _C_ UnitNumber( unit ) 
);
 
-       if( UnitReachable(unit,building,unit->Type->RepairRange) ) {
-           CommandRepair(unit, 0, 0, building,FlushCommands);
+       if ( UnitReachable( unit, building, unit->Type->RepairRange ) ) {
+           CommandRepair( unit, 0, 0, building, FlushCommands );
            return 1;
        }
-       k=i;
+       k = i;
     }
-    AiPlayer->TriedRepairWorkers[UnitNumber(building)]=k+1;
+    AiPlayer->TriedRepairWorkers[UnitNumber( building )] = k + 1;
     return 0;
 }
 
@@ -1087,36 +1129,36 @@
 **     @param unit     Unit that must be repaired.
 **     @return         True if made, false if can't be made.
 */
-local int AiRepairUnit(Unit* unit)
+local int AiRepairUnit( Unit * unit )
 {
     int i;
     int n;
-    const UnitType* type;
-    const int* unit_count;
-    AiUnitTypeTable* const* tablep;
-    const AiUnitTypeTable* table;
-
-    n=AiHelpers.RepairCount;
-    tablep=AiHelpers.Repair;
-    type=unit->Type;
-    if( type->Type>n ) {               // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    const UnitType *type;
+    const int *unit_count;
+    AiUnitTypeTable *const *tablep;
+    const AiUnitTypeTable *table;
+
+    n = AiHelpers.RepairCount;
+    tablep = AiHelpers.Repair;
+    type = unit->Type;
+    if ( type->Type > n ) {    // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return 0;
     }
-    table=tablep[type->Type];
-    if( !table ) {                     // Oops not known.
-       DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+    table = tablep[type->Type];
+    if ( !table ) {            // Oops not known.
+       DebugLevel0Fn( "Nothing known about `%s'\n" _C_ type->Ident );
        return 0;
     }
 
-    n=table->Count;
-    unit_count=AiPlayer->Player->UnitTypesCount;
-    for( i=0; i<n; ++i ) {
-       //
-       //      The type is available
-       //
-       if( unit_count[table->Table[i]->Type] ) {
-           if( AiRepairBuilding(table->Table[i],unit) ) {
+    n = table->Count;
+    unit_count = AiPlayer->Player->UnitTypesCount;
+    for ( i = 0; i < n; ++i ) {
+       //
+       //      The type is available
+       //
+       if ( unit_count[table->Table[i]->Type] ) {
+           if ( AiRepairBuilding( table->Table[i], unit ) ) {
                return 1;
            }
        }
@@ -1128,65 +1170,64 @@
 /**
 **     Look through the units, if an unit must be repaired.
 */
-local void AiCheckRepair(void)
+local void AiCheckRepair( void )
 {
-    int i,j,k;
+    int i, j, k;
     int n;
     int repair_flag;
-    Unit* unit;
+    Unit *unit;
 
-    n=AiPlayer->Player->TotalNumUnits;
-    k=0;
-       // Selector for next unit
-    for( i=n; (i>0); --i ) {
-       unit=AiPlayer->Player->Units[i];
-       if (unit) {
-           if (UnitNumber(unit)==AiPlayer->LastRepairBuilding) {
-               k=i+1;
+    n = AiPlayer->Player->TotalNumUnits;
+    k = 0;
+   // Selector for next unit
+    for ( i = n; ( i > 0 ); --i ) {
+       unit = AiPlayer->Player->Units[i];
+       if ( unit ) {
+           if ( UnitNumber( unit ) == AiPlayer->LastRepairBuilding ) {
+               k = i + 1;
            }
        }
     }
 
-    for( i=k; i<n; ++i ) {
-       unit=AiPlayer->Player->Units[i];
-       repair_flag=1;
-       // Unit damaged?
-       if( unit->Type->Building
-               && unit->Orders[0].Action!=UnitActionBuilded
-               && unit->Orders[0].Action!=UnitActionUpgradeTo
-               && unit->HP<unit->Stats->HitPoints ) {
-
-           DebugLevel3Fn("Have building to repair %d(%s)\n" _C_
-                   UnitNumber(unit) _C_ unit->Type->Ident);
-
-           //
-           //  FIXME: Repair only buildings under control
-           //
-           if( EnemyUnitsInDistance(unit,unit->Stats->SightRange) ) {
+    for ( i = k; i < n; ++i ) {
+       unit = AiPlayer->Player->Units[i];
+       repair_flag = 1;
+       // Unit damaged?
+       if ( unit->Type->Building
+            && unit->Orders[0].Action != UnitActionBuilded
+            && unit->Orders[0].Action != UnitActionUpgradeTo
+            && unit->HP < unit->Stats->HitPoints ) {
+
+           DebugLevel3Fn( "Have building to repair %d(%s)\n" _C_
+                          UnitNumber( unit ) _C_ unit->Type->Ident );
+
+          //
+          //  FIXME: Repair only buildings under control
+          //
+           if ( EnemyUnitsInDistance( unit, unit->Stats->SightRange ) ) {
                continue;
            }
-
-           //
-           //  Must check, if there are enough resources
-           //
-           for( j=1; j<MaxCosts; ++j ) {
-               if( unit->Stats->Costs[j]
-                       && AiPlayer->Player->Resources[j]<99 ) {
-                   repair_flag=0;
+          //
+          //  Must check, if there are enough resources
+          //
+           for ( j = 1; j < MaxCosts; ++j ) {
+               if ( unit->Stats->Costs[j]
+                    && AiPlayer->Player->Resources[j] < 99 ) {
+                   repair_flag = 0;
                }
            }
 
-           //
-           //  Find a free worker, who can build this building can repair it?
-           //
+          //
+          //  Find a free worker, who can build this building can repair it?
+          //
            if ( repair_flag ) {
-               AiRepairUnit(unit);
-               AiPlayer->LastRepairBuilding=UnitNumber(unit);
+               AiRepairUnit( unit );
+               AiPlayer->LastRepairBuilding = UnitNumber( unit );
                return;
            }
        }
     }
-    AiPlayer->LastRepairBuilding=0;
+    AiPlayer->LastRepairBuilding = 0;
 }
 
 /**
@@ -1197,52 +1238,51 @@
 **
 **     @todo FIXME: should store the end of list and not search it.
 */
-global void AiAddUnitTypeRequest(UnitType* type,int count)
+global void AiAddUnitTypeRequest( UnitType * type, int count )
 {
-    AiBuildQueue** queue;
+    AiBuildQueue **queue;
 
-    DebugLevel3Fn("%s %d\n" _C_ type->Ident _C_ count);
+    DebugLevel3Fn( "%s %d\n" _C_ type->Ident _C_ count );
 
-    //
-    // Find end of the list.
-    //
-    for( queue=&AiPlayer->UnitTypeBuilded; *queue; queue=&(*queue)->Next ) {
+   //
+   //  Find end of the list.
+   //
+    for ( queue = &AiPlayer->UnitTypeBuilded; *queue; queue = &( *queue 
)->Next ) {
     }
 
-    *queue=malloc(sizeof(*AiPlayer->UnitTypeBuilded));
-    (*queue)->Next=NULL;
-    (*queue)->Type=type;
-    (*queue)->Want=count;
-    (*queue)->Made=0;
+    *queue = malloc( sizeof ( *AiPlayer->UnitTypeBuilded ) );
+    ( *queue )->Next = NULL;
+    ( *queue )->Type = type;
+    ( *queue )->Want = count;
+    ( *queue )->Made = 0;
 }
 
 /**
 **     Entry point of resource manager, periodically called.
 */
-global void AiResourceManager(void)
+global void AiResourceManager( void )
 {
-    //
-    // Check if something needs to be build / trained.
-    //
+   //
+   //  Check if something needs to be build / trained.
+   //
     AiCheckingWork();
-    //
-    // Look if we can build a farm in advance.
-    //
-    if( !AiPlayer->NeedFood
-           && AiPlayer->Player->NumFoodUnits==AiPlayer->Player->Food ) {
-       DebugLevel3Fn("Farm in advance request\n");
+   //
+   //  Look if we can build a farm in advance.
+   //
+    if ( !AiPlayer->NeedFood && AiPlayer->Player->NumFoodUnits == 
AiPlayer->Player->Food ) {
+       DebugLevel3Fn( "Farm in advance request\n" );
        AiRequestFarms();
     }
-    //
-    // Collect resources.
-    //
+   //
+   //  Collect resources.
+   //
     AiCollectResources();
-    //
-    // Check repair.
-    //
+   //
+   //  Check repair.
+   //
     AiCheckRepair();
 
-    AiPlayer->NeededMask=0;
+    AiPlayer->NeededMask = 0;
 }
 
 //@}
Index: stratagus/src/ai/ccl_ai.c
diff -u stratagus/src/ai/ccl_ai.c:1.68 stratagus/src/ai/ccl_ai.c:1.69
--- stratagus/src/ai/ccl_ai.c:1.68      Thu Sep 25 02:58:36 2003
+++ stratagus/src/ai/ccl_ai.c   Thu Oct 23 14:38:34 2003
@@ -5,12 +5,12 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden ccl_ai.c       -       The AI ccl functions. */
 //
-//     (c) Copyright 2000-2002 by Lutz Sammer
+//      (c) Copyright 2000-2002 by Lutz Sammer and Ludovic Pollet
 //
 //      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: ccl_ai.c,v 1.68 2003/09/25 06:58:36 mr-russ Exp $
+//      $Id: ccl_ai.c,v 1.69 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -42,13 +42,511 @@
 #include "unittype.h"
 #include "ccl.h"
 #include "ai.h"
+#include "pathfinder.h"
+
 #include "ai_local.h"
 
+#include "ccl_helpers.h"
+
+
+/*----------------------------------------------------------------------------
+--     Forwards
+----------------------------------------------------------------------------*/
+/// Handle saving/loading a reference to an AiType.
+local void IOAiTypePtr( SCM from, void *binaryform, void *para );
+/// Handle saving/loading a reference to an AiScriptAction.
+local void IOAiScriptActionPtr( SCM scmfrom, void *binaryform, void *para );
+/// Handle saving/loading an array of int for ressources.
+local void IORessourceArray( SCM scmfrom, void *binaryform, void *para );
+/// Handle saving/loading a ressource mask
+local void IORessourceMask( SCM scmfrom, void *binaryform, void *para );
+
+/*----------------------------------------------------------------------------
+--     Constants
+----------------------------------------------------------------------------*/
+
+/// Description of the AiActionEvaluation structure 
+static CclStructDef AiActionEvaluationStructDef = {
+    "AiActionEvaluation",
+    sizeof ( AiActionEvaluation ),
+    -1,
+    {
+     {"`next", NULL, &( ( AiActionEvaluation * ) 0 )->Next, NULL}
+     ,
+     {"ai-script-action", &IOAiScriptActionPtr,
+      &( ( AiActionEvaluation * ) 0 )->aiScriptAction, NULL}
+     ,
+     {"hotspot-x", &IOInt, &( ( AiActionEvaluation * ) 0 )->hotSpotX, NULL}
+     ,
+     {"hotspot-y", &IOInt, &( ( AiActionEvaluation * ) 0 )->hotSpotY, NULL}
+     ,
+     {"hotspot-value", &IOInt, &( ( AiActionEvaluation * ) 0 )->hotSpotValue, 
NULL}
+     ,
+     {"value", &IOInt, &( ( AiActionEvaluation * ) 0 )->value, NULL}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the AiRunningScript structure
+static CclStructDef AiRunningScriptStructDef = {
+    "AiRunningScript",
+    sizeof ( AiRunningScript ),
+    AI_MAX_RUNNING_SCRIPTS,
+    {
+     {"script", &IOCcl, &( ( AiRunningScript * ) 0 )->Script, NULL}
+     ,
+     {"sleep-cycles", &IOInt, &( ( AiRunningScript * ) 0 )->SleepCycles, NULL}
+     ,
+     {"ident", &IOStrBuffer, &( ( AiRunningScript * ) 0 )->ident, ( void * ) 
10},
+     {"hotspot-x", &IOInt, &( ( AiRunningScript * ) 0 )->HotSpot_X, NULL},
+     {"hotspot-y", &IOInt, &( ( AiRunningScript * ) 0 )->HotSpot_Y, NULL},
+     {"hotspot-ray", &IOInt, &( ( AiRunningScript * ) 0 )->HotSpot_Ray, NULL},
+     {"own-force", &IOInt, &( ( AiRunningScript * ) 0 )->ownForce, NULL},
+     {"gauges", &IOIntArrayPtr, &( ( AiRunningScript * ) 0 )->gauges, ( void * 
) GAUGE_NB},
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the role flags
+static CclFlagDef AiRoleFlag[] = {
+    {"attack", AiForceRoleAttack}, {"defend", AiForceRoleDefend}, {0, 0}
+};
+
+/// Description of the populate flags
+static CclFlagDef AiPopulateFlag[] = {
+    {"dont-populate", AiForceDontPopulate}, {"from-scratch", 
AiForcePopulateFromScratch},
+    {"from-attack", AiForcePopulateFromAttack}, {"any", AiForcePopulateAny}, 
{0, 0}
+};
+
+/// Description of the help flags
+static CclFlagDef AiHelpFlag[] = {
+    {"no-help", AiForceDontHelp}, {"force-help", AiForceHelpForce},
+    {"full-help", AiForceHelpFull}, {0, 0}
+};
+
+/// Description of the AiUnitType structure
+static CclStructDef AiUnitTypeStructDef = {
+    "AiUnitType",
+    sizeof ( AiUnitType ),
+    -1,
+    {
+     {"'next", 0, &( ( AiUnitType * ) 0 )->Next, 0}
+     ,
+     {"type", &IOUnitTypePtr, &( ( AiUnitType * ) 0 )->Type, 0}
+     ,
+     {"want", &IOInt, &( ( AiUnitType * ) 0 )->Want, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the AiUnit structure
+static CclStructDef AiUnitStructDef = {
+    "AiUnit",
+    sizeof ( AiUnit ),
+    -1,
+    {
+     {"'next", NULL, &( ( AiUnit * ) 0 )->Next, 0}
+     ,
+     {"unit", &IOUnitPtr, &( ( AiUnit * ) 0 )->Unit, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the AiForce structure
+static CclStructDef AiForceStructDef = {
+    "AiForce",
+    sizeof ( AiForce ),
+    AI_MAX_FORCES,
+    {
+     {"completed", &IOCharBool, &( ( AiForce * ) 0 )->Completed, 0}
+     ,
+     {"attacking", &IOCharBool, &( ( AiForce * ) 0 )->Attacking, 0}
+     ,
+     {"role", &IOCharFlag, &( ( AiForce * ) 0 )->Role, &AiRoleFlag}
+     ,
+     {"populate-mode", &IOCharFlag, &( ( AiForce * ) 0 )->PopulateMode, 
&AiPopulateFlag}
+     ,
+     {"units-reusable", &IOCharBool, &( ( AiForce * ) 0 )->UnitsReusable, 0}
+     ,
+     {"help-mode", &IOCharFlag, &( ( AiForce * ) 0 )->HelpMode, &AiHelpFlag}
+     ,
+
+     {"unit-wants", &IOLinkedList, &( ( AiForce * ) 0 )->UnitTypes, 
&AiUnitTypeStructDef}
+     ,
+     {"unit-presents", &IOLinkedList, &( ( AiForce * ) 0 )->Units, 
&AiUnitStructDef}
+     ,
+
+     {"attack-state", &IOInt, &( ( AiForce * ) 0 )->State, 0}
+     ,
+     {"attack-goal-x", &IOInt, &( ( AiForce * ) 0 )->GoalX, 0}
+     ,
+     {"attack-goal-y", &IOInt, &( ( AiForce * ) 0 )->GoalY, 0}
+     ,
+     {"must-transport", &IOBool, &( ( AiForce * ) 0 )->MustTransport, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the AiBuildQueue structure/linked list
+static CclStructDef AiBuildQueueStructDef = {
+    "AiBuildQueue",
+    sizeof ( AiBuildQueue ),
+    -1,
+    {
+     {"`next", 0, &( ( AiBuildQueue * ) 0 )->Next, 0}
+     ,
+     {"want", &IOInt, &( ( AiBuildQueue * ) 0 )->Want, 0}
+     ,
+     {"made", &IOInt, &( ( AiBuildQueue * ) 0 )->Made, 0}
+     ,
+     {"type", &IOUnitTypePtr, &( ( AiBuildQueue * ) 0 )->Type, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the AiUnitTypeTable table in PlayerAi
+static CclStructDef AiUnitTypeTableStructDef = {
+    "AiUnitTypeTable",
+    sizeof ( AiUnitTypeTable ),
+    -1,
+    {
+     {"unittype", IOUnitTypePtr, &( ( AiUnitTypeTable * ) 0 )->Table, 0}
+     ,
+     {"count", IOInt, &( ( AiUnitTypeTable * ) 0 )->Count, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+
+/// Description of the UnitTypeRequests table in PlayerAi
+static CclStructDef UnitTypeRequestsTableDef = {
+    "UnitTypeRequests",
+    sizeof ( AiUnitTypeTable ),
+    -1,
+    {
+     {"`ptr", 0, &( ( PlayerAi * ) 0 )->UnitTypeRequests, 0}
+     ,
+     {"`count", 0, &( ( PlayerAi * ) 0 )->UnitTypeRequestsCount, 0}
+     ,
+     {"`items", &IOStruct, 0, &AiUnitTypeTableStructDef}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the UpgradeToRequests table in PlayerAi
+static CclStructDef UpgradeToRequestsTableDef = {
+    "UpgradeToRequests",
+    sizeof ( UnitType * ),
+    -1,
+    {
+     {"`ptr", 0, &( ( PlayerAi * ) 0 )->UpgradeToRequests, 0}
+     ,
+     {"`count", 0, &( ( PlayerAi * ) 0 )->UpgradeToRequestsCount, 0}
+     ,
+     {"`items", &IOUnitTypePtr, 0, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the ResearchRequests table in PlayerAi
+static CclStructDef ResearchRequestsTableDef = {
+    "ResearchRequests",
+    sizeof ( Upgrade * ),
+    -1,
+    {
+     {"`ptr", 0, &( ( PlayerAi * ) 0 )->ResearchRequests, 0}
+     ,
+     {"`count", 0, &( ( PlayerAi * ) 0 )->ResearchRequestsCount, 0}
+     ,
+     {"`items", &IOUpgradePtr, 0, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the PlayerAi structure
+static CclStructDef PlayerAiStructDef = {
+    "PlayerAi",
+    sizeof ( PlayerAi ),
+    -1,
+    {
+     {"player", &IOPlayerPtr, &( ( PlayerAi * ) 0 )->Player, 0}
+     ,
+     {"ai-type", &IOAiTypePtr, &( ( PlayerAi * ) 0 )->AiType, 0}
+     ,
+     {"scripts", &IOStructArray, &( ( PlayerAi * ) 0 )->Scripts, 
&AiRunningScriptStructDef}
+     ,
+     {"past-evaluations", &IOLinkedList, &( ( PlayerAi * ) 0 
)->FirstEvaluation,
+      &AiActionEvaluationStructDef}
+     ,
+     {"debug", &IOBool, &( ( PlayerAi * ) 0 )->ScriptDebug, 0}
+     ,
+     {"auto-attack", &IOBool, &( ( PlayerAi * ) 0 )->AutoAttack, 0}
+     ,
+     {"forces", &IOStructArray, &( ( PlayerAi * ) 0 )->Force, 
&AiForceStructDef}
+     ,
+
+     {"reserve", &IORessourceArray, &( ( PlayerAi * ) 0 )->Reserve, 0}
+     ,
+     {"used", &IORessourceArray, &( ( PlayerAi * ) 0 )->Used, 0}
+     ,
+     {"needed", &IORessourceArray, &( ( PlayerAi * ) 0 )->Needed, 0}
+     ,
+     {"collect", &IORessourceArray, &( ( PlayerAi * ) 0 )->Collect, 0}
+     ,
+     {"neededmask", &IORessourceMask, &( ( PlayerAi * ) 0 )->Reserve, 0}
+     ,
+     {"need-food", &IOBool, &( ( PlayerAi * ) 0 )->NeedFood, 0}
+     ,
+
+     {"unit-type-requests", &IOTable, 0, &UnitTypeRequestsTableDef}
+     ,
+     {"upgrade-to-requests", &IOTable, 0, &UpgradeToRequestsTableDef}
+     ,
+     {"research-requests", &IOTable, 0, &ResearchRequestsTableDef}
+     ,
+
+     {"unit-type-builded", &IOLinkedList, &( ( PlayerAi * ) 0 
)->UnitTypeBuilded,
+      &AiBuildQueueStructDef}
+     ,
+
+     {"last-repair-building", &IOInt, &( ( PlayerAi * ) 0 
)->LastRepairBuilding, 0}
+     ,
+     {"tried-repair-worker", &IOIntArray, &( ( PlayerAi * ) 0 
)->TriedRepairWorkers,
+      ( void * ) UnitMax},
+     {0, 0, 0, 0}
+     }
+};
+
+/// Description of the PlayerAi structure
+static CclStructDef AiTypeStructDef = {
+    "AiType",
+    sizeof ( AiType ),
+    -1,
+    {
+     {"name", &IOString, &( ( AiType * ) 0 )->Name, 0}
+     ,
+     {"race", &IOString, &( ( AiType * ) 0 )->Race, 0}
+     ,
+     {"class", &IOString, &( ( AiType * ) 0 )->Class, 0}
+     ,
+     {"script", &IOCcl, &( ( AiType * ) 0 )->Script, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+static CclStructDef AiScriptActionStructDef = {
+    "AiScriptAction",
+    sizeof ( AiScriptAction ),
+    -1,
+    {
+     {"action", &IOCcl, &( ( AiScriptAction * ) 0 )->Action, 0}
+     ,
+     {"defensive", &IOBool, &( ( AiScriptAction * ) 0 )->Defensive, 0}
+     ,
+     {"offensive", &IOBool, &( ( AiScriptAction * ) 0 )->Offensive, 0}
+     ,
+     {0, 0, 0, 0}
+     }
+};
+
+
 /*----------------------------------------------------------------------------
 --     Functions
 ----------------------------------------------------------------------------*/
 
 /**
+**     Handle saving/loading a reference to an AiType ( AiType * ).
+**     The null case is handled.
+**
+**     @param  scmform         When loading, the scm data to load
+**     @param  binaryform      Pointer to the unit'ref ( AiType ** )
+**     @param  para            unused
+*/
+local void IOAiTypePtr( SCM from, void *binaryform, void *para )
+{
+    char buffer[512];
+    char *str;
+    AiType *cur;
+
+    if ( IOHandleNullPtr( from, binaryform ) ) {
+       return;
+    }
+    if ( IOLoadingMode ) {
+       str = gh_scm2newstr( from, 0 );
+       cur = AiTypes;
+       while ( cur ) {
+           snprintf( buffer, 512, "%s-%s-%s", cur->Name, cur->Race, cur->Class 
);
+           if ( !strcmp( str, buffer ) ) {
+               *( ( AiType ** ) binaryform ) = cur;
+               return;
+           }
+           cur = cur->Next;
+       }
+       errl( "unknown aitype ", from );
+    } else {
+       cur = *( ( AiType ** ) binaryform );
+
+       snprintf( buffer, 512, "%s-%s-%s", cur->Name, cur->Race, cur->Class );
+       CLprintf( IOOutFile, " \"%s\"", buffer );
+    }
+}
+
+
+/**
+**     Handle saving/loading a reference to an AiScriptAction.
+**     The null case is handled.
+**
+**     @param  scmform         When loading, the scm data to load
+**     @param  binaryform      Pointer to the unit'ref ( AiScriptAction ** )
+**     @param  para            unused
+*/
+local void IOAiScriptActionPtr( SCM scmfrom, void *binaryform, void *para )
+{
+    int slot;
+    AiScriptAction *a;
+    if ( IOHandleNullPtr( scmfrom, binaryform ) ) {
+       return;
+    }
+    if ( IOLoadingMode ) {
+       slot = gh_scm2int( scmfrom );
+       *( ( AiScriptAction ** ) binaryform ) = AiScriptActions + slot;
+    } else {
+       a = *( ( AiScriptAction ** ) binaryform );
+       CLprintf( IOOutFile, " %d", a - AiScriptActions );
+    }
+}
+
+/// Handle loading an array of int for each ressource ( int[MAX_COSTS] )
+local void IORessourceArray( SCM scmfrom, void *binaryform, void *para )
+{
+    IOIntArray( scmfrom, binaryform, ( void * ) MaxCosts );
+}
+
+/// Handle loading a mask for each ressource ( int[MAX_COSTS] )
+local void IORessourceMask( SCM scmfrom, void *binaryform, void *para )
+{
+    int tmp[MaxCosts];
+    int mask;
+    int i;
+
+    if ( IOLoadingMode ) {
+       IOIntArray( scmfrom, tmp, ( void * ) MaxCosts );
+
+       mask = 0;
+       for ( i = 0; i < MaxCosts; i++ ) {
+           if ( tmp[i] ) {
+               mask |= ( 1 << i );
+           }
+       }
+
+       *( int * ) binaryform = mask;
+    } else {
+       mask = *( int * ) binaryform;
+       for ( i = 0; i < MaxCosts; i++ ) {
+           if ( mask & ( 1 << i ) ) {
+               tmp[i] = 1;
+           } else {
+               tmp[i] = 0;
+           }
+       }
+
+       IOIntArray( scmfrom, tmp, ( void * ) MaxCosts );
+    }
+}
+
+/**
+**     Handle saving/loading a full PlayerAi structure.
+**     The structure is allocated on the heap, filled from ccl, then completed.
+**
+**     @param  scmform         When loading, the scm data to load
+**     @param  binaryform      Pointer to the PlayerAi'ref ( PlayerAi ** )
+**     @param  para            unused
+*/
+global void IOPlayerAiFullPtr( SCM form, void *binaryform, void *para )
+{
+    AiActionEvaluation *aa;
+    PlayerAi **playerAi = ( PlayerAi ** ) binaryform;
+
+    IOStructPtr( form, binaryform, &PlayerAiStructDef );
+    if ( IOLoadingMode && ( *playerAi ) ) {
+       // Finalize the playerAi struct !
+       // => last evaluation, evaluation count
+       aa = ( *playerAi )->FirstEvaluation;
+       while ( aa ) {
+           ( *playerAi )->LastEvaluation = aa;
+           ( *playerAi )->EvaluationCount++;
+           aa = aa->Next;
+       }
+    }
+}
+
+global void IOAiTypeFullPtr( SCM form, void *binaryform, void *para )
+{
+    AiType **aiType = ( AiType ** ) binaryform;
+    IOStructPtr( form, binaryform, &AiTypeStructDef );
+    if ( IOLoadingMode && ( *aiType ) ) {
+       // Append the ai_type...
+       ( *aiType )->Next = AiTypes;
+       AiTypes = ( *aiType );
+    }
+}
+
+global void IOAiScriptActionFull( SCM form, void *binaryform, void *para )
+{
+   /*AiScriptAction * asa = (AiScriptAction*) binaryform; */
+    IOStruct( form, binaryform, &AiScriptActionStructDef );
+}
+
+
+#define INCOMPLETE_SIOD        1
+
+#ifdef INCOMPLETE_SIOD
+
+local SCM CclQuotient( SCM a, SCM b )
+{
+    int va, vb;
+    va = gh_scm2int( a );
+    vb = gh_scm2int( b );
+    if ( vb == 0 ) {
+       errl( "CclQuotient division by zero", b );
+    }
+    return gh_int2scm( va / vb );
+}
+
+local SCM CclOutput( SCM x )
+{
+    if ( gh_null_p( x ) ) {
+       printf( " '()" );
+       return SCM_BOOL_T;
+    }
+    if ( gh_list_p( x ) ) {
+       printf( " (" );
+       while ( !gh_null_p( x ) ) {
+           CclOutput( gh_car( x ) );
+           x = gh_cdr( x );
+       }
+       printf( " )" );
+       return SCM_BOOL_T;
+    }
+    printf( " " );
+    gh_display( x );
+    return x;
+}
+
+#endif
+
+
+/**
 **     Setup AI helper table.
 **
 **     Expand the table if needed.
@@ -57,20 +555,20 @@
 **     @param table    Pointer to table with elements.
 **     @param n        Index to insert new into table
 */
-local void AiHelperSetupTable(int* count,AiUnitTypeTable*** table,int n)
+local void AiHelperSetupTable( int *count, AiUnitTypeTable *** table, int n )
 {
     int i;
 
     ++n;
-    if( n>(i=*count) ) {
-       if( *table ) {
-           *table=realloc(*table,n*sizeof(AiUnitTypeTable*));
-           memset((*table)+i,0,(n-i)*sizeof(AiUnitTypeTable*));
+    if ( n > ( i = *count ) ) {
+       if ( *table ) {
+           *table = realloc( *table, n * sizeof ( AiUnitTypeTable * ) );
+           memset( ( *table ) + i, 0, ( n - i ) * sizeof ( AiUnitTypeTable * ) 
);
        } else {
-           *table=malloc(n*sizeof(AiUnitTypeTable*));
-           memset(*table,0,n*sizeof(AiUnitTypeTable*));
+           *table = malloc( n * sizeof ( AiUnitTypeTable * ) );
+           memset( *table, 0, n * sizeof ( AiUnitTypeTable * ) );
        }
-       *count=n;
+       *count = n;
     }
 }
 
@@ -80,45 +578,44 @@
 **     @param tablep   Pointer to table with elements.
 **     @param base     Base type to insert into table.
 */
-local void AiHelperInsert(AiUnitTypeTable** tablep,UnitType* base)
+local void AiHelperInsert( AiUnitTypeTable ** tablep, UnitType * base )
 {
     int i;
     int n;
-    AiUnitTypeTable* table;
+    AiUnitTypeTable *table;
 
-    //
-    // New unit-type
-    //
-    if( !(table=*tablep) ) {
-       table=*tablep=malloc(sizeof(AiUnitTypeTable));
-       table->Count=1;
-       table->Table[0]=base;
+   //
+   //  New unit-type
+   //
+    if ( !( table = *tablep ) ) {
+       table = *tablep = malloc( sizeof ( AiUnitTypeTable ) );
+       table->Count = 1;
+       table->Table[0] = base;
        return;
     }
-
-    //
-    // Look if already known.
-    //
-    n=table->Count;
-    for( i=0; i<n; ++i ) {
-       if( table->Table[i]==base ) {
+   //
+   //  Look if already known.
+   //
+    n = table->Count;
+    for ( i = 0; i < n; ++i ) {
+       if ( table->Table[i] == base ) {
            return;
        }
     }
 
-    //
-    // Append new base unit-type to units.
-    //
-    table=*tablep=realloc(table,sizeof(AiUnitTypeTable)+sizeof(UnitType*)*n);
-    table->Count=n+1;
-    table->Table[n]=base;
+   //
+   //  Append new base unit-type to units.
+   //
+    table = *tablep = realloc( table, sizeof ( AiUnitTypeTable ) + sizeof ( 
UnitType * ) * n );
+    table->Count = n + 1;
+    table->Table[n] = base;
 }
 
 #ifdef DEBUG
 /**
 **     Print AI helper table.
 */
-local void PrintAiHelperTable(void)
+local void PrintAiHelperTable( void )
 {
 }
 #endif
@@ -130,136 +627,128 @@
 **
 **     @todo   FIXME: the first unit could be a list see ../doc/ccl/ai.html
 */
-local SCM CclDefineAiHelper(SCM list)
+local SCM CclDefineAiHelper( SCM list )
 {
     SCM sub_list;
     SCM value;
     int what;
-    char* str;
-    UnitType* base;
-    UnitType* type;
-    Upgrade* upgrade;
+    char *str;
+    UnitType *base;
+    UnitType *type;
+    Upgrade *upgrade;
     int cost;
 
-    IfDebug( type=NULL; upgrade=NULL; cost=0; );// keep the compiler happy
-    while( !gh_null_p(list) ) {
-       sub_list=gh_car(list);
-       list=gh_cdr(list);
-
-       //
-       //      Type build,train,research/upgrade.
-       //
-       value=gh_car(sub_list);
-       sub_list=gh_cdr(sub_list);
-       if( gh_eq_p(value,gh_symbol2scm("build")) ) {
-           what=0;
-       } else if( gh_eq_p(value,gh_symbol2scm("train")) ) {
-           what=1;
-       } else if( gh_eq_p(value,gh_symbol2scm("upgrade")) ) {
-           what=2;
-       } else if( gh_eq_p(value,gh_symbol2scm("research")) ) {
-           what=3;
-       } else if( gh_eq_p(value,gh_symbol2scm("unit-limit")) ) {
-           what=4;
-       } else if( gh_eq_p(value,gh_symbol2scm("unit-equiv")) ) {
-           what=5;
-       } else if( gh_eq_p(value,gh_symbol2scm("repair")) ) {
-           what=6;
+    IfDebug( type = NULL; upgrade = NULL; cost = 0; ); // keep the compiler 
happy
+    while ( !gh_null_p( list ) ) {
+       sub_list = gh_car( list );
+       list = gh_cdr( list );
+
+       //
+       //      Type build,train,research/upgrade.
+       //
+       value = gh_car( sub_list );
+       sub_list = gh_cdr( sub_list );
+       if ( gh_eq_p( value, gh_symbol2scm( "build" ) ) ) {
+           what = 0;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "train" ) ) ) {
+           what = 1;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "upgrade" ) ) ) {
+           what = 2;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "research" ) ) ) {
+           what = 3;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "unit-limit" ) ) ) {
+           what = 4;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "unit-equiv" ) ) ) {
+           what = 5;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "repair" ) ) ) {
+           what = 6;
        } else {
-           fprintf(stderr,"unknown tag\n");
+           fprintf( stderr, "unknown tag\n" );
            continue;
        }
 
-       //
-       //      Get the base unit type, which could handle the action.
-       //
-       value=gh_car(sub_list);
-       sub_list=gh_cdr(sub_list);
-
-       // FIXME: support value as list!
-       str=gh_scm2newstr(value,NULL);
-       base=UnitTypeByIdent(str);
-       if( !base ) {
-           fprintf(stderr,"unknown unittype %s\n",str);
-           free(str);
+       //
+       //      Get the base unit type, which could handle the action.
+       //
+       value = gh_car( sub_list );
+       sub_list = gh_cdr( sub_list );
+
+       // FIXME: support value as list!
+       str = gh_scm2newstr( value, NULL );
+       base = UnitTypeByIdent( str );
+       if ( !base ) {
+           fprintf( stderr, "unknown unittype %s\n", str );
+           free( str );
            continue;
        }
-       DebugLevel3Fn("%s\n" _C_ base->Name);
-       free(str);
+       DebugLevel3Fn( "%s\n" _C_ base->Name );
+       free( str );
 
-       //
-       //      Get the unit types, which could be produced
-       //
-       while( !gh_null_p(sub_list) ) {
-           value=gh_car(sub_list);
-           sub_list=gh_cdr(sub_list);
-           str=gh_scm2newstr(value,NULL);
-           if( what==3 ) {
-               upgrade=UpgradeByIdent(str);
-               if( !upgrade ) {
-                   fprintf(stderr,"unknown upgrade %s\n",str);
-                   free(str);
+       //
+       //      Get the unit types, which could be produced
+       //
+       while ( !gh_null_p( sub_list ) ) {
+           value = gh_car( sub_list );
+           sub_list = gh_cdr( sub_list );
+           str = gh_scm2newstr( value, NULL );
+           if ( what == 3 ) {
+               upgrade = UpgradeByIdent( str );
+               if ( !upgrade ) {
+                   fprintf( stderr, "unknown upgrade %s\n", str );
+                   free( str );
                    continue;
                }
-               DebugLevel3Fn("> %s\n" _C_ upgrade->Ident);
-           } else if( what==4 ) {
-               if( !strcmp("food",str) ) {
-                   cost=0;
+               DebugLevel3Fn( "> %s\n" _C_ upgrade->Ident );
+           } else if ( what == 4 ) {
+               if ( !strcmp( "food", str ) ) {
+                   cost = 0;
                } else {
-                   fprintf(stderr,"unknown limit %s\n",str);
-                   free(str);
+                   fprintf( stderr, "unknown limit %s\n", str );
+                   free( str );
                    continue;
                }
-               DebugLevel3Fn("> %s\n" _C_ str);
+               DebugLevel3Fn( "> %s\n" _C_ str );
            } else {
-               type=UnitTypeByIdent(str);
-               if( !type ) {
-                   fprintf(stderr,"unknown unittype %s\n",str);
-                   free(str);
+               type = UnitTypeByIdent( str );
+               if ( !type ) {
+                   fprintf( stderr, "unknown unittype %s\n", str );
+                   free( str );
                    continue;
                }
-               DebugLevel3Fn("> %s\n" _C_ type->Name);
+               DebugLevel3Fn( "> %s\n" _C_ type->Name );
            }
-           free(str);
+           free( str );
 
-           switch( what ) {
-               case 0:                 // build
-                   AiHelperSetupTable(
-                           &AiHelpers.BuildCount,&AiHelpers.Build,type->Type);
-                   AiHelperInsert(AiHelpers.Build+type->Type,base);
-                   break;
-               case 1:                 // train
-                   AiHelperSetupTable(
-                           &AiHelpers.TrainCount,&AiHelpers.Train,type->Type);
-                   AiHelperInsert(AiHelpers.Train+type->Type,base);
-                   break;
-               case 2:                 // upgrade
-                   AiHelperSetupTable(
-                           &AiHelpers.UpgradeCount,&AiHelpers.Upgrade,
-                           type->Type);
-                   AiHelperInsert(AiHelpers.Upgrade+type->Type,base);
-                   break;
-               case 3:                 // research
-                   AiHelperSetupTable(
-                           &AiHelpers.ResearchCount,&AiHelpers.Research,
-                           upgrade-Upgrades);
-                   AiHelperInsert(AiHelpers.Research+(upgrade-Upgrades),base);
-                   break;
-               case 4:                 // unit-limit
-                   AiHelperSetupTable(
-                       &AiHelpers.UnitLimitCount,&AiHelpers.UnitLimit,cost);
-                   AiHelperInsert(AiHelpers.UnitLimit+cost,base);
-                   break;
-               case 5:                 // equivalence
-                   AiHelperSetupTable(
-                           &AiHelpers.EquivCount,&AiHelpers.Equiv,base->Type);
-                   AiHelperInsert(AiHelpers.Equiv+base->Type,type);
-                   break;
-               case 6:                 // repair
-                   AiHelperSetupTable(
-                       &AiHelpers.RepairCount,&AiHelpers.Repair,type->Type);
-                   AiHelperInsert(AiHelpers.Repair+type->Type,base);
-                   break;
+           switch ( what ) {
+           case 0:             // build
+               AiHelperSetupTable( &AiHelpers.BuildCount, &AiHelpers.Build, 
type->Type );
+               AiHelperInsert( AiHelpers.Build + type->Type, base );
+               break;
+           case 1:             // train
+               AiHelperSetupTable( &AiHelpers.TrainCount, &AiHelpers.Train, 
type->Type );
+               AiHelperInsert( AiHelpers.Train + type->Type, base );
+               break;
+           case 2:             // upgrade
+               AiHelperSetupTable( &AiHelpers.UpgradeCount, 
&AiHelpers.Upgrade, type->Type );
+               AiHelperInsert( AiHelpers.Upgrade + type->Type, base );
+               break;
+           case 3:             // research
+               AiHelperSetupTable( &AiHelpers.ResearchCount, 
&AiHelpers.Research,
+                                   upgrade - Upgrades );
+               AiHelperInsert( AiHelpers.Research + ( upgrade - Upgrades ), 
base );
+               break;
+           case 4:             // unit-limit
+               AiHelperSetupTable( &AiHelpers.UnitLimitCount, 
&AiHelpers.UnitLimit, cost );
+               AiHelperInsert( AiHelpers.UnitLimit + cost, base );
+               break;
+           case 5:             // equivalence
+               AiHelperSetupTable( &AiHelpers.EquivCount, &AiHelpers.Equiv, 
base->Type );
+               AiHelperInsert( AiHelpers.Equiv + base->Type, type );
+               break;
+           case 6:             // repair
+               AiHelperSetupTable( &AiHelpers.RepairCount, &AiHelpers.Repair, 
type->Type );
+               AiHelperInsert( AiHelpers.Repair + type->Type, base );
+               break;
            }
        }
     }
@@ -267,72 +756,96 @@
     return list;
 }
 
+local SCM CclDefineAiAction( SCM type, SCM definition )
+{
+    AiScriptAction *aiScriptAction;
+
+    aiScriptAction = AiScriptActions + AiScriptActionNum;
+    AiScriptActionNum++;
+
+    memset( aiScriptAction, 0, sizeof ( AiScriptAction ) );
+
+    aiScriptAction->Action = definition;
+    CclGcProtect( aiScriptAction->Action );
+
+    while ( !gh_null_p( type ) ) {
+       if ( gh_eq_p( gh_car( type ), gh_symbol2scm( "defense" ) ) ) {
+           aiScriptAction->Defensive = 1;
+       }
+       if ( gh_eq_p( gh_car( type ), gh_symbol2scm( "attack" ) ) ) {
+           aiScriptAction->Offensive = 1;
+       }
+       type = gh_cdr( type );
+    }
+
+    return SCM_UNSPECIFIED;
+}
+
 /**
 **     Define an AI engine.
 */
-local SCM CclDefineAi(SCM list)
+local SCM CclDefineAi( SCM list )
 {
     SCM value;
-    char* str;
-    AiType* aitype;
+    char *str;
+    AiType *aitype;
 #ifdef DEBUG
-    const AiType* ait;
+    const AiType *ait;
 #endif
 
-    aitype=malloc(sizeof(AiType));
-    aitype->Next=AiTypes;
-    AiTypes=aitype;
-
-    //
-    // AI Name
-    //
-    value=gh_car(list);
-    list=gh_cdr(list);
-    str=gh_scm2newstr(value,NULL);
-    DebugLevel3Fn("%s\n" _C_ str);
-    aitype->Name=str;
+    aitype = malloc( sizeof ( AiType ) );
+    aitype->Next = AiTypes;
+    AiTypes = aitype;
+
+   //
+   //  AI Name
+   //
+    value = gh_car( list );
+    list = gh_cdr( list );
+    str = gh_scm2newstr( value, NULL );
+    DebugLevel3Fn( "%s\n" _C_ str );
+    aitype->Name = str;
 
 #ifdef DEBUG
-    for( ait=AiTypes->Next; ait; ait=ait->Next ) {
-       if( !strcmp(aitype->Name,ait->Name) ) {
-           DebugLevel0Fn("Warning two or more AI's with the same name '%s'\n" 
_C_
-                   ait->Name);
+    for ( ait = AiTypes->Next; ait; ait = ait->Next ) {
+       if ( !strcmp( aitype->Name, ait->Name ) ) {
+           DebugLevel0Fn( "Warning two or more AI's with the same name '%s'\n" 
_C_ ait->Name );
        }
     }
 #endif
 
-    //
-    // AI Race
-    //
-    value=gh_car(list);
-    list=gh_cdr(list);
-    str=gh_scm2newstr(value,NULL);
-    DebugLevel3Fn("%s\n" _C_ str);
-    if( *str!='*' ) {
-       aitype->Race=str;
+   //
+   //  AI Race
+   //
+    value = gh_car( list );
+    list = gh_cdr( list );
+    str = gh_scm2newstr( value, NULL );
+    DebugLevel3Fn( "%s\n" _C_ str );
+    if ( *str != '*' ) {
+       aitype->Race = str;
     } else {
-       aitype->Race=NULL;
-       free(str);
+       aitype->Race = NULL;
+       free( str );
     }
 
-    //
-    // AI Class
-    //
-    value=gh_car(list);
-    list=gh_cdr(list);
-    str=gh_scm2newstr(value,NULL);
-    DebugLevel3Fn("%s\n" _C_ str);
-    aitype->Class=str;
-
-    //
-    // AI Script
-    //
-    value=gh_car(list);
-    list=gh_cdr(list);
-    aitype->Script=value;
+   //
+   //  AI Class
+   //
+    value = gh_car( list );
+    list = gh_cdr( list );
+    str = gh_scm2newstr( value, NULL );
+    DebugLevel3Fn( "%s\n" _C_ str );
+    aitype->Class = str;
+
+   //
+   //  AI Script
+   //
+    value = gh_car( list );
+    list = gh_cdr( list );
+    aitype->Script = value;
 
-    // Protect the scheme script against GC garbage-collect.
-    CclGcProtect(value);
+   // Protect the scheme script against GC garbage-collect.
+    CclGcProtect( value );
 
     return list;
 }
@@ -342,7 +855,7 @@
 ----------------------------------------------------------------------------*/
 
     /// Get unit-type.
-extern UnitType* CclGetUnitType(SCM ptr);
+extern UnitType *CclGetUnitType( SCM ptr );
 
 /**
 **     Append unit-type to request table.
@@ -350,21 +863,22 @@
 **     @param type     Unit-type to be appended.
 **     @param count    How many unit-types to build.
 */
-local void InsertUnitTypeRequests(UnitType* type,int count)
+local void InsertUnitTypeRequests( UnitType * type, int count )
 {
     int n;
 
-    if( AiPlayer->UnitTypeRequests ) {
-       n=AiPlayer->UnitTypeRequestsCount;
-       AiPlayer->UnitTypeRequests=realloc(AiPlayer->UnitTypeRequests,
-               (n+1)*sizeof(*AiPlayer->UnitTypeRequests));
+    if ( AiPlayer->UnitTypeRequests ) {
+       n = AiPlayer->UnitTypeRequestsCount;
+       AiPlayer->UnitTypeRequests = realloc( AiPlayer->UnitTypeRequests,
+                                             ( n +
+                                               1 ) * sizeof ( 
*AiPlayer->UnitTypeRequests ) );
     } else {
-       AiPlayer->UnitTypeRequests=malloc(sizeof(*AiPlayer->UnitTypeRequests));
-       n=0;
+       AiPlayer->UnitTypeRequests = malloc( sizeof ( 
*AiPlayer->UnitTypeRequests ) );
+       n = 0;
     }
-    AiPlayer->UnitTypeRequests[n].Table[0]=type;
-    AiPlayer->UnitTypeRequests[n].Count=count;
-    AiPlayer->UnitTypeRequestsCount=n+1;
+    AiPlayer->UnitTypeRequests[n].Table[0] = type;
+    AiPlayer->UnitTypeRequests[n].Count = count;
+    AiPlayer->UnitTypeRequestsCount = n + 1;
 }
 
 /**
@@ -372,14 +886,14 @@
 **
 **     @param type     Unit-type to be found.
 */
-local AiUnitTypeTable* FindInUnitTypeRequests(const UnitType* type)
+local AiUnitTypeTable *FindInUnitTypeRequests( const UnitType * type )
 {
     int i;
     int n;
 
-    n=AiPlayer->UnitTypeRequestsCount;
-    for( i=0; i<n; ++i ) {
-       if( AiPlayer->UnitTypeRequests[i].Table[0]==type ) {
+    n = AiPlayer->UnitTypeRequestsCount;
+    for ( i = 0; i < n; ++i ) {
+       if ( AiPlayer->UnitTypeRequests[i].Table[0] == type ) {
            return &AiPlayer->UnitTypeRequests[i];
        }
     }
@@ -391,14 +905,14 @@
 **
 **     @param type     Unit-type to be found.
 */
-local int FindInUpgradeToRequests(const UnitType* type)
+local int FindInUpgradeToRequests( const UnitType * type )
 {
     int i;
     int n;
 
-    n=AiPlayer->UnitTypeRequestsCount;
-    for( i=0; i<n; ++i ) {
-       if( AiPlayer->UpgradeToRequests[i]==type ) {
+    n = AiPlayer->UnitTypeRequestsCount;
+    for ( i = 0; i < n; ++i ) {
+       if ( AiPlayer->UpgradeToRequests[i] == type ) {
            return 1;
        }
     }
@@ -410,21 +924,22 @@
 **
 **     @param type     Unit-type to be appended.
 */
-local void InsertUpgradeToRequests(UnitType* type)
+local void InsertUpgradeToRequests( UnitType * type )
 {
     int n;
 
-    if( AiPlayer->UpgradeToRequests ) {
-       n=AiPlayer->UpgradeToRequestsCount;
-       AiPlayer->UpgradeToRequests=realloc(AiPlayer->UpgradeToRequests,
-               (n+1)*sizeof(*AiPlayer->UpgradeToRequests));
+    if ( AiPlayer->UpgradeToRequests ) {
+       n = AiPlayer->UpgradeToRequestsCount;
+       AiPlayer->UpgradeToRequests = realloc( AiPlayer->UpgradeToRequests,
+                                              ( n +
+                                                1 ) *
+                                              sizeof ( 
*AiPlayer->UpgradeToRequests ) );
     } else {
-       AiPlayer->UpgradeToRequests=
-               malloc(sizeof(*AiPlayer->UpgradeToRequests));
-       n=0;
+       AiPlayer->UpgradeToRequests = malloc( sizeof ( 
*AiPlayer->UpgradeToRequests ) );
+       n = 0;
     }
-    AiPlayer->UpgradeToRequests[n]=type;
-    AiPlayer->UpgradeToRequestsCount=n+1;
+    AiPlayer->UpgradeToRequests[n] = type;
+    AiPlayer->UpgradeToRequestsCount = n + 1;
 }
 
 /**
@@ -432,20 +947,21 @@
 **
 **     @param upgrade  Upgrade to be appended.
 */
-local void InsertResearchRequests(Upgrade* upgrade)
+local void InsertResearchRequests( Upgrade * upgrade )
 {
     int n;
 
-    if( AiPlayer->ResearchRequests ) {
-       n=AiPlayer->ResearchRequestsCount;
-       AiPlayer->ResearchRequests=realloc(AiPlayer->ResearchRequests,
-               (n+1)*sizeof(*AiPlayer->ResearchRequests));
+    if ( AiPlayer->ResearchRequests ) {
+       n = AiPlayer->ResearchRequestsCount;
+       AiPlayer->ResearchRequests = realloc( AiPlayer->ResearchRequests,
+                                             ( n +
+                                               1 ) * sizeof ( 
*AiPlayer->ResearchRequests ) );
     } else {
-       AiPlayer->ResearchRequests=malloc(sizeof(*AiPlayer->ResearchRequests));
-       n=0;
+       AiPlayer->ResearchRequests = malloc( sizeof ( 
*AiPlayer->ResearchRequests ) );
+       n = 0;
     }
-    AiPlayer->ResearchRequests[n]=upgrade;
-    AiPlayer->ResearchRequestsCount=n+1;
+    AiPlayer->ResearchRequests[n] = upgrade;
+    AiPlayer->ResearchRequestsCount = n + 1;
 }
 
 //----------------------------------------------------------------------------
@@ -453,17 +969,17 @@
 /**
 **     Get the race of the current AI player.
 */
-local SCM CclAiGetRace(void)
+local SCM CclAiGetRace( void )
 {
-    return gh_symbol2scm(AiPlayer->Player->RaceName);
+    return gh_symbol2scm( AiPlayer->Player->RaceName );
 }
 
 /**
 **     Get the number of cycles to sleep.
 */
-local SCM CclAiGetSleepCycles(void)
+local SCM CclAiGetSleepCycles( void )
 {
-    return gh_int2scm(AiSleepCycles);
+    return gh_int2scm( AiSleepCycles );
 }
 
 //----------------------------------------------------------------------------
@@ -471,12 +987,12 @@
 /**
 **     Set debuging flag of AI script.
 */
-local SCM CclAiDebug(SCM flag)
+local SCM CclAiDebug( SCM flag )
 {
-    if( gh_eq_p(flag,SCM_BOOL_F) ) {
-       AiPlayer->ScriptDebug=0;
+    if ( gh_eq_p( flag, SCM_BOOL_F ) ) {
+       AiPlayer->ScriptDebug = 0;
     } else {
-       AiPlayer->ScriptDebug=1;
+       AiPlayer->ScriptDebug = 1;
     }
     return SCM_BOOL_F;
 }
@@ -486,9 +1002,9 @@
 **
 **     @param value    Unit-type as string/symbol/object.
 */
-local SCM CclAiNeed(SCM value)
+local SCM CclAiNeed( SCM value )
 {
-    InsertUnitTypeRequests(CclGetUnitType(value),1);
+    InsertUnitTypeRequests( CclGetUnitType( value ), 1 );
 
     return SCM_BOOL_F;
 }
@@ -501,17 +1017,17 @@
 **
 **     @todo FIXME:    count==0 should remove the request.
 */
-local SCM CclAiSet(SCM value,SCM count)
+local SCM CclAiSet( SCM value, SCM count )
 {
-    AiUnitTypeTable* autt;
-    UnitType* type;
+    AiUnitTypeTable *autt;
+    UnitType *type;
 
-    type=CclGetUnitType(value);
-    if( (autt=FindInUnitTypeRequests(type)) ) {
-       autt->Count=gh_scm2int(count);
-       // FIXME: 0 should remove it.
+    type = CclGetUnitType( value );
+    if ( ( autt = FindInUnitTypeRequests( type ) ) ) {
+       autt->Count = gh_scm2int( count );
+       // FIXME: 0 should remove it.
     } else {
-       InsertUnitTypeRequests(type,gh_scm2int(count));
+       InsertUnitTypeRequests( type, gh_scm2int( count ) );
     }
 
     return SCM_BOOL_F;
@@ -522,61 +1038,56 @@
 **
 **     @param value    Unit-type as string/symbol/object.
 */
-local SCM CclAiWait(SCM value)
+local SCM CclAiWait( SCM value )
 {
-    const AiUnitTypeTable* autt;
-    const UnitType* type;
-    const int* unit_types_count;
+    const AiUnitTypeTable *autt;
+    const UnitType *type;
+    const int *unit_types_count;
     int j;
     int n;
 
-    type=CclGetUnitType(value);
-    unit_types_count=AiPlayer->Player->UnitTypesCount;
-    if( !(autt=FindInUnitTypeRequests(type)) ) {
-       //
-       //      Look if we have this unit-type.
-       //
-       if( unit_types_count[type->Type] ) {
+    type = CclGetUnitType( value );
+    unit_types_count = AiPlayer->Player->UnitTypesCount;
+    if ( !( autt = FindInUnitTypeRequests( type ) ) ) {
+       //
+       //      Look if we have this unit-type.
+       //
+       if ( unit_types_count[type->Type] ) {
            return SCM_BOOL_F;
        }
-       //
-       //      Look if we have equivalent unit-types.
-       //
-       if( type->Type<AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
-           DebugLevel3Fn("Equivalence for %s\n" _C_ type->Ident);
-           for( j=0; j<AiHelpers.Equiv[type->Type]->Count; ++j ) {
-               if( unit_types_count[
-                       AiHelpers.Equiv[type->Type]->Table[j]->Type] ) {
+       //
+       //      Look if we have equivalent unit-types.
+       //
+       if ( type->Type < AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) 
{
+           DebugLevel3Fn( "Equivalence for %s\n" _C_ type->Ident );
+           for ( j = 0; j < AiHelpers.Equiv[type->Type]->Count; ++j ) {
+               if ( 
unit_types_count[AiHelpers.Equiv[type->Type]->Table[j]->Type] ) {
                    return SCM_BOOL_F;
                }
            }
        }
-
-       //
-       //      Look if we have an upgrade-to request.
-       //
-       if( FindInUpgradeToRequests(type) ) {
+       //
+       //      Look if we have an upgrade-to request.
+       //
+       if ( FindInUpgradeToRequests( type ) ) {
            return SCM_BOOL_T;
        }
-       DebugLevel0Fn("Broken? waiting on %s which wasn't requested.\n" _C_
-               type->Ident);
+       DebugLevel0Fn( "Broken? waiting on %s which wasn't requested.\n" _C_ 
type->Ident );
        return SCM_BOOL_F;
     }
-
-    //
-    // Add equivalent units
-    //
-    n=unit_types_count[type->Type];
-    if( type->Type<AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
-       for( j=0; j<AiHelpers.Equiv[type->Type]->Count; ++j ) {
-           n+=unit_types_count[AiHelpers.Equiv[type->Type]->Table[j]->Type];
+   //
+   //  Add equivalent units
+   //
+    n = unit_types_count[type->Type];
+    if ( type->Type < AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
+       for ( j = 0; j < AiHelpers.Equiv[type->Type]->Count; ++j ) {
+           n += unit_types_count[AiHelpers.Equiv[type->Type]->Table[j]->Type];
        }
     }
+   // units available?
+    DebugLevel3Fn( "%d,%d\n" _C_ n _C_ autt->Count );
 
-    // units available?
-    DebugLevel3Fn("%d,%d\n" _C_ n _C_ autt->Count);
-
-    if( n>=autt->Count ) {
+    if ( n >= autt->Count ) {
        return SCM_BOOL_F;
     }
 
@@ -584,58 +1095,221 @@
 }
 
 /**
+**     Give the number of the script specific force.
+**
+*/
+local SCM CclAiOwnForce()
+{
+    return gh_int2scm( AiScript->ownForce );
+}
+
+/**
+**     Free a force ( requirements and current units )
+**
+**     @param s_force  Force to free.
+*/
+local SCM CclAiClearForce( SCM s_force )
+{
+    int force;
+/*    AiUnitType * aiut,*next;
+    AiUnit *aiu,*next_u;
+*/
+    force = gh_scm2int( s_force );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", s_force );
+    }
+/*
+    aiut=AiPlayer->Force[force].UnitTypes;
+    while(aiut){
+       next=aiut->Next;
+       free(aiut);
+       aiut=next;
+    }
+    AiPlayer->Force[force].UnitTypes=0;
+
+    aiu=AiPlayer->Force[force].Units;
+    while(aiu){
+       next_u=aiu->Next;
+       free(aiu);
+       aiu=next_u;
+    }
+    AiPlayer->Force[force].Units=0;
+    
+    AiAssignFreeUnitsToForce();
+    */
+    AiEraseForce( force );
+    return SCM_BOOL_F;
+
+}
+
+local SCM CclAiGetForce( SCM list )
+{
+    int force;
+    SCM rslt;
+    AiUnitType *aiut;
+
+    force = gh_scm2int( list );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", list );
+    }
+    rslt = SCM_UNSPECIFIED;
+    aiut = AiPlayer->Force[force].UnitTypes;
+    while ( aiut ) {
+       rslt =
+           cons( gh_symbol2scm( aiut->Type->Ident ), cons( gh_int2scm( 
aiut->Want ), rslt ) );
+       aiut = aiut->Next;
+    }
+    CclOutput( rslt );
+    return rslt;
+}
+
+/**
+**     Return true if a force has no unit, fase otherwise.
+**
+**
+*/
+local SCM CclAiForceEmpty( SCM list )
+{
+    int force;
+
+    force = gh_scm2int( list );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", list );
+    }
+
+    if ( AiPlayer->Force[force].Units ) {
+       return SCM_BOOL_F;
+    } else {
+       return SCM_BOOL_T;
+    }
+}
+
+local SCM CclAiAdHocForce( SCM requirement, SCM scm_unittypes )
+{
+    int want[3];
+    int *unittypes;
+    int unittypecount;
+    UnitType *unittype;
+    char *str;
+    int i;
+    int rslt;
+
+    for ( i = 0; i < 3; i++ ) {
+       want[i] = gh_scm2int( gh_car( requirement ) );
+       requirement = gh_cdr( requirement );
+    }
+
+    unittypecount = gh_length( scm_unittypes );
+    if ( unittypecount ) {
+       unittypes = ( int * ) malloc( sizeof ( int ) * unittypecount );
+
+       for ( i = 0; i < unittypecount; i++ ) {
+
+           str = gh_scm2newstr( gh_car( scm_unittypes ), NULL );
+           scm_unittypes = gh_cdr( scm_unittypes );
+
+
+           unittype = UnitTypeByIdent( str );
+           if ( !unittype ) {
+               fprintf( stderr, "unknown unittype %s\n", str );
+               free( str );
+               i--;
+               unittypecount--;
+               continue;
+
+           }
+           free( str );
+
+           unittypes[i] = unittype->Type;
+       }
+    } else {
+       unittypes = 0;
+    }
+    rslt = AiCreateSpecificForce( want, unittypes, unittypecount );
+    if ( unittypes ) {
+       free( unittypes );
+    }
+
+    if ( rslt != -1 ) {
+       return SCM_BOOL_T;
+    } else {
+       return SCM_BOOL_F;
+    }
+}
+
+local SCM CclAiForceActive( SCM list )
+{
+    int force;
+
+    force = gh_scm2int( list );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", list );
+    }
+
+    if ( AiPlayer->Force[force].Attacking ) {
+       return SCM_BOOL_T;
+    } else {
+       return SCM_BOOL_F;
+    }
+}
+
+/**
 **     Define a force, a groups of units.
+**     If force already exists, list is interpreted as a minimum...
 **
 **     @param list     Pairs of unit-types and counts.
 */
-local SCM CclAiForce(SCM list)
+local SCM CclAiForce( SCM list )
 {
-    AiUnitType** prev;
-    AiUnitType* aiut;
-    UnitType* type;
+    AiUnitType **prev;
+    AiUnitType *aiut;
+    UnitType *type;
     int count;
     int force;
 
-    force=gh_scm2int(gh_car(list));
-    if( force<0 || force>=AI_MAX_FORCES ) {
-       errl("Force out of range",gh_car(list));
-    }
-    list=gh_cdr(list);
-
-    while( !gh_null_p(list) ) {
-       type=CclGetUnitType(gh_car(list));
-       list=gh_cdr(list);
-       count=gh_scm2int(gh_car(list));
-       list=gh_cdr(list);
+    force = gh_scm2int( gh_car( list ) );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", gh_car( list ) );
+    }
+    list = gh_cdr( list );
+
+    while ( !gh_null_p( list ) ) {
+       type = CclGetUnitType( gh_car( list ) );
+       list = gh_cdr( list );
+       count = gh_scm2int( gh_car( list ) );
+       list = gh_cdr( list );
 
-       if( !type ) {                   // bulletproof
+       if ( !type ) {          // bulletproof
            continue;
        }
+       if ( !count ) {         // Don't care
+           continue;
+       }
+       //
+       //      Look if already in force.
+       //
+       for ( prev = &AiPlayer->Force[force].UnitTypes; ( aiut = *prev ); prev 
= &aiut->Next ) {
+           if ( aiut->Type == type ) { // found
+               if ( aiut->Want < count ) {
+                   aiut->Want = count;
+               }
 
-       //
-       //      Look if already in force.
-       //
-       for( prev=&AiPlayer->Force[force].UnitTypes; (aiut=*prev);
-               prev=&aiut->Next ) {
-           if( aiut->Type==type ) {    // found
-               if( count ) {
-                   aiut->Want=count;
-               } else {
-                   *prev=aiut->Next;
-                   free(aiut);
+               if ( !aiut->Want ) {
+                   *prev = aiut->Next;
+                   free( aiut );
                }
                break;
            }
        }
 
-       //
-       //      New type append it.
-       //
-       if( !aiut ) {
-           *prev=aiut=malloc(sizeof(*aiut));
-           aiut->Next=NULL;
-           aiut->Want=count;
-           aiut->Type=type;
+       //
+       //      New type append it.
+       //
+       if ( !aiut ) {
+           *prev = aiut = malloc( sizeof ( *aiut ) );
+           aiut->Next = NULL;
+           aiut->Want = count;
+           aiut->Type = type;
        }
     }
 
@@ -644,71 +1318,241 @@
     return SCM_BOOL_F;
 }
 
+local SCM CclAiForceTransfert( SCM sourceForce, SCM destForce )
+{
+    int src, dst;
+
+    src = gh_scm2int( sourceForce );
+    dst = gh_scm2int( destForce );
+    AiForceTransfert( src, dst );
+    return SCM_BOOL_F;
+}
+
+/**
+**     Wrapper of AiForceComplete.
+**     Complete a force with existing units.
+**
+**     @param destForce        the force to complete
+*/
+local SCM CclAiForceComplete( SCM destForce )
+{
+    int dst;
+
+    dst = gh_scm2int( destForce );
+    AiForceComplete( dst );
+    return SCM_BOOL_F;
+}
+
 /**
 **     Define the role of a force.
 **
 **     @param value    Force number.
 **     @param flag     Which role of the force.
 */
-local SCM CclAiForceRole(SCM value,SCM flag)
+local SCM CclAiForceRole( SCM value, SCM flag )
 {
     int force;
 
-    force=gh_scm2int(value);
-    if( force<0 || force>=AI_MAX_FORCES ) {
-       errl("Force out of range",value);
-    }
-    if( gh_eq_p(flag,gh_symbol2scm("attack")) ) {
-       AiPlayer->Force[force].Role=AiForceRoleAttack;
-    } else if( gh_eq_p(flag,gh_symbol2scm("defend")) ) {
-       AiPlayer->Force[force].Role=AiForceRoleDefend;
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
+    }
+    if ( gh_eq_p( flag, gh_symbol2scm( "attack" ) ) ) {
+       AiPlayer->Force[force].Role = AiForceRoleAttack;
+    } else if ( gh_eq_p( flag, gh_symbol2scm( "defend" ) ) ) {
+       AiPlayer->Force[force].Role = AiForceRoleDefend;
     } else {
-       errl("Unknown force role",flag);
+       errl( "Unknown force role", flag );
+    }
+
+    return SCM_BOOL_F;
+}
+
+
+/**
+**     Return wether a force is defending or not.
+**
+**     @param  value   the force
+**     @return         true if the force is defending, false otherwise
+*/
+local SCM CclAiIsForceDefending( SCM value )
+{
+    int force;
+
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
     }
 
+    if ( AiPlayer->Force[force].Role == AiForceRoleDefend ) {
+       return SCM_BOOL_T;
+    }
     return SCM_BOOL_F;
 }
 
+
+/**
+**     Check if the hotspot can be reached.
+**     The parameter describe which element we are travelling in.
+**
+**     @param way      air, ground or sea
+**     @return         true if the hotspot is reachable
+*/
+local SCM CclAiCanReachHotSpot( SCM way )
+{
+    int wayid, i;
+    int x, y, w, h;
+    Unit *unit;
+
+
+    if ( ( AiScript->HotSpot_X == -1 ) || ( AiScript->HotSpot_Y == -1 )
+        || ( AiScript->HotSpot_Ray <= 0 ) ) {
+       return SCM_BOOL_T;
+    }
+
+    wayid = -1;
+   // Air is always accessible...
+    if ( gh_eq_p( way, gh_symbol2scm( "air" ) ) ) {
+       wayid = 0;
+    }
+    if ( gh_eq_p( way, gh_symbol2scm( "ground" ) ) ) {
+       wayid = 1;
+    }
+    if ( gh_eq_p( way, gh_symbol2scm( "sea" ) ) ) {
+       wayid = 2;
+    }
+
+    if ( wayid == -1 ) {
+       errl( "Unknown way ", way );
+    }
+   // Calculate a rectangle...
+   // FIXME : Why 2 ?
+    x = AiScript->HotSpot_X - 2;
+    y = AiScript->HotSpot_Y - 2;
+    w = 5;
+    h = 5;
+
+   // clip it
+    if ( x < 0 ) {
+       w += x;
+       x = 0;
+    }
+    if ( y < 0 ) {
+       h += y;
+       y = 0;
+    }
+    if ( x + w >= TheMap.Width ) {
+       w = TheMap.Width - x;
+    }
+
+    if ( y + h >= TheMap.Height ) {
+       h = TheMap.Height - y;
+    }
+   // Dummy check...
+    if ( ( w <= 0 ) || ( h <= 0 ) ) {
+       return SCM_BOOL_F;
+    }
+   // Air is no problem...
+    if ( wayid == 0 ) {
+       return SCM_BOOL_T;
+    }
+   // Find a unit which can move, check if it can access the hotspot.
+    for ( i = 0; i < AiPlayer->Player->TotalNumUnits; i++ ) {
+       unit = AiPlayer->Player->Units[i];
+
+       if ( unit->Orders[0].Action == UnitActionDie ) {
+           continue;
+       }
+
+       if ( unit->Removed ) {
+           continue;
+       }
+
+       if ( ( unit->X == -1 ) || ( unit->Y == -1 ) ) {
+           continue;
+       }
+
+       if ( unit->Type->Building ) {
+           continue;
+       }
+
+       if ( ( wayid == 1 ) && ( unit->Type->UnitType != UnitTypeLand ) ) {
+           continue;
+       }
+
+       if ( ( wayid == 2 ) && ( unit->Type->UnitType != UnitTypeNaval ) ) {
+           continue;
+       }
+       // Ok, unit is a possible test
+       if ( PlaceReachable( unit, x, y, w, h, 2 ) ) {
+           return SCM_BOOL_T;
+       }
+       return SCM_BOOL_F;
+    }
+
+   // Fall back : no unit at all ? Use the starting point...
+    DebugLevel3Fn( "CclAiCanReach failled to use a test unit...\n" );
+    return SCM_BOOL_T;
+}
+
+
 /**
 **     Check if a force ready.
 **
 **     @param value    Force number.
 **     @return         #t if ready, #f otherwise.
 */
-local SCM CclAiCheckForce(SCM value)
+local SCM CclAiCheckForce( SCM value )
 {
     int force;
 
-    force=gh_scm2int(value);
-    if( force<0 || force>=AI_MAX_FORCES ) {
-       errl("Force out of range",value);
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
     }
-    if( AiPlayer->Force[force].Completed ) {
+    if ( AiPlayer->Force[force].Completed ) {
        return SCM_BOOL_T;
     }
-
     return SCM_BOOL_F;
 }
 
 /**
+** Evaluate the ressources needed to complete a force.
+**
+** @param s_force the force
+**
+** @return -1 if it is not possible ( upgrade missing )
+*/
+local SCM CclAiEvaluateForceCost( SCM s_force )
+{
+    return gh_int2scm( AiEvaluateForceCost( gh_scm2int( s_force ), 0 ) );
+}
+
+// Just hang...
+local SCM CclAiIdle()
+{
+    return SCM_BOOL_T;
+}
+
+/**
 **     Wait for a force ready.
 **
 **     @param value    Force number.
 */
-local SCM CclAiWaitForce(SCM value)
+local SCM CclAiWaitForce( SCM value )
 {
     int force;
 
-    force=gh_scm2int(value);
-    if( force<0 || force>=AI_MAX_FORCES ) {
-       errl("Force out of range",value);
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
     }
-    if( AiPlayer->Force[force].Completed ) {
+    if ( AiPlayer->Force[force].Completed ) {
        return SCM_BOOL_F;
     }
-    DebugLevel3Fn("Wait force %d\n" _C_ force);
+    DebugLevel3Fn( "Wait force %d\n" _C_ force );
 #if 0
-    // Debuging
+   // Debuging
     AiCleanForces();
     DebugCheck( AiPlayer->Force[force].Completed );
 #endif
@@ -721,38 +1565,114 @@
 **
 **     @param value    Force number.
 */
-local SCM CclAiAttackWithForce(SCM value)
+local SCM CclAiAttackWithForce( SCM value )
 {
     int force;
 
-    force=gh_scm2int(value);
-    if( force<0 || force>=AI_MAX_FORCES ) {
-       errl("Force out of range",value);
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
     }
 
-    AiAttackWithForce(force);
+    AiAttackWithForce( force );
 
     return SCM_BOOL_F;
 }
 
 /**
+**     Attack with force, on the current script hotspot.
+**
+**     @param value    Force number.
+*/
+local SCM CclAiHotSpotAttackWithForce( SCM value )
+{
+    int force;
+
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
+    }
+
+    AiAttackWithForceAt( force, AiScript->HotSpot_X, AiScript->HotSpot_Y );
+
+    return SCM_BOOL_F;
+}
+
+/**
+**
+**
+*/
+local SCM CclAiGroupForce( SCM value )
+{
+    int force;
+
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
+    }
+
+    AiGroupForceNear( force, AiScript->HotSpot_X, AiScript->HotSpot_Y );
+
+    return SCM_BOOL_F;
+}
+
+local SCM CclAiForceHome( SCM value )
+{
+    int force;
+
+    force = gh_scm2int( value );
+    if ( force < 0 || force >= AI_MAX_FORCES ) {
+       errl( "Force out of range", value );
+    }
+
+    AiSendForceHome( force );
+
+    return SCM_BOOL_F;
+}
+
+/**
+**     Wait for a force (like CclAiWaitForce), limited in time.
+**
+**     @param s_force  Force number.
+**     @param s_wait   Maximum number of cycles to delay.
+*/
+local SCM CclAiTimedWaitForce( SCM s_force, SCM s_wait )
+{
+    SCM result;
+   // return true after n call or when force is ready
+    if ( AiScript->SleepCycles ) {
+       if ( AiScript->SleepCycles < GameCycle ) {
+           AiScript->SleepCycles = 0;
+           return SCM_BOOL_F;
+       }
+    } else {
+       AiScript->SleepCycles = GameCycle + gh_scm2int( s_wait );
+    }
+    result = CclAiWaitForce( s_force );
+    if ( result == SCM_BOOL_F ) {
+       AiScript->SleepCycles = 0;
+    }
+    return result;
+}
+
+/**
 **     Sleep n cycles.
 **
 **     @param value    Number of cycles to delay.
 */
-local SCM CclAiSleep(SCM value)
+local SCM CclAiSleep( SCM value )
 {
     int i;
 
-    DebugLevel3Fn("%lu %d\n" _C_ GameCycle _C_ AiPlayer->SleepCycles);
-    if( AiPlayer->SleepCycles ) {
-       if( AiPlayer->SleepCycles<GameCycle ) {
-           AiPlayer->SleepCycles=0;
+    DebugLevel3Fn( "%lu %d\n" _C_ GameCycle _C_ AiPlayer->SleepCycles );
+    if ( AiScript->SleepCycles ) {
+       if ( AiScript->SleepCycles < GameCycle ) {
+           AiScript->SleepCycles = 0;
            return SCM_BOOL_F;
        }
     } else {
-       i=gh_scm2int(value);
-       AiPlayer->SleepCycles=GameCycle+i;
+       i = gh_scm2int( value );
+       AiScript->SleepCycles = GameCycle + i;
     }
 
     return SCM_BOOL_T;
@@ -763,20 +1683,20 @@
 **
 **     @param value    Upgrade as string/symbol/object.
 */
-local SCM CclAiResearch(SCM value)
+local SCM CclAiResearch( SCM value )
 {
-    const char* str;
-    Upgrade* upgrade;
+    const char *str;
+    Upgrade *upgrade;
 
-    // Be kind allow also strings or symbols
-    if( (str=try_get_c_string(value)) ) {
-       upgrade=UpgradeByIdent(str);
+   // Be kind allow also strings or symbols
+    if ( ( str = try_get_c_string( value ) ) ) {
+       upgrade = UpgradeByIdent( str );
     } else {
-       errl("Upgrade needed",value);
+       errl( "Upgrade needed", value );
        return SCM_BOOL_F;
     }
 
-    InsertResearchRequests(upgrade);
+    InsertResearchRequests( upgrade );
 
     return SCM_BOOL_F;
 }
@@ -786,33 +1706,117 @@
 **
 **     @param value    Unit-type as string/symbol/object.
 */
-local SCM CclAiUpgradeTo(SCM value)
+local SCM CclAiUpgradeTo( SCM value )
 {
-    UnitType* type;
+    UnitType *type;
 
-    type=CclGetUnitType(value);
-    InsertUpgradeToRequests(type);
+    type = CclGetUnitType( value );
+    InsertUpgradeToRequests( type );
 
     return SCM_BOOL_F;
 }
 
+local SCM CclAiSetHotSpotRay( SCM value )
+{
+    return SCM_BOOL_F;
+}
+
+local SCM CclAiComputeGauges()
+{
+    AiComputeCurrentScriptGauges();
+    return SCM_BOOL_F;
+}
+
+local SCM CclAiDebugGauges()
+{
+    AiDebugGauges();
+    return SCM_BOOL_F;
+}
+
+local SCM CclAiGetGauge( SCM value )
+{
+    int gauge;
+    if ( gh_exact_p( value ) ) {
+       gauge = gh_scm2int( value );
+    } else {
+       gauge = AiFindGaugeId( value );
+       if ( gauge == -1 ) {
+           errl( "invalid gauge name", value );
+       }
+    }
+    return gh_int2scm( AiGetGaugeValue( gauge ) );
+}
+
+local SCM CclGetUnitTypeForce( SCM value )
+{
+    UnitType *unitType;
+
+    unitType = CclGetUnitType( value );
+
+    return gh_int2scm( AiUnittypeForce( unitType ) );
+}
+
 /**
 **     Simple restart the AI.
 */
-local SCM CclAiRestart(void)
+local SCM CclAiRestart( void )
 {
-    AiPlayer->Script=AiPlayer->AiType->Script;
-
+    int i;
+    AiPlayer->Scripts[0].Script = AiPlayer->AiType->Script;
+    AiPlayer->Scripts[0].SleepCycles = 0;
+    snprintf( AiPlayer->Scripts[0].ident, 10, "Main AI" );
+    for ( i = 1; i < AI_MAX_RUNNING_SCRIPTS; i++ ) {
+       AiPlayer->Scripts[i].Script = NIL;
+       AiPlayer->Scripts[i].SleepCycles = 0;
+       snprintf( AiPlayer->Scripts[i].ident, 10, "Empty" );
+    }
     return SCM_BOOL_T;
 }
 
 /**
-**     Execute new script
+**     Start an AI script at the given id.
+**
+**      @param script          The Id of the script to run ( main, defend, ... 
)
+**     @param list             The script execution
+**     @param hotSpotX         position of the hotspot (X)
+**     @param hotSpotY         position of the hotspot (Y)
+**     @param hotSpotRay       ray of the hotspot
 */
-local SCM CclAiScript(SCM value)
+global void AiRunScript( int script, SCM list, int hotSpotX, int hotSpotY, int 
hotSpotRay )
 {
-    AiPlayer->Script=value;
+    AiPlayer->Scripts[script].Script = list;
+    AiPlayer->Scripts[script].SleepCycles = 0;
+    snprintf( AiPlayer->Scripts[script].ident, 10, "AiRunScript" );
+    AiPlayer->Scripts[script].HotSpot_X = hotSpotX;
+    AiPlayer->Scripts[script].HotSpot_Y = hotSpotY;
+    AiPlayer->Scripts[script].HotSpot_Ray = hotSpotRay;
+   // TODO : Compute gauges here ?    
+}
 
+/**
+**     Change the current script
+*/
+local SCM CclAiSwitchTo( SCM value )
+{
+    AiScript->Script = value;
+    AiScript->SleepCycles = 0;
+    return SCM_BOOL_T;
+}
+
+/**
+**     Execute new main script
+*/
+local SCM CclAiScript( SCM value )
+{
+    int i;
+    AiPlayer->Scripts[0].Script = value;
+    AiPlayer->Scripts[0].SleepCycles = 0;
+    snprintf( AiPlayer->Scripts[0].ident, 10, "MainScript" );
+    for ( i = 1; i < AI_MAX_RUNNING_SCRIPTS; i++ ) {
+       AiPlayer->Scripts[i].Script = NIL;
+       AiPlayer->Scripts[i].SleepCycles = 0;
+       snprintf( AiPlayer->Scripts[i].ident, 10, "Empty" );
+    }
     return SCM_BOOL_T;
 }
 
@@ -821,9 +1825,9 @@
 **
 **     @return         Player number of the AI.
 */
-local SCM CclAiPlayer(void)
+local SCM CclAiPlayer( void )
 {
-    return gh_int2scm(AiPlayer->Player->Player);
+    return gh_int2scm( AiPlayer->Player->Player );
 }
 
 /**
@@ -832,17 +1836,17 @@
 **     @param vec      Resources vector
 **     @return         Old resource vector
 */
-local SCM CclAiSetReserve(SCM vec)
+local SCM CclAiSetReserve( SCM vec )
 {
     int i;
     SCM old;
 
-    old = cons_array(gh_int2scm(MaxCosts), 0);
-    for( i=0; i<MaxCosts; ++i ) {
-       aset1(old,gh_int2scm(i),gh_int2scm(AiPlayer->Reserve[i]));
+    old = cons_array( gh_int2scm( MaxCosts ), 0 );
+    for ( i = 0; i < MaxCosts; ++i ) {
+       aset1( old, gh_int2scm( i ), gh_int2scm( AiPlayer->Reserve[i] ) );
     }
-    for( i=0; i<MaxCosts; ++i ) {
-       AiPlayer->Reserve[i]=gh_scm2int(gh_vector_ref(vec,gh_int2scm(i)));
+    for ( i = 0; i < MaxCosts; ++i ) {
+       AiPlayer->Reserve[i] = gh_scm2int( gh_vector_ref( vec, gh_int2scm( i ) 
) );
     }
     return old;
 }
@@ -853,86 +1857,99 @@
 **     @param vec      Resources vector
 **     @return         Old resource vector
 */
-local SCM CclAiSetCollect(SCM vec)
+local SCM CclAiSetCollect( SCM vec )
 {
     int i;
     SCM old;
 
-    old = cons_array(gh_int2scm(MaxCosts), 0);
-    for( i=0; i<MaxCosts; ++i ) {
-       aset1(old,gh_int2scm(i),gh_int2scm(AiPlayer->Collect[i]));
+    old = cons_array( gh_int2scm( MaxCosts ), 0 );
+    for ( i = 0; i < MaxCosts; ++i ) {
+       aset1( old, gh_int2scm( i ), gh_int2scm( AiPlayer->Collect[i] ) );
     }
-    for( i=0; i<MaxCosts; ++i ) {
-       AiPlayer->Collect[i]=gh_scm2int(gh_vector_ref(vec,gh_int2scm(i)));
+    for ( i = 0; i < MaxCosts; ++i ) {
+       AiPlayer->Collect[i] = gh_scm2int( gh_vector_ref( vec, gh_int2scm( i ) 
) );
     }
     return old;
 }
 
 /**
+**     Set the autoattack flag of the current AiPlayer
+**
+**     @param val      new value of the autoattack flag
+**     @return         SCM_BOOL_F
+*/
+local SCM CclAiSetAutoAttack( SCM val )
+{
+    AiPlayer->AutoAttack = gh_scm2bool( val );
+    return SCM_BOOL_F;
+}
+
+/**
 **     Dump some AI debug informations.
 */
-local SCM CclAiDump(void)
+local SCM CclAiDump( void )
 {
     int i;
     int n;
-    const AiUnitType* aut;
-    const AiBuildQueue* queue;
+    const AiUnitType *aut;
+    const AiBuildQueue *queue;
 
-    //
-    // Script
-    //
-    printf("------\n");
-    for( i=0; i<MaxCosts; ++i ) {
-       printf("%s(%4d) 
",DefaultResourceNames[i],AiPlayer->Player->Resources[i]);
-    }
-    printf("\n");
-    printf("%d:",AiPlayer->Player->Player);
-    gh_display(gh_car(AiPlayer->Script));
+   //
+   //  Script
+   //
+    printf( "------\n" );
+    for ( i = 0; i < MaxCosts; ++i ) {
+       printf( "%s(%4d) ", DefaultResourceNames[i], 
AiPlayer->Player->Resources[i] );
+    }
+    printf( "\n" );
+    printf( "%d:", AiPlayer->Player->Player );
+    for ( i = 0; i < AI_MAX_RUNNING_SCRIPTS; ++i ) {
+       gh_display( gh_car( AiPlayer->Scripts[i].Script ) );
+    }
     gh_newline();
 
-    //
-    // Requests
-    //
-    n=AiPlayer->UnitTypeRequestsCount;
-    printf("UnitTypeRequests(%d):\n",n);
-    for( i=0; i<n; ++i ) {
-       printf("%s ",AiPlayer->UnitTypeRequests[i].Table[0]->Ident);
-    }
-    printf("\n");
-    n=AiPlayer->UpgradeToRequestsCount;
-    printf("UpgradeToRequests(%d):\n",n);
-    for( i=0; i<n; ++i ) {
-       printf("%s ",AiPlayer->UpgradeToRequests[i]->Ident);
-    }
-    printf("\n");
-    n=AiPlayer->ResearchRequestsCount;
-    printf("ResearchRequests(%d):\n",n);
-    for( i=0; i<n; ++i ) {
-       printf("%s ",AiPlayer->ResearchRequests[i]->Ident);
-    }
-    printf("\n");
-
-    //
-    // Building queue
-    //
-    printf("Building queue:\n");
-    for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
-       printf("%s(%d/%d) ",queue->Type->Ident,queue->Made,queue->Want);
-    }
-    printf("\n");
-
-    //
-    // PrintForce
-    //
-    for( i=0; i<AI_MAX_ATTACKING_FORCES; ++i) {
-       printf("Force(%d%s%s%s):\n",i,
+   //
+   //  Requests
+   //
+    n = AiPlayer->UnitTypeRequestsCount;
+    printf( "UnitTypeRequests(%d):\n", n );
+    for ( i = 0; i < n; ++i ) {
+       printf( "%s ", AiPlayer->UnitTypeRequests[i].Table[0]->Ident );
+    }
+    printf( "\n" );
+    n = AiPlayer->UpgradeToRequestsCount;
+    printf( "UpgradeToRequests(%d):\n", n );
+    for ( i = 0; i < n; ++i ) {
+       printf( "%s ", AiPlayer->UpgradeToRequests[i]->Ident );
+    }
+    printf( "\n" );
+    n = AiPlayer->ResearchRequestsCount;
+    printf( "ResearchRequests(%d):\n", n );
+    for ( i = 0; i < n; ++i ) {
+       printf( "%s ", AiPlayer->ResearchRequests[i]->Ident );
+    }
+    printf( "\n" );
+
+   //
+   //  Building queue
+   //
+    printf( "Building queue:\n" );
+    for ( queue = AiPlayer->UnitTypeBuilded; queue; queue = queue->Next ) {
+       printf( "%s(%d/%d) ", queue->Type->Ident, queue->Made, queue->Want );
+    }
+    printf( "\n" );
+
+   //
+   //  PrintForce
+   //
+    for ( i = 0; i < AI_MAX_FORCES; ++i ) {
+       printf( "Force(%d%s%s):\n", i,
                AiPlayer->Force[i].Completed ? ",complete" : ",recruit",
-               AiPlayer->Force[i].Attacking ? ",attack" : "",
-               AiPlayer->Force[i].Defending ? ",defend" : "");
-       for( aut=AiPlayer->Force[i].UnitTypes; aut; aut=aut->Next ) {
-           printf("%s(%d) ",aut->Type->Ident,aut->Want);
+               AiPlayer->Force[i].Attacking ? ",attack" : "" );
+       for ( aut = AiPlayer->Force[i].UnitTypes; aut; aut = aut->Next ) {
+           printf( "%s(%d) ", aut->Type->Ident, aut->Want );
        }
-       printf("\n");
+       printf( "\n" );
     }
 
     return SCM_BOOL_F;
@@ -943,28 +1960,27 @@
 **
 **     @param list     List of all names.
 */
-local SCM CclDefineAiWcNames(SCM list)
+local SCM CclDefineAiWcNames( SCM list )
 {
     int i;
-    char** cp;
+    char **cp;
 
-    if( (cp=AiTypeWcNames) ) {         // Free all old names
-       while( *cp ) {
-           free(*cp++);
+    if ( ( cp = AiTypeWcNames ) ) {    // Free all old names
+       while ( *cp ) {
+           free( *cp++ );
        }
-       free(AiTypeWcNames);
+       free( AiTypeWcNames );
     }
-
-    //
-    // Get new table.
-    //
-    i=gh_length(list);
-    AiTypeWcNames=cp=malloc((i+1)*sizeof(char*));
-    while( i-- ) {
-       *cp++=gh_scm2newstr(gh_car(list),NULL);
-       list=gh_cdr(list);
+   //
+   //  Get new table.
+   //
+    i = gh_length( list );
+    AiTypeWcNames = cp = malloc( ( i + 1 ) * sizeof ( char * ) );
+    while ( i-- ) {
+       *cp++ = gh_scm2newstr( gh_car( list ), NULL );
+       list = gh_cdr( list );
     }
-    *cp=NULL;
+    *cp = NULL;
 
     return SCM_UNSPECIFIED;
 }
@@ -976,363 +1992,429 @@
 **
 **     @return         The number of the resource in DEFAULT_NAMES
 */
-local int DefaultResourceNumber(const char *type)
+local int DefaultResourceNumber( const char *type )
 {
     int i;
-    for( i=0; i<MaxCosts; ++i ) {
-       if( !strcmp(DefaultResourceNames[i],type) ) {
+    for ( i = 0; i < MaxCosts; ++i ) {
+       if ( !strcmp( DefaultResourceNames[i], type ) ) {
            return i;
        }
     }
-    // Resource not found, should never happen
-    DebugCheck(1);
+   // Resource not found, should never happen
+    DebugCheck( 1 );
     return -1;
 }
 
 /**
 **     Define an AI player.
 **
+**     Format of the list is :
+**     (       <player_id>
+**             <value> <list>
+**             [ <value> <list> [ ... ] ]
+**     )
+**
+**     <value> can be :
+**             ai-type => the name of the ai
+**             script  => ???
+**             script-debug => ???
+**                             
 **     @param list     List of the AI Player.
 */
-local SCM CclDefineAiPlayer(SCM list)
+local SCM CclDefineAiPlayer( SCM list )
 {
-    SCM value;
-    SCM sublist;
+   //SCM value;
+   //SCM sublist;
     int i;
-    char* str;
-    PlayerAi* ai;
+   //char* str;
+    PlayerAi *ai;
+
+    IOLoadingMode = 1;
+
+    IOPlayerAiFullPtr( gh_car( list ), &ai, 0 );
 
-    i=gh_scm2int(gh_car(list));
-    list=gh_cdr(list);
+    i = ai->Player->Player;
+    DebugCheck( i < 0 || i > PlayerMax );
+    Players[i].Ai = ai;
 
-    DebugCheck( i<0 || i>PlayerMax );
-    DebugLevel0Fn("%p %d\n" _C_ Players[i].Ai _C_ Players[i].AiEnabled );
-    // FIXME: loose this:
-    // DebugCheck( Players[i].Ai || !Players[i].AiEnabled );
-
-    ai=Players[i].Ai=calloc(1,sizeof(PlayerAi));
-    ai->Player=&Players[i];
-
-    //
-    // Parse the list: (still everything could be changed!)
-    //
-    while( !gh_null_p(list) ) {
-
-       value=gh_car(list);
-       list=gh_cdr(list);
-
-       if( gh_eq_p(value,gh_symbol2scm("ai-type")) ) {
-           AiType* ait;
-
-           str=gh_scm2newstr(gh_car(list),NULL);
-           for( ait=AiTypes; ait; ait=ait->Next ) {
-               if( !strcmp(ait->Name,str) ) {
+#if 0
+    i = gh_scm2int( gh_car( list ) );
+    list = gh_cdr( list );
+
+    DebugCheck( i < 0 || i > PlayerMax );
+    DebugLevel0Fn( "%p %d\n" _C_ Players[i].Ai _C_ Players[i].AiEnabled );
+   // FIXME: loose this:
+   // DebugCheck( Players[i].Ai || !Players[i].AiEnabled );
+
+    ai = Players[i].Ai = calloc( 1, sizeof ( PlayerAi ) );
+    ai->Player = &Players[i];
+
+    snprintf( AiPlayer->Scripts[0].ident, 10, "Empty" );
+    for ( i = 1; i < AI_MAX_RUNNING_SCRIPTS; i++ ) {
+       ai->Scripts[i].Script = NIL;
+       ai->Scripts[i].SleepCycles = 0;
+       snprintf( AiPlayer->Scripts[i].ident, 10, "Empty" );
+    }
+
+   //
+   //  Parse the list: (still everything could be changed!)
+   //
+    while ( !gh_null_p( list ) ) {
+
+       value = gh_car( list );
+       list = gh_cdr( list );
+
+       if ( gh_eq_p( value, gh_symbol2scm( "ai-type" ) ) ) {
+           AiType *ait;
+
+           str = gh_scm2newstr( gh_car( list ), NULL );
+           for ( ait = AiTypes; ait; ait = ait->Next ) {
+               if ( !strcmp( ait->Name, str ) ) {
                    break;
                }
            }
-           free(str);
-           if( !ait ) {
-              errl("ai-type not found",gh_car(list));
-           }
-           ai->AiType=ait;
-           ai->Script=ait->Script;
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("script")) ) {
-           sublist=gh_car(list);
-           value=gh_car(sublist);
-           sublist=gh_cdr(sublist);
-           if( gh_eq_p(value,gh_symbol2scm("aitypes")) ) {
-               i=gh_scm2int(gh_car(sublist));
-               while( i-- ) {
-                   ai->Script=gh_cdr(ai->Script);
+           free( str );
+           if ( !ait ) {
+               errl( "ai-type not found", gh_car( list ) );
+           }
+           ai->AiType = ait;
+           ai->Scripts[0].Script = ait->Script;
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "script" ) ) ) {
+           sublist = gh_car( list );
+           value = gh_car( sublist );
+           sublist = gh_cdr( sublist );
+           if ( gh_eq_p( value, gh_symbol2scm( "aitypes" ) ) ) {
+               i = gh_scm2int( gh_car( sublist ) );
+               while ( i-- ) {
+                   ai->Scripts[0].Script = gh_cdr( ai->Scripts[0].Script );
                }
            } else {
-               DebugLevel0Fn("FIXME: not written\n");
+               DebugLevel0Fn( "FIXME: not written\n" );
            }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("script-debug")) ) {
-           ai->ScriptDebug=gh_scm2bool(gh_car(list));
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("sleep-cycles")) ) {
-           ai->SleepCycles=gh_scm2int(gh_car(list));
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("force")) ) {
-           sublist=gh_car(list);
-           value=gh_car(sublist);
-           sublist=gh_cdr(sublist);
-           i=gh_scm2int(value);
-           while( !gh_null_p(sublist) ) {
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               if( gh_eq_p(value,gh_symbol2scm("complete")) ) {
-                   ai->Force[i].Completed=1;
-               } else if( gh_eq_p(value,gh_symbol2scm("recruit")) ) {
-                   ai->Force[i].Completed=0;
-               } else if( gh_eq_p(value,gh_symbol2scm("attack")) ) {
-                   ai->Force[i].Attacking=1;
-               } else if( gh_eq_p(value,gh_symbol2scm("defend")) ) {
-                   ai->Force[i].Defending=1;
-               } else if( gh_eq_p(value,gh_symbol2scm("role")) ) {
-                   if( gh_eq_p(gh_car(sublist),gh_symbol2scm("attack")) ) {
-                       ai->Force[i].Role=AiForceRoleAttack;
-                   } else if( gh_eq_p(gh_car(sublist),gh_symbol2scm("defend")) 
) {
-                       ai->Force[i].Role=AiForceRoleDefend;
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "script-debug" ) ) ) {
+           ai->ScriptDebug = gh_scm2bool( gh_car( list ) );
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "sleep-cycles" ) ) ) {
+           ai->Scripts[0].SleepCycles = gh_scm2int( gh_car( list ) );
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "force" ) ) ) {
+           sublist = gh_car( list );
+           value = gh_car( sublist );
+           sublist = gh_cdr( sublist );
+           i = gh_scm2int( value );
+           while ( !gh_null_p( sublist ) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               if ( gh_eq_p( value, gh_symbol2scm( "complete" ) ) ) {
+                   ai->Force[i].Completed = 1;
+               } else if ( gh_eq_p( value, gh_symbol2scm( "recruit" ) ) ) {
+                   ai->Force[i].Completed = 0;
+               } else if ( gh_eq_p( value, gh_symbol2scm( "attack" ) ) ) {
+                   ai->Force[i].Attacking = 1;
+               } else if ( gh_eq_p( value, gh_symbol2scm( "role" ) ) ) {
+                   if ( gh_eq_p( gh_car( sublist ), gh_symbol2scm( "attack" ) 
) ) {
+                       ai->Force[i].Role = AiForceRoleAttack;
+                   } else if ( gh_eq_p( gh_car( sublist ), gh_symbol2scm( 
"defend" ) ) ) {
+                       ai->Force[i].Role = AiForceRoleDefend;
                    }
-                   sublist=gh_cdr(sublist);
-               } else if( gh_eq_p(value,gh_symbol2scm("types")) ) {
+                   sublist = gh_cdr( sublist );
+               } else if ( gh_eq_p( value, gh_symbol2scm( "types" ) ) ) {
                    AiUnitType **queue;
                    SCM subsublist;
-                   subsublist=gh_car(sublist);
-                   queue=&ai->Force[i].UnitTypes;
-                   while( !gh_null_p(subsublist) ) {
+                   subsublist = gh_car( sublist );
+                   queue = &ai->Force[i].UnitTypes;
+                   while ( !gh_null_p( subsublist ) ) {
                        int num;
                        char *ident;
-                       value=gh_car(subsublist);
-                       subsublist=gh_cdr(subsublist);
-                       num=gh_scm2int(value);
-                       value=gh_car(subsublist);
-                       subsublist=gh_cdr(subsublist);
-                       ident=get_c_string(value);
-                       *queue=malloc(sizeof(AiUnitType));
-                       (*queue)->Next=NULL;
-                       (*queue)->Want=num;
-                       (*queue)->Type=UnitTypeByIdent(ident);
-                       queue=&(*queue)->Next;
+                       value = gh_car( subsublist );
+                       subsublist = gh_cdr( subsublist );
+                       num = gh_scm2int( value );
+                       value = gh_car( subsublist );
+                       subsublist = gh_cdr( subsublist );
+                       ident = get_c_string( value );
+                       *queue = malloc( sizeof ( AiUnitType ) );
+                       ( *queue )->Next = NULL;
+                       ( *queue )->Want = num;
+                       ( *queue )->Type = UnitTypeByIdent( ident );
+                       queue = &( *queue )->Next;
                    }
-                   sublist=gh_cdr(sublist);
-               } else if( gh_eq_p(value,gh_symbol2scm("units")) ) {
+                   sublist = gh_cdr( sublist );
+               } else if ( gh_eq_p( value, gh_symbol2scm( "units" ) ) ) {
                    AiUnit **queue;
                    SCM subsublist;
-                   subsublist=gh_car(sublist);
-                   queue=&ai->Force[i].Units;
-                   while( !gh_null_p(subsublist) ) {
+                   subsublist = gh_car( sublist );
+                   queue = &ai->Force[i].Units;
+                   while ( !gh_null_p( subsublist ) ) {
                        int num;
                        char *ident;
-                       value=gh_car(subsublist);
-                       subsublist=gh_cdr(subsublist);
-                       num=gh_scm2int(value);
-                       value=gh_car(subsublist);
-                       subsublist=gh_cdr(subsublist);
-                       ident=get_c_string(value);
-                       *queue=malloc(sizeof(AiUnit));
-                       (*queue)->Next=NULL;
-                       (*queue)->Unit=UnitSlots[num];
-                       queue=&(*queue)->Next;
+                       value = gh_car( subsublist );
+                       subsublist = gh_cdr( subsublist );
+                       num = gh_scm2int( value );
+                       value = gh_car( subsublist );
+                       subsublist = gh_cdr( subsublist );
+                       ident = get_c_string( value );
+                       *queue = malloc( sizeof ( AiUnit ) );
+                       ( *queue )->Next = NULL;
+                       ( *queue )->Unit = UnitSlots[num];
+                       queue = &( *queue )->Next;
                    }
                }
            }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("reserve")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "reserve" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                char *type;
                int num;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               type=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               num=gh_scm2int(value);
-               ai->Reserve[DefaultResourceNumber(type)]=num;
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("used")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               type = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               num = gh_scm2int( value );
+               ai->Reserve[DefaultResourceNumber( type )] = num;
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "used" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                char *type;
                int num;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               type=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               num=gh_scm2int(value);
-               ai->Used[DefaultResourceNumber(type)]=num;
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("needed")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               type = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               num = gh_scm2int( value );
+               ai->Used[DefaultResourceNumber( type )] = num;
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "needed" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                char *type;
                int num;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               type=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               num=gh_scm2int(value);
-               ai->Needed[DefaultResourceNumber(type)]=num;
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("collect")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               type = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               num = gh_scm2int( value );
+               ai->Needed[DefaultResourceNumber( type )] = num;
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "collect" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                char *type;
                int num;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               type=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               num=gh_scm2int(value);
-               ai->Collect[DefaultResourceNumber(type)]=num;
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("need-mask")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               type = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               num = gh_scm2int( value );
+               ai->Collect[DefaultResourceNumber( type )] = num;
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "need-mask" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                char *type;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               type=get_c_string(value);
-               ai->NeededMask|=(1<<DefaultResourceNumber(type));
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("need-food")) ) {
-           ai->NeedFood=1;
-       } else if( gh_eq_p(value,gh_symbol2scm("unit-type")) ) {
-           sublist=gh_car(list);
-           i=0;
-           if( gh_length(sublist) ) {
-               
ai->UnitTypeRequests=malloc(gh_length(sublist)/2*sizeof(AiUnitTypeTable));
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               type = get_c_string( value );
+               ai->NeededMask |= ( 1 << DefaultResourceNumber( type ) );
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "need-food" ) ) ) {
+           ai->NeedFood = 1;
+       } else if ( gh_eq_p( value, gh_symbol2scm( "unit-type" ) ) ) {
+           sublist = gh_car( list );
+           i = 0;
+           if ( gh_length( sublist ) ) {
+               ai->UnitTypeRequests =
+                   malloc( gh_length( sublist ) / 2 * sizeof ( AiUnitTypeTable 
) );
            }
-           while( !gh_null_p(sublist) ) {
+           while ( !gh_null_p( sublist ) ) {
                char *ident;
                int count;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               ident=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               count=gh_scm2int(value);
-               ai->UnitTypeRequests[i].Table[0]=UnitTypeByIdent(ident);
-               ai->UnitTypeRequests[i].Count=count;
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               ident = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               count = gh_scm2int( value );
+               ai->UnitTypeRequests[i].Table[0] = UnitTypeByIdent( ident );
+               ai->UnitTypeRequests[i].Count = count;
                ++i;
            }
-           ai->UnitTypeRequestsCount=i;
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("upgrade")) ) {
-           sublist=gh_car(list);
-           i=0;
-           if( gh_length(sublist) ) {
-               
ai->UpgradeToRequests=malloc(gh_length(sublist)*sizeof(UnitType*));
+           ai->UnitTypeRequestsCount = i;
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "upgrade" ) ) ) {
+           sublist = gh_car( list );
+           i = 0;
+           if ( gh_length( sublist ) ) {
+               ai->UpgradeToRequests = malloc( gh_length( sublist ) * sizeof ( 
UnitType * ) );
            }
-           while( !gh_null_p(sublist) ) {
+           while ( !gh_null_p( sublist ) ) {
                char *ident;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               ident=get_c_string(value);
-               ai->UpgradeToRequests[i]=UnitTypeByIdent(ident);
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               ident = get_c_string( value );
+               ai->UpgradeToRequests[i] = UnitTypeByIdent( ident );
                ++i;
            }
-           ai->UpgradeToRequestsCount=i;
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("research")) ) {
-           sublist=gh_car(list);
-           i=0;
-           if( gh_length(sublist) ) {
-               
ai->ResearchRequests=malloc(gh_length(sublist)*sizeof(Upgrade*));
+           ai->UpgradeToRequestsCount = i;
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "research" ) ) ) {
+           sublist = gh_car( list );
+           i = 0;
+           if ( gh_length( sublist ) ) {
+               ai->ResearchRequests = malloc( gh_length( sublist ) * sizeof ( 
Upgrade * ) );
            }
-           while( !gh_null_p(sublist) ) {
+           while ( !gh_null_p( sublist ) ) {
                char *ident;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               ident=get_c_string(value);
-               ai->ResearchRequests[i]=UpgradeByIdent(ident);
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               ident = get_c_string( value );
+               ai->ResearchRequests[i] = UpgradeByIdent( ident );
                ++i;
            }
-           ai->ResearchRequestsCount=i;
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("building")) ) {
+           ai->ResearchRequestsCount = i;
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "building" ) ) ) {
            AiBuildQueue **queue;
-           sublist=gh_car(list);
-           queue=&ai->UnitTypeBuilded;
-           while( !gh_null_p(sublist) ) {
+           sublist = gh_car( list );
+           queue = &ai->UnitTypeBuilded;
+           while ( !gh_null_p( sublist ) ) {
                char *ident;
                int made;
                int want;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               ident=get_c_string(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               made=gh_scm2int(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               want=gh_scm2int(value);
-               *queue=malloc(sizeof(AiBuildQueue));
-               (*queue)->Next=NULL;
-               (*queue)->Type=UnitTypeByIdent(ident);
-               (*queue)->Want=want;
-               (*queue)->Made=made;
-               queue=&(*queue)->Next;
-           }
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("repair-building")) ) {
-           ai->LastRepairBuilding=gh_scm2int(gh_car(list));
-           list=gh_cdr(list);
-       } else if( gh_eq_p(value,gh_symbol2scm("repair-workers")) ) {
-           sublist=gh_car(list);
-           while( !gh_null_p(sublist) ) {
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               ident = get_c_string( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               made = gh_scm2int( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               want = gh_scm2int( value );
+               *queue = malloc( sizeof ( AiBuildQueue ) );
+               ( *queue )->Next = NULL;
+               ( *queue )->Type = UnitTypeByIdent( ident );
+               ( *queue )->Want = want;
+               ( *queue )->Made = made;
+               queue = &( *queue )->Next;
+           }
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "repair-building" ) ) ) {
+           ai->LastRepairBuilding = gh_scm2int( gh_car( list ) );
+           list = gh_cdr( list );
+       } else if ( gh_eq_p( value, gh_symbol2scm( "repair-workers" ) ) ) {
+           sublist = gh_car( list );
+           while ( !gh_null_p( sublist ) ) {
                int num;
                int workers;
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               num=gh_scm2int(value);
-               value=gh_car(sublist);
-               sublist=gh_cdr(sublist);
-               workers=gh_scm2int(value);
-               ai->TriedRepairWorkers[num]=workers;
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               num = gh_scm2int( value );
+               value = gh_car( sublist );
+               sublist = gh_cdr( sublist );
+               workers = gh_scm2int( value );
+               ai->TriedRepairWorkers[num] = workers;
                ++i;
            }
-           list=gh_cdr(list);
+           list = gh_cdr( list );
        } else {
           // FIXME: this leaves a half initialized ai player
-          errl("Unsupported tag",value);
+           errl( "Unsupported tag", value );
        }
     }
-
+#endif
     return SCM_UNSPECIFIED;
 }
 
 /**
 **     Register CCL features for unit-type.
 */
-global void AiCclRegister(void)
+global void AiCclRegister( void )
 {
-    // FIXME: Need to save memory here.
-    // Loading all into memory isn't necessary.
+   // FIXME: Need to save memory here.
+   // Loading all into memory isn't necessary.
+
+    gh_new_procedureN( "define-ai-helper", CclDefineAiHelper );
+    gh_new_procedureN( "define-ai", CclDefineAi );
+
+#ifdef INCOMPLETE_SIOD
+    gh_new_procedure2_0( "quotient", CclQuotient );
+    gh_new_procedure1_0( "output", CclOutput );
+#endif
+    gh_new_procedure2_0( "define-ai-action", CclDefineAiAction );
+
+    gh_new_procedure0_0( "ai:get-race", CclAiGetRace );
+    gh_new_procedure0_0( "ai:get-sleep-cycles", CclAiGetSleepCycles );
+
+    gh_new_procedure1_0( "ai:debug", CclAiDebug );
+    gh_new_procedure1_0( "ai:need", CclAiNeed );
+    gh_new_procedure2_0( "ai:set", CclAiSet );
+    gh_new_procedure1_0( "ai:wait", CclAiWait );
+
+    gh_new_procedure0_0( "ai:own-force", CclAiOwnForce );
+
+    gh_new_procedure1_0( "ai:get-force", CclAiGetForce );
+
+
+    gh_new_procedureN( "ai:force", CclAiForce );
+
+    gh_new_procedure2_0( "ai:adhoc-force", CclAiAdHocForce );
+
+    gh_new_procedure1_0( "ai:force-empty", CclAiForceEmpty );
+    gh_new_procedure1_0( "ai:force-active", CclAiForceActive );
+    gh_new_procedure1_0( "ai:force-list", CclAiForce );
+    gh_new_procedure2_0( "ai:force-transfer", CclAiForceTransfert );
+    gh_new_procedure1_0( "ai:force-complete", CclAiForceComplete );
+    gh_new_procedure2_0( "ai:force-role", CclAiForceRole );
+    gh_new_procedure1_0( "ai:is-force-defending", CclAiIsForceDefending );
+    gh_new_procedure1_0( "ai:check-force", CclAiCheckForce );
+    gh_new_procedure1_0( "ai:group-force", CclAiGroupForce );
+    gh_new_procedure1_0( "ai:wait-force", CclAiWaitForce );
+    gh_new_procedure1_0( "ai:clear-force", CclAiClearForce );
+    gh_new_procedure1_0( "ai:evaluate-force-cost", CclAiEvaluateForceCost );
+
+    gh_new_procedure1_0( "ai:can-reach-hotspot", CclAiCanReachHotSpot );
+
+    gh_new_procedure1_0( "ai:set-hotspot-ray", CclAiSetHotSpotRay );
+    gh_new_procedure0_0( "ai:compute-gauges", CclAiComputeGauges );
+    gh_new_procedure0_0( "ai:debug-gauges", CclAiDebugGauges );
+    gh_new_procedure1_0( "ai:get-gauge", CclAiGetGauge );
+    gh_new_procedure1_0( "ai:get-unittype-force", CclGetUnitTypeForce );
+
+    gh_new_procedure0_0( "ai:idle", CclAiIdle );
+    gh_new_procedure2_0( "ai:timed-wait-force", CclAiTimedWaitForce );
+    gh_new_procedure1_0( "ai:attack-with-force", CclAiAttackWithForce );
+    gh_new_procedure1_0( "ai:hotspot-attack-with-force", 
CclAiHotSpotAttackWithForce );
+    gh_new_procedure1_0( "ai:force-go-home", CclAiForceHome );
+    gh_new_procedure1_0( "ai:sleep", CclAiSleep );
+    gh_new_procedure1_0( "ai:research", CclAiResearch );
+    gh_new_procedure1_0( "ai:upgrade-to", CclAiUpgradeTo );
+    gh_new_procedure1_0( "ai:script", CclAiScript );
+    gh_new_procedure1_0( "ai:goto", CclAiSwitchTo );
 
-    gh_new_procedureN("define-ai-helper",CclDefineAiHelper);
-    gh_new_procedureN("define-ai",CclDefineAi);
+    gh_new_procedure0_0( "ai:restart", CclAiRestart );
 
-    gh_new_procedure0_0("ai:get-race",CclAiGetRace);
-    gh_new_procedure0_0("ai:get-sleep-cycles",CclAiGetSleepCycles);
-
-    gh_new_procedure1_0("ai:debug",CclAiDebug);
-    gh_new_procedure1_0("ai:need",CclAiNeed);
-    gh_new_procedure2_0("ai:set",CclAiSet);
-    gh_new_procedure1_0("ai:wait",CclAiWait);
-    gh_new_procedureN("ai:force",CclAiForce);
-    gh_new_procedure2_0("ai:force-role",CclAiForceRole);
-    gh_new_procedure1_0("ai:check-force",CclAiCheckForce);
-    gh_new_procedure1_0("ai:wait-force",CclAiWaitForce);
-    gh_new_procedure1_0("ai:attack-with-force",CclAiAttackWithForce);
-    gh_new_procedure1_0("ai:sleep",CclAiSleep);
-    gh_new_procedure1_0("ai:research",CclAiResearch);
-    gh_new_procedure1_0("ai:upgrade-to",CclAiUpgradeTo);
-    gh_new_procedure1_0("ai:script",CclAiScript);
-    gh_new_procedure0_0("ai:restart",CclAiRestart);
-
-    gh_new_procedure0_0("ai:player",CclAiPlayer);
-    gh_new_procedure1_0("ai:set-reserve!",CclAiSetReserve);
-    gh_new_procedure1_0("ai:set-collect!",CclAiSetCollect);
+    gh_new_procedure0_0( "ai:player", CclAiPlayer );
+    gh_new_procedure1_0( "ai:set-reserve!", CclAiSetReserve );
+    gh_new_procedure1_0( "ai:set-collect!", CclAiSetCollect );
+    gh_new_procedure1_0( "ai:set-auto-attack", CclAiSetAutoAttack );
 
-    gh_new_procedure0_0("ai:dump",CclAiDump);
+    gh_new_procedure0_0( "ai:dump", CclAiDump );
 
-    gh_new_procedureN("define-ai-wc-names",CclDefineAiWcNames);
+    gh_new_procedureN( "define-ai-wc-names", CclDefineAiWcNames );
 
-    gh_new_procedureN("define-ai-player",CclDefineAiPlayer);
+    gh_new_procedureN( "define-ai-player", CclDefineAiPlayer );
 }
 
 //@}
Index: stratagus/src/ai/new_ai.c
diff -u stratagus/src/ai/new_ai.c:1.74 stratagus/src/ai/new_ai.c:1.75
--- stratagus/src/ai/new_ai.c:1.74      Wed Oct  8 04:47:42 2003
+++ stratagus/src/ai/new_ai.c   Thu Oct 23 14:38:34 2003
@@ -5,12 +5,12 @@
 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
 //             \/                  \/          \//_____/            \/ 
 //  ______________________                           ______________________
-//                       T H E   W A R   B E G I N S
-//        Stratagus - A free fantasy real time strategy game engine
+//                        T H E   W A R   B E G I N S
+//         Stratagus - A free fantasy real time strategy game engine
 //
 /address@hidden new_ai.c       -       The new computer player AI main file. */
 //
-//      (c) Copyright 2000-2002 by Lutz Sammer
+//      (c) Copyright 2000-2003 by Lutz Sammer and Ludovic Pollet
 //
 //      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,15 +26,15 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//      $Id: new_ai.c,v 1.74 2003/10/08 08:47:42 martinxyz Exp $
+//      $Id: new_ai.c,v 1.75 2003/10/23 18:38:34 n0body Exp $
 
 
 //@{
 
-#define noTIMEIT                       /// Enable CPU use debugging
+#define noTIMEIT               /// Enable CPU use debugging
 
 //----------------------------------------------------------------------------
-//     Documentation
+//      Documentation
 //----------------------------------------------------------------------------
 
 /**
@@ -142,6 +142,8 @@
 
 #include "player.h"
 #include "unit.h"
+#include "ccl.h"
+#include "ccl_helpers.h"
 #if defined(DEBUG) && defined(TIMEIT)
 #include "rdtsc.h"
 #endif
@@ -152,42 +154,96 @@
 --     Variables
 ----------------------------------------------------------------------------*/
 
-global int AiSleepCycles;              /// Ai sleeps # cycles
-global int AiTimeFactor = 100;         /// Adjust the AI build times
-global int AiCostFactor = 100;         /// Adjust the AI costs
-
-global AiType* AiTypes;                        /// List of all AI types.
-global AiHelper AiHelpers;             /// AI helper variables
-
-global PlayerAi* AiPlayer;             /// Current AI player
+global int AiSleepCycles;      /// Ai sleeps # cycles
+global int AiTimeFactor = 100; /// Adjust the AI build times
+global int AiCostFactor = 100; /// Adjust the AI costs
+
+global AiType *AiTypes;                /// List of all AI types.
+global AiHelper AiHelpers;     /// AI helper variables
+global int AiScriptActionNum = 0;      /// number of action script ( FIXME : 
initialized only once )
+global AiScriptAction AiScriptActions[MaxAiScriptActions];     /// definitions 
of action scripts
 
+global PlayerAi *AiPlayer;     /// Current AI player
+global AiRunningScript *AiScript;      /// Current AI script
 /**
 **     W*rCr*ft number to internal ai-type name.
 */
-global char** AiTypeWcNames;
+global char **AiTypeWcNames;
 
 /*----------------------------------------------------------------------------
 --     Lowlevel functions
 ----------------------------------------------------------------------------*/
 
+local void debugForces()
+{
+    const AiUnit *aiunit;
+    const AiUnitType *aiunittype;
+    int force, i;
+    int count[UnitTypeMax];
+
+    DebugLevel3Fn( " ! : completed    A/D : attacking/defending\n" );
+    for ( force = 0; force < AI_MAX_FORCES; force++ ) {
+       DebugLevel3Fn( "force %5d %c%c :" _C_
+                      force _C_
+                      ( AiPlayer->Force[force].Role == AiForceRoleAttack ? 'A' 
: 'D' ) _C_
+                      ( AiPlayer->Force[force].Completed ? '!' : ' ' ) );
+
+       for ( i = 0; i < UnitTypeMax; i++ ) {
+           count[i] = 0;
+       }
+
+       aiunit = AiPlayer->Force[force].Units;
+
+       while ( aiunit ) {
+           count[aiunit->Unit->Type->Type]++;
+           aiunit = aiunit->Next;
+       }
+
+       aiunittype = AiPlayer->Force[force].UnitTypes;
+       while ( aiunittype ) {
+           DebugLevel3Fn( " %s(%d/%d)" _C_ aiunittype->Type->
+                          Ident _C_ count[aiunittype->Type->Type] _C_ 
aiunittype->Want );
+           count[aiunittype->Type->Type] = 0;
+           aiunittype = aiunittype->Next;
+       }
+
+       for ( i = 0; i < UnitTypeMax; i++ ) {
+           if ( count[i] ) {
+               DebugLevel3Fn( " %s(%d/0)" _C_ UnitTypes[i]->Ident _C_ count[i] 
);
+           }
+       }
+
+       DebugLevel3Fn( "\n" );
+    }
+}
+
 /**
 **     Execute the AI Script.
 */
-local void AiExecuteScript(void)
+local void AiExecuteScripts( void )
 {
-    PlayerAi* pai;
+    int i;
+    PlayerAi *pai;
     SCM value;
 
-    pai=AiPlayer;
-    if( !gh_null_p(pai->Script) ) {
-       if( pai->ScriptDebug ) {                // display executed command
-           printf("%d:",pai->Player->Player);
-           gh_display(gh_car(pai->Script));
-           gh_newline();
-       }
-       value=gh_eval(gh_car(pai->Script),NIL);
-       if( !gh_eq_p(value,SCM_BOOL_T) ) {
-           pai->Script=gh_cdr(pai->Script);
+    pai = AiPlayer;
+    debugForces();
+    for ( i = 0; i < AI_MAX_RUNNING_SCRIPTS; i++ ) {
+       AiScript = pai->Scripts + i;
+       if ( !gh_null_p( AiScript->Script ) ) {
+          /*
+             if( pai->ScriptDebug ) {         // display executed command
+             DebugLevel3Fn("%d.%d (%12s) @ %3d.%3d :" _C_ pai->Player->Player 
_C_ i _C_ AiScript->ident _C_ AiScript->HotSpot_X _C_ AiScript->HotSpot_Y);
+             gh_display(AiScript->Script);
+             gh_newline();
+             } */
+           value = gh_eval( gh_car( AiScript->Script ), NIL );
+           if ( !gh_eq_p( value, SCM_BOOL_T ) ) {
+               AiScript->Script = gh_cdr( AiScript->Script );
+           }
+           if ( ( gh_null_p( AiScript->Script ) ) && ( AiScript->ownForce ) ) {
+               AiEraseForce( AiScript->ownForce );
+           }
        }
     }
 }
@@ -195,12 +251,11 @@
 /**
 **     Check if everything is fine, send new requests to resource manager.
 */
-local void AiCheckUnits(void)
+local void AiCheckUnits( void )
 {
     int counter[UnitTypeMax];
-    int attacking[UnitTypeMax];
-    const AiBuildQueue* queue;
-    const int* unit_types_count;
+    const AiBuildQueue *queue;
+    const int *unit_types_count;
     int i;
     int j;
     int n;
@@ -208,133 +263,134 @@
     int x;
     int e;
 
-    memset(counter,0,sizeof(counter));
-    memset(attacking,0,sizeof(attacking));
-    //
-    // Count the already made build requests.
-    //
-    for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
-       counter[queue->Type->Type]+=queue->Want;
-       DebugLevel3Fn("Already in build queue: %s %d/%d\n" _C_
-               queue->Type->Ident _C_ queue->Made _C_ queue->Want);
-    }
-
-    //
-    // Remove non active units.
-    //
-    n=AiPlayer->Player->TotalNumUnits;
-    for( i=0; i<n; ++i ) {
-       if( !AiPlayer->Player->Units[i]->Active ) {
+    memset( counter, 0, sizeof ( counter ) );
+
+   //
+   //  Count the already made build requests.
+   //
+    for ( queue = AiPlayer->UnitTypeBuilded; queue; queue = queue->Next ) {
+       counter[queue->Type->Type] += queue->Want;
+       DebugLevel3Fn( "Already in build queue: %s %d/%d\n" _C_
+                      queue->Type->Ident _C_ queue->Made _C_ queue->Want );
+    }
+
+   //
+   //  Remove non active units.
+   //
+    n = AiPlayer->Player->TotalNumUnits;
+    for ( i = 0; i < n; ++i ) {
+       if ( !AiPlayer->Player->Units[i]->Active ) {
            counter[AiPlayer->Player->Units[i]->Type->Type]--;
-           DebugLevel3Fn("Removing non active unit: %s\n" _C_
-                   AiPlayer->Player->Units[i]->Type->Ident);
+           DebugLevel3Fn( "Removing non active unit: %s\n" _C_
+                          AiPlayer->Player->Units[i]->Type->Ident );
        }
     }
-    unit_types_count=AiPlayer->Player->UnitTypesCount;
-
-    //
-    // Look if some unit-types are missing.
-    //
-    n=AiPlayer->UnitTypeRequestsCount;
-    for( i=0; i<n; ++i ) {
-       t=AiPlayer->UnitTypeRequests[i].Table[0]->Type;
-       x=AiPlayer->UnitTypeRequests[i].Count;
+    unit_types_count = AiPlayer->Player->UnitTypesCount;
 
-       //
-       //      Add equivalent units
-       //
-       e=unit_types_count[t];
-       if( t<AiHelpers.EquivCount && AiHelpers.Equiv[t] ) {
-           DebugLevel3Fn("Equivalence for %s\n" _C_
-                   AiPlayer->UnitTypeRequests[i].Table[0]->Ident);
-           for( j=0; j<AiHelpers.Equiv[t]->Count; ++j ) {
-               e+=unit_types_count[AiHelpers.Equiv[t]->Table[j]->Type];
+   //
+   //  Look if some unit-types are missing.
+   //
+    n = AiPlayer->UnitTypeRequestsCount;
+    for ( i = 0; i < n; ++i ) {
+       t = AiPlayer->UnitTypeRequests[i].Table[0]->Type;
+       x = AiPlayer->UnitTypeRequests[i].Count;
+
+       //
+       //      Add equivalent units
+       //
+       e = unit_types_count[t];
+       if ( t < AiHelpers.EquivCount && AiHelpers.Equiv[t] ) {
+           DebugLevel3Fn( "Equivalence for %s\n" _C_
+                          AiPlayer->UnitTypeRequests[i].Table[0]->Ident );
+           for ( j = 0; j < AiHelpers.Equiv[t]->Count; ++j ) {
+               e += unit_types_count[AiHelpers.Equiv[t]->Table[j]->Type];
            }
        }
 
-       if( x>e+counter[t] ) {  // Request it.
-           DebugLevel3Fn("Need %s *%d\n" _C_
-                   AiPlayer->UnitTypeRequests[i].Table[0]->Ident _C_ x);
-           AiAddUnitTypeRequest(AiPlayer->UnitTypeRequests[i].Table[0],
-                   x-e-counter[t]);
-           counter[t]+=x-e-counter[t];
+       if ( x > e + counter[t] ) {     // Request it.
+           DebugLevel3Fn( "Need %s *%d\n" _C_
+                          AiPlayer->UnitTypeRequests[i].Table[0]->Ident _C_ x 
);
+           AiAddUnitTypeRequest( AiPlayer->UnitTypeRequests[i].Table[0], x - e 
- counter[t] );
+           counter[t] += x - e - counter[t];
        }
-       counter[t]-=x;
+       counter[t] -= x;
     }
 
-    //
-    // Look through the forces what is missing.
-    //
-    for( i=AI_MAX_FORCES; i<AI_MAX_ATTACKING_FORCES; ++i ) {
-       const AiUnit* unit;
+   //
+   // Magically complete all forces
+   //
+    for ( i = 0; i < AI_MAX_FORCES; ++i ) {
+       if ( ( !AiPlayer->Force[i].Completed ) &&
+            ( ( AiPlayer->Force[i].PopulateMode == AiForcePopulateFromAttack ) 
||
+              ( AiPlayer->Force[i].PopulateMode == AiForcePopulateAny ) ) ) {
 
-       for( unit=AiPlayer->Force[i].Units; unit; unit=unit->Next ) {
-           attacking[unit->Unit->Type->Type]++;
+          // This force should be completed from other forces.
+           AiForceComplete( i );
        }
     }
-    for( i=0; i<AI_MAX_FORCES; ++i ) {
-       const AiUnitType* aiut;
 
-       // No troops for attacking force
-       if( !AiPlayer->Force[i].Defending
-               && AiPlayer->Force[i].Attacking ) {
+   //
+   // create missing units
+   //
+    for ( i = 0; i < AI_MAX_FORCES; ++i ) {
+       const AiUnitType *aiut;
+
+       // Create units only for AiForceCreateFromScratch forces
+       if ( AiPlayer->Force[i].PopulateMode != AiForcePopulateFromScratch ) {
            continue;
        }
 
-       for( aiut=AiPlayer->Force[i].UnitTypes; aiut; aiut=aiut->Next ) {
-           t=aiut->Type->Type;
-           x=aiut->Want;
-           if( x>unit_types_count[t]+counter[t]-attacking[t] ) {       // 
Request it.
-               DebugLevel2Fn("Force %d need %s * %d\n" _C_ i _C_
-                       aiut->Type->Ident _C_ x);
-               AiAddUnitTypeRequest(aiut->Type,
-                       x-(unit_types_count[t]+counter[t]-attacking[t]));
-               counter[t]+=x-(unit_types_count[t]+counter[t]-attacking[t]);
-               AiPlayer->Force[i].Completed=0;
-           }
-           counter[t]-=x;
+       for ( aiut = AiPlayer->Force[i].UnitTypes; aiut; aiut = aiut->Next ) {
+           t = aiut->Type->Type;
+           x = aiut->Want;
+           if ( x > unit_types_count[t] + counter[t] ) {       // Request it.
+               DebugLevel2Fn( "Force %d need %s * %d\n" _C_ i _C_ 
aiut->Type->Ident _C_ x );
+               AiAddUnitTypeRequest( aiut->Type, x - unit_types_count[t] - 
counter[t] );
+               counter[t] += x - unit_types_count[t] - counter[t];
+               AiPlayer->Force[i].Completed = 0;
+           }
+           counter[t] -= x;
        }
     }
 
-    //
-    // Look if some upgrade-to are missing.
-    //
-    n=AiPlayer->UpgradeToRequestsCount;
-    for( i=0; i<n; ++i ) {
-       t=AiPlayer->UpgradeToRequests[i]->Type;
-       x=1;
-
-       //
-       //      Add equivalent units
-       //
-       e=unit_types_count[t];
-       if( t<AiHelpers.EquivCount && AiHelpers.Equiv[t] ) {
-           DebugLevel3Fn("Equivalence for %s\n" _C_
-                   AiPlayer->UpgradeToRequests[i]->Ident);
-           for( j=0; j<AiHelpers.Equiv[t]->Count; ++j ) {
-               e+=unit_types_count[AiHelpers.Equiv[t]->Table[j]->Type];
+   //
+   //  Look if some upgrade-to are missing.
+   //
+    n = AiPlayer->UpgradeToRequestsCount;
+    for ( i = 0; i < n; ++i ) {
+       t = AiPlayer->UpgradeToRequests[i]->Type;
+       x = 1;
+
+       //
+       //      Add equivalent units
+       //
+       e = unit_types_count[t];
+       if ( t < AiHelpers.EquivCount && AiHelpers.Equiv[t] ) {
+           DebugLevel3Fn( "Equivalence for %s\n" _C_ 
AiPlayer->UpgradeToRequests[i]->Ident );
+           for ( j = 0; j < AiHelpers.Equiv[t]->Count; ++j ) {
+               e += unit_types_count[AiHelpers.Equiv[t]->Table[j]->Type];
            }
        }
 
-       if( x>e+counter[t] ) {  // Request it.
-           AiAddUpgradeToRequest(AiPlayer->UpgradeToRequests[i]);
-           counter[t]+=x-e-counter[t];
-       }
-       counter[t]-=x;
-    }
-
-    //
-    // Look if some researches are missing.
-    //
-    n=AiPlayer->ResearchRequestsCount;
-    for( i=0; i<n; ++i ) {
-       DebugLevel3Fn("%s - %c\n" _C_
-               AiPlayer->ResearchRequests[i]->Ident _C_
-               UpgradeIdAllowed(AiPlayer->Player,
-                   AiPlayer->ResearchRequests[i]-Upgrades));
-       if( UpgradeIdAllowed(AiPlayer->Player,
-                   AiPlayer->ResearchRequests[i]-Upgrades)=='A' ) {
-           AiAddResearchRequest(AiPlayer->ResearchRequests[i]);
+       if ( x > e + counter[t] ) {     // Request it.
+           AiAddUpgradeToRequest( AiPlayer->UpgradeToRequests[i] );
+           counter[t] += x - e - counter[t];
+       }
+       counter[t] -= x;
+    }
+
+   //
+   //  Look if some researches are missing.
+   //
+    n = AiPlayer->ResearchRequestsCount;
+    for ( i = 0; i < n; ++i ) {
+       DebugLevel3Fn( "%s - %c\n" _C_
+                      AiPlayer->ResearchRequests[i]->Ident _C_
+                      UpgradeIdAllowed( AiPlayer->Player,
+                                        AiPlayer->ResearchRequests[i] - 
Upgrades ) );
+       if ( UpgradeIdAllowed( AiPlayer->Player,
+                              AiPlayer->ResearchRequests[i] - Upgrades ) == 
'A' ) {
+           AiAddResearchRequest( AiPlayer->ResearchRequests[i] );
        }
     }
 }
@@ -348,25 +404,25 @@
 **
 **     @param file     Output file.
 */
-local void SaveAiTypesWcName(CLFile *file)
+local void SaveAiTypesWcName( CLFile * file )
 {
-    char** cp;
+    char **cp;
     int i;
 
-    //
-    // Dump table wc2 race numbers -> internal symbol.
-    //
-    if( (cp=AiTypeWcNames) ) {
-       CLprintf(file,"(define-ai-wc-names");
-
-       i=90;
-       while( *cp ) {
-           if( i+strlen(*cp)>79 ) {
-               i=CLprintf(file,"\n ");
+   //
+   //  Dump table wc2 race numbers -> internal symbol.
+   //
+    if ( ( cp = AiTypeWcNames ) ) {
+       CLprintf( file, "(define-ai-wc-names" );
+
+       i = 90;
+       while ( *cp ) {
+           if ( i + strlen( *cp ) > 79 ) {
+               i = CLprintf( file, "\n " );
            }
-           i+=CLprintf(file," '%s",*cp++);
+           i += CLprintf( file, " '%s", *cp++ );
        }
-       CLprintf(file,")\n\n");
+       CLprintf( file, ")\n\n" );
     }
 }
 
@@ -379,42 +435,42 @@
 **     @param n        Number of elements in table
 **     @param table    unit-type table.
 */
-local void SaveAiHelperTable(CLFile* file,const char* name,int upgrade,int n,
-       AiUnitTypeTable*const * table)
+local void SaveAiHelperTable( CLFile * file, const char *name, int upgrade, 
int n,
+                             AiUnitTypeTable * const *table )
 {
     int t;
     int i;
     int j;
     int f;
 
-    for( t=0; t<(upgrade ? UpgradeMax : NumUnitTypes); ++t ) {
-       // Look if that unit-type can build something
-       for( f=i=0; i<n; ++i ) {
-           if( table[i] ) {
-               for( j=0; j<table[i]->Count; ++j ) {
-                   if( table[i]->Table[j]->Type==t ) {
-                       if( !f ) {
-                           CLprintf(file,"\n  (list '%s '%s\n    ",name,
-                                   UnitTypes[t]->Ident);
-                           f=4;
+    for ( t = 0; t < ( upgrade ? UpgradeMax : NumUnitTypes ); ++t ) {
+       // Look if that unit-type can build something
+       for ( f = i = 0; i < n; ++i ) {
+           if ( table[i] ) {
+               for ( j = 0; j < table[i]->Count; ++j ) {
+                   if ( table[i]->Table[j]->Type == t ) {
+                       if ( !f ) {
+                           CLprintf( file, "\n  (list '%s '%s\n    ", name,
+                                     UnitTypes[t]->Ident );
+                           f = 4;
                        }
-                       if( upgrade ) {
-                           if( f+strlen(Upgrades[i].Ident)>78 ) {
-                               f=CLprintf(file,"\n    ");
+                       if ( upgrade ) {
+                           if ( f + strlen( Upgrades[i].Ident ) > 78 ) {
+                               f = CLprintf( file, "\n    " );
                            }
-                           f+=CLprintf(file,"'%s ",Upgrades[i].Ident);
+                           f += CLprintf( file, "'%s ", Upgrades[i].Ident );
                        } else {
-                           if( f+strlen(UnitTypes[i]->Ident)>78 ) {
-                               f=CLprintf(file,"\n    ");
+                           if ( f + strlen( UnitTypes[i]->Ident ) > 78 ) {
+                               f = CLprintf( file, "\n    " );
                            }
-                           f+=CLprintf(file,"'%s ",UnitTypes[i]->Ident);
+                           f += CLprintf( file, "'%s ", UnitTypes[i]->Ident );
                        }
                    }
                }
            }
        }
-       if( f ) {
-           CLprintf(file,")");
+       if ( f ) {
+           CLprintf( file, ")" );
        }
     }
 }
@@ -427,25 +483,24 @@
 **     @param n        Number of elements in table
 **     @param table    unit-type table.
 */
-local void SaveAiEquivTable(CLFile* file,const char* name,int n,
-       AiUnitTypeTable*const * table)
+local void SaveAiEquivTable( CLFile * file, const char *name, int n,
+                            AiUnitTypeTable * const *table )
 {
     int i;
     int j;
     int f;
 
-    for( i=0; i<n; ++i ) {
-       if( table[i] ) {
-           CLprintf(file,"\n  (list '%s '%s\n    ",name,
-                   UnitTypes[i]->Ident);
-           f=4;
-           for( j=0; j<table[i]->Count; ++j ) {
-               if( f+strlen(table[i]->Table[j]->Ident)>78 ) {
-                   f=CLprintf(file,"\n    ");
+    for ( i = 0; i < n; ++i ) {
+       if ( table[i] ) {
+           CLprintf( file, "\n  (list '%s '%s\n    ", name, 
UnitTypes[i]->Ident );
+           f = 4;
+           for ( j = 0; j < table[i]->Count; ++j ) {
+               if ( f + strlen( table[i]->Table[j]->Ident ) > 78 ) {
+                   f = CLprintf( file, "\n    " );
                }
-               f+=CLprintf(file,"'%s ",table[i]->Table[j]->Ident);
+               f += CLprintf( file, "'%s ", table[i]->Table[j]->Ident );
            }
-           CLprintf(file,")");
+           CLprintf( file, ")" );
        }
     }
 }
@@ -458,35 +513,35 @@
 **     @param n        Number of elements in table
 **     @param table    unit-type table.
 */
-local void SaveAiCostTable(CLFile* file,const char* name,int n,
-       AiUnitTypeTable*const * table)
+local void SaveAiCostTable( CLFile * file, const char *name, int n,
+                           AiUnitTypeTable * const *table )
 {
     int t;
     int i;
     int j;
     int f;
 
-    for( t=0; t<NumUnitTypes; ++t ) {
-       // Look if that unit-type can build something
-       for( f=i=0; i<n; ++i ) {
-           if( table[i] ) {
-               for( j=0; j<table[i]->Count; ++j ) {
-                   if( table[i]->Table[j]->Type==t ) {
-                       if( !f ) {
-                           CLprintf(file,"\n  (list '%s '%s\n    ",name,
-                                   UnitTypes[t]->Ident);
-                           f=4;
+    for ( t = 0; t < NumUnitTypes; ++t ) {
+       // Look if that unit-type can build something
+       for ( f = i = 0; i < n; ++i ) {
+           if ( table[i] ) {
+               for ( j = 0; j < table[i]->Count; ++j ) {
+                   if ( table[i]->Table[j]->Type == t ) {
+                       if ( !f ) {
+                           CLprintf( file, "\n  (list '%s '%s\n    ", name,
+                                     UnitTypes[t]->Ident );
+                           f = 4;
                        }
-                       if( f+strlen(DefaultResourceNames[i])>78 ) {
-                           f=CLprintf(file,"\n    ");
+                       if ( f + strlen( DefaultResourceNames[i] ) > 78 ) {
+                           f = CLprintf( file, "\n    " );
                        }
-                       f+=CLprintf(file,"'%s ",DefaultResourceNames[i]);
+                       f += CLprintf( file, "'%s ", DefaultResourceNames[i] );
                    }
                }
            }
        }
-       if( f ) {
-           CLprintf(file,")");
+       if ( f ) {
+           CLprintf( file, ")" );
        }
     }
 }
@@ -499,87 +554,106 @@
 **     @param n        Number of elements in table
 **     @param table    unit-type table.
 */
-local void SaveAiUnitLimitTable(CLFile* file,const char* name,int n,
-       AiUnitTypeTable*const * table)
+local void SaveAiUnitLimitTable( CLFile * file, const char *name, int n,
+                                AiUnitTypeTable * const *table )
 {
     int t;
     int i;
     int j;
     int f;
 
-    for( t=0; t<NumUnitTypes; ++t ) {
-       // Look if that unit-type can build something
-       for( f=i=0; i<n; ++i ) {
-           if( table[i] ) {
-               for( j=0; j<table[i]->Count; ++j ) {
-                   if( table[i]->Table[j]->Type==t ) {
-                       if( !f ) {
-                           CLprintf(file,"\n  (list '%s '%s\n    ",name,
-                                   UnitTypes[t]->Ident);
-                           f=4;
+    for ( t = 0; t < NumUnitTypes; ++t ) {
+       // Look if that unit-type can build something
+       for ( f = i = 0; i < n; ++i ) {
+           if ( table[i] ) {
+               for ( j = 0; j < table[i]->Count; ++j ) {
+                   if ( table[i]->Table[j]->Type == t ) {
+                       if ( !f ) {
+                           CLprintf( file, "\n  (list '%s '%s\n    ", name,
+                                     UnitTypes[t]->Ident );
+                           f = 4;
                        }
-                       if( f+strlen("food")>78 ) {
-                           f=CLprintf(file,"\n    ");
+                       if ( f + strlen( "food" ) > 78 ) {
+                           f = CLprintf( file, "\n    " );
                        }
-                       f+=CLprintf(file,"'%s ","food");
+                       f += CLprintf( file, "'%s ", "food" );
                    }
                }
            }
        }
-       if( f ) {
-           CLprintf(file,")");
+       if ( f ) {
+           CLprintf( file, ")" );
        }
     }
 }
+
 /**
 **     Save AI helper table.
 **
 **     @param file     Output file.
 */
-local void SaveAiHelper(CLFile* file)
+local void SaveAiHelper( CLFile * file )
 {
-    CLprintf(file,"(define-ai-helper");
-    //
-    // Save build table
-    //
-    SaveAiHelperTable(file,"build",0,AiHelpers.BuildCount,AiHelpers.Build);
-
-    //
-    // Save train table
-    //
-    SaveAiHelperTable(file,"train",0,AiHelpers.TrainCount,AiHelpers.Train);
-
-    //
-    // Save upgrade table
-    //
-    SaveAiHelperTable(file,"upgrade",0,AiHelpers.UpgradeCount,
-           AiHelpers.Upgrade);
-
-    //
-    // Save research table
-    //
-    SaveAiHelperTable(file,"research",1,AiHelpers.ResearchCount,
-           AiHelpers.Research);
-
-    //
-    // Save repair table
-    //
-    SaveAiHelperTable(file,"repair",0,AiHelpers.RepairCount,
-           AiHelpers.Repair);
-
-    //
-    // Save limits table
-    //
-    SaveAiUnitLimitTable(file,"unit-limit",AiHelpers.UnitLimitCount,
-           AiHelpers.UnitLimit);
-
-    //
-    // Save equivalence table
-    //
-    SaveAiEquivTable(file,"unit-equiv",AiHelpers.EquivCount,
-           AiHelpers.Equiv);
+    CLprintf( file, "(define-ai-helper" );
+   //
+   //  Save build table
+   //
+    SaveAiHelperTable( file, "build", 0, AiHelpers.BuildCount, AiHelpers.Build 
);
+
+   //
+   //  Save train table
+   //
+    SaveAiHelperTable( file, "train", 0, AiHelpers.TrainCount, AiHelpers.Train 
);
 
-    CLprintf(file," )\n\n");
+   //
+   //  Save upgrade table
+   //
+    SaveAiHelperTable( file, "upgrade", 0, AiHelpers.UpgradeCount, 
AiHelpers.Upgrade );
+
+   //
+   //  Save research table
+   //
+    SaveAiHelperTable( file, "research", 1, AiHelpers.ResearchCount, 
AiHelpers.Research );
+
+   //
+   //  Save repair table
+   //
+    SaveAiHelperTable( file, "repair", 0, AiHelpers.RepairCount, 
AiHelpers.Repair );
+
+   //
+   //  Save limits table
+   //
+    SaveAiUnitLimitTable( file, "unit-limit", AiHelpers.UnitLimitCount, 
AiHelpers.UnitLimit );
+
+   //
+   //  Save equivalence table
+   //
+    SaveAiEquivTable( file, "unit-equiv", AiHelpers.EquivCount, 
AiHelpers.Equiv );
+
+    CLprintf( file, " )\n\n" );
+}
+
+/**
+**     Save all the AiScriptAction defined
+**
+**     @param file     Output file
+*/
+local void SaveAiScriptActions( CLFile * file )
+{
+    AiScriptAction *aiScriptAction;
+    int i;
+
+   // FIXME : should import the built-in lambda as well ( really needed ? )
+    for ( i = 0; i < AiScriptActionNum; i++ ) {
+       aiScriptAction = AiScriptActions + i;
+
+       CLprintf( file, "(define-ai-action '(%s%s)\n  '",
+                 ( aiScriptAction->Defensive ? " defense " : "" ),
+                 ( aiScriptAction->Offensive ? " attack " : "" ) );
+
+       lprin1CL( aiScriptAction->Action, file );
+       CLprintf( file, "\n)\n" );
+    }
 }
 
 /**
@@ -588,26 +662,26 @@
 **     @param file     Output file.
 **     @param aitype   AI type to save.
 */
-local void SaveAiType(CLFile* file,const AiType* aitype)
+local void SaveAiType( CLFile * file, const AiType * aitype )
 {
     SCM list;
 
-    if( aitype->Next ) {
-       SaveAiType(file,aitype->Next);
+    if ( aitype->Next ) {
+       SaveAiType( file, aitype->Next );
     }
-    DebugLevel3Fn("%s,%s,%s\n" _C_ aitype->Name _C_ aitype->Race _C_ 
aitype->Class);
-    CLprintf(file,"(define-ai \"%s\" '%s '%s\n",
-           aitype->Name,aitype->Race ? aitype->Race : "*",aitype->Class);
-
-    CLprintf(file,"  '(");
-    // Print the script a little formated
-    list=aitype->Script;
-    while( !gh_null_p(list) ) {
-       CLprintf(file,"\n    ");
-       lprin1CL(gh_car(list),file);
-       list=gh_cdr(list);
+    DebugLevel3Fn( "%s,%s,%s\n" _C_ aitype->Name _C_ aitype->Race _C_ 
aitype->Class );
+    CLprintf( file, "(define-ai \"%s\" '%s '%s\n",
+             aitype->Name, aitype->Race ? aitype->Race : "*", aitype->Class );
+
+    CLprintf( file, "  '(" );
+   //  Print the script a little formated
+    list = aitype->Script;
+    while ( !gh_null_p( list ) ) {
+       CLprintf( file, "\n    " );
+       //lprin1CL(gh_car(list),file);
+       list = gh_cdr( list );
     }
-    CLprintf(file," ))\n\n");
+    CLprintf( file, " ))\n\n" );
 }
 
 /**
@@ -615,12 +689,12 @@
 **
 **     @param file     Output file.
 */
-local void SaveAiTypes(CLFile*file)
+local void SaveAiTypes( CLFile * file )
 {
-    SaveAiType(file,AiTypes);
+    SaveAiType( file, AiTypes );
 
-    // FIXME: Must save references to other scripts - scheme functions
-    // Perhaps we should dump the complete scheme state
+   // FIXME: Must save references to other scripts - scheme functions
+   // Perhaps we should dump the complete scheme state
 }
 
 /**
@@ -630,153 +704,15 @@
 **     @param plynr    Player number.
 **     @param ai       Player AI.
 */
-local void SaveAiPlayer(CLFile* file,unsigned plynr,const PlayerAi* ai)
+local void SaveAiPlayer( CLFile * file, unsigned plynr, const PlayerAi * ai )
 {
-    SCM script;
-    int i;
-    const AiBuildQueue* queue;
-
-    CLprintf(file,"(define-ai-player %u\n",plynr);
-    CLprintf(file,"  'ai-type '%s\n",ai->AiType->Name);
-    //
-    // Find the script.
-    //
-    if( !gh_null_p(ai->Script) ) {
-       i=0;
-       script=ai->AiType->Script;
-       do {
-           if( ai->Script==script ) {
-               CLprintf(file,"  'script '(aitypes %d)\n",i);
-               break;
-           }
-           script=gh_cdr(script);
-           ++i;
-       } while( !gh_null_p(script) );
-
-       if( gh_null_p(script) ) {       // Not found in ai-types.
-           DebugLevel0Fn("FIXME: not written\n");
-           CLprintf(file,"  'script '(FIXME: %d)\n",i);
-       }
-
-    }
-    CLprintf(file,"  'script-debug #%s\n",ai->ScriptDebug ? "t" : "f");
-    CLprintf(file,"  'sleep-cycles %lu\n",ai->SleepCycles);
-
-    //
-    // All forces
-    //
-    for( i=0; i<AI_MAX_ATTACKING_FORCES; ++i ) {
-       const AiUnitType* aut;
-       const AiUnit* aiunit;
-
-       CLprintf(file,"  'force '(%d %s%s%s",i,
-               ai->Force[i].Completed ? "complete" : "recruit",
-               ai->Force[i].Attacking ? " attack" : "",
-               ai->Force[i].Defending ? " defend" : "");
-
-       CLprintf(file," role ");
-       switch( ai->Force[i].Role ) {
-           case AiForceRoleAttack:
-               CLprintf(file,"attack");
-               break;
-           case AiForceRoleDefend:
-               CLprintf(file,"defend");
-               break;
-           default:
-               CLprintf(file,"unknown");
-               break;
-       }
-
-       CLprintf(file,"\n    types ( ");
-       for( aut=ai->Force[i].UnitTypes; aut; aut=aut->Next ) {
-           CLprintf(file,"%d %s ",aut->Want,aut->Type->Ident);
-       }
-       CLprintf(file,")\n    units (");
-       for( aiunit=ai->Force[i].Units; aiunit; aiunit=aiunit->Next ) {
-           CLprintf(file," %d %s",UnitNumber(aiunit->Unit),
-                   aiunit->Unit->Type->Ident);
-       }
-       CLprintf(file," ))\n");
-    }
-
-    CLprintf(file,"  'reserve '(");
-    for( i=0; i<MaxCosts; ++i ) {
-       CLprintf(file,"%s %d ",DefaultResourceNames[i],ai->Reserve[i]);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'used '(");
-    for( i=0; i<MaxCosts; ++i ) {
-       CLprintf(file,"%s %d ",DefaultResourceNames[i],ai->Used[i]);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'needed '(");
-    for( i=0; i<MaxCosts; ++i ) {
-       CLprintf(file,"%s %d ",DefaultResourceNames[i],ai->Needed[i]);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'collect '(");
-    for( i=0; i<MaxCosts; ++i ) {
-       CLprintf(file,"%s %d ",DefaultResourceNames[i],ai->Collect[i]);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'need-mask '(");
-    for( i=0; i<MaxCosts; ++i ) {
-       if( ai->NeededMask&(1<<i) ) {
-           CLprintf(file,"%s ",DefaultResourceNames[i]);
-       }
-    }
-    CLprintf(file,")\n");
-
-    if( ai->NeedFood ) {
-       CLprintf(file,"  'need-food\n");
-    }
-
-    //
-    // Requests
-    //
-    CLprintf(file,"  'unit-type '(");
-    for( i=0; i<ai->UnitTypeRequestsCount; ++i ) {
-       CLprintf(file,"%s ",ai->UnitTypeRequests[i].Table[0]->Ident);
-       CLprintf(file,"%d ",ai->UnitTypeRequests[i].Count);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'upgrade '(");
-    for( i=0; i<ai->UpgradeToRequestsCount; ++i ) {
-       CLprintf(file,"%s ",ai->UpgradeToRequests[i]->Ident);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'research '(");
-    for( i=0; i<ai->ResearchRequestsCount; ++i ) {
-       CLprintf(file,"%s ",ai->ResearchRequests[i]->Ident);
-    }
-    CLprintf(file,")\n");
-
-    //
-    // Building queue
-    //
-    CLprintf(file,"  'building '(");
-    for( queue=ai->UnitTypeBuilded; queue; queue=queue->Next ) {
-       CLprintf(file,"%s %d %d ",queue->Type->Ident,queue->Made,queue->Want);
-    }
-    CLprintf(file,")\n");
-
-    CLprintf(file,"  'repair-building %u\n",ai->LastRepairBuilding);
-
-    CLprintf(file,"  'repair-workers '(");
-    for( i=0; i<UnitMax; ++i ) {
-       if( ai->TriedRepairWorkers[i] ) {
-           CLprintf(file,"%d %d ",i,ai->TriedRepairWorkers[i]);
-       }
-    }
-    CLprintf(file,")");
-
-    CLprintf(file,")\n\n");
+    IOOutFile = file;
+    IOLoadingMode = 0;
+    IOTabLevel = 1;
+
+    CLprintf( IOOutFile, "(define-ai-player '" );
+    IOPlayerAiFullPtr( SCM_UNSPECIFIED, &ai, 0 );
+    CLprintf( IOOutFile, ")\n" );
 }
 
 /**
@@ -784,13 +720,13 @@
 **
 **     @param file     Output file.
 */
-local void SaveAiPlayers(CLFile*file)
+local void SaveAiPlayers( CLFile * file )
 {
     unsigned p;
 
-    for( p=0; p<PlayerMax; ++p ) {
-       if( Players[p].Ai ) {
-           SaveAiPlayer(file,p,Players[p].Ai);
+    for ( p = 0; p < PlayerMax; ++p ) {
+       if ( Players[p].Ai ) {
+           SaveAiPlayer( file, p, Players[p].Ai );
        }
     }
 }
@@ -800,17 +736,19 @@
 **
 **     @param file     Output file.
 */
-global void SaveAi(CLFile* file)
+global void SaveAi( CLFile * file )
 {
-    CLprintf(file,"\n;;; -----------------------------------------\n");
-    CLprintf(file,";;; MODULE: AI $Id: new_ai.c,v 1.74 2003/10/08 08:47:42 
martinxyz Exp $\n\n");
-
-    SaveAiTypesWcName(file);
-    SaveAiHelper(file);
-    SaveAiTypes(file);
-    SaveAiPlayers(file);
+    CLprintf( file, "\n;;; -----------------------------------------\n" );
+    CLprintf( file,
+             ";;; MODULE: AI $Id: new_ai.c,v 1.75 2003/10/23 18:38:34 n0body 
Exp $\n\n" );
+
+    SaveAiTypesWcName( file );
+    SaveAiHelper( file );
+    SaveAiTypes( file );
+    SaveAiScriptActions( file );
+    SaveAiPlayers( file );
 
-    DebugLevel0Fn("FIXME: Saving AI isn't supported\n");
+    DebugLevel0Fn( "FIXME: Saving AI isn't supported\n" );
 }
 
 /**
@@ -818,201 +756,234 @@
 **
 **      @param player   The player structure pointer.
 */
-global void AiInit(Player* player)
+global void AiInit( Player * player )
 {
-    PlayerAi* pai;
-    AiType* ait;
-    char* ainame;
-
-    DebugLevel0Fn("%d - %s -" _C_ player->Player _C_ player->Name);
-
-    pai=calloc(1,sizeof(PlayerAi));
-    if( !pai ) {
-       fprintf(stderr,"Out of memory.\n");
-       exit(0);
-    }
-    pai->Player=player;
-    ait=AiTypes;
-
-    ainame=AiTypeWcNames[player->AiNum];
-    DebugLevel0(" looking for class %s\n" _C_ ainame);
-
-    //
-    // Search correct AI type.
-    //
-    if( !ait ) {
-       DebugLevel0Fn("AI: Got no scripts at all! You need at least one dummy 
fallback script.\n");
-       DebugLevel0Fn("AI: Look at the (define-ai) documentation.\n");
-       exit(0);
-    }
-    for( ;; ) {
-       if( ait->Race && strcmp(ait->Race,player->RaceName) ) {
-           ait=ait->Next;
-           if( !ait && ainame ) {
-               ainame=NULL;
-               ait=AiTypes;
+    int i;
+    PlayerAi *pai;
+    AiType *ait;
+    char *ainame;
+
+    DebugLevel0Fn( "%d - %s -" _C_ player->Player _C_ player->Name );
+
+    pai = calloc( 1, sizeof ( PlayerAi ) );
+    if ( !pai ) {
+       fprintf( stderr, "Out of memory.\n" );
+       exit( 0 );
+    }
+    pai->Player = player;
+    ait = AiTypes;
+
+    for ( i = 0; i < AI_MAX_RUNNING_SCRIPTS; i++ ) {
+       pai->Scripts[i].ownForce = AI_GENERIC_FORCES + i;
+       pai->Scripts[i].HotSpot_X = -1;
+       pai->Scripts[i].HotSpot_Y = -1;
+       pai->Scripts[i].HotSpot_Ray = -1;
+       pai->Scripts[i].gauges = 0;
+       pai->Scripts[i].SleepCycles = 0;
+       pai->Scripts[i].Script = NIL;
+       snprintf( pai->Scripts[i].ident, 10, "Empty" );
+    }
+
+   // Set autoattack to 1 as default
+    pai->AutoAttack = 1;
+
+    for ( i = 0; i < AI_GENERIC_FORCES; i++ ) {
+       // First force defend, others are attacking...
+       pai->Force[i].Role = ( i ? AiForceRoleAttack : AiForceRoleDefend );
+
+       // Theses forces should be built from scratch
+       pai->Force[i].PopulateMode = AiForcePopulateFromScratch;
+       pai->Force[i].UnitsReusable = 1;
+       pai->Force[i].HelpMode = AiForceHelpFull;
+    }
+
+
+    ainame = AiTypeWcNames[player->AiNum];
+    DebugLevel0( " looking for class %s\n" _C_ ainame );
+
+   //
+   //  Search correct AI type.
+   //
+    if ( !ait ) {
+       DebugLevel0Fn
+           ( "AI: Got no scripts at all! You need at least one dummy fallback 
script.\n" );
+       DebugLevel0Fn( "AI: Look at the (define-ai) documentation.\n" );
+       exit( 0 );
+    }
+    for ( ;; ) {
+       if ( ait->Race && strcmp( ait->Race, player->RaceName ) ) {
+           ait = ait->Next;
+           if ( !ait && ainame ) {
+               ainame = NULL;
+               ait = AiTypes;
+           }
+           if ( !ait ) {
+               break;
            }
-           if( !ait ) break;
            continue;
        }
-       if( ainame && strcmp(ainame,ait->Class) ) {
-           ait=ait->Next;
-           if( !ait && ainame ) {
-               ainame=NULL;
-               ait=AiTypes;
+       if ( ainame && strcmp( ainame, ait->Class ) ) {
+           ait = ait->Next;
+           if ( !ait && ainame ) {
+               ainame = NULL;
+               ait = AiTypes;
+           }
+           if ( !ait ) {
+               break;
            }
-           if( !ait ) break;
            continue;
        }
        break;
     }
-    if( !ait ) {
-       DebugLevel0Fn("AI: Found no matching ai scripts at all!\n");
-       exit(0);
-    }
-    if( !ainame ) {
-       DebugLevel0Fn("AI: not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
-       DebugLevel0Fn("AI: Using fallback:\n");
-    }
-    DebugLevel0Fn("AI: %s:%s with %s:%s\n" _C_ player->RaceName _C_ ait->Race
-           _C_ ainame _C_ ait->Class );
-
-    pai->AiType=ait;
-    pai->Script=ait->Script;
-
-    pai->Collect[TimeCost]=0;
-    pai->Collect[GoldCost]=50;
-    pai->Collect[WoodCost]=50;
-    pai->Collect[OilCost]=0;
-    pai->Collect[OreCost]=0;
-    pai->Collect[StoneCost]=0;
-    pai->Collect[CoalCost]=0;
+    if ( !ait ) {
+       DebugLevel0Fn( "AI: Found no matching ai scripts at all!\n" );
+       exit( 0 );
+    }
+    if ( !ainame ) {
+       DebugLevel0Fn( "AI: not found!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" 
);
+       DebugLevel0Fn( "AI: Using fallback:\n" );
+    }
+    DebugLevel0Fn( "AI: %s:%s with %s:%s\n" _C_ player->RaceName _C_ ait->Race
+                  _C_ ainame _C_ ait->Class );
+
+    pai->AiType = ait;
+    pai->Scripts[0].Script = ait->Script;
+
+    pai->Collect[TimeCost] = 0;
+    pai->Collect[GoldCost] = 50;
+    pai->Collect[WoodCost] = 50;
+    pai->Collect[OilCost] = 0;
+    pai->Collect[OreCost] = 0;
+    pai->Collect[StoneCost] = 0;
+    pai->Collect[CoalCost] = 0;
 
-    player->Ai=pai;
+    player->Ai = pai;
 }
 
 /**
 **     Cleanup the AI.
 */
-global void CleanAi(void)
+global void CleanAi( void )
 {
     int i;
     int p;
-    PlayerAi* pai;
-    void* temp;
-    AiType* aitype;
-    AiBuildQueue* queue;
-    char** cp;
-
-    for( p=0; p<PlayerMax; ++p ) {
-       if( (pai=Players[p].Ai) ) {
-           //
-           //  Free forces
-           //
-           for( i=0; i<AI_MAX_ATTACKING_FORCES; ++i ) {
-               AiUnitType* aut;
-               AiUnit* aiunit;
-
-               for( aut=pai->Force[i].UnitTypes; aut; aut=temp ) {
-                   temp=aut->Next;
-                   free(aut);
+    PlayerAi *pai;
+    void *temp;
+    AiType *aitype;
+    AiBuildQueue *queue;
+    char **cp;
+
+    for ( p = 0; p < PlayerMax; ++p ) {
+       if ( ( pai = Players[p].Ai ) ) {
+          //
+          //  Free forces
+          //
+           for ( i = 0; i < AI_MAX_FORCES; ++i ) {
+               AiUnitType *aut;
+               AiUnit *aiunit;
+
+               for ( aut = pai->Force[i].UnitTypes; aut; aut = temp ) {
+                   temp = aut->Next;
+                   free( aut );
                }
-               for( aiunit=pai->Force[i].Units; aiunit; aiunit=temp ) {
-                   temp=aiunit->Next;
-                   free(aiunit);
+               for ( aiunit = pai->Force[i].Units; aiunit; aiunit = temp ) {
+                   temp = aiunit->Next;
+                   free( aiunit );
                }
            }
-           //
-           //  Free UnitTypeRequests
-           //
-           free(pai->UnitTypeRequests);
-           //
-           //  Free UpgradeToRequests
-           //
-           free(pai->UpgradeToRequests);
-           //
-           //  Free ResearchRequests
-           //
-           free(pai->ResearchRequests);
-           //
-           //  Free UnitTypeBuilded
-           //
-           for( queue=pai->UnitTypeBuilded; queue; queue=temp ) {
-               temp=queue->Next;
-               free(queue);
+          //
+          //  Free UnitTypeRequests
+          //
+           free( pai->UnitTypeRequests );
+          //
+          //  Free UpgradeToRequests
+          //
+           free( pai->UpgradeToRequests );
+          //
+          //  Free ResearchRequests
+          //
+           free( pai->ResearchRequests );
+          //
+          //  Free UnitTypeBuilded
+          //
+           for ( queue = pai->UnitTypeBuilded; queue; queue = temp ) {
+               temp = queue->Next;
+               free( queue );
            }
 
-           free(pai);
-           Players[p].Ai=NULL;
+           free( pai );
+           Players[p].Ai = NULL;
        }
     }
 
-    //
-    // Free AiTypes.
-    //
-    for( aitype=AiTypes; aitype; aitype=temp ) {
-       DebugLevel3Fn("%s,%s,%s\n" _C_ aitype->Name _C_ aitype->Race _C_ 
aitype->Class);
-       free(aitype->Name);
-       free(aitype->Race);
-       free(aitype->Class);
+   //
+   //  Free AiTypes.
+   //
+    for ( aitype = AiTypes; aitype; aitype = temp ) {
+       DebugLevel3Fn( "%s,%s,%s\n" _C_ aitype->Name _C_ aitype->Race _C_ 
aitype->Class );
+       free( aitype->Name );
+       free( aitype->Race );
+       free( aitype->Class );
 
-       // ai-type->Script freed by ccl
+       // ai-type->Script freed by ccl
 
-       temp=aitype->Next;
-       free(aitype);
+       temp = aitype->Next;
+       free( aitype );
     }
-    AiTypes=NULL;
+    AiTypes = NULL;
 
-    //
-    // Free AiHelpers.
-    //
-    for( i=0; i<AiHelpers.TrainCount; ++i ) {
-       free(AiHelpers.Train[i]);
+   //
+   //  Free AiHelpers.
+   //
+    for ( i = 0; i < AiHelpers.TrainCount; ++i ) {
+       free( AiHelpers.Train[i] );
     }
-    free(AiHelpers.Train);
+    free( AiHelpers.Train );
 
-    for( i=0; i<AiHelpers.BuildCount; ++i ) {
-       free(AiHelpers.Build[i]);
+    for ( i = 0; i < AiHelpers.BuildCount; ++i ) {
+       free( AiHelpers.Build[i] );
     }
-    free(AiHelpers.Build);
+    free( AiHelpers.Build );
 
-    for( i=0; i<AiHelpers.UpgradeCount; ++i ) {
-       free(AiHelpers.Upgrade[i]);
+    for ( i = 0; i < AiHelpers.UpgradeCount; ++i ) {
+       free( AiHelpers.Upgrade[i] );
     }
-    free(AiHelpers.Upgrade);
+    free( AiHelpers.Upgrade );
 
-    for( i=0; i<AiHelpers.ResearchCount; ++i ) {
-       free(AiHelpers.Research[i]);
+    for ( i = 0; i < AiHelpers.ResearchCount; ++i ) {
+       free( AiHelpers.Research[i] );
     }
-    free(AiHelpers.Research);
+    free( AiHelpers.Research );
 
-    for( i=0; i<AiHelpers.RepairCount; ++i ) {
-       free(AiHelpers.Repair[i]);
+    for ( i = 0; i < AiHelpers.RepairCount; ++i ) {
+       free( AiHelpers.Repair[i] );
     }
-    free(AiHelpers.Repair);
+    free( AiHelpers.Repair );
 
-    for( i=0; i<AiHelpers.UnitLimitCount; ++i ) {
-       free(AiHelpers.UnitLimit[i]);
+    for ( i = 0; i < AiHelpers.UnitLimitCount; ++i ) {
+       free( AiHelpers.UnitLimit[i] );
     }
-    free(AiHelpers.UnitLimit);
+    free( AiHelpers.UnitLimit );
 
-    for( i=0; i<AiHelpers.EquivCount; ++i ) {
-       free(AiHelpers.Equiv[i]);
+    for ( i = 0; i < AiHelpers.EquivCount; ++i ) {
+       free( AiHelpers.Equiv[i] );
     }
-    free(AiHelpers.Equiv);
+    free( AiHelpers.Equiv );
 
-    memset(&AiHelpers,0,sizeof(AiHelpers));
+    memset( &AiHelpers, 0, sizeof ( AiHelpers ) );
 
-    //
-    // Mapping original AI numbers in puds to our internal strings
-    //
-    if( (cp=AiTypeWcNames) ) {                 // Free all old names
-       while( *cp ) {
-           free(*cp++);
+   //
+   //  Mapping original AI numbers in puds to our internal strings
+   //
+    if ( ( cp = AiTypeWcNames ) ) {    // Free all old names
+       while ( *cp ) {
+           free( *cp++ );
        }
-       free(AiTypeWcNames);
-       AiTypeWcNames=NULL;
+       free( AiTypeWcNames );
+       AiTypeWcNames = NULL;
     }
+   // TODO : AiScriptActions are not freed
+    AiScriptActionNum = 0;
 }
 
 /*----------------------------------------------------------------------------
@@ -1026,21 +997,21 @@
 **     @param type     Unit-type which is now available.
 **     @return         True, if unit-type was found in list.
 */
-local int AiRemoveFromBuilded2(PlayerAi* pai,const UnitType* type)
+local int AiRemoveFromBuilded2( PlayerAi * pai, const UnitType * type )
 {
-    AiBuildQueue** queue;
-    AiBuildQueue* next;
+    AiBuildQueue **queue;
+    AiBuildQueue *next;
 
-    //
-    // Search the unit-type order.
-    //
-    for( queue=&pai->UnitTypeBuilded; (next=*queue); queue=&next->Next ) {
+   //
+   //  Search the unit-type order.
+   //
+    for ( queue = &pai->UnitTypeBuilded; ( next = *queue ); queue = 
&next->Next ) {
        DebugCheck( !next->Want );
-       if( type==next->Type && next->Made ) {
+       if ( type == next->Type && next->Made ) {
            --next->Made;
-           if( !--next->Want ) {
-               *queue=next->Next;
-               free(next);
+           if ( !--next->Want ) {
+               *queue = next->Next;
+               free( next );
            }
            return 1;
        }
@@ -1054,21 +1025,20 @@
 **     @param pai      Computer AI player.
 **     @param type     Unit-type which is now available.
 */
-local void AiRemoveFromBuilded(PlayerAi* pai,const UnitType* type)
+local void AiRemoveFromBuilded( PlayerAi * pai, const UnitType * type )
 {
     int i;
 
-    if( AiRemoveFromBuilded2(pai,type) ) {
+    if ( AiRemoveFromBuilded2( pai, type ) ) {
        return;
     }
-    //
-    // This could happen if an upgrade is ready, look for equivalent units.
-    //
-    if( type->Type<AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
-       DebugLevel2Fn("Equivalence for %s\n" _C_ type ->Ident);
-       for( i=0; i<AiHelpers.Equiv[type->Type]->Count; ++i ) {
-           if( AiRemoveFromBuilded2(pai,
-                   AiHelpers.Equiv[type->Type]->Table[i]) ) {
+   //
+   //  This could happen if an upgrade is ready, look for equivalent units.
+   //
+    if ( type->Type < AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
+       DebugLevel2Fn( "Equivalence for %s\n" _C_ type->Ident );
+       for ( i = 0; i < AiHelpers.Equiv[type->Type]->Count; ++i ) {
+           if ( AiRemoveFromBuilded2( pai, 
AiHelpers.Equiv[type->Type]->Table[i] ) ) {
                return;
            }
        }
@@ -1084,15 +1054,15 @@
 **     @param type     Unit-type which is now available.
 **     @return         True if the unit-type could be reduced.
 */
-local int AiReduceMadeInBuilded2(const PlayerAi* pai,const UnitType* type)
+local int AiReduceMadeInBuilded2( const PlayerAi * pai, const UnitType * type )
 {
-    AiBuildQueue* queue;
+    AiBuildQueue *queue;
 
-    //
-    // Search the unit-type order.
-    //
-    for( queue=pai->UnitTypeBuilded; queue; queue=queue->Next ) {
-       if( type==queue->Type && queue->Made ) {
+   //
+   //  Search the unit-type order.
+   //
+    for ( queue = pai->UnitTypeBuilded; queue; queue = queue->Next ) {
+       if ( type == queue->Type && queue->Made ) {
            queue->Made--;
            return 1;
        }
@@ -1106,21 +1076,20 @@
 **     @param pai      Computer AI player.
 **     @param type     Unit-type which is now available.
 */
-local void AiReduceMadeInBuilded(const PlayerAi* pai,const UnitType* type)
+local void AiReduceMadeInBuilded( const PlayerAi * pai, const UnitType * type )
 {
     int i;
 
-    if( AiReduceMadeInBuilded2(pai,type) ) {
+    if ( AiReduceMadeInBuilded2( pai, type ) ) {
        return;
     }
-    //
-    // This could happen if an upgrade is ready, look for equivalent units.
-    //
-    if( type->Type<AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
-       DebugLevel2Fn("Equivalence for %s\n" _C_ type ->Ident);
-       for( i=0; i<AiHelpers.Equiv[type->Type]->Count; ++i ) {
-           if( AiReduceMadeInBuilded2(pai,
-                   AiHelpers.Equiv[type->Type]->Table[i]) ) {
+   //
+   //  This could happen if an upgrade is ready, look for equivalent units.
+   //
+    if ( type->Type < AiHelpers.EquivCount && AiHelpers.Equiv[type->Type] ) {
+       DebugLevel2Fn( "Equivalence for %s\n" _C_ type->Ident );
+       for ( i = 0; i < AiHelpers.Equiv[type->Type]->Count; ++i ) {
+           if ( AiReduceMadeInBuilded2( pai, 
AiHelpers.Equiv[type->Type]->Table[i] ) ) {
                return;
            }
        }
@@ -1139,63 +1108,42 @@
 **     @param attacker Pointer to attacker unit.
 **     @param defender Pointer to unit that is being attacked.
 */
-global void AiHelpMe(const Unit* attacker,Unit* defender)
+global void AiHelpMe( const Unit * attacker, Unit * defender )
 {
-    PlayerAi* pai;
-    AiUnit* aiunit;
+    PlayerAi *pai;
+    AiUnit *aiunit;
     int force;
 
-    DebugLevel0Fn("%d: %d(%s) attacked at %d,%d\n" _C_
-           defender->Player->Player _C_ UnitNumber(defender) _C_
-           defender->Type->Ident _C_ defender->X _C_ defender->Y);
-
-    //
-    // Don't send help to scouts (zeppelin,eye of vision).
-    //
-    if( !defender->Type->CanAttack && defender->Type->UnitType==UnitTypeFly ) {
+    DebugLevel0Fn( "%d: %d(%s) attacked at %d,%d\n" _C_
+                  defender->Player->Player _C_ UnitNumber( defender ) _C_
+                  defender->Type->Ident _C_ defender->X _C_ defender->Y );
+
+   //
+   //  Don't send help to scouts (zeppelin,eye of vision).
+   //
+    if ( !defender->Type->CanAttack && defender->Type->UnitType == UnitTypeFly 
) {
        return;
     }
 
-    AiPlayer=pai=defender->Player->Ai;
-    if( pai->Force[0].Attacking ) {            // Force 0 busy
-       return;
-    }
+    AiPlayer = pai = defender->Player->Ai;
 
-    //
-    // If unit belongs to an attacking force, don't defend it.
-    //
-    for( force=0; force<AI_MAX_ATTACKING_FORCES; ++force ) {
-       if( !pai->Force[force].Attacking ) {    // none attacking
-           // FIXME, send the force for help
-           continue;
-       }
-       aiunit=pai->Force[force].Units;
-       while( aiunit ) {
-           if( defender==aiunit->Unit ) {
+   //
+   //  If unit belongs to an attack/defend force, don't defend it.
+   //
+    for ( force = 1; force < AI_MAX_FORCES; ++force ) {
+       aiunit = pai->Force[force].Units;
+
+       while ( aiunit ) {
+           if ( defender == aiunit->Unit ) {
+               AiForceHelpMe( force, attacker, defender );
                return;
            }
-           aiunit=aiunit->Next;
+           aiunit = aiunit->Next;
        }
     }
 
-    DebugLevel2Fn("Sending force 0 and 1 to defend\n");
-    //
-    // Send force 0 defending, also send force 1 if this is home.
-    //
-    if( attacker ) {
-       AiAttackWithForceAt(0,attacker->X,attacker->Y);
-       if( !pai->Force[1].Attacking ) {        // none attacking
-           pai->Force[1].Defending=1;
-           AiAttackWithForceAt(1,attacker->X,attacker->Y);
-       }
-    } else {
-       AiAttackWithForceAt(0,defender->X,defender->Y);
-       if( !pai->Force[1].Attacking ) {        // none attacking
-           pai->Force[1].Defending=1;
-           AiAttackWithForceAt(1,defender->X,defender->Y);
-       }
-    }
-    pai->Force[0].Defending=1;
+   // Unit can't be found in forces, consider it's in force 0
+    AiForceHelpMe( 0, attacker, defender );
 }
 
 /**
@@ -1203,38 +1151,36 @@
 **
 **     @param unit     Pointer to unit.
 */
-global void AiUnitKilled(Unit* unit)
+global void AiUnitKilled( Unit * unit )
 {
-    DebugLevel1Fn("%d: %d(%s) killed\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident);
+    DebugLevel1Fn( "%d: %d(%s) killed\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    // FIXME: must handle all orders...
+   // FIXME: must handle all orders...
 
-    switch( unit->Orders[0].Action ) {
-       case UnitActionStill:
-       case UnitActionAttack:
-       case UnitActionMove:
-           break;
-       case UnitActionBuilded:
-           DebugLevel1Fn("%d: %d(%s) killed, under construction!\n" _C_
-                   unit->Player->Player _C_ UnitNumber(unit) _C_
-                   unit->Type->Ident);
-           AiReduceMadeInBuilded(unit->Player->Ai,unit->Type);
-           break;
-       case UnitActionBuild:
-           DebugLevel1Fn("%d: %d(%s) killed, with order %s!\n" _C_
-                   unit->Player->Player _C_ UnitNumber(unit) _C_
-                   unit->Type->Ident _C_
-                   unit->Orders[0].Type->Ident);
-           AiReduceMadeInBuilded(unit->Player->Ai,unit->Orders[0].Type);
-           break;
-       default:
-           DebugLevel1Fn("FIXME: %d: %d(%s) killed, with order %d!\n" _C_
-                   unit->Player->Player _C_ UnitNumber(unit) _C_
-                   unit->Type->Ident _C_ unit->Orders[0].Action);
-           break;
+    switch ( unit->Orders[0].Action ) {
+    case UnitActionStill:
+    case UnitActionAttack:
+    case UnitActionMove:
+       break;
+    case UnitActionBuilded:
+       DebugLevel1Fn( "%d: %d(%s) killed, under construction!\n" _C_
+                      unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident );
+       AiReduceMadeInBuilded( unit->Player->Ai, unit->Type );
+       break;
+    case UnitActionBuild:
+       DebugLevel1Fn( "%d: %d(%s) killed, with order %s!\n" _C_
+                      unit->Player->Player _C_ UnitNumber( unit ) _C_
+                      unit->Type->Ident _C_ unit->Orders[0].Type->Ident );
+       AiReduceMadeInBuilded( unit->Player->Ai, unit->Orders[0].Type );
+       break;
+    default:
+       DebugLevel1Fn( "FIXME: %d: %d(%s) killed, with order %d!\n" _C_
+                      unit->Player->Player _C_ UnitNumber( unit ) _C_
+                      unit->Type->Ident _C_ unit->Orders[0].Action );
+       break;
     }
 }
 
@@ -1244,20 +1190,20 @@
 **     @param unit     Pointer to unit that builds the building.
 **     @param what     Pointer to unit building that was built.
 */
-global void AiWorkComplete(Unit* unit,Unit* what)
+global void AiWorkComplete( Unit * unit, Unit * what )
 {
-    if (unit) {
-       DebugLevel1Fn("%d: %d(%s) build %s at %d,%d completed\n" _C_
-               what->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident 
_C_
-               what->Type->Ident _C_ unit->X _C_ unit->Y);
+    if ( unit ) {
+       DebugLevel1Fn( "%d: %d(%s) build %s at %d,%d completed\n" _C_
+                      what->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                      what->Type->Ident _C_ unit->X _C_ unit->Y );
     } else {
-       DebugLevel1Fn("%d: building %s at %d,%d completed\n" _C_
-               what->Player->Player _C_ what->Type->Ident _C_ what->X _C_ 
what->Y);
+       DebugLevel1Fn( "%d: building %s at %d,%d completed\n" _C_
+                      what->Player->Player _C_ what->Type->Ident _C_ what->X 
_C_ what->Y );
     }
 
-    DebugCheck(what->Player->Type == PlayerPerson);
+    DebugCheck( what->Player->Type == PlayerPerson );
 
-    AiRemoveFromBuilded(what->Player->Ai,what->Type);
+    AiRemoveFromBuilded( what->Player->Ai, what->Type );
 }
 
 /**
@@ -1266,15 +1212,15 @@
 **     @param unit     Pointer to unit what builds the building.
 **     @param what     Pointer to unit-type.
 */
-global void AiCanNotBuild(Unit* unit,const UnitType* what)
+global void AiCanNotBuild( Unit * unit, const UnitType * what )
 {
-    DebugLevel0Fn("%d: %d(%s) Can't build %s at %d,%d\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident
-           _C_ what->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel0Fn( "%d: %d(%s) Can't build %s at %d,%d\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident
+                  _C_ what->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    AiReduceMadeInBuilded(unit->Player->Ai,what);
+    AiReduceMadeInBuilded( unit->Player->Ai, what );
 }
 
 /**
@@ -1283,15 +1229,15 @@
 **     @param unit     Pointer to unit what builds the building.
 **     @param what     Pointer to unit-type.
 */
-global void AiCanNotReach(Unit* unit,const UnitType* what)
+global void AiCanNotReach( Unit * unit, const UnitType * what )
 {
-    DebugLevel3Fn("%d: %d(%s) Can't reach %s at %d,%d\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident _C_
-           what->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel3Fn( "%d: %d(%s) Can't reach %s at %d,%d\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                  what->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    AiReduceMadeInBuilded(unit->Player->Ai,what);
+    AiReduceMadeInBuilded( unit->Player->Ai, what );
 }
 
 /**
@@ -1300,16 +1246,15 @@
 **     @param unit     Point to unit.
 **      @param what     Pointer to unit-type.
 */
-global void AiNeedMoreFarms(Unit* unit,
-       const UnitType* what __attribute__((unused)))
+global void AiNeedMoreFarms( Unit * unit, const UnitType * what __attribute__ 
( ( unused ) ) )
 {
-    DebugLevel3Fn("%d: %d(%s) need more farms %s at %d,%d\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident _C_
-           what->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel3Fn( "%d: %d(%s) need more farms %s at %d,%d\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                  what->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    ((PlayerAi*)unit->Player->Ai)->NeedFood=1;
+    ( ( PlayerAi * ) unit->Player->Ai )->NeedFood = 1;
 }
 
 /**
@@ -1318,19 +1263,19 @@
 **     @param unit     Pointer to unit making.
 **     @param what     Pointer to new ready trained unit.
 */
-global void AiTrainingComplete(Unit* unit,Unit* what)
+global void AiTrainingComplete( Unit * unit, Unit * what )
 {
-    DebugLevel1Fn("%d: %d(%s) training %s at %d,%d completed\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident _C_
-           what->Type->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel1Fn( "%d: %d(%s) training %s at %d,%d completed\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                  what->Type->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    AiRemoveFromBuilded(unit->Player->Ai,what->Type);
+    AiRemoveFromBuilded( unit->Player->Ai, what->Type );
 
-    AiPlayer=unit->Player->Ai;
+    AiPlayer = unit->Player->Ai;
     AiCleanForces();
-    AiAssignToForce(what);
+    AiAssignToForce( what );
 }
 
 /**
@@ -1339,14 +1284,14 @@
 **     @param unit     Pointer to unit working.
 **     @param what     Pointer to the new unit-type.
 */
-global void AiUpgradeToComplete(Unit* unit __attribute__((unused)),
-       const UnitType* what __attribute__((unused)))
+global void AiUpgradeToComplete( Unit * unit __attribute__ ( ( unused ) ),
+                                const UnitType * what __attribute__ ( ( unused 
) ) )
 {
-    DebugLevel1Fn("%d: %d(%s) upgrade-to %s at %d,%d completed\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident _C_
-           what->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel1Fn( "%d: %d(%s) upgrade-to %s at %d,%d completed\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                  what->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 }
 
 /**
@@ -1355,16 +1300,16 @@
 **     @param unit     Pointer to unit working.
 **     @param what     Pointer to the new upgrade.
 */
-global void AiResearchComplete(Unit* unit __attribute__((unused)),
-       const Upgrade* what __attribute__((unused)))
+global void AiResearchComplete( Unit * unit __attribute__ ( ( unused ) ),
+                               const Upgrade * what __attribute__ ( ( unused ) 
) )
 {
-    DebugLevel1Fn("%d: %d(%s) research %s at %d,%d completed\n" _C_
-           unit->Player->Player _C_ UnitNumber(unit) _C_ unit->Type->Ident _C_
-           what->Ident _C_ unit->X _C_ unit->Y);
+    DebugLevel1Fn( "%d: %d(%s) research %s at %d,%d completed\n" _C_
+                  unit->Player->Player _C_ UnitNumber( unit ) _C_ 
unit->Type->Ident _C_
+                  what->Ident _C_ unit->X _C_ unit->Y );
 
-    DebugCheck(unit->Player->Type == PlayerPerson);
+    DebugCheck( unit->Player->Type == PlayerPerson );
 
-    // FIXME: upgrading knights -> paladins, must rebuild lists!
+   // FIXME: upgrading knights -> paladins, must rebuild lists!
 }
 
 /**
@@ -1372,7 +1317,7 @@
 **
 **     @param player   The player structure pointer.
 */
-global void AiEachCycle(Player* player __attribute__((unused)))
+global void AiEachCycle( Player * player __attribute__ ( ( unused ) ) )
 {
 }
 
@@ -1381,45 +1326,50 @@
 **
 **     @param player   The player structure pointer.
 */
-global void AiEachSecond(Player* player)
+global void AiEachSecond( Player * player )
 {
 #ifdef TIMEIT
-    u_int64_t sv=rdtsc();
+    u_int64_t sv = rdtsc();
     u_int64_t ev;
     static long mv;
     long sx;
 #endif
 
-    DebugLevel3Fn("%d:\n" _C_ player->Player);
+    DebugLevel3Fn( "%d:\n" _C_ player->Player );
+
+    AiPlayer = player->Ai;
+    IfDebug( if ( !AiPlayer ) return; );       // For debug only!
 
-    AiPlayer=player->Ai;
-    IfDebug( if( !AiPlayer ) return; );        // For debug only!
-    //
-    // Advance script
-    //
-    AiExecuteScript();
-    //
-    // Look if everything is fine.
-    //
+   //
+   //  Advance script
+   //
+    AiExecuteScripts();
+
+   //
+   //  Look if everything is fine.
+   //
     AiCheckUnits();
-    //
-    // Handle the resource manager.
-    //
+   //
+   //  Handle the resource manager.
+   //
     AiResourceManager();
-    //
-    // Handle the force manager.
-    //
+   //
+   //  Handle the force manager.
+   //
     AiForceManager();
-    //
-    // Check for magic actions.
-    //
+   //
+   //  Check for magic actions.
+   //
     AiCheckMagic();
 
+    if ( AiPlayer->AutoAttack ) {
+       AiPeriodicAttack();
+    }
 #ifdef TIMEIT
-    ev=rdtsc();
-    sx=(ev-sv);
-    mv=(mv+sx)/2;
-    DebugLevel1Fn("%ld %ld\n" _C_ sx/1000 _C_ mv/1000);
+    ev = rdtsc();
+    sx = ( ev - sv );
+    mv = ( mv + sx ) / 2;
+    DebugLevel1Fn( "%ld %ld\n" _C_ sx / 1000 _C_ mv / 1000 );
 #endif
 }
 
Index: stratagus/src/clone/Module.make
diff -u stratagus/src/clone/Module.make:1.6 stratagus/src/clone/Module.make:1.7
--- stratagus/src/clone/Module.make:1.6 Mon Sep 22 06:40:51 2003
+++ stratagus/src/clone/Module.make     Thu Oct 23 14:38:34 2003
@@ -25,7 +25,7 @@
 MODULE= src/clone
 MSRC=  ccl.c ccl_player.c clone.c construct.c groups.c iolib.c mainloop.c \
        mpq.c player.c pud.c scm.c selection.c spells.c unit.c unit_draw.c \
-       unit_find.c unitcache.c ccl_spell.c
+       unit_find.c unitcache.c ccl_spell.c ccl_helpers.c
 
 SRC+=  $(addprefix $(MODULE)/,$(MSRC))
 HDRS+=
Index: stratagus/src/clone/ccl.c
diff -u stratagus/src/clone/ccl.c:1.117 stratagus/src/clone/ccl.c:1.118
--- stratagus/src/clone/ccl.c:1.117     Tue Oct 21 18:31:31 2003
+++ stratagus/src/clone/ccl.c   Thu Oct 23 14:38:34 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl.c,v 1.117 2003/10/21 22:31:31 jsalmon3 Exp $
+//     $Id: ccl.c,v 1.118 2003/10/23 18:38:34 n0body Exp $
 
 //@{
 
@@ -1050,7 +1050,7 @@
     }
 
     fprintf(fd, ";;; -----------------------------------------\n");
-    fprintf(fd, ";;; $Id: ccl.c,v 1.117 2003/10/21 22:31:31 jsalmon3 Exp $\n");
+    fprintf(fd, ";;; $Id: ccl.c,v 1.118 2003/10/23 18:38:34 n0body Exp $\n");
 
     fprintf(fd, "(set-video-resolution! %d %d)\n", VideoWidth, VideoHeight);
     
@@ -1075,7 +1075,7 @@
     }
 
     fprintf(fd, ";;; -----------------------------------------\n");
-    fprintf(fd, ";;; $Id: ccl.c,v 1.117 2003/10/21 22:31:31 jsalmon3 Exp $\n");
+    fprintf(fd, ";;; $Id: ccl.c,v 1.118 2003/10/23 18:38:34 n0body Exp $\n");
 
     // Global options
     if (OriginalFogOfWar) {
@@ -1181,11 +1181,12 @@
 {
 #ifdef USE_GUILE
 #else
+#if 0
     SCM list;
     extern SCM oblistvar;
 
     CLprintf(file, "\n;;; -----------------------------------------\n");
-    CLprintf(file, ";;; MODULE: CCL $Id: ccl.c,v 1.117 2003/10/21 22:31:31 
jsalmon3 Exp $\n\n");
+    CLprintf(file, ";;; MODULE: CCL $Id: ccl.c,v 1.118 2003/10/23 18:38:34 
n0body Exp $\n\n");
 
     for (list = oblistvar; gh_list_p(list); list = gh_cdr(list)) {
        SCM sym;
@@ -1193,7 +1194,6 @@
        sym = gh_car(list);
        if (symbol_boundp(sym, NIL)) {
            SCM value;
-
            CLprintf(file, ";;(define %s\n", get_c_string(sym));
            value = symbol_value(sym, NIL);
            CLprintf(file, ";;");
@@ -1205,6 +1205,7 @@
 #endif
        }
     }
+#endif
 #endif
 }
 
Index: stratagus/src/clone/ccl_spell.c
diff -u stratagus/src/clone/ccl_spell.c:1.19 
stratagus/src/clone/ccl_spell.c:1.20
--- stratagus/src/clone/ccl_spell.c:1.19        Wed Oct 22 15:28:05 2003
+++ stratagus/src/clone/ccl_spell.c     Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_spell.c,v 1.19 2003/10/22 19:28:05 n0body Exp $
+//     $Id: ccl_spell.c,v 1.20 2003/10/23 18:38:35 n0body Exp $
 //@{
 
 /*----------------------------------------------------------------------------
@@ -35,6 +35,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "stratagus.h"
 /*
@@ -165,6 +166,21 @@
                errl("Unsupported area-bombardment tag", value);
            }
        }
+    } else if (gh_eq_p(value, gh_symbol2scm("demolish"))) {
+       spellaction->CastFunction = CastDemolish;
+       while (!gh_null_p(list)) {
+           value = gh_car(list);
+           list = gh_cdr(list);
+           if (gh_eq_p(value, gh_symbol2scm("range"))) {
+               spellaction->Data.Demolish.Range = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else if (gh_eq_p(value, gh_symbol2scm("damage"))) {
+               spellaction->Data.Demolish.Damage = gh_scm2int(gh_car(list));
+               list = gh_cdr(list);
+           } else {
+               errl("Unsupported demolish tag", value);
+           }
+       }
     } else if (gh_eq_p(value, gh_symbol2scm("adjust-buffs"))) {
        spellaction->CastFunction = CastAdjustBuffs;
        spellaction->Data.AdjustBuffs.HasteTicks = BUFF_NOT_AFFECTED;
@@ -631,6 +647,10 @@
            CLprintf(file, " require-corpse ");
        }
        CLprintf(file, ")\n");
+    } else if (action->CastFunction == CastDemolish) {
+       CLprintf(file, "(demolish range %d damage %d)\n",
+               action->Data.Demolish.Range,
+               action->Data.Demolish.Damage);
     } else if (action->CastFunction == CastAdjustBuffs) {
        CLprintf(file, "(adjust-buffs");
        if (action->Data.AdjustBuffs.HasteTicks != BUFF_NOT_AFFECTED) {
Index: stratagus/src/clone/mainloop.c
diff -u stratagus/src/clone/mainloop.c:1.149 
stratagus/src/clone/mainloop.c:1.150
--- stratagus/src/clone/mainloop.c:1.149        Thu Oct 16 21:23:09 2003
+++ stratagus/src/clone/mainloop.c      Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: mainloop.c,v 1.149 2003/10/17 01:23:09 jsalmon3 Exp $
+//     $Id: mainloop.c,v 1.150 2003/10/23 18:38:35 n0body Exp $
 
 //@{
 
@@ -754,6 +754,7 @@
 #else
     int showtip;
 #endif
+    int player;
     int RealVideoSyncSpeed;
     
     GameCallbacks.ButtonPressed = HandleButtonDown;
@@ -813,26 +814,37 @@
            //          Check rescue of units.
            //
            switch (GameCycle % CYCLES_PER_SECOND) {
-               case 0:
+               case 0:                         
+                   // At cycle 0 , start all ai players...
+                   if (GameCycle == 0){
+                       for (player = 0; player<NumPlayers; ++player){
+                           PlayersEachSecond(player);
+                       }
+                   }
+                   // Clear scheme heap each second
+                   user_gc(SCM_BOOL_F);
+                   break;                  
+               case 1:
                    HandleCloak();
                    break;
-               case 1:
+               case 2:
                    break;
-               case 2:                         // minimap update
+               case 3:                         // minimap update
                    UpdateMinimap();
                    MustRedraw |= RedrawMinimap;
-                   break;
-               case 3:                         // computer players
-                   PlayersEachSecond();
-                   break;
-               case 4:                         // forest grow
+                   break;              
+               case 5:                         // forest grow
                    RegenerateForest();
                    break;
-               case 5:                         // overtaking units
+               case 6:                         // overtaking units
                    RescueUnits();
                    break;
-               case 6:
-                   break;
+               default:
+                   // FIXME : assume that NumPlayers < (CYCLES_PER_SECOND -7) 
+                   player = ( GameCycle % CYCLES_PER_SECOND ) - 7;
+                   if (player < NumPlayers){
+                       PlayersEachSecond(player);
+                   }                               
            }
 
            //
Index: stratagus/src/clone/player.c
diff -u stratagus/src/clone/player.c:1.94 stratagus/src/clone/player.c:1.95
--- stratagus/src/clone/player.c:1.94   Thu Oct  9 23:56:40 2003
+++ stratagus/src/clone/player.c        Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: player.c,v 1.94 2003/10/10 03:56:40 jsalmon3 Exp $
+//     $Id: player.c,v 1.95 2003/10/23 18:38:35 n0body Exp $
 
 //@{
 
@@ -202,7 +202,7 @@
     int j;
 
     CLprintf(file, "\n;;; -----------------------------------------\n");
-    CLprintf(file, ";;; MODULE: players $Id: player.c,v 1.94 2003/10/10 
03:56:40 jsalmon3 Exp $\n\n");
+    CLprintf(file, ";;; MODULE: players $Id: player.c,v 1.95 2003/10/23 
18:38:35 n0body Exp $\n\n");
 
     //
     // Dump table wc2 race numbers -> internal symbol.
@@ -840,27 +840,26 @@
 }
 
 /**
-**     Handle AI of all players each second.
+**     Handle AI of a player each second.
+** 
+**      @param player  the player to update AI
 */
-global void PlayersEachSecond(void)
-{
-    int player;
+global void PlayersEachSecond(int player)
+{    
     int res;
 
-    for (player = 0; player < NumPlayers; ++player) {
-       if ((GameCycle / CYCLES_PER_SECOND) % 10 == 0) {
-           for (res = 0; res < MaxCosts; res++) {
-               Players[player].Revenue[res] =
-                   Players[player].Resources[res] -
-                   Players[player].LastResources[res];
-               Players[player].Revenue[res] *= 6;      // estimate per minute
-               Players[player].LastResources[res] =
-                   Players[player].Resources[res];
-           }
-       }
-       if (Players[player].AiEnabled) {
-           AiEachSecond(&Players[player]);
+    if ((GameCycle / CYCLES_PER_SECOND) % 10 == 0) {
+       for (res = 0; res < MaxCosts; res++) {
+           Players[player].Revenue[res] =
+               Players[player].Resources[res] -
+               Players[player].LastResources[res];
+           Players[player].Revenue[res] *= 6;  // estimate per minute
+           Players[player].LastResources[res] =
+               Players[player].Resources[res];
        }
+    }
+    if (Players[player].AiEnabled) {
+       AiEachSecond(&Players[player]);
     }
 }
 
Index: stratagus/src/clone/spells.c
diff -u stratagus/src/clone/spells.c:1.112 stratagus/src/clone/spells.c:1.113
--- stratagus/src/clone/spells.c:1.112  Wed Oct 22 15:28:05 2003
+++ stratagus/src/clone/spells.c        Thu Oct 23 14:38:35 2003
@@ -27,7 +27,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.c,v 1.112 2003/10/22 19:28:05 n0body Exp $
+//     $Id: spells.c,v 1.113 2003/10/23 18:38:35 n0body Exp $
 
 /*
 **     And when we cast our final spell
@@ -87,6 +87,82 @@
 // ****************************************************************************
 
 /**
+**     Cast demolish
+**     @param caster   Unit that casts the spell
+**     @param spell    Spell-type pointer
+**     @param target   Target unit that spell is addressed to
+**     @param x        X coord of target spot when/if target does not exist
+**     @param y        Y coord of target spot when/if target does not exist
+**
+**     @return         =!0 if spell should be repeated, 0 if not
+*/
+global int CastDemolish(Unit* caster, const SpellType* spell 
__attribute__((unused)),
+       const SpellActionType* action,Unit* target __attribute__((unused)), int 
x, int y)
+{
+    int xmin;
+    int ymin;
+    int xmax;
+    int ymax;
+    int i;
+    int ix;
+    int iy;
+    int n;
+    Unit* table[UnitMax];
+
+    xmin = x - action->Data.Demolish.Range;
+    ymin = y - action->Data.Demolish.Range;
+    xmax = x + action->Data.Demolish.Range;
+    ymax = y + action->Data.Demolish.Range;
+    if (xmin < 0) {
+       xmin = 0;
+    }
+    if (xmax > TheMap.Width - 1) {
+       xmax = TheMap.Width - 1;
+    }
+    if (ymin < 0) {
+       ymin = 0;
+    }
+    if (ymax > TheMap.Height - 1) {
+       ymax = TheMap.Height - 1;
+    }
+
+    //
+    //  Effect of the explosion on units. Don't bother if damage is 0
+    //
+    if (action->Data.Demolish.Damage) {
+       n = SelectUnits(xmin, ymin, xmax+1, ymax+1, table);
+       for (i = 0; i < n; ++i) {
+           DebugLevel0("Hit an unit at %d %d?\n" _C_ table[i]->X _C_ 
table[i]->Y);
+           if (table[i]->Type->UnitType != UnitTypeFly && table[i]->HP &&
+                   MapDistanceToUnit(x, y, table[i]) <= 
action->Data.Demolish.Range) {
+               // Don't hit flying units!
+               HitUnit(caster, table[i], action->Data.Demolish.Damage);
+           }
+       }
+    }
+
+    //
+    // Terrain effect of the explosion
+    //
+    for (ix = xmin; ix <= xmax; ++ix) {
+       for (iy = ymin; iy <= ymax; ++iy) {
+           n = TheMap.Fields[ix + iy * TheMap.Width].Flags;
+           if (MapDistance(ix, iy, x, y ) > action->Data.Demolish.Range) {
+               // Not in circle range
+               continue;
+           } else if (n & MapFieldWall) {
+               MapRemoveWall(ix, iy);
+           } else if (n & MapFieldRocks) {
+               MapRemoveRock(ix, iy);
+           } else if (n & MapFieldForest) {
+               MapRemoveWood(ix, iy);
+           }
+       }
+    }
+    return 0;
+}
+
+/**
 **     Cast circle of power.
 **
 **     @param caster   Unit that casts the spell
@@ -1073,6 +1149,7 @@
        }
        PlayGameSound(spell->SoundWhenCast.Sound, MaxSampleVolume);
        while (act) {
+           DebugCheck(!act->CastFunction);
            act->CastFunction(caster, spell, act, target, x, y);
            act=act->Next;
        }
Index: stratagus/src/clone/unit_find.c
diff -u stratagus/src/clone/unit_find.c:1.62 
stratagus/src/clone/unit_find.c:1.63
--- stratagus/src/clone/unit_find.c:1.62        Fri Oct 17 00:56:20 2003
+++ stratagus/src/clone/unit_find.c     Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit_find.c,v 1.62 2003/10/17 04:56:20 mr-russ Exp $
+//     $Id: unit_find.c,v 1.63 2003/10/23 18:38:35 n0body Exp $
 
 //@{
 
@@ -63,8 +63,8 @@
 #define HEALTH_FACTOR          0x00000001
 #define DISTANCE_FACTOR                0x00100000
 #define INRANGE_FACTOR         0x00010000
-#define INRANGE_BONUS          0x00100000
-#define CANATTACK_BONUS                0x01000000
+#define INRANGE_BONUS          0x01000000
+#define CANATTACK_BONUS                0x00100000
 
 /*----------------------------------------------------------------------------
 --     Local Data
Index: stratagus/src/game/savegame.c
diff -u stratagus/src/game/savegame.c:1.34 stratagus/src/game/savegame.c:1.35
--- stratagus/src/game/savegame.c:1.34  Wed Oct 15 21:36:25 2003
+++ stratagus/src/game/savegame.c       Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: savegame.c,v 1.34 2003/10/16 01:36:25 jsalmon3 Exp $
+//     $Id: savegame.c,v 1.35 2003/10/23 18:38:35 n0body Exp $
 
 //@{
 
@@ -101,7 +101,7 @@
     CLprintf(file, ";;;(save-game\n");
     CLprintf(file, ";;;  'comment\t\"Generated by Stratagus Version " VERSION 
"\"\n");
     CLprintf(file, ";;;  'comment\t\"Visit http://Stratagus.Org for more 
informations\"\n");
-    CLprintf(file, ";;;  'comment\t\"$Id: savegame.c,v 1.34 2003/10/16 
01:36:25 jsalmon3 Exp $\"\n");
+    CLprintf(file, ";;;  'comment\t\"$Id: savegame.c,v 1.35 2003/10/23 
18:38:35 n0body Exp $\"\n");
     CLprintf(file, ";;;  'type\t\"%s\"\n", "single-player");
     CLprintf(file, ";;;  'date\t\"%s\"\n", s);
     CLprintf(file, ";;;  'map\t\"%s\"\n", TheMap.Description);
@@ -115,12 +115,13 @@
 
        CLprintf(file, ";;;  'media\t'");
        var = gh_symbol2scm("media-version");
-       if (symbol_boundp(var, NIL)) {
-           var = symbol_value(var, NIL);
-           lprin1CL(var, file);
-       } else {
+       // FIXME : guile todo
+       //if (symbol_boundp(var, NIL)) {
+       //    var = symbol_value(var, NIL);
+       //    lprin1CL(var, file);
+       //} else {
            CLprintf(file, "nil");
-       }
+       //}
     }
     CLprintf(file, "\n;;;  'preview\t\"%s.pam\"\n", filename);
     CLprintf(file, ";;;  )\n");
Index: stratagus/src/include/pathfinder.h
diff -u stratagus/src/include/pathfinder.h:1.34 
stratagus/src/include/pathfinder.h:1.35
--- stratagus/src/include/pathfinder.h:1.34     Thu Oct  9 19:15:29 2003
+++ stratagus/src/include/pathfinder.h  Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: pathfinder.h,v 1.34 2003/10/09 23:15:29 mr-russ Exp $
+//     $Id: pathfinder.h,v 1.35 2003/10/23 18:38:35 n0body Exp $
 
 #ifndef        __PATH_FINDER_H__
 #define        __PATH_FINDER_H__
@@ -99,6 +99,8 @@
 extern int NewPath(Unit* unit);
     /// Return distance to unit.
 extern int UnitReachable(Unit* unit,Unit* dst,int range);
+
+extern int PlaceReachable(Unit* src,int x,int y,int w,int h,int range);
 
 //
 //     in astar.c
Index: stratagus/src/include/player.h
diff -u stratagus/src/include/player.h:1.75 stratagus/src/include/player.h:1.76
--- stratagus/src/include/player.h:1.75 Tue Oct  7 20:06:42 2003
+++ stratagus/src/include/player.h      Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: player.h,v 1.75 2003/10/08 00:06:42 jsalmon3 Exp $
+//     $Id: player.h,v 1.76 2003/10/23 18:38:35 n0body Exp $
 
 #ifndef __PLAYER_H__
 #define __PLAYER_H__
@@ -521,8 +521,8 @@
 extern void PlayersInitAi(void);
     /// Called each game cycle for player handlers (AI)
 extern void PlayersEachCycle(void);
-    /// Called each second for player handlers (AI)
-extern void PlayersEachSecond(void);
+    /// Called each second for a given player handler (AI)
+extern void PlayersEachSecond(int player);
 
     /// Change current color set to new player
 extern void PlayerPixels(const Player* player);
Index: stratagus/src/include/spells.h
diff -u stratagus/src/include/spells.h:1.33 stratagus/src/include/spells.h:1.34
--- stratagus/src/include/spells.h:1.33 Wed Oct 22 15:28:05 2003
+++ stratagus/src/include/spells.h      Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: spells.h,v 1.33 2003/10/22 19:28:05 n0body Exp $
+//     $Id: spells.h,v 1.34 2003/10/23 18:38:35 n0body Exp $
 
 #ifndef __SPELLS_H__
 #define __SPELLS_H__
@@ -96,15 +96,20 @@
     // FIXME" some time information doesn't work as it should.
     union {
        struct {
-           int Damage;                                 /// Missile damage
-           int TTL;                                    /// Missile TTL
-           int Delay;                                  /// Missile original 
delay
-           SpellActionMissileLocation StartPoint;      /// Start point 
description
-           SpellActionMissileLocation EndPoint;        /// Start point 
description
+           int Damage;                                 /// Missile damage.
+           int TTL;                                    /// Missile TTL.
+           int Delay;                                  /// Missile original 
delay.
+           SpellActionMissileLocation StartPoint;      /// Start point 
description.
+           SpellActionMissileLocation EndPoint;        /// Start point 
description.
        } SpawnMissile;
 
        struct {
-           int Fields;                 /// The size of the affected square
+           int Damage;                 /// Damage for every unit in range.
+           int Range;                  /// Range of the explosion.
+       } Demolish;
+
+       struct {
+           int Fields;                 /// The size of the affected square.
            int Shards;                 /// Number of shards thrown.
            int Damage;                 /// Damage for every shard.
            /// The offset of the missile start point to the hit location.
@@ -326,6 +331,7 @@
 SpellFunc CastPolymorph;
 SpellFunc CastAreaBombardment;
 SpellFunc CastSummon;
+SpellFunc CastDemolish;
 SpellFunc CastDeathCoil;
 SpellFunc CastSpawnPortal;
 SpellFunc CastSpawnMissile;
Index: stratagus/src/include/unit.h
diff -u stratagus/src/include/unit.h:1.221 stratagus/src/include/unit.h:1.222
--- stratagus/src/include/unit.h:1.221  Wed Oct 22 14:02:35 2003
+++ stratagus/src/include/unit.h        Thu Oct 23 14:38:35 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: unit.h,v 1.221 2003/10/22 18:02:35 jsalmon3 Exp $
+//     $Id: unit.h,v 1.222 2003/10/23 18:38:35 n0body Exp $
 
 #ifndef __UNIT_H__
 #define __UNIT_H__
@@ -593,7 +593,7 @@
     struct _order_resource_ {
        int     Active;                 /// how many units are harvesting from 
the resource.
     }          Resource;               /// Resource still
-    struct _order_resource_worker_ {
+    struct _order_resource_worker_ {   
        int     TimeToHarvest;          /// how much time until we harvest some 
more.
        unsigned DoneHarvesting:1;      /// Harvesting done, wait for action to 
break.
     }          ResWorker;              /// Worker harvesting
@@ -647,6 +647,11 @@
 **     Returns unit number (unique to this unit)
 */
 #define UnitNumber(unit)       ((unit)->Slot)
+
+/**
+**     Check if a unit is idle.
+*/
+#define UnitIdle(unit)         
((unit->Orders[0].Action==UnitActionStill)&&(unit->OrderCount==1))
 
 /**
 **      Return the unit type movement mask.
Index: stratagus/src/pathfinder/pathfinder.c
diff -u stratagus/src/pathfinder/pathfinder.c:1.57 
stratagus/src/pathfinder/pathfinder.c:1.58
--- stratagus/src/pathfinder/pathfinder.c:1.57  Fri Oct 17 02:04:31 2003
+++ stratagus/src/pathfinder/pathfinder.c       Thu Oct 23 14:38:36 2003
@@ -28,7 +28,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: pathfinder.c,v 1.57 2003/10/17 06:04:31 mr-russ Exp $
+//     $Id: pathfinder.c,v 1.58 2003/10/23 18:38:36 n0body Exp $
 
 //@{
 
@@ -74,7 +74,7 @@
 */
 global unsigned char Matrix[(MaxMapWidth+2)*(MaxMapHeight+3)+2];       /// 
Path matrix
 local unsigned int LocalMatrix[MaxMapWidth*MaxMapHeight];
-local int PlaceReachable(Unit* src,int x,int y,int w,int h,int range);
+global int PlaceReachable(Unit* src,int x,int y,int w,int h,int range);
 
 /*----------------------------------------------------------------------------
 --     Functions
@@ -380,7 +380,7 @@
 **
 **     @return         Distance to place.
 */
-local int PlaceReachable(Unit* src,int x,int y,int w,int h,int range)
+global int PlaceReachable(Unit* src,int x,int y,int w,int h,int range)
 {
     int depth;
     static unsigned long LastGameCycle;
Index: stratagus/src/sound/ccl_sound.c
diff -u stratagus/src/sound/ccl_sound.c:1.53 
stratagus/src/sound/ccl_sound.c:1.54
--- stratagus/src/sound/ccl_sound.c:1.53        Thu Oct 16 14:18:06 2003
+++ stratagus/src/sound/ccl_sound.c     Thu Oct 23 14:38:36 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: ccl_sound.c,v 1.53 2003/10/16 18:18:06 jsalmon3 Exp $
+//     $Id: ccl_sound.c,v 1.54 2003/10/23 18:38:36 n0body Exp $
 
 //@{
 
@@ -493,7 +493,7 @@
 
                    value = gh_car(sublist);
                    sublist = gh_cdr(sublist);
-                   for (i = 0; i < gh_vector_length(value); ++i) {
+                   for (i = 0; i < (signed)gh_vector_length(value); ++i) {
                        temp=gh_vector_ref(value, gh_int2scm(i));
                        p->CDTracks |= (1 << gh_scm2int(temp));
                    }
Index: stratagus/src/video/sdl.c
diff -u stratagus/src/video/sdl.c:1.101 stratagus/src/video/sdl.c:1.102
--- stratagus/src/video/sdl.c:1.101     Thu Oct 16 13:03:01 2003
+++ stratagus/src/video/sdl.c   Thu Oct 23 14:38:36 2003
@@ -26,7 +26,7 @@
 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 //      02111-1307, USA.
 //
-//     $Id: sdl.c,v 1.101 2003/10/16 17:03:01 jsalmon3 Exp $
+//     $Id: sdl.c,v 1.102 2003/10/23 18:38:36 n0body Exp $
 
 //@{
 
@@ -39,9 +39,8 @@
 #ifdef USE_SDL // {
 
 #include <stdlib.h>
-#ifdef BSD
 #include <string.h>
-#endif
+
 #include <limits.h>
 #ifndef _MSC_VER
 #include <sys/time.h>




reply via email to

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