summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Stinson <stinson@lindenlab.com>2012-03-08 12:34:11 -0800
committerTodd Stinson <stinson@lindenlab.com>2012-03-08 12:34:11 -0800
commitf578181af9cbe3277374578c27487e2e72956079 (patch)
treeab7c041c277d708f805dc3bf9e80418616c19277
parentdcf7ed021b11b2ec990625389aa185081eeab915 (diff)
PATH-304: Adding functionality to handle the reloading of out-of-date navmeshes.
-rw-r--r--etc/message.xml12
-rw-r--r--indra/newview/llfloaterpathfindingconsole.cpp20
-rw-r--r--indra/newview/llfloaterpathfindingconsole.h4
-rw-r--r--indra/newview/llpathfindingmanager.cpp60
-rw-r--r--indra/newview/llpathfindingmanager.h2
-rw-r--r--indra/newview/llpathfindingnavmesh.cpp11
-rw-r--r--indra/newview/llpathfindingnavmesh.h2
-rw-r--r--indra/newview/llpathfindingnavmeshzone.cpp58
-rw-r--r--indra/newview/llpathfindingnavmeshzone.h7
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_console.xml2
10 files changed, 153 insertions, 25 deletions
diff --git a/etc/message.xml b/etc/message.xml
index 3445975545..9407888a92 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -546,8 +546,16 @@
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
-
- <!-- UDPDeprecated Messages -->
+
+ <key>NavmeshStatusUpdate</key>
+ <map>
+ <key>flavor</key>
+ <string>llsd</string>
+ <key>trusted-sender</key>
+ <boolean>true</boolean>
+ </map>
+
+ <!-- UDPDeprecated Messages -->
<key>ScriptRunningReply</key>
<map>
<key>flavor</key>
diff --git a/indra/newview/llfloaterpathfindingconsole.cpp b/indra/newview/llfloaterpathfindingconsole.cpp
index 6824e629c9..493b4617b5 100644
--- a/indra/newview/llfloaterpathfindingconsole.cpp
+++ b/indra/newview/llfloaterpathfindingconsole.cpp
@@ -171,6 +171,7 @@ void LLFloaterPathfindingConsole::onOpen(const LLSD& pKey)
mNavMeshZoneSlot = mNavMeshZone.registerNavMeshZoneListener(boost::bind(&LLFloaterPathfindingConsole::onNavMeshZoneCB, this, _1));
}
+ mIsNavMeshUpdating = false;
mNavMeshZone.initialize();
mNavMeshZone.enable();
@@ -478,6 +479,7 @@ LLFloaterPathfindingConsole::LLFloaterPathfindingConsole(const LLSD& pSeed)
mClearPathButton(NULL),
mNavMeshZoneSlot(),
mNavMeshZone(),
+ mIsNavMeshUpdating(false),
mAgentStateSlot(),
mConsoleState(kConsoleStateUnknown),
mPathData(),
@@ -616,10 +618,15 @@ void LLFloaterPathfindingConsole::onNavMeshZoneCB(LLPathfindingNavMeshZone::ENav
case LLPathfindingNavMeshZone::kNavMeshZoneRequestUnknown :
setConsoleState(kConsoleStateUnknown);
break;
+ case LLPathfindingNavMeshZone::kNavMeshZoneRequestNeedsUpdate :
+ mIsNavMeshUpdating = true;
+ mNavMeshZone.refresh();
+ break;
case LLPathfindingNavMeshZone::kNavMeshZoneRequestStarted :
setConsoleState(kConsoleStateDownloading);
break;
case LLPathfindingNavMeshZone::kNavMeshZoneRequestCompleted :
+ mIsNavMeshUpdating = false;
setConsoleState(kConsoleStateHasNavMesh);
break;
case LLPathfindingNavMeshZone::kNavMeshZoneRequestNotEnabled :
@@ -689,7 +696,6 @@ void LLFloaterPathfindingConsole::updateControlsOnConsoleState()
mHasEndPoint = false;
break;
case kConsoleStateHasNavMesh :
- case kConsoleStateHasNavMeshDownloading :
mShowNavMeshCheckBox->setEnabled(TRUE);
mShowNavMeshWalkabilityComboBox->setEnabled(TRUE);
mShowWalkablesCheckBox->setEnabled(TRUE);
@@ -731,14 +737,18 @@ void LLFloaterPathfindingConsole::updateStatusOnConsoleState()
styleParams.color = warningColor;
break;
case kConsoleStateDownloading :
- statusText = getString("navmesh_status_downloading");
+ if (mIsNavMeshUpdating)
+ {
+ statusText = getString("navmesh_status_updating");
+ }
+ else
+ {
+ statusText = getString("navmesh_status_downloading");
+ }
break;
case kConsoleStateHasNavMesh :
statusText = getString("navmesh_status_has_navmesh");
break;
- case kConsoleStateHasNavMeshDownloading :
- statusText = getString("navmesh_status_has_navmesh_downloading");
- break;
case kConsoleStateError :
statusText = getString("navmesh_status_error");
styleParams.color = warningColor;
diff --git a/indra/newview/llfloaterpathfindingconsole.h b/indra/newview/llfloaterpathfindingconsole.h
index b1886fb716..8c29bf5909 100644
--- a/indra/newview/llfloaterpathfindingconsole.h
+++ b/indra/newview/llfloaterpathfindingconsole.h
@@ -122,7 +122,6 @@ private:
kConsoleStateRegionNotEnabled,
kConsoleStateDownloading,
kConsoleStateHasNavMesh,
- kConsoleStateHasNavMeshDownloading,
kConsoleStateError
} EConsoleState;
@@ -179,9 +178,10 @@ private:
LLTextBase *mPathTestingStatus;
LLButton *mClearPathButton;
-
LLPathfindingNavMeshZone::navmesh_zone_slot_t mNavMeshZoneSlot;
LLPathfindingNavMeshZone mNavMeshZone;
+ bool mIsNavMeshUpdating;
+
LLPathfindingManager::agent_state_slot_t mAgentStateSlot;
EConsoleState mConsoleState;
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index cba0501ad2..ebefebbb64 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -26,8 +26,10 @@
*/
#include <string>
+#include <vector>
#include "llviewerprecompiledheaders.h"
+#include "llsd.h"
#include "llpathfindingmanager.h"
#include "llsingleton.h"
#include "llhttpclient.h"
@@ -36,6 +38,7 @@
#include "llpathfindingnavmesh.h"
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
+#include "llhttpnode.h"
#include <boost/function.hpp>
#include <boost/signals2.hpp>
@@ -49,6 +52,20 @@
#define CAP_SERVICE_OBJECT_LINKSETS "ObjectNavMeshProperties"
#define CAP_SERVICE_TERRAIN_LINKSETS "TerrainNavMeshProperties"
+#define SIM_MESSAGE_NAVMESH_STATUS_UPDATE "/message/NavmeshStatusUpdate"
+
+//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+class LLNavMeshSimStateChangeNode : public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const;
+};
+
+LLHTTPRegistration<LLNavMeshSimStateChangeNode> gHTTPRegistrationNavMeshSimStateChangeNode(SIM_MESSAGE_NAVMESH_STATUS_UPDATE);
+
//---------------------------------------------------------------------------
// NavMeshResponder
//---------------------------------------------------------------------------
@@ -243,6 +260,12 @@ void LLPathfindingManager::requestGetNavMeshForRegion(LLViewerRegion *pRegion)
}
}
+void LLPathfindingManager::handleNavMeshUpdate(const LLUUID &pRegionUUID, U32 pNavMeshVersion)
+{
+ LLPathfindingNavMeshPtr navMeshPtr = getNavMeshForRegion(pRegionUUID);
+ navMeshPtr->handleNavMeshNewVersion(++mNavMeshVersionXXX);
+}
+
LLPathfindingManager::agent_state_slot_t LLPathfindingManager::registerAgentStateListener(agent_state_callback_t pAgentStateCallback)
{
return mAgentStateSignal.connect(pAgentStateCallback);
@@ -368,21 +391,14 @@ LLPathfindingManager::ELinksetsRequestStatus LLPathfindingManager::requestSetLin
return status;
}
-LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion)
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(const LLUUID &pRegionUUID)
{
-
- LLUUID regionUUID;
- if (pRegion != NULL)
- {
- regionUUID = pRegion->getRegionID();
- }
-
LLPathfindingNavMeshPtr navMeshPtr;
- NavMeshMap::iterator navMeshIter = mNavMeshMap.find(regionUUID);
+ NavMeshMap::iterator navMeshIter = mNavMeshMap.find(pRegionUUID);
if (navMeshIter == mNavMeshMap.end())
{
- navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(regionUUID));
- mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(regionUUID, navMeshPtr));
+ navMeshPtr = LLPathfindingNavMeshPtr(new LLPathfindingNavMesh(pRegionUUID));
+ mNavMeshMap.insert(std::pair<LLUUID, LLPathfindingNavMeshPtr>(pRegionUUID, navMeshPtr));
}
else
{
@@ -392,6 +408,17 @@ LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion
return navMeshPtr;
}
+LLPathfindingNavMeshPtr LLPathfindingManager::getNavMeshForRegion(LLViewerRegion *pRegion)
+{
+ LLUUID regionUUID;
+ if (pRegion != NULL)
+ {
+ regionUUID = pRegion->getRegionID();
+ }
+
+ return getNavMeshForRegion(regionUUID);
+}
+
bool LLPathfindingManager::isValidAgentState(EAgentState pAgentState)
{
return ((pAgentState == kAgentStateFrozen) || (pAgentState == kAgentStateUnfrozen));
@@ -514,6 +541,17 @@ LLViewerRegion *LLPathfindingManager::getCurrentRegion() const
}
//---------------------------------------------------------------------------
+// LLNavMeshSimStateChangeNode
+//---------------------------------------------------------------------------
+
+void LLNavMeshSimStateChangeNode::post(ResponsePtr pResponse, const LLSD &pContext, const LLSD &pInput) const
+{
+ LLViewerRegion *region = gAgent.getRegion();
+ U32 navMeshVersion = 0U;
+ LLPathfindingManager::getInstance()->handleNavMeshUpdate(region->getRegionID(), navMeshVersion);
+}
+
+//---------------------------------------------------------------------------
// NavMeshResponder
//---------------------------------------------------------------------------
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index eb8704e308..3e85cb1291 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -80,6 +80,7 @@ public:
LLPathfindingNavMesh::navmesh_slot_t registerNavMeshListenerForRegion(LLViewerRegion *pRegion, LLPathfindingNavMesh::navmesh_callback_t pNavMeshCallback);
void requestGetNavMeshForRegion(LLViewerRegion *pRegion);
+ void handleNavMeshUpdate(const LLUUID &pRegionUUID, U32 pNavMeshVersion);
agent_state_slot_t registerAgentStateListener(agent_state_callback_t pAgentStateCallback);
EAgentState getAgentState();
@@ -92,6 +93,7 @@ public:
protected:
private:
+ LLPathfindingNavMeshPtr getNavMeshForRegion(const LLUUID &pRegionUUID);
LLPathfindingNavMeshPtr getNavMeshForRegion(LLViewerRegion *pRegion);
static bool isValidAgentState(EAgentState pAgentState);
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
index 469972efa9..84343cf31e 100644
--- a/indra/newview/llpathfindingnavmesh.cpp
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -64,6 +64,13 @@ void LLPathfindingNavMesh::handleRefresh()
mNavMeshSignal(mNavMeshRequestStatus, mRegionUUID, mNavMeshVersion, mNavMeshData);
}
+void LLPathfindingNavMesh::handleNavMeshNewVersion(U32 pNavMeshVersion)
+{
+ mNavMeshData.clear();
+ mNavMeshVersion = pNavMeshVersion;
+ setRequestStatus(kNavMeshRequestNeedsUpdate);
+}
+
void LLPathfindingNavMesh::handleNavMeshStart(U32 pNavMeshVersion)
{
mNavMeshVersion = pNavMeshVersion;
@@ -72,7 +79,6 @@ void LLPathfindingNavMesh::handleNavMeshStart(U32 pNavMeshVersion)
void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion)
{
- llassert(mNavMeshVersion == pNavMeshVersion);
if (mNavMeshVersion == pNavMeshVersion)
{
if ( pContent.has("navmesh_data") )
@@ -118,10 +124,9 @@ void LLPathfindingNavMesh::handleNavMeshNotEnabled()
void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion)
{
llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
- llassert(mNavMeshVersion == pNavMeshVersion);
- mNavMeshData.clear();
if (mNavMeshVersion == pNavMeshVersion)
{
+ mNavMeshData.clear();
setRequestStatus(kNavMeshRequestError);
}
}
diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h
index 26ef21f90e..eb9ef9683d 100644
--- a/indra/newview/llpathfindingnavmesh.h
+++ b/indra/newview/llpathfindingnavmesh.h
@@ -47,6 +47,7 @@ class LLPathfindingNavMesh
public:
typedef enum {
kNavMeshRequestUnknown,
+ kNavMeshRequestNeedsUpdate,
kNavMeshRequestStarted,
kNavMeshRequestCompleted,
kNavMeshRequestNotEnabled,
@@ -65,6 +66,7 @@ public:
bool hasNavMeshVersion(U32 pNavMeshVersion) const;
void handleRefresh();
+ void handleNavMeshNewVersion(U32 pNavMeshVersion);
void handleNavMeshStart(U32 pNavMeshVersion);
void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
void handleNavMeshNotEnabled();
diff --git a/indra/newview/llpathfindingnavmeshzone.cpp b/indra/newview/llpathfindingnavmeshzone.cpp
index 983b88fe05..3767834655 100644
--- a/indra/newview/llpathfindingnavmeshzone.cpp
+++ b/indra/newview/llpathfindingnavmeshzone.cpp
@@ -67,6 +67,24 @@ void LLPathfindingNavMeshZone::initialize()
{
mNavMeshLocationPtrs.clear();
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ LLViewerRegion *currentRegion = gAgent.getRegion();
+ if (currentRegion != NULL)
+ {
+ llinfos << "STINSON DEBUG: currentRegion: '" << currentRegion->getName() << "' (" << currentRegion->getRegionID().asString() << ")" << llendl;
+ std::vector<S32> availableRegions;
+ currentRegion->getNeighboringRegionsStatus( availableRegions );
+ std::vector<LLViewerRegion*> neighborRegionsPtrs;
+ currentRegion->getNeighboringRegions( neighborRegionsPtrs );
+ for (std::vector<S32>::const_iterator statusIter = availableRegions.begin();
+ statusIter != availableRegions.end(); ++statusIter)
+ {
+ LLViewerRegion *region = neighborRegionsPtrs[statusIter - availableRegions.begin()];
+ llinfos << "STINSON DEBUG: region #" << *statusIter << ": '" << region->getName() << "' (" << region->getRegionID().asString() << ")" << llendl;
+ }
+ }
+
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
NavMeshLocationPtr centerNavMeshPtr(new NavMeshLocation(CENTER_REGION, boost::bind(&LLPathfindingNavMeshZone::handleNavMeshLocation, this)));
mNavMeshLocationPtrs.push_back(centerNavMeshPtr);
@@ -122,20 +140,30 @@ void LLPathfindingNavMeshZone::handleNavMeshLocation()
void LLPathfindingNavMeshZone::updateStatus()
{
bool hasRequestUnknown = false;
+ bool hasRequestNeedsUpdate = false;
bool hasRequestStarted = false;
bool hasRequestCompleted = false;
bool hasRequestNotEnabled = false;
bool hasRequestError = false;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update BEGIN" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
for (NavMeshLocationPtrs::iterator navMeshLocationPtrIter = mNavMeshLocationPtrs.begin();
navMeshLocationPtrIter != mNavMeshLocationPtrs.end(); ++navMeshLocationPtrIter)
{
NavMeshLocationPtr navMeshLocationPtr = *navMeshLocationPtrIter;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: region #" << navMeshLocationPtr->getDirection() << ": region(" << navMeshLocationPtr->getRegionUUID().asString() << ") status:" << navMeshLocationPtr->getRequestStatus() << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
switch (navMeshLocationPtr->getRequestStatus())
{
case LLPathfindingNavMesh::kNavMeshRequestUnknown :
hasRequestUnknown = true;
break;
+ case LLPathfindingNavMesh::kNavMeshRequestNeedsUpdate :
+ hasRequestNeedsUpdate = true;
+ break;
case LLPathfindingNavMesh::kNavMeshRequestStarted :
hasRequestStarted = true;
break;
@@ -156,34 +184,62 @@ void LLPathfindingNavMeshZone::updateStatus()
}
ENavMeshZoneRequestStatus zoneRequestStatus = kNavMeshZoneRequestUnknown;
- if (hasRequestStarted)
+ if (hasRequestNeedsUpdate)
+ {
+ zoneRequestStatus = kNavMeshZoneRequestNeedsUpdate;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is NEEDS UPDATE" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
+ }
+ else if (hasRequestStarted)
{
zoneRequestStatus = kNavMeshZoneRequestStarted;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is STARTED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
}
else if (hasRequestError)
{
zoneRequestStatus = kNavMeshZoneRequestError;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is ERROR" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
}
else if (hasRequestUnknown)
{
zoneRequestStatus = kNavMeshZoneRequestUnknown;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is UNKNOWN" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
}
else if (hasRequestCompleted)
{
zoneRequestStatus = kNavMeshZoneRequestCompleted;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is stitching" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
llassert(LLPathingLib::getInstance() != NULL);
if (LLPathingLib::getInstance() != NULL)
{
LLPathingLib::getInstance()->stitchNavMeshes( gSavedSettings.getBOOL("EnableVBOForNavMeshVisualization") );
}
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is COMPLETED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
}
else if (hasRequestNotEnabled)
{
zoneRequestStatus = kNavMeshZoneRequestNotEnabled;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is NOT ENABLED" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
}
else
{
zoneRequestStatus = kNavMeshZoneRequestError;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ llinfos << "STINSON DEBUG: Navmesh zone update is BAD ERROR" << llendl;
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
llassert(0);
}
diff --git a/indra/newview/llpathfindingnavmeshzone.h b/indra/newview/llpathfindingnavmeshzone.h
index 8489b5899b..7084869b33 100644
--- a/indra/newview/llpathfindingnavmeshzone.h
+++ b/indra/newview/llpathfindingnavmeshzone.h
@@ -38,11 +38,14 @@
#include <boost/function.hpp>
#include <boost/signals2.hpp>
+#define XXX_STINSON_DEBUG_NAVMESH_ZONE
+
class LLPathfindingNavMeshZone
{
public:
typedef enum {
kNavMeshZoneRequestUnknown,
+ kNavMeshZoneRequestNeedsUpdate,
kNavMeshZoneRequestStarted,
kNavMeshZoneRequestCompleted,
kNavMeshZoneRequestNotEnabled,
@@ -78,6 +81,10 @@ private:
void disable();
LLPathfindingNavMesh::ENavMeshRequestStatus getRequestStatus() const;
+#ifdef XXX_STINSON_DEBUG_NAVMESH_ZONE
+ const LLUUID &getRegionUUID() const {return mRegionUUID;};
+ S32 getDirection() const {return mDirection;};
+#endif // XXX_STINSON_DEBUG_NAVMESH_ZONE
protected:
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
index 6c97af2878..75465f1aea 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
@@ -15,8 +15,8 @@
<floater.string name="navmesh_status_library_not_implemented">Cannot find pathing library implementation.</floater.string>
<floater.string name="navmesh_status_region_not_enabled">This region is not enabled for pathfinding.</floater.string>
<floater.string name="navmesh_status_downloading">Downloading the navmesh ...</floater.string>
+ <floater.string name="navmesh_status_updating">The navmesh has changed on the server. Downloading the latest navmesh ...</floater.string>
<floater.string name="navmesh_status_has_navmesh">Navmesh received.</floater.string>
- <floater.string name="navmesh_status_has_navmesh_downloading">Downloading the latest navmesh ...</floater.string>
<floater.string name="navmesh_status_error">Unable to download navmesh successfully.</floater.string>
<floater.string name="pathing_choose_start_and_end_points">Please choose start and end points.</floater.string>
<floater.string name="pathing_choose_start_point">Please choose start point.</floater.string>