This commit is contained in:
johns 2001-04-27 21:54:02 +00:00
parent 5bde80c5fc
commit 0c708dfecc
3 changed files with 313 additions and 43 deletions

View file

@ -76,6 +76,7 @@ local void AiExecuteScript(void)
local void AiCheckUnits(void)
{
int counter[UnitTypeMax];
AiBuildQueue* queue;
int i;
int n;
int t;
@ -85,13 +86,10 @@ local void AiCheckUnits(void)
//
// Count the already made build requests.
//
n=AiPlayer->BuildedCount;
for( i=0; i<n; ++i ) {
counter[AiPlayer->UnitTypeBuilded[i].Type->Type]
+=AiPlayer->UnitTypeBuilded[i].Want;
DebugLevel0Fn("Already in build queue: %s %d\n" _C_
AiPlayer->UnitTypeBuilded[i].Type->Ident _C_
AiPlayer->UnitTypeBuilded[i].Want);
for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
counter[queue->Type->Type]+=queue->Want;
DebugLevel0Fn("Already in build queue: %s %d/%d\n" _C_
queue->Type->Ident _C_ queue->Made _C_ queue->Want);
}
//
@ -171,6 +169,30 @@ global void AiHelpMe(Unit* unit)
*/
global void AiWorkComplete(Unit* unit,Unit* what)
{
AiBuildQueue** queue;
AiBuildQueue* next;
PlayerAi* pai;
DebugLevel1Fn("AiPlayer %d: %d build %s at %d,%d completed\n" _C_
unit->Player->Player _C_ UnitNumber(unit), what->Type->Ident _C_
unit->X _C_ unit->Y);
DebugCheck(unit->Player->Type == PlayerHuman);
//
// Search the unit-type order.
//
pai=unit->Player->Ai;
for( queue=&pai->UnitTypeBuilded; (next=*queue); queue=&next->Next ) {
if( what->Type==next->Type && next->Want && next->Made ) {
if( next->Want==next->Made ) {
*queue=next->Next;
free(next);
}
return;
}
}
DebugCheck( 1 );
}
/**
@ -181,6 +203,26 @@ global void AiWorkComplete(Unit* unit,Unit* what)
*/
global void AiCanNotBuild(Unit* unit,const UnitType* what)
{
AiBuildQueue* queue;
const PlayerAi* pai;
DebugLevel1Fn("AiPlayer %d: %d Can't build %s at %d,%d\n" _C_
unit->Player->Player _C_ UnitNumber(unit), what->Ident _C_
unit->X _C_ unit->Y);
DebugCheck(unit->Player->Type == PlayerHuman);
//
// Search the unit-type order.
//
pai=unit->Player->Ai;
for( queue=pai->UnitTypeBuilded; queue; queue=queue->Next ) {
if( what==queue->Type && queue->Made ) {
queue->Made--;
return;
}
}
DebugCheck( 1 );
}
/**
@ -191,6 +233,26 @@ global void AiCanNotBuild(Unit* unit,const UnitType* what)
*/
global void AiCanNotReach(Unit* unit,const UnitType* what)
{
AiBuildQueue* queue;
const PlayerAi* pai;
DebugLevel1Fn("AiPlayer %d: %d Can't reach %s at %d,%d\n" _C_
unit->Player->Player _C_ UnitNumber(unit), what->Ident _C_
unit->X _C_ unit->Y);
DebugCheck(unit->Player->Type == PlayerHuman);
//
// Search the unit-type order.
//
pai=unit->Player->Ai;
for( queue=pai->UnitTypeBuilded; queue; queue=queue->Next ) {
if( what==queue->Type && queue->Made ) {
queue->Made--;
return;
}
}
DebugCheck( 1 );
}
/**
@ -201,6 +263,40 @@ global void AiCanNotReach(Unit* unit,const UnitType* what)
*/
global void AiTrainingComplete(Unit* unit,Unit* what)
{
AiBuildQueue** queue;
AiBuildQueue* next;
PlayerAi* pai;
DebugLevel1Fn("AiPlayer %d: %d training %s at %d,%d completed\n" _C_
unit->Player->Player _C_ UnitNumber(unit), what->Type->Ident _C_
unit->X _C_ unit->Y);
DebugCheck(unit->Player->Type == PlayerHuman);
//
// Search the unit-type order.
//
pai=unit->Player->Ai;
for( queue=&pai->UnitTypeBuilded; (next=*queue); queue=&next->Next ) {
if( what->Type==next->Type && next->Want && next->Made ) {
if( next->Want==next->Made ) {
*queue=next->Next;
free(next);
}
return;
}
}
DebugCheck( 1 );
}
/**
** Called if an unit is killed.
**
** @param unit Pointer to unit.
*/
global void AiUnitKilled(Unit* unit)
{
// FIXME: if the unit builds something for us it must restartet!!!!
}
/**

View file

@ -33,6 +33,8 @@
#include "ai_local.h"
#include "actions.h"
local int AiMakeUnit(UnitType* type);
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
@ -133,6 +135,9 @@ global int AiFindBuildingPlace(const Unit * worker, const UnitType * type,
if (x-- == end) {
state = 0;
end = y + addy++;
if( addx>=TheMap.Width && addy>=TheMap.Height ) {
return 0;
}
}
break;
}
@ -141,7 +146,7 @@ global int AiFindBuildingPlace(const Unit * worker, const UnitType * type,
if (y < 0 || x < 0 || y >= TheMap.Height || x >= TheMap.Width) {
continue;
}
if (CanBuildUnitType(worker, type, x, y)
if (CanBuildUnitType(worker, type, x, y)
&& PlaceReachable(worker, x, y, 1)) {
*dx=x;
*dy=y;
@ -184,24 +189,121 @@ local int AiBuildBuilding(const UnitType* type,UnitType* building)
}
}
if( !num ) { // No available unit.
return 0;
for( i=0; i<num; ++i ) {
unit=table[i];
DebugLevel0Fn("Have an unit to build %d :)\n" _C_ UnitNumber(unit));
//
// Find place on that could be build.
//
if ( !AiFindBuildingPlace(unit,building,&x,&y) ) {
continue;
}
DebugLevel0Fn("Have a building place %d,%d :)\n" _C_ x _C_ y);
CommandBuildBuilding(unit, x, y, building,FlushCommands);
return 1;
}
DebugLevel0Fn("Have an unit to build :)\n");
return 0;
}
/**
** Build new units to reduce the food shortage.
*/
local void AiRequestFarms(void)
{
int i;
int n;
int c;
UnitType* type;
AiBuildQueue* queue;
int counter[UnitTypeMax];
//
// Find place on that could be build.
// Count the already made build requests.
//
if ( !AiFindBuildingPlace(unit,building,&x,&y) ) {
return 0;
memset(counter,0,sizeof(counter));
for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
counter[queue->Type->Type]+=queue->Want;
}
DebugLevel0Fn("Have a building place :)\n");
//
// 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;
}
CommandBuildBuilding(unit, x, y, building,FlushCommands);
DebugLevel0Fn("Must build: %s " _C_ type->Ident);
//
// Check if resources available.
//
if( (c=AiCheckUnitTypeCosts(type)) ) {
DebugLevel0("- no resources\n");
AiPlayer->NeededMask|=c;
return;
} else {
AiPlayer->NeededMask=0;
DebugLevel0("- 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;
}
}
}
}
return 1;
/**
** Check if we can train the unit.
**
** @param type Unit that can train the unit.
** @param what what to be trained.
** @return True if made, false if can't be made.
*/
local int AiTrainUnit(const UnitType* type,UnitType* what)
{
Unit* table[UnitMax];
Unit* unit;
int nunits;
int i;
int num;
DebugLevel0Fn("%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++) {
unit = table[i];
if (unit->Orders[0].Action==UnitActionStill && unit->OrderCount==1 ) {
table[num++] = unit;
}
}
for( i=0; i<num; ++i ) {
unit=table[i];
DebugLevel0Fn("Have an unit to train %d :)\n" _C_ UnitNumber(unit));
CommandTrainUnit(unit, what,FlushCommands);
return 1;
}
return 0;
}
/**
@ -246,8 +348,14 @@ local int AiMakeUnit(UnitType* type)
// The type is available
//
if( unit_count[table->Table[i]->Type] ) {
if( AiBuildBuilding(table->Table[i],type) ) {
return 1;
if( type->Building ) {
if( AiBuildBuilding(table->Table[i],type) ) {
return 1;
}
} else {
if( AiTrainUnit(table->Table[i],type) ) {
return 1;
}
}
}
}
@ -260,17 +368,30 @@ local int AiMakeUnit(UnitType* type)
*/
local void AiCheckingWork(void)
{
int i;
int n;
int c;
UnitType* type;
AiBuildQueue* queue;
n=AiPlayer->BuildedCount;
for( i=0; i<n; ++i ) {
if( AiPlayer->UnitTypeBuilded[i].Want
>AiPlayer->UnitTypeBuilded[i].Made ) {
type=AiPlayer->UnitTypeBuilded[i].Type;
DebugLevel0Fn("%d %d %d\n" _C_
AiPlayer->Player->Resources[1] _C_
AiPlayer->Player->Resources[2] _C_
AiPlayer->Player->Resources[3]);
for( queue=AiPlayer->UnitTypeBuilded; queue; queue=queue->Next ) {
if( queue->Want>queue->Made ) {
type=queue->Type;
DebugLevel0Fn("Must build: %s " _C_ type->Ident);
//
// Check if we have enough food.
//
if( !type->Building && AiPlayer->Player->Food
<=AiPlayer->Player->NumFoodUnits ) {
DebugLevel0Fn("Need food\n");
AiRequestFarms();
return;
}
//
// Check if resources available.
//
@ -279,9 +400,10 @@ local void AiCheckingWork(void)
AiPlayer->NeededMask=c;
return;
} else {
AiPlayer->NeededMask=0;
DebugLevel0("- enough resources\n");
if( AiMakeUnit(type) ) {
++AiPlayer->UnitTypeBuilded[i].Made;
++queue->Made;
}
}
}
@ -413,7 +535,7 @@ local void AiCollectResources(void)
Unit* table[UnitMax];
int nunits;
DebugLevel0Fn("%x\n",AiPlayer->NeededMask);
DebugLevel0Fn("%x\n" _C_ AiPlayer->NeededMask);
//
// Look through all costs, if needed.
@ -430,7 +552,7 @@ local void AiCollectResources(void)
nunits += FindPlayerUnitsByType(AiPlayer->Player,
types[i],table+nunits);
}
DebugLevel0Fn("%s: units %d\n",DEFAULT_NAMES[c],nunits);
DebugLevel0Fn("%s: units %d\n" _C_ DEFAULT_NAMES[c] _C_ nunits);
//
// Assign the worker
@ -472,7 +594,7 @@ local void AiCollectResources(void)
nunits += FindPlayerUnitsByType(AiPlayer->Player,
types[i],table+nunits);
}
DebugLevel0Fn("%s: units %d\n",DEFAULT_NAMES[c],nunits);
DebugLevel0Fn("%s: units %d\n" _C_ DEFAULT_NAMES[c] _C_ nunits);
//
// Assign the worker
@ -495,6 +617,35 @@ local void AiCollectResources(void)
}
}
}
//
// Let all workers with resource return it.
//
nunits=0;
for( c=0; c<OreCost; ++c ) {
if( c>=AiHelpers.WithGoodsCount || !AiHelpers.WithGoods[c] ) {
continue;
}
types=AiHelpers.WithGoods[c]->Table;
n=AiHelpers.WithGoods[c]->Count;
for( i=0; i<n; ++i ) {
nunits+=FindPlayerUnitsByType(AiPlayer->Player,
types[i],table+nunits);
}
}
DebugLevel0Fn("Return: units %d\n" _C_ nunits);
//
// Assign the workers with goods
//
for( i=0; i<nunits; ++i ) {
// Unit is already busy
if (table[i]->Orders[0].Action != UnitActionStill
|| table[i]->OrderCount>1 ) {
continue;
}
CommandReturnGoods(table[i],NULL,FlushCommands);
}
}
/**
@ -505,21 +656,21 @@ local void AiCollectResources(void)
*/
global void AiAddUnitTypeRequest(UnitType* type,int count)
{
int n;
AiBuildQueue** queue;
DebugLevel0Fn("%s %d\n" _C_ type->Ident _C_ count);
if( AiPlayer->UnitTypeBuilded ) {
n=AiPlayer->BuildedCount;
AiPlayer->UnitTypeBuilded=realloc(AiPlayer->UnitTypeBuilded,
(n+1)*sizeof(*AiPlayer->UnitTypeBuilded));
} else {
AiPlayer->UnitTypeBuilded=malloc(sizeof(*AiPlayer->UnitTypeBuilded));
n=0;
//
// Find end of the list.
//
for( queue=&AiPlayer->UnitTypeBuilded; *queue; queue=&(*queue)->Next ) {
}
AiPlayer->UnitTypeBuilded[n].Type=type;
AiPlayer->UnitTypeBuilded[n].Want=count;
AiPlayer->UnitTypeBuilded[n].Made=0;
AiPlayer->BuildedCount=n+1;
*queue=malloc(sizeof(*AiPlayer->UnitTypeBuilded));
(*queue)->Next=NULL;
(*queue)->Type=type;
(*queue)->Want=count;
(*queue)->Made=0;
}
/**

View file

@ -149,6 +149,10 @@ local SCM CclDefineAiHelper(SCM list)
what=3;
} else if( gh_eq_p(value,gh_symbol2scm("collect")) ) {
what=4;
} else if( gh_eq_p(value,gh_symbol2scm("with-goods")) ) {
what=5;
} else if( gh_eq_p(value,gh_symbol2scm("unit-limit")) ) {
what=6;
} else {
fprintf(stderr,"unknown tag\n");
continue;
@ -184,7 +188,7 @@ local SCM CclDefineAiHelper(SCM list)
continue;
}
DebugLevel0Fn("> %s\n" _C_ upgrade->Ident);
} else if( what==4 ) {
} else if( what==4 || what==5 ) {
if( !strcmp(DEFAULT_NAMES[1],str) ) {
cost=1;
} else if( !strcmp(DEFAULT_NAMES[2],str) ) {
@ -203,6 +207,15 @@ local SCM CclDefineAiHelper(SCM list)
continue;
}
DebugLevel0Fn("> %s\n" _C_ str);
} else if( what==6 ) {
if( !strcmp("food",str) ) {
cost=0;
} else {
fprintf(stderr,"unknown limit %s\n",str);
free(str);
continue;
}
DebugLevel0Fn("> %s\n" _C_ str);
} else {
type=UnitTypeByIdent(str);
if( !type ) {
@ -246,6 +259,16 @@ local SCM CclDefineAiHelper(SCM list)
&AiHelpers.CollectCount,&AiHelpers.Collect,cost);
AiHelperInsert( AiHelpers.Collect+cost,base);
break;
case 5: // with-goods
AiHelperSetupTable(
&AiHelpers.WithGoodsCount,&AiHelpers.WithGoods,cost);
AiHelperInsert( AiHelpers.WithGoods+cost,base);
break;
case 6: // unit-limit
AiHelperSetupTable(
&AiHelpers.UnitLimitCount,&AiHelpers.UnitLimit,cost);
AiHelperInsert( AiHelpers.UnitLimit+cost,base);
break;
}
}
}