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: 4 additions & 0 deletions Core/GameEngine/Include/Common/GameDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
#define PRESERVE_UNRELIABLE_FIRESTORMS (0) // The fix for this unfavorable behavior was approved by the Game Design Committee.
#endif

#ifndef PRESERVE_SNIPING_EMPTY_STINGER_SITES
#define PRESERVE_SNIPING_EMPTY_STINGER_SITES (0) // The fix for this unfavorable behavior was approved by the Game Design Committee.
#endif

#ifndef PRESERVE_RETAIL_SCRIPTED_CAMERA
#define PRESERVE_RETAIL_SCRIPTED_CAMERA (1) // Retain scripted camera behavior present in retail Generals 1.08 and Zero Hour 1.04
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class SpawnBehaviorInterface
virtual CanAttackResult getCanAnySlavesUseWeaponAgainstTarget( AbleToAttackType attackType, const Object *victim, const Coord3D *pos, CommandSourceType cmdSource ) = 0;
virtual Bool canAnySlavesAttack() = 0;
virtual void orderSlavesToGoIdle( CommandSourceType cmdSource ) = 0;
virtual Int getSlaveCount() const = 0;
};

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -160,6 +161,7 @@ class SpawnBehavior : public UpdateModule,
virtual CanAttackResult getCanAnySlavesUseWeaponAgainstTarget( AbleToAttackType attackType, const Object *victim, const Coord3D *pos, CommandSourceType cmdSource ) override;
virtual Bool canAnySlavesAttack() override;
virtual void orderSlavesToGoIdle( CommandSourceType cmdSource ) override;
virtual Int getSlaveCount() const override { return m_spawnCount; }

// **********************************************************************************************
// our own methods
Expand Down
22 changes: 22 additions & 0 deletions Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include "GameLogic/Module/AssistedTargetingUpdate.h"
#include "GameLogic/Module/ProjectileStreamUpdate.h"
#include "GameLogic/Module/PhysicsUpdate.h"
#include "GameLogic/Module/SpawnBehavior.h"
#include "GameLogic/TerrainLogic.h"

#define RATIONALIZE_ATTACK_RANGE
Expand Down Expand Up @@ -581,6 +582,27 @@ Real WeaponTemplate::estimateWeaponTemplateDamage(
}
}

#if !RETAIL_COMPATIBLE_CRC
Comment thread
xezon marked this conversation as resolved.
// hmm.. must be shooting a firebase or such, if there is noone home to take the bullet, return 0!
if ( victimObj->isKindOf( KINDOF_STRUCTURE) && damageType == DAMAGE_SNIPER )
{
#if PRESERVE_SNIPING_EMPTY_STINGER_SITES
if (victimObj->getContain())
{
if (victimObj->getContain()->getContainCount() == 0)
return 0.0f;
}
#else
// TheSuperHackers @bugfix Stubbjax 22/06/2026 Only allow targeting Stinger Sites when they contain Soldiers.
const Bool hasOccupants = victimObj->getContain() && victimObj->getContain()->getContainCount() > 0;
const Bool hasSlaves = victimObj->getSpawnBehaviorInterface() && victimObj->getSpawnBehaviorInterface()->getSlaveCount() > 0;

if (!hasOccupants && !hasSlaves)
return 0.0f;
#endif
}
#endif
Comment thread
greptile-apps[bot] marked this conversation as resolved.

// this stays, even if ALLOW_SURRENDER is not defed, since flashbangs still use 'em
if ( damageType == DAMAGE_SURRENDER || m_allowAttackGarrisonedBldgs )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class SpawnBehaviorInterface
virtual Bool areAllSlavesStealthed() const = 0;
virtual void revealSlaves() = 0;
virtual Bool doSlavesHaveFreedom() const = 0;
virtual Int getSlaveCount() const = 0;
};

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -177,6 +178,7 @@ class SpawnBehavior : public UpdateModule,
virtual Bool areAllSlavesStealthed() const override;
virtual void revealSlaves() override;
virtual Bool doSlavesHaveFreedom() const override { return getSpawnBehaviorModuleData()->m_slavesHaveFreeWill; }
virtual Int getSlaveCount() const override { return m_spawnCount; }

// **********************************************************************************************
// our own methods
Expand Down
11 changes: 11 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include "GameLogic/Module/AssistedTargetingUpdate.h"
#include "GameLogic/Module/ProjectileStreamUpdate.h"
#include "GameLogic/Module/PhysicsUpdate.h"
#include "GameLogic/Module/SpawnBehavior.h"
#include "GameLogic/TerrainLogic.h"

#define RATIONALIZE_ATTACK_RANGE
Expand Down Expand Up @@ -599,11 +600,21 @@ Real WeaponTemplate::estimateWeaponTemplateDamage(
// hmm.. must be shooting a firebase or such, if there is noone home to take the bullet, return 0!
if ( victimObj->isKindOf( KINDOF_STRUCTURE) && damageType == DAMAGE_SNIPER )
{

#if RETAIL_COMPATIBLE_CRC || PRESERVE_SNIPING_EMPTY_STINGER_SITES
if ( victimObj->getContain() )
{
if ( victimObj->getContain()->getContainCount() == 0 )
return 0.0f;
}
#else
// TheSuperHackers @bugfix Stubbjax 22/06/2026 Only allow targeting Stinger Sites when they contain Soldiers.
const Bool hasOccupants = victimObj->getContain() && victimObj->getContain()->getContainCount() > 0;
const Bool hasSlaves = victimObj->getSpawnBehaviorInterface() && victimObj->getSpawnBehaviorInterface()->getSlaveCount() > 0;

if (!hasOccupants && !hasSlaves)
return 0.0f;
#endif
}


Expand Down
Loading