Next step of AI, builds and collects something.
This commit is contained in:
parent
ef0564970b
commit
d4b518e16b
6 changed files with 554 additions and 24 deletions
src
|
@ -89,8 +89,8 @@ local void AiCheckUnits(void)
|
|||
for( i=0; i<n; ++i ) {
|
||||
counter[AiPlayer->UnitTypeBuilded[i].Type->Type]
|
||||
+=AiPlayer->UnitTypeBuilded[i].Want;
|
||||
DebugLevel0Fn("Already in build queue: %s %d\n",
|
||||
AiPlayer->UnitTypeBuilded[i].Type->Ident,
|
||||
DebugLevel0Fn("Already in build queue: %s %d\n" _C_
|
||||
AiPlayer->UnitTypeBuilded[i].Type->Ident _C_
|
||||
AiPlayer->UnitTypeBuilded[i].Want);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,8 @@ local void AiCheckUnits(void)
|
|||
t=AiPlayer->UnitTypeRequests[i].Table[0]->Type;
|
||||
x=AiPlayer->UnitTypeRequests[i].Count;
|
||||
if( x>AiPlayer->Player->UnitTypesCount[t]+counter[t] ) {
|
||||
DebugLevel0Fn("Need %s\n",AiPlayer->UnitTypeRequests[i].Table[0]->Ident);
|
||||
DebugLevel0Fn("Need %s\n" _C_
|
||||
AiPlayer->UnitTypeRequests[i].Table[0]->Ident);
|
||||
// Request it.
|
||||
AiAddUnitTypeRequest(AiPlayer->UnitTypeRequests[i].Table[0],
|
||||
x-AiPlayer->Player->UnitTypesCount[t]-counter[t]);
|
||||
|
@ -123,6 +124,7 @@ local void AiCheckUnits(void)
|
|||
global void AiInit(Player* player)
|
||||
{
|
||||
PlayerAi* pai;
|
||||
AiType* ait;
|
||||
|
||||
DebugLevel0Fn("%d - %s\n" _C_ player->Player _C_ player->Name);
|
||||
|
||||
|
@ -132,8 +134,16 @@ global void AiInit(Player* player)
|
|||
exit(0);
|
||||
}
|
||||
pai->Player=player;
|
||||
pai->AiType=AiTypes;
|
||||
pai->Script=AiTypes->Script;
|
||||
ait=AiTypes;
|
||||
//
|
||||
// Search correct AI type.
|
||||
//
|
||||
while( ait->Race && strcmp(ait->Race,player->RaceName) ) {
|
||||
ait=ait->Next;
|
||||
DebugCheck( !ait );
|
||||
}
|
||||
pai->AiType=ait;
|
||||
pai->Script=ait->Script;
|
||||
|
||||
player->Ai=pai;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ enum _ai_script_command_ {
|
|||
AiCmdBuild, /// build building
|
||||
AiCmdTrain, /// train unit
|
||||
AiCmdResearch, /// research upgrade
|
||||
AiCmdForce, /// Set force.
|
||||
AiCmdForce, /// Set force
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -78,9 +78,9 @@ enum _ai_priority_ {
|
|||
*/
|
||||
struct _ai_goal_ {
|
||||
AiGoal* Next; /// double linked list of all goals
|
||||
AiGoal* Down; /// dependend goals.
|
||||
AiGoal* Down; /// dependend goals
|
||||
AiGoal* Prev; /// double linked list of all goals
|
||||
int Priority; /// Priority of this goal.
|
||||
int Priority; /// Priority of this goal
|
||||
};
|
||||
|
||||
// goals stuff
|
||||
|
@ -108,15 +108,15 @@ typedef struct _ai_type_ AiType;
|
|||
** Ai Type structure.
|
||||
*/
|
||||
struct _ai_type_ {
|
||||
AiType* Next; /// Next ai type.
|
||||
AiType* Next; /// Next ai type
|
||||
|
||||
char* Name; /// Name of this ai.
|
||||
char* Race; /// for this race.
|
||||
char* Class; /// class of this ai.
|
||||
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.
|
||||
//unsigned char AllExplored : 1; /// Ai sees unexplored area
|
||||
//unsigned char AllVisibile : 1; /// Ai sees invisibile area
|
||||
|
||||
SCM Script; /// Main script
|
||||
};
|
||||
|
@ -157,6 +157,11 @@ typedef struct _player_ai_ {
|
|||
|
||||
// resource manager
|
||||
|
||||
int Reserve[MaxCosts]; /// Resources to keep in reserve
|
||||
int Used[MaxCosts]; /// Used resources
|
||||
int Needed[MaxCosts]; /// Needed resources
|
||||
int NeededMask; /// Mask for needed resources
|
||||
|
||||
/// number of elements in UnitTypeRequests
|
||||
int RequestsCount;
|
||||
/// unit-types to build/train requested and priority list
|
||||
|
@ -204,6 +209,12 @@ typedef struct _ai_helper_ {
|
|||
*/
|
||||
int ResearchCount;
|
||||
AiUnitTypeTable** Research;
|
||||
/**
|
||||
** The index is the costs that should be collected, giving a table of all
|
||||
** untis/buildings which could collect this resource.
|
||||
*/
|
||||
int CollectCount;
|
||||
AiUnitTypeTable** Collect;
|
||||
} AiHelper;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
#include "freecraft.h"
|
||||
|
||||
#include "unit.h"
|
||||
#include "map.h"
|
||||
#include "pathfinder.h"
|
||||
#include "ai_local.h"
|
||||
#include "actions.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
|
@ -38,6 +41,462 @@
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Check if the costs are available for the AI.
|
||||
**
|
||||
** Take reserve and already used resources into account.
|
||||
**
|
||||
** @param costs Costs for something.
|
||||
**
|
||||
** @return A bit field of the missing costs.
|
||||
*/
|
||||
local int AiCheckCosts(const int* costs)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
const int* resources;
|
||||
const int* reserve;
|
||||
const int* used;
|
||||
|
||||
err=0;
|
||||
resources=AiPlayer->Player->Resources;
|
||||
reserve=AiPlayer->Reserve;
|
||||
used=AiPlayer->Used;
|
||||
for( i=1; i<MaxCosts; ++i ) {
|
||||
if( resources[i]<costs[i]-reserve[i]-used[i] ) {
|
||||
err|=1<<i;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
** Check if the costs for an unit-type are available for the AI.
|
||||
**
|
||||
** Take reserve and already used resources into account.
|
||||
**
|
||||
** @param costs Costs for something.
|
||||
**
|
||||
** @return A bit field of the missing costs.
|
||||
*/
|
||||
local int AiCheckUnitTypeCosts(const UnitType* type)
|
||||
{
|
||||
return AiCheckCosts(type->Stats[AiPlayer->Player->Player].Costs);
|
||||
}
|
||||
|
||||
/**
|
||||
** Find free building place.
|
||||
**
|
||||
** @param worker Worker to build building.
|
||||
** @param type Type of building.
|
||||
** @param dx Pointer for X position returned.
|
||||
** @param dy Pointer for Y position returned.
|
||||
** @return True if place found, false if no found.
|
||||
*/
|
||||
global int AiFindBuildingPlace(const Unit * worker, const UnitType * type,
|
||||
int *dx, int *dy)
|
||||
{
|
||||
int wx, wy, x, y, addx, addy;
|
||||
int end, state;
|
||||
|
||||
wx = worker->X;
|
||||
wy = worker->Y;
|
||||
x = wx;
|
||||
y = wy;
|
||||
addx = 1;
|
||||
addy = 1;
|
||||
|
||||
state = 0;
|
||||
end = y + addy - 1;
|
||||
for (;;) { // test rectangles arround 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++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 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)
|
||||
&& PlaceReachable(worker, x, y, 1)) {
|
||||
*dx=x;
|
||||
*dy=y;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Check if we can build the building.
|
||||
**
|
||||
** @param type Unit that can build the building.
|
||||
** @param building Building to be build.
|
||||
** @return True if made, false if can't be made.
|
||||
*/
|
||||
local int AiBuildBuilding(const UnitType* type,UnitType* building)
|
||||
{
|
||||
Unit* table[UnitMax];
|
||||
Unit* unit;
|
||||
int nunits;
|
||||
int i;
|
||||
int num;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
DebugLevel0Fn("%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++) {
|
||||
unit = table[i];
|
||||
if (unit->Orders[0].Action != UnitActionBuild
|
||||
&& (unit->OrderCount==1
|
||||
|| unit->Orders[1].Action != UnitActionBuild) ) {
|
||||
table[num++] = unit;
|
||||
}
|
||||
}
|
||||
|
||||
if( !num ) { // No available unit.
|
||||
return 0;
|
||||
}
|
||||
|
||||
DebugLevel0Fn("Have an unit to build :)\n");
|
||||
|
||||
//
|
||||
// Find place on that could be build.
|
||||
//
|
||||
if ( !AiFindBuildingPlace(unit,building,&x,&y) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DebugLevel0Fn("Have a building place :)\n");
|
||||
|
||||
CommandBuildBuilding(unit, x, y, building,FlushCommands);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Check if we can make an unit-type.
|
||||
**
|
||||
** @param type Unit-type that must be made.
|
||||
** @return True if made, false if can't be made.
|
||||
*/
|
||||
local int AiMakeUnit(UnitType* type)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
const int* unit_count;
|
||||
AiUnitTypeTable* const* tablep;
|
||||
const AiUnitTypeTable* table;
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
i=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( AiBuildBuilding(table->Table[i],type) ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Check what must be builded / trained.
|
||||
*/
|
||||
local void AiCheckingWork(void)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
int c;
|
||||
UnitType* type;
|
||||
|
||||
n=AiPlayer->BuildedCount;
|
||||
for( i=0; i<n; ++i ) {
|
||||
if( AiPlayer->UnitTypeBuilded[i].Want
|
||||
>AiPlayer->UnitTypeBuilded[i].Made ) {
|
||||
type=AiPlayer->UnitTypeBuilded[i].Type;
|
||||
DebugLevel0Fn("Must build: %s " _C_ type->Ident);
|
||||
//
|
||||
// Check if resources available.
|
||||
//
|
||||
if( (c=AiCheckUnitTypeCosts(type)) ) {
|
||||
DebugLevel0("- no resources\n");
|
||||
AiPlayer->NeededMask=c;
|
||||
return;
|
||||
} else {
|
||||
DebugLevel0("- enough resources\n");
|
||||
if( AiMakeUnit(type) ) {
|
||||
++AiPlayer->UnitTypeBuilded[i].Made;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- WORKERS/RESOURCES
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Assign worker to mine gold.
|
||||
**
|
||||
** IDEA: If no way to goldmine, we must dig the way.
|
||||
** IDEA: If goldmine is on an other island, we must transport the workers.
|
||||
*/
|
||||
local void AiMineGold(Unit * unit)
|
||||
{
|
||||
Unit *dest;
|
||||
|
||||
DebugLevel3Fn("%d\n", UnitNumber(unit));
|
||||
dest = FindGoldMine(unit, unit->X, unit->Y);
|
||||
if (!dest) {
|
||||
DebugLevel0Fn("goldmine not reachable\n");
|
||||
return;
|
||||
}
|
||||
CommandMineGold(unit, dest,FlushCommands);
|
||||
}
|
||||
|
||||
/**
|
||||
** Assign worker to harvest.
|
||||
*/
|
||||
local int AiHarvest(Unit * unit)
|
||||
{
|
||||
int x, y, addx, addy, i, n, r, wx, wy, bestx, besty, cost;
|
||||
Unit *dest;
|
||||
|
||||
DebugLevel3Fn("%d\n", UnitNumber(unit));
|
||||
x = unit->X;
|
||||
y = unit->Y;
|
||||
addx = unit->Type->TileWidth;
|
||||
addy = unit->Type->TileHeight;
|
||||
r = TheMap.Width;
|
||||
if (r < TheMap.Height) {
|
||||
r = TheMap.Height;
|
||||
}
|
||||
|
||||
// This is correct, but can this be written faster???
|
||||
if ((dest = FindWoodDeposit(unit->Player, x, y))) {
|
||||
NearestOfUnit(dest, x, y, &wx, &wy);
|
||||
DebugLevel3("To %d,%d\n", wx, wy);
|
||||
} else {
|
||||
wx = unit->X;
|
||||
wy = unit->Y;
|
||||
}
|
||||
cost = 99999;
|
||||
IfDebug(bestx = besty = 0; ); // keep the compiler happy
|
||||
|
||||
// FIXME: if we reach the map borders we can go fast up, left, ...
|
||||
--x;
|
||||
while (addx <= r && addy <= r) {
|
||||
for (i = addy; i--; y++) { // go down
|
||||
if (CheckedForestOnMap(x, y)) {
|
||||
n = max(abs(wx - x), abs(wy - y));
|
||||
DebugLevel3("Distance %d,%d %d\n", x, y, n);
|
||||
if (n < cost && PlaceReachable(unit, x, y, 1)) {
|
||||
cost = n;
|
||||
bestx = x;
|
||||
besty = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
++addx;
|
||||
for (i = addx; i--; x++) { // go right
|
||||
if (CheckedForestOnMap(x, y)) {
|
||||
n = max(abs(wx - x), abs(wy - y));
|
||||
DebugLevel3("Distance %d,%d %d\n", x, y, n);
|
||||
if (n < cost && PlaceReachable(unit, x, y, 1)) {
|
||||
cost = n;
|
||||
bestx = x;
|
||||
besty = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
++addy;
|
||||
for (i = addy; i--; y--) { // go up
|
||||
if (CheckedForestOnMap(x, y)) {
|
||||
n = max(abs(wx - x), abs(wy - y));
|
||||
DebugLevel3("Distance %d,%d %d\n", x, y, n);
|
||||
if (n < cost && PlaceReachable(unit, x, y, 1)) {
|
||||
cost = n;
|
||||
bestx = x;
|
||||
besty = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
++addx;
|
||||
for (i = addx; i--; x--) { // go left
|
||||
if (CheckedForestOnMap(x, y)) {
|
||||
n = max(abs(wx - x), abs(wy - y));
|
||||
DebugLevel3("Distance %d,%d %d\n", x, y, n);
|
||||
if (n < cost && PlaceReachable(unit, x, y, 1)) {
|
||||
cost = n;
|
||||
bestx = x;
|
||||
besty = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cost != 99999) {
|
||||
DebugLevel3Fn("wood on %d,%d\n", x, y);
|
||||
CommandHarvest(unit, bestx, besty,FlushCommands);
|
||||
return 1;
|
||||
}
|
||||
++addy;
|
||||
}
|
||||
DebugLevel0Fn("no wood reachable\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Assign workers to collect resources.
|
||||
*/
|
||||
local void AiCollectResources(void)
|
||||
{
|
||||
int c;
|
||||
int i;
|
||||
int n;
|
||||
UnitType** types;
|
||||
Unit* table[UnitMax];
|
||||
int nunits;
|
||||
|
||||
DebugLevel0Fn("%x\n",AiPlayer->NeededMask);
|
||||
|
||||
//
|
||||
// Look through all costs, if needed.
|
||||
//
|
||||
for( c=0; c<OreCost; ++c ) {
|
||||
if( c>=AiHelpers.CollectCount || !AiHelpers.Collect[c]
|
||||
|| !(AiPlayer->NeededMask&(1<<c)) ) {
|
||||
continue;
|
||||
}
|
||||
types=AiHelpers.Collect[c]->Table;
|
||||
n=AiHelpers.Collect[c]->Count;
|
||||
nunits=0;
|
||||
for( i=0; i<n; ++i ) {
|
||||
nunits += FindPlayerUnitsByType(AiPlayer->Player,
|
||||
types[i],table+nunits);
|
||||
}
|
||||
DebugLevel0Fn("%s: units %d\n",DEFAULT_NAMES[c],nunits);
|
||||
|
||||
//
|
||||
// Assign the worker
|
||||
//
|
||||
for( i=0; i<nunits; ++i ) {
|
||||
// Unit is already *very* busy
|
||||
if (table[i]->Orders[0].Action != UnitActionBuild
|
||||
&& (table[i]->OrderCount==1
|
||||
|| table[i]->Orders[1].Action != UnitActionBuild) ) {
|
||||
switch( c ) {
|
||||
case 1:
|
||||
if (table[i]->Orders[0].Action != UnitActionMineGold ) {
|
||||
AiMineGold(table[i]);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (table[i]->Orders[0].Action != UnitActionHarvest ) {
|
||||
AiHarvest(table[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugCheck( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Assign the remaining unit.
|
||||
//
|
||||
for( c=0; c<OreCost; ++c ) {
|
||||
if( c>=AiHelpers.CollectCount || !AiHelpers.Collect[c] ) {
|
||||
continue;
|
||||
}
|
||||
types=AiHelpers.Collect[c]->Table;
|
||||
n=AiHelpers.Collect[c]->Count;
|
||||
nunits=0;
|
||||
for( i=0; i<n; ++i ) {
|
||||
nunits += FindPlayerUnitsByType(AiPlayer->Player,
|
||||
types[i],table+nunits);
|
||||
}
|
||||
DebugLevel0Fn("%s: units %d\n",DEFAULT_NAMES[c],nunits);
|
||||
|
||||
//
|
||||
// Assign the worker
|
||||
//
|
||||
for( i=0; i<nunits; ++i ) {
|
||||
// Unit is already busy
|
||||
if (table[i]->Orders[0].Action != UnitActionStill
|
||||
|| table[i]->OrderCount>1 ) {
|
||||
continue;
|
||||
}
|
||||
switch( c ) {
|
||||
case 1:
|
||||
AiMineGold(table[i]);
|
||||
break;
|
||||
case 2:
|
||||
AiHarvest(table[i]);
|
||||
break;
|
||||
default:
|
||||
DebugCheck( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Add unit-type request to resource manager.
|
||||
**
|
||||
|
@ -48,7 +507,7 @@ global void AiAddUnitTypeRequest(UnitType* type,int count)
|
|||
{
|
||||
int n;
|
||||
|
||||
DebugLevel0Fn("%s %d\n",type->Ident,count);
|
||||
DebugLevel0Fn("%s %d\n" _C_ type->Ident _C_ count);
|
||||
if( AiPlayer->UnitTypeBuilded ) {
|
||||
n=AiPlayer->BuildedCount;
|
||||
AiPlayer->UnitTypeBuilded=realloc(AiPlayer->UnitTypeBuilded,
|
||||
|
@ -68,6 +527,14 @@ global void AiAddUnitTypeRequest(UnitType* type,int count)
|
|||
*/
|
||||
global void AiResourceManager(void)
|
||||
{
|
||||
//
|
||||
// Check if something needs to be build / trained.
|
||||
//
|
||||
AiCheckingWork();
|
||||
//
|
||||
// Collect resources.
|
||||
//
|
||||
AiCollectResources();
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
local void AiHelperSetupTable(int* count,AiUnitTypeTable*** table,int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
++n;
|
||||
if( n>(i=*count) ) {
|
||||
if( *table ) {
|
||||
|
@ -127,8 +127,9 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
UnitType* base;
|
||||
UnitType* type;
|
||||
Upgrade* upgrade;
|
||||
int cost;
|
||||
|
||||
IfDebug( type=NULL; upgrade=NULL; ); // keep the compiler happy
|
||||
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);
|
||||
|
@ -146,6 +147,8 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
what=2;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("research")) ) {
|
||||
what=3;
|
||||
} else if( gh_eq_p(value,gh_symbol2scm("collect")) ) {
|
||||
what=4;
|
||||
} else {
|
||||
fprintf(stderr,"unknown tag\n");
|
||||
continue;
|
||||
|
@ -163,7 +166,7 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0Fn("%s\n",base->Name);
|
||||
DebugLevel0Fn("%s\n" _C_ base->Name);
|
||||
free(str);
|
||||
|
||||
//
|
||||
|
@ -180,7 +183,26 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0Fn("> %s\n",upgrade->Ident);
|
||||
DebugLevel0Fn("> %s\n" _C_ upgrade->Ident);
|
||||
} else if( what==4 ) {
|
||||
if( !strcmp(DEFAULT_NAMES[1],str) ) {
|
||||
cost=1;
|
||||
} else if( !strcmp(DEFAULT_NAMES[2],str) ) {
|
||||
cost=2;
|
||||
} else if( !strcmp(DEFAULT_NAMES[3],str) ) {
|
||||
cost=3;
|
||||
} else if( !strcmp(DEFAULT_NAMES[4],str) ) {
|
||||
cost=4;
|
||||
} else if( !strcmp(DEFAULT_NAMES[5],str) ) {
|
||||
cost=5;
|
||||
} else if( !strcmp(DEFAULT_NAMES[6],str) ) {
|
||||
cost=6;
|
||||
} else {
|
||||
fprintf(stderr,"unknown cost %s\n",str);
|
||||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0Fn("> %s\n" _C_ str);
|
||||
} else {
|
||||
type=UnitTypeByIdent(str);
|
||||
if( !type ) {
|
||||
|
@ -188,7 +210,7 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
free(str);
|
||||
continue;
|
||||
}
|
||||
DebugLevel0Fn("> %s\n",type->Name);
|
||||
DebugLevel0Fn("> %s\n" _C_ type->Name);
|
||||
}
|
||||
free(str);
|
||||
|
||||
|
@ -219,6 +241,11 @@ local SCM CclDefineAiHelper(SCM list)
|
|||
AiHelperInsert(
|
||||
AiHelpers.Research+(upgrade-Upgrades),base);
|
||||
break;
|
||||
case 4: // collect
|
||||
AiHelperSetupTable(
|
||||
&AiHelpers.CollectCount,&AiHelpers.Collect,cost);
|
||||
AiHelperInsert( AiHelpers.Collect+cost,base);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +272,7 @@ local SCM CclDefineAi(SCM list)
|
|||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0Fn("%s\n",str);
|
||||
DebugLevel0Fn("%s\n" _C_ str);
|
||||
aitype->Name=str;
|
||||
|
||||
//
|
||||
|
@ -254,7 +281,7 @@ local SCM CclDefineAi(SCM list)
|
|||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0Fn("%s\n",str);
|
||||
DebugLevel0Fn("%s\n" _C_ str);
|
||||
aitype->Race=str;
|
||||
|
||||
//
|
||||
|
@ -263,7 +290,7 @@ local SCM CclDefineAi(SCM list)
|
|||
value=gh_car(list);
|
||||
list=gh_cdr(list);
|
||||
str=gh_scm2newstr(value,NULL);
|
||||
DebugLevel0Fn("%s\n",str);
|
||||
DebugLevel0Fn("%s\n" _C_ str);
|
||||
aitype->Class=str;
|
||||
|
||||
//
|
||||
|
@ -424,7 +451,8 @@ local SCM CclAiWait(SCM value)
|
|||
return SCM_BOOL_F;
|
||||
}
|
||||
// units available?
|
||||
DebugLevel0Fn("%d,%d\n",AiPlayer->Player->UnitTypesCount[type->Type],autt->Count);
|
||||
DebugLevel0Fn("%d,%d\n"
|
||||
_C_ AiPlayer->Player->UnitTypesCount[type->Type] _C_ autt->Count);
|
||||
if( AiPlayer->Player->UnitTypesCount[type->Type]>=autt->Count ) {
|
||||
return SCM_BOOL_F;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ struct _player_ {
|
|||
char* Name; /// name of non computer
|
||||
|
||||
unsigned Type; /// type of player (human,computer,...)
|
||||
char* RaceName; /// name of race.
|
||||
unsigned Race; /// race of player (orc,human,...)
|
||||
unsigned AiNum; /// AI for computer
|
||||
|
||||
|
|
|
@ -159,6 +159,7 @@ global void CreatePlayer(char* name,int type)
|
|||
player->Name=name;
|
||||
player->Type=type;
|
||||
player->Race=PlayerRaceHuman;
|
||||
player->RaceName="human";
|
||||
player->Team=team;
|
||||
player->Enemy=0;
|
||||
player->Allied=0;
|
||||
|
@ -262,6 +263,18 @@ global void CreatePlayer(char* name,int type)
|
|||
global void PlayerSetSide(Player* player,int side)
|
||||
{
|
||||
player->Race=side;
|
||||
switch( side ) {
|
||||
case PlayerRaceHuman:
|
||||
player->RaceName="human";
|
||||
break;
|
||||
case PlayerRaceOrc:
|
||||
player->RaceName="orc";
|
||||
break;
|
||||
default:
|
||||
DebugLevel0Fn("Unsupported side %d\n",side);
|
||||
player->RaceName="oops";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue