aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/he/moonbase
diff options
context:
space:
mode:
authorEugene Sandulenko2016-05-26 21:06:43 +0200
committerEugene Sandulenko2016-05-26 21:06:43 +0200
commit2b5ecc4f88a21b673af14849630c598261f3c743 (patch)
tree3332abd0ac0e7dbf5ce611f02ee4be38f843f5c7 /engines/scumm/he/moonbase
parent056c5a7ae71128cbbe55dcf45a8989e71f7d9ae5 (diff)
downloadscummvm-rg350-2b5ecc4f88a21b673af14849630c598261f3c743.tar.gz
scummvm-rg350-2b5ecc4f88a21b673af14849630c598261f3c743.tar.bz2
scummvm-rg350-2b5ecc4f88a21b673af14849630c598261f3c743.zip
SCUMM HE: Wrapped Moonbase AI into a class
Diffstat (limited to 'engines/scumm/he/moonbase')
-rw-r--r--engines/scumm/he/moonbase/ai_defenseunit.cpp86
-rw-r--r--engines/scumm/he/moonbase/ai_defenseunit.h45
-rw-r--r--engines/scumm/he/moonbase/ai_main.cpp190
-rw-r--r--engines/scumm/he/moonbase/ai_main.h203
-rw-r--r--engines/scumm/he/moonbase/ai_targetacquisition.cpp118
-rw-r--r--engines/scumm/he/moonbase/ai_targetacquisition.h6
-rw-r--r--engines/scumm/he/moonbase/ai_traveller.cpp68
-rw-r--r--engines/scumm/he/moonbase/ai_traveller.h5
-rw-r--r--engines/scumm/he/moonbase/ai_tree.cpp17
-rw-r--r--engines/scumm/he/moonbase/ai_tree.h14
-rw-r--r--engines/scumm/he/moonbase/moonbase.cpp4
-rw-r--r--engines/scumm/he/moonbase/moonbase.h4
12 files changed, 398 insertions, 362 deletions
diff --git a/engines/scumm/he/moonbase/ai_defenseunit.cpp b/engines/scumm/he/moonbase/ai_defenseunit.cpp
index ba180bac66..ad9792d0b9 100644
--- a/engines/scumm/he/moonbase/ai_defenseunit.cpp
+++ b/engines/scumm/he/moonbase/ai_defenseunit.cpp
@@ -23,12 +23,13 @@
#include "common/rect.h"
#include "common/util.h"
#include "scumm/he/intern_he.h"
+#include "scumm/he/moonbase/moonbase.h"
#include "scumm/he/moonbase/ai_defenseunit.h"
#include "scumm/he/moonbase/ai_main.h"
namespace Scumm {
-DefenseUnit::DefenseUnit() {
+DefenseUnit::DefenseUnit(AI *ai) : _ai(ai) {
_state = DUS_ON;
_id = -1;
@@ -39,7 +40,7 @@ DefenseUnit::DefenseUnit() {
_cost = 0;
}
-DefenseUnit::DefenseUnit(DefenseUnit *inUnit) {
+DefenseUnit::DefenseUnit(DefenseUnit *inUnit, AI *ai) : _ai(ai) {
_id = inUnit->getID();
_pos.x = inUnit->getPosX();
_pos.y = inUnit->getPosY();
@@ -131,13 +132,13 @@ int AntiAirUnit::selectWeapon(int index) {
case 2:
if (getState() == DUS_OFF) {
- if (getPlayerEnergy() > 6) {
+ if (_ai->getPlayerEnergy() > 6) {
if (!_vm->_rnd.getRandomNumber(3)) {
return ITEM_VIRUS;
}
}
- if (getPlayerEnergy() > 2) {
+ if (_ai->getPlayerEnergy() > 2) {
if (!_vm->_rnd.getRandomNumber(1)) {
return ITEM_SPIKE;
}
@@ -177,8 +178,8 @@ Common::Point *ShieldUnit::createTargetPos(int index, int distance, int weaponTy
case ITEM_CRAWLER:
ratio = MAX(0.0, 1.0 - (static_cast<float>(getRadius()) / static_cast<float>(distance - 20)));
{
- int maxX = getMaxX();
- int maxY = getMaxY();
+ int maxX = _ai->getMaxX();
+ int maxY = _ai->getMaxY();
int thisX = (static_cast<int>(sourceX + ratio * (getPosX() - sourceX)) + maxX) % maxX;
int thisY = (static_cast<int>(sourceY + ratio * (getPosY() - sourceY)) + maxY) % maxY;
targetPos->x = thisX;
@@ -229,8 +230,8 @@ Common::Point *ShieldUnit::createTargetPos(int index, int distance, int weaponTy
int ShieldUnit::selectWeapon(int index) {
warning("Shield weapon select");
- int myUnit = getClosestUnit(getPosX(), getPosY(), getMaxX(), getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 0);
- int dist = getDistance(getPosX(), getPosY(), getHubX(myUnit), getHubY(myUnit));
+ int myUnit = _ai->getClosestUnit(getPosX(), getPosY(), _ai->getMaxX(), _ai->getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 0);
+ int dist = _ai->getDistance(getPosX(), getPosY(), _ai->getHubX(myUnit), _ai->getHubY(myUnit));
if ((dist < (getRadius() - 20)) && (dist > 90)) {
return ITEM_SPIKE;
@@ -239,7 +240,7 @@ int ShieldUnit::selectWeapon(int index) {
switch (index) {
case 0:
if (getState() == DUS_OFF) {
- if (getPlayerEnergy() < 3) {
+ if (_ai->getPlayerEnergy() < 3) {
return ITEM_BOMB;
} else {
return ITEM_SPIKE;
@@ -295,11 +296,11 @@ Common::Point *MineUnit::createTargetPos(int index, int distance, int weaponType
}
int MineUnit::selectWeapon(int index) {
- int myUnit = getClosestUnit(getPosX(), getPosY(), getMaxX(), getCurrentPlayer(), 1, 0, 0, 0);
+ int myUnit = _ai->getClosestUnit(getPosX(), getPosY(), _ai->getMaxX(), _ai->getCurrentPlayer(), 1, 0, 0, 0);
int x = getPosX();
int y = getPosY();
- int dist = getDistance(x, y, getHubX(myUnit), getHubY(myUnit));
+ int dist = _ai->getDistance(x, y, _ai->getHubX(myUnit), _ai->getHubY(myUnit));
if ((getState() == DUS_ON) && (dist < 110)) {
return ITEM_EMP;
@@ -342,17 +343,17 @@ Common::Point *HubUnit::createTargetPos(int index, int distance, int weaponType,
int HubUnit::selectWeapon(int index) {
warning("Hub weapon select");
- int energy = getPlayerEnergy();
+ int energy = _ai->getPlayerEnergy();
if (energy > 6) {
//possibly choose crawler
- if (getBuildingWorth(getID()) > 21) {
+ if (_ai->getBuildingWorth(getID()) > 21) {
return ITEM_CRAWLER;
}
}
//choose betw/ bomb and cluster
- if (getBuildingArmor(getID()) < 1.5) {
+ if (_ai->getBuildingArmor(getID()) < 1.5) {
return ITEM_CLUSTER;
}
@@ -457,7 +458,6 @@ int BridgeUnit::selectWeapon(int index) {
}
}
-
Common::Point *EnergyUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) {
Common::Point *targetPos = new Common::Point;
@@ -491,17 +491,17 @@ Common::Point *EnergyUnit::createTargetPos(int index, int distance, int weaponTy
int EnergyUnit::selectWeapon(int index) {
warning("Energy weapon select");
- int energy = getPlayerEnergy();
+ int energy = _ai->getPlayerEnergy();
if (energy > 6) {
//possibly choose crawler
- if (getBuildingWorth(getID()) > 21) {
+ if (_ai->getBuildingWorth(getID()) > 21) {
return ITEM_CRAWLER;
}
}
//choose betw/ bomb and cluster
- if (getBuildingArmor(getID()) < 1.5) {
+ if (_ai->getBuildingArmor(getID()) < 1.5) {
return ITEM_CLUSTER;
}
@@ -547,17 +547,17 @@ Common::Point *OffenseUnit::createTargetPos(int index, int distance, int weaponT
int OffenseUnit::selectWeapon(int index) {
warning("Offense weapon select");
- int energy = getPlayerEnergy();
+ int energy = _ai->getPlayerEnergy();
if (energy > 6) {
//possibly choose crawler
- if (getBuildingWorth(getID()) > 21) {
+ if (_ai->getBuildingWorth(getID()) > 21) {
return ITEM_CRAWLER;
}
}
//choose betw/ bomb and cluster
- if (getBuildingArmor(getID()) < 1.5) {
+ if (_ai->getBuildingArmor(getID()) < 1.5) {
return ITEM_CLUSTER;
}
@@ -597,13 +597,13 @@ Common::Point *CrawlerUnit::createTargetPos(int index, int distance, int weaponT
int CrawlerUnit::selectWeapon(int index) {
warning("Crawler weapon select");
- int myUnit = getClosestUnit(getPosX(), getPosY(), getMaxX(), getCurrentPlayer(), 1, 0, 0, 0);
- int dist = getDistance(getHubX(myUnit), getHubY(myUnit), getPosX(), getPosY());
+ int myUnit = _ai->getClosestUnit(getPosX(), getPosY(), _ai->getMaxX(), _ai->getCurrentPlayer(), 1, 0, 0, 0);
+ int dist = _ai->getDistance(_ai->getHubX(myUnit), _ai->getHubY(myUnit), getPosX(), getPosY());
int x = getPosX();
int y = getPosY();
- int energy = getPlayerEnergy();
- int terrain = getTerrain(x, y);
+ int energy = _ai->getPlayerEnergy();
+ int terrain = _ai->getTerrain(x, y);
if (terrain != TERRAIN_TYPE_WATER) {
if ((energy > 2) && (dist < 220)) {
@@ -628,61 +628,61 @@ int CrawlerUnit::selectWeapon(int index) {
return SKIP_TURN;
}
-AntiAirUnit::AntiAirUnit() {
+AntiAirUnit::AntiAirUnit(AI *ai) : DefenseUnit(ai) {
setRadius(190);
setArmor(3);
setCost(1);
}
-ShieldUnit::ShieldUnit() {
+ShieldUnit::ShieldUnit(AI *ai) : DefenseUnit(ai) {
setRadius(170);
setArmor(3);
setCost(7);
}
-MineUnit::MineUnit() {
+MineUnit::MineUnit(AI *ai) : DefenseUnit(ai) {
setRadius(80);
setArmor(1);
setCost(3);
}
-HubUnit::HubUnit() {
+HubUnit::HubUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(5);
setCost(7);
}
-TowerUnit::TowerUnit() {
+TowerUnit::TowerUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(3);
setCost(1);
}
-BridgeUnit::BridgeUnit() {
+BridgeUnit::BridgeUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(3);
setCost(1);
}
-EnergyUnit::EnergyUnit() {
+EnergyUnit::EnergyUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(5);
setCost(7);
}
-OffenseUnit::OffenseUnit() {
+OffenseUnit::OffenseUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(3);
setCost(7);
}
-CrawlerUnit::CrawlerUnit() {
+CrawlerUnit::CrawlerUnit(AI *ai) : DefenseUnit(ai) {
setRadius(1);
setArmor(3);
setCost(7);
}
-AntiAirUnit::AntiAirUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+AntiAirUnit::AntiAirUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -692,7 +692,7 @@ AntiAirUnit::AntiAirUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
}
-ShieldUnit::ShieldUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+ShieldUnit::ShieldUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -701,7 +701,7 @@ ShieldUnit::ShieldUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-MineUnit::MineUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+MineUnit::MineUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -710,7 +710,7 @@ MineUnit::MineUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-HubUnit::HubUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+HubUnit::HubUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -719,7 +719,7 @@ HubUnit::HubUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-TowerUnit::TowerUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+TowerUnit::TowerUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -728,7 +728,7 @@ TowerUnit::TowerUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-BridgeUnit::BridgeUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+BridgeUnit::BridgeUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -737,7 +737,7 @@ BridgeUnit::BridgeUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-EnergyUnit::EnergyUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+EnergyUnit::EnergyUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -746,7 +746,7 @@ EnergyUnit::EnergyUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-OffenseUnit::OffenseUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+OffenseUnit::OffenseUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
@@ -755,7 +755,7 @@ OffenseUnit::OffenseUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
setArmor(inUnit->getArmor());
}
-CrawlerUnit::CrawlerUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) {
+CrawlerUnit::CrawlerUnit(DefenseUnit *inUnit, AI *ai) : DefenseUnit(inUnit, ai) {
setID(inUnit->getID());
setPos(inUnit->getPosX(), inUnit->getPosY());
setDistanceTo(inUnit->getDistanceTo());
diff --git a/engines/scumm/he/moonbase/ai_defenseunit.h b/engines/scumm/he/moonbase/ai_defenseunit.h
index e658fc31ab..a6085da859 100644
--- a/engines/scumm/he/moonbase/ai_defenseunit.h
+++ b/engines/scumm/he/moonbase/ai_defenseunit.h
@@ -25,6 +25,8 @@
namespace Scumm {
+class AI;
+
enum {
DUT_ANTI_AIR = 1,
DUT_SHIELD = 2,
@@ -53,9 +55,12 @@ private:
int _armor;
int _cost;
+protected:
+ AI *_ai;
+
public:
- DefenseUnit();
- DefenseUnit(DefenseUnit *inUnit);
+ DefenseUnit(AI *ai);
+ DefenseUnit(DefenseUnit *inUnit, AI *ai);
virtual ~DefenseUnit();
@@ -90,8 +95,8 @@ class AntiAirUnit : public DefenseUnit {
private:
public:
- AntiAirUnit();
- AntiAirUnit(DefenseUnit *inUnit);
+ AntiAirUnit(AI *ai);
+ AntiAirUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_ANTI_AIR; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -101,8 +106,8 @@ class ShieldUnit : public DefenseUnit {
private:
public:
- ShieldUnit();
- ShieldUnit(DefenseUnit *inUnit);
+ ShieldUnit(AI *ai);
+ ShieldUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_SHIELD; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -112,8 +117,8 @@ class MineUnit : public DefenseUnit {
private:
public:
- MineUnit();
- MineUnit(DefenseUnit *inUnit);
+ MineUnit(AI *ai);
+ MineUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_MINE; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -123,8 +128,8 @@ class HubUnit : public DefenseUnit {
private:
public:
- HubUnit();
- HubUnit(DefenseUnit *inUnit);
+ HubUnit(AI *ai);
+ HubUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_HUB; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -134,8 +139,8 @@ class TowerUnit : public DefenseUnit {
private:
public:
- TowerUnit();
- TowerUnit(DefenseUnit *inUnit);
+ TowerUnit(AI *ai);
+ TowerUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_TOWER; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -145,8 +150,8 @@ class BridgeUnit : public DefenseUnit {
private:
public:
- BridgeUnit();
- BridgeUnit(DefenseUnit *inUnit);
+ BridgeUnit(AI *ai);
+ BridgeUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_BRIDGE; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -156,8 +161,8 @@ class EnergyUnit : public DefenseUnit {
private:
public:
- EnergyUnit();
- EnergyUnit(DefenseUnit *inUnit);
+ EnergyUnit(AI *ai);
+ EnergyUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_ENERGY; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -167,8 +172,8 @@ class OffenseUnit : public DefenseUnit {
private:
public:
- OffenseUnit();
- OffenseUnit(DefenseUnit *inUnit);
+ OffenseUnit(AI *ai);
+ OffenseUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_OFFENSE; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
@@ -178,8 +183,8 @@ class CrawlerUnit : public DefenseUnit {
private:
public:
- CrawlerUnit();
- CrawlerUnit(DefenseUnit *inUnit);
+ CrawlerUnit(AI *ai);
+ CrawlerUnit(DefenseUnit *inUnit, AI *ai);
int getType() const { return DUT_CRAWLER; }
Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY);
int selectWeapon(int index);
diff --git a/engines/scumm/he/moonbase/ai_main.cpp b/engines/scumm/he/moonbase/ai_main.cpp
index d34a5c163a..d7e86d52fb 100644
--- a/engines/scumm/he/moonbase/ai_main.cpp
+++ b/engines/scumm/he/moonbase/ai_main.cpp
@@ -166,10 +166,7 @@ int *storedLaunchAction[5] = {NULL};
const int32 *MCP_params;
-Common::Array<int> lastXCoord[5];
-Common::Array<int> lastYCoord[5];
-
-void resetAI(ScummEngine_v90he *vm) {
+void AI::resetAI(ScummEngine_v90he *vm) {
_vm = vm;
AIstate = STATE_CHOOSE_BEHAVIOR;
@@ -194,7 +191,7 @@ void resetAI(ScummEngine_v90he *vm) {
}
}
-void cleanUpAI() {
+void AI::cleanUpAI() {
warning("----------------------> Cleaning Up AI");
for (int i = 1; i != 5; i++) {
@@ -212,7 +209,7 @@ void cleanUpAI() {
}
}
-void setAIType(const int paramCount, const int32 *params) {
+void AI::setAIType(const int paramCount, const int32 *params) {
if (AItype[params[AI_TYPE_PLAYER_NUM]]) {
delete AItype[params[AI_TYPE_PLAYER_NUM]];
AItype[params[AI_TYPE_PLAYER_NUM]] = NULL;
@@ -229,7 +226,7 @@ void setAIType(const int paramCount, const int32 *params) {
warning("AI for player %d is %s", params[AI_TYPE_PLAYER_NUM], AItype[params[AI_TYPE_PLAYER_NUM]]->getNameString());
}
-int masterControlProgram(const int paramCount, const int32 *params) {
+int AI::masterControlProgram(const int paramCount, const int32 *params) {
static Tree *myTree;
static int index;
@@ -1026,7 +1023,7 @@ int masterControlProgram(const int paramCount, const int32 *params) {
return 1;
}
-int chooseBehavior() {
+int AI::chooseBehavior() {
static int dominantMode = 0;
if (getBuildingStackPtr() < 5)
@@ -1446,7 +1443,7 @@ int chooseBehavior() {
return -1;
}
-int chooseTarget(int behavior1) {
+int AI::chooseTarget(int behavior1) {
int numPools = getNumberOfPools();
int currentPlayer = getCurrentPlayer();
@@ -1805,7 +1802,7 @@ int chooseTarget(int behavior1) {
return 0;
}
-Tree *initApproachTarget(int targetX, int targetY, Node **retNode) {
+Tree *AI::initApproachTarget(int targetX, int targetY, Node **retNode) {
int sourceHub = 0;
if (behavior == 2)
@@ -1813,7 +1810,7 @@ Tree *initApproachTarget(int targetX, int targetY, Node **retNode) {
else
sourceHub = getClosestUnit(targetX + 10, targetY, getMaxX(), getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, MIN_DIST);
- Traveller *myTraveller = new Traveller(getHubX(sourceHub), getHubY(sourceHub));
+ Traveller *myTraveller = new Traveller(getHubX(sourceHub), getHubY(sourceHub), this);
myTraveller->setSourceHub(sourceHub);
//target adjustment so that room is allowed for the appropriate shot
@@ -1825,13 +1822,13 @@ Tree *initApproachTarget(int targetX, int targetY, Node **retNode) {
Traveller::setTargetPosY(targetY + adjY);
Traveller::setMaxDist(340);
- Tree *myTree = new Tree(myTraveller, TREE_DEPTH);
+ Tree *myTree = new Tree(myTraveller, TREE_DEPTH, this);
*retNode = myTree->aStarSearch_singlePassInit();
return myTree;
}
-int *approachTarget(Tree *myTree, int &xTarget, int &yTarget, Node **currentNode) {
+int *AI::approachTarget(Tree *myTree, int &xTarget, int &yTarget, Node **currentNode) {
int *retVal = NULL;
*currentNode = NULL;
@@ -1905,13 +1902,13 @@ int *approachTarget(Tree *myTree, int &xTarget, int &yTarget, Node **currentNode
return retVal;
}
-Tree *initAcquireTarget(int targetX, int targetY, Node **retNode) {
+Tree *AI::initAcquireTarget(int targetX, int targetY, Node **retNode) {
int sourceHub = getClosestUnit(targetX, targetY, getMaxX(), getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, MIN_DIST);
warning("My coords (%d): %d %d", sourceHub, getHubX(sourceHub), getHubY(sourceHub));
Sortie::setSourcePos(getHubX(sourceHub), getHubY(sourceHub));
Sortie::setTargetPos(targetX, targetY);
- Sortie *myBaseTarget = new Sortie();
+ Sortie *myBaseTarget = new Sortie(this);
myBaseTarget->setValueG(0);
myBaseTarget->setUnitType(ITEM_BOMB);
@@ -1932,14 +1929,13 @@ Tree *initAcquireTarget(int targetX, int targetY, Node **retNode) {
return NULL;
}
- Tree *myTree = new Tree(myBaseTarget, 4);
+ Tree *myTree = new Tree(myBaseTarget, 4, this);
*retNode = myTree->aStarSearch_singlePassInit();
return myTree;
}
-
-int *acquireTarget(int targetX, int targetY, Tree *myTree, int &errorCode) {
+int *AI::acquireTarget(int targetX, int targetY, Tree *myTree, int &errorCode) {
int currentPlayer = getCurrentPlayer();
int *retVal = NULL;
@@ -2005,7 +2001,7 @@ int *acquireTarget(int targetX, int targetY, Tree *myTree, int &errorCode) {
return retVal;
}
-int *acquireTarget(int targetX, int targetY) {
+int *AI::acquireTarget(int targetX, int targetY) {
int *retVal = new int[4];
int sourceHub = getClosestUnit(targetX, targetY, getMaxX(), getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 110);
@@ -2023,7 +2019,7 @@ int *acquireTarget(int targetX, int targetY) {
return retVal;
}
-int *energizeTarget(int &targetX, int &targetY, int index) {
+int *AI::energizeTarget(int &targetX, int &targetY, int index) {
int n = 10;
static int currentPlayer = 0;
static int pool = 0;
@@ -2237,7 +2233,7 @@ int *energizeTarget(int &targetX, int &targetY, int index) {
return retVal;
}
-int *offendTarget(int &targetX, int &targetY, int index) {
+int *AI::offendTarget(int &targetX, int &targetY, int index) {
int *retVal = NULL;
int target = getClosestUnit(targetX + 10, targetY, 20, 0, 0, 0, 0);
@@ -2253,35 +2249,35 @@ int *offendTarget(int &targetX, int &targetY, int index) {
switch (type) {
case BUILDING_OFFENSIVE_LAUNCHER:
- thisUnit = new OffenseUnit();
+ thisUnit = new OffenseUnit(this);
break;
case BUILDING_TOWER:
- thisUnit = new TowerUnit();
+ thisUnit = new TowerUnit(this);
break;
case BUILDING_MAIN_BASE:
- thisUnit = new HubUnit();
+ thisUnit = new HubUnit(this);
break;
case BUILDING_ENERGY_COLLECTOR:
- thisUnit = new EnergyUnit();
+ thisUnit = new EnergyUnit(this);
break;
case BUILDING_CRAWLER:
- thisUnit = new CrawlerUnit();
+ thisUnit = new CrawlerUnit(this);
break;
case BUILDING_BRIDGE:
- thisUnit = new BridgeUnit();
+ thisUnit = new BridgeUnit(this);
break;
case BUILDING_SHIELD:
- thisUnit = new ShieldUnit();
+ thisUnit = new ShieldUnit(this);
break;
default:
- thisUnit = new HubUnit();
+ thisUnit = new HubUnit(this);
break;
}
@@ -2355,9 +2351,9 @@ int *offendTarget(int &targetX, int &targetY, int index) {
return retVal;
}
-int *defendTarget(int &targetX, int &targetY, int index) {
+int *AI::defendTarget(int &targetX, int &targetY, int index) {
int *retVal = NULL;
- Defender *thisDefender = new Defender;
+ Defender *thisDefender = new Defender(this);
int defStatus = thisDefender->calculateDefenseUnitPosition(targetX, targetY, index);
if (defStatus > 0) {
@@ -2407,138 +2403,138 @@ int *defendTarget(int &targetX, int &targetY, int index) {
return retVal;
}
-int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled) {
+int AI::getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled) {
assert((unitType >= 0) && (unitType <= 12));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_CLOSEST_UNIT], 7, x, y, radius, player, alignment, unitType, checkUnitEnabled);
return retVal;
}
-int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled, int minDist) {
+int AI::getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled, int minDist) {
assert((unitType >= 0) && (unitType <= 12));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_CLOSEST_UNIT], 8, x, y, radius, player, alignment, unitType, checkUnitEnabled, minDist);
return retVal;
}
-int getDistance(int originX, int originY, int endX, int endY) {
+int AI::getDistance(int originX, int originY, int endX, int endY) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_WORLD_DIST], 4, originX, originY, endX, endY);
return retVal;
}
-int calcAngle(int originX, int originY, int endX, int endY) {
+int AI::calcAngle(int originX, int originY, int endX, int endY) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_WORLD_ANGLE], 5, originX, originY, endX, endY, 0);
return retVal;
}
-int calcAngle(int originX, int originY, int endX, int endY, int noWrapFlag) {
+int AI::calcAngle(int originX, int originY, int endX, int endY, int noWrapFlag) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_WORLD_ANGLE], 5, originX, originY, endX, endY, noWrapFlag);
return retVal;
}
-int getTerrain(int x, int y) {
+int AI::getTerrain(int x, int y) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_TERRAIN_TYPE], 2, x, y);
return retVal;
}
-int estimateNextRoundEnergy(int player) {
+int AI::estimateNextRoundEnergy(int player) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_ESTIMATE_NEXT_ROUND_ENERGY], 1, player);
return retVal / 10;
}
-int getHubX(int hub) {
+int AI::getHubX(int hub) {
assert(hub >= 0 && hub <= 500);
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_HUB_X, hub);
return retVal;
}
-int getHubY(int hub) {
+int AI::getHubY(int hub) {
assert(hub >= 0 && hub <= 500);
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_HUB_Y, hub);
return retVal;
}
-int getMaxX() {
+int AI::getMaxX() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WORLD_X_SIZE);
return retVal;
}
-int getMaxY() {
+int AI::getMaxY() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WORLD_Y_SIZE);
return retVal;
}
-int getCurrentPlayer() {
+int AI::getCurrentPlayer() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_CURRENT_PLAYER);
assert(retVal != 0);
return retVal;
}
-int getMaxPower() {
+int AI::getMaxPower() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_MAX_POWER);
return retVal;
}
-int getMinPower() {
+int AI::getMinPower() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_MIN_POWER);
return retVal;
}
-int getTerrainSquareSize() {
+int AI::getTerrainSquareSize() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_TERRAIN_SQUARE_SIZE);
return retVal;
}
-int getBuildingOwner(int building) {
+int AI::getBuildingOwner(int building) {
assert((building > 0) && (building < 501));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_OWNER, building);
return retVal;
}
-int getBuildingState(int building) {
+int AI::getBuildingState(int building) {
assert((building > 0) && (building < 501));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_STATE, building);
return retVal;
}
-int getBuildingType(int building) {
+int AI::getBuildingType(int building) {
assert((building > 0) && (building < 501));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_TYPE, building);
return retVal;
}
-int getBuildingArmor(int building) {
+int AI::getBuildingArmor(int building) {
assert((building > 0) && (building < 501));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_ARMOR, building);
return retVal;
}
-int getBuildingWorth(int building) {
+int AI::getBuildingWorth(int building) {
assert((building > 0) && (building < 501));
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_WORTH, building);
return retVal;
}
-int getEnergyPoolsArray() {
+int AI::getEnergyPoolsArray() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_ENERGY_POOLS_ARRAY);
return retVal;
}
-int getCoordinateVisibility(int x, int y, int playerNum) {
+int AI::getCoordinateVisibility(int x, int y, int playerNum) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 4, D_GET_COORDINATE_VISIBILITY, x, y, playerNum);
return retVal;
}
-int getUnitVisibility(int unit, int playerNum) {
+int AI::getUnitVisibility(int unit, int playerNum) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 3, D_GET_UNIT_VISIBILITY, unit, playerNum);
return retVal;
}
-int getEnergyPoolVisibility(int pool, int playerNum) {
+int AI::getEnergyPoolVisibility(int pool, int playerNum) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 3, D_GET_ENERGY_POOL_VISIBILITY, pool, playerNum);
return retVal;
}
-int getNumberOfPools() {
+int AI::getNumberOfPools() {
int retVal = 0;
if (AItype[getCurrentPlayer()]->getID() == ENERGY_HOG) {
@@ -2550,72 +2546,72 @@ int getNumberOfPools() {
return retVal;
}
-int getNumberOfPlayers() {
+int AI::getNumberOfPlayers() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_NUMBER_OF_PLAYERS);
return retVal;
}
-int getPlayerEnergy() {
+int AI::getPlayerEnergy() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_PLAYER_ENERGY);
return static_cast<int>(static_cast<float>(retVal) / 10.0);
}
-int getPlayerMaxTime() {
+int AI::getPlayerMaxTime() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_PLAYER_MAX_TIME);
return retVal;
}
-int getWindXSpeed() {
+int AI::getWindXSpeed() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WIND_X_SPEED);
return retVal;
}
-int getWindYSpeed() {
+int AI::getWindYSpeed() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WIND_Y_SPEED);
return retVal;
}
-int getTotalWindSpeed() {
+int AI::getTotalWindSpeed() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_TOTAL_WIND_SPEED);
return retVal;
}
-int getWindXSpeedMax() {
+int AI::getWindXSpeedMax() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WIND_X_SPEED_MAX);
return retVal;
}
-int getWindYSpeedMax() {
+int AI::getWindYSpeedMax() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_WIND_Y_SPEED_MAX);
return retVal;
}
-int getBigXSize() {
+int AI::getBigXSize() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_BIG_X_SIZE);
return retVal;
}
-int getBigYSize() {
+int AI::getBigYSize() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_BIG_Y_SIZE);
return retVal;
}
-int getEnergyPoolWidth(int pool) {
+int AI::getEnergyPoolWidth(int pool) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_ENERGY_POOL_WIDTH, pool);
return retVal;
}
-int getBuildingMaxArmor(int building) {
+int AI::getBuildingMaxArmor(int building) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_BUILDING_MAX_ARMOR, building);
return retVal;
}
-int getTimerValue(int timerNum) {
+int AI::getTimerValue(int timerNum) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_TIMER_VALUE, timerNum);
return retVal;
}
-int getLastAttacked(int &x, int &y) {
+int AI::getLastAttacked(int &x, int &y) {
int currentPlayer = getCurrentPlayer();
x = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_LAST_ATTACKED_X, currentPlayer);
y = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_LAST_ATTACKED_Y, currentPlayer);
@@ -2625,12 +2621,12 @@ int getLastAttacked(int &x, int &y) {
return 0;
}
-int getPlayerTeam(int player) {
+int AI::getPlayerTeam(int player) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 2, D_GET_PLAYER_TEAM, player);
return retVal;
}
-int getBuildingTeam(int building) {
+int AI::getBuildingTeam(int building) {
assert((building >= 1) && (building <= 500));
if (getBuildingOwner(building) == 0) return 0;
@@ -2639,37 +2635,37 @@ int getBuildingTeam(int building) {
return retVal;
}
-int getFOW() {
+int AI::getFOW() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_FOW);
return retVal;
}
-int getAnimSpeed() {
+int AI::getAnimSpeed() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_ANIM_SPEED);
return retVal;
}
-int getBuildingStackPtr() {
+int AI::getBuildingStackPtr() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_BUILDING_STACK_PTR);
return retVal;
}
-int getTurnCounter() {
+int AI::getTurnCounter() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_SCUMM_DATA], 1, D_GET_TURN_COUNTER);
return retVal;
}
-int getGroundAltitude(int x, int y) {
+int AI::getGroundAltitude(int x, int y) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_GROUND_ALTITUDE], 2, x, y);
return retVal;
}
-int checkForCordOverlap(int xStart, int yStart, int affectRadius, int simulateFlag) {
+int AI::checkForCordOverlap(int xStart, int yStart, int affectRadius, int simulateFlag) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_CHECK_FOR_CORD_OVERLAP], 4, xStart, yStart, affectRadius, simulateFlag);
return retVal;
}
-int checkForAngleOverlap(int unit, int angle) {
+int AI::checkForAngleOverlap(int unit, int angle) {
assert(angle > -721);
assert(angle < 721);
@@ -2679,42 +2675,42 @@ int checkForAngleOverlap(int unit, int angle) {
return retVal;
}
-int checkForUnitOverlap(int x, int y, int radius, int ignoredUnit) {
+int AI::checkForUnitOverlap(int x, int y, int radius, int ignoredUnit) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_CHECK_FOR_UNIT_OVERLAP], 4, x, y, radius, ignoredUnit);
return retVal;
}
-int checkForEnergySquare(int x, int y) {
+int AI::checkForEnergySquare(int x, int y) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_CHECK_FOR_ENERGY_SQUARE], 2, x, y);
return retVal;
}
-int aiChat() {
+int AI::aiChat() {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_AI_CHAT], 0);
return retVal;
}
-int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold, int olFlag) {
+int AI::getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold, int olFlag) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_POWER_ANGLE_FROM_POINT], 6, originX, originY, endX, endY, threshold, olFlag);
return retVal;
}
-int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold) {
+int AI::getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_POWER_ANGLE_FROM_POINT], 5, originX, originY, endX, endY, threshold);
return retVal;
}
-int checkIfWaterState(int x, int y) {
+int AI::checkIfWaterState(int x, int y) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_CHECK_IF_WATER_STATE], 2, x, y);
return retVal;
}
-int checkIfWaterSquare(int x, int y) {
+int AI::checkIfWaterSquare(int x, int y) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_CHECK_IF_WATER_SQUARE], 2, x, y);
return retVal;
}
-int getUnitsWithinRadius(int x, int y, int radius) {
+int AI::getUnitsWithinRadius(int x, int y, int radius) {
assert(x >= 0);
assert(y >= 0);
assert(radius >= 0);
@@ -2725,21 +2721,21 @@ int getUnitsWithinRadius(int x, int y, int radius) {
return retVal;
}
-int getLandingPoint(int x, int y, int power, int angle) {
+int AI::getLandingPoint(int x, int y, int power, int angle) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_LANDING_POINT], 4, x, y, power, angle);
return retVal;
}
-int getEnemyUnitsVisible(int playerNum) {
+int AI::getEnemyUnitsVisible(int playerNum) {
int retVal = _vm->_moonbase->callScummFunction(MCP_params[F_GET_ENEMY_UNITS_VISIBLE], 1, playerNum);
return retVal;
}
-float degToRad(float degrees) {
+float AI::degToRad(float degrees) {
return degrees * M_PI / 180.;
}
-void limitLocation(int &a, int &b, int c, int d) {
+void AI::limitLocation(int &a, int &b, int c, int d) {
if (a >= 0) {
a = (a % c);
} else {
@@ -2753,7 +2749,7 @@ void limitLocation(int &a, int &b, int c, int d) {
}
}
-int energyPoolSize(int pool) {
+int AI::energyPoolSize(int pool) {
int width = getEnergyPoolWidth(pool);
switch (width) {
@@ -2770,7 +2766,7 @@ int energyPoolSize(int pool) {
return 0;
}
-int getMaxCollectors(int pool) {
+int AI::getMaxCollectors(int pool) {
int width = getEnergyPoolWidth(pool);
switch (width) {
@@ -2787,7 +2783,7 @@ int getMaxCollectors(int pool) {
return 0;
}
-int simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps, int isEnergy) {
+int AI::simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps, int isEnergy) {
static int sXSpeed = 0;
static int sYSpeed = 0;
static int sZSpeed = 0;
@@ -2939,7 +2935,7 @@ int simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps, int
return 0;
}
-int simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps) {
+int AI::simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps) {
static int sXSpeed = 0;
static int sYSpeed = 0;
static int sZSpeed = 0;
@@ -3054,7 +3050,7 @@ int simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps) {
return 0;
}
-int fakeSimulateWeaponLaunch(int x, int y, int power, int angle) {
+int AI::fakeSimulateWeaponLaunch(int x, int y, int power, int angle) {
int distance = power * 480 / getMaxPower();
float radAngle = degToRad(angle);
int maxX = getMaxX();
@@ -3069,7 +3065,7 @@ int fakeSimulateWeaponLaunch(int x, int y, int power, int angle) {
return MAX(1, x + y * maxX);
}
-int getEnergyHogType() {
+int AI::getEnergyHogType() {
return energyHogType;
}
diff --git a/engines/scumm/he/moonbase/ai_main.h b/engines/scumm/he/moonbase/ai_main.h
index 8c58a70b28..7bd9a8f550 100644
--- a/engines/scumm/he/moonbase/ai_main.h
+++ b/engines/scumm/he/moonbase/ai_main.h
@@ -23,6 +23,7 @@
#ifndef SCUMM_HE_MOONBASE_AI_MAIN_H
#define SCUMM_HE_MOONBASE_AI_MAIN_H
+#include "common/array.h"
#include "scumm/he/moonbase/ai_tree.h"
namespace Scumm {
@@ -31,8 +32,6 @@ class ScummEngine_v90he;
extern ScummEngine_v90he *_vm;
-typedef Common::Array<int>::iterator intVecItr;
-
enum {
TERRAIN_TYPE_GOOD = 0,
TERRAIN_TYPE_SLOPE = 1,
@@ -84,98 +83,114 @@ enum {
MIN_DIST = 108
};
-void resetAI(ScummEngine_v90he *vm);
-void cleanUpAI();
-void setAIType(const int paramCount, const int32 *params);
-int masterControlProgram(const int paramCount, const int32 *params);
-
-int chooseBehavior();
-int chooseTarget(int behavior);
-
-Tree *initApproachTarget(int targetX, int targetY, Node **retNode);
-int *approachTarget(Tree *myTree, int &x, int &y, Node **currentNode);
-Tree *initAcquireTarget(int targetX, int targetY, Node **retNode);
-int *acquireTarget(int targetX, int targetY);
-int *acquireTarget(int targetX, int targetY, Tree *myTree, int &errorCode);
-int *offendTarget(int &targetX, int &targetY, int index);
-int *defendTarget(int &targetX, int &targetY, int index);
-int *energizeTarget(int &targetX, int &targetY, int index);
-
-int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled);
-int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled, int minDist);
-
-int getDistance(int originX, int originY, int endX, int endY);
-int calcAngle(int originX, int originY, int endX, int endY);
-int calcAngle(int originX, int originY, int endX, int endY, int noWrapFlag);
-int getTerrain(int x, int y);
-int getHubX(int hub);
-int getHubY(int hub);
-int getMaxX();
-int getMaxY();
-int getCurrentPlayer();
-int getMaxPower();
-int getMinPower();
-int getTerrainSquareSize();
-int getBuildingOwner(int building);
-int getBuildingState(int building);
-int getBuildingType(int building);
-int getBuildingArmor(int building);
-int getBuildingWorth(int building);
-int getEnergyPoolsArray();
-int getCoordinateVisibility(int x, int y, int playerNum);
-int getUnitVisibility(int unit, int playerNum);
-int getEnergyPoolVisibility(int pool, int playerNum);
-int getNumberOfPools();
-int getNumberOfPlayers();
-int getPlayerEnergy();
-int getPlayerMaxTime();
-int getWindXSpeed();
-int getWindYSpeed();
-int getTotalWindSpeed();
-int getWindXSpeedMax();
-int getWindYSpeedMax();
-int getBigXSize();
-int getBigYSize();
-int getEnergyPoolWidth(int pool);
-int getBuildingMaxArmor(int building);
-int getTimerValue(int timerNum);
-int getLastAttacked(int &x, int &y);
-int getPlayerTeam(int player);
-int getBuildingTeam(int building);
-int getFOW();
-int getAnimSpeed();
-int getBuildingStackPtr();
-int getTurnCounter();
-
-int getGroundAltitude(int x, int y);
-int checkForCordOverlap(int xStart, int yStart, int affectRadius, int simulateFlag);
-int checkForAngleOverlap(int unit, int angle);
-int estimateNextRoundEnergy(int player);
-int checkForUnitOverlap(int x, int y, int radius, int ignoredUnit);
-int checkForEnergySquare(int x, int y);
-int aiChat();
-
-int simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps, int isEnergy);
-int simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps);
-int fakeSimulateWeaponLaunch(int x, int y, int power, int angle);
-
-int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold, int olFlag);
-int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold);
-int checkIfWaterState(int x, int y);
-int checkIfWaterSquare(int x, int y);
-int getUnitsWithinRadius(int x, int y, int radius);
-int getLandingPoint(int x, int y, int power, int angle);
-int getEnemyUnitsVisible(int playerNum);
-
-float degToRad(float degrees);
-void limitLocation(int &a, int &b, int c, int d);
-int energyPoolSize(int pool);
-int getMaxCollectors(int pool);
-
-int getEnergyHogType();
-
-extern Common::Array<int> lastXCoord[];
-extern Common::Array<int> lastYCoord[];
+class AI {
+public:
+ void resetAI(ScummEngine_v90he *vm);
+ void cleanUpAI();
+ void setAIType(const int paramCount, const int32 *params);
+ int masterControlProgram(const int paramCount, const int32 *params);
+
+private:
+ int chooseBehavior();
+ int chooseTarget(int behavior);
+
+ Tree *initApproachTarget(int targetX, int targetY, Node **retNode);
+ int *approachTarget(Tree *myTree, int &x, int &y, Node **currentNode);
+ Tree *initAcquireTarget(int targetX, int targetY, Node **retNode);
+ int *acquireTarget(int targetX, int targetY);
+ int *acquireTarget(int targetX, int targetY, Tree *myTree, int &errorCode);
+ int *offendTarget(int &targetX, int &targetY, int index);
+ int *defendTarget(int &targetX, int &targetY, int index);
+ int *energizeTarget(int &targetX, int &targetY, int index);
+
+public:
+ int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled);
+ int getClosestUnit(int x, int y, int radius, int player, int alignment, int unitType, int checkUnitEnabled, int minDist);
+
+ int getDistance(int originX, int originY, int endX, int endY);
+ int calcAngle(int originX, int originY, int endX, int endY);
+ int calcAngle(int originX, int originY, int endX, int endY, int noWrapFlag);
+ int getTerrain(int x, int y);
+
+ int getHubX(int hub);
+ int getHubY(int hub);
+ int getMaxX();
+ int getMaxY();
+
+ int getCurrentPlayer();
+ int getMaxPower();
+ int getMinPower();
+ int getTerrainSquareSize();
+ int getBuildingOwner(int building);
+ int getBuildingState(int building);
+ int getBuildingType(int building);
+ int getBuildingArmor(int building);
+ int getBuildingMaxArmor(int building);
+ int getBuildingWorth(int building);
+ int getBuildingTeam(int building);
+
+ int getPlayerEnergy();
+ int getPlayerMaxTime();
+ int getTimerValue(int timerNum);
+ int getPlayerTeam(int player);
+
+ int getAnimSpeed();
+
+ int simulateBuildingLaunch(int x, int y, int power, int angle, int numSteps, int isEnergy);
+
+ int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold, int olFlag);
+ int getPowerAngleFromPoint(int originX, int originY, int endX, int endY, int threshold);
+ int checkIfWaterState(int x, int y);
+ int getUnitsWithinRadius(int x, int y, int radius);
+
+ float degToRad(float degrees);
+
+ int getEnergyHogType();
+
+private:
+ int getEnergyPoolsArray();
+ int getCoordinateVisibility(int x, int y, int playerNum);
+ int getUnitVisibility(int unit, int playerNum);
+ int getEnergyPoolVisibility(int pool, int playerNum);
+ int getNumberOfPools();
+ int getNumberOfPlayers();
+ int getWindXSpeed();
+ int getWindYSpeed();
+ int getTotalWindSpeed();
+ int getWindXSpeedMax();
+ int getWindYSpeedMax();
+ int getBigXSize();
+ int getBigYSize();
+ int getEnergyPoolWidth(int pool);
+ int getLastAttacked(int &x, int &y);
+ int getFOW();
+ int getBuildingStackPtr();
+ int getTurnCounter();
+
+ int getGroundAltitude(int x, int y);
+ int checkForCordOverlap(int xStart, int yStart, int affectRadius, int simulateFlag);
+ int checkForAngleOverlap(int unit, int angle);
+ int estimateNextRoundEnergy(int player);
+ int checkForUnitOverlap(int x, int y, int radius, int ignoredUnit);
+ int checkForEnergySquare(int x, int y);
+ int aiChat();
+
+ int simulateWeaponLaunch(int x, int y, int power, int angle, int numSteps);
+ int fakeSimulateWeaponLaunch(int x, int y, int power, int angle);
+
+ int checkIfWaterSquare(int x, int y);
+
+ int getLandingPoint(int x, int y, int power, int angle);
+ int getEnemyUnitsVisible(int playerNum);
+
+ void limitLocation(int &a, int &b, int c, int d);
+ int energyPoolSize(int pool);
+ int getMaxCollectors(int pool);
+
+public:
+ Common::Array<int> lastXCoord[5];
+ Common::Array<int> lastYCoord[5];
+};
} // End of namespace Scumm
diff --git a/engines/scumm/he/moonbase/ai_targetacquisition.cpp b/engines/scumm/he/moonbase/ai_targetacquisition.cpp
index 253142a82f..d91660c693 100644
--- a/engines/scumm/he/moonbase/ai_targetacquisition.cpp
+++ b/engines/scumm/he/moonbase/ai_targetacquisition.cpp
@@ -43,28 +43,28 @@ Sortie::~Sortie() {
void Sortie::setEnemyDefenses(int enemyDefensesScummArray, int defendX, int defendY) {
DefenseUnit *thisUnit;
- int currentPlayer = getCurrentPlayer();
+ int currentPlayer = _ai->getCurrentPlayer();
for (int i = 0; i < 200; i++) {
int thisElement = _vm->_moonbase->readFromArray(enemyDefensesScummArray, 0, i);
if (thisElement) {
- if (getBuildingOwner(thisElement)) {
- if (getPlayerTeam(currentPlayer) != getBuildingTeam(thisElement)) {
- int type = getBuildingType(thisElement);
+ if (_ai->getBuildingOwner(thisElement)) {
+ if (_ai->getPlayerTeam(currentPlayer) != _ai->getBuildingTeam(thisElement)) {
+ int type = _ai->getBuildingType(thisElement);
switch (type) {
case BUILDING_ANTI_AIR:
- thisUnit = new AntiAirUnit();
+ thisUnit = new AntiAirUnit(_ai);
break;
case BUILDING_SHIELD:
- thisUnit = new ShieldUnit();
+ thisUnit = new ShieldUnit(_ai);
break;
case BUILDING_EXPLOSIVE_MINE:
- if (getDistance(getHubX(thisElement), getHubY(thisElement), defendX, defendY) < 90)
- thisUnit = new MineUnit();
+ if (_ai->getDistance(_ai->getHubX(thisElement), _ai->getHubY(thisElement), defendX, defendY) < 90)
+ thisUnit = new MineUnit(_ai);
else
thisUnit = NULL;
@@ -81,9 +81,9 @@ void Sortie::setEnemyDefenses(int enemyDefensesScummArray, int defendX, int defe
if (thisUnit != NULL) {
thisUnit->setID(thisElement);
- thisUnit->setPos(getHubX(thisElement), getHubY(thisElement));
+ thisUnit->setPos(_ai->getHubX(thisElement), _ai->getHubY(thisElement));
- if (getBuildingState(thisElement)) thisUnit->setState(DUS_OFF);
+ if (_ai->getBuildingState(thisElement)) thisUnit->setState(DUS_OFF);
_enemyDefenses.push_back(thisUnit);
}
@@ -111,7 +111,7 @@ int Sortie::numChildrenToGen() {
IContainedObject *Sortie::createChildObj(int index, int &completionFlag) {
float thisDamage;
- Sortie *retSortie = new Sortie;
+ Sortie *retSortie = new Sortie(_ai);
int activeDefenses = 0;
Common::Array<DefenseUnit *> thisEnemyDefenses;
@@ -122,23 +122,23 @@ IContainedObject *Sortie::createChildObj(int index, int &completionFlag) {
switch ((*k)->getType()) {
case DUT_ANTI_AIR:
- temp = new AntiAirUnit(*k);
+ temp = new AntiAirUnit(*k, _ai);
break;
case DUT_SHIELD:
- temp = new ShieldUnit(*k);
+ temp = new ShieldUnit(*k, _ai);
break;
case DUT_MINE:
- temp = new MineUnit(*k);
+ temp = new MineUnit(*k, _ai);
break;
case DUT_CRAWLER:
- temp = new CrawlerUnit(*k);
+ temp = new CrawlerUnit(*k, _ai);
break;
default:
- temp = new ShieldUnit(*k);
+ temp = new ShieldUnit(*k, _ai);
break;
}
@@ -155,7 +155,7 @@ IContainedObject *Sortie::createChildObj(int index, int &completionFlag) {
retSortie->setUnitType(currentWeapon->getTypeID());
// Calculate distance from target to source hub
- int distance = getDistance(currentTarget->getPosX(), currentTarget->getPosY(), getSourcePosX(), getSourcePosY());
+ int distance = _ai->getDistance(currentTarget->getPosX(), currentTarget->getPosY(), getSourcePosX(), getSourcePosY());
// Pick correct shot position according to index
Common::Point *targetCoords;
@@ -169,7 +169,7 @@ IContainedObject *Sortie::createChildObj(int index, int &completionFlag) {
// Loop through defensive units, toggling anti-air units and deciding if this weapon will land safely
for (Common::Array<DefenseUnit *>::iterator i = thisEnemyDefenses.begin(); i != thisEnemyDefenses.end(); i++) {
- distance = getDistance((*i)->getPosX(), (*i)->getPosY(), targetCoords->x, targetCoords->y);
+ distance = _ai->getDistance((*i)->getPosX(), (*i)->getPosY(), targetCoords->x, targetCoords->y);
// Check to see if we're within an active defense's radius
if ((distance < (*i)->getRadius()) && ((*i)->getState() == DUS_ON)) {
@@ -210,10 +210,10 @@ IContainedObject *Sortie::createChildObj(int index, int &completionFlag) {
for (Common::Array<DefenseUnit *>::iterator i = thisEnemyDefenses.begin(); i != thisEnemyDefenses.end(); ) {
// Special simulated crawler detonation location used, since it walks a bit
if (currentWeapon->getTypeID() == ITEM_CRAWLER)
- distance = getDistance((*i)->getPosX(), (*i)->getPosY(), currentTarget->getPosX(), currentTarget->getPosY());
+ distance = _ai->getDistance((*i)->getPosX(), (*i)->getPosY(), currentTarget->getPosX(), currentTarget->getPosY());
// Normal detonation location used here
else {
- distance = getDistance((*i)->getPosX(), (*i)->getPosY(), targetCoords->x, targetCoords->y);
+ distance = _ai->getDistance((*i)->getPosX(), (*i)->getPosY(), targetCoords->x, targetCoords->y);
}
if (distance < currentWeapon->getRadius()) {
@@ -320,10 +320,10 @@ void Sortie::printEnemyDefenses() {
}
int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index) {
- int currentPlayer = getCurrentPlayer();
+ int currentPlayer = _ai->getCurrentPlayer();
//get list of near hubs
- int unitsArray = getUnitsWithinRadius(targetX + 5, targetY, 480);
+ int unitsArray = _ai->getUnitsWithinRadius(targetX + 5, targetY, 480);
const int NUM_HUBS = 10;
//Order on dist
@@ -334,11 +334,11 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
int thisUnit = _vm->_moonbase->readFromArray(unitsArray, 0, i);
if (thisUnit) {
- if (((getBuildingType(thisUnit) == BUILDING_MAIN_BASE) || (getBuildingType(thisUnit) == BUILDING_OFFENSIVE_LAUNCHER)) && (getBuildingOwner(thisUnit) == currentPlayer)) {
+ if (((_ai->getBuildingType(thisUnit) == BUILDING_MAIN_BASE) || (_ai->getBuildingType(thisUnit) == BUILDING_OFFENSIVE_LAUNCHER)) && (_ai->getBuildingOwner(thisUnit) == currentPlayer)) {
for (int j = 0; j < NUM_HUBS; j++) {
if (hubArray[j]) {
- int distCurrent = getDistance(targetX, targetY, getHubX(thisUnit), getHubY(thisUnit));
- int distSaved = getDistance(targetX, targetY, getHubX(hubArray[j]), getHubY(hubArray[j]));
+ int distCurrent = _ai->getDistance(targetX, targetY, _ai->getHubX(thisUnit), _ai->getHubY(thisUnit));
+ int distSaved = _ai->getDistance(targetX, targetY, _ai->getHubX(hubArray[j]), _ai->getHubY(hubArray[j]));
if (distCurrent < distSaved) {
hubArray[hubIndex] = hubArray[j];
@@ -364,20 +364,20 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
_vm->_moonbase->deallocateArray(unitsArray);
//Check if repair is needed
- int targetUnit = getClosestUnit(targetX + 5, targetY, 15, currentPlayer, 1, 0, 0, 0);
+ int targetUnit = _ai->getClosestUnit(targetX + 5, targetY, 15, currentPlayer, 1, 0, 0, 0);
- if (targetUnit && (targetUnit != BUILDING_CRAWLER) && (getBuildingTeam(targetUnit) == getPlayerTeam(currentPlayer))) {
- int armor = getBuildingArmor(targetUnit);
+ if (targetUnit && (targetUnit != BUILDING_CRAWLER) && (_ai->getBuildingTeam(targetUnit) == _ai->getPlayerTeam(currentPlayer))) {
+ int armor = _ai->getBuildingArmor(targetUnit);
- if (armor < getBuildingMaxArmor(targetUnit)) {
- unitsArray = getUnitsWithinRadius(targetX + 5, targetY, 170);
+ if (armor < _ai->getBuildingMaxArmor(targetUnit)) {
+ unitsArray = _ai->getUnitsWithinRadius(targetX + 5, targetY, 170);
int defCount = 0;
for (int i = 0; i < 200; i++) {
int thisUnit = _vm->_moonbase->readFromArray(unitsArray, 0, i);
if (thisUnit) {
- if (((getBuildingType(thisUnit) == BUILDING_SHIELD) || (getBuildingType(thisUnit) == BUILDING_ANTI_AIR)) && (getBuildingOwner(thisUnit) == currentPlayer) && (getBuildingState(thisUnit) == 0)) {
+ if (((_ai->getBuildingType(thisUnit) == BUILDING_SHIELD) || (_ai->getBuildingType(thisUnit) == BUILDING_ANTI_AIR)) && (_ai->getBuildingOwner(thisUnit) == currentPlayer) && (_ai->getBuildingState(thisUnit) == 0)) {
defCount++;
i = 200;
}
@@ -388,10 +388,10 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
if (defCount) {
//repair
- int hubUnit = getClosestUnit(targetX, targetY, 480, currentPlayer, 1, BUILDING_MAIN_BASE, 1, 110);
+ int hubUnit = _ai->getClosestUnit(targetX, targetY, 480, currentPlayer, 1, BUILDING_MAIN_BASE, 1, 110);
if (hubUnit && (hubUnit != targetUnit)) {
- int powAngle = abs(getPowerAngleFromPoint(getHubX(hubUnit), getHubY(hubUnit), targetX, targetY, 20));
+ int powAngle = abs(_ai->getPowerAngleFromPoint(_ai->getHubX(hubUnit), _ai->getHubY(hubUnit), targetX, targetY, 20));
int power = powAngle / 360;
int angle = powAngle - (power * 360);
@@ -411,18 +411,18 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
//For each hub
for (int i = 0; i < MIN(NUM_HUBS, hubIndex); i++) {
- int hubX = getHubX(hubArray[i]);
- int hubY = getHubY(hubArray[i]);
+ int hubX = _ai->getHubX(hubArray[i]);
+ int hubY = _ai->getHubY(hubArray[i]);
//get angle to hub
int directAngleToHub = 0;
//If this hub is the target
if ((hubX == targetX) && (hubY == targetY)) {
//make the angle seed point at the closest enemy
- int enemyUnit = getClosestUnit(hubX, hubY, getMaxX(), currentPlayer, 0, 0, 0);
- directAngleToHub = calcAngle(targetX, targetY, getHubX(enemyUnit), getHubY(enemyUnit));
+ int enemyUnit = _ai->getClosestUnit(hubX, hubY, _ai->getMaxX(), currentPlayer, 0, 0, 0);
+ directAngleToHub = _ai->calcAngle(targetX, targetY, _ai->getHubX(enemyUnit), _ai->getHubY(enemyUnit));
} else {
- directAngleToHub = calcAngle(targetX, targetY, hubX, hubY);
+ directAngleToHub = _ai->calcAngle(targetX, targetY, hubX, hubY);
}
//Number of random chances to land
@@ -431,10 +431,10 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
int randAngle = directAngleToHub + _vm->_rnd.getRandomNumber(179) - 90;
int randDist = _vm->_rnd.getRandomNumber(109) + 40;
- int x = targetX + randDist * cos(degToRad(randAngle));
- int y = targetY + randDist * sin(degToRad(randAngle));
+ int x = targetX + randDist * cos(_ai->degToRad(randAngle));
+ int y = targetY + randDist * sin(_ai->degToRad(randAngle));
- int powAngle = getPowerAngleFromPoint(hubX, hubY, x, y, 20);
+ int powAngle = _ai->getPowerAngleFromPoint(hubX, hubY, x, y, 20);
if (powAngle < 0)
continue;
@@ -443,7 +443,7 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
int angle = powAngle - (power * 360);
int coords = 0;
- coords = simulateBuildingLaunch(hubX, hubY, power, angle, 100, 0);
+ coords = _ai->simulateBuildingLaunch(hubX, hubY, power, angle, 100, 0);
//if valid, return
if (coords > 0) {
@@ -451,28 +451,28 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
setSourceX(hubX);
setSourceY(hubY);
- setTargetX((x + getMaxX()) % getMaxX());
- setTargetY((y + getMaxY()) % getMaxY());
+ setTargetX((x + _ai->getMaxX()) % _ai->getMaxX());
+ setTargetY((y + _ai->getMaxY()) % _ai->getMaxY());
setSourceUnit(hubArray[i]);
- int unitsArray2 = getUnitsWithinRadius(targetX + 5, targetY, 200);
+ int unitsArray2 = _ai->getUnitsWithinRadius(targetX + 5, targetY, 200);
int shieldCount = 0;
for (int k = 0; k < 200; k++) {
int thisUnit = _vm->_moonbase->readFromArray(unitsArray2, 0, k);
if (thisUnit) {
- if ((getBuildingType(thisUnit) == BUILDING_SHIELD) && (getBuildingOwner(thisUnit) == currentPlayer))
+ if ((_ai->getBuildingType(thisUnit) == BUILDING_SHIELD) && (_ai->getBuildingOwner(thisUnit) == currentPlayer))
shieldCount++;
- if ((getBuildingType(thisUnit) == BUILDING_BRIDGE) && (getBuildingOwner(thisUnit) == currentPlayer)) {
+ if ((_ai->getBuildingType(thisUnit) == BUILDING_BRIDGE) && (_ai->getBuildingOwner(thisUnit) == currentPlayer)) {
shieldCount--;
shieldCount = MAX(-1, shieldCount);
}
}
}
- if ((_vm->_rnd.getRandomNumber((int)pow(3.0f, shieldCount + 1) - 1) == 0) && (getPlayerEnergy() > 6))
+ if ((_vm->_rnd.getRandomNumber((int)pow(3.0f, shieldCount + 1) - 1) == 0) && (_ai->getPlayerEnergy() > 6))
setUnit(ITEM_SHIELD);
else
setUnit(ITEM_ANTIAIR);
@@ -486,11 +486,11 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
if (coords < 0) {
//drop a bridge for the cord
- int yCoord = -coords / getMaxX();
- int xCoord = -coords - (yCoord * getMaxX());
+ int yCoord = -coords / _ai->getMaxX();
+ int xCoord = -coords - (yCoord * _ai->getMaxX());
- if (checkIfWaterState(xCoord, yCoord)) {
- int terrainSquareSize = getTerrainSquareSize();
+ if (_ai->checkIfWaterState(xCoord, yCoord)) {
+ int terrainSquareSize = _ai->getTerrainSquareSize();
xCoord = ((xCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2));
yCoord = ((yCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2));
@@ -502,8 +502,8 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
setTargetX(x);
setTargetY(y);
- int nextUnit = getClosestUnit(x, y, 480, getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 120);
- powAngle = getPowerAngleFromPoint(getHubX(nextUnit), getHubY(nextUnit), x, y, 15);
+ int nextUnit = _ai->getClosestUnit(x, y, 480, _ai->getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 120);
+ powAngle = _ai->getPowerAngleFromPoint(_ai->getHubX(nextUnit), _ai->getHubY(nextUnit), x, y, 15);
powAngle = abs(powAngle);
power = powAngle / 360;
@@ -529,8 +529,8 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
do {
int sourceHub = hubArray[_vm->_rnd.getRandomNumber(hubIndex - 1)];
- setSourceX(getHubX(sourceHub));
- setSourceY(getHubY(sourceHub));
+ setSourceX(_ai->getHubX(sourceHub));
+ setSourceY(_ai->getHubY(sourceHub));
setSourceUnit(sourceHub);
setUnit(ITEM_HUB);
setPower(_vm->_rnd.getRandomNumber(299) + 200);
@@ -539,12 +539,12 @@ int Defender::calculateDefenseUnitPosition(int targetX, int targetY, int index)
if (count > (NUM_HUBS * 3)) break;
- coords = simulateBuildingLaunch(getSourceX(), getSourceY(), getPower(), getAngle(), 100, 0);
+ coords = _ai->simulateBuildingLaunch(getSourceX(), getSourceY(), getPower(), getAngle(), 100, 0);
} while (coords <= 0);
if (coords > 0) {
- setTargetX(coords % getMaxX());
- setTargetY(coords / getMaxX());
+ setTargetX(coords % _ai->getMaxX());
+ setTargetY(coords / _ai->getMaxX());
} else {
setTargetX(0);
setTargetY(0);
diff --git a/engines/scumm/he/moonbase/ai_targetacquisition.h b/engines/scumm/he/moonbase/ai_targetacquisition.h
index 6ac9e34751..9afe0f50ab 100644
--- a/engines/scumm/he/moonbase/ai_targetacquisition.h
+++ b/engines/scumm/he/moonbase/ai_targetacquisition.h
@@ -44,10 +44,10 @@ private:
int _unitType;
int _shotPosX, _shotPosY;
Common::Array<DefenseUnit *> _enemyDefenses;
-
+ AI *_ai;
public:
- Sortie() { _unitType = 0; _shotPosX = _shotPosY = 0; }
+ Sortie(AI *ai) { _ai = ai; _unitType = 0; _shotPosX = _shotPosY = 0; }
virtual ~Sortie();
static void setSourcePos(int x, int y) {
@@ -109,8 +109,10 @@ private:
int _power;
int _angle;
int _unit;
+ AI *_ai;
public:
+ Defender(AI *ai) : _ai(ai) {}
void setSourceX(int sourceX) { _sourceX = sourceX; }
void setSourceY(int sourceY) { _sourceY = sourceY; }
void setTargetX(int targetX) { _targetX = targetX; }
diff --git a/engines/scumm/he/moonbase/ai_traveller.cpp b/engines/scumm/he/moonbase/ai_traveller.cpp
index 755ae36779..51060ad971 100644
--- a/engines/scumm/he/moonbase/ai_traveller.cpp
+++ b/engines/scumm/he/moonbase/ai_traveller.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "scumm/he/intern_he.h"
+#include "scumm/he/moonbase/moonbase.h"
#include "scumm/he/moonbase/ai_traveller.h"
#include "scumm/he/moonbase/ai_main.h"
@@ -32,7 +34,7 @@ int Traveller::_maxDist = 0;
int Traveller::_numToGen = 0;
int Traveller::_sizeAngleStep = 0;
-Traveller::Traveller() {
+Traveller::Traveller(AI *ai) : _ai(ai) {
_waterFlag = 0;
setValueG(0);
unsetDisabled();
@@ -46,7 +48,7 @@ Traveller::Traveller() {
_waterDestY = 0;
}
-Traveller::Traveller(int originX, int originY) {
+Traveller::Traveller(int originX, int originY, AI *ai) : _ai(ai) {
_waterFlag = 0;
setValueG(0);
unsetDisabled();
@@ -64,7 +66,7 @@ Traveller::Traveller(int originX, int originY) {
}
void Traveller::adjustPosX(int offsetX) {
- int maxX = getMaxX();
+ int maxX = _ai->getMaxX();
int deltaX = _posX + offsetX;
if (deltaX < 0) _posX = maxX + deltaX;
@@ -73,7 +75,7 @@ void Traveller::adjustPosX(int offsetX) {
}
void Traveller::adjustPosY(int offsetY) {
- int maxY = getMaxX();
+ int maxY = _ai->getMaxX();
int deltaY = _posY + offsetY;
if (deltaY < 0) _posY = maxY + deltaY;
@@ -89,7 +91,7 @@ void Traveller::adjustXY(int offsetX, int offsetY) {
float Traveller::calcH() {
float retVal = 0;
// Calc dist from here to target
- retVal = getDistance(_posX, _posY, _targetPosX, _targetPosY);
+ retVal = _ai->getDistance(_posX, _posY, _targetPosX, _targetPosY);
// Divide by _maxDist to get minimum number of jumps to goal
retVal /= static_cast<float>(_maxDist);
@@ -98,7 +100,7 @@ float Traveller::calcH() {
int Traveller::numChildrenToGen() {
if (!_numToGen)
- _numToGen = getAnimSpeed() + 2;
+ _numToGen = _ai->getAnimSpeed() + 2;
return _numToGen;
}
@@ -111,7 +113,7 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
nodeCount++;
- Traveller *retTraveller = new Traveller;
+ Traveller *retTraveller = new Traveller(_ai);
static int dir, angle, power;
@@ -119,14 +121,14 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
// Calculate angle between here and target
int directAngle = 0;
- if (getEnergyHogType())
- directAngle = calcAngle(_posX, _posY, _targetPosX, _targetPosY, 1);
+ if (_ai->getEnergyHogType())
+ directAngle = _ai->calcAngle(_posX, _posY, _targetPosX, _targetPosY, 1);
else
- directAngle = calcAngle(_posX, _posY, _targetPosX, _targetPosY);
+ directAngle = _ai->calcAngle(_posX, _posY, _targetPosX, _targetPosY);
// Calculate the offset angle for this index
if (!_sizeAngleStep)
- _sizeAngleStep = 52 - (getAnimSpeed() * 7);
+ _sizeAngleStep = 52 - (_ai->getAnimSpeed() * 7);
dir = _sizeAngleStep * ((static_cast<int>(index / NUM_POWER_STEPS) + 1) >> 1);
// Calculate the sign value for the offset for this index
@@ -136,12 +138,12 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
// Calculate power for this index
int maxPower = 0;
- int directDist = getDistance(_posX, _posY, _targetPosX, _targetPosY);
+ int directDist = _ai->getDistance(_posX, _posY, _targetPosX, _targetPosY);
if (directDist > _maxDist + 120)
- maxPower = getMaxPower();
+ maxPower = _ai->getMaxPower();
else
- maxPower = (static_cast<float>(directDist) / static_cast<float>(_maxDist + 120)) * getMaxPower();
+ maxPower = (static_cast<float>(directDist) / static_cast<float>(_maxDist + 120)) * _ai->getMaxPower();
maxPower -= 70;
power = maxPower * (1 - ((index % NUM_POWER_STEPS) * SIZE_POWER_STEP));
@@ -155,7 +157,7 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
int coords = 0;
if (!(index % NUM_POWER_STEPS) || (!lastSuccessful)) {
- coords = simulateBuildingLaunch(_posX, _posY, power, angle, 10, 0);
+ coords = _ai->simulateBuildingLaunch(_posX, _posY, power, angle, 10, 0);
lastSuccessful = 0;
} else {
completionState = 1;
@@ -172,34 +174,34 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
completionState = 1;
}
- int whoseTurn = getCurrentPlayer();
- int maxX = getMaxX();
+ int whoseTurn = _ai->getCurrentPlayer();
+ int maxX = _ai->getMaxX();
// Check new position to see if landing is clear
if (coords > 0) {
int yCoord = coords / maxX;
int xCoord = coords - (yCoord * maxX);
- int terrain = getTerrain(xCoord, yCoord);
+ int terrain = _ai->getTerrain(xCoord, yCoord);
assert(terrain == TERRAIN_TYPE_GOOD);
- float pwr = getMinPower() * .3;
+ float pwr = _ai->getMinPower() * .3;
float cosine = cos((static_cast<float>(angle) / 360) * (2 * M_PI));
float sine = sin((static_cast<float>(angle) / 360) * (2 * M_PI));
int xParam = xCoord + (pwr * cosine);
int yParam = yCoord + (pwr * sine);
if (xParam < 0)
- xParam += getMaxX();
- else if (xParam > getMaxX())
- xParam -= getMaxX();
+ xParam += _ai->getMaxX();
+ else if (xParam > _ai->getMaxX())
+ xParam -= _ai->getMaxX();
if (yParam < 0)
- yParam += getMaxY();
- else if (yParam > getMaxY())
- yParam -= getMaxY();
+ yParam += _ai->getMaxY();
+ else if (yParam > _ai->getMaxY())
+ yParam -= _ai->getMaxY();
- if (checkIfWaterState(xParam, yParam)) {
+ if (_ai->checkIfWaterState(xParam, yParam)) {
delete retTraveller;
return NULL;
}
@@ -208,7 +210,7 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
retTraveller->setPosX(xCoord);
// Iterate through the previous action list, making sure this one isn't on it
- for (intVecItr i = (lastXCoord[whoseTurn]).begin(), j = (lastYCoord[whoseTurn]).begin(); i != (lastXCoord[whoseTurn]).end(); i++, j++) {
+ for (Common::Array<int>::iterator i = (_ai->lastXCoord[whoseTurn]).begin(), j = (_ai->lastYCoord[whoseTurn]).begin(); i != (_ai->lastXCoord[whoseTurn]).end(); i++, j++) {
// Check if this shot is the same as the last time we tried
if ((*i == retTraveller->getPosX()) && (*j == retTraveller->getPosY())) {
retTraveller->setDisabled();
@@ -224,8 +226,8 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
int xCoord = -coords - (yCoord * maxX);
// If landing fault is because of water, add 1 extra to g and turn on water flag. Also set coords, and adjust power to water fault location
- if (checkIfWaterState(xCoord, yCoord)) {
- int terrainSquareSize = getTerrainSquareSize();
+ if (_ai->checkIfWaterState(xCoord, yCoord)) {
+ int terrainSquareSize = _ai->getTerrainSquareSize();
xCoord = ((xCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2));
yCoord = ((yCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2));
@@ -234,10 +236,10 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
retTraveller->setPosX(xCoord + (terrainSquareSize * 1.414 * (xDist / (abs(xDist) + 1))));
retTraveller->setPosY(yCoord + (terrainSquareSize * 1.414 * (yDist / (abs(yDist) + 1))));
- int closestHub = getClosestUnit(retTraveller->getPosX(), retTraveller->getPosY(), getMaxX(), getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 110);
+ int closestHub = _ai->getClosestUnit(retTraveller->getPosX(), retTraveller->getPosY(), _ai->getMaxX(), _ai->getCurrentPlayer(), 1, BUILDING_MAIN_BASE, 1, 110);
- retTraveller->setWaterSourceX(getHubX(closestHub));
- retTraveller->setWaterSourceY(getHubY(closestHub));
+ retTraveller->setWaterSourceX(_ai->getHubX(closestHub));
+ retTraveller->setWaterSourceY(_ai->getHubY(closestHub));
retTraveller->setWaterDestX(retTraveller->getPosX());
retTraveller->setWaterDestY(retTraveller->getPosY());
@@ -258,7 +260,7 @@ IContainedObject *Traveller::createChildObj(int index, int &completionFlag) {
}
int Traveller::checkSuccess() {
- if (getDistance(_posX + 1, _posY, _targetPosX, _targetPosY) < _maxDist)
+ if (_ai->getDistance(_posX + 1, _posY, _targetPosX, _targetPosY) < _maxDist)
return SUCCESS;
return 0;
diff --git a/engines/scumm/he/moonbase/ai_traveller.h b/engines/scumm/he/moonbase/ai_traveller.h
index 63a56d77af..20e69eb76c 100644
--- a/engines/scumm/he/moonbase/ai_traveller.h
+++ b/engines/scumm/he/moonbase/ai_traveller.h
@@ -58,13 +58,14 @@ private:
int _waterDestX;
int _waterDestY;
+ AI *_ai;
protected:
virtual float calcH();
public:
- Traveller();
- Traveller(int originX, int originY);
+ Traveller(AI *ai);
+ Traveller(int originX, int originY, AI *ai);
~Traveller() {}
IContainedObject *duplicate() { return this; }
diff --git a/engines/scumm/he/moonbase/ai_tree.cpp b/engines/scumm/he/moonbase/ai_tree.cpp
index 2571928074..e3098a7b24 100644
--- a/engines/scumm/he/moonbase/ai_tree.cpp
+++ b/engines/scumm/he/moonbase/ai_tree.cpp
@@ -20,6 +20,9 @@
*
*/
+#include "scumm/he/intern_he.h"
+
+#include "scumm/he/moonbase/moonbase.h"
#include "scumm/he/moonbase/ai_tree.h"
#include "scumm/he/moonbase/ai_main.h"
@@ -29,7 +32,7 @@ static int compareTreeNodes(const void *a, const void *b) {
return ((const TreeNode *)a)->value - ((const TreeNode *)b)->value;
}
-Tree::Tree() {
+Tree::Tree(AI *ai) : _ai(ai) {
pBaseNode = new Node;
_maxDepth = MAX_DEPTH;
_maxNodes = MAX_NODES;
@@ -39,7 +42,7 @@ Tree::Tree() {
_currentMap = new Common::SortedArray<TreeNode *>(compareTreeNodes);
}
-Tree::Tree(IContainedObject *contents) {
+Tree::Tree(IContainedObject *contents, AI *ai) : _ai(ai) {
pBaseNode = new Node;
pBaseNode->setContainedObject(contents);
_maxDepth = MAX_DEPTH;
@@ -50,7 +53,7 @@ Tree::Tree(IContainedObject *contents) {
_currentMap = new Common::SortedArray<TreeNode *>(compareTreeNodes);
}
-Tree::Tree(IContainedObject *contents, int maxDepth) {
+Tree::Tree(IContainedObject *contents, int maxDepth, AI *ai) : _ai(ai) {
pBaseNode = new Node;
pBaseNode->setContainedObject(contents);
_maxDepth = maxDepth;
@@ -61,7 +64,7 @@ Tree::Tree(IContainedObject *contents, int maxDepth) {
_currentMap = new Common::SortedArray<TreeNode *>(compareTreeNodes);
}
-Tree::Tree(IContainedObject *contents, int maxDepth, int maxNodes) {
+Tree::Tree(IContainedObject *contents, int maxDepth, int maxNodes, AI *ai) : _ai(ai) {
pBaseNode = new Node;
pBaseNode->setContainedObject(contents);
_maxDepth = maxDepth;
@@ -84,7 +87,7 @@ void Tree::duplicateTree(Node *sourceNode, Node *destNode) {
}
}
-Tree::Tree(const Tree *sourceTree) {
+Tree::Tree(const Tree *sourceTree, AI *ai) : _ai(ai) {
pBaseNode = new Node(sourceTree->getBaseNode());
_maxDepth = sourceTree->getMaxDepth();
_maxNodes = sourceTree->getMaxNodes();
@@ -181,7 +184,7 @@ Node *Tree::aStarSearch_singlePass() {
static int maxTime = 0;
if (_currentChildIndex == 1) {
- maxTime = getPlayerMaxTime();
+ maxTime = _ai->getPlayerMaxTime();
}
if (_currentChildIndex) {
@@ -194,7 +197,7 @@ Node *Tree::aStarSearch_singlePass() {
_currentMap->erase(_currentMap->begin());
}
- if ((_currentNode->getDepth() < _maxDepth) && (Node::getNodeCount() < _maxNodes) && ((!maxTime) || (getTimerValue(3) < maxTime))) {
+ if ((_currentNode->getDepth() < _maxDepth) && (Node::getNodeCount() < _maxNodes) && ((!maxTime) || (_ai->getTimerValue(3) < maxTime))) {
// Generate nodes
_currentChildIndex = _currentNode->generateChildren();
diff --git a/engines/scumm/he/moonbase/ai_tree.h b/engines/scumm/he/moonbase/ai_tree.h
index 5da5b3a920..45d4963bc1 100644
--- a/engines/scumm/he/moonbase/ai_tree.h
+++ b/engines/scumm/he/moonbase/ai_tree.h
@@ -31,6 +31,8 @@ namespace Scumm {
const int MAX_DEPTH = 100;
const int MAX_NODES = 1000000;
+class AI;
+
struct TreeNode {
float value;
Node *node;
@@ -50,12 +52,14 @@ private:
Common::SortedArray<TreeNode *> *_currentMap;
Node *_currentNode;
+ AI *_ai;
+
public:
- Tree();
- Tree(IContainedObject *contents);
- Tree(IContainedObject *contents, int maxDepth);
- Tree(IContainedObject *contents, int maxDepth, int maxNodes);
- Tree(const Tree *sourceTree);
+ Tree(AI *ai);
+ Tree(IContainedObject *contents, AI *ai);
+ Tree(IContainedObject *contents, int maxDepth, AI *ai);
+ Tree(IContainedObject *contents, int maxDepth, int maxNodes, AI *ai);
+ Tree(const Tree *sourceTree, AI *ai);
~Tree();
void duplicateTree(Node *sourceNode, Node *destNode);
diff --git a/engines/scumm/he/moonbase/moonbase.cpp b/engines/scumm/he/moonbase/moonbase.cpp
index 833d84706d..be845c7cd3 100644
--- a/engines/scumm/he/moonbase/moonbase.cpp
+++ b/engines/scumm/he/moonbase/moonbase.cpp
@@ -22,14 +22,18 @@
#include "scumm/he/intern_he.h"
#include "scumm/he/moonbase/moonbase.h"
+#include "scumm/he/moonbase/ai_main.h"
namespace Scumm {
Moonbase::Moonbase(ScummEngine_v71he *vm) : _vm(vm) {
initFOW();
+
+ _ai = new AI;
}
Moonbase::~Moonbase() {
+ delete _ai;
}
int Moonbase::readFromArray(int array, int y, int x) {
diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h
index f7d8cdbb94..1150fec470 100644
--- a/engines/scumm/he/moonbase/moonbase.h
+++ b/engines/scumm/he/moonbase/moonbase.h
@@ -29,6 +29,8 @@
namespace Scumm {
+class AI;
+
class Moonbase {
public:
Moonbase(ScummEngine_v71he *vm);
@@ -66,6 +68,8 @@ public:
int _fowSentinelState;
uint32 _fowSentinelConditionBits;
+ AI *_ai;
+
private:
ScummEngine_v71he *_vm;