Created
July 8, 2014 10:39
-
-
Save ProdigySim/e0a9aeaa82d720f74493 to your computer and use it in GitHub Desktop.
CTerrorPlayer::UpdateZombieFrustration()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Reverse-engineered CTerrorPlayer::UpdateZombieFrustration(). | |
| // I can claim no copyright for this code. | |
| // This representation of code was produced by reverse engineering for interoperability. | |
| // Any resemblance to original source is completely accidental. | |
| void CTerrorPlayer::UpdateZombieFrustration() | |
| { | |
| if ( !ZombieFrustration.GetBool()) | |
| || this->GetTeamNumber() != 3 | |
| || this->GetClass() != 8 | |
| || this->IsBot() | |
| || this->IsGhost)() | |
| || !TheDirector->m_bTankFrustrationEnabled ) | |
| { | |
| // Frustration is not currently enabled, reset the frustration var to 0% frustrated | |
| goto RESET_FRUSTRATION; | |
| } | |
| if ( !this->m_FrustrationUpdateTimer.HasStarted() | |
| || !this->m_FrustrationUpdateTimer.IsElapsed()) ) | |
| { | |
| // It's not time to update frustration yet | |
| return; | |
| } | |
| // How long has it been since the tank last saw a player? | |
| float flTimeSinceLastLOS = this->m_TimeSinceLastLOS.GetElapsedTime(); | |
| if ( flTimeSinceLastLOS <= ZombieFrustrationLOSDelay.GetFloat()) ) | |
| { | |
| // It hasn't been at least z_frustration_los_delay seconds since the last LOS of the tank. | |
| // Don't tick down the frustration yet. | |
| return; | |
| } | |
| // Set the next frustration update to happen in another second. | |
| this->m_FrustrationUpdateTimer.Start(1.0); | |
| // LSCFLAG_SKIP_INCAPPED=1, | |
| // LSCFLAG_ONLY_INCAPPED=2, | |
| // LSCFLAG_SKIP_BOTS=4, | |
| int liveSurvivorCount = ForEachTerrorPlayer<LiveSurvivorCounter>(LSCFLAG_SKIP_INCAPPED); | |
| if ( !liveSurvivorCount ) | |
| { | |
| RESET_FRUSTRATION: | |
| // Networkvar update. | |
| // Setting frustration to 0 means "full" rage meter, i.e. not going to pass. | |
| this->.m_frustration = 0; | |
| return; | |
| } | |
| if ( !TheDirector->HasAnySurvivorLeftSafeArea() | |
| || !CDirector::IsAnySurvivorInExitCheckpoint() | |
| || TheDirector->IsFinaleWon() ) | |
| { | |
| // Freeze current frustration in these cases. | |
| return; | |
| } | |
| int currentFrustration = a1->CTerrorPlayer.m_frustration; | |
| // Calculate what one more tick of frustration will add as a percent of 100. | |
| float newFrustration = currentFrustration + (100 / ZombieFrustrationLifetime.GetInt()); | |
| // Clamp the value to an upper bound of 100. | |
| // (Note: this is probably done with a macro in original source, evidenced by duplicate calculations of the previous value) | |
| newFrustration = newFrustration <= 100 ? newFrustration : 100; | |
| if(currentFrustration != newFrustration) | |
| { | |
| // NetworkVar Update | |
| this->m_frustration = newFrustration; | |
| } | |
| // If we're not at 100 frustration yet, or something something, we're done here. | |
| if ( newFrustration <= 99 || this->unknown328[7] & 8 ) | |
| return; | |
| // Otherwise, the tank is frustrated! Whatever shall we do! | |
| if ( TheDirector->ChallengeModePtr->TankRun() ) | |
| { | |
| // When a tank gets frustrated in "TankRun" mode, we apparently kill it. | |
| CBasePlayer::CommitSuicide(a1, 0, 0); | |
| return; | |
| } | |
| // This method was actually inlined, but it's just a big hunk of player looping code. | |
| // Checks for: (GetTeamNumber() == 3 && !IsBot() && !IsAlive()) || GetTeamNumber() != 3 || GetClass() != 8) | |
| // The conflicting conditionals point to a bug... But I'm not really sure. | |
| int eligiblePassTargetCount = CountEligibleTankTargets(); | |
| // I don't know why they don't just use IsElapsed()... | |
| // There's some odd repetition here that suggests Macro usage | |
| if(TheDirector->TankLotteryEntryTimer.GetRemainingRatio() == 0.0f) | |
| { | |
| // Fire the frustrated event so clients and other stuff know about it. | |
| IGameEvent * event = gameeventmanager->CreateEvent("tank_frustrated"); | |
| if ( event ) | |
| { | |
| // I don't really know how the edict_t reference is retrieved, but this is basically what's happening. | |
| event->SetInt("userid", engine->GetPlayerUserId(this->GetEdict())); | |
| gameeventmanager->FireEvent(event); | |
| } | |
| if ( eligiblePassTargetCount && TheDirector->m_iTankSwapCount <= 1 ) | |
| { | |
| TheDirector->TryOfferingTankBot(this, false); | |
| } | |
| else | |
| { | |
| // Offering tank bot currently unavailable for some reason. | |
| this->ReplaceWithBot(false); | |
| this->SetPreSpawnClass(ZC_HUNTER); // Set to spawn as a hunter I guess... | |
| this->State_Transition(CCSPlayerState_GHOST); // Transition to ghost state (state 8 anyway, I think it's ghost) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment