2784 lines
83 KiB
C#
2784 lines
83 KiB
C#
//-----------------------------------------------------------------------------
|
|
// 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)
|
|
{
|
|
%this.getPrefs();
|
|
|
|
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", "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("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", "-", 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.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.attachTerrain();
|
|
TerraformerInit();
|
|
TextureInit();
|
|
|
|
//
|
|
Creator.init();
|
|
EditorTree.init();
|
|
ObjectBuilderGui.init();
|
|
|
|
EWorldEditor.isDirty = false;
|
|
ETerrainEditor.isDirty = false;
|
|
ETerrainEditor.isMissionDirty = false;
|
|
EditorGui.saveAs = false;
|
|
}
|
|
|
|
function EditorNewMission()
|
|
{
|
|
if(ETerrainEditor.isMissionDirty || ETerrainEditor.isDirty || EWorldEditor.isDirty)
|
|
{
|
|
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:
|
|
if((EWorldEditor.isDirty || ETerrainEditor.isMissionDirty) && !isWriteableFileName($Server::MissionFile))
|
|
{
|
|
MessageBoxOK("Error", "Mission file \""@ $Server::MissionFile @ "\" is read-only.");
|
|
return false;
|
|
}
|
|
if(ETerrainEditor.isDirty && !isWriteableFileName(Terrain.terrainFile))
|
|
{
|
|
MessageBoxOK("Error", "Terrain file \""@ Terrain.terrainFile @ "\" is read-only.");
|
|
return false;
|
|
}
|
|
|
|
// now write the terrain and mission files out:
|
|
|
|
if(EWorldEditor.isDirty || ETerrainEditor.isMissionDirty)
|
|
MissionGroup.save($Server::MissionFile);
|
|
if(ETerrainEditor.isDirty)
|
|
Terrain.save(Terrain.terrainFile);
|
|
EWorldEditor.isDirty = false;
|
|
ETerrainEditor.isDirty = false;
|
|
ETerrainEditor.isMissionDirty = false;
|
|
EditorGui.saveAs = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
function EditorDoSaveAs(%missionName)
|
|
{
|
|
ETerrainEditor.isDirty = true;
|
|
EWorldEditor.isDirty = true;
|
|
%saveMissionFile = $Server::MissionFile;
|
|
%saveTerrName = Terrain.terrainFile;
|
|
|
|
$Server::MissionFile = %missionName;
|
|
Terrain.terrainFile = filePath(%missionName) @ "/" @ fileBase(%missionName) @ ".ter";
|
|
|
|
if(!EditorSaveMission())
|
|
{
|
|
$Server::MissionFile = %saveMissionFile;
|
|
Terrain.terrainFile = %saveTerrName;
|
|
}
|
|
}
|
|
|
|
function EditorSaveMissionAs()
|
|
{
|
|
getSaveFilename("*.mis", "EditorDoSaveAs", $Server::MissionFile);
|
|
|
|
}
|
|
|
|
function EditorDoLoadMission(%file)
|
|
{
|
|
// close the current editor, it will get cleaned up by MissionCleanup
|
|
Editor.close();
|
|
|
|
loadMission( %file, true ) ;
|
|
|
|
// recreate and open the editor
|
|
Editor::create();
|
|
MissionCleanup.add(Editor);
|
|
EditorGui.loadingMission = true;
|
|
Editor.open();
|
|
}
|
|
|
|
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)
|
|
{
|
|
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...", ETerrainEditor.isDirty || ETerrainEditor.isMissionDirty || EWorldEditor.isDirty);
|
|
}
|
|
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", %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);
|
|
}
|
|
}
|
|
|
|
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 "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();
|
|
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 EditorMenuBar::onWindowMenuItemSelect(%this, %itemId, %item)
|
|
{
|
|
EditorGui.setEditor(%item);
|
|
}
|
|
|
|
function EditorGui::setWorldEditorVisible(%this)
|
|
{
|
|
EWorldEditor.setVisible(true);
|
|
ETerrainEditor.setVisible(false);
|
|
EditorMenuBar.setMenuVisible("World", true);
|
|
EditorMenuBar.setMenuVisible("Action", false);
|
|
EditorMenuBar.setMenuVisible("Brush", false);
|
|
EWorldEditor.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);
|
|
ETerrainEditor.makeFirstResponder(true);
|
|
EPainter.setVisible(false);
|
|
}
|
|
|
|
function EditorGui::setEditor(%this, %editor)
|
|
{
|
|
EditorMenuBar.setMenuItemBitmap("Window", %this.currentEditor, -1);
|
|
EditorMenuBar.setMenuItemBitmap("Window", %editor, 0);
|
|
%this.currentEditor = %editor;
|
|
|
|
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 "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 "5. World Editor";
|
|
case "Mission Area Editor":
|
|
return "6. Mission Area Editor";
|
|
case "Terrain Editor":
|
|
return "7. Terrain Editor";
|
|
case "Terrain Terraform Editor":
|
|
return "8. Terrain Terraform Editor";
|
|
case "Terrain Texture Editor":
|
|
return "9. Terrain Texture Editor";
|
|
case "Terrain Texture Painter":
|
|
return "10. Terrain Texture Painter";
|
|
}
|
|
}
|
|
|
|
|
|
function ETerrainEditor::setPaintMaterial(%this, %matIndex)
|
|
{
|
|
ETerrainEditor.paintMaterial = EPainter.mat[%matIndex];
|
|
}
|
|
|
|
function ETerrainEditor::changeMaterial(%this, %matIndex)
|
|
{
|
|
EPainter.matIndex = %matIndex;
|
|
getLoadFilename("*/terrains/*.png\t*/terrains/*.jpg", EPainterChangeMat);
|
|
}
|
|
|
|
function EPainterChangeMat(%file)
|
|
{
|
|
// make sure the material isn't already in the terrain.
|
|
%file = filePath(%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(fileBase(%mat));
|
|
("ETerrainMaterialBitmap" @ %i).setBitmap(%mat);
|
|
("ETerrainMaterialChange" @ %i).setActive(true);
|
|
("ETerrainMaterialPaint" @ %i).setActive(%mat !$= "");
|
|
if(%mat $= "")
|
|
{
|
|
("ETerrainMaterialChange" @ %i).setText("Add...");
|
|
if(%valid)
|
|
%valid = false;
|
|
else
|
|
("ETerrainMaterialChange" @ %i).setActive(false);
|
|
}
|
|
else
|
|
("ETerrainMaterialChange" @ %i).setText("Change...");
|
|
}
|
|
ETerrainMaterialPaint0.performClick();
|
|
}
|
|
|
|
function EditorGui::onWake(%this)
|
|
{
|
|
MoveMap.push();
|
|
EditorMap.push();
|
|
%this.setEditor(%this.currentEditor);
|
|
// sorry nothing
|
|
$alwaysDisqualify = 1;
|
|
}
|
|
|
|
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);
|
|
ECreateSubsBtn.setVisible(%obj.getClassName() $= "InteriorInstance");
|
|
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 WorldEditor::createSubs(%this)
|
|
{
|
|
for(%i = 0; %i < %this.getSelectionSize(); %i++)
|
|
{
|
|
%obj = %this.getSelectedObject(%i);
|
|
if(%obj.getClassName() $= "InteriorInstance")
|
|
%obj.magicButton();
|
|
}
|
|
}
|
|
|
|
function WorldEditor::init(%this)
|
|
{
|
|
// add objclasses which we do not want to collide with
|
|
%this.ignoreObjClass(TerrainBlock, Sky, AIObjective);
|
|
|
|
// editing modes
|
|
%this.numEditModes = 3;
|
|
%this.editMode[0] = "move";
|
|
%this.editMode[1] = "rotate";
|
|
%this.editMode[2] = "scale";
|
|
|
|
// 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::onClick( %this, %obj )
|
|
{
|
|
Inspector.inspect( %obj );
|
|
ECreateSubsBtn.setVisible(%obj.getClassName() $= "InteriorInstance");
|
|
InspectorNameEdit.setValue( %obj.getName() );
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
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)
|
|
{
|
|
exec("~/editor/" @ %file);
|
|
}
|
|
|
|
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();
|
|
|
|
$InstantGroup = "MissionGroup";
|
|
|
|
// ---------- INTERIORS
|
|
%base = %this.addGroup( 0, "Interiors" );
|
|
|
|
// walk all the interiors and add them to the correct group
|
|
%interiorId = "";
|
|
%file = findFirstFile( "*.dif" );
|
|
|
|
while( %file !$= "" )
|
|
{
|
|
// Determine which group to put the file in
|
|
// and build the group heirarchy as we go
|
|
%split = strreplace(%file, "/", " ");
|
|
%dirCount = getWordCount(%split)-1;
|
|
%parentId = %base;
|
|
|
|
for(%i=0; %i<%dirCount; %i++)
|
|
{
|
|
%parent = getWords(%split, 0, %i);
|
|
// if the group doesn't exist create it
|
|
if ( !%interiorId[%parent] )
|
|
%interiorId[%parent] = %this.addGroup( %parentId, getWord(%split, %i));
|
|
%parentId = %interiorId[%parent];
|
|
}
|
|
// Add the file to the group
|
|
%create = "createInterior(" @ "\"" @ %file @ "\"" @ ");";
|
|
%this.addItem( %parentId, fileBase( %file ), %create );
|
|
|
|
%file = findNextFile( "*.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);
|
|
echo ("Obj: " @ %obj.getName() @ " - " @ %obj.category );
|
|
if(%obj.category !$= "" || %obj.category != 0)
|
|
{
|
|
%grp = %this.addGroup(%base, %obj.category);
|
|
%this.addItem(%grp, %obj.getName(), %obj.getClassName() @ "::create(" @ %obj.getName() @ ");");
|
|
}
|
|
}
|
|
|
|
|
|
// ---------- Static Shapes
|
|
%base = %this.addGroup( 0, "Static Shapes" );
|
|
|
|
// walk all the statics and add them to the correct group
|
|
%staticId = "";
|
|
%file = findFirstFile( "*.dts" );
|
|
while( %file !$= "" )
|
|
{
|
|
// Determine which group to put the file in
|
|
// and build the group heirarchy as we go
|
|
%split = strreplace(%file, "/", " ");
|
|
%dirCount = getWordCount(%split)-1;
|
|
%parentId = %base;
|
|
|
|
for(%i=0; %i<%dirCount; %i++)
|
|
{
|
|
%parent = getWords(%split, 0, %i);
|
|
// if the group doesn't exist create it
|
|
if ( !%staticId[%parent] )
|
|
%staticId[%parent] = %this.addGroup( %parentId, getWord(%split, %i));
|
|
%parentId = %staticId[%parent];
|
|
}
|
|
// Add the file to the group
|
|
%create = "TSStatic::create(\"" @ %file @ "\");";
|
|
%this.addItem( %parentId, fileBase( %file ), %create );
|
|
|
|
%file = findNextFile( "*.dts" );
|
|
}
|
|
|
|
|
|
// *** 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] = "Marker";
|
|
%Mission_Item[2] = "Trigger";
|
|
%Mission_Item[3] = "PhysicalZone";
|
|
%Mission_Item[4] = "Camera";
|
|
//%Mission_Item[5] = "GameType";
|
|
//%Mission_Item[6] = "Forcefield";
|
|
|
|
%System_Item[0] = "SimGroup";
|
|
|
|
//%AI_Item[0] = "Objective";
|
|
//%AI_Item[1] = "NavigationGraph";
|
|
|
|
// objects group
|
|
%base = %this.addGroup(0, "Mission 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("*/terrains/*.png\t*/terrains/*.jpg", addLoadedMaterial);
|
|
}
|
|
|
|
function addLoadedMaterial(%file)
|
|
{
|
|
Texture::saveMaterial();
|
|
Texture::hideTab();
|
|
%text = filePath(%file) @ "/" @ 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 = %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);
|
|
}
|
|
|
|
|
|
|
|
$TerraformerHeightfieldDir = "common/editor/heightScripts";
|
|
|
|
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 = $TerraformerHeightfieldDir @ "/*.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,true);
|
|
|
|
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("*.png", "Heightfield::doSaveBitmap",
|
|
$TerraformerHeightfieldDir @ "/" @ fileBase($Client::MissionFile) @ ".png");
|
|
else
|
|
Heightfield::doSaveBitmap(%name);
|
|
}
|
|
|
|
function Heightfield::doSaveBitmap(%name)
|
|
{
|
|
terraformer.saveGreyscale($TerraformerSaveRegister, %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);
|
|
}
|
|
terrain.setHeightfieldScript(%script);
|
|
ETerrainEditor.isDirty = true;
|
|
}
|
|
|
|
//--------------------------------------
|
|
function Heightfield::import()
|
|
{
|
|
getLoadFilename("*.ter", "Heightfield::doLoadHeightfield");
|
|
}
|
|
|
|
|
|
//--------------------------------------
|
|
function Heightfield::loadFromScript(%script,%leaveCamera)
|
|
{
|
|
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));
|
|
|
|
// Move the control object to the specified position
|
|
if (!%leaveCamera)
|
|
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 -1000";
|
|
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($TerraformerHeightfieldDir @ "/*.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)
|
|
{
|
|
%this.prevContent = Canvas.getContent();
|
|
|
|
Canvas.setContent(EditorGui);
|
|
}
|
|
|
|
function Editor::close(%this)
|
|
{
|
|
if(%this.prevContent == -1 || %this.prevContent $= "")
|
|
%this.prevContent = "PlayGui";
|
|
|
|
Canvas.setContent(%this.prevContent);
|
|
|
|
MessageHud.close();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|