RigsofRods
Soft-body Physics Simulation
GUI_TopMenubar.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2005-2012 Pierre-Michel Ricordel
4  Copyright 2007-2012 Thomas Fischer
5  Copyright 2016-2020 Petr Ohlidal
6 
7  For more information, see http://www.rigsofrods.org/
8 
9  Rigs of Rods is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License version 3, as
11  published by the Free Software Foundation.
12 
13  Rigs of Rods is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
25 
26 #include "GUI_TopMenubar.h"
27 
28 #include "Application.h"
29 #include "Actor.h"
30 #include "ActorManager.h"
31 #include "CameraManager.h"
32 #include "DashBoardManager.h"
33 #include "FlexBody.h"
34 #include "GameContext.h"
35 #include "GfxScene.h"
36 #include "GUIManager.h"
37 #include "GUIUtils.h"
38 #include "GUI_MainSelector.h"
39 #include "InputEngine.h"
40 #include "Language.h"
41 #include "Network.h"
42 #include "PlatformUtils.h"
43 #include "Replay.h"
44 #include "SkyManager.h"
45 #include "Terrain.h"
46 #include "TuneupFileFormat.h"
47 #include "Water.h"
48 #include "ScriptEngine.h"
49 #include "Console.h"
50 #include "ContentManager.h"
51 
52 #include <algorithm>
53 #include <fmt/format.h>
54 
55 
56 #ifdef USE_CURL
57 # include <curl/curl.h>
58 # include <curl/easy.h>
59 #endif //USE_CURL
60 
61 #if defined(_MSC_VER) && defined(GetObject) // This MS Windows macro from <wingdi.h> (Windows Kit 8.1) clashes with RapidJSON
62 # undef GetObject
63 #endif
64 
65 using namespace RoR;
66 using namespace GUI;
67 
68 #if defined(USE_CURL)
69 
70 static size_t CurlWriteFunc(void *ptr, size_t size, size_t nmemb, std::string* data)
71 {
72  data->append((char*)ptr, size * nmemb);
73  return size * nmemb;
74 }
75 
77 {
78  // If local file 'savegames/waypoints.json' exists, load it; otherwise download from GitHub.
79  // -----------------------------------------------------------------------------------------
80 
81  if (FileExists(PathCombine(App::sys_savegames_dir->getStr(), "waypoints.json")))
82  {
83  try
84  {
85  Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource("waypoints.json", RGN_SAVEGAMES);
87  m.description = stream->getAsString();
89  }
90  catch (...)
91  {
92  RoR::HandleGenericException("Top menubar / AI presets");
94  m.description = "Failed to load local AI presets.";
96  }
97 
98  return; // DONE
99  }
100 
101  std::string url = "https://raw.githubusercontent.com/RigsOfRods-Community/ai-waypoints/main/waypoints.json";
102  std::string response_payload;
103  long response_code = 0;
104 
105  CURL *curl = curl_easy_init();
106  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
107  curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
108 #ifdef _WIN32
109  curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
110 #endif // _WIN32
111  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlWriteFunc);
112  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_payload);
113 
114  CURLcode curl_result = curl_easy_perform(curl);
115  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
116 
117  curl_easy_cleanup(curl);
118  curl = nullptr;
119 
120  if (curl_result != CURLE_OK || response_code != 200)
121  {
122  Ogre::LogManager::getSingleton().stream()
123  << "[RoR|Repository] Failed to download AI presets;"
124  << " Error: '" << curl_easy_strerror(curl_result) << "'; HTTP status code: " << response_code;
126  m.description = "Failed to download AI presets.";
128  }
129  else
130  {
132  m.description = response_payload;
134  }
135 }
136 
137 #endif // defined(USE_CURL)
138 
140 {
141  // Constructs `ActorPtr` - doesn't compile without `#include Actor.h` - not pretty if in header (even if auto-generated by C++).
142 
143  ai_presets_all.SetArray();
144  ai_presets_bundled.SetArray();
145  ai_presets_extern.SetArray();
146 }
147 
149 {
150  // Destructs `ActorPtr` - doesn't compile without `#include Actor.h` - not pretty if in header (even if auto-generated by C++).
151 }
152 
153 void TopMenubar::Draw(float dt)
154 {
155  // ## ImGui's 'menubar' and 'menuitem' features won't quite cut it...
156  // ## Let's do our own menus and menuitems using buttons and coloring tricks.
157 
159 
160  int num_playable_actors = 0;
161  for (ActorPtr& actor: App::GetGameContext()->GetActorManager()->GetActors())
162  {
163  if (!actor->ar_hide_in_actor_list)
164  {
165  num_playable_actors++;
166  }
167  }
168 
169  std::string sim_title = _LC("TopMenubar", "Simulation");
170  std::string actors_title = fmt::format("{} ({})", _LC("TopMenubar", "Vehicles"), num_playable_actors);
171  std::string savegames_title = _LC("TopMenubar", "Saves");
172  std::string settings_title = _LC("TopMenubar", "Settings");
173  std::string tools_title = _LC("TopMenubar", "Tools");
174  std::string ai_title = _LC("TopMenubar", "Vehicle AI");
175  std::string tuning_title = _LC("TopMenubar", "Tuning");
176 
177  int menubar_num_buttons = 5;
178  float menubar_content_width =
179  ImGui::CalcTextSize(sim_title.c_str()).x +
180  ImGui::CalcTextSize(actors_title.c_str()).x +
181  ImGui::CalcTextSize(savegames_title.c_str()).x +
182  ImGui::CalcTextSize(settings_title.c_str()).x +
183  ImGui::CalcTextSize(tools_title.c_str()).x;
184 
186  {
187  menubar_num_buttons += 1;
188  menubar_content_width += ImGui::CalcTextSize(ai_title.c_str()).x;
189  }
190 
192  {
193  menubar_num_buttons += 1;
194  menubar_content_width += ImGui::CalcTextSize(tuning_title.c_str()).x;
195  }
196 
197  menubar_content_width +=
198  (ImGui::GetStyle().ItemSpacing.x * (menubar_num_buttons - 1)) +
199  (ImGui::GetStyle().FramePadding.x * (menubar_num_buttons * 2));
200 
201  ImVec2 window_target_pos = ImVec2((ImGui::GetIO().DisplaySize.x/2.f) - (menubar_content_width / 2.f), theme.screen_edge_padding.y);
202  if (!this->ShouldDisplay(window_target_pos))
203  {
205  m_confirm_remove_all = false;
206  this->DrawSpecialStateBox(10.f);
207  return;
208  }
209 
210  ImGui::PushStyleColor(ImGuiCol_WindowBg, theme.semitransparent_window_bg);
211  ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0,0,0,0)); // Fully transparent
212 
213  // The panel
214  int flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove
215  | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize;
216  ImGui::SetNextWindowContentSize(ImVec2(menubar_content_width, 0.f));
217  ImGui::SetNextWindowPos(window_target_pos);
218  ImGui::Begin("Top menubar", nullptr, flags);
219 
220  if (ImGui::IsWindowHovered())
221  {
222  ai_menu = false;
223  }
224 
225  // The 'simulation' button
226  ImVec2 window_pos = ImGui::GetWindowPos();
227  ImVec2 sim_cursor = ImGui::GetCursorPos();
228  ImGui::Button(sim_title.c_str());
229  if ((m_open_menu != TopMenu::TOPMENU_SIM) && ImGui::IsItemHovered())
230  {
232  }
233 
234  // The 'Tuning' button - only shown if enabled
235  ImVec2 tuning_cursor = ImVec2(0, 0);
237  {
238  ImGui::SameLine();
239  tuning_cursor = ImGui::GetCursorPos();
240  ImGui::Button(tuning_title.c_str());
241  if ((m_open_menu != TopMenu::TOPMENU_TUNING) && ImGui::IsItemHovered())
242  {
244  }
245  }
246 
247  // The 'AI' button - only shown in singleplayer
248  ImVec2 ai_cursor = ImVec2(0, 0);
250  {
251  ImGui::SameLine();
252  ai_cursor = ImGui::GetCursorPos();
253  ImGui::Button(ai_title.c_str());
254  if ((m_open_menu != TopMenu::TOPMENU_AI) && ImGui::IsItemHovered())
255  {
257  }
258  }
259 
260  ImGui::SameLine();
261 
262  // The 'vehicles' button
263  ImVec2 actors_cursor = ImGui::GetCursorPos();
264  ImGui::Button(actors_title.c_str());
265  if ((m_open_menu != TopMenu::TOPMENU_ACTORS) && ImGui::IsItemHovered())
266  {
268  }
269 
270  ImGui::SameLine();
271 
272  // The 'savegames' button
273  ImVec2 savegames_cursor = ImGui::GetCursorPos();
274  ImGui::Button(savegames_title.c_str());
275  if ((m_open_menu != TopMenu::TOPMENU_SAVEGAMES) && ImGui::IsItemHovered())
276  {
280  m_savegame_names.clear();
281  for (int i = 0; i <= 9; i++)
282  {
283  Ogre::String filename = Ogre::StringUtil::format("quicksave-%d.sav", i);
284  m_savegame_names.push_back(App::GetGameContext()->ExtractSceneName(filename));
285  }
286  }
287 
288  ImGui::SameLine();
289 
290  // The 'settings' button
291  ImVec2 settings_cursor = ImGui::GetCursorPos();
292  ImGui::Button(settings_title.c_str());
293  if ((m_open_menu != TopMenu::TOPMENU_SETTINGS) && ImGui::IsItemHovered())
294  {
296 #ifdef USE_CAELUM
297  if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::CAELUM)
299 #endif // USE_CAELUM
300  }
301 
302  ImGui::SameLine();
303 
304  // The 'tools' button
305  ImVec2 tools_cursor = ImGui::GetCursorPos();
306  ImGui::Button(tools_title.c_str());
307  if ((m_open_menu != TopMenu::TOPMENU_TOOLS) && ImGui::IsItemHovered())
308  {
310  }
311 
312  ImVec2 topmenu_final_size = ImGui::GetWindowSize();
313  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
314  ImGui::End();
315 
316  this->DrawSpecialStateBox(window_target_pos.y + topmenu_final_size.y + 10.f);
317 
318  ImVec2 menu_pos;
319  ActorPtr current_actor = App::GetGameContext()->GetPlayerActor();
320  switch (m_open_menu)
321  {
323  menu_pos.y = window_pos.y + sim_cursor.y + MENU_Y_OFFSET;
324  menu_pos.x = sim_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
325  ImGui::SetNextWindowPos(menu_pos);
326  if (ImGui::Begin(_LC("TopMenubar", "Sim menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
327  {
328  // TODO: Display hotkeys on the right side of the menu (with different text color)
329 
330  if (ImGui::Button(_LC("TopMenubar", "Get new vehicle")))
331  {
333 
335  m.payload = reinterpret_cast<void*>(new LoaderType(LT_AllBeam));
337  }
338 
339  if (current_actor != nullptr)
340  {
341  if (ImGui::Button(_LC("TopMenubar", "Show vehicle description")))
342  {
344  }
345 
346  if (current_actor->ar_state != ActorState::NETWORKED_OK)
347  {
348  if (ImGui::Button(_LC("TopMenubar", "Reload current vehicle")))
349  {
352  rq->amr_actor = current_actor->ar_instance_id;
354  }
355 
356  if (ImGui::Button(_LC("TopMenubar", "Remove current vehicle")))
357  {
358  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(current_actor))));
359  }
360  }
361  }
362  else if (App::GetGameContext()->GetLastSpawnedActor())
363  {
364  if (ImGui::Button(_LC("TopMenubar", "Activate last spawned vehicle")))
365  {
368  rq->amr_actor = App::GetGameContext()->GetLastSpawnedActor()->ar_instance_id;
370  }
371 
372  if (ImGui::Button(_LC("TopMenubar", "Reload last spawned vehicle")))
373  {
376  rq->amr_actor = App::GetGameContext()->GetLastSpawnedActor()->ar_instance_id;
378  }
379 
380  if (ImGui::Button(_LC("TopMenubar", "Remove last spawned vehicle")))
381  {
382  ActorPtr actor = App::GetGameContext()->GetLastSpawnedActor();
384  }
385  }
386 
387  if (!App::GetGameContext()->GetActorManager()->GetLocalActors().empty())
388  {
389  if (ImGui::Button(_LC("TopMenubar", "Remove all vehicles")))
390  {
391  m_confirm_remove_all = true;
392  }
394  {
395  ImGui::PushStyleColor(ImGuiCol_Text, ORANGE_TEXT);
396  if (ImGui::Button(_LC("TopMenubar", " [!] Confirm removal")))
397  {
398  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetLocalActors())
399  {
400  if (!actor->ar_hide_in_actor_list && !actor->isPreloadedWithTerrain() &&
401  actor->ar_state != ActorState::NETWORKED_OK)
402  {
404  }
405  }
406  m_confirm_remove_all = false;
407  }
408  ImGui::PopStyleColor();
409  }
410 
411  if (ImGui::Button(_LC("TopMenubar", "Activate all vehicles")))
412  {
414  }
415 
416  bool force_trucks_active = App::GetGameContext()->GetActorManager()->AreTrucksForcedAwake();
417  if (ImGui::Checkbox(_LC("TopMenubar", "Activated vehicles never sleep"), &force_trucks_active))
418  {
419  App::GetGameContext()->GetActorManager()->SetTrucksForcedAwake(force_trucks_active);
420  }
421 
422  if (ImGui::Button(_LC("TopMenubar", "Send all vehicles to sleep")))
423  {
425  }
426  }
427 
428  if (App::mp_state->getEnum<MpState>() != MpState::CONNECTED)
429  {
430  if (ImGui::Button(_LC("TopMenubar", "Reload current terrain")))
431  {
433  // Order is required - create chain.
435  new CacheEntryPtr(App::GetGameContext()->GetTerrain()->getCacheEntry())));
437  App::GetGameContext()->GetTerrain()->getCacheEntry()->fname));
438  }
439  }
440 
441  ImGui::Separator();
442 
443  if (ImGui::Button(_LC("TopMenubar", "Back to menu")))
444  {
445  if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
446  {
448  }
451  }
452 
453  if (ImGui::Button(_LC("TopMenubar", "Exit")))
454  {
456  }
457 
459  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
460  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
461  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
462  ImGui::End();
463  }
464  break;
465 
467  menu_pos.y = window_pos.y + actors_cursor.y + MENU_Y_OFFSET;
468  menu_pos.x = actors_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
469  ImGui::SetNextWindowPos(menu_pos);
470  if (ImGui::Begin(_LC("TopMenubar", "Actors menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
471  {
472  if (App::mp_state->getEnum<MpState>() != MpState::CONNECTED)
473  {
475  }
476  else
477  {
478 #ifdef USE_SOCKETW
480  this->DrawMpUserToActorList(net_user_info);
481 
482  std::vector<RoRnet::UserInfo> remote_users = App::GetNetwork()->GetUserInfos();
483  for (auto& user: remote_users)
484  {
485  this->DrawMpUserToActorList(user);
486  }
487 #endif // USE_SOCKETW
488  }
490  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
491  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
492  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
493  ImGui::End();
494  }
495  break;
496 
498  menu_pos.y = window_pos.y + savegames_cursor.y + MENU_Y_OFFSET;
499  menu_pos.x = savegames_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
500  ImGui::SetNextWindowPos(menu_pos);
501  if (ImGui::Begin(_LC("TopMenubar", "Savegames"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
502  {
503  if (ImGui::Button(_LC("TopMenubar", "Quicksave")))
504  {
507  }
508  ImGui::SameLine();
509  ImGui::TextColored(GRAY_HINT_TEXT, "(NUMPAD: /)");
510 
511  if (m_quickload)
512  {
513  if (ImGui::Button(_LC("TopMenubar", "Quickload")))
514  {
517  }
518  ImGui::SameLine();
519  ImGui::TextColored(GRAY_HINT_TEXT, "(NUMPAD: *)");
520  }
521 
522  ImGui::Separator();
523 
524  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "(Save with CTRL+ALT+1..5)"));
525  for (int i = 1; i <= 5; i++)
526  {
527  Ogre::String name = _LC("TopMenubar", "Empty Slot");
528  if (!m_savegame_names[i].empty())
529  {
530  name = m_savegame_names[i];
531  }
532  Ogre::String caption = Ogre::StringUtil::format("%d. %s##Save", i, name.c_str());
533  if (ImGui::Button(caption.c_str()))
534  {
535  Ogre::String filename = Ogre::StringUtil::format("quicksave-%d.sav", i);
538  }
539  }
540 
541  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "(Load with ALT+1..5)"));
542  for (int i = 1; i <= 5; i++)
543  {
544  if (!m_savegame_names[i].empty())
545  {
546  Ogre::String name = m_savegame_names[i];
547  Ogre::String caption = Ogre::StringUtil::format("%d. %s##Load", i, name.c_str());
548  if (ImGui::Button(caption.c_str()))
549  {
550  Ogre::String filename = Ogre::StringUtil::format("quicksave-%d.sav", i);
553  }
554  }
555  }
556 
558  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
559  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
560  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
561  ImGui::End();
562  }
563  break;
564 
566  menu_pos.y = window_pos.y + settings_cursor.y + MENU_Y_OFFSET;
567  menu_pos.x = settings_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
568  ImGui::SetNextWindowPos(menu_pos);
569  if (ImGui::Begin(_LC("TopMenubar", "Settings menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
570  {
571  ImGui::PushItemWidth(125.f); // Width includes [+/-] buttons
572  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Audio:"));
573  DrawGFloatSlider(App::audio_master_volume, _LC("TopMenubar", "Volume"), 0, 1);
574  ImGui::Separator();
575  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Frames per second:"));
576  if (App::gfx_envmap_enabled->getBool())
577  {
578  DrawGIntSlider(App::gfx_envmap_rate, _LC("TopMenubar", "Reflections"), 0, 6);
579  }
580  DrawGIntSlider(App::gfx_fps_limit, _LC("TopMenubar", "Game"), 0, 240);
581 
582  ImGui::Separator();
583  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Simulation:"));
584  float slowmotion = std::min(App::GetGameContext()->GetActorManager()->GetSimulationSpeed(), 1.0f);
585  if (ImGui::SliderFloat(_LC("TopMenubar", "Slow motion"), &slowmotion, 0.01f, 1.0f))
586  {
588  }
589  float timelapse = std::max(App::GetGameContext()->GetActorManager()->GetSimulationSpeed(), 1.0f);
590  if (ImGui::SliderFloat(_LC("TopMenubar", "Time lapse"), &timelapse, 1.0f, 10.0f))
591  {
593  }
594  if (App::GetCameraManager()->GetCurrentBehavior() == CameraManager::CAMERA_BEHAVIOR_STATIC)
595  {
596  ImGui::Separator();
597  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Camera:"));
598  DrawGFloatSlider(App::gfx_static_cam_fov_exp, _LC("TopMenubar", "FOV"), 0.8f, 1.5f);
599  DrawGIntSlider(App::gfx_camera_height, _LC("TopMenubar", "Height"), 1, 50);
600  }
601  else
602  {
603  ImGui::Separator();
604  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Camera:"));
606  {
607  int fov = App::gfx_fov_internal->getInt();
608  if (ImGui::SliderInt(_LC("TopMenubar", "FOV"), &fov, 10, 120))
609  {
611  }
612  }
613  else
614  {
615  int fov = App::gfx_fov_external->getInt();
616  if (ImGui::SliderInt(_LC("TopMenubar", "FOV"), &fov, 10, 120))
617  {
619  }
620  }
621  if (App::GetCameraManager()->GetCurrentBehavior() == CameraManager::CAMERA_BEHAVIOR_FIXED)
622  {
623  DrawGCheckbox(App::gfx_fixed_cam_tracking, _LC("TopMenubar", "Tracking"));
624  }
625  }
626 #ifdef USE_CAELUM
627  if (App::gfx_sky_mode->getEnum<GfxSkyMode>() == GfxSkyMode::CAELUM)
628  {
629  ImGui::Separator();
630  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Time of day:"));
631  float time = App::GetGameContext()->GetTerrain()->getSkyManager()->GetTime();
632  if (ImGui::SliderFloat("", &time, m_daytime - 0.5f, m_daytime + 0.5f, ""))
633  {
634  App::GetGameContext()->GetTerrain()->getSkyManager()->SetTime(time);
635  }
636  ImGui::SameLine();
637  DrawGCheckbox(App::gfx_sky_time_cycle, _LC("TopMenubar", "Cycle"));
638  if (App::gfx_sky_time_cycle->getBool())
639  {
640  DrawGIntSlider(App::gfx_sky_time_speed, _LC("TopMenubar", "Speed"), 10, 2000);
641  }
642  }
643 #endif // USE_CAELUM
644  if (RoR::App::gfx_water_waves->getBool() && App::mp_state->getEnum<MpState>() != MpState::CONNECTED && App::GetGameContext()->GetTerrain()->getWater())
645  {
646  if (App::gfx_water_mode->getEnum<GfxWaterMode>() != GfxWaterMode::HYDRAX && App::gfx_water_mode->getEnum<GfxWaterMode>() != GfxWaterMode::NONE)
647  {
648  ImGui::PushID("waves");
649  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Waves Height:"));
650  if(ImGui::SliderFloat("", &m_waves_height, 0.f, 4.f, ""))
651  {
653  }
654  ImGui::PopID();
655  }
656  }
657 
658  if (current_actor != nullptr)
659  {
660  ImGui::Separator();
661  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Vehicle control options:"));
662  DrawGCheckbox(App::io_hydro_coupling, _LC("TopMenubar", "Keyboard steering speed coupling"));
663  }
664  if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
665  {
666  ImGui::Separator();
667  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Multiplayer:"));
668  DrawGCheckbox(App::mp_pseudo_collisions, _LC("TopMenubar", "Collisions"));
669  DrawGCheckbox(App::mp_hide_net_labels, _LC("TopMenubar", "Hide labels"));
670  }
671  ImGui::PopItemWidth();
673  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
674  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
675  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
676  ImGui::End();
677  }
678  break;
679 
681  menu_pos.y = window_pos.y + tools_cursor.y + MENU_Y_OFFSET;
682  menu_pos.x = tools_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
683  ImGui::SetNextWindowPos(menu_pos);
684  if (ImGui::Begin(_LC("TopMenubar", "Tools menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
685  {
686  if (ImGui::Button(_LC("TopMenubar", "Friction settings")))
687  {
690  }
691 
692  if (ImGui::Button(_LC("TopMenubar", "Show console")))
693  {
696  }
697 
698  if (ImGui::Button(_LC("TopMenubar", "Texture tool")))
699  {
702  }
703 
704  if (ImGui::Button(_LC("TopMenubar", "Collisions debug")))
705  {
708  }
709 
710  if (current_actor != nullptr)
711  {
712  if (ImGui::Button(_LC("TopMenubar", "Node / Beam utility")))
713  {
716  }
717 
718  if (ImGui::Button(_LC("TopMenubar", "FlexBody debug")))
719  {
722  }
723  }
724 
725  ImGui::Separator();
726  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Pre-spawn diag. options:"));
727 
728  bool diag_mass = App::diag_truck_mass->getBool();
729  if (ImGui::Checkbox(_LC("TopMenubar", "Node mass recalc. logging"), &diag_mass))
730  {
731  App::diag_truck_mass->setVal(diag_mass);
732  }
733  if (ImGui::IsItemHovered())
734  {
735  ImGui::BeginTooltip();
736  ImGui::Text("%s", _LC("TopMenubar", "Extra logging on runtime - mass recalculation"));
737  ImGui::EndTooltip();
738  }
739 
740  bool diag_break = App::diag_log_beam_break->getBool();
741  if (ImGui::Checkbox(_LC("TopMenubar", "Beam break logging"), &diag_break))
742  {
743  App::diag_log_beam_break->setVal(diag_break);
744  }
745  if (ImGui::IsItemHovered())
746  {
747  ImGui::BeginTooltip();
748  ImGui::Text("%s", _LC("TopMenubar", "Extra logging on runtime"));
749  ImGui::EndTooltip();
750  }
751 
752  bool diag_deform = App::diag_log_beam_deform->getBool();
753  if (ImGui::Checkbox(_LC("TopMenubar", "Beam deform. logging"), &diag_deform))
754  {
755  App::diag_log_beam_deform->setVal(diag_deform);
756  }
757  if (ImGui::IsItemHovered())
758  {
759  ImGui::BeginTooltip();
760  ImGui::Text("%s", _LC("TopMenubar", "Extra logging on runtime"));
761  ImGui::EndTooltip();
762  }
763 
764  bool diag_trig = App::diag_log_beam_trigger->getBool();
765  if (ImGui::Checkbox(_LC("TopMenubar", "Trigger logging"), &diag_trig))
766  {
768  }
769  if (ImGui::IsItemHovered())
770  {
771  ImGui::BeginTooltip();
772  ImGui::Text("%s", _LC("TopMenubar", "Extra logging on runtime - trigger beams activity"));
773  ImGui::EndTooltip();
774  }
775 
776  bool diag_vcam = App::diag_videocameras->getBool();
777  if (ImGui::Checkbox(_LC("TopMenubar", "VideoCamera direction marker"), &diag_vcam))
778  {
779  App::diag_videocameras->setVal(diag_vcam);
780  }
781  if (ImGui::IsItemHovered())
782  {
783  ImGui::BeginTooltip();
784  ImGui::Text("%s", _LC("TopMenubar", "Visual marker of VideoCameras direction"));
785  ImGui::EndTooltip();
786  }
787 
788  ImGui::PushItemWidth(125.f); // Width includes [+/-] buttons
789  ImGui::Separator();
790  ImGui::TextColored(GRAY_HINT_TEXT, _LC("TopMenubar", "Visual options:"));
791  DrawGIntSlider(App::gfx_polygon_mode, _LC("TopMenubar", "Polygon mode"), 1, 3);
792  if (ImGui::IsItemHovered())
793  {
794  ImGui::BeginTooltip();
795  ImGui::Text("%s", _LC("TopMenubar", "1 = Solid"));
796  ImGui::Text("%s", _LC("TopMenubar", "2 = Wireframe"));
797  ImGui::Text("%s", _LC("TopMenubar", "3 = Points"));
798  ImGui::EndTooltip();
799  }
800 
802  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
803  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
804  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
805  ImGui::End();
806  }
807  break;
808 
809  case TopMenu::TOPMENU_AI:
810  menu_pos.y = window_pos.y + ai_cursor.y + MENU_Y_OFFSET;
811  menu_pos.x = ai_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
812  ImGui::SetNextWindowPos(menu_pos);
813  if (ImGui::Begin(_LC("TopMenubar", "AI menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
814  {
815  if (ImGui::IsWindowHovered())
816  {
817  ai_menu = false;
818  }
819 
820  ImGui::PushItemWidth(125.f); // Width includes [+/-] buttons
821  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "General options:"));
822 
823  if (ai_num < 1)
824  ai_num = 1;
825 
826 
827  if (ai_mode == 2 || ai_mode == 3) // Drag Race or Crash driving mode
828  {
829  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
830  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
831  }
832 
833  ImGui::InputInt(_LC("TopMenubar", "Vehicle count"), &ai_num, 1, 100);
834  if (ImGui::IsItemHovered())
835  {
836  ImGui::BeginTooltip();
837  ImGui::Text("%s", _LC("TopMenubar", "Number of vehicles"));
838  ImGui::EndTooltip();
839  }
840 
841  if (ai_mode == 2 || ai_mode == 3) // Drag Race or Crash driving mode
842  {
843  ImGui::PopItemFlag();
844  ImGui::PopStyleVar();
845  }
846 
847  if (ai_num < 2)
848  {
849  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
850  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
851  }
852 
853  if (ai_mode == 3) // Crash driving mode
854  {
855  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
856  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
857  }
858 
859  ImGui::InputInt(_LC("TopMenubar", "Distance"), &ai_distance, 1, 100);
860  if (ImGui::IsItemHovered())
861  {
862  ImGui::BeginTooltip();
863  ImGui::Text("%s", _LC("TopMenubar", "Following distance in meters"));
864  ImGui::EndTooltip();
865  }
866 
867  if (ai_mode == 3) // Crash driving mode
868  {
869  ImGui::PopItemFlag();
870  ImGui::PopStyleVar();
871  }
872 
873  std::string label1 = "Behind";
874  if (ai_position_scheme == 1)
875  {
876  label1 = "Parallel";
877  }
878  else if (ai_position_scheme == 2)
879  {
880  label1 = "Opposite";
881  }
882 
883  if (ai_mode == 2 || ai_mode == 3) // Drag Race or Crash driving mode
884  {
885  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
886  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
887  }
888 
889  if (ImGui::BeginCombo("Position", label1.c_str()))
890  {
891  if (ImGui::Selectable("Behind"))
892  {
893  ai_position_scheme = 0;
894  }
895  if (ImGui::Selectable("Parallel"))
896  {
897  ai_position_scheme = 1;
898  }
899  ImGui::EndCombo();
900  }
901  if (ImGui::IsItemHovered())
902  {
903  ImGui::BeginTooltip();
904  ImGui::Text("%s", _LC("TopMenubar", "Positioning scheme"));
905  ImGui::Separator();
906  ImGui::Text("%s", _LC("TopMenubar", "Behind: Set vehicle behind vehicle, in line"));
907  ImGui::Text("%s", _LC("TopMenubar", "Parallel: Set vehicles in parallel, useful for certain scenarios like drag races"));
908  ImGui::EndTooltip();
909  }
910 
911  if (ai_num < 2)
912  {
913  ImGui::PopItemFlag();
914  ImGui::PopStyleVar();
915  }
916 
917  if (ai_times < 1)
918  ai_times = 1;
919 
920  if (ai_mode == 4) // Chase driving mode
921  {
922  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
923  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
924  }
925 
926  ImGui::InputInt(_LC("TopMenubar", "Repeat times"), &ai_times, 1, 100);
927  if (ImGui::IsItemHovered())
928  {
929  ImGui::BeginTooltip();
930  ImGui::Text("%s", _LC("TopMenubar", "How many times to loop the path"));
931  ImGui::EndTooltip();
932  }
933 
934  if (ai_mode == 4) // Chase driving mode
935  {
936  ImGui::PopItemFlag();
937  ImGui::PopStyleVar();
938  }
939 
940  if (ai_mode == 2 || ai_mode == 3) // Drag Race or Crash driving mode
941  {
942  ImGui::PopItemFlag();
943  ImGui::PopStyleVar();
944  }
945 
946  ImGui::Separator();
947  ImGui::TextColored(GRAY_HINT_TEXT, "%s", _LC("TopMenubar", "Vehicle options:"));
948 
949  std::string label2 = "Normal";
950  if (ai_mode == 1)
951  {
952  label2 = "Race";
953  }
954  else if (ai_mode == 2)
955  {
956  label2 = "Drag Race";
957  }
958  else if (ai_mode == 3)
959  {
960  label2 = "Crash";
961  }
962  else if (ai_mode == 4)
963  {
964  label2 = "Chase";
965  }
966 
967  for (auto actor : App::GetGameContext()->GetActorManager()->GetLocalActors())
968  {
969  if (actor->ar_driveable == AI)
970  {
971  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
972  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
973  break;
974  }
975  }
976 
977  if (ImGui::BeginCombo("Mode", label2.c_str()))
978  {
979  if (ImGui::Selectable("Normal"))
980  {
981  ai_mode = 0;
982 
983  if (ai_mode_prev == 2 || ai_mode_prev == 3)
984  {
989  }
991  }
992  if (ImGui::Selectable("Race"))
993  {
994  ai_mode = 1;
995 
996  if (ai_mode_prev == 2 || ai_mode_prev == 3)
997  {
1002  }
1004  }
1005  if (ImGui::Selectable("Drag Race"))
1006  {
1007  ai_mode = 2;
1008 
1009  if (ai_mode_prev != 3)
1010  {
1011  ai_num_prev = ai_num;
1015  }
1017  ai_num = 2;
1018  ai_speed = 1000;
1019  ai_position_scheme = 1;
1020  ai_times = 1;
1021  }
1022  if (ImGui::Selectable("Crash"))
1023  {
1024  ai_mode = 3;
1025  if (ai_mode_prev != 2)
1026  {
1027  ai_num_prev = ai_num;
1031  }
1033  ai_num = 2;
1034  ai_speed = 100;
1035  ai_position_scheme = 2;
1036  ai_times = 1;
1037  }
1038  if (ImGui::Selectable("Chase"))
1039  {
1040  ai_mode = 4;
1041 
1042  if (ai_mode_prev == 2 || ai_mode_prev == 3)
1043  {
1044  ai_num = ai_num_prev;
1048  }
1050  }
1051  ImGui::EndCombo();
1052  }
1053  if (ImGui::IsItemHovered())
1054  {
1055  ImGui::BeginTooltip();
1056  ImGui::Text("%s", _LC("TopMenubar", "Land vehicle driving mode"));
1057  ImGui::Separator();
1058  ImGui::Text("%s", _LC("TopMenubar", "Normal: Modify speed according to turns, other vehicles and character"));
1059  ImGui::Text("%s", _LC("TopMenubar", "Race: Always keep defined speed"));
1060  ImGui::Text("%s", _LC("TopMenubar", "Drag Race: Two vehicles performing a drag race"));
1061  ImGui::Text("%s", _LC("TopMenubar", "Crash: Two vehicles driving in opposite direction"));
1062  ImGui::Text("%s", _LC("TopMenubar", "Chase: Follow character and player vehicle"));
1063  ImGui::EndTooltip();
1064  }
1065 
1066  for (auto actor : App::GetGameContext()->GetActorManager()->GetLocalActors())
1067  {
1068  if (actor->ar_driveable == AI)
1069  {
1070  ImGui::PopItemFlag();
1071  ImGui::PopStyleVar();
1072  break;
1073  }
1074  }
1075 
1076  if (ai_speed < 1)
1077  ai_speed = 1;
1078 
1079  ImGui::InputInt(_LC("TopMenubar", "Speed"), &ai_speed, 1, 100);
1080  if (ImGui::IsItemHovered())
1081  {
1082  ImGui::BeginTooltip();
1083  ImGui::Text("%s", _LC("TopMenubar", "Speed in km/h for land vehicles or knots/s for boats"));
1084  ImGui::EndTooltip();
1085  }
1086 
1087  if (ai_altitude < 1)
1088  ai_altitude = 1;
1089 
1090  ImGui::InputInt(_LC("TopMenubar", "Altitude"), &ai_altitude, 1, 100);
1091  if (ImGui::IsItemHovered())
1092  {
1093  ImGui::BeginTooltip();
1094  ImGui::Text("%s", _LC("TopMenubar", "Airplane maximum altitude in feet"));
1095  ImGui::EndTooltip();
1096  }
1097 
1098  ImGui::Separator();
1099 
1100  if (ImGui::Button(StripColorMarksFromText(ai_dname).c_str(), ImVec2(250, 0)))
1101  {
1102  ai_select = true;
1103 
1105  m.payload = reinterpret_cast<void*>(new LoaderType(LT_AllBeam));
1107  }
1108  if (ImGui::IsItemHovered())
1109  {
1110  ImGui::BeginTooltip();
1111  ImGui::Text("%s", _LC("TopMenubar", "Land vehicles, boats and airplanes"));
1112  ImGui::EndTooltip();
1113  }
1114 
1115  if (ai_mode == 2 || ai_mode == 3) // Drag Race or Crash driving mode
1116  {
1117  ImGui::PushID("vehicle2");
1118  if (ImGui::Button(StripColorMarksFromText(ai_dname2).c_str(), ImVec2(250, 0)))
1119  {
1120  ai_select2 = true;
1121 
1123  m.payload = reinterpret_cast<void*>(new LoaderType(LT_AllBeam));
1125  }
1126  if (ImGui::IsItemHovered())
1127  {
1128  ImGui::BeginTooltip();
1129  ImGui::Text("%s", _LC("TopMenubar", "Land vehicles, boats and airplanes"));
1130  ImGui::EndTooltip();
1131  }
1132  ImGui::PopID();
1133  }
1134 
1135  ImGui::Separator();
1136 
1137  if (ai_rec)
1138  {
1139  ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
1140  ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
1141  }
1142 
1143  if (!ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode
1144  {
1145  ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]);
1146  }
1147 
1148  if (ImGui::Button(_LC("TopMenubar", "Start"), ImVec2(80, 0)))
1149  {
1150  if (ai_mode == 4) // Chase driving mode
1151  {
1152  ai_waypoints.clear();
1153  if (App::GetGameContext()->GetPlayerActor()) // We are in vehicle
1154  {
1155  ai_events waypoint;
1156  waypoint.position = App::GetGameContext()->GetPlayerActor()->getPosition() + Ogre::Vector3(20, 0, 0);
1157  ai_waypoints.push_back(waypoint);
1158  }
1159  else // We are in feet
1160  {
1161  ai_events waypoint;
1162  waypoint.position = App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(20, 0, 0);
1163  ai_waypoints.push_back(waypoint);
1164  }
1166  }
1167  else
1168  {
1169  if (ai_waypoints.empty())
1170  {
1172  fmt::format(_LC("TopMenubar", "Select a preset, record or open survey map ({}) to set waypoints."),
1173  App::GetInputEngine()->getEventCommandTrimmed(EV_SURVEY_MAP_CYCLE)), "lightbulb.png");
1174  }
1175  else
1176  {
1178  }
1179  }
1180  }
1181 
1182  if (!ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode
1183  {
1184  ImGui::PopStyleColor();
1185  }
1186 
1187  ImGui::SameLine();
1188 
1189  if (ImGui::Button(_LC("TopMenubar", "Stop"), ImVec2(80, 0)))
1190  {
1191  if (ai_mode == 4) // Chase driving mode
1192  {
1193  ai_waypoints.clear();
1194  }
1195 
1196  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetLocalActors())
1197  {
1198  if (actor->ar_driveable == AI)
1199  {
1200  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(actor))));
1201  }
1202  }
1203  }
1204 
1205  if (ai_rec)
1206  {
1207  ImGui::PopItemFlag();
1208  ImGui::PopStyleVar();
1209  }
1210 
1211  ImGui::SameLine();
1212 
1213  ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_Button]);
1214  std::string label = "Record";
1215  if (ai_rec)
1216  {
1217  label = "Recording";
1218  ImGui::PushStyleColor(ImGuiCol_Button, RED_TEXT);
1219  }
1220 
1221  if (ImGui::Button(label.c_str(), ImVec2(80, 0)))
1222  {
1223  if (!ai_rec)
1224  {
1225  ai_waypoints.clear();
1226  ai_rec = true;
1227  }
1228  else
1229  {
1230  ai_rec = false;
1231  }
1232  }
1233 
1234  ImGui::PopStyleColor();
1235  ImGui::Separator();
1236 
1237  if (ImGui::CollapsingHeader(_LC("TopMenubar", "Presets")))
1238  {
1239  // Draw whatever we already have (i.e. presets bundled with terrain, see '[AI Presets]' in terrn2 format).
1240  size_t num_rows = ai_presets_all.GetArray().Size();
1241  int display_count = 0;
1242  for (size_t i = 0; i < num_rows; i++)
1243  {
1244  rapidjson::Value& j_row = ai_presets_all[static_cast<rapidjson::SizeType>(i)];
1245 
1246  if (j_row.HasMember("terrain") && App::sim_terrain_name->getStr() == j_row["terrain"].GetString())
1247  {
1248  display_count++;
1249  if (ImGui::Button(j_row["preset"].GetString(), ImVec2(250, 0)))
1250  {
1251  ai_waypoints.clear();
1252 
1253  for (size_t i = 0; i < j_row["waypoints"].Size(); i++)
1254  {
1255  float x = j_row["waypoints"][i][0].GetFloat();
1256  float y = j_row["waypoints"][i][1].GetFloat();
1257  float z = j_row["waypoints"][i][2].GetFloat();
1258 
1259  ai_events waypoint;
1260  waypoint.position = Ogre::Vector3(x, y, z);
1261 
1262  int speed = -1;
1263  if (j_row["waypoints"][i].Size() == 4) // Custom speed defined
1264  {
1265  speed = j_row["waypoints"][i][3].GetInt();
1266  if (speed < 5)
1267  {
1268  speed = -1;
1269  }
1270  }
1271  waypoint.speed = speed;
1272  ai_waypoints.push_back(waypoint);
1273  }
1274  }
1275  }
1276  }
1277 
1278  // Fetch additional presets, or display error if failed
1279  if (ai_presets_extern.Empty())
1280  {
1282  {
1283  float spinner_size = 8.f;
1284  ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.f) - spinner_size);
1285  LoadingIndicatorCircle("spinner", spinner_size, theme.value_blue_text_color, theme.value_blue_text_color, 10, 10);
1286  }
1287  else if (ai_presets_extern_error != "")
1288  {
1289  ImGui::TextColored(RED_TEXT, "%s", _LC("TopMenubar", "Failed to fetch external presets."));
1290  if (ImGui::Button(_LC("TopMenubar", "Retry")))
1291  {
1292  this->FetchExternAiPresetsOnBackground(); // Will post `MSG_NET_REFRESH_AI_PRESETS` when done.
1293  }
1294  }
1295  else
1296  {
1297  this->FetchExternAiPresetsOnBackground(); // Will post `MSG_NET_REFRESH_AI_PRESETS` when done.
1298  }
1299  }
1300 
1301  // If no presets found, display message
1302  if (display_count == 0 && !ai_presets_extern_fetching && ai_presets_extern_error == "")
1303  {
1304  ImGui::Text("%s", _LC("TopMenubar", "No presets found for this terrain :("));
1305  ImGui::Text("%s", _LC("TopMenubar", "Supported terrains:"));
1306  ImGui::Separator();
1307 
1308  ImGui::BeginChild("terrains-scrolling", ImVec2(0.f, 200), false);
1309 
1310  for (size_t i = 0; i < num_rows; i++)
1311  {
1312  rapidjson::Value& j_row_terrains = ai_presets_all[static_cast<rapidjson::SizeType>(i)];
1313  if (j_row_terrains.HasMember("terrains"))
1314  {
1315  for (size_t i = 0; i < j_row_terrains["terrains"].Size(); i++)
1316  {
1317  ImGui::Text("%s", j_row_terrains["terrains"][i].GetString());
1318  }
1319  }
1320  }
1321 
1322  ImGui::EndChild();
1323  }
1324  }
1325 
1326  if (ImGui::CollapsingHeader(_LC("TopMenubar", "Waypoints")))
1327  {
1328  if (ai_waypoints.empty())
1329  {
1330  ImGui::Text("%s", _LC("TopMenubar", "No waypoints defined."));
1331  }
1332  else
1333  {
1334  if (ImGui::Button(_LC("TopMenubar", "Export"), ImVec2(250, 0)))
1335  {
1336  std::string s;
1337 
1338  for (int i = 0; i < ai_waypoints.size(); i++)
1339  {
1340  // Write position
1341  s += "\n [" + std::to_string(ai_waypoints[i].position.x) + ", " + std::to_string(ai_waypoints[i].position.y) + ", " + std::to_string(ai_waypoints[i].position.z);
1342 
1343  // Write custom speed
1344  if (ai_waypoints[i].speed >= 5)
1345  {
1346  s += ", " + std::to_string(ai_waypoints[i].speed);
1347  }
1348 
1349  // Close
1350  s += "]";
1351  if (i != ai_waypoints.size() - 1)
1352  {
1353  s += ",";
1354  }
1355  }
1356 
1357  std::string json = fmt::format("\n {{\n \"terrain\":\"{}\",\n \"preset\":\"Preset name\",\n \"waypoints\":\n [{}\n ]\n }}", App::sim_terrain_name->getStr(), s);
1358  RoR::Log(json.c_str());
1359 
1361  fmt::format(_LC("TopMenubar", "{} waypoints exported to RoR.log"),
1362  ai_waypoints.size()), "lightbulb.png");
1363  }
1364 
1365  ImGui::BeginChild("waypoints-scrolling", ImVec2(0.f, 200), false);
1366 
1367  for (int i = 0; i < ai_waypoints.size(); i++)
1368  {
1369  ImGui::PushID(i);
1370  ImGui::AlignTextToFramePadding();
1371  ImGui::Text("%d", i);
1372  ImGui::SameLine();
1373  if (ImGui::Button("teleport", ImVec2(60, 0)))
1374  {
1375  Ogre::Vector3* payload = new Ogre::Vector3(ai_waypoints[i].position);
1377  }
1378  if (ImGui::IsItemHovered())
1379  {
1380  ImGui::BeginTooltip();
1381  std::string w = "x:" + std::to_string(ai_waypoints[i].position.x) + " y:" + std::to_string(ai_waypoints[i].position.y) + " z:" + std::to_string(ai_waypoints[i].position.z);
1382  ImGui::Text(w.c_str());
1383  ImGui::EndTooltip();
1384  }
1385  ImGui::SameLine();
1386  ImGui::SetNextItemWidth(90);
1387 
1388  if (ai_waypoints[i].speed < -1)
1389  {
1390  ai_waypoints[i].speed = -1;
1391  }
1392  ImGui::InputInt(_LC("TopMenubar", "speed"), &ai_waypoints[i].speed, 1, 100);
1393  if (ImGui::IsItemHovered())
1394  {
1395  ImGui::BeginTooltip();
1396  ImGui::Text(_LC("TopMenubar", "Set waypoint speed in km/h for land vehicles"));
1397  ImGui::Separator();
1398  ImGui::Text(_LC("TopMenubar", "Value -1: Ignore, vehicle will use default speed"));
1399  ImGui::Text(_LC("TopMenubar", "Value >= 5: Override default speed"));
1400  ImGui::EndTooltip();
1401  }
1402  ImGui::PopID();
1403  }
1404 
1405  ImGui::EndChild();
1406  }
1407  }
1408 
1409  ImGui::PopItemWidth();
1411  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
1412  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
1413  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
1414  ImGui::End();
1415  }
1416  break;
1417 
1419  menu_pos.y = window_pos.y + tuning_cursor.y + MENU_Y_OFFSET;
1420  menu_pos.x = tuning_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
1421  ImGui::SetNextWindowPos(menu_pos);
1422  if (ImGui::Begin(_LC("TopMenubar", "Tuning menu"), nullptr, static_cast<ImGuiWindowFlags_>(flags)))
1423  {
1424  this->RefreshTuningMenu(); // make sure our local context is valid
1425  if (!tuning_actor)
1426  {
1427  ImGui::PushStyleColor(ImGuiCol_Text, GRAY_HINT_TEXT);
1428  ImGui::Text("%s", _LC("Tuning", "You are on foot."));
1429  ImGui::Text("%s", _LC("Tuning", "Enter a vehicle to tune it."));
1430  ImGui::PopStyleColor();
1431  }
1432  else
1433  {
1436 
1437  // SAVED TUNEUPS
1438  ImGui::TextDisabled(fmt::format(_LC("Tuning", "Saved tuneups ({})"), tuning_saves.cqy_results.size()).c_str());
1439  for (CacheQueryResult& tuneup_result: tuning_saves.cqy_results)
1440  {
1441  ImGui::PushID(tuneup_result.cqr_entry->fname.c_str());
1442 
1443  ImGui::AlignTextToFramePadding();
1444  ImGui::Bullet();
1445 
1446  // Load button (with tuneup name)
1447  ImGui::SameLine();
1448  if (ImGui::Button(tuneup_result.cqr_entry->dname.c_str()))
1449  {
1452  req->mpr_subject = tuneup_result.cqr_entry->fname;
1455  // Why 'MODIFY_PROJECT_REQUESTED' for loading?
1456  // Instead of loading with the saved tuneup directly, we keep the autogenerated and sync it with the save.
1457  // That way, subsequent editing doesn't modify the save until user saves again.
1458  }
1459 
1460  // Delete button (right-aligned)
1461  ImGui::SameLine();
1462  if (tuning_rwidget_cursorx_min < ImGui::GetCursorPosX()) // Make sure button won't draw over item name
1463  tuning_rwidget_cursorx_min = ImGui::GetCursorPosX();
1464  std::string delbtn_text = _LC("Tuning", "Delete");
1465  float delbtn_w = ImGui::CalcTextSize(delbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1466  float delbtn_cursorx = ImGui::GetWindowContentRegionWidth() - delbtn_w;
1467  if (delbtn_cursorx < tuning_rwidget_cursorx_min)
1468  delbtn_cursorx = tuning_rwidget_cursorx_min;
1469  ImGui::SetCursorPosX(delbtn_cursorx);
1470  ImGui::PushStyleColor(ImGuiCol_Button, TUNING_HOLDTOCONFIRM_COLOR);
1471  bool delbtn_pressed = RoR::ImButtonHoldToConfirm(delbtn_text, /*small:*/true, TUNING_HOLDTOCONFIRM_TIMELIMIT);
1472  ImGui::PopStyleColor(); //ImGuiCol_Button
1473  if (delbtn_pressed)
1474  {
1476  }
1477 
1478  ImGui::PopID(); // tuneup_result.cqr_entry->fname.c_str()
1479  }
1480 
1481  // WORKING TUNEUP
1482  ImGui::Separator();
1483  ImGui::AlignTextToFramePadding();
1484  ImGui::TextDisabled(_LC("Tuning", "Working tuneup"));
1486  {
1487  ImGui::InputText(_LC("Tuning", "Name"), tuning_savebox_buf.GetBuffer(), tuning_savebox_buf.GetCapacity());
1488 
1489  if (ImGui::Button(_LC("Tuning","Save")))
1490  {
1498  }
1499  ImGui::SameLine();
1500  ImGui::Checkbox(_LC("Tuning", "Overwrite"), &tuning_savebox_overwrite);
1501 
1502  // Cancel button (right-aligned)
1503  if (tuning_rwidget_cursorx_min < ImGui::GetCursorPosX()) // Make sure button won't draw over save button
1504  tuning_rwidget_cursorx_min = ImGui::GetCursorPosX();
1505  std::string cancelbtn_text = _LC("Tuning", "Cancel");
1506  float cancelbtn_w = ImGui::CalcTextSize(cancelbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1507  float cancelbtn_cursorx = ImGui::GetWindowContentRegionWidth() - cancelbtn_w;
1508  if (cancelbtn_cursorx < tuning_rwidget_cursorx_min)
1509  cancelbtn_cursorx = tuning_rwidget_cursorx_min;
1510  ImGui::SetCursorPosX(cancelbtn_cursorx);
1511  if (ImGui::SmallButton(_LC("Tuning", "Cancel")))
1512  {
1513  tuning_savebox_visible = false;
1514  }
1515  ImGui::Separator();
1516  }
1517  else if (tuneup_def)
1518  {
1519  ImGui::SameLine();
1520  if (ImGui::Button(_LC("Tuning", "Save as...")))
1521  {
1522  tuning_savebox_visible = true;
1523  }
1524 
1525  // Reset button (right-aligned)
1526  ImGui::SameLine();
1527  if (tuning_rwidget_cursorx_min < ImGui::GetCursorPosX()) // Make sure button won't draw over save button
1528  tuning_rwidget_cursorx_min = ImGui::GetCursorPosX();
1529  ImGui::AlignTextToFramePadding();
1530  std::string resetbtn_text = _LC("Tuning", "Reset");
1531  float delbtn_w = ImGui::CalcTextSize(resetbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1532  float delbtn_cursorx = ImGui::GetWindowContentRegionWidth() - delbtn_w;
1533  if (delbtn_cursorx < tuning_rwidget_cursorx_min)
1534  delbtn_cursorx = tuning_rwidget_cursorx_min;
1535  ImGui::SetCursorPosX(delbtn_cursorx);
1536  ImGui::PushStyleColor(ImGuiCol_Button, TUNING_HOLDTOCONFIRM_COLOR);
1537  bool resetbtn_pressed = ImButtonHoldToConfirm(resetbtn_text, /*small:*/false, TUNING_HOLDTOCONFIRM_TIMELIMIT);
1538  ImGui::PopStyleColor(); //ImGuiCol_Button
1539  if (resetbtn_pressed)
1540  {
1541  ModifyProjectRequest* request = new ModifyProjectRequest();
1542  request->mpr_target_actor = tuning_actor;
1545  }
1546  }
1547 
1548  // ADDONPARTS
1549 
1550  ImGui::SetNextItemOpen(true, ImGuiCond_FirstUseEver);
1551  std::string addonparts_title = fmt::format(_LC("TopMenubar", "Addon parts ({})"), tuning_addonparts.size());
1552  if (ImGui::CollapsingHeader(addonparts_title.c_str()))
1553  {
1554  for (size_t i = 0; i < tuning_addonparts.size(); i++)
1555  {
1556  const CacheEntryPtr& addonpart_entry = tuning_addonparts[i];
1557 
1558  ImGui::PushID(addonpart_entry->fname.c_str());
1559  const bool conflict_w_hovered = tuning_hovered_addonpart
1560  && (addonpart_entry != tuning_hovered_addonpart)
1562  bool used = TuneupUtil::isAddonPartUsed(tuneup_def, addonpart_entry->fname);
1563  const ImVec2 checkbox_cursor = ImGui::GetCursorScreenPos();
1564  if (ImGui::Checkbox(addonpart_entry->dname.c_str(), &used)
1565  && !conflict_w_hovered
1567  {
1569  req->mpr_type = (used)
1572  req->mpr_subject = addonpart_entry->fname;
1575  }
1576  // Draw conflict markers
1578  {
1579  // Gray-ish X inside the checkbox
1580  const float square_sz = ImGui::GetFrameHeight();
1581  const ImVec2 min = checkbox_cursor + ImGui::GetStyle().FramePadding*1.4f;
1582  const ImVec2 max = checkbox_cursor + (ImVec2(square_sz, square_sz) - ImGui::GetStyle().FramePadding*1.5f);
1583  const ImColor X_COLOR(0.5f, 0.48f, 0.45f);
1584  ImGui::GetWindowDrawList()->AddLine(min, max, X_COLOR, 4.f);
1585  ImGui::GetWindowDrawList()->AddLine(ImVec2(min.x, max.y), ImVec2(max.x, min.y), X_COLOR, 4.f);
1586  }
1587  if (conflict_w_hovered)
1588  {
1589  // Red unrounded square around the checkbox
1590  const float square_sz = ImGui::GetFrameHeight();
1591  const ImVec2 min = checkbox_cursor;
1592  const ImVec2 max = checkbox_cursor + ImVec2(square_sz + 0.5f, square_sz);
1593  const ImColor SQ_COLOR(0.7f, 0.1f, 0.f);
1594  ImGui::GetWindowDrawList()->AddRect(min, max, SQ_COLOR, 0.f, ImDrawCornerFlags_None, 3.f);
1595  }
1596  // Record when checkbox is hovered - for drawing conflict markers
1597  if (ImGui::IsItemHovered())
1598  {
1599  tuning_hovered_addonpart = addonpart_entry;
1600  }
1601  else if (tuning_hovered_addonpart == addonpart_entry)
1602  {
1603  tuning_hovered_addonpart = nullptr;
1604  }
1605  // Reload button (right-aligned)
1606  ImGui::SameLine();
1607  if (tuning_rwidget_cursorx_min < ImGui::GetCursorPosX()) // Make sure button won't draw over save button
1608  tuning_rwidget_cursorx_min = ImGui::GetCursorPosX();
1609  ImGui::AlignTextToFramePadding();
1610  std::string reloadbtn_text = _LC("Tuning", "Reload");
1611  const float reloadbtn_w = ImGui::CalcTextSize(reloadbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1612  const float reloadbtn_cursorx = std::max(ImGui::GetWindowContentRegionWidth() - reloadbtn_w, tuning_rwidget_cursorx_min);
1613  ImGui::SetCursorPosX(reloadbtn_cursorx);
1614  const bool reloadbtn_pressed = ImGui::SmallButton(reloadbtn_text.c_str());
1615  if (reloadbtn_pressed)
1616  {
1617  // Create spawn request while actor still exists
1618  // Note we don't use `ActorModifyRequest::Type::RELOAD` because we don't need the bundle reloaded.
1621  srq->asr_rotation = Ogre::Quaternion(Ogre::Degree(270) - Ogre::Radian(tuning_actor->getRotation()), Ogre::Vector3::UNIT_Y);
1628 
1629  // Request bundle reloading and chain the actor delete/spawn messages to it.
1633  }
1634 
1635  ImGui::PopID(); //(addonpart_entry->fname.c_str());
1636  }
1637 
1638  if (ImGui::Button(_LC("Tuning", "Browse all parts")))
1639  {
1641  }
1642 
1643  ImGui::Separator();
1644  }
1645 
1646  // Draw props
1647  size_t total_props = tuning_actor->GetGfxActor()->getProps().size();
1648  std::string props_title = fmt::format(_LC("Tuning", "Props ({})"), total_props);
1649  if (ImGui::CollapsingHeader(props_title.c_str()))
1650  {
1651  // Draw all props (those removed by addonparts are also present as placeholders)
1652  for (Prop const& p: tuning_actor->GetGfxActor()->getProps())
1653  {
1654  ImGui::PushID(p.pp_id);
1655  ImGui::AlignTextToFramePadding();
1656 
1657  this->DrawTuningBoxedSubjectIdInline(p.pp_id);
1658 
1660  p.pp_id,
1661  p.pp_media[0],
1662  tuneup_def && tuneup_def->isPropUnwanted(p.pp_id),
1663  tuneup_def && tuneup_def->isPropForceRemoved(p.pp_id),
1666 
1667  // Draw special prop tooltip
1668  if (p.pp_beacon_type == 'L' || p.pp_beacon_type == 'R' || p.pp_beacon_type == 'w')
1669  {
1670  ImGui::SameLine();
1671  ImGui::TextDisabled("(special!)");
1672  if (ImGui::IsItemHovered())
1673  {
1674  ImGui::BeginTooltip();
1675  ImGui::Text("special prop - aerial nav light");
1676  ImGui::EndTooltip();
1677  }
1678  }
1679  else if (p.pp_wheel_mesh_obj)
1680  {
1681  ImGui::SameLine();
1682  ImGui::TextDisabled("(special!)");
1683  if (ImGui::IsItemHovered())
1684  {
1685  ImGui::BeginTooltip();
1686  ImGui::Text("special prop - dashboard + dirwheel");
1687  ImGui::EndTooltip();
1688  }
1689 
1690  }
1691 
1693  p.pp_id,
1694  tuneup_def && tuneup_def->isPropProtected(p.pp_id),
1697 
1698  ImGui::PopID(); // p.pp_id
1699  }
1700 
1701  ImGui::Separator();
1702  }
1703 
1704  // Ditto for flexbodies
1705  size_t total_flexbodies = tuning_actor->GetGfxActor()->GetFlexbodies().size();
1706  std::string flexbodies_title = fmt::format(_LC("Tuning", "Flexbodies ({})"), total_flexbodies);
1707  if (ImGui::CollapsingHeader(flexbodies_title.c_str()))
1708  {
1709  // Draw all flexbodies (those removed by addonparts are also present as placeholders)
1710  for (FlexBody* flexbody: tuning_actor->GetGfxActor()->GetFlexbodies())
1711  {
1712  ImGui::PushID(flexbody->getID());
1713  ImGui::AlignTextToFramePadding();
1714 
1715  this->DrawTuningBoxedSubjectIdInline(flexbody->getID());
1716 
1718  flexbody->getID(),
1719  flexbody->getOrigMeshName(),
1720  tuneup_def && tuneup_def->isFlexbodyUnwanted(flexbody->getID()),
1721  tuneup_def && tuneup_def->isFlexbodyForceRemoved(flexbody->getID()),
1724 
1726  flexbody->getID(),
1727  tuneup_def && tuneup_def->isFlexbodyProtected(flexbody->getID()),
1730 
1731  ImGui::PopID(); // flexbody->getID()
1732  }
1733  }
1734 
1735  // Draw wheels
1736  const int total_wheels = tuning_actor->ar_num_wheels;
1737  std::string wheels_title = fmt::format(_LC("TopMenubar", "Wheels ({})"), total_wheels);
1738  if (ImGui::CollapsingHeader(wheels_title.c_str()))
1739  {
1740  for (WheelID_t i = 0; i < total_wheels; i++)
1741  {
1742  ImGui::PushID(i);
1743  ImGui::AlignTextToFramePadding();
1744 
1746 
1747  // Draw R/L radio buttons
1748  WheelSide forced_side = WheelSide::INVALID;
1749  if (tuneup_def && tuneup_def->isWheelSideForced(i, /*[out]*/forced_side))
1750  {
1751  ImGui::PushStyleColor(ImGuiCol_Border, ORANGE_TEXT);
1752  ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f);
1753  }
1754  const RoR::WheelSide active_side = TuneupUtil::getTweakedWheelSide(tuneup_def, i, tuning_actor->GetGfxActor()->getWheelSide(i));
1755  RoR::WheelSide selected_side = active_side;
1756  if (ImGui::RadioButton("##L", active_side == WheelSide::LEFT))
1757  selected_side = WheelSide::LEFT;
1758  ImGui::SameLine();
1759  ImGui::TextDisabled("|");
1760  ImGui::SameLine();
1761  if (ImGui::RadioButton("##R", active_side == WheelSide::RIGHT))
1762  selected_side = WheelSide::RIGHT;
1763 
1764  // Draw rim mesh name
1765  ImGui::SameLine();
1766  ImGui::Text("%s", tuning_actor->GetGfxActor()->getWheelRimMeshName(i).c_str());
1767 
1768  // Draw reset button
1769 
1770  bool resetPressed = false;
1771  if (tuneup_def && tuneup_def->isWheelSideForced(i, forced_side))
1772  {
1773  ImGui::SameLine();
1774  ImGui::SameLine();
1775  ImGui::PushStyleColor(ImGuiCol_Text, GRAY_HINT_TEXT);
1776  resetPressed = ImGui::SmallButton(_LC("Tuning", "Reset"));
1777  ImGui::PopStyleColor(); //ImGuiCol_Text, GRAY_HINT_TEXT
1778  ImGui::PopStyleVar(); //ImGuiStyleVar_FrameBorderSize, 1.f
1779  ImGui::PopStyleColor(); //ImGuiCol_Border, ORANGE_TEXT
1780  }
1781 
1782  // modify project if needed
1783  if (selected_side != active_side)
1784  {
1787  req->mpr_subject_id = i;
1788  req->mpr_value_int = (int)selected_side;
1791  }
1792  else if (resetPressed)
1793  {
1796  req->mpr_subject_id = i;
1799  }
1800 
1802  i,
1803  tuneup_def && tuneup_def->isWheelProtected(i),
1806 
1807  ImGui::PopID(); // i
1808  }
1809  }
1810 
1811  // Draw flares
1812  size_t total_flares = tuning_actor->ar_flares.size();
1813  std::string flares_title = fmt::format(_LC("Tuning", "Flares ({})"), total_flares);
1814  if (ImGui::CollapsingHeader(flares_title.c_str()))
1815  {
1816  // Draw all flares (those removed by addonparts are also present as placeholders)
1817  for (FlareID_t flareid = 0; flareid < (int)tuning_actor->ar_flares.size(); flareid++)
1818  {
1819  ImGui::PushID(flareid);
1820  ImGui::AlignTextToFramePadding();
1821 
1822  this->DrawTuningBoxedSubjectIdInline(flareid);
1823 
1824  // Compose flare description string
1825  const FlareType flaretype = tuning_actor->ar_flares[flareid].fl_type;
1826  std::string flarename;
1827  if (flaretype == FlareType::USER)
1828  {
1829  int controlnumber = tuning_actor->ar_flares[flareid].controlnumber + 1; // Convert range 0-9 to 1-10
1830  flarename = fmt::format("{} {}", (char)flaretype, controlnumber);
1831  }
1832  else if (flaretype == FlareType::DASHBOARD)
1833  {
1834  std::string linkname = tuning_actor->ar_dashboard->getLinkNameForID((DashData)tuning_actor->ar_flares[flareid].dashboard_link);
1835  flarename = fmt::format("{} {}", (char)flaretype, linkname);
1836  }
1837  else
1838  {
1839  flarename = fmt::format("{}", (char)flaretype);
1840  }
1841 
1843  flareid,
1844  flarename,
1845  tuneup_def && tuneup_def->isFlareUnwanted(flareid),
1846  tuneup_def && tuneup_def->isFlareForceRemoved(flareid),
1849 
1851  flareid,
1852  tuneup_def && tuneup_def->isFlareProtected(flareid),
1855 
1856  ImGui::PopID(); // flareid
1857  }
1858  }
1859 
1860  // Draw exhausts
1861  size_t total_exhausts = tuning_actor->exhausts.size();
1862  std::string exhausts_title = fmt::format(_LC("Tuning", "Exhausts ({})"), total_exhausts);
1863  if (ImGui::CollapsingHeader(exhausts_title.c_str()))
1864  {
1865  // Draw all exhausts (those removed by addonparts are also present as placeholders)
1866  for (ExhaustID_t exhaustid = 0; exhaustid < (int)tuning_actor->exhausts.size(); exhaustid++)
1867  {
1868  ImGui::PushID(exhaustid);
1869  ImGui::AlignTextToFramePadding();
1870 
1871  this->DrawTuningBoxedSubjectIdInline(exhaustid);
1872 
1874  exhaustid,
1875  tuning_actor->exhausts[exhaustid].particleSystemName,
1876  tuneup_def && tuneup_def->isExhaustUnwanted(exhaustid),
1877  tuneup_def && tuneup_def->isExhaustForceRemoved(exhaustid),
1880 
1882  exhaustid,
1883  tuneup_def && tuneup_def->isExhaustProtected(exhaustid),
1886 
1887  ImGui::PopID(); // exhaustid
1888  }
1889  }
1890 
1891  // Draw managed materials
1892  size_t total_materials = tuning_actor->ar_managed_materials.size();
1893  std::string materials_title = fmt::format(_LC("Tuning", "Managed Materials ({})"), total_materials);
1894  if (ImGui::CollapsingHeader(materials_title.c_str()))
1895  {
1896  // Draw all materials (those removed by addonparts are also present as placeholders)
1897  for (auto mm_pair: tuning_actor->ar_managed_materials)
1898  {
1899  const std::string& material_name = mm_pair.first;
1900  ImGui::PushID(material_name.c_str());
1901  ImGui::AlignTextToFramePadding();
1902 
1905  material_name,
1906  tuneup_def && tuneup_def->isManagedMatUnwanted(material_name),
1907  tuneup_def && tuneup_def->isManagedMatForceRemoved(material_name),
1910 
1913  tuneup_def && tuneup_def->isManagedMatProtected(material_name),
1916  material_name);
1917 
1918  ImGui::PopID(); // material_name.c_str()
1919  }
1920  }
1921  }
1922 
1924  m_open_menu_hoverbox_max.x = menu_pos.x + ImGui::GetWindowWidth() + MENU_HOVERBOX_PADDING.x;
1925  m_open_menu_hoverbox_max.y = menu_pos.y + ImGui::GetWindowHeight() + MENU_HOVERBOX_PADDING.y;
1926  App::GetGuiManager()->RequestGuiCaptureKeyboard(ImGui::IsWindowHovered());
1927  ImGui::End();
1928  }
1929  break;
1930 
1931  default:
1932  m_open_menu_hoverbox_min = ImVec2(0,0);
1933  m_open_menu_hoverbox_max = ImVec2(0,0);
1934  }
1935 
1936  ImGui::PopStyleColor(2); // WindowBg, Button
1937 }
1938 
1939 bool TopMenubar::ShouldDisplay(ImVec2 window_pos)
1940 {
1941  if (!App::GetGuiManager()->AreStaticMenusAllowed())
1942  {
1943  return false;
1944  }
1945 
1946  if (ImGui::IsMouseDown(1))
1947  {
1948  return false;
1949  }
1950 
1951  if (ai_menu)
1952  {
1954  return true;
1955  }
1956 
1957  ImVec2 box_min(0,0);
1958  ImVec2 box_max(ImGui::GetIO().DisplaySize.x, ImGui::GetStyle().WindowPadding.y + PANEL_HOVERBOX_HEIGHT);
1959  ImVec2 mouse_pos = ImGui::GetIO().MousePos;
1960  const bool window_hovered ((mouse_pos.x >= box_min.x) && (mouse_pos.x <= box_max.x) &&
1961  (mouse_pos.y >= box_min.y) && (mouse_pos.y <= box_max.y));
1962  bool result = window_hovered;
1963 
1964  bool menu_hovered = false;
1966  {
1967  menu_hovered = ((mouse_pos.x >= m_open_menu_hoverbox_min.x) && (mouse_pos.x <= m_open_menu_hoverbox_max.x) &&
1968  (mouse_pos.y >= m_open_menu_hoverbox_min.y) && (mouse_pos.y <= m_open_menu_hoverbox_max.y));
1969  }
1970  result |= menu_hovered;
1971 
1972  bool box_hovered = false;
1974  {
1975  box_hovered = ((mouse_pos.x >= m_state_box_hoverbox_min.x) && (mouse_pos.x <= m_state_box_hoverbox_max.x) &&
1976  (mouse_pos.y >= m_state_box_hoverbox_min.y) && (mouse_pos.y <= m_state_box_hoverbox_max.y));
1977  result |= box_hovered;
1978  }
1979 
1980  if (box_hovered && !menu_hovered)
1981  {
1983  }
1984 
1985  return result;
1986 }
1987 
1989 {
1990  // Count actors owned by the player
1991  unsigned int num_actors_player = 0;
1992  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors())
1993  {
1994  if (actor->ar_net_source_id == user.uniqueid)
1995  {
1996  ++num_actors_player;
1997  }
1998  }
1999 
2000  // Display user in list
2001 #ifdef USE_SOCKETW
2002  const Ogre::ColourValue player_color = App::GetNetwork()->GetPlayerColor(user.colournum);
2003  ImVec4 player_gui_color(player_color.r, player_color.g, player_color.b, 1.f);
2004  ImGui::PushStyleColor(ImGuiCol_Text, player_gui_color);
2005  ImGui::Text("%s: %u (%s, Ver: %s, Lang: %s)",
2006  user.username, num_actors_player,
2007  App::GetNetwork()->UserAuthToStringShort(user).c_str(),
2008  user.clientversion, user.language);
2009  ImGui::PopStyleColor();
2010 #endif // USE_SOCKETW
2011 
2012  // Display actor list
2013  Ogre::TexturePtr tex1 = FetchIcon("control_pause.png");
2014  Ogre::TexturePtr tex2 = FetchIcon("control_play.png");
2015  int i = 0;
2016  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors())
2017  {
2018  if ((!actor->ar_hide_in_actor_list) && (actor->ar_net_source_id == user.uniqueid))
2019  {
2020  std::string id = fmt::format("{}:{}", i++, user.uniqueid);
2021  ImGui::PushID(id.c_str());
2022  if (actor->ar_state == ActorState::NETWORKED_OK)
2023  {
2024  if (ImGui::ImageButton(reinterpret_cast<ImTextureID>(tex1->getHandle()), ImVec2(16, 16)))
2025  {
2027  }
2028  }
2029  else if (actor->ar_state == ActorState::NETWORKED_HIDDEN)
2030  {
2031  if (ImGui::ImageButton(reinterpret_cast<ImTextureID>(tex2->getHandle()), ImVec2(16, 16)))
2032  {
2034  }
2035  }
2036  else // Our actor(s)
2037  {
2038  std::string text_buf_rem = fmt::format(" X ##[{}]", i);
2039  ImGui::PushStyleColor(ImGuiCol_Text, RED_TEXT);
2040  if (ImGui::Button(text_buf_rem.c_str()))
2041  {
2042  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(actor))));
2043  }
2044  ImGui::PopStyleColor();
2045  }
2046  ImGui::PopID();
2047  ImGui::SameLine();
2048 
2049  std::string actortext_buf = fmt::format("{} ({}) ##[{}:{}]", StripColorMarksFromText(actor->ar_design_name).c_str(), actor->ar_filename.c_str(), i++, user.uniqueid);
2050  if (ImGui::Button(actortext_buf.c_str())) // Button clicked?
2051  {
2052  App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast<void*>(new ActorPtr(actor))));
2053  }
2054  }
2055  }
2056 }
2057 
2059 {
2060  std::vector<ActorPtr> actor_list;
2061  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors())
2062  {
2063  if (!actor->ar_hide_in_actor_list)
2064  {
2065  actor_list.emplace_back(actor);
2066  }
2067  }
2068  if (actor_list.empty())
2069  {
2070  ImGui::PushStyleColor(ImGuiCol_Text, GRAY_HINT_TEXT);
2071  ImGui::Text("%s", _LC("TopMenubar", "None spawned yet"));
2072  ImGui::Text("%s", _LC("TopMenubar", "Use [Simulation] menu"));
2073  ImGui::PopStyleColor();
2074  }
2075  else
2076  {
2077  ActorPtr player_actor = App::GetGameContext()->GetPlayerActor();
2078  int i = 0;
2079  for (ActorPtr& actor : actor_list)
2080  {
2081  std::string text_buf_rem = fmt::format("X ##[{}]", i);
2082  ImGui::PushStyleColor(ImGuiCol_Text, RED_TEXT);
2083  if (ImGui::Button(text_buf_rem.c_str()))
2084  {
2085  App::GetGameContext()->PushMessage(Message(MSG_SIM_DELETE_ACTOR_REQUESTED, static_cast<void*>(new ActorPtr(actor))));
2086  }
2087  ImGui::PopStyleColor();
2088  ImGui::SameLine();
2089 
2090  std::string text_buf = fmt::format( "[{}] {}", i++, StripColorMarksFromText(actor->ar_design_name).c_str());
2091  if (actor == player_actor)
2092  {
2093  ImGui::PushStyleColor(ImGuiCol_Text, GREEN_TEXT);
2094  }
2095  else if (std::find(actor->ar_linked_actors.begin(), actor->ar_linked_actors.end(), player_actor) != actor->ar_linked_actors.end())
2096  {
2097  ImGui::PushStyleColor(ImGuiCol_Text, ORANGE_TEXT);
2098  }
2099  else if (actor->ar_state == ActorState::LOCAL_SIMULATED)
2100  {
2101  ImGui::PushStyleColor(ImGuiCol_Text, WHITE_TEXT);
2102  }
2103  else
2104  {
2105  ImGui::PushStyleColor(ImGuiCol_Text, GRAY_HINT_TEXT);
2106  }
2107  if (ImGui::Button(text_buf.c_str())) // Button clicked?
2108  {
2109  App::GetGameContext()->PushMessage(Message(MSG_SIM_SEAT_PLAYER_REQUESTED, static_cast<void*>(new ActorPtr(actor))));
2110  }
2111  ImGui::PopStyleColor();
2112  }
2113  }
2114 }
2115 
2116 void DrawRepairBoxEvent(events ev, std::string const& desc)
2117 {
2118  ImDrawEventHighlighted(ev); ImGui::SameLine(); ImGui::TextDisabled(desc.c_str()); ImGui::NextColumn();
2119 }
2120 
2121 void DrawRepairBoxModkey(OIS::KeyCode modkey, std::string const& desc)
2122 {
2123  ImDrawModifierKeyHighlighted(modkey); ImGui::SameLine(); ImGui::TextDisabled(desc.c_str()); ImGui::NextColumn();
2124 }
2125 
2126 void TopMenubar::DrawSpecialStateBox(float top_offset)
2127 {
2128  float content_width = 0.f;
2129  // Always drawn on top:
2130  std::string special_text;
2131  ImVec4 special_color = ImGui::GetStyle().Colors[ImGuiCol_Text]; // Regular color
2132  float special_text_centering_weight = 1.f; // 0 = no centering
2133  // Only for race_box:
2134  std::string special_text_b;
2135  std::string special_text_c;
2136  std::string special_text_d;
2137  ImVec4 special_color_c = ImVec4(0,0,0,0);
2139 
2140  // Gather state info
2141  if (App::GetGameContext()->GetActorManager()->IsSimulationPaused() && !App::GetGuiManager()->IsGuiHidden())
2142  {
2143  special_color = ORANGE_TEXT;
2144  special_text = fmt::format(_LC("TopMenubar", "All physics paused, press {} to resume"),
2145  App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_TOGGLE_PHYSICS));
2146  content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2147  }
2148  else if (App::GetGameContext()->GetPlayerActor() &&
2149  App::GetGameContext()->GetPlayerActor()->ar_physics_paused &&
2150  !App::GetGuiManager()->IsGuiHidden())
2151  {
2152  special_color = GREEN_TEXT;
2153  special_text = fmt::format(_LC("TopMenubar", "Vehicle physics paused, press {} to resume"),
2154  App::GetInputEngine()->getEventCommandTrimmed(EV_TRUCK_TOGGLE_PHYSICS));
2155  content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2156  }
2157  else if (App::GetGameContext()->GetPlayerActor() &&
2158  App::GetGameContext()->GetPlayerActor()->ar_state == ActorState::LOCAL_REPLAY)
2159  {
2160  content_width = 300;
2162  special_text = _LC("TopMenubar", "Replay");
2163  }
2164  else if (App::GetGameContext()->GetRepairMode().IsLiveRepairActive())
2165  {
2166  special_text = fmt::format(_LC("TopMenubar", "Live repair mode, hit '{}' to stop"),
2167  App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_REPAIR_TRUCK));
2168  content_width = 450;
2170  special_color = GREEN_TEXT;
2171  special_text_centering_weight = 0.7f;
2172  }
2173  else if (App::GetGameContext()->GetRepairMode().IsQuickRepairActive())
2174  {
2175  special_text = fmt::format(_LC("TopMenubar", "Quick repair ('{}' for Live repair)"),
2176  App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_LIVE_REPAIR_MODE));
2177  content_width = 450;
2179  special_color = ORANGE_TEXT;
2180  special_text_centering_weight = 0.7f;
2181  }
2182  else if (App::GetGfxScene()->GetSimDataBuffer().simbuf_dir_arrow_visible)
2183  {
2185 
2186  // Calculate distance
2188  GUIManager::GuiTheme const& theme = App::GetGuiManager()->GetTheme();
2189  float distance = 0.0f;
2191  if (player_actor != nullptr && App::GetGameContext()->GetPlayerActor() &&
2193  {
2194  distance = player_actor->GetGfxActor()->GetSimDataBuffer().simbuf_pos.distance(data.simbuf_dir_arrow_target);
2195  }
2196  else
2197  {
2198  distance = data.simbuf_character_pos.distance(data.simbuf_dir_arrow_target);
2199  }
2200 
2201  // format text
2203  special_text_b = fmt::format("{:.1f} {}", distance, _LC("DirectionArrow", "meter"));
2204  content_width = ImGui::CalcTextSize(special_text.c_str()).x + ImGui::CalcTextSize(special_text_b.c_str()).x;
2205 
2207  special_text_c = fmt::format("{:02d}.{:02d}.{:02d}", (int)(time) / 60, (int)(time) % 60, (int)(time * 100.0) % 100);
2209  special_color_c = (time_diff > 0.0f)
2210  ? theme.value_red_text_color
2211  : ((time_diff < 0.0f) ? theme.success_text_color : theme.value_blue_text_color);
2212 
2214  {
2216  special_text_d = fmt::format("{:02d}.{:02d}.{:02d}", (int)(best_time) / 60, (int)(best_time) % 60, (int)(best_time * 100.0) % 100);
2217  }
2218  }
2219  else if (App::sim_state->getEnum<SimState>() == SimState::EDITOR_MODE)
2220  {
2221  special_color = GREEN_TEXT;
2222  special_text = fmt::format(_LC("TopMenubar", "Terrain editing mode, press {} to save and exit"),
2223  App::GetInputEngine()->getEventCommandTrimmed(EV_COMMON_TOGGLE_TERRAIN_EDITOR));
2224  content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2225  }
2226 
2227  // Draw box if needed
2228  if (!special_text.empty())
2229  {
2230  ImVec2 box_pos;
2231  box_pos.y = top_offset;
2232  box_pos.x = (ImGui::GetIO().DisplaySize.x / 2) - ((content_width / 2) + ImGui::GetStyle().FramePadding.x);
2233  ImGui::SetNextWindowPos(box_pos);
2234  ImGui::SetNextWindowSize(ImVec2(0.f, 0.f));
2235  ImGui::SetNextWindowContentWidth(content_width);
2236  ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
2237  ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse;
2238  ImGui::PushStyleColor(ImGuiCol_WindowBg, App::GetGuiManager()->GetTheme().semitransparent_window_bg);
2239  if (ImGui::Begin(special_text.c_str(), nullptr, flags))
2240  {
2242  {
2243  // Center the text, the box may be wider
2244  float text_w = ImGui::CalcTextSize(special_text.c_str()).x;
2245  ImGui::SetCursorPosX(((content_width / 2) - (text_w / 2)) * special_text_centering_weight);
2246  }
2247  ImGui::TextColored(special_color, "%s", special_text.c_str());
2248 
2250  {
2251  ImGui::SameLine();
2252 
2253  // Progress bar with frame index/count
2255  float fraction = (float)std::abs(replay->getCurrentFrame())/(float)replay->getNumFrames();
2256  Str<100> pbar_text; pbar_text << replay->getCurrentFrame() << "/" << replay->getNumFrames();
2257  float pbar_width = content_width - (ImGui::GetStyle().ItemSpacing.x + ImGui::CalcTextSize(special_text.c_str()).x);
2258  ImGui::ProgressBar(fraction, ImVec2(pbar_width, ImGui::GetTextLineHeight()), pbar_text.ToCStr());
2259 
2260  // Game time text
2261  float time_sec = replay->getLastReadTime() / 1000000.0;
2262  char str[200];
2263  int str_pos = 0;
2264  if (time_sec > 60)
2265  {
2266  int min = (int)time_sec / 60;
2267  str_pos = snprintf(str, 200, "%dmin ", min);
2268  time_sec -= (float)min * 60.f;
2269  }
2270  snprintf(str+str_pos, 200-str_pos, "%.2fsec", time_sec);
2271  ImGui::TextDisabled("%s: %s", _LC("TopMenubar", "Time"), str);
2272 
2273  }
2275  {
2276  ImGui::SameLine();
2277  ImGui::Text(special_text_b.c_str());
2278  ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2) - (ImGui::CalcTextSize(special_text_c.c_str()).x / 2));
2279  ImGui::TextColored(special_color_c,"%s", special_text_c.c_str());
2280 
2281  Str<300> text;
2282  text << "Best Time: " << special_text_d.c_str();
2283  ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2) - (ImGui::CalcTextSize(text).x / 2));
2284 
2285  if (!special_text_d.empty())
2286  {
2287  ImGui::TextDisabled(text);
2288  }
2289  }
2291  {
2292  // Draw special element on the right
2293  ImGui::SameLine();
2294  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.f, 0.f));
2296  {
2298  ImGui::ProgressBar(fraction, ImVec2(15.f, ImGui::GetTextLineHeight() / 2.f), "");
2299  ImGui::SameLine();
2300  }
2301  DrawGCheckbox(App::ui_show_live_repair_controls, _LC("LiveRepair", "Show controls"));
2302  ImGui::PopStyleVar(); // FramePadding
2303 
2304  const ImVec2 MINI_SPACING = ImVec2(2.f,0.f);
2305  ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, MINI_SPACING);
2306 
2307  if (App::ui_show_live_repair_controls->getBool())
2308  {
2309  const float INDENT = 15.f;
2310  ImGui::Separator();
2311  ImGui::TextDisabled("%s:", _LC("LiveRepair", "Movement"));
2312  ImGui::Columns(3);
2313  ImGui::SetColumnWidth(0, INDENT);
2314  ImGui::NextColumn();
2315  DrawRepairBoxEvent(EV_CHARACTER_FORWARD,_LC("LiveRepair", "Forward"));
2316  DrawRepairBoxEvent(EV_CHARACTER_BACKWARDS,_LC("LiveRepair", "Backward"));
2317  ImGui::NextColumn();
2318  DrawRepairBoxEvent(EV_CHARACTER_SIDESTEP_LEFT,_LC("LiveRepair", "Left"));
2319  DrawRepairBoxEvent(EV_CHARACTER_SIDESTEP_RIGHT,_LC("LiveRepair", "Right"));
2320  ImGui::NextColumn();
2321  DrawRepairBoxEvent(EV_TRUCK_ACCELERATE,_LC("LiveRepair", "Up"));
2322  DrawRepairBoxEvent(EV_TRUCK_BRAKE,_LC("LiveRepair", "Down"));
2323  ImGui::Columns(1);
2324 
2325  ImGui::TextDisabled("%s:", _LC("LiveRepair", "Rotation"));
2326  ImGui::Columns(3);
2327  ImGui::SetColumnWidth(0, INDENT);
2328  ImGui::NextColumn();
2329  DrawRepairBoxEvent(EV_TRUCK_STEER_LEFT,_LC("LiveRepair", "Rot. left"));
2330  DrawRepairBoxEvent(EV_TRUCK_STEER_RIGHT,_LC("LiveRepair", "Rot. right"));
2331  ImGui::Columns(1);
2332 
2333  ImGui::TextDisabled("%s:", _LC("LiveRepair", "Modifiers"));
2334  ImGui::Columns(4);
2335  ImGui::SetColumnWidth(0, INDENT);
2336  ImGui::SetColumnWidth(1, 125);
2337  ImGui::SetColumnWidth(2, 125);
2338  ImGui::NextColumn();
2339  DrawRepairBoxModkey(OIS::KC_LMENU,_LC("LiveRepair", "Slow step")); // Left alt
2340  DrawRepairBoxModkey(OIS::KC_LSHIFT,_LC("LiveRepair", "Fast step"));
2341  DrawRepairBoxModkey(OIS::KC_LCONTROL,_LC("LiveRepair", "10x step")); // Left ctrl
2342  ImGui::Columns(1);
2343 
2345  ImGui::TextDisabled("%s (%s):", _LC("LiveRepair", "Reset mode"), ToLocalizedString(resetmode).c_str());
2346  ImGui::Dummy(ImVec2(INDENT, 1.f));
2347  ImGui::SameLine();
2348  DrawRepairBoxEvent(EV_COMMON_TOGGLE_RESET_MODE,_LC("LiveRepair", "Switch reset mode"));
2349  }
2350  ImGui::PopStyleVar(); // ItemSpacing
2351  }
2352  const ImVec2 PAD = ImVec2(5, 5); // To bridge top menubar hoverbox and statebox hoverbox
2353  m_state_box_hoverbox_min = box_pos - PAD;
2354  m_state_box_hoverbox_max.x = box_pos.x + ImGui::GetWindowWidth();
2355  m_state_box_hoverbox_max.y = box_pos.y + ImGui::GetWindowHeight();
2356  m_state_box_hoverbox_max += PAD;
2357  // DO NOT `RequestGuiCaptureKeyboard()` - we want to use the hotkeys through it.
2358  ImGui::End();
2359  }
2360  ImGui::PopStyleColor(1); // WindowBg
2361  }
2362 }
2363 
2365 {
2366  // Load 'bundled' AI presets - see section `[AI Presets]` in terrn2 file format
2367  // ----------------------------------------------------------------------------
2368 
2370 
2371  for (const std::string& filename: terrain->GetDef().ai_presets_files)
2372  {
2373  rapidjson::Document j_doc;
2374  if (Ogre::ResourceGroupManager::getSingleton().resourceExists(terrain->getTerrainFileResourceGroup(), filename))
2375  {
2377  }
2378  else
2379  {
2380  LOG(fmt::format("[RoR|Terrain] AI presets file '{}' declared in '{}' not found!", filename, terrain->getTerrainFileName()));
2381  }
2382 
2383  // Ensure the format is about right
2384  if (!j_doc.IsArray())
2385  {
2386  LOG(fmt::format("[RoR|Terrain] AI presets file '{}' declared in '{}' has wrong format - the root element is not an array!",
2387  filename, terrain->getTerrainFileName()));
2388  }
2389  else
2390  {
2391  // Finally add the presets to the list
2392  for (const rapidjson::Value& j_bundled_preset: j_doc.GetArray())
2393  {
2394  rapidjson::Value preset_copy(j_bundled_preset, App::GetGuiManager()->TopMenubar.ai_presets_bundled.GetAllocator());
2396  }
2397  }
2398  }
2399 
2401 }
2402 
2404 {
2405 #if defined(USE_CURL)
2406  std::packaged_task<void()> task(FetchAiPresetsThreadFunc);
2407  std::thread(std::move(task)).detach();
2409 #endif // defined(USE_CURL)
2410 }
2411 
2413 {
2414  // Combine external and bundled presets into one JSON doc
2415  // -------------------------------------------------------
2416 
2417  ai_presets_all.Clear();
2418  ai_presets_all.SetArray();
2419 
2420  for (rapidjson::Value& bundled_preset: ai_presets_bundled.GetArray())
2421  {
2422  rapidjson::Value preset_copy(bundled_preset, ai_presets_all.GetAllocator());
2423  ai_presets_all.PushBack(preset_copy, ai_presets_all.GetAllocator());
2424  }
2425 
2426  for (const rapidjson::Value& extern_preset: ai_presets_extern.GetArray())
2427  {
2428  rapidjson::Value preset_copy(extern_preset, ai_presets_all.GetAllocator());
2429  ai_presets_all.PushBack(preset_copy, ai_presets_all.GetAllocator());
2430  }
2431 }
2432 
2434 {
2435  // Updates/resets the tuning menu for the current vehicle driven by player (if any).
2436  // -------------------------------------------------------------------------------
2437 
2438  if (App::sim_tuning_enabled->getBool()
2439  && (App::mp_state->getEnum<MpState>() != MpState::CONNECTED)
2440  && App::GetGameContext()->GetPlayerActor()
2441  && (tuning_actor != App::GetGameContext()->GetPlayerActor()))
2442  {
2445 
2446  tuning_addonparts.clear();
2448 
2449  // Addonparts matched by GUID
2450  if (tuning_actor->getUsedActorEntry()->guid != "")
2451  {
2452  CacheQuery query_addonparts;
2453  query_addonparts.cqy_filter_type = LT_AddonPart;
2454  query_addonparts.cqy_filter_guid = tuning_actor->getUsedActorEntry()->guid;
2455  query_addonparts.cqy_filter_target_filename = tuning_actor->getTruckFileName(); // Addonparts without any filenames listed will just pass.
2456  App::GetCacheSystem()->Query(query_addonparts);
2457  for (CacheQueryResult& res: query_addonparts.cqy_results)
2458  {
2459  tuning_addonparts.push_back(res.cqr_entry);
2460  }
2461  }
2462 
2463  // Addonparts force-installed via [browse all] button; watch for duplicates.
2465  {
2466  for (std::string const& use_addonpart_fname: tuning_actor->getWorkingTuneupDef()->use_addonparts)
2467  {
2468  CacheEntryPtr entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*partial:*/false, use_addonpart_fname);
2469  if (entry)
2470  {
2471  if (std::find(tuning_addonparts.begin(), tuning_addonparts.end(), entry) == tuning_addonparts.end())
2472  {
2473  tuning_addonparts.push_back(entry);
2474  }
2475  }
2476  }
2477  }
2478 
2482  tuning_saves.cqy_filter_category_id = CID_Tuneups; // Exclude auto-generated entries
2485 
2486  // Refresh `tuning_conflicts` database ~ test eligible addonparts each with each once.
2487  tuning_conflicts.clear();
2488  for (size_t i1 = 0; i1 < tuning_addonparts.size(); i1++)
2489  {
2490  for (size_t i2 = i1; i2 < tuning_addonparts.size(); i2++)
2491  {
2492  if (i1 != i2)
2493  {
2495  }
2496  }
2497  }
2498 
2499  // Refresh `tuning_addonparts_conflicting` listing ~ test used addonparts against unused.
2503  {
2504  for (const std::string& use_addonpart_fname: tuning_actor->getWorkingTuneupDef()->use_addonparts)
2505  {
2506  CacheEntryPtr use_addonpart_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AddonPart, /*partial:*/false, use_addonpart_fname);
2507  for (size_t i = 0; i < tuning_addonparts.size(); i++)
2508  {
2509  if (tuning_addonparts[i] != use_addonpart_entry)
2510  {
2513  }
2514  }
2515  }
2516  }
2517 
2519  }
2520  else if (!App::sim_tuning_enabled->getBool() || !App::GetGameContext()->GetPlayerActor())
2521  {
2522  tuning_addonparts.clear();
2524  tuning_actor = nullptr;
2525  }
2526 }
2527 
2528 void TopMenubar::DrawTuningProtectedChkRightAligned(const int subject_id, bool protectchk_value, ModifyProjectRequestType request_type_set, ModifyProjectRequestType request_type_reset, const std::string& subject /* ="" */)
2529 {
2530  // > resolve the alignment
2531  ImGui::SameLine();
2532  if (tuning_rwidget_cursorx_min < ImGui::GetCursorPosX()) // Make sure button won't draw over item name
2533  tuning_rwidget_cursorx_min = ImGui::GetCursorPosX();
2534  std::string protectchk_text = _LC("Tuning", "Protected");
2535  float protectchk_w = ImGui::CalcTextSize(protectchk_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
2536  float protectchk_cursorx = (ImGui::GetWindowContentRegionWidth() - protectchk_w) - 20.f;
2537  if (protectchk_cursorx < tuning_rwidget_cursorx_min)
2538  protectchk_cursorx = tuning_rwidget_cursorx_min;
2539  ImGui::SetCursorPosX(protectchk_cursorx);
2540 
2541  // > set styling and draw
2542  ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
2543  bool chk_pressed = ImGui::Checkbox(protectchk_text.c_str(), &protectchk_value);
2544  ImGui::PopStyleVar(1); // ImGuiStyleVar_FramePadding
2545 
2546  // > handle user action
2547  if (chk_pressed)
2548  {
2549  ModifyProjectRequest* request = new ModifyProjectRequest();
2550  request->mpr_target_actor = tuning_actor;
2551  if (subject_id == TUNING_SUBJECTID_USE_NAME)
2552  {
2553  request->mpr_subject = subject;
2554  }
2555  else
2556  {
2557  request->mpr_subject_id = subject_id;
2558  }
2559  request->mpr_type = (protectchk_value) ? request_type_set : request_type_reset;
2561  }
2562 }
2563 
2565 {
2566  // Draw subject ID in outlined box
2567  // -------------------------------
2568  ImGui::GetWindowDrawList()->AddRect(
2569  ImGui::GetCursorScreenPos(),
2570  ImGui::GetCursorScreenPos() + ImGui::CalcTextSize("00") + ImGui::GetStyle().FramePadding*2,
2571  ImColor(ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]),
2572  ImGui::GetStyle().FrameRounding);
2573  ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().FramePadding.x);
2574  ImGui::Text("%02d", subject_id);
2575  ImGui::SameLine();
2576  ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().FramePadding.x);
2577 }
2578 
2579 void TopMenubar::DrawTuningForceRemoveControls(const int subject_id, const std::string& name, const bool is_unwanted, const bool is_force_removed, ModifyProjectRequestType request_type_set, ModifyProjectRequestType request_type_reset)
2580 {
2581  // Common for props and flexbodies: draws the force-remove checkbox and the reset button
2582  // ------------------------------------------------------------------------------------
2583 
2584  // Draw the checkbox for force-removing.
2585  bool isEnabled = !is_unwanted && !is_force_removed;
2586  if (is_force_removed)
2587  {
2588  ImGui::PushStyleColor(ImGuiCol_Border, ORANGE_TEXT);
2589  ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f);
2590  }
2591  bool chkPressed = ImGui::Checkbox(name.c_str(), &isEnabled);
2592  bool resetPressed = false;
2593  if (is_force_removed)
2594  {
2595  ImGui::SameLine();
2596  ImGui::PushStyleColor(ImGuiCol_Text, GRAY_HINT_TEXT);
2597  resetPressed = ImGui::SmallButton(_LC("Tuning", "Reset"));
2598  ImGui::PopStyleColor(); //ImGuiCol_Text, GRAY_HINT_TEXT
2599  ImGui::PopStyleVar(); //ImGuiStyleVar_FrameBorderSize, 1.f
2600  ImGui::PopStyleColor(); //ImGuiCol_Border, ORANGE_TEXT
2601  }
2602 
2603  // perform project modification if needed
2604  if (chkPressed && !isEnabled)
2605  {
2607  req->mpr_type = request_type_set;
2608  if (subject_id == TUNING_SUBJECTID_USE_NAME)
2609  {
2610  req->mpr_subject = name;
2611  }
2612  else
2613  {
2614  req->mpr_subject_id = subject_id;
2615  }
2618  }
2619  else if ((chkPressed && isEnabled) || resetPressed)
2620  {
2622  req->mpr_type = request_type_reset;
2623  if (subject_id == TUNING_SUBJECTID_USE_NAME)
2624  {
2625  req->mpr_subject = name;
2626  }
2627  else
2628  {
2629  req->mpr_subject_id = subject_id;
2630  }
2633  }
2634 
2635 }
2636 
2638 {
2639  switch (which)
2640  {
2641  case TopMenu::TOPMENU_AI:
2645  default:
2646  return true;
2647  }
2648 }
RoR::GUI::TopMenubar::m_quickload
bool m_quickload
Definition: GUI_TopMenubar.h:149
RoR::MSG_EDI_MODIFY_PROJECT_REQUESTED
@ MSG_EDI_MODIFY_PROJECT_REQUESTED
Payload = RoR::UpdateProjectRequest* (owner)
Definition: Application.h:151
ROR_ASSERT
#define ROR_ASSERT(_EXPR)
Definition: Application.h:40
GameContext.h
Game state manager and message-queue provider.
RoR::GUI::TopMenubar::m_confirm_remove_all
bool m_confirm_remove_all
Definition: GUI_TopMenubar.h:145
RoR::App::diag_truck_mass
CVar * diag_truck_mass
Definition: Application.cpp:137
RoR::GUIManager::VehicleInfoTPanel
GUI::VehicleInfoTPanel VehicleInfoTPanel
Definition: GUIManager.h:107
RoR::MSG_SIM_LOAD_TERRN_REQUESTED
@ MSG_SIM_LOAD_TERRN_REQUESTED
Definition: Application.h:116
RoR::App::gfx_envmap_rate
CVar * gfx_envmap_rate
Definition: Application.cpp:233
RoR::GUI::TopMenubar::ShouldDisplay
bool ShouldDisplay(ImVec2 window_pos)
Definition: GUI_TopMenubar.cpp:1939
RoR::GUI::TopMenubar::GRAY_HINT_TEXT
const ImVec4 GRAY_HINT_TEXT
Definition: GUI_TopMenubar.h:51
DrawRepairBoxEvent
void DrawRepairBoxEvent(events ev, std::string const &desc)
Definition: GUI_TopMenubar.cpp:2116
RoR::App::gfx_polygon_mode
CVar * gfx_polygon_mode
Definition: Application.cpp:216
RoR::GUI::ConsoleWindow::IsVisible
bool IsVisible() const
Definition: GUI_ConsoleWindow.h:47
RoR::EV_SURVEY_MAP_CYCLE
@ EV_SURVEY_MAP_CYCLE
cycle overview-map mode
Definition: InputEngine.h:292
RoR::App::GetNetwork
Network * GetNetwork()
Definition: Application.cpp:284
RoR::TuneupDef::isFlexbodyForceRemoved
bool isFlexbodyForceRemoved(FlexbodyID_t flexbodyid)
Definition: TuneupFileFormat.h:170
RoR::GUI::TopMenubar::MENU_HOVERBOX_PADDING
const ImVec2 MENU_HOVERBOX_PADDING
Definition: GUI_TopMenubar.h:56
RoR::App::GetContentManager
ContentManager * GetContentManager()
Definition: Application.cpp:267
RoR::GUI::TopMenubar::StateBox::STATEBOX_NONE
@ STATEBOX_NONE
RoR::GUI::TopMenubar::ai_presets_extern
rapidjson::Document ai_presets_extern
Externally provided presets (GitHub repo or local 'savegames/waypoints.json' file).
Definition: GUI_TopMenubar.h:105
RoR::ModifyProjectRequest::mpr_subject
std::string mpr_subject
Definition: CacheSystem.h:271
RoR::SimResetMode
SimResetMode
Definition: Application.h:275
RoR::GUI::TopMenubar::DrawTuningBoxedSubjectIdInline
void DrawTuningBoxedSubjectIdInline(int subject_id)
Definition: GUI_TopMenubar.cpp:2564
RoR::TuneupUtil::isAddonPartUsed
static bool isAddonPartUsed(TuneupDefPtr &tuneup_entry, const std::string &filename)
Definition: TuneupFileFormat.cpp:540
RoR::GUI::TopMenubar::FetchExternAiPresetsOnBackground
void FetchExternAiPresetsOnBackground()
Initiate threaded (down)load of 'extern' waypoints from GitHub repo.
Definition: GUI_TopMenubar.cpp:2403
RoR::CacheEntry::dname
Ogre::String dname
name parsed from the file
Definition: CacheSystem.h:70
RoR::GUI::TopMenubar::tuning_savebox_buf
Str< 200 > tuning_savebox_buf
Buffer for tuneup name to be saved.
Definition: GUI_TopMenubar.h:116
ai_events::position
Ogre::Vector3 position
Definition: GUI_TopMenubar.h:39
RoR::GUI::TopMenubar::GREEN_TEXT
const ImVec4 GREEN_TEXT
Definition: GUI_TopMenubar.h:53
RoR::ActorModifyRequest::Type::WAKE_UP
@ WAKE_UP
RoR::App::gfx_fov_internal
CVar * gfx_fov_internal
Definition: Application.cpp:240
y
float y
Definition: (ValueTypes) quaternion.h:6
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_PROP_SET
@ TUNEUP_FORCEREMOVE_PROP_SET
'subject_id' is prop ID.
RoR::Network::GetUserInfos
std::vector< RoRnet::UserInfo > GetUserInfos()
Definition: Network.cpp:703
RoR::GUI::TopMenubar::ai_num
int ai_num
Definition: GUI_TopMenubar.h:72
RoR::ModifyProjectRequest::mpr_subject_id
int mpr_subject_id
Definition: CacheSystem.h:272
RoR::GUIManager::GuiTheme::value_red_text_color
ImVec4 value_red_text_color
Definition: GUIManager.h:74
RoR::MSG_SIM_MODIFY_ACTOR_REQUESTED
@ MSG_SIM_MODIFY_ACTOR_REQUESTED
Payload = RoR::ActorModifyRequest* (owner)
Definition: Application.h:120
RoR::App::mp_hide_net_labels
CVar * mp_hide_net_labels
Definition: Application.cpp:118
RoR::StripColorMarksFromText
std::string StripColorMarksFromText(std::string const &text)
Definition: GUIUtils.cpp:199
RoR::DrawGFloatSlider
void DrawGFloatSlider(CVar *cvar, const char *label, float v_min, float v_max)
Definition: GUIUtils.cpp:300
RoR::FetchIcon
Ogre::TexturePtr FetchIcon(const char *name)
Definition: GUIUtils.cpp:344
RoR::EV_COMMON_REPAIR_TRUCK
@ EV_COMMON_REPAIR_TRUCK
repair truck to original condition
Definition: InputEngine.h:250
RoR::RepairMode::GetLiveRepairTimer
float GetLiveRepairTimer() const
Definition: RepairMode.h:44
RoR::EV_COMMON_TOGGLE_PHYSICS
@ EV_COMMON_TOGGLE_PHYSICS
toggle physics on/off
Definition: InputEngine.h:271
RoR::TuneupDef::isManagedMatProtected
bool isManagedMatProtected(const std::string &matname) const
Definition: TuneupFileFormat.h:155
RoR::MSG_EDI_RELOAD_BUNDLE_REQUESTED
@ MSG_EDI_RELOAD_BUNDLE_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
Definition: Application.h:148
RoR::GUI::TopMenubar::TopMenubar
TopMenubar()
Definition: GUI_TopMenubar.cpp:139
RoR::ActorManager::SaveScene
bool SaveScene(Ogre::String filename)
Definition: Savegame.cpp:421
RoR::MpState::CONNECTED
@ CONNECTED
RoR::Network::UserAuthToStringShort
std::string UserAuthToStringShort(RoRnet::UserInfo const &user)
Definition: Network.cpp:796
RoR::GUIManager::FrictionSettings
GUI::FrictionSettings FrictionSettings
Definition: GUIManager.h:114
RoR::GUI::TopMenubar::TopMenu::TOPMENU_TUNING
@ TOPMENU_TUNING
RoR::Str::GetBuffer
char * GetBuffer()
Definition: Str.h:48
RoR::GfxScene::GetSimDataBuffer
GameContextSB & GetSimDataBuffer()
Definition: GfxScene.h:61
RoR::CacheQuery::cqy_filter_category_id
int cqy_filter_category_id
Definition: CacheSystem.h:185
RoR::GUI::TopMenubar::ai_presets_all
rapidjson::Document ai_presets_all
The full list of presets, used for display. Needs to be refreshed when terrain is loaded.
Definition: GUI_TopMenubar.h:104
RoR::GameContextSB
Definition: SimBuffers.h:196
RoR::LT_AddonPart
@ LT_AddonPart
Definition: Application.h:304
RoR::GUIManager::GuiTheme
Definition: GUIManager.h:68
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_FLEXBODY_SET
@ TUNEUP_PROTECTED_FLEXBODY_SET
'subject_id' is flexbody ID.
RoR::ActorSpawnRequest::asr_origin
Origin asr_origin
Definition: SimData.h:857
RoR::GUI::TopMenubar::DrawSpecialStateBox
void DrawSpecialStateBox(float top_offset)
Definition: GUI_TopMenubar.cpp:2126
RoR::CacheEntryPtr
RefCountingObjectPtr< CacheEntry > CacheEntryPtr
Definition: ForwardDeclarations.h:197
RoR::GameContextSB::simbuf_race_time
float simbuf_race_time
Definition: SimBuffers.h:209
RoR::ModifyProjectRequestType
ModifyProjectRequestType
Definition: CacheSystem.h:232
RoR::App::GetGuiManager
GUIManager * GetGuiManager()
Definition: Application.cpp:269
RoR::GUIManager::GuiTheme::value_blue_text_color
ImVec4 value_blue_text_color
Definition: GUIManager.h:75
RoR::MSG_EDI_CREATE_PROJECT_REQUESTED
@ MSG_EDI_CREATE_PROJECT_REQUESTED
Payload = RoR::CreateProjectRequest* (owner)
Definition: Application.h:150
RoR::App::sim_soft_reset_mode
CVar * sim_soft_reset_mode
Definition: Application.cpp:109
RoR::GUI::VehicleInfoTPanel::TPANELMODE_OPAQUE
@ TPANELMODE_OPAQUE
Definition: GUI_VehicleInfoTPanel.h:37
DrawRepairBoxModkey
void DrawRepairBoxModkey(OIS::KeyCode modkey, std::string const &desc)
Definition: GUI_TopMenubar.cpp:2121
RoRnet::UserInfo
Definition: RoRnet.h:168
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_PROP_RESET
@ TUNEUP_FORCEREMOVE_PROP_RESET
'subject_id' is prop ID.
RoR::GUI::TopMenubar::ai_position_scheme
int ai_position_scheme
Definition: GUI_TopMenubar.h:77
RoR::EV_COMMON_TOGGLE_RESET_MODE
@ EV_COMMON_TOGGLE_RESET_MODE
toggle truck reset truck mode (soft vs. hard)
Definition: InputEngine.h:258
DashBoardManager.h
RoR::Actor::ar_instance_id
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition: Actor.h:376
RoR::CacheSystem::FindEntryByFilename
CacheEntryPtr FindEntryByFilename(RoR::LoaderType type, bool partial, const std::string &filename)
Returns NULL if none found.
Definition: CacheSystem.cpp:184
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_FLEXBODY_SET
@ TUNEUP_FORCEREMOVE_FLEXBODY_SET
'subject_id' is flexbody ID.
z
float z
Definition: (ValueTypes) quaternion.h:7
RoR::GUI::TopMenubar::ai_position_scheme_prev
int ai_position_scheme_prev
Definition: GUI_TopMenubar.h:96
SkyManager.h
RoR::App::gfx_fixed_cam_tracking
CVar * gfx_fixed_cam_tracking
Definition: Application.cpp:243
RoR::MSG_SIM_UNLOAD_TERRN_REQUESTED
@ MSG_SIM_UNLOAD_TERRN_REQUESTED
Definition: Application.h:118
RoR::DashData
DashData
Definition: DashBoardManager.h:84
RoR::GUI::TopMenubar::m_quicksave_name
std::string m_quicksave_name
Definition: GUI_TopMenubar.h:150
ContentManager.h
GUI_TopMenubar.h
RoR::CreateProjectRequestType::SAVE_TUNEUP
@ SAVE_TUNEUP
Dumps .tuneup file with CID_Tuneup from source actor, will not overwrite existing unless explicitly i...
RoR::Actor::exhausts
std::vector< exhaust_t > exhausts
Definition: Actor.h:298
RoR::Terrain::getTerrainFileResourceGroup
std::string getTerrainFileResourceGroup()
Definition: Terrain.cpp:555
RoR::ActorState::LOCAL_REPLAY
@ LOCAL_REPLAY
RoR::App::sim_live_repair_interval
CVar * sim_live_repair_interval
Hold EV_COMMON_REPAIR_TRUCK to enter LiveRepair mode. 0 or negative interval disables.
Definition: Application.cpp:111
format
Truck file format(technical spec)
GUIUtils.h
RoR::Terrain::getSkyManager
SkyManager * getSkyManager()
Definition: Terrain.cpp:513
RoR::ActorManager::AreTrucksForcedAwake
bool AreTrucksForcedAwake() const
Definition: ActorManager.h:91
CurlWriteFunc
static size_t CurlWriteFunc(void *ptr, size_t size, size_t nmemb, std::string *data)
Definition: GUI_TopMenubar.cpp:70
RoR::GUI::TopMenubar::MENU_Y_OFFSET
const float MENU_Y_OFFSET
Definition: GUI_TopMenubar.h:49
RoR::HandleGenericException
void HandleGenericException(const std::string &from, BitMask_t flags)
Definition: Application.cpp:369
RoR::LT_Tuneup
@ LT_Tuneup
Definition: Application.h:305
RoR::CreateProjectRequest::cpr_type
CreateProjectRequestType cpr_type
Definition: CacheSystem.h:228
RoR::GUIManager::TextureToolWindow
GUI::TextureToolWindow TextureToolWindow
Definition: GUIManager.h:115
RoR::GameContext::GetPlayerCharacter
Character * GetPlayerCharacter()
Definition: GameContext.cpp:873
RoR::ImDrawModifierKeyHighlighted
void ImDrawModifierKeyHighlighted(OIS::KeyCode key)
Definition: GUIUtils.cpp:451
RoR::Str::GetCapacity
size_t GetCapacity() const
Definition: Str.h:49
RoR::GUI::TopMenubar::ai_altitude
int ai_altitude
Definition: GUI_TopMenubar.h:75
RoR::CVar::getBool
bool getBool() const
Definition: CVar.h:98
RoR::SimState::EDITOR_MODE
@ EDITOR_MODE
Hacky, but whatever... added by Ulteq, 2016.
RoR::ModifyProjectRequestType::TUNEUP_USE_ADDONPART_RESET
@ TUNEUP_USE_ADDONPART_RESET
'subject' is addonpart filename.
RoR::MpState
MpState
Definition: Application.h:169
RoR::GUI::ConsoleWindow::SetVisible
void SetVisible(bool visible)
Definition: GUI_ConsoleWindow.h:46
RoR::FlareType::USER
@ USER
RoR::CacheQuery
Definition: CacheSystem.h:182
RoR::EV_CHARACTER_BACKWARDS
@ EV_CHARACTER_BACKWARDS
step backwards with the character
Definition: InputEngine.h:129
CameraManager.h
RoR::Terrain::GetDef
Terrn2Def & GetDef()
Definition: Terrain.h:63
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_WHEEL_RESET
@ TUNEUP_PROTECTED_WHEEL_RESET
'subject_id' is wheel ID.
RoR::GameContextSB::simbuf_dir_arrow_text
std::string simbuf_dir_arrow_text
Definition: SimBuffers.h:215
RoR::EV_COMMON_LIVE_REPAIR_MODE
@ EV_COMMON_LIVE_REPAIR_MODE
toggles live repair and recovery mode, controlled by keyboard
Definition: InputEngine.h:251
RoR::GUI::TopMenubar::PANEL_HOVERBOX_HEIGHT
const float PANEL_HOVERBOX_HEIGHT
Definition: GUI_TopMenubar.h:50
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_FLEXBODY_RESET
@ TUNEUP_PROTECTED_FLEXBODY_RESET
'subject_id' is flexbody ID.
Console.h
RoR::GfxWaterMode::NONE
@ NONE
None.
RoR::TuneupDef::isFlexbodyProtected
bool isFlexbodyProtected(FlexbodyID_t flexbodyid) const
Definition: TuneupFileFormat.h:150
RoR::Console::putMessage
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition: Console.cpp:97
RoR::GUI::TopMenubar::TopMenu
TopMenu
Definition: GUI_TopMenubar.h:59
RoR::GUI::TopMenubar::TopMenu::TOPMENU_SAVEGAMES
@ TOPMENU_SAVEGAMES
RoR::DrawGIntSlider
void DrawGIntSlider(CVar *cvar, const char *label, int v_min, int v_max)
Definition: GUIUtils.cpp:290
RoR::ActorSpawnRequest::asr_working_tuneup
TuneupDefPtr asr_working_tuneup
Only filled when editing tuneup via Tuning menu.
Definition: SimData.h:856
RoR::FlareType
FlareType
Definition: SimData.h:229
TuneupFileFormat.h
The vehicle tuning system; applies addonparts and user overrides to vehicles.
RoR::GameContextSB::simbuf_character_pos
Ogre::Vector3 simbuf_character_pos
Definition: SimBuffers.h:202
RoR::App::gfx_static_cam_fov_exp
CVar * gfx_static_cam_fov_exp
Definition: Application.cpp:242
RoR::Actor::GetGfxActor
GfxActor * GetGfxActor()
Definition: Actor.h:269
RoR::TuneupDef::use_addonparts
std::set< std::string > use_addonparts
Addonpart filenames.
Definition: TuneupFileFormat.h:109
RoR::ScriptEngine::loadScript
ScriptUnitId_t loadScript(Ogre::String scriptname, ScriptCategory category=ScriptCategory::TERRAIN, ActorPtr associatedActor=nullptr, std::string buffer="")
Loads a script.
Definition: ScriptEngine.cpp:759
RoR::ModifyProjectRequestType::TUNEUP_USE_ADDONPART_SET
@ TUNEUP_USE_ADDONPART_SET
'subject' is addonpart filename.
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_RESET
@ TUNEUP_PROTECTED_EXHAUST_RESET
'subject_id' is exhaust ID.
RoR::GUI::TopMenubar::ai_waypoints
std::vector< ai_events > ai_waypoints
Definition: GUI_TopMenubar.h:68
RoR::TuneupDef::isExhaustUnwanted
bool isExhaustUnwanted(ExhaustID_t exhaustid)
Definition: TuneupFileFormat.h:163
RoR::TuneupDef::isPropUnwanted
bool isPropUnwanted(PropID_t propid)
Definition: TuneupFileFormat.h:160
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_MANAGEDMAT_SET
@ TUNEUP_PROTECTED_MANAGEDMAT_SET
'subject' is managed material name.
RoR::ActorState::LOCAL_SIMULATED
@ LOCAL_SIMULATED
simulated (local) actor
RoR::App::sim_state
CVar * sim_state
Definition: Application.cpp:96
RoR::GUI::TopMenubar::TopMenu::TOPMENU_NONE
@ TOPMENU_NONE
Language.h
RoR::App::sys_savegames_dir
CVar * sys_savegames_dir
Definition: Application.cpp:170
RoR::GUIManager::GuiTheme::semitransparent_window_bg
ImVec4 semitransparent_window_bg
Definition: GUIManager.h:81
RoR::GameContextSB::simbuf_player_actor
ActorPtr simbuf_player_actor
Definition: SimBuffers.h:201
RoR::Actor::ar_dashboard
DashBoardManager * ar_dashboard
Definition: Actor.h:433
RoR::CacheQueryResult::cqr_entry
CacheEntryPtr cqr_entry
Definition: CacheSystem.h:168
RoR::GUI::TopMenubar::LoadBundledAiPresets
void LoadBundledAiPresets(TerrainPtr terrain)
Loads JSON files from [AI Presets] section in .terrn2 file format.
Definition: GUI_TopMenubar.cpp:2364
RefCountingObjectPtr< Actor >
RoR::GUI::TopMenubar::m_waves_height
float m_waves_height
Definition: GUI_TopMenubar.h:148
RoR::DashBoardManager::getLinkNameForID
std::string getLinkNameForID(DashData id)
Definition: DashBoardManager.cpp:161
GUIManager.h
RoR::CreateProjectRequest::cpr_source_entry
CacheEntryPtr cpr_source_entry
The original mod to copy files from.
Definition: CacheSystem.h:226
ActorManager.h
RoR::GUI::TopMenubar::tuning_conflicts
AddonPartConflictVec tuning_conflicts
Conflicts between eligible addonparts tweaking the same element.
Definition: GUI_TopMenubar.h:114
Actor.h
RoR::CreateProjectRequest::cpr_name
std::string cpr_name
Directory and also the mod file (without extension).
Definition: CacheSystem.h:224
RoR::ExhaustID_t
int ExhaustID_t
Index into Actor::exhausts, use RoR::EXHAUSTID_INVALID as empty value.
Definition: ForwardDeclarations.h:71
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_MANAGEDMAT_SET
@ TUNEUP_FORCEREMOVE_MANAGEDMAT_SET
'subject' is managed material name.
RoR::App::GetScriptEngine
ScriptEngine * GetScriptEngine()
Definition: Application.cpp:279
w
float w
Definition: (ValueTypes) quaternion.h:4
RoR::GUI::TopMenubar::DrawTuningProtectedChkRightAligned
void DrawTuningProtectedChkRightAligned(const int subject_id, bool is_protected, ModifyProjectRequestType request_type_set, ModifyProjectRequestType request_type_reset, const std::string &subject="")
Definition: GUI_TopMenubar.cpp:2528
RoR::GUI::TopMenubar::ai_menu
bool ai_menu
Definition: GUI_TopMenubar.h:85
RoR::Console::CONSOLE_SYSTEM_NOTICE
@ CONSOLE_SYSTEM_NOTICE
Definition: Console.h:51
RoR::ActorSpawnRequest
Definition: SimData.h:832
RoR::ActorManager::SendAllActorsSleeping
void SendAllActorsSleeping()
Definition: ActorManager.cpp:795
RoR::Terrain::getTerrainFileName
std::string getTerrainFileName()
Definition: Terrain.cpp:550
RoR::GUI::TopMenubar::tuning_savebox_visible
bool tuning_savebox_visible
User pressed 'save active' to open savebox.
Definition: GUI_TopMenubar.h:117
RoR::GUI::TopMenubar::ai_num_prev
int ai_num_prev
Definition: GUI_TopMenubar.h:94
RoR::TuneupDef::isPropProtected
bool isPropProtected(PropID_t propid) const
Definition: TuneupFileFormat.h:149
RoR::GUI::TopMenubar::StateBox::STATEBOX_QUICK_REPAIR
@ STATEBOX_QUICK_REPAIR
RoR::App::sim_tuning_enabled
CVar * sim_tuning_enabled
Definition: Application.cpp:112
RoR::GameContextSB::simbuf_race_best_time
float simbuf_race_best_time
Definition: SimBuffers.h:210
RoR::GUI::TopMenubar::ai_rec
bool ai_rec
Definition: GUI_TopMenubar.h:83
RoR::App::mp_state
CVar * mp_state
Definition: Application.cpp:115
RoR::ModifyProjectRequestType::TUNEUP_FORCED_WHEEL_SIDE_SET
@ TUNEUP_FORCED_WHEEL_SIDE_SET
'subject_id' is wheel ID, 'value_int' is RoR::WheelSide
RoR::GUI::TopMenubar::ai_speed
int ai_speed
Definition: GUI_TopMenubar.h:73
Replay.h
RoR::ActorModifyRequest::amr_actor
ActorInstanceID_t amr_actor
Definition: SimData.h:886
RoR::Actor::getReplay
Replay * getReplay()
Definition: Actor.cpp:4561
RoR::EV_TRUCK_STEER_LEFT
@ EV_TRUCK_STEER_LEFT
steer left
Definition: InputEngine.h:357
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_FLARE_RESET
@ TUNEUP_PROTECTED_FLARE_RESET
'subject_id' is flare ID.
RoR::App::gfx_camera_height
CVar * gfx_camera_height
Definition: Application.cpp:237
RoR::CameraManager::CAMERA_BEHAVIOR_STATIC
@ CAMERA_BEHAVIOR_STATIC
Definition: CameraManager.h:47
RoR::App::audio_master_volume
CVar * audio_master_volume
Definition: Application.cpp:209
RoR::GUI::TopMenubar::TopMenu::TOPMENU_SIM
@ TOPMENU_SIM
Script2Game::KC_LSHIFT
enum Script2Game::inputEvents KC_LSHIFT
RoR::MSG_NET_FETCH_AI_PRESETS_FAILURE
@ MSG_NET_FETCH_AI_PRESETS_FAILURE
Description = message.
Definition: Application.h:112
RoR::GUIManager::GetTheme
GuiTheme & GetTheme()
Definition: GUIManager.h:154
RoR::ActorSpawnRequest::asr_config
Ogre::String asr_config
Definition: SimData.h:850
RoR::GUI::TopMenubar::tuning_rwidget_cursorx_min
float tuning_rwidget_cursorx_min
Avoid drawing right-side widgets ('Delete' button or 'Protected' chk) over saved tuneup names.
Definition: GUI_TopMenubar.h:121
RoR::GUI::TopMenubar::WHITE_TEXT
const ImVec4 WHITE_TEXT
Definition: GUI_TopMenubar.h:52
RoR::FlareType::DASHBOARD
@ DASHBOARD
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_FLARE_RESET
@ TUNEUP_FORCEREMOVE_FLARE_RESET
'subject_id' is flare ID.
RoR::ToLocalizedString
std::string ToLocalizedString(SimGearboxMode e)
Definition: Application.cpp:440
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_FLARE_SET
@ TUNEUP_PROTECTED_FLARE_SET
'subject_id' is flare ID.
RoR::GameContext::ChainMessage
void ChainMessage(Message m)
Add to last pushed message's chain.
Definition: GameContext.cpp:72
RoR::GUI::TopMenubar::ai_presets_bundled
rapidjson::Document ai_presets_bundled
Presets bundled with the terrain, see [AI Presets] section in .terrn2 file format.
Definition: GUI_TopMenubar.h:108
RoR::GUI::TopMenubar::m_open_menu
TopMenu m_open_menu
Definition: GUI_TopMenubar.h:139
RoR::GUI::TopMenubar::ai_dname2
Ogre::String ai_dname2
Definition: GUI_TopMenubar.h:90
RoR::GfxSkyMode::CAELUM
@ CAELUM
Caelum (best looking, slower)
RoR::Actor::getMinHeight
float getMinHeight(bool skip_virtual_nodes=true)
Definition: Actor.cpp:1511
RoR::CVar::getStr
std::string const & getStr() const
Definition: CVar.h:95
RoR::App::diag_log_beam_break
CVar * diag_log_beam_break
Definition: Application.cpp:147
RoR::GUI::TopMenubar::TopMenu::TOPMENU_TOOLS
@ TOPMENU_TOOLS
RoR::GUI::TopMenubar::RED_TEXT
const ImVec4 RED_TEXT
Definition: GUI_TopMenubar.h:55
RoR::Str
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition: Str.h:35
RoR::Actor::ar_flares
std::vector< flare_t > ar_flares
Definition: Actor.h:303
RoR::TuneupDef::isManagedMatForceRemoved
bool isManagedMatForceRemoved(const std::string &matname)
Definition: TuneupFileFormat.h:174
RoR::ActorModifyRequest
Definition: SimData.h:870
RoR::PathCombine
std::string PathCombine(std::string a, std::string b)
Definition: PlatformUtils.h:48
RoR::MSG_SIM_SEAT_PLAYER_REQUESTED
@ MSG_SIM_SEAT_PLAYER_REQUESTED
Payload = RoR::ActorPtr (owner) | nullptr.
Definition: Application.h:122
RoR::AddonPartUtility::RecordAddonpartConflicts
static void RecordAddonpartConflicts(CacheEntryPtr addonpart1, CacheEntryPtr addonpart2, AddonPartConflictVec &conflicts)
Definition: AddonPartFileFormat.cpp:812
RoR::GUI::TopMenubar::DrawTuningForceRemoveControls
void DrawTuningForceRemoveControls(const int subject_id, const std::string &name, const bool is_unwanted, const bool is_force_removed, ModifyProjectRequestType request_type_set, ModifyProjectRequestType request_type_reset)
Definition: GUI_TopMenubar.cpp:2579
RoR::App::gfx_fps_limit
CVar * gfx_fps_limit
Definition: Application.cpp:244
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_EXHAUST_SET
@ TUNEUP_PROTECTED_EXHAUST_SET
'subject_id' is exhaust ID.
RoR::GUI::TopMenubar::m_daytime
float m_daytime
Definition: GUI_TopMenubar.h:147
GUI_MainSelector.h
RoR::GUIManager::CollisionsDebug
GUI::CollisionsDebug CollisionsDebug
Definition: GUIManager.h:103
RoR::EV_CHARACTER_SIDESTEP_RIGHT
@ EV_CHARACTER_SIDESTEP_RIGHT
sidestep to the right
Definition: InputEngine.h:138
RoR::GUI::TopMenubar::ai_times
int ai_times
Definition: GUI_TopMenubar.h:74
RoR::GameContextSB::simbuf_race_time_diff
float simbuf_race_time_diff
Definition: SimBuffers.h:211
RoR::ActorSpawnRequest::asr_cache_entry
CacheEntryPtr asr_cache_entry
Optional, overrides 'asr_filename' and 'asr_cache_entry_num'.
Definition: SimData.h:848
RoR::CacheQueryResult
Definition: CacheSystem.h:162
ScriptEngine.h
RoR::GUI::TextureToolWindow::SetVisible
void SetVisible(bool visible)
Definition: GUI_TextureToolWindow.h:34
RoR::App::diag_log_beam_trigger
CVar * diag_log_beam_trigger
Definition: Application.cpp:149
RoR::GameContext::PushMessage
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
Definition: GameContext.cpp:65
RoR::WheelID_t
int WheelID_t
Index to Actor::ar_wheels, use RoR::WHEELID_INVALID as empty value.
Definition: ForwardDeclarations.h:56
RoR::Replay
Definition: Replay.h:39
RoR::GUI::TopMenubar::Draw
void Draw(float dt)
Definition: GUI_TopMenubar.cpp:153
RoR::Actor::getSectionConfig
Ogre::String getSectionConfig()
Definition: Actor.h:230
RoR::Str::ToCStr
const char * ToCStr() const
Definition: Str.h:46
RoR::GUI::TopMenubar::ai_times_prev
int ai_times_prev
Definition: GUI_TopMenubar.h:97
RoR::App::sim_terrain_name
CVar * sim_terrain_name
Definition: Application.cpp:97
RoR::ImButtonHoldToConfirm
bool ImButtonHoldToConfirm(const std::string &btn_idstr, const bool smallbutton, const float time_limit)
Definition: GUIUtils.cpp:474
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_MANAGEDMAT_RESET
@ TUNEUP_FORCEREMOVE_MANAGEDMAT_RESET
'subject' is managed material name.
RoR::Actor::getTruckFileName
std::string getTruckFileName()
Definition: Actor.h:227
RoR::Actor::getPosition
Ogre::Vector3 getPosition()
Definition: Actor.cpp:423
RoR::ContentManager::LoadAndParseJson
bool LoadAndParseJson(std::string const &filename, std::string const &rg_name, rapidjson::Document &j_doc)
Definition: ContentManager.cpp:452
GfxScene.h
RoR::GUI::TopMenubar::ai_presets_extern_fetching
bool ai_presets_extern_fetching
True if the (down)load of 'extern' waypoints is in progress.
Definition: GUI_TopMenubar.h:106
RoR::TuneupDef::isWheelProtected
bool isWheelProtected(WheelID_t wheelid) const
Definition: TuneupFileFormat.h:151
PlatformUtils.h
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
RoR::GUI::TopMenubar::ai_mode_prev
int ai_mode_prev
Definition: GUI_TopMenubar.h:98
RoR::App::ui_show_live_repair_controls
CVar * ui_show_live_repair_controls
Definition: Application.cpp:262
RoR::MSG_GUI_OPEN_SELECTOR_REQUESTED
@ MSG_GUI_OPEN_SELECTOR_REQUESTED
Payload = LoaderType* (owner), Description = GUID | empty.
Definition: Application.h:135
RoR::App::diag_log_beam_deform
CVar * diag_log_beam_deform
Definition: Application.cpp:148
RoR::TuneupDef::isFlareUnwanted
bool isFlareUnwanted(FlareID_t flareid)
Definition: TuneupFileFormat.h:162
RoR::WheelSide::RIGHT
@ RIGHT
RoR::WheelSide::LEFT
@ LEFT
RoR::MSG_SIM_HIDE_NET_ACTOR_REQUESTED
@ MSG_SIM_HIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
Definition: Application.h:124
RoR::LoaderType
LoaderType
< Search mode for ModCache::Query() & Operation mode for GUI::MainSelector
Definition: Application.h:289
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_RESET
@ TUNEUP_FORCEREMOVE_EXHAUST_RESET
'subject_id' is exhaust ID.
RoR::Prop
A mesh attached to vehicle frame via 3 nodes.
Definition: GfxData.h:162
RoR::GUI::TopMenubar
Definition: GUI_TopMenubar.h:46
RoR::ModifyProjectRequest::mpr_target_actor
ActorPtr mpr_target_actor
Definition: CacheSystem.h:267
Application.h
Central state/object manager and communications hub.
RoR::App::GetConsole
Console * GetConsole()
Definition: Application.cpp:270
RoR::GUI::TopMenubar::tuning_addonparts
std::vector< CacheEntryPtr > tuning_addonparts
Addonparts eligible for current actor, both matched by GUID and force-installed by user via [browse a...
Definition: GUI_TopMenubar.h:112
RoR::Replay::getCurrentFrame
int getCurrentFrame() const
Definition: Replay.h:54
RoR::Message::payload
void * payload
Definition: GameContext.h:59
RoR::Network::GetLocalUserData
RoRnet::UserInfo GetLocalUserData()
Definition: Network.cpp:697
RoR::CameraManager::CAMERA_BEHAVIOR_FIXED
@ CAMERA_BEHAVIOR_FIXED
Definition: CameraManager.h:53
FlexBody.h
RoR::GUI::TopMenubar::TUNING_HOLDTOCONFIRM_COLOR
const ImVec4 TUNING_HOLDTOCONFIRM_COLOR
Definition: GUI_TopMenubar.h:119
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::CVar::getEnum
T getEnum() const
Definition: CVar.h:99
RoR::GUI::FrictionSettings::SetVisible
void SetVisible(bool visible)
Definition: GUI_FrictionSettings.h:51
RoR::Character::getPosition
Ogre::Vector3 getPosition()
Definition: Character.cpp:92
RoR::EV_CHARACTER_FORWARD
@ EV_CHARACTER_FORWARD
step forward with the character
Definition: InputEngine.h:130
RoR::GUI::TopMenubar::StateBox::STATEBOX_RACE
@ STATEBOX_RACE
RoR::GUI::FlexbodyDebug::SetVisible
void SetVisible(bool value)
Definition: GUI_FlexbodyDebug.h:37
RoR::App::gfx_envmap_enabled
CVar * gfx_envmap_enabled
Definition: Application.cpp:232
RoR::App::diag_videocameras
CVar * diag_videocameras
Definition: Application.cpp:139
RoR::ActorSB::simbuf_actor_state
ActorState simbuf_actor_state
Definition: SimBuffers.h:115
RoR::Replay::getNumFrames
int getNumFrames() const
Definition: Replay.h:53
RoR::GUIManager::GuiTheme::success_text_color
ImVec4 success_text_color
Definition: GUIManager.h:77
RoR::GUIManager::NodeBeamUtils
GUI::NodeBeamUtils NodeBeamUtils
Definition: GUIManager.h:118
RoR::GUIManager::ConsoleWindow
GUI::ConsoleWindow ConsoleWindow
Definition: GUIManager.h:121
RoRnet::UserInfo::clientversion
char clientversion[25]
a version number of the client. For example 1 for RoR 0.35
Definition: RoRnet.h:180
RoR::GameContext::GetQuicksaveFilename
std::string GetQuicksaveFilename()
For currently loaded terrain (cvar 'sim_terrain_name')
Definition: Savegame.cpp:55
RoR::GUI::TopMenubar::RefreshTuningMenu
void RefreshTuningMenu()
Definition: GUI_TopMenubar.cpp:2433
RoR::App::gfx_water_mode
CVar * gfx_water_mode
Definition: Application.cpp:224
RoR::GUI::TopMenubar::StateBox::STATEBOX_REPLAY
@ STATEBOX_REPLAY
RoR::EV_COMMON_TOGGLE_TERRAIN_EDITOR
@ EV_COMMON_TOGGLE_TERRAIN_EDITOR
toggle terrain editor
Definition: InputEngine.h:267
RoR::ActorSpawnRequest::asr_skin_entry
CacheEntryPtr asr_skin_entry
Definition: SimData.h:854
RoR::ActorSB::simbuf_pos
Ogre::Vector3 simbuf_pos
Definition: SimBuffers.h:123
RoR::ModifyProjectRequest::mpr_value_int
int mpr_value_int
Definition: CacheSystem.h:273
RoR::ActorManager::SetSimulationSpeed
void SetSimulationSpeed(float speed)
Definition: ActorManager.h:92
RoR::App::gfx_sky_mode
CVar * gfx_sky_mode
Definition: Application.cpp:219
RoR::MSG_SIM_TELEPORT_PLAYER_REQUESTED
@ MSG_SIM_TELEPORT_PLAYER_REQUESTED
Payload = Ogre::Vector3* (owner)
Definition: Application.h:123
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_EXHAUST_SET
@ TUNEUP_FORCEREMOVE_EXHAUST_SET
'subject_id' is exhaust ID.
RoR::TuneupDef::isFlareForceRemoved
bool isFlareForceRemoved(FlareID_t flareid)
Definition: TuneupFileFormat.h:172
RoR::Message::description
std::string description
Definition: GameContext.h:58
RoR::Actor::getUsedActorEntry
CacheEntryPtr & getUsedActorEntry()
The actor entry itself.
Definition: Actor.cpp:4709
_LC
#define _LC(ctx, str)
Definition: Language.h:42
RoR::GUIManager::TopMenubar
GUI::TopMenubar TopMenubar
Definition: GUIManager.h:120
RoR::GUI::TopMenubar::RefreshAiPresets
void RefreshAiPresets()
Refresh the list of presets, used for display. Needs to be called when terrain is loaded.
Definition: GUI_TopMenubar.cpp:2412
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_FLARE_SET
@ TUNEUP_FORCEREMOVE_FLARE_SET
'subject_id' is flare ID.
RoR::CacheQuery::resetResults
void resetResults()
Definition: CacheSystem.h:195
RoR::Network::GetPlayerColor
Ogre::ColourValue GetPlayerColor(int color_num)
Definition: Network.cpp:94
RoR::ModifyProjectRequest
Definition: CacheSystem.h:265
RoR::CreateProjectRequest
Creates subdirectory in 'My Games\Rigs of Rods\projects', pre-populates it with files and adds modcac...
Definition: CacheSystem.h:219
RoR::GUIManager::GuiTheme::screen_edge_padding
ImVec2 screen_edge_padding
Definition: GUIManager.h:85
RoR::ModifyProjectRequestType::PROJECT_LOAD_TUNEUP
@ PROJECT_LOAD_TUNEUP
'subject' is tuneup filename. This overwrites the auto-generated tuneup with the save.
RoR::GUI::TopMenubar::m_state_box_hoverbox_min
ImVec2 m_state_box_hoverbox_min
Definition: GUI_TopMenubar.h:141
RoR::GUI::TopMenubar::ai_speed_prev
int ai_speed_prev
Definition: GUI_TopMenubar.h:95
RoR::App::gfx_water_waves
CVar * gfx_water_waves
Definition: Application.cpp:226
RoR::GUI::TopMenubar::m_savegame_names
std::vector< std::string > m_savegame_names
Definition: GUI_TopMenubar.h:151
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_PROP_SET
@ TUNEUP_PROTECTED_PROP_SET
'subject_id' is prop ID.
RoR::MSG_NET_FETCH_AI_PRESETS_SUCCESS
@ MSG_NET_FETCH_AI_PRESETS_SUCCESS
Description = JSON string.
Definition: Application.h:111
RoR::AddonPartUtility::CheckForAddonpartConflict
static bool CheckForAddonpartConflict(CacheEntryPtr addonpart1, CacheEntryPtr addonpart2, AddonPartConflictVec &conflicts)
Definition: AddonPartFileFormat.cpp:884
RoR::CreateProjectRequest::cpr_source_actor
ActorPtr cpr_source_actor
Only for type SAVE_TUNEUP
Definition: CacheSystem.h:227
RoR::GUI::TopMenubar::m_state_box_hoverbox_max
ImVec2 m_state_box_hoverbox_max
Definition: GUI_TopMenubar.h:142
RoR::App::GetCacheSystem
CacheSystem * GetCacheSystem()
Definition: Application.cpp:272
RoR::GUI::TopMenubar::TopMenu::TOPMENU_AI
@ TOPMENU_AI
RoR::GfxActor::getWheelRimMeshName
std::string getWheelRimMeshName(WheelID_t wheel_id)
Definition: GfxActor.h:149
RoR::App::gfx_sky_time_speed
CVar * gfx_sky_time_speed
Definition: Application.cpp:221
RoR::GUI::TopMenubar::ai_mode
int ai_mode
Definition: GUI_TopMenubar.h:84
RoR::CID_Tuneups
@ CID_Tuneups
For unsorted tuneup files.
Definition: CacheSystem.h:152
RoRnet::UserInfo::colournum
int32_t colournum
colour set by server
Definition: RoRnet.h:173
RoR::EV_TRUCK_ACCELERATE
@ EV_TRUCK_ACCELERATE
accelerate the truck
Definition: InputEngine.h:297
RoR::GUIManager::FlexbodyDebug
GUI::FlexbodyDebug FlexbodyDebug
Definition: GUIManager.h:124
RoRnet::UserInfo::username
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)
Definition: RoRnet.h:175
RoRnet::UserInfo::uniqueid
uint32_t uniqueid
user unique id
Definition: RoRnet.h:170
RoR::GfxActor::GetFlexbodies
std::vector< FlexBody * > & GetFlexbodies()
Definition: GfxActor.h:135
RoR::Actor::getRotation
float getRotation()
Definition: Actor.cpp:408
RoR::CacheQuery::cqy_filter_type
RoR::LoaderType cqy_filter_type
Definition: CacheSystem.h:184
RoR::WheelSide::INVALID
@ INVALID
RoR::MSG_EDI_DELETE_PROJECT_REQUESTED
@ MSG_EDI_DELETE_PROJECT_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
Definition: Application.h:152
ai_events
Definition: GUI_TopMenubar.h:37
RoR::Message
Unified game event system - all requests and state changes are reported using a message.
Definition: GameContext.h:51
RoR::CVar::setVal
void setVal(T val)
Definition: CVar.h:72
RoR::MSG_GUI_OPEN_MENU_REQUESTED
@ MSG_GUI_OPEN_MENU_REQUESTED
Definition: Application.h:133
RoR::EV_TRUCK_STEER_RIGHT
@ EV_TRUCK_STEER_RIGHT
steer right
Definition: InputEngine.h:358
RoR::Actor::getUsedSkinEntry
CacheEntryPtr & getUsedSkinEntry()
Definition: Actor.cpp:4714
RoR::GUI::TopMenubar::TopMenu::TOPMENU_SETTINGS
@ TOPMENU_SETTINGS
RoR::ModifyProjectRequestType::TUNEUP_FORCEREMOVE_FLEXBODY_RESET
@ TUNEUP_FORCEREMOVE_FLEXBODY_RESET
'subject_id' is flexbody ID.
RoR::GUI::TopMenubar::IsMenuEnabled
bool IsMenuEnabled(TopMenu which)
Definition: GUI_TopMenubar.cpp:2637
RoR::GfxActor::getProps
std::vector< Prop > & getProps()
Definition: GfxActor.h:145
RoR::CreateProjectRequest::cpr_overwrite
bool cpr_overwrite
Definition: CacheSystem.h:229
RoR::GUI::NodeBeamUtils::SetVisible
void SetVisible(bool visible)
Definition: GUI_NodeBeamUtils.cpp:188
RoR::EV_TRUCK_TOGGLE_PHYSICS
@ EV_TRUCK_TOGGLE_PHYSICS
toggle physics simulation
Definition: InputEngine.h:365
RoR::ActorSpawnRequest::asr_debugview
int asr_debugview
Definition: SimData.h:858
RoR::IWater::SetWavesHeight
virtual void SetWavesHeight(float value)
Definition: IWater.h:46
RoR::GUI::CollisionsDebug::SetVisible
void SetVisible(bool v)
Definition: GUI_CollisionsDebug.cpp:564
RoR::FlareID_t
int FlareID_t
Index into Actor::ar_flares, use RoR::FLAREID_INVALID as empty value.
Definition: ForwardDeclarations.h:68
RoR::ActorManager::SetTrucksForcedAwake
void SetTrucksForcedAwake(bool forced)
Definition: ActorManager.h:90
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_PROP_RESET
@ TUNEUP_PROTECTED_PROP_RESET
'subject_id' is prop ID.
RoR::TuneupUtil::getTweakedWheelSide
static WheelSide getTweakedWheelSide(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, WheelSide orig_val)
Definition: TuneupFileFormat.cpp:193
RoR::TuneupDef::isFlareProtected
bool isFlareProtected(FlareID_t flareid) const
Definition: TuneupFileFormat.h:153
RoR::MSG_SIM_SPAWN_ACTOR_REQUESTED
@ MSG_SIM_SPAWN_ACTOR_REQUESTED
Payload = RoR::ActorSpawnRequest* (owner)
Definition: Application.h:119
RoR::Actor::ar_num_wheels
int ar_num_wheels
Definition: Actor.h:324
RoR::App::GetInputEngine
InputEngine * GetInputEngine()
Definition: Application.cpp:271
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_MANAGEDMAT_RESET
@ TUNEUP_PROTECTED_MANAGEDMAT_RESET
'subject' is managed material name.
RoR::TuneupDef::isExhaustForceRemoved
bool isExhaustForceRemoved(ExhaustID_t exhaustid)
Definition: TuneupFileFormat.h:173
RoR::ModifyProjectRequestType::TUNEUP_PROTECTED_WHEEL_SET
@ TUNEUP_PROTECTED_WHEEL_SET
'subject_id' is wheel ID.
RoR::ActorPtr
RefCountingObjectPtr< Actor > ActorPtr
Definition: ForwardDeclarations.h:194
RoR::MSG_SIM_DELETE_ACTOR_REQUESTED
@ MSG_SIM_DELETE_ACTOR_REQUESTED
Payload = RoR::ActorPtr* (owner)
Definition: Application.h:121
RoR::LT_AllBeam
@ LT_AllBeam
Definition: Application.h:303
RoR::GUI::TopMenubar::ai_presets_extern_error
std::string ai_presets_extern_error
Error message from the (down)load of 'extern' waypoints.
Definition: GUI_TopMenubar.h:107
RoR::Replay::getLastReadTime
unsigned long getLastReadTime()
Definition: Replay.cpp:178
RoR::App::gfx_fov_external
CVar * gfx_fov_external
Definition: Application.cpp:238
RoR::EV_CHARACTER_SIDESTEP_LEFT
@ EV_CHARACTER_SIDESTEP_LEFT
sidestep to the left
Definition: InputEngine.h:137
Terrain.h
RoR::ModifyProjectRequestType::PROJECT_RESET_TUNEUP
@ PROJECT_RESET_TUNEUP
'subject' is empty. This resets the auto-generated tuneup to orig. values.
RoR::GUI::TopMenubar::tuning_hovered_addonpart
CacheEntryPtr tuning_hovered_addonpart
Definition: GUI_TopMenubar.h:122
RoR::ActorState::NETWORKED_HIDDEN
@ NETWORKED_HIDDEN
not simulated, not updated (remote)
RoR::GUI::TopMenubar::TopMenu::TOPMENU_ACTORS
@ TOPMENU_ACTORS
InputEngine.h
Handles controller inputs from player. Defines input events and binding mechanism,...
RGN_SAVEGAMES
#define RGN_SAVEGAMES
Definition: Application.h:50
RoR::CacheQuery::cqy_filter_guid
std::string cqy_filter_guid
Exact match (case-insensitive); leave empty to disable.
Definition: CacheSystem.h:186
RoR::CVar::getFloat
float getFloat() const
Definition: CVar.h:96
RoR::GameContextSB::simbuf_dir_arrow_target
Ogre::Vector3 simbuf_dir_arrow_target
Definition: SimBuffers.h:214
RoR::GUI::TopMenubar::ORANGE_TEXT
const ImVec4 ORANGE_TEXT
Definition: GUI_TopMenubar.h:54
RoR::ActorSpawnRequest::Origin::USER
@ USER
Direct selection by user via GUI.
RoR::MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED
@ MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
Definition: Application.h:125
RoR::DrawGCheckbox
bool DrawGCheckbox(CVar *cvar, const char *label)
Definition: GUIUtils.cpp:261
RoR::GUI::TopMenubar::DrawActorListSinglePlayer
void DrawActorListSinglePlayer()
Definition: GUI_TopMenubar.cpp:2058
RoR::GUI::TopMenubar::tuning_saves
CacheQuery tuning_saves
Tuneups saved by user, with category ID RoR::CID_AddonpartUser
Definition: GUI_TopMenubar.h:115
RoR::GfxActor::GetDebugView
DebugViewType GetDebugView() const
Definition: GfxActor.h:138
RoR::TuneupDef::isExhaustProtected
bool isExhaustProtected(ExhaustID_t exhaustid) const
Definition: TuneupFileFormat.h:154
RoR::TuneupDef::isFlexbodyUnwanted
bool isFlexbodyUnwanted(FlexbodyID_t flexbodyid)
Definition: TuneupFileFormat.h:161
RoR::GUI::TopMenubar::tuning_addonparts_conflict_w_used
std::vector< bool > tuning_addonparts_conflict_w_used
1:1 with tuning_addonparts; True means the eligible (not used) addonpart conflicts with an used addon...
Definition: GUI_TopMenubar.h:113
RoR::CVar::getInt
int getInt() const
Definition: CVar.h:97
RoR::ImDrawEventHighlighted
void ImDrawEventHighlighted(events input_event)
Definition: GUIUtils.cpp:408
RoR::Console::CONSOLE_MSGTYPE_INFO
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition: Console.h:60
ai_events::speed
int speed
Definition: GUI_TopMenubar.h:40
RoR::WheelSide
WheelSide
Used by rig-def/addonpart/tuneup formats to specify wheel rim mesh orientation.
Definition: GfxData.h:115
RoR::GUI::TopMenubar::ai_dname
Ogre::String ai_dname
Definition: GUI_TopMenubar.h:79
RoR::ActorSpawnRequest::asr_position
Ogre::Vector3 asr_position
Definition: SimData.h:851
RoR::GUI::VehicleInfoTPanel::SetVisible
void SetVisible(TPanelMode mode, TPanelFocus focus=TPANELFOCUS_NONE)
Definition: GUI_VehicleInfoTPanel.cpp:555
RoR::TuneupDef::isWheelSideForced
bool isWheelSideForced(WheelID_t wheelid, WheelSide &out_val) const
Definition: TuneupFileFormat.cpp:107
RoR::ActorManager::WakeUpAllActors
void WakeUpAllActors()
Definition: ActorManager.cpp:783
RoR::Terrn2Def::ai_presets_files
std::list< std::string > ai_presets_files
Definition: Terrn2FileFormat.h:66
RoR::ModifyProjectRequest::mpr_type
ModifyProjectRequestType mpr_type
Definition: CacheSystem.h:268
RoR::FlexBody
Flexbody = A deformable mesh; updated on CPU every frame, then uploaded to video memory.
Definition: FlexBody.h:43
RoR::ModifyProjectRequestType::TUNEUP_FORCED_WHEEL_SIDE_RESET
@ TUNEUP_FORCED_WHEEL_SIDE_RESET
'subject_id' is wheel ID.
RoR::GameContext::GetRepairMode
RepairMode & GetRepairMode()
Definition: GameContext.h:169
RoR::GUI::TopMenubar::ai_select2
bool ai_select2
Definition: GUI_TopMenubar.h:88
RoR::events
events
Definition: InputEngine.h:74
RoR::ActorState::NETWORKED_OK
@ NETWORKED_OK
not simulated (remote) actor
RoR::GUI::ConsoleWindow
Definition: GUI_ConsoleWindow.h:40
RoR::Actor::ar_state
ActorState ar_state
Definition: Actor.h:446
RoR::ActorManager::LoadScene
bool LoadScene(Ogre::String filename)
Definition: Savegame.cpp:239
RoR::GUI::TopMenubar::StateBox::STATEBOX_LIVE_REPAIR
@ STATEBOX_LIVE_REPAIR
RoR::GUI::TopMenubar::~TopMenubar
~TopMenubar()
Definition: GUI_TopMenubar.cpp:148
RoR::GameContext::GetPlayerActor
const ActorPtr & GetPlayerActor()
Definition: GameContext.h:134
RoR::AI
@ AI
machine controlled by an Artificial Intelligence
Definition: SimData.h:97
RoR::GUI::VehicleInfoTPanel::TPANELFOCUS_COMMANDS
@ TPANELFOCUS_COMMANDS
Definition: GUI_VehicleInfoTPanel.h:38
RoR::App::gfx_sky_time_cycle
CVar * gfx_sky_time_cycle
Definition: Application.cpp:220
RoR::MSG_SIM_LOAD_SAVEGAME_REQUESTED
@ MSG_SIM_LOAD_SAVEGAME_REQUESTED
Definition: Application.h:117
RoR::LoadingIndicatorCircle
void LoadingIndicatorCircle(const char *label, const float indicator_radius, const ImVec4 &main_color, const ImVec4 &backdrop_color, const int circle_count, const float speed)
Draws animated loading spinner.
Definition: GUIUtils.cpp:132
RoR::TuneupDef::isPropForceRemoved
bool isPropForceRemoved(PropID_t propid)
Definition: TuneupFileFormat.h:169
RoR::ActorModifyRequest::amr_type
Type amr_type
Definition: SimData.h:887
RoR::CacheQuery::cqy_filter_target_filename
std::string cqy_filter_target_filename
Exact match (case-insensitive); leave empty to disable (currently only used with addonparts)
Definition: CacheSystem.h:187
RoR::ActorSpawnRequest::asr_rotation
Ogre::Quaternion asr_rotation
Definition: SimData.h:852
RoR::CameraManager::CAMERA_BEHAVIOR_VEHICLE_CINECAM
@ CAMERA_BEHAVIOR_VEHICLE_CINECAM
Definition: CameraManager.h:50
RoR::Actor::getWorkingTuneupDef
TuneupDefPtr & getWorkingTuneupDef()
Definition: Actor.cpp:4719
RoR::GUIManager::RequestGuiCaptureKeyboard
void RequestGuiCaptureKeyboard(bool val)
Pass true during frame to prevent input passing to application.
Definition: GUIManager.cpp:439
RoR::GfxActor::GetSimDataBuffer
ActorSB & GetSimDataBuffer()
Definition: GfxActor.h:119
RoR
Definition: AppContext.h:36
Network.h
x
float x
Definition: (ValueTypes) quaternion.h:5
RoR::CacheSystem::Query
size_t Query(CacheQuery &query)
Definition: CacheSystem.cpp:2089
RoR::GUI::TopMenubar::ai_select
bool ai_select
Definition: GUI_TopMenubar.h:82
RoR::Log
void Log(const char *msg)
The ultimate, application-wide logging function. Adds a line (any length) in 'RoR....
Definition: Application.cpp:419
RoR::GUI::TopMenubar::m_open_menu_hoverbox_max
ImVec2 m_open_menu_hoverbox_max
Definition: GUI_TopMenubar.h:138
RoR::TuneupDef::isManagedMatUnwanted
bool isManagedMatUnwanted(const std::string &matname)
Definition: TuneupFileFormat.h:164
Water.h
RoR::ScriptCategory::CUSTOM
@ CUSTOM
Loaded by user via either: A) ingame console 'loadscript'; B) RoR.cfg 'app_custom_scripts'; C) comman...
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:276
RoR::GameContext::GetActorManager
ActorManager * GetActorManager()
Definition: GameContext.h:127
RoRnet::UserInfo::language
char language[10]
user's language. For example "de-DE" or "en-US"
Definition: RoRnet.h:178
RoR::EV_TRUCK_BRAKE
@ EV_TRUCK_BRAKE
brake
Definition: InputEngine.h:306
RoR::Actor::ar_managed_materials
std::map< std::string, Ogre::MaterialPtr > ar_managed_materials
Definition: Actor.h:318
RoR::CacheQuery::cqy_results
std::vector< CacheQueryResult > cqy_results
Definition: CacheSystem.h:191
RoR::GUI::TopMenubar::m_open_menu_hoverbox_min
ImVec2 m_open_menu_hoverbox_min
Definition: GUI_TopMenubar.h:137
RoR::MSG_APP_SHUTDOWN_REQUESTED
@ MSG_APP_SHUTDOWN_REQUESTED
Definition: Application.h:85
RoR::GUI::TopMenubar::tuning_savebox_overwrite
bool tuning_savebox_overwrite
Status of "Overwrite?" checkbox.
Definition: GUI_TopMenubar.h:118
RoR::GUI::TopMenubar::TUNING_HOLDTOCONFIRM_TIMELIMIT
const float TUNING_HOLDTOCONFIRM_TIMELIMIT
Delete button must be held for several sec to confirm.
Definition: GUI_TopMenubar.h:120
RoR::GUI::TopMenubar::ai_distance
int ai_distance
Definition: GUI_TopMenubar.h:76
RoR::Terrain::getWater
IWater * getWater()
Definition: Terrain.h:84
RoR::GfxActor::getWheelSide
WheelSide getWheelSide(WheelID_t wheel_id)
Definition: GfxActor.h:148
RoR::FileExists
bool FileExists(const char *path)
Path must be UTF-8 encoded.
Definition: PlatformUtils.cpp:163
RoR::CacheEntry::guid
Ogre::String guid
global unique id; Type "addonpart" leaves this empty and uses addonpart_guids; Always lowercase.
Definition: CacheSystem.h:77
RoR::MSG_NET_DISCONNECT_REQUESTED
@ MSG_NET_DISCONNECT_REQUESTED
Definition: Application.h:103
RoR::GUI::TopMenubar::tuning_actor
ActorPtr tuning_actor
Detecting actor change to update cached values.
Definition: GUI_TopMenubar.h:111
FetchAiPresetsThreadFunc
void FetchAiPresetsThreadFunc()
Definition: GUI_TopMenubar.cpp:76
RoR::App::mp_pseudo_collisions
CVar * mp_pseudo_collisions
Definition: Application.cpp:120
RoR::GameContext::GetTerrain
const TerrainPtr & GetTerrain()
Definition: GameContext.h:117
RoR::CacheEntry::fname
Ogre::String fname
filename
Definition: CacheSystem.h:67
RoR::GUI::TopMenubar::DrawMpUserToActorList
void DrawMpUserToActorList(RoRnet::UserInfo &user)
Definition: GUI_TopMenubar.cpp:1988
RoR::App::io_hydro_coupling
CVar * io_hydro_coupling
Definition: Application.cpp:199
RoR::GfxWaterMode::HYDRAX
@ HYDRAX
HydraX.
RoR::GUI::TopMenubar::m_state_box
StateBox m_state_box
Definition: GUI_TopMenubar.h:143
RoR::ActorModifyRequest::Type::RELOAD
@ RELOAD
Full reload from filesystem, requested by user.
RoR::GUI::TopMenubar::TUNING_SUBJECTID_USE_NAME
const int TUNING_SUBJECTID_USE_NAME
Definition: GUI_TopMenubar.h:57