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
4 changes: 2 additions & 2 deletions Generals/Code/GameEngine/Include/Common/BuildAssistant.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,14 @@ class BuildAssistant : public SubsystemInterface
const ThingTemplate *build,
Real angle, // angle to construct 'build' at
UnsignedInt options, // use LocationLegalToBuildOptions
Object *builderObject,
const Object *builderObject,
Player *player);

/// query if we can build at this location
virtual Bool isLocationClearOfObjects( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle, // angle to construct 'build' a
Object *builderObject,
const Object *builderObject,
UnsignedInt options,
Player *thePlayer);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ void BuildAssistant::iterateFootprint( const ThingTemplate *build,
Bool BuildAssistant::isLocationClearOfObjects( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle,
Object *builderObject,
const Object *builderObject,
UnsignedInt options,
Player *thePlayer)
{
Expand Down Expand Up @@ -842,7 +842,7 @@ LegalBuildCode BuildAssistant::isLocationLegalToBuild( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle,
UnsignedInt options,
Object *builderObject,
const Object *builderObject,
Player *player)
{

Expand Down Expand Up @@ -928,7 +928,7 @@ LegalBuildCode BuildAssistant::isLocationLegalToBuild( const Coord3D *worldPos,
// if clear path is requested check to see if the builder object can get there
if( BitIsSet( options, CLEAR_PATH ) && builderObject )
{
AIUpdateInterface *ai = builderObject->getAIUpdateInterface();
const AIUpdateInterface *ai = builderObject->getAIUpdateInterface();

//
// if there is no AI interface for this object, it cannot possible pass a clear path
Expand Down
4 changes: 2 additions & 2 deletions GeneralsMD/Code/GameEngine/Include/Common/BuildAssistant.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ class BuildAssistant : public SubsystemInterface
const ThingTemplate *build,
Real angle, // angle to construct 'build' at
UnsignedInt options, // use LocationLegalToBuildOptions
Object *builderObject,
const Object *builderObject,
Player *player);

/// query if we can build at this location
virtual LegalBuildCode isLocationClearOfObjects( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle, // angle to construct 'build' a
Object *builderObject,
const Object *builderObject,
UnsignedInt options,
Player *thePlayer);

Expand Down
32 changes: 30 additions & 2 deletions GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine

#include "Common/ActionManager.h"
#include "Common/BuildAssistant.h"
#include "Common/GlobalData.h"
#include "Common/Player.h"
#include "Common/PlayerList.h"
Expand Down Expand Up @@ -1506,7 +1507,7 @@ Bool ActionManager::canDoSpecialPowerAtLocation( const Object *obj, const Coord3
}
}

// Last check is shroudedness, if it is cared about
// Second check is shroudedness, if it is cared about
switch( spTemplate->getSpecialPowerType() )
{
case SPECIAL_DAISY_CUTTER:
Expand Down Expand Up @@ -1552,7 +1553,6 @@ Bool ActionManager::canDoSpecialPowerAtLocation( const Object *obj, const Coord3
case SUPW_SPECIAL_PARTICLE_UPLINK_CANNON:
case LAZR_SPECIAL_PARTICLE_UPLINK_CANNON:
case SPECIAL_CLEANUP_AREA:
case SPECIAL_SNEAK_ATTACK:
case SPECIAL_BATTLESHIP_BOMBARDMENT:
//Don't allow "damaging" special powers in shrouded areas, but Fogged are okay.
return ThePartitionManager->getShroudStatusForPlayer( obj->getControllingPlayer()->getPlayerIndex(), loc ) != CELLSHROUD_SHROUDED;
Expand Down Expand Up @@ -1586,6 +1586,34 @@ Bool ActionManager::canDoSpecialPowerAtLocation( const Object *obj, const Coord3
case SPECIAL_CHANGE_BATTLE_PLANS:
return false;
}

// TheSuperHackers @fix stephanmeesters 04/04/2026 Some special powers can spawn a building.
// To avoid cheating, verify that it is legal to place this building.
switch( spTemplate->getSpecialPowerType() )
{
case SPECIAL_SNEAK_ATTACK:
{
#if RETAIL_COMPATIBLE_CRC
return ThePartitionManager->getShroudStatusForPlayer( obj->getControllingPlayer()->getPlayerIndex(), loc ) != CELLSHROUD_SHROUDED;
#else
const ThingTemplate* referenceThing = mod->getReferenceThingTemplate();
if (!referenceThing)
return FALSE;

const Real angle = referenceThing->getPlacementViewAngle();

return TheBuildAssistant->isLocationLegalToBuild(
loc, referenceThing, angle,
BuildAssistant::USE_QUICK_PATHFIND |
BuildAssistant::TERRAIN_RESTRICTIONS |
BuildAssistant::CLEAR_PATH |
BuildAssistant::NO_OBJECT_OVERLAP |
BuildAssistant::SHROUD_REVEALED |
BuildAssistant::IGNORE_STEALTHED,
obj, nullptr) == LBC_OK;
#endif
}
}
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ void BuildAssistant::iterateFootprint( const ThingTemplate *build,
LegalBuildCode BuildAssistant::isLocationClearOfObjects( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle,
Object *builderObject,
const Object *builderObject,
UnsignedInt options,
Player *thePlayer)
{
Expand Down Expand Up @@ -915,7 +915,7 @@ LegalBuildCode BuildAssistant::isLocationLegalToBuild( const Coord3D *worldPos,
const ThingTemplate *build,
Real angle,
UnsignedInt options,
Object *builderObject,
const Object *builderObject,
Player *player)
{

Expand Down Expand Up @@ -1002,7 +1002,7 @@ LegalBuildCode BuildAssistant::isLocationLegalToBuild( const Coord3D *worldPos,
// if clear path is requested check to see if the builder object can get there (unless it's a structure)
if( BitIsSet( options, CLEAR_PATH ) && builderObject && !builderObject->isKindOf( KINDOF_IMMOBILE ) )
{
AIUpdateInterface *ai = builderObject->getAIUpdateInterface();
const AIUpdateInterface *ai = builderObject->getAIUpdateInterface();

//
// if there is no AI interface for this object, it cannot possible pass a clear path
Expand Down
Loading