//----------------------------------------------------------------------------- // Torque Game Engine // // Copyright (c) 2001 GarageGames.Com //----------------------------------------------------------------------------- function EditorGui::getPrefs() { EWorldEditor.dropType = getPrefSetting($Pref::WorldEditor::dropType, "atCamera"); // same defaults as WorldEditor ctor EWorldEditor.planarMovement = getPrefSetting($pref::WorldEditor::planarMovement, true); EWorldEditor.undoLimit = getPrefSetting($pref::WorldEditor::undoLimit, 40); EWorldEditor.dropType = getPrefSetting($pref::WorldEditor::dropType, "screenCenter"); EWorldEditor.projectDistance = getPrefSetting($pref::WorldEditor::projectDistance, 2000); EWorldEditor.boundingBoxCollision = getPrefSetting($pref::WorldEditor::boundingBoxCollision, true); EWorldEditor.renderPlane = getPrefSetting($pref::WorldEditor::renderPlane, true); EWorldEditor.renderPlaneHashes = getPrefSetting($pref::WorldEditor::renderPlaneHashes, true); EWorldEditor.gridColor = getPrefSetting($pref::WorldEditor::gridColor, "255 255 255 20"); EWorldEditor.planeDim = getPrefSetting($pref::WorldEditor::planeDim, 500); EWorldEditor.gridSize = getPrefSetting($pref::WorldEditor::gridSize, "10 10 10"); EWorldEditor.renderPopupBackground = getPrefSetting($pref::WorldEditor::renderPopupBackground, true); EWorldEditor.popupBackgroundColor = getPrefSetting($pref::WorldEditor::popupBackgroundColor, "100 100 100"); EWorldEditor.popupTextColor = getPrefSetting($pref::WorldEditor::popupTextColor, "255 255 0"); EWorldEditor.selectHandle = getPrefSetting($pref::WorldEditor::selectHandle, "gui/Editor_SelectHandle.png"); EWorldEditor.defaultHandle = getPrefSetting($pref::WorldEditor::defaultHandle, "gui/Editor_DefaultHandle.png"); EWorldEditor.lockedHandle = getPrefSetting($pref::WorldEditor::lockedHandle, "gui/Editor_LockedHandle.png"); EWorldEditor.objectTextColor = getPrefSetting($pref::WorldEditor::objectTextColor, "255 255 255"); EWorldEditor.objectsUseBoxCenter = getPrefSetting($pref::WorldEditor::objectsUseBoxCenter, true); EWorldEditor.axisGizmoMaxScreenLen = getPrefSetting($pref::WorldEditor::axisGizmoMaxScreenLen, 200); EWorldEditor.axisGizmoActive = getPrefSetting($pref::WorldEditor::axisGizmoActive, true); EWorldEditor.mouseMoveScale = getPrefSetting($pref::WorldEditor::mouseMoveScale, 0.2); EWorldEditor.mouseRotateScale = getPrefSetting($pref::WorldEditor::mouseRotateScale, 0.01); EWorldEditor.mouseScaleScale = getPrefSetting($pref::WorldEditor::mouseScaleScale, 0.01); EWorldEditor.minScaleFactor = getPrefSetting($pref::WorldEditor::minScaleFactor, 0.1); EWorldEditor.maxScaleFactor = getPrefSetting($pref::WorldEditor::maxScaleFactor, 4000); EWorldEditor.objSelectColor = getPrefSetting($pref::WorldEditor::objSelectColor, "255 0 0"); EWorldEditor.objMouseOverSelectColor = getPrefSetting($pref::WorldEditor::objMouseOverSelectColor, "0 0 255"); EWorldEditor.objMouseOverColor = getPrefSetting($pref::WorldEditor::objMouseOverColor, "0 255 0"); EWorldEditor.showMousePopupInfo = getPrefSetting($pref::WorldEditor::showMousePopupInfo, true); EWorldEditor.dragRectColor = getPrefSetting($pref::WorldEditor::dragRectColor, "255 255 0"); EWorldEditor.renderObjText = getPrefSetting($pref::WorldEditor::renderObjText, true); EWorldEditor.renderObjHandle = getPrefSetting($pref::WorldEditor::renderObjHandle, true); EWorldEditor.faceSelectColor = getPrefSetting($pref::WorldEditor::faceSelectColor, "0 0 100 100"); EWorldEditor.renderSelectionBox = getPrefSetting($pref::WorldEditor::renderSelectionBox, true); EWorldEditor.selectionBoxColor = getPrefSetting($pref::WorldEditor::selectionBoxColor, "255 255 0"); EWorldEditor.snapToGrid = getPrefSetting($pref::WorldEditor::snapToGrid, false); EWorldEditor.snapRotations = getPrefSetting($pref::WorldEditor::snapRotations, false); EWorldEditor.rotationSnap = getPrefSetting($pref::WorldEditor::rotationSnap, "15"); ETerrainEditor.softSelecting = 1; ETerrainEditor.currentAction = "raiseHeight"; ETerrainEditor.currentMode = "select"; } function EditorGui::setPrefs() { $Pref::WorldEditor::dropType = EWorldEditor.dropType; $pref::WorldEditor::planarMovement = EWorldEditor.planarMovement; $pref::WorldEditor::undoLimit = EWorldEditor.undoLimit; $pref::WorldEditor::dropType = EWorldEditor.dropType; $pref::WorldEditor::projectDistance = EWorldEditor.projectDistance; $pref::WorldEditor::boundingBoxCollision = EWorldEditor.boundingBoxCollision; $pref::WorldEditor::renderPlane = EWorldEditor.renderPlane; $pref::WorldEditor::renderPlaneHashes = EWorldEditor.renderPlaneHashes; $pref::WorldEditor::gridColor = EWorldEditor.GridColor; $pref::WorldEditor::planeDim = EWorldEditor.planeDim; $pref::WorldEditor::gridSize = EWorldEditor.GridSize; $pref::WorldEditor::renderPopupBackground = EWorldEditor.renderPopupBackground; $pref::WorldEditor::popupBackgroundColor = EWorldEditor.PopupBackgroundColor; $pref::WorldEditor::popupTextColor = EWorldEditor.PopupTextColor; $pref::WorldEditor::selectHandle = EWorldEditor.selectHandle; $pref::WorldEditor::defaultHandle = EWorldEditor.defaultHandle; $pref::WorldEditor::lockedHandle = EWorldEditor.lockedHandle; $pref::WorldEditor::objectTextColor = EWorldEditor.ObjectTextColor; $pref::WorldEditor::objectsUseBoxCenter = EWorldEditor.objectsUseBoxCenter; $pref::WorldEditor::axisGizmoMaxScreenLen = EWorldEditor.axisGizmoMaxScreenLen; $pref::WorldEditor::axisGizmoActive = EWorldEditor.axisGizmoActive; $pref::WorldEditor::mouseMoveScale = EWorldEditor.mouseMoveScale; $pref::WorldEditor::mouseRotateScale = EWorldEditor.mouseRotateScale; $pref::WorldEditor::mouseScaleScale = EWorldEditor.mouseScaleScale; $pref::WorldEditor::minScaleFactor = EWorldEditor.minScaleFactor; $pref::WorldEditor::maxScaleFactor = EWorldEditor.maxScaleFactor; $pref::WorldEditor::objSelectColor = EWorldEditor.objSelectColor; $pref::WorldEditor::objMouseOverSelectColor = EWorldEditor.objMouseOverSelectColor; $pref::WorldEditor::objMouseOverColor = EWorldEditor.objMouseOverColor; $pref::WorldEditor::showMousePopupInfo = EWorldEditor.showMousePopupInfo; $pref::WorldEditor::dragRectColor = EWorldEditor.dragRectColor; $pref::WorldEditor::renderObjText = EWorldEditor.renderObjText; $pref::WorldEditor::renderObjHandle = EWorldEditor.renderObjHandle; $pref::WorldEditor::raceSelectColor = EWorldEditor.faceSelectColor; $pref::WorldEditor::renderSelectionBox = EWorldEditor.renderSelectionBox; $pref::WorldEditor::selectionBoxColor = EWorldEditor.selectionBoxColor; $pref::WorldEditor::snapToGrid = EWorldEditor.snapToGrid; $pref::WorldEditor::snapRotations = EWorldEditor.snapRotations; $pref::WorldEditor::rotationSnap = EWorldEditor.rotationSnap; } function EditorGui::onSleep(%this) { %this.setPrefs(); } function EditorGui::init(%this) { DropTypeMenu.setEnumContent(WorldEditor, dropType); %this.getPrefs(); DropTypeMenu.setText(EWorldEditor.dropType); if(!isObject("terraformer")) new Terraformer("terraformer"); $SelectedOperation = -1; $NextOperationId = 1; $HeightfieldDirtyRow = -1; EditorMenuBar.clearMenus(); EditorMenuBar.addMenu("File", 0); EditorMenuBar.addMenuItem("File", "New Mission...", 1); EditorMenuBar.addMenuItem("File", "Open Mission...", 2, "Ctrl O"); EditorMenuBar.addMenuItem("File", "Save Mission...", 3, "Ctrl S"); EditorMenuBar.addMenuItem("File", "Save Mission As...", 4); EditorMenuBar.addMenuItem("File", "-", 0); EditorMenuBar.addMenuItem("File", "Export World Editor Selection...", 0); EditorMenuBar.addMenuItem("File", "Import World Editor Selection...", 0); EditorMenuBar.addMenuItem("File", "-", 0); EditorMenuBar.addMenuItem("File", "Import Terraform Data...", 6); EditorMenuBar.addMenuItem("File", "Import Texture Data...", 5); EditorMenuBar.addMenuItem("File", "-", 0); EditorMenuBar.addMenuItem("File", "Export Terraform Bitmap...", 5); EditorMenuBar.addMenu("Edit", 1); EditorMenuBar.addMenuItem("Edit", "Undo", 1, "Ctrl Z"); EditorMenuBar.setMenuItemBitmap("Edit", "Undo", 1); EditorMenuBar.addMenuItem("Edit", "Redo", 2, "Ctrl R"); EditorMenuBar.setMenuItemBitmap("Edit", "Redo", 2); EditorMenuBar.addMenuItem("Edit", "-", 0); EditorMenuBar.addMenuItem("Edit", "Cut", 3, "Ctrl X"); EditorMenuBar.setMenuItemBitmap("Edit", "Cut", 3); EditorMenuBar.addMenuItem("Edit", "Copy", 4, "Ctrl C"); EditorMenuBar.setMenuItemBitmap("Edit", "Copy", 4); EditorMenuBar.addMenuItem("Edit", "Paste", 5, "Ctrl V"); EditorMenuBar.setMenuItemBitmap("Edit", "Paste", 5); EditorMenuBar.addMenuItem("Edit", "-", 0); EditorMenuBar.addMenuItem("Edit", "Select All", 6, "Ctrl A"); EditorMenuBar.addMenuItem("Edit", "Select None", 7, "Ctrl N"); EditorMenuBar.addMenuItem("Edit", "-", 0); EditorMenuBar.addMenuItem("Edit", "Relight Scene", 14, "Alt L"); EditorMenuBar.addMenuItem("Edit", "-", 0); EditorMenuBar.addMenuItem("Edit", "World Editor Settings...", 12); EditorMenuBar.addMenuItem("Edit", "Terrain Editor Settings...", 13); EditorMenuBar.addMenu("Camera", 7); EditorMenuBar.addMenuItem("Camera", "Drop Camera at Player", 1, "Alt Q"); EditorMenuBar.addMenuItem("Camera", "Drop Player at Camera", 2, "Alt W"); EditorMenuBar.addMenuItem("Camera", "Toggle Camera", 10, "Alt C"); EditorMenuBar.addMenuItem("Camera", "-", 0); EditorMenuBar.addMenuItem("Camera", "Slowest", 3, "Shift 1", 1); EditorMenuBar.addMenuItem("Camera", "Very Slow", 4, "Shift 2", 1); EditorMenuBar.addMenuItem("Camera", "Slow", 5, "Shift 3", 1); EditorMenuBar.addMenuItem("Camera", "Medium Pace", 6, "Shift 4", 1); EditorMenuBar.addMenuItem("Camera", "Fast", 7, "Shift 5", 1); EditorMenuBar.addMenuItem("Camera", "Very Fast", 8, "Shift 6", 1); EditorMenuBar.addMenuItem("Camera", "Fastest", 9, "Shift 7", 1); EditorMenuBar.addMenu("World", 6); EditorMenuBar.addMenuItem("World", "Lock Selection", 10, "Ctrl L"); EditorMenuBar.addMenuItem("World", "Unlock Selection", 11, "Ctrl Shift L"); EditorMenuBar.addMenuItem("World", "-", 0); EditorMenuBar.addMenuItem("World", "Hide Selection", 12, "Ctrl H"); EditorMenuBar.addMenuItem("World", "Show Selection", 13, "Ctrl Shift H"); EditorMenuBar.addMenuItem("World", "-", 0); EditorMenuBar.addMenuItem("World", "Delete Selection", 17, "Delete"); EditorMenuBar.addMenuItem("World", "Camera To Selection", 14); EditorMenuBar.addMenuItem("World", "Reset Transforms", 15); EditorMenuBar.addMenuItem("World", "Drop Selection", 16, "Ctrl D"); EditorMenuBar.addMenuItem("World", "Add Selection to Instant Group", 17); EditorMenuBar.addMenuItem("World", "-", 0); EditorMenuBar.addMenuItem("World", "Drop at Origin", 0, "", 1); EditorMenuBar.addMenuItem("World", "Drop at Camera", 1, "", 1); EditorMenuBar.addMenuItem("World", "Drop at Camera w/Rot", 2, "", 1); EditorMenuBar.addMenuItem("World", "Drop below Camera", 3, "", 1); EditorMenuBar.addMenuItem("World", "Drop at Screen Center", 4, "", 1); EditorMenuBar.addMenuItem("World", "Drop at Centroid", 5, "", 1); EditorMenuBar.addMenuItem("World", "Drop to Ground", 6, "", 1); EditorMenuBar.addMenu("Action", 3); EditorMenuBar.addMenuItem("Action", "Select", 1, "", 1); EditorMenuBar.addMenuItem("Action", "Adjust Selection", 2, "", 1); EditorMenuBar.addMenuItem("Action", "-", 0); EditorMenuBar.addMenuItem("Action", "Add Dirt", 6, "", 1); EditorMenuBar.addMenuItem("Action", "Excavate", 6, "", 1); EditorMenuBar.addMenuItem("Action", "Adjust Height", 6, "", 1); EditorMenuBar.addMenuItem("Action", "Flatten", 4, "", 1); EditorMenuBar.addMenuItem("Action", "Smooth", 5, "", 1); EditorMenuBar.addMenuItem("Action", "Set Height", 7, "", 1); EditorMenuBar.addMenuItem("Action", "-", 0); EditorMenuBar.addMenuItem("Action", "Set Empty", 8, "", 1); EditorMenuBar.addMenuItem("Action", "Clear Empty", 8, "", 1); EditorMenuBar.addMenuItem("Action", "-", 0); EditorMenuBar.addMenuItem("Action", "Paint Material", 9, "", 1); EditorMenuBar.addMenu("Brush", 4); EditorMenuBar.addMenuItem("Brush", "Box Brush", 91, "", 1); EditorMenuBar.addMenuItem("Brush", "Circle Brush", 92, "", 1); EditorMenuBar.addMenuItem("Brush", "-", 0); EditorMenuBar.addMenuItem("Brush", "Soft Brush", 93, "", 2); EditorMenuBar.addMenuItem("Brush", "Hard Brush", 94, "", 2); EditorMenuBar.addMenuItem("Brush", "-", 0); EditorMenuBar.addMenuItem("Brush", "Size 1 x 1", 1, "Alt 1", 3); EditorMenuBar.addMenuItem("Brush", "Size 3 x 3", 3, "Alt 2", 3); EditorMenuBar.addMenuItem("Brush", "Size 5 x 5", 5, "Alt 3", 3); EditorMenuBar.addMenuItem("Brush", "Size 9 x 9", 9, "Alt 4", 3); EditorMenuBar.addMenuItem("Brush", "Size 15 x 15", 15, "Alt 5", 3); EditorMenuBar.addMenuItem("Brush", "Size 25 x 25", 25, "Alt 6", 3); EditorMenuBar.addMenu("AI", 8); EditorMenuBar.addMenuItem("AI", "Render Indoor Graphs", 3); EditorMenuBar.addMenuItem("AI", "Render Outdoor Graph", 4); EditorMenuBar.addMenuItem("AI", "Render Jet Edges", 4); EditorMenuBar.addMenuItem("AI", "-", 0); EditorMenuBar.addMenuItem("AI", "Edit AI for Team 1", 4); EditorMenuBar.addMenuItem("AI", "Edit AI for Team 2", 7); EditorMenuBar.addMenuItem("AI", "-", 0); EditorMenuBar.addMenuItem("AI", "Build Objectives", 5); EditorMenuBar.addMenuItem("AI", "Build Bot Nav Graph...", 5); EditorMenuBar.addMenuItem("AI", "Build Spawn Graph...", 5); EditorMenuBar.addMenuItem("AI", "Build LOS Crossrefs...", 5); EditorMenuBar.addMenuItem("AI", "-", 0); EditorMenuBar.addMenuItem("AI", "Add Defend Location Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Repair Equipment Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Deploy Outdoor Turret Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Deploy Indoor Turret Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Attack Target Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Touch FlipFlop Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Mortar Target Objective", 5); EditorMenuBar.addMenuItem("AI", "Add Deploy Inventory Objective", 5); EditorMenuBar.addMenuItem("AI", "Add New Objective Set", 6); EditorMenuBar.addMenu("Window", 2); EditorMenuBar.addMenuItem("Window", "World Editor", 2, "F2", 1); EditorMenuBar.addMenuItem("Window", "World Editor Inspector", 3, "F3", 1); EditorMenuBar.addMenuItem("Window", "World Editor Creator", 4, "F4", 1); EditorMenuBar.addMenuItem("Window", "Mission Area Editor", 5, "F5", 1); EditorMenuBar.addMenuItem("Window", "AI Editor", 10); EditorMenuBar.addMenuItem("Window", "-", 0); EditorMenuBar.addMenuItem("Window", "Terrain Editor", 6, "F6", 1); EditorMenuBar.addMenuItem("Window", "Terrain Terraform Editor", 7, "F7", 1); EditorMenuBar.addMenuItem("Window", "Terrain Texture Editor", 8, "F8", 1); EditorMenuBar.addMenuItem("Window", "Terrain Texture Painter", 9, "", 1); EditorMenuBar.setMenuItemChecked("AI", "Render Indoor Graphs", $pref::NavGraph::drawIndoor); EditorMenuBar.setMenuItemChecked("AI", "Render Outdoor Graph", $pref::NavGraph::drawOutdoor); EditorMenuBar.setMenuItemChecked("AI", "Render Jet Edges", $pref::NavGraph::drawJetEdges); $AIEditor::inspectTeam = 1; EditorMenuBar.setMenuItemChecked("AI", "Edit AI for Team 1", $AIEditor::inspectTeam == 1); EditorMenuBar.setMenuItemChecked("AI", "Edit AI for Team 2", $AIEditor::inspectTeam == 2); ETerrainEditor.getPrefs(); EditorMenuBar.onActionMenuItemSelect(0, "Paint"); EditorMenuBar.onActionMenuItemSelect(0, "Adjust Height"); EditorMenuBar.onBrushMenuItemSelect(0, "Circle Brush"); EditorMenuBar.onBrushMenuItemSelect(0, "Soft Brush"); EditorMenuBar.onBrushMenuItemSelect(9, "Size 9 x 9"); EditorMenuBar.onCameraMenuItemSelect(6, "Medium Pace"); EditorMenuBar.onWorldMenuItemSelect(0, "Drop at Screen Center"); EWorldEditor.init(); ETerrainEditor.init(); ETerrainEditor.attachTerrain(); TerraformerInit(); TextureInit(); // Creator.init(); Inspector.init(); AreaEditor.init(); EditorTree.init(); ObjectBuilderGui.init(); EWorldEditor.isDirty = false; ETerrainEditor.isDirty = false; ETerrainEditor.isMissionDirty = false; EWorldEditor.isGraphDirty = false; EditorGui.saveAs = false; if(isObject(MissionGroup) && isObject(MissionCleanup)) { MissionGroup.add(MissionCleanup); MissionCleanup.setPersistent(false); } } function EditorNewMission() { if(ETerrainEditor.isMissionDirty || ETerrainEditor.isDirty || EWorldEditor.isDirty || EWorldEditor.isGraphDirty) { MessageBoxYesNo("Mission Modified", "Would you like to save changes to the current mission \"" @ $Server::MissionFile @ "\" before creating a new mission?", "EditorDoNewMission(true);", "EditorDoNewMission(false);"); } else EditorDoNewMission(false); } function EditorSaveMissionMenu() { if(EditorGui.saveAs) EditorSaveMissionAs(); else EditorSaveMission(); } function EditorSaveMission() { // just save the mission without renaming it // first check for dirty and read-only files: %missionFile = "missions/" @ $CurrentMission @ ".mis"; %terrainFile = "terrains/" @ Terrain.terrainFile; if((EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) && !isWriteableFileName(%missionFile)) { MessageBoxOK("Error", "Mission file \""@ %missionFile @ "\" is read-only."); return false; } if(ETerrainEditor.isDirty && !isWriteableFileName(%terrainFile)) { MessageBoxOK("Error", "Terrain file \""@ %terrainFile @ "\" is read-only."); return false; } // now write the terrain and mission files out: //exec("temp\\day.cs"); //exec("temp\\night.cs"); //MissionGroup.add(day); //MissionGroup.add(night); if(EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) MissionGroup.save(%missionFile); if(ETerrainEditor.isDirty) Terrain.save(Terrain.terrainFile); if(EWorldEditor.isGraphDirty && isObject(NavGraph)) NavGraph.saveGraph(); EWorldEditor.isDirty = false; EWorldEditor.isGraphDirty = false; ETerrainEditor.isDirty = false; ETerrainEditor.isMissionDirty = false; EditorGui.saveAs = false; return true; } function EditorDoSaveAs(%missionName) { ETerrainEditor.isDirty = true; EWorldEditor.isDirty = true; EWorldEditor.isGraphDirty = true; %saveMissionFile = $CurrentMission; %saveTerrName = Terrain.terrainFile; $CurrentMission = fileBase(%missionName); Terrain.terrainFile = fileBase(%missionName) @ ".ter"; if(!EditorSaveMission()) { $CurrentMission = %saveMissionFile; Terrain.terrainFile = %saveTerrName; } } function EditorSaveMissionAs() { getSaveFilename("*.mis", "EditorDoSaveAs", $Server::MissionFile); } function EditorDoLoadMission(%file) { // gotta strip off the missions path %file = fileBase(%file); loadMission( %file, $CurrentMissionType, true ) ; // and re-init the EditorGui EditorGui.init(); EditorGui.loadingMission = true; Canvas.setContent(LoadingGui); } function EditorSaveBeforeLoad() { if(EditorSaveMission()) getLoadFilename("*.mis", "EditorDoLoadMission"); } function EditorDoNewMission(%saveFirst) { if(%saveFirst) EditorSaveMission(); %file = findFirstFile("*/newMission.mis"); if(%file $= "") { MessageBoxOk("Error", "Missing mission template \"newMission.mis\"."); return; } EditorDoLoadMission(%file); EditorGui.saveAs = true; EWorldEditor.isDirty = true; ETerrainEditor.isDirty = true; } function EditorOpenMission() { if(ETerrainEditor.isMissionDirty || ETerrainEditor.isDirty || EWorldEditor.isDirty || EWorldEditor.isGraphDirty) { MessageBoxYesNo("Mission Modified", "Would you like to save changes to the current mission \"" @ $Server::MissionFile @ "\" before opening a new mission?", "EditorSaveBeforeLoad();", "getLoadFilename(\"*.mis\", \"EditorDoLoadMission\");"); } else getLoadFilename("*.mis", "EditorDoLoadMission"); } function EditorMenuBar::onMenuSelect(%this, %menuId, %menu) { if(%menu $= "File") { %editingHeightfield = ETerrainEditor.isVisible() && EHeightField.isVisible(); EditorMenuBar.setMenuItemEnable("File", "Export Terraform Bitmap...", %editingHeightfield); EditorMenuBar.setMenuItemEnable("File", "Save Mission...", EWorldEditor.isGraphDirty || ETerrainEditor.isDirty || ETerrainEditor.isMissionDirty || EWorldEditor.isDirty); EditorMenuBar.setMenuItemEnable("File", "Export World Editor Selection...", EWorldEditor.isVisible() && EWorldEditor.getSelectionSize()); EditorMenuBar.setMenuItemEnable("File", "Import World Editor Selection...", EWorldEditor.isVisible()); } else if(%menu $= "Edit") { // enable/disable undo, redo, cut, copy, paste depending on editor settings if(EWorldEditor.isVisible()) { // do actions based on world editor... EditorMenuBar.setMenuItemEnable("Edit", "Select All", true); EditorMenuBar.setMenuItemEnable("Edit", "Paste", EWorldEditor.canPasteSelection()); %canCutCopy = EWorldEditor.getSelectionSize() > 0; EditorMenuBar.setMenuItemEnable("Edit", "Cut", %canCutCopy); EditorMenuBar.setMenuItemEnable("Edit", "Copy", %canCutCopy); } else if(ETerrainEditor.isVisible()) { EditorMenuBar.setMenuItemEnable("Edit", "Cut", false); EditorMenuBar.setMenuItemEnable("Edit", "Copy", false); EditorMenuBar.setMenuItemEnable("Edit", "Paste", false); EditorMenuBar.setMenuItemEnable("Edit", "Select All", false); } } else if(%menu $= "World") { %selSize = EWorldEditor.getSelectionSize(); %lockCount = EWorldEditor.getSelectionLockCount(); %hideCount = EWorldEditor.getSelectionHiddenCount(); EditorMenuBar.setMenuItemEnable("World", "Lock Selection", %lockCount < %selSize); EditorMenuBar.setMenuItemEnable("World", "Unlock Selection", %lockCount > 0); EditorMenuBar.setMenuItemEnable("World", "Hide Selection", %hideCount < %selSize); EditorMenuBar.setMenuItemEnable("World", "Show Selection", %hideCount > 0); EditorMenuBar.setMenuItemEnable("World", "Add Selection to Instant Group", %selSize > 0); EditorMenuBar.setMenuItemEnable("World", "Camera To Selection", %selSize > 0); EditorMenuBar.setMenuItemEnable("World", "Reset Transforms", %selSize > 0 && %lockCount == 0); EditorMenuBar.setMenuItemEnable("World", "Drop Selection", %selSize > 0 && %lockCount == 0); EditorMenuBar.setMenuItemEnable("World", "Delete Selection", (!EditorTree.isSelectionEmpty() || %selSize > 0) && %lockCount == 0); } } function EditorMenuBar::onMenuItemSelect(%this, %menuId, %menu, %itemId, %item) { switch$(%menu) { case "File": %this.onFileMenuItemSelect(%itemId, %item); case "Edit": %this.onEditMenuItemSelect(%itemId, %item); case "World": %this.onWorldMenuItemSelect(%itemId, %item); case "Window": %this.onWindowMenuItemSelect(%itemId, %item); case "Action": %this.onActionMenuItemSelect(%itemId, %item); case "Brush": %this.onBrushMenuItemSelect(%itemId, %item); case "Camera": %this.onCameraMenuItemSelect(%itemId, %item); case "AI": %this.onAIMenuItemSelect(%itemId, %item); } } function EditorMenuBar::onFileMenuItemSelect(%this, %itemId, %item) { switch$(%item) { case "New Mission...": EditorNewMission(); case "Open Mission...": EditorOpenMission(); case "Save Mission...": EditorSaveMissionMenu(); case "Save Mission As...": EditorSaveMissionAs(); case "Export World Editor Selection...": EWorldEditor.export(); case "Import World Editor Selection...": EWorldEditor.import(); case "Import Texture Data...": Texture::import(); case "Import Terraform Data...": Heightfield::import(); case "Export Terraform Bitmap...": Heightfield::saveBitmap(""); case "Quit": } } function EditorMenuBar::onCameraMenuItemSelect(%this, %itemId, %item) { switch$(%item) { case "Drop Camera at Player": commandToServer('dropCameraAtPlayer'); case "Drop Player at Camera": commandToServer('DropPlayerAtCamera'); case "Toggle Camera": commandToServer('ToggleCamera'); default: // all the rest are camera speeds: // item ids go from 3 (slowest) to 9 (fastest) %this.setMenuItemChecked("Camera", %itemId, true); // camera movement speed goes from 5 to 200: $Camera::movementSpeed = ((%itemId - 3) / 6.0) * 195 + 5; } } function EditorMenuBar::onActionMenuItemSelect(%this, %itemId, %item) { EditorMenuBar.setMenuItemChecked("Action", %item, true); switch$(%item) { case "Select": ETerrainEditor.currentMode = "select"; ETerrainEditor.selectionHidden = false; ETerrainEditor.renderVertexSelection = true; ETerrainEditor.setAction("select"); case "Adjust Selection": ETerrainEditor.currentMode = "adjust"; ETerrainEditor.selectionHidden = false; ETerrainEditor.setAction("adjustHeight"); ETerrainEditor.currentAction = brushAdjustHeight; ETerrainEditor.renderVertexSelection = true; default: ETerrainEditor.currentMode = "paint"; ETerrainEditor.selectionHidden = true; ETerrainEditor.setAction(ETerrainEditor.currentAction); switch$(%item) { case "Add Dirt": ETerrainEditor.currentAction = raiseHeight; ETerrainEditor.renderVertexSelection = true; case "Paint Material": ETerrainEditor.currentAction = paintMaterial; ETerrainEditor.renderVertexSelection = true; case "Excavate": ETerrainEditor.currentAction = lowerHeight; ETerrainEditor.renderVertexSelection = true; case "Set Height": ETerrainEditor.currentAction = setHeight; ETerrainEditor.renderVertexSelection = true; case "Adjust Height": ETerrainEditor.currentAction = brushAdjustHeight; ETerrainEditor.renderVertexSelection = true; case "Flatten": ETerrainEditor.currentAction = flattenHeight; ETerrainEditor.renderVertexSelection = true; case "Smooth": ETerrainEditor.currentAction = smoothHeight; ETerrainEditor.renderVertexSelection = true; case "Set Empty": ETerrainEditor.currentAction = setEmpty; ETerrainEditor.renderVertexSelection = false; case "Clear Empty": ETerrainEditor.currentAction = clearEmpty; ETerrainEditor.renderVertexSelection = false; } if(ETerrainEditor.currentMode $= "select") ETerrainEditor.processAction(ETerrainEditor.currentAction); else if(ETerrainEditor.currentMode $= "paint") ETerrainEditor.setAction(ETerrainEditor.currentAction); } } function EditorMenuBar::onBrushMenuItemSelect(%this, %itemId, %item) { EditorMenuBar.setMenuItemChecked("Brush", %item, true); switch$(%item) { case "Box Brush": ETerrainEditor.setBrushType(box); case "Circle Brush": ETerrainEditor.setBrushType(ellipse); case "Soft Brush": ETerrainEditor.enableSoftBrushes = true; case "Hard Brush": ETerrainEditor.enableSoftBrushes = false; default: // the rest are brush sizes: ETerrainEditor.brushSize = %itemId; ETerrainEditor.setBrushSize(%itemId, %itemId); } } function EditorMenuBar::onWorldMenuItemSelect(%this, %itemId, %item) { // edit commands for world editor... switch$(%item) { case "Lock Selection": EWorldEditor.lockSelection(true); case "Unlock Selection": EWorldEditor.lockSelection(false); case "Hide Selection": EWorldEditor.hideSelection(true); case "Show Selection": EWorldEditor.hideSelection(false); case "Camera To Selection": EWorldEditor.dropCameraToSelection(); case "Reset Transforms": EWorldEditor.resetTransforms(); case "Drop Selection": EWorldEditor.dropSelection(); case "Delete Selection": EWorldEditor.deleteSelection(); EditorTree.deleteSelection(); if(!isObject($InstantGroup)) $InstantGroup = "MissionGroup"; case "Add Selection to Instant Group": EWorldEditor.addSelectionToAddGroup(); default: EditorMenuBar.setMenuItemChecked("World", %item, true); switch$(%item) { case "Drop at Origin": EWorldEditor.dropType = "atOrigin"; case "Drop at Camera": EWorldEditor.dropType = "atCamera"; case "Drop at Camera w/Rot": EWorldEditor.dropType = "atCameraRot"; case "Drop below Camera": EWorldEditor.dropType = "belowCamera"; case "Drop at Screen Center": EWorldEditor.dropType = "screenCenter"; case "Drop to Ground": EWorldEditor.dropType = "toGround"; case "Drop at Centroid": EWorldEditor.dropType = "atCentroid"; } } } function EditorMenuBar::onEditMenuItemSelect(%this, %itemId, %item) { if(%item $= "World Editor Settings...") Canvas.pushDialog(WorldEditorSettingsDlg); else if(%item $= "Terrain Editor Settings...") Canvas.pushDialog(TerrainEditorValuesSettingsGui, 99); else if(%item $= "Relight Scene") lightScene("", forceAlways); else if(EWorldEditor.isVisible()) { // edit commands for world editor... switch$(%item) { case "Undo": EWorldEditor.undo(); case "Redo": EWorldEditor.redo(); case "Copy": EWorldEditor.copySelection(); case "Cut": EWorldEditor.copySelection(); EWorldEditor.deleteSelection(); case "Paste": EWorldEditor.pasteSelection(); case "Select All": case "Select None": } } else if(ETerrainEditor.isVisible()) { // do some terrain stuffin' switch$(%item) { case "Undo": ETerrainEditor.undo(); case "Redo": ETerrainEditor.redo(); case "Select None": ETerrainEditor.clearSelection(); } } } function WorldEditor::export(%this) { getSaveFilename("editor/*.mac", %this @ ".doExport", "selection.mac"); } function WorldEditor::doExport(%this, %file) { missionGroup.save("editor/" @ %file, true); } function WorldEditor::import(%this) { getLoadFilename("editor/*.mac", %this @ ".doImport"); } function WorldEditor::doImport(%this, %file) { %tempInstant = $InstantGroup; %grp = new SimGroup(); $InstantGroup = %grp; MissionGroup.add(%grp); exec(%file); EWorldEditor.clearSelection(); while(%grp.getCount()) { EWorldEditor.selectObject(%grp.getObject(0)); %tempInstant.add(%grp.getObject(0)); } EWorldEditor.dropSelection(); EditorTree.fillSelectionFromWorldEditor(%this); $InstantGroup = %tempInstant; %grp.delete(); } function EditorMenuBar::onWindowMenuItemSelect(%this, %itemId, %item) { EditorGui.setEditor(%item); } function EditorGui::setAIEditTeam(%this, %team) { $AIEditor::inspectTeam = %team; EditorMenuBar.setMenuItemChecked("AI", "Edit AI for Team 1", $AIEditor::inspectTeam == 1); EditorMenuBar.setMenuItemChecked("AI", "Edit AI for Team 2", $AIEditor::inspectTeam == 2); EditorTree.open("MissionGroup/Teams/team" @ %team @ "/AIObjectives"); $InstantGroup = nameToId("MissionGroup/Teams/team" @ %team @ "/AIObjectives"); } function EditorGui::makeUnbridgedGraph() { GraphCurrentOperation.setValue("Generating interior nodes..."); Canvas.repaint(); navGraph::generateInterior(); EditorGui.dataProgress(); GraphCurrentOperation.setValue("Remaking graph..."); Canvas.repaint(); EditorGui.remakeTheGraph(); EditorGui.dataProgress(); EWorldEditor.isGraphDirty = true; } function EditorGui::AIworking(%this, %working) { if(%working) { Canvas.pushDialog(AIEWorkingDlg); GraphBuildProgress.setValue(0.0); } else Canvas.popDialog(AIEWorkingDlg); Canvas.repaint(); } function EditorGui::dataProgress(%this) { $NavGraph::operationsDone++; %percent = $NavGraph::operationsDone / $NavGraph::operations; GraphBuildProgress.setValue(%percent); Canvas.repaint(); } //------------------------------------------------------------------------------ function EditorGui::remakeTheGraph(%this) { GraphCurrentOperation.setValue("making graph..."); Canvas.repaint(); navGraph.makeGraph(); EditorGui.dataProgress(); } function EditorGui::createLOSXref(%this) { EditorGui.AIworking(true); GraphCurrentOperation.setValue("Making LOS CrossRef Table..."); GraphBuildProgress.setValue(0); if(2.player) navGraph.prepLOS(2.player.getTransform()); else navGraph.prepLOS("0 0 0"); while(navGraph.makeLOS()) { GraphBuildProgress.setValue($graphProcessPercent); Canvas.repaint(); } GraphBuildProgress.setValue(100); Canvas.repaint(); EWorldEditor.isGraphDirty = true; EditorGui.AIworking(false); } function EditorGui::makeJettableGraph(%this, %NAVorSPAWN) { %this.AIworking(true); $NavGraph::operations = 7; $NavGraph::operationsDone = 0; navGraph.setGenMode(%NAVorSPAWN); navGraph::exteriorInspect(); %this.dataProgress(); %this.makeUnbridgedGraph(); GraphCurrentOperation.setValue("Beginning slow bridge finding pass"); Canvas.repaint(); navGraph.assemble(); navGraph.cullIslands(); %this.remakeTheGraph(); navGraph.pushBridges(); navGraph.makeTables(); %this.dataProgress(); EWorldEditor.isGraphDirty = true; %this.AIworking(false); } function EditorMenuBar::onAIMenuItemSelect(%this, %itemId, %item) { switch$(%item) { case "Build Objectives": AICreateObjectives(); case "Build Bot Nav Graph...": EditorGui.makeJettableGraph(Nav); case "Build Spawn Graph...": EditorGui.makeJettableGraph(Spawn); case "Build LOS Crossrefs...": EditorGui.createLOSXref(); case "Render Indoor Graphs": $pref::NavGraph::drawIndoor = !$pref::NavGraph::drawIndoor; EditorMenuBar.setMenuItemChecked("AI", "Render Indoor Graphs", $pref::NavGraph::drawIndoor); case "Render Outdoor Graph": $pref::NavGraph::drawOutdoor = !$pref::NavGraph::drawOutdoor; EditorMenuBar.setMenuItemChecked("AI", "Render Outdoor Graph", $pref::NavGraph::drawOutdoor); case "Render Jet Edges": $pref::NavGraph::drawJetEdges = !$pref::NavGraph::drawJetEdges; EditorMenuBar.setMenuItemChecked("AI", "Render Jet Edges", $pref::NavGraph::drawJetEdges); case "Edit AI for Team 1": EditorGui.setAIEditTeam(1); case "Edit AI for Team 2": EditorGui.setAIEditTeam(2); case "Add New Objective Set": %set = new SimGroup("ObjectiveSet"); $InstantGroup.add(%set); default: EditorGui.addNewObjective(getWord(%item, 1) SPC getWord(%item, 2)); } } function EditorGui::addNewObjective(%this, %type) { if($AIEditor::inspectTeam == 1) %team = 1; else if($AIEditor::inspectTeam == 2) %team = 2; else %team = 1; if(nameToId($InstantGroup) < 1) return; switch$(%type) { case "Defend Location": %objective = new AIObjective(AIODefendLocation) { dataBlock = "AIObjectiveMarker"; }; case "Repair Equipment": %objective = new AIObjective(AIORepairObject) { dataBlock = "AIObjectiveMarker"; }; case "Deploy Outdoor": %Objective = new AIObjective(AIODeployEquipment) { dataBlock = "AIObjectiveMarker"; weightLevel1 = 4100; weightLevel2 = 0; description = "Deploy outdoor Turret"; offense = false; defense = true; targetObjectId = -1; targetObject = -1; targetClientId = -1; equipment = "TurretOutdoorDeployable"; buyEquipmentSet = "MediumOutdoorTurretSet"; }; case "Deploy Indoor": %Objective = new AIObjective(AIODeployEquipment) { dataBlock = "AIObjectiveMarker"; weightLevel1 = 4100; weightLevel2 = 0; description = "Deploy indoor Turret"; offense = false; defense = true; targetObjectId = -1; targetObject = -1; targetClientId = -1; equipment = "TurretIndoorDeployable"; buyEquipmentSet = "MediumIndoorTurretSet"; }; case "Attack Target": %objective = new AIObjective(AIOAttackObject) { dataBlock = "AIObjectiveMarker"; }; case "Touch FlipFlop": %objective = new AIObjective(AIOTouchObject) { dataBlock = "AIObjectiveMarker"; }; case "Mortar Target": %objective = new AIObjective(AIOMortarObject) { dataBlock = "AIObjectiveMarker"; }; case "Deploy Inventory": %Objective = new AIObjective(AIODeployEquipment) { dataBlock = "AIObjectiveMarker"; weightLevel1 = 4100; weightLevel2 = 0; description = "Deploy Inventory Station"; offense = false; defense = true; targetObjectId = -1; targetObject = -1; targetClientId = -1; equipment = "InventoryDeployable"; buyEquipmentSet = "MediumInventorySet"; }; case "New Group": %set = new SimGroup("ObjectiveSet"); %tGroup.add(%set); return; default: error("no defined type."); return; } $InstantGroup.add(%objective); EWorldEditor.clearSelection(); EWorldEditor.selectObject(%objective); EWorldEditor.dropSelection(); %objective.location = %objective.getWorldBoxCenter(); Inspector.inspect(%objective); InspectorNameEdit.setValue(%objective.getName()); } function EditorGui::setWorldEditorVisible(%this) { EWorldEditor.setVisible(true); ETerrainEditor.setVisible(false); EditorMenuBar.setMenuVisible("World", true); EditorMenuBar.setMenuVisible("Action", false); EditorMenuBar.setMenuVisible("Brush", false); EditorMenuBar.setMenuVisible("AI", false); EWorldEditor.schedule(0, makeFirstResponder, true); } function EditorGui::setTerrainEditorVisible(%this) { EWorldEditor.setVisible(false); ETerrainEditor.setVisible(true); ETerrainEditor.attachTerrain(); EHeightField.setVisible(false); ETexture.setVisible(false); EditorMenuBar.setMenuVisible("World", false); EditorMenuBar.setMenuVisible("Action", true); EditorMenuBar.setMenuVisible("Brush", true); EditorMenuBar.setMenuVisible("AI", false); ETerrainEditor.schedule(0, makeFirstResponder, true); EPainter.setVisible(false); } function EditorGui::setEditor(%this, %editor) { EditorMenuBar.setMenuItemBitmap("Window", %this.currentEditor, -1); EditorMenuBar.setMenuItemBitmap("Window", %editor, 0); if(%this.currentEditor $= "AI Editor" && %this.lastInstantGroup !$= "") { %grp = nameToID(%this.lastInstantGroup); if(%grp != -1) $InstantGroup = %grp; } %this.currentEditor = %editor; $AIEdit = false; EWorldEditor.renderNav = false; // add objclasses which we do not want to collide with EWorldEditor.clearIgnoreList(); EWorldEditor.ignoreObjClass(TerrainBlock, Sky, AIObjective); EWorldEditor.toggleIgnoreList = false; EditorTree.open("MissionGroup"); switch$(%editor) { case "World Editor": EWFrame.setVisible(false); EWMissionArea.setVisible(false); %this.setWorldEditorVisible(); case "World Editor Inspector": EWFrame.setVisible(true); EWMissionArea.setVisible(false); EWCreatorPane.setVisible(false); EWInspectorPane.setVisible(true); %this.setWorldEditorVisible(); case "World Editor Creator": EWFrame.setVisible(true); EWMissionArea.setVisible(false); EWCreatorPane.setVisible(true); EWInspectorPane.setVisible(false); %this.setWorldEditorVisible(); case "Mission Area Editor": EWFrame.setVisible(false); EWMissionArea.setVisible(true); %this.setWorldEditorVisible(); case "AI Editor": if(%this.currentEditor !$= "AI Editor") %this.lastInstantGroup = $InstantGroup; EWFrame.setVisible(true); EWMissionArea.setVisible(false); EWCreatorPane.setVisible(false); EWInspectorPane.setVisible(true); %this.setWorldEditorVisible(true); EditorMenuBar.setMenuVisible("AI", true); EWorldEditor.clearIgnoreList(); EWorldEditor.ignoreObjClass(AIObjective); EWorldEditor.toggleIgnoreList = true; EWorldEditor.renderNav = true; EditorGui.setAIEditTeam($AIEditor::inspectTeam); case "Terrain Editor": %this.setTerrainEditorVisible(); case "Terrain Terraform Editor": %this.setTerrainEditorVisible(); EHeightField.setVisible(true); case "Terrain Texture Editor": %this.setTerrainEditorVisible(); ETexture.setVisible(true); case "Terrain Texture Painter": %this.setTerrainEditorVisible(); EPainter.setVisible(true); EPainter.setup(); } } function EditorGui::getHelpPage(%this) { switch$(%this.currentEditor) { case "World Editor" or "World Editor Inspector" or "World Editor Creator": return "3. World Editor"; case "Mission Area Editor": return "4. Mission Area Editor"; case "Terrain Editor": return "5. Terrain Editor"; case "Terrain Terraform Editor": return "6. Terrain Terraform Editor"; case "Terrain Texture Editor": return "7. Terrain Texture Editor"; case "Terrain Texture Painter": return "8. Terrain Texture Painter"; default: return "2. Mission Editor Overview"; } } function ETerrainEditor::setPaintMaterial(%this, %matIndex) { ETerrainEditor.paintMaterial = EPainter.mat[%matIndex]; } function ETerrainEditor::changeMaterial(%this, %matIndex) { EPainter.matIndex = %matIndex; getLoadFilename("textures/terrain/*.png\ttextures/terrain/*.jpg", EPainterChangeMat, true); } function EPainterChangeMat(%file) { // make sure the material isn't already in the terrain. %file = fileBase(%file); for(%i = 0; %i < 6; %i++) if(EPainter.mat[%i] $= %file) return; EPainter.mat[EPainter.matIndex] = %file; %mats = ""; for(%i = 0; %i < 6; %i++) %mats = %mats @ EPainter.mat[%i] @ "\n"; ETerrainEditor.setTerrainMaterials(%mats); EPainter.setup(); ("ETerrainMaterialPaint" @ EPainter.matIndex).performClick(); } function EPainter::setup(%this) { EditorMenuBar.onActionMenuItemSelect(0, "Paint Material"); %mats = ETerrainEditor.getTerrainMaterials(); %valid = true; for(%i = 0; %i < 6; %i++) { %mat = getRecord(%mats, %i); %this.mat[%i] = %mat; ("ETerrainMaterialText" @ %i).setText(%mat); ("ETerrainMaterialBitmap" @ %i).setBitmap("terrain/" @ %mat); ("ETerrainMaterialChange" @ %i).setActive(true); ("ETerrainMaterialPaint" @ %i).setActive(%mat !$= ""); if(%mat $= "") { ("ETerrainMaterialChange" @ %i).setValue("Add..."); if(%valid) %valid = false; else ("ETerrainMaterialChange" @ %i).setActive(false); } else ("ETerrainMaterialChange" @ %i).setValue("Change..."); } ETerrainMaterialPaint0.performClick(); } function EditorGui::onWake(%this) { MoveMap.push(); EditorMap.push(); %this.setEditor(%this.currentEditor); } function EditorGui::onSleep(%this) { EditorMap.pop(); MoveMap.pop(); } function AreaEditor::onUpdate(%this, %area) { AreaEditingText.setValue( "X: " @ getWord(%area,0) @ " Y: " @ getWord(%area,1) @ " W: " @ getWord(%area,2) @ " H: " @ getWord(%area,3)); } function AreaEditor::onWorldOffset(%this, %offset) { } function EditorTree::init(%this) { %this.open(MissionGroup); // context menu new GuiControl(ETContextPopupDlg) { profile = "GuiModelessDialogProfile"; horizSizing = "width"; vertSizing = "height"; position = "0 0"; extent = "640 480"; minExtent = "8 8"; visible = "1"; setFirstResponder = "0"; modal = "1"; new GuiPopUpMenuCtrl(ETContextPopup) { profile = "GuiScrollProfile"; position = "0 0"; extent = "0 0"; minExtent = "0 0"; maxPopupHeight = "200"; command = "canvas.popDialog(ETContextPopupDlg);"; }; }; ETContextPopup.setVisible(false); } function EditorTree::onInspect(%this, %obj) { Inspector.inspect(%obj); InspectorNameEdit.setValue(%obj.getName()); } function EditorTree::onSelect(%this, %obj) { if($AIEdit) aiEdit.selectObject(%obj); else EWorldEditor.selectObject(%obj); } function EditorTree::onUnselect(%this, %obj) { if($AIEdit) aiEdit.unselectObject(%obj); else EWorldEditor.unselectObject(%obj); } function ETContextPopup::onSelect(%this, %index, %value) { switch(%index) { case 0: EditorTree.contextObj.delete(); } } //------------------------------------------------------------------------------ // Functions //------------------------------------------------------------------------------ function DropTypeMenu::onSelect(%this, %id, %text) { EWorldEditor.dropType = %text; } function WorldEditor::init(%this) { %this.getPrefs(); // editing modes %this.numEditModes = 3; %this.editMode[0] = "move"; %this.editMode[1] = "rotate"; %this.editMode[2] = "scale"; %this.setMode(%this.currentMode); // context menu new GuiControl(WEContextPopupDlg) { profile = "GuiModelessDialogProfile"; horizSizing = "width"; vertSizing = "height"; position = "0 0"; extent = "640 480"; minExtent = "8 8"; visible = "1"; setFirstResponder = "0"; modal = "1"; new GuiPopUpMenuCtrl(WEContextPopup) { profile = "GuiScrollProfile"; position = "0 0"; extent = "0 0"; minExtent = "0 0"; maxPopupHeight = "200"; command = "canvas.popDialog(WEContextPopupDlg);"; }; }; WEContextPopup.setVisible(false); } //------------------------------------------------------------------------------ function WorldEditor::onDblClick(%this, %obj) { // Commented out because making someone double click to do this is stupid // and has the possibility of moving hte object //Inspector.inspect(%obj); //InspectorNameEdit.setValue(%obj.getName()); } function WorldEditor::onSelectionChanged(%this) { EditorTree.fillSelectionFromWorldEditor(%this); } function WorldEditor::onClick( %this, %obj ) { Inspector.inspect( %obj ); InspectorNameEdit.setValue( %obj.getName() ); } //------------------------------------------------------------------------------ function WorldEditor::onGuiUpdate(%this, %text) { } function WorldEditor::getSelectionLockCount(%this) { %ret = 0; for(%i = 0; %i < %this.getSelectionSize(); %i++) { %obj = %this.getSelectedObject(%i); if(%obj.locked $= "true") %ret++; } return %ret; } function WorldEditor::getSelectionHiddenCount(%this) { %ret = 0; for(%i = 0; %i < %this.getSelectionSize(); %i++) { %obj = %this.getSelectedObject(%i); if(%obj.hidden $= "true") %ret++; } return %ret; } function WorldEditor::dropCameraToSelection(%this) { if(%this.getSelectionSize() == 0) return; %pos = %this.getSelectionCentroid(); %cam = LocalClientConnection.camera.getTransform(); // set the pnt %cam = setWord(%cam, 0, getWord(%pos, 0)); %cam = setWord(%cam, 1, getWord(%pos, 1)); %cam = setWord(%cam, 2, getWord(%pos, 2)); LocalClientConnection.camera.setTransform(%cam); } // * pastes the selection at the same place (used to move obj from a group to another) function WorldEditor::moveSelectionInPlace(%this) { %saveDropType = %this.dropType; %this.dropType = "atCentroid"; %this.copySelection(); %this.deleteSelection(); %this.pasteSelection(); %this.dropType = %saveDropType; } function WorldEditor::addSelectionToAddGroup(%this) { for(%i = 0; %i < %this.getSelectionSize(); %i++) { %obj = %this.getSelectedObject(%i); $InstantGroup.add(%obj); } } // resets the scale and rotation on the selection set function WorldEditor::resetTransforms(%this) { %this.addUndoState(); for(%i = 0; %i < %this.getSelectionSize(); %i++) { %obj = %this.getSelectedObject(%i); %transform = %obj.getTransform(); %transform = setWord(%transform, 3, "0"); %transform = setWord(%transform, 4, "0"); %transform = setWord(%transform, 5, "1"); %transform = setWord(%transform, 6, "0"); // %obj.setTransform(%transform); %obj.setScale("1 1 1"); } } function WorldEditorToolbarDlg::init(%this) { WorldEditorInspectorCheckBox.setValue(WorldEditorToolFrameSet.isMember("EditorToolInspectorGui")); WorldEditorMissionAreaCheckBox.setValue(WorldEditorToolFrameSet.isMember("EditorToolMissionAreaGui")); WorldEditorTreeCheckBox.setValue(WorldEditorToolFrameSet.isMember("EditorToolTreeViewGui")); WorldEditorCreatorCheckBox.setValue(WorldEditorToolFrameSet.isMember("EditorToolCreatorGui")); } function Creator::init(%this) { %this.clear(); // %this.currentSel = -1; // %this.currentRoot = -1; // %this.currentObj = -1; $InstantGroup = "MissionGroup"; // *** INTERIORS %base = %this.addGroup(0, "Interiors"); %misc = %this.addGroup(%base, "Misc."); // %shapeGroup[0] = "Blood Eagle - Lush"; %shapeGroup[1] = "Diamond Sword - Volcanic"; %shapeGroup[2] = "Star Wolf - Ice"; %shapeGroup[3] = "Children of the Phoenix - Desert"; %shapeGroup[4] = "Bioderm - Badlands"; %groupShort[0] = "b"; %groupShort[1] = "d"; %groupShort[2] = "s"; %groupShort[3] = "p"; %groupShort[4] = "x"; // %shapeType[0] = "Towers"; %shapeType[1] = "Bunkers"; %shapeType[2] = "Base"; %shapeType[3] = "Platform"; %shapeType[4] = "Bridge"; %shapeType[5] = "Wall"; %shapeType[6] = "Unique"; %shapeType[7] = "Power"; %shapeType[8] = "Misc."; %shapeType[9] = "Vehicle"; %shapeType[10] = "Rocks"; %typeShort[0] = "towr"; %typeShort[1] = "bunk"; %typeShort[2] = "base"; %typeShort[3] = "plat"; %typeShort[4] = "brdg"; %typeShort[5] = "wall"; %typeShort[6] = "uniq"; %typeShort[7] = "powr"; %typeShort[8] = "misc"; %typeShort[9] = "vbay"; %typeShort[10] = "rock"; // create the groups %grpCount = 0; for(%i = 0; %shapeGroup[%i] !$= ""; %i++) { %parent = Creator.addGroup(%base, %shapeGroup[%i]); for(%j = 0; %shapeType[%j] !$= ""; %j++) { %group[%grpCount] = %this.addGroup(%parent, %shapeType[%j]); %grpCount++; } } // walk all the interiors and add them to the correct group %file = findFirstFile("interiors/*.dif"); while(%file !$= "") { %file = fileBase(%file); %grpCount = 0; %added = false; for(%i = 0; !%added && %shapeGroup[%i] !$= ""; %i++) { for(%j = 0; %shapeType[%j] !$= ""; %j++) { if(%this.fileNameMatch(%groupShort[%i], %typeShort[%j], %file)) { %this.addItem(%group[%grpCount], %file, "createInterior(" @ "\"" @ %file @ ".dif\"" @ ");"); %added = true; } %grpCount++; } } // throw it in the 'misc' directory if(!%added) %this.addItem(%misc, %file, "createInterior(" @ "\"" @ %file @ ".dif\"" @ ");"); %file = findNextFile("interiors/*.dif"); } // *** SHAPES - add in all the shapes now... %base = %this.addGroup(0, "Shapes"); %dataGroup = "DataBlockGroup"; for(%i = 0; %i < %dataGroup.getCount(); %i++) { %obj = %dataGroup.getObject(%i); if(%obj.catagory !$= "" || %obj.catagory != 0) { %grp = %this.addGroup(%base, %obj.catagory); %this.addItem(%grp, %obj.getName(), %obj.getClassName() @ "::create(" @ %obj.getName() @ ");"); } } // Statics %staticBase = %this.addGroup(0, "Static Objects"); for (%i = 0; %i < $NumStaticTSObjects; %i++) { echo("This: " SPC $StaticTSObjects[%i]); echo(getWord($StaticTSObjects[%i], 2)); %grp = %this.addGroup(%staticBase, getWord($StaticTSObjects[%i], 0)); echo("TSStatic::create(" @ getWord($StaticTSObjects[%i], 2) @");"); %this.addItem(%grp, getWord($StaticTSObjects[%i], 1), "TSStatic::create(\"" @ getWord($StaticTSObjects[%i], 2) @"\");"); } // *** OBJECTS - do the objects now... %objGroup[0] = "Environment"; %objGroup[1] = "Mission"; %objGroup[2] = "System"; %objGroup[3] = "AI"; %Environment_Item[0] = "Sky"; %Environment_Item[1] = "Sun"; %Environment_Item[2] = "Lightning"; %Environment_Item[3] = "Water"; %Environment_Item[4] = "Terrain"; %Environment_Item[5] = "AudioEmitter"; %Environment_Item[6] = "Precipitation"; %Environment_Item[7] = "ParticleEmitter"; %Mission_Item[0] = "MissionArea"; %Mission_Item[1] = "GameType"; %Mission_Item[2] = "Marker"; %Mission_Item[3] = "Forcefield"; %Mission_Item[4] = "Trigger"; %Mission_Item[5] = "PhysicalZone"; %Mission_Item[6] = "Camera"; %System_Item[0] = "SimGroup"; %AI_Item[0] = "Objective"; //%AI_Item[1] = "NavigationGraph"; // objects group %base = %this.addGroup(0, "Objects"); // create 'em for(%i = 0; %objGroup[%i] !$= ""; %i++) { %grp = %this.addGroup(%base, %objGroup[%i]); %groupTag = "%" @ %objGroup[%i] @ "_Item"; %done = false; for(%j = 0; !%done; %j++) { eval("%itemTag = " @ %groupTag @ %j @ ";"); if(%itemTag $= "") %done = true; else %this.addItem(%grp, %itemTag, "ObjectBuilderGui.build" @ %itemTag @ "();"); } } } function createInterior(%name) { %obj = new InteriorInstance() { position = "0 0 0"; rotation = "0 0 0"; interiorFile = %name; }; return(%obj); } function Creator::onAction(%this) { // %this.currentSel = -1; // %this.currentRoot = -1; // %this.currentObj = -1; %sel = %this.getSelected(); if(%sel == -1 || %this.isGroup(%sel) || !$MissionRunning) return; // the value is the callback function.. if(%this.getValue(%sel) $= "") return; %this.currentSel = %sel; %this.currentRoot = %this.getRootGroup(%sel); %this.create(%sel); } function Creator::create(%this, %sel) { // create the obj and add to the instant group %obj = eval(%this.getValue(%sel)); if(%obj == -1 || %obj == 0) return; // %this.currentObj = %obj; $InstantGroup.add(%obj); // drop it from the editor - only SceneObjects can be selected... EWorldEditor.clearSelection(); EWorldEditor.selectObject(%obj); EWorldEditor.dropSelection(); } function TSStatic::create(%shapeName) { %obj = new TSStatic() { shapeName = %shapeName; }; return(%obj); } function TSStatic::damage(%this) { // prevent console error spam } //function Creator::getRootGroup(%sel) //{ // if(%sel == -1 || %sel == 0) // return(-1); // // %parent = %this.getParent(%sel); // while(%parent != 0 || %parent != -1) // { // %sel = %parent; // %parent = %this.getParent(%sel); // } // // return(%sel); //} // //function Creator::getLastItem(%rootGroup) //{ // %traverse = %rootGroup + 1; // while(%this.getRootGroup(%traverse) == %rootGroup) // %traverse++; // return(%traverse - 1); //} // //function Creator::createNext(%this) //{ // if(%this.currentSel == -1 || %this.currentRoot == -1 || %this.currentObj == -1) // return; // // %sel = %this.currentSel; // %this.currentSel++; // // while(%this.currentSel != %sel) // { // if(%this.getRootGroup(%this.currentSel) != %this.currentRoot) // %this.currentSel = %this.currentRoot + 1; // // if(%this.isGroup(%this.currentSel)) // %this.currentSel++; // else // %sel = %this.currentSel; // } // // // // %this.currentObj.delete(); // %this.create(%sel); //} // //function Creator::createPrevious(%this) //{ // if(%this.currentSel == -1 || %this.currentGroup == -1 || %this.currentObj == -1) // return; // // %sel = %this.currentSel; // %this.currentSel--; // // while(%this.currentSel != %sel) // { // if(%this.getRootGroup(%this.currentSel) != %this.currentRoot) // %this.currentSel = getLastItem(%this.currentRoot); // // if(%this.isGroup(%this.currentSel)) // %this.currentSel--; // else // %sel = %this.currentSel; // } // // // // %this.currentObj.delete(); // %this.create(%sel); //} function TerraformerGui::init(%this) { TerraformerHeightfieldGui.init(); TerraformerTextureGui.init(); } function TerraformerGui::onWake(%this) { // Only the canvas level gui's get wakes, so udpate manually. TerraformerTextureGui.update(); } function TerraformerGui::onSleep(%this) { %this.setPrefs(); } $nextTextureId = 1; $nextTextureRegister = 1000; $selectedMaterial = -1; $selectedTextureOperation = -1; $TerraformerTextureDir = "common/editor/textureScripts"; //-------------------------------------- function TextureInit() { // Assumes the terrain object is called terrain Texture_operation_menu.clear(); Texture_operation_menu.setText("Placement Operations"); Texture_operation_menu.add("Place by Fractal", 1); Texture_operation_menu.add("Place by Height", 2); Texture_operation_menu.add("Place by Slope", 3); Texture_operation_menu.add("Place by Water Level", 4); $HeightfieldSrcRegister = Heightfield_operation.rowCount()-1; // sync up the preview windows TexturePreview.setValue(HeightfieldPreview.getValue()); %script = terrain.getTextureScript(); if(%script !$= "") Texture::loadFromScript(%script); if (Texture_material.rowCount() == 0) { Texture_operation.clear(); $nextTextureRegister = 1000; } else { // it's difficult to tell if the heightfield was modified so // just in case flag all dependent operations as dirty. %rowCount = Texture_material.rowCount(); for (%row = 0; %row < %rowCount; %row++) { %data = Texture_material.getRowText(%row); %entry= getRecord(%data,0); %reg = getField(%entry,1); $dirtyTexture[ %reg ] = true; %opCount = getRecordCount(%data); for (%op = 2; %op < %opCount; %op++) { %entry= getRecord(%data,%op); %label= getField(%entry,0); if (%label !$= "Place by Fractal" && %label !$= "Fractal Distortion") { %reg = getField(%entry,2); $dirtyTexture[ %reg ] = true; } } } Texture::previewMaterial(); } } function TerraformerTextureGui::refresh(%this) { } //-------------------------------------- function Texture_material_menu::onSelect(%this, %id, %text) { %this.setText("Materials"); // FORMAT // material name // register // operation // name // tab name // register // distortion register // {field,value}, ... // operation // ... Texture::saveMaterial(); Texture::hideTab(); %id = Texture::addMaterial(%text @ "\t" @ $nextTextureRegister++); if (%id != -1) { Texture_material.setSelectedById(%id); Texture::addOperation("Fractal Distortion\ttab_DistortMask\t" @ $nextTextureRegister++ @ "\t0\tdmask_interval\t20\tdmask_rough\t0\tdmask_seed\t" @ terraFormer.generateSeed() @ "\tdmask_filter\t0.00000 0.00000 0.13750 0.487500 0.86250 1.00000 1.00000"); } } function Texture::addMaterialTexture() { %root = filePath(terrain.terrainFile); getLoadFilename("textures/terrain/*.png\ttextures/terrain/*.jpg", addLoadedMaterial); } function addLoadedMaterial(%file) { Texture::saveMaterial(); Texture::hideTab(); %text = fileBase(%file); %id = Texture::addMaterial(%text @ "\t" @ $nextTextureRegister++); if (%id != -1) { Texture_material.setSelectedById(%id); Texture::addOperation("Fractal Distortion\ttab_DistortMask\t" @ $nextTextureRegister++ @ "\t0\tdmask_interval\t20\tdmask_rough\t0\tdmask_seed\t" @ terraFormer.generateSeed() @ "\tdmask_filter\t0.00000 0.00000 0.13750 0.487500 0.86250 1.00000 1.00000"); } Texture::save(); } //-------------------------------------- function Texture_material::onSelect(%this, %id, %text) { Texture::saveMaterial(); if (%id != $selectedMaterial) { $selectedTextureOperation = -1; Texture_operation.clear(); Texture::hideTab(); Texture::restoreMaterial(%id); } %matName = getField(%text, 0); ETerrainEditor.paintMaterial = %matName; Texture::previewMaterial(%id); $selectedMaterial = %id; $selectedTextureOperation = -1; Texture_operation.clearSelection(); } //-------------------------------------- function Texture_operation_menu::onSelect(%this, %id, %text) { %this.setText("Placement Operations"); %id = -1; if ($selectedMaterial == -1) return; %dreg = getField(Texture_operation.getRowText(0),2); switch$ (%text) { case "Place by Fractal": %id = Texture::addOperation("Place by Fractal\ttab_FractalMask\t" @ $nextTextureRegister++ @ "\t" @ %dreg @ "\tfbmmask_interval\t16\tfbmmask_rough\t0.000\tfbmmask_seed\t" @ terraFormer.generateSeed() @ "\tfbmmask_filter\t0.000000 0.166667 0.333333 0.500000 0.666667 0.833333 1.000000\tfBmDistort\ttrue"); case "Place by Height": %id = Texture::addOperation("Place by Height\ttab_HeightMask\t" @ $nextTextureRegister++ @ "\t" @ %dreg @ "\ttextureHeightFilter\t0 0.2 0.4 0.6 0.8 1.0\theightDistort\ttrue"); case "Place by Slope": %id = Texture::addOperation("Place by Slope\ttab_SlopeMask\t" @ $nextTextureRegister++ @ "\t" @ %dreg @ "\ttextureSlopeFilter\t0 0.2 0.4 0.6 0.8 1.0\tslopeDistort\ttrue"); case "Place by Water Level": %id = Texture::addOperation("Place by Water Level\ttab_WaterMask\t" @ $nextTextureRegister++ @ "\t" @ %dreg @ "\twaterDistort\ttrue"); } // select it Texture::hideTab(); if (%id != -1) Texture_operation.setSelectedById(%id); } //-------------------------------------- function Texture_operation::onSelect(%this, %id, %text) { Texture::saveOperation(); if (%id !$= $selectedTextureOperation) { Texture::hideTab(); Texture::restoreOperation(%id); Texture::showTab(%id); } Texture::previewOperation(%id); $selectedTextureOperation = %id; } //-------------------------------------- function Texture::deleteMaterial(%id) { if (%id $= "") %id = $selectedMaterial; if (%id == -1) return; %row = Texture_material.getRowNumById(%id); Texture_material.removeRow(%row); // find the next row to select %rowCount = Texture_material.rowCount()-1; if (%row > %rowCount) %row = %rowCount; if (%id == $selectedMaterial) $selectedMaterial = -1; Texture_operation.clear(); %id = Texture_material.getRowId(%row); Texture_material.setSelectedById(%id); Texture::save(); } //-------------------------------------- function Texture::deleteOperation(%id) { if (%id $= "") %id = $selectedTextureOperation; if (%id == -1) return; %row = Texture_operation.getRowNumById(%id); // don't delete the first entry if (%row == 0) return; Texture_operation.removeRow(%row); // find the next row to select %rowCount = Texture_operation.rowCount()-1; if (%row > %rowCount) %row = %rowCount; if (%id == $selectedTextureOperation) $selectedTextureOperation = -1; %id = Texture_operation.getRowId(%row); Texture_operation.setSelectedById(%id); Texture::save(); } //-------------------------------------- function Texture::applyMaterials() { Texture::saveMaterial(); %count = Texture_material.rowCount(); if (%count > 0) { %data = getRecord(Texture_material.getRowText(0),0); %mat_list = getField( %data, 0); %reg_list = getField( %data, 1); Texture::evalMaterial(Texture_material.getRowId(0)); for (%i=1; %i<%count; %i++) { Texture::evalMaterial(Texture_material.getRowId(%i)); %data = getRecord(Texture_material.getRowText(%i),0); %mat_list = %mat_list @ " " @ getField( %data, 0); %reg_list = %reg_list @ " " @ getField( %data, 1); } terraformer.setMaterials(%reg_list, %mat_list); } } //-------------------------------------- function Texture::previewMaterial(%id) { if (%id $= "") %id = $selectedMaterial; if (%id == -1) return; %data = Texture_material.getRowTextById(%id); %row = Texture_material.getRowNumById(%id); %reg = getField(getRecord(%data,0),1); Texture::evalMaterial(%id); terraformer.preview(TexturePreview, %reg); } //-------------------------------------- function Texture::evalMaterial(%id) { if (%id $= "") %id = $selectedMaterial; if (%id == -1) return; %data = Texture_material.getRowTextbyId(%id); %reg = getField(getRecord(%data,0), 1); // make sure all operation on this material are up to date // and accumulate register data for each %opCount = getRecordCount(%data); if (%opCount >= 2) // record0=material record1=fractal { %entry = getRecord(%data, 1); Texture::evalOperationData(%entry, 1); for (%op=2; %op<%opCount; %op++) { %entry = getRecord(%data, %op); %reg_list = %reg_list @ getField(%entry, 2) @ " "; Texture::evalOperationData(%entry, %op); } // merge the masks in to the dst reg terraformer.mergeMasks(%reg_list, %reg); } Texture::save(); } //-------------------------------------- function Texture::evalOperation(%id) { if (%id $= "") %id = $selectedTextureOperation; if (%id == -1) return; %data = Texture_operation.getRowTextById(%id); %row = Texture_operation.getRowNumById(%id); if (%row != 0) Texture::evalOperation( Texture_operation.getRowId(0) ); Texture::evalOperationData(%data, %row); Texture::save(); } //-------------------------------------- function Texture::evalOperationData(%data, %row) { %label = getField(%data, 0); %reg = getField(%data, 2); %dreg = getField(%data, 3); %id = Texture_material.getRowId(%row); if ( $dirtyTexture[%reg] == false ) { return; } switch$ (%label) { case "Fractal Distortion": terraformer.maskFBm( %reg, getField(%data,5), getField(%data,7), getField(%data,9), getField(%data,11), false, 0 ); case "Place by Fractal": terraformer.maskFBm( %reg, getField(%data,5), getField(%data,7), getField(%data,9), getField(%data,11), getField(%data,13), %dreg ); case "Place by Height": terraformer.maskHeight( $HeightfieldSrcRegister, %reg, getField(%data,5), getField(%data,7), %dreg ); case "Place by Slope": terraformer.maskSlope( $HeightfieldSrcRegister, %reg, getField(%data,5), getField(%data,7), %dreg ); case "Place by Water Level": terraformer.maskWater( $HeightfieldSrcRegister, %reg, getField(%data,5), %dreg ); } $dirtyTexture[%reg] = false; } //-------------------------------------- function Texture::previewOperation(%id) { if (%id $= "") %id = $selectedTextureOperation; if (%id == -1) return; %row = Texture_operation.getRowNumById(%id); %data = Texture_operation.getRowText(%row); %reg = getField(%data,2); Texture::evalOperation(%id); terraformer.preview(TexturePreview, %reg); } //-------------------------------------- function Texture::restoreMaterial(%id) { if (%id == -1) return; %data = Texture_material.getRowTextById(%id); Texture_operation.clear(); %recordCount = getRecordCount(%data); for (%record=1; %record<%recordCount; %record++) { %entry = getRecord(%data, %record); Texture_operation.addRow($nextTextureId++, %entry); } } //-------------------------------------- function Texture::saveMaterial() { %id = $selectedMaterial; if (%id == -1) return; Texture::SaveOperation(); %data = Texture_Material.getRowTextById(%id); %newData = getRecord(%data,0); %rowCount = Texture_Operation.rowCount(); for (%row=0; %row<%rowCount; %row++) %newdata = %newdata @ "\n" @ Texture_Operation.getRowText(%row); Texture_Material.setRowById(%id, %newdata); Texture::save(); } //-------------------------------------- function Texture::restoreOperation(%id) { if (%id == -1) return; %data = Texture_operation.getRowTextById(%id); %fieldCount = getFieldCount(%data); for (%field=4; %field<%fieldCount; %field += 2) { %obj = getField(%data, %field); %obj.setValue( getField(%data, %field+1) ); } Texture::save(); } //-------------------------------------- function Texture::saveOperation() { %id = $selectedTextureOperation; if (%id == -1) return; %data = Texture_operation.getRowTextById(%id); %newData = getField(%data,0) @ "\t" @ getField(%data,1) @ "\t" @ getField(%data,2) @ "\t" @ getField(%data,3); // go through each object and update its value %fieldCount = getFieldCount(%data); for (%field=4; %field<%fieldCount; %field += 2) { %obj = getField(%data, %field); %newdata = %newdata @ "\t" @ %obj @ "\t" @ %obj.getValue(); } %dirty = (%data !$= %newdata); %reg = getField(%data, 2); $dirtyTexture[%reg] = %dirty; Texture_operation.setRowById(%id, %newdata); // mark the material register as dirty too if (%dirty == true) { %data = Texture_Material.getRowTextById($selectedMaterial); %reg = getField(getRecord(%data,0), 1); $dirtyTexture[ %reg ] = true; } // if row is zero the fractal mask was modified // mark everything else in the list as dirty %row = Texture_material.getRowNumById(%id); if (%row == 0) { %rowCount = Texture_operation.rowCount(); for (%r=1; %r<%rowCount; %r++) { %data = Texture_operation.getRowText(%r); $dirtyTexture[ getField(%data,2) ] = true; } } Texture::save(); } //-------------------------------------- function Texture::addMaterial(%entry) { %id = $nextTextureId++; Texture_material.addRow(%id, %entry); %reg = getField(%entry, 1); $dirtyTexture[%reg] = true; Texture::save(); return %id; } //-------------------------------------- function Texture::addOperation(%entry) { // Assumes: operation is being added to selected material %id = $nextTextureId++; Texture_operation.addRow(%id, %entry); %reg = getField(%entry, 2); $dirtyTexture[%reg] = true; Texture::save(); return %id; } //-------------------------------------- function Texture::save() { %script = ""; // loop through each operation and save it to disk %rowCount = Texture_material.rowCount(); for(%row = 0; %row < %rowCount; %row++) { if(%row != 0) %script = %script @ "\n"; %data = expandEscape(Texture_material.getRowText(%row)); %script = %script @ %data; } terrain.setTextureScript(%script); ETerrainEditor.isDirty = true; } //-------------------------------------- function Texture::import() { getLoadFilename("*.ter", "Texture::doLoadTexture"); } function Texture::loadFromScript(%script) { Texture_material.clear(); Texture_operation.clear(); $selectedMaterial = -1; $selectedTextureOperation = -1; %i = 0; for(%rec = getRecord(%script, %i); %rec !$= ""; %rec = getRecord(%script, %i++)) Texture::addMaterial(collapseEscape(%rec)); // initialize dirty register array // patch up register usage // ...and deterime what the next register should be. $nextTextureRegister = 1000; %rowCount = Texture_material.rowCount(); for (%row = 0; %row < %rowCount; %row++) { $dirtyTexture[ $nextTextureRegister ] = true; %data = Texture_material.getRowText(%row); %rec = getRecord(%data, 0); %rec = setField(%rec, 1, $nextTextureRegister); %data = setRecord(%data, 0, %rec); $nextTextureRegister++; %opCount = getRecordCount(%data); for (%op = 1; %op < %opCount; %op++) { if (%op == 1) %frac_reg = $nextTextureRegister; $dirtyTexture[ $nextTextureRegister ] = true; %rec = getRecord(%data,%op); %rec = setField(%rec, 2, $nextTextureRegister); %rec = setField(%rec, 3, %frac_reg); %data = setRecord(%data, %op, %rec); $nextTextureRegister++; } %id = Texture_material.getRowId(%row); Texture_material.setRowById(%id, %data); } $selectedMaterial = -1; Texture_material.setSelectedById(Texture_material.getRowId(0)); } //-------------------------------------- function Texture::doLoadTexture(%name) { // ok, we're getting a terrain file... %newTerr = new TerrainBlock() // unnamed - since we'll be deleting it shortly: { position = "0 0 0"; terrainFile = strip("terrains/", %name); squareSize = 8; visibleDistance = 100; }; if(isObject(%newTerr)) { %script = %newTerr.getTextureScript(); if(%script !$= "") Texture::loadFromScript(%script); %newTerr.delete(); } } //-------------------------------------- function Texture::hideTab() { tab_DistortMask.setVisible(false); tab_FractalMask.setVisible(false); tab_HeightMask.setVisible(false); tab_SlopeMask.setVisible(false); tab_waterMask.setVisible(false); } //-------------------------------------- function Texture::showTab(%id) { Texture::hideTab(); %data = Texture_operation.getRowTextById(%id); %tab = getField(%data,1); %tab.setVisible(true); } function tab_Blend::reset(%this) { blend_option.clear(); blend_option.add("Add", 0); blend_option.add("Subtract", 1); blend_option.add("Max", 2); blend_option.add("Min", 3); blend_option.add("Multiply", 4); } function tab_fBm::reset(%this) { fBm_detail.clear(); fBm_detail.add("Very Low", 0); fBm_detail.add("Low", 1); fBm_detail.add("Normal", 2); fBm_detail.add("High", 3); fBm_detail.add("Very High", 4); } function tab_RMF::reset(%this) { rmf_detail.clear(); rmf_detail.add("Very Low", 0); rmf_detail.add("Low", 1); rmf_detail.add("Normal", 2); rmf_detail.add("High", 3); rmf_detail.add("Very High", 4); } function tab_terrainFile::reset(%this) { // update tab controls.. terrainFile_textList.clear(); %filespec = "terrains/*.ter"; for(%file = findFirstFile(%filespec); %file !$= ""; %file = findNextFile(%filespec)) terrainFile_textList.addRow(%i++, fileBase(%file) @ fileExt(%file)); } function tab_canyon::reset() { } function tab_smooth::reset() { } function tab_smoothWater::reset() { } function tab_smoothRidge::reset() { } function tab_filter::reset() { } function tab_turbulence::reset() { } function tab_thermal::reset() { } function tab_hydraulic::reset() { } function tab_general::reset() { } function tab_bitmap::reset() { } function tab_sinus::reset() { } //-------------------------------------- function Heightfield::resetTabs() { tab_terrainFile.reset(); tab_fbm.reset(); tab_rmf.reset(); tab_canyon.reset(); tab_smooth.reset(); tab_smoothWater.reset(); tab_smoothRidge.reset(); tab_filter.reset(); tab_turbulence.reset(); tab_thermal.reset(); tab_hydraulic.reset(); tab_general.reset(); tab_bitmap.reset(); tab_blend.reset(); tab_sinus.reset(); } //-------------------------------------- function TerraformerInit() { Heightfield_options.clear(); Heightfield_options.setText("Operation"); Heightfield_options.add("fBm Fractal",0); Heightfield_options.add("Rigid MultiFractal",1); Heightfield_options.add("Canyon Fractal",2); Heightfield_options.add("Sinus",3); Heightfield_options.add("Bitmap",4); Heightfield_options.add("Turbulence",5); Heightfield_options.add("Smoothing",6); Heightfield_options.add("Smooth Water",7); Heightfield_options.add("Smooth Ridges/Valleys", 8); Heightfield_options.add("Filter",9); Heightfield_options.add("Thermal Erosion",10); Heightfield_options.add("Hydraulic Erosion",11); Heightfield_options.add("Blend",12); Heightfield_options.add("Terrain File",13); Heightfield::resetTabs(); %script = Terrain.getHeightfieldScript(); if(%script !$= "") Heightfield::loadFromScript(%script); if (Heightfield_operation.rowCount() == 0) { Heightfield_operation.clear(); %id1 = Heightfield::add("General\tTab_general\tgeneral_min_height\t50\tgeneral_scale\t300\tgeneral_water\t0.000\tgeneral_centerx\t0\tgeneral_centery\t0"); Heightfield_operation.setSelectedById(%id1); } Heightfield::resetTabs(); Heightfield::preview(); } //-------------------------------------- function Heightfield_options::onSelect(%this, %_id, %text) { Heightfield_options.setText("Operation"); %id = -1; %rowCount = Heightfield_operation.rowCount(); // FORMAT // item name // tab name // control name // control value switch$(%text) { case "Terrain File": %id = HeightField::add("Terrain File\ttab_terrainFile\tterrainFile_terrFileText\tterrains/terr1.ter\tterrainFile_textList\tterr1.ter"); case "fBm Fractal": %id = Heightfield::add("fBm Fractal\ttab_fBm\tfbm_interval\t9\tfbm_rough\t0.000\tfBm_detail\tNormal\tfBm_seed\t" @ terraformer.generateSeed()); case "Rigid MultiFractal": %id = Heightfield::add("Rigid MultiFractal\ttab_RMF\trmf_interval\t4\trmf_rough\t0.000\trmf_detail\tNormal\trmf_seed\t" @ terraformer.generateSeed()); case "Canyon Fractal": %id = Heightfield::add("Canyon Fractal\ttab_Canyon\tcanyon_freq\t5\tcanyon_factor\t0.500\tcanyon_seed\t" @ terraformer.generateSeed()); case "Sinus": %id = Heightfield::add("Sinus\ttab_Sinus\tsinus_filter\t1 0.83333 0.6666 0.5 0.33333 0.16666 0\tsinus_seed\t" @ terraformer.generateSeed()); case "Bitmap": %id = Heightfield::add("Bitmap\ttab_Bitmap\tbitmap_name\t"); Heightfield::setBitmap(); } if (Heightfield_operation.rowCount() >= 1) { switch$(%text) { case "Smoothing": %id = Heightfield::add("Smoothing\ttab_Smooth\tsmooth_factor\t0.500\tsmooth_iter\t0"); case "Smooth Water": %id = Heightfield::add("Smooth Water\ttab_SmoothWater\twatersmooth_factor\t0.500\twatersmooth_iter\t0"); case "Smooth Ridges/Valleys": %id = Heightfield::add("Smooth Ridges/Valleys\ttab_SmoothRidge\tridgesmooth_factor\t0.8500\tridgesmooth_iter\t1"); case "Filter": %id = Heightfield::add("Filter\ttab_Filter\tfilter\t0 0.16666667 0.3333333 0.5 0.6666667 0.8333333 1"); case "Turbulence": %id = Heightfield::add("Turbulence\ttab_Turbulence\tturbulence_factor\t0.250\tturbulence_radius\t10"); case "Thermal Erosion": %id = Heightfield::add("Thermal Erosion\ttab_Thermal\tthermal_slope\t30\tthermal_cons\t80.0\tthermal_iter\t0"); case "Hydraulic Erosion": %id = Heightfield::add("Hydraulic Erosion\ttab_Hydraulic\thydraulic_iter\t0\thydraulic_filter\t0 0.16666667 0.3333333 0.5 0.6666667 0.8333333 1"); } } if (Heightfield_operation.rowCount() >= 2) { if("Blend" $= %text) %id = Heightfield::add("Blend\ttab_Blend\tblend_factor\t0.500\tblend_srcB\t" @ %rowCount-2 @"\tblend_option\tadd"); } // select it if (%id != -1) Heightfield_operation.setSelectedById(%id); } //-------------------------------------- function Heightfield::eval(%id) { if (%id == -1) return; %data = restWords(Heightfield_operation.getRowTextById(%id)); %label = getField(%data,0); %row = Heightfield_operation.getRowNumById(%id); echo("Heightfield::eval:" @ %row @ " " @ %label ); switch$(%label) { case "General": if (Terrain.squareSize>0) %size = Terrain.squareSize; else %size = 8; terraformer.setTerrainInfo( 256, %size, getField(%data,3), getField(%data,5), getField(%data,7) ); terraformer.setShift( getField(%data,9), getField(%data,11) ); terraformer.terrainData(%row); case "Terrain File": terraformer.terrainFile(%row, getField(%data,3)); case "fBm Fractal": terraformer.fBm( %row, getField(%data,3), getField(%data,5), getField(%data,7), getField(%data,9) ); case "Sinus": terraformer.sinus( %row, getField(%data,3), getField(%data,5) ); case "Rigid MultiFractal": terraformer.rigidMultiFractal( %row, getField(%data,3), getField(%data,5), getField(%data,7), getField(%data,9) ); case "Canyon Fractal": terraformer.canyon( %row, getField(%data,3), getField(%data,5), getField(%data,7) ); case "Smoothing": terraformer.smooth( %row-1, %row, getField(%data,3), getField(%data,5) ); case "Smooth Water": terraformer.smoothWater( %row-1, %row, getField(%data,3), getField(%data,5) ); case "Smooth Ridges/Valleys": terraformer.smoothRidges( %row-1, %row, getField(%data,3), getField(%data,5) ); case "Filter": terraformer.filter( %row-1, %row, getField(%data,3) ); case "Turbulence": terraformer.turbulence( %row-1, %row, getField(%data,3), getField(%data,5) ); case "Thermal Erosion": terraformer.erodeThermal( %row-1, %row, getField(%data,3), getField(%data,5),getField(%data,7) ); case "Hydraulic Erosion": terraformer.erodeHydraulic( %row-1, %row, getField(%data,3), getField(%data,5) ); case "Bitmap": terraformer.loadGreyscale(%row, getField(%data,3)); case "Blend": %rowCount = Heightfield_operation.rowCount(); if(%rowCount > 2) { %a = Heightfield_operation.getRowNumById(%id)-1; %b = getField(%data, 5); echo("Blend: " @ %data); echo("Blend: " @ getField(%data,3) @ " " @ getField(%data,7)); if(%a < %rowCount || %a > 0 || %b < %rowCount || %b > 0 ) terraformer.blend(%a, %b, %row, getField(%data,3), getField(%data,7) ); else echo("Heightfield Editor: Blend parameters out of range."); } } } //-------------------------------------- function Heightfield::add(%entry) { Heightfield::saveTab(); Heightfield::hideTab(); %id = $NextOperationId++; if ($selectedOperation != -1) { %row = Heightfield_operation.getRowNumById($selectedOperation) + 1; %entry = %row @ " " @ %entry; Heightfield_operation.addRow(%id, %entry, %row); // insert // adjust row numbers for(%i = %row+1; %i < Heightfield_operation.rowCount(); %i++) { %id = Heightfield_operation.getRowId(%i); %text = Heightfield_operation.getRowTextById(%id); %text = setWord(%text, 0, %i); Heightfield_operation.setRowById(%id, %text); } } else { %entry = Heightfield_operation.rowCount() @ " " @ %entry; Heightfield_operation.addRow(%id, %entry); // add to end } %row = Heightfield_operation.getRowNumById(%id); if (%row <= $HeightfieldDirtyRow) $HeightfieldDirtyRow = %row; Heightfield::save(); return %id; } //-------------------------------------- function Heightfield::onDelete(%id) { if (%id $= "") %id = $selectedOperation; %row = Heightfield_operation.getRowNumById(%id); // don't delete the first entry if (%row == 0) return; Heightfield_operation.removeRow(%row); // adjust row numbers for(%i = %row; %i < Heightfield_operation.rowCount(); %i++) { %id2 = Heightfield_operation.getRowId(%i); %text = Heightfield_operation.getRowTextById(%id2); %text = setWord(%text, 0, %i); Heightfield_operation.setRowById(%id2, %text); } // adjust the Dirty Row position if ($HeightfieldDirtyRow >= %row) $HeightfieldDirtyRow = %row; // find the next row to select %rowCount = Heightfield_operation.rowCount()-1; if (%row > %rowCount) %row = %rowCount; if (%id == $selectedOperation) $selectedOperation = -1; %id = Heightfield_operation.getRowId(%row); Heightfield_operation.setSelectedById(%id); Heightfield::save(); } //-------------------------------------- function Heightfield_operation::onSelect(%this, %id, %text) { Heightfield::saveTab(); Heightfield::hideTab(); $selectedOperation = %id; Heightfield::restoreTab($selectedOperation); Heightfield::showTab($selectedOperation); Heightfield::preview($selectedOperation); } //-------------------------------------- function Heightfield::restoreTab(%id) { if (%id == -1) return; Heightfield::hideTab(); %data = restWords(Heightfield_operation.getRowTextById(%id)); %fieldCount = getFieldCount(%data); for (%field=2; %field<%fieldCount; %field += 2) { %obj = getField(%data, %field); %obj.setValue( getField(%data, %field+1) ); } Heightfield::save(); } //-------------------------------------- function Heightfield::saveTab() { if ($selectedOperation == -1) return; %data = Heightfield_operation.getRowTextById($selectedOperation); %rowNum = getWord(%data, 0); %data = restWords(%data); %newdata = getField(%data,0) @ "\t" @ getField(%data,1); %fieldCount = getFieldCount(%data); for (%field=2; %field < %fieldCount; %field += 2) { %obj = getField(%data, %field); %newdata = %newdata @ "\t" @ %obj @ "\t" @ %obj.getValue(); } // keep track of the top-most dirty operation // so we know who to evaluate later if (%data !$= %newdata) { %row = Heightfield_operation.getRowNumById($selectedOperation); if (%row <= $HeightfieldDirtyRow && %row > 0) $HeightfieldDirtyRow = %row; } Heightfield_operation.setRowById($selectedOperation, %rowNum @ " " @ %newdata); Heightfield::save(); } //-------------------------------------- function Heightfield::preview(%id) { %rowCount = Heightfield_operation.rowCount(); if (%id $= "") %id = Heightfield_operation.getRowId(%rowCount-1); %row = Heightfield_operation.getRowNumById(%id); Heightfield::refresh(%row); terraformer.previewScaled(HeightfieldPreview, %row); } //-------------------------------------- function Heightfield::refresh(%last) { if (%last $= "") %last = Heightfield_operation.rowCount()-1; // always update the general info Heightfield::eval(Heightfield_operation.getRowId(0)); for( 0; $HeightfieldDirtyRow<=%last; $HeightfieldDirtyRow++) { %id = Heightfield_operation.getRowId($HeightfieldDirtyRow); Heightfield::eval(%id); } Heightfield::save(); } //-------------------------------------- function Heightfield::apply(%id) { %rowCount = Heightfield_operation.rowCount(); if (%rowCount < 1) return; if (%id $= "") %id = Heightfield_operation.getRowId(%rowCount-1); %row = Heightfield_operation.getRowNumById(%id); HeightfieldPreview.setRoot(); Heightfield::refresh(%row); terraformer.setTerrain(%row); terraformer.setCameraPosition(0,0,0); ETerrainEditor.isDirty = true; } //-------------------------------------- $TerraformerSaveRegister = 0; function Heightfield::saveBitmap(%name) { if(%name $= "") getSaveFilename("terrains/heightfield/*png", "Heightfield::doSaveBitmap"); else Heightfield::doSaveBitmap(%name); } function Heightfield::doSaveBitmap(%name) { %name = fileBase(%name) @ fileExt(%name); terraformer.saveGreyscale($TerraformerSaveRegister, "terrains/heightfield/" @ %name); } //-------------------------------------- function Heightfield::save() { %script = ""; %rowCount = Heightfield_operation.rowCount(); for(%row = 0; %row < %rowCount; %row++) { if(%row != 0) %script = %script @ "\n"; %data = restWords(Heightfield_operation.getRowText(%row)); %script = %script @ expandEscape(%data); } echo("Heightfield Script:" @ %script); terrain.setHeightfieldScript(%script); ETerrainEditor.isDirty = true; } //-------------------------------------- function Heightfield::import() { getLoadFilename("*.ter", "Heightfield::doLoadHeightfield"); } //-------------------------------------- function Heightfield::loadFromScript(%script) { echo(%script); Heightfield_operation.clear(); $selectedOperation = -1; $HeightfieldDirtyRow = -1; // zero out all shifting HeightfieldPreview.reset(); for(%rec = getRecord(%script, %i); %rec !$= ""; %rec = getRecord(%script, %i++)) Heightfield::add(collapseEscape(%rec)); if (Heightfield_operation.rowCount() == 0) { // if there was a problem executing the script restore // the operations list to a known state Heightfield_operation.clear(); Heightfield::add("General\tTab_general\tgeneral_min_height\t50\tgeneral_scale\t300\tgeneral_water\t0.000\tgeneral_centerx\t0\tgeneral_centery\t0"); } %data = restWords(Heightfield_operation.getRowText(0)); %x = getField(%data,7); %y = getField(%data,9); HeightfieldPreview.setOrigin(%x, %y); Heightfield_operation.setSelectedById(Heightfield_operation.getRowId(0)); terraformer.setCameraPosition(%x,%y); } //-------------------------------------- //-------------------------------------- function strip(%stripStr, %strToStrip) { %len = strlen(%stripStr); if(strcmp(getSubStr(%strToStrip, 0, %len), %stripStr) == 0) return getSubStr(%strToStrip, %len, 100000); return %strToStrip; } function Heightfield::doLoadHeightfield(%name) { // ok, we're getting a terrain file... %newTerr = new TerrainBlock() // unnamed - since we'll be deleting it shortly: { position = "0 0 0"; terrainFile = strip("terrains/", %name); squareSize = 8; visibleDistance = 100; }; if(isObject(%newTerr)) { %script = %newTerr.getHeightfieldScript(); if(%script !$= "") Heightfield::loadFromScript(%script); %newTerr.delete(); } } //-------------------------------------- function Heightfield::setBitmap() { getLoadFilename("terrains/heightfield/*.png", "Heightfield::doSetBitmap"); } //-------------------------------------- function Heightfield::doSetBitmap(%name) { bitmap_name.setValue(%name); Heightfield::saveTab(); Heightfield::preview($selectedOperation); } //-------------------------------------- function Heightfield::hideTab() { tab_terrainFile.setVisible(false); tab_fbm.setvisible(false); tab_rmf.setvisible(false); tab_canyon.setvisible(false); tab_smooth.setvisible(false); tab_smoothWater.setvisible(false); tab_smoothRidge.setvisible(false); tab_filter.setvisible(false); tab_turbulence.setvisible(false); tab_thermal.setvisible(false); tab_hydraulic.setvisible(false); tab_general.setvisible(false); tab_bitmap.setvisible(false); tab_blend.setvisible(false); tab_sinus.setvisible(false); } //-------------------------------------- function Heightfield::showTab(%id) { Heightfield::hideTab(); %data = restWords(Heightfield_operation.getRowTextById(%id)); %tab = getField(%data,1); echo("Tab data: " @ %data @ " tab: " @ %tab); %tab.setVisible(true); } //-------------------------------------- function Heightfield::center() { %camera = terraformer.getCameraPosition(); %x = getWord(%camera, 0); %y = getWord(%camera, 1); HeightfieldPreview.setOrigin(%x, %y); %origin = HeightfieldPreview.getOrigin(); %x = getWord(%origin, 0); %y = getWord(%origin, 1); %root = HeightfieldPreview.getRoot(); %x += getWord(%root, 0); %y += getWord(%root, 1); general_centerx.setValue(%x); general_centery.setValue(%y); Heightfield::saveTab(); } function ExportHeightfield::onAction() { error("Time to export the heightfield..."); if (Heightfield_operation.getSelectedId() != -1) { $TerraformerSaveRegister = getWord(Heightfield_operation.getValue(), 0); Heightfield::saveBitmap(""); } } //------------------------------------------------------------------------------ // Functions //------------------------------------------------------------------------------ function TerrainEditor::onGuiUpdate(%this, %text) { %mouseBrushInfo = " (Mouse Brush) #: " @ getWord(%text, 0) @ " avg: " @ getWord(%text, 1); %selectionInfo = " (Selection) #: " @ getWord(%text, 2) @ " avg: " @ getWord(%text, 3); TEMouseBrushInfo.setValue(%mouseBrushInfo); TEMouseBrushInfo1.setValue(%mouseBrushInfo); TESelectionInfo.setValue(%selectionInfo); TESelectionInfo1.setValue(%selectionInfo); } function TerrainEditor::offsetBrush(%this, %x, %y) { %curPos = %this.getBrushPos(); %this.setBrushPos(getWord(%curPos, 0) + %x, getWord(%curPos, 1) + %y); } function TerrainEditor::swapInLoneMaterial(%this, %name) { // swapped? if(%this.baseMaterialsSwapped $= "true") { %this.baseMaterialsSwapped = "false"; tEditor.popBaseMaterialInfo(); } else { %this.baseMaterialsSwapped = "true"; %this.pushBaseMaterialInfo(); %this.setLoneBaseMaterial(%name); } // flushTextureCache(); } //------------------------------------------------------------------------------ // Functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function TELoadTerrainButton::onAction(%this) { getLoadFilename("terrains/*.ter", %this @ ".gotFileName"); } function TELoadTerrainButton::gotFileName(%this, %name) { // %pos = "0 0 0"; %squareSize = "8"; %visibleDistance = "1200"; // delete current if(isObject(terrain)) { %pos = terrain.position; %squareSize = terrain.squareSize; %visibleDistance = terrain.visibleDistance; terrain.delete(); } // create new new TerrainBlock(terrain) { position = %pos; terrainFile = %name; squareSize = %squareSize; visibleDistance = %visibleDistance; }; ETerrainEditor.attachTerrain(); } function TerrainEditorSettingsGui::onWake(%this) { TESoftSelectFilter.setValue(ETerrainEditor.softSelectFilter); } function TerrainEditorSettingsGui::onSleep(%this) { ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); } function TESettingsApplyButton::onAction(%this) { ETerrainEditor.softSelectFilter = TESoftSelectFilter.getValue(); ETerrainEditor.resetSelWeights(true); ETerrainEditor.processAction("softSelect"); } function getPrefSetting(%pref, %default) { // if(%pref $= "") return(%default); else return(%pref); } //------------------------------------------------------------------------------ function Editor::open(%this) { // get the defaults %this.getPrefs(); %this.prevContent = Canvas.getContent(); Canvas.setContent(EditorGui); } function Editor::close(%this) { if(%this.prevContent == -1 || %this.prevContent $= "") %this.prevContent = "PlayGui"; Canvas.setContent(%this.prevContent); closeMessageHud(); } //------------------------------------------------------------------------------