Daniel Buckmaster 10 лет назад
Родитель
Сommit
163b14fac1
40 измененных файлов с 5642 добавлено и 6 удалено
  1. 356 0
      Templates/Empty/game/tools/navEditor/CreateNewNavMeshDlg.gui
  2. 169 0
      Templates/Empty/game/tools/navEditor/NavEditorConsoleDlg.gui
  3. 851 0
      Templates/Empty/game/tools/navEditor/NavEditorGui.gui
  4. 506 0
      Templates/Empty/game/tools/navEditor/NavEditorSettingsTab.gui
  5. 144 0
      Templates/Empty/game/tools/navEditor/NavEditorToolbar.gui
  6. BIN
      Templates/Empty/game/tools/navEditor/done.wav
  7. BIN
      Templates/Empty/game/tools/navEditor/images/nav-cover_d.png
  8. BIN
      Templates/Empty/game/tools/navEditor/images/nav-cover_h.png
  9. BIN
      Templates/Empty/game/tools/navEditor/images/nav-cover_n.png
  10. BIN
      Templates/Empty/game/tools/navEditor/images/nav-editor_d.png
  11. BIN
      Templates/Empty/game/tools/navEditor/images/nav-editor_h.png
  12. BIN
      Templates/Empty/game/tools/navEditor/images/nav-editor_n.png
  13. BIN
      Templates/Empty/game/tools/navEditor/images/nav-link_d.png
  14. BIN
      Templates/Empty/game/tools/navEditor/images/nav-link_h.png
  15. BIN
      Templates/Empty/game/tools/navEditor/images/nav-link_n.png
  16. 276 0
      Templates/Empty/game/tools/navEditor/main.cs
  17. 37 0
      Templates/Empty/game/tools/navEditor/navEditor.cs
  18. 351 0
      Templates/Empty/game/tools/navEditor/navEditorGui.cs
  19. 130 0
      Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui
  20. 1 3
      Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs
  21. 356 0
      Templates/Full/game/tools/navEditor/CreateNewNavMeshDlg.gui
  22. 169 0
      Templates/Full/game/tools/navEditor/NavEditorConsoleDlg.gui
  23. 851 0
      Templates/Full/game/tools/navEditor/NavEditorGui.gui
  24. 506 0
      Templates/Full/game/tools/navEditor/NavEditorSettingsTab.gui
  25. 144 0
      Templates/Full/game/tools/navEditor/NavEditorToolbar.gui
  26. BIN
      Templates/Full/game/tools/navEditor/done.wav
  27. BIN
      Templates/Full/game/tools/navEditor/images/nav-cover_d.png
  28. BIN
      Templates/Full/game/tools/navEditor/images/nav-cover_h.png
  29. BIN
      Templates/Full/game/tools/navEditor/images/nav-cover_n.png
  30. BIN
      Templates/Full/game/tools/navEditor/images/nav-editor_d.png
  31. BIN
      Templates/Full/game/tools/navEditor/images/nav-editor_h.png
  32. BIN
      Templates/Full/game/tools/navEditor/images/nav-editor_n.png
  33. BIN
      Templates/Full/game/tools/navEditor/images/nav-link_d.png
  34. BIN
      Templates/Full/game/tools/navEditor/images/nav-link_h.png
  35. BIN
      Templates/Full/game/tools/navEditor/images/nav-link_n.png
  36. 276 0
      Templates/Full/game/tools/navEditor/main.cs
  37. 37 0
      Templates/Full/game/tools/navEditor/navEditor.cs
  38. 351 0
      Templates/Full/game/tools/navEditor/navEditorGui.cs
  39. 130 0
      Templates/Full/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui
  40. 1 3
      Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs

+ 356 - 0
Templates/Empty/game/tools/navEditor/CreateNewNavMeshDlg.gui

