mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-03 18:14:01 +00:00
Cleanup underwater checks, fix rectangular water bubbles
Long/thin rectangular nodes were not handled correctly, because it would only check the nearest waterbubble node for overlap, not all on the map. + Lua func: isUnderWater(x, y, radius)
This commit is contained in:
parent
5e75bc486c
commit
aaed341569
9 changed files with 71 additions and 50 deletions
|
@ -277,13 +277,14 @@ bool Entity::checkSplash(const Vector &o)
|
||||||
if (!o.isZero())
|
if (!o.isZero())
|
||||||
check = o;
|
check = o;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if (wasUnderWater && !isUnderWater(o))
|
bool uw = isUnderWater(o);
|
||||||
|
if (wasUnderWater && !uw)
|
||||||
{
|
{
|
||||||
sound("splash-outof");
|
sound("splash-outof");
|
||||||
changed = true;
|
changed = true;
|
||||||
wasUnderWater = false;
|
wasUnderWater = false;
|
||||||
}
|
}
|
||||||
else if (!wasUnderWater && isUnderWater(o))
|
else if (!wasUnderWater && uw)
|
||||||
{
|
{
|
||||||
sound("splash-into");
|
sound("splash-into");
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -1774,34 +1775,21 @@ int Entity::getRandomTargetPoint()
|
||||||
return rand()%targetPoints.size();
|
return rand()%targetPoints.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::isUnderWater(const Vector &override)
|
bool Entity::isUnderWater()
|
||||||
{
|
{
|
||||||
Vector check = position;
|
return _isUnderWaterPos(position);
|
||||||
if (!override.isZero())
|
}
|
||||||
check = override;
|
|
||||||
|
|
||||||
if (game->useWaterLevel && game->waterLevel.x > 0 && check.y-collideRadius > game->waterLevel.x)
|
bool Entity::isUnderWater(const Vector& overridePos)
|
||||||
return true;
|
{
|
||||||
|
return _isUnderWaterPos(overridePos.isZero() ? position : overridePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Entity::_isUnderWaterPos(const Vector& pos)
|
||||||
Path *p = game->getNearestPath(position, PATH_WATERBUBBLE);
|
{
|
||||||
if (p && p->active && p->isCoordinateInside(position, collideRadius))
|
UnderWaterResult res = game->isUnderWater(pos, collideRadius);
|
||||||
{
|
waterBubble = res.waterbubble;
|
||||||
waterBubble = p;
|
return res.uw;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!game->useWaterLevel || game->waterLevel.x == 0) return true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (check.y-collideRadius > game->waterLevel.x)
|
|
||||||
{
|
|
||||||
waterBubble = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::push(const Vector &vec, float time, float maxSpeed, float dmg)
|
void Entity::push(const Vector &vec, float time, float maxSpeed, float dmg)
|
||||||
|
|
|
@ -103,7 +103,9 @@ public:
|
||||||
virtual int messageVariadic(lua_State *L, int nparams) { return 0; }
|
virtual int messageVariadic(lua_State *L, int nparams) { return 0; }
|
||||||
virtual int activateVariadic(lua_State *L, int nparams) { return 0; }
|
virtual int activateVariadic(lua_State *L, int nparams) { return 0; }
|
||||||
|
|
||||||
bool isUnderWater(const Vector &o=Vector());
|
bool isUnderWater();
|
||||||
|
bool isUnderWater(const Vector& overridePos);
|
||||||
|
bool _isUnderWaterPos(const Vector& pos);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1262,6 +1262,30 @@ Path *Game::getPathByName(std::string name)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path *Game::getWaterbubbleAt(const Vector& pos, float rad) const
|
||||||
|
{
|
||||||
|
for (Path *p = getFirstPathOfType(PATH_WATERBUBBLE); p; p = p->nextOfType)
|
||||||
|
if(p->active && p->isCoordinateInside(pos, rad))
|
||||||
|
return p;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnderWaterResult Game::isUnderWater(const Vector& pos, float rad) const
|
||||||
|
{
|
||||||
|
UnderWaterResult ret { false, NULL };
|
||||||
|
if (!game->useWaterLevel || game->waterLevel.x == 0
|
||||||
|
|| (useWaterLevel && waterLevel.x > 0 && pos.y-rad > waterLevel.x))
|
||||||
|
{
|
||||||
|
ret.uw = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path *p = game->getWaterbubbleAt(pos, rad);
|
||||||
|
ret.waterbubble = p;
|
||||||
|
ret.uw = !!p;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Game::toggleOverrideZoom(bool on)
|
void Game::toggleOverrideZoom(bool on)
|
||||||
{
|
{
|
||||||
if (avatar)
|
if (avatar)
|
||||||
|
@ -2536,14 +2560,7 @@ int game_collideParticle(Vector pos)
|
||||||
bool inWaterBubble = false;
|
bool inWaterBubble = false;
|
||||||
if (!aboveWaterLine)
|
if (!aboveWaterLine)
|
||||||
{
|
{
|
||||||
Path *p = game->getNearestPath(pos, PATH_WATERBUBBLE);
|
inWaterBubble = !!game->getWaterbubbleAt(pos);
|
||||||
if (p && p->active)
|
|
||||||
{
|
|
||||||
if (p->isCoordinateInside(pos))
|
|
||||||
{
|
|
||||||
inWaterBubble = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!inWaterBubble && aboveWaterLine)
|
if (!inWaterBubble && aboveWaterLine)
|
||||||
{
|
{
|
||||||
|
|
|
@ -283,6 +283,9 @@ public:
|
||||||
Path *getNearestPath(const Vector &pos, PathType pathType=PATH_NONE);
|
Path *getNearestPath(const Vector &pos, PathType pathType=PATH_NONE);
|
||||||
Path *getNearestPath(Path *p, std::string name);
|
Path *getNearestPath(Path *p, std::string name);
|
||||||
|
|
||||||
|
Path *getWaterbubbleAt(const Vector& pos, float rad = 0) const;
|
||||||
|
UnderWaterResult isUnderWater(const Vector& pos, float rad = 0) const;
|
||||||
|
|
||||||
SceneEditor sceneEditor;
|
SceneEditor sceneEditor;
|
||||||
bool isSceneEditorActive() {return sceneEditor.isOn();}
|
bool isSceneEditorActive() {return sceneEditor.isOn();}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "GameEnums.h"
|
#include "GameEnums.h"
|
||||||
|
|
||||||
|
class Path;
|
||||||
|
|
||||||
struct ElementEffect
|
struct ElementEffect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -191,5 +193,11 @@ private:
|
||||||
typedef std::vector<IngredientData*> IngredientDatas;
|
typedef std::vector<IngredientData*> IngredientDatas;
|
||||||
|
|
||||||
|
|
||||||
|
struct UnderWaterResult
|
||||||
|
{
|
||||||
|
bool uw;
|
||||||
|
Path *waterbubble;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -105,20 +105,13 @@ void Path::setActive(bool v)
|
||||||
active = v;
|
active = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Path::isCoordinateInside(const Vector &pos, int radius)
|
bool Path::isCoordinateInside(const Vector &pos, float radius) const
|
||||||
{
|
{
|
||||||
if (nodes.empty()) return false;
|
if (nodes.empty()) return false;
|
||||||
if (pathShape == PATHSHAPE_CIRCLE)
|
Vector diff = pos - nodes[0].position;
|
||||||
{
|
return pathShape == PATHSHAPE_CIRCLE
|
||||||
Vector diff = pos - nodes[0].position;
|
? diff.isLength2DIn(rect.getWidth()*0.5f - radius)
|
||||||
return diff.isLength2DIn(this->rect.getWidth()*0.5f - radius);
|
: rect.isCoordinateInside(diff, radius);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vector rel = pos - nodes[0].position;
|
|
||||||
return rect.isCoordinateInside(rel);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Path::getEnterNormal()
|
Vector Path::getEnterNormal()
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
void setEmitter(const std::string& name);
|
void setEmitter(const std::string& name);
|
||||||
|
|
||||||
PathNode *getPathNode(size_t idx);
|
PathNode *getPathNode(size_t idx);
|
||||||
bool isCoordinateInside(const Vector &pos, int rad=0);
|
bool isCoordinateInside(const Vector &pos, float rad=0) const;
|
||||||
|
|
||||||
void reverseNodes();
|
void reverseNodes();
|
||||||
|
|
||||||
|
|
|
@ -7930,6 +7930,15 @@ luaFunc(findWall)
|
||||||
luaReturnNum(wall);
|
luaReturnNum(wall);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luaFunc(isUnderWater)
|
||||||
|
{
|
||||||
|
float x = lua_tonumber(L, 1);
|
||||||
|
float y = lua_tonumber(L, 2);
|
||||||
|
float rad = lua_tonumber(L, 3);
|
||||||
|
luaReturnBool(game->isUnderWater(Vector(x, y), rad).uw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
luaFunc(setCutscene)
|
luaFunc(setCutscene)
|
||||||
{
|
{
|
||||||
dsq->setCutscene(getBool(L, 1), getBool(L, 2));
|
dsq->setCutscene(getBool(L, 1), getBool(L, 2));
|
||||||
|
@ -10796,6 +10805,7 @@ static const struct {
|
||||||
luaRegister(entity_alpha),
|
luaRegister(entity_alpha),
|
||||||
|
|
||||||
luaRegister(findWall),
|
luaRegister(findWall),
|
||||||
|
luaRegister(isUnderWater),
|
||||||
|
|
||||||
|
|
||||||
luaRegister(overrideZoom),
|
luaRegister(overrideZoom),
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
*x = x1 + ((*w) / 2);
|
*x = x1 + ((*w) / 2);
|
||||||
*y = y1 + ((*h) / 2);
|
*y = y1 + ((*h) / 2);
|
||||||
}
|
}
|
||||||
bool isCoordinateInside(const Vector &vec, int radius=0) const
|
bool isCoordinateInside(const Vector &vec, float radius=0) const
|
||||||
{
|
{
|
||||||
return ((vec.x >= x1-radius && vec.x <= x2+radius) && (vec.y >= y1-radius && vec.y <= y2+radius));
|
return ((vec.x >= x1-radius && vec.x <= x2+radius) && (vec.y >= y1-radius && vec.y <= y2+radius));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue