mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-11-15 05:59:16 +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:
parent
1ab32b585f
commit
9dbdac547e
3 changed files with 35 additions and 31 deletions
|
@ -640,7 +640,7 @@ public:
|
|||
int getGridRaw(unsigned int x, unsigned int y) const;
|
||||
const signed char *getGridColumn(int tileX);
|
||||
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();
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ void Game::setGrid(const TileVector &tile, int v)
|
|||
}
|
||||
|
||||
inline
|
||||
bool Game::isObstructed(const TileVector &tile, int t)
|
||||
bool Game::isObstructed(const TileVector &tile, int t) const
|
||||
{
|
||||
if (t == -1)
|
||||
return (getGrid(tile) != 0);
|
||||
|
|
|
@ -586,7 +586,7 @@ void Shot::targetDied(Entity *target)
|
|||
*/
|
||||
}
|
||||
|
||||
bool Shot::isHitEnts()
|
||||
bool Shot::isHitEnts() const
|
||||
{
|
||||
if (!shotData || shotData->hitEnts)
|
||||
{
|
||||
|
@ -684,14 +684,14 @@ void Shot::noSegs()
|
|||
}
|
||||
}
|
||||
|
||||
int Shot::getCollideRadius()
|
||||
int Shot::getCollideRadius() const
|
||||
{
|
||||
if (shotData)
|
||||
return shotData->collideRadius;
|
||||
return 0;
|
||||
}
|
||||
|
||||
float Shot::getDamage()
|
||||
float Shot::getDamage() const
|
||||
{
|
||||
if (shotData)
|
||||
{
|
||||
|
@ -700,7 +700,7 @@ float Shot::getDamage()
|
|||
return 0;
|
||||
}
|
||||
|
||||
DamageType Shot::getDamageType()
|
||||
DamageType Shot::getDamageType() const
|
||||
{
|
||||
if (shotData)
|
||||
{
|
||||
|
@ -733,11 +733,11 @@ void Shot::setTargetPoint(int pt)
|
|||
targetPt = pt;
|
||||
}
|
||||
|
||||
bool Shot::isObstructed()
|
||||
bool Shot::isObstructed(float dt) const
|
||||
{
|
||||
if (shotData->wallHitRadius == 0)
|
||||
{
|
||||
TileVector t(position);
|
||||
TileVector t(position + velocity * dt);
|
||||
if (dsq->game->isObstructed(t)
|
||||
|| 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;
|
||||
if (shotData->hitWalls)
|
||||
{
|
||||
if (isObstructed())
|
||||
if (isObstructed(dt))
|
||||
{
|
||||
switch(shotData->bounceType)
|
||||
{
|
||||
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);
|
||||
}
|
||||
float len = velocity.getLength2D();
|
||||
Vector I = velocity/len;
|
||||
Vector N = dsq->game->getWallNormal(position);
|
||||
if (!shotData->bounceSfx.empty())
|
||||
{
|
||||
dsq->playPositionalSfx(shotData->bounceSfx, position);
|
||||
}
|
||||
float len = velocity.getLength2D();
|
||||
Vector I = velocity/len;
|
||||
Vector N = dsq->game->getWallNormal(position);
|
||||
|
||||
if (!N.isZero())
|
||||
{
|
||||
//2*(-I dot N)*N + I
|
||||
velocity = 2*(-I.dot(N))*N + I;
|
||||
velocity *= len;
|
||||
}
|
||||
Vector test = position+velocity;
|
||||
if (dsq->game->isObstructed(test))
|
||||
{
|
||||
suicide();
|
||||
if (!N.isZero())
|
||||
{
|
||||
//2*(-I dot N)*N + I
|
||||
velocity = 2*(-I.dot(N))*N + I;
|
||||
velocity *= len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
suicide();
|
||||
|
|
|
@ -109,13 +109,13 @@ public:
|
|||
void setAimVector(const Vector &aim);
|
||||
void setTarget(Entity *target);
|
||||
void setTargetPoint(int pt);
|
||||
float getDamage();
|
||||
int getCollideRadius();
|
||||
DamageType getDamageType();
|
||||
float getDamage() const;
|
||||
int getCollideRadius() const;
|
||||
DamageType getDamageType() const;
|
||||
ShotData *shotData;
|
||||
void updatePosition();
|
||||
bool isHitEnts();
|
||||
bool isObstructed();
|
||||
bool isHitEnts() const;
|
||||
bool isObstructed(float dt) const;
|
||||
|
||||
float extraDamage;
|
||||
protected:
|
||||
|
|
Loading…
Reference in a new issue