From e08f20218b3b6e488b20daaae88203c46d146838 Mon Sep 17 00:00:00 2001 From: tritonas00 Date: Mon, 11 Sep 2023 01:08:54 +0300 Subject: [PATCH] AI: Per waypoint speed --- resources/scripts/AI.as | 15 +++- source/main/GameContext.cpp | 14 ++- source/main/gameplay/VehicleAI.cpp | 46 ++++++---- source/main/gameplay/VehicleAI.h | 2 +- source/main/gui/panels/GUI_SurveyMap.cpp | 32 +++---- source/main/gui/panels/GUI_SurveyMap.h | 2 - source/main/gui/panels/GUI_TopMenubar.cpp | 90 ++++++++++++++----- source/main/gui/panels/GUI_TopMenubar.h | 7 ++ source/main/main.cpp | 3 +- source/main/scripting/GameScript.cpp | 38 +++++++- source/main/scripting/GameScript.h | 1 + .../bindings/GameScriptAngelscript.cpp | 1 + 12 files changed, 186 insertions(+), 65 deletions(-) diff --git a/resources/scripts/AI.as b/resources/scripts/AI.as index 341d47204d..a1e1c2b3de 100644 --- a/resources/scripts/AI.as +++ b/resources/scripts/AI.as @@ -1,5 +1,7 @@ #include "base.as" +array waypoints_speed = game.getWaypointsSpeed(); + void main() { int offset = 0; @@ -50,7 +52,18 @@ void main() } CurrentTruckai.setActive(true); - CurrentTruckai.setValueAtWaypoint("way0",AI_SPEED, game.getAIVehicleSpeed()); + + for (uint i = 0; i < waypoints_speed.length(); i++) + { + if (waypoints_speed[i] >= 5) + { + CurrentTruckai.setValueAtWaypoint("way"+i, AI_SPEED, waypoints_speed[i]); + } + else + { + CurrentTruckai.setValueAtWaypoint("way"+i, AI_SPEED, -1); + } + } offset -= game.getAIVehicleDistance(); translation_x = CurrentTruckai.getTranslation(offset, 0).x; diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index 703c367150..6e687bcde4 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -34,7 +34,6 @@ #include "GUI_FrictionSettings.h" #include "GUI_MainSelector.h" #include "GUI_TopMenubar.h" -#include "GUI_SurveyMap.h" #include "InputEngine.h" #include "OverlayWrapper.h" #include "Replay.h" @@ -1112,7 +1111,14 @@ void GameContext::UpdateSimInputEvents(float dt) { if (App::GetGameContext()->GetPlayerActor()->getPosition().distance(prev_pos) >= 5) // Skip very close positions { - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(App::GetGameContext()->GetPlayerActor()->getPosition()); + ai_events waypoint; + waypoint.position = App::GetGameContext()->GetPlayerActor()->getPosition(); + waypoint.speed = App::GetGameContext()->GetPlayerActor()->getWheelSpeed() * 3.6; + if (waypoint.speed < 5) + { + waypoint.speed = -1; + } + App::GetGuiManager()->TopMenubar.ai_waypoints.push_back(waypoint); } prev_pos = App::GetGameContext()->GetPlayerActor()->getPosition(); } @@ -1120,7 +1126,9 @@ void GameContext::UpdateSimInputEvents(float dt) { if (App::GetGameContext()->GetPlayerCharacter()->getPosition() != prev_pos) // Skip same positions { - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(App::GetGameContext()->GetPlayerCharacter()->getPosition()); + ai_events waypoint; + waypoint.position = App::GetGameContext()->GetPlayerCharacter()->getPosition(); + App::GetGuiManager()->TopMenubar.ai_waypoints.push_back(waypoint); } prev_pos = App::GetGameContext()->GetPlayerCharacter()->getPosition(); } diff --git a/source/main/gameplay/VehicleAI.cpp b/source/main/gameplay/VehicleAI.cpp index fb6686210b..6e9584b329 100644 --- a/source/main/gameplay/VehicleAI.cpp +++ b/source/main/gameplay/VehicleAI.cpp @@ -32,7 +32,6 @@ #include "ScrewProp.h" #include "GUIManager.h" #include "GUI_TopMenubar.h" -#include "GUI_SurveyMap.h" #include "scriptdictionary/scriptdictionary.h" @@ -106,12 +105,12 @@ Ogre::Vector3 VehicleAI::getTranslation(int offset, unsigned int wp) { if (App::GetGuiManager()->TopMenubar.ai_position_scheme == 0) { - Ogre::Vector3 dir = App::GetGuiManager()->SurveyMap.ai_waypoints[int(wp)-1] - App::GetGuiManager()->SurveyMap.ai_waypoints[int(wp)]; + Ogre::Vector3 dir = App::GetGuiManager()->TopMenubar.ai_waypoints[int(wp)-1].position - App::GetGuiManager()->TopMenubar.ai_waypoints[int(wp)].position; translation -= offset * dir.normalisedCopy(); } else if (App::GetGuiManager()->TopMenubar.ai_position_scheme == 1) { - Ogre::Vector3 dir = App::GetGuiManager()->SurveyMap.ai_waypoints[int(wp)] - App::GetGuiManager()->SurveyMap.ai_waypoints[int(wp)-1]; + Ogre::Vector3 dir = App::GetGuiManager()->TopMenubar.ai_waypoints[int(wp)].position - App::GetGuiManager()->TopMenubar.ai_waypoints[int(wp)-1].position; float angle = Ogre::Vector3::UNIT_Z.angleBetween(dir.normalisedCopy()).valueRadians(); if (dir.x > 0) // Direction on the right fails to produce offset in some angles, invert to have the same offset on both sides @@ -142,7 +141,7 @@ void VehicleAI::setValueAtWaypoint(std::string const& id, int value_id, float va switch (value_id) { case AI_SPEED: - waypoint_speed.emplace(waypointid, value); + waypoint_speed.emplace(id, value); break; case AI_POWER: waypoint_power.emplace(waypointid, value); @@ -176,7 +175,7 @@ void VehicleAI::updateWaypoint() } } - float speed = waypoint_speed[current_waypoint_id]; + float speed = waypoint_speed[waypoint_names[current_waypoint_id]]; if (speed) maxspeed = speed; @@ -398,25 +397,28 @@ void VehicleAI::update(float dt, int doUpdate) Ogre::Vector3 pos = beam->getPosition(); pos.y = 0; - // Turn ahead, reduce speed relative to the angle and the current speed - if (angle_deg > 0 && current_waypoint.distance(pos) < kmh_wheel_speed) + if (waypoint_speed[waypoint_names[current_waypoint_id-1]] == -1) { - // Speed limit: 10 - 180 degree angle -> 50 - 5 km/h - float t = ((angle_deg - 10) / (180 - 10))*1.4f; // Reduce a bit to achive ~20 km/h for a 90 degree angle - maxspeed = (1 - t)*50 + t*5; - if (maxspeed > 50) // Limit to 50 km/h + // Turn ahead, reduce speed relative to the angle and the current speed + if (angle_deg > 0 && current_waypoint.distance(pos) < kmh_wheel_speed) { - maxspeed = 50; + // Speed limit: 10 - 180 degree angle -> 50 - 5 km/h + float t = ((angle_deg - 10) / (180 - 10))*1.4f; // Reduce a bit to achive ~20 km/h for a 90 degree angle + maxspeed = (1 - t)*50 + t*5; + if (maxspeed > 50) // Limit to 50 km/h + { + maxspeed = 50; + } + if (maxspeed > App::GetGuiManager()->TopMenubar.ai_speed) // Respect user defined lower speed + { + maxspeed = App::GetGuiManager()->TopMenubar.ai_speed; + } } - if (maxspeed > App::GetGuiManager()->TopMenubar.ai_speed) // Respect user defined lower speed + else // Reset { maxspeed = App::GetGuiManager()->TopMenubar.ai_speed; } } - else // Reset - { - maxspeed = App::GetGuiManager()->TopMenubar.ai_speed; - } // Collision avoidance with other actors for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors()) @@ -478,6 +480,15 @@ void VehicleAI::update(float dt, int doUpdate) } } } + else if (App::GetGuiManager()->TopMenubar.ai_mode == 1 || // Race driving mode + App::GetGuiManager()->TopMenubar.ai_mode == 2 || // Drag race mode + App::GetGuiManager()->TopMenubar.ai_mode == 3) // Crash driving mode + { + if (waypoint_speed[waypoint_names[current_waypoint_id-1]] == -1) + { + maxspeed = App::GetGuiManager()->TopMenubar.ai_speed; + } + } else if (App::GetGuiManager()->TopMenubar.ai_mode == 4) // Chase driving mode { if (App::GetGameContext()->GetPlayerActor()) @@ -586,6 +597,7 @@ void VehicleAI::update(float dt, int doUpdate) { Vector3 hdir = beam->GetCameraDir(); float knots = hdir.dotProduct(beam->ar_nodes[beam->ar_main_camera_node_pos].Velocity) * 1.9438f; // 1.943 = m/s in knots/s + maxspeed = App::GetGuiManager()->TopMenubar.ai_speed; if (abs(mYaw) < 0.5f) { diff --git a/source/main/gameplay/VehicleAI.h b/source/main/gameplay/VehicleAI.h index 16a9a0ba99..f67a9d07d7 100644 --- a/source/main/gameplay/VehicleAI.h +++ b/source/main/gameplay/VehicleAI.h @@ -148,7 +148,7 @@ class VehicleAI : public RefCountingObject std::map waypoint_ids;//!< Map with all waypoint IDs. std::map waypoint_names;//!< Map with all waypoint names. std::map waypoint_events;//!< Map with all waypoint events. - std::map waypoint_speed;//!< Map with all waypoint speeds. + std::map waypoint_speed;//!< Map with all waypoint speeds. std::map waypoint_power;//!< Map with all waypoint engine power. std::map waypoint_wait_time;//!< Map with all waypoint wait times. int free_waypoints = 0;//!< The amount of waypoints. diff --git a/source/main/gui/panels/GUI_SurveyMap.cpp b/source/main/gui/panels/GUI_SurveyMap.cpp index bccfc40b7a..9af3b23aa2 100644 --- a/source/main/gui/panels/GUI_SurveyMap.cpp +++ b/source/main/gui/panels/GUI_SurveyMap.cpp @@ -164,9 +164,9 @@ void SurveyMap::Draw() } bool w_adj = false; - if (!ai_waypoints.empty()) + if (!App::GetGuiManager()->TopMenubar.ai_waypoints.empty()) { - for (int i = 0; i < ai_waypoints.size(); i++) + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) { ImVec2 cw_dist = this->CalcWaypointMapPos(tl_screen_pos, view_size, view_origin, i); if (abs(cw_dist.x) <= 5 && abs(cw_dist.y) <= 5) @@ -195,7 +195,9 @@ void SurveyMap::Draw() if (ImGui::IsItemClicked(1)) // Set AI waypoint { float y = App::GetGameContext()->GetTerrain()->GetCollisions()->getSurfaceHeight(mouse_map_pos.x, mouse_map_pos.y); - ai_waypoints.push_back(Ogre::Vector3(mouse_map_pos.x, y, mouse_map_pos.y)); + ai_events waypoint; + waypoint.position = Ogre::Vector3(mouse_map_pos.x, y, mouse_map_pos.y); + App::GetGuiManager()->TopMenubar.ai_waypoints.push_back(waypoint); } else if (!w_adj) // Teleport { @@ -205,7 +207,7 @@ void SurveyMap::Draw() } else if (ImGui::IsItemClicked(2) && !w_adj) // 2 = middle click, clear AI waypoints { - ai_waypoints.clear(); + App::GetGuiManager()->TopMenubar.ai_waypoints.clear(); } else if (ImGui::IsItemHovered()) { @@ -222,9 +224,9 @@ void SurveyMap::Draw() } // Draw AI waypoints - if (!ai_waypoints.empty()) + if (!App::GetGuiManager()->TopMenubar.ai_waypoints.empty()) { - for (int i = 0; i < ai_waypoints.size(); i++) + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) { ImVec2 cw_dist = this->DrawWaypoint(tl_screen_pos, view_size, view_origin, std::to_string(i), i); @@ -255,11 +257,11 @@ void SurveyMap::Draw() } float y = App::GetGameContext()->GetTerrain()->GetCollisions()->getSurfaceHeight(mouse_map_pos.x, mouse_map_pos.y); - ai_waypoints[mWaypointNum] = Ogre::Vector3(mouse_map_pos.x, y, mouse_map_pos.y); + App::GetGuiManager()->TopMenubar.ai_waypoints[mWaypointNum].position = Ogre::Vector3(mouse_map_pos.x, y, mouse_map_pos.y); } else if (abs(cw_dist.x) <= 5 && abs(cw_dist.y) <= 5 && ImGui::IsItemClicked(2)) { - ai_waypoints.erase(ai_waypoints.begin() + i); + App::GetGuiManager()->TopMenubar.ai_waypoints.erase(App::GetGuiManager()->TopMenubar.ai_waypoints.begin() + i); } } } @@ -532,8 +534,8 @@ ImVec2 SurveyMap::DrawWaypoint(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 } ImVec2 pos1; - pos1.x = view_pos.x + ((ai_waypoints[idx].x - view_origin.x) / terrn_size_adj.x) * view_size.x; - pos1.y = view_pos.y + ((ai_waypoints[idx].z - view_origin.y) / terrn_size_adj.y) * view_size.y; + pos1.x = view_pos.x + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx].position.x - view_origin.x) / terrn_size_adj.x) * view_size.x; + pos1.y = view_pos.y + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx].position.z - view_origin.y) / terrn_size_adj.y) * view_size.y; ImDrawList* drawlist = ImGui::GetWindowDrawList(); ImVec4 col = ImVec4(1,0,0,1); @@ -546,11 +548,11 @@ ImVec2 SurveyMap::DrawWaypoint(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 ImVec2 text_pos(pos1.x - (ImGui::CalcTextSize(caption.c_str()).x/2), pos1.y + 5); drawlist->AddText(text_pos, ImGui::GetColorU32(ImGui::GetStyle().Colors[ImGuiCol_Text]), caption.c_str()); - if (ai_waypoints.size() >= 2 && idx != ai_waypoints.size() - 1) + if (App::GetGuiManager()->TopMenubar.ai_waypoints.size() >= 2 && idx != App::GetGuiManager()->TopMenubar.ai_waypoints.size() - 1) { ImVec2 pos2; - pos2.x = view_pos.x + ((ai_waypoints[idx+1].x - view_origin.x) / terrn_size_adj.x) * view_size.x; - pos2.y = view_pos.y + ((ai_waypoints[idx+1].z - view_origin.y) / terrn_size_adj.y) * view_size.y; + pos2.x = view_pos.x + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx+1].position.x - view_origin.x) / terrn_size_adj.x) * view_size.x; + pos2.y = view_pos.y + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx+1].position.z - view_origin.y) / terrn_size_adj.y) * view_size.y; drawlist->AddLine(pos1, pos2, ImGui::GetColorU32(ImVec4(1,0,0,1))); } @@ -566,8 +568,8 @@ ImVec2 SurveyMap::CalcWaypointMapPos(ImVec2 view_pos, ImVec2 view_size, Ogre::Ve } ImVec2 pos; - pos.x = view_pos.x + ((ai_waypoints[idx].x - view_origin.x) / terrn_size_adj.x) * view_size.x; - pos.y = view_pos.y + ((ai_waypoints[idx].z - view_origin.y) / terrn_size_adj.y) * view_size.y; + pos.x = view_pos.x + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx].position.x - view_origin.x) / terrn_size_adj.x) * view_size.x; + pos.y = view_pos.y + ((App::GetGuiManager()->TopMenubar.ai_waypoints[idx].position.z - view_origin.y) / terrn_size_adj.y) * view_size.y; return ImGui::GetMousePos() - pos; } diff --git a/source/main/gui/panels/GUI_SurveyMap.h b/source/main/gui/panels/GUI_SurveyMap.h index 232a1632a4..d6b24a2e3f 100644 --- a/source/main/gui/panels/GUI_SurveyMap.h +++ b/source/main/gui/panels/GUI_SurveyMap.h @@ -59,8 +59,6 @@ class SurveyMap const char* getTypeByDriveable(int driveable); - std::vector ai_waypoints; - protected: enum class SurveyMapMode diff --git a/source/main/gui/panels/GUI_TopMenubar.cpp b/source/main/gui/panels/GUI_TopMenubar.cpp index 47d5bca508..f64fa644cf 100644 --- a/source/main/gui/panels/GUI_TopMenubar.cpp +++ b/source/main/gui/panels/GUI_TopMenubar.cpp @@ -34,7 +34,6 @@ #include "GUIManager.h" #include "GUIUtils.h" #include "GUI_MainSelector.h" -#include "GUI_SurveyMap.h" #include "InputEngine.h" #include "Language.h" #include "Network.h" @@ -1139,7 +1138,7 @@ void TopMenubar::Update() ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f); } - if (!App::GetGuiManager()->SurveyMap.ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode + if (!ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode { ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]); } @@ -1148,20 +1147,24 @@ void TopMenubar::Update() { if (ai_mode == 4) // Chase driving mode { - App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); + ai_waypoints.clear(); if (App::GetGameContext()->GetPlayerActor()) // We are in vehicle { - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(App::GetGameContext()->GetPlayerActor()->getPosition() + Ogre::Vector3(20, 0, 0)); + ai_events waypoint; + waypoint.position = App::GetGameContext()->GetPlayerActor()->getPosition() + Ogre::Vector3(20, 0, 0); + ai_waypoints.push_back(waypoint); } else // We are in feet { - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(20, 0, 0)); + ai_events waypoint; + waypoint.position = App::GetGameContext()->GetPlayerCharacter()->getPosition() + Ogre::Vector3(20, 0, 0); + ai_waypoints.push_back(waypoint); } App::GetScriptEngine()->loadScript("AI.as", ScriptCategory::CUSTOM); } else { - if (App::GetGuiManager()->SurveyMap.ai_waypoints.empty()) + if (ai_waypoints.empty()) { App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, fmt::format(_LC("TopMenubar", "Select a preset, record or open survey map ({}) to set waypoints."), @@ -1174,7 +1177,7 @@ void TopMenubar::Update() } } - if (!App::GetGuiManager()->SurveyMap.ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode + if (!ai_waypoints.empty() || ai_mode == 4) // Waypoints provided or Chase driving mode { ImGui::PopStyleColor(); } @@ -1185,7 +1188,7 @@ void TopMenubar::Update() { if (ai_mode == 4) // Chase driving mode { - App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); + ai_waypoints.clear(); } for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetLocalActors()) @@ -1217,7 +1220,7 @@ void TopMenubar::Update() { if (!ai_rec) { - App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); + ai_waypoints.clear(); ai_rec = true; } else @@ -1262,14 +1265,28 @@ void TopMenubar::Update() count++; if (ImGui::Button(j_row["preset"].GetString(), ImVec2(250, 0))) { - App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); + ai_waypoints.clear(); for (size_t i = 0; i < j_row["waypoints"].Size(); i++) { float x = j_row["waypoints"][i][0].GetFloat(); float y = j_row["waypoints"][i][1].GetFloat(); float z = j_row["waypoints"][i][2].GetFloat(); - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(Ogre::Vector3(x, y, z)); + + ai_events waypoint; + waypoint.position = Ogre::Vector3(x, y, z); + + int speed = -1; + if (j_row["waypoints"][i].Size() == 4) // Custom speed defined + { + speed = j_row["waypoints"][i][3].GetInt(); + if (speed < 5) + { + speed = -1; + } + } + waypoint.speed = speed; + ai_waypoints.push_back(waypoint); } } } @@ -1300,7 +1317,7 @@ void TopMenubar::Update() if (ImGui::CollapsingHeader(_LC("TopMenubar", "Waypoints"))) { - if (App::GetGuiManager()->SurveyMap.ai_waypoints.empty()) + if (ai_waypoints.empty()) { ImGui::Text("%s", _LC("TopMenubar", "No waypoints defined.")); } @@ -1310,10 +1327,20 @@ void TopMenubar::Update() { std::string s; - for (int i = 0; i < App::GetGuiManager()->SurveyMap.ai_waypoints.size(); i++) + for (int i = 0; i < ai_waypoints.size(); i++) { - s += "\n [" + std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].x) + ", " + std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].y) + ", " + std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].z) + "]"; - if (i != App::GetGuiManager()->SurveyMap.ai_waypoints.size() - 1) + // Write position + 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); + + // Write custom speed + if (ai_waypoints[i].speed >= 5) + { + s += ", " + std::to_string(ai_waypoints[i].speed); + } + + // Close + s += "]"; + if (i != ai_waypoints.size() - 1) { s += ","; } @@ -1324,23 +1351,46 @@ void TopMenubar::Update() App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, fmt::format(_LC("TopMenubar", "{} waypoints exported to RoR.log"), - App::GetGuiManager()->SurveyMap.ai_waypoints.size()), "lightbulb.png"); + ai_waypoints.size()), "lightbulb.png"); } ImGui::BeginChild("waypoints-scrolling", ImVec2(0.f, 200), false); - for (int i = 0; i < App::GetGuiManager()->SurveyMap.ai_waypoints.size(); i++) + for (int i = 0; i < ai_waypoints.size(); i++) { ImGui::PushID(i); ImGui::AlignTextToFramePadding(); ImGui::Text("%d", i); ImGui::SameLine(); - std::string w = std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].x) + " " + std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].y) + " " + std::to_string(App::GetGuiManager()->SurveyMap.ai_waypoints[i].z); - if (ImGui::Button(w.c_str(), ImVec2(230, 0))) + if (ImGui::Button("teleport", ImVec2(60, 0))) { - Ogre::Vector3* payload = new Ogre::Vector3(App::GetGuiManager()->SurveyMap.ai_waypoints[i]); + Ogre::Vector3* payload = new Ogre::Vector3(ai_waypoints[i].position); App::GetGameContext()->PushMessage(Message(MSG_SIM_TELEPORT_PLAYER_REQUESTED, (void*)payload)); } + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + 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); + ImGui::Text(w.c_str()); + ImGui::EndTooltip(); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(90); + + if (ai_waypoints[i].speed < -1) + { + ai_waypoints[i].speed = -1; + } + ImGui::InputInt(_LC("TopMenubar", "speed"), &ai_waypoints[i].speed, 1, 100); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text(_LC("TopMenubar", "Set waypoint speed in km/h for land vehicles")); + ImGui::Separator(); + ImGui::Text(_LC("TopMenubar", "Value -1: Ignore, vehicle will use default speed")); + ImGui::Text(_LC("TopMenubar", "Value >= 5: Override default speed")); + ImGui::EndTooltip(); + } ImGui::PopID(); } diff --git a/source/main/gui/panels/GUI_TopMenubar.h b/source/main/gui/panels/GUI_TopMenubar.h index a9ac10c577..3e5d5184da 100644 --- a/source/main/gui/panels/GUI_TopMenubar.h +++ b/source/main/gui/panels/GUI_TopMenubar.h @@ -32,6 +32,12 @@ #include #include +struct ai_events +{ + Ogre::Vector3 position; + int speed = -1; +}; + namespace RoR { namespace GUI { @@ -57,6 +63,7 @@ class TopMenubar bool IsVisible() { return m_open_menu != TopMenu::TOPMENU_NONE; }; // Vehicle AI + std::vector ai_waypoints; int ai_num = 1; int ai_speed = 50; int ai_times = 1; diff --git a/source/main/main.cpp b/source/main/main.cpp index 596929048d..51fa5e156e 100644 --- a/source/main/main.cpp +++ b/source/main/main.cpp @@ -42,7 +42,6 @@ #include "GUI_MultiplayerClientList.h" #include "GUI_RepositorySelector.h" #include "GUI_SimActorStats.h" -#include "GUI_SurveyMap.h" #include "GUIManager.h" #include "GUIUtils.h" #include "InputEngine.h" @@ -637,7 +636,7 @@ int main(int argc, char *argv[]) App::GetGuiManager()->MainSelector.Close(); App::GetGuiManager()->LoadingWindow.SetVisible(false); App::GetGuiManager()->MenuWallpaper->show(); - App::GetGuiManager()->SurveyMap.ai_waypoints.clear(); + App::GetGuiManager()->TopMenubar.ai_waypoints.clear(); App::sim_state->setVal((int)SimState::OFF); App::app_state->setVal((int)AppState::MAIN_MENU); App::GetGameContext()->UnloadTerrain(); diff --git a/source/main/scripting/GameScript.cpp b/source/main/scripting/GameScript.cpp index bd82971f0e..9de963bea5 100644 --- a/source/main/scripting/GameScript.cpp +++ b/source/main/scripting/GameScript.cpp @@ -46,7 +46,6 @@ #include "GameContext.h" #include "GfxScene.h" #include "GUIManager.h" -#include "GUI_SurveyMap.h" #include "GUI_TopMenubar.h" #include "Language.h" #include "Network.h" @@ -953,7 +952,11 @@ ActorPtr GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, O rq.asr_position = pos; // Set rotation based on first two waypoints - std::vector waypoints = App::GetGuiManager()->SurveyMap.ai_waypoints; + std::vector waypoints; + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) + { + waypoints.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position); + } if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode { std::reverse(waypoints.begin(), waypoints.end()); @@ -983,7 +986,11 @@ ActorPtr GameScript::spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, O AngelScript::CScriptArray* GameScript::getWaypoints(int x) { - std::vector vec = App::GetGuiManager()->SurveyMap.ai_waypoints; + std::vector vec; + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) + { + vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position); + } if (App::GetGuiManager()->TopMenubar.ai_mode == 3 && x == 1) // Crash driving mode { std::reverse(vec.begin(), vec.end()); @@ -1016,7 +1023,30 @@ AngelScript::CScriptArray* GameScript::getAllTrucks() void GameScript::addWaypoint(const Ogre::Vector3& pos) { - App::GetGuiManager()->SurveyMap.ai_waypoints.push_back(pos); + std::vector waypoints; + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) + { + waypoints.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].position); + } +} + +AngelScript::CScriptArray* GameScript::getWaypointsSpeed() +{ + std::vector vec; + for (int i = 0; i < App::GetGuiManager()->TopMenubar.ai_waypoints.size(); i++) + { + vec.push_back(App::GetGuiManager()->TopMenubar.ai_waypoints[i].speed); + } + + AngelScript::CScriptArray* arr = AngelScript::CScriptArray::Create(AngelScript::asGetActiveContext()->GetEngine()->GetTypeInfoByDecl("array"), vec.size()); + + for(AngelScript::asUINT i = 0; i < arr->GetSize(); i++) + { + // Set the value of each element + arr->SetValue(i, &vec[i]); + } + + return arr; } int GameScript::getAIVehicleCount() diff --git a/source/main/scripting/GameScript.h b/source/main/scripting/GameScript.h index 8d692508d9..8e774471df 100644 --- a/source/main/scripting/GameScript.h +++ b/source/main/scripting/GameScript.h @@ -391,6 +391,7 @@ class GameScript ActorPtr spawnTruckAI(Ogre::String& truckName, Ogre::Vector3& pos, Ogre::String& truckSectionConfig, std::string& truckSkin, int x); AngelScript::CScriptArray* getWaypoints(int x); + AngelScript::CScriptArray* getWaypointsSpeed(); void addWaypoint(const Ogre::Vector3& pos); int getAIVehicleCount(); int getAIVehicleDistance(); diff --git a/source/main/scripting/bindings/GameScriptAngelscript.cpp b/source/main/scripting/bindings/GameScriptAngelscript.cpp index 8bc586b634..61082cf356 100644 --- a/source/main/scripting/bindings/GameScriptAngelscript.cpp +++ b/source/main/scripting/bindings/GameScriptAngelscript.cpp @@ -123,6 +123,7 @@ void RoR::RegisterGameScript(asIScriptEngine *engine) // > Waypoint AI for actors result = engine->RegisterObjectMethod("GameScriptClass", "BeamClassPtr @spawnTruckAI(string &in, vector3 &in, string &in, string &in, int x)", AngelScript::asMETHOD(GameScript, spawnTruckAI), AngelScript::asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("GameScriptClass", "array @getWaypoints(int x)", AngelScript::asMETHOD(GameScript, getWaypoints), AngelScript::asCALL_THISCALL); ROR_ASSERT(result >= 0); + result = engine->RegisterObjectMethod("GameScriptClass", "array @getWaypointsSpeed()", AngelScript::asMETHOD(GameScript, getWaypointsSpeed), AngelScript::asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("GameScriptClass", "void addWaypoint(vector3 &in)", asMETHOD(GameScript, addWaypoint), asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("GameScriptClass", "int getAIVehicleCount()", AngelScript::asMETHOD(GameScript, getAIVehicleCount), AngelScript::asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("GameScriptClass", "int getAIVehicleDistance()", AngelScript::asMETHOD(GameScript, getAIVehicleDistance), AngelScript::asCALL_THISCALL); ROR_ASSERT(result >= 0);