[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stratagus-CVS] stratagus/src/ai ai_building.c ai_force.c ai_lo...
From: |
address@hidden |
Subject: |
[Stratagus-CVS] stratagus/src/ai ai_building.c ai_force.c ai_lo... |
Date: |
14 Dec 2003 20:44:32 +1100 |
CVSROOT: /home/strat
Module name: stratagus
Changes by: <address@hidden> 03/12/14 20:44:31
Modified files:
src/ai : ai_building.c ai_force.c ai_local.h
Log message:
Tabs, Cleanup
Patches:
Index: stratagus/src/ai/ai_building.c
diff -u stratagus/src/ai/ai_building.c:1.44 stratagus/src/ai/ai_building.c:1.45
--- stratagus/src/ai/ai_building.c:1.44 Tue Nov 25 21:34:15 2003
+++ stratagus/src/ai/ai_building.c Sun Dec 14 20:44:31 2003
@@ -3,14 +3,14 @@
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
// 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. */
+/address@hidden ai_building.c - AI building functions. */
//
-// (c) Copyright 2001-2003 by Lutz Sammer
+// (c) Copyright 2001-2004 by Lutz Sammer
//
// 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,580 +26,582 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_building.c,v 1.44 2003/11/25 10:34:15 pludov Exp $
+// $Id: ai_building.c,v 1.45 2003/12/14 09:44:31 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include "stratagus.h"
-
#include "unit.h"
#include "map.h"
#include "pathfinder.h"
#include "ai_local.h"
/*----------------------------------------------------------------------------
--- Variables
+-- Variables
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Check if the surrounding are free. Depending on the value of flag, it
will check :
-** 0: the building will not block any way
-** 1: all surrounding is free
-**
-** @param worker Worker to build.
-** @param type Type of building.
-** @param x X map tile position for the building.
-** @param y Y map tile position for the building.
-** @param flag 0: only check that building will not block anything.
+** Check if the surrounding are free. Depending on the value of flag, it will
check :
+** 0: the building will not block any way
+** 1: all surrounding is free
+**
+** @param worker Worker to build.
+** @param type Type of building.
+** @param x X map tile position for the building.
+** @param y Y map tile position for the building.
+** @param flag 0: only check that building will not block anything.
**
-** @return True if the surrounding is free, false otherwise.
+** @return True if the surrounding is free, false otherwise.
**
-** @note Can be faster written.
+** @note Can be faster written.
*/
local int AiCheckSurrounding(const Unit * worker, const UnitType * type, int
x, int y, int flag)
{
- static int dirs[5][2] = {{1,0},{0,1},{-1,0},{0,-1},{0,0}};
- int surrounding[1024]; // Max criconference for building
- int surroundingnb;
- int x0, y0, x1, y1;
- int i;
- int lastval;
- int dir;
- int obstacle;
-
- x0 = x - 1;
- y0 = y - 1;
- x1 = x0 + type->TileWidth + 1;
- y1 = y0 + type->TileWidth + 1;
-
-
- x = x0;
- y = y0;
- dir = -1;
- surroundingnb = 0;
- while (dir < 4) {
- if ((unsigned)x < (unsigned)TheMap.Width && (unsigned)y <
(unsigned)TheMap.Height) {
- if (worker && x == worker->X && y == worker->Y) {
- surrounding[surroundingnb++] = 1;
- } else if (TheMap.Fields[x + y * TheMap.Width].Flags &
- (MapFieldUnpassable | MapFieldWall | MapFieldRocks |
- MapFieldForest | MapFieldBuilding)) {
- surrounding[surroundingnb++] = 0;
- } else{
- // Can pass there
- surrounding[surroundingnb++] = (TheMap.Fields[x + y *
TheMap.Width].Flags &
- (MapFieldWaterAllowed + MapFieldCoastAllowed +
MapFieldLandAllowed)) != 0;;
- }
+ static int dirs[5][2] = {{1,0},{0,1},{-1,0},{0,-1},{0,0}};
+ int surrounding[1024]; // Max criconference for building
+ int surroundingnb;
+ int x0, y0, x1, y1;
+ int i;
+ int lastval;
+ int dir;
+ int obstacle;
+
+ x0 = x - 1;
+ y0 = y - 1;
+ x1 = x0 + type->TileWidth + 1;
+ y1 = y0 + type->TileWidth + 1;
+
+
+ x = x0;
+ y = y0;
+ dir = -1;
+ surroundingnb = 0;
+ while (dir < 4) {
+ if ((unsigned)x < (unsigned)TheMap.Width && (unsigned)y <
(unsigned)TheMap.Height) {
+ if (worker && x == worker->X && y == worker->Y) {
+ surrounding[surroundingnb++] = 1;
+ } else if (TheMap.Fields[x + y * TheMap.Width].Flags &
+ (MapFieldUnpassable |
MapFieldWall | MapFieldRocks |
+ MapFieldForest |
MapFieldBuilding)) {
+ surrounding[surroundingnb++] = 0;
+ } else{
+ // Can pass there
+ surrounding[surroundingnb++] = (TheMap.Fields[x
+ y * TheMap.Width].Flags &
+ (MapFieldWaterAllowed +
MapFieldCoastAllowed + MapFieldLandAllowed)) != 0;;
+ }
+ } else {
+ surrounding[surroundingnb++] = 0;
+ }
+
+ if ((x == x0 || x == x1) && (y == y0 || y == y1)) {
+ dir++;
+ }
+
+ x += dirs[dir][0];
+ y += dirs[dir][1];
+ }
+
+ lastval = surrounding[surroundingnb - 1];
+ obstacle = 0;
+ for (i = 0 ; i < surroundingnb; i++) {
+ if (lastval && !surrounding[i]) {
+ obstacle++;
+ }
+ lastval = surrounding[i];
+ }
+
+ if (obstacle == 0) {
+ obstacle = !surrounding[0];
+ }
+
+ if (flag) {
+ return obstacle == 0;
+ } else if (!type->ShoreBuilding) {
+ return obstacle < 2;
} else {
- surrounding[surroundingnb++] = 0;
+ // Shore building haves at least 2 obstacles : sea->ground &
ground->sea
+ return obstacle < 3;
}
-
- if ((x == x0 || x == x1) && (y == y0 || y == y1)) {
- dir++;
- }
-
- x += dirs[dir][0];
- y += dirs[dir][1];
- }
-
- lastval = surrounding[surroundingnb - 1];
- obstacle = 0;
- for (i = 0 ; i < surroundingnb; i++) {
- if (lastval && !surrounding[i]) {
- obstacle++;
- }
- lastval = surrounding[i];
- }
-
- if (obstacle == 0) {
- obstacle = !surrounding[0];
- }
-
- if (flag) {
- return obstacle == 0;
- } else if (!type->ShoreBuilding) {
- return obstacle < 2;
- } else {
- // Shore building haves at least 2 obstacles : sea->ground & ground->sea
- return obstacle < 3;
- }
}
/**
-** Find free building place. (flood fill version)
+** Find free building place. (flood fill version)
+**
+** @param worker Worker to build building.
+** @param type Type of building.
+** @param ox Original X position to try building
+** @param oy Original Y position to try building
+** @param dx Pointer for X position returned.
+** @param dy Pointer for Y position returned.
+** @param flag Flag if surrounding must be free.
**
-** @param worker Worker to build building.
-** @param type Type of building.
-** @param ox Original X position to try building
-** @param oy Original Y position to try building
-** @param dx Pointer for X position returned.
-** @param dy Pointer for Y position returned.
-** @param flag Flag if surrounding must be free.
-** @return True if place found, false if no found.
+** @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)
+ 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 {
- unsigned short X;
- unsigned short Y;
- } *points;
- int size;
- int x;
- int y;
- int rx;
- int ry;
- int mask;
- int wp;
- int rp;
- int ep;
- int i;
- int w;
- unsigned char *m;
- unsigned char *matrix;
-
- 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, flag))) {
- *dx = x;
- *dy = y;
- free(points);
- return 1;
- }
- //
- // Make movement matrix.
- //
- matrix = CreateMatrix();
- w = TheMap.Width + 2;
-
- 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) {
- points[1].X = x + type->TileWidth - 1;
- points[1].Y = y + type->TileWidth - 1;
- ep = wp = 2; // start with two points
- } else {
- ep = wp = 1; // start with one point
- }
- matrix += w + w + 2;
- rp = 0;
- matrix[x + y * w] = 1; // mark start point
-
- //
- // 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
- x = rx + xoffset[i];
- y = ry + yoffset[i];
- m = matrix + x + y * w;
- if (*m) { // already checked
- continue;
- }
+ 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;
+ int size;
+ int x;
+ int y;
+ int rx;
+ int ry;
+ int mask;
+ int wp;
+ int rp;
+ int ep;
+ int i;
+ int w;
+ unsigned char *m;
+ unsigned char *matrix;
- DebugLevel3Fn("Checking to build %s(%s) at %d,%d\n" _C_
- type->Ident _C_ type->Name _C_ x _C_ y);
+ points = malloc(TheMap.Width * TheMap.Height);
+ size = TheMap.Width * TheMap.Height / sizeof (*points);
- //
- // Look if we can build here.
- //
- if (CanBuildUnitType(worker, type, x, y) &&
- (/*!flag ||*/ AiCheckSurrounding(worker, type, x, y,
flag))) {
- *dx = x;
- *dy = y;
- free(points);
- DebugLevel3Fn("Found a building place!!!\n");
- return 1;
- }
-
- 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;
- }
- }
+ x = ox;
+ y = oy;
+ //
+ // Look if we can build at current place.
+ //
+ if (CanBuildUnitType(worker, type, x, y) &&
+ (/*!flag || */AiCheckSurrounding(worker, type, x, y, flag))) {
+ *dx = x;
+ *dy = y;
+ free(points);
+ return 1;
+ }
+ //
+ // Make movement matrix.
+ //
+ matrix = CreateMatrix();
+ w = TheMap.Width + 2;
- if (++rp >= size) { // round about
- rp = 0;
- }
+ 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) {
+ points[1].X = x + type->TileWidth - 1;
+ points[1].Y = y + type->TileWidth - 1;
+ ep = wp = 2; // start with two points
+ } else {
+ ep = wp = 1; // start with one point
}
+ matrix += w + w + 2;
+ rp = 0;
+ matrix[x + y * w] = 1; // mark start point
//
- // Continue with next frame.
+ // Pop a point from stack, push all neighbours which could be entered.
//
- if (rp == wp) { // unreachable, no more points available
- break;
+ 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;
+ }
+
+ 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, flag))) {
+ *dx = x;
+ *dy = y;
+ free(points);
+ DebugLevel3Fn("Found a building
place!!!\n");
+ return 1;
+ }
+
+ 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;
+ }
+ }
+
+ if (++rp >= size) { // round about
+ rp = 0;
+ }
+ }
+
+ //
+ // Continue with next frame.
+ //
+ if (rp == wp) { // unreachable, no more points available
+ break;
+ }
+ ep = wp;
}
- ep = wp;
- }
- free(points);
+ free(points);
- return 0;
+ return 0;
}
/**
-** Find building place for hall. (flood fill version)
+** Find building place for hall. (flood fill version)
**
-** The best place:
-** 1) near to goldmine.
-** !2) near to wood.
-** !3) near to worker and must be reachable.
-** 4) no enemy near it.
-** 5) no hall already near
-** !6) enough gold in mine
-**
-** @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.
+** The best place:
+** 1) near to goldmine.
+** !2) near to wood.
+** !3) near to worker and must be reachable.
+** 4) no enemy near it.
+** 5) no hall already near
+** !6) enough gold in mine
+**
+** @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 not found.
+** @return True if place found, false if not found.
**
-** @todo FIXME: This is slow really slow, using two flood fills, is not
-** a perfect solution.
+** @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)
{
- 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;
- int size;
- int x;
- int y;
- int rx;
- int ry;
- int mask;
- int wp;
- int rp;
- int ep;
- int i;
- int w;
- 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));
-
- //
- // Make movement matrix. FIXME: can create smaller matrix.
- //
- morg = MakeMatrix();
- w = TheMap.Width + 2;
- matrix = morg + 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(worker);
-
- //
- // 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
- x = rx + xoffset[i];
- y = ry + yoffset[i];
- m = matrix + x + y * w;
- if (*m) { // already checked
- continue;
- }
- //
- // Look if there is a mine
- //
- if ((mine = ResourceOnMap(x, y, GoldCost))) {
- int buildings;
- int j;
- int minx;
- int maxx;
- int miny;
- int maxy;
- int nunits;
- Unit *units[UnitMax];
-
- buildings = 0;
-
- //
- // Check units around mine
- //
- minx = mine->X - 5;
- if (minx < 0) {
- minx = 0;
- }
- miny = mine->Y - 5;
- if (miny < 0) {
- miny = 0;
- }
- maxx = mine->X + mine->Type->TileWidth + 5;
- if (maxx > TheMap.Width) {
- maxx = TheMap.Width;
- }
- maxy = mine->Y + mine->Type->TileHeight + 5;
- 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)) {
- break;
- }
- // 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) {
- ++buildings;
- if (buildings == 2) {
- break;
- }
+ 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;
+ int size;
+ int x;
+ int y;
+ int rx;
+ int ry;
+ int mask;
+ int wp;
+ int rp;
+ int ep;
+ int i;
+ int w;
+ 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));
+
+ //
+ // Make movement matrix. FIXME: can create smaller matrix.
+ //
+ morg = MakeMatrix();
+ w = TheMap.Width + 2;
+ matrix = morg + 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(worker);
+
+ //
+ // 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
+ x = rx + xoffset[i];
+ y = ry + yoffset[i];
+ m = matrix + x + y * w;
+ if (*m) { // already checked
+ continue;
+ }
+ //
+ // Look if there is a mine
+ //
+ if ((mine = ResourceOnMap(x, y, GoldCost))) {
+ int buildings;
+ int j;
+ int minx;
+ int maxx;
+ int miny;
+ int maxy;
+ int nunits;
+ Unit *units[UnitMax];
+
+ buildings = 0;
+
+ //
+ // Check units around mine
+ //
+ minx = mine->X - 5;
+ if (minx < 0) {
+ minx = 0;
+ }
+ miny = mine->Y - 5;
+ if (miny < 0) {
+ miny = 0;
+ }
+ maxx = mine->X + mine->Type->TileWidth
+ 5;
+ if (maxx > TheMap.Width) {
+ maxx = TheMap.Width;
+ }
+ maxy = mine->Y + mine->Type->TileHeight
+ 5;
+ 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)) {
+ break;
+ }
+ // 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) {
+ ++buildings;
+ if (buildings == 2) {
+ break;
+ }
+ }
+ }
+ if (j == nunits) {
+ if
(AiFindBuildingPlace2(worker, type, x, y, dx, dy, 0)) {
+ free(morg);
+ free(points);
+ return 1;
+ }
+ }
+ }
+
+ 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;
+ }
}
- }
- if (j == nunits) {
- if (AiFindBuildingPlace2(worker, type, x, y, dx, dy,
0)) {
- free(morg);
- free(points);
- return 1;
+ if (++rp >= size) { // round about
+ rp = 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;
+ //
+ // Continue with next frame.
+ //
+ if (rp == wp) { // unreachable, no more points available
+ break;
}
- }
- if (++rp >= size) { // round about
- rp = 0;
- }
+ ep = wp;
}
- //
- // Continue with next frame.
- //
- if (rp == wp) { // unreachable, no more points available
- break;
- }
- ep = wp;
- }
-
- free(morg);
- free(points);
- return 0;
+ free(morg);
+ free(points);
+ return 0;
}
/**
-** Find free building place for lumber mill. (flood fill version)
+** Find free building place for lumber mill. (flood fill version)
+**
+** @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.
**
-** @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 not found.
+** @return True if place found, false if not found.
**
-** @todo FIXME: This is slow really slow, using two flood fills, is not
-** a perfect solution.
+** @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)
+ 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 {
- unsigned short X;
- unsigned short Y;
- } *points;
- int size;
- int x;
- int y;
- int rx;
- int ry;
- int mask;
- int wp;
- int rp;
- int ep;
- int i;
- int w;
- 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));
-
- //
- // Make movement matrix.
- //
- morg = MakeMatrix();
- w = TheMap.Width + 2;
- matrix = morg + 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(worker);
-
- //
- // 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;
- }
- //
- // Look if there is wood
- //
- if (ForestOnMap(x, y)) {
- if (AiFindBuildingPlace2(worker, type, x, y, dx, dy, 1)) {
- free(morg);
- free(points);
- return 1;
- }
- }
+ 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;
+ int size;
+ int x;
+ int y;
+ int rx;
+ int ry;
+ int mask;
+ int wp;
+ int rp;
+ int ep;
+ int i;
+ int w;
+ 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));
- 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;
- }
- }
+ //
+ // Make movement matrix.
+ //
+ morg = MakeMatrix();
+ w = TheMap.Width + 2;
+ matrix = morg + 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
- if (++rp >= size) { // round about
- rp = 0;
- }
- }
+ mask = UnitMovementMask(worker);
//
- // Continue with next frame.
+ // Pop a point from stack, push all neightbors which could be entered.
//
- if (rp == wp) { // unreachable, no more points available
- break;
+ 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;
+ }
+ //
+ // 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
+ *m = 1;
+ points[wp].X = x; // push the point
+ points[wp].Y = y;
+ if (++wp >= size) { // round about
+ wp = 0;
+ }
+ } else { // unreachable
+ *m = 99;
+ }
+ }
+
+ if (++rp >= size) { // round about
+ rp = 0;
+ }
+ }
+
+ //
+ // Continue with next frame.
+ //
+ if (rp == wp) { // unreachable, no more points available
+ break;
+ }
+ ep = wp;
}
- ep = wp;
- }
- free(morg);
- free(points);
- return 0;
+ free(morg);
+ free(points);
+ return 0;
}
/**
-** Find free building place.
+** 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.
+** @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.
**
-** @todo Better and faster way to find building place of oil platforms
-** Special routines for special buildings.
+** @return True if place found, false if no found.
+**
+** @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)
{
- //
- // 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)) {
- return 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);
+ //
+ // 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)) {
+ return 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);
- // return 0;
+ // return 0;
}
//@}
Index: stratagus/src/ai/ai_force.c
diff -u stratagus/src/ai/ai_force.c:1.43 stratagus/src/ai/ai_force.c:1.44
--- stratagus/src/ai/ai_force.c:1.43 Fri Nov 21 03:48:11 2003
+++ stratagus/src/ai/ai_force.c Sun Dec 14 20:44:31 2003
@@ -1,16 +1,16 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
// 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. */
+/address@hidden ai_force.c - AI force functions. */
//
-// (c) Copyright 2001-2003 by Lutz Sammer
+// (c) Copyright 2001-2004 by Lutz Sammer
//
// 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,12 +26,12 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_force.c,v 1.43 2003/11/20 16:48:11 pludov Exp $
+// $Id: ai_force.c,v 1.44 2003/12/14 09:44:31 wizzard Exp $
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include <stdio.h>
@@ -39,958 +39,985 @@
#include <string.h>
#include "stratagus.h"
-
#include "unittype.h"
#include "unit.h"
#include "ai_local.h"
#include "actions.h"
#include "map.h"
#include "depend.h"
-
#include "pathfinder.h"
/*----------------------------------------------------------------------------
--- Variables
+-- Variables
----------------------------------------------------------------------------*/
-global int UnitTypeEquivs[UnitTypeMax + 1];/// equivalence between unittypes
+global int UnitTypeEquivs[UnitTypeMax + 1]; /// equivalence between unittypes
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
/**
-** Remove any equivalence between unittypes
+** Remove any equivalence between unittypes
*/
global void AiResetUnitTypeEquiv(void)
{
- int i;
- for (i = 0; i <= UnitTypeMax; i++) {
- UnitTypeEquivs[i] = i;
- }
+ int i;
+
+ for (i = 0; i <= UnitTypeMax; i++) {
+ UnitTypeEquivs[i] = i;
+ }
}
/**
-** Make two unittypes equivalents from the AI's point of vue
+** Make two unittypes equivalents from the AI's point of vue
**
-** @param a the first unittype
-** @param b the second unittype
+** @param a the first unittype
+** @param b the second unittype
*/
-global void AiNewUnitTypeEquiv(UnitType * a,UnitType * b)
+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;
+ int find;
+ int replace;
+ int 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
+** 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)
**
-** @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
+** @return the number of unittype found
*/
-global int AiFindUnitTypeEquiv(const UnitType * unittype,int * result)
+global int AiFindUnitTypeEquiv(const UnitType* unittype, int* result)
{
- int i;
- int search;
- int count;
+ int i;
+ int search;
+ int count;
- search = UnitTypeEquivs[unittype->Type];
- count = 0;
+ search = UnitTypeEquivs[unittype->Type];
+ count = 0;
- for (i = 0; i < UnitTypeMax + 1; i++) {
- if (UnitTypeEquivs[i] == search) {
- // Found one
- result[count] = i;
- count++;
+ for (i = 0; i < UnitTypeMax + 1; ++i) {
+ if (UnitTypeEquivs[i] == search) {
+ // Found one
+ result[count] = i;
+ count++;
+ }
}
- }
- return 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... )
+** 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 usabelTypes int array which will hold the result. (Size
UnitTypeMax+1)
**
-** @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
+** @return the number of unittype found
*/
-global int AiFindAvailableUnitTypeEquiv(const UnitType * unittype,int *
usableTypes)
+global int AiFindAvailableUnitTypeEquiv(const UnitType* unittype, int*
usableTypes)
{
- int usableTypesCount;
- int i, j;
- int tmp;
- int playerid;
- int bestlevel, curlevel;
+ int usableTypesCount;
+ int i;
+ int j;
+ int tmp;
+ int playerid;
+ int bestlevel;
+ int curlevel;
- // 1 - Find equivalents
- usableTypesCount = AiFindUnitTypeEquiv(unittype, usableTypes);
+ // 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++;
+ // 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;
+ // 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;
- }
+ // 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;
+ }
+ }
}
- }
- DebugLevel3Fn("prefered order for %s is " _C_ unittype->Ident);
- for (i = 0; i < usableTypesCount; i++) {
- DebugLevel3(" %s" _C_ UnitTypes[usableTypes[i]]->Ident);
- }
- DebugLevel3("\n");
-
- return usableTypesCount;
+ DebugLevel3Fn("prefered order for %s is " _C_ unittype->Ident);
+ for (i = 0; i < usableTypesCount; i++) {
+ DebugLevel3(" %s" _C_ UnitTypes[usableTypes[i]]->Ident);
+ }
+ DebugLevel3("\n");
+
+ return usableTypesCount;
}
/**
-** Count available units by type in a force.
+** 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
+** 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)
+global void AiForceCountUnits(int force, int* countByType)
{
- int type;
- AiUnit *aiunit;
- memset(countByType, 0, sizeof (int) * (UnitTypeMax + 1));
+ int type;
+ AiUnit* aiunit;
+
+ memset(countByType, 0, sizeof (int) * (UnitTypeMax + 1));
- aiunit = AiPlayer->Force[force].Units;
- while (aiunit) {
- if ((!aiunit->Unit->Destroyed) &&
- (aiunit->Unit->HP) && (aiunit->Unit->Orders[0].Action !=
UnitActionDie)) {
- type = UnitTypeEquivs[aiunit->Unit->Type->Type];
+ aiunit = AiPlayer->Force[force].Units;
+ while (aiunit) {
+ if ((!aiunit->Unit->Destroyed) &&
+ (aiunit->Unit->HP) && (aiunit->Unit->Orders[0].Action
!= UnitActionDie)) {
+ type = UnitTypeEquivs[aiunit->Unit->Type->Type];
- DebugCheck((type < 0) || (type > UnitTypeMax));
- countByType[type]++;
+ DebugCheck((type < 0) || (type > UnitTypeMax));
+ countByType[type]++;
+ }
+ aiunit = aiunit->Next;
}
- aiunit = aiunit->Next;
- }
}
/**
-** Substract wanted unit in a force. ( from the result of
AiForceCountUnits )
+** 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
**
-** @param force the force to count unit
-** @param countByType array[UnitTypeMax+1] of int
-** @return The number of missing unit
+** @return The number of missing unit
*/
-global int AiForceSubstractWant(int force, int *countByType)
+global int AiForceSubstractWant(int force, int* countByType)
{
- int missing;
- int type;
- const AiUnitType *aitype;
+ int missing;
+ int type;
+ const AiUnitType* aitype;
- missing = 0;
- aitype = AiPlayer->Force[force].UnitTypes;
- while (aitype) {
- type=UnitTypeEquivs[aitype->Type->Type];
- countByType[type] -= aitype->Want;
- if (countByType[type] < 0) {
- missing -= countByType[type];
+ missing = 0;
+ aitype = AiPlayer->Force[force].UnitTypes;
+ while (aitype) {
+ type=UnitTypeEquivs[aitype->Type->Type];
+ countByType[type] -= aitype->Want;
+ if (countByType[type] < 0) {
+ missing -= countByType[type];
+ }
+ aitype = aitype->Next;
}
- aitype = aitype->Next;
- }
- return missing;
+ return missing;
}
/**
-** Complete dst force with units from src force.
+** Complete dst force with units from src force.
**
-** FIXME : should check that unit can reach dst force's hotspot.
+** @todo 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
+** @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 type;
- int counter[UnitTypeMax + 1];
- int missing;
-
- //
- // Count units in dest force.
- //
- AiForceCountUnits(dst, counter);
-
- //
- // Check the dest force requirements.
- //
- if ((missing = AiForceSubstractWant(dst, counter)) == 0) {
- // Nothing missing => mark completed & abort.
- AiPlayer->Force[dst].Completed = 1;
- return;
- }
-
- // Iterate the source force, moving needed units into dest...
- prev = &AiPlayer->Force[src].Units;
- while (*prev) {
- aiunit = (*prev);
- 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[type]++;
- missing--;
-
- if (!missing) {
+ AiUnit** prev;
+ AiUnit* aiunit;
+ int type;
+ int counter[UnitTypeMax + 1];
+ int missing;
+
+ //
+ // Count units in dest force.
+ //
+ AiForceCountUnits(dst, counter);
+
+ //
+ // Check the dest force requirements.
+ //
+ if ((missing = AiForceSubstractWant(dst, counter)) == 0) {
+ // Nothing missing => mark completed & abort.
AiPlayer->Force[dst].Completed = 1;
return;
- }
- } else {
- // Just iterate
- prev = &aiunit->Next;
}
- }
+
+ // Iterate the source force, moving needed units into dest...
+ prev = &AiPlayer->Force[src].Units;
+ while (*prev) {
+ aiunit = (*prev);
+ 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[type]++;
+ missing--;
+
+ if (!missing) {
+ AiPlayer->Force[dst].Completed = 1;
+ return;
+ }
+ } else {
+ // Just iterate
+ prev = &aiunit->Next;
+ }
+ }
}
/**
-** Complete dst force with overflow units in src force.
+** Complete dst force with overflow units in src force.
**
-** FIXME : should check that unit can reach dst force's hotspot.
+** @todo 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
+** @param src the force from which units are taken
+** @param dst the force into which units go
*/
global void AiForceTransfertOverflow(int src, int dst)
{
- AiUnit **prev;
- AiUnit *aiunit;
- int type;
- int counter[UnitTypeMax + 1];
- int overflow[UnitTypeMax + 1];
- int missing;
-
- //
- // Count units in dest force.
- //
- AiForceCountUnits(dst, counter);
-
- //
- // Check the dest force requirements.
- //
- if ((missing = AiForceSubstractWant(dst, counter)) == 0) {
- // Nothing missing => abort.
- AiPlayer->Force[dst].Completed = 1;
- return;
- }
-
- //
- // Find overflow units in src force
- //
- AiForceCountUnits(src, overflow);
- AiForceSubstractWant(src, overflow);
-
- // Iterate the source force, moving needed units into dest...
- prev = &AiPlayer->Force[src].Units;
- while (*prev) {
- aiunit = (*prev);
- type = UnitTypeEquivs[aiunit->Unit->Type->Type];
- if (counter[type] < 0 && overflow[type] > 0) {
- // move in dest force...
- *prev = aiunit->Next;
-
- aiunit->Next = AiPlayer->Force[dst].Units;
- AiPlayer->Force[dst].Units = aiunit;
-
- counter[type]++;
- overflow[type]--;
- missing--;
- if (!missing) {
+ AiUnit** prev;
+ AiUnit* aiunit;
+ int type;
+ int counter[UnitTypeMax + 1];
+ int overflow[UnitTypeMax + 1];
+ int missing;
+
+ //
+ // Count units in dest force.
+ //
+ AiForceCountUnits(dst, counter);
+
+ //
+ // Check the dest force requirements.
+ //
+ if ((missing = AiForceSubstractWant(dst, counter)) == 0) {
+ // Nothing missing => abort.
AiPlayer->Force[dst].Completed = 1;
return;
- }
- } else {
- // Just iterate
- prev = &aiunit->Next;
}
- }
+
+ //
+ // Find overflow units in src force
+ //
+ AiForceCountUnits(src, overflow);
+ AiForceSubstractWant(src, overflow);
+
+ // Iterate the source force, moving needed units into dest...
+ prev = &AiPlayer->Force[src].Units;
+ while (*prev) {
+ aiunit = (*prev);
+ type = UnitTypeEquivs[aiunit->Unit->Type->Type];
+ if (counter[type] < 0 && overflow[type] > 0) {
+ // move in dest force...
+ *prev = aiunit->Next;
+
+ aiunit->Next = AiPlayer->Force[dst].Units;
+ AiPlayer->Force[dst].Units = aiunit;
+
+ ++counter[type];
+ --overflow[type];
+ --missing;
+ if (!missing) {
+ AiPlayer->Force[dst].Completed = 1;
+ return;
+ }
+ } else {
+ // Just iterate
+ prev = &aiunit->Next;
+ }
+ }
}
/**
-** Ai clean units in a force.
+** Ai clean units in a force.
**
-** @param force Force number.
+** @param force Force number.
*/
global void AiCleanForce(int force)
{
- 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) {
- RefsDecrease(aiunit->Unit);
- *prev = aiunit->Next;
- free(aiunit);
- continue;
- } else if (!aiunit->Unit->HP || aiunit->Unit->Orders[0].Action ==
UnitActionDie) {
- RefsDecrease(aiunit->Unit);
- *prev = aiunit->Next;
- free(aiunit);
- continue;
- }
- prev = &aiunit->Next;
- }
-
- //
- // 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) {
- DebugLevel3Fn("Release unit %s\n" _C_
aiunit->Unit->Type->Ident);
- counter[aiunit->Unit->Type->Type]--;
- RefsDecrease(aiunit->Unit);
- *prev = aiunit->Next;
-
- // Move this unit somewhere else...
- AiAssignToForce(aiunit->Unit);
- free(aiunit);
-
- continue;
- }
- prev = &aiunit->Next;
- }
- }
+ AiUnit** prev;
+ AiUnit* aiunit;
+ int counter[UnitTypeMax + 1];
+ int unit_released;
- DebugLevel3Fn("%d complete %d\n" _C_ force _C_
AiPlayer->Force[force].Completed);
+ //
+ // Release all killed units.
+ //
+ prev = &AiPlayer->Force[force].Units;
+ while ((aiunit = *prev)) {
+ if (aiunit->Unit->Destroyed) {
+ RefsDecrease(aiunit->Unit);
+ *prev = aiunit->Next;
+ free(aiunit);
+ continue;
+ } else if (!aiunit->Unit->HP || aiunit->Unit->Orders[0].Action
== UnitActionDie) {
+ RefsDecrease(aiunit->Unit);
+ *prev = aiunit->Next;
+ free(aiunit);
+ continue;
+ }
+ prev = &aiunit->Next;
+ }
+
+ //
+ // 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) {
+ DebugLevel3Fn("Release unit %s\n" _C_
aiunit->Unit->Type->Ident);
+ counter[aiunit->Unit->Type->Type]--;
+ RefsDecrease(aiunit->Unit);
+ *prev = aiunit->Next;
+
+ // 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);
}
/**
**
-** Remove everything in the given force
+** Remove everything in the given force
**
-** @param force the force to erase
+** @param force the force to erase
*/
global void AiEraseForce(int force)
{
- AiUnitType *aiut, *next;
- AiUnit *aiu, *next_u;
+ AiUnitType* aiut;
+ AiUnitType* next;
+ AiUnit* aiu;
+ AiUnit* next_u;
- aiut = AiPlayer->Force[force].UnitTypes;
- while (aiut) {
- next = aiut->Next;
- free(aiut);
- aiut = next;
- }
- AiPlayer->Force[force].UnitTypes = 0;
+ 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) {
- // Decrease usage count
- RefsDecrease(aiu->Unit);
+ aiu = AiPlayer->Force[force].Units;
+ while (aiu) {
+ // Decrease usage count
+ RefsDecrease(aiu->Unit);
- next_u = aiu->Next;
- free(aiu);
- aiu = next_u;
- }
- AiPlayer->Force[force].Units = 0;
+ next_u = aiu->Next;
+ free(aiu);
+ aiu = next_u;
+ }
+ AiPlayer->Force[force].Units = 0;
- AiAssignFreeUnitsToForce();
+ AiAssignFreeUnitsToForce();
}
/**
-** Cleanup units in forces.
+** Cleanup units in forces.
*/
global void AiCleanForces(void)
{
- int force;
+ int force;
- //
- // Release all killed units.
- //
- for (force = 0; force < AI_MAX_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
+** 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 & update completed flag, false
otherwise.
+** @param force Force to be checked.
+** @param type Type to check.
+**
+** @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)
{
- int counter[UnitTypeMax + 1];
- int missing;
- int realtype;
+ int counter[UnitTypeMax + 1];
+ int missing;
+ int realtype;
- //
- // Count units in force.
- //
- AiForceCountUnits(force, counter);
+ //
+ // Count units in force.
+ //
+ AiForceCountUnits(force, counter);
- //
- // Look what should be in the force.
- //
- missing = AiForceSubstractWant(force, counter);
- AiPlayer->Force[force].Completed = (missing == 0);
+ //
+ // Look what should be in the force.
+ //
+ missing = AiForceSubstractWant(force, counter);
+ AiPlayer->Force[force].Completed = (missing == 0);
- realtype = UnitTypeEquivs[type->Type];
+ realtype = UnitTypeEquivs[type->Type];
- if (counter[realtype] < 0) {
- // Ok we will put this unit in this force !
- // Just one missing ?
- if ((counter[realtype] == -1) && (missing == 1)) {
- AiPlayer->Force[force].Completed = 1;
+ if (counter[realtype] < 0) {
+ // Ok we will put this unit in this force !
+ // Just one missing ?
+ if ((counter[realtype] == -1) && (missing == 1)) {
+ AiPlayer->Force[force].Completed = 1;
+ }
+ return 1;
}
- return 1;
- }
- return 0;
+ return 0;
}
/**
-** Ai assign unit to force.
+** Ai assign unit to force.
**
-** @param unit Unit to assign to force.
+** @param unit Unit to assign to force.
*/
-global void AiAssignToForce(Unit * unit)
+global void AiAssignToForce(Unit* unit)
{
- AiUnit *aiunit;
- int force;
+ AiUnit* aiunit;
+ int force;
- //
- // 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;
- }
+ //
+ // 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 = malloc(sizeof (*aiunit));
- aiunit->Next = AiPlayer->Force[force].Units;
- AiPlayer->Force[force].Units = aiunit;
- aiunit->Unit = unit;
- RefsIncrease(unit);
- return;
+ if (AiCheckBelongsToForce(force, unit->Type)) {
+ aiunit = malloc(sizeof (*aiunit));
+ aiunit->Next = AiPlayer->Force[force].Units;
+ AiPlayer->Force[force].Units = aiunit;
+ aiunit->Unit = unit;
+ RefsIncrease(unit);
+ 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;
- RefsIncrease(unit);
+ // 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;
+ RefsIncrease(unit);
}
/**
-** Try to complete a force, using all available units
+** Try to complete a force, using all available units
**
-** @param force the force to complete
+** @param force the force to complete
*/
global void AiForceComplete(int force)
{
- int j, overflowonly;;
+ int j;
+ int overflowonly;;
- for (j = 0; j < AI_MAX_FORCES; ++j) {
- // Don't complete with self ...
- if (j == force) {
- continue;
- }
+ 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;
- }
+ // 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)) {
+ // Honor "populate from attack"
+ if ((AiPlayer->Force[force].PopulateMode ==
AiForcePopulateFromAttack) &&
+ (!AiPlayer->Force[j].Role == AiForceRoleAttack)) {
+
+ // Use overflow from force 0...
+ if (j == 0) {
+ overflowonly = 1;
+ } else {
+ continue;
+ }
+ } else {
+ overflowonly = 0;
+ }
- // Use overflow from force 0...
- if (j == 0) {
- overflowonly = 1;
- } else {
- continue;
- }
- } else {
- overflowonly = 0;
- }
+ // Complete the force automatically...
+ if (!overflowonly) {
+ AiForceTransfert(j, force);
+ } else {
+ AiForceTransfertOverflow(j, force);
+ }
- // Complete the force automatically...
- if (!overflowonly) {
- AiForceTransfert(j, force);
- } else {
- AiForceTransfertOverflow(j, force);
+ if (AiPlayer->Force[force].Completed) {
+ break;
+ }
}
+}
- if (AiPlayer->Force[force].Completed) {
- break;
+/**
+** Enrole a unit in the specific force.
+** Does not take equivalence into account
+**
+** @todo 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.
+**
+** @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 successful)
+*/
+global int AiEnroleSpecificUnitType(int force, UnitType* ut, int count)
+{
+ AiForce* dstForce;
+ int src_force;
+ AiUnit* 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) {
+ if (aiUnit->Unit->Type->Type == ut->Type) {
+ *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;
}
/**
-** 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.
+** Make sure that current force requirement are superior to actual assigned
unit count
**
-** @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)
+local void AiFinalizeForce(int force)
{
- 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;
+ int i;
+ int type;
+ int unitcount[UnitTypeMax + 1];
+ AiUnitType *aitype;
+
+ AiForceCountUnits(force, unitcount);
+ aitype = AiPlayer->Force[force].UnitTypes;
+ while (aitype) {
+ type = UnitTypeEquivs[aitype->Type->Type];
+ if (unitcount[type] > aitype->Want) {
+ aitype->Want = unitcount[type];
+ unitcount[type] = 0;
+ }
+ aitype = aitype->Next;
}
- aiUnit = AiPlayer->Force[src_force].Units;
- prev = &AiPlayer->Force[src_force].Units;
- while (aiUnit) {
- if (aiUnit->Unit->Type->Type == ut->Type) {
- *prev = aiUnit->Next;
-
- // Move to dstForce
- AiPlayer->Force[src_force].Completed = 0;
- aiUnit->Next = dstForce->Units;
- dstForce->Units = aiUnit;
-
- count--;
- if (!count) {
- return 0;
+ 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;
}
- }
- prev = &aiUnit->Next;
- aiUnit = aiUnit->Next;
}
- }
- return count;
}
/**
-** Make sure that current force requirement are superior to actual
assigned unit count
+** 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.
*/
-local void AiFinalizeForce(int force)
+global int AiCreateSpecificForce(int* power, int* unittypes, int
unittypescount)
{
- int i;
- int type;
- int unitcount[UnitTypeMax + 1];
- AiUnitType *aitype;
-
- AiForceCountUnits(force, unitcount);
- aitype = AiPlayer->Force[force].UnitTypes;
- while (aitype) {
- type = UnitTypeEquivs[aitype->Type->Type];
- if (unitcount[type] > aitype->Want) {
- aitype->Want = unitcount[type];
- unitcount[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];
- 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++) {
- // 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);
- unittypeforce = (unittypeforce ? unittypeforce : 1);
-
- // Try to respond to the most important power ...
- maxadd = 1 + curpower[maxPower] / unittypeforce;
-
- lefttoadd = AiEnroleSpecificUnitType(AiScript->ownForce, ut,
maxadd);
-
- // Nothing added, continue.
- if (lefttoadd == maxadd) {
- continue;
- }
-
- // FIXME : don't always use the right unittype here...
- curpower[maxPower] -= (maxadd - lefttoadd) * unittypeforce;
-
- forceUpdated = 1;
-
+ UnitType *ut;
+ int id;
+ int maxPower;
+ int forceUpdated;
+ 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));
- if (curpower[maxPower] <= 0) {
- AiFinalizeForce(AiScript->ownForce);
- return 0;
+ (curpower[0] > curpower[2] ? 0 : 2) : (curpower[1] >
curpower[2] ? 1 : 2));
+
+ for (id = 0; id < unittypescount; id++) {
+ // 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);
+ unittypeforce = (unittypeforce ? unittypeforce
: 1);
+
+ // Try to respond to the most important power
...
+ maxadd = 1 + curpower[maxPower] / unittypeforce;
+
+ lefttoadd =
AiEnroleSpecificUnitType(AiScript->ownForce, ut, maxadd);
+
+ // 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);
- // Sth missing...
- AiFinalizeForce(AiScript->ownForce);
- return -1;
+ } while (forceUpdated);
+ // Sth missing...
+ AiFinalizeForce(AiScript->ownForce);
+ return -1;
}
/**
-** Assign free units to force.
+** Assign free units to force.
*/
global void AiAssignFreeUnitsToForce(void)
{
- Unit *table[UnitMax];
- int n;
- int f;
- int i;
- Unit *unit;
- const AiUnit *aiunit;
-
- AiCleanForces();
-
- n = AiPlayer->Player->TotalNumUnits;
- memcpy(table, AiPlayer->Player->Units, sizeof (*AiPlayer->Player->Units) *
n);
-
- //
- // Remove all units already in forces.
- //
- for (f = 0; f < AI_MAX_FORCES; ++f) {
- aiunit = AiPlayer->Force[f].Units;
- while (aiunit) {
- unit = aiunit->Unit;
- for (i = 0; i < n; ++i) {
- if (table[i] == unit) {
- table[i] = table[--n];
+ const AiUnit* aiunit;
+ Unit* table[UnitMax];
+ Unit* unit;
+ int n;
+ int f;
+ int i;
+
+ AiCleanForces();
+
+ n = AiPlayer->Player->TotalNumUnits;
+ memcpy(table, AiPlayer->Player->Units, sizeof(*AiPlayer->Player->Units)
* n);
+
+ //
+ // Remove all units already in forces.
+ //
+ for (f = 0; f < AI_MAX_FORCES; ++f) {
+ aiunit = AiPlayer->Force[f].Units;
+ while (aiunit) {
+ unit = aiunit->Unit;
+ for (i = 0; i < n; ++i) {
+ if (table[i] == unit) {
+ table[i] = table[--n];
+ }
+ }
+ aiunit = aiunit->Next;
}
- }
- aiunit = aiunit->Next;
}
- }
- //
- // 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]);
+ }
}
- }
}
/**
-** Attack at position with force.
+** Attack at position with force.
**
-** @param force Force number to attack with.
-** @param x X tile map position to be attacked.
-** @param y Y tile map position to be attacked.
+** @param force Force number to attack with.
+** @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)
{
- const AiUnit *aiunit;
+ const AiUnit* aiunit;
- AiCleanForce(force);
+ AiCleanForce(force);
- if ((aiunit = AiPlayer->Force[force].Units)) {
- AiPlayer->Force[force].Attacking = 1;
+ 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);
- } else {
- CommandMove(aiunit->Unit, x, y, 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);
+ }
- aiunit = aiunit->Next;
+ aiunit = aiunit->Next;
+ }
}
- }
}
/**
-** Try to group units in a force. Units are grouped arround the closest
units of the hotspot.
+** Try to group units in a force. Units are grouped arround the closest units
of the hotspot.
**
-** @param force the force to send home.
+** @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;
+ const AiUnit *aiunit;
+ const AiUnit *groupunit;
+ int unitdst, groupdst;
- // Step 1 : find the unit closest to the force hotspot
- AiCleanForce(force);
-
- groupdst = -1;
+ // Step 1 : find the unit closest to the force hotspot
+ AiCleanForce(force);
- groupunit = 0;
+ groupdst = -1;
- aiunit = AiPlayer->Force[force].Units;
+ groupunit = 0;
- // Sanity : don't group force with only one unit !
- if ((!aiunit) || (!aiunit->Next)) {
- return;
- }
+ aiunit = AiPlayer->Force[force].Units;
- while (aiunit) {
- unitdst = abs(aiunit->Unit->X - targetX) + abs(aiunit->Unit->Y -
targetY);
- if ((unitdst < groupdst) || (!groupunit)) {
- groupunit = aiunit;
- groupdst = unitdst;
+ // Sanity : don't group force with only one unit !
+ if ((!aiunit) || (!aiunit->Next)) {
+ return;
}
- aiunit = aiunit->Next;
- }
+ while (aiunit) {
+ unitdst = abs(aiunit->Unit->X - targetX) + abs(aiunit->Unit->Y
- targetY);
+ if ((unitdst < groupdst) || (!groupunit)) {
+ groupunit = aiunit;
+ groupdst = unitdst;
+ }
- AiPlayer->Force[force].Attacking = 1;
+ 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);
+ // 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;
}
- aiunit = aiunit->Next;
- }
}
/**
-** Find the closest home batiment.
-** ground is 0 : land, 1 : air, 2 : water ( as UnitType::UnitType )
+** 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
**
-** @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
+** @todo Find in the player unit's the closer to
*/
-local void AiFindHome(int ground, int x, int y, int *rsltx, int *rslty)
+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;
+ // Find in the player unit's the closer to
+ *rsltx = AiPlayer->Player->StartX;
+ *rslty = AiPlayer->Player->StartY;
}
/**
-** Try to send this force home
+** Try to send this force home
**
-** @param force the force to send home.
+** @param force the force to send home.
*/
global void AiSendForceHome(int force)
{
- const AiUnit *aiunit;
- int i, type;
- int x[3], y[3];
+ const AiUnit* aiunit;
+ int i;
+ int type;
+ int x[3];
+ int y[3];
- AiCleanForce(force);
- aiunit = AiPlayer->Force[force].Units;
+ AiCleanForce(force);
+ aiunit = AiPlayer->Force[force].Units;
- for (i = 0; i < 3; i++) {
- x[i] = -1;
- y[i] = -1;
- }
+ for (i = 0; i < 3; i++) {
+ x[i] = -1;
+ y[i] = -1;
+ }
- while (aiunit) {
- type = aiunit->Unit->Type->UnitType;
+ while (aiunit) {
+ type = aiunit->Unit->Type->UnitType;
- if (x[type] == -1) {
- AiFindHome(type, aiunit->Unit->X, aiunit->Unit->Y, &x[type],
&y[type]);
- }
+ if (x[type] == -1) {
+ AiFindHome(type, aiunit->Unit->X, aiunit->Unit->Y,
&x[type], &y[type]);
+ }
- CommandMove(aiunit->Unit, x[type], y[type], FlushCommands);
+ CommandMove(aiunit->Unit, x[type], y[type], FlushCommands);
- aiunit = aiunit->Next;
- }
+ aiunit = aiunit->Next;
+ }
}
-global void AiForceHelpMe(int force, const Unit * attacker, Unit * defender)
+/**
+** Ai Force Action when unit/force requires assistance
+**
+** @param force Force Number (FIXME: which?)
+** @param attacker attacking unit
+** @param defender defending unit
+*/
+global void AiForceHelpMe(int force, const Unit* attacker, Unit* defender)
{
- AiForce *aiForce;
- AiUnit *rescue;
-
- aiForce = AiPlayer->Force + force;
+ AiForce* aiForce;
+ AiUnit* rescue;
- // Don't handle special cases
- if (aiForce->State > 0) {
- return;
- }
+ aiForce = AiPlayer->Force + force;
- switch (aiForce->HelpMode) {
- case AiForceDontHelp:
- // Don't react (easy)
- return;
-
- case AiForceHelpForce:
- // Send all idles units in the attacked force for 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;
+ // Don't handle special cases
+ if (aiForce->State > 0) {
+ return;
+ }
- default:
- // the usual way : create a defense force, send it, ...
- AiFindDefendScript(attacker->X, attacker->Y);
- break;
- }
+ switch (aiForce->HelpMode) {
+ case AiForceDontHelp:
+ // Don't react (easy)
+ return;
+
+ case AiForceHelpForce:
+ // Send all idles units in the attacked force for 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;
+ }
}
/**
-** Entry point of force manager, perodic called.
+** Entry point of force manager, perodic called.
+**
+** @todo FIXME : is this really needed anymore
*/
global void AiForceManager(void)
{
- // FIXME : is this really needed anymore
- AiAssignFreeUnitsToForce();
+ AiAssignFreeUnitsToForce();
}
//@}
Index: stratagus/src/ai/ai_local.h
diff -u stratagus/src/ai/ai_local.h:1.47 stratagus/src/ai/ai_local.h:1.48
--- stratagus/src/ai/ai_local.h:1.47 Sat Dec 13 17:06:10 2003
+++ stratagus/src/ai/ai_local.h Sun Dec 14 20:44:31 2003
@@ -1,14 +1,14 @@
-// _________ __ __
+// _________ __ __
// / _____// |_____________ _/ |______ ____ __ __ ______
// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
-// \/ \/ \//_____/ \/
+// \/ \/ \//_____/ \/
// ______________________ ______________________
// 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. */
+/address@hidden ai_local.h - The local AI header file. */
//
// (c) Copyright 2000-2003 by Lutz Sammer and Antonis Chaniotis.
//
@@ -26,7 +26,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
-// $Id: ai_local.h,v 1.47 2003/12/13 06:06:10 jsalmon3 Exp $
+// $Id: ai_local.h,v 1.48 2003/12/14 09:44:31 wizzard Exp $
#ifndef __AI_LOCAL_H__
#define __AI_LOCAL_H__
@@ -34,7 +34,7 @@
//@{
/*----------------------------------------------------------------------------
--- Includes
+-- Includes
----------------------------------------------------------------------------*/
#include "ccl.h"
@@ -43,448 +43,426 @@
#include "upgrade.h"
/*----------------------------------------------------------------------------
--- Declarations
+-- Declarations
----------------------------------------------------------------------------*/
/**
-** Ai Type typedef
+** Ai Type typedef
*/
typedef struct _ai_type_ AiType;
/**
-** Ai Type structure.
+** 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
-
- // nice flags
- //unsigned char AllExplored : 1;/// Ai sees unexplored area
- //unsigned char AllVisbile : 1;/// Ai sees invisibile area
+ char* Name; /// Name of this ai
+ char* Race; /// for this race
+ char* Class; /// class of this ai
+
+ // nice flags
+#if 0
+ unsigned char AllExplored : 1; /// Ai sees unexplored area
+ unsigned char AllVisbile : 1; /// Ai sees invisibile area
+#endif
#if defined(USE_GUILE) || defined(USE_SIOD)
- SCM Script; /// Main script (gc-protected!)
+ SCM Script; /// Main script (gc-protected!)
#elif defined(USE_LUA)
#endif
};
/**
-** AI unit-type table with counter in front.
+** AI unit-type table with counter in front.
*/
typedef struct _ai_unittype_table_ {
- int Count; /// elements in table
- UnitType* Table[1]; /// the table
+ int Count; /// elements in table
+ UnitType* Table[1]; /// the table
} AiUnitTypeTable;
/**
-** Ai unit-type typedef
+** Ai unit-type typedef
*/
typedef struct _ai_unit_type_ AiUnitType;
/**
-** Ai unit-type in a force.
+** 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
+ AiUnitType* Next; /// next unit-type
+ int Want; /// number of this unit-type wanted
+ UnitType* Type; /// unit-type self
};
/**
-** AIUnit typedef
+** AIUnit typedef
*/
typedef struct _ai_unit_ AiUnit;
/**
-** Ai unit in a force.
+** Ai unit in a force.
*/
struct _ai_unit_ {
- AiUnit* Next; /// next unit
- Unit* Unit; /// unit self
+ AiUnit* Next; /// next unit
+ Unit* Unit; /// unit self
};
/**
-** Roles for forces
+** Roles for forces
*/
enum _ai_force_role_ {
- AiForceRoleAttack, /// Force should attack
- AiForceRoleDefend, /// Force should defend
+ AiForceRoleAttack, /// Force should attack
+ AiForceRoleDefend, /// Force should defend
};
/**
-** Ways to populate a force
+** 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
+ 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
+** 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, ...
+ AiForceDontHelp, /// Don't react to attack on this force
+ AiForceHelpForce, /// Send idle units to defend
+ AiForceHelpFull /// Create a defend force, send it, ...
};
/**
-** Define an AI force.
+** Define an AI force.
**
-** A force is a group of units belonging together.
+** A force is a group of units belonging together.
*/
typedef 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
+ 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
} AiForce;
/**
-** AI build queue typedef
+** AI build queue typedef
*/
typedef struct _ai_build_queue_ AiBuildQueue;
/**
-** AI build queue.
+** AI build queue.
**
-** List of orders for the resource manager to handle
+** 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
+ AiBuildQueue* Next; /// next request
+ int Want; /// requested number
+ int Made; /// builded number
+ UnitType* Type; /// unit-type
};
/**
-** AI running script ( with state, ... )
+** AI running script ( with state, ... )
*/
typedef struct _ai_running_script_ {
#if defined(USE_GUILE) || defined(USE_SIOD)
- SCM Script; /// Script executed
+ SCM Script; /// Script executed
#elif defined(USE_LUA)
#endif
- unsigned long SleepCycles; /// Cycles to sleep
- char ident[10]; /// Debugging !
- int HotSpotX; /// Hot spot ( for defense,
attack, ... )
- int HotSpotY;
- int HotSpotRay;
-
- int ownForce; /// A force ID ( the n° of the
script... )
+ unsigned long SleepCycles; /// Cycles to sleep
+ char ident[10]; /// Debugging !
+ int HotSpotX; /// Hot spot ( for defense, attack, ... )
+ int HotSpotY;
+ int HotSpotRay;
+ int ownForce; /// A force ID ( the n° of the script... )
+ int* gauges; /// Gauges values ( initially 0 )
- // Total number of resource gauges
+ // Total number of resource gauges
#define RESOURCE_COUNT 3
- // Total number of forces gauges
-#define FORCE_COUNT 11
+ // Total number of forces gauges
+#define FORCE_COUNT 11
#define GAUGE_NB (3 + (RESOURCE_COUNT * 2) + (FORCE_COUNT * 6))
- int* gauges; /// Gauges values ( initially 0 )
} AiRunningScript;
/**
-** Ai script action
+** Ai script action
**
-** Describe each different attack/defend scheme.
+** Describe each different attack/defend scheme.
**
-** Linked list.
+** Linked list.
*/
typedef struct _ai_script_action_ {
#if defined(USE_GUILE) || defined(USE_SIOD)
- SCM Action; /// Scheme description, in the
form :
- /// '((name evaluate-lambda run-script)
... )
+ SCM Action; /// Scheme description, in the form :
+
/// '((name evaluate-lambda run-script) ... )
#elif defined(USE_LUA)
#endif
- int Defensive; /// Is this action usable for
defense
- int Offensive; /// Is this action usable for
attack
+ 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
+ /// TODO : hotspot_kind : set if the hotspot should contain path from
base
} AiScriptAction;
/**
-** AiActionEvaluation typedef
+** AiActionEvaluation typedef
*/
typedef struct _ai_action_evaluation_ AiActionEvaluation;
/**
-** Ai action evaluation
+** Ai action evaluation
+**
+** Each AiPlayer periodically evaluation an attack action.
**
-** 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.
**
-** 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.
-**
*/
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
-
- int hotSpotValue; /// Value of the hotspot (
total points to get... )
-
- int value; /// Result of the evaluation (
resources needed... )
-
- AiActionEvaluation* Next; /// Next in linked list
+ 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
+ int hotSpotValue; /// Value of the hotspot ( total
points to get... )
+ int value; /// Result of the evaluation (
resources needed... )
+ AiActionEvaluation* Next; /// Next in linked list
};
typedef struct _ai_exploration_request_ AiExplorationRequest;
struct _ai_exploration_request_ {
- int X; /// x pos on map
- int Y; /// y pos on map
- int Mask; /// mask ( ex: MapFieldLandUnit
)
- AiExplorationRequest*Next; /// Next in linked list
+ int X; /// x pos on map
+ int Y; /// y pos on map
+ int Mask; /// mask ( ex: MapFieldLandUnit )
+ AiExplorationRequest* Next; /// Next in linked list
};
typedef struct _ai_transport_request_ AiTransportRequest;
struct _ai_transport_request_ {
- Unit* Unit;
-
- Order Order;
-
- AiTransportRequest* Next;
-};
+ Unit* Unit;
+ Order Order;
+ AiTransportRequest* Next;
+};
/**
-** AI variables.
+** 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, ... )
+ 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];/// All running scripts
+ AiRunningScript Scripts[AI_MAX_RUNNING_SCRIPTS]; /// All running scripts
- // Ai "memory"
-#define AI_MEMORY_SIZE 30 /// Max number of keept evaluation ( =>
30 sec )
- AiActionEvaluation* FirstEvaluation;/// begining of linked list of
evaluation
- AiActionEvaluation* LastEvaluation; /// end of linked list of
evaluation
- int EvaluationCount;/// size of linked list of
evaluation
-
- 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 NeedSupply; /// Flag need food
-
- AiExplorationRequest*FirstExplorationRequest;/// Requests for exploration
- unsigned int LastExplorationGameCycle;/// When did the last explore
occur ?
-
- AiTransportRequest* TransportRequests;
-
- unsigned int LastCanNotMoveGameCycle;
- /// 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];
+ // Ai "memory"
+#define AI_MEMORY_SIZE 30 /// Max number of keept evaluation ( => 30 sec )
+ AiActionEvaluation* FirstEvaluation; /// begining of linked list of
evaluation
+ AiActionEvaluation* LastEvaluation; /// end of linked list of
evaluation
+ int EvaluationCount; /// size of linked list of
evaluation
+ 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 NeedSupply; /// Flag need food
+
+ AiExplorationRequest* FirstExplorationRequest; /// Requests for
exploration
+ unsigned int LastExplorationGameCycle; /// When did the last
explore occur ?
+ AiTransportRequest* TransportRequests;
+ unsigned int LastCanNotMoveGameCycle; /// number of elements
in UnitTypeRequests
+ int UnitTypeRequestsCount; /// unit-types to
build/train request,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; /// No. workers that
failed trying to repair a building
+ unsigned TriedRepairWorkers[UnitMax];
} PlayerAi;
/**
-** AI Helper.
+** AI Helper.
**
-** Contains informations needed for the AI. If the AI needs an unit or
-** building or upgrade or spell, it could lookup in this tables to find
-** where it could be trained, builded or researched.
+** Contains informations needed for the AI. If the AI needs an unit or
+** 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_ {
- /**
- ** 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;
- /**
- ** 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;
- /**
- ** 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;
- /**
- ** 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;
- /**
- ** 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;
- /**
- ** 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;
- /**
- ** The index is the unit that should be made, giving a table of all
- ** units/buildings which are equivalent.
- */
- int EquivCount;
- AiUnitTypeTable** Equiv;
+ /**
+ ** 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;
+ /**
+ ** 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;
+ /**
+ ** 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;
+ /**
+ ** 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;
+ /**
+ ** 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;
+ /**
+ ** 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;
+ /**
+ ** The index is the unit that should be made, giving a table of all
+ ** units/buildings which are equivalent.
+ */
+ int EquivCount;
+ AiUnitTypeTable** Equiv;
} AiHelper;
/*----------------------------------------------------------------------------
--- Variables
+-- 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
-#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
+#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
/*----------------------------------------------------------------------------
--- Functions
+-- Functions
----------------------------------------------------------------------------*/
//
-// Resource manager
+// Resource manager
//
- /// Add unit-type request to resource manager
-extern void AiAddUnitTypeRequest(UnitType * type, int count);
- /// Add upgrade-to request to resource manager
-extern void AiAddUpgradeToRequest(UnitType * type);
- /// Add research request to resource manager
-extern void AiAddResearchRequest(Upgrade * upgrade);
- /// Periodic called resource manager handler
+ /// Add unit-type request to resource manager
+extern void AiAddUnitTypeRequest(UnitType* type, int count);
+ /// Add upgrade-to request to resource manager
+extern void AiAddUpgradeToRequest(UnitType* type);
+ /// Add research request to resource manager
+extern void AiAddResearchRequest(Upgrade* upgrade);
+ /// Periodic called resource manager handler
extern void AiResourceManager(void);
- /// Ask the ai to explore around x,y
+ /// Ask the ai to explore around x,y
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
+ /// 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);
+ /// 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
+// Buildings
//
- /// Find nice building place
-extern int AiFindBuildingPlace(const Unit *, const UnitType *, int *, int *);
+ /// Find nice building place
+extern int AiFindBuildingPlace(const Unit*, const UnitType*, int*, int*);
//
-// Forces
+// Forces
//
- /// Cleanup units in force
+ /// Cleanup units in force
extern void AiCleanForces(void);
- /// Cleanup units in the given force
+ /// Cleanup units in the given force
extern void AiCleanForce(int force);
- /// Remove everything in the given force
+ /// Remove everything in the given force
extern void AiEraseForce(int force);
- /// Assign a new unit to a force
-extern void AiAssignToForce(Unit * unit);
- /// Assign a free units to a force
+ /// Assign a new unit to a force
+extern void AiAssignToForce(Unit* unit);
+ /// Assign a free units to a force
extern void AiAssignFreeUnitsToForce(void);
- /// Complete a force with units form another
+ /// Complete a force with units form another
extern void AiForceTransfert(int src, int dst);
- /// Group a force on the nearest unit to target
+ /// Group a force on the nearest unit to target
extern void AiGroupForceNear(int force, int targetx, int targety);
- /// Attack with force at position
+ /// Attack with force at position
extern void AiAttackWithForceAt(int force, int x, int y);
- /// Attack with force
+ /// Attack with force
extern void AiAttackWithForce(int force);
- /// Send force home
+ /// Send force home
extern void AiSendForceHome(int force);
- /// Evaluate the cost to build a force (time to build + resources)
+ /// Evaluate the cost to build a force (time to build + resources)
extern int AiEvaluateForceCost(int force, int total);
- /// Complete a force from existing units.
+ /// 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
+ /// 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
+ /// Force's unit is attacked.
+extern void AiForceHelpMe(int force, const Unit* attacker, Unit* defender);
+ /// Periodic called force manager handler
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);
+ /// 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
-//
- /// Find a wall to attack
-extern int AiFindWall(AiForce * force);
- /// Plan the an attack
-extern int AiPlanAttack(AiForce * force);
- /// Send explorers around the map
+// Plans
+//
+ /// Find a wall to attack
+extern int AiFindWall(AiForce* force);
+ /// Plan the an attack
+extern int AiPlanAttack(AiForce* force);
+ /// Send explorers around the map
extern void AiSendExplorers(void);
//
-// Scripts
+// Scripts
//
/// Run a script ( for the current AiPlayer )
#if defined(USE_GUILE) || defined(USE_SIOD)
@@ -497,39 +475,39 @@
extern void AiPeriodicAttack(void);
//
-// Gauges
+// Gauges
//
- /// Compute gauges for the current RunningScript
+ /// Compute gauges for the current RunningScript
extern void AiComputeCurrentScriptGauges(void);
- /// Output gauges values
+ /// Output gauges values
extern void AiDebugGauges(void);
- /// Give the value of a specific gauge, for the current RunningScript
+ /// Give the value of a specific gauge, for the current RunningScript
extern int AiGetGaugeValue(int gauge);
- /// Find a gauge given its identifier.
+ /// Find a gauge given its identifier.
#if defined(USE_GUILE) || defined(USE_SIOD)
extern int AiFindGaugeId(SCM id);
#elif defined(USE_LUA)
extern int AiFindGaugeId(lua_State* l);
#endif
- /// return the force of the unittype.
-extern int AiUnittypeForce(UnitType * unitType);
+ /// return the force of the unittype.
+extern int AiUnittypeForce(UnitType* unitType);
//
-// Magic
+// Magic
//
- /// Check for magic
+ /// Check for magic
extern void AiCheckMagic(void);
//
-// Ccl helpers
+// Ccl helpers
//
- /// Save/Load a PlayerAi structure ( see ccl_helpers.h for details )
+ /// Save/Load a PlayerAi structure ( see ccl_helpers.h for details )
#if defined(USE_GUILE) || defined(USE_SIOD)
-extern void IOPlayerAiFullPtr(SCM form, void *binaryform, void *para);
+extern void IOPlayerAiFullPtr(SCM form, void* binaryform, void* para);
#elif defined(USE_LUA)
#endif
//@}
-#endif // !__AI_LOCAL_H__
+#endif // !__AI_LOCAL_H__
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Stratagus-CVS] stratagus/src/ai ai_building.c ai_force.c ai_lo...,
address@hidden <=