Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Core/GameEngine/Include/GameClient/TerrainRoads.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class TerrainRoadType : public MemoryPoolObject
AsciiString getRepairedToFXString( BodyDamageType state, Int index ) { return m_repairedToFXString[ state ][ index ]; }
Real getTransitionEffectsHeight( void ) { return m_transitionEffectsHeight; }
Int getNumFXPerType( void ) { return m_numFXPerType; }
Real getBridgeHoleAreaPercentage( void ) { return m_bridgeHoleAreaPercentage; }

// friend access methods to be used by the road collection only!
void friend_setName( AsciiString name ) { m_name = name; }
Expand Down Expand Up @@ -188,6 +189,7 @@ class TerrainRoadType : public MemoryPoolObject
Real m_transitionEffectsHeight;
Int m_numFXPerType; ///< for *each* fx/ocl we will make this many of them on the bridge area

Real m_bridgeHoleAreaPercentage; ///< if bridge is openable/destroyable, how much % of length becomes open
};

//-------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,5 +697,7 @@ static PoolSizeRec PoolSizes[] =
{ "DroneCarrierContain", 8, 8 },
{ "W3DDependencyCarrierDraw", 16, 16 },
{ "CarrierDroneAIUpdate", 16, 16 },
{ "DrawBridgeTowerUpdate", 8, 8 },
{ "DrawBridgeUpdate", 4, 4 },
{ 0, 0, 0 }
};
1 change: 1 addition & 0 deletions Core/GameEngine/Source/GameClient/Terrain/TerrainRoads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const FieldParse TerrainRoadType::m_terrainBridgeFieldParseTable[] =
{ "RepairedToSound", INI::parseAsciiString, nullptr, offsetof( TerrainRoadType, m_repairedToSoundString[ BODY_DAMAGED ] ) },
{ "TransitionToOCL", parseTransitionToOCL, nullptr, 0 },
{ "TransitionToFX", parseTransitionToFX, nullptr, 0 },
{ "BridgeHoleAreaPercentage", INI::parsePercentToReal, nullptr, offsetof( TerrainRoadType, m_bridgeHoleAreaPercentage) },


{ nullptr, nullptr, nullptr, 0 },
Expand Down
4 changes: 4 additions & 0 deletions GeneralsMD/Code/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/DroneCarrierContain.h
Include/GameLogic/Module/CarrierDroneAIUpdate.h
Include/GameLogic/Module/BridgeTowerBody.h
Include/GameLogic/Module/DrawBridgeTowerUpdate.h
Include/GameLogic/Module/DrawBridgeUpdate.h
Include/GameLogic/Object.h
Include/GameLogic/ObjectCreationList.h
Include/GameLogic/BuffSystem.h
Expand Down Expand Up @@ -1116,6 +1118,8 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Update/KodiakDeploymentUpdate.cpp
Source/GameLogic/Object/Update/KodiakUpdate.cpp
Source/GameLogic/Object/Update/DroneCarrierSlavedUpdate.cpp
Source/GameLogic/Object/Update/DrawBridgeTowerUpdate.cpp
Source/GameLogic/Object/Update/DrawBridgeUpdate.cpp
Source/GameLogic/Object/Upgrade/ActiveShroudUpgrade.cpp
Source/GameLogic/Object/Upgrade/ArmorUpgrade.cpp
Source/GameLogic/Object/Upgrade/CommandSetUpgrade.cpp
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/SpecialPowerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ enum SpecialPowerType CPP_11(: Int)
SUPW_SPECIAL_SPECTRE_GUNSHIP,
SUPW_SPECIAL_ORBITAL_STRIKE,

SPECIAL_TOGGLE_DRAWBRIDGE,

SPECIALPOWER_COUNT,
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NEW CONSTANTS NEED A BEHAVIORTYPE DEFINED IN THE SPECIALPOWER OR return one in getFallbackBehaviorType in ActionManager.cpp
Expand Down
44 changes: 36 additions & 8 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/AIPathfind.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ class Path : public MemoryPoolObject, public Snapshot
/// Given a location, return closest location on path, and along-path dist to end as function result
void markOptimized(void) {m_isOptimized = true;}

inline Bool needCheckBridges( void ) const { return m_moveUnderBridges != 0U; };

static inline UnsignedShort layerIndexToBitFlag(UnsignedShort layer_index) {
return static_cast<UnsignedShort>(1u << layer_index);
};

inline void setPathBelowBridge(PathfindLayerEnum layer) { BitSet(m_moveUnderBridges, layerIndexToBitFlag(static_cast<UnsignedShort>(layer))); };
inline Bool isPathBelowBridge(UnsignedShort layer_index) { return BitIsSet(m_moveUnderBridges, layerIndexToBitFlag(layer_index)); };

