54#include <fmt/format.h>
58# include <curl/curl.h>
59# include <curl/easy.h>
62#if defined(_MSC_VER) && defined(GetObject)
71static size_t CurlWriteFunc(
void *ptr,
size_t size,
size_t nmemb, std::string* data)
73 data->append((
char*)ptr, size * nmemb);
71static size_t CurlWriteFunc(
void *ptr,
size_t size,
size_t nmemb, std::string* data) {
…}
86 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(
"waypoints.json",
RGN_SAVEGAMES);
102 std::string url =
"https://raw.githubusercontent.com/RigsOfRods-Community/ai-waypoints/main/waypoints.json";
103 std::string response_payload;
104 long response_code = 0;
106 CURL *curl = curl_easy_init();
107 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
108 curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
110 curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
112 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
CurlWriteFunc);
113 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_payload);
115 CURLcode curl_result = curl_easy_perform(curl);
116 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
118 curl_easy_cleanup(curl);
121 if (curl_result != CURLE_OK || response_code != 200)
123 Ogre::LogManager::getSingleton().stream()
124 <<
"[RoR|Repository] Failed to download AI presets;"
125 <<
" Error: '" << curl_easy_strerror(curl_result) <<
"'; HTTP status code: " << response_code;
161 int num_playable_actors = 0;
164 if (!actor->ar_hide_in_actor_list)
166 num_playable_actors++;
170 std::string sim_title =
_LC(
"TopMenubar",
"Simulation");
171 std::string actors_title = fmt::format(
"{} ({})",
_LC(
"TopMenubar",
"Vehicles"), num_playable_actors);
172 std::string savegames_title =
_LC(
"TopMenubar",
"Saves");
173 std::string settings_title =
_LC(
"TopMenubar",
"Settings");
174 std::string tools_title =
_LC(
"TopMenubar",
"Tools");
175 std::string ai_title =
_LC(
"TopMenubar",
"Vehicle AI");
176 std::string tuning_title =
_LC(
"TopMenubar",
"Tuning");
178 int menubar_num_buttons = 5;
179 float menubar_content_width =
180 ImGui::CalcTextSize(sim_title.c_str()).x +
181 ImGui::CalcTextSize(actors_title.c_str()).x +
182 ImGui::CalcTextSize(savegames_title.c_str()).x +
183 ImGui::CalcTextSize(settings_title.c_str()).x +
184 ImGui::CalcTextSize(tools_title.c_str()).x;
188 menubar_num_buttons += 1;
189 menubar_content_width += ImGui::CalcTextSize(ai_title.c_str()).x;
194 menubar_num_buttons += 1;
195 menubar_content_width += ImGui::CalcTextSize(tuning_title.c_str()).x;
198 menubar_content_width +=
199 (ImGui::GetStyle().ItemSpacing.x * (menubar_num_buttons - 1)) +
200 (ImGui::GetStyle().FramePadding.x * (menubar_num_buttons * 2));
202 ImVec2 window_target_pos = ImVec2((ImGui::GetIO().DisplaySize.x/2.f) - (menubar_content_width / 2.f), theme.
screen_edge_padding.y);
212 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0,0,0,0));
215 int flags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove
216 | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize;
217 ImGui::SetNextWindowContentSize(ImVec2(menubar_content_width, 0.f));
218 ImGui::SetNextWindowPos(window_target_pos);
219 ImGui::Begin(
"Top menubar",
nullptr, flags);
221 if (ImGui::IsWindowHovered())
227 ImVec2 window_pos = ImGui::GetWindowPos();
228 ImVec2 sim_cursor = ImGui::GetCursorPos();
229 ImGui::Button(sim_title.c_str());
236 ImVec2 tuning_cursor = ImVec2(0, 0);
240 tuning_cursor = ImGui::GetCursorPos();
241 ImGui::Button(tuning_title.c_str());
249 ImVec2 ai_cursor = ImVec2(0, 0);
253 ai_cursor = ImGui::GetCursorPos();
254 ImGui::Button(ai_title.c_str());
264 ImVec2 actors_cursor = ImGui::GetCursorPos();
265 ImGui::Button(actors_title.c_str());
274 ImVec2 savegames_cursor = ImGui::GetCursorPos();
275 ImGui::Button(savegames_title.c_str());
282 for (
int i = 0; i <= 9; i++)
284 Ogre::String filename = Ogre::StringUtil::format(
"quicksave-%d.sav", i);
292 ImVec2 settings_cursor = ImGui::GetCursorPos();
293 ImGui::Button(settings_title.c_str());
306 ImVec2 tools_cursor = ImGui::GetCursorPos();
307 ImGui::Button(tools_title.c_str());
313 ImVec2 topmenu_final_size = ImGui::GetWindowSize();
325 menu_pos.x = sim_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
326 ImGui::SetNextWindowPos(menu_pos);
327 if (ImGui::Begin(
_LC(
"TopMenubar",
"Sim menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
331 if (ImGui::Button(
_LC(
"TopMenubar",
"Get new vehicle")))
340 if (current_actor !=
nullptr)
342 if (ImGui::Button(
_LC(
"TopMenubar",
"Show vehicle description")))
349 if (ImGui::Button(
_LC(
"TopMenubar",
"Reload current vehicle")))
357 if (ImGui::Button(
_LC(
"TopMenubar",
"Remove current vehicle")))
365 if (ImGui::Button(
_LC(
"TopMenubar",
"Activate last spawned vehicle")))
373 if (ImGui::Button(
_LC(
"TopMenubar",
"Reload last spawned vehicle")))
381 if (ImGui::Button(
_LC(
"TopMenubar",
"Remove last spawned vehicle")))
390 if (ImGui::Button(
_LC(
"TopMenubar",
"Remove all vehicles")))
397 if (ImGui::Button(
_LC(
"TopMenubar",
" [!] Confirm removal")))
401 if (!actor->ar_hide_in_actor_list && !actor->isPreloadedWithTerrain() &&
409 ImGui::PopStyleColor();
412 if (ImGui::Button(
_LC(
"TopMenubar",
"Activate all vehicles")))
418 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"Activated vehicles never sleep"), &force_trucks_active))
423 if (ImGui::Button(
_LC(
"TopMenubar",
"Send all vehicles to sleep")))
431 if (ImGui::Button(
_LC(
"TopMenubar",
"Reload current terrain")))
442 &&
App::GetGameContext()->GetTerrain()->getCacheEntry()->resource_bundle_type ==
"FileSystem"
443 && ImGui::Button(
_LC(
"TopMenubar",
"Save changes to terrain")))
452 if (ImGui::Button(
_LC(
"TopMenubar",
"Back to menu")))
462 if (ImGui::Button(
_LC(
"TopMenubar",
"Exit")))
477 menu_pos.x = actors_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
478 ImGui::SetNextWindowPos(menu_pos);
479 if (ImGui::Begin(
_LC(
"TopMenubar",
"Actors menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
492 for (
auto& user: remote_users)
507 menu_pos.y = window_pos.y + savegames_cursor.y +
MENU_Y_OFFSET;
508 menu_pos.x = savegames_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
509 ImGui::SetNextWindowPos(menu_pos);
510 if (ImGui::Begin(
_LC(
"TopMenubar",
"Savegames"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
512 if (ImGui::Button(
_LC(
"TopMenubar",
"Quicksave")))
522 if (ImGui::Button(
_LC(
"TopMenubar",
"Quickload")))
533 ImGui::TextColored(
GRAY_HINT_TEXT,
"%s",
_LC(
"TopMenubar",
"(Save with CTRL+ALT+1..5)"));
534 for (
int i = 1; i <= 5; i++)
536 Ogre::String name =
_LC(
"TopMenubar",
"Empty Slot");
541 Ogre::String caption = Ogre::StringUtil::format(
"%d. %s##Save", i, name.c_str());
542 if (ImGui::Button(caption.c_str()))
544 Ogre::String filename = Ogre::StringUtil::format(
"quicksave-%d.sav", i);
550 ImGui::TextColored(
GRAY_HINT_TEXT,
"%s",
_LC(
"TopMenubar",
"(Load with ALT+1..5)"));
551 for (
int i = 1; i <= 5; i++)
556 Ogre::String caption = Ogre::StringUtil::format(
"%d. %s##Load", i, name.c_str());
557 if (ImGui::Button(caption.c_str()))
559 Ogre::String filename = Ogre::StringUtil::format(
"quicksave-%d.sav", i);
575 menu_pos.y = window_pos.y + settings_cursor.y +
MENU_Y_OFFSET;
576 menu_pos.x = settings_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
577 ImGui::SetNextWindowPos(menu_pos);
578 if (ImGui::Begin(
_LC(
"TopMenubar",
"Settings menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
582 ImGui::PushItemWidth(125.f);
588 ImGui::TextColored(
GRAY_HINT_TEXT,
"%s",
_LC(
"TopMenubar",
"Frames per second:"));
598 float slowmotion = std::min(
App::GetGameContext()->GetActorManager()->GetSimulationSpeed(), 1.0f);
599 if (ImGui::SliderFloat(
_LC(
"TopMenubar",
"Slow motion"), &slowmotion, 0.01f, 1.0f))
603 float timelapse = std::max(
App::GetGameContext()->GetActorManager()->GetSimulationSpeed(), 1.0f);
604 if (ImGui::SliderFloat(
_LC(
"TopMenubar",
"Time lapse"), &timelapse, 1.0f, 10.0f))
624 if (ImGui::SliderInt(
_LC(
"TopMenubar",
"FOV"), &fov, 10, 120))
632 if (ImGui::SliderInt(
_LC(
"TopMenubar",
"FOV"), &fov, 10, 120))
668 ImGui::PushID(
"waves");
679 if (current_actor !=
nullptr)
682 ImGui::TextColored(
GRAY_HINT_TEXT,
"%s",
_LC(
"TopMenubar",
"Vehicle control options:"));
694 ImGui::PopItemWidth();
705 menu_pos.x = tools_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
706 ImGui::SetNextWindowPos(menu_pos);
707 if (ImGui::Begin(
_LC(
"TopMenubar",
"Tools menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
709 if (ImGui::Button(
_LC(
"TopMenubar",
"Friction settings")))
715 if (ImGui::Button(
_LC(
"TopMenubar",
"Show console")))
721 if (ImGui::Button(
_LC(
"TopMenubar",
"Texture tool")))
727 if (ImGui::Button(
_LC(
"TopMenubar",
"Collisions debug")))
733 if (current_actor !=
nullptr)
735 if (ImGui::Button(
_LC(
"TopMenubar",
"Node / Beam utility")))
741 if (ImGui::Button(
_LC(
"TopMenubar",
"FlexBody debug")))
748 if (ImGui::Button(
_LC(
"TopMenubar",
"Browse gadgets ...")))
754 if (ImGui::Button(
_LC(
"TopMenubar",
"Browse repository ...")))
761 ImGui::TextColored(
GRAY_HINT_TEXT,
"%s",
_LC(
"TopMenubar",
"Pre-spawn diag. options:"));
764 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"Node mass recalc. logging"), &diag_mass))
768 if (ImGui::IsItemHovered())
770 ImGui::BeginTooltip();
771 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Extra logging on runtime - mass recalculation"));
776 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"Beam break logging"), &diag_break))
780 if (ImGui::IsItemHovered())
782 ImGui::BeginTooltip();
783 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Extra logging on runtime"));
788 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"Beam deform. logging"), &diag_deform))
792 if (ImGui::IsItemHovered())
794 ImGui::BeginTooltip();
795 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Extra logging on runtime"));
800 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"Trigger logging"), &diag_trig))
804 if (ImGui::IsItemHovered())
806 ImGui::BeginTooltip();
807 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Extra logging on runtime - trigger beams activity"));
812 if (ImGui::Checkbox(
_LC(
"TopMenubar",
"VideoCamera direction marker"), &diag_vcam))
816 if (ImGui::IsItemHovered())
818 ImGui::BeginTooltip();
819 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Visual marker of VideoCameras direction"));
823 ImGui::PushItemWidth(125.f);
827 if (ImGui::IsItemHovered())
829 ImGui::BeginTooltip();
830 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"1 = Solid"));
831 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"2 = Wireframe"));
832 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"3 = Points"));
846 menu_pos.x = ai_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
847 ImGui::SetNextWindowPos(menu_pos);
848 if (ImGui::Begin(
_LC(
"TopMenubar",
"AI menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
850 if (ImGui::IsWindowHovered())
855 ImGui::PushItemWidth(125.f);
864 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
865 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
868 ImGui::InputInt(
_LC(
"TopMenubar",
"Vehicle count"), &
ai_num, 1, 100);
869 if (ImGui::IsItemHovered())
871 ImGui::BeginTooltip();
872 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Number of vehicles"));
878 ImGui::PopItemFlag();
879 ImGui::PopStyleVar();
884 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
885 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
890 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
891 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
894 ImGui::InputInt(
_LC(
"TopMenubar",
"Distance"), &
ai_distance, 1, 100);
895 if (ImGui::IsItemHovered())
897 ImGui::BeginTooltip();
898 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Following distance in meters"));
904 ImGui::PopItemFlag();
905 ImGui::PopStyleVar();
908 std::string label1 =
"Behind";
920 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
921 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
924 if (ImGui::BeginCombo(
"Position", label1.c_str()))
926 if (ImGui::Selectable(
"Behind"))
930 if (ImGui::Selectable(
"Parallel"))
936 if (ImGui::IsItemHovered())
938 ImGui::BeginTooltip();
939 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Positioning scheme"));
941 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Behind: Set vehicle behind vehicle, in line"));
942 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Parallel: Set vehicles in parallel, useful for certain scenarios like drag races"));
948 ImGui::PopItemFlag();
949 ImGui::PopStyleVar();
957 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
958 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
961 ImGui::InputInt(
_LC(
"TopMenubar",
"Repeat times"), &
ai_times, 1, 100);
962 if (ImGui::IsItemHovered())
964 ImGui::BeginTooltip();
965 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"How many times to loop the path"));
971 ImGui::PopItemFlag();
972 ImGui::PopStyleVar();
977 ImGui::PopItemFlag();
978 ImGui::PopStyleVar();
984 std::string label2 =
"Normal";
991 label2 =
"Drag Race";
1004 if (actor->ar_driveable ==
AI)
1006 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
1007 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
1012 if (ImGui::BeginCombo(
"Mode", label2.c_str()))
1014 if (ImGui::Selectable(
"Normal"))
1027 if (ImGui::Selectable(
"Race"))
1040 if (ImGui::Selectable(
"Drag Race"))
1057 if (ImGui::Selectable(
"Crash"))
1073 if (ImGui::Selectable(
"Chase"))
1088 if (ImGui::IsItemHovered())
1090 ImGui::BeginTooltip();
1091 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Land vehicle driving mode"));
1093 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Normal: Modify speed according to turns, other vehicles and character"));
1094 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Race: Always keep defined speed"));
1095 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Drag Race: Two vehicles performing a drag race"));
1096 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Crash: Two vehicles driving in opposite direction"));
1097 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Chase: Follow character and player vehicle"));
1098 ImGui::EndTooltip();
1103 if (actor->ar_driveable ==
AI)
1105 ImGui::PopItemFlag();
1106 ImGui::PopStyleVar();
1114 ImGui::InputInt(
_LC(
"TopMenubar",
"Speed"), &
ai_speed, 1, 100);
1115 if (ImGui::IsItemHovered())
1117 ImGui::BeginTooltip();
1118 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Speed in km/h for land vehicles or knots/s for boats"));
1119 ImGui::EndTooltip();
1125 ImGui::InputInt(
_LC(
"TopMenubar",
"Altitude"), &
ai_altitude, 1, 100);
1126 if (ImGui::IsItemHovered())
1128 ImGui::BeginTooltip();
1129 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Airplane maximum altitude in feet"));
1130 ImGui::EndTooltip();
1143 if (ImGui::IsItemHovered())
1145 ImGui::BeginTooltip();
1146 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Land vehicles, boats and airplanes"));
1147 ImGui::EndTooltip();
1152 ImGui::PushID(
"vehicle2");
1161 if (ImGui::IsItemHovered())
1163 ImGui::BeginTooltip();
1164 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Land vehicles, boats and airplanes"));
1165 ImGui::EndTooltip();
1174 ImGui::PushItemFlag(ImGuiItemFlags_Disabled,
true);
1175 ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
1180 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]);
1183 if (ImGui::Button(
_LC(
"TopMenubar",
"Start"), ImVec2(80, 0)))
1207 fmt::format(
_LC(
"TopMenubar",
"Select a preset, record or open survey map ({}) to set waypoints."),
1219 ImGui::PopStyleColor();
1224 if (ImGui::Button(
_LC(
"TopMenubar",
"Stop"), ImVec2(80, 0)))
1233 if (actor->ar_driveable ==
AI)
1242 ImGui::PopItemFlag();
1243 ImGui::PopStyleVar();
1248 ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_Button]);
1249 std::string label =
"Record";
1252 label =
"Recording";
1253 ImGui::PushStyleColor(ImGuiCol_Button,
RED_TEXT);
1256 if (ImGui::Button(label.c_str(), ImVec2(80, 0)))
1269 ImGui::PopStyleColor();
1272 if (ImGui::CollapsingHeader(
_LC(
"TopMenubar",
"Presets")))
1276 int display_count = 0;
1277 for (
size_t i = 0; i < num_rows; i++)
1279 rapidjson::Value& j_row =
ai_presets_all[
static_cast<rapidjson::SizeType
>(i)];
1284 if (ImGui::Button(j_row[
"preset"].GetString(), ImVec2(250, 0)))
1288 for (
size_t i = 0; i < j_row[
"waypoints"].Size(); i++)
1290 float x = j_row[
"waypoints"][i][0].GetFloat();
1291 float y = j_row[
"waypoints"][i][1].GetFloat();
1292 float z = j_row[
"waypoints"][i][2].GetFloat();
1298 if (j_row[
"waypoints"][i].Size() == 4)
1300 speed = j_row[
"waypoints"][i][3].GetInt();
1306 waypoint.
speed = speed;
1318 float spinner_size = 8.f;
1319 ImGui::SetCursorPosX((ImGui::GetWindowSize().
x / 2.f) - spinner_size);
1324 ImGui::TextColored(
RED_TEXT,
"%s",
_LC(
"TopMenubar",
"Failed to fetch external presets."));
1325 if (ImGui::Button(
_LC(
"TopMenubar",
"Retry")))
1339 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"No presets found for this terrain :("));
1340 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Supported terrains:"));
1343 ImGui::BeginChild(
"terrains-scrolling", ImVec2(0.f, 200),
false);
1345 for (
size_t i = 0; i < num_rows; i++)
1347 rapidjson::Value& j_row_terrains =
ai_presets_all[
static_cast<rapidjson::SizeType
>(i)];
1348 if (j_row_terrains.HasMember(
"terrains"))
1350 for (
size_t i = 0; i < j_row_terrains[
"terrains"].Size(); i++)
1352 ImGui::Text(
"%s", j_row_terrains[
"terrains"][i].GetString());
1361 if (ImGui::CollapsingHeader(
_LC(
"TopMenubar",
"Waypoints")))
1365 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"No waypoints defined."));
1369 if (ImGui::Button(
_LC(
"TopMenubar",
"Export"), ImVec2(250, 0)))
1392 std::string json = fmt::format(
"\n {{\n \"terrain\":\"{}\",\n \"preset\":\"Preset name\",\n \"waypoints\":\n [{}\n ]\n }}",
App::sim_terrain_name->getStr(), s);
1396 fmt::format(
_LC(
"TopMenubar",
"{} waypoints exported to RoR.log"),
1400 ImGui::BeginChild(
"waypoints-scrolling", ImVec2(0.f, 200),
false);
1405 ImGui::AlignTextToFramePadding();
1406 ImGui::Text(
"%d", i);
1408 if (ImGui::Button(
"teleport", ImVec2(60, 0)))
1410 Ogre::Vector3* payload =
new Ogre::Vector3(
ai_waypoints[i].position);
1413 if (ImGui::IsItemHovered())
1415 ImGui::BeginTooltip();
1417 ImGui::Text(
w.c_str());
1418 ImGui::EndTooltip();
1421 ImGui::SetNextItemWidth(90);
1427 ImGui::InputInt(
_LC(
"TopMenubar",
"speed"), &
ai_waypoints[i].speed, 1, 100);
1428 if (ImGui::IsItemHovered())
1430 ImGui::BeginTooltip();
1431 ImGui::Text(
_LC(
"TopMenubar",
"Set waypoint speed in km/h for land vehicles"));
1433 ImGui::Text(
_LC(
"TopMenubar",
"Value -1: Ignore, vehicle will use default speed"));
1434 ImGui::Text(
_LC(
"TopMenubar",
"Value >= 5: Override default speed"));
1435 ImGui::EndTooltip();
1444 ImGui::PopItemWidth();
1454 menu_pos.y = window_pos.y + tuning_cursor.y +
MENU_Y_OFFSET;
1455 menu_pos.x = tuning_cursor.x + window_pos.x - ImGui::GetStyle().WindowPadding.x;
1456 ImGui::SetNextWindowPos(menu_pos);
1457 if (ImGui::Begin(
_LC(
"TopMenubar",
"Tuning menu"),
nullptr,
static_cast<ImGuiWindowFlags_
>(flags)))
1463 ImGui::Text(
"%s",
_LC(
"Tuning",
"You are on foot."));
1464 ImGui::Text(
"%s",
_LC(
"Tuning",
"Enter a vehicle to tune it."));
1465 ImGui::PopStyleColor();
1476 ImGui::PushID(tuneup_result.cqr_entry->fname.c_str());
1478 ImGui::AlignTextToFramePadding();
1483 if (ImGui::Button(tuneup_result.cqr_entry->dname.c_str()))
1487 req->
mpr_subject = tuneup_result.cqr_entry->fname;
1499 std::string delbtn_text =
_LC(
"Tuning",
"Delete");
1500 float delbtn_w = ImGui::CalcTextSize(delbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1501 float delbtn_cursorx = ImGui::GetWindowContentRegionWidth() - delbtn_w;
1504 ImGui::SetCursorPosX(delbtn_cursorx);
1507 ImGui::PopStyleColor();
1518 ImGui::AlignTextToFramePadding();
1519 ImGui::TextDisabled(
_LC(
"Tuning",
"Working tuneup"));
1524 if (ImGui::Button(
_LC(
"Tuning",
"Save")))
1540 std::string cancelbtn_text =
_LC(
"Tuning",
"Cancel");
1541 float cancelbtn_w = ImGui::CalcTextSize(cancelbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1542 float cancelbtn_cursorx = ImGui::GetWindowContentRegionWidth() - cancelbtn_w;
1545 ImGui::SetCursorPosX(cancelbtn_cursorx);
1546 if (ImGui::SmallButton(
_LC(
"Tuning",
"Cancel")))
1552 else if (tuneup_def)
1555 if (ImGui::Button(
_LC(
"Tuning",
"Save as...")))
1564 ImGui::AlignTextToFramePadding();
1565 std::string resetbtn_text =
_LC(
"Tuning",
"Reset");
1566 float delbtn_w = ImGui::CalcTextSize(resetbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1567 float delbtn_cursorx = ImGui::GetWindowContentRegionWidth() - delbtn_w;
1570 ImGui::SetCursorPosX(delbtn_cursorx);
1573 ImGui::PopStyleColor();
1574 if (resetbtn_pressed)
1585 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
1586 std::string addonparts_title = fmt::format(
_LC(
"TopMenubar",
"Addon parts ({})"),
tuning_addonparts.size());
1587 if (ImGui::CollapsingHeader(addonparts_title.c_str()))
1593 ImGui::PushID(addonpart_entry->
fname.c_str());
1598 const ImVec2 checkbox_cursor = ImGui::GetCursorScreenPos();
1599 if (ImGui::Checkbox(addonpart_entry->
dname.c_str(), &used)
1600 && !conflict_w_hovered
1615 const float square_sz = ImGui::GetFrameHeight();
1616 const ImVec2 min = checkbox_cursor + ImGui::GetStyle().FramePadding*1.4f;
1617 const ImVec2 max = checkbox_cursor + (ImVec2(square_sz, square_sz) - ImGui::GetStyle().FramePadding*1.5f);
1618 const ImColor X_COLOR(0.5f, 0.48f, 0.45f);
1619 ImGui::GetWindowDrawList()->AddLine(min, max, X_COLOR, 4.f);
1620 ImGui::GetWindowDrawList()->AddLine(ImVec2(min.x, max.y), ImVec2(max.x, min.y), X_COLOR, 4.f);
1622 if (conflict_w_hovered)
1625 const float square_sz = ImGui::GetFrameHeight();
1626 const ImVec2 min = checkbox_cursor;
1627 const ImVec2 max = checkbox_cursor + ImVec2(square_sz + 0.5f, square_sz);
1628 const ImColor SQ_COLOR(0.7f, 0.1f, 0.f);
1629 ImGui::GetWindowDrawList()->AddRect(min, max, SQ_COLOR, 0.f, ImDrawCornerFlags_None, 3.f);
1632 if (ImGui::IsItemHovered())
1644 ImGui::AlignTextToFramePadding();
1645 std::string reloadbtn_text =
_LC(
"Tuning",
"Reload");
1646 const float reloadbtn_w = ImGui::CalcTextSize(reloadbtn_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
1648 ImGui::SetCursorPosX(reloadbtn_cursorx);
1649 const bool reloadbtn_pressed = ImGui::SmallButton(reloadbtn_text.c_str());
1650 if (reloadbtn_pressed)
1673 if (ImGui::Button(
_LC(
"Tuning",
"Browse all parts")))
1683 std::string props_title = fmt::format(
_LC(
"Tuning",
"Props ({})"), total_props);
1684 if (ImGui::CollapsingHeader(props_title.c_str()))
1689 ImGui::PushID(p.pp_id);
1690 ImGui::AlignTextToFramePadding();
1703 if (p.pp_beacon_type ==
'L' || p.pp_beacon_type ==
'R' || p.pp_beacon_type ==
'w')
1706 ImGui::TextDisabled(
"(special!)");
1707 if (ImGui::IsItemHovered())
1709 ImGui::BeginTooltip();
1710 ImGui::Text(
"special prop - aerial nav light");
1711 ImGui::EndTooltip();
1714 else if (p.pp_wheel_mesh_obj)
1717 ImGui::TextDisabled(
"(special!)");
1718 if (ImGui::IsItemHovered())
1720 ImGui::BeginTooltip();
1721 ImGui::Text(
"special prop - dashboard + dirwheel");
1722 ImGui::EndTooltip();
1741 std::string flexbodies_title = fmt::format(
_LC(
"Tuning",
"Flexbodies ({})"), total_flexbodies);
1742 if (ImGui::CollapsingHeader(flexbodies_title.c_str()))
1747 ImGui::PushID(flexbody->getID());
1748 ImGui::AlignTextToFramePadding();
1754 flexbody->getOrigMeshName(),
1772 std::string wheels_title = fmt::format(
_LC(
"TopMenubar",
"Wheels ({})"), total_wheels);
1773 if (ImGui::CollapsingHeader(wheels_title.c_str()))
1775 for (
WheelID_t i = 0; i < total_wheels; i++)
1778 ImGui::AlignTextToFramePadding();
1786 ImGui::PushStyleColor(ImGuiCol_Border,
ORANGE_TEXT);
1787 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f);
1794 ImGui::TextDisabled(
"|");
1805 bool resetPressed =
false;
1811 resetPressed = ImGui::SmallButton(
_LC(
"Tuning",
"Reset"));
1812 ImGui::PopStyleColor();
1813 ImGui::PopStyleVar();
1814 ImGui::PopStyleColor();
1818 if (selected_side != active_side)
1827 else if (resetPressed)
1848 std::string flares_title = fmt::format(
_LC(
"Tuning",
"Flares ({})"), total_flares);
1849 if (ImGui::CollapsingHeader(flares_title.c_str()))
1854 ImGui::PushID(flareid);
1855 ImGui::AlignTextToFramePadding();
1861 std::string flarename;
1865 flarename = fmt::format(
"{} {}", (
char)flaretype, controlnumber);
1870 flarename = fmt::format(
"{} {}", (
char)flaretype, linkname);
1874 flarename = fmt::format(
"{}", (
char)flaretype);
1897 std::string exhausts_title = fmt::format(
_LC(
"Tuning",
"Exhausts ({})"), total_exhausts);
1898 if (ImGui::CollapsingHeader(exhausts_title.c_str()))
1901 for (
ExhaustID_t exhaustid = 0; exhaustid < (int)total_exhausts; exhaustid++)
1903 ImGui::PushID(exhaustid);
1904 ImGui::AlignTextToFramePadding();
1928 std::string materials_title = fmt::format(
_LC(
"Tuning",
"Managed Materials ({})"), total_materials);
1929 if (ImGui::CollapsingHeader(materials_title.c_str()))
1934 const std::string& material_name = mm_pair.first;
1935 ImGui::PushID(material_name.c_str());
1936 ImGui::AlignTextToFramePadding();
1959 std::string videocameras_title = fmt::format(
_LC(
"Tuning",
"Videocameras ({})"), total_videocameras);
1960 if (ImGui::CollapsingHeader(videocameras_title.c_str()))
1963 for (
VideoCameraID_t videocameraid = 0; videocameraid < (int)total_videocameras; videocameraid++)
1965 ImGui::PushID(videocameraid);
1966 ImGui::AlignTextToFramePadding();
1974 ImGui::Dummy(ImVec2(3, 3));
1983 ImGui::PushStyleColor(ImGuiCol_Border,
ORANGE_TEXT);
1984 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f);
1990 bool checkbox_pressed =
false;
1992 if ((is_mirror_flip || is_mirror_noflip))
1995 bool checkbox_checked = is_mirror_flip;
1996 checkbox_pressed = ImGui::Checkbox(
_LC(
"Tuning",
"Flipped"), &checkbox_checked);
2014 default: ImGui::TextDisabled(
_LC(
"Tuning",
"(Videocamera)"));
break;
2020 bool reset_pressed =
false;
2026 reset_pressed = ImGui::SmallButton(
_LC(
"Tuning",
"Reset"));
2027 ImGui::PopStyleColor();
2028 ImGui::PopStyleVar();
2029 ImGui::PopStyleColor();
2033 if (checkbox_pressed)
2042 else if (reset_pressed)
2070 ImGui::PopStyleColor(2);
2080 if (ImGui::IsMouseDown(1))
2091 ImVec2 box_min(0,0);
2092 ImVec2 box_max(ImGui::GetIO().DisplaySize.x, ImGui::GetStyle().WindowPadding.y +
PANEL_HOVERBOX_HEIGHT);
2093 ImVec2 mouse_pos = ImGui::GetIO().MousePos;
2094 const bool window_hovered ((mouse_pos.x >= box_min.x) && (mouse_pos.x <= box_max.x) &&
2095 (mouse_pos.y >= box_min.y) && (mouse_pos.y <= box_max.y));
2096 bool result = window_hovered;
2098 bool menu_hovered =
false;
2104 result |= menu_hovered;
2106 bool box_hovered =
false;
2111 result |= box_hovered;
2114 if (box_hovered && !menu_hovered)
2125 unsigned int num_actors_player = 0;
2128 if (actor->ar_net_source_id == user.
uniqueid)
2130 ++num_actors_player;
2137 ImVec4 player_gui_color(player_color.r, player_color.g, player_color.b, 1.f);
2138 ImGui::PushStyleColor(ImGuiCol_Text, player_gui_color);
2139 ImGui::Text(
"%s: %u (%s, Ver: %s, Lang: %s)",
2143 ImGui::PopStyleColor();
2147 Ogre::TexturePtr tex1 =
FetchIcon(
"control_pause.png");
2148 Ogre::TexturePtr tex2 =
FetchIcon(
"control_play.png");
2152 if ((!actor->ar_hide_in_actor_list) && (actor->ar_net_source_id == user.
uniqueid))
2154 std::string
id = fmt::format(
"{}:{}", i++, user.
uniqueid);
2155 ImGui::PushID(
id.c_str());
2158 if (ImGui::ImageButton(
reinterpret_cast<ImTextureID
>(tex1->getHandle()), ImVec2(16, 16)))
2165 if (ImGui::ImageButton(
reinterpret_cast<ImTextureID
>(tex2->getHandle()), ImVec2(16, 16)))
2172 std::string text_buf_rem = fmt::format(
" X ##[{}]", i);
2173 ImGui::PushStyleColor(ImGuiCol_Text,
RED_TEXT);
2174 if (ImGui::Button(text_buf_rem.c_str()))
2178 ImGui::PopStyleColor();
2183 std::string actortext_buf = fmt::format(
"{} ({}) ##[{}:{}]",
StripColorMarksFromText(actor->ar_design_name).c_str(), actor->ar_filename.c_str(), i++, user.
uniqueid);
2184 if (ImGui::Button(actortext_buf.c_str()))
2194 std::vector<ActorPtr> actor_list;
2197 if (!actor->ar_hide_in_actor_list)
2199 actor_list.emplace_back(actor);
2202 if (actor_list.empty())
2205 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"None spawned yet"));
2206 ImGui::Text(
"%s",
_LC(
"TopMenubar",
"Use [Simulation] menu"));
2207 ImGui::PopStyleColor();
2215 std::string text_buf_rem = fmt::format(
"X ##[{}]", i);
2216 ImGui::PushStyleColor(ImGuiCol_Text,
RED_TEXT);
2217 if (ImGui::Button(text_buf_rem.c_str()))
2221 ImGui::PopStyleColor();
2225 if (actor == player_actor)
2227 ImGui::PushStyleColor(ImGuiCol_Text,
GREEN_TEXT);
2229 else if (std::find(actor->ar_linked_actors.begin(), actor->ar_linked_actors.end(), player_actor) != actor->ar_linked_actors.end())
2231 ImGui::PushStyleColor(ImGuiCol_Text,
ORANGE_TEXT);
2235 ImGui::PushStyleColor(ImGuiCol_Text,
WHITE_TEXT);
2241 if (ImGui::Button(text_buf.c_str()))
2245 ImGui::PopStyleColor();
2262 float content_width = 0.f;
2264 std::string special_text;
2265 ImVec4 special_color = ImGui::GetStyle().Colors[ImGuiCol_Text];
2266 float special_text_centering_weight = 1.f;
2268 std::string special_text_b;
2269 std::string special_text_c;
2270 std::string special_text_d;
2271 ImVec4 special_color_c = ImVec4(0,0,0,0);
2278 special_text = fmt::format(
_LC(
"TopMenubar",
"All physics paused, press {} to resume"),
2280 content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2287 special_text = fmt::format(
_LC(
"TopMenubar",
"Vehicle physics paused, press {} to resume"),
2289 content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2294 content_width = 300;
2296 special_text =
_LC(
"TopMenubar",
"Replay");
2300 special_text = fmt::format(
_LC(
"TopMenubar",
"Live repair mode, hit '{}' to stop"),
2302 content_width = 450;
2305 special_text_centering_weight = 0.7f;
2309 special_text = fmt::format(
_LC(
"TopMenubar",
"Quick repair ('{}' for Live repair)"),
2311 content_width = 450;
2314 special_text_centering_weight = 0.7f;
2323 float distance = 0.0f;
2337 special_text_b = fmt::format(
"{:.1f} {}", distance,
_LC(
"DirectionArrow",
"meter"));
2338 content_width = ImGui::CalcTextSize(special_text.c_str()).x + ImGui::CalcTextSize(special_text_b.c_str()).x;
2341 special_text_c = fmt::format(
"{:02d}.{:02d}.{:02d}", (
int)(time) / 60, (
int)(time) % 60, (
int)(time * 100.0) % 100);
2343 special_color_c = (time_diff > 0.0f)
2350 special_text_d = fmt::format(
"{:02d}.{:02d}.{:02d}", (
int)(best_time) / 60, (
int)(best_time) % 60, (
int)(best_time * 100.0) % 100);
2356 special_text = fmt::format(
_LC(
"TopMenubar",
"Terrain editing mode, press {} to exit"),
2362 content_width = ImGui::CalcTextSize(special_text.c_str()).x + 25.f;
2367 special_text = fmt::format(
_LC(
"TopMenubar",
"Terrain editing mode, press {} to exit"),
2369 content_width = ImGui::CalcTextSize(special_text.c_str()).x;
2375 if (!special_text.empty())
2378 box_pos.y = top_offset;
2379 box_pos.x = (ImGui::GetIO().DisplaySize.x / 2) - ((content_width / 2) + ImGui::GetStyle().FramePadding.x);
2380 ImGui::SetNextWindowPos(box_pos);
2381 ImGui::SetNextWindowSize(ImVec2(0.f, 0.f));
2382 ImGui::SetNextWindowContentWidth(content_width);
2383 ImGuiWindowFlags flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
2384 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse;
2385 ImGui::PushStyleColor(ImGuiCol_WindowBg,
App::GetGuiManager()->GetTheme().semitransparent_window_bg);
2386 if (ImGui::Begin(special_text.c_str(),
nullptr, flags))
2391 float text_w = ImGui::CalcTextSize(special_text.c_str()).x;
2392 ImGui::SetCursorPosX(((content_width / 2) - (text_w / 2)) * special_text_centering_weight);
2394 ImGui::TextColored(special_color,
"%s", special_text.c_str());
2404 float pbar_width = content_width - (ImGui::GetStyle().ItemSpacing.x + ImGui::CalcTextSize(special_text.c_str()).x);
2405 ImGui::ProgressBar(fraction, ImVec2(pbar_width, ImGui::GetTextLineHeight()), pbar_text.
ToCStr());
2413 int min = (int)time_sec / 60;
2414 str_pos = snprintf(str, 200,
"%dmin ", min);
2415 time_sec -= (float)min * 60.f;
2417 snprintf(str+str_pos, 200-str_pos,
"%.2fsec", time_sec);
2418 ImGui::TextDisabled(
"%s: %s",
_LC(
"TopMenubar",
"Time"), str);
2424 ImGui::Text(special_text_b.c_str());
2425 ImGui::SetCursorPosX((ImGui::GetWindowSize().
x / 2) - (ImGui::CalcTextSize(special_text_c.c_str()).x / 2));
2426 ImGui::TextColored(special_color_c,
"%s", special_text_c.c_str());
2429 text <<
"Best Time: " << special_text_d.c_str();
2430 ImGui::SetCursorPosX((ImGui::GetWindowSize().
x / 2) - (ImGui::CalcTextSize(text).
x / 2));
2432 if (!special_text_d.empty())
2434 ImGui::TextDisabled(text);
2441 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.f, 0.f));
2445 ImGui::ProgressBar(fraction, ImVec2(15.f, ImGui::GetTextLineHeight() / 2.f),
"");
2449 ImGui::PopStyleVar();
2451 const ImVec2 MINI_SPACING = ImVec2(2.f,0.f);
2452 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, MINI_SPACING);
2456 const float INDENT = 15.f;
2458 ImGui::TextDisabled(
"%s:",
_LC(
"LiveRepair",
"Movement"));
2460 ImGui::SetColumnWidth(0, INDENT);
2461 ImGui::NextColumn();
2464 ImGui::NextColumn();
2467 ImGui::NextColumn();
2472 ImGui::TextDisabled(
"%s:",
_LC(
"LiveRepair",
"Rotation"));
2474 ImGui::SetColumnWidth(0, INDENT);
2475 ImGui::NextColumn();
2480 ImGui::TextDisabled(
"%s:",
_LC(
"LiveRepair",
"Modifiers"));
2482 ImGui::SetColumnWidth(0, INDENT);
2483 ImGui::SetColumnWidth(1, 125);
2484 ImGui::SetColumnWidth(2, 125);
2485 ImGui::NextColumn();
2492 ImGui::TextDisabled(
"%s (%s):",
_LC(
"LiveRepair",
"Reset mode"),
ToLocalizedString(resetmode).c_str());
2493 ImGui::Dummy(ImVec2(INDENT, 1.f));
2497 ImGui::PopStyleVar();
2503 std::string lbl_readonly =
_LC(
"TopMenubar",
"This terrain is read only.");
2504 ImGui::SetCursorPosX(ImGui::GetCursorPosX()
2505 + (ImGui::GetWindowContentRegionWidth() / 2 - ImGui::CalcTextSize(lbl_readonly.c_str()).x/2));
2506 ImGui::TextDisabled(
"%s", lbl_readonly.c_str());
2508 ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2, 0.2, 0.2, 1.0));
2509 std::string btn_import =
_LC(
"TopMenubar",
"Import as editable project.");
2510 ImGui::SetCursorPosX(ImGui::GetCursorPosX()
2511 + ((ImGui::GetWindowContentRegionWidth() / 2 - ImGui::CalcTextSize(btn_import.c_str()).x / 2) - ImGui::GetStyle().FramePadding.x));
2520 ImGui::PopStyleColor();
2525 std::string lbl_usemenu =
_LC(
"TopMenubar",
"Use 'Simulation' menu to save changes.");
2526 ImGui::SetCursorPosX(ImGui::GetCursorPosX()
2527 + (ImGui::GetWindowContentRegionWidth() / 2 - ImGui::CalcTextSize(lbl_usemenu.c_str()).x / 2));
2528 ImGui::TextDisabled(
"%s", lbl_usemenu.c_str());
2530 const ImVec2 PAD = ImVec2(5, 5);
2538 ImGui::PopStyleColor(1);
2554 for (
const std::string& filename: terrain->
GetDef()->ai_presets_files)
2556 rapidjson::Document j_doc;
2563 LOG(fmt::format(
"[RoR|Terrain] AI presets file '{}' declared in '{}' not found!", filename, terrain->
getTerrainFileName()));
2567 if (!j_doc.IsArray())
2569 LOG(fmt::format(
"[RoR|Terrain] AI presets file '{}' declared in '{}' has wrong format - the root element is not an array!",
2575 for (
const rapidjson::Value& j_bundled_preset: j_doc.GetArray())
2588#if defined(USE_CURL)
2590 std::thread(std::move(task)).detach();
2605 rapidjson::Value preset_copy(bundled_preset,
ai_presets_all.GetAllocator());
2611 rapidjson::Value preset_copy(extern_preset,
ai_presets_all.GetAllocator());
2717 std::string protectchk_text =
_LC(
"Tuning",
"Protected");
2718 float protectchk_w = ImGui::CalcTextSize(protectchk_text.c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
2719 float protectchk_cursorx = (ImGui::GetWindowContentRegionWidth() - protectchk_w) - 20.f;
2722 ImGui::SetCursorPosX(protectchk_cursorx);
2725 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
2726 bool chk_pressed = ImGui::Checkbox(protectchk_text.c_str(), &protectchk_value);
2727 ImGui::PopStyleVar(1);
2742 request->
mpr_type = (protectchk_value) ? request_type_set : request_type_reset;
2751 ImGui::GetWindowDrawList()->AddRect(
2752 ImGui::GetCursorScreenPos(),
2753 ImGui::GetCursorScreenPos() + ImGui::CalcTextSize(
"00") + ImGui::GetStyle().FramePadding*2,
2754 ImColor(ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]),
2755 ImGui::GetStyle().FrameRounding);
2756 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().FramePadding.x);
2757 ImGui::Text(
"%02d", subject_id);
2759 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().FramePadding.x);
2768 bool isEnabled = !is_unwanted && !is_force_removed;
2769 if (is_force_removed)
2771 ImGui::PushStyleColor(ImGuiCol_Border,
ORANGE_TEXT);
2772 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.f);
2774 bool chkPressed = ImGui::Checkbox(name.c_str(), &isEnabled);
2775 bool resetPressed =
false;
2776 if (is_force_removed)
2780 resetPressed = ImGui::SmallButton(
_LC(
"Tuning",
"Reset"));
2781 ImGui::PopStyleColor();
2782 ImGui::PopStyleVar();
2783 ImGui::PopStyleColor();
2787 if (chkPressed && !isEnabled)
2802 else if ((chkPressed && isEnabled) || resetPressed)
2805 req->
mpr_type = request_type_reset;
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
void LOG(const char *msg)
Legacy alias - formerly a macro.
Game state manager and message-queue provider.
CacheEntryPtr & getUsedSkinEntry()
DashBoardManagerPtr ar_dashboard
float getMinHeight(bool skip_virtual_nodes=true)
Ogre::Vector3 getPosition()
std::vector< flare_t > ar_flares
std::string getTruckFileName()
std::map< std::string, Ogre::MaterialPtr > ar_managed_materials
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Ogre::String getSectionConfig()
CacheEntryPtr & getUsedActorEntry()
The actor entry itself.
TuneupDefPtr & getWorkingTuneupDef()
ActorPtrVec & GetActors()
bool LoadScene(Ogre::String filename)
void SetSimulationSpeed(float speed)
bool SaveScene(Ogre::String filename)
void SendAllActorsSleeping()
void SetTrucksForcedAwake(bool forced)
bool AreTrucksForcedAwake() const
std::vector< ActorPtr > GetLocalActors()
static bool CheckForAddonpartConflict(CacheEntryPtr addonpart1, CacheEntryPtr addonpart2, AddonPartConflictVec &conflicts)
static void RecordAddonpartConflicts(CacheEntryPtr addonpart1, CacheEntryPtr addonpart2, AddonPartConflictVec &conflicts)
std::string const & getStr() const
Ogre::String fname
filename
Ogre::String dname
name parsed from the file
Ogre::String guid
global unique id; Type "addonpart" leaves this empty and uses addonpart_guids; Always lowercase.
CacheEntryPtr FindEntryByFilename(RoR::LoaderType type, bool partial, const std::string &_filename_maybe_bundlequalified)
Returns NULL if none found; "Bundle-qualified" format also specifies the ZIP/directory in modcache,...
size_t Query(CacheQuery &query)
@ CAMERA_BEHAVIOR_VEHICLE_CINECAM
Ogre::Vector3 getPosition()
@ CONSOLE_MSGTYPE_INFO
Generic message.
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
bool LoadAndParseJson(std::string const &filename, std::string const &rg_name, rapidjson::Document &j_doc)
std::string getLinkNameForID(DashData id)
Flexbody = A deformable mesh; updated on CPU every frame, then uploaded to video memory.
void SetVisible(bool visible)
void SetVisible(bool value)
void SetVisible(bool visible)
void SetVisible(bool visible)
void SetVisible(bool visible)
void SetVisible(bool visible)
void SetVisible(TPanelMode mode, TPanelFocus focus=TPANELFOCUS_NONE)
GUI::RepositorySelector RepositorySelector
GUI::TextureToolWindow TextureToolWindow
GUI::VehicleInfoTPanel VehicleInfoTPanel
GUI::TopMenubar TopMenubar
GUI::FrictionSettings FrictionSettings
GUI::CollisionsDebug CollisionsDebug
void RequestGuiCaptureKeyboard(bool val)
Pass true during frame to prevent input passing to application.
GUI::NodeBeamUtils NodeBeamUtils
GUI::ConsoleWindow ConsoleWindow
GUI::FlexbodyDebug FlexbodyDebug
Character * GetPlayerCharacter()
const ActorPtr & GetPlayerActor()
const TerrainPtr & GetTerrain()
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
const ActorPtr & GetLastSpawnedActor()
Last actor spawned by user and still alive.
RepairMode & GetRepairMode()
void ChainMessage(Message m)
Add to last pushed message's chain.
std::string GetQuicksaveFilename()
For currently loaded terrain (cvar 'sim_terrain_name')
ActorManager * GetActorManager()
std::vector< FlexBody * > & GetFlexbodies()
ActorSB & GetSimDataBuffer()
std::string getWheelRimMeshName(WheelID_t wheel_id)
std::vector< VideoCamera > & getVideoCameras()
std::vector< Prop > & getProps()
WheelSide getWheelSide(WheelID_t wheel_id)
std::vector< Exhaust > & getExhausts()
DebugViewType GetDebugView() const
GameContextSB & GetSimDataBuffer()
Ogre::ColourValue GetPlayerColor(int color_num)
std::string UserAuthToStringShort(RoRnet::UserInfo const &user)
RoRnet::UserInfo GetLocalUserData()
std::vector< RoRnet::UserInfo > GetUserInfos()
float GetLiveRepairTimer() const
int getCurrentFrame() const
unsigned long getLastReadTime()
ScriptUnitID_t loadScript(Ogre::String filename, ScriptCategory category=ScriptCategory::TERRAIN, ActorPtr associatedActor=nullptr, std::string buffer="")
Loads a script.
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
const char * ToCStr() const
size_t GetCapacity() const
std::string getTerrainFileResourceGroup()
SkyManager * getSkyManager()
std::string getTerrainFileName()
Terrn2DocumentPtr GetDef()
static bool isAddonPartUsed(TuneupDefPtr &tuneup_entry, const std::string &filename)
static WheelSide getTweakedWheelSide(TuneupDefPtr &tuneup_entry, WheelID_t wheel_id, WheelSide orig_val)
void SetWavesHeight(float)
std::string PathCombine(std::string a, std::string b)
bool FileExists(const char *path)
Path must be UTF-8 encoded.
@ EDITOR_MODE
Hacky, but whatever... added by Ulteq, 2016.
@ AI
machine controlled by an Artificial Intelligence
@ MSG_GUI_OPEN_MENU_REQUESTED
@ MSG_SIM_TELEPORT_PLAYER_REQUESTED
Payload = Ogre::Vector3* (owner)
@ MSG_NET_FETCH_AI_PRESETS_SUCCESS
Description = JSON string.
@ MSG_SIM_UNHIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
@ MSG_SIM_HIDE_NET_ACTOR_REQUESTED
Payload = ActorPtr* (owner)
@ MSG_SIM_UNLOAD_TERRN_REQUESTED
@ MSG_NET_DISCONNECT_REQUESTED
@ MSG_NET_FETCH_AI_PRESETS_FAILURE
Description = message.
@ MSG_SIM_SPAWN_ACTOR_REQUESTED
Payload = RoR::ActorSpawnRequest* (owner)
@ MSG_GUI_OPEN_SELECTOR_REQUESTED
Payload = LoaderType* (owner), Description = GUID | empty.
@ MSG_SIM_SEAT_PLAYER_REQUESTED
Payload = RoR::ActorPtr (owner) | nullptr.
@ MSG_EDI_SAVE_TERRN_CHANGES_REQUESTED
@ MSG_APP_LOAD_SCRIPT_REQUESTED
Payload = RoR::LoadScriptRequest* (owner)
@ MSG_SIM_LOAD_SAVEGAME_REQUESTED
@ MSG_APP_SHUTDOWN_REQUESTED
@ MSG_EDI_CREATE_PROJECT_REQUESTED
Payload = RoR::CreateProjectRequest* (owner)
@ MSG_EDI_DELETE_PROJECT_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
@ MSG_EDI_MODIFY_PROJECT_REQUESTED
Payload = RoR::UpdateProjectRequest* (owner)
@ MSG_SIM_LOAD_TERRN_REQUESTED
@ MSG_SIM_DELETE_ACTOR_REQUESTED
Payload = RoR::ActorPtr* (owner)
@ MSG_SIM_MODIFY_ACTOR_REQUESTED
Payload = RoR::ActorModifyRequest* (owner)
@ MSG_EDI_RELOAD_BUNDLE_REQUESTED
Payload = RoR::CacheEntryPtr* (owner)
@ LOCAL_SIMULATED
simulated (local) actor
@ NETWORKED_OK
not simulated (remote) actor
@ NETWORKED_HIDDEN
not simulated, not updated (remote)
@ CUSTOM
Loaded by user via either: A) ingame console 'loadscript'; B) RoR.cfg 'app_custom_scripts'; C) comman...
std::string ToLocalizedString(SimGearboxMode e)
ContentManager * GetContentManager()
CVar * gfx_static_cam_fov_exp
CVar * ui_show_live_repair_controls
bool
CVar * gfx_sky_time_cycle
CVar * mp_hide_net_labels
InputEngine * GetInputEngine()
CVar * diag_log_beam_trigger
CVar * gfx_sky_time_speed
CameraManager * GetCameraManager()
CVar * audio_master_volume
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CVar * sim_tuning_enabled
CVar * sim_soft_reset_mode
CVar * diag_log_beam_deform
CVar * sim_live_repair_interval
Hold EV_COMMON_REPAIR_TRUCK to enter LiveRepair mode. 0 or negative interval disables.
CVar * mp_pseudo_collisions
ScriptEngine * GetScriptEngine()
CacheSystem * GetCacheSystem()
CVar * gfx_envmap_enabled
CVar * diag_log_beam_break
CVar * gfx_fixed_cam_tracking
void ImDrawEventHighlighted(events input_event)
void Log(const char *msg)
The ultimate, application-wide logging function. Adds a line (any length) in 'RoR....
LoaderType
< Search mode for ModCache::Query() & Operation mode for GUI::MainSelector
@ SAVE_TUNEUP
Dumps .tuneup file with CID_Tuneup from source actor, will not overwrite existing unless explicitly i...
@ TUNEUP_PROTECTED_WHEEL_RESET
'subject_id' is wheel ID.
@ TUNEUP_FORCED_VCAM_ROLE_RESET
'subject_id' is video camera ID.
@ TUNEUP_FORCEREMOVE_MANAGEDMAT_RESET
'subject' is managed material name.
@ TUNEUP_FORCEREMOVE_FLEXBODY_SET
'subject_id' is flexbody ID.
@ TUNEUP_PROTECTED_WHEEL_SET
'subject_id' is wheel ID.
@ TUNEUP_PROTECTED_MANAGEDMAT_SET
'subject' is managed material name.
@ TUNEUP_FORCEREMOVE_EXHAUST_SET
'subject_id' is exhaust ID.
@ TUNEUP_USE_ADDONPART_RESET
'subject' is addonpart filename.
@ TUNEUP_PROTECTED_PROP_SET
'subject_id' is prop ID.
@ TUNEUP_USE_ADDONPART_SET
'subject' is addonpart filename.
@ TUNEUP_FORCEREMOVE_PROP_SET
'subject_id' is prop ID.
@ TUNEUP_PROTECTED_EXHAUST_SET
'subject_id' is exhaust ID.
@ TUNEUP_PROTECTED_FLARE_SET
'subject_id' is flare ID.
@ TUNEUP_FORCED_WHEEL_SIDE_RESET
'subject_id' is wheel ID.
@ TUNEUP_FORCEREMOVE_MANAGEDMAT_SET
'subject' is managed material name.
@ TUNEUP_PROTECTED_FLEXBODY_RESET
'subject_id' is flexbody ID.
@ TUNEUP_PROTECTED_FLEXBODY_SET
'subject_id' is flexbody ID.
@ TUNEUP_FORCED_WHEEL_SIDE_SET
'subject_id' is wheel ID, 'value_int' is RoR::WheelSide
@ TUNEUP_PROTECTED_EXHAUST_RESET
'subject_id' is exhaust ID.
@ TUNEUP_PROTECTED_MANAGEDMAT_RESET
'subject' is managed material name.
@ TUNEUP_FORCED_VCAM_ROLE_SET
'subject_id' is video camera ID, 'value_int' is RoR::VideoCamRole
@ PROJECT_RESET_TUNEUP
'subject' is empty. This resets the auto-generated tuneup to orig. values.
@ TUNEUP_FORCEREMOVE_FLARE_RESET
'subject_id' is flare ID.
@ TUNEUP_PROTECTED_PROP_RESET
'subject_id' is prop ID.
@ TUNEUP_FORCEREMOVE_FLEXBODY_RESET
'subject_id' is flexbody ID.
@ TUNEUP_FORCEREMOVE_PROP_RESET
'subject_id' is prop ID.
@ TUNEUP_PROTECTED_FLARE_RESET
'subject_id' is flare ID.
@ TUNEUP_FORCEREMOVE_EXHAUST_RESET
'subject_id' is exhaust ID.
@ PROJECT_LOAD_TUNEUP
'subject' is tuneup filename. This overwrites the auto-generated tuneup with the save.
@ TUNEUP_FORCEREMOVE_FLARE_SET
'subject_id' is flare ID.
void HandleGenericException(const std::string &from, BitMask_t flags)
WheelSide
Used by rig-def/addonpart/tuneup formats to specify wheel rim mesh orientation.
@ VCAM_ROLE_MIRROR
Flips the video output and when not in driver cam, acts like a natural mirror, not a screen.
@ VCAM_ROLE_TRACKING_MIRROR_NOFLIP
A MIRROR_NOFLIP(2) with tracking node set.
@ VCAM_ROLE_TRACKING_MIRROR
A MIRROR(1) with tracking node set.
@ VCAM_ROLE_MIRROR_PROP_LEFT
The classic 'special prop/rear view mirror'.
@ VCAM_ROLE_MIRROR_PROP_RIGHT
The classic 'special prop/rear view mirror'.
@ VCAM_ROLE_MIRROR_NOFLIP
Same as VCAM_ROLE_MIRROR, but without flipping the texture horizontally (expects texcoords to be alre...
void DrawGIntSlider(CVar *cvar, const char *label, int v_min, int v_max)
int WheelID_t
Index to Actor::ar_wheels, use RoR::WHEELID_INVALID as empty value.
RefCountingObjectPtr< Actor > ActorPtr
int VideoCameraID_t
Index into GfxActor::m_videocameras, use RoR::VIDEOCAMERAID_INVALID as empty value.
@ CAELUM
Caelum (best looking, slower)
int FlareID_t
Index into Actor::ar_flares, use RoR::FLAREID_INVALID as empty value.
int ExhaustID_t
Index into GfxActor::m_exhausts, use RoR::EXHAUSTID_INVALID as empty value.
void ImDrawModifierKeyHighlighted(OIS::KeyCode key)
void DrawGFloatSlider(CVar *cvar, const char *label, float v_min, float v_max)
bool DrawGCheckbox(CVar *cvar, const char *label)
@ CID_Tuneups
For unsorted tuneup files.
std::string StripColorMarksFromText(std::string const &text)
RefCountingObjectPtr< CacheEntry > CacheEntryPtr
Ogre::TexturePtr FetchIcon(const char *name)
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.
bool ImButtonHoldToConfirm(const std::string &btn_idstr, const bool smallbutton, const float time_limit)
ActorInstanceID_t amr_actor
@ RELOAD
Full reload from filesystem, requested by user.
ActorState simbuf_actor_state
CacheEntryPtr asr_cache_entry
Optional, overrides 'asr_filename' and 'asr_cache_entry_num'.
TuneupDefPtr asr_working_tuneup
Only filled when editing tuneup via Tuning menu.
Ogre::Vector3 asr_position
CacheEntryPtr asr_skin_entry
Ogre::Quaternion asr_rotation
@ USER
Direct selection by user via GUI.
int cqy_filter_category_id
std::string cqy_filter_target_filename
Exact match (case-insensitive); leave empty to disable (currently only used with addonparts)
std::string cqy_filter_guid
Exact match (case-insensitive); leave empty to disable.
std::vector< CacheQueryResult > cqy_results
RoR::LoaderType cqy_filter_type
Creates subdirectory in 'My Games\Rigs of Rods\projects', pre-populates it with files and adds modcac...
CreateProjectRequestType cpr_type
CacheEntryPtr cpr_source_entry
The original mod to copy files from.
std::string cpr_name
Directory and also the mod file (without extension).
ActorPtr cpr_source_actor
Only for type SAVE_TUNEUP
ImVec4 semitransparent_window_bg
ImVec4 success_text_color
ImVec2 screen_edge_padding
ImVec4 value_blue_text_color
ImVec4 value_red_text_color
Ogre::Vector3 simbuf_character_pos
float simbuf_race_time_diff
ActorPtr simbuf_player_actor
Ogre::Vector3 simbuf_dir_arrow_target
float simbuf_race_best_time
std::string simbuf_dir_arrow_text
std::string lsr_filename
Load from resource ('.as' file or '.gadget' file); If buffer is supplied, use this as display name on...
ScriptCategory lsr_category
Unified game event system - all requests and state changes are reported using a message.
ModifyProjectRequestType mpr_type
ActorPtr mpr_target_actor
A mesh attached to vehicle frame via 3 nodes.
bool isFlexbodyUnwanted(FlexbodyID_t flexbodyid)
bool isManagedMatUnwanted(const std::string &matname)
bool isVideoCameraRoleForced(VideoCameraID_t camera_id, VideoCamRole &out_val) const
bool isFlexbodyProtected(FlexbodyID_t flexbodyid) const
bool isPropProtected(PropID_t propid) const
bool isFlareUnwanted(FlareID_t flareid)
bool isPropForceRemoved(PropID_t propid)
bool isPropUnwanted(PropID_t propid)
bool isWheelSideForced(WheelID_t wheelid, WheelSide &out_val) const
std::set< std::string > use_addonparts
Addonpart filenames.
bool isFlexbodyForceRemoved(FlexbodyID_t flexbodyid)
bool isFlareForceRemoved(FlareID_t flareid)
bool isManagedMatForceRemoved(const std::string &matname)
bool isWheelProtected(WheelID_t wheelid) const
bool isManagedMatProtected(const std::string &matname) const
bool isExhaustUnwanted(ExhaustID_t exhaustid)
bool isExhaustProtected(ExhaustID_t exhaustid) const
bool isExhaustForceRemoved(ExhaustID_t exhaustid)
bool isFlareProtected(FlareID_t flareid) const
An Ogre::Camera mounted on the actor and rendering into either in-scene texture or external window.
char language[10]
user's language. For example "de-DE" or "en-US"
char username[RORNET_MAX_USERNAME_LEN]
the nickname of the user (UTF-8)
int32_t colournum
colour set by server
uint32_t uniqueid
user unique id
char clientversion[25]
a version number of the client. For example 1 for RoR 0.35