[Top][All Lists]
[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>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Stratagus-CVS] stratagus data/ccl/ai.ccl data/ccl/spells.ccl d...,
Crestez Leonard <=