mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 05:31:00 +00:00
- moved the blockmap into a substructure of FLevelLocals.
This part can certainly improved a lot but the most important thing, grouping all those global variables into one place, is done.
This commit is contained in:
parent
f864a09faa
commit
33d36157c8
10 changed files with 189 additions and 174 deletions
|
@ -1831,6 +1831,8 @@ void AM_drawGrid (int color)
|
||||||
mline_t ml;
|
mline_t ml;
|
||||||
double minlen, extx, exty;
|
double minlen, extx, exty;
|
||||||
double minx, miny;
|
double minx, miny;
|
||||||
|
auto bmaporgx = level.blockmap.bmaporgx;
|
||||||
|
auto bmaporgy = level.blockmap.bmaporgy;
|
||||||
|
|
||||||
// [RH] Calculate a minimum for how long the grid lines should be so that
|
// [RH] Calculate a minimum for how long the grid lines should be so that
|
||||||
// they cover the screen at any rotation.
|
// they cover the screen at any rotation.
|
||||||
|
@ -1843,12 +1845,12 @@ void AM_drawGrid (int color)
|
||||||
|
|
||||||
// Figure out start of vertical gridlines
|
// Figure out start of vertical gridlines
|
||||||
start = minx - extx;
|
start = minx - extx;
|
||||||
start = ceil((start - bmaporgx) / MAPBLOCKUNITS) * MAPBLOCKUNITS + bmaporgx;
|
start = ceil((start - bmaporgx) / FBlockmap::MAPBLOCKUNITS) * FBlockmap::MAPBLOCKUNITS + bmaporgx;
|
||||||
|
|
||||||
end = minx + minlen - extx;
|
end = minx + minlen - extx;
|
||||||
|
|
||||||
// draw vertical gridlines
|
// draw vertical gridlines
|
||||||
for (x = start; x < end; x += MAPBLOCKUNITS)
|
for (x = start; x < end; x += FBlockmap::MAPBLOCKUNITS)
|
||||||
{
|
{
|
||||||
ml.a.x = x;
|
ml.a.x = x;
|
||||||
ml.b.x = x;
|
ml.b.x = x;
|
||||||
|
@ -1864,11 +1866,11 @@ void AM_drawGrid (int color)
|
||||||
|
|
||||||
// Figure out start of horizontal gridlines
|
// Figure out start of horizontal gridlines
|
||||||
start = miny - exty;
|
start = miny - exty;
|
||||||
start = ceil((start - bmaporgy) / MAPBLOCKUNITS) * MAPBLOCKUNITS + bmaporgy;
|
start = ceil((start - bmaporgy) / FBlockmap::MAPBLOCKUNITS) * FBlockmap::MAPBLOCKUNITS + bmaporgy;
|
||||||
end = miny + minlen - exty;
|
end = miny + minlen - exty;
|
||||||
|
|
||||||
// draw horizontal gridlines
|
// draw horizontal gridlines
|
||||||
for (y=start; y<end; y+=MAPBLOCKUNITS)
|
for (y=start; y<end; y+=FBlockmap::MAPBLOCKUNITS)
|
||||||
{
|
{
|
||||||
ml.a.x = minx - extx;
|
ml.a.x = minx - extx;
|
||||||
ml.b.x = ml.a.x + minlen;
|
ml.b.x = ml.a.x + minlen;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "g_level.h"
|
#include "g_level.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
#include "portal.h"
|
#include "portal.h"
|
||||||
|
#include "p_blockmap.h"
|
||||||
|
|
||||||
struct FLevelLocals
|
struct FLevelLocals
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,8 @@ struct FLevelLocals
|
||||||
TArray<FSectorPortal> sectorPortals;
|
TArray<FSectorPortal> sectorPortals;
|
||||||
TArray<zone_t> Zones;
|
TArray<zone_t> Zones;
|
||||||
|
|
||||||
|
FBlockmap blockmap;
|
||||||
|
|
||||||
// These are copies of the loaded map data that get used by the savegame code to skip unaltered fields
|
// These are copies of the loaded map data that get used by the savegame code to skip unaltered fields
|
||||||
// Without such a mechanism the savegame format would become too slow and large because more than 80-90% are normally still unaltered.
|
// Without such a mechanism the savegame format would become too slow and large because more than 80-90% are normally still unaltered.
|
||||||
TArray<sector_t> loadsectors;
|
TArray<sector_t> loadsectors;
|
||||||
|
|
|
@ -22,30 +22,73 @@ struct FBlockNode
|
||||||
static FBlockNode *FreeBlocks;
|
static FBlockNode *FreeBlocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int* blockmaplump; // offsets in blockmap are from here
|
// BLOCKMAP
|
||||||
|
// Created from axis aligned bounding box
|
||||||
|
// of the map, a rectangular array of
|
||||||
|
// blocks of size 128x128.
|
||||||
|
// Used to speed up collision detection
|
||||||
|
// by spatial subdivision in 2D.
|
||||||
|
//
|
||||||
|
|
||||||
extern int* blockmap;
|
struct FBlockmap
|
||||||
extern int bmapwidth;
|
{
|
||||||
extern int bmapheight; // in mapblocks
|
int* blockmaplump; // offsets in blockmap are from here
|
||||||
extern double bmaporgx;
|
|
||||||
extern double bmaporgy; // origin of block map
|
int* blockmap;
|
||||||
extern FBlockNode** blocklinks; // for thing chains
|
int bmapwidth;
|
||||||
|
int bmapheight; // in mapblocks
|
||||||
|
double bmaporgx;
|
||||||
|
double bmaporgy; // origin of block map
|
||||||
|
FBlockNode** blocklinks; // for thing chains
|
||||||
|
|
||||||
// mapblocks are used to check movement
|
// mapblocks are used to check movement
|
||||||
// against lines and things
|
// against lines and things
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MAPBLOCKUNITS = 128
|
MAPBLOCKUNITS = 128
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int GetBlockX(double xpos)
|
||||||
|
{
|
||||||
|
return int((xpos - bmaporgx) / MAPBLOCKUNITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int GetBlockY(double ypos)
|
||||||
|
{
|
||||||
|
return int((ypos - bmaporgy) / MAPBLOCKUNITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isValidBlock(int x, int y) const
|
||||||
|
{
|
||||||
|
return ((unsigned int)x < (unsigned int)bmapwidth &&
|
||||||
|
(unsigned int)y < (unsigned int)bmapheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int *GetLines(int x, int y) const
|
||||||
|
{
|
||||||
|
// There is an extra entry at the beginning of every block.
|
||||||
|
// Apparently, id had originally intended for it to be used
|
||||||
|
// to keep track of things, but the final code does not do that.
|
||||||
|
int offset = y*bmapwidth + x;
|
||||||
|
return blockmaplump + *(blockmap + offset) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FBlockmap::VerifyBlockMap(int count);
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
if (blockmaplump != NULL)
|
||||||
|
{
|
||||||
|
delete[] blockmaplump;
|
||||||
|
blockmaplump = NULL;
|
||||||
|
}
|
||||||
|
if (blocklinks != NULL)
|
||||||
|
{
|
||||||
|
delete[] blocklinks;
|
||||||
|
blocklinks = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int GetBlockX(double xpos)
|
|
||||||
{
|
|
||||||
return int((xpos - bmaporgx) / MAPBLOCKUNITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int GetBlockY(double ypos)
|
|
||||||
{
|
|
||||||
return int((ypos - bmaporgy) / MAPBLOCKUNITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1434,7 +1434,7 @@ AActor *LookForTIDInBlock (AActor *lookee, int index, void *extparams)
|
||||||
AActor *link;
|
AActor *link;
|
||||||
AActor *other;
|
AActor *other;
|
||||||
|
|
||||||
for (block = blocklinks[index]; block != NULL; block = block->NextActor)
|
for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
|
||||||
{
|
{
|
||||||
link = block->Me;
|
link = block->Me;
|
||||||
|
|
||||||
|
@ -1613,7 +1613,7 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam)
|
||||||
AActor *other;
|
AActor *other;
|
||||||
FLookExParams *params = (FLookExParams *)extparam;
|
FLookExParams *params = (FLookExParams *)extparam;
|
||||||
|
|
||||||
for (block = blocklinks[index]; block != NULL; block = block->NextActor)
|
for (block = level.blockmap.blocklinks[index]; block != NULL; block = block->NextActor)
|
||||||
{
|
{
|
||||||
link = block->Me;
|
link = block->Me;
|
||||||
|
|
||||||
|
|
|
@ -322,16 +322,15 @@ bool AActor::FixMapthingPos()
|
||||||
{
|
{
|
||||||
sector_t *secstart = P_PointInSectorBuggy(X(), Y());
|
sector_t *secstart = P_PointInSectorBuggy(X(), Y());
|
||||||
|
|
||||||
int blockx = GetBlockX(X());
|
int blockx = level.blockmap.GetBlockX(X());
|
||||||
int blocky = GetBlockY(Y());
|
int blocky = level.blockmap.GetBlockY(Y());
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if ((unsigned int)blockx < (unsigned int)bmapwidth &&
|
if (level.blockmap.isValidBlock(blockx, blocky))
|
||||||
(unsigned int)blocky < (unsigned int)bmapheight)
|
|
||||||
{
|
{
|
||||||
int *list;
|
int *list;
|
||||||
|
|
||||||
for (list = blockmaplump + blockmap[blocky*bmapwidth + blockx] + 1; *list != -1; ++list)
|
for (list = level.blockmap.GetLines(blockx, blocky); *list != -1; ++list)
|
||||||
{
|
{
|
||||||
line_t *ldef = &level.lines[*list];
|
line_t *ldef = &level.lines[*list];
|
||||||
|
|
||||||
|
@ -487,25 +486,25 @@ void AActor::LinkToWorld(FLinkContext *ctx, bool spawningmapthing, sector_t *sec
|
||||||
{
|
{
|
||||||
DVector3 pos = i==-1? Pos() : PosRelative(check[i] & ~FPortalGroupArray::FLAT);
|
DVector3 pos = i==-1? Pos() : PosRelative(check[i] & ~FPortalGroupArray::FLAT);
|
||||||
|
|
||||||
int x1 = GetBlockX(pos.X - radius);
|
int x1 = level.blockmap.GetBlockX(pos.X - radius);
|
||||||
int x2 = GetBlockX(pos.X + radius);
|
int x2 = level.blockmap.GetBlockX(pos.X + radius);
|
||||||
int y1 = GetBlockY(pos.Y - radius);
|
int y1 = level.blockmap.GetBlockY(pos.Y - radius);
|
||||||
int y2 = GetBlockY(pos.Y + radius);
|
int y2 = level.blockmap.GetBlockY(pos.Y + radius);
|
||||||
|
|
||||||
if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0)
|
if (x1 >= level.blockmap.bmapwidth || x2 < 0 || y1 >= level.blockmap.bmapheight || y2 < 0)
|
||||||
{ // thing is off the map
|
{ // thing is off the map
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // [RH] Link into every block this actor touches, not just the center one
|
{ // [RH] Link into every block this actor touches, not just the center one
|
||||||
x1 = MAX(0, x1);
|
x1 = MAX(0, x1);
|
||||||
y1 = MAX(0, y1);
|
y1 = MAX(0, y1);
|
||||||
x2 = MIN(bmapwidth - 1, x2);
|
x2 = MIN(level.blockmap.bmapwidth - 1, x2);
|
||||||
y2 = MIN(bmapheight - 1, y2);
|
y2 = MIN(level.blockmap.bmapheight - 1, y2);
|
||||||
for (int y = y1; y <= y2; ++y)
|
for (int y = y1; y <= y2; ++y)
|
||||||
{
|
{
|
||||||
for (int x = x1; x <= x2; ++x)
|
for (int x = x1; x <= x2; ++x)
|
||||||
{
|
{
|
||||||
FBlockNode **link = &blocklinks[y*bmapwidth + x];
|
FBlockNode **link = &level.blockmap.blocklinks[y*level.blockmap.bmapwidth + x];
|
||||||
FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup);
|
FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup);
|
||||||
|
|
||||||
// Link in to block
|
// Link in to block
|
||||||
|
@ -580,7 +579,7 @@ FBlockNode *FBlockNode::Create (AActor *who, int x, int y, int group)
|
||||||
{
|
{
|
||||||
block = new FBlockNode;
|
block = new FBlockNode;
|
||||||
}
|
}
|
||||||
block->BlockIndex = x + y*bmapwidth;
|
block->BlockIndex = x + y*level.blockmap.bmapwidth;
|
||||||
block->Me = who;
|
block->Me = who;
|
||||||
block->NextActor = NULL;
|
block->NextActor = NULL;
|
||||||
block->PrevActor = NULL;
|
block->PrevActor = NULL;
|
||||||
|
@ -624,10 +623,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m
|
||||||
void FBlockLinesIterator::init(const FBoundingBox &box)
|
void FBlockLinesIterator::init(const FBoundingBox &box)
|
||||||
{
|
{
|
||||||
validcount++;
|
validcount++;
|
||||||
maxy = GetBlockY(box.Top());
|
maxy = level.blockmap.GetBlockY(box.Top());
|
||||||
miny = GetBlockY(box.Bottom());
|
miny = level.blockmap.GetBlockY(box.Bottom());
|
||||||
maxx = GetBlockX(box.Right());
|
maxx = level.blockmap.GetBlockX(box.Right());
|
||||||
minx = GetBlockX(box.Left());
|
minx = level.blockmap.GetBlockX(box.Left());
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,16 +645,13 @@ void FBlockLinesIterator::StartBlock(int x, int y)
|
||||||
{
|
{
|
||||||
curx = x;
|
curx = x;
|
||||||
cury = y;
|
cury = y;
|
||||||
if (x >= 0 && y >= 0 && x < bmapwidth && y <bmapheight)
|
if (level.blockmap.isValidBlock(x, y))
|
||||||
{
|
{
|
||||||
int offset = y*bmapwidth + x;
|
int offset = y*level.blockmap.bmapwidth + x;
|
||||||
polyLink = PolyBlockMap? PolyBlockMap[offset] : NULL;
|
polyLink = PolyBlockMap? PolyBlockMap[offset] : NULL;
|
||||||
polyIndex = 0;
|
polyIndex = 0;
|
||||||
|
|
||||||
// There is an extra entry at the beginning of every block.
|
list = level.blockmap.GetLines(x, y);
|
||||||
// Apparently, id had originally intended for it to be used
|
|
||||||
// to keep track of things, but the final code does not do that.
|
|
||||||
list = blockmaplump + *(blockmap + offset) + 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -994,10 +990,10 @@ FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int
|
||||||
|
|
||||||
void FBlockThingsIterator::init(const FBoundingBox &box)
|
void FBlockThingsIterator::init(const FBoundingBox &box)
|
||||||
{
|
{
|
||||||
maxy = GetBlockY(box.Top());
|
maxy = level.blockmap.GetBlockY(box.Top());
|
||||||
miny = GetBlockY(box.Bottom());
|
miny = level.blockmap.GetBlockY(box.Bottom());
|
||||||
maxx = GetBlockX(box.Right());
|
maxx = level.blockmap.GetBlockX(box.Right());
|
||||||
minx = GetBlockX(box.Left());
|
minx = level.blockmap.GetBlockX(box.Left());
|
||||||
ClearHash();
|
ClearHash();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
@ -1025,9 +1021,9 @@ void FBlockThingsIterator::StartBlock(int x, int y)
|
||||||
{
|
{
|
||||||
curx = x;
|
curx = x;
|
||||||
cury = y;
|
cury = y;
|
||||||
if (x >= 0 && y >= 0 && x < bmapwidth && y <bmapheight)
|
if (level.blockmap.isValidBlock(x, y))
|
||||||
{
|
{
|
||||||
block = blocklinks[y*bmapwidth + x];
|
block = level.blockmap.blocklinks[y*level.blockmap.bmapwidth + x];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1075,10 +1071,10 @@ AActor *FBlockThingsIterator::Next(bool centeronly)
|
||||||
if (centeronly)
|
if (centeronly)
|
||||||
{
|
{
|
||||||
// Block boundaries for compatibility mode
|
// Block boundaries for compatibility mode
|
||||||
double blockleft = (curx * MAPBLOCKUNITS) + bmaporgx;
|
double blockleft = (curx * FBlockmap::MAPBLOCKUNITS) + level.blockmap.bmaporgx;
|
||||||
double blockright = blockleft + MAPBLOCKUNITS;
|
double blockright = blockleft + FBlockmap::MAPBLOCKUNITS;
|
||||||
double blockbottom = (cury * MAPBLOCKUNITS) + bmaporgy;
|
double blockbottom = (cury * FBlockmap::MAPBLOCKUNITS) + level.blockmap.bmaporgy;
|
||||||
double blocktop = blockbottom + MAPBLOCKUNITS;
|
double blocktop = blockbottom + FBlockmap::MAPBLOCKUNITS;
|
||||||
|
|
||||||
// only return actors with the center in this block
|
// only return actors with the center in this block
|
||||||
if (me->X() >= blockleft && me->X() < blockright &&
|
if (me->X() >= blockleft && me->X() < blockright &&
|
||||||
|
@ -1618,15 +1614,15 @@ void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags,
|
||||||
y2 += y1;
|
y2 += y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 -= bmaporgx;
|
x1 -= level.blockmap.bmaporgx;
|
||||||
y1 -= bmaporgy;
|
y1 -= level.blockmap.bmaporgy;
|
||||||
xt1 = x1 / MAPBLOCKUNITS;
|
xt1 = x1 / FBlockmap::MAPBLOCKUNITS;
|
||||||
yt1 = y1 / MAPBLOCKUNITS;
|
yt1 = y1 / FBlockmap::MAPBLOCKUNITS;
|
||||||
|
|
||||||
x2 -= bmaporgx;
|
x2 -= level.blockmap.bmaporgx;
|
||||||
y2 -= bmaporgy;
|
y2 -= level.blockmap.bmaporgy;
|
||||||
xt2 = x2 / MAPBLOCKUNITS;
|
xt2 = x2 / FBlockmap::MAPBLOCKUNITS;
|
||||||
yt2 = y2 / MAPBLOCKUNITS;
|
yt2 = y2 / FBlockmap::MAPBLOCKUNITS;
|
||||||
|
|
||||||
mapx = xs_FloorToInt(xt1);
|
mapx = xs_FloorToInt(xt1);
|
||||||
mapy = xs_FloorToInt(yt1);
|
mapy = xs_FloorToInt(yt1);
|
||||||
|
@ -1834,7 +1830,7 @@ FPathTraverse::~FPathTraverse()
|
||||||
// P_RoughMonsterSearch
|
// P_RoughMonsterSearch
|
||||||
//
|
//
|
||||||
// Searches though the surrounding mapblocks for monsters/players
|
// Searches though the surrounding mapblocks for monsters/players
|
||||||
// distance is in MAPBLOCKUNITS
|
// distance is in FBlockmap::MAPBLOCKUNITS
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params)
|
AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, int, void *), void *params)
|
||||||
|
@ -1849,12 +1845,14 @@ AActor *P_BlockmapSearch (AActor *mo, int distance, AActor *(*check)(AActor*, in
|
||||||
int finalStop;
|
int finalStop;
|
||||||
int count;
|
int count;
|
||||||
AActor *target;
|
AActor *target;
|
||||||
|
int bmapwidth = level.blockmap.bmapwidth;
|
||||||
|
int bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
startX = GetBlockX(mo->X());
|
startX = level.blockmap.GetBlockX(mo->X());
|
||||||
startY = GetBlockY(mo->Y());
|
startY = level.blockmap.GetBlockY(mo->Y());
|
||||||
validcount++;
|
validcount++;
|
||||||
|
|
||||||
if (startX >= 0 && startX < bmapwidth && startY >= 0 && startY < bmapheight)
|
if (level.blockmap.isValidBlock(startX, startY))
|
||||||
{
|
{
|
||||||
if ( (target = check (mo, startY*bmapwidth+startX, params)) )
|
if ( (target = check (mo, startY*bmapwidth+startX, params)) )
|
||||||
{ // found a target right away
|
{ // found a target right away
|
||||||
|
@ -1945,7 +1943,7 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param)
|
||||||
|
|
||||||
FBlockNode *link;
|
FBlockNode *link;
|
||||||
|
|
||||||
for (link = blocklinks[index]; link != NULL; link = link->NextActor)
|
for (link = level.blockmap.blocklinks[index]; link != NULL; link = link->NextActor)
|
||||||
{
|
{
|
||||||
if (link->Me != mo)
|
if (link->Me != mo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -388,11 +388,11 @@ void AActor::UpdateRenderSectorList()
|
||||||
ClearRenderLineList();
|
ClearRenderLineList();
|
||||||
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY())
|
||||||
{
|
{
|
||||||
int bx = GetBlockX(X());
|
int bx = level.blockmap.GetBlockX(X());
|
||||||
int by = GetBlockY(Y());
|
int by = level.blockmap.GetBlockY(Y());
|
||||||
FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors
|
FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors
|
||||||
// Are there any portals near the actor's position?
|
// Are there any portals near the actor's position?
|
||||||
if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines)
|
if (level.blockmap.isValidBlock(bx, by) && PortalBlockmap(bx, by).neighborContainsLines)
|
||||||
{
|
{
|
||||||
// Go through the entire list. In most cases this is faster than setting up a blockmap iterator
|
// Go through the entire list. In most cases this is faster than setting up a blockmap iterator
|
||||||
for (auto &p : linePortals)
|
for (auto &p : linePortals)
|
||||||
|
|
|
@ -136,34 +136,6 @@ sidei_t *sidetemp;
|
||||||
|
|
||||||
TArray<int> linemap;
|
TArray<int> linemap;
|
||||||
|
|
||||||
// BLOCKMAP
|
|
||||||
// Created from axis aligned bounding box
|
|
||||||
// of the map, a rectangular array of
|
|
||||||
// blocks of size 256x256.
|
|
||||||
// Used to speed up collision detection
|
|
||||||
// by spatial subdivision in 2D.
|
|
||||||
//
|
|
||||||
// Blockmap size.
|
|
||||||
int bmapwidth;
|
|
||||||
int bmapheight; // size in mapblocks
|
|
||||||
|
|
||||||
int *blockmap; // int for larger maps ([RH] Made int because BOOM does)
|
|
||||||
int *blockmaplump; // offsets in blockmap are from here
|
|
||||||
|
|
||||||
double bmaporgx; // origin of block map
|
|
||||||
double bmaporgy;
|
|
||||||
|
|
||||||
FBlockNode** blocklinks; // for thing chains
|
|
||||||
|
|
||||||
|
|
||||||
// REJECT
|
|
||||||
// For fast sight rejection.
|
|
||||||
// Speeds up enemy AI by skipping detailed
|
|
||||||
// LineOf Sight calculation.
|
|
||||||
// Without special effect, this could be
|
|
||||||
// used as a PVS lookup as well.
|
|
||||||
//
|
|
||||||
|
|
||||||
bool ForceNodeBuild;
|
bool ForceNodeBuild;
|
||||||
|
|
||||||
static void P_AllocateSideDefs (MapData *map, int count);
|
static void P_AllocateSideDefs (MapData *map, int count);
|
||||||
|
@ -2868,10 +2840,10 @@ static void P_CreateBlockMap ()
|
||||||
CreatePackedBlockmap (BlockMap, BlockLists, bmapwidth, bmapheight);
|
CreatePackedBlockmap (BlockMap, BlockLists, bmapwidth, bmapheight);
|
||||||
delete[] BlockLists;
|
delete[] BlockLists;
|
||||||
|
|
||||||
blockmaplump = new int[BlockMap.Size()];
|
level.blockmap.blockmaplump = new int[BlockMap.Size()];
|
||||||
for (unsigned int ii = 0; ii < BlockMap.Size(); ++ii)
|
for (unsigned int ii = 0; ii < BlockMap.Size(); ++ii)
|
||||||
{
|
{
|
||||||
blockmaplump[ii] = BlockMap[ii];
|
level.blockmap.blockmaplump[ii] = BlockMap[ii];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2882,7 +2854,7 @@ static void P_CreateBlockMap ()
|
||||||
//
|
//
|
||||||
// haleyjd 03/04/10: do verification on validity of blockmap.
|
// haleyjd 03/04/10: do verification on validity of blockmap.
|
||||||
//
|
//
|
||||||
static bool P_VerifyBlockMap(int count)
|
bool FBlockmap::VerifyBlockMap(int count)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
int *maxoffs = blockmaplump + count;
|
int *maxoffs = blockmaplump + count;
|
||||||
|
@ -2905,7 +2877,7 @@ static bool P_VerifyBlockMap(int count)
|
||||||
// check that block offset is in bounds
|
// check that block offset is in bounds
|
||||||
if(blockoffset >= maxoffs)
|
if(blockoffset >= maxoffs)
|
||||||
{
|
{
|
||||||
Printf(PRINT_HIGH, "P_VerifyBlockMap: block offset overflow\n");
|
Printf(PRINT_HIGH, "VerifyBlockMap: block offset overflow\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2914,7 +2886,7 @@ static bool P_VerifyBlockMap(int count)
|
||||||
// check that list offset is in bounds
|
// check that list offset is in bounds
|
||||||
if(offset < 4 || offset >= count)
|
if(offset < 4 || offset >= count)
|
||||||
{
|
{
|
||||||
Printf(PRINT_HIGH, "P_VerifyBlockMap: list offset overflow\n");
|
Printf(PRINT_HIGH, "VerifyBlockMap: list offset overflow\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2926,7 +2898,7 @@ static bool P_VerifyBlockMap(int count)
|
||||||
// we have overflowed the lump?
|
// we have overflowed the lump?
|
||||||
if(tmplist >= maxoffs)
|
if(tmplist >= maxoffs)
|
||||||
{
|
{
|
||||||
Printf(PRINT_HIGH, "P_VerifyBlockMap: open blocklist\n");
|
Printf(PRINT_HIGH, "VerifyBlockMap: open blocklist\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(*tmplist == -1) // found -1
|
if(*tmplist == -1) // found -1
|
||||||
|
@ -2938,7 +2910,7 @@ static bool P_VerifyBlockMap(int count)
|
||||||
// to be on the safe side.
|
// to be on the safe side.
|
||||||
if (*list != 0)
|
if (*list != 0)
|
||||||
{
|
{
|
||||||
Printf(PRINT_HIGH, "P_VerifyBlockMap: first entry is not 0.\n");
|
Printf(PRINT_HIGH, "VerifyBlockMap: first entry is not 0.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2947,7 +2919,7 @@ static bool P_VerifyBlockMap(int count)
|
||||||
{
|
{
|
||||||
if((unsigned)*tmplist >= level.lines.Size())
|
if((unsigned)*tmplist >= level.lines.Size())
|
||||||
{
|
{
|
||||||
Printf(PRINT_HIGH, "P_VerifyBlockMap: index >= numlines\n");
|
Printf(PRINT_HIGH, "VerifyBlockMap: index >= numlines\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2986,26 +2958,26 @@ void P_LoadBlockMap (MapData * map)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
count/=2;
|
count/=2;
|
||||||
blockmaplump = new int[count];
|
level.blockmap.blockmaplump = new int[count];
|
||||||
|
|
||||||
// killough 3/1/98: Expand wad blockmap into larger internal one,
|
// killough 3/1/98: Expand wad blockmap into larger internal one,
|
||||||
// by treating all offsets except -1 as unsigned and zero-extending
|
// by treating all offsets except -1 as unsigned and zero-extending
|
||||||
// them. This potentially doubles the size of blockmaps allowed,
|
// them. This potentially doubles the size of blockmaps allowed,
|
||||||
// because Doom originally considered the offsets as always signed.
|
// because Doom originally considered the offsets as always signed.
|
||||||
|
|
||||||
blockmaplump[0] = LittleShort(wadblockmaplump[0]);
|
level.blockmap.blockmaplump[0] = LittleShort(wadblockmaplump[0]);
|
||||||
blockmaplump[1] = LittleShort(wadblockmaplump[1]);
|
level.blockmap.blockmaplump[1] = LittleShort(wadblockmaplump[1]);
|
||||||
blockmaplump[2] = (uint32_t)(LittleShort(wadblockmaplump[2])) & 0xffff;
|
level.blockmap.blockmaplump[2] = (uint32_t)(LittleShort(wadblockmaplump[2])) & 0xffff;
|
||||||
blockmaplump[3] = (uint32_t)(LittleShort(wadblockmaplump[3])) & 0xffff;
|
level.blockmap.blockmaplump[3] = (uint32_t)(LittleShort(wadblockmaplump[3])) & 0xffff;
|
||||||
|
|
||||||
for (i = 4; i < count; i++)
|
for (i = 4; i < count; i++)
|
||||||
{
|
{
|
||||||
short t = LittleShort(wadblockmaplump[i]); // killough 3/1/98
|
short t = LittleShort(wadblockmaplump[i]); // killough 3/1/98
|
||||||
blockmaplump[i] = t == -1 ? (uint32_t)0xffffffff : (uint32_t) t & 0xffff;
|
level.blockmap.blockmaplump[i] = t == -1 ? (uint32_t)0xffffffff : (uint32_t) t & 0xffff;
|
||||||
}
|
}
|
||||||
delete[] data;
|
delete[] data;
|
||||||
|
|
||||||
if (!P_VerifyBlockMap(count))
|
if (!level.blockmap.VerifyBlockMap(count))
|
||||||
{
|
{
|
||||||
DPrintf (DMSG_SPAMMY, "Generating BLOCKMAP\n");
|
DPrintf (DMSG_SPAMMY, "Generating BLOCKMAP\n");
|
||||||
P_CreateBlockMap();
|
P_CreateBlockMap();
|
||||||
|
@ -3013,16 +2985,16 @@ void P_LoadBlockMap (MapData * map)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bmaporgx = blockmaplump[0];
|
level.blockmap.bmaporgx = level.blockmap.blockmaplump[0];
|
||||||
bmaporgy = blockmaplump[1];
|
level.blockmap.bmaporgy = level.blockmap.blockmaplump[1];
|
||||||
bmapwidth = blockmaplump[2];
|
level.blockmap.bmapwidth = level.blockmap.blockmaplump[2];
|
||||||
bmapheight = blockmaplump[3];
|
level.blockmap.bmapheight = level.blockmap.blockmaplump[3];
|
||||||
|
|
||||||
// clear out mobj chains
|
// clear out mobj chains
|
||||||
count = bmapwidth*bmapheight;
|
count = level.blockmap.bmapwidth*level.blockmap.bmapheight;
|
||||||
blocklinks = new FBlockNode *[count];
|
level.blockmap.blocklinks = new FBlockNode *[count];
|
||||||
memset (blocklinks, 0, count*sizeof(*blocklinks));
|
memset (level.blockmap.blocklinks, 0, count*sizeof(*level.blockmap.blocklinks));
|
||||||
blockmap = blockmaplump+4;
|
level.blockmap.blockmap = level.blockmap.blockmaplump+4;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3432,20 +3404,11 @@ void P_FreeLevelData ()
|
||||||
level.gamesubsectors.Reset();
|
level.gamesubsectors.Reset();
|
||||||
level.rejectmatrix.Clear();
|
level.rejectmatrix.Clear();
|
||||||
level.Zones.Clear();
|
level.Zones.Clear();
|
||||||
|
level.blockmap.Clear();
|
||||||
|
|
||||||
if (blockmaplump != NULL)
|
|
||||||
{
|
|
||||||
delete[] blockmaplump;
|
|
||||||
blockmaplump = NULL;
|
|
||||||
}
|
|
||||||
if (blocklinks != NULL)
|
|
||||||
{
|
|
||||||
delete[] blocklinks;
|
|
||||||
blocklinks = NULL;
|
|
||||||
}
|
|
||||||
if (PolyBlockMap != NULL)
|
if (PolyBlockMap != NULL)
|
||||||
{
|
{
|
||||||
for (int i = bmapwidth*bmapheight-1; i >= 0; --i)
|
for (int i = level.blockmap.bmapwidth*level.blockmap.bmapheight-1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
polyblock_t *link = PolyBlockMap[i];
|
polyblock_t *link = PolyBlockMap[i];
|
||||||
while (link != NULL)
|
while (link != NULL)
|
||||||
|
|
|
@ -470,7 +470,7 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y)
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
extern polyblock_t **PolyBlockMap;
|
extern polyblock_t **PolyBlockMap;
|
||||||
|
|
||||||
offset = y*bmapwidth+x;
|
offset = y*level.blockmap.bmapwidth+x;
|
||||||
|
|
||||||
// if any of the previous blocks may contain a portal we may abort the collection of lines here, but we may not abort the sight check.
|
// if any of the previous blocks may contain a portal we may abort the collection of lines here, but we may not abort the sight check.
|
||||||
// (We still try to delay activating this for as long as possible.)
|
// (We still try to delay activating this for as long as possible.)
|
||||||
|
@ -498,9 +498,7 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y)
|
||||||
polyLink = polyLink->next;
|
polyLink = polyLink->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = *(blockmap + offset);
|
for (list = level.blockmap.GetLines(x, y); *list != -1; list++)
|
||||||
|
|
||||||
for (list = blockmaplump + offset + 1; *list != -1; list++)
|
|
||||||
{
|
{
|
||||||
if (!P_SightCheckLine (&level.lines[*list]))
|
if (!P_SightCheckLine (&level.lines[*list]))
|
||||||
{
|
{
|
||||||
|
@ -655,15 +653,15 @@ bool SightCheck::P_SightPathTraverse ()
|
||||||
portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->GetOppositePortalGroup(sector_t::floor) });
|
portals.Push({ 0, topslope, bottomslope, sector_t::floor, lastsector->GetOppositePortalGroup(sector_t::floor) });
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 -= bmaporgx;
|
x1 -= level.blockmap.bmaporgx;
|
||||||
y1 -= bmaporgy;
|
y1 -= level.blockmap.bmaporgy;
|
||||||
xt1 = x1 / MAPBLOCKUNITS;
|
xt1 = x1 / FBlockmap::MAPBLOCKUNITS;
|
||||||
yt1 = y1 / MAPBLOCKUNITS;
|
yt1 = y1 / FBlockmap::MAPBLOCKUNITS;
|
||||||
|
|
||||||
x2 -= bmaporgx;
|
x2 -= level.blockmap.bmaporgx;
|
||||||
y2 -= bmaporgy;
|
y2 -= level.blockmap.bmaporgy;
|
||||||
xt2 = x2 / MAPBLOCKUNITS;
|
xt2 = x2 / FBlockmap::MAPBLOCKUNITS;
|
||||||
yt2 = y2 / MAPBLOCKUNITS;
|
yt2 = y2 / FBlockmap::MAPBLOCKUNITS;
|
||||||
|
|
||||||
mapx = xs_FloorToInt(xt1);
|
mapx = xs_FloorToInt(xt1);
|
||||||
mapy = xs_FloorToInt(yt1);
|
mapy = xs_FloorToInt(yt1);
|
||||||
|
@ -741,7 +739,7 @@ bool SightCheck::P_SightPathTraverse ()
|
||||||
{
|
{
|
||||||
// end traversing when reaching the end of the blockmap
|
// end traversing when reaching the end of the blockmap
|
||||||
// an early out is not possible because with portals a trace can easily land outside the map's bounds.
|
// an early out is not possible because with portals a trace can easily land outside the map's bounds.
|
||||||
if (mapx < 0 || mapx >= bmapwidth || mapy < 0 || mapy >= bmapheight)
|
if (level.blockmap.isValidBlock(mapx, mapy))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1069,10 +1069,10 @@ void FPolyObj::UnLinkPolyobj ()
|
||||||
// remove the polyobj from each blockmap section
|
// remove the polyobj from each blockmap section
|
||||||
for(j = bbox[BOXBOTTOM]; j <= bbox[BOXTOP]; j++)
|
for(j = bbox[BOXBOTTOM]; j <= bbox[BOXTOP]; j++)
|
||||||
{
|
{
|
||||||
index = j*bmapwidth;
|
index = j*level.blockmap.bmapwidth;
|
||||||
for(i = bbox[BOXLEFT]; i <= bbox[BOXRIGHT]; i++)
|
for(i = bbox[BOXLEFT]; i <= bbox[BOXRIGHT]; i++)
|
||||||
{
|
{
|
||||||
if(i >= 0 && i < bmapwidth && j >= 0 && j < bmapheight)
|
if(i >= 0 && i < level.blockmap.bmapwidth && j >= 0 && j < level.blockmap.bmapheight)
|
||||||
{
|
{
|
||||||
link = PolyBlockMap[index+i];
|
link = PolyBlockMap[index+i];
|
||||||
while(link != NULL && link->polyobj != this)
|
while(link != NULL && link->polyobj != this)
|
||||||
|
@ -1105,13 +1105,15 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
|
||||||
line_t *ld;
|
line_t *ld;
|
||||||
bool blocked;
|
bool blocked;
|
||||||
bool performBlockingThrust;
|
bool performBlockingThrust;
|
||||||
|
int bmapwidth = level.blockmap.bmapwidth;
|
||||||
|
int bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
ld = sd->linedef;
|
ld = sd->linedef;
|
||||||
|
|
||||||
top = GetBlockY(ld->bbox[BOXTOP]);
|
top = level.blockmap.GetBlockY(ld->bbox[BOXTOP]);
|
||||||
bottom = GetBlockY(ld->bbox[BOXBOTTOM]);
|
bottom = level.blockmap.GetBlockY(ld->bbox[BOXBOTTOM]);
|
||||||
left = GetBlockX(ld->bbox[BOXLEFT]);
|
left = level.blockmap.GetBlockX(ld->bbox[BOXLEFT]);
|
||||||
right = GetBlockX(ld->bbox[BOXRIGHT]);
|
right = level.blockmap.GetBlockX(ld->bbox[BOXRIGHT]);
|
||||||
|
|
||||||
blocked = false;
|
blocked = false;
|
||||||
checker.Clear();
|
checker.Clear();
|
||||||
|
@ -1129,7 +1131,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd)
|
||||||
{
|
{
|
||||||
for (i = left; i <= right; i++)
|
for (i = left; i <= right; i++)
|
||||||
{
|
{
|
||||||
for (block = blocklinks[j+i]; block != NULL; block = block->NextActor)
|
for (block = level.blockmap.blocklinks[j+i]; block != NULL; block = block->NextActor)
|
||||||
{
|
{
|
||||||
mobj = block->Me;
|
mobj = block->Me;
|
||||||
for (k = (int)checker.Size()-1; k >= 0; --k)
|
for (k = (int)checker.Size()-1; k >= 0; --k)
|
||||||
|
@ -1230,6 +1232,8 @@ void FPolyObj::LinkPolyobj ()
|
||||||
{
|
{
|
||||||
polyblock_t **link;
|
polyblock_t **link;
|
||||||
polyblock_t *tempLink;
|
polyblock_t *tempLink;
|
||||||
|
int bmapwidth = level.blockmap.bmapwidth;
|
||||||
|
int bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
// calculate the polyobj bbox
|
// calculate the polyobj bbox
|
||||||
Bounds.ClearBox();
|
Bounds.ClearBox();
|
||||||
|
@ -1242,10 +1246,10 @@ void FPolyObj::LinkPolyobj ()
|
||||||
vt = Sidedefs[i]->linedef->v2;
|
vt = Sidedefs[i]->linedef->v2;
|
||||||
Bounds.AddToBox(vt->fPos());
|
Bounds.AddToBox(vt->fPos());
|
||||||
}
|
}
|
||||||
bbox[BOXRIGHT] = GetBlockX(Bounds.Right());
|
bbox[BOXRIGHT] = level.blockmap.GetBlockX(Bounds.Right());
|
||||||
bbox[BOXLEFT] = GetBlockX(Bounds.Left());
|
bbox[BOXLEFT] = level.blockmap.GetBlockX(Bounds.Left());
|
||||||
bbox[BOXTOP] = GetBlockY(Bounds.Top());
|
bbox[BOXTOP] = level.blockmap.GetBlockY(Bounds.Top());
|
||||||
bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom());
|
bbox[BOXBOTTOM] = level.blockmap.GetBlockY(Bounds.Bottom());
|
||||||
// add the polyobj to each blockmap section
|
// add the polyobj to each blockmap section
|
||||||
for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth;
|
for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth;
|
||||||
j += bmapwidth)
|
j += bmapwidth)
|
||||||
|
@ -1398,6 +1402,8 @@ void FPolyObj::ClosestPoint(const DVector2 &fpos, DVector2 &out, side_t **side)
|
||||||
static void InitBlockMap (void)
|
static void InitBlockMap (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int bmapwidth = level.blockmap.bmapwidth;
|
||||||
|
int bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
PolyBlockMap = new polyblock_t *[bmapwidth*bmapheight];
|
PolyBlockMap = new polyblock_t *[bmapwidth*bmapheight];
|
||||||
memset (PolyBlockMap, 0, bmapwidth*bmapheight*sizeof(polyblock_t *));
|
memset (PolyBlockMap, 0, bmapwidth*bmapheight*sizeof(polyblock_t *));
|
||||||
|
|
|
@ -113,14 +113,16 @@ struct FPortalBits
|
||||||
|
|
||||||
static void BuildBlockmap()
|
static void BuildBlockmap()
|
||||||
{
|
{
|
||||||
|
auto bmapwidth = level.blockmap.bmapwidth;
|
||||||
|
auto bmapheight = level.blockmap.bmapheight;
|
||||||
|
|
||||||
PortalBlockmap.Clear();
|
PortalBlockmap.Clear();
|
||||||
PortalBlockmap.Create(bmapwidth, bmapheight);
|
PortalBlockmap.Create(bmapwidth, bmapheight);
|
||||||
for (int y = 0; y < bmapheight; y++)
|
for (int y = 0; y < bmapheight; y++)
|
||||||
{
|
{
|
||||||
for (int x = 0; x < bmapwidth; x++)
|
for (int x = 0; x < bmapwidth; x++)
|
||||||
{
|
{
|
||||||
int offset = y*bmapwidth + x;
|
int *list = level.blockmap.GetLines(x, y);
|
||||||
int *list = blockmaplump + *(blockmap + offset) + 1;
|
|
||||||
FPortalBlock &block = PortalBlockmap(x, y);
|
FPortalBlock &block = PortalBlockmap(x, y);
|
||||||
|
|
||||||
while (*list != -1)
|
while (*list != -1)
|
||||||
|
@ -165,7 +167,7 @@ static void BuildBlockmap()
|
||||||
|
|
||||||
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
|
void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
|
||||||
{
|
{
|
||||||
if (by < 0 || by >= bmapheight || bx < 0 || bx >= bmapwidth) return;
|
if (by < 0 || by >= PortalBlockmap.dx || bx < 0 || bx >= PortalBlockmap.dy) return;
|
||||||
|
|
||||||
FPortalBlock &block = PortalBlockmap(bx, by);
|
FPortalBlock &block = PortalBlockmap(bx, by);
|
||||||
|
|
||||||
|
@ -743,9 +745,9 @@ DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
|
||||||
// Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map.
|
// Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map.
|
||||||
if (dx < 128 && dy < 128)
|
if (dx < 128 && dy < 128)
|
||||||
{
|
{
|
||||||
int blockx = GetBlockX(actx);
|
int blockx = level.blockmap.GetBlockX(actx);
|
||||||
int blocky = GetBlockY(acty);
|
int blocky = level.blockmap.GetBlockY(acty);
|
||||||
if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
|
if (blockx < 0 || blocky < 0 || blockx >= PortalBlockmap.dx || blocky >= PortalBlockmap.dy || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool repeat;
|
bool repeat;
|
||||||
|
|
Loading…
Reference in a new issue