Initial commit
This commit is contained in:
238
engines/scumm/he/basketball/basketball.cpp
Normal file
238
engines/scumm/he/basketball/basketball.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "scumm/he/intern_he.h"
|
||||
#include "scumm/he/basketball/basketball.h"
|
||||
#include "scumm/he/basketball/collision/bball_collision_shields.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
Basketball::Basketball(ScummEngine_v100he *vm) {
|
||||
_vm = vm;
|
||||
_court = new CBBallCourt();
|
||||
_shields = new CCollisionShieldVector();
|
||||
}
|
||||
|
||||
Basketball::~Basketball() {
|
||||
delete _court;
|
||||
delete _shields;
|
||||
}
|
||||
|
||||
int Basketball::u32FloatToInt(float input) {
|
||||
int output = 0;
|
||||
|
||||
if (input < 0)
|
||||
output = (int)(input - 0.5F);
|
||||
else if (input > 0)
|
||||
output = (int)(input + 0.5F);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int Basketball::u32DoubleToInt(double input) {
|
||||
int output = 0;
|
||||
|
||||
if (input < 0)
|
||||
output = (int)(input - 0.5);
|
||||
else if (input > 0)
|
||||
output = (int)(input + 0.5);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void Basketball::fillBallTargetList(const CCollisionSphere *sourceObject, CCollisionObjectVector *targetList) {
|
||||
// Add all of the court objects...
|
||||
_court->_objectTree.selectObjectsInBound(sourceObject->getBigBoundingBox(), targetList);
|
||||
|
||||
// Add the shields...
|
||||
CCollisionShieldVector::const_iterator shieldIt;
|
||||
|
||||
for (shieldIt = _shields->begin(); shieldIt != _shields->end(); ++shieldIt) {
|
||||
if (!shieldIt->_ignore) {
|
||||
targetList->push_back(&(*shieldIt));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all of the home players...
|
||||
Common::Array<CCollisionPlayer>::const_iterator homePlayerIt;
|
||||
|
||||
for (homePlayerIt = _court->_homePlayerList.begin();
|
||||
homePlayerIt != _court->_homePlayerList.end();
|
||||
++homePlayerIt) {
|
||||
if (!homePlayerIt->_ignore) {
|
||||
targetList->push_back(&(*homePlayerIt));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all of the away players...
|
||||
Common::Array<CCollisionPlayer>::const_iterator awayPlayerIt;
|
||||
|
||||
for (awayPlayerIt = _court->_awayPlayerList.begin();
|
||||
awayPlayerIt != _court->_awayPlayerList.end();
|
||||
++awayPlayerIt) {
|
||||
if (!awayPlayerIt->_ignore) {
|
||||
targetList->push_back(&(*awayPlayerIt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Basketball::fillPlayerTargetList(const CCollisionPlayer *sourceObject, CCollisionObjectVector *targetList) {
|
||||
// Add all of the court objects...
|
||||
_court->_objectTree.selectObjectsInBound(sourceObject->getBigBoundingBox(), targetList);
|
||||
|
||||
// Add the shields if the player has the ball...
|
||||
if (sourceObject->_playerHasBall) {
|
||||
CCollisionShieldVector::const_iterator shieldIt;
|
||||
|
||||
for (shieldIt = _shields->begin(); shieldIt != _shields->end(); ++shieldIt) {
|
||||
if (!shieldIt->_ignore) {
|
||||
targetList->push_back(&(*shieldIt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the basketball...
|
||||
if (!_court->_basketBall._ignore) {
|
||||
targetList->push_back((ICollisionObject *)&_court->_basketBall);
|
||||
}
|
||||
|
||||
// Add the virtual basketball...
|
||||
if (!_court->_virtualBall._ignore) {
|
||||
targetList->push_back((ICollisionObject *)&_court->_virtualBall);
|
||||
}
|
||||
|
||||
// Add all of the home players...
|
||||
Common::Array<CCollisionPlayer>::const_iterator homePlayerIt;
|
||||
|
||||
for (homePlayerIt = _court->_homePlayerList.begin();
|
||||
homePlayerIt != _court->_homePlayerList.end();
|
||||
++homePlayerIt) {
|
||||
if ((sourceObject != &(*homePlayerIt)) &&
|
||||
(!homePlayerIt->_ignore)) {
|
||||
targetList->push_back(&(*homePlayerIt));
|
||||
}
|
||||
}
|
||||
|
||||
// Add all of the away players...
|
||||
Common::Array<CCollisionPlayer>::const_iterator awayPlayerIt;
|
||||
|
||||
for (awayPlayerIt = _court->_awayPlayerList.begin();
|
||||
awayPlayerIt != _court->_awayPlayerList.end();
|
||||
++awayPlayerIt) {
|
||||
if ((sourceObject != &(*awayPlayerIt)) &&
|
||||
(!awayPlayerIt->_ignore)) {
|
||||
targetList->push_back(&(*awayPlayerIt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double Basketball::getLaunchAngle(int velocity, int hDist, int vDist, int gravity) {
|
||||
double theta;
|
||||
double bestTheta;
|
||||
double tempTheta;
|
||||
double thetaMin, thetaMax;
|
||||
|
||||
double answer;
|
||||
double bestAnswer;
|
||||
double hiAnswer, loAnswer;
|
||||
|
||||
double time;
|
||||
double bestTime;
|
||||
|
||||
double targetAngle;
|
||||
int counter;
|
||||
|
||||
assert(hDist > 0);
|
||||
|
||||
// Set the search limits, and get a first guess...
|
||||
targetAngle = atan2(vDist, hDist);
|
||||
|
||||
// The minimum angle of the pass is the angle directly between us and the target...
|
||||
thetaMin = targetAngle;
|
||||
|
||||
// The maximum angle is straight up...
|
||||
thetaMax = BBALL_M_PI / 4;
|
||||
|
||||
theta = (thetaMin + thetaMax) / 2;
|
||||
bestTheta = theta;
|
||||
bestTime = hDist / (velocity * cos(theta));
|
||||
if (bestTime < 0)
|
||||
bestTime *= -1;
|
||||
|
||||
// Start binary searching for a close answer...
|
||||
counter = 0;
|
||||
answer = (2 * velocity * velocity * hDist * sin(theta) * cos(theta)) - (2 * velocity * velocity * vDist * cos(theta) * cos(theta)) - (gravity * hDist * hDist);
|
||||
if (answer < 0)
|
||||
answer *= -1;
|
||||
bestAnswer = answer;
|
||||
|
||||
while ((fabs(answer * 1000.0) > 10.0) && (++counter <= 100)) {
|
||||
if (theta < 0)
|
||||
targetAngle += (2 * BBALL_M_PI);
|
||||
|
||||
// Get a theta above and below the current one and see which one gets us closer
|
||||
// to satisfying the equation...
|
||||
tempTheta = (thetaMin + theta) / 2;
|
||||
loAnswer = (2 * velocity * velocity * hDist * sin(tempTheta) * cos(tempTheta)) - (2 * velocity * velocity * vDist * cos(tempTheta) * cos(tempTheta)) - (gravity * hDist * hDist);
|
||||
if (loAnswer < 0)
|
||||
loAnswer = 0 - loAnswer;
|
||||
|
||||
tempTheta = (thetaMax + theta) / 2;
|
||||
hiAnswer = (2 * velocity * velocity * hDist * sin(tempTheta) * cos(tempTheta)) - (2 * velocity * velocity * vDist * cos(tempTheta) * cos(tempTheta)) - (gravity * hDist * hDist);
|
||||
if (hiAnswer < 0)
|
||||
hiAnswer = 0 - hiAnswer;
|
||||
|
||||
if (loAnswer < hiAnswer) {
|
||||
thetaMax = theta;
|
||||
answer = loAnswer;
|
||||
} else {
|
||||
thetaMin = theta;
|
||||
answer = hiAnswer;
|
||||
}
|
||||
theta = (thetaMin + thetaMax) / 2;
|
||||
if (answer < 0)
|
||||
answer *= -1;
|
||||
|
||||
if (answer <= bestAnswer) {
|
||||
if (answer == bestAnswer) {
|
||||
time = hDist / (velocity * cos(theta));
|
||||
if (time < 0)
|
||||
time *= -1;
|
||||
if (time < bestTime) {
|
||||
bestTheta = theta;
|
||||
bestTime = time;
|
||||
bestAnswer = answer;
|
||||
}
|
||||
} else {
|
||||
bestTheta = theta;
|
||||
bestTime = hDist / (velocity * cos(theta));
|
||||
if (bestTime < 0)
|
||||
bestTime *= -1;
|
||||
bestAnswer = answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bestTheta = (bestTheta * 180) / BBALL_M_PI;
|
||||
return bestTheta;
|
||||
}
|
||||
|
||||
} // End of namespace Scumm
|
||||
Reference in New Issue
Block a user