mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-25 14:15:46 +00:00
Pathfinding & map grid improvements.
There were still only 6 of 8 bits of the map grid in use. The last 2 bits are now available as non-colliding user bits, and are ignored unless specially treated. The findPath() function can now be told which bits to respect, which allows to prevent pathfinding to pass through fish tunnels, for example. A function for fast user bit map dilation is added as well.
This commit is contained in:
parent
b98e2532ed
commit
3db8c9e13a
8 changed files with 185 additions and 124 deletions
|
@ -3561,7 +3561,7 @@ void Avatar::lockToWall()
|
||||||
while(0);
|
while(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dsq->game->getGrid(t)==OT_HURT && isDamageTarget(DT_WALLHURT))
|
if (dsq->game->isObstructed(t, OT_HURT) && isDamageTarget(DT_WALLHURT))
|
||||||
{
|
{
|
||||||
good = false;
|
good = false;
|
||||||
}
|
}
|
||||||
|
@ -3612,16 +3612,16 @@ void Avatar::lockToWall()
|
||||||
Vector offdiff = t.worldVector() - position;
|
Vector offdiff = t.worldVector() - position;
|
||||||
if (!offdiff.isZero())
|
if (!offdiff.isZero())
|
||||||
{
|
{
|
||||||
if (tileType != OT_INVISIBLEIN)
|
if (tileType & OT_INVISIBLEIN)
|
||||||
{
|
{
|
||||||
Vector adjust = offdiff;
|
Vector adjust = offdiff;
|
||||||
adjust.setLength2D(TILE_SIZE*2);
|
adjust.setLength2D(TILE_SIZE/2);
|
||||||
offdiff -= adjust;
|
offdiff -= adjust;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector adjust = offdiff;
|
Vector adjust = offdiff;
|
||||||
adjust.setLength2D(TILE_SIZE/2);
|
adjust.setLength2D(TILE_SIZE*2);
|
||||||
offdiff -= adjust;
|
offdiff -= adjust;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1509,13 +1509,13 @@ bool Entity::isSittingOnInvisibleIn()
|
||||||
{
|
{
|
||||||
for (int y = 0; y < 4; y++)
|
for (int y = 0; y < 4; y++)
|
||||||
{
|
{
|
||||||
if (dsq->game->getGrid(TileVector(t.x+x, t.y+y))==OT_INVISIBLEIN)
|
if (dsq->game->isObstructed(TileVector(t.x+x, t.y+y), OT_INVISIBLEIN))
|
||||||
return true;
|
return true;
|
||||||
if (dsq->game->getGrid(TileVector(t.x-x, t.y+y))==OT_INVISIBLEIN)
|
if (dsq->game->isObstructed(TileVector(t.x-x, t.y+y), OT_INVISIBLEIN))
|
||||||
return true;
|
return true;
|
||||||
if (dsq->game->getGrid(TileVector(t.x+x, t.y-y))==OT_INVISIBLEIN)
|
if (dsq->game->isObstructed(TileVector(t.x+x, t.y-y), OT_INVISIBLEIN))
|
||||||
return true;
|
return true;
|
||||||
if (dsq->game->getGrid(TileVector(t.x-x, t.y-y))==OT_INVISIBLEIN)
|
if (dsq->game->isObstructed(TileVector(t.x-x, t.y-y), OT_INVISIBLEIN))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3055,6 +3055,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i
|
||||||
int minDist=-1;
|
int minDist=-1;
|
||||||
TileVector t(position);
|
TileVector t(position);
|
||||||
TileVector useTile;
|
TileVector useTile;
|
||||||
|
const int blockObs = ~ignoreObs;
|
||||||
|
|
||||||
float totalDist = sqrtf(float(sqr((search*2)*TILE_SIZE)+sqr((search*2)*TILE_SIZE)));
|
float totalDist = sqrtf(float(sqr((search*2)*TILE_SIZE)+sqr((search*2)*TILE_SIZE)));
|
||||||
for (int x = -search; x <= search; x++)
|
for (int x = -search; x <= search; x++)
|
||||||
|
@ -3069,7 +3070,7 @@ bool Entity::doCollisionAvoidance(float dt, int search, float mod, Vector *vp, i
|
||||||
}
|
}
|
||||||
if (waterBlocked || dsq->game->isObstructed(checkT))
|
if (waterBlocked || dsq->game->isObstructed(checkT))
|
||||||
{
|
{
|
||||||
if (dsq->game->getGrid(checkT) != ignoreObs)
|
if (dsq->game->isObstructed(checkT, blockObs))
|
||||||
{
|
{
|
||||||
Vector vtc(t.x+x, t.y+y);
|
Vector vtc(t.x+x, t.y+y);
|
||||||
Vector vt(t.x, t.y);
|
Vector vt(t.x, t.y);
|
||||||
|
|
159
Aquaria/Game.cpp
159
Aquaria/Game.cpp
|
@ -2075,8 +2075,8 @@ void Game::fillGridFromQuad(Quad *q, ObsType obsType, bool trim)
|
||||||
|
|
||||||
//dsq->game->setGrid(TileVector(tpos.x+(w2*TILE_SIZE)+(x/TILE_SIZE), tpos.y+(h2*TILE_SIZE)+(y/TILE_SIZE)), obsType);
|
//dsq->game->setGrid(TileVector(tpos.x+(w2*TILE_SIZE)+(x/TILE_SIZE), tpos.y+(h2*TILE_SIZE)+(y/TILE_SIZE)), obsType);
|
||||||
TileVector tvec(tpos.x+w2+x, tpos.y+h2+y);
|
TileVector tvec(tpos.x+w2+x, tpos.y+h2+y);
|
||||||
if (dsq->game->getGrid(tvec) == OT_EMPTY)
|
if (!dsq->game->isObstructed(tvec))
|
||||||
dsq->game->setGrid(tvec, obsType);
|
dsq->game->addGrid(tvec, obsType);
|
||||||
|
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
@ -2103,7 +2103,7 @@ void Game::clearDynamicGrid(unsigned char maskbyte /* = OT_MASK_BLACK */)
|
||||||
// otherwise there is a chance to write a few bytes over the end of the buffer -- FG
|
// otherwise there is a chance to write a few bytes over the end of the buffer -- FG
|
||||||
compile_assert(sizeof(grid) % sizeof(uint32) == 0);
|
compile_assert(sizeof(grid) % sizeof(uint32) == 0);
|
||||||
|
|
||||||
signed char *gridstart = &grid[0][0];
|
unsigned char *gridstart = &grid[0][0];
|
||||||
uint32 *gridend = (uint32*)(gridstart + sizeof(grid));
|
uint32 *gridend = (uint32*)(gridstart + sizeof(grid));
|
||||||
uint32 *gridptr = (uint32*)gridstart;
|
uint32 *gridptr = (uint32*)gridstart;
|
||||||
// mask out specific bytes
|
// mask out specific bytes
|
||||||
|
@ -2165,9 +2165,9 @@ void Game::trimGrid()
|
||||||
// from beeing drawn. (The maps were designed with this mind...)
|
// from beeing drawn. (The maps were designed with this mind...)
|
||||||
for (int x = 0; x < MAX_GRID; x++)
|
for (int x = 0; x < MAX_GRID; x++)
|
||||||
{
|
{
|
||||||
const signed char *curCol = dsq->game->getGridColumn(x);
|
const unsigned char *curCol = grid[x]; // safe
|
||||||
const signed char *leftCol = dsq->game->getGridColumn(x-1);
|
const unsigned char *leftCol = dsq->game->getGridColumn(x-1); // unsafe
|
||||||
const signed char *rightCol = dsq->game->getGridColumn(x+1);
|
const unsigned char *rightCol = dsq->game->getGridColumn(x+1); // unsafe
|
||||||
for (int y = 0; y < MAX_GRID; y++)
|
for (int y = 0; y < MAX_GRID; y++)
|
||||||
{
|
{
|
||||||
if (curCol[y] & OT_MASK_BLACK)
|
if (curCol[y] & OT_MASK_BLACK)
|
||||||
|
@ -2179,6 +2179,66 @@ void Game::trimGrid()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Game::dilateGrid(unsigned int radius, ObsType test, ObsType set, ObsType allowOverwrite)
|
||||||
|
{
|
||||||
|
if(!radius)
|
||||||
|
return;
|
||||||
|
const int lim = MAX_GRID - radius;
|
||||||
|
const unsigned int denyOverwrite = ~allowOverwrite;
|
||||||
|
// Box dilation is separable, so we do a two-pass by axis
|
||||||
|
int dilate = 0;
|
||||||
|
|
||||||
|
// dilate rows
|
||||||
|
for (int y = 0; y < MAX_GRID; ++y)
|
||||||
|
{
|
||||||
|
for (int x = radius; x < lim; ++x)
|
||||||
|
{
|
||||||
|
if (grid[x][y] & test)
|
||||||
|
{
|
||||||
|
dilate = 2 * radius;
|
||||||
|
goto doDilate1;
|
||||||
|
}
|
||||||
|
if(dilate)
|
||||||
|
{
|
||||||
|
--dilate;
|
||||||
|
doDilate1:
|
||||||
|
if((grid[x - radius][y] & denyOverwrite) == OT_EMPTY)
|
||||||
|
grid[x - radius][y] |= set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(lim + dilate < MAX_GRID);
|
||||||
|
for(int x = 0; x < dilate; ++x)
|
||||||
|
if(!(grid[x][y - radius] & test))
|
||||||
|
grid[x][y - radius] |= set;
|
||||||
|
}
|
||||||
|
|
||||||
|
// dilate colums
|
||||||
|
dilate = 0;
|
||||||
|
for (int x = 0; x < MAX_GRID; ++x)
|
||||||
|
{
|
||||||
|
unsigned char * const curCol = grid[x];
|
||||||
|
for (int y = radius; y < lim; ++y)
|
||||||
|
{
|
||||||
|
if (curCol[y] & test)
|
||||||
|
{
|
||||||
|
dilate = 2 * radius;
|
||||||
|
goto doDilate2;
|
||||||
|
}
|
||||||
|
if(dilate)
|
||||||
|
{
|
||||||
|
--dilate;
|
||||||
|
doDilate2:
|
||||||
|
if((curCol[y - radius] & denyOverwrite) == OT_EMPTY)
|
||||||
|
curCol[y - radius] |= set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(lim + dilate < MAX_GRID);
|
||||||
|
for(int y = 0; y < dilate; ++y)
|
||||||
|
if(!(curCol[y - radius] & test))
|
||||||
|
curCol[y - radius] |= set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float Game::getCoverage(Vector pos, int sampleArea)
|
float Game::getCoverage(Vector pos, int sampleArea)
|
||||||
{
|
{
|
||||||
TileVector t(pos);
|
TileVector t(pos);
|
||||||
|
@ -6451,30 +6511,46 @@ void Game::applyState()
|
||||||
addRenderObject(songLineRender, LR_HUD);
|
addRenderObject(songLineRender, LR_HUD);
|
||||||
|
|
||||||
gridRender = new GridRender(OT_INVISIBLE);
|
gridRender = new GridRender(OT_INVISIBLE);
|
||||||
|
gridRender->color = Vector(1, 0, 0);
|
||||||
addRenderObject(gridRender, LR_DEBUG_TEXT);
|
addRenderObject(gridRender, LR_DEBUG_TEXT);
|
||||||
gridRender->alpha = 0;
|
gridRender->alpha = 0;
|
||||||
|
|
||||||
gridRender2 = new GridRender(OT_HURT);
|
gridRender2 = new GridRender(OT_HURT);
|
||||||
|
gridRender2->color = Vector(1, 1, 0);
|
||||||
addRenderObject(gridRender2, LR_DEBUG_TEXT);
|
addRenderObject(gridRender2, LR_DEBUG_TEXT);
|
||||||
gridRender2->alpha = 0;
|
gridRender2->alpha = 0;
|
||||||
|
|
||||||
gridRender3 = new GridRender(OT_INVISIBLEIN);
|
gridRender3 = new GridRender(OT_INVISIBLEIN);
|
||||||
|
gridRender3->color = Vector(1, 0.5f, 0);
|
||||||
addRenderObject(gridRender3, LR_DEBUG_TEXT);
|
addRenderObject(gridRender3, LR_DEBUG_TEXT);
|
||||||
gridRender3->alpha = 0;
|
gridRender3->alpha = 0;
|
||||||
|
|
||||||
edgeRender = new GridRender(OT_BLACKINVIS);
|
edgeRender = new GridRender(OT_BLACKINVIS);
|
||||||
|
edgeRender->color = Vector(0.3f, 0, 0.6f);
|
||||||
addRenderObject(edgeRender, LR_DEBUG_TEXT);
|
addRenderObject(edgeRender, LR_DEBUG_TEXT);
|
||||||
edgeRender->alpha = 0;
|
edgeRender->alpha = 0;
|
||||||
|
|
||||||
gridRenderEnt = new GridRender(OT_INVISIBLEENT);
|
gridRenderEnt = new GridRender(OT_INVISIBLEENT);
|
||||||
|
gridRenderEnt->color = Vector(0, 1, 0.5);
|
||||||
addRenderObject(gridRenderEnt, LR_DEBUG_TEXT);
|
addRenderObject(gridRenderEnt, LR_DEBUG_TEXT);
|
||||||
gridRenderEnt->alpha = 0;
|
gridRenderEnt->alpha = 0;
|
||||||
|
|
||||||
|
gridRenderUser1 = new GridRender(OT_USER1);
|
||||||
|
addRenderObject(gridRenderUser1, LR_DEBUG_TEXT);
|
||||||
|
gridRenderUser1->color = Vector(1, 0, 1);
|
||||||
|
gridRenderUser1->alpha = 0;
|
||||||
|
|
||||||
|
gridRenderUser2 = new GridRender(OT_USER2);
|
||||||
|
addRenderObject(gridRenderUser2, LR_DEBUG_TEXT);
|
||||||
|
gridRenderUser2->color = Vector(1, 1, 1);
|
||||||
|
gridRenderUser2->alpha = 0;
|
||||||
|
|
||||||
waterSurfaceRender = new WaterSurfaceRender();
|
waterSurfaceRender = new WaterSurfaceRender();
|
||||||
//waterSurfaceRender->setRenderPass(-1);
|
//waterSurfaceRender->setRenderPass(-1);
|
||||||
addRenderObject(waterSurfaceRender, LR_WATERSURFACE);
|
addRenderObject(waterSurfaceRender, LR_WATERSURFACE);
|
||||||
|
|
||||||
GridRender *blackRender = new GridRender(OT_BLACK);
|
GridRender *blackRender = new GridRender(OT_BLACK);
|
||||||
|
blackRender->color = Vector(0, 0, 0);
|
||||||
//blackRender->alpha = 0;
|
//blackRender->alpha = 0;
|
||||||
blackRender->blendEnabled = false;
|
blackRender->blendEnabled = false;
|
||||||
addRenderObject(blackRender, LR_ELEMENTS4);
|
addRenderObject(blackRender, LR_ELEMENTS4);
|
||||||
|
@ -8515,22 +8591,17 @@ void Game::toggleMiniMapRender(int v)
|
||||||
void Game::toggleGridRender()
|
void Game::toggleGridRender()
|
||||||
{
|
{
|
||||||
float t = 0;
|
float t = 0;
|
||||||
|
float a = 0;
|
||||||
if (gridRender->alpha == 0)
|
if (gridRender->alpha == 0)
|
||||||
{
|
a = 0.5f;
|
||||||
gridRender->alpha.interpolateTo(0.5, t);
|
|
||||||
gridRender2->alpha.interpolateTo(0.5, t);
|
gridRender->alpha.interpolateTo(a, t);
|
||||||
gridRender3->alpha.interpolateTo(0.5, t);
|
gridRender2->alpha.interpolateTo(a, t);
|
||||||
edgeRender->alpha.interpolateTo(0.5, t);
|
gridRender3->alpha.interpolateTo(a, t);
|
||||||
gridRenderEnt->alpha.interpolateTo(0.5, t);
|
edgeRender->alpha.interpolateTo(a, t);
|
||||||
}
|
gridRenderEnt->alpha.interpolateTo(a, t);
|
||||||
else if (gridRender->alpha == 0.5)
|
gridRenderUser1->alpha.interpolateTo(a, t);
|
||||||
{
|
gridRenderUser2->alpha.interpolateTo(a, t);
|
||||||
gridRender->alpha.interpolateTo(0, t);
|
|
||||||
gridRender2->alpha.interpolateTo(0, t);
|
|
||||||
gridRender3->alpha.interpolateTo(0, t);
|
|
||||||
edgeRender->alpha.interpolateTo(0, t);
|
|
||||||
gridRenderEnt->alpha.interpolateTo(0, t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector Game::getCameraPositionFor(const Vector &pos)
|
Vector Game::getCameraPositionFor(const Vector &pos)
|
||||||
|
@ -10624,7 +10695,7 @@ void Game::setGrid(ElementTemplate *et, Vector position, float rot360)
|
||||||
}
|
}
|
||||||
TileVector s(t.x+x, t.y+y);
|
TileVector s(t.x+x, t.y+y);
|
||||||
//Vector v = Vector(position.x+et->grid[i].x*TILE_SIZE, position.y+et->grid[i].y*TILE_SIZE);
|
//Vector v = Vector(position.x+et->grid[i].x*TILE_SIZE, position.y+et->grid[i].y*TILE_SIZE);
|
||||||
setGrid(s, 1);
|
setGrid(s, OT_INVISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10752,6 +10823,12 @@ void Game::removeState()
|
||||||
|
|
||||||
miniMapRender = 0;
|
miniMapRender = 0;
|
||||||
gridRender = 0;
|
gridRender = 0;
|
||||||
|
gridRender2 = 0;
|
||||||
|
gridRender3 = 0;
|
||||||
|
edgeRender = 0;
|
||||||
|
gridRenderEnt = 0;
|
||||||
|
gridRenderUser1 = 0;
|
||||||
|
gridRenderUser2 = 0;
|
||||||
worldMapRender = 0;
|
worldMapRender = 0;
|
||||||
//core->sound->stopStreamingOgg();
|
//core->sound->stopStreamingOgg();
|
||||||
|
|
||||||
|
@ -10922,44 +10999,6 @@ bool Game::collideCircleWithGrid(const Vector& position, float r)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Game::collideBoxWithGrid(const Vector& position, int hw, int hh)
|
|
||||||
{
|
|
||||||
Vector tile = position;
|
|
||||||
TileVector t(tile);
|
|
||||||
tile.x = t.x;
|
|
||||||
tile.y = t.y;
|
|
||||||
|
|
||||||
float hsz = TILE_SIZE/2;
|
|
||||||
int xrange=1,yrange=1;
|
|
||||||
xrange = (hw/TILE_SIZE)+1;
|
|
||||||
yrange = (hh/TILE_SIZE)+1;
|
|
||||||
for (int x = tile.x-xrange; x <= tile.x+xrange; x++)
|
|
||||||
{
|
|
||||||
for (int y = tile.y-yrange; y <= tile.y+yrange; y++)
|
|
||||||
{
|
|
||||||
int v = this->getGrid(TileVector(x, y));
|
|
||||||
if (v == 1)
|
|
||||||
{
|
|
||||||
if (tile.x == x && tile.y == y) return true;
|
|
||||||
float rx = (x*TILE_SIZE)+TILE_SIZE/2;
|
|
||||||
float ry = (y*TILE_SIZE)+TILE_SIZE/2;
|
|
||||||
|
|
||||||
|
|
||||||
if (isBoxIn(position, Vector(hw, hh), Vector(rx, ry), Vector(hsz, hsz)))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (isBoxIn(Vector(rx, ry), Vector(hsz, hsz), position, Vector(hw, hh)))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Game::learnedRecipe(Recipe *r, bool effects)
|
void Game::learnedRecipe(Recipe *r, bool effects)
|
||||||
{
|
{
|
||||||
if (nocasecmp(dsq->getTopStateData()->name,"Game")==0 && !applyingState)
|
if (nocasecmp(dsq->getTopStateData()->name,"Game")==0 && !applyingState)
|
||||||
|
|
|
@ -587,6 +587,14 @@ enum ObsType
|
||||||
|
|
||||||
// set by entities
|
// set by entities
|
||||||
OT_INVISIBLEENT = 0x20,
|
OT_INVISIBLEENT = 0x20,
|
||||||
|
|
||||||
|
// mask for all bits that block
|
||||||
|
OT_BLOCKING = OT_MASK_BLACK | OT_INVISIBLE | OT_INVISIBLEIN | OT_HURT | OT_INVISIBLEENT,
|
||||||
|
|
||||||
|
// free for use, not colliding by default
|
||||||
|
OT_USER1 = 0x40,
|
||||||
|
OT_USER2 = 0x80,
|
||||||
|
OT_USER_MASK = OT_USER1 | OT_USER2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntitySaveData
|
struct EntitySaveData
|
||||||
|
@ -620,12 +628,14 @@ public:
|
||||||
|
|
||||||
std::string getSelectedChoice() { return selectedChoice; }
|
std::string getSelectedChoice() { return selectedChoice; }
|
||||||
|
|
||||||
int getGrid(const TileVector &tile) const;
|
ObsType getGrid(const TileVector &tile) const;
|
||||||
int getGridRaw(unsigned int x, unsigned int y) const;
|
ObsType getGridRaw(const TileVector &tile) const;
|
||||||
const signed char *getGridColumn(int tileX);
|
unsigned char *getGridColumn(int tileX);
|
||||||
void setGrid(const TileVector &tile, int v);
|
void setGrid(const TileVector &tile, ObsType v);
|
||||||
bool isObstructed(const TileVector &tile, int t = -1) const;
|
void addGrid(const TileVector &tile, ObsType v);
|
||||||
|
bool isObstructed(const TileVector &tile, int t = OT_BLOCKING) const;
|
||||||
void trimGrid();
|
void trimGrid();
|
||||||
|
void dilateGrid(unsigned int radius, ObsType test, ObsType set, ObsType allowOverwrite);
|
||||||
|
|
||||||
void clearPointers();
|
void clearPointers();
|
||||||
|
|
||||||
|
@ -655,7 +665,6 @@ public:
|
||||||
|
|
||||||
void registerSporeDrop(const Vector &pos, int t);
|
void registerSporeDrop(const Vector &pos, int t);
|
||||||
|
|
||||||
bool collideBoxWithGrid(const Vector& position, int w, int h);
|
|
||||||
bool collideCircleWithGrid(const Vector& position, float r);
|
bool collideCircleWithGrid(const Vector& position, float r);
|
||||||
|
|
||||||
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, float radius, float perc=0, int *colSegment=0);
|
bool collideHairVsCircle(Entity *a, int num, const Vector &pos2, float radius, float perc=0, int *colSegment=0);
|
||||||
|
@ -959,7 +968,7 @@ public:
|
||||||
void createGradient();
|
void createGradient();
|
||||||
|
|
||||||
std::string saveMusic;
|
std::string saveMusic;
|
||||||
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt;
|
GridRender *gridRender, *gridRender2, *gridRender3, *edgeRender, *gridRenderEnt, *gridRenderUser1, *gridRenderUser2;
|
||||||
void toggleGridRender();
|
void toggleGridRender();
|
||||||
ElementUpdateList elementUpdateList;
|
ElementUpdateList elementUpdateList;
|
||||||
ElementUpdateList elementInteractionList;
|
ElementUpdateList elementInteractionList;
|
||||||
|
@ -1174,7 +1183,7 @@ protected:
|
||||||
void toggleSceneEditor();
|
void toggleSceneEditor();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signed char grid[MAX_GRID][MAX_GRID];
|
unsigned char grid[MAX_GRID][MAX_GRID];
|
||||||
|
|
||||||
|
|
||||||
Quad *bg, *bg2;
|
Quad *bg, *bg2;
|
||||||
|
@ -1200,21 +1209,23 @@ extern Game *game;
|
||||||
// INLINE FUNCTIONS
|
// INLINE FUNCTIONS
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int Game::getGridRaw(unsigned int x, unsigned int y) const
|
ObsType Game::getGridRaw(const TileVector &tile) const
|
||||||
{
|
{
|
||||||
return grid[x][y];
|
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
|
||||||
|
? ObsType(grid[tile.x][tile.y])
|
||||||
|
: OT_INVISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int Game::getGrid(const TileVector &tile) const
|
ObsType Game::getGrid(const TileVector &tile) const
|
||||||
{
|
{
|
||||||
//if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return OT_INVISIBLE;
|
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
|
||||||
//return grid[tile.x][tile.y];
|
? ObsType(grid[tile.x][tile.y] & OT_BLOCKING)
|
||||||
return (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID)) ? grid[tile.x][tile.y] : OT_INVISIBLE;
|
: OT_INVISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
const signed char *Game::getGridColumn(int tileX)
|
unsigned char *Game::getGridColumn(int tileX)
|
||||||
{
|
{
|
||||||
if (tileX < 0)
|
if (tileX < 0)
|
||||||
return grid[0];
|
return grid[0];
|
||||||
|
@ -1225,14 +1236,21 @@ const signed char *Game::getGridColumn(int tileX)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void Game::setGrid(const TileVector &tile, int v)
|
void Game::setGrid(const TileVector &tile, ObsType v)
|
||||||
{
|
{
|
||||||
if (tile.x < 0 || tile.x >= MAX_GRID || tile.y < 0 || tile.y >= MAX_GRID) return;
|
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
|
||||||
grid[tile.x][tile.y] = v;
|
grid[tile.x][tile.y] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool Game::isObstructed(const TileVector &tile, int t /* = -1 */) const
|
void Game::addGrid(const TileVector &tile, ObsType v)
|
||||||
|
{
|
||||||
|
if (unsigned(tile.x) < unsigned(MAX_GRID) && unsigned(tile.y) < unsigned(MAX_GRID))
|
||||||
|
grid[tile.x][tile.y] |= v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool Game::isObstructed(const TileVector &tile, int t /* = OT_BLOCKING */) const
|
||||||
{
|
{
|
||||||
return (getGrid(tile) & t);
|
return (getGrid(tile) & t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,30 +66,6 @@ inline static void doRenderGrid(int x, int startCol, int endCol)
|
||||||
|
|
||||||
void GridRender::onRender()
|
void GridRender::onRender()
|
||||||
{
|
{
|
||||||
switch(obsType)
|
|
||||||
{
|
|
||||||
case OT_INVISIBLE:
|
|
||||||
core->setColor(1, 0, 0, alpha.getValue());
|
|
||||||
break;
|
|
||||||
case OT_INVISIBLEIN:
|
|
||||||
core->setColor(1, 0.5, 0, alpha.getValue());
|
|
||||||
break;
|
|
||||||
case OT_INVISIBLEENT:
|
|
||||||
core->setColor(0, 1, 0.5, alpha.getValue());
|
|
||||||
break;
|
|
||||||
case OT_BLACK:
|
|
||||||
core->setColor(0, 0, 0, 1);
|
|
||||||
break;
|
|
||||||
case OT_BLACKINVIS:
|
|
||||||
core->setColor(0.3, 0, 0.6, alpha.getValue());
|
|
||||||
break;
|
|
||||||
case OT_HURT:
|
|
||||||
core->setColor(1, 1, 0, alpha.getValue());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const signed char obsType = this->obsType;
|
const signed char obsType = this->obsType;
|
||||||
Vector camPos = core->cameraPos;
|
Vector camPos = core->cameraPos;
|
||||||
camPos.x -= core->getVirtualOffX() * (core->invGlobalScale);
|
camPos.x -= core->getVirtualOffX() * (core->invGlobalScale);
|
||||||
|
@ -112,11 +88,11 @@ void GridRender::onRender()
|
||||||
return;
|
return;
|
||||||
for (int x = startX; x <= endX; ++x)
|
for (int x = startX; x <= endX; ++x)
|
||||||
{
|
{
|
||||||
const signed char *gridColumn = dsq->game->getGridColumn(x);
|
const unsigned char *gridColumn = dsq->game->getGridColumn(x);
|
||||||
int startCol = -1, y;
|
int startCol = -1, y;
|
||||||
|
|
||||||
// fast-forward to next drawable byte
|
// fast-forward to next drawable byte
|
||||||
if(const signed char *next = (const signed char*)memchr(gridColumn + startY, obsType, endY - startY + 1)) // find next byte with correct obs type
|
if(const unsigned char *next = (const unsigned char*)memchr(gridColumn + startY, obsType, endY - startY + 1)) // find next byte with correct obs type
|
||||||
{
|
{
|
||||||
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
|
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
|
||||||
startCol = y;
|
startCol = y;
|
||||||
|
@ -131,7 +107,7 @@ void GridRender::onRender()
|
||||||
doRenderGrid(x, startCol, y - 1);
|
doRenderGrid(x, startCol, y - 1);
|
||||||
|
|
||||||
// fast-forward to next drawable byte
|
// fast-forward to next drawable byte
|
||||||
if(const signed char *next = (const signed char*)memchr(gridColumn + y, obsType, endY - y)) // find next byte with correct obs type
|
if(const unsigned char *next = (const unsigned char*)memchr(gridColumn + y, obsType, endY - y)) // find next byte with correct obs type
|
||||||
{
|
{
|
||||||
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
|
y = next - gridColumn; // will get incremented right away, which is okay, because we alrady set startCol
|
||||||
startCol = y;
|
startCol = y;
|
||||||
|
|
|
@ -24,16 +24,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "DSQ.h"
|
#include "DSQ.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
|
||||||
class SearchGrid
|
class SearchGridRaw
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SearchGrid() : game(dsq->game) {}
|
SearchGridRaw(ObsType blocking) : game(dsq->game), blockingObsBits(blocking) {}
|
||||||
inline bool operator()(unsigned x, unsigned y) const
|
inline bool operator()(unsigned x, unsigned y) const
|
||||||
{
|
{
|
||||||
return game->getGrid(TileVector(x, y)) == OT_EMPTY;
|
return (game->getGridRaw(TileVector(x, y)) & blockingObsBits) == OT_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const ObsType blockingObsBits;
|
||||||
const Game *game;
|
const Game *game;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -157,7 +158,7 @@ void PathFinding::generatePath(RenderObject *ro, TileVector start, TileVector go
|
||||||
VectorPath& vp = ro->position.data->path;
|
VectorPath& vp = ro->position.data->path;
|
||||||
vp.clear();
|
vp.clear();
|
||||||
|
|
||||||
SearchGrid grid;
|
SearchGridRaw grid(OT_BLOCKING);
|
||||||
JPS::PathVector path;
|
JPS::PathVector path;
|
||||||
if(JPS::findPath(path, grid, start.x, start.y, goal.x, goal.y, 1))
|
if(JPS::findPath(path, grid, start.x, start.y, goal.x, goal.y, 1))
|
||||||
{
|
{
|
||||||
|
@ -166,9 +167,12 @@ void PathFinding::generatePath(RenderObject *ro, TileVector start, TileVector go
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathFinding::generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step /* = 0 */)
|
bool PathFinding::generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step /* = 0 */, unsigned int obs /* = 0 */)
|
||||||
{
|
{
|
||||||
SearchGrid grid;
|
if(obs == OT_EMPTY)
|
||||||
|
obs = OT_BLOCKING;
|
||||||
|
|
||||||
|
SearchGridRaw grid((ObsType)obs);
|
||||||
JPS::PathVector p;
|
JPS::PathVector p;
|
||||||
TileVector tstart(start);
|
TileVector tstart(start);
|
||||||
TileVector tend(end);
|
TileVector tend(end);
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
void molestPath(VectorPath &path);
|
void molestPath(VectorPath &path);
|
||||||
void generatePath(RenderObject *go, TileVector g1, TileVector g2, int offx=0, int offy=0);
|
void generatePath(RenderObject *go, TileVector g1, TileVector g2, int offx=0, int offy=0);
|
||||||
|
|
||||||
bool generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step = 0);
|
bool generatePathSimple(VectorPath& path, const Vector& start, const Vector& end, unsigned int step = 0, unsigned int obs = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2898,6 +2898,16 @@ luaFunc(reconstructEntityGrid)
|
||||||
luaReturnNil();
|
luaReturnNil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luaFunc(dilateGrid)
|
||||||
|
{
|
||||||
|
unsigned int radius = lua_tointeger(L, 1);
|
||||||
|
ObsType test = (ObsType)lua_tointeger(L, 2);
|
||||||
|
ObsType set = (ObsType)lua_tointeger(L, 3);
|
||||||
|
ObsType allowOverwrite = (ObsType)lua_tointeger(L, 4);
|
||||||
|
dsq->game->dilateGrid(radius, test, set, allowOverwrite);
|
||||||
|
luaReturnNil();
|
||||||
|
}
|
||||||
|
|
||||||
luaFunc(entity_setCanLeaveWater)
|
luaFunc(entity_setCanLeaveWater)
|
||||||
{
|
{
|
||||||
Entity *e = entity(L);
|
Entity *e = entity(L);
|
||||||
|
@ -8347,6 +8357,11 @@ luaFunc(getObstruction)
|
||||||
luaReturnInt(dsq->game->getGrid(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
|
luaReturnInt(dsq->game->getGrid(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
luaFunc(getGridRaw)
|
||||||
|
{
|
||||||
|
luaReturnInt(dsq->game->getGridRaw(TileVector(Vector(lua_tonumber(L, 1), lua_tonumber(L, 2)))));
|
||||||
|
}
|
||||||
|
|
||||||
luaFunc(isObstructedBlock)
|
luaFunc(isObstructedBlock)
|
||||||
{
|
{
|
||||||
float x = lua_tonumber(L, 1);
|
float x = lua_tonumber(L, 1);
|
||||||
|
@ -8568,13 +8583,14 @@ luaFunc(isShuttingDownGameState)
|
||||||
luaReturnBool(dsq->game->isShuttingDownGameState());
|
luaReturnBool(dsq->game->isShuttingDownGameState());
|
||||||
}
|
}
|
||||||
|
|
||||||
// startx, starty, endx, endy [, step, xtab, ytab]
|
// startx, starty, endx, endy [, step, xtab, ytab, obsMask]
|
||||||
luaFunc(findPath)
|
luaFunc(findPath)
|
||||||
{
|
{
|
||||||
VectorPath path;
|
VectorPath path;
|
||||||
Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
Vector start(lua_tonumber(L, 1), lua_tonumber(L, 2));
|
||||||
Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
Vector end(lua_tonumber(L, 3), lua_tonumber(L, 4));
|
||||||
if(!dsq->pathFinding.generatePathSimple(path, start, end, lua_tointeger(L, 5)))
|
ObsType obs = ObsType(lua_tointeger(L, 8));
|
||||||
|
if(!dsq->pathFinding.generatePathSimple(path, start, end, lua_tointeger(L, 5), obs))
|
||||||
luaReturnBool(false);
|
luaReturnBool(false);
|
||||||
|
|
||||||
const unsigned num = path.getNumPathNodes();
|
const unsigned num = path.getNumPathNodes();
|
||||||
|
@ -8964,6 +8980,7 @@ static const struct {
|
||||||
|
|
||||||
luaRegister(reconstructGrid),
|
luaRegister(reconstructGrid),
|
||||||
luaRegister(reconstructEntityGrid),
|
luaRegister(reconstructEntityGrid),
|
||||||
|
luaRegister(dilateGrid),
|
||||||
|
|
||||||
luaRegister(ing_hasIET),
|
luaRegister(ing_hasIET),
|
||||||
luaRegister(ing_getIngredientName),
|
luaRegister(ing_getIngredientName),
|
||||||
|
@ -9463,6 +9480,7 @@ static const struct {
|
||||||
luaRegister(isObstructed),
|
luaRegister(isObstructed),
|
||||||
luaRegister(isObstructedBlock),
|
luaRegister(isObstructedBlock),
|
||||||
luaRegister(getObstruction),
|
luaRegister(getObstruction),
|
||||||
|
luaRegister(getGridRaw),
|
||||||
luaRegister(findPath),
|
luaRegister(findPath),
|
||||||
luaRegister(castLine),
|
luaRegister(castLine),
|
||||||
luaRegister(getUserInputString),
|
luaRegister(getUserInputString),
|
||||||
|
@ -10597,6 +10615,11 @@ static const struct {
|
||||||
luaConstant(OT_INVISIBLEIN),
|
luaConstant(OT_INVISIBLEIN),
|
||||||
luaConstant(OT_HURT),
|
luaConstant(OT_HURT),
|
||||||
luaConstant(OT_INVISIBLEENT),
|
luaConstant(OT_INVISIBLEENT),
|
||||||
|
luaConstant(OT_USER1),
|
||||||
|
luaConstant(OT_USER2),
|
||||||
|
luaConstant(OT_MASK_BLACK),
|
||||||
|
luaConstant(OT_BLOCKING),
|
||||||
|
luaConstant(OT_USER_MASK),
|
||||||
|
|
||||||
luaConstant(SEE_MAP_NEVER),
|
luaConstant(SEE_MAP_NEVER),
|
||||||
luaConstant(SEE_MAP_DEFAULT),
|
luaConstant(SEE_MAP_DEFAULT),
|
||||||
|
|
Loading…
Reference in a new issue