walls: Make blueprint walls match each other, and match real walls.

Fixes ticket:2581.
master
Cyp 2011-11-17 13:14:56 +01:00
parent 7e449bf18b
commit 42f57b6116
6 changed files with 105 additions and 36 deletions

View File

@ -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 */
@ -2724,7 +2724,7 @@ STRUCTURE *psStructure;
psNotDroid = getTileOccupier(mouseTileX, mouseTileY);
if (psNotDroid == NULL)
{
psNotDroid = getTileBlueprint(mouseTileX, mouseTileY);
psNotDroid = getTileBlueprintStructure(mouseTileX, mouseTileY);
}
}

View File

@ -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;
@ -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();
}
}

View File

@ -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;

View File

@ -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.
@ -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])
{
@ -1159,17 +1154,60 @@ 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
}
static void structFindWalls(unsigned player, int mapX, int mapY, bool aWallPresent[5][5], STRUCTURE *apsStructs[5][5])
{
for (int y = -2; y <= 2; ++y)
for (int x = -2; x <= 2; ++x)
{
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 SDWORD structChooseWallType(UDWORD player, UDWORD mapX, UDWORD mapY)
static WallOrientation structChooseWallType(unsigned player, int mapX, int mapY)
{
bool aWallPresent[5][5];
STRUCTURE *psStruct;
@ -1178,18 +1216,7 @@ static SDWORD structChooseWallType(UDWORD player, UDWORD mapX, UDWORD mapY)
// 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))
{
aWallPresent[x + 2][y + 2] = true;
apsStructs[x + 2][y + 2] = psStruct;
}
}
// add in the wall about to be built
aWallPresent[2][2] = true;
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)

View File

@ -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);

View File

@ -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__