[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stratagus-CVS] stratagus data/ccl/ai.ccl src/ai/ai_force.c src...
From: |
ludovic pollet |
Subject: |
[Stratagus-CVS] stratagus data/ccl/ai.ccl src/ai/ai_force.c src... |
Date: |
Fri, 31 Oct 2003 04:14:49 -0500 |
CVSROOT: /cvsroot/stratagus
Module name: stratagus
Branch:
Changes by: ludovic pollet <address@hidden> 03/10/31 04:14:48
Modified files:
data/ccl : ai.ccl
src/ai : ai_force.c ai_local.h ai_resource.c ai_rules.c
ccl_ai.c new_ai.c
src/clone : ccl.c clone.c
src/game : loadgame.c
src/include : ai.h ccl.h
Log message:
Fix for debugcheck in AiRemoveFromBuilded and others
Patches:
Index: stratagus/data/ccl/ai.ccl
diff -u stratagus/data/ccl/ai.ccl:1.57 stratagus/data/ccl/ai.ccl:1.58
--- stratagus/data/ccl/ai.ccl:1.57 Mon Oct 27 05:33:45 2003
+++ stratagus/data/ccl/ai.ccl Fri Oct 31 04:14:41 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.57 2003/10/27 10:33:45 pludov Exp $
+;; $Id: ai.ccl,v 1.58 2003/10/31 09:14:41 pludov Exp $
;(define (ai:sleep) () #t)
@@ -129,9 +129,7 @@
(list 'unit-equiv 'unit-knight
'unit-paladin)
(list 'unit-equiv 'unit-peasant)
- (list 'unit-equiv 'unit-human-oil-tanker)
- (list 'unit-equiv 'unit-alliance-watch-tower
- 'unit-alliance-guard-tower 'unit-alliance-cannon-tower) )
+ (list 'unit-equiv 'unit-human-oil-tanker) )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; * Race orc.
@@ -218,9 +216,7 @@
(list 'unit-equiv 'unit-ogre
'unit-ogre-mage)
(list 'unit-equiv 'unit-peon)
- (list 'unit-equiv 'unit-orc-oil-tanker)
- (list 'unit-equiv 'unit-mythical-watch-tower
- 'unit-mythical-guard-tower 'unit-mythical-cannon-tower) )
+ (list 'unit-equiv 'unit-orc-oil-tanker) )
;;=============================================================================
;;
@@ -308,41 +304,39 @@
;;
-(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-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-knight
+;; unit-ballista
+;; 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)
@@ -361,7 +355,7 @@
;; Global force requirement ( percentages ).
;; Must send unit of at least this force... ( can remove allied force ... )
- (force-minimum (enemy-hotspot-ground-force 100) )
+ (force-minimum (enemy-hotspot-ground-force 100) (enemy-map-ground-force
20))
;; force requirements in units ( percentages )
((ai:soldier) (enemy-hotspot-ground-force 110))
@@ -383,7 +377,7 @@
;; Global force requirement ( percentages ).
;; Must send unit of at least this force... ( can remove allied force ... )
- (force-minimum (enemy-hotspot-ground-force 200) )
+ (force-minimum (enemy-hotspot-ground-force 200) (enemy-map-ground-force
20))
;; force requirements in units ( percentages )
((ai:worker) (enemy-hotspot-ground-force 110))))
@@ -404,7 +398,7 @@
;; Global force requirement ( percentages ).
;; Must send unit of at least this force... ( can remove allied force ... )
- (force-minimum (enemy-hotspot-air-fire 110) )
+ (force-minimum (enemy-hotspot-air-fire 110) (enemy-map-air-force
25))
;; force requirements in units ( percentages )
((ai:flyer)
@@ -423,7 +417,7 @@
ai:default-defend
)
(zero-gauges)
- (force-minimum (enemy-hotspot-sea-force 100) )
+ (force-minimum (enemy-hotspot-sea-force 100) (enemy-map-sea-force 25))
((ai:battleship)
(enemy-hotspot-sea-fire 70)
(enemy-hotspot-ground-force 30) (enemy-hotspot-sea-force 30))
@@ -441,7 +435,7 @@
ai:default-defend
)
(zero-gauges enemy-hotspot-detectors)
- (force-minimum (enemy-hotspot-sea-force 50))
+ (force-minimum (enemy-hotspot-sea-force 50) (enemy-map-sea-force 25))
((ai:submarine) (enemy-hotspot-sea-force 50))
))
@@ -455,12 +449,12 @@
ai:default-defend
)
- ;; gauge which must be 0..
+ ;; 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-minimum (enemy-hotspot-ground-force 100) (enemy-map-ground-force
25))
;; force requirements in units ( percentages )
((ai:cavalrie) (enemy-hotspot-ground-force 130))
@@ -475,18 +469,19 @@
;; Ai Script to execute when ready
ai:default-defend
)
- ;; gauge which must be 0..
+ ;; 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-minimum (enemy-hotspot-ground-force 100)
(enemy-hotspot-air-force 100)
+ (enemy-map-ground-force 25) (enemy-map-air-force 25))
;; 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))
+ ((ai:cavalrie) (enemy-hotspot-ground-force 75))
+ ((ai:soldier) (enemy-hotspot-ground-force 20))
))
(define-ai-action '(defense attack)
@@ -499,10 +494,11 @@
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))
+ (force-minimum (enemy-hotspot-ground-force 100)
(enemy-hotspot-air-force 100)
+ (enemy-map-ground-force 25) (enemy-map-air-force 25))
((ai:shooter) (enemy-hotspot-ground-force 40)
(enemy-hotspot-air-force 120))
+ ((ai:soldier) (enemy-hotspot-ground-force 80))
))
;;
@@ -755,8 +751,10 @@
(ai:need 'unit-mythical-blacksmith)
;; (ai:force 1 'unit-grunt 1)
(ai:force 0 'unit-grunt 1)
+ (ai:force 1 'unit-grunt 2)
;; (ai:wait-force 1) ;; wait until attack party is completed
;; (ai:attack-with-force 1)
+ (ai:sleep 20)
(ai:force 0 'unit-grunt 2)
(ai:research 'upgrade-battle-axe1)
@@ -765,6 +763,7 @@
(ai:research 'upgrade-orc-shield2)
(ai:set 'unit-peon 20)
(ai:force 0 'unit-grunt 6)
+ (ai:force 1 'unit-grunt 6)
;; (ai:wait-force 1) ;; wait until attack party is completed
(ai:set 'unit-mythical-barracks 3)
(ai:force 0 'unit-grunt 20)
@@ -1442,7 +1441,7 @@
(ai:upgrade-to (ai:guard-tower))
(ai:need (ai:airport))
(ai:set (ai:worker) 20)
-;; (ai:force 1 (ai:flyer) 2)
+ (ai:force 1 (ai:flyer) 4)
;; (ai:attack-with-force 2)
(ai:sleep 500)
@@ -1612,7 +1611,7 @@
(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:submarine) 1
(ai:destroyer) 2 (ai:battleship) 1 )
+ (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)
@@ -1664,8 +1663,7 @@
;;
(define ai:human-land-attack-endloop
'((writes nil "Looping !\n")
- (ai:force 0 'unit-footman 2 'unit-ranger 4 'unit-paladin 8 'unit-ballista 2
- 'unit-mage 6 'unit-gryphon-rider 3)
+ (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) ) )
@@ -1682,7 +1680,8 @@
(ai:set 'unit-peasant 4)
(ai:need 'unit-elven-lumber-mill)
(ai:need 'unit-alliance-barracks)
- (ai:force 0 'unit-footman 3)
+ (ai:force 0 'unit-footman 3)
+ (ai:force 1 'unit-footman 4)
(ai:set 'unit-peasant 9)
(ai:sleep 500)
@@ -1703,6 +1702,7 @@
(ai:sleep 500)
(ai:set 'unit-peasant 15)
(ai:force 0 'unit-footman 6 'unit-archer 3 'unit-ballista 1)
+ (ai:force 1 'unit-footman 6 'unit-archer 3 'unit-ballista 1)
(ai:sleep 500)
(ai:upgrade-to 'unit-keep)
Index: stratagus/src/ai/ai_force.c
diff -u stratagus/src/ai/ai_force.c:1.36 stratagus/src/ai/ai_force.c:1.37
--- stratagus/src/ai/ai_force.c:1.36 Sun Oct 26 10:34:58 2003
+++ stratagus/src/ai/ai_force.c Fri Oct 31 04:14:45 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_force.c,v 1.36 2003/10/26 15:34:58 pludov Exp $
+// $Id: ai_force.c,v 1.37 2003/10/31 09:14:45 pludov Exp $
//@{
@@ -45,17 +45,145 @@
#include "ai_local.h"
#include "actions.h"
#include "map.h"
+#include "depend.h"
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
+global int UnitTypeEquivs[UnitTypeMax + 1];/// equivalence between unittypes
+
/*----------------------------------------------------------------------------
-- Functions
----------------------------------------------------------------------------*/
/**
+** Remove any equivalence between unittypes
+*/
+global void AiResetUnitTypeEquiv(void)
+{
+ int i;
+ for (i = 0; i <= UnitTypeMax; i++) {
+ UnitTypeEquivs[i] = i;
+ }
+}
+
+/**
+** Make two unittypes equivalents from the AI's point of vue
+**
+** @param a the first unittype
+** @param b the second unittype
+*/
+global void AiNewUnitTypeEquiv(UnitType * a,UnitType * b)
+{
+ int find,replace,i;
+
+ find = UnitTypeEquivs[a->Type];
+ replace = UnitTypeEquivs[b->Type];
+
+ // Always record equivalences with the lowest unittype.
+ if (find < replace) {
+ i = find;
+ find = replace;
+ replace = i;
+ }
+
+ // Then just find & replace in UnitTypeEquivs...
+ for (i = 0; i <= UnitTypeMax; i++) {
+ if (UnitTypeEquivs[i] == find) {
+ UnitTypeEquivs[i] = replace;
+ }
+ }
+}
+
+
+/**
+** Find All unittypes equivalent to a given one
+**
+** @param unittype the unittype to find equivalence for
+** @param result int array which will hold the result. (Size
UnitTypeMax+1)
+** @return the number of unittype found
+*/
+global int AiFindUnitTypeEquiv(const UnitType * unittype,int * result)
+{
+ int i;
+ int search;
+ int count;
+
+ search = UnitTypeEquivs[unittype->Type];
+ count = 0;
+
+ for (i = 0; i < UnitTypeMax + 1; i++) {
+ if (UnitTypeEquivs[i] == search) {
+ // Found one
+ result[count] = i;
+ count++;
+ }
+ }
+
+ return count;
+}
+
+/**
+** Find All unittypes equivalent to a given one, and which are available
+** UnitType are returned in the prefered order ( ie palladin >> knight... )
+**
+** @param unittype the unittype to find equivalence for
+** @param result int array which will hold the result. (Size
UnitTypeMax+1)
+** @return the number of unittype found
+*/
+global int AiFindAvailableUnitTypeEquiv(const UnitType * unittype,int *
usableTypes)
+{
+ int usableTypesCount;
+ int i, j;
+ int tmp;
+ int playerid;
+ int bestlevel, curlevel;
+
+ // 1 - Find equivalents
+ usableTypesCount = AiFindUnitTypeEquiv(unittype, usableTypes);
+
+ // 2 - Remove unavailable unittypes
+ for (i = 0; i < usableTypesCount; ) {
+ if (! CheckDependByIdent(AiPlayer->Player,
UnitTypes[usableTypes[i]]->Ident)) {
+ // Not available, remove it
+ usableTypes[i] = usableTypes[usableTypesCount - 1];
+ usableTypesCount--;
+ } else {
+ i++;
+ }
+ }
+
+ // 3 - Sort by level
+ playerid = AiPlayer->Player->Player;
+
+ // We won't have usableTypesCount>4, so simple sort should do it
+ for (i = 0; i < usableTypesCount-1; i++) {
+ bestlevel = UnitTypes[usableTypes[i]]->Priority;
+ for (j = i + 1; j < usableTypesCount; j++) {
+ curlevel = UnitTypes[usableTypes[j]]->Priority;
+
+ if (curlevel > bestlevel) {
+ // Swap
+ tmp = usableTypes[j];
+ usableTypes[j] = usableTypes[i];
+ usableTypes[i] = tmp;
+
+ bestlevel = curlevel;
+ }
+ }
+ }
+ DebugLevel0Fn("prefered order for %s is " _C_ unittype->Ident);
+ for (i = 0; i < usableTypesCount; i++) {
+ DebugLevel0(" %s" _C_ UnitTypes[usableTypes[i]]->Ident);
+ }
+ DebugLevel0("\n");
+
+ return usableTypesCount;
+}
+
+/**
** Count available units by type in a force.
**
** The returned array will map UnitType=>number of unit
@@ -69,12 +197,11 @@
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;
+ type = UnitTypeEquivs[aiunit->Unit->Type->Type];
DebugCheck((type < 0) || (type > UnitTypeMax));
countByType[type]++;
@@ -93,14 +220,16 @@
global int AiForceSubstractWant(int force, int *countByType)
{
int missing;
+ int type;
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];
+ type=UnitTypeEquivs[aitype->Type->Type];
+ countByType[type] -= aitype->Want;
+ if (countByType[type] < 0) {
+ missing -= countByType[type];
}
aitype = aitype->Next;
}
@@ -111,6 +240,8 @@
/**
** Complete dst force with units from src force.
**
+** FIXME : should check that unit can reach dst force's hotspot.
+**
** @param src the force from which units are taken
** @param dst the force into which units go
*/
@@ -118,7 +249,7 @@
{
AiUnit **prev;
AiUnit *aiunit;
-
+ int type;
int counter[UnitTypeMax + 1];
//
@@ -133,18 +264,20 @@
// 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) {
+ type = UnitTypeEquivs[aiunit->Unit->Type->Type];
+ if (counter[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]++;
+ counter[type]++;
} else {
// Just iterate
prev = &aiunit->Next;
@@ -248,6 +381,10 @@
aiu = AiPlayer->Force[force].Units;
while (aiu) {
+ // Decrease usage count
+ RefsDebugCheck(!aiu->Unit->Refs);
+ --aiu->Unit->Refs;
+
next_u = aiu->Next;
free(aiu);
aiu = next_u;
@@ -284,6 +421,7 @@
{
int counter[UnitTypeMax + 1];
int missing;
+ int realtype;
//
// Count units in force.
@@ -296,10 +434,12 @@
missing = AiForceSubstractWant(force, counter);
AiPlayer->Force[force].Completed = (missing == 0);
- if (counter[type->Type] < 0) {
+ realtype = UnitTypeEquivs[type->Type];
+
+ if (counter[realtype] < 0) {
// Ok we will put this unit in this force !
- // Just one missing...
- if ((counter[type->Type] == -1) && (missing == 1)) {
+ // Just one missing ?
+ if ((counter[realtype] == -1) && (missing == 1)) {
AiPlayer->Force[force].Completed = 1;
}
return 1;
@@ -381,6 +521,9 @@
/**
** Enrole a unit in the specific force.
+** Does not take equivalence into account
+**
+** FIXME : currently iterate all units (slow)
** FIXME : should take units which are closer to the hotspot.
** FIXME : should ensure that units can move to the hotspot.
**
@@ -413,8 +556,7 @@
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) {
+ if (aiUnit->Unit->Type->Type == ut->Type) {
*prev = aiUnit->Next;
// Move to dstForce
@@ -441,15 +583,17 @@
local void AiFinalizeForce(int force)
{
int i;
+ int type;
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;
+ type = UnitTypeEquivs[aitype->Type->Type];
+ if (unitcount[type] > aitype->Want) {
+ aitype->Want = unitcount[type];
+ unitcount[type] = 0;
}
aitype = aitype->Next;
}
@@ -480,35 +624,59 @@
int id, maxPower, forceUpdated;
UnitType *ut;
int curpower[3];
+ int maxadd;
+ int lefttoadd;
+ int unittypeforce;
+ int equivalents[UnitTypeMax + 1];
+ int equivalentscount;
+ int equivalentid;
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;
- }
+ // Search in equivalents
+ equivalentscount =
AiFindAvailableUnitTypeEquiv(UnitTypes[unittypes[id]], equivalents);
+ for (equivalentid = 0; equivalentid < equivalentscount;
equivalentid++) {
+ ut = UnitTypes[equivalents[equivalentid]];
+ if (!(ut->CanTarget & (1 << maxPower))) {
+ continue;
+ }
+
+ unittypeforce = AiUnittypeForce(ut) / 8;
+ unittypeforce = (unittypeforce ? unittypeforce : 1);
+
+ // Try to respond to the most important power ...
+ maxadd = 1 + curpower[maxPower] / unittypeforce;
+
+ lefttoadd = AiEnroleSpecificUnitType(AiScript->ownForce, ut,
maxadd);
- 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;
+ // Nothing added, continue.
+ if (lefttoadd == maxadd) {
+ continue;
+ }
+
+ // FIXME : don't always use the right unittype here...
+ curpower[maxPower] -= (maxadd - lefttoadd) * unittypeforce;
+
+ 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);
@@ -950,7 +1118,7 @@
return;
case AiForceHelpForce:
- // Send all idles units to help
+ // Send all idles units in the attacked force for help
rescue = aiForce->Units;
while (rescue) {
// TODO : check that dead units does appear there
Index: stratagus/src/ai/ai_local.h
diff -u stratagus/src/ai/ai_local.h:1.39 stratagus/src/ai/ai_local.h:1.40
--- stratagus/src/ai/ai_local.h:1.39 Wed Oct 29 18:11:53 2003
+++ stratagus/src/ai/ai_local.h Fri Oct 31 04:14:45 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_local.h,v 1.39 2003/10/29 23:11:53 pludov Exp $
+// $Id: ai_local.h,v 1.40 2003/10/31 09:14:45 pludov Exp $
#ifndef __AI_LOCAL_H__
#define __AI_LOCAL_H__
@@ -228,7 +228,7 @@
*/
struct _ai_action_evaluation_ {
AiScriptAction* aiScriptAction; /// Action evaluated
-
+ int gamecycle; /// Gamecycle when this
evaluation occured
int hotSpotX; /// X position of the hotspot,
or -1
int hotSpotY; /// Y position of the hotspot,
or -1
@@ -372,7 +372,7 @@
#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 int UnitTypeEquivs[UnitTypeMax + 1];/// equivalence between unittypes
extern PlayerAi* AiPlayer; /// Current AI player
extern AiRunningScript* AiScript; /// Currently running script
extern char** AiTypeWcNames; /// pud num to internal string mapping
@@ -396,6 +396,14 @@
extern void AiExplore(int x, int y, int exploreMask);
/// Count the number of builder unit available for the given unittype
extern int AiCountUnitBuilders(UnitType * type);
+ /// Make two unittypes be considered equals
+extern void AiNewUnitTypeEquiv(UnitType * a,UnitType * b);
+ /// Remove any equivalence between unittypes
+extern void AiResetUnitTypeEquiv(void);
+ /// Finds all equivalents units to a given one
+extern int AiFindUnitTypeEquiv(const UnitType * i,int * result);
+ /// Finds all available equivalents units to a given one, in the prefered
order
+extern int AiFindAvailableUnitTypeEquiv(const UnitType * i,int * result);
//
// Buildings
Index: stratagus/src/ai/ai_resource.c
diff -u stratagus/src/ai/ai_resource.c:1.75 stratagus/src/ai/ai_resource.c:1.76
--- stratagus/src/ai/ai_resource.c:1.75 Wed Oct 29 18:11:54 2003
+++ stratagus/src/ai/ai_resource.c Fri Oct 31 04:14:45 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_resource.c,v 1.75 2003/10/29 23:11:54 pludov Exp $
+// $Id: ai_resource.c,v 1.76 2003/10/31 09:14:45 pludov Exp $
//@{
@@ -469,49 +469,61 @@
const int *unit_count;
AiUnitTypeTable *const *tablep;
const AiUnitTypeTable *table;
-
+
+ int usableTypes[UnitTypeMax+1];
+ int usableTypesCount;
+ int currentType;
+
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;
- }
- 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;
+ // Find equivalents unittypes.
+ usableTypesCount = AiFindAvailableUnitTypeEquiv(type, usableTypes);
+
+ // Iterate them
+ for (currentType = 0; currentType < usableTypesCount; currentType++) {
+
+ type = UnitTypes[usableTypes[currentType]];
- unit_count = AiPlayer->Player->UnitTypesCount;
- for (i = 0; i < n; ++i) {
//
- // The type for builder/trainer is available
+ // Check if we have a place for building or an unit to build.
//
- 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)) {
- return 1;
+ 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);
+ continue;
+ }
+ table = tablep[type->Type];
+ if (!table) { // Oops not known.
+ DebugLevel0Fn("Nothing known about `%s'\n" _C_ type->Ident);
+ continue;
+ }
+ 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)) {
+ return 1;
+ }
+ } else {
+ if (AiTrainUnit(table->Table[i], type)) {
+ return 1;
+ }
}
}
}
}
-
return 0;
}
@@ -1336,6 +1348,7 @@
// Collect resources.
//
AiCollectResources();
+
//
// Check repair.
//
Index: stratagus/src/ai/ai_rules.c
diff -u stratagus/src/ai/ai_rules.c:1.3 stratagus/src/ai/ai_rules.c:1.4
--- stratagus/src/ai/ai_rules.c:1.3 Sun Oct 26 10:34:59 2003
+++ stratagus/src/ai/ai_rules.c Fri Oct 31 04:14:46 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_rules.c,v 1.3 2003/10/26 15:34:59 pludov Exp $
+// $Id: ai_rules.c,v 1.4 2003/10/31 09:14:46 pludov Exp $
//@{
@@ -585,19 +585,25 @@
*/
global int AiEvaluateForceCost(int force, int total)
{
- int want, i;
+ int want, i, j;
int count[UnitTypeMax + 1];
int builders;
+ int equivtypesnb;
+ int equivtypes[UnitTypeMax + 1];
+
int globalCosts[MaxCosts];
int globalTime;
int cost, own;
-
+
+ int forcesize;
+
AiUnitType *unittype;
-
+ UnitType * usedtype;
AiForceCountUnits(force, count);
+
// We have everything ready
if (!total) {
if (!AiForceSubstractWant(force, count)) {
@@ -613,37 +619,54 @@
// For each "want" unittype, evaluate a cost, based on the number of units.
unittype = AiPlayer->Force[force].UnitTypes;
+
+ forcesize=0;
+
while (unittype) {
- want = (-count[unittype->Type->Type]);
+ forcesize += unittype->Want;
+
+ want = (-count[UnitTypeEquivs[unittype->Type->Type]]);
- // Don't count full unittypes...
+ // Don't count full unittypes...
if (want > 0) {
- if (!CheckDependByIdent(AiPlayer->Player, unittype->Type->Ident)) {
- return -1;
- }
- // Find number of units which can build this
- builders = AiCountUnitBuilders(unittype->Type);
+ // Never count it twice...
+ count[UnitTypeEquivs[unittype->Type->Type]] = 0;
+ // Find usable types for building
+ equivtypesnb = AiFindAvailableUnitTypeEquiv(unittype->Type,
equivtypes);
+
+ // Find number of units which can build them
+ builders = 0;
+ usedtype = 0;
+ for (i = 0;i < equivtypesnb; i++) {
+ j = AiCountUnitBuilders(UnitTypes[equivtypes[i]]);
+ if (j > builders) {
+ usedtype = UnitTypes[equivtypes[i]];
+ builders = j;
+ }
+ }
+
// No way to build this, return -1
if (!builders) {
return -1;
}
+
// FIXME : all costs count the same there
// ( sum all costs ... )
-
for (i = 0; i < MaxCosts; i++) {
- globalCosts[i] += want * unittype->Type->_Costs[i];
+ globalCosts[i] += want * usedtype->_Costs[i];
}
// FIXME : buildtime is assumed to be proportionnal to hitpoints
// Time to build the first
- globalTime += unittype->Type->_HitPoints;
+ globalTime += usedtype->_HitPoints;
// Time to build the nexts
- globalTime += (unittype->Type->_HitPoints * want) / builders;
+ globalTime += (usedtype->_HitPoints * want) / builders;
}
unittype = unittype->Next;
}
+
// Count the ressource proportionnaly to player ressource
cost = 0;
@@ -661,10 +684,16 @@
}
- // FIXME : 20 / 1 ratio between buildtime and cost is hardcoded
+ // FIXME : 20 / 1 ratio between buildtime and cost is hardcoded
// Here globalTime is ~ the sum of all HitPoints...
cost += globalTime / 20;
+ // Apply a multiplier on big forces :
+ // 100+(n-5)*10 % : 5 unit = 100 %, 15 units = 200 %, 25 units = 300 %,
...
+ if (forcesize > 5) {
+ cost = (cost * (100 + (forcesize - 5) * 10)) / 100;
+ }
+
return cost;
}
@@ -780,8 +809,8 @@
AiEraseForce(AiScript->ownForce);
AiPlayer->Force[AiScript->ownForce].Role =
(defend ? AiForceRoleDefend : AiForceRoleAttack);
- AiPlayer->Force[AiScript->ownForce].PopulateMode =
- (defend ? AiForcePopulateAny : AiForcePopulateFromAttack);
+ AiPlayer->Force[AiScript->ownForce].PopulateMode =
+ (defend ? AiForcePopulateAny : AiForcePopulateFromAttack);
AiPlayer->Force[AiScript->ownForce].UnitsReusable = 0;
AiPlayer->Force[AiScript->ownForce].HelpMode = AiForceHelpForce;
@@ -796,6 +825,7 @@
// Compute force requirements.
AiEvaluateScript(script->Action);
+
// TODO : move from force 0 to force script->ownForce
// TODO : give some feedback on force 0 !
@@ -810,6 +840,7 @@
global void AiFindDefendScript(int attackX, int attackY)
{
int bestValue;
+ int totalCost, leftCost;
AiScriptAction *bestScriptAction;
if (!AiPrepareScript(attackX, attackY, 12, 1)) {
@@ -825,8 +856,18 @@
DebugLevel3Fn("no correct defense action script available...\n");
return;
}
- DebugLevel3Fn("launch script with value %d\n" _C_ bestValue);
- AiStartScript(bestScriptAction, "defend");
+
+ AiEvaluateScript(bestScriptAction->Action);
+
+ leftCost = AiEvaluateForceCost(AiScript->ownForce, 0);
+ totalCost = AiEvaluateForceCost(AiScript->ownForce, 1);
+ if (leftCost <= ((7 * totalCost) / 10)) {
+ DebugLevel3Fn("launch defense script\n");
+ AiStartScript(bestScriptAction, "defend");
+ }else{
+ DebugLevel3Fn("not ready for defense\n");
+ AiStartScript(bestScriptAction, "defend");
+ }
}
local Unit *RandomPlayerUnit(Player * player)
@@ -834,15 +875,31 @@
int try;
int unitId;
Unit *unit;
+ AiActionEvaluation * action;
if (!player->TotalNumUnits) {
return NoUnitP;
}
- for (try = 0; try < 10; try++) {
+ for (try = 0; try < 20; try++) {
unitId = SyncRand() % player->TotalNumUnits;
unit = player->Units[unitId];
- // FIXME : is this unit targettable ?
- if ((!unit->Removed) && (!((unit)->Orders[0].Action == UnitActionDie)))
{
+
+ // FIXME : is this unit targettable ?
+ if ((unit->Removed) || ((unit)->Orders[0].Action == UnitActionDie)) {
+ continue;
+ }
+
+ // Don't take unit near past evaluations
+ action = AiPlayer->FirstEvaluation;
+ while (action) {
+ if ((abs(action->hotSpotX - unit->X) < 8)
+ && (abs(action->hotSpotY - unit->Y) < 8)) {
+ unit = NoUnitP;
+ break;
+ }
+ action = action->Next;
+ }
+ if (unit != NoUnitP) {
return unit;
}
}
@@ -886,15 +943,42 @@
return NoUnitP;
}
+/**
+** Remove the oldest action evaluation
+*/
local void AiRemoveFirstAiPlayerEvaluation(void)
{
AiActionEvaluation *actionEvaluation = AiPlayer->FirstEvaluation;
AiPlayer->FirstEvaluation = actionEvaluation->Next;
+ if (! AiPlayer->FirstEvaluation) {
+ AiPlayer->LastEvaluation = 0;
+ }
+
free(actionEvaluation);
AiPlayer->EvaluationCount--;
}
+/**
+** Remove outdated evaluations
+*/
+local void AiCleanAiPlayerEvaluations(void)
+{
+ int memorylimit;
+
+ // Don't keep more than AI_MEMORY_SIZE ( remove old ones )
+ while (AiPlayer->EvaluationCount >= AI_MEMORY_SIZE) {
+ AiRemoveFirstAiPlayerEvaluation();
+ }
+
+ // Keep no more than 1 minutes.
+ memorylimit=GameCycle-30*60;
+
+ while (AiPlayer->FirstEvaluation && AiPlayer->FirstEvaluation->gamecycle <
memorylimit){
+ AiRemoveFirstAiPlayerEvaluation();
+ }
+}
+
global void AiPeriodicAttack(void)
{
AiScriptAction *bestScriptAction;
@@ -904,6 +988,9 @@
AiActionEvaluation *bestActionEvaluation;
int bestValue, bestHotSpot;
int leftCost, totalCost;
+ int delta, bestDelta;
+
+ AiCleanAiPlayerEvaluations();
// Find a random enemy unit.
enemy = RandomEnemyUnit();
@@ -911,6 +998,7 @@
DebugLevel3Fn("No enemy unit found for attack, giving up !\n");
return;
}
+
// Find a unit as start point.
// own=RandomPlayerUnit(AiPlayer->Player);
// Need to set AiScript, to make AiEvaluateScript work
@@ -924,9 +1012,11 @@
DebugLevel3Fn("No usable attack script, giving up !\n");
return;
}
+
// Add a new ActionEvaluation at the end of the queue
actionEvaluation = (AiActionEvaluation *) malloc(sizeof
(AiActionEvaluation));
actionEvaluation->aiScriptAction = bestScriptAction;
+ actionEvaluation->gamecycle = GameCycle;
actionEvaluation->hotSpotX = enemy->X;
actionEvaluation->hotSpotY = enemy->Y;
actionEvaluation->value = bestScriptValue;
@@ -934,7 +1024,7 @@
AiGetGaugeValue(ForceGauge(WATER_UNITS_VALUE, HOTSPOT_AREA, FOR_ENEMY))
+ AiGetGaugeValue(ForceGauge(GROUND_UNITS_VALUE, HOTSPOT_AREA,
FOR_ENEMY))
+ AiGetGaugeValue(ForceGauge(AIR_UNITS_VALUE, HOTSPOT_AREA, FOR_ENEMY));
- DebugLevel3Fn("new action at %d %d, hotspotValue=%d, cost=%d\n" _C_
+ DebugLevel2Fn("new action at %d %d, hotspotValue=%d, cost=%d\n" _C_
enemy->X _C_ enemy->Y _C_
actionEvaluation->hotSpotValue _C_ actionEvaluation->value);
@@ -948,11 +1038,6 @@
}
AiPlayer->LastEvaluation = actionEvaluation;
- // Don't keep more than AI_MEMORY_SIZE ( remove old ones )
- while (AiPlayer->EvaluationCount > AI_MEMORY_SIZE) {
- AiRemoveFirstAiPlayerEvaluation();
- }
-
// Iterate all actionEvalution. If one of them is better than all others,
go !
bestActionEvaluation = 0;
bestValue = -1;
@@ -974,6 +1059,18 @@
actionEvaluation = actionEvaluation->Next;
}
+ if ((! bestActionEvaluation) && bestValue != -1 ){
+ // If nothing available, try the best compromis ( value - hotspot )
+ actionEvaluation = AiPlayer->FirstEvaluation;
+ bestDelta=0;
+ while (actionEvaluation) {
+ delta = (20 * actionEvaluation->hotSpotValue) /
(actionEvaluation->value + 1);
+ if (bestDelta == -1 || delta <= bestDelta) {
+ bestActionEvaluation = actionEvaluation;
+ }
+ }
+ }
+
if ((bestActionEvaluation)) {
DebugLevel3Fn("has a best script, value=%d, hotspot=%d\n" _C_ bestValue
_C_
bestHotSpot);
@@ -985,15 +1082,20 @@
leftCost = AiEvaluateForceCost(AiScript->ownForce, 0);
totalCost = AiEvaluateForceCost(AiScript->ownForce, 1);
+ if (leftCost > totalCost) {
+ DebugLevel3Fn("Left cost superior to totalcost ( %d > %d )\n" _C_
leftCost _C_ totalCost);
+ }
- if (leftCost <= ((8 * totalCost) / 10)) {
+ if (leftCost <= ((2 * totalCost) / 10)) {
DebugLevel3Fn("Attack script !...\n");
AiStartScript(bestActionEvaluation->aiScriptAction, "attack");
- } else {
+ } else if (leftCost <= ((8 * totalCost) /10)) {
DebugLevel3Fn("Not ready for attack script, wait...\n");
- //AiForceTransfert(AiScript->ownForce,0);
AiUpdateForce(1, AiScript->ownForce);
+ AiEraseForce(AiScript->ownForce);
+ } else {
+ DebugLevel3Fn("Attacking crisis ! reseting.\n");
AiEraseForce(AiScript->ownForce);
}
}
Index: stratagus/src/ai/ccl_ai.c
diff -u stratagus/src/ai/ccl_ai.c:1.74 stratagus/src/ai/ccl_ai.c:1.75
--- stratagus/src/ai/ccl_ai.c:1.74 Wed Oct 29 18:11:55 2003
+++ stratagus/src/ai/ccl_ai.c Fri Oct 31 04:14:46 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ccl_ai.c,v 1.74 2003/10/29 23:11:55 pludov Exp $
+// $Id: ccl_ai.c,v 1.75 2003/10/31 09:14:46 pludov Exp $
//@{
@@ -73,6 +73,7 @@
{
{"`next", NULL, &((AiActionEvaluation *)
0)->Next, NULL},
{"ai-script-action", &IOAiScriptActionPtr,&((AiActionEvaluation *)
0)->aiScriptAction,NULL},
+ {"gamecycle", &IOInt, &((AiActionEvaluation *)
0)->gamecycle, NULL},
{"hotspot-x", &IOInt, &((AiActionEvaluation *)
0)->hotSpotX, NULL},
{"hotspot-y", &IOInt, &((AiActionEvaluation *)
0)->hotSpotY, NULL},
{"hotspot-value", &IOInt, &((AiActionEvaluation *)
0)->hotSpotValue,NULL},
@@ -693,6 +694,8 @@
AiHelperSetupTable(&AiHelpers.EquivCount, &AiHelpers.Equiv,
base->Type);
AiHelperInsert(AiHelpers.Equiv + base->Type, type);
+
+ AiNewUnitTypeEquiv(base,type);
break;
case 6: // repair
AiHelperSetupTable(&AiHelpers.RepairCount,
&AiHelpers.Repair,
@@ -817,7 +820,7 @@
local void InsertUnitTypeRequests(UnitType * type, int count)
{
int n;
-
+
if (AiPlayer->UnitTypeRequests) {
n = AiPlayer->UnitTypeRequestsCount;
AiPlayer->UnitTypeRequests = realloc(AiPlayer->UnitTypeRequests,
@@ -1232,12 +1235,16 @@
if (!count) { // Don't care
continue;
}
+
+ // Use the equivalent unittype.
+ type = UnitTypes[UnitTypeEquivs[type->Type]];
+
//
// Look if already in force.
//
for (prev = &AiPlayer->Force[force].UnitTypes; (aiut = *prev);
prev = &aiut->Next) {
- if (aiut->Type == type) { // found
+ if (UnitTypeEquivs[aiut->Type->Type] == type->Type) { // found
if (aiut->Want < count) {
aiut->Want = count;
}
Index: stratagus/src/ai/new_ai.c
diff -u stratagus/src/ai/new_ai.c:1.81 stratagus/src/ai/new_ai.c:1.82
--- stratagus/src/ai/new_ai.c:1.81 Wed Oct 29 18:11:55 2003
+++ stratagus/src/ai/new_ai.c Fri Oct 31 04:14:46 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: new_ai.c,v 1.81 2003/10/29 23:11:55 pludov Exp $
+// $Id: new_ai.c,v 1.82 2003/10/31 09:14:46 pludov Exp $
//@{
@@ -57,6 +57,11 @@
**
** Manage the inititialse and cleanup of the AI players.
**
+** ::InitAiModule(void)
+**
+** Initialise all global varaibles and structures.
+** Called before AiInit, or before game loading.
+**
** ::AiInit(::Player)
**
** Called for each player, to setup the AI structures
@@ -176,44 +181,55 @@
local void debugForces(void)
{
- const AiUnit *aiunit;
- const AiUnitType *aiunittype;
+ const AiActionEvaluation * aiaction;
int force, i;
- int count[UnitTypeMax];
-
- DebugLevel3Fn(" ! : completed A/D : attacking/defending\n");
+ int count[UnitTypeMax+1];
+ int want[UnitTypeMax+1];
+ char * str;
+
+ DebugLevel2Fn(" AI MEMORY (%d)\n" _C_ AiPlayer->EvaluationCount);
+ aiaction = AiPlayer->FirstEvaluation;
+ while (aiaction) {
+ str =
gh_scm2newstr(gh_car(gh_car(aiaction->aiScriptAction->Action)),NULL);
+ DebugLevel2(" %8d: (%3d,%3d) => points:%9d, needs: %9d ( %s )\n" _C_
+ aiaction->gamecycle _C_
+ aiaction->hotSpotX _C_
+ aiaction->hotSpotY _C_
+ aiaction->hotSpotValue _C_
+ aiaction->value _C_
+ str);
+ free(str);
+ aiaction = aiaction->Next;
+ }
+ DebugLevel2Fn(" AI FORCES ! : completed A/D :
attacking/defending\n");
for (force = 0; force < AI_MAX_FORCES; force++) {
- DebugLevel3Fn("force %5d %c%c :" _C_
+ DebugLevel2("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;
+ AiForceCountUnits(force, count);
+
+ for (i = 0; i <= UnitTypeMax; i++) {
+ want[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;
- }
-
+ AiForceSubstractWant(force, want);
+
for (i = 0; i < UnitTypeMax; i++) {
- if (count[i]) {
- DebugLevel3Fn(" %s(%d/0)" _C_ UnitTypes[i]->Ident _C_ count[i]);
+ if (count[i] || want[i]) {
+ DebugLevel2(" %s(%d/%d)" _C_ UnitTypes[i]->Ident _C_ count[i]
_C_ want[i]);
}
}
- DebugLevel3Fn("\n");
+ if (force > AI_GENERIC_FORCES || force == 0) {
+ if (!gh_null_p(AiPlayer->Scripts[force ? force - AI_GENERIC_FORCES
: 0].Script)) {
+ DebugLevel2(" => ");
+ fflush(stdout);
+ gh_display(gh_car(AiPlayer->Scripts[force ? force -
AI_GENERIC_FORCES : 0].Script));
+ CclFlushOutput();
+ }
+ }
+ DebugLevel2("\n");
}
}
@@ -227,20 +243,22 @@
SCM value;
pai = AiPlayer;
+
+ // Debugging
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();
- } */
+ /*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);
}
@@ -744,7 +762,7 @@
{
CLprintf(file, "\n;;; -----------------------------------------\n");
CLprintf(file,
- ";;; MODULE: AI $Id: new_ai.c,v 1.81 2003/10/29 23:11:55 pludov Exp
$\n\n");
+ ";;; MODULE: AI $Id: new_ai.c,v 1.82 2003/10/31 09:14:46 pludov Exp
$\n\n");
SaveAiTypesWcName(file);
SaveAiHelper(file);
@@ -865,6 +883,14 @@
}
/**
+** Initialise global structures of the AI
+*/
+global void InitAiModule(void)
+{
+ AiResetUnitTypeEquiv();
+}
+
+/**
** Cleanup the AI.
*/
global void CleanAi(void)
@@ -996,6 +1022,9 @@
free(AiTypeWcNames);
AiTypeWcNames = NULL;
}
+
+ AiResetUnitTypeEquiv();
+
// TODO : AiScriptActions are not freed
AiScriptActionNum = 0;
}
@@ -1042,19 +1071,20 @@
local void AiRemoveFromBuilded(PlayerAi * pai, const UnitType * type)
{
int i;
+ int equivalents[UnitTypeMax+1];
+ int equivalentsCount;
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])) {
- return;
- }
+ equivalentsCount = AiFindUnitTypeEquiv(type, equivalents);
+ for (i = 0; i < equivalentsCount; i++) {
+ if (AiRemoveFromBuilded2(pai, UnitTypes[equivalents[i]])) {
+ return;
}
}
@@ -1063,6 +1093,7 @@
("My guess is that you built something under ai me. naughty
boy!\n");
return;
}
+
DebugCheck(1);
}
Index: stratagus/src/clone/ccl.c
diff -u stratagus/src/clone/ccl.c:1.121 stratagus/src/clone/ccl.c:1.122
--- stratagus/src/clone/ccl.c:1.121 Wed Oct 29 07:58:36 2003
+++ stratagus/src/clone/ccl.c Fri Oct 31 04:14:46 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ccl.c,v 1.121 2003/10/29 12:58:36 mr-russ Exp $
+// $Id: ccl.c,v 1.122 2003/10/31 09:14:46 pludov Exp $
//@{
@@ -68,6 +68,7 @@
#include "cdaudio.h"
#include "spells.h"
+
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
@@ -247,6 +248,15 @@
#endif
}
+global void CclFlushOutput(void)
+{
+#ifdef USE_GUILE
+ scm_flush_all_ports();
+#else
+ fflush(stdout);
+#endif
+}
+
/*............................................................................
.. Config
............................................................................*/
@@ -1046,7 +1056,7 @@
}
fprintf(fd, ";;; -----------------------------------------\n");
- fprintf(fd, ";;; $Id: ccl.c,v 1.121 2003/10/29 12:58:36 mr-russ Exp $\n");
+ fprintf(fd, ";;; $Id: ccl.c,v 1.122 2003/10/31 09:14:46 pludov Exp $\n");
fprintf(fd, "(set-video-resolution! %d %d)\n", VideoWidth, VideoHeight);
@@ -1071,7 +1081,7 @@
}
fprintf(fd, ";;; -----------------------------------------\n");
- fprintf(fd, ";;; $Id: ccl.c,v 1.121 2003/10/29 12:58:36 mr-russ Exp $\n");
+ fprintf(fd, ";;; $Id: ccl.c,v 1.122 2003/10/31 09:14:46 pludov Exp $\n");
// Global options
if (OriginalFogOfWar) {
@@ -1182,7 +1192,7 @@
extern SCM oblistvar;
CLprintf(file, "\n;;; -----------------------------------------\n");
- CLprintf(file, ";;; MODULE: CCL $Id: ccl.c,v 1.121 2003/10/29 12:58:36
mr-russ Exp $\n\n");
+ CLprintf(file, ";;; MODULE: CCL $Id: ccl.c,v 1.122 2003/10/31 09:14:46
pludov Exp $\n\n");
for (list = oblistvar; gh_list_p(list); list = gh_cdr(list)) {
SCM sym;
Index: stratagus/src/clone/clone.c
diff -u stratagus/src/clone/clone.c:1.216 stratagus/src/clone/clone.c:1.217
--- stratagus/src/clone/clone.c:1.216 Tue Oct 28 12:03:40 2003
+++ stratagus/src/clone/clone.c Fri Oct 31 04:14:47 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: clone.c,v 1.216 2003/10/28 17:03:40 jsalmon3 Exp $
+// $Id: clone.c,v 1.217 2003/10/31 09:14:47 pludov Exp $
//@{
@@ -1516,7 +1516,12 @@
--argc;
}
+
InitCcl(); // init CCL and load configurations!
+
+ // Initialise AI module
+ InitAiModule();
+
LoadCcl();
main1(argc, argv);
Index: stratagus/src/game/loadgame.c
diff -u stratagus/src/game/loadgame.c:1.65 stratagus/src/game/loadgame.c:1.66
--- stratagus/src/game/loadgame.c:1.65 Fri Oct 3 06:37:08 2003
+++ stratagus/src/game/loadgame.c Fri Oct 31 04:14:47 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: loadgame.c,v 1.65 2003/10/03 10:37:08 n0body Exp $
+// $Id: loadgame.c,v 1.66 2003/10/31 09:14:47 pludov Exp $
//@{
@@ -152,6 +152,9 @@
InitDependencies();
InitButtons();
+
+ InitAiModule();
+
#ifdef HIERARCHIC_PATHFINDER
PfHierInitialize();
#endif
Index: stratagus/src/include/ai.h
diff -u stratagus/src/include/ai.h:1.29 stratagus/src/include/ai.h:1.30
--- stratagus/src/include/ai.h:1.29 Sun Aug 17 11:57:07 2003
+++ stratagus/src/include/ai.h Fri Oct 31 04:14:47 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai.h,v 1.29 2003/08/17 15:57:07 n0body Exp $
+// $Id: ai.h,v 1.30 2003/10/31 09:14:47 pludov Exp $
#ifndef __AI_H__
#define __AI_H__
@@ -54,11 +54,12 @@
extern void AiEachCycle(Player* player); /// Called each game cycle
extern void AiEachSecond(Player* player); /// Called each second
+extern void InitAiModule(void); /// Init AI global
structures
extern void AiInit(Player* player); /// Init AI for this player
extern void CleanAi(void); /// Cleanup the AI module
extern void SaveAi(CLFile*file); /// Save the AI state
-extern void AiCclRegister(void); /// Register ccl features
+extern void AiCclRegister(void); /// Register ccl features
/*--------------------------------------------------------
-- Call Backs/Triggers
Index: stratagus/src/include/ccl.h
diff -u stratagus/src/include/ccl.h:1.39 stratagus/src/include/ccl.h:1.40
--- stratagus/src/include/ccl.h:1.39 Mon Oct 27 05:49:37 2003
+++ stratagus/src/include/ccl.h Fri Oct 31 04:14:48 2003
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ccl.h,v 1.39 2003/10/27 10:49:37 pludov Exp $
+// $Id: ccl.h,v 1.40 2003/10/31 09:14:48 pludov Exp $
#ifndef __CCL_H__
#define __CCL_H__
@@ -172,6 +172,7 @@
extern void CclGcProtect(SCM obj); /// Protect scm object for GC
extern void CclGcUnprotect(SCM obj); /// Unprotect scm object for GC
+extern void CclFlushOutput(); /// Flush ccl output
extern void InitCcl(void); /// Initialise ccl
extern void LoadCcl(void); /// Load ccl config file
extern void SaveCcl(CLFile* file); /// Save CCL module
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Stratagus-CVS] stratagus data/ccl/ai.ccl src/ai/ai_force.c src...,
ludovic pollet <=