From 7104026f2e2e3c8b8d57b05c0822944aa2c2e4f8 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Sun, 3 Dec 2023 02:06:57 +0100 Subject: [PATCH] Tuning: added "kill switch" cvar `sim_tuning_enabled` (bool) --- source/main/Application.cpp | 1 + source/main/Application.h | 1 + source/main/GameContext.cpp | 45 ++++++++++++---------- source/main/gui/GUIUtils.cpp | 4 +- source/main/gui/GUIUtils.h | 2 +- source/main/gui/panels/GUI_TopMenubar.cpp | 47 ++++++++++++++++++----- source/main/resources/CacheSystem.h | 7 ++++ source/main/system/CVar.cpp | 3 +- 8 files changed, 76 insertions(+), 34 deletions(-) diff --git a/source/main/Application.cpp b/source/main/Application.cpp index 6d8689d909..07f97371c1 100644 --- a/source/main/Application.cpp +++ b/source/main/Application.cpp @@ -109,6 +109,7 @@ CVar* sim_gearbox_mode; CVar* sim_soft_reset_mode; CVar* sim_quickload_dialog; CVar* sim_live_repair_interval; +CVar* sim_tuning_enabled; // Multiplayer CVar* mp_state; diff --git a/source/main/Application.h b/source/main/Application.h index 44f1a8cc70..c80d34fe0f 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -319,6 +319,7 @@ extern CVar* sim_gearbox_mode; extern CVar* sim_soft_reset_mode; extern CVar* sim_quickload_dialog; extern CVar* sim_live_repair_interval; //!< Hold EV_COMMON_REPAIR_TRUCK to enter LiveRepair mode. 0 or negative interval disables. +extern CVar* sim_tuning_enabled; // Multiplayer extern CVar* mp_state; diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index d315c07dbc..b3b6aebbbf 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -192,30 +192,33 @@ ActorPtr GameContext::SpawnActor(ActorSpawnRequest& rq) m_last_section_config = rq.asr_config; // Make sure the actor has a default .tuneup project assigned. If not, create it. - CacheQuery query; - query.cqy_filter_type = LT_Tuneup; - query.cqy_filter_category_id = CID_TuneupsAuto; - query.cqy_filter_guid = rq.asr_cache_entry->guid; - if (App::GetCacheSystem()->Query(query) > 0) + if (App::sim_tuning_enabled->getBool()) { - rq.asr_tuneup_entry = query.cqy_results[0].cqr_entry; - } - else - { - CreateProjectRequest req; - req.cpr_type = CreateProjectRequestType::CREATE_TUNEUP; - req.cpr_source_entry = rq.asr_cache_entry; - req.cpr_name = fmt::format("tuned_{}", rq.asr_cache_entry->fname); - req.cpr_description = fmt::format("Customized {}", rq.asr_cache_entry->dname); + CacheQuery query; + query.cqy_filter_type = LT_Tuneup; + query.cqy_filter_category_id = CID_TuneupsAuto; + query.cqy_filter_guid = rq.asr_cache_entry->guid; + if (App::GetCacheSystem()->Query(query) > 0) + { + rq.asr_tuneup_entry = query.cqy_results[0].cqr_entry; + } + else + { + CreateProjectRequest req; + req.cpr_type = CreateProjectRequestType::CREATE_TUNEUP; + req.cpr_source_entry = rq.asr_cache_entry; + req.cpr_name = fmt::format("tuned_{}", rq.asr_cache_entry->fname); + req.cpr_description = fmt::format("Customized {}", rq.asr_cache_entry->dname); - rq.asr_tuneup_entry = App::GetCacheSystem()->CreateProject(&req); // Do it synchronously + rq.asr_tuneup_entry = App::GetCacheSystem()->CreateProject(&req); // Do it synchronously - if (!rq.asr_tuneup_entry) - { - Str<500> msg; msg <<"Cannot spawn actor; .tuneup project could not be created."; - App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_ACTOR, Console::CONSOLE_SYSTEM_ERROR, msg.ToCStr()); - return nullptr; - } + if (!rq.asr_tuneup_entry) + { + Str<500> msg; msg <<"Cannot spawn actor; .tuneup project could not be created."; + App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_ACTOR, Console::CONSOLE_SYSTEM_ERROR, msg.ToCStr()); + return nullptr; + } + } } if (rq.asr_spawnbox == nullptr) diff --git a/source/main/gui/GUIUtils.cpp b/source/main/gui/GUIUtils.cpp index 1e6cc96724..be595a539a 100644 --- a/source/main/gui/GUIUtils.cpp +++ b/source/main/gui/GUIUtils.cpp @@ -257,13 +257,15 @@ void RoR::ImTextWrappedColorMarked(std::string const& text) ImGui::ItemAdd(bb, 0); } -void RoR::DrawGCheckbox(CVar* cvar, const char* label) +bool RoR::DrawGCheckbox(CVar* cvar, const char* label) { bool val = cvar->getBool(); if (ImGui::Checkbox(label, &val)) { cvar->setVal(val); + return true; } + return false; } void RoR::DrawGIntCheck(CVar* cvar, const char* label) diff --git a/source/main/gui/GUIUtils.h b/source/main/gui/GUIUtils.h index 74822b2c9d..5db2382d79 100644 --- a/source/main/gui/GUIUtils.h +++ b/source/main/gui/GUIUtils.h @@ -56,7 +56,7 @@ std::string StripColorMarksFromText(std::string const& text); /// Prints multiline text with '#rrggbb' color markers. Behaves like `ImGui::Text*` functions. void ImTextWrappedColorMarked(std::string const& text); -void DrawGCheckbox(CVar* cvar, const char* label); +bool DrawGCheckbox(CVar* cvar, const char* label); void DrawGIntCheck(CVar* cvar, const char* label); diff --git a/source/main/gui/panels/GUI_TopMenubar.cpp b/source/main/gui/panels/GUI_TopMenubar.cpp index 66e1b91f85..2e16eec831 100644 --- a/source/main/gui/panels/GUI_TopMenubar.cpp +++ b/source/main/gui/panels/GUI_TopMenubar.cpp @@ -1450,12 +1450,34 @@ void TopMenubar::Draw(float dt) { ROR_ASSERT(tuning_actor->getUsedActorEntry()); CacheEntryPtr& tuneup_entry = tuning_actor->getUsedTuneupEntry(); - ROR_ASSERT(tuneup_entry); // Created by `GameContext::SpawnActor()` - ROR_ASSERT(tuneup_entry->resource_group != ""); - ROR_ASSERT(tuneup_entry->tuneup_def != nullptr); + if (tuneup_entry) + { + ROR_ASSERT(tuneup_entry->resource_group != ""); + ROR_ASSERT(tuneup_entry->tuneup_def != nullptr); + } - // SAVED TUNEUPS + // KILL SWITCH + if (DrawGCheckbox(App::sim_tuning_enabled, _LC("Tuning", "Enable tuning"))) + { + // Create spawn request while actor still exists + // Note we don't use `ActorModifyRequest::Type::RELOAD` because we don't need the bundle reloaded. + ActorSpawnRequest* srq = new ActorSpawnRequest; + srq->asr_position = Ogre::Vector3(tuning_actor->getPosition().x, tuning_actor->getMinHeight(), tuning_actor->getPosition().z); + srq->asr_rotation = Ogre::Quaternion(Ogre::Degree(270) - Ogre::Radian(tuning_actor->getRotation()), Ogre::Vector3::UNIT_Y); + srq->asr_config = tuning_actor->getSectionConfig(); + srq->asr_skin_entry = tuning_actor->getUsedSkinEntry(); + srq->asr_cache_entry = tuning_actor->getUsedActorEntry(); + srq->asr_debugview = (int)tuning_actor->GetGfxActor()->GetDebugView(); + srq->asr_origin = ActorSpawnRequest::Origin::USER; + + // Request actor delete and chain the actor spawn message to it. + App::GetGameContext()->ChainMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, new ActorPtr(tuning_actor))); + App::GetGameContext()->ChainMessage(Message(MSG_SIM_SPAWN_ACTOR_REQUESTED, srq)); + } + + // SAVED TUNEUPS + ImGui::Separator(); ImGui::TextDisabled(fmt::format(_LC("Tuning", "Saved tuneups ({})"), tuning_saves.cqy_results.size()).c_str()); for (CacheQueryResult& tuneup_result: tuning_saves.cqy_results) { @@ -1627,7 +1649,7 @@ void TopMenubar::Draw(float dt) // Draw props size_t total_props = tuning_actor->GetGfxActor()->getProps().size(); std::string props_title = fmt::format(_LC("TopMenubar", "Props ({})"), total_props); - if (ImGui::CollapsingHeader(props_title.c_str())) + if (ImGui::CollapsingHeader(props_title.c_str()) && tuneup_entry) { // Draw all props (those removed by addonparts are also present as placeholders) for (Prop const& p: tuning_actor->GetGfxActor()->getProps()) @@ -1688,7 +1710,7 @@ void TopMenubar::Draw(float dt) // Ditto for flexbodies size_t total_flexbodies = tuning_actor->GetGfxActor()->GetFlexbodies().size(); std::string flexbodies_title = fmt::format(_LC("TopMenubar", "Flexbodies ({})"), total_flexbodies); - if (ImGui::CollapsingHeader(flexbodies_title.c_str())) + if (ImGui::CollapsingHeader(flexbodies_title.c_str()) && tuneup_entry) { // Draw all flexbodies (those removed by addonparts are also present as placeholders) for (FlexBody* flexbody: tuning_actor->GetGfxActor()->GetFlexbodies()) @@ -1725,7 +1747,7 @@ void TopMenubar::Draw(float dt) // Draw wheels const int total_wheels = tuning_actor->ar_num_wheels; std::string wheels_title = fmt::format(_LC("TopMenubar", "Wheels ({})"), total_wheels); - if (ImGui::CollapsingHeader(wheels_title.c_str())) + if (ImGui::CollapsingHeader(wheels_title.c_str()) && tuneup_entry) { for (WheelID_t i = 0; i < total_wheels; i++) { @@ -2229,23 +2251,28 @@ void TopMenubar::GetPresets() void TopMenubar::RefreshTuningMenu() { const ActorPtr& current_actor = App::GetGameContext()->GetPlayerActor(); - if (current_actor && (tuning_actor != current_actor || tuning_force_refresh)) + if (App::sim_tuning_enabled->getBool() && current_actor && (tuning_actor != current_actor || tuning_force_refresh)) { ROR_ASSERT(current_actor->getUsedActorEntry()); tuning_addonparts.cqy_filter_type = LT_AddonPart; tuning_addonparts.cqy_filter_guid = current_actor->getUsedActorEntry()->guid; - tuning_addonparts.cqy_results.clear(); + tuning_addonparts.resetResults(); App::GetCacheSystem()->Query(tuning_addonparts); tuning_saves.cqy_filter_type = LT_Tuneup; tuning_saves.cqy_filter_guid = current_actor->getUsedActorEntry()->guid; tuning_saves.cqy_filter_category_id = CID_TuneupsUser; // Exclude auto-generated entries - tuning_saves.cqy_results.clear(); + tuning_saves.resetResults(); App::GetCacheSystem()->Query(tuning_saves); tuning_rwidget_cursorx_min = 0.f; } + else if (!App::sim_tuning_enabled->getBool()) + { + tuning_addonparts.resetResults(); + tuning_saves.resetResults(); + } tuning_actor = current_actor; } diff --git a/source/main/resources/CacheSystem.h b/source/main/resources/CacheSystem.h index 315a8fd059..0789d0093c 100644 --- a/source/main/resources/CacheSystem.h +++ b/source/main/resources/CacheSystem.h @@ -181,6 +181,13 @@ struct CacheQuery std::vector cqy_results; std::map cqy_res_category_usage; //!< Total usage (ignores search params + category filter) std::time_t cqy_res_last_update = std::time_t(); + + void resetResults() + { + cqy_results.clear(); + cqy_res_category_usage.clear(); + cqy_res_last_update = std::time_t(); + } }; enum class CacheValidity diff --git a/source/main/system/CVar.cpp b/source/main/system/CVar.cpp index 93cf1dec55..19bf9b6703 100644 --- a/source/main/system/CVar.cpp +++ b/source/main/system/CVar.cpp @@ -58,7 +58,8 @@ void Console::cVarSetupBuiltins() App::sim_gearbox_mode = this->cVarCreate("sim_gearbox_mode", "GearboxMode", CVAR_ARCHIVE | CVAR_TYPE_INT); App::sim_soft_reset_mode = this->cVarCreate("sim_soft_reset_mode", "", CVAR_TYPE_BOOL, "false"); App::sim_quickload_dialog = this->cVarCreate("sim_quickload_dialog", "", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "true"); - App::sim_live_repair_interval = this->cVarCreate("sim_live_repair_interval", "", CVAR_ARCHIVE | CVAR_TYPE_FLOAT, "2.f"); + App::sim_live_repair_interval = this->cVarCreate("sim_live_repair_interval", "", CVAR_ARCHIVE | CVAR_TYPE_FLOAT, "2.f"); + App::sim_tuning_enabled = this->cVarCreate("sim_tuning_enabled", "", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "false"); App::mp_state = this->cVarCreate("mp_state", "", CVAR_TYPE_INT, "0"/*(int)MpState::DISABLED*/); App::mp_join_on_startup = this->cVarCreate("mp_join_on_startup", "Auto connect", CVAR_ARCHIVE | CVAR_TYPE_BOOL, "false");