Skip to content

Commit

Permalink
Simplify validLocation.
Browse files Browse the repository at this point in the history
Check against blueprints, instead of going through all droids and checking their build
queues (but erroneously ignoring their current order). Should improve symmetry of valid
building locations next to map edges.

Fixes ticket:2999.
  • Loading branch information
Cyp committed Dec 24, 2011
1 parent ca0c37a commit 79d8d22
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 374 deletions.
17 changes: 3 additions & 14 deletions src/action.cpp
Expand Up @@ -1482,9 +1482,7 @@ void actionUpdateDroid(DROID *psDroid)
if (psDroid->order == DORDER_BUILD && psDroid->psTarget == NULL)
{
// Starting a new structure
// calculate the top left of the structure
const UDWORD tlx = psDroid->orderX - getStructureStatsWidth(psStructStats, dir) * TILE_UNITS/2;
const UDWORD tly = psDroid->orderY - getStructureStatsBreadth(psStructStats, dir) * TILE_UNITS/2;
const Vector2i pos(psDroid->orderX, psDroid->orderY);

//need to check if something has already started building here?
//unless its a module!
Expand Down Expand Up @@ -1531,11 +1529,7 @@ void actionUpdateDroid(DROID *psDroid)
cancelBuild(psDroid);
}
}
else if (!validLocation(psDroid->psTarStats,
map_coord(tlx),
map_coord(tly), dir,
psDroid->player,
false))
else if (!validLocation(psDroid->psTarStats, pos, dir, psDroid->player, false))
{
syncDebug("Reached build target: invalid");
objTrace(psDroid->id, "DACTION_MOVETOBUILD: !validLocation");
Expand Down Expand Up @@ -1789,10 +1783,6 @@ void actionUpdateDroid(DROID *psDroid)
//building a structure's foundation - flattening the ground for now
{
MAPTILE* const psTile = mapTile(map_coord(psDroid->orderX), map_coord(psDroid->orderY));
STRUCTURE_STATS* const psStructStats = (STRUCTURE_STATS*)psDroid->psTarStats;
uint16_t dir = psDroid->orderDirection;
const UDWORD tlx = psDroid->orderX - getStructureStatsWidth(psStructStats, dir) * TILE_UNITS/2;
const UDWORD tly = psDroid->orderY - getStructureStatsBreadth(psStructStats, dir) * TILE_UNITS/2;
if ((psDroid->psTarget == NULL) &&
(TileHasStructure(psTile) ||
TileHasFeature(psTile)))
Expand All @@ -1812,8 +1802,7 @@ void actionUpdateDroid(DROID *psDroid)
}
}
else if (!validLocation(psDroid->psTarStats,
map_coord(tlx),
map_coord(tly), dir,
Vector2i(psDroid->orderX, psDroid->orderY), psDroid->orderDirection,
psDroid->player,
false))
{
Expand Down
6 changes: 3 additions & 3 deletions src/aud.cpp
Expand Up @@ -62,7 +62,7 @@ Vector3f audio_GetPlayerPos(void)

// Invert Y to match QSOUND axes
// @NOTE What is QSOUND? Why invert the Y axis?
pos.y = world_coord(GetHeightOfMap()) - pos.y;
pos.y = world_coord(mapHeight) - pos.y;

return pos;
}
Expand All @@ -84,7 +84,7 @@ void audio_GetStaticPos(SDWORD iWorldX, SDWORD iWorldY, SDWORD *piX, SDWORD *piY
*piX = iWorldX;
*piZ = map_TileHeight(map_coord(iWorldX), map_coord(iWorldY));
/* invert y to match QSOUND axes */
*piY = world_coord(GetHeightOfMap()) - iWorldY;
*piY = world_coord(mapHeight) - iWorldY;
}

// @FIXME we don't need to do this, since we are not using qsound.
Expand All @@ -98,7 +98,7 @@ void audio_GetObjectPos(SIMPLE_OBJECT *psBaseObj, SDWORD *piX, SDWORD *piY, SDWO
*piZ = map_TileHeight(map_coord(psBaseObj->pos.x), map_coord(psBaseObj->pos.y));

/* invert y to match QSOUND axes */
*piY = world_coord(GetHeightOfMap()) - psBaseObj->pos.y;
*piY = world_coord(mapHeight) - psBaseObj->pos.y;
}

UDWORD sound_GetGameTime()
Expand Down
13 changes: 13 additions & 0 deletions src/display3d.cpp
Expand Up @@ -351,6 +351,19 @@ STRUCTURE_STATS const *getTileBlueprintStats(int mapX, int mapY)
return getTileBlueprint(mapX, mapY).stats;
}

bool anyBlueprintTooClose(STRUCTURE_STATS const *stats, Vector2i pos, uint16_t dir)
{
for (std::vector<Blueprint>::const_iterator blueprint = blueprints.begin(); blueprint != blueprints.end(); ++blueprint)
{
if ((blueprint->state == SS_BLUEPRINT_PLANNED || blueprint->state == SS_BLUEPRINT_PLANNED_BY_ALLY)
&& isBlueprintTooClose(stats, pos, dir, blueprint->stats, blueprint->pos, blueprint->dir))
{
return true;
}
}
return false;
}

