void MQ2NavigationPlugin::StuckCheck() { if (m_isPaused) return; if (!mq2nav::GetSettings().attempt_unstuck) return; clock::time_point now = clock::now(); // check every 100 ms if (now > m_stuckTimer + std::chrono::milliseconds(100)) { m_stuckTimer = now; if (GetCharInfo()) { if (GetCharInfo()->pSpawn->SpeedMultiplier != -10000 && FindSpeed(GetCharInfo()->pSpawn) && (GetDistance(m_stuckX, m_stuckY) < FindSpeed(GetCharInfo()->pSpawn) / 600) && !ClickNearestClosedDoor(25) && !GetCharInfo()->pSpawn->Levitate && !GetCharInfo()->pSpawn->UnderWater && !GetCharInfo()->Stunned && m_isActive) { int jumpCmd = FindMappableCommand("JUMP"); MQ2Globals::ExecuteCmd(jumpCmd, 1, 0); MQ2Globals::ExecuteCmd(jumpCmd, 0, 0); } m_stuckX = GetCharInfo()->pSpawn->X; m_stuckY = GetCharInfo()->pSpawn->Y; } } }
//EQLIB_API VOID DoMappable(PSPAWNINFO pChar, PCHAR szLine) int CMD_Keypress(int argc, char *argv[]) { if (argc<2) { WriteChatf("Syntax: %s <eqcommand|keycombo> [hold|chat]",argv[0]); return 0; } bool bHold=false; bool bChat=false; if (argc==3) { if (!stricmp(argv[2],"hold")) { bHold=true; } else if (!stricmp(argv[2],"chat")) { bChat=true; } } if (!PressMQ2KeyBind(argv[1],bHold)) { int N=FindMappableCommand(argv[1]); if (N>=0) { ExecuteCmd(N,1,0); if (!bHold) ExecuteCmd(N,0,0); return 0; } KeyCombo Temp; if (ParseKeyCombo(argv[1],Temp)) { if (bChat) { pWndMgr->HandleKeyboardMsg(Temp.Data[3],1); pWndMgr->HandleKeyboardMsg(Temp.Data[3],0); } else { MQ2HandleKeyDown(Temp); if (!bHold) MQ2HandleKeyUp(Temp); } return 0; } WriteChatf("Invalid mappable command or key combo '%s'",argv[1]); return -1; } return 0; }
void MQ2NavigationPlugin::Stop() { if (m_isActive) { WriteChatf(PLUGIN_MSG "Stopping navigation"); MQ2Globals::ExecuteCmd(FindMappableCommand("FORWARD"), 0, 0); } m_activePath.reset(); m_isActive = false; m_pEndingDoor = nullptr; m_pEndingItem = nullptr; }
void MQ2NavigationPlugin::OnUpdateTab(TabPage tabId) { if (tabId == TabPage::Navigation) { ImGui::TextColored(ImColor(255, 255, 0), "Type /nav ui to toggle this window"); if (ImGui::Checkbox("Pause navigation", &m_isPaused)) { if (m_isPaused) MQ2Globals::ExecuteCmd(FindMappableCommand("FORWARD"), 0, 0); } if (ImGui::CollapsingHeader("Pathing Debug")) { bool settingsChanged = false; auto& settings = mq2nav::GetSettings(); if (ImGui::Checkbox("Render pathing debug draw", &settings.debug_render_pathing)) settingsChanged = true; if (ImGui::Checkbox("Use Pathing Corridor (experimental)", &settings.debug_use_pathing_corridor)) settingsChanged = true; if (settingsChanged) mq2nav::SaveSettings(); if (m_activePath) { auto charInfo = GetCharInfo(); glm::vec3 myPos(charInfo->pSpawn->X, charInfo->pSpawn->Z, charInfo->pSpawn->Y); auto dest = m_activePath->GetDestination(); ImGui::LabelText("Position", "(%.2f, %.2f, %.2f)", myPos.x, myPos.y, myPos.z); ImGui::LabelText("Current Waypoint", "(%.2f, %.2f, %.2f,", m_currentWaypoint.x, m_currentWaypoint.y, m_currentWaypoint.z); ImGui::LabelText("Distance to Waypoint", "%.2f", glm::distance(m_currentWaypoint, myPos)); ImGui::LabelText("Destination", "(%.2f, %.2f, %.2f)", dest.x, dest.y, dest.z); ImGui::LabelText("Distance", "%.2f", glm::distance(dest, myPos)); ImGui::Text("Path Nodes"); ImGui::Separator(); ImGui::BeginChild("PathNodes"); for (int i = 0; i < m_activePath->GetPathSize(); ++i) { ImColor color(255, 255, 255); if (i == 0) color = ImColor(255, 255, 0); if (i == m_activePath->GetPathIndex()) color = ImColor(0, 255, 0); if (i == m_activePath->GetPathSize() - 1) color = ImColor(255, 0, 0); auto pos = m_activePath->GetRawPosition(i); ImGui::TextColored(color, "%04d: (%.2f, %.2f, %.2f)", i, pos[0], pos[1], pos[2]); } ImGui::EndChild(); } else { ImGui::LabelText("Destination", "<none>"); ImGui::LabelText("Distance", ""); } ImGui::Separator(); ImGui::LabelText("Ending Door", "%s", m_pEndingDoor ? m_pEndingDoor->Name : "<none>"); ImGui::LabelText("Ending Item", "%s", m_pEndingItem ? m_pEndingItem->Name : "<none>"); ImGui::LabelText("Is Active", "%s", m_isActive ? "true" : "false"); ImGui::LabelText("Spam Click", "%s", m_bSpamClick ? "true" : "false"); ImGui::LabelText("Current Waypoint", "(%.2f, %.2f, %.2f)", m_currentWaypoint.x, m_currentWaypoint.y, m_currentWaypoint.z); ImGui::LabelText("Stuck Data", "(%.2f, %.2f) %d", m_stuckX, m_stuckY, m_stuckTimer.time_since_epoch()); ImGui::LabelText("Last Click", "%d", m_lastClick.time_since_epoch() / 1000000); ImGui::LabelText("Pathfind Timer", "%d", m_pathfindTimer.time_since_epoch() / 1000000); } ImGui::Separator(); auto navmeshRenderer = Get<NavMeshRenderer>(); navmeshRenderer->OnUpdateUI(); if (m_activePath) m_activePath->OnUpdateUI(); } }
void MQ2NavigationPlugin::AttemptMovement() { if (m_isActive) { clock::time_point now = clock::now(); if (now - m_pathfindTimer > std::chrono::milliseconds(PATHFINDING_DELAY_MS)) { //WriteChatf(PLUGIN_MSG "Recomputing Path..."); // update path m_activePath->UpdatePath(); m_isActive = m_activePath->GetPathSize() > 0; m_pathfindTimer = now; } } // if no active path, then leave if (!m_isActive) return; //WriteChatf(PLUGIN_MSG "AttemptMovement - cursor = %d, size = %d, isActive = %d", // m_activePath->GetPathIndex() , m_activePath->GetPathSize(), m_isActive ? 1 : 0); const glm::vec3& dest = m_activePath->GetDestination(); float distanceToTarget = GetDistance(dest.x, dest.z); //PSPAWNINFO me = GetCharInfo()->pSpawn; //WriteChatf(PLUGIN_MSG "Distance from target: %.2f. I am at: %.2f %.2f %.2f", distanceToTarget, // me->X, me->Y, me->Z); if (m_activePath->IsAtEnd()) { DebugSpewAlways("[MQ2Nav] Reached destination at: %.2f %.2f %.2f", dest.x, dest.z, dest.y); WriteChatf(PLUGIN_MSG "\agReached destination at: %.2f %.2f %.2f", dest.x, dest.y, dest.z); if (PSPAWNINFO me = GetCharInfo()->pSpawn) { if (distanceToTarget < ENDPOINT_STOP_DISTANCE && !m_bSpamClick) { LookAt(dest); } } Stop(); } else if (m_activePath->GetPathSize() > 0) { if (!m_isPaused) { if (!GetCharInfo()->pSpawn->SpeedRun) MQ2Globals::ExecuteCmd(FindMappableCommand("FORWARD"), 1, 0); } glm::vec3 nextPosition = m_activePath->GetNextPosition(); float distanceFromNextPosition = GetDistance(nextPosition.x, nextPosition.z); if (distanceFromNextPosition < WAYPOINT_PROGRESSION_DISTANCE) { m_activePath->Increment(); if (!m_activePath->IsAtEnd()) { m_activePath->UpdatePath(); nextPosition = m_activePath->GetNextPosition(); } } if (m_currentWaypoint != nextPosition) { m_currentWaypoint = nextPosition; DebugSpewAlways("[MQ2Nav] Moving Towards: %.2f %.2f %.2f", nextPosition.x, nextPosition.z, nextPosition.y); } glm::vec3 eqPoint(nextPosition.x, nextPosition.z, nextPosition.y); LookAt(eqPoint); } }