diff options
author | Eugene Sandulenko | 2016-05-26 21:06:43 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2016-05-26 21:06:43 +0200 |
commit | 2b5ecc4f88a21b673af14849630c598261f3c743 (patch) | |
tree | 3332abd0ac0e7dbf5ce611f02ee4be38f843f5c7 /engines/scumm/he/moonbase | |
parent | 056c5a7ae71128cbbe55dcf45a8989e71f7d9ae5 (diff) | |
download | scummvm-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.cpp | 86 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_defenseunit.h | 45 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_main.cpp | 190 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_main.h | 203 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_targetacquisition.cpp | 118 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_targetacquisition.h | 6 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_traveller.cpp | 68 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_traveller.h | 5 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_tree.cpp | 17 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_tree.h | 14 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.h | 4 |
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; |