1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-08-11 00:29:53 +00:00

Corrected shot bouncing logic

There was a problem calculating how shots with the BOUNCE_REAL attribute
would bounce off walls. The calculation was triggered when the shot
was already obstructed, which possibly got the shot stuck,
and later killed by a wrong obstruction check, which almost always killed
fast shots in narrow tunnels.

Also added some const.
This commit is contained in:
fgenesis 2012-01-10 22:27:52 +01:00
parent 1ab32b585f
commit 9dbdac547e
3 changed files with 35 additions and 31 deletions

View file

@ -640,7 +640,7 @@ public:
int getGridRaw(unsigned int x, unsigned int y) const; int getGridRaw(unsigned int x, unsigned int y) const;
const signed char *getGridColumn(int tileX); const signed char *getGridColumn(int tileX);
void setGrid(const TileVector &tile, int v); void setGrid(const TileVector &tile, int v);
bool isObstructed(const TileVector &tile, int t = -1); bool isObstructed(const TileVector &tile, int t = -1) const;
void clearPointers(); void clearPointers();
@ -1246,7 +1246,7 @@ void Game::setGrid(const TileVector &tile, int v)
} }
inline inline
bool Game::isObstructed(const TileVector &tile, int t) bool Game::isObstructed(const TileVector &tile, int t) const
{ {
if (t == -1) if (t == -1)
return (getGrid(tile) != 0); return (getGrid(tile) != 0);

View file

@ -586,7 +586,7 @@ void Shot::targetDied(Entity *target)
*/ */
} }
bool Shot::isHitEnts() bool Shot::isHitEnts() const
{ {
if (!shotData || shotData->hitEnts) if (!shotData || shotData->hitEnts)
{ {
@ -684,14 +684,14 @@ void Shot::noSegs()
} }
} }
int Shot::getCollideRadius() int Shot::getCollideRadius() const
{ {
if (shotData) if (shotData)
return shotData->collideRadius; return shotData->collideRadius;
return 0; return 0;
} }
float Shot::getDamage() float Shot::getDamage() const
{ {
if (shotData) if (shotData)
{ {
@ -700,7 +700,7 @@ float Shot::getDamage()
return 0; return 0;
} }
DamageType Shot::getDamageType() DamageType Shot::getDamageType() const
{ {
if (shotData) if (shotData)
{ {
@ -733,11 +733,11 @@ void Shot::setTargetPoint(int pt)
targetPt = pt; targetPt = pt;
} }
bool Shot::isObstructed() bool Shot::isObstructed(float dt) const
{ {
if (shotData->wallHitRadius == 0) if (shotData->wallHitRadius == 0)
{ {
TileVector t(position); TileVector t(position + velocity * dt);
if (dsq->game->isObstructed(t) if (dsq->game->isObstructed(t)
|| dsq->game->isObstructed(TileVector(t.x+1, t.y)) || dsq->game->isObstructed(TileVector(t.x+1, t.y))
|| dsq->game->isObstructed(TileVector(t.x-1, t.y)) || dsq->game->isObstructed(TileVector(t.x-1, t.y))
@ -858,33 +858,37 @@ void Shot::onUpdate(float dt)
diff.z = 0; diff.z = 0;
if (shotData->hitWalls) if (shotData->hitWalls)
{ {
if (isObstructed()) if (isObstructed(dt))
{ {
switch(shotData->bounceType) switch(shotData->bounceType)
{ {
case BOUNCE_REAL: case BOUNCE_REAL:
{ {
if (!shotData->bounceSfx.empty()) // Should have been checked in last onUpdate()
// If it is stuck now, it must have been fired from a bad position,
// the obstruction map changed, or it was a bouncing beast form shot,
// fired from avatar head - which may be inside a wall.
// In any of these cases, there is nowhere to bounce, so we let the shot die. -- FG
if (!isObstructed(0))
{ {
dsq->playPositionalSfx(shotData->bounceSfx, position); if (!shotData->bounceSfx.empty())
} {
float len = velocity.getLength2D(); dsq->playPositionalSfx(shotData->bounceSfx, position);
Vector I = velocity/len; }
Vector N = dsq->game->getWallNormal(position); float len = velocity.getLength2D();
Vector I = velocity/len;
Vector N = dsq->game->getWallNormal(position);
if (!N.isZero()) if (!N.isZero())
{ {
//2*(-I dot N)*N + I //2*(-I dot N)*N + I
velocity = 2*(-I.dot(N))*N + I; velocity = 2*(-I.dot(N))*N + I;
velocity *= len; velocity *= len;
} }
Vector test = position+velocity; break;
if (dsq->game->isObstructed(test))
{
suicide();
} }
// fall through
} }
break;
default: default:
{ {
suicide(); suicide();

View file

@ -109,13 +109,13 @@ public:
void setAimVector(const Vector &aim); void setAimVector(const Vector &aim);
void setTarget(Entity *target); void setTarget(Entity *target);
void setTargetPoint(int pt); void setTargetPoint(int pt);
float getDamage(); float getDamage() const;
int getCollideRadius(); int getCollideRadius() const;
DamageType getDamageType(); DamageType getDamageType() const;
ShotData *shotData; ShotData *shotData;
void updatePosition(); void updatePosition();
bool isHitEnts(); bool isHitEnts() const;
bool isObstructed(); bool isObstructed(float dt) const;
float extraDamage; float extraDamage;
protected: protected: