-
Notifications
You must be signed in to change notification settings - Fork 128
bugfix: Do not show veterancy effects for dead units #1968
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 |
|---|---|---|
|
|
@@ -2789,6 +2789,11 @@ Bool Object::hasSpecialPower( SpecialPowerType type ) const | |
| //------------------------------------------------------------------------------------------------- | ||
| void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel, Bool provideFeedback ) | ||
| { | ||
| #if !RETAIL_COMPATIBLE_CRC | ||
| if (isEffectivelyDead()) | ||
| return; | ||
| #endif | ||
|
|
||
| updateUpgradeModules(); | ||
|
|
||
| const UpgradeTemplate* up = TheUpgradeCenter->findVeterancyUpgrade(newLevel); | ||
|
|
@@ -2843,6 +2848,11 @@ void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel ne | |
| && outerDrawable | ||
| && outerDrawable->isVisible(); | ||
|
|
||
| #if RETAIL_COMPATIBLE_CRC | ||
| if (isEffectivelyDead()) | ||
| return; | ||
| #endif | ||
|
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. That should do: #if RETAIL_COMPATIBLE_CRC
doAnimation &= isEffectivelyDead();
#endif
Author
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. Does it really matter when they're effectively the same thing and this one is deprecated? Having them the same highlights that both compatible and non-compatible logic is identical and the only difference is when it is called. 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. My motivation here was to get rid of the return in the middle of the function.
Author
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. Why is a return undesirable? 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. Breakdown, courtesy of Chat GippityReturning early from a function (i.e., having multiple 1. Loss of a clear control-flow narrativeIn long or complex functions, early returns can fragment the logic.
This is especially problematic when:
2. Harder reasoning about invariants and stateComplex functions often establish invariants: // After this point, x and y are valid and synchronizedIf you return early:
This increases the cognitive load when modifying the function later. 3. Resource management and cleanup risks (without RAII)Historically (and still in some legacy code):
Example risk: lock(m);
if (error) return; // mutex never unlockedModern C++ mitigates this with RAII, but:
4. Debugging and instrumentation complexityMultiple return points complicate:
With one exit point, you can:
5. Increased risk when modifying or extending the functionIn long functions, future changes are common:
With many early returns:
This scales poorly as complexity grows. 6. Violates some team or project conventionsMany codebases explicitly prefer:
Violating conventions reduces consistency and codebase readability. 7. Encourages overly large functionsEarly returns can mask deeper design issues:
Refactoring into smaller functions often:
Balanced perspective (important)Early returns are not inherently bad. They are generally good when:
They are more questionable when:
Practical guidelineA commonly accepted compromise in modern C++:
If mid-function returns feel necessary:
Author
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. Not many if any of those concerns apply here. The method is clearly separated into two blocks - logic and then animation; placing a return between the two blocks is reasonable. Matching the code within both precompiler directives aids in understanding that it is the same logic with only the placement being the difference. |
||
|
|
||
| if( doAnimation && TheGameLogic->getDrawIconUI() ) | ||
| { | ||
| if( TheAnim2DCollection && TheGlobalData->m_levelGainAnimationName.isEmpty() == FALSE ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3104,6 +3104,11 @@ Bool Object::hasAnySpecialPower() const | |
| //------------------------------------------------------------------------------------------------- | ||
| void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel, Bool provideFeedback ) | ||
| { | ||
| #if !RETAIL_COMPATIBLE_CRC | ||
| if (isEffectivelyDead()) | ||
| return; | ||
| #endif | ||
|
|
||
| updateUpgradeModules(); | ||
|
|
||
| const UpgradeTemplate* up = TheUpgradeCenter->findVeterancyUpgrade(newLevel); | ||
|
|
@@ -3158,6 +3163,11 @@ void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel ne | |
| && outerDrawable | ||
| && outerDrawable->isVisible(); | ||
|
|
||
| #if RETAIL_COMPATIBLE_CRC | ||
|
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. Does this require retail compatibility? It looks like this only disables sound and visuals locally.
Author
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. Technically not. The idea is that this code gets removed when retail compatibility is dropped, so leaving this here will make it easier to keep track of. |
||
| if (isEffectivelyDead()) | ||
| return; | ||
| #endif | ||
|
|
||
| if( doAnimation && TheGameLogic->getDrawIconUI() ) | ||
| { | ||
| if( TheAnim2DCollection && TheGlobalData->m_levelGainAnimationName.isEmpty() == FALSE ) | ||
|
|
||
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.
Can add TheSuperHackers comment because it is user facing, even if obvious what it does.