Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AI: Per waypoint speed #3085

Merged
merged 1 commit into from
Sep 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion resources/scripts/AI.as
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "base.as"

array<int> waypoints_speed = game.getWaypointsSpeed();

void main()
{
int offset = 0;
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 11 additions & 3 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -1112,15 +1111,24 @@ 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();
}
else // We are in feet
{
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();
}
Expand Down
46 changes: 29 additions & 17 deletions source/main/gameplay/VehicleAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include "ScrewProp.h"
#include "GUIManager.h"
#include "GUI_TopMenubar.h"
#include "GUI_SurveyMap.h"

#include "scriptdictionary/scriptdictionary.h"

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion source/main/gameplay/VehicleAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class VehicleAI : public RefCountingObject<VehicleAI>
std::map<std::string, int> waypoint_ids;//!< Map with all waypoint IDs.
std::map<int, std::string> waypoint_names;//!< Map with all waypoint names.
std::map<int, int> waypoint_events;//!< Map with all waypoint events.
std::map<int, float> waypoint_speed;//!< Map with all waypoint speeds.
std::map<Ogre::String, float> waypoint_speed;//!< Map with all waypoint speeds.
std::map<int, float> waypoint_power;//!< Map with all waypoint engine power.
std::map<int, float> waypoint_wait_time;//!< Map with all waypoint wait times.
int free_waypoints = 0;//!< The amount of waypoints.
Expand Down
32 changes: 17 additions & 15 deletions source/main/gui/panels/GUI_SurveyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
{
Expand All @@ -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())
{
Expand All @@ -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);

Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
Expand All @@ -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)));
}

Expand All @@ -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;
}
Expand Down
2 changes: 0 additions & 2 deletions source/main/gui/panels/GUI_SurveyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class SurveyMap

const char* getTypeByDriveable(int driveable);

std::vector<Ogre::Vector3> ai_waypoints;

protected:

enum class SurveyMapMode
Expand Down
Loading