static PIELIGHT structureBrightness(STRUCTURE *psStructure)
{
PIELIGHT buildingBrightness;
Expand Down
1 change: 1 addition & 0 deletions src/display3d.h
Expand Up @@ -112,6 +112,7 @@ extern SDWORD getCentreZ( void );

STRUCTURE *getTileBlueprintStructure(int mapX, int mapY); ///< Gets the blueprint at those coordinates, if any. Previous return value becomes invalid.
STRUCTURE_STATS const *getTileBlueprintStats(int mapX, int mapY); ///< Gets the structure stats of the blueprint at those coordinates, if any.
bool anyBlueprintTooClose(STRUCTURE_STATS const *stats, Vector2i pos, uint16_t dir); ///< Checks if any blueprint is too close to the given structure.

extern SDWORD mouseTileX, mouseTileY;
extern Vector2i mousePos;
Expand Down
55 changes: 9 additions & 46 deletions src/edit3d.cpp
Expand Up @@ -169,8 +169,6 @@ void kill3DBuilding ( void )
//
bool process3DBuilding(void)
{
UDWORD bX,bY;

//if not trying to build ignore
if (buildState == BUILD3D_NONE)
{
Expand All @@ -182,13 +180,16 @@ bool process3DBuilding(void)
return true;
}

/* Need to update the building locations if we're building */
int bX = clip(mouseTileX, 2, mapWidth - 3);
int bY = clip(mouseTileY, 2, mapHeight - 3);

if (buildState != BUILD3D_FINISHED)// && buildState != BUILD3D_NONE)
if (buildState != BUILD3D_FINISHED)
{
bX = mouseTileX;
bY = mouseTileY;
Vector2i size = getStatsSize(sBuildDetails.psStats, player.r.y);
Vector2i offset = size * (TILE_UNITS / 2); // This presumably gets added to the chosen coordinates, somewhere, based on looking at what pickStructLocation does. No idea where it gets added, though.

if (validLocation(sBuildDetails.psStats, bX, bY, player.r.y, selectedPlayer, true))
if (validLocation(sBuildDetails.psStats, world_coord(Vector2i(bX, bY)) + offset, player.r.y, selectedPlayer, true))
{
buildState = BUILD3D_VALID;
}
Expand All @@ -198,46 +199,8 @@ bool process3DBuilding(void)
}
}

/* Need to update the building locations if we're building */
bX = mouseTileX;
bY = mouseTileY;

if(mouseTileX<2)
{
bX = 2;
}
else
{
bX = mouseTileX;
}
if(mouseTileX > (SDWORD)(mapWidth-3))
{
bX = mapWidth-3;
}
else
{
bX = mouseTileX;
}

if(mouseTileY<2)
{
bY = 2;
}
else
{
bY = mouseTileY;
}
if(mouseTileY > (SDWORD)(mapHeight-3))
{
bY = mapHeight-3;
}
else
{
bY = mouseTileY;
}

sBuildDetails.x = buildSite.xTL = (UWORD)bX;
sBuildDetails.y = buildSite.yTL = (UWORD)bY;
sBuildDetails.x = buildSite.xTL = bX;
sBuildDetails.y = buildSite.yTL = bY;
if (((player.r.y + 0x2000) & 0x4000) == 0)
{
buildSite.xBR = buildSite.xTL+sBuildDetails.width-1;
Expand Down
50 changes: 8 additions & 42 deletions src/map.cpp
Expand Up @@ -1381,54 +1381,20 @@ bool mapObjIsAboveGround(const SIMPLE_OBJECT *psObj)

/* returns the max and min height of a tile by looking at the four corners
in tile coords */
void getTileMaxMin(UDWORD x, UDWORD y, UDWORD *pMax, UDWORD *pMin)
void getTileMaxMin(int x, int y, int *pMax, int *pMin)
{
UDWORD height, i, j;
int tileHeight = TILE_MIN_HEIGHT;
*pMin = INT32_MAX;
*pMax = INT32_MIN;

*pMin = TILE_MAX_HEIGHT;
*pMax = TILE_MIN_HEIGHT;

for (j=0; j < 2; j++)
for (int j = 0; j < 2; ++j)
for (int i = 0; i < 2; ++i)
{
for (i=0; i < 2; i++)
{
// it tileHeight is negative, that means we are in water, and will cause a underflow
// FIXME: When we add structures that *can* be on water, we need to handle this differently.
tileHeight = map_TileHeight(x+i, y+j);
if (tileHeight < 0)
{
// NOTE: should we assert here ?
height = TILE_MIN_HEIGHT;
}
else
{
height = tileHeight;
}
if (*pMin > height)
{
*pMin = height;
}
if (*pMax < height)
{
*pMax = height;
}
}
int height = map_TileHeight(x+i, y+j);
*pMin = std::min(*pMin, height);
*pMax = std::max(*pMax, height);
}
}

UDWORD GetWidthOfMap(void)
{
return mapWidth;
}



UDWORD GetHeightOfMap(void)
{
return mapHeight;
}


// -----------------------------------------------------------------------------------
/* This will save out the visibility data */
Expand Down
11 changes: 1 addition & 10 deletions src/map.h
Expand Up @@ -497,13 +497,6 @@ WZ_DECL_ALWAYS_INLINE static inline bool tileOnMap(Vector2i pos)
return tileOnMap(pos.x, pos.y);
}

/* Return true if a tile is not too near the map edge and not outside of the map */
static inline bool tileInsideBuildRange(SDWORD x, SDWORD y)
{
return (x >= TOO_NEAR_EDGE) && (x < ((SDWORD)mapWidth - TOO_NEAR_EDGE)) &&
(y >= TOO_NEAR_EDGE) && (y < ((SDWORD)mapHeight - TOO_NEAR_EDGE));
}

/* Return whether a world coordinate is on the map */
WZ_DECL_ALWAYS_INLINE static inline bool worldOnMap(int x, int y)
{
Expand Down Expand Up @@ -532,10 +525,8 @@ bool mapObjIsAboveGround(const SIMPLE_OBJECT *psObj);

/* returns the max and min height of a tile by looking at the four corners
in tile coords */
extern void getTileMaxMin(UDWORD x, UDWORD y, UDWORD *pMax, UDWORD *pMin);
void getTileMaxMin(int x, int y, int *pMax, int *pMin);

UDWORD GetHeightOfMap(void);
UDWORD GetWidthOfMap(void);
extern bool readVisibilityData(const char* fileName);
extern bool writeVisibilityData(const char* fileName);

Expand Down
4 changes: 3 additions & 1 deletion src/qtscriptfuncs.cpp
Expand Up @@ -438,10 +438,12 @@ static QScriptValue js_pickStructLocation(QScriptContext *context, QScriptEngine
x = startX;
y = startY;

Vector2i offset(psStat->baseWidth * (TILE_UNITS / 2), psStat->baseBreadth * (TILE_UNITS / 2)); // This presumably gets added to the chosen coordinates, somewhere, based on looking at what pickStructLocation does. No idea where it gets added, though, maybe inside the scripts?

// save a lot of typing... checks whether a position is valid
#define LOC_OK(_x, _y) (tileOnMap(_x, _y) && \
(!psDroid || fpathCheck(psDroid->pos, Vector3i(world_coord(_x), world_coord(_y), 0), PROPULSION_TYPE_WHEELED)) \
&& validLocation((BASE_STATS*)psStat, _x, _y, 0, player, false) && structDoubleCheck((BASE_STATS*)psStat, _x, _y, maxBlockingTiles))
&& validLocation(psStat, world_coord(Vector2i(_x, _y)) + offset, 0, player, false) && structDoubleCheck(psStat, _x, _y, maxBlockingTiles))

// first try the original location
if (LOC_OK(startX, startY))
Expand Down
10 changes: 6 additions & 4 deletions src/scriptfuncs.cpp
Expand Up @@ -5419,6 +5419,8 @@ static bool pickStructLocation(DROID *psDroid, int index, int *pX, int *pY, int

ASSERT_OR_RETURN(false, player < MAX_PLAYERS && player >= 0, "Invalid player number %d", player);

Vector2i offset(psStat->baseWidth * (TILE_UNITS / 2), psStat->baseBreadth * (TILE_UNITS / 2)); // This gets added to the chosen coordinates, at the end of the function.

// check for wacky coords.
if (*pX < 0 || *pX > world_coord(mapWidth) || *pY < 0 || *pY > world_coord(mapHeight))
{
Expand All @@ -5433,8 +5435,8 @@ static bool pickStructLocation(DROID *psDroid, int index, int *pX, int *pY, int

// save a lot of typing... checks whether a position is valid
#define LOC_OK(_x, _y) (tileOnMap(_x, _y) && \
(!psDroid || fpathCheck(psDroid->pos, Vector3i(world_coord(_x), world_coord(_y), 0), PROPULSION_TYPE_WHEELED)) \
&& validLocation((BASE_STATS*)psStat, _x, _y, 0, player, false) && structDoubleCheck((BASE_STATS*)psStat, _x, _y, maxBlockingTiles))
(!psDroid || fpathCheck(psDroid->pos, Vector3i(world_coord(_x), world_coord(_y), 0), PROPULSION_TYPE_WHEELED)) \
&& validLocation(psStat, world_coord(Vector2i(_x, _y)) + offset, 0, player, false) && structDoubleCheck(psStat, _x, _y, maxBlockingTiles))

// first try the original location
if (LOC_OK(startX, startY))
Expand Down Expand Up @@ -5487,8 +5489,8 @@ static bool pickStructLocation(DROID *psDroid, int index, int *pX, int *pY, int
// back to world coords.
if (found) // did it!
{
*pX = world_coord(x) + (psStat->baseWidth * (TILE_UNITS / 2));
*pY = world_coord(y) + (psStat->baseBreadth * (TILE_UNITS / 2));
*pX = world_coord(x) + offset.x;
*pY = world_coord(y) + offset.y;
}
else
{
Expand Down

0 comments on commit 79d8d22

Please sign in to comment.