Skip to content
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

Incorrect code / logic for StuntJumpManager#update #785

Open
Lordmau5 opened this issue Oct 12, 2024 · 1 comment · May be fixed by #786
Open

Incorrect code / logic for StuntJumpManager#update #785

Lordmau5 opened this issue Oct 12, 2024 · 1 comment · May be fixed by #786

Comments

@Lordmau5
Copy link

I'm working on a custom MTA stunt jump gamemode where players can create their own jumps, but it also includes the ones from the base game (converted).
I wanted to get the jump logic as close as possible to the original game, so I'm very thankful that this class was reverse engineered.

However, looking at the original code in a disassembler (IDA) I've noticed the logic is wrong

Reversed engineered code in question:

case eJumpState::END_POINT_INTERSECTED: {
m_iTimer += (uint32)CTimer::GetTimeStepInMS();
if (m_iTimer < 300)
return;
CTimer::ResetTimeScale();
TheCamera.RestoreWithJumpCut();
if (!m_bHitReward || mp_Active->done) {
m_jumpState = eJumpState::START_POINT_INTERSECTED;
mp_Active = nullptr;
break;
}
mp_Active->done = true;
++m_iNumCompleted;
CStats::IncrementStat(STAT_UNIQUE_JUMPS_DONE, 1.0f);
int32 reward = m_iNumCompleted == m_iNumJumps ? 10000 : mp_Active->reward;
playerInfo->m_nMoney += reward;
AudioEngine.ReportFrontendAudioEvent(AE_FRONTEND_PART_MISSION_COMPLETE);
auto bonusMessage = TheText.Get("USJ"); // UNIQUE STUNT BONUS!
if (bonusMessage)
CMessages::AddBigMessageQ(bonusMessage, 5000, STYLE_MIDDLE_SMALLER_HIGHER);
if (m_iNumCompleted == m_iNumJumps) {
auto stuntsCompleteMessage = TheText.Get("USJ_ALL"); // ALL UNIQUE STUNTS COMPLETED!
if (stuntsCompleteMessage)
CHud::SetHelpMessage(stuntsCompleteMessage, false, false, false);
}
auto rewardMessage = TheText.Get("REWARD");
if (rewardMessage)
CMessages::AddBigMessageWithNumber(rewardMessage, 6000, STYLE_WHITE_MIDDLE_SMALLER, reward, -1, -1, -1, -1, -1);
break;

Decompiled through IDA:

      else if ( CurrentUJStatus == 2 )
      {
        CurentUJTimeInFly += (CTimer::ms_fTimeStep * 0.02 * 1000.0);
        if ( CurentUJTimeInFly >= 300 )
        {
          CTimer::ms_fTimeScale = 1.0;
          CCamera::RestoreWithJumpCut(&TheCamera);
		  // Check if the end area was hit (m_bHitReward) and if the jump wasn't completed previously (mp_Active->done)
          if ( IsCurrentUJDone && !*(pCurrentUJData + 64) )
          {
            *(pCurrentUJData + 64) = 1;
            ++nUJs_done;
            CStats::IncrementStat(145, 1.0);
            if ( nUJs_done == nUniqueJumps )
              v3 = 10000;
            else
              v3 = *(pCurrentUJData + 60);
            v2->m_nScore += v3;
            CAudioEngine::ReportFrontendAudioEvent(&AudioEngine, 43, 0.0, 1.0);
            v4 = CText::Get(&TheText, "USJ");
            if ( v4 )
              CMessages::AddBigMessageQ(v4, 5000, 4u);
            if ( nUJs_done == nUniqueJumps )
            {
              v5 = CText::Get(&TheText, "USJ_ALL");
              if ( v5 )
                CHud::SetHelpMessage(v5, 0, 0, 0);
            }
            v6 = CText::Get(&TheText, "REWARD");
            if ( v6 )
              CMessages::AddBigMessageWithNumber(v6, 6000, 5u, v3, -1, -1, -1, -1, -1);
          }
          // Afterwards, reset the CurrentUJStatus (m_jumpState) and currently active jump (mp_Active)
          CurrentUJStatus = 0;
          pCurrentUJData = 0;
        }
      }
    }

Looking at the currently reverse engineered code on this repository I was wondering why it wasn't properly resetting it back to START_POINT_INTERSECTED when the player successfully completes a stunt jump

Turns out that it does an early break;, probably to simplify the code readability, at the cost of the function not being correctly implemented

@Lordmau5 Lordmau5 changed the title Incorrect code for StuntJumpManager#update Incorrect code / logic for StuntJumpManager#update Oct 12, 2024
@Lordmau5
Copy link
Author

Lordmau5 commented Oct 12, 2024

Reading through the code with a clearer mind, it seems like it is working correctly after all
(Landed, check if the player hit the area, set it to done, the switch case will run into the check again and then detect the jump is done and reset the jump state)

However, it is still calling the timescale and camera restore twice - not sure if that's intentional

@yukani yukani linked a pull request Oct 12, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant