From c3bc281c5b96add3fef6097e274f83943596dcb7 Mon Sep 17 00:00:00 2001 From: Barinade Date: Thu, 31 Oct 2019 20:27:56 -0500 Subject: [PATCH] Create PlayerPractice derivative of Player for Practice Mode for finer control of the inner working of the game and make cheating both easier and harder at the same time (please) --- src/Etterna/Actor/CMakeLists.txt | 2 + src/Etterna/Actor/Gameplay/PlayerPractice.cpp | 84 +++++++++++++++++++ src/Etterna/Actor/Gameplay/PlayerPractice.h | 30 +++++++ src/Etterna/Models/Misc/PlayerInfo.cpp | 3 + 4 files changed, 119 insertions(+) create mode 100644 src/Etterna/Actor/Gameplay/PlayerPractice.cpp create mode 100644 src/Etterna/Actor/Gameplay/PlayerPractice.h diff --git a/src/Etterna/Actor/CMakeLists.txt b/src/Etterna/Actor/CMakeLists.txt index 519aefbebc..9b417a8e13 100644 --- a/src/Etterna/Actor/CMakeLists.txt +++ b/src/Etterna/Actor/CMakeLists.txt @@ -46,6 +46,7 @@ list(APPEND ACTOR_GAMEPLAY_SRC "Gameplay/NoteDisplay.cpp" "Gameplay/NoteField.cpp" "Gameplay/Player.cpp" + "Gameplay/PlayerPractice.cpp" "Gameplay/PlayerReplay.cpp" "Gameplay/ReceptorArrow.cpp" "Gameplay/ReceptorArrowRow.cpp") @@ -63,6 +64,7 @@ list(APPEND ACTOR_GAMEPLAY_HPP "Gameplay/NoteDisplay.h" "Gameplay/NoteField.h" "Gameplay/Player.h" + "Gameplay/PlayerPractice.h" "Gameplay/PlayerReplay.h" "Gameplay/ReceptorArrow.h" "Gameplay/ReceptorArrowRow.h") diff --git a/src/Etterna/Actor/Gameplay/PlayerPractice.cpp b/src/Etterna/Actor/Gameplay/PlayerPractice.cpp new file mode 100644 index 0000000000..f6a3c5532d --- /dev/null +++ b/src/Etterna/Actor/Gameplay/PlayerPractice.cpp @@ -0,0 +1,84 @@ +#include "Etterna/Globals/global.h" +#include "Etterna/Models/Misc/PlayerAI.h" +#include "Etterna/Models/Misc/PlayerState.h" +#include "ArrowEffects.h" +#include "NoteField.h" +#include "Etterna/Models/Misc/AdjustSync.h" +#include "Etterna/Models/Misc/Game.h" +#include "Etterna/Models/NoteData/NoteDataWithScoring.h" +#include "Etterna/Models/ScoreKeepers/ScoreKeeperNormal.h" +#include "Etterna/Singletons/GameState.h" +#include "Etterna/Singletons/NoteSkinManager.h" +#include "Etterna/Singletons/StatsManager.h" +#include "Etterna/Singletons/ScreenManager.h" +#include "Etterna/Singletons/ThemeManager.h" +#include "Etterna/Models/Misc/ThemeMetric.h" +#include "RageUtil/Utils/RageUtil.h" +#include "PlayerPractice.h" + +PlayerPractice::PlayerPractice(NoteData& nd, bool bVisibleParts) + : Player(nd, bVisibleParts) +{ + // eh +} + +PlayerPractice::~PlayerPractice() +{ + // dont have to do anything here +} + +void +PlayerPractice::Init(const std::string& sType, + PlayerState* pPlayerState, + PlayerStageStats* pPlayerStageStats, + LifeMeter* pLM, + ScoreKeeper* pPrimaryScoreKeeper) +{ + Player::Init( + sType, pPlayerState, pPlayerStageStats, pLM, pPrimaryScoreKeeper); + if (m_pPlayerStageStats) + m_pPlayerStageStats->m_bDisqualified = true; +} + +void +PlayerPractice::Update(float fDeltaTime) +{ + const auto now = std::chrono::steady_clock::now(); + if (!m_bLoaded || GAMESTATE->m_pCurSong == NULL) + return; + + ActorFrame::Update(fDeltaTime); + + const float fSongBeat = m_pPlayerState->m_Position.m_fSongBeat; + const int iSongRow = BeatToNoteRow(fSongBeat); + + ArrowEffects::SetCurrentOptions( + &m_pPlayerState->m_PlayerOptions.GetCurrent()); + + UpdateVisibleParts(); + + // Sure, why not? + if (GAMESTATE->GetPaused()) + return; + + // Tell the NoteField we pressed (or didnt press) certain columns + UpdatePressedFlags(); + + // Tell Rolls to update (if in Autoplay) + // Tell Holds to update (lose life) + UpdateHoldsAndRolls(fDeltaTime, now); + + // A lot of logic... basically everything not listed here + UpdateCrossedRows(now); + + // Check for completely judged rows. + UpdateJudgedRows(fDeltaTime); + UpdateTapNotesMissedOlderThan(GetMaxStepDistanceSeconds()); +} + +void +PlayerPractice::PositionReset() +{ + // Reset stage stats and stuff + countStats = false; +} diff --git a/src/Etterna/Actor/Gameplay/PlayerPractice.h b/src/Etterna/Actor/Gameplay/PlayerPractice.h new file mode 100644 index 0000000000..6187e795e6 --- /dev/null +++ b/src/Etterna/Actor/Gameplay/PlayerPractice.h @@ -0,0 +1,30 @@ +#ifndef PlayerPractice_H +#define PlayerPractice_H + +#include "Player.h" + +// Player derivative meant to ignore useless stuff +class PlayerPractice : public Player +{ + public: + PlayerPractice(NoteData& nd, bool bVisibleParts = true); + ~PlayerPractice() override; + + void Init(const std::string& sType, + PlayerState* pPlayerState, + PlayerStageStats* pPlayerStageStats, + LifeMeter* pLM, + ScoreKeeper* pPrimaryScoreKeeper) override; + void Update(float fDeltaTime) override; + + // When called, resets stage stats and necessary things + // Also sets countStats to false. + void PositionReset(); + + private: + // Becomes true immediately on first button press. + // Allows notes to pass without counting for anything. + bool countStats = false; +}; + +#endif diff --git a/src/Etterna/Models/Misc/PlayerInfo.cpp b/src/Etterna/Models/Misc/PlayerInfo.cpp index 5e3429e07d..65a26f6f51 100644 --- a/src/Etterna/Models/Misc/PlayerInfo.cpp +++ b/src/Etterna/Models/Misc/PlayerInfo.cpp @@ -8,6 +8,7 @@ #include "PlayerStageStats.h" #include "Etterna/Models/ScoreKeepers/ScoreKeeper.h" #include "Etterna/Actor/Gameplay/Player.h" +#include "Etterna/Actor/Gameplay/PlayerPractice.h" #include "Etterna/Actor/Gameplay/PlayerReplay.h" #include "Etterna/Actor/Gameplay/LifeMeter.h" @@ -64,6 +65,8 @@ PlayerInfo::Load(PlayerNumber pn, m_ptextPlayerOptions = NULL; if (mode == GameplayMode_Replay) { m_pPlayer = new PlayerReplay(m_NoteData, bShowNoteField); + } else if (mode == GameplayMode_Practice) { + m_pPlayer = new PlayerPractice(m_NoteData, bShowNoteField); } else { m_pPlayer = new Player(m_NoteData, bShowNoteField); }