Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix gates.

It is now possible to go through gates when, and only when, they are open, and friendly gates are always ignored by pathfinding.

Fixes ticket:2486.
  • Loading branch information...
commit 48f00204553b976f60b198bb5583a5889c1b12f3 1 parent f18f984
@Cyp Cyp authored
View
4 src/display3d.cpp
@@ -2571,11 +2571,11 @@ static BOOL renderWallSection(STRUCTURE *psStructure)
}
else if (psStructure->pStructureType->type == REF_GATE && psStructure->state == SAS_OPENING)
{
- dv.y -= (height * (gameTime - psStructure->lastStateTime)) / SAS_OPEN_SPEED;
+ dv.y -= (height * std::max<int>(graphicsTime + GAME_TICKS_PER_UPDATE - psStructure->lastStateTime, 0)) / SAS_OPEN_SPEED;
}
else if (psStructure->pStructureType->type == REF_GATE && psStructure->state == SAS_CLOSING)
{
- dv.y -= height - (height * (gameTime - psStructure->lastStateTime)) / SAS_OPEN_SPEED;
+ dv.y -= height - (height * std::max<int>(graphicsTime - psStructure->lastStateTime, 0)) / SAS_OPEN_SPEED;
}
/* Push the indentity matrix */
View
3  src/fpath.cpp
@@ -267,6 +267,7 @@ BOOL fpathBaseBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion, int m
if ((unitbits & FEATURE_BLOCKED)
&& ((moveType == FMT_MOVE && (aux & AUXBITS_ANY_BUILDING)) // do not wish to shoot our way through enemy buildings
+ || (moveType == FMT_BLOCK && (aux & AUXBITS_CLOSED_GATE)) // Do not wish to tunnel through closed gates.
|| (aux & AUXBITS_OUR_BUILDING))) // move blocked by friendly building, assuming we do not want to shoot it up en route
{
return true; // move blocked by building, and we cannot or do not want to shoot our way through anything
@@ -284,7 +285,7 @@ BOOL fpathDroidBlockingTile(DROID *psDroid, int x, int y, FPATH_MOVETYPE moveTyp
// Check if the map tile at a location blocks a droid
BOOL fpathBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion)
{
- return fpathBaseBlockingTile(x, y, propulsion, 0, FMT_MOVE); // with FMT_MOVE, it is irrelevant which player is passed in
+ return fpathBaseBlockingTile(x, y, propulsion, 0, FMT_BLOCK); // with FMT_BLOCK, it is irrelevant which player is passed in
}
View
1  src/fpath.h
@@ -36,6 +36,7 @@ enum FPATH_MOVETYPE
{
FMT_MOVE, ///< Move around all obstacles
FMT_ATTACK, ///< Assume that we will destroy enemy obstacles
+ FMT_BLOCK, ///< Don't go through obstacles, not even gates.
};
struct PathBlockingMap;
View
16 src/map.h
@@ -124,7 +124,7 @@ extern char *tileset;
#define WATER_BLOCKED 0x04 ///< Units that cannot pass water are blocked by this tile
#define LAND_BLOCKED 0x08 ///< The inverse of the above -- for propeller driven crafts
-#define AUXBITS_UNUSED 0x01 ///< Unused for now
+#define AUXBITS_CLOSED_GATE 0x01 ///< There is a gate which is not open.
#define AUXBITS_OUR_BUILDING 0x02 ///< Do we or our allies have a building at this tile
#define AUXBITS_ANY_BUILDING 0x04 ///< Is there any building that might be blocking here?
#define AUXBITS_TEMPORARY 0x08 ///< Temporary bit used in calculations
@@ -206,6 +206,20 @@ WZ_DECL_ALWAYS_INLINE static inline void auxSetAllied(int x, int y, int player,
}
}
+/// Set aux bits. Always set identically for all players. States not set are retained.
+WZ_DECL_ALWAYS_INLINE static inline void auxSetEnemy(int x, int y, int player, int state)
+{
+ int i;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (!(alliancebits[player] & (1 << i)))
+ {
+ psAuxMap[i][x + y * mapWidth] |= state;
+ }
+ }
+}
+
/// Clear aux bits. Always set identically for all players. States not cleared are retained.
WZ_DECL_ALWAYS_INLINE static inline void auxClear(int x, int y, int player, int state)
{
View
19 src/move.cpp
@@ -872,26 +872,13 @@ static void moveCalcBlockingSlide(DROID *psDroid, int32_t *pmx, int32_t *pmy, ui
psTile = mapTile(ntx, nty);
}
if (!isFlying(psDroid) && psTile && psTile->psObject && psTile->psObject->type == OBJ_STRUCTURE
- && aiCheckAlliances(psTile->psObject->player, psDroid->player)
- && ((STRUCTURE *)psTile->psObject)->status == SS_BUILT
- && ((STRUCTURE *)psTile->psObject)->pStructureType->type == REF_GATE)
+ && aiCheckAlliances(psTile->psObject->player, psDroid->player))
{
- STRUCTURE *psStruct = (STRUCTURE *)psTile->psObject;
-
- if (psStruct->state == SAS_NORMAL)
- {
- psStruct->lastStateTime = gameTime;
- psStruct->state = SAS_OPENING;
- psDroid->sMove.Status = MOVEPAUSE;
- psDroid->sMove.pauseTime = SAS_OPEN_SPEED;
- psDroid->sMove.bumpTime = gameTime;
- psDroid->sMove.lastBump = 0;
- return; // wait for it to open
- }
+ requestOpenGate((STRUCTURE *)psTile->psObject); // If it's a friendly gate, open it. (It would be impolite to open an enemy gate.)
}
// is the new tile blocking?
- if (!fpathBaseBlockingTile(ntx, nty, propulsion, psDroid->player, FMT_MOVE))
+ if (!fpathBlockingTile(ntx, nty, propulsion))
{
// not blocking, don't change the move vector
return;
View
74 src/structure.cpp
@@ -211,7 +211,7 @@ static void auxStructureNonblocking(STRUCTURE *psStructure)
{
for (int j = 0; j < size.y; j++)
{
- auxClearAll(map.x + i, map.y + j, AUXBITS_ANY_BUILDING | AUXBITS_OUR_BUILDING);
+ auxClearAll(map.x + i, map.y + j, AUXBITS_ANY_BUILDING | AUXBITS_OUR_BUILDING | AUXBITS_CLOSED_GATE);
}
}
}
@@ -231,6 +231,35 @@ static void auxStructureBlocking(STRUCTURE *psStructure)
}
}
+static void auxStructureOpenGate(STRUCTURE *psStructure)
+{
+ Vector2i size = getStructureSize(psStructure);
+ Vector2i map = map_coord(removeZ(psStructure->pos)) - size/2;
+
+ for (int i = 0; i < size.x; i++)
+ {
+ for (int j = 0; j < size.y; j++)
+ {
+ auxClearAll(map.x + i, map.y + j, AUXBITS_CLOSED_GATE);
+ }
+ }
+}
+
+static void auxStructureClosedGate(STRUCTURE *psStructure)
+{
+ Vector2i size = getStructureSize(psStructure);
+ Vector2i map = map_coord(removeZ(psStructure->pos)) - size/2;
+
+ for (int i = 0; i < size.x; i++)
+ {
+ for (int j = 0; j < size.y; j++)
+ {
+ auxSetEnemy(map.x + i, map.y + j, psStructure->player, AUXBITS_ANY_BUILDING);
+ auxSetAll(map.x + i, map.y + j, AUXBITS_CLOSED_GATE);
+ }
+ }
+}
+
BOOL IsStatExpansionModule(STRUCTURE_STATS *psStats)
{
// If the stat is any of the 3 expansion types ... then return true
@@ -1505,9 +1534,16 @@ STRUCTURE* buildStructureDir(STRUCTURE_STATS *pStructureType, UDWORD x, UDWORD y
}
}
- if (pStructureType->type != REF_REARM_PAD && pStructureType->type != REF_GATE)
+ switch (pStructureType->type)
{
- auxStructureBlocking(psBuilding);
+ case REF_REARM_PAD:
+ break; // Not blocking.
+ case REF_GATE:
+ auxStructureClosedGate(psBuilding); // Don't block for the sake of allied pathfinding.
+ break;
+ default:
+ auxStructureBlocking(psBuilding);
+ break;
}
//set up the rest of the data
@@ -3605,6 +3641,34 @@ void _syncDebugStructure(const char *function, STRUCTURE const *psStruct, char c
getPrecisePower(psStruct->player));
}
+int requestOpenGate(STRUCTURE *psStructure)
+{
+ if (psStructure->status != SS_BUILT || psStructure->pStructureType->type != REF_GATE)
+ {
+ return 0; // Can't open.
+ }
+
+ switch (psStructure->state)
+ {
+ case SAS_NORMAL:
+ psStructure->lastStateTime = gameTime;
+ psStructure->state = SAS_OPENING;
+ break;
+ case SAS_OPEN:
+ psStructure->lastStateTime = gameTime;
+ return 0; // Already open.
+ case SAS_OPENING:
+ break;
+ case SAS_CLOSING:
+ psStructure->lastStateTime = 2*gameTime - psStructure->lastStateTime - SAS_OPEN_SPEED;
+ psStructure->state = SAS_OPENING;
+ default:
+ return 0; // Unknown state...
+ }
+
+ return psStructure->lastStateTime + SAS_OPEN_SPEED - gameTime;
+}
+
/* The main update routine for all Structures */
void structureUpdate(STRUCTURE *psBuilding, bool mission)
{
@@ -3631,14 +3695,14 @@ void structureUpdate(STRUCTURE *psBuilding, bool mission)
if (!found) // no droids on our tile, safe to close
{
psBuilding->state = SAS_CLOSING;
- auxStructureBlocking(psBuilding); // closed
+ auxStructureClosedGate(psBuilding); // closed
psBuilding->lastStateTime = gameTime; // reset timer
}
}
else if (psBuilding->state == SAS_OPENING && psBuilding->lastStateTime + SAS_OPEN_SPEED < gameTime)
{
psBuilding->state = SAS_OPEN;
- auxStructureNonblocking(psBuilding); // opened
+ auxStructureOpenGate(psBuilding); // opened
psBuilding->lastStateTime = gameTime; // reset timer
}
else if (psBuilding->state == SAS_CLOSING && psBuilding->lastStateTime + SAS_OPEN_SPEED < gameTime)
View
2  src/structure.h
@@ -110,6 +110,8 @@ extern BOOL loadStructureStrengthModifiers(const char *pStrengthModData, UDWORD
extern BOOL structureStatsShutDown(void);
+int requestOpenGate(STRUCTURE *psStructure);
+
int32_t structureDamage(STRUCTURE *psStructure, UDWORD damage, WEAPON_CLASS weaponClass, WEAPON_SUBCLASS weaponSubClass, HIT_SIDE impactSide);
extern void structureBuild(STRUCTURE *psStructure, DROID *psDroid, int buildPoints);
extern void structureDemolish(STRUCTURE *psStructure, DROID *psDroid, int buildPoints);
Please sign in to comment.
Something went wrong with that request. Please try again.