Initial Superweapon countdown is incorrect if construction completed in subdued state
Opened this issue · 5 comments
Initial Superweapon countdown is incorrect if construction completed in subdued state. The USA Microwave Tank is used to apply the subdual damage and disable the scaffold before construction completion.
generals.2023-05-11.18-42-58-96.mp4
We can avoid this bug by applying the same workaround as with
However, this is a hack. The disadvantage of these fixes is that the affected structure scaffolds will no longer be targetable by the USA Microwave Tank before completion. Plus the PLAYER_UPGRADE is consumed for this fix, which likely will cause conflicts with GLA Scud Storm + Fortified Structure upgrade.
I think these 3 bugs
- USA Supply Drop Zone subdual bug
- Negative power subdual bug
- Superweapon timer subdual bug
need to be fixed in Thyme, and then all INI changes related to "StructureArmor_NoSubdualDamage" need to be reverted.
need to be fixed in Thyme, and then all INI changes related to "StructureArmor_NoSubdualDamage" need to be reverted.
Fully agree, but as temporary solutions, they can stay for now.
Started code investigation in #374 as I thought they may have been related, but that doesn't seem to be the case.
I did a test with building two particle cannons at the same time, but disabling it at different moments. One particle cannon finished 45 seconds after I disabled it and started its counter at 4:45. The other particle cannon finished 15 seconds after I disabled it and started its counter at 4:15.
Issue seems to be in SpecialPowerModule.cpp or related to classes calling SpecialPowerModule.
The UI timer uses getReadFrame() to calculate the time (InGameUi.cpp line 3571).
getReadyFrame() uses two private parameters: m_availableOnFrame which states in which frame the super weapon is ready, and m_pausedOnFrame , the frame number the timer has been paused (e.g. due to power outage or microwave disabling).
m_pausedOnFrame is set the moment the building is paused. Once the building is unpaused, the number of frames passed since m_pausedFrames is added to m_availableOnFrame to calculate the new frame when the super weapon is ready.
The most likely scenario here is that m_availableOnFrame is set when the construction of the building finishes, but that m_pausedOnFrame is not reset to the frame the construction is finished. This means that the amount of time the building was paused during construction is added to the timer. The earlier the building was paused in the construction phase, the longer the super weapon timer becomes.
In setReadyFrame(), this is done correctly,
void SpecialPowerModule::setReadyFrame( UnsignedInt frame )
{
m_availableOnFrame = frame;
//If a script should change the ready frame, we need to update the paused frame. This value isn't
//used directly to determine if paused or not... it uses m_pausedCount.
m_pausedOnFrame = TheGameLogic->getFrame();
}However in startPowerRecharge(), m_availableOnFrame is set directly, while m_pausedFrame is not set.
Solutions is to change:
to
// set the frame we will be 100% available on now
setReadyFrame(TheGameLogic->getFrame() + getSpecialPowerTemplate()->getReloadTime());Once there is a working compiling version, I will test this solution and create a PR.
This fix will break compatibility.
@xezon Can you assign this issue to me.
Solutions is to change:
to
// set the frame we will be 100% available on now setReadyFrame(TheGameLogic->getFrame() + getSpecialPowerTemplate()->getReloadTime());
I think this fixes the timer as intended. There's still one issue to be resolved, however. The first time this appears to work perfectly. If you sell the Particle Cannon and finish building it again while subdued by the microwave tank and then stop the attack, the PC will keep cycling through some of the 'antenna' raising animations. It looks purely like a visual / animation glitch and it stops once the weapon's been fired, but it'd be better if we can fix it.
I tried a bunch of things, but I wasn't able to figure how to fix the visual glitch yet. I did figure out a more complicated alternative to the above code fix, but I want to mention it here lest I forget about it. It also suffers from the same visual glitch.
- Add to
Player::onStructureConstructionComplete:
if (structure->isDisabled())
structure->pauseAllSpecialPowers(TRUE);
GeneralsGameCode/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp
Lines 2113 to 2114 in a86ed98
Change to:
if ( type != DISABLED_HELD && !isDisabledByType( type ) && !testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )GeneralsGameCode/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp
Lines 2271 to 2272 in a86ed98
Change to:
if ( type != DISABLED_HELD && isDisabledByType( type ) && !testStatus( OBJECT_STATUS_UNDER_CONSTRUCTION ) )