Repository navigation
bugfix(ThingFactory): Return the final override of the ThingTemplate. #3445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -262,7 +262,14 @@ const ThingTemplate *ThingFactory::findByTemplateID( UnsignedShort id ) | |
| for (ThingTemplate *tmpl = m_firstTemplate; tmpl; tmpl = tmpl->friend_getNextTemplate()) | ||
| { | ||
| if (tmpl->getTemplateID() == id) | ||
| { | ||
| #if RETAIL_COMPATIBLE_SCRIPTING | ||
| return tmpl; | ||
| #else | ||
| // TheSuperHackers @bugfix DrGoldFish 08/10/2026 Return the final override of the ThingTemplate. | ||
| return (ThingTemplate*)tmpl->getFinalOverride(); | ||
| #endif | ||
| } | ||
| } | ||
| DEBUG_CRASH(("template %d not found",(Int)id)); | ||
| return nullptr; | ||
|
|
@@ -276,7 +283,12 @@ ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name, Bool | |
| ThingTemplateHashMapIt tIt = m_templateHashMap.find(name); | ||
|
|
||
| if (tIt != m_templateHashMap.end()) { | ||
| #if RETAIL_COMPATIBLE_SCRIPTING | ||
| return tIt->second; | ||
| #else | ||
| // TheSuperHackers @bugfix DrGoldFish 08/10/2026 Return the final override of the ThingTemplate. | ||
| return (ThingTemplate*)tIt->second->getFinalOverride(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Keep name lookups returning the base template, or update persistent callers before changing this behavior. Both game versions have this change. |
||
| #endif | ||
| } | ||
|
|
||
| #ifdef LOAD_TEST_ASSETS | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 41019
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 42895
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 42461
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 34331
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 39078
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 41569
🏁 Script executed:
Repository: TheSuperHackers/GeneralsGameCode
Length of output: 2271
Resolve final overrides in
ThingTemplate::calcCostToBuild().firstTemplate()returnsm_firstTemplatewithout resolving overrides. Both AI variants assign this pointer toWorkOrder::m_thingfor supply trucks and dozers, then pass it toqueueCreateUnit(). That function callsunitType->calcCostToBuild(player), which reads the base template’sm_buildCost. AI purchases and their refunds can therefore use the base cost instead of the finalmap.iniorsolo.inicost.Make
calcCostToBuild()use the final override before reading the cost and applying player modifiers. The restored-queue path already resolves the name throughfindTemplate()during load.📍 Affects 2 files
Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp#L289-L290(this comment)GeneralsMD/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp#L289-L290