Skip to content

Commit

Permalink
walls: Make blueprint walls match each other, and match real walls.
Browse files Browse the repository at this point in the history
Fixes ticket:2581.
  • Loading branch information
Cyp committed Nov 17, 2011
1 parent 7e449bf commit 42f57b6
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 34 deletions.
4 changes: 2 additions & 2 deletions src/display.cpp
Expand Up @@ -1429,7 +1429,7 @@ UDWORD dispX,dispY,dispR;

if (psReturn == NULL)
{
psReturn = getTileBlueprint(mouseTileX, mouseTileY);
psReturn = getTileBlueprintStructure(mouseTileX, mouseTileY);
}

/* Send the result back - if it's null then we clicked on an area of terrain */
Expand Down Expand Up @@ -2724,7 +2724,7 @@ STRUCTURE *psStructure;
psNotDroid = getTileOccupier(mouseTileX, mouseTileY);
if (psNotDroid == NULL)
{
psNotDroid = getTileBlueprint(mouseTileX, mouseTileY);
psNotDroid = getTileBlueprintStructure(mouseTileX, mouseTileY);
}
}

Expand Down
48 changes: 40 additions & 8 deletions src/display3d.cpp
Expand Up @@ -315,27 +315,42 @@ void NotifyUserOfError(char *msg)
lastErrorTime = gameTime2;
}

STRUCTURE *getTileBlueprint(int mapX, int mapY)
static Blueprint getTileBlueprint(int mapX, int mapY)
{
static STRUCTURE *psStruct = NULL;

Vector2i mouse(world_coord(mapX) + TILE_UNITS/2, world_coord(mapY) + TILE_UNITS/2);

for (std::vector<Blueprint>::const_iterator blueprint = blueprints.begin(); blueprint != blueprints.end(); ++blueprint)
{
Vector2i size = getStructureStatsSize(blueprint->stats, blueprint->dir)*TILE_UNITS;
if (blueprint->state == SS_BLUEPRINT_PLANNED &&
abs(mouse.x - blueprint->pos.x) < size.x/2 && abs(mouse.y - blueprint->pos.y) < size.y/2)
if (abs(mouse.x - blueprint->pos.x) < size.x/2 && abs(mouse.y - blueprint->pos.y) < size.y/2)
{
delete psStruct; // Delete previously returned structure, if any.
psStruct = blueprint->buildBlueprint();
return psStruct; // This blueprint was clicked on.
return *blueprint;
}
}

return Blueprint(NULL, Vector2i(), 0, SS_BEING_BUILT);
}

STRUCTURE *getTileBlueprintStructure(int mapX, int mapY)
{
static STRUCTURE *psStruct = NULL;

Blueprint blueprint = getTileBlueprint(mapX, mapY);
if (blueprint.state == SS_BLUEPRINT_PLANNED)
{
delete psStruct; // Delete previously returned structure, if any.
psStruct = blueprint.buildBlueprint();
return psStruct; // This blueprint was clicked on.
}

return NULL;
}

STRUCTURE_STATS *getTileBlueprintStats(int mapX, int mapY)
{
return getTileBlueprint(mapX, mapY).stats;
}

