mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-08-11 08:49:54 +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;
|
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);
|
||||||
|
|
|
@ -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,11 +858,18 @@ 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:
|
||||||
|
{
|
||||||
|
// 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))
|
||||||
{
|
{
|
||||||
if (!shotData->bounceSfx.empty())
|
if (!shotData->bounceSfx.empty())
|
||||||
{
|
{
|
||||||
|
@ -878,13 +885,10 @@ void Shot::onUpdate(float dt)
|
||||||
velocity = 2*(-I.dot(N))*N + I;
|
velocity = 2*(-I.dot(N))*N + I;
|
||||||
velocity *= len;
|
velocity *= len;
|
||||||
}
|
}
|
||||||
Vector test = position+velocity;
|
|
||||||
if (dsq->game->isObstructed(test))
|
|
||||||
{
|
|
||||||
suicide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
suicide();
|
suicide();
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue