diff options
author | Eugene Sandulenko | 2016-05-19 22:30:56 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2016-05-22 00:45:03 +0200 |
commit | 9d60209a33d2eab4075662e9ed4f1e9215c719a2 (patch) | |
tree | 21f3398b5d64a292df3332113f2e51a0b4dbe49b /engines | |
parent | 4ed193b51e62891fca2c79b2195aacb83c9b65fb (diff) | |
download | scummvm-rg350-9d60209a33d2eab4075662e9ed4f1e9215c719a2.tar.gz scummvm-rg350-9d60209a33d2eab4075662e9ed4f1e9215c719a2.tar.bz2 scummvm-rg350-9d60209a33d2eab4075662e9ed4f1e9215c719a2.zip |
SCUMM HE: Initial stub for Moonbase AI
Diffstat (limited to 'engines')
-rw-r--r-- | engines/scumm/he/moonbase/ai_defenseunit.cpp | 759 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_defenseunit.h | 190 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_main.h | 188 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_node.h | 106 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/ai_tree.h | 78 | ||||
-rw-r--r-- | engines/scumm/he/moonbase/moonbase.h | 4 | ||||
-rw-r--r-- | engines/scumm/module.mk | 1 |
7 files changed, 1324 insertions, 2 deletions
diff --git a/engines/scumm/he/moonbase/ai_defenseunit.cpp b/engines/scumm/he/moonbase/ai_defenseunit.cpp new file mode 100644 index 0000000000..1312752fef --- /dev/null +++ b/engines/scumm/he/moonbase/ai_defenseunit.cpp @@ -0,0 +1,759 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/rect.h" +#include "common/util.h" +#include "scumm/scumm.h" +#include "scumm/he/moonbase/ai_defenseunit.h" +#include "scumm/he/moonbase/ai_main.h" + +namespace Scumm { + +DefenseUnit::DefenseUnit() { + m_state = DUS_ON; +} + +DefenseUnit::DefenseUnit(DefenseUnit *inUnit) { + m_ID = inUnit->getID(); + m_pos.x = inUnit->getPosX(); + m_pos.y = inUnit->getPosY(); + m_distanceTo = inUnit->getDistanceTo(); + m_state = inUnit->getState(); + m_radius = inUnit->getRadius(); + m_armor = inUnit->getArmor(); +} + +DefenseUnit::~DefenseUnit() { +} + +Common::Point *AntiAirUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + float ratio; + int radius; + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CRAWLER: + radius = getRadius(); + + if ((distance < radius) || (getState() == DUS_OFF)) { + targetPos->x = getPosX(); + targetPos->y = getPosY(); + } else { + ratio = MAX(0, (getRadius() / distance)); + targetPos->x = getPosX() - ratio * (getPosX() - sourceX); + targetPos->y = getPosY() - ratio * (getPosY() - sourceY); + } + + break; + + case ITEM_EMP: + if (getRadius() + 215 > distance) { //emp radius + double x1 = static_cast<double>(sourceX); + double y1 = static_cast<double>(sourceY); + double x2 = static_cast<double>(getPosX()); + double y2 = static_cast<double>(getPosY()); + double r1 = static_cast<double>(215); + double r2 = static_cast<double>(getRadius() + 3); + double d = static_cast<double>(distance); + + //formulae for calculating one point of intersection of two circles + float root = sqrt((((r1 + r2) * (r1 + r2)) - (d * d)) * ((d * d) - ((r2 - r1) * (r2 - r1)))); + int x = ((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root; + int y = ((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root; + + targetPos->x = x; + targetPos->y = y; + } else { + ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); + targetPos->x = sourceX + ratio * (getPosX() - sourceX); + targetPos->y = sourceY + ratio * (getPosY() - sourceY); + } + + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int AntiAirUnit::selectWeapon(int index) { + switch (index) { + case 0: + return ITEM_CLUSTER; + break; + + case 1: + return ITEM_EMP; + break; + + case 2: + if (getState() == DUS_OFF) { + if (GetPlayerEnergy() > 6) { + if (!_vm->_rnd.getRandomNumber(3)) { + return ITEM_VIRUS; + } + } + + if (GetPlayerEnergy() > 2) { + if (!_vm->_rnd.getRandomNumber(1)) { + return ITEM_SPIKE; + } + } + + return ITEM_BOMB; + } + + return ITEM_CLUSTER; + break; + + default: + return ITEM_CLUSTER; + break; + } +} + +Common::Point *ShieldUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + float ratio; + Common::Point *targetPos = new Common::Point; + + if (getState() == DUS_OFF) { + targetPos->x = getPosX(); + targetPos->y = getPosY(); + } else { + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + 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 thisX = (static_cast<int>(sourceX + ratio * (getPosX() - sourceX)) + maxX) % maxX; + int thisY = (static_cast<int>(sourceY + ratio * (getPosY() - sourceY)) + maxY) % maxY; + targetPos->x = thisX; + targetPos->y = thisY; + } + break; + + case ITEM_EMP: + if (getRadius() + 215 > distance) { //emp radius + double x1 = static_cast<double>(sourceX); + double y1 = static_cast<double>(sourceY); + double x2 = static_cast<double>(getPosX()); + double y2 = static_cast<double>(getPosY()); + double r1 = static_cast<double>(215); + double r2 = static_cast<double>(getRadius() + 10); + double d = static_cast<double>(distance); + + //formulae for calculating one point of intersection of two circles + float root = sqrt((((r1 + r2) * (r1 + r2)) - (d * d)) * ((d * d) - ((r2 - r1) * (r2 - r1)))); + int x = ((x1 + x2) / 2) + ((x2 - x1) * (r1 * r1 - r2 * r2)) / (2 * d * d) + ((y2 - y1) / (2 * d * d)) * root; + int y = ((y1 + y2) / 2) + ((y2 - y1) * (r1 * r1 - r2 * r2)) / (2 * d * d) - ((x2 - x1) / (2 * d * d)) * root; + + targetPos->x = x; + targetPos->y = y; + } else { + ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); + targetPos->x = sourceX + ratio * (getPosX() - sourceX); + targetPos->y = sourceY + ratio * (getPosY() - sourceY); + } + + if (distance < getRadius()) { + targetPos->x = getPosX(); + targetPos->y = getPosY(); + } + + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + } + + return targetPos; +} + +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)); + + if ((dist < (getRadius() - 20)) && (dist > 90)) { + return ITEM_SPIKE; + } + + switch (index) { + case 0: + if (getState() == DUS_OFF) { + if (GetPlayerEnergy() < 3) { + return ITEM_BOMB; + } else { + return ITEM_SPIKE; + } + } + + return ITEM_EMP; + break; + + case 1: + if (dist < getRadius() + 150) { + return ITEM_EMP; + } else { + return ITEM_CRAWLER; + } + + break; + + default: + return ITEM_EMP; + break; + } +} + +Common::Point *MineUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + float ratio; + Common::Point *targetPos = new Common::Point; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_EMP: + ratio = 1 - (getRadius() / static_cast<float>(distance - 20)); + targetPos->x = sourceX + ratio * (getPosX() - sourceX); + targetPos->y = sourceY + ratio * (getPosY() - sourceY); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int MineUnit::selectWeapon(int index) { + int myUnit = GetClosestUnit(getPosX(), getPosY(), GetMaxX(), GetCurrentPlayer(), 1, 0, 0, 0); + int x = getPosX(); + int y = getPosY(); + + int dist = GetDistance(x, y, GetHubX(myUnit), GetHubY(myUnit)); + + if ((getState() == DUS_ON) && (dist < 110)) { + return ITEM_EMP; + } else { + return ITEM_BOMB; + } +} + + +Common::Point *HubUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CRAWLER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int HubUnit::selectWeapon(int index) { + warning("Hub weapon select"); + + int energy = GetPlayerEnergy(); + + if (energy > 6) { + //possibly choose crawler + if (GetBuildingWorth(getID()) > 21) { + return ITEM_CRAWLER; + } + } + + //choose betw/ bomb and cluster + if (GetBuildingArmor(getID()) < 1.5) { + return ITEM_CLUSTER; + } + + if (energy > 2) { + if (!_vm->_rnd.getRandomNumber(3)) { + return ITEM_SPIKE; + } + + if (!_vm->_rnd.getRandomNumber(4)) { + return ITEM_GUIDED; + } + + if (!_vm->_rnd.getRandomNumber(4)) { + return ITEM_MINE; + } + + if (!_vm->_rnd.getRandomNumber(9)) { + return ITEM_EMP; + } + } + + return ITEM_BOMB; +} + + +Common::Point *TowerUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_SPIKE: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int TowerUnit::selectWeapon(int index) { + switch (index) { + case 0: + return ITEM_SPIKE; + break; + + default: + return ITEM_SPIKE; + break; + } +} + + +Common::Point *BridgeUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int BridgeUnit::selectWeapon(int index) { + switch (index) { + case 0: + return ITEM_BOMB; + break; + + case 1: + return ITEM_CLUSTER; + break; + + default: + return ITEM_BOMB; + break; + } +} + + +Common::Point *EnergyUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CRAWLER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int EnergyUnit::selectWeapon(int index) { + warning("Energy weapon select"); + + int energy = GetPlayerEnergy(); + + if (energy > 6) { + //possibly choose crawler + if (GetBuildingWorth(getID()) > 21) { + return ITEM_CRAWLER; + } + } + + //choose betw/ bomb and cluster + if (GetBuildingArmor(getID()) < 1.5) { + return ITEM_CLUSTER; + } + + if (energy > 2) { + if (!_vm->_rnd.getRandomNumber(3)) { + return ITEM_EMP; + } + } + + return ITEM_BOMB; +} + +Common::Point *OffenseUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CRAWLER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +int OffenseUnit::selectWeapon(int index) { + warning("Offense weapon select"); + + int energy = GetPlayerEnergy(); + + if (energy > 6) { + //possibly choose crawler + if (GetBuildingWorth(getID()) > 21) { + return ITEM_CRAWLER; + } + } + + //choose betw/ bomb and cluster + if (GetBuildingArmor(getID()) < 1.5) { + return ITEM_CLUSTER; + } + + return ITEM_BOMB; +} + +Common::Point *CrawlerUnit::createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) { + Common::Point *targetPos = new Common::Point; + + if (!distance) + distance = 1; + + switch (weaponType) { + case ITEM_BOMB: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CLUSTER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + case ITEM_CRAWLER: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + + default: + targetPos->x = getPosX(); + targetPos->y = getPosY(); + break; + } + + return targetPos; +} + +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 x = getPosX(); + int y = getPosY(); + int energy = GetPlayerEnergy(); + int terrain = GetTerrain(x, y); + + if (terrain != TERRAIN_TYPE_WATER) { + if ((energy > 2) && (dist < 220)) { + return ITEM_RECLAIMER; + } else { + return ITEM_BOMB; + } + } else { + if (energy > 6) { + return ITEM_CRAWLER; + } + + if (energy > 2) { + if (_vm->_rnd.getRandomNumber(1)) { + return ITEM_MINE; + } else { + return ITEM_TIME_EXPIRED; + } + } + } + + return SKIP_TURN; +} + +AntiAirUnit::AntiAirUnit() { + setRadius(190); + setArmor(3); + setCost(1); +} + +ShieldUnit::ShieldUnit() { + setRadius(170); + setArmor(3); + setCost(7); +} + +MineUnit::MineUnit() { + setRadius(80); + setArmor(1); + setCost(3); +} + +HubUnit::HubUnit() { + setRadius(1); + setArmor(5); + setCost(7); +} + +TowerUnit::TowerUnit() { + setRadius(1); + setArmor(3); + setCost(1); +} + +BridgeUnit::BridgeUnit() { + setRadius(1); + setArmor(3); + setCost(1); +} + +EnergyUnit::EnergyUnit() { + setRadius(1); + setArmor(5); + setCost(7); +} + +OffenseUnit::OffenseUnit() { + setRadius(1); + setArmor(3); + setCost(7); +} + +CrawlerUnit::CrawlerUnit() { + setRadius(1); + setArmor(3); + setCost(7); +} + +AntiAirUnit::AntiAirUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); + +} + +ShieldUnit::ShieldUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +MineUnit::MineUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +HubUnit::HubUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +TowerUnit::TowerUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +BridgeUnit::BridgeUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +EnergyUnit::EnergyUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +OffenseUnit::OffenseUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +CrawlerUnit::CrawlerUnit(DefenseUnit *inUnit) : DefenseUnit(inUnit) { + setID(inUnit->getID()); + setPos(inUnit->getPosX(), inUnit->getPosY()); + setDistanceTo(inUnit->getDistanceTo()); + setState(inUnit->getState()); + setRadius(inUnit->getRadius()); + setArmor(inUnit->getArmor()); +} + +} // End of namespace Scumm diff --git a/engines/scumm/he/moonbase/ai_defenseunit.h b/engines/scumm/he/moonbase/ai_defenseunit.h new file mode 100644 index 0000000000..bc4c79a6b5 --- /dev/null +++ b/engines/scumm/he/moonbase/ai_defenseunit.h @@ -0,0 +1,190 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_HE_MOONBASE_AI_DEFENCEUNIT_H +#define SCUMM_HE_MOONBASE_AI_DEFENCEUNIT_H + +namespace Scumm { + +enum { + DUT_ANTI_AIR = 1, + DUT_SHIELD = 2, + DUT_MINE = 3, + DUT_HUB = 4, + DUT_TOWER = 5, + DUT_BRIDGE = 6, + DUT_ENERGY = 7, + DUT_OFFENSE = 8, + DUT_CRAWLER = 9 +}; + +enum { + DUS_ON = 1, + DUS_OFF = 2, + DUS_DESTROYED = 3 +}; + +class DefenseUnit { +private: + int m_ID; + Common::Point m_pos; + int m_distanceTo; + int m_state; + int m_radius; + int m_armor; + int m_cost; + +public: + DefenseUnit(); + DefenseUnit(DefenseUnit *inUnit); + + virtual ~DefenseUnit(); + + void setID(int id) { m_ID = id; } + void setDistanceTo(int distanceTo) { m_distanceTo = distanceTo; } + void setState(int state) { m_state = state; } + void setRadius(int radius) { m_radius = radius; } + void setArmor(int armor) { m_armor = armor; } + void setDamage(int damage) { m_armor -= damage; } + void setPos(int x, int y) { + m_pos.x = x; + m_pos.y = y; + } + void setCost(int cost) { m_cost = cost; } + + int getID() const { return m_ID; } + int getDistanceTo() const { return m_distanceTo; } + int getState() const { return m_state; } + int getRadius() const { return m_radius; } + int getArmor() const { return m_armor; } + int getPosX() const { return m_pos.x; } + int getPosY() const { return m_pos.y; } + int getCost() const { return m_cost; } + + virtual int getType() const = 0; + + virtual Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY) = 0; + virtual int selectWeapon(int index) = 0; +}; + +class AntiAirUnit : public DefenseUnit { +private: + +public: + AntiAirUnit(); + AntiAirUnit(DefenseUnit *inUnit); + int getType() const { return DUT_ANTI_AIR; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class ShieldUnit : public DefenseUnit { +private: + +public: + ShieldUnit(); + ShieldUnit(DefenseUnit *inUnit); + int getType() const { return DUT_SHIELD; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class MineUnit : public DefenseUnit { +private: + +public: + MineUnit(); + MineUnit(DefenseUnit *inUnit); + int getType() const { return DUT_MINE; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class HubUnit : public DefenseUnit { +private: + +public: + HubUnit(); + HubUnit(DefenseUnit *inUnit); + int getType() const { return DUT_HUB; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class TowerUnit : public DefenseUnit { +private: + +public: + TowerUnit(); + TowerUnit(DefenseUnit *inUnit); + int getType() const { return DUT_TOWER; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class BridgeUnit : public DefenseUnit { +private: + +public: + BridgeUnit(); + BridgeUnit(DefenseUnit *inUnit); + int getType() const { return DUT_BRIDGE; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class EnergyUnit : public DefenseUnit { +private: + +public: + EnergyUnit(); + EnergyUnit(DefenseUnit *inUnit); + int getType() const { return DUT_ENERGY; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class OffenseUnit : public DefenseUnit { +private: + +public: + OffenseUnit(); + OffenseUnit(DefenseUnit *inUnit); + int getType() const { return DUT_OFFENSE; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +class CrawlerUnit : public DefenseUnit { +private: + +public: + CrawlerUnit(); + CrawlerUnit(DefenseUnit *inUnit); + int getType() const { return DUT_CRAWLER; } + Common::Point *createTargetPos(int index, int distance, int weaponType, int sourceX, int sourceY); + int selectWeapon(int index); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/he/moonbase/ai_main.h b/engines/scumm/he/moonbase/ai_main.h new file mode 100644 index 0000000000..ca85ff1811 --- /dev/null +++ b/engines/scumm/he/moonbase/ai_main.h @@ -0,0 +1,188 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_HE_MOONBASE_AI_MAIN_H +#define SCUMM_HE_MOONBASE_AI_MAIN_H + +#include "scumm/he/moonbase/ai_tree.h" + +namespace Scumm { + +extern ScummEngine *_vm; + +typedef Common::List<int>::iterator intVecItr; + +enum { + TERRAIN_TYPE_GOOD = 0, + TERRAIN_TYPE_SLOPE = 1, + TERRAIN_TYPE_WATER = 2, + MAX_MEMORY = 3 +}; + +enum { + ITEM_BOMB = 0, + ITEM_CLUSTER = 1, + ITEM_REPAIR = 2, + ITEM_ANTIAIR = 3, + ITEM_BRIDGE = 4, + ITEM_TOWER = 5, + ITEM_GUIDED = 6, + ITEM_EMP = 7, + ITEM_SPIKE = 8, + ITEM_RECLAIMER = 9, + ITEM_BALLOON = 10, + ITEM_MINE = 11, + ITEM_CRAWLER = 12, + ITEM_VIRUS = 13, + ITEM_ENERGY = 14, + ITEM_SHIELD = 15, + ITEM_OFFENSE = 16, + ITEM_HUB = 17, + ITEM_TIME_EXPIRED = 18, + SKIP_TURN = -999 +}; + +enum BuildingTypes { + BUILDING_ENERGY_COLLECTOR = 3, + BUILDING_MAIN_BASE = 4, + BUILDING_BRIDGE = 5, + BUILDING_TOWER = 6, + BUILDING_EXPLOSIVE_MINE = 7, + BUILDING_SHIELD = 8, + BUILDING_ANTI_AIR = 9, + BUILDING_OFFENSIVE_LAUNCHER = 10, + BUILDING_BALLOON = 11, + BUILDING_CRAWLER = 12 +}; + +enum { + ENERGY_POOL_X = 45, + ENERGY_POOL_Y = 46, + ENERGY_POOL_UNITS_ON = 47, + + MIN_DIST = 108 +}; + +static int energyHogType = 0; + +void ResetAI(); +void CleanUpAI(); +void SetAIType(const int paramCount, const int *params); +int MasterControlProgram(const int paramCount, const int *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 GetAngle(int originX, int originY, int endX, int endY); +int GetAngle(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); +void DebugBreak(); +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 PrintDebugTimer(int max, int timerVal); +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 MACRO_LimitLocation(int &a, int &b, int c, int d); +int energyPoolSize(int pool); +int GetMaxCollectors(int pool); + +int TempChooseBehavior(); +int TempChooseTarget(int behavior); + +int GetEnergyHogType(); + +extern Common::List<int> lastXCoord[]; +extern Common::List<int> lastYCoord[]; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/he/moonbase/ai_node.h b/engines/scumm/he/moonbase/ai_node.h new file mode 100644 index 0000000000..87b6b96ebb --- /dev/null +++ b/engines/scumm/he/moonbase/ai_node.h @@ -0,0 +1,106 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_HE_MOONBASE_AI_NODE_H +#define SCUMM_HE_MOONBASE_AI_NODE_H + +#include "common/list.h" + +namespace Scumm { + +const float SUCCESS = -1; +const float FAILURE = 1e20; + +class IContainedObject { +private: + int objID; + float valueG; + +protected: + virtual float getG() const { return valueG; } + virtual float calcH() { return 0; } + + +public: + IContainedObject() { valueG = 0; } + IContainedObject(float inG) { valueG = inG; } + IContainedObject(IContainedObject &sourceContainedObject); + virtual ~IContainedObject() {} + + virtual IContainedObject *duplicate() = 0; + + void setValueG(float inG) { valueG = inG; } + float getValueG() { return valueG; } + + int getObjID() const { return objID; } + void setObjID(int inputObjID) { objID = inputObjID; } + + virtual int numChildrenToGen() = 0; + virtual IContainedObject *createChildObj(int index, int &completionFlag) = 0; + + virtual int checkSuccess() = 0; + virtual float calcT() { return getG(); } + + float returnG() const { return getG(); } +}; + +class Node { +private: + Node *pParent; + Common::List<Node *> vpChildren; + + int m_depth; + static int m_nodeCount; + + IContainedObject *pContents; + +public: + Node(); + Node(Node *sourceNode); + ~Node(); + + void setParent(Node *parentPtr) { pParent = parentPtr; } + Node *getParent() const { return pParent; } + + void setDepth(int depth) { m_depth = depth; } + int getDepth() const { return m_depth; } + + static int getNodeCount() { return m_nodeCount; } + + void setContainedObject(IContainedObject *pValue) { pContents = pValue; } + IContainedObject *getContainedObject() { return pContents; } + + Common::List<Node *> getChildren() const { return vpChildren; } + int generateChildren(); + int generateNextChild(); + Node *popChild(); + + float getObjectT() { return pContents->calcT(); } + + Node *getFirstStep(); + + void printPath(); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/he/moonbase/ai_tree.h b/engines/scumm/he/moonbase/ai_tree.h new file mode 100644 index 0000000000..c76d03c541 --- /dev/null +++ b/engines/scumm/he/moonbase/ai_tree.h @@ -0,0 +1,78 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_HE_MOONBASE_AI_TREE_H +#define SCUMM_HE_MOONBASE_AI_TREE_H + +#include "scumm/he/moonbase/ai_node.h" + +namespace Scumm { + +//typedef std::multimap< float, Node *, std::less<float> > fnpMMap; + +const int MAX_DEPTH = 100; +const int MAX_NODES = 1000000; + +class Tree { +private: + Node *pBaseNode; + + int m_maxDepth; + int m_maxNodes; + + int currentChildIndex; + unsigned long m_startTime; + + //fnpMMap m_currentMap; + Node *m_currentNode; + +public: + Tree(); + Tree(IContainedObject *contents); + Tree(IContainedObject *contents, int maxDepth); + Tree(IContainedObject *contents, int maxDepth, int maxNodes); + Tree(const Tree *sourceTree); + ~Tree(); + + void duplicateTree(Node *sourceNode, Node *destNode); + + Node *GetBaseNode() const { return pBaseNode; } + void setMaxDepth(int maxDepth) { m_maxDepth = maxDepth; } + int getMaxDepth() const { return m_maxDepth; } + + void setMaxNodes(int maxNodes) { m_maxNodes = maxNodes; } + int getMaxNodes() const { return m_maxNodes; } + + void setStartTime(unsigned long sTime) { m_startTime = sTime; } + unsigned long getStartTime() const { return m_startTime; } + + Node *aStarSearch(); + + Node *aStarSearch_singlePassInit(); + Node *aStarSearch_singlePass(Node **currentNode); + + int IsBaseNode(Node *thisNode); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/he/moonbase/moonbase.h b/engines/scumm/he/moonbase/moonbase.h index e82ae0164f..0b47ba6dc3 100644 --- a/engines/scumm/he/moonbase/moonbase.h +++ b/engines/scumm/he/moonbase/moonbase.h @@ -20,8 +20,8 @@ * */ -#ifndef SCUMM_HE_MOONBASE_H -#define SCUMM_HE_MOONBASE_H +#ifndef SCUMM_HE_MOONBASE_MOONBASE_H +#define SCUMM_HE_MOONBASE_MOONBASE_H #ifdef ENABLE_HE diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index c56ef7e5f4..f1551b2bd2 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -139,6 +139,7 @@ MODULE_OBJS += \ he/logic/moonbase_logic.o \ he/logic/puttrace.o \ he/logic/soccer.o \ + he/moonbase/ai_defenseunit.o \ he/moonbase/moonbase.o \ he/moonbase/moonbase_fow.o endif |