diff options
| author | Eugene Sandulenko | 2016-05-20 22:15:38 +0200 | 
|---|---|---|
| committer | Eugene Sandulenko | 2016-05-22 00:45:04 +0200 | 
| commit | bb88aaf119f2946b7c3fba01c4f7da5d40d2aa5c (patch) | |
| tree | c0082f977f2faa743d97d035c54d8bef01fa58b3 /engines | |
| parent | e4de5bf9ce8d447e5ab000aa354aafa513dc080b (diff) | |
| download | scummvm-rg350-bb88aaf119f2946b7c3fba01c4f7da5d40d2aa5c.tar.gz scummvm-rg350-bb88aaf119f2946b7c3fba01c4f7da5d40d2aa5c.tar.bz2 scummvm-rg350-bb88aaf119f2946b7c3fba01c4f7da5d40d2aa5c.zip  | |
SCUMM HE: Added Moonbase Traveller class
Diffstat (limited to 'engines')
| -rw-r--r-- | engines/scumm/he/moonbase/ai_traveller.cpp | 259 | ||||
| -rw-r--r-- | engines/scumm/he/moonbase/ai_traveller.h | 122 | ||||
| -rw-r--r-- | engines/scumm/module.mk | 1 | 
3 files changed, 382 insertions, 0 deletions
diff --git a/engines/scumm/he/moonbase/ai_traveller.cpp b/engines/scumm/he/moonbase/ai_traveller.cpp new file mode 100644 index 0000000000..5437ab1547 --- /dev/null +++ b/engines/scumm/he/moonbase/ai_traveller.cpp @@ -0,0 +1,259 @@ +/* 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 "scumm/he/moonbase/ai_traveller.h" +#include "scumm/he/moonbase/ai_main.h" + +namespace Scumm { + +int Traveller::_targetPosX = 0; +int Traveller::_targetPosY = 0; +int Traveller::_maxDist = 0; + +int Traveller::_numToGen = 0; +int Traveller::_sizeAngleStep = 0; + +Traveller::Traveller() { +	_waterFlag = 0; +	setValueG(0); +	unsetDisabled(); +} + +Traveller::Traveller(int originX, int originY) { +	_waterFlag = 0; +	setValueG(0); +	unsetDisabled(); + +	_posX = originX; +	_posY = originY; +} + +void Traveller::adjustPosX(int offsetX) { +	int maxX = GetMaxX(); +	int deltaX = _posX + offsetX; + +	if (deltaX < 0) _posX = maxX + deltaX; +	else if (deltaX > maxX) _posX = deltaX - maxX; +	else _posX = deltaX; +} + +void Traveller::adjustPosY(int offsetY) { +	int maxY = GetMaxX(); +	int deltaY = _posY + offsetY; + +	if (deltaY < 0) _posY = maxY + deltaY; +	else if (deltaY > maxY) _posY = deltaY - maxY; +	else _posY = deltaY; +} + +void Traveller::adjustXY(int offsetX, int offsetY) { +	adjustPosX(offsetX); +	adjustPosY(offsetY); +} + +float Traveller::calcH() { +	float retVal = 0; +	// Calc dist from here to target +	retVal = GetDistance(_posX, _posY, _targetPosX, _targetPosY); +	// Divide by _maxDist to get minimum number of jumps to goal +	retVal /= static_cast<float>(_maxDist); + +	return retVal * 2.0; +} + +int Traveller::numChildrenToGen() { +	if (!_numToGen) +		_numToGen = GetAnimSpeed() + 2; + +	return _numToGen; +} + +IContainedObject *Traveller::createChildObj(int index, int &completionFlag) { +	static int nodeCount = 0; +	static int completionState = 1; + +	if (!index) nodeCount = 0; + +	nodeCount++; + +	Traveller *retTraveller = new Traveller; + +	static int dir, angle, power; + +	if (completionState) { +		// Calculate angle between here and target +		int directAngle = 0; + +		if (GetEnergyHogType()) +			directAngle = GetAngle(_posX, _posY, _targetPosX, _targetPosY, 1); +		else +			directAngle = GetAngle(_posX, _posY, _targetPosX, _targetPosY); + +		// Calculate the offset angle for this index +		if (!_sizeAngleStep) +			_sizeAngleStep = 52 - (GetAnimSpeed() * 7); + +		dir = _sizeAngleStep * ((static_cast<int>(index / NUM_POWER_STEPS) + 1) >> 1); +		// Calculate the sign value for the offset for this index +		int orientation = dir * (((static_cast<int>(index / NUM_POWER_STEPS) % 2) << 1) - 1); +		// Add the offset angle to the direct angle to target +		angle = orientation + directAngle; + +		// Calculate power for this index +		int maxPower = 0; +		int directDist = GetDistance(_posX, _posY, _targetPosX, _targetPosY); + +		if (directDist > _maxDist + 120) +			maxPower = GetMaxPower(); +		else +			maxPower = (static_cast<float>(directDist) / static_cast<float>(_maxDist + 120)) * GetMaxPower(); + +		maxPower -= 70; +		power = maxPower * (1 - ((index % NUM_POWER_STEPS) * SIZE_POWER_STEP)); +	} + +	retTraveller->setAngleTo(angle); +	retTraveller->setPowerTo(power); + +	// Set this object's position to the new one determined by the power and angle from above +	static int lastSuccessful = 0; +	int coords = 0; + +	if (!(index % NUM_POWER_STEPS) || (!lastSuccessful)) { +		coords = SimulateBuildingLaunch(_posX, _posY, power, angle, 10, 0); +		lastSuccessful = 0; +	} else { +		completionState = 1; +		lastSuccessful = 0; +	} + +	if (!coords) { +		completionFlag = 0; +		completionState = 0; +		delete retTraveller; +		return NULL; +	} else { +		completionFlag = 1; +		completionState = 1; +	} + +	int whoseTurn = GetCurrentPlayer(); +	int maxX = 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); +		assert(terrain == TERRAIN_TYPE_GOOD); + +		float pwr = 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(); + +		if (yParam < 0) +			yParam += GetMaxY(); +		else if (yParam > GetMaxY()) +			yParam -= GetMaxY(); + +		if (CheckIfWaterState(xParam, yParam)) { +			delete retTraveller; +			return NULL; +		} + +		retTraveller->setPosY(yCoord); +		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) { +			// Check if this shot is the same as the last time we tried +			if ((*i == retTraveller->getPosX()) && (*j == retTraveller->getPosY())) { +				retTraveller->setDisabled(); +				delete retTraveller; +				return NULL; +			} +		} + +		retTraveller->setValueG(getG() + 7 + (dir * DIRECTION_WEIGHT)); +		lastSuccessful = 1; +	} else { +		int yCoord  = -coords / maxX; +		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(); +			xCoord = ((xCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2)); +			yCoord = ((yCoord / terrainSquareSize * terrainSquareSize) + (terrainSquareSize / 2)); + +			int xDist = xCoord - _posX; +			int yDist = yCoord - _posY; +			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); + +			retTraveller->setWaterSourceX(GetHubX(closestHub)); +			retTraveller->setWaterSourceY(GetHubY(closestHub)); +			retTraveller->setWaterDestX(retTraveller->getPosX()); +			retTraveller->setWaterDestY(retTraveller->getPosY()); + +			retTraveller->setPowerTo(power); +			retTraveller->setAngleTo(angle); + +			retTraveller->setValueG(getG() + 10 + (dir * DIRECTION_WEIGHT)); +			retTraveller->enableWaterFlag(); +		} else { +			// If not, set G to highest value +			retTraveller->setDisabled(); +			delete retTraveller; +			return NULL; +		} +	} + +	return retTraveller; +} + +int Traveller::checkSuccess() { +	if (GetDistance(_posX + 1, _posY, _targetPosX, _targetPosY) < _maxDist) +		return SUCCESS; + +	return 0; +} + +float Traveller::calcT() { +	assert(!_disabled); + +	if (_disabled) return FAILURE; + +	return (checkSuccess() != SUCCESS) ? (getG() + calcH()) : SUCCESS; +} + +} // End of namespace Scumm diff --git a/engines/scumm/he/moonbase/ai_traveller.h b/engines/scumm/he/moonbase/ai_traveller.h new file mode 100644 index 0000000000..7b1bad9a29 --- /dev/null +++ b/engines/scumm/he/moonbase/ai_traveller.h @@ -0,0 +1,122 @@ +/* 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_TRAVELER_H +#define SCUMM_HE_MOONBASE_AI_TRAVELER_H + +#include "scumm/he/moonbase/ai_node.h" + +namespace Scumm { + +const int NUM_TO_GEN = 9; + +const int NUM_POWER_STEPS = 3; +const double SIZE_POWER_STEP = .15; +const int SIZE_ANGLE_STEP = 45; +const int VARIATION_EXTENT = 3; +const int DIRECTION_WEIGHT = 5; + +class Traveller : public IContainedObject { +private: +	static int _targetPosX; +	static int _targetPosY; +	static int _maxDist; + +	static int _numToGen; +	static int _sizeAngleStep; + +	int _sourceHub; + +	int _posX; +	int _posY; +	int _angleTo; +	int _powerTo; + +	int _disabled; +	int _waterFlag; +	int _waterSourceX; +	int _waterSourceY; +	int _waterDestX; +	int _waterDestY; + + +protected: +	virtual float calcH(); + +public: +	Traveller(); +	Traveller(int originX, int originY); +	~Traveller() {} + +	IContainedObject *duplicate() { return this; } + +	static void setTargetPosX(int posX) { _targetPosX = posX; } +	static void setTargetPosY(int posY) { _targetPosY = posY; } +	static void setMaxDist(int maxDist) { _maxDist = maxDist; } + +	void setSourceHub(int sourceHub) { _sourceHub = sourceHub; } + +	void setPosX(int posX) { _posX = posX; } +	void setPosY(int posY) { _posY = posY; } +	void setAngleTo(int angleTo) { _angleTo = angleTo; } +	void setPowerTo(int powerTo) { _powerTo = powerTo; } + +	void setWaterSourceX(int waterSourceX) { _waterSourceX = waterSourceX; } +	void setWaterSourceY(int waterSourceY) { _waterSourceY = waterSourceY; } + +	void setWaterDestX(int waterDestX) { _waterDestX = waterDestX; } +	void setWaterDestY(int waterDestY) { _waterDestY = waterDestY; } + +	int getSourceHub() const { return _sourceHub; } + +	int getPosX() const { return _posX; } +	int getPosY() const { return _posY; } +	int getAngleTo() const { return _angleTo; } +	int getPowerTo() const { return _powerTo; } + +	int getWaterSourceX() const { return _waterSourceX; } +	int getWaterSourceY() const { return _waterSourceY; } +	int getWaterDestX() const { return _waterDestX; } +	int getWaterDestY() const { return _waterDestY; } + +	void setDisabled() { _disabled = 1; } +	void unsetDisabled() { _disabled = 0; } +	int getDisabled() { return _disabled; } + +	void adjustPosX(int offsetX); +	void adjustPosY(int offsetY); +	void adjustXY(int offsetX, int offsetY); + +	void enableWaterFlag() { _waterFlag = 1; } +	void disableWaterFlag() { _waterFlag = 0; } +	int GetWaterFlag() const { return _waterFlag; } + +	virtual int numChildrenToGen(); +	virtual IContainedObject *createChildObj(int, int &); + +	virtual int checkSuccess(); +	virtual float calcT(); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index d6199f5b01..57b687231f 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -142,6 +142,7 @@ MODULE_OBJS += \  	he/moonbase/ai_defenseunit.o \  	he/moonbase/ai_node.o \  	he/moonbase/ai_targetacquisition.o \ +	he/moonbase/ai_traveller.o \  	he/moonbase/ai_types.o \  	he/moonbase/ai_weapon.o \  	he/moonbase/moonbase.o \  | 