static PIELIGHT structureBrightness(STRUCTURE *psStructure)
{
PIELIGHT buildingBrightness;
Expand Down Expand Up @@ -1613,6 +1628,23 @@ void displayBlueprints(void)
// Actually render everything.
for (std::vector<Blueprint>::iterator blueprint = blueprints.begin(); blueprint != blueprints.end(); ++blueprint)
{
// Rotate wall if needed.
if (blueprint->stats->type == REF_WALL || blueprint->stats->type == REF_GATE)
{
WallOrientation orientation = structChooseWallTypeBlueprint(map_coord(blueprint->pos.x), map_coord(blueprint->pos.y));
switch (orientation)
{
case WALL_HORIZ: blueprint->dir = DEG(0); break;
case WALL_VERT: blueprint->dir = DEG(90); break;
case WALL_CORNER:
if (blueprint->stats->type != REF_GATE)
{
blueprint->stats = ((WALL_FUNCTION *)blueprint->stats->asFuncList[0])->pCornerStat;
}
break;
}
}

blueprint->renderBlueprint();
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/display3d.h
Expand Up @@ -110,7 +110,8 @@ extern void setRubbleTile(UDWORD num);
extern SDWORD getCentreX( void );
extern SDWORD getCentreZ( void );

STRUCTURE *getTileBlueprint(int mapX, int mapY); ///< Gets the blueprint at those coordinates, if any.
STRUCTURE *getTileBlueprintStructure(int mapX, int mapY); ///< Gets the blueprint at those coordinates, if any. Previous return value becomes invalid.
STRUCTURE_STATS *getTileBlueprintStats(int mapX, int mapY); ///< Gets the structure stats of the blueprint at those coordinates, if any.

extern SDWORD mouseTileX, mouseTileY;
extern Vector2i mousePos;
Expand Down
73 changes: 50 additions & 23 deletions src/structure.cpp
Expand Up @@ -92,11 +92,6 @@

#include "random.h"

// Possible types of wall to build
#define WALL_HORIZ 0
#define WALL_VERT 1
#define WALL_CORNER 2

#define STR_RECOIL_TIME (GAME_TICKS_PER_SEC/4)

// Maximum Distance allowed between a friendly structure and an assembly point.
Expand Down Expand Up @@ -1140,7 +1135,7 @@ bool structSetManufacture(STRUCTURE *psStruct, DROID_TEMPLATE *psTempl, QUEUE_MO
*/

// look at where other walls are to decide what type of wall to build
static SDWORD structWallScan(bool aWallPresent[5][5], SDWORD x, SDWORD y)
static WallOrientation structWallScan(bool aWallPresent[5][5], int x, int y)
{
if (aWallPresent[x-1][y] || aWallPresent[x+1][y])
{
Expand All @@ -1159,37 +1154,69 @@ static SDWORD structWallScan(bool aWallPresent[5][5], SDWORD x, SDWORD y)
}
}

static bool isWallCombiningStructure(STRUCTURE *psStruct)
static bool isWallCombiningStructureType(STRUCTURE_STATS *pStructureType)
{
return psStruct->pStructureType->type == REF_WALL ||
psStruct->pStructureType->type == REF_GATE ||
psStruct->pStructureType->type == REF_WALLCORNER ||
(psStruct->pStructureType->type == REF_DEFENSE && psStruct->pStructureType->strength == STRENGTH_HARD) ||
(psStruct->pStructureType->type == REF_BLASTDOOR && psStruct->pStructureType->strength == STRENGTH_HARD); // fortresses
return pStructureType->type == REF_WALL ||
pStructureType->type == REF_GATE ||
pStructureType->type == REF_WALLCORNER ||
(pStructureType->type == REF_DEFENSE && pStructureType->strength == STRENGTH_HARD) ||
(pStructureType->type == REF_BLASTDOOR && pStructureType->strength == STRENGTH_HARD); // fortresses
}

// Choose a type of wall for a location - and update any neighbouring walls
static SDWORD structChooseWallType(UDWORD player, UDWORD mapX, UDWORD mapY)
static void structFindWalls(unsigned player, int mapX, int mapY, bool aWallPresent[5][5], STRUCTURE *apsStructs[5][5])
{
bool aWallPresent[5][5];
STRUCTURE *psStruct;
STRUCTURE *apsStructs[5][5];
SDWORD neighbourType, scanType;

// scan around the location looking for walls
memset(aWallPresent, 0, sizeof(aWallPresent));
for (int y = -2; y <= 2; ++y)
for (int x = -2; x <= 2; ++x)
{
psStruct = castStructure(mapTile(mapX + x, mapY + y)->psObject);
if (psStruct != NULL && isWallCombiningStructure(psStruct) && aiCheckAlliances(player, psStruct->player))
STRUCTURE *psStruct = castStructure(mapTile(mapX + x, mapY + y)->psObject);
if (psStruct != NULL && isWallCombiningStructureType(psStruct->pStructureType) && aiCheckAlliances(player, psStruct->player))
{
aWallPresent[x + 2][y + 2] = true;
apsStructs[x + 2][y + 2] = psStruct;
}
}
// add in the wall about to be built
aWallPresent[2][2] = true;
}

static void structFindWallBlueprints(int mapX, int mapY, bool aWallPresent[5][5])
{
for (int y = -2; y <= 2; ++y)
for (int x = -2; x <= 2; ++x)
{
STRUCTURE_STATS *stats = getTileBlueprintStats(mapX + x, mapY + y);
if (stats != NULL && isWallCombiningStructureType(stats))
{
aWallPresent[x + 2][y + 2] = true;
}
}
}

WallOrientation structChooseWallTypeBlueprint(int mapX, int mapY)
{
bool aWallPresent[5][5];
STRUCTURE * apsStructs[5][5];

// scan around the location looking for walls
memset(aWallPresent, 0, sizeof(aWallPresent));
structFindWalls(selectedPlayer, mapX, mapY, aWallPresent, apsStructs);
structFindWallBlueprints(mapX, mapY, aWallPresent);

// finally return the type for this wall
return structWallScan(aWallPresent, 2, 2);
}

// Choose a type of wall for a location - and update any neighbouring walls
static WallOrientation structChooseWallType(unsigned player, int mapX, int mapY)
{
bool aWallPresent[5][5];
STRUCTURE *psStruct;
STRUCTURE *apsStructs[5][5];
SDWORD neighbourType, scanType;

// scan around the location looking for walls
memset(aWallPresent, 0, sizeof(aWallPresent));
structFindWalls(player, mapX, mapY, aWallPresent, apsStructs);

// now make sure that all the walls around this one are OK
for (int x = 1; x <= 3; ++x)
Expand Down
2 changes: 2 additions & 0 deletions src/structure.h
Expand Up @@ -385,6 +385,8 @@ extern bool IsStatExpansionModule(STRUCTURE_STATS *psStats);
bool structureIsBlueprint(STRUCTURE *psStructure);
bool isBlueprint(BASE_OBJECT *psObject);

WallOrientation structChooseWallTypeBlueprint(int mapX, int mapY); ///< Which orientation should a wall blueprint at this position have?

/*checks that the structure stats have loaded up as expected - must be done after
all StructureStats parts have been loaded*/
extern bool checkStructureStats(void);
Expand Down
7 changes: 7 additions & 0 deletions src/structuredef.h
Expand Up @@ -350,4 +350,11 @@ typedef UPGRADE REPAIR_FACILITY_UPGRADE;
typedef UPGRADE POWER_UPGRADE;
typedef UPGRADE REARM_UPGRADE;

enum WallOrientation
{
WALL_HORIZ,
WALL_VERT,
WALL_CORNER,
};

#endif // __INCLUDED_STRUCTUREDEF_H__

0 comments on commit 42f57b6

Please sign in to comment.