protected:
// snapshot interface
virtual void crc( Xfer *xfer );
Expand All @@ -195,6 +204,9 @@ class Path : public MemoryPoolObject, public Snapshot
Coord3D m_cpopIn;
ClosestPointOnPathInfo m_cpopOut;
const PathNode* m_cpopRecentStart;

// Stores opened/destroyed bridges that this path moves below.
UnsignedShort m_moveUnderBridges; // 16bit -> use as bitset for PATHFIND LAYER ENUMS (2-14 for bridges)
};

//----------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -372,6 +384,11 @@ class PathfindCell
Short getWaterLevel(void) const { return m_waterLevel; }
void setWaterLevel(Short level) { m_waterLevel = level; }

UnsignedByte getBridgeHeight(void) const { return m_bridgeHeight; }
void setBridgeHeight(UnsignedByte height) { m_bridgeHeight = height; }
PathfindLayerEnum getBridgeLayer(void) const { return (PathfindLayerEnum)m_bridgeLayer; }
void setBridgeLayer(PathfindLayerEnum layer) { m_bridgeLayer = (UnsignedByte)layer; }

Bool allocateInfo(const ICoord2D &pos);
void releaseInfo(void);
Bool hasInfo(void) const {return m_info!=nullptr;}
Expand All @@ -392,6 +409,9 @@ class PathfindCell
void setConnectLayer( PathfindLayerEnum layer ) { m_connectsToLayer = layer; } ///< set the cell layer connect id
PathfindLayerEnum getConnectLayer( void ) const { return (PathfindLayerEnum)m_connectsToLayer; } ///< get the cell layer connect id

/// Get the layer if this cell under a bridge that is currently destroyed or opened or LAYER_INVALID if not
PathfindLayerEnum getUnderDestroyedBridgeLayer( void ) const;

private:
PathfindCellInfo *m_info;
ObjectID m_obstacleID; ///< the object ID who overlaps this cell
Expand All @@ -409,6 +429,9 @@ class PathfindCell
UnsignedByte m_layer : 4; ///< Layer of this cell.
//This is added for ship pathing
Short m_waterLevel:8; ///< how far away is this cell from land (distance transform), capped at 15
//This is added for bridge pathing, determine if unit can go under bridge or not
UnsignedByte m_bridgeHeight : 4; // stored as number 0-15, rounded from 0.0-150.0 float. Space below bridge (to ground or water)
UnsignedByte m_bridgeLayer : 4; // Layer number of bridge above this cell
};

typedef PathfindCell *PathfindCellP;
Expand Down Expand Up @@ -660,7 +683,7 @@ class Pathfinder : PathfindServicesInterface, public Snapshot
void xfer( Xfer *xfer );
void loadPostProcess( void );

Bool clientSafeQuickDoesPathExist( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain & buildings check - fast)
Bool clientSafeQuickDoesPathExist( const LocomotorSet& locomotorSet, Short requiredBridgeHeight, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain & buildings check - fast)
Bool clientSafeQuickDoesPathExistForUI( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain onlyk - fast)
Bool slowDoesPathExist( Object *obj, const Coord3D *from,
const Coord3D *to, ObjectID ignoreObject=INVALID_ID ); ///< Can we build any path at all between the locations (terrain, buildings & units check - slower)
Expand Down Expand Up @@ -709,9 +732,9 @@ class Pathfinder : PathfindServicesInterface, public Snapshot

void setIgnoreObstacleID( ObjectID objID ); ///< if non-zero, the pathfinder will ignore the given obstacle

Bool validMovementPosition( Bool isCrusher, LocomotorSurfaceTypeMask acceptableSurfaces, Int requiredWaterLevel, PathfindCell *toCell, PathfindCell *fromCell = NULL ); ///< Return true if given position is a valid movement location
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Int x, Int y ); ///< Return true if given position is a valid movement location
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, const Coord3D *pos ); ///< Return true if given position is a valid movement location
Bool validMovementPosition( Bool isCrusher, LocomotorSurfaceTypeMask acceptableSurfaces, Int requiredWaterLevel, Short requiredBridgeHeight, PathfindCell *toCell, PathfindCell *fromCell = NULL ); ///< Return true if given position is a valid movement location
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Short requiredBridgeHeight, Int x, Int y ); ///< Return true if given position is a valid movement location
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Short requiredBridgeHeight, const Coord3D *pos ); ///< Return true if given position is a valid movement location
Bool validMovementTerrain( PathfindLayerEnum layer, const Locomotor* locomotor, const Coord3D *pos ); ///< Return true if given position is a valid movement location

Locomotor* chooseBestLocomotorForPosition(PathfindLayerEnum layer, LocomotorSet* locomotorSet, const Coord3D* pos );
Expand Down Expand Up @@ -760,6 +783,11 @@ class Pathfinder : PathfindServicesInterface, public Snapshot

PathfindLayerEnum addBridge(Bridge *theBridge); // Adds a bridge layer, and returns the layer id.

// return if the passed layer is currently passable (checks for destroyed bridges)
inline Bool isPathfindLayerPassable(PathfindLayerEnum layer) {
return !m_layers[layer].isUnused() && !m_layers[layer].isDestroyed();
}

void addWallPiece(Object *wallPiece); // Adds a wall piece.
void removeWallPiece(Object *wallPiece); // Removes a wall piece.
Real getWallHeight(void) {return m_wallHeight;}
Expand Down Expand Up @@ -919,18 +947,18 @@ inline void Pathfinder::worldToGrid( const Coord3D *pos, ICoord2D *cellIndex )
cellIndex->y = REAL_TO_INT(pos->y/PATHFIND_CELL_SIZE);
}

inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Int x, Int y )
inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Short requiredBridgeHeight, Int x, Int y )
{
return validMovementPosition( isCrusher, locomotorSet.getValidSurfaces(), locomotorSet.getRequiredWaterLevel(), getCell(layer, x, y));
return validMovementPosition( isCrusher, locomotorSet.getValidSurfaces(), locomotorSet.getRequiredWaterLevel(), requiredBridgeHeight, getCell(layer, x, y));
}

inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, const Coord3D *pos )
inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Short requiredBridgeHeight, const Coord3D *pos )
{

Int x = REAL_TO_INT(pos->x/PATHFIND_CELL_SIZE);
Int y = REAL_TO_INT(pos->y/PATHFIND_CELL_SIZE);

return validMovementPosition( isCrusher, layer, locomotorSet, x, y );
return validMovementPosition( isCrusher, layer, locomotorSet, requiredBridgeHeight, x, y );
}

inline const Coord3D *Pathfinder::getDebugPathPosition( void )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
Bool isBlockedAndStuck(void) const {return m_isBlockedAndStuck;}
Bool canComputeQuickPath(void); ///< Returns true if we can quickly comput a path. Usually missiles & the like that just move straight to the destination.
Bool computeQuickPath(const Coord3D *destination); ///< Computes a quick path to the destination.
Bool arePathLayersStillValid(); ///< Check if the current used layers are still passable

Bool isMoving() const;
Bool isMovingAwayFrom(Object* obj) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "GameLogic/Module/DamageModule.h"
#include "GameLogic/Module/DieModule.h"
#include "GameLogic/Module/UpdateModule.h"
#include "GameLogic/Module/DrawBridgeTowerUpdate.h"

// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
enum BridgeTowerType CPP_11(: Int);
Expand Down Expand Up @@ -84,7 +85,9 @@ class BridgeBehaviorInterface
virtual void removeScaffolding( void ) = 0;
virtual Bool isScaffoldInMotion( void ) = 0;
virtual Bool isScaffoldPresent( void ) = 0;

virtual void towerCaptured(Player* oldOwner, Player* newOwner, const Object* fromTower) {};
virtual void towerDrawBridgeUpdate(const Object* fromTower, DrawBridgeTowerInfo towerInfo) {};
virtual void onRepaired( void ) = 0;
};

// ------------------------------------------------------------------------------------------------
Expand All @@ -104,6 +107,8 @@ class BridgeBehaviorModuleData : public BehaviorModuleData
BridgeFXList m_fx; ///< list of FX lists to execute
BridgeOCLList m_ocl; ///< list of OCL to execute
Bool m_restoreable; ///< if bridge is repairable, towers do not fully die
UnsignedInt m_repairPushDuration; ///< if bridge is repaired, push units away for this amount of frames
Real m_repairPushForce; ///< lateral acceleration applied to units while pushing them off a repaired bridge (0 = no push)

static void parseFX( INI *ini, void *instance, void *store, const void* userData );
static void parseOCL( INI *ini, void *instance, void *store, const void* userData );
Expand Down Expand Up @@ -149,6 +154,8 @@ class BridgeBehavior : public UpdateModule,
virtual UpdateModuleInterface *getUpdate( void ) { return this; }
virtual UpdateSleepTime update( void );

virtual void towerCaptured(Player* oldOwner, Player* newOwner, const Object* fromTower) override;

// our own methods
static BridgeBehaviorInterface *getBridgeBehaviorInterfaceFromObject( Object *obj );
virtual void setTower( BridgeTowerType towerType, Object *tower ); ///< connect tower to us
Expand All @@ -157,6 +164,7 @@ class BridgeBehavior : public UpdateModule,
virtual void removeScaffolding( void ); ///< remove scaffolding around bridge
virtual Bool isScaffoldInMotion( void ); ///< is scaffold in motion
virtual Bool isScaffoldPresent( void ) { return m_scaffoldPresent; }
virtual void onRepaired(void) override;

protected:

Expand All @@ -175,6 +183,8 @@ class BridgeBehavior : public UpdateModule,
const BridgeInfo *bridgeInfo,
Coord3D *pos );

void pushObjectsOnBridgeSideways();

ObjectID m_towerID[ BRIDGE_MAX_TOWERS ]; ///< the towers that are a part of us

// got damaged fx stuff
Expand All @@ -193,5 +203,6 @@ class BridgeBehavior : public UpdateModule,
ObjectIDList m_scaffoldObjectIDList; ///< list of scaffold object IDs

UnsignedInt m_deathFrame; ///< frame we died on
UnsignedInt m_repairedFrame; ///< frame we got repaired

};
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class BridgeTowerBehavior : public BehaviorModule,
virtual void setBridge( Object *bridge );
virtual ObjectID getBridgeID( void );
virtual void setTowerType( BridgeTowerType type );
virtual void onCapture(Player* oldOwner, Player* newOwner) override;

static BridgeTowerBehaviorInterface *getBridgeTowerBehaviorInterfaceFromObject( Object *obj );

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// FILE: DrawBridgeTowerUpdate.h //////////////////////////////////////////////////////////////////////////
// Desc: Update module to handle draw bridge toggling
///////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "Common/KindOf.h"
#include "GameLogic/Module/SpecialPowerUpdateModule.h"
#include "GameLogic/Module/DrawBridgeUpdate.h"
#include "UpdateModule.h"

// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class SpecialPowerModule;
class ParticleSystem;
class FXList;
class AudioEventRTS;
enum CommandOption CPP_11(: Int);

//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class DrawBridgeTowerUpdateModuleData : public ModuleData
{
public:
SpecialPowerTemplate *m_specialPowerTemplate;

DrawBridgeTowerUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p);

private:

};

enum BridgeTransitionStatus CPP_11(: Int)
{
TRANSITIONSTATUS_CLOSED,
TRANSITIONSTATUS_OPENING,
TRANSITIONSTATUS_OPENED,
TRANSITIONSTATUS_CLOSING,

TRANSITIONSTATUS_COUNT
};

enum BridgeState CPP_11(: Int)
{
BRIDGESTATE_CLOSE,
BRIDGESTATE_OPEN,

BRIDGESTATE_COUNT
};

struct DrawBridgeTowerInfo {
BridgeState currentState;
BridgeState desiredState;
BridgeTransitionStatus transitionStatus;

UnsignedInt nextReadyFrame;
};

//-------------------------------------------------------------------------------------------------
/** The default update module */
//-------------------------------------------------------------------------------------------------
class DrawBridgeTowerUpdate : public SpecialPowerUpdateModule
{

MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DrawBridgeTowerUpdate, "DrawBridgeTowerUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DrawBridgeTowerUpdate, DrawBridgeTowerUpdateModuleData );

public:

DrawBridgeTowerUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration

// SpecialPowerUpdateInterface
virtual Bool initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, const Waypoint *way, UnsignedInt commandOptions );
virtual Bool isSpecialAbility() const { return false; }
virtual Bool isSpecialPower() const { return true; }
virtual Bool isActive() const {return false;}
virtual SpecialPowerUpdateInterface* getSpecialPowerUpdateInterface() { return this; }
virtual Bool doesSpecialPowerHaveOverridableDestinationActive() const { return false; } //Is it active now?
virtual Bool doesSpecialPowerHaveOverridableDestination() const { return false; } //Does it have it, even if it's not active?
virtual void setSpecialPowerOverridableDestination( const Coord3D *loc ) {}
virtual Bool isPowerCurrentlyInUse( const CommandButton *command = nullptr ) const;

virtual void onObjectCreated();
virtual void onDelete();
virtual UpdateSleepTime update();

virtual CommandOption getCommandOption() const;

protected:
DrawBridgeUpdate* getDrawBridgeUpdate() const;
Object* getBridge() const;

SpecialPowerModuleInterface *m_specialPowerModule;
};
Loading
Loading