void CMomentumPlayer::UpdateRunStats() { //should velocity be XY or XYZ? ConVarRef hvel("mom_speedometer_hvel"); IGameEvent *playerMoveEvent = gameeventmanager->CreateEvent("keypress"); float velocity = hvel.GetBool() ? GetLocalVelocity().Length2D() : GetLocalVelocity().Length(); if (g_Timer.IsRunning()) { int currentStage = g_Timer.GetCurrentStageNumber(); if (!m_bPrevTimerRunning) //timer started on this tick { //Reset old run stats ResetRunStats(); m_flStartSpeed = GetLocalVelocity().Length2D(); //prestrafe should always be XY only //Comapre against successive bhops to avoid incrimenting when the player was in the air without jumping (for surf) if (GetGroundEntity() == NULL && m_iSuccessiveBhops) { m_nStageJumps[0]++; } } if (m_nButtons & IN_MOVELEFT && !(m_nPrevButtons & IN_MOVELEFT)) { m_nStageStrafes[0]++; m_nStageStrafes[currentStage]++; } else if (m_nButtons & IN_MOVERIGHT && !(m_nPrevButtons & IN_MOVERIGHT)) { m_nStageStrafes[0]++; m_nStageStrafes[currentStage]++; } // ---- MAX VELOCITY ---- if (velocity > m_flStageVelocityMax[0]) m_flStageVelocityMax[0] = velocity; //also do max velocity per stage if (velocity > m_flStageVelocityMax[currentStage]) m_flStageVelocityMax[currentStage] = velocity; // ---------- // --- STAGE ENTER VELOCITY --- } // ---- STRAFE SYNC ----- float SyncVelocity = GetLocalVelocity().Length2DSqr(); //we always want HVEL for checking velocity sync if (!(GetFlags() & (FL_ONGROUND | FL_INWATER)) && GetMoveType() != MOVETYPE_LADDER) { if (EyeAngles().y > m_qangLastAngle.y) //player turned left { m_nStrafeTicks++; if ((m_nButtons & IN_MOVELEFT) && !(m_nButtons & IN_MOVERIGHT)) m_nPerfectSyncTicks++; if (SyncVelocity > m_flLastSyncVelocity) m_nAccelTicks++; } else if (EyeAngles().y < m_qangLastAngle.y) //player turned right { m_nStrafeTicks++; if ((m_nButtons & IN_MOVERIGHT) && !(m_nButtons & IN_MOVELEFT)) m_nPerfectSyncTicks++; if (SyncVelocity > m_flLastSyncVelocity) m_nAccelTicks++; } } if (m_nStrafeTicks && m_nAccelTicks && m_nPerfectSyncTicks) { m_flStrafeSync = ((float)m_nPerfectSyncTicks / (float)m_nStrafeTicks) * 100; // ticks strafing perfectly / ticks strafing m_flStrafeSync2 = ((float)m_nAccelTicks / (float)m_nStrafeTicks) * 100; // ticks gaining speed / ticks strafing } // ---------- m_qangLastAngle = EyeAngles(); m_flLastSyncVelocity = SyncVelocity; //this might be used in a later update //m_flLastVelocity = velocity; m_bPrevTimerRunning = g_Timer.IsRunning(); m_nPrevButtons = m_nButtons; if (playerMoveEvent) { playerMoveEvent->SetInt("num_strafes", m_nStageStrafes[0]); playerMoveEvent->SetInt("num_jumps", m_nStageJumps[0]); if ((m_nButtons & IN_JUMP && GetGroundEntity() != NULL) || m_nButtons & IN_MOVELEFT | IN_MOVERIGHT) gameeventmanager->FireEvent(playerMoveEvent); } //think once per tick SetNextThink(gpGlobals->curtime + gpGlobals->interval_per_tick, "THINK_EVERY_TICK"); }
void CMomentumPlayer::Spawn() { SetModel(ENTITY_MODEL); SetBodygroup(1, 11);//BODY_PROLATE_ELLIPSE // BASECLASS SPAWN MUST BE AFTER SETTING THE MODEL, OTHERWISE A NULL HAPPENS! BaseClass::Spawn(); AddFlag(FL_GODMODE); RemoveSolidFlags(FSOLID_NOT_SOLID); // this removes the flag that was added while switching to spectator mode which // prevented the player from activating triggers // do this here because we can't get a local player in the timer class ConVarRef gm("mom_gamemode"); switch (gm.GetInt()) { case MOMGM_BHOP: case MOMGM_SURF: case MOMGM_UNKNOWN: default: EnableAutoBhop(); break; case MOMGM_SCROLL: DisableAutoBhop(); break; } // Reset all bool gameevents IGameEvent *runSaveEvent = gameeventmanager->CreateEvent("run_save"); IGameEvent *runUploadEvent = gameeventmanager->CreateEvent("run_upload"); IGameEvent *timerStartEvent = gameeventmanager->CreateEvent("timer_state"); m_RunData.m_bIsInZone = false; m_RunData.m_bMapFinished = false; m_RunData.m_iCurrentZone = 0; m_bHasPracticeMode = false; ResetRunStats(); if (runSaveEvent) { runSaveEvent->SetBool("run_saved", false); gameeventmanager->FireEvent(runSaveEvent); } if (runUploadEvent) { runUploadEvent->SetBool("run_posted", false); runUploadEvent->SetString("web_msg", ""); gameeventmanager->FireEvent(runUploadEvent); } if (timerStartEvent) { timerStartEvent->SetInt("ent", entindex()); timerStartEvent->SetBool("is_running", false); gameeventmanager->FireEvent(timerStartEvent); } // Linear/etc map g_Timer->DispatchMapInfo(); RegisterThinkContext("THINK_EVERY_TICK"); RegisterThinkContext("CURTIME"); RegisterThinkContext("THINK_AVERAGE_STATS"); RegisterThinkContext("CURTIME_FOR_START"); RegisterThinkContext("TWEEN"); SetContextThink(&CMomentumPlayer::UpdateRunStats, gpGlobals->curtime + gpGlobals->interval_per_tick, "THINK_EVERY_TICK"); SetContextThink(&CMomentumPlayer::CheckForBhop, gpGlobals->curtime, "CURTIME"); SetContextThink(&CMomentumPlayer::CalculateAverageStats, gpGlobals->curtime + AVERAGE_STATS_INTERVAL, "THINK_AVERAGE_STATS"); SetContextThink(&CMomentumPlayer::LimitSpeedInStartZone, gpGlobals->curtime, "CURTIME_FOR_START"); SetContextThink(&CMomentumPlayer::TweenSlowdownPlayer, gpGlobals->curtime, "TWEEN"); SetNextThink(gpGlobals->curtime); DevLog("Finished spawn!\n"); }