@@ -0,0 +1,356 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(CreateNewNavMeshDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiWindowCtrl() {
+      text = "New NavMesh";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "Canvas.popDialog(CreateNewNavMeshDlg);";
+      edgeSnap = "1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "283 240";
+      extent = "200 151";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiTextCtrl() {
+         text = "Name:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 29";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "Nav";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 30";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshName";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Position:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 51";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "0 0 0";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 52";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshPosition";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Scale:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 73";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "50 50 20";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 74";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshScale";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl() {
+         text = " Fit NavMesh to mission area?";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "22 99";
+         extent = "159 15";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Positions and scales the NavMesh so it includes all your mission objects.";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "MeshMissionBounds";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Create!";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "12 121";
+         extent = "87 19";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "CreateNewNavMeshDlg.create();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "104 121";
+         extent = "84 19";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(CreateNewNavMeshDlg);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+
+function CreateNewNavMeshDlg::onWake(%this)
+{
+   %this-->MeshName.setText("Nav");
+   %this-->MeshPosition.setText("0 0 0");
+   %this-->MeshScale.setText("50 50 20");
+}
+
+function MissionBoundsExtents(%group)
+{
+   %box = "0 0 0 0 0 0";
+   foreach(%obj in %group)
+   {
+      // Skip LevelInfos. Need a way to detect other non-SceneObjects.
+      // Also skip GroundPlanes. They're too big.
+      %cls = %obj.getClassName();
+      if(%cls $= "LevelInfo" || %cls $= "GroundPlane" || %cls $= "GroundCover")
+         continue;
+
+      // Get world box - might have to recurse into nested SimGroups.
+      %wbox = "0 0 0 0 0 0";
+      if(%cls $= "SimGroup" || %cls $= "SimSet" || %cls $= "Path")
+         %wbox = MissionBoundsExtents(%obj);
+      else if(%obj.getType() & $TypeMasks::StaticObjectType &&
+         !(%obj.getType() & $TypeMasks::EnvironmentObjectType))
+         %wbox = %obj.getWorldBox();
+      else
+         continue;
+
+      // Update min point.
+      for(%j = 0; %j < 3; %j++)
+      {
+         if(GetWord(%box, %j) > GetWord(%wbox, %j))
+            %box = SetWord(%box, %j, GetWord(%wbox, %j));
+      }
+      // Update max point.
+      for(%j = 3; %j < 6; %j++)
+      {
+         if(GetWord(%box, %j) < GetWord(%wbox, %j))
+            %box = SetWord(%box, %j, GetWord(%wbox, %j));
+      }
+   }
+   return %box;
+}
+
+function CreateNewNavMeshDlg::create(%this)
+{
+   %name = %this-->MeshName.getText();
+   if(%name $= "" || nameToID(%name) != -1)
+   {
+      MessageBoxOk("Error", "A NavMesh must have a unique name!");
+      return;
+   }
+
+   %mesh = 0;
+
+   if(%this-->MeshMissionBounds.isStateOn())
+   {
+      if(!isObject(MissionGroup))
+      {
+         MessageBoxOk("Error", "You must have a MissionGroup to use the mission bounds function.");
+         return;
+      }
+      // Get maximum extents of all objects.
+      %box = MissionBoundsExtents(MissionGroup);
+      %pos = GetBoxCenter(%box);
+      %scale = (GetWord(%box, 3) - GetWord(%box, 0)) / 2 + 5
+         SPC (GetWord(%box, 4) - GetWord(%box, 1)) / 2 + 5
+         SPC (GetWord(%box, 5) - GetWord(%box, 2)) / 2 + 5;
+
+      %mesh = new NavMesh(%name)
+      {
+         position = %pos;
+         scale = %scale;
+      };
+   }
+   else
+   {
+      %mesh = new NavMesh(%name)
+      {
+         position = %this-->MeshPosition.getText();
+         scale = %this-->MeshScale.getText();
+      };
+   }
+   MissionGroup.add(%mesh);
+   NavEditorGui.selectObject(%mesh);
+
+   Canvas.popDialog(CreateNewNavMeshDlg);
+}

+ 169 - 0
Templates/Empty/game/tools/navEditor/NavEditorConsoleDlg.gui

@@ -0,0 +1,169 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiWindowCtrl(NavEditorConsoleDlg) {
+   text = "Nav Console";
+   resizeWidth = "1";
+   resizeHeight = "1";
+   canMove = "1";
+   canClose = "1";
+   canMinimize = "1";
+   canMaximize = "1";
+   canCollapse = "0";
+   closeCommand = "NavEditorConsoleDlg.setVisible(false);";
+   edgeSnap = "1";
+   margin = "0 0 0 0";
+   padding = "0 0 0 0";
+   anchorTop = "1";
+   anchorBottom = "0";
+   anchorLeft = "1";
+   anchorRight = "0";
+   position = "238 170";
+   extent = "320 240";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiWindowProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiTextCtrl() {
+      maxLength = "1024";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "3 222";
+      extent = "149 13";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "top";
+      profile = "GuiTextProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "StatusLeft";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiScrollCtrl() {
+      willFirstRespond = "1";
+      hScrollBar = "dynamic";
+      vScrollBar = "dynamic";
+      lockHorizScroll = "1";
+      lockVertScroll = "0";
+      constantThumbHeight = "0";
+      childMargin = "0 0";
+      mouseWheelScrollSpeed = "-1";
+      margin = "-14 41 3 3";
+      padding = "0 0 0 0";
+      anchorTop = "0";
+      anchorBottom = "0";
+      anchorLeft = "0";
+      anchorRight = "0";
+      position = "3 23";
+      extent = "314 194";
+      minExtent = "8 2";
+      horizSizing = "relative";
+      vertSizing = "relative";
+      profile = "GuiEditorScrollProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "OutputScroll";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiListBoxCtrl() {
+         allowMultipleSelections = "0";
+         fitParentWidth = "1";
+         colorBullet = "1";
+         position = "1 1";
+         extent = "312 16";
+         minExtent = "8 2";
+         horizSizing = "relative";
+         vertSizing = "relative";
+         profile = "GuiListBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "Output";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+
+new ScriptMsgListener(NavEditorConsoleListener);
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshCreated");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshRemoved");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshStartUpdate");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshUpdate");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshTileUpdate");
+
+function NavEditorConsoleListener::onNavMeshCreated(%this, %data)
+{
+}
+
+function NavEditorConsoleListener::onNavMeshRemoved(%this, %data)
+{
+}
+
+function NavEditorConsoleListener::onNavMeshStartUpdate(%this, %data)
+{
+   NavEditorConsoleDlg-->Output.clearItems();
+   NavEditorConsoleDlg-->Output.addItem("Build starting for NavMesh" SPC %data, "0 0.6 0");
+   NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+}
+
+function NavEditorConsoleListener::onNavMeshUpdate(%this, %data)
+{
+   %message = "";
+   if(getWordCount(%data) == 2)
+   {
+      %seconds = getWord(%data, 1);
+      %minutes = mFloor(%seconds / 60);
+      %seconds -= %minutes * 60;
+      %message = "Built NavMesh" SPC getWord(%data, 0) SPC "in" SPC %minutes @ "m" SPC mRound(%seconds) @ "s";
+      if($Nav::Editor::playSoundWhenDone)
+      {
+         sfxPlayOnce(Audio2D, "tools/navEditor/done.wav");
+      }
+   }
+   else
+   {
+      %message = "Loaded NavMesh" SPC %data;
+   }
+   NavEditorConsoleDlg-->Output.addItem(%message, "0 0.6 0");
+   NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+   NavEditorConsoleDlg->StatusLeft.setText("");
+}
+
+function NavEditorConsoleListener::onNavMeshTileUpdate(%this, %data)
+{
+   %mesh = getWord(%data, 0);
+   %index = getWord(%data, 1);
+   %total = getWord(%data, 2);
+   %tile = getWords(%data, 3, 4);
+   %success = getWord(%data, 5) == "1";
+   if(!%success)
+   {
+      %message = "NavMesh" SPC %mesh SPC "tile" SPC %tile SPC "build failed!";
+      NavEditorConsoleDlg-->Output.addItem(%message, "1 0 0");
+      NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+   }
+   %percent = %index / %total * 100;
+   NavEditorConsoleDlg->StatusLeft.setText("Build progress:" SPC mRound(%percent) @ "%");
+}

+ 851 - 0
Templates/Empty/game/tools/navEditor/NavEditorGui.gui

@@ -0,0 +1,851 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiNavEditorCtrl(NavEditorGui, EditorGuiGroup) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "NavEditorProfile";
+   HorizSizing = "width";
+   VertSizing = "height";
+   Position = "0 0";
+   Extent = "800 600";
+   MinExtent = "8 8";
+   canSave = "1";
+   Visible = "1";
+   tooltipprofile = "GuiToolTipProfile";
+   hovertime = "1000";
+   Docking = "None";
+   Margin = "0 0 0 0";
+   Padding = "0 0 0 0";
+   AnchorTop = "0";
+   AnchorBottom = "0";
+   AnchorLeft = "0";
+   AnchorRight = "0";
+   cameraZRot = "0";
+   forceFOV = "0";
+   renderMissionArea = "0";
+   missionAreaFillColor = "255 0 0 20";
+   missionAreaFrameColor = "255 0 0 128";
+   allowBorderMove = "0";
+   borderMovePixelSize = "20";
+   borderMoveSpeed = "0.1";
+   consoleFrameColor = "255 0 0 255";
+   consoleFillColor = "0 0 0 0";
+   consoleSphereLevel = "1";
+   consoleCircleSegments = "32";
+   consoleLineWidth = "1";
+   GizmoProfile = "GlobalGizmoProfile";
+
+   new GuiWindowCollapseCtrl(NavEditorTreeWindow) {
+      internalName = "";
+      canSaveDynamicFields = "0";
+      Enabled = "1";
+      isContainer = "1";
+      Profile = "GuiWindowProfile";
+      HorizSizing = "windowRelative";
+      VertSizing = "windowRelative";
+      Position = getWord($pref::Video::mode, 0) - 209
+         SPC getWord(EditorGuiToolbar.extent, 1) - 1;
+      Extent = "210 167";
+      MinExtent = "210 100";
+      canSave = "1";
+      isDecoy = "0";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      Margin = "0 0 0 0";
+      Padding = "0 0 0 0";
+      AnchorTop = "1";
+      AnchorBottom = "0";
+      AnchorLeft = "1";
+      AnchorRight = "0";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      EdgeSnap = "1";
+      text = "Navigation";
+
+      new GuiButtonCtrl() {
+         Profile = "GuiButtonProfile";
+         buttonType = "PushButton";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "115 2";
+         extent = "90 18";
+         text = "New NavMesh";
+         command = "Canvas.pushDialog(CreateNewNavMeshDlg);";
+      };
+
+      new GuiContainer(){
+         profile = GuiDefaultProfile;
+         Position = "5 25";
+         Extent = "200 120";
+         Docking = "Client";
+         Margin = "3 1 3 3 ";
+         HorizSizing = "width";
+         VertSizing = "height";
+         isContainer = "1";
+         
+         new GuiScrollCtrl() {
+            canSaveDynamicFields = "0";
+            Enabled = "1";
+            isContainer = "1";
+            Profile = "GuiEditorScrollProfile";
+            HorizSizing = "width";
+            VertSizing = "height";
+            Position = "0 0";
+            Extent = "200 118";
+            MinExtent = "8 8";
+            canSave = "1";
+            isDecoy = "0";
+            Visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            Docking = "Client";
+            Margin = "0 0 0 0";
+            Padding = "0 0 0 0";
+            AnchorTop = "1";
+            AnchorBottom = "0";
+            AnchorLeft = "1";
+            AnchorRight = "0";
+            willFirstRespond = "1";
+            hScrollBar = "alwaysOff";
+            vScrollBar = "dynamic";
+            lockHorizScroll = "true";
+            lockVertScroll = "false";
+            constantThumbHeight = "0";
+            childMargin = "0 0";
+            mouseWheelScrollSpeed = "-1";
+
+            new GuiTreeViewCtrl(NavTreeView) {
+               canSaveDynamicFields = "0";
+               Enabled = "1";
+               isContainer = "1";
+               Profile = "ToolsGuiTreeViewProfile";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Position = "1 1";
+               Extent = "193 21";
+               MinExtent = "8 8";
+               canSave = "1";
+               Visible = "1";
+               hovertime = "1000";
+               tabSize = "16";
+               textOffset = "2";
+               fullRowSelect = "0";
+               itemHeight = "21";
+               destroyTreeOnSleep = "1";
+               MouseDragging = "0";
+               MultipleSelections = "0";
+               DeleteObjectAllowed = "1";
+               DragToItemAllowed = "0";
+               showRoot = "0";
+               internalNamesOnly = "0";
+            };
+         };
+      };
+   };
+   new GuiWindowCollapseCtrl(NavEditorOptionsWindow) {
+      internalName = "Window";
+      canSaveDynamicFields = "0";
+      Enabled = "1";
+      isContainer = "1";
+      Profile = "GuiWindowProfile";
+      HorizSizing = "windowRelative";
+      VertSizing = "windowRelative";
+      Position = getWord($pref::Video::mode, 0) - 209 
+         SPC getWord(EditorGuiToolbar.extent, 1) + getWord(NavEditorTreeWindow.extent, 1) - 2;
+      Extent = "210 530";
+      MinExtent = "210 300";
+      canSave = "1";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      Margin = "0 0 0 0";
+      Padding = "0 0 0 0";
+      AnchorTop = "0";
+      AnchorBottom = "0";
+      AnchorLeft = "0";
+      AnchorRight = "0";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      EdgeSnap = "1";
+      text = "Properties";
+      
+      new GuiContainer(){ //Actions
+         isContainer = "1";
+         Profile = "inspectorStyleRolloutDarkProfile";
+         HorizSizing = "width";
+         VertSizing = "bottom";
+         Position = "4 24";
+         Extent = "202 85";
+         Docking = "Top";
+         Margin = "3 3 3 3";
+         internalName = "ActionsBox";
+         
+         new GuiTextCtrl(){
+            Profile = "GuiDefaultProfile";
+            HorizSizing = "right";
+            VertSizing = "bottom";
+            Position = "5 0";
+            Extent = "86 18";
+            text = "Actions";
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "SelectActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Build NavMesh";
+               command = "NavEditorGui.buildSelectedMeshes();";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "BackgroundBuildButton";
+               text = "Background";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "75 20";
+               minExtent = "8 2";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::backgroundBuild";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "SaveIntermediatesButton";
+               text = "Keep intermediates";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "105 20";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::saveIntermediates";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "BuildSoundButton";
+               text = "Play sound when done";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "150 20";
+               minExtent = "8 2";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::playSoundWhenDone";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "LinkActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Rebuild links";
+               command = "NavEditorGui.buildLinks();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "CoverActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Create Cover";
+               command = "NavEditorGui.createCoverPoints();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Delete Cover";
+               command = "NavEditorGui.deleteCoverPoints();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TileActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Rebuild tile";
+               command = "NavEditorGui.buildTile();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TestActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "180 18";
+               text = "Spawn";
+               command = "NavEditorGui.spawnPlayer();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Delete";
+               command = "NavEditorGui.getPlayer().delete();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Find cover";
+               command = "NavEditorGui.findCover();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Follow";
+               command = "NavEditorGui.followObject();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Stop";
+               command = "NavEditorGui.getPlayer().stop();";
+            };
+         };
+      };
+      new GuiContainer(){
+         isContainer = "1";
+         Profile = "inspectorStyleRolloutDarkProfile";
+         HorizSizing = "width";
+         VertSizing = "bottom";
+         Position = "4 112";
+         Extent = "202 31";
+         Docking = "Top";
+         Margin = "0 0 3 3";
+         
+         new GuiTextCtrl(){
+            Profile = "GuiDefaultProfile";
+            HorizSizing = "right";
+            VertSizing = "bottom";
+            Position = "5 0";
+            Extent = "121 18";
+            text = "Properties";
+         };
+      };
+
+      new GuiScrollCtrl() {
+         canSaveDynamicFields = "0";
+         Enabled = "1";
+         isContainer = "1";
+         Profile = "GuiEditorScrollProfile";
+         HorizSizing = "width";
+         VertSizing = "height";
+         Position = "4 129";
+         Extent = "202 357";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         Docking = "Client";
+         Margin = "-14 41 3 3";
+         Padding = "0 0 0 0";
+         AnchorTop = "0";
+         AnchorBottom = "0";
+         AnchorLeft = "0";
+         AnchorRight = "0";
+         willFirstRespond = "1";
+         hScrollBar = "alwaysOff";
+         vScrollBar = "dynamic";
+         lockHorizScroll = "true";
+         lockVertScroll = "false";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         internalName = "PropertiesBox";
+
+         new GuiInspector(NavInspector) {
+            StackingType = "Vertical";
+            HorizStacking = "Left to Right";
+            VertStacking = "Top to Bottom";
+            Padding = "1";
+            name = "NavInspector";
+            canSaveDynamicFields = "0";
+            Enabled = "1";
+            isContainer = "1";
+            Profile = "GuiTransparentProfile";
+            HorizSizing = "width";
+            VertSizing = "height";
+            Position = "1 1";
+            Extent = "178 16";
+            MinExtent = "16 16";
+            canSave = "1";
+            Visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            dividerMargin = "5";
+         };
+         
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "LinkProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkWalkFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Walk";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "This link is just ordinary flat ground.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkJumpFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Jump";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link require a jump?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkDropFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Drop";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link involve a significant drop?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkLedgeFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Ledge";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Should the character jump at the next ledge?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkClimbFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Climb";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link involve climbing?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkTeleportFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Teleport";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Is this link a teleporter?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TileProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+            new GuiCheckBoxCtrl() {
+               text = " Display input geometry";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+			   variable = "$Nav::Editor::renderInput";
+            };
+            new GuiCheckBoxCtrl() {
+               text = " Display voxels";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+			   variable = "$Nav::Editor::renderVoxels";
+            };
+         };
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TestProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+			new GuiTextCtrl() {
+			   text = "Cover";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiTextEditCtrl() {
+               internalName = "CoverRadius";
+               text = "10";
+               profile = "GuiTextEditProfile";
+               extent = "40 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Radius for cover-finding.";
+            };
+			new GuiTextEditCtrl() {
+               internalName = "CoverPosition";
+               text = "LocalClientConnection.getControlObject().getPosition();";
+               profile = "GuiTextEditProfile";
+               extent = "140 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Position to find cover from.";
+			};
+			new GuiTextCtrl() {
+			   text = "Follow";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiTextEditCtrl() {
+               internalName = "FollowRadius";
+               text = "1";
+               profile = "GuiTextEditProfile";
+               extent = "40 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Radius for following.";
+            };
+			new GuiTextEditCtrl() {
+               internalName = "FollowObject";
+               text = "LocalClientConnection.player";
+               profile = "GuiTextEditProfile";
+               extent = "140 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Object to follow.";
+			};
+			new GuiTextCtrl() {
+			   text = "Movement";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkWalkFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Walk";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character walk on ground?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkJumpFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Jump";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character jump?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkDropFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Drop";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character drop over edges?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkLedgeFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Ledge";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character jump from ledges?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkClimbFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Climb";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character climb?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkTeleportFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Teleport";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character teleport?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+      new GuiMLTextCtrl(NavFieldInfoControl) {
+         canSaveDynamicFields = "0";
+         Enabled = "1";
+         isContainer = "0";
+         Profile = "GuiInspectorFieldInfoMLTextProfile";
+         HorizSizing = "width";
+         VertSizing = "top";
+         Position = "1 485";
+         Extent = "202 42";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+         useURLMouseCursor = "0";
+      };
+   };
+   
+};
+
+//--- OBJECT WRITE END ---

+ 506 - 0
Templates/Empty/game/tools/navEditor/NavEditorSettingsTab.gui

@@ -0,0 +1,506 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiTabPageCtrl(ENavEditorSettingsPage) {
+   fitBook = "1";
+   text = "Navigation Editor";
+   maxLength = "1024";
+   margin = "0 0 0 0";
+   padding = "0 0 0 0";
+   anchorTop = "1";
+   anchorBottom = "0";
+   anchorLeft = "1";
+   anchorRight = "0";
+   position = "0 0";
+   extent = "208 292";
+   minExtent = "8 2";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiSolidDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiScrollCtrl() {
+      willFirstRespond = "1";
+      hScrollBar = "alwaysOff";
+      vScrollBar = "dynamic";
+      lockHorizScroll = "1";
+      lockVertScroll = "0";
+      constantThumbHeight = "0";
+      childMargin = "0 0";
+      mouseWheelScrollSpeed = "-1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "0 0";
+      extent = "208 292";
+      minExtent = "8 2";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "GuiScrollProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiStackControl() {
+         stackingType = "Vertical";
+         horizStacking = "Left to Right";
+         vertStacking = "Top to Bottom";
+         padding = "0";
+         dynamicSize = "1";
+         dynamicNonStackExtent = "0";
+         dynamicPos = "0";
+         changeChildSizeToFit = "1";
+         changeChildPosition = "1";
+         position = "1 1";
+         extent = "206 124";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiRolloutCtrl() {
+            caption = "Test spawn";
+            margin = "0 3 0 0";
+            defaultHeight = "40";
+            expanded = "1";
+            clickCollapse = "1";
+            hideHeader = "0";
+            autoCollapseSiblings = "0";
+            position = "0 0";
+            extent = "206 62";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiRolloutProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiStackControl() {
+               stackingType = "Vertical";
+               horizStacking = "Left to Right";
+               vertStacking = "Top to Bottom";
+               padding = "3";
+               dynamicSize = "1";
+               dynamicNonStackExtent = "0";
+               dynamicPos = "0";
+               changeChildSizeToFit = "1";
+               changeChildPosition = "1";
+               position = "0 20";
+               extent = "206 39";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiControl() {
+                  position = "0 0";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+
+                  new GuiTextCtrl() {
+                     text = "Spawn class:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "5 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+                  };
+                  new GuiPopUpMenuCtrlEx() {
+                     maxPopupHeight = "200";
+                     sbUsesNAColor = "0";
+                     reverseTextList = "0";
+                     bitmapBounds = "16 16";
+                     hotTrackCallback = "0";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "81 0";
+                     extent = "121 18";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiPopUpMenuProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "1";
+                     internalName = "SpawnClassOptions";
+                     class = "ESettingsWindowPopup";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                        editorSettingsRead = "NavEditorPlugin.readSettings();";
+                        editorSettingsValue = "NavEditor/SpawnClass";
+                        editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+                  };
+               };
+               new GuiControl() {
+                  position = "0 21";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+
+                  new GuiTextCtrl() {
+                     text = "Datablock:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "5 1";
+                     extent = "70 18";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     text = "DefaultPlayerData";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "81 0";
+                     extent = "121 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     class = "ESettingsWindowTextEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                        editorSettingsRead = "NavEditorPlugin.readSettings();";
+                        editorSettingsValue = "NavEditor/SpawnDatablock";
+                        editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+                  };
+               };
+            };
+         };
+         new GuiRolloutCtrl() {
+            caption = "Colors";
+            margin = "0 3 0 0";
+            defaultHeight = "40";
+            expanded = "1";
+            clickCollapse = "1";
+            hideHeader = "0";
+            autoCollapseSiblings = "0";
+            position = "0 62";
+            extent = "206 62";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiRolloutProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiStackControl() {
+               stackingType = "Vertical";
+               horizStacking = "Left to Right";
+               vertStacking = "Top to Bottom";
+               padding = "3";
+               dynamicSize = "1";
+               dynamicNonStackExtent = "0";
+               dynamicPos = "0";
+               changeChildSizeToFit = "1";
+               changeChildPosition = "1";
+               position = "0 20";
+               extent = "206 39";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiControl() {
+                  position = "0 0";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  class = "ESettingsWindowColor";
+                  canSave = "1";
+                  canSaveDynamicFields = "1";
+                     editorSettingsRead = "NavEditorPlugin.readSettings();";
+                     editorSettingsValue = "NavEditor/HoverSplineColor";
+                     editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+
+                  new GuiTextCtrl() {
+                     text = "Hover Spline:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "80 0";
+                     extent = "104 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorEdit";
+                     class = "ESettingsWindowColorEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiSwatchButtonCtrl() {
+                     color = "0 0 0 0";
+                     groupNum = "-1";
+                     buttonType = "PushButton";
+                     useMouseEvents = "0";
+                     position = "188 2";
+                     extent = "14 14";
+                     minExtent = "8 2";
+                     horizSizing = "left";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorButton";
+                     class = "ESettingsWindowColorButton";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+               };
+               new GuiControl() {
+                  position = "0 21";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  class = "ESettingsWindowColor";
+                  canSave = "1";
+                  canSaveDynamicFields = "1";
+                     editorSettingsRead = "NavEditorPlugin.readSettings();";
+                     editorSettingsValue = "NavEditor/SelectedSplineColor";
+                     editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+
+                  new GuiTextCtrl() {
+                     text = "Sel. Spline:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "80 0";
+                     extent = "104 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorEdit";
+                     class = "ESettingsWindowColorEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiSwatchButtonCtrl() {
+                     color = "0 0 0 0";
+                     groupNum = "-1";
+                     buttonType = "PushButton";
+                     useMouseEvents = "0";
+                     position = "188 2";
+                     extent = "14 14";
+                     minExtent = "8 2";
+                     horizSizing = "left";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorButton";
+                     class = "ESettingsWindowColorButton";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+               };
+            };
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 144 - 0
Templates/Empty/game/tools/navEditor/NavEditorToolbar.gui

@@ -0,0 +1,144 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(NavEditorToolbar,EditorGuiGroup) {
+   position = "306 0";
+   extent = "800 32";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   internalName = "NavEditorToolbar";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      enabled = "1";
+
+   new GuiTextCtrl() {
+      text = "Navigation Editor";
+      maxLength = "255";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "6 6";
+      extent = "150 20";
+      minExtent = "8 8";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiTextProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiBitmapCtrl() {
+      bitmap = "core/art/gui/images/separator-h.png";
+      wrap = "0";
+      position = "90 3";
+      extent = "2 26";
+      minExtent = "1 1";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiButtonCtrl(NavEditorAboutBtn) {
+      text = "Console";
+      groupNum = "7";
+      buttonType = "PushButton";
+      useMouseEvents = "0";
+      position = "100 6";
+      extent = "54 20";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiButtonProfile";
+      visible = "1";
+      active = "1";
+      command = "NavEditorConsoleDlg.setVisible(!NavEditorConsoleDlg.isVisible());";
+      tooltipProfile = "GuiToolTipProfile";
+      tooltip = "Show Console";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "Mesh";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "167 1";
+      extent = "50 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderMesh";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "MeshButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "Portals";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "224 1";
+      extent = "54 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderPortals";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "PortalButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "BV tree";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "286 1";
+      extent = "140 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderBVTree";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "BVTreeButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+};
+//--- OBJECT WRITE END ---

BIN
Templates/Empty/game/tools/navEditor/done.wav


BIN
Templates/Empty/game/tools/navEditor/images/nav-cover_d.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-cover_h.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-cover_n.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-editor_d.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-editor_h.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-editor_n.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-link_d.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-link_h.png


BIN
Templates/Empty/game/tools/navEditor/images/nav-link_n.png


+ 276 - 0
Templates/Empty/game/tools/navEditor/main.cs

@@ -0,0 +1,276 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// These values should align with enum PolyFlags in walkabout/nav.h
+$Nav::WalkFlag = 1 << 0;
+$Nav::SwimFlag = 1 << 1;
+$Nav::JumpFlag = 1 << 2;
+$Nav::LedgeFlag = 1 << 3;
+$Nav::DropFlag = 1 << 4;
+$Nav::ClimbFlag = 1 << 5;
+$Nav::TeleportFlag = 1 << 6;
+
+function initializeNavEditor()
+{
+   echo(" % - Initializing Navigation Editor");
+
+   // Execute all relevant scripts and GUIs.
+   exec("./NavEditor.cs");
+   exec("./NavEditorGui.gui");
+   exec("./NavEditorToolbar.gui");
+   exec("./NavEditorGui.cs");
+   exec("./NavEditorAboutDlg.gui");
+   exec("./NavEditorConsoleDlg.gui");
+   exec("./CreateNewNavMeshDlg.gui");
+
+   // Add ourselves to EditorGui, where all the other tools reside
+   NavEditorGui.setVisible(false);  
+   NavEditorToolbar.setVisible(false); 
+   NavEditorOptionsWindow.setVisible(false);
+   NavEditorTreeWindow.setVisible(false);
+   NavEditorConsoleDlg.setVisible(false);
+
+   EditorGui.add(NavEditorGui);
+   EditorGui.add(NavEditorToolbar);
+   EditorGui.add(NavEditorOptionsWindow);
+   EditorGui.add(NavEditorTreeWindow);
+   EditorGui.add(NavEditorConsoleDlg);
+
+   new ScriptObject(NavEditorPlugin)
+   {
+      superClass = "EditorPlugin";
+      editorGui = NavEditorGui;
+   };
+
+   // Bind shortcuts for the nav editor.
+   %map = new ActionMap();
+   %map.bindCmd(keyboard, "1", "ENavEditorSelectModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "2", "ENavEditorLinkModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "3", "ENavEditorCoverModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "4", "ENavEditorTileModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "5", "ENavEditorTestModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "c", "NavEditorConsoleBtn.performClick();", "");
+   NavEditorPlugin.map = %map;
+
+   NavEditorPlugin.initSettings();
+}
+
+function destroyNavEditor()
+{
+}
+
+function NavEditorPlugin::onWorldEditorStartup(%this)
+{    
+    // Add ourselves to the window menu.
+   %accel = EditorGui.addToEditorsMenu("Navigation Editor", "", NavEditorPlugin);   
+
+   // Add ourselves to the ToolsToolbar.
+   %tooltip = "Navigation Editor (" @ %accel @ ")";   
+   EditorGui.addToToolsToolbar("NavEditorPlugin", "NavEditorPalette", expandFilename("tools/navEditor/images/nav-editor"), %tooltip);
+
+   GuiWindowCtrl::attach(NavEditorOptionsWindow, NavEditorTreeWindow);
+
+   // Add ourselves to the Editor Settings window.
+   exec("./NavEditorSettingsTab.gui");
+   ESettingsWindow.addTabPage(ENavEditorSettingsPage);
+   ENavEditorSettingsPage.init();
+
+   // Add items to World Editor Creator
+   EWCreatorWindow.beginGroup("Navigation");
+
+      EWCreatorWindow.registerMissionObject("NavMesh", "Navigation mesh");
+      EWCreatorWindow.registerMissionObject("NavPath", "Path");
+      EWCreatorWindow.registerMissionObject("CoverPoint", "Cover point");
+
+   EWCreatorWindow.endGroup();
+}
+
+function ENavEditorSettingsPage::init(%this)
+{
+   // Initialises the settings controls in the settings dialog box.
+   %this-->SpawnClassOptions.clear();
+   %this-->SpawnClassOptions.add("AIPlayer");
+   %this-->SpawnClassOptions.setFirstSelected();
+}
+
+function NavEditorPlugin::onActivated(%this)
+{
+   %this.readSettings();
+
+   // Set a global variable so everyone knows we're editing!
+   $Nav::EditorOpen = true;
+
+   // Start off in Select mode.
+   ToolsPaletteArray->NavEditorSelectMode.performClick();
+   EditorGui.bringToFront(NavEditorGui);
+
+   NavEditorGui.setVisible(true);
+   NavEditorGui.makeFirstResponder(true);
+   NavEditorToolbar.setVisible(true);
+
+   NavEditorOptionsWindow.setVisible(true);
+   NavEditorTreeWindow.setVisible(true);
+
+   // Inspect the ServerNavMeshSet, which contains all the NavMesh objects
+   // in the mission.
+   if(!isObject(ServerNavMeshSet))
+      new SimSet(ServerNavMeshSet);
+   if(ServerNavMeshSet.getCount() == 0)
+	  MessageBoxYesNo("No NavMesh", "There is no NavMesh in this level. Would you like to create one?" SPC
+	                                "If not, please use the World Editor to create a new NavMesh.",
+	                                "Canvas.pushDialog(CreateNewNavMeshDlg);");
+   NavTreeView.open(ServerNavMeshSet, true);
+
+   // Push our keybindings to the top. (See initializeNavEditor for where this
+   // map was created.)
+   %this.map.push();
+
+   // Store this on a dynamic field
+   // in order to restore whatever setting
+   // the user had before.
+   %this.prevGizmoAlignment = GlobalGizmoProfile.alignment;
+
+   // Always use Object alignment.
+   GlobalGizmoProfile.alignment = "Object";
+
+   // Set the status bar here until all tool have been hooked up
+   EditorGuiStatusBar.setInfo("Navigation editor.");
+   EditorGuiStatusBar.setSelection("");
+
+   // Allow the Gui to setup.
+   NavEditorGui.onEditorActivated(); 
+
+   Parent::onActivated(%this);
+}
+
+function NavEditorPlugin::onDeactivated(%this)
+{
+   %this.writeSettings();
+
+   $Nav::EditorOpen = false;   
+
+   NavEditorGui.setVisible(false);
+   NavEditorToolbar.setVisible(false);
+   NavEditorOptionsWindow.setVisible(false);
+   NavEditorTreeWindow.setVisible(false);
+   %this.map.pop();
+
+   // Restore the previous Gizmo alignment settings.
+   GlobalGizmoProfile.alignment = %this.prevGizmoAlignment;  
+
+   // Allow the Gui to cleanup.
+   NavEditorGui.onEditorDeactivated(); 
+
+   Parent::onDeactivated(%this);
+}
+
+function NavEditorPlugin::onEditMenuSelect(%this, %editMenu)
+{
+   %hasSelection = false;
+}
+
+function NavEditorPlugin::handleDelete(%this)
+{
+   // Event happens when the user hits 'delete'.
+   NavEditorGui.deleteSelected();
+}
+
+function NavEditorPlugin::handleEscape(%this)
+{
+   return NavEditorGui.onEscapePressed();  
+}
+
+function NavEditorPlugin::isDirty(%this)
+{
+   return NavEditorGui.isDirty;
+}
+
+function NavEditorPlugin::onSaveMission(%this, %missionFile)
+{
+   if(NavEditorGui.isDirty)
+   {
+      MissionGroup.save(%missionFile);
+      NavEditorGui.isDirty = false;
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Settings
+//-----------------------------------------------------------------------------
+
+function NavEditorPlugin::initSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   EditorSettings.setDefaultValue("SpawnClass",     "AIPlayer");
+   EditorSettings.setDefaultValue("SpawnDatablock", "DefaultPlayerData");
+
+   EditorSettings.endGroup();
+}
+
+function NavEditorPlugin::readSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   NavEditorGui.spawnClass     = EditorSettings.value("SpawnClass");
+   NavEditorGui.spawnDatablock = EditorSettings.value("SpawnDatablock");
+
+   EditorSettings.endGroup();  
+}
+
+function NavEditorPlugin::writeSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   EditorSettings.setValue("SpawnClass",     NavEditorGui.spawnClass);
+   EditorSettings.setValue("SpawnDatablock", NavEditorGui.spawnDatablock);
+
+   EditorSettings.endGroup();
+}
+
+function ESettingsWindowPopup::onWake(%this)
+{
+   %this.setSelected(%this.findText(EditorSettings.value(%this.editorSettingsValue)));
+}
+
+function ESettingsWindowPopup::onSelect(%this)
+{
+   EditorSettings.setValue(%this.editorSettingsValue, %this.getText());
+   eval(%this.editorSettingsRead);
+}
+
+//-----------------------------------------------------------------------------
+// Demo
+//-----------------------------------------------------------------------------
+
+function OnWalkaboutDemoLimit()
+{
+   MessageBoxOK("Walkabout demo",
+      "This demo only allows two NavMeshes to be created. Sorry!");
+}
+
+function OnWalkaboutDemoSave()
+{
+   MessageBoxOK("Walkabout demo",
+      "This demo doesn't allow you to save NavMeshes. Sorry!" SPC
+      "The rest of your mission will still be saved.");
+}

+ 37 - 0
Templates/Empty/game/tools/navEditor/navEditor.cs

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile(NavEditorProfile)
+{
+   canKeyFocus = true;
+   opaque = true;
+   fillColor = "192 192 192 192";
+   category = "Editor";
+};
+
+singleton GuiControlProfile(GuiSimpleBorderProfile)
+{
+   opaque = false;   
+   border = 1;   
+   category = "Editor";
+};
+ 

+ 351 - 0
Templates/Empty/game/tools/navEditor/navEditorGui.cs

@@ -0,0 +1,351 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+$Nav::EditorOpen = false;
+$Nav::Editor::renderMesh = true;
+$Nav::Editor::renderPortals = false;
+$Nav::Editor::renderBVTree = false;
+$Nav::Editor::backgroundBuild = true;
+$Nav::Editor::saveIntermediates = false;
+$Nav::Editor::playSoundWhenDone = false;
+
+function NavEditorGui::onEditorActivated(%this)
+{
+   if(%this.selectedObject)
+      %this.selectObject(%this.selectedObject);
+   %this.prepSelectionMode();
+}
+
+function NavEditorGui::onEditorDeactivated(%this)
+{
+   if(%this.getMesh())
+      %this.deselect();
+}
+
+function NavEditorGui::onModeSet(%this, %mode)
+{
+   // Callback when the nav editor changes mode. Set the appropriate dynamic
+   // GUI contents in the properties/actions boxes.
+   NavInspector.setVisible(false);
+
+   %actions = NavEditorOptionsWindow->ActionsBox;
+   %actions->SelectActions.setVisible(false);
+   %actions->LinkActions.setVisible(false);
+   %actions->CoverActions.setVisible(false);
+   %actions->TileActions.setVisible(false);
+   %actions->TestActions.setVisible(false);
+
+   %properties = NavEditorOptionsWindow->PropertiesBox;
+   %properties->LinkProperties.setVisible(false);
+   %properties->TileProperties.setVisible(false);
+   %properties->TestProperties.setVisible(false);
+
+   switch$(%mode)
+   {
+   case "SelectMode":
+      NavInspector.setVisible(true);
+      %actions->SelectActions.setVisible(true);
+   case "LinkMode":
+      %actions->LinkActions.setVisible(true);
+      %properties->LinkProperties.setVisible(true);
+   case "CoverMode":
+      // 
+      %actions->CoverActions.setVisible(true);
+   case "TileMode":
+      %actions->TileActions.setVisible(true);
+      %properties->TileProperties.setVisible(true);
+   case "TestMode":
+      %actions->TestActions.setVisible(true);
+      %properties->TestProperties.setVisible(true);
+   }
+}
+
+function NavEditorGui::paletteSync(%this, %mode)
+{
+   // Synchronise the palette (small buttons on the left) with the actual mode
+   // the nav editor is in.
+   %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);";
+   eval(%evalShortcut);
+} 
+
+function NavEditorGui::onEscapePressed(%this)
+{
+   return false;
+}
+
+function NavEditorGui::selectObject(%this, %obj)
+{
+   NavTreeView.clearSelection();
+   if(isObject(%obj))
+      NavTreeView.selectItem(%obj);
+   %this.onObjectSelected(%obj);
+}
+
+function NavEditorGui::onObjectSelected(%this, %obj)
+{
+   if(isObject(%this.selectedObject))
+      %this.deselect();
+   %this.selectedObject = %obj;
+   if(isObject(%obj))
+   {
+      %this.selectMesh(%obj);
+      NavInspector.inspect(%obj);
+   }
+}
+
+function NavEditorGui::deleteMesh(%this)
+{
+   if(isObject(%this.selectedObject))
+   {
+      %this.selectedObject.delete();
+      %this.selectObject(-1);
+   }
+}
+
+function NavEditorGui::deleteSelected(%this)
+{
+   switch$(%this.getMode())
+   {
+   case "SelectMode":
+      // Try to delete the selected NavMesh.
+      if(isObject(NavEditorGui.selectedObject))
+         MessageBoxYesNo("Warning",
+            "Are you sure you want to delete" SPC NavEditorGui.selectedObject.getName(),
+            "NavEditorGui.deleteMesh();");
+   case "TestMode":
+      %this.getPlayer().delete();
+      %this.onPlayerDeselected();
+   case "LinkMode":
+      %this.deleteLink();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::buildSelectedMeshes(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().build($Nav::Editor::backgroundBuild, $Nav::Editor::saveIntermediates);
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::buildLinks(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().buildLinks();
+      %this.isDirty = true;
+   }
+}
+
+function updateLinkData(%control, %flags)
+{
+   %control->LinkWalkFlag.setActive(true);
+   %control->LinkJumpFlag.setActive(true);
+   %control->LinkDropFlag.setActive(true);
+   %control->LinkLedgeFlag.setActive(true);
+   %control->LinkClimbFlag.setActive(true);
+   %control->LinkTeleportFlag.setActive(true);
+
+   %control->LinkWalkFlag.setStateOn(%flags & $Nav::WalkFlag);
+   %control->LinkJumpFlag.setStateOn(%flags & $Nav::JumpFlag);
+   %control->LinkDropFlag.setStateOn(%flags & $Nav::DropFlag);
+   %control->LinkLedgeFlag.setStateOn(%flags & $Nav::LedgeFlag);
+   %control->LinkClimbFlag.setStateOn(%flags & $Nav::ClimbFlag);
+   %control->LinkTeleportFlag.setStateOn(%flags & $Nav::TeleportFlag);
+}
+
+function getLinkFlags(%control)
+{
+   return (%control->LinkWalkFlag.isStateOn() ? $Nav::WalkFlag : 0) |
+          (%control->LinkJumpFlag.isStateOn() ? $Nav::JumpFlag : 0) |
+          (%control->LinkDropFlag.isStateOn() ? $Nav::DropFlag : 0) |
+          (%control->LinkLedgeFlag.isStateOn() ? $Nav::LedgeFlag : 0) |
+          (%control->LinkClimbFlag.isStateOn() ? $Nav::ClimbFlag : 0) |
+          (%control->LinkTeleportFlag.isStateOn() ? $Nav::TeleportFlag : 0);
+}
+
+function disableLinkData(%control)
+{
+   %control->LinkWalkFlag.setActive(false);
+   %control->LinkJumpFlag.setActive(false);
+   %control->LinkDropFlag.setActive(false);
+   %control->LinkLedgeFlag.setActive(false);
+   %control->LinkClimbFlag.setActive(false);
+   %control->LinkTeleportFlag.setActive(false);
+}
+
+function NavEditorGui::onLinkSelected(%this, %flags)
+{
+   updateLinkData(NavEditorOptionsWindow-->LinkProperties, %flags);
+}
+
+function NavEditorGui::onPlayerSelected(%this, %flags)
+{
+   updateLinkData(NavEditorOptionsWindow-->TestProperties, %flags);
+}
+
+function NavEditorGui::updateLinkFlags(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %properties = NavEditorOptionsWindow-->LinkProperties;
+      %this.setLinkFlags(getLinkFlags(%properties));
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::updateTestFlags(%this)
+{
+   if(isObject(%this.getPlayer()))
+   {
+      %properties = NavEditorOptionsWindow-->TestProperties;
+      %player = %this.getPlayer();
+
+      %player.allowWwalk = %properties->LinkWalkFlag.isStateOn();
+      %player.allowJump = %properties->LinkJumpFlag.isStateOn();
+      %player.allowDrop = %properties->LinkDropFlag.isStateOn();
+      %player.allowLedge = %properties->LinkLedgeFlag.isStateOn();
+      %player.allowClimb = %properties->LinkClimbFlag.isStateOn();
+      %player.allowTeleport = %properties->LinkTeleportFlag.isStateOn();
+
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::onLinkDeselected(%this)
+{
+   disableLinkData(NavEditorOptionsWindow-->LinkProperties);
+}
+
+function NavEditorGui::onPlayerDeselected(%this)
+{
+   disableLinkData(NavEditorOptionsWindow-->TestProperties);
+}
+
+function NavEditorGui::createCoverPoints(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().createCoverPoints();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::deleteCoverPoints(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().deleteCoverPoints();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::findCover(%this)
+{
+   if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer()))
+   {
+      %pos = LocalClientConnection.getControlObject().getPosition();
+      %text = NavEditorOptionsWindow-->TestProperties->CoverPosition.getText();
+      if(%text !$= "")
+         %pos = eval(%text);
+      %this.getPlayer().findCover(%pos, NavEditorOptionsWindow-->TestProperties->CoverRadius.getText());
+   }
+}
+
+function NavEditorGui::followObject(%this)
+{
+   if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer()))
+   {
+      %obj = LocalClientConnection.player;
+      %text = NavEditorOptionsWindow-->TestProperties->FollowObject.getText();
+      if(%text !$= "")
+      {
+         eval("%obj = " @ %text);
+         if(!isObject(%obj))
+            MessageBoxOk("Error", "Cannot find object" SPC %text);
+      }
+      if(isObject(%obj))
+         %this.getPlayer().followObject(%obj, NavEditorOptionsWindow-->TestProperties->FollowRadius.getText());
+   }
+}
+
+function NavInspector::inspect(%this, %obj)
+{
+   %name = "";
+   if(isObject(%obj))
+      %name = %obj.getName();
+   else
+      NavFieldInfoControl.setText("");
+
+   Parent::inspect(%this, %obj);
+}
+
+function NavInspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   // Same work to do as for the regular WorldEditor Inspector.
+   Inspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue);
+}
+
+function NavInspector::onFieldSelected(%this, %fieldName, %fieldTypeStr, %fieldDoc)
+{
+   NavFieldInfoControl.setText("<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc);
+}
+
+function NavTreeView::onInspect(%this, %obj)
+{
+   NavInspector.inspect(%obj);
+}
+
+function NavTreeView::onSelect(%this, %obj)
+{
+   NavInspector.inspect(%obj);
+   NavEditorGui.onObjectSelected(%obj);
+}
+
+function NavEditorGui::prepSelectionMode(%this)
+{
+   %this.setMode("SelectMode");
+   ToolsPaletteArray-->NavEditorSelectMode.setStateOn(1);
+}
+
+//-----------------------------------------------------------------------------
+
+function ENavEditorPaletteButton::onClick(%this)
+{
+   // When clicking on a pelette button, add its description to the bottom of
+   // the editor window.
+   EditorGuiStatusBar.setInfo(%this.DetailedDesc);
+}
+
+//-----------------------------------------------------------------------------
+
+function NavMeshLinkFlagButton::onClick(%this)
+{
+   NavEditorGui.updateLinkFlags();
+}
+
+function NavMeshTestFlagButton::onClick(%this)
+{
+   NavEditorGui.updateTestFlags();
+}

+ 130 - 0
Templates/Empty/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui

@@ -0,0 +1,130 @@
+%paletteId = new GuiControl(NavEditorPalette,EditorGuiGroup) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "GuiDefaultProfile";
+   HorizSizing = "right";
+   VertSizing = "bottom";
+   Position = "0 0";
+   Extent = "1024 768";
+   MinExtent = "8 2";
+   canSave = "1";
+   Visible = "1";
+   hovertime = "1000";
+   
+   new GuiBitmapButtonCtrl(ENavEditorSelectModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorSelectMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.prepSelectionMode();";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "View NavMesh (1).";
+      DetailedDesc = "";
+      hovertime = "1000";
+      bitmap = "tools/gui/images/menubar/visibility-toggle";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorLinkModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorLinkMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"LinkMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Create off-mesh links (2).";
+      DetailedDesc = "Click to select/add. Shift-click to add multiple end points.";
+      hovertime = "1000";
+      bitmap = "tools/navEditor/images/nav-link";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorCoverModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorCoverMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"CoverMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Edit cover (3).";
+      DetailedDesc = "";
+      hovertime = "1000";
+      bitmap = "tools/navEditor/images/nav-cover";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorTileModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorTileMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"TileMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "View tiles (4).";
+      DetailedDesc = "Click to select.";
+      hovertime = "1000";
+      bitmap = "tools/gui/images/menubar/select-bounds";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorTestModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorTestMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"TestMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Test pathfinding (5).";
+      DetailedDesc = "Click to select/move character, CTRL-click to spawn, SHIFT-click to deselect.";
+      hovertime = "1000";
+      bitmap = "tools/worldEditor/images/toolbar/3rd-person-camera";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+};

+ 1 - 3
Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs

@@ -83,8 +83,6 @@ function EWCreatorWindow::init( %this )
       %this.registerMissionObject( "SpawnSphere",  "Observer Spawn Sphere", "ObserverDropPoint" );
       %this.registerMissionObject( "SFXSpace",      "Sound Space" );
       %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" );
-      %this.registerMissionObject("NavMesh", "Navigation mesh");
-      %this.registerMissionObject("NavPath", "Path");
       
    %this.endGroup();
    
@@ -787,4 +785,4 @@ function genericCreateObject( %class )
    
    // In case the caller wants it.
    return %obj;   
-}
+}

+ 356 - 0
Templates/Full/game/tools/navEditor/CreateNewNavMeshDlg.gui

@@ -0,0 +1,356 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(CreateNewNavMeshDlg) {
+   position = "0 0";
+   extent = "1024 768";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiWindowCtrl() {
+      text = "New NavMesh";
+      resizeWidth = "0";
+      resizeHeight = "0";
+      canMove = "1";
+      canClose = "1";
+      canMinimize = "0";
+      canMaximize = "0";
+      canCollapse = "0";
+      closeCommand = "Canvas.popDialog(CreateNewNavMeshDlg);";
+      edgeSnap = "1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "283 240";
+      extent = "200 151";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiWindowProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiTextCtrl() {
+         text = "Name:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 29";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "Nav";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 30";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshName";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Position:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 51";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "0 0 0";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 52";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshPosition";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextCtrl() {
+         text = "Scale:";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "12 73";
+         extent = "39 21";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextRightProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiTextEditCtrl() {
+         historySize = "0";
+         tabComplete = "0";
+         sinkAllKeyEvents = "0";
+         password = "0";
+         passwordMask = "*";
+         text = "50 50 20";
+         maxLength = "1024";
+         margin = "0 0 0 0";
+         padding = "0 0 0 0";
+         anchorTop = "1";
+         anchorBottom = "0";
+         anchorLeft = "1";
+         anchorRight = "0";
+         position = "59 74";
+         extent = "129 18";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiTextEditProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         internalName = "MeshScale";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiCheckBoxCtrl() {
+         text = " Fit NavMesh to mission area?";
+         groupNum = "-1";
+         buttonType = "ToggleButton";
+         useMouseEvents = "0";
+         position = "22 99";
+         extent = "159 15";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiCheckBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         tooltip = "Positions and scales the NavMesh so it includes all your mission objects.";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "MeshMissionBounds";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Create!";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "12 121";
+         extent = "87 19";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "CreateNewNavMeshDlg.create();";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+      new GuiButtonCtrl() {
+         text = "Cancel";
+         groupNum = "-1";
+         buttonType = "PushButton";
+         useMouseEvents = "0";
+         position = "104 121";
+         extent = "84 19";
+         minExtent = "8 2";
+         horizSizing = "right";
+         vertSizing = "bottom";
+         profile = "GuiButtonProfile";
+         visible = "1";
+         active = "1";
+         command = "Canvas.popDialog(CreateNewNavMeshDlg);";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+
+function CreateNewNavMeshDlg::onWake(%this)
+{
+   %this-->MeshName.setText("Nav");
+   %this-->MeshPosition.setText("0 0 0");
+   %this-->MeshScale.setText("50 50 20");
+}
+
+function MissionBoundsExtents(%group)
+{
+   %box = "0 0 0 0 0 0";
+   foreach(%obj in %group)
+   {
+      // Skip LevelInfos. Need a way to detect other non-SceneObjects.
+      // Also skip GroundPlanes. They're too big.
+      %cls = %obj.getClassName();
+      if(%cls $= "LevelInfo" || %cls $= "GroundPlane" || %cls $= "GroundCover")
+         continue;
+
+      // Get world box - might have to recurse into nested SimGroups.
+      %wbox = "0 0 0 0 0 0";
+      if(%cls $= "SimGroup" || %cls $= "SimSet" || %cls $= "Path")
+         %wbox = MissionBoundsExtents(%obj);
+      else if(%obj.getType() & $TypeMasks::StaticObjectType &&
+         !(%obj.getType() & $TypeMasks::EnvironmentObjectType))
+         %wbox = %obj.getWorldBox();
+      else
+         continue;
+
+      // Update min point.
+      for(%j = 0; %j < 3; %j++)
+      {
+         if(GetWord(%box, %j) > GetWord(%wbox, %j))
+            %box = SetWord(%box, %j, GetWord(%wbox, %j));
+      }
+      // Update max point.
+      for(%j = 3; %j < 6; %j++)
+      {
+         if(GetWord(%box, %j) < GetWord(%wbox, %j))
+            %box = SetWord(%box, %j, GetWord(%wbox, %j));
+      }
+   }
+   return %box;
+}
+
+function CreateNewNavMeshDlg::create(%this)
+{
+   %name = %this-->MeshName.getText();
+   if(%name $= "" || nameToID(%name) != -1)
+   {
+      MessageBoxOk("Error", "A NavMesh must have a unique name!");
+      return;
+   }
+
+   %mesh = 0;
+
+   if(%this-->MeshMissionBounds.isStateOn())
+   {
+      if(!isObject(MissionGroup))
+      {
+         MessageBoxOk("Error", "You must have a MissionGroup to use the mission bounds function.");
+         return;
+      }
+      // Get maximum extents of all objects.
+      %box = MissionBoundsExtents(MissionGroup);
+      %pos = GetBoxCenter(%box);
+      %scale = (GetWord(%box, 3) - GetWord(%box, 0)) / 2 + 5
+         SPC (GetWord(%box, 4) - GetWord(%box, 1)) / 2 + 5
+         SPC (GetWord(%box, 5) - GetWord(%box, 2)) / 2 + 5;
+
+      %mesh = new NavMesh(%name)
+      {
+         position = %pos;
+         scale = %scale;
+      };
+   }
+   else
+   {
+      %mesh = new NavMesh(%name)
+      {
+         position = %this-->MeshPosition.getText();
+         scale = %this-->MeshScale.getText();
+      };
+   }
+   MissionGroup.add(%mesh);
+   NavEditorGui.selectObject(%mesh);
+
+   Canvas.popDialog(CreateNewNavMeshDlg);
+}

+ 169 - 0
Templates/Full/game/tools/navEditor/NavEditorConsoleDlg.gui

@@ -0,0 +1,169 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiWindowCtrl(NavEditorConsoleDlg) {
+   text = "Nav Console";
+   resizeWidth = "1";
+   resizeHeight = "1";
+   canMove = "1";
+   canClose = "1";
+   canMinimize = "1";
+   canMaximize = "1";
+   canCollapse = "0";
+   closeCommand = "NavEditorConsoleDlg.setVisible(false);";
+   edgeSnap = "1";
+   margin = "0 0 0 0";
+   padding = "0 0 0 0";
+   anchorTop = "1";
+   anchorBottom = "0";
+   anchorLeft = "1";
+   anchorRight = "0";
+   position = "238 170";
+   extent = "320 240";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiWindowProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiTextCtrl() {
+      maxLength = "1024";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "3 222";
+      extent = "149 13";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "top";
+      profile = "GuiTextProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "StatusLeft";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiScrollCtrl() {
+      willFirstRespond = "1";
+      hScrollBar = "dynamic";
+      vScrollBar = "dynamic";
+      lockHorizScroll = "1";
+      lockVertScroll = "0";
+      constantThumbHeight = "0";
+      childMargin = "0 0";
+      mouseWheelScrollSpeed = "-1";
+      margin = "-14 41 3 3";
+      padding = "0 0 0 0";
+      anchorTop = "0";
+      anchorBottom = "0";
+      anchorLeft = "0";
+      anchorRight = "0";
+      position = "3 23";
+      extent = "314 194";
+      minExtent = "8 2";
+      horizSizing = "relative";
+      vertSizing = "relative";
+      profile = "GuiEditorScrollProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      internalName = "OutputScroll";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiListBoxCtrl() {
+         allowMultipleSelections = "0";
+         fitParentWidth = "1";
+         colorBullet = "1";
+         position = "1 1";
+         extent = "312 16";
+         minExtent = "8 2";
+         horizSizing = "relative";
+         vertSizing = "relative";
+         profile = "GuiListBoxProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "0";
+         internalName = "Output";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+      };
+   };
+};
+//--- OBJECT WRITE END ---
+
+new ScriptMsgListener(NavEditorConsoleListener);
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshCreated");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshRemoved");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshStartUpdate");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshUpdate");
+getNavMeshEventManager().subscribe(NavEditorConsoleListener, "NavMeshTileUpdate");
+
+function NavEditorConsoleListener::onNavMeshCreated(%this, %data)
+{
+}
+
+function NavEditorConsoleListener::onNavMeshRemoved(%this, %data)
+{
+}
+
+function NavEditorConsoleListener::onNavMeshStartUpdate(%this, %data)
+{
+   NavEditorConsoleDlg-->Output.clearItems();
+   NavEditorConsoleDlg-->Output.addItem("Build starting for NavMesh" SPC %data, "0 0.6 0");
+   NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+}
+
+function NavEditorConsoleListener::onNavMeshUpdate(%this, %data)
+{
+   %message = "";
+   if(getWordCount(%data) == 2)
+   {
+      %seconds = getWord(%data, 1);
+      %minutes = mFloor(%seconds / 60);
+      %seconds -= %minutes * 60;
+      %message = "Built NavMesh" SPC getWord(%data, 0) SPC "in" SPC %minutes @ "m" SPC mRound(%seconds) @ "s";
+      if($Nav::Editor::playSoundWhenDone)
+      {
+         sfxPlayOnce(Audio2D, "tools/navEditor/done.wav");
+      }
+   }
+   else
+   {
+      %message = "Loaded NavMesh" SPC %data;
+   }
+   NavEditorConsoleDlg-->Output.addItem(%message, "0 0.6 0");
+   NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+   NavEditorConsoleDlg->StatusLeft.setText("");
+}
+
+function NavEditorConsoleListener::onNavMeshTileUpdate(%this, %data)
+{
+   %mesh = getWord(%data, 0);
+   %index = getWord(%data, 1);
+   %total = getWord(%data, 2);
+   %tile = getWords(%data, 3, 4);
+   %success = getWord(%data, 5) == "1";
+   if(!%success)
+   {
+      %message = "NavMesh" SPC %mesh SPC "tile" SPC %tile SPC "build failed!";
+      NavEditorConsoleDlg-->Output.addItem(%message, "1 0 0");
+      NavEditorConsoleDlg-->OutputScroll.scrollToBottom();
+   }
+   %percent = %index / %total * 100;
+   NavEditorConsoleDlg->StatusLeft.setText("Build progress:" SPC mRound(%percent) @ "%");
+}

+ 851 - 0
Templates/Full/game/tools/navEditor/NavEditorGui.gui

@@ -0,0 +1,851 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiNavEditorCtrl(NavEditorGui, EditorGuiGroup) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "NavEditorProfile";
+   HorizSizing = "width";
+   VertSizing = "height";
+   Position = "0 0";
+   Extent = "800 600";
+   MinExtent = "8 8";
+   canSave = "1";
+   Visible = "1";
+   tooltipprofile = "GuiToolTipProfile";
+   hovertime = "1000";
+   Docking = "None";
+   Margin = "0 0 0 0";
+   Padding = "0 0 0 0";
+   AnchorTop = "0";
+   AnchorBottom = "0";
+   AnchorLeft = "0";
+   AnchorRight = "0";
+   cameraZRot = "0";
+   forceFOV = "0";
+   renderMissionArea = "0";
+   missionAreaFillColor = "255 0 0 20";
+   missionAreaFrameColor = "255 0 0 128";
+   allowBorderMove = "0";
+   borderMovePixelSize = "20";
+   borderMoveSpeed = "0.1";
+   consoleFrameColor = "255 0 0 255";
+   consoleFillColor = "0 0 0 0";
+   consoleSphereLevel = "1";
+   consoleCircleSegments = "32";
+   consoleLineWidth = "1";
+   GizmoProfile = "GlobalGizmoProfile";
+
+   new GuiWindowCollapseCtrl(NavEditorTreeWindow) {
+      internalName = "";
+      canSaveDynamicFields = "0";
+      Enabled = "1";
+      isContainer = "1";
+      Profile = "GuiWindowProfile";
+      HorizSizing = "windowRelative";
+      VertSizing = "windowRelative";
+      Position = getWord($pref::Video::mode, 0) - 209
+         SPC getWord(EditorGuiToolbar.extent, 1) - 1;
+      Extent = "210 167";
+      MinExtent = "210 100";
+      canSave = "1";
+      isDecoy = "0";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      Margin = "0 0 0 0";
+      Padding = "0 0 0 0";
+      AnchorTop = "1";
+      AnchorBottom = "0";
+      AnchorLeft = "1";
+      AnchorRight = "0";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      EdgeSnap = "1";
+      text = "Navigation";
+
+      new GuiButtonCtrl() {
+         Profile = "GuiButtonProfile";
+         buttonType = "PushButton";
+         HorizSizing = "right";
+         VertSizing = "bottom";
+         position = "115 2";
+         extent = "90 18";
+         text = "New NavMesh";
+         command = "Canvas.pushDialog(CreateNewNavMeshDlg);";
+      };
+
+      new GuiContainer(){
+         profile = GuiDefaultProfile;
+         Position = "5 25";
+         Extent = "200 120";
+         Docking = "Client";
+         Margin = "3 1 3 3 ";
+         HorizSizing = "width";
+         VertSizing = "height";
+         isContainer = "1";
+         
+         new GuiScrollCtrl() {
+            canSaveDynamicFields = "0";
+            Enabled = "1";
+            isContainer = "1";
+            Profile = "GuiEditorScrollProfile";
+            HorizSizing = "width";
+            VertSizing = "height";
+            Position = "0 0";
+            Extent = "200 118";
+            MinExtent = "8 8";
+            canSave = "1";
+            isDecoy = "0";
+            Visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            Docking = "Client";
+            Margin = "0 0 0 0";
+            Padding = "0 0 0 0";
+            AnchorTop = "1";
+            AnchorBottom = "0";
+            AnchorLeft = "1";
+            AnchorRight = "0";
+            willFirstRespond = "1";
+            hScrollBar = "alwaysOff";
+            vScrollBar = "dynamic";
+            lockHorizScroll = "true";
+            lockVertScroll = "false";
+            constantThumbHeight = "0";
+            childMargin = "0 0";
+            mouseWheelScrollSpeed = "-1";
+
+            new GuiTreeViewCtrl(NavTreeView) {
+               canSaveDynamicFields = "0";
+               Enabled = "1";
+               isContainer = "1";
+               Profile = "ToolsGuiTreeViewProfile";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Position = "1 1";
+               Extent = "193 21";
+               MinExtent = "8 8";
+               canSave = "1";
+               Visible = "1";
+               hovertime = "1000";
+               tabSize = "16";
+               textOffset = "2";
+               fullRowSelect = "0";
+               itemHeight = "21";
+               destroyTreeOnSleep = "1";
+               MouseDragging = "0";
+               MultipleSelections = "0";
+               DeleteObjectAllowed = "1";
+               DragToItemAllowed = "0";
+               showRoot = "0";
+               internalNamesOnly = "0";
+            };
+         };
+      };
+   };
+   new GuiWindowCollapseCtrl(NavEditorOptionsWindow) {
+      internalName = "Window";
+      canSaveDynamicFields = "0";
+      Enabled = "1";
+      isContainer = "1";
+      Profile = "GuiWindowProfile";
+      HorizSizing = "windowRelative";
+      VertSizing = "windowRelative";
+      Position = getWord($pref::Video::mode, 0) - 209 
+         SPC getWord(EditorGuiToolbar.extent, 1) + getWord(NavEditorTreeWindow.extent, 1) - 2;
+      Extent = "210 530";
+      MinExtent = "210 300";
+      canSave = "1";
+      Visible = "1";
+      tooltipprofile = "GuiToolTipProfile";
+      hovertime = "1000";
+      Margin = "0 0 0 0";
+      Padding = "0 0 0 0";
+      AnchorTop = "0";
+      AnchorBottom = "0";
+      AnchorLeft = "0";
+      AnchorRight = "0";
+      resizeWidth = "1";
+      resizeHeight = "1";
+      canMove = "1";
+      canClose = "0";
+      canMinimize = "0";
+      canMaximize = "0";
+      minSize = "50 50";
+      EdgeSnap = "1";
+      text = "Properties";
+      
+      new GuiContainer(){ //Actions
+         isContainer = "1";
+         Profile = "inspectorStyleRolloutDarkProfile";
+         HorizSizing = "width";
+         VertSizing = "bottom";
+         Position = "4 24";
+         Extent = "202 85";
+         Docking = "Top";
+         Margin = "3 3 3 3";
+         internalName = "ActionsBox";
+         
+         new GuiTextCtrl(){
+            Profile = "GuiDefaultProfile";
+            HorizSizing = "right";
+            VertSizing = "bottom";
+            Position = "5 0";
+            Extent = "86 18";
+            text = "Actions";
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "SelectActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Build NavMesh";
+               command = "NavEditorGui.buildSelectedMeshes();";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "BackgroundBuildButton";
+               text = "Background";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "75 20";
+               minExtent = "8 2";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::backgroundBuild";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "SaveIntermediatesButton";
+               text = "Keep intermediates";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "105 20";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::saveIntermediates";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckboxCtrl() {
+               internalName = "BuildSoundButton";
+               text = "Play sound when done";
+               groupNum = "-1";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "150 20";
+               minExtent = "8 2";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               variable = "$Nav::Editor::playSoundWhenDone";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "LinkActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Rebuild links";
+               command = "NavEditorGui.buildLinks();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "CoverActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Create Cover";
+               command = "NavEditorGui.createCoverPoints();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Delete Cover";
+               command = "NavEditorGui.deleteCoverPoints();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TileActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "182 18";
+               text = "Rebuild tile";
+               command = "NavEditorGui.buildTile();";
+            };
+         };
+         new GuiFlexibleArrayControl()
+         {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TestActions";
+            position = "7 21";
+            extent = "190 64";
+            
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "180 18";
+               text = "Spawn";
+               command = "NavEditorGui.spawnPlayer();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Delete";
+               command = "NavEditorGui.getPlayer().delete();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Find cover";
+               command = "NavEditorGui.findCover();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Follow";
+               command = "NavEditorGui.followObject();";
+            };
+            new GuiButtonCtrl() {
+               Profile = "GuiButtonProfile";
+               buttonType = "PushButton";
+               HorizSizing = "right";
+               VertSizing = "bottom";
+               Extent = "90 18";
+               text = "Stop";
+               command = "NavEditorGui.getPlayer().stop();";
+            };
+         };
+      };
+      new GuiContainer(){
+         isContainer = "1";
+         Profile = "inspectorStyleRolloutDarkProfile";
+         HorizSizing = "width";
+         VertSizing = "bottom";
+         Position = "4 112";
+         Extent = "202 31";
+         Docking = "Top";
+         Margin = "0 0 3 3";
+         
+         new GuiTextCtrl(){
+            Profile = "GuiDefaultProfile";
+            HorizSizing = "right";
+            VertSizing = "bottom";
+            Position = "5 0";
+            Extent = "121 18";
+            text = "Properties";
+         };
+      };
+
+      new GuiScrollCtrl() {
+         canSaveDynamicFields = "0";
+         Enabled = "1";
+         isContainer = "1";
+         Profile = "GuiEditorScrollProfile";
+         HorizSizing = "width";
+         VertSizing = "height";
+         Position = "4 129";
+         Extent = "202 357";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         Docking = "Client";
+         Margin = "-14 41 3 3";
+         Padding = "0 0 0 0";
+         AnchorTop = "0";
+         AnchorBottom = "0";
+         AnchorLeft = "0";
+         AnchorRight = "0";
+         willFirstRespond = "1";
+         hScrollBar = "alwaysOff";
+         vScrollBar = "dynamic";
+         lockHorizScroll = "true";
+         lockVertScroll = "false";
+         constantThumbHeight = "0";
+         childMargin = "0 0";
+         internalName = "PropertiesBox";
+
+         new GuiInspector(NavInspector) {
+            StackingType = "Vertical";
+            HorizStacking = "Left to Right";
+            VertStacking = "Top to Bottom";
+            Padding = "1";
+            name = "NavInspector";
+            canSaveDynamicFields = "0";
+            Enabled = "1";
+            isContainer = "1";
+            Profile = "GuiTransparentProfile";
+            HorizSizing = "width";
+            VertSizing = "height";
+            Position = "1 1";
+            Extent = "178 16";
+            MinExtent = "16 16";
+            canSave = "1";
+            Visible = "1";
+            tooltipprofile = "GuiToolTipProfile";
+            hovertime = "1000";
+            dividerMargin = "5";
+         };
+         
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "LinkProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkWalkFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Walk";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "This link is just ordinary flat ground.";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkJumpFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Jump";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link require a jump?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkDropFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Drop";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link involve a significant drop?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkLedgeFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Ledge";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Should the character jump at the next ledge?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkClimbFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Climb";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Does this link involve climbing?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkTeleportFlag";
+			   class = "NavMeshLinkFlagButton";
+               text = " Teleport";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Is this link a teleporter?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TileProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+            new GuiCheckBoxCtrl() {
+               text = " Display input geometry";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+			   variable = "$Nav::Editor::renderInput";
+            };
+            new GuiCheckBoxCtrl() {
+               text = " Display voxels";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+			   variable = "$Nav::Editor::renderVoxels";
+            };
+         };
+         new GuiFlexibleArrayControl() {
+            colSpacing = 2;
+            rowSpacing = 2;
+            internalName = "TestProperties";
+            position = "7 21";
+            extent = "186 64";
+            padding = "2 2 2 2";
+            
+			new GuiTextCtrl() {
+			   text = "Cover";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiTextEditCtrl() {
+               internalName = "CoverRadius";
+               text = "10";
+               profile = "GuiTextEditProfile";
+               extent = "40 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Radius for cover-finding.";
+            };
+			new GuiTextEditCtrl() {
+               internalName = "CoverPosition";
+               text = "LocalClientConnection.getControlObject().getPosition();";
+               profile = "GuiTextEditProfile";
+               extent = "140 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Position to find cover from.";
+			};
+			new GuiTextCtrl() {
+			   text = "Follow";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiTextEditCtrl() {
+               internalName = "FollowRadius";
+               text = "1";
+               profile = "GuiTextEditProfile";
+               extent = "40 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Radius for following.";
+            };
+			new GuiTextEditCtrl() {
+               internalName = "FollowObject";
+               text = "LocalClientConnection.player";
+               profile = "GuiTextEditProfile";
+               extent = "140 20";
+               minExtent = "8 2";
+               visible = "1";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Object to follow.";
+			};
+			new GuiTextCtrl() {
+			   text = "Movement";
+               profile = "GuiTextProfile";
+               extent = "180 20";
+               minExtent = "8 2";
+               visible = "1";
+			};
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkWalkFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Walk";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character walk on ground?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkJumpFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Jump";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character jump?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkDropFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Drop";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character drop over edges?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkLedgeFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Ledge";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character jump from ledges?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkClimbFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Climb";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character climb?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+            new GuiCheckBoxCtrl() {
+			   internalName = "LinkTeleportFlag";
+			   class = "NavMeshTestFlagButton";
+               text = " Teleport";
+               buttonType = "ToggleButton";
+               useMouseEvents = "0";
+               extent = "159 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiCheckBoxProfile";
+               visible = "1";
+               active = "0";
+               tooltipProfile = "GuiToolTipProfile";
+			   toolTip = "Can this character teleport?";
+               hovertime = "1000";
+               isContainer = "0";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+            };
+         };
+      };
+      new GuiMLTextCtrl(NavFieldInfoControl) {
+         canSaveDynamicFields = "0";
+         Enabled = "1";
+         isContainer = "0";
+         Profile = "GuiInspectorFieldInfoMLTextProfile";
+         HorizSizing = "width";
+         VertSizing = "top";
+         Position = "1 485";
+         Extent = "202 42";
+         MinExtent = "8 2";
+         canSave = "1";
+         Visible = "1";
+         tooltipprofile = "GuiToolTipProfile";
+         hovertime = "1000";
+         lineSpacing = "2";
+         allowColorChars = "0";
+         maxChars = "-1";
+         useURLMouseCursor = "0";
+      };
+   };
+   
+};
+
+//--- OBJECT WRITE END ---

+ 506 - 0
Templates/Full/game/tools/navEditor/NavEditorSettingsTab.gui

@@ -0,0 +1,506 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiTabPageCtrl(ENavEditorSettingsPage) {
+   fitBook = "1";
+   text = "Navigation Editor";
+   maxLength = "1024";
+   margin = "0 0 0 0";
+   padding = "0 0 0 0";
+   anchorTop = "1";
+   anchorBottom = "0";
+   anchorLeft = "1";
+   anchorRight = "0";
+   position = "0 0";
+   extent = "208 292";
+   minExtent = "8 2";
+   horizSizing = "width";
+   vertSizing = "height";
+   profile = "GuiSolidDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+
+   new GuiScrollCtrl() {
+      willFirstRespond = "1";
+      hScrollBar = "alwaysOff";
+      vScrollBar = "dynamic";
+      lockHorizScroll = "1";
+      lockVertScroll = "0";
+      constantThumbHeight = "0";
+      childMargin = "0 0";
+      mouseWheelScrollSpeed = "-1";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "0 0";
+      extent = "208 292";
+      minExtent = "8 2";
+      horizSizing = "width";
+      vertSizing = "height";
+      profile = "GuiScrollProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+
+      new GuiStackControl() {
+         stackingType = "Vertical";
+         horizStacking = "Left to Right";
+         vertStacking = "Top to Bottom";
+         padding = "0";
+         dynamicSize = "1";
+         dynamicNonStackExtent = "0";
+         dynamicPos = "0";
+         changeChildSizeToFit = "1";
+         changeChildPosition = "1";
+         position = "1 1";
+         extent = "206 124";
+         minExtent = "8 2";
+         horizSizing = "width";
+         vertSizing = "bottom";
+         profile = "GuiDefaultProfile";
+         visible = "1";
+         active = "1";
+         tooltipProfile = "GuiToolTipProfile";
+         hovertime = "1000";
+         isContainer = "1";
+         canSave = "1";
+         canSaveDynamicFields = "0";
+
+         new GuiRolloutCtrl() {
+            caption = "Test spawn";
+            margin = "0 3 0 0";
+            defaultHeight = "40";
+            expanded = "1";
+            clickCollapse = "1";
+            hideHeader = "0";
+            autoCollapseSiblings = "0";
+            position = "0 0";
+            extent = "206 62";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiRolloutProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiStackControl() {
+               stackingType = "Vertical";
+               horizStacking = "Left to Right";
+               vertStacking = "Top to Bottom";
+               padding = "3";
+               dynamicSize = "1";
+               dynamicNonStackExtent = "0";
+               dynamicPos = "0";
+               changeChildSizeToFit = "1";
+               changeChildPosition = "1";
+               position = "0 20";
+               extent = "206 39";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiControl() {
+                  position = "0 0";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+
+                  new GuiTextCtrl() {
+                     text = "Spawn class:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "5 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+                  };
+                  new GuiPopUpMenuCtrlEx() {
+                     maxPopupHeight = "200";
+                     sbUsesNAColor = "0";
+                     reverseTextList = "0";
+                     bitmapBounds = "16 16";
+                     hotTrackCallback = "0";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "81 0";
+                     extent = "121 18";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiPopUpMenuProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "1";
+                     internalName = "SpawnClassOptions";
+                     class = "ESettingsWindowPopup";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                        editorSettingsRead = "NavEditorPlugin.readSettings();";
+                        editorSettingsValue = "NavEditor/SpawnClass";
+                        editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+                  };
+               };
+               new GuiControl() {
+                  position = "0 21";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  canSave = "1";
+                  canSaveDynamicFields = "0";
+
+                  new GuiTextCtrl() {
+                     text = "Datablock:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "5 1";
+                     extent = "70 18";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "0";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     text = "DefaultPlayerData";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "81 0";
+                     extent = "121 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     class = "ESettingsWindowTextEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                        editorSettingsRead = "NavEditorPlugin.readSettings();";
+                        editorSettingsValue = "NavEditor/SpawnDatablock";
+                        editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+                  };
+               };
+            };
+         };
+         new GuiRolloutCtrl() {
+            caption = "Colors";
+            margin = "0 3 0 0";
+            defaultHeight = "40";
+            expanded = "1";
+            clickCollapse = "1";
+            hideHeader = "0";
+            autoCollapseSiblings = "0";
+            position = "0 62";
+            extent = "206 62";
+            minExtent = "8 2";
+            horizSizing = "right";
+            vertSizing = "bottom";
+            profile = "GuiRolloutProfile";
+            visible = "1";
+            active = "1";
+            tooltipProfile = "GuiToolTipProfile";
+            hovertime = "1000";
+            isContainer = "1";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+
+            new GuiStackControl() {
+               stackingType = "Vertical";
+               horizStacking = "Left to Right";
+               vertStacking = "Top to Bottom";
+               padding = "3";
+               dynamicSize = "1";
+               dynamicNonStackExtent = "0";
+               dynamicPos = "0";
+               changeChildSizeToFit = "1";
+               changeChildPosition = "1";
+               position = "0 20";
+               extent = "206 39";
+               minExtent = "8 2";
+               horizSizing = "width";
+               vertSizing = "bottom";
+               profile = "GuiDefaultProfile";
+               visible = "1";
+               active = "1";
+               tooltipProfile = "GuiToolTipProfile";
+               hovertime = "1000";
+               isContainer = "1";
+               canSave = "1";
+               canSaveDynamicFields = "0";
+
+               new GuiControl() {
+                  position = "0 0";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  class = "ESettingsWindowColor";
+                  canSave = "1";
+                  canSaveDynamicFields = "1";
+                     editorSettingsRead = "NavEditorPlugin.readSettings();";
+                     editorSettingsValue = "NavEditor/HoverSplineColor";
+                     editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+
+                  new GuiTextCtrl() {
+                     text = "Hover Spline:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "80 0";
+                     extent = "104 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorEdit";
+                     class = "ESettingsWindowColorEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiSwatchButtonCtrl() {
+                     color = "0 0 0 0";
+                     groupNum = "-1";
+                     buttonType = "PushButton";
+                     useMouseEvents = "0";
+                     position = "188 2";
+                     extent = "14 14";
+                     minExtent = "8 2";
+                     horizSizing = "left";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorButton";
+                     class = "ESettingsWindowColorButton";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+               };
+               new GuiControl() {
+                  position = "0 21";
+                  extent = "206 18";
+                  minExtent = "8 2";
+                  horizSizing = "right";
+                  vertSizing = "bottom";
+                  profile = "GuiDefaultProfile";
+                  visible = "1";
+                  active = "1";
+                  tooltipProfile = "GuiToolTipProfile";
+                  hovertime = "1000";
+                  isContainer = "1";
+                  class = "ESettingsWindowColor";
+                  canSave = "1";
+                  canSaveDynamicFields = "1";
+                     editorSettingsRead = "NavEditorPlugin.readSettings();";
+                     editorSettingsValue = "NavEditor/SelectedSplineColor";
+                     editorSettingsWrite = "NavEditorPlugin.writeSettings();";
+
+                  new GuiTextCtrl() {
+                     text = "Sel. Spline:";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "0 1";
+                     extent = "70 16";
+                     minExtent = "8 2";
+                     horizSizing = "right";
+                     vertSizing = "bottom";
+                     profile = "GuiTextRightProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiTextEditCtrl() {
+                     historySize = "0";
+                     tabComplete = "0";
+                     sinkAllKeyEvents = "0";
+                     password = "0";
+                     passwordMask = "*";
+                     maxLength = "1024";
+                     margin = "0 0 0 0";
+                     padding = "0 0 0 0";
+                     anchorTop = "1";
+                     anchorBottom = "0";
+                     anchorLeft = "1";
+                     anchorRight = "0";
+                     position = "80 0";
+                     extent = "104 18";
+                     minExtent = "8 2";
+                     horizSizing = "width";
+                     vertSizing = "bottom";
+                     profile = "GuiTextEditProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorEdit";
+                     class = "ESettingsWindowColorEdit";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+                  new GuiSwatchButtonCtrl() {
+                     color = "0 0 0 0";
+                     groupNum = "-1";
+                     buttonType = "PushButton";
+                     useMouseEvents = "0";
+                     position = "188 2";
+                     extent = "14 14";
+                     minExtent = "8 2";
+                     horizSizing = "left";
+                     vertSizing = "bottom";
+                     profile = "GuiDefaultProfile";
+                     visible = "1";
+                     active = "1";
+                     tooltipProfile = "GuiToolTipProfile";
+                     hovertime = "1000";
+                     isContainer = "0";
+                     internalName = "ColorButton";
+                     class = "ESettingsWindowColorButton";
+                     canSave = "1";
+                     canSaveDynamicFields = "1";
+                  };
+               };
+            };
+         };
+      };
+   };
+};
+//--- OBJECT WRITE END ---

+ 144 - 0
Templates/Full/game/tools/navEditor/NavEditorToolbar.gui

@@ -0,0 +1,144 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(NavEditorToolbar,EditorGuiGroup) {
+   position = "306 0";
+   extent = "800 32";
+   minExtent = "8 2";
+   horizSizing = "right";
+   vertSizing = "bottom";
+   profile = "GuiDefaultProfile";
+   visible = "1";
+   active = "1";
+   tooltipProfile = "GuiToolTipProfile";
+   hovertime = "1000";
+   isContainer = "1";
+   internalName = "NavEditorToolbar";
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      enabled = "1";
+
+   new GuiTextCtrl() {
+      text = "Navigation Editor";
+      maxLength = "255";
+      margin = "0 0 0 0";
+      padding = "0 0 0 0";
+      anchorTop = "1";
+      anchorBottom = "0";
+      anchorLeft = "1";
+      anchorRight = "0";
+      position = "6 6";
+      extent = "150 20";
+      minExtent = "8 8";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiTextProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "1";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiBitmapCtrl() {
+      bitmap = "core/art/gui/images/separator-h.png";
+      wrap = "0";
+      position = "90 3";
+      extent = "2 26";
+      minExtent = "1 1";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiDefaultProfile";
+      visible = "1";
+      active = "1";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiButtonCtrl(NavEditorAboutBtn) {
+      text = "Console";
+      groupNum = "7";
+      buttonType = "PushButton";
+      useMouseEvents = "0";
+      position = "100 6";
+      extent = "54 20";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiButtonProfile";
+      visible = "1";
+      active = "1";
+      command = "NavEditorConsoleDlg.setVisible(!NavEditorConsoleDlg.isVisible());";
+      tooltipProfile = "GuiToolTipProfile";
+      tooltip = "Show Console";
+      hovertime = "1000";
+      isContainer = "0";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "Mesh";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "167 1";
+      extent = "50 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderMesh";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "MeshButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "Portals";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "224 1";
+      extent = "54 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderPortals";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "PortalButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+   new GuiCheckBoxCtrl() {
+      text = "BV tree";
+      groupNum = "-1";
+      buttonType = "ToggleButton";
+      useMouseEvents = "0";
+      position = "286 1";
+      extent = "140 30";
+      minExtent = "8 2";
+      horizSizing = "right";
+      vertSizing = "bottom";
+      profile = "GuiCheckBoxProfile";
+      visible = "1";
+      active = "1";
+      variable = "$Nav::Editor::renderBVTree";
+      tooltipProfile = "GuiToolTipProfile";
+      hovertime = "1000";
+      isContainer = "0";
+      internalName = "BVTreeButton";
+      canSave = "1";
+      canSaveDynamicFields = "0";
+   };
+};
+//--- OBJECT WRITE END ---

BIN
Templates/Full/game/tools/navEditor/done.wav


BIN
Templates/Full/game/tools/navEditor/images/nav-cover_d.png


BIN
Templates/Full/game/tools/navEditor/images/nav-cover_h.png


BIN
Templates/Full/game/tools/navEditor/images/nav-cover_n.png


BIN
Templates/Full/game/tools/navEditor/images/nav-editor_d.png


BIN
Templates/Full/game/tools/navEditor/images/nav-editor_h.png


BIN
Templates/Full/game/tools/navEditor/images/nav-editor_n.png


BIN
Templates/Full/game/tools/navEditor/images/nav-link_d.png


BIN
Templates/Full/game/tools/navEditor/images/nav-link_h.png


BIN
Templates/Full/game/tools/navEditor/images/nav-link_n.png


+ 276 - 0
Templates/Full/game/tools/navEditor/main.cs

@@ -0,0 +1,276 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// These values should align with enum PolyFlags in walkabout/nav.h
+$Nav::WalkFlag = 1 << 0;
+$Nav::SwimFlag = 1 << 1;
+$Nav::JumpFlag = 1 << 2;
+$Nav::LedgeFlag = 1 << 3;
+$Nav::DropFlag = 1 << 4;
+$Nav::ClimbFlag = 1 << 5;
+$Nav::TeleportFlag = 1 << 6;
+
+function initializeNavEditor()
+{
+   echo(" % - Initializing Navigation Editor");
+
+   // Execute all relevant scripts and GUIs.
+   exec("./NavEditor.cs");
+   exec("./NavEditorGui.gui");
+   exec("./NavEditorToolbar.gui");
+   exec("./NavEditorGui.cs");
+   exec("./NavEditorAboutDlg.gui");
+   exec("./NavEditorConsoleDlg.gui");
+   exec("./CreateNewNavMeshDlg.gui");
+
+   // Add ourselves to EditorGui, where all the other tools reside
+   NavEditorGui.setVisible(false);  
+   NavEditorToolbar.setVisible(false); 
+   NavEditorOptionsWindow.setVisible(false);
+   NavEditorTreeWindow.setVisible(false);
+   NavEditorConsoleDlg.setVisible(false);
+
+   EditorGui.add(NavEditorGui);
+   EditorGui.add(NavEditorToolbar);
+   EditorGui.add(NavEditorOptionsWindow);
+   EditorGui.add(NavEditorTreeWindow);
+   EditorGui.add(NavEditorConsoleDlg);
+
+   new ScriptObject(NavEditorPlugin)
+   {
+      superClass = "EditorPlugin";
+      editorGui = NavEditorGui;
+   };
+
+   // Bind shortcuts for the nav editor.
+   %map = new ActionMap();
+   %map.bindCmd(keyboard, "1", "ENavEditorSelectModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "2", "ENavEditorLinkModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "3", "ENavEditorCoverModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "4", "ENavEditorTileModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "5", "ENavEditorTestModeBtn.performClick();", "");
+   %map.bindCmd(keyboard, "c", "NavEditorConsoleBtn.performClick();", "");
+   NavEditorPlugin.map = %map;
+
+   NavEditorPlugin.initSettings();
+}
+
+function destroyNavEditor()
+{
+}
+
+function NavEditorPlugin::onWorldEditorStartup(%this)
+{    
+    // Add ourselves to the window menu.
+   %accel = EditorGui.addToEditorsMenu("Navigation Editor", "", NavEditorPlugin);   
+
+   // Add ourselves to the ToolsToolbar.
+   %tooltip = "Navigation Editor (" @ %accel @ ")";   
+   EditorGui.addToToolsToolbar("NavEditorPlugin", "NavEditorPalette", expandFilename("tools/navEditor/images/nav-editor"), %tooltip);
+
+   GuiWindowCtrl::attach(NavEditorOptionsWindow, NavEditorTreeWindow);
+
+   // Add ourselves to the Editor Settings window.
+   exec("./NavEditorSettingsTab.gui");
+   ESettingsWindow.addTabPage(ENavEditorSettingsPage);
+   ENavEditorSettingsPage.init();
+
+   // Add items to World Editor Creator
+   EWCreatorWindow.beginGroup("Navigation");
+
+      EWCreatorWindow.registerMissionObject("NavMesh", "Navigation mesh");
+      EWCreatorWindow.registerMissionObject("NavPath", "Path");
+      EWCreatorWindow.registerMissionObject("CoverPoint", "Cover point");
+
+   EWCreatorWindow.endGroup();
+}
+
+function ENavEditorSettingsPage::init(%this)
+{
+   // Initialises the settings controls in the settings dialog box.
+   %this-->SpawnClassOptions.clear();
+   %this-->SpawnClassOptions.add("AIPlayer");
+   %this-->SpawnClassOptions.setFirstSelected();
+}
+
+function NavEditorPlugin::onActivated(%this)
+{
+   %this.readSettings();
+
+   // Set a global variable so everyone knows we're editing!
+   $Nav::EditorOpen = true;
+
+   // Start off in Select mode.
+   ToolsPaletteArray->NavEditorSelectMode.performClick();
+   EditorGui.bringToFront(NavEditorGui);
+
+   NavEditorGui.setVisible(true);
+   NavEditorGui.makeFirstResponder(true);
+   NavEditorToolbar.setVisible(true);
+
+   NavEditorOptionsWindow.setVisible(true);
+   NavEditorTreeWindow.setVisible(true);
+
+   // Inspect the ServerNavMeshSet, which contains all the NavMesh objects
+   // in the mission.
+   if(!isObject(ServerNavMeshSet))
+      new SimSet(ServerNavMeshSet);
+   if(ServerNavMeshSet.getCount() == 0)
+	  MessageBoxYesNo("No NavMesh", "There is no NavMesh in this level. Would you like to create one?" SPC
+	                                "If not, please use the World Editor to create a new NavMesh.",
+	                                "Canvas.pushDialog(CreateNewNavMeshDlg);");
+   NavTreeView.open(ServerNavMeshSet, true);
+
+   // Push our keybindings to the top. (See initializeNavEditor for where this
+   // map was created.)
+   %this.map.push();
+
+   // Store this on a dynamic field
+   // in order to restore whatever setting
+   // the user had before.
+   %this.prevGizmoAlignment = GlobalGizmoProfile.alignment;
+
+   // Always use Object alignment.
+   GlobalGizmoProfile.alignment = "Object";
+
+   // Set the status bar here until all tool have been hooked up
+   EditorGuiStatusBar.setInfo("Navigation editor.");
+   EditorGuiStatusBar.setSelection("");
+
+   // Allow the Gui to setup.
+   NavEditorGui.onEditorActivated(); 
+
+   Parent::onActivated(%this);
+}
+
+function NavEditorPlugin::onDeactivated(%this)
+{
+   %this.writeSettings();
+
+   $Nav::EditorOpen = false;   
+
+   NavEditorGui.setVisible(false);
+   NavEditorToolbar.setVisible(false);
+   NavEditorOptionsWindow.setVisible(false);
+   NavEditorTreeWindow.setVisible(false);
+   %this.map.pop();
+
+   // Restore the previous Gizmo alignment settings.
+   GlobalGizmoProfile.alignment = %this.prevGizmoAlignment;  
+
+   // Allow the Gui to cleanup.
+   NavEditorGui.onEditorDeactivated(); 
+
+   Parent::onDeactivated(%this);
+}
+
+function NavEditorPlugin::onEditMenuSelect(%this, %editMenu)
+{
+   %hasSelection = false;
+}
+
+function NavEditorPlugin::handleDelete(%this)
+{
+   // Event happens when the user hits 'delete'.
+   NavEditorGui.deleteSelected();
+}
+
+function NavEditorPlugin::handleEscape(%this)
+{
+   return NavEditorGui.onEscapePressed();  
+}
+
+function NavEditorPlugin::isDirty(%this)
+{
+   return NavEditorGui.isDirty;
+}
+
+function NavEditorPlugin::onSaveMission(%this, %missionFile)
+{
+   if(NavEditorGui.isDirty)
+   {
+      MissionGroup.save(%missionFile);
+      NavEditorGui.isDirty = false;
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Settings
+//-----------------------------------------------------------------------------
+
+function NavEditorPlugin::initSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   EditorSettings.setDefaultValue("SpawnClass",     "AIPlayer");
+   EditorSettings.setDefaultValue("SpawnDatablock", "DefaultPlayerData");
+
+   EditorSettings.endGroup();
+}
+
+function NavEditorPlugin::readSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   NavEditorGui.spawnClass     = EditorSettings.value("SpawnClass");
+   NavEditorGui.spawnDatablock = EditorSettings.value("SpawnDatablock");
+
+   EditorSettings.endGroup();  
+}
+
+function NavEditorPlugin::writeSettings(%this)
+{
+   EditorSettings.beginGroup("NavEditor", true);
+
+   EditorSettings.setValue("SpawnClass",     NavEditorGui.spawnClass);
+   EditorSettings.setValue("SpawnDatablock", NavEditorGui.spawnDatablock);
+
+   EditorSettings.endGroup();
+}
+
+function ESettingsWindowPopup::onWake(%this)
+{
+   %this.setSelected(%this.findText(EditorSettings.value(%this.editorSettingsValue)));
+}
+
+function ESettingsWindowPopup::onSelect(%this)
+{
+   EditorSettings.setValue(%this.editorSettingsValue, %this.getText());
+   eval(%this.editorSettingsRead);
+}
+
+//-----------------------------------------------------------------------------
+// Demo
+//-----------------------------------------------------------------------------
+
+function OnWalkaboutDemoLimit()
+{
+   MessageBoxOK("Walkabout demo",
+      "This demo only allows two NavMeshes to be created. Sorry!");
+}
+
+function OnWalkaboutDemoSave()
+{
+   MessageBoxOK("Walkabout demo",
+      "This demo doesn't allow you to save NavMeshes. Sorry!" SPC
+      "The rest of your mission will still be saved.");
+}

+ 37 - 0
Templates/Full/game/tools/navEditor/navEditor.cs

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+singleton GuiControlProfile(NavEditorProfile)
+{
+   canKeyFocus = true;
+   opaque = true;
+   fillColor = "192 192 192 192";
+   category = "Editor";
+};
+
+singleton GuiControlProfile(GuiSimpleBorderProfile)
+{
+   opaque = false;   
+   border = 1;   
+   category = "Editor";
+};
+ 

+ 351 - 0
Templates/Full/game/tools/navEditor/navEditorGui.cs

@@ -0,0 +1,351 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 Daniel Buckmaster
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+$Nav::EditorOpen = false;
+$Nav::Editor::renderMesh = true;
+$Nav::Editor::renderPortals = false;
+$Nav::Editor::renderBVTree = false;
+$Nav::Editor::backgroundBuild = true;
+$Nav::Editor::saveIntermediates = false;
+$Nav::Editor::playSoundWhenDone = false;
+
+function NavEditorGui::onEditorActivated(%this)
+{
+   if(%this.selectedObject)
+      %this.selectObject(%this.selectedObject);
+   %this.prepSelectionMode();
+}
+
+function NavEditorGui::onEditorDeactivated(%this)
+{
+   if(%this.getMesh())
+      %this.deselect();
+}
+
+function NavEditorGui::onModeSet(%this, %mode)
+{
+   // Callback when the nav editor changes mode. Set the appropriate dynamic
+   // GUI contents in the properties/actions boxes.
+   NavInspector.setVisible(false);
+
+   %actions = NavEditorOptionsWindow->ActionsBox;
+   %actions->SelectActions.setVisible(false);
+   %actions->LinkActions.setVisible(false);
+   %actions->CoverActions.setVisible(false);
+   %actions->TileActions.setVisible(false);
+   %actions->TestActions.setVisible(false);
+
+   %properties = NavEditorOptionsWindow->PropertiesBox;
+   %properties->LinkProperties.setVisible(false);
+   %properties->TileProperties.setVisible(false);
+   %properties->TestProperties.setVisible(false);
+
+   switch$(%mode)
+   {
+   case "SelectMode":
+      NavInspector.setVisible(true);
+      %actions->SelectActions.setVisible(true);
+   case "LinkMode":
+      %actions->LinkActions.setVisible(true);
+      %properties->LinkProperties.setVisible(true);
+   case "CoverMode":
+      // 
+      %actions->CoverActions.setVisible(true);
+   case "TileMode":
+      %actions->TileActions.setVisible(true);
+      %properties->TileProperties.setVisible(true);
+   case "TestMode":
+      %actions->TestActions.setVisible(true);
+      %properties->TestProperties.setVisible(true);
+   }
+}
+
+function NavEditorGui::paletteSync(%this, %mode)
+{
+   // Synchronise the palette (small buttons on the left) with the actual mode
+   // the nav editor is in.
+   %evalShortcut = "ToolsPaletteArray-->" @ %mode @ ".setStateOn(1);";
+   eval(%evalShortcut);
+} 
+
+function NavEditorGui::onEscapePressed(%this)
+{
+   return false;
+}
+
+function NavEditorGui::selectObject(%this, %obj)
+{
+   NavTreeView.clearSelection();
+   if(isObject(%obj))
+      NavTreeView.selectItem(%obj);
+   %this.onObjectSelected(%obj);
+}
+
+function NavEditorGui::onObjectSelected(%this, %obj)
+{
+   if(isObject(%this.selectedObject))
+      %this.deselect();
+   %this.selectedObject = %obj;
+   if(isObject(%obj))
+   {
+      %this.selectMesh(%obj);
+      NavInspector.inspect(%obj);
+   }
+}
+
+function NavEditorGui::deleteMesh(%this)
+{
+   if(isObject(%this.selectedObject))
+   {
+      %this.selectedObject.delete();
+      %this.selectObject(-1);
+   }
+}
+
+function NavEditorGui::deleteSelected(%this)
+{
+   switch$(%this.getMode())
+   {
+   case "SelectMode":
+      // Try to delete the selected NavMesh.
+      if(isObject(NavEditorGui.selectedObject))
+         MessageBoxYesNo("Warning",
+            "Are you sure you want to delete" SPC NavEditorGui.selectedObject.getName(),
+            "NavEditorGui.deleteMesh();");
+   case "TestMode":
+      %this.getPlayer().delete();
+      %this.onPlayerDeselected();
+   case "LinkMode":
+      %this.deleteLink();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::buildSelectedMeshes(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().build($Nav::Editor::backgroundBuild, $Nav::Editor::saveIntermediates);
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::buildLinks(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().buildLinks();
+      %this.isDirty = true;
+   }
+}
+
+function updateLinkData(%control, %flags)
+{
+   %control->LinkWalkFlag.setActive(true);
+   %control->LinkJumpFlag.setActive(true);
+   %control->LinkDropFlag.setActive(true);
+   %control->LinkLedgeFlag.setActive(true);
+   %control->LinkClimbFlag.setActive(true);
+   %control->LinkTeleportFlag.setActive(true);
+
+   %control->LinkWalkFlag.setStateOn(%flags & $Nav::WalkFlag);
+   %control->LinkJumpFlag.setStateOn(%flags & $Nav::JumpFlag);
+   %control->LinkDropFlag.setStateOn(%flags & $Nav::DropFlag);
+   %control->LinkLedgeFlag.setStateOn(%flags & $Nav::LedgeFlag);
+   %control->LinkClimbFlag.setStateOn(%flags & $Nav::ClimbFlag);
+   %control->LinkTeleportFlag.setStateOn(%flags & $Nav::TeleportFlag);
+}
+
+function getLinkFlags(%control)
+{
+   return (%control->LinkWalkFlag.isStateOn() ? $Nav::WalkFlag : 0) |
+          (%control->LinkJumpFlag.isStateOn() ? $Nav::JumpFlag : 0) |
+          (%control->LinkDropFlag.isStateOn() ? $Nav::DropFlag : 0) |
+          (%control->LinkLedgeFlag.isStateOn() ? $Nav::LedgeFlag : 0) |
+          (%control->LinkClimbFlag.isStateOn() ? $Nav::ClimbFlag : 0) |
+          (%control->LinkTeleportFlag.isStateOn() ? $Nav::TeleportFlag : 0);
+}
+
+function disableLinkData(%control)
+{
+   %control->LinkWalkFlag.setActive(false);
+   %control->LinkJumpFlag.setActive(false);
+   %control->LinkDropFlag.setActive(false);
+   %control->LinkLedgeFlag.setActive(false);
+   %control->LinkClimbFlag.setActive(false);
+   %control->LinkTeleportFlag.setActive(false);
+}
+
+function NavEditorGui::onLinkSelected(%this, %flags)
+{
+   updateLinkData(NavEditorOptionsWindow-->LinkProperties, %flags);
+}
+
+function NavEditorGui::onPlayerSelected(%this, %flags)
+{
+   updateLinkData(NavEditorOptionsWindow-->TestProperties, %flags);
+}
+
+function NavEditorGui::updateLinkFlags(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %properties = NavEditorOptionsWindow-->LinkProperties;
+      %this.setLinkFlags(getLinkFlags(%properties));
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::updateTestFlags(%this)
+{
+   if(isObject(%this.getPlayer()))
+   {
+      %properties = NavEditorOptionsWindow-->TestProperties;
+      %player = %this.getPlayer();
+
+      %player.allowWwalk = %properties->LinkWalkFlag.isStateOn();
+      %player.allowJump = %properties->LinkJumpFlag.isStateOn();
+      %player.allowDrop = %properties->LinkDropFlag.isStateOn();
+      %player.allowLedge = %properties->LinkLedgeFlag.isStateOn();
+      %player.allowClimb = %properties->LinkClimbFlag.isStateOn();
+      %player.allowTeleport = %properties->LinkTeleportFlag.isStateOn();
+
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::onLinkDeselected(%this)
+{
+   disableLinkData(NavEditorOptionsWindow-->LinkProperties);
+}
+
+function NavEditorGui::onPlayerDeselected(%this)
+{
+   disableLinkData(NavEditorOptionsWindow-->TestProperties);
+}
+
+function NavEditorGui::createCoverPoints(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().createCoverPoints();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::deleteCoverPoints(%this)
+{
+   if(isObject(%this.getMesh()))
+   {
+      %this.getMesh().deleteCoverPoints();
+      %this.isDirty = true;
+   }
+}
+
+function NavEditorGui::findCover(%this)
+{
+   if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer()))
+   {
+      %pos = LocalClientConnection.getControlObject().getPosition();
+      %text = NavEditorOptionsWindow-->TestProperties->CoverPosition.getText();
+      if(%text !$= "")
+         %pos = eval(%text);
+      %this.getPlayer().findCover(%pos, NavEditorOptionsWindow-->TestProperties->CoverRadius.getText());
+   }
+}
+
+function NavEditorGui::followObject(%this)
+{
+   if(%this.getMode() $= "TestMode" && isObject(%this.getPlayer()))
+   {
+      %obj = LocalClientConnection.player;
+      %text = NavEditorOptionsWindow-->TestProperties->FollowObject.getText();
+      if(%text !$= "")
+      {
+         eval("%obj = " @ %text);
+         if(!isObject(%obj))
+            MessageBoxOk("Error", "Cannot find object" SPC %text);
+      }
+      if(isObject(%obj))
+         %this.getPlayer().followObject(%obj, NavEditorOptionsWindow-->TestProperties->FollowRadius.getText());
+   }
+}
+
+function NavInspector::inspect(%this, %obj)
+{
+   %name = "";
+   if(isObject(%obj))
+      %name = %obj.getName();
+   else
+      NavFieldInfoControl.setText("");
+
+   Parent::inspect(%this, %obj);
+}
+
+function NavInspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue)
+{
+   // Same work to do as for the regular WorldEditor Inspector.
+   Inspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue);
+}
+
+function NavInspector::onFieldSelected(%this, %fieldName, %fieldTypeStr, %fieldDoc)
+{
+   NavFieldInfoControl.setText("<font:ArialBold:14>" @ %fieldName @ "<font:ArialItalic:14> (" @ %fieldTypeStr @ ") " NL "<font:Arial:14>" @ %fieldDoc);
+}
+
+function NavTreeView::onInspect(%this, %obj)
+{
+   NavInspector.inspect(%obj);
+}
+
+function NavTreeView::onSelect(%this, %obj)
+{
+   NavInspector.inspect(%obj);
+   NavEditorGui.onObjectSelected(%obj);
+}
+
+function NavEditorGui::prepSelectionMode(%this)
+{
+   %this.setMode("SelectMode");
+   ToolsPaletteArray-->NavEditorSelectMode.setStateOn(1);
+}
+
+//-----------------------------------------------------------------------------
+
+function ENavEditorPaletteButton::onClick(%this)
+{
+   // When clicking on a pelette button, add its description to the bottom of
+   // the editor window.
+   EditorGuiStatusBar.setInfo(%this.DetailedDesc);
+}
+
+//-----------------------------------------------------------------------------
+
+function NavMeshLinkFlagButton::onClick(%this)
+{
+   NavEditorGui.updateLinkFlags();
+}
+
+function NavMeshTestFlagButton::onClick(%this)
+{
+   NavEditorGui.updateTestFlags();
+}

+ 130 - 0
Templates/Full/game/tools/worldEditor/gui/ToolsPaletteGroups/NavEditorPalette.ed.gui

@@ -0,0 +1,130 @@
+%paletteId = new GuiControl(NavEditorPalette,EditorGuiGroup) {
+   canSaveDynamicFields = "0";
+   Enabled = "1";
+   isContainer = "1";
+   Profile = "GuiDefaultProfile";
+   HorizSizing = "right";
+   VertSizing = "bottom";
+   Position = "0 0";
+   Extent = "1024 768";
+   MinExtent = "8 2";
+   canSave = "1";
+   Visible = "1";
+   hovertime = "1000";
+   
+   new GuiBitmapButtonCtrl(ENavEditorSelectModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorSelectMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.prepSelectionMode();";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "View NavMesh (1).";
+      DetailedDesc = "";
+      hovertime = "1000";
+      bitmap = "tools/gui/images/menubar/visibility-toggle";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorLinkModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorLinkMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"LinkMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Create off-mesh links (2).";
+      DetailedDesc = "Click to select/add. Shift-click to add multiple end points.";
+      hovertime = "1000";
+      bitmap = "tools/navEditor/images/nav-link";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorCoverModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorCoverMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"CoverMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Edit cover (3).";
+      DetailedDesc = "";
+      hovertime = "1000";
+      bitmap = "tools/navEditor/images/nav-cover";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorTileModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorTileMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"TileMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "View tiles (4).";
+      DetailedDesc = "Click to select.";
+      hovertime = "1000";
+      bitmap = "tools/gui/images/menubar/select-bounds";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+   new GuiBitmapButtonCtrl(ENavEditorTestModeBtn) {
+      canSaveDynamicFields = "1";
+      class = ENavEditorPaletteButton;
+      internalName = "NavEditorTestMode";
+      Enabled = "1";
+      isContainer = "0";
+      Profile = "GuiButtonProfile";
+      HorizSizing = "right";
+      VertSizing = "bottom";
+      Position = "0 0";
+      Extent = "25 19";
+      MinExtent = "8 2";
+      canSave = "1";
+      Visible = "1";
+      Command = "NavEditorGui.setMode(\"TestMode\");";
+      tooltipprofile = "GuiToolTipProfile";
+      ToolTip = "Test pathfinding (5).";
+      DetailedDesc = "Click to select/move character, CTRL-click to spawn, SHIFT-click to deselect.";
+      hovertime = "1000";
+      bitmap = "tools/worldEditor/images/toolbar/3rd-person-camera";
+      buttonType = "RadioButton";
+      useMouseEvents = "0";
+   };
+};

+ 1 - 3
Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs

@@ -83,8 +83,6 @@ function EWCreatorWindow::init( %this )
       %this.registerMissionObject( "SpawnSphere",  "Observer Spawn Sphere", "ObserverDropPoint" );
       %this.registerMissionObject( "SFXSpace",      "Sound Space" );
       %this.registerMissionObject( "OcclusionVolume", "Occlusion Volume" );
-      %this.registerMissionObject("NavMesh", "Navigation mesh");
-      %this.registerMissionObject("NavPath", "Path");
       
    %this.endGroup();
    
@@ -787,4 +785,4 @@ function genericCreateObject( %class )
    
    // In case the caller wants it.
    return %obj;   
-}
+}