Skip to content

bugfix(specialpower): Fix special powers never becoming ready on constructed structures - #3629

Open
tintinhamans wants to merge 2 commits into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/special-power-under-construction
Open

tintinhamans wants to merge 2 commits into
TheSuperHackers:mainfrom
tintinhamans:arctic/fix/special-power-under-construction

Conversation

@tintinhamans

@tintinhamans tintinhamans commented Oct 29, 2026 •

Copy link
Copy Markdown

Fixes #3618

With RETAIL_COMPATIBLE_CRC off, #1218 starts the special power timer at 0xFFFFFFFF so a structure cannot fire while under construction. Only SpecialPowerCreate resets it when construction completes. A dozer-built structure without that module never gets a timer.

  • Zero Hour: Strategy Center battle plans and Intelligence.
  • Generals: Strategy Center battle plans, Detention Camp Intelligence, and Spy Drone on a Command Center built after the science. Shared timers and the superweapons are fine.

The timer starts at 0 again, like retail, and a structure under construction reports its powers as not ready. The UI and ActionManager::canDoSpecialPower both check that, so the nuke exploit from #1218 stays closed.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b445992f-c1d5-494c-b071-54519df0e77b
Commits

Reviewing files that changed from the base of the PR and between 522bf93 and 4b714eb.

Files selected for processing: 2
  • Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
  • GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Walkthrough

Both game editions initialize m_availableOnFrame to zero and set the ready frame only when a pre-built, non-shared power does not start paused. In non-retail-compatible builds, readiness queries return false and zero percent while the object is under construction.

Changes

Special-power readiness

Layer / File(s) Summary
Availability and construction readiness
Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp, GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
Both editions initialize m_availableOnFrame to zero and set the ready frame only when a pre-built, non-shared power does not start paused. In non-retail-compatible builds, isReady() returns false and getPercentReady() returns 0.0f while the object is under construction. isReady() retrieves the controlling player through the validated local object pointer.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested labels: Fix

Suggested reviewers: stubbjax, xezon

Merge Risk: Minimal · previous review 4b714

No concrete merge-blocking defect is established by the available evidence.

Pre-merge checks: Passed 4
Check name Status Explanation
Description check Passed The description directly explains the special-power readiness bug, its cause, affected scenarios, and the safeguards preserved by the fix.
Title check Passed The title clearly and concisely identifies the fix for special powers that remain unready on constructed structures.
Linked Issues check Passed [#3618] requires USA Strategy Center battle plans to become available when RETAIL_COMPATIBLE_CRC is disabled. Both Generals/.../SpecialPowerModule.cpp and GeneralsMD/.../SpecialPowerModule.cpp n…
Out of Scope Changes check Passed The whole-PR diff is limited to SpecialPowerModule.cpp in the Generals and GeneralsMD trees. The timer initialization, construction readiness checks, paused-power handling, and validated-object play…
Full details: Linked Issues check

Explanation

[#3618] requires USA Strategy Center battle plans to become available when RETAIL_COMPATIBLE_CRC is disabled. Both Generals/.../SpecialPowerModule.cpp and GeneralsMD/.../SpecialPowerModule.cpp now initialize m_availableOnFrame to 0 instead of 0xFFFFFFFF. Both files also report powers as not ready during construction, so the construction safeguard remains active. The paused-power condition prevents paused powers from being marked ready before they are unpaused. No linked issue requires an automated test change.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff is limited to SpecialPowerModule.cpp in the Generals and GeneralsMD trees. The timer initialization, construction readiness checks, paused-power handling, and validated-object player lookup directly support the special-power readiness fix and its safety behavior. No unrelated change is demonstrated.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

Fixes special powers that never become ready on newly built structures in Generals and Zero Hour.

  • Structure powers stay unavailable until construction ends, then can become ready.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Create special power module] --> B[Initialize timer to zero]
  B --> C{Structure under construction?}
  C -->|Yes| D[Report not ready]
  C -->|No| E[Check pause state and timer]
  D --> F[Construction finishes]
  F --> E
Loading

Reviews (5) · Last reviewed commit: "bugfix(specialpower): Fix paused special..." · Reviewed by Greptile

@tintinhamans
tintinhamans force-pushed the arctic/fix/special-power-under-construction branch from c5e2c9c to 41e618d Compare October 29, 2026 02:01
@tintinhamans tintinhamans changed the title bugfix(specialpower): Fix special powers that never become ready on newly built structures when retail compatibility is disabled bugfix(specialpower): Fix special powers never becoming ready on constructed structures Oct 29, 2026
@tintinhamans tintinhamans added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour ThisProject The issue was introduced by this project, or this task is specific to this project NoRetail This fix or change is not applicable with Retail game compatibility labels Oct 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (1)

Minor · Check construction status before the cheat bypass. · SpecialPowerModule.cpp:277-302

Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp:277-302
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Check construction status before the cheat bypass.

The special-power delay cheat can set m_specialPowerUsesDelay to FALSE. In non-retail builds, isReady() then returns TRUE before checking OBJECT_STATUS_UNDER_CONSTRUCTION. The same PR already makes getPercentReady() return 0.0f during construction before its cheat path, so construction is not intended to be a cheat exception. A direct script consumer can pass its isReady() gate while the object is still being built.

Apply the same ordering in both mirrored files.

Suggested fix
--- a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
+++ b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
@@ -274,6 +274,14 @@ Bool SpecialPowerModule::isReady() const
 //-------------------------------------------------------------------------------------------------
 Bool SpecialPowerModule::isReady() const
 {
+	const Object* obj = getObject();
+
+#if !RETAIL_COMPATIBLE_CRC
+	if ( obj && obj->testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )
+		return FALSE;
+#endif
+
 #if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)
 	// this is a cheat ... remove this for release!
 	if( TheGlobalData->m_specialPowerUsesDelay == FALSE )
@@ -281,15 +289,8 @@ Bool SpecialPowerModule::isReady() const
 #endif
 
-	const Object* obj = getObject();
 	const SpecialPowerModuleData *modData = getSpecialPowerModuleData();
 
 	if ( obj && modData )
 	{
-#if !RETAIL_COMPATIBLE_CRC
-		// TheSuperHackers @bugfix arcticdolphin 29/10/2026 Not ready while under construction.
-		if ( obj->testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )
-			return FALSE;
-#endif
-
 		Player *player = getObject()->getControllingPlayer();
--- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
@@ -290,6 +290,14 @@ Bool SpecialPowerModule::isReady() const
 //-------------------------------------------------------------------------------------------------
 Bool SpecialPowerModule::isReady() const
 {
+	const Object* obj = getObject();
+
+#if !RETAIL_COMPATIBLE_CRC
+	if ( obj && obj->testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )
+		return FALSE;
+#endif
+
 #if defined(RTS_DEBUG) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)
 	// this is a cheat ... remove this for release!
 	if( TheGlobalData->m_specialPowerUsesDelay == FALSE )
@@ -297,15 +305,8 @@ Bool SpecialPowerModule::isReady() const
 #endif
 
-	const Object* obj = getObject();
 	const SpecialPowerModuleData *modData = getSpecialPowerModuleData();
 
 	if ( obj && modData )
 	{
-#if !RETAIL_COMPATIBLE_CRC
-		// TheSuperHackers @bugfix arcticdolphin 29/10/2026 Not ready while under construction.
-		if ( obj->testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )
-			return FALSE;
-#endif
-
 		Player *player = getObject()->getControllingPlayer();

Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ef02c0d5-cd3c-4205-aff8-95918fa02480
Commits

Reviewing files that changed from the base of the PR and between 68d1668 and 41e618d.

Files selected for processing: 2
  • Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp
  • GeneralsMD/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@Caball009
Caball009 requested a review from Mauller October 29, 2026 02:21
@tintinhamans
tintinhamans force-pushed the arctic/fix/special-power-under-construction branch from 41e618d to 522bf93 Compare October 29, 2026 02:38
@Stubbjax

Stubbjax commented Oct 29, 2026 •

Copy link
Copy Markdown

While you're at it, would you mind adding !md->m_startsPaused to the startsReady condition in the SpecialPowerModule's constructor? This fixes a visual glitch on upgrade-dependent abilities with no initial cooldown. I missed it after the refactor in #3054.

image

@tintinhamans

Copy link
Copy Markdown
Author

While you're at it, would you mind adding !md->m_startsPaused to the startsReady condition in the SpecialPowerModule's constructor? This fixes a visual glitch on upgrade-dependent abilities with no initial cooldown. I missed it after the refactor in #3054.

Done.

@tintinhamans
tintinhamans requested a review from Stubbjax October 29, 2026 07:33
@Mauller

Mauller commented Oct 29, 2026

Copy link
Copy Markdown

I was going to have a look at this later, i can check if i can still launch nuke scaffolds with this implementation.

@tintinhamans
tintinhamans force-pushed the arctic/fix/special-power-under-construction branch from 4b714eb to 607b4a6 Compare October 29, 2026 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker NoRetail This fix or change is not applicable with Retail game compatibility ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

USA strategy center battle plans are never available to player with retail compatibility disabled

4 participants