From 9c654d79325a24e493fa3c53b77e0c7cd92fb32c Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 25 Aug 2025 23:35:28 -0500 Subject: [PATCH 1/2] - Fixes the display of the preview in the MaterialAsset fields - Hides the special-case direct filepath field for ShapeAsset persist fields macro - Shifts the handling of TSStatics so the shape instance will load materials on the server as well as the client. This opens gameplay options as well as allowing rebaking of meshes functionality more easily - Expands AssetBase's isValidAsset utility function to actually check validity instead of just returning true - Adds isValid utility function to AssetPtr - Added new field flag that makes the field not write out to file - Removed legacy iconBitmap field from GuiIconButtonCtrl because it was causing errors - Fixed group filtering check of guiInspector to ignore case - Removed unneeded isFile checks for common datablock script files in Prototyping module script - Removed test datablocks from Prototyping module - Removed unnecessary container control from AssetBrowser - Adjusted preview regen logic of AssetBrowser so it doesn't trip if you're simply resizing the window - Fixed issue where row-vs-column layout logic for AssetBrowser when resizing window was fiddly - Added handling for when Dragging and Dropping datablock from AssetBrowser to spawn, it'll prompt if it spawns the actual object, or a spawnsphere that spawns said object. In the event of an PlayerData will also prompt if it should spawn an AIPlayer - Added ability to take a TSStatic that uses a baked down mesh and are able to restore it to the cache prefab, or trigger and in-place rebake to refresh it if something has changed in the original contents via RMB menu on the scene tree - Added ability to explode prefab to RMB menu on scene tree - Added ability to convert selection to prefab or bake to mesh in RMB menu on scene tree - Tweaked sizing of the DatablockEditorCreatePrompt window to not have cut off elements and easier to see/work with - Added sanity check to datablock editor creation - Fixed preview display of material in Decal Editor - Made compositeTextureEditor use the cached preview of images - Fixed sizing/spacing of gui selection dropdown as well as resolution dropdown of GuiEditor - Fixes MaterialEditor to properly save the group collapse state when editing - Adds ability to in-flow edit and create datablocks in the NavMesh Editor for the testing panel, and makes the datablock dropdown searchable - Fixed issue where opening the ShapeEditor via the edit button on a ShapeAsset field would cause the action buttons on the top bar to not show - Fixed error in shape editor where when exiting it was erroneously checking for a clear value of -1 rather than 0 - Removed unneeded top tabbook and tab page for main editor panel - Fixed issue where reset button of TerrainBrush Softness Curve editor didn't actually reset - Resized Object Builder window to not cut off elements and have enough width to show more data - Added a TypeCommand field type to Object Builder and changed spawnscript field of SpawnSphere to use it rather than a simple text edit field - Allow SpawnSphere in ObjectBuilder to be passed in spawn class and spawn datablock default info - Injects button to controllable objects when Inspecting them to make it easy to toggle if you're in control of it or not - --- Engine/source/T3D/assets/MaterialAsset.cpp | 44 ++- Engine/source/T3D/assets/ShapeAsset.h | 2 +- Engine/source/T3D/tsStatic.cpp | 16 +- Engine/source/assets/assetBase.h | 5 +- Engine/source/assets/assetPtr.h | 1 + Engine/source/console/consoleObject.h | 3 +- Engine/source/console/persistenceManager.cpp | 2 +- Engine/source/console/simObject.cpp | 2 +- .../source/gui/buttons/guiIconButtonCtrl.cpp | 1 - Engine/source/gui/editor/guiInspector.cpp | 4 +- .../game/data/Prototyping/Prototyping.tscript | 15 +- .../managedData/managedDatablocks.tscript | 57 +-- .../tools/assetBrowser/guis/assetBrowser.gui | 56 +-- .../assetBrowser/scripts/assetBrowser.tscript | 20 +- .../assetTypes/datablockObjects.tscript | 84 ++++- .../scripts/assetTypes/prefab.tscript | 74 +++- .../DatablockEditorCreatePrompt.ed.gui | 12 +- .../datablockEditor/datablockEditor.tscript | 12 +- .../tools/decalEditor/decalEditorGui.tscript | 31 +- .../tools/gui/compositeTextureEditor.tscript | 4 +- .../fieldTypes/toggleControlButton.tscript | 46 +++ .../game/tools/gui/guiDialogs.ed.tscript | 1 + .../game/tools/gui/saveChangesMBDlg.ed.gui | 4 +- .../game/tools/guiEditor/gui/guiEditor.ed.gui | 13 +- .../scripts/guiEditorToolbox.ed.tscript | 4 +- .../scripts/materialEditor.ed.tscript | 1 + .../game/tools/navEditor/NavEditorGui.gui | 59 +++- .../game/tools/navEditor/navEditor.tscript | 20 ++ .../game/tools/shapeEditor/main.tscript | 6 +- .../scripts/shapeEditor.ed.tscript | 2 +- .../tools/worldEditor/gui/EditorGui.ed.gui | 25 +- .../gui/TerrainBrushSoftnessCurveDlg.ed.gui | 2 +- .../worldEditor/gui/objectBuilderGui.ed.gui | 329 ++++++++++++------ .../worldEditor/scripts/EditorGui.ed.tscript | 30 +- .../scripts/editors/creator.ed.tscript | 10 +- .../scripts/editors/worldEditor.ed.tscript | 9 + .../scripts/menuHandlers.ed.tscript | 68 ++-- 37 files changed, 728 insertions(+), 346 deletions(-) create mode 100644 Templates/BaseGame/game/tools/gui/fieldTypes/toggleControlButton.tscript diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index 9bb30145d..8c40b9779 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -599,20 +599,42 @@ void GuiInspectorTypeMaterialAssetPtr::updateValue() void GuiInspectorTypeMaterialAssetPtr::updatePreviewImage() { - const char* previewImage; + const char* matAssetId; if (mInspector->getInspectObject() != nullptr) - previewImage = mInspector->getInspectObject()->getDataField(mCaption, NULL); + matAssetId = mInspector->getInspectObject()->getDataField(mCaption, NULL); else - previewImage = Con::getVariable(mVariableName); + matAssetId = Con::getVariable(mVariableName); //if what we're working with isn't even a valid asset, don't present like we found a good one - if (!AssetDatabase.isDeclaredAsset(previewImage)) + if (!AssetDatabase.isDeclaredAsset(matAssetId)) { - mPreviewImage->_setBitmap(StringTable->EmptyString()); + mPreviewImage->_setBitmap(StringTable->insert("Core_Rendering:NoMaterial")); return; } - String matPreviewAssetId = String(previewImage) + "_PreviewImage"; + AssetPtr matAssetDef = matAssetId; + if (matAssetDef.isNull() || matAssetDef->getStatus() != AssetBase::AssetErrCode::Ok || + matAssetDef->getMaterialDefinitionName() == StringTable->EmptyString()) + { + mPreviewImage->_setBitmap(StringTable->insert("Core_Rendering:WarningMaterial")); + return; + } + + Material* matDef; + if (!Sim::findObject(matAssetDef->getMaterialDefinitionName(), matDef)) + { + mPreviewImage->_setBitmap(StringTable->insert("Core_Rendering:WarningMaterial")); + return; + } + + AssetPtr difMapAsset = matDef->getDiffuseMapAsset(0); + if (difMapAsset.isNull() || difMapAsset->getStatus() != AssetBase::AssetErrCode::Ok) + { + mPreviewImage->_setBitmap(StringTable->insert("Core_Rendering:WarningMaterial")); + return; + } + + String matPreviewAssetId = String(difMapAsset->getAssetName()) + "_PreviewImage"; matPreviewAssetId.replace(":", "_"); matPreviewAssetId = "ToolsModule:" + matPreviewAssetId; if (AssetDatabase.isDeclaredAsset(matPreviewAssetId.c_str())) @@ -621,18 +643,14 @@ void GuiInspectorTypeMaterialAssetPtr::updatePreviewImage() } else { - if (AssetDatabase.isDeclaredAsset(previewImage)) + if (AssetDatabase.isDeclaredAsset(difMapAsset->getAssetId())) { - MaterialAsset* matAsset = AssetDatabase.acquireAsset(previewImage); - if (matAsset && matAsset->getMaterialDefinition()) - { - mPreviewImage->_setBitmap(matAsset->getMaterialDefinition()->_getDiffuseMap(0)); - } + mPreviewImage->setBitmap(difMapAsset->getAssetId()); } } if (mPreviewImage->getBitmapAsset().isNull()) - mPreviewImage->_setBitmap(StringTable->insert("ToolsModule:genericAssetIcon_image")); + mPreviewImage->setBitmap(StringTable->insert("ToolsModule:genericAssetIcon_image")); } void GuiInspectorTypeMaterialAssetPtr::setPreviewImage(StringTableEntry assetId) diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 2328280da..55178160c 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -360,7 +360,7 @@ public: #define INITPERSISTFIELD_SHAPEASSET_REFACTOR(name, consoleClass, docs) \ addProtectedField(assetText(name, Asset), TypeShapeAssetPtr, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.)); \ - addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.)); + addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.), AbstractClassRep::FIELD_HideInInspectors); #define DECLARE_SHAPEASSET_ARRAY_REFACTOR(className, name, max) \ diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 1c74b6287..7f82408ea 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -400,7 +400,7 @@ bool TSStatic::_createShape() mObjBox = getShape()->mBounds; resetWorldBox(); - mShapeInstance = new TSShapeInstance(getShape(), isClientObject()); + mShapeInstance = new TSShapeInstance(getShape(), true); mShapeInstance->resetMaterialList(); mShapeInstance->cloneMaterialList(); @@ -711,7 +711,7 @@ void TSStatic::_updateShouldTick() void TSStatic::prepRenderImage(SceneRenderState* state) { - if (!mShapeInstance) + if (!mShapeAsset.isValid() || !mShapeInstance) return; Point3F cameraOffset; @@ -1326,27 +1326,25 @@ bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const B } //Next, process the LOD levels and materials. - if (isServerObject() && getClientObject()) + if (isServerObject()) { - TSStatic* clientShape = dynamic_cast(getClientObject()); - exportData->meshData.increment(); //Prep a meshData for this shape in particular ColladaUtils::ExportData::meshLODData* meshData = &exportData->meshData.last(); //Fill out the info we'll need later to actually append our mesh data for the detail levels during the processing phase - meshData->shapeInst = clientShape->mShapeInstance; + meshData->shapeInst = mShapeInstance; meshData->originatingObject = this; meshData->meshTransform = mObjToWorld; meshData->scale = mObjScale; //Iterate over all our detail levels - for (U32 i = 0; i < clientShape->mShapeInstance->getNumDetails(); i++) + for (U32 i = 0; i < mShapeInstance->getNumDetails(); i++) { - TSShape::Detail detail = clientShape->mShapeInstance->getShape()->details[i]; + TSShape::Detail detail = mShapeInstance->getShape()->details[i]; - String detailName = String::ToLower(clientShape->mShapeInstance->getShape()->getName(detail.nameIndex)); + String detailName = String::ToLower(mShapeInstance->getShape()->getName(detail.nameIndex)); //Skip it if it's a collision or line of sight element if (detailName.startsWith("col") || detailName.startsWith("los")) diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index fe14c7729..fa62065bc 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -123,7 +123,10 @@ public: StringTableEntry expandAssetFilePath(const char* pAssetFilePath) const; StringTableEntry collapseAssetFilePath(const char* pAssetFilePath) const; - virtual bool isAssetValid(void) const { return true; } + virtual bool isAssetValid(void) const + { + return mpOwningAssetManager != nullptr && mAssetInitialized && (mLoadedState == AssetErrCode::Ok || mLoadedState == AssetErrCode::UsingFallback); + } void refreshAsset(void); diff --git a/Engine/source/assets/assetPtr.h b/Engine/source/assets/assetPtr.h index d30b822d9..5d5f4173f 100644 --- a/Engine/source/assets/assetPtr.h +++ b/Engine/source/assets/assetPtr.h @@ -179,6 +179,7 @@ public: /// Validity. bool isNull( void ) const override { return mpAsset.isNull(); } bool notNull( void ) const override { return !mpAsset.isNull(); } + bool isValid(void) const { return notNull() && static_cast(mpAsset.getObject())->isAssetValid(); } }; #endif // _ASSET_PTR_H_ diff --git a/Engine/source/console/consoleObject.h b/Engine/source/console/consoleObject.h index 9995dc2aa..2d5586613 100644 --- a/Engine/source/console/consoleObject.h +++ b/Engine/source/console/consoleObject.h @@ -498,7 +498,8 @@ public: FIELD_ComponentInspectors = BIT(1), ///< Custom fields used by components. They are likely to be non-standard size/configuration, so ///< They are handled specially FIELD_CustomInspectors = BIT(2), ///< Display as a button in inspectors. - FIELD_SpecialtyArrayField = BIT(3) + FIELD_SpecialtyArrayField = BIT(3), + FIELD_DontWriteToFile = BIT(4), }; struct Field diff --git a/Engine/source/console/persistenceManager.cpp b/Engine/source/console/persistenceManager.cpp index 30c01ff06..0c12b11d5 100644 --- a/Engine/source/console/persistenceManager.cpp +++ b/Engine/source/console/persistenceManager.cpp @@ -1383,7 +1383,7 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj const AbstractClassRep::Field* f = &list[i]; // Skip the special field types. - if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors) || f->flag.test(AbstractClassRep::FieldFlags::FIELD_DontWriteToFile)) continue; if (f->flag.test(AbstractClassRep::FIELD_SpecialtyArrayField)) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index cabafe466..cfcbbd72b 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -372,7 +372,7 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) const AbstractClassRep::Field* f = &list[i]; // Skip the special field types. - if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + if ( f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors) || f->flag.test(AbstractClassRep::FieldFlags::FIELD_DontWriteToFile)) continue; for(U32 j = 0; S32(j) < f->elementCount; j++) diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index 44cb8e2b5..813a3a2e2 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -126,7 +126,6 @@ void GuiIconButtonCtrl::initPersistFields() docsURL; addField( "buttonMargin", TypePoint2I, Offset( mButtonMargin, GuiIconButtonCtrl ),"Margin area around the button.\n"); - addProtectedField( "iconBitmap", TypeImageFilename, Offset( mBitmapAsset, GuiIconButtonCtrl ), &_setBitmapData, &defaultProtectedGetFn, "Bitmap file for the icon to display on the button.\n", AbstractClassRep::FIELD_HideInInspectors); INITPERSISTFIELD_IMAGEASSET(Bitmap, GuiIconButtonCtrl, "Bitmap file for the icon to display on the button.\n"); addField( "iconLocation", TYPEID< IconLocation >(), Offset( mIconLocation, GuiIconButtonCtrl ),"Where to place the icon on the control. Options are 0 (None), 1 (Left), 2 (Right), 3 (Center).\n"); diff --git a/Engine/source/gui/editor/guiInspector.cpp b/Engine/source/gui/editor/guiInspector.cpp index 1b231a5ec..45db16a91 100644 --- a/Engine/source/gui/editor/guiInspector.cpp +++ b/Engine/source/gui/editor/guiInspector.cpp @@ -501,7 +501,7 @@ bool GuiInspector::isGroupFiltered( const char *groupName ) const // Is this group explicitly show? Does it immediately follow a + char. searchStr = String::ToString( "+%s", groupName ); - if ( mGroupFilters.find( searchStr ) != String::NPos ) + if ( mGroupFilters.find( searchStr, 0, String::NoCase | String::Left) != String::NPos ) return false; // Were there any other + characters, if so, we are implicitly hidden. @@ -510,7 +510,7 @@ bool GuiInspector::isGroupFiltered( const char *groupName ) const // Is this group explicitly hidden? Does it immediately follow a - char. searchStr = String::ToString( "-%s", groupName ); - if ( mGroupFilters.find( searchStr ) != String::NPos ) + if ( mGroupFilters.find( searchStr, 0, String::NoCase | String::Left) != String::NPos ) return true; return false; diff --git a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript b/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript index e2c8b407a..9ea6b613e 100644 --- a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript @@ -17,16 +17,11 @@ function Prototyping::onCreateGameServer(%this) //These are common managed data files. For any datablock-based stuff that gets generated by the editors //(that doesn't have a specific associated file, like data for a player class) will go into these. //So we'll register them now if they exist. - if(isFile("./scripts/managedData/managedDatablocks." @ $TorqueScriptFileExtension)) - %this.registerDatablock("./scripts/managedData/managedDatablocks"); - if(isFile("./scripts/managedData/managedForestItemData." @ $TorqueScriptFileExtension)) - %this.registerDatablock("./scripts/managedData/managedForestItemData"); - if(isFile("./scripts/managedData/managedForestBrushData." @ $TorqueScriptFileExtension)) - %this.registerDatablock("./scripts/managedData/managedForestBrushData"); - if(isFile("./scripts/managedData/managedParticleEmitterData." @ $TorqueScriptFileExtension)) - %this.registerDatablock("./scripts/managedData/managedParticleEmitterData"); - if(isFile("./scripts/managedData/managedParticleData." @ $TorqueScriptFileExtension)) - %this.registerDatablock("./scripts/managedData/managedParticleData"); + %this.registerDatablock("./scripts/managedData/managedDatablocks"); + %this.registerDatablock("./scripts/managedData/managedForestItemData"); + %this.registerDatablock("./scripts/managedData/managedForestBrushData"); + %this.registerDatablock("./scripts/managedData/managedParticleEmitterData"); + %this.registerDatablock("./scripts/managedData/managedParticleData"); } //This is called when the server is shut down due to the game/map being exited diff --git a/Templates/BaseGame/game/data/Prototyping/scripts/managedData/managedDatablocks.tscript b/Templates/BaseGame/game/data/Prototyping/scripts/managedData/managedDatablocks.tscript index e73435b9b..f92918a1f 100644 --- a/Templates/BaseGame/game/data/Prototyping/scripts/managedData/managedDatablocks.tscript +++ b/Templates/BaseGame/game/data/Prototyping/scripts/managedData/managedDatablocks.tscript @@ -3,59 +3,4 @@ datablock ItemData(PrototypeItemData) { ShapeAsset = "Prototyping:TorusPrimitive_shape"; cameraMaxDist = "0.75"; -}; - -datablock PlayerData( ProtoPlayer ) { - // Third person shape - ShapeAsset = "Prototyping:Playerbot_shape"; - controlMap = "playerKeyMap"; - AIControllerData = "aiPlayerControl"; -}; - -datablock WheeledVehicleTire(ProtoCarTire) -{ - // Tires act as springs and generate lateral and longitudinal - // forces to move the vehicle. These distortion/spring forces - // are what convert wheel angular velocity into forces that - // act on the rigid body. - shapeAsset = "Prototyping:carwheel_shape"; - - staticFriction = 1; - kineticFriction = 4.2; - - // Spring that generates lateral tire forces - lateralForce = 150000; - lateralDamping = 30000; - lateralRelaxation = 0.1; - - // Spring that generates longitudinal tire forces - longitudinalForce = 600; - longitudinalDamping = 1600; - longitudinalRelaxation = 0.1; -}; - -datablock WheeledVehicleSpring(ProtoCarSpring) -{ - // Wheel suspension properties - length = "0.6"; // Suspension travel - force = 3600; // Spring force - damping = 2800; // Spring damping - antiSwayForce = 300; // Lateral anti-sway force -}; - -datablock WheeledVehicleData(ProtoCar) -{ - category = "Vehicles"; - shapeAsset = "Prototyping:car_shape"; - - collisionMul = 0; - impactMul = 0; - controlMap = "vehicleKeyMap"; - AIControllerData = "aiCarControl"; - cameraMaxDist = "2.81993"; - ShapeFile = "data/Prototyping/shapes/Vehicles/car.dae"; - mass = "1000"; - originalAssetName = "ProtoCar"; - massCenter = "0 0.75 0"; - dragForce = "0.1"; -}; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui index 963091338..b6749d818 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui +++ b/Templates/BaseGame/game/tools/assetBrowser/guis/assetBrowser.gui @@ -972,57 +972,33 @@ $guiContent = new GuiControl(AssetBrowser) { canSave = "1"; canSaveDynamicFields = "0"; }; - new GuiStackControl() { - stackingType = "Vertical"; - horizStacking = "Left to Right"; - vertStacking = "Top to Bottom"; - padding = "0"; + + new GuiDynamicCtrlArrayControl() { + colCount = "4"; + colSize = "100"; + rowCount = "1"; + rowSize = "120"; + rowSpacing = "2"; + colSpacing = "2"; + frozen = "0"; + autoCellSize = "1"; + fillRowFirst = "1"; dynamicSize = "1"; - dynamicNonStackExtent = "0"; - dynamicPos = "0"; - changeChildSizeToFit = "1"; - changeChildPosition = "0"; - position = "2 2"; + padding = "0 0 0 0"; + position = "3 0"; extent = "414 120"; - minExtent = "16 16"; + minExtent = "8 8"; horizSizing = "width"; vertSizing = "bottom"; - profile = "ToolsGuiModelessDialogProfile"; + profile = "ToolsGuiDefaultNonModalProfile"; visible = "1"; active = "1"; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; + internalName = "assetList"; canSave = "1"; canSaveDynamicFields = "0"; - - new GuiDynamicCtrlArrayControl() { - colCount = "4"; - colSize = "100"; - rowCount = "1"; - rowSize = "120"; - rowSpacing = "2"; - colSpacing = "2"; - frozen = "0"; - autoCellSize = "1"; - fillRowFirst = "1"; - dynamicSize = "1"; - padding = "0 0 0 0"; - position = "3 0"; - extent = "414 120"; - minExtent = "8 8"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultNonModalProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - internalName = "assetList"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; }; }; new GuiContainer() { diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index 99fa7fdea..86a1b6642 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -778,9 +778,12 @@ function AssetBrowser::buildAssetPreview( %this, %asset, %moduleName ) AssetPreviewArray.add( %previewButton ); } -function AssetBrowser::refresh(%this) +function AssetBrowser::refresh(%this, %regenPreviews) { - if(!%this.dirty) + if(%regenPreviews $= "") + %regenPreviews = true; + + if(!%this.dirty && %regenPreviews) { %this.dirty = true; @@ -839,7 +842,7 @@ function AssetPreviewButton::onDoubleClick(%this) function assetBrowserPreviewSlider::onMouseDragged(%this) { EditorSettings.setValue("Assets/Browser/previewTileSize", %this.getValue()); - AssetBrowser.refresh(); + AssetBrowser.refresh(false); } function AssetBrowser::loadDirectories( %this ) @@ -2417,7 +2420,7 @@ function AssetBrowserPreviewButton::onMouseDragged(%this) Canvas.repaint(); } -function AssetBrowserPreviewButton::onControlDragCancelled(%this) +function AssetPreviewControlType_AssetDrop::onControlDragCancelled(%this) { Canvas.popDialog(EditorDragAndDropLayer); } @@ -2852,8 +2855,15 @@ function AssetBrowserWindow::releasePanel(%this) function AssetBrowserWindow::onResize(%this, %posX, %posY, %width, %height) { if (%width>%height) + { AssetBrowser-->assetList.fillRowFirst = true; + AssetBrowser-->assetList.extent.x = AssetListPanel.extent.x; + } else + { AssetBrowser-->assetList.fillRowFirst = false; - AssetBrowser.rebuildAssetArray(); + AssetBrowser-->assetList.extent.y = AssetListPanel.extent.y; + } + + //AssetBrowser.rebuildAssetArray(); } diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.tscript index d46aeac57..0bdd92dc4 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/datablockObjects.tscript @@ -16,7 +16,6 @@ function DatablockObjectType::onEdit(%this, %className) function DatablockObjectType::buildBrowserElement(%this, %className, %previewData) { - echo("DatablockObjectType::buildBrowserElement() - " @ %this @ ", " @ %previewData); %previewData.assetName = %this.getName(); %previewData.assetPath = %this.getFileName(); @@ -71,19 +70,92 @@ function DatablockObjectType::onShowActionMenu(%this, %className) $CurrentAssetBrowser.popupMenu = EditDatablockObjectTypePopup; } -function spawnDatablockObject(%datablock) +function spawnDatablockObject(%datablock, %position) { %name = %datablock.getName(); %class = %datablock.getClassName(); %cmd = %class @ "::create(" @ %name @ ");"; - %shapePath = ( %datablock.shapeAsset !$= "" ) ? %datablock.shapeFile : %datablock.shapeName; %createCmd = "ObjectCreator.createObject( \"" @ %cmd @ "\" );"; - return eval(%createCmd);//eval("showImportDialog( \"" @ %shapePath @ "\", \"" @ %createCmd @ "\" );"); + %newObject = eval(%createCmd); + + if(%position !$= "") + %newObject.position = %position; + + return %newObject; +} + +function spawnAIObject(%datablock, %position) +{ + %name = %datablock.getName(); + + %class = %datablock.getClassName(); + %class = strreplace(%class, "Data", ""); + + %cmd = "AI" @ %class @ "::create(" @ %name @ ");"; + + %createCmd = "ObjectCreator.createObject( \"" @ %cmd @ "\" );"; + %newObject = eval(%createCmd); + + if(%position !$= "") + %newObject.position = %position; + + return %newObject; +} + +function spawnSpawnMarker(%datablock, %position) +{ + %class = %datablock.getClassName(); + %class = strreplace(%class, "Data", ""); + + ObjectBuilderGui.newObjectCallback = "finishedSpawningSpawnMarker"; + ObjectCreator.createObject( "ObjectBuilderGui.buildSpawnSphere(" @ %class @ ", " @ %datablock.getName() @ ");" ); +} + +function finishedSpawningSpawnMarker(%objId) +{ + %objId.position = SpawnDatablockObjectPopup.position; } function DatablockObjectType::onWorldEditorDropped(%this, %position) { - %newObj = spawnDatablockObject(%this); - %newObj.position = %position; + if( !isObject( SpawnDatablockObjectPopup ) ) + { + new PopupMenu( SpawnDatablockObjectPopup ) + { + superClass = "MenuBuilder"; + class = "EditorWorldMenu"; + + jumpFileName = ""; + jumpLineNumber = ""; + }; + } + + SpawnDatablockObjectPopup.objectData = %this; + SpawnDatablockObjectPopup.objectType = "DatablockObjectType"; + SpawnDatablockObjectPopup.position = %position; + + //Regen the menu so we're fully up and current with options and references + SpawnDatablockObjectPopup.clearItems(); + + %class = %this.getClassName(); + %class = strreplace(%class, "Data", ""); + + SpawnDatablockObjectPopup.appendItem("Create " @ %class @ " Object" TAB "" TAB "spawnDatablockObject(" @ %this @ ", " @ %position @ ");"); + + %category = getCategoryOfClass(%class); + if(%class $= "Player") + { + SpawnDatablockObjectPopup.appendItem("Create AI" @ %class @ " Object" TAB "" TAB "spawnAIObject(" @ %this @ ", " @ %position @ ");"); + } + + SpawnDatablockObjectPopup.appendItem("Create SpawnNode of " @ %class TAB "" TAB "spawnSpawnMarker(" @ %this @ "," @ %position @ ");"); + + SpawnDatablockObjectPopup.reloadItems(); + + SpawnDatablockObjectPopup.showPopup(Canvas); + + + //%newObj = spawnDatablockObject(%this); + //%newObj.position = %position; } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript index 08a8cf393..49382a3e7 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/prefab.tscript @@ -24,8 +24,6 @@ function PrefabFileType::buildBrowserElement(%filePath, %previewData) %previewData.assetName = fileName(%filePath); %previewData.assetPath = %filePath; - echo("PrefabFileType::buildBrowserElement() - name, path: " @ %previewData.assetName @ ", " @ %filePath); - %previewData.previewImage = "ToolsModule:prefabIcon_image"; //%previewData.assetFriendlyName = %assetDef.assetName; @@ -49,4 +47,76 @@ function PrefabFileType::onWorldEditorDropped(%filePath, %position) EWorldEditor.selectObject(%newPrefab); EWorldEditor.isDirty = true; +} + +function EWorldEditor::restoreSelectedToPrefab(%this, %object) +{ + %assetDef = AssetDatabase.acquireAsset(%object.shapeAsset); + %assetFileName = %assetDef.getFilename(); + + %assetFileBase = strreplace(fileBase(%assetFileName), ".asset", ""); + %assetFileBase = strreplace(%assetFileBase, ".taml", ""); + + %prefabFile = filePath(%assetFileName) @ "/" @ %assetFileBase @ ".prefab"; + + %name = %object.getName(); + + %prefab = new Prefab() { + fileName = %prefabFile; + position = %object.position; + rotation = %object.rotation; + scale = %object.scale; + }; + + %object.getGroup().add(%prefab); + + %prefab.setName(%name); + + MECreateUndoAction::submit( %prefab ); + + MEDeleteUndoAction::submit( %object ); +} + +function EWorldEditor::rebakeSelectedMesh(%this, %object) +{ + %assetDef = AssetDatabase.acquireAsset(%object.shapeAsset); + %assetFileName = %assetDef.getFilename(); + + %assetFileBase = strreplace(fileBase(%assetFileName), ".asset", ""); + %assetFileBase = strreplace(%assetFileBase, ".taml", ""); + + %prefabFile = filePath(%assetFileName) @ "/" @ %assetFileBase @ ".prefab"; + + %name = %object; + + %prefab = new Prefab() { + fileName = %prefabFile; + position = %object.position; + rotation = %object.rotation; + scale = %object.scale; + }; + + %object.getGroup().add(%prefab); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%prefab); + + EWorldEditor.explodeSelectedPrefab(); + + //after the explode, we'll have the group selected + %prefabGroup = EWorldEditor.getSelectedObject(0); + + EWorldEditor.clearSelection(); + for(%i=0; %i < %prefabGroup.getCount(); %i++) + { + %prefabObj = %prefabGroup.getObject(%i); + EWorldEditor.getActiveSelection().add(%prefabObj); + } + + makeSelectedAMesh(%object.shapeAsset, false, false); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%object); + + %prefabGroup.delete(); } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui index 29b3afb9e..ddd523181 100644 --- a/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui +++ b/Templates/BaseGame/game/tools/datablockEditor/DatablockEditorCreatePrompt.ed.gui @@ -32,11 +32,11 @@ $guiContent = new GuiControl(DatablockEditorCreatePrompt,EditorGuiGroup) { anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "374 252"; - extent = "309 167"; + position = "758 420"; + extent = "400 167"; minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; + horizSizing = "center"; + vertSizing = "center"; profile = "ToolsGuiWindowProfile"; visible = "1"; active = "1"; @@ -57,7 +57,7 @@ $guiContent = new GuiControl(DatablockEditorCreatePrompt,EditorGuiGroup) { anchorLeft = "1"; anchorRight = "0"; position = "7 26"; - extent = "190 15"; + extent = "250 15"; minExtent = "8 2"; horizSizing = "right"; vertSizing = "bottom"; @@ -76,7 +76,7 @@ $guiContent = new GuiControl(DatablockEditorCreatePrompt,EditorGuiGroup) { sinkAllKeyEvents = "0"; password = "0"; passwordMask = "*"; - text = "Name"; + placeholderText = "Name"; maxLength = "1024"; margin = "0 0 0 0"; padding = "0 0 0 0"; diff --git a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript index 2633e0dc4..5e590f34e 100644 --- a/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript +++ b/Templates/BaseGame/game/tools/datablockEditor/datablockEditor.tscript @@ -647,8 +647,7 @@ function DatablockEditorPlugin::createDatablock(%this) if( %class !$= "" ) { // Need to prompt for a name. - - DatablockEditorCreatePrompt-->CreateDatablockName.setText("Name"); + DatablockEditorCreatePrompt-->CreateDatablockName.setText(""); DatablockEditorCreatePrompt-->CreateDatablockName.selectAllText(); // Populate the copy source dropdown. @@ -686,7 +685,7 @@ function DatablockEditorPlugin::createDatablock(%this) // Show the dialog. canvas.pushDialog( DatablockEditorCreatePrompt, 0, true ); - DatablockEditorCreatePrompt-->promptWindow.text = "Create New Datablock in module: " @ DatablockEditorPlugin.targetCreationModule; + DatablockEditorCreatePrompt-->promptWindow.text = "Create New " @ %class @ " Datablock in module: " @ DatablockEditorPlugin.targetCreationModule; } } @@ -717,7 +716,10 @@ function DatablockEditorPlugin::createPromptNameCheck(%this, %path) { %name = DatablockEditorCreatePrompt-->CreateDatablockName.getText(); if( !Editor::validateObjectName( %name, true ) ) - return; + { + toolsMessageBoxOK("Error", "Unable to validate new datablock name. Please make sure it's an alphanumeric value and that it is unique!"); + return; + } // Fetch the copy source and clear the list. @@ -762,6 +764,8 @@ function DatablockEditorPlugin::createDatablockFinish( %this, %name, %copySource %this.submitUndo( %action ); %action.redo(); + + DatablockEditorPlugin.openDatablock(%name); } $DATABLOCK_EDITOR_NEWDB_CLASS = ""; diff --git a/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.tscript b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.tscript index 8da862041..056c188cb 100644 --- a/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.tscript +++ b/Templates/BaseGame/game/tools/decalEditor/decalEditorGui.tscript @@ -585,18 +585,35 @@ function DecalEditorGui::updateDecalPreview( %this, %material ) if( isObject( %material ) ) { - %previewImage = %material.getDiffuseMap(0); + %previewImage = %material.getDiffuseMapAsset(0); + } + else if(AssetDatabase.isDeclaredAsset(%material)) + { + if(AssetDatabase.getAssetType(%material) $= "MaterialAsset") + { + %matAsset = AssetDatabase.acquireAsset(%material); + + %previewImage = %matAsset.materialDefinitionName.getDiffuseMap(0); + //AssetDatabase.releaseAsset(%material); + } + else if(AssetDatabase.getAssetType(%material) $= "ImageAsset") + { + %previewImage = %material; + } + else + { + error("DecalEditorGui::updateDecalPreview() - Tried to set an invalid asset type for the editor preview!"); + return; + } } else { - if(AssetDatabase.isDeclaredAsset(%material)) - { - %previewImage = %material; - } - } + error("DecalEditorGui::updateDecalPreview() - Tried to set a non material, non asset value for the editor preview!"); + return; + } DecalPreviewWindow-->decalPreview.setBitmap( getAssetPreviewImage(%previewImage) ); - } +} function DecalEditorGui::updateInstancePreview( %this, %material ) { diff --git a/Templates/BaseGame/game/tools/gui/compositeTextureEditor.tscript b/Templates/BaseGame/game/tools/gui/compositeTextureEditor.tscript index 673a81323..fc58c01ec 100644 --- a/Templates/BaseGame/game/tools/gui/compositeTextureEditor.tscript +++ b/Templates/BaseGame/game/tools/gui/compositeTextureEditor.tscript @@ -34,7 +34,7 @@ function CompositeTextureSlotContainer::setChannelData(%this, %sourceValue, %sou { %this-->InputMode.setSelected(1); - %this-->bitmap.setBitmap(%sourceValue); + %this-->bitmap.setBitmap(getAssetPreviewImage(%sourceValue)); if(%sourceChannel $= "") %sourceChannel = "Red"; @@ -74,7 +74,7 @@ function CompositeTextureEditor::setSourceTex(%this, %assetId) $CompTexSourceChannel = 0; %channelContainer = CompositeTextureEditorWindow.getObject($CompTexSourceChannel); - %channelContainer-->bitmap.setBitmap(%assetId); + %channelContainer-->bitmap.setBitmap(getAssetPreviewImage(%assetId)); } function CompositeTextureEditor::saveComposite(%this) diff --git a/Templates/BaseGame/game/tools/gui/fieldTypes/toggleControlButton.tscript b/Templates/BaseGame/game/tools/gui/fieldTypes/toggleControlButton.tscript new file mode 100644 index 000000000..061ef5c07 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/fieldTypes/toggleControlButton.tscript @@ -0,0 +1,46 @@ +function GuiInspectorGroup::buildToggleControlButtonField(%this, %fieldName, %fieldLabel, %fieldDesc, + %fieldDefaultVal, %fieldDataVals, %callback, %ownerObj) +{ + %extent = 200; + + %fieldCtrl = %this.createInspectorField(); + + %extent = %this.stack.getExtent(); + + %width = mRound(%extent/2); + %height = 20; + %inset = 10; + + %editControl = new GuiButtonCtrl() { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + maxLength = "1024"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + isContainer = "0"; + Profile = "ToolsGuiButtonProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + Position = %fieldCtrl.edit.position; + Extent = %fieldCtrl.edit.extent; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + tooltip = "";// %tooltip; + text = "Toggle"; + hovertime = "1000"; + command = "EditorToggleControlOfEntity();"; + }; + + %fieldCtrl.setCaption("Toggle Control"); + %fieldCtrl.setEditControl(%editControl); + + %this.addInspectorField(%fieldCtrl); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.tscript b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.tscript index 1eae6bb2e..685e61619 100644 --- a/Templates/BaseGame/game/tools/gui/guiDialogs.ed.tscript +++ b/Templates/BaseGame/game/tools/gui/guiDialogs.ed.tscript @@ -42,3 +42,4 @@ exec("./fieldTypes/listField." @ $TorqueScriptFileExtension); exec("./fieldTypes/range." @ $TorqueScriptFileExtension); exec("./fieldTypes/moduleDependencies." @ $TorqueScriptFileExtension); exec("./fieldTypes/buttonField." @ $TorqueScriptFileExtension); +exec("./fieldTypes/toggleControlButton." @ $TorqueScriptFileExtension); diff --git a/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui b/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui index 3c7e26fd3..5cd22f2e4 100644 --- a/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui +++ b/Templates/BaseGame/game/tools/gui/saveChangesMBDlg.ed.gui @@ -46,7 +46,7 @@ $guiContent = new GuiControl(toolsMessageBoxSaveChangesDlg, EditorGuiGroup) { text = "Save"; groupNum = "-1"; buttonType = "PushButton"; - iconBitmap = "~/levelEditor/gui/images/iconAccept.png"; + iconBitmapFile = "~/levelEditor/gui/images/iconAccept.png"; sizeIconToButton = "0"; textLocation = "Center"; textMargin = "4"; @@ -66,7 +66,7 @@ $guiContent = new GuiControl(toolsMessageBoxSaveChangesDlg, EditorGuiGroup) { text = "Cancel"; groupNum = "-1"; buttonType = "PushButton"; - iconBitmap = "~/levelEditor/gui/images/iconCancel.png"; + iconBitmapFile = "~/levelEditor/gui/images/iconCancel.png"; sizeIconToButton = "0"; textLocation = "Center"; textMargin = "4"; diff --git a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui index bb7f0c450..96e6422b4 100644 --- a/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui +++ b/Templates/BaseGame/game/tools/guiEditor/gui/guiEditor.ed.gui @@ -273,12 +273,12 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { bitmapAsset = "ToolsModule:separator_xt_h_image"; bitmapMode = "Centered"; }; - new GuiPopUpMenuCtrl(GuiEditorContentList) { + new GuiPopUpMenuCtrlEx(GuiEditorContentList) { maxPopupHeight = "200"; sbUsesNAColor = "0"; reverseTextList = "0"; bitmapBounds = "16 16"; - text = "NewGui - 8844"; + text = ""; maxLength = "1024"; margin = "0 0 0 0"; padding = "0 0 0 0"; @@ -291,13 +291,14 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { horizSizing = "right"; vertSizing = "center"; position = "8 0"; - extent = "145 27"; + extent = "300 27"; minExtent = "8 2"; canSave = "1"; visible = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; canSaveDynamicFields = "0"; + allowTextSearch = true; }; new GuiPopUpMenuCtrl(GuiEditorResList) { maxPopupHeight = "200"; @@ -316,8 +317,8 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { profile = "ToolsGuiPopUpMenuProfile"; horizSizing = "right"; vertSizing = "center"; - position = "161 0"; - extent = "136 27"; + position = "303 0"; + extent = "250 27"; minExtent = "8 2"; canSave = "1"; visible = "1"; @@ -333,7 +334,7 @@ $guiContent = new GuiControl(GuiEditorGui, EditorGuiGroup) { profile = "ToolsGuiDefaultProfile"; horizSizing = "right"; vertSizing = "center"; - position = "307 3"; + position = "556 3"; extent = "9 26"; minExtent = "1 1"; canSave = "1"; diff --git a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.tscript b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.tscript index f8a67f2a9..e85f7c71e 100644 --- a/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.tscript +++ b/Templates/BaseGame/game/tools/guiEditor/scripts/guiEditorToolbox.ed.tscript @@ -91,7 +91,7 @@ function GuiEditorToolbox::setViewTypeAlphabetical( %this ) profile = "ToolsGuiIconButtonSmallProfile"; extent = "128 18"; text = %className; - iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + iconBitmapFile = EditorIconRegistry::findIconByClassName( %className ); buttonMargin = "2 2"; iconLocation = "left"; textLocation = "left"; @@ -174,7 +174,7 @@ function GuiEditorToolbox::setViewTypeCategorized( %this ) profile = "ToolsGuiIconButtonSmallProfile"; extent = "128 18"; text = %className; - iconBitmap = EditorIconRegistry::findIconByClassName( %className ); + iconBitmapFile = EditorIconRegistry::findIconByClassName( %className ); buttonMargin = "2 2"; iconLocation = "left"; textLocation = "left"; diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index c1f0fcdb9..93118d8b8 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -1992,6 +1992,7 @@ function MaterialEditorGui::doSwapMaterial(%this, %materialAsset) function MaterialEditorPropInspector::onInspectorFieldModified(%this, %object, %fieldName, %arrayIndex, %oldValue, %newValue) { MaterialEditorPropInspector.saveScrollState(); + MaterialEditorPropInspector.saveCollapseState(); if(%arrayIndex !$= "" && %arrayIndex !$= "(null)") MaterialEditorGui.updateActiveMaterial(%fieldName @ "[" @ %arrayIndex @ "]", %newValue); diff --git a/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui b/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui index 064a56ad0..30b9148bb 100644 --- a/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui +++ b/Templates/BaseGame/game/tools/navEditor/NavEditorGui.gui @@ -427,7 +427,8 @@ $guiContent = new GuiNavEditorCtrl(NavEditorGui, EditorGuiGroup) { { internalName = "TestActions"; position = "7 21"; - extent = "190 136"; + extent = "300 136"; + new GuiControl() { profile = "GuiDefaultProfile"; Extent = "190 20"; @@ -445,18 +446,70 @@ $guiContent = new GuiNavEditorCtrl(NavEditorGui, EditorGuiGroup) { }; new GuiControl() { profile = "GuiDefaultProfile"; - Extent = "190 20"; + Extent = "300 20"; new GuiPopUpMenuCtrl(SpawnClassSelector) { extent = "89 20"; profile = "ToolsGuiPopUpMenuProfile"; tooltipProfile = "GuiToolTipProfile"; }; - new GuiPopUpMenuCtrl(SpawnDatablockSelector) { + new GuiPopUpMenuCtrlEx(SpawnDatablockSelector) { position = "100 0"; extent = "89 20"; profile = "ToolsGuiPopUpMenuProfile"; tooltipProfile = "GuiToolTipProfile"; + allowTextSearch = true; + }; + + new GuiButtonCtrl(SpawnDatablockEditDBBtn) { + text = "..."; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "193 0"; + extent = "17 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + tooltip = "Edit Datablock"; + }; + + new GuiBitmapButtonCtrl(SpawnDatablockAddDBBtn) { + bitmapAsset = "ToolsModule:iconAdd_image"; + bitmapMode = "Centered"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "211 -2"; + extent = "22 22"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + tooltip = "Create new Datablock"; }; }; diff --git a/Templates/BaseGame/game/tools/navEditor/navEditor.tscript b/Templates/BaseGame/game/tools/navEditor/navEditor.tscript index 3a501cddd..5d32ddf61 100644 --- a/Templates/BaseGame/game/tools/navEditor/navEditor.tscript +++ b/Templates/BaseGame/game/tools/navEditor/navEditor.tscript @@ -575,6 +575,26 @@ function SpawnDatablockSelector::onSelect(%this, %id) NavMeshTools->TestTool.setSpawnDatablock(%className); } +function SpawnDatablockEditDBBtn::onClick(%this) +{ + %dbName = SpawnDatablockSelector.getText(); + DatablockEditorPlugin.openDatablock(%dbName); +} + +function SpawnDatablockAddDBBtn::onClick(%this) +{ + %className = SpawnClassSelector.getText(); + %classData = %className @ "Data"; + if(%className $= "AIPlayer") + { + %classData = "PlayerData"; + } + + %dbName = SpawnDatablockSelector.getText(); + + DatablockEditorPlugin.createNewDatablockOfType(%classData, %dbName); +} + //------------------------------------------------------ // TILETOOL //------------------------------------------------------ diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.tscript b/Templates/BaseGame/game/tools/shapeEditor/main.tscript index ac4758e16..21516fb48 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/main.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/main.tscript @@ -151,8 +151,8 @@ function ShapeEditorPlugin::openShapeAsset(%this, %assetDef) function ShapeEditorPlugin::openShapeAssetId(%this, %assetId) { %this.selectedAssetDef = AssetDatabase.acquireAsset(%assetId); - //%this.selectedAssetDef = %assetDef; - %this.open(%this.selectedAssetDef); + EditorGui.setEditor( ShapeEditorPlugin ); + ShapeEditorPlugin.openShapeAsset(%this.selectedAssetDef); } function ShapeEditorPlugin::open(%this, %shapeAsset) @@ -323,7 +323,7 @@ function ShapeEditorPlugin::onExitMission( %this ) { // unselect the current shape ShapeEdShapeView.setModel( "" ); - if (ShapeEditor.shape != -1) + if (ShapeEditor.shape != 0) ShapeEditor.shape.delete(); ShapeEditor.shape = 0; ShapeEdUndoManager.clearAll(); diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript index f16e0c1c5..5e982cdba 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditor.ed.tscript @@ -546,7 +546,7 @@ function ShapeEdSelectWindow::addObjectHint( %this, %type, %name, %desc, %presen autoSize = true; buttonType = "radioButton"; groupNum = "-1"; - iconBitmap = "tools/editorClasses/gui/images/iconCancel"; + iconBitmapFile = "tools/editorClasses/gui/images/iconCancel"; text = "hint"; tooltip = ""; }; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui index 810a923d4..8199497d8 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/EditorGui.ed.gui @@ -32,30 +32,11 @@ $guiContent = new GuiContainer(EditorGui,EditorGuiGroup) { isDecoy = "1"; }; - new GuiTabBookCtrl(EditorGuiMainTabBook) { - tabHeight = "20"; - selectedPage = "0"; - position = "0 5"; - extent = "800 595"; - horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiTabBookProfile"; - tooltipProfile = "GuiToolTipProfile"; - - new GuiTabPageCtrl(MainSceneEditorTab) { - text = "Main Scene"; - position = 0 SPC 20; - extent = 800 SPC 580; - horizSizing = "width"; - vertSizing = "height"; - profile = "ToolsGuiTabPageProfile"; - tooltipProfile = "GuiToolTipProfile"; - new GuiContainer(MainSceneTabPanel) { HorizSizing = "width"; VertSizing = "height"; - Position = "0 0"; - Extent = "800 580"; + Position = "0 5"; + Extent = "800 595"; new WorldEditor(EWorldEditor) { canSaveDynamicFields = "0"; @@ -1569,7 +1550,5 @@ $guiContent = new GuiContainer(EditorGui,EditorGuiGroup) { }; }; }; - }; - }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui index f58b8fb6c..9418ad267 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/TerrainBrushSoftnessCurveDlg.ed.gui @@ -228,5 +228,5 @@ function TerrainBrushSoftnessCurveDlg::onOk( %this ) function TerrainBrushSoftnessCurveDlg::resetCurve( %this ) { %curve = %this-->FilterCurveCtrl; - %curve.identity(); + %curve.resetFiltering(); } diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui index c84636946..1af096387 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -1,106 +1,76 @@ //--- OBJECT WRITE BEGIN --- -$guiContent = new GuiControl(ObjectBuilderGui, EditorGuiGroup) { - profile = "ToolsGuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "800 600"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; +$guiContent = new GuiControl(ObjectBuilderGui,EditorGuiGroup) { + extent = "1920 1080"; + minExtent = "8 8"; + profile = "ToolsGuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + isContainer = "1"; + canSaveDynamicFields = "1"; + helpTag = "0"; - new GuiWindowCtrl(OBTargetWindow) { - profile = "ToolsGuiWindowProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "384 205"; - extent = "256 282"; - minExtent = "256 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - resizeWidth = "1"; - resizeHeight = "1"; - canMove = "1"; - canClose = "0"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - text = "Create Object"; + new GuiWindowCtrl(OBTargetWindow) { + Text = "Create Object"; + canClose = "0"; + canMinimize = "0"; + canMaximize = "0"; + position = "735 399"; + extent = "449 282"; + minExtent = "256 8"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + tooltipProfile = "GuiToolTipProfile"; - new GuiTextCtrl() { - profile = "ToolsGuiTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 26"; - extent = "84 16"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = "Object Name:"; - }; - new GuiTextEditCtrl(OBObjectName) { - class = ObjectBuilderGuiTextEditCtrl; - profile = "ToolsGuiTextEditProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "78 26"; - extent = "172 18"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - historySize = "0"; - }; - new GuiBitmapBorderCtrl(OBContentWindow) { - profile = "ToolsGuiGroupBorderProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 51"; - extent = "243 193"; - minExtent = "0 0"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - }; - new GuiButtonCtrl(OBOKButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 250"; - extent = "156 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "ObjectBuilderGui.onOK();"; - helpTag = "0"; - text = "Create New"; - Accelerator = "return"; - }; - new GuiButtonCtrl(OBCancelButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "170 250"; - extent = "80 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "ObjectBuilderGui.onCancel();"; - helpTag = "0"; - text = "Cancel"; - Accelerator = "escape"; - }; - }; + new GuiTextCtrl() { + Text = "Object Name:"; + position = "9 26"; + extent = "84 16"; + minExtent = "8 8"; + profile = "ToolsGuiTextProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiTextEditCtrl(OBObjectName) { + position = "102 26"; + extent = "341 20"; + minExtent = "8 8"; + horizSizing = "width"; + profile = "ToolsGuiTextEditProfile"; + tooltipProfile = "GuiToolTipProfile"; + class = "ObjectBuilderGuiTextEditCtrl"; + }; + new GuiBitmapBorderCtrl(OBContentWindow) { + position = "7 51"; + extent = "437 193"; + minExtent = "0 0"; + horizSizing = "width"; + profile = "ToolsGuiGroupBorderProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl(OBOKButton) { + Text = "Create New"; + position = "263 250"; + extent = "97 24"; + minExtent = "8 8"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + command = "ObjectBuilderGui.onOK();"; + accelerator = "return"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl(OBCancelButton) { + Text = "Cancel"; + position = "364 250"; + extent = "80 24"; + minExtent = "8 8"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + command = "ObjectBuilderGui.onCancel();"; + accelerator = "escape"; + tooltipProfile = "GuiToolTipProfile"; + }; + }; }; //--- OBJECT WRITE END --- @@ -110,13 +80,13 @@ function ObjectBuilderGui::init(%this) %this.baseOffsetY = 5; %this.defaultObjectName = ""; %this.defaultFieldStep = 22; - %this.columnOffset = 110; + %this.columnOffset = 140; - %this.fieldNameExtent = "105 18"; - %this.textEditExtent = "122 18"; + %this.fieldNameExtent = "135 18"; + %this.textEditExtent = "280 18"; %this.checkBoxExtent = "13 18"; - %this.popupMenuExtent = "122 18"; - %this.fileButtonExtent = "122 18"; + %this.popupMenuExtent = "280 18"; + %this.fileButtonExtent = "280 18"; %this.matButtonExtent = "17 18"; // @@ -886,6 +856,50 @@ function ObjectBuilderGui::createStringType(%this, %index) %this.curYPos += %this.defaultFieldStep; } +function ObjectBuilderGuiCommandCtrl::apply(%this, %text) +{ + %this.text = %text; +} + +function ObjectBuilderGui::createCommandType(%this, %index) +{ + if(%index >= %this.numFields || %this.field[%index, name] $= "") + { + error("ObjectBuilderGui::createCommandType: invalid field"); + return; + } + + // + if(%this.field[%index, text] $= "") + %name = %this.field[%index, name]; + else + %name = %this.field[%index, text]; + + // + %this.textControls[%this.numControls] = new GuiTextCtrl() { + profile = "ToolsGuiTextRightProfile"; + text = %name; + extent = %this.fieldNameExtent; + position = %this.curXPos @ " " @ %this.curYPos; + modal = "1"; + }; + + // + %this.controls[%this.numControls] = new GuiButtonCtrl() { + class = ObjectBuilderGuiCommandCtrl; + HorizSizing = "width"; + profile = "ToolsGuiTextEditProfile"; + extent = %this.textEditExtent; + text = %this.field[%index, value]; + position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; + modal = "1"; + command = "TextPad($ThisControl.text, \"$ThisControl.apply\", $ThisControl.getRoot());"; + }; + + %this.numControls++; + %this.curYPos += %this.defaultFieldStep; +} + //------------------------------------------------------------------------------ function ObjectBuilderGui::adjustSizes(%this) @@ -940,6 +954,9 @@ function ObjectBuilderGui::process(%this) case "TypeMaterialName": %this.createMaterialNameType(%i); + + case "TypeCommand": + %this.createCommandType(%i); default: %this.createStringType(%i); @@ -1502,18 +1519,18 @@ function ObjectBuilderGui::buildFlyingVehicle(%this) %this.process(); } -function ObjectBuilderGui::buildSpawnSphere(%this) +function ObjectBuilderGui::buildSpawnSphere(%this, %spawnClass, %spawnDatablock) { %this.objectClassName = "SpawnSphere"; %this.addField("dataBlock", "TypeDataBlock", "dataBlock", "MissionMarkerData SpawnSphereMarker"); %this.addField("radius", "TypeFloat", "Radius", 1); %this.addField("sphereWeight", "TypeFloat", "Sphere Weight", 1); - %this.addField("spawnClass", "TypeString", "Spawn Class", ""); - %this.addField("spawnDatablock", "TypeString", "Spawn Data", ""); + %this.addField("spawnClass", "TypeString", "Spawn Class", %spawnClass); + %this.addField("spawnDatablock", "TypeString", "Spawn Data", %spawnDatablock); %this.addField("spawnTransform", "TypeBool", "Spawn Here", "true"); %this.addField("autoSpawn", "TypeBool", "Auto Spawn Objects", "false"); - %this.addField("spawnScript", "TypeString", "spawnScript", "%this.spawned = $SpawnObject;"); + %this.addField("spawnScript", "TypeCommand", "spawnScript", "%this.spawned = $SpawnObject;"); %this.addField("canSaveDynamicFields", "TypeBool", "Save metadata", "false"); %this.process(); } @@ -1768,4 +1785,98 @@ function TriggerData::create(%datablock) polyhedron = "-0.5 0.5 0.0 1.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 1.0"; }; return %obj; +} + +// +function PlayerData::create(%datablock) +{ + %obj = new Player() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +function Player::create(%datablock) +{ + %obj = new Player() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +function AIPlayer::create(%datablock) +{ + %obj = new AIPlayer() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +// +function WheeledVehicleData::create(%datablock) +{ + %obj = new WheeledVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +function WheeledVehicle::create(%datablock) +{ + %obj = new WheeledVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +// +function FlyingVehicleData::create(%datablock) +{ + %obj = new FlyingVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +function FlyingVehicle::create(%datablock) +{ + %obj = new FlyingVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +// +function HoverVehicleData::create(%datablock) +{ + %obj = new HoverVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; +} + +function HoverVehicle::create(%datablock) +{ + %obj = new HoverVehicle() + { + dataBlock = %datablock; + parentGroup = ObjectCreator.objectGroup; + }; + return %obj; } \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript index 7fe337545..b57fdf092 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.tscript @@ -1709,7 +1709,7 @@ function EWorldEditor::maxSize(%this, %window) %fixedWindow = EWTreeWindow; %fluidWindow = EWInspectorWindow; - %offset = 25; // tweak the vertical offset so that it aligns neatly + %offset = 0; // tweak the vertical offset so that it aligns neatly %top = EditorGuiToolbar.extent.y + %offset; %bottom = %top + 59; %maxHeight = Canvas.extent.y - %top - %bottom + 12; @@ -2101,7 +2101,10 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %popup.item[ 0 ] = "Delete" TAB "" TAB "EditorMenuEditDelete();"; %popup.item[ 1 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; %popup.item[ 2 ] = "-"; - %popup.item[ 3 ] = "Make selected a Sub-Level" TAB "" TAB "MakeSelectionASublevel();"; + %popup.item[ 3 ] = "Make selected a Prefab" TAB "" TAB "EWorldEditor.makeSelectionPrefab();"; + %popup.item[ 4 ] = "Bake selected into Mesh" TAB "" TAB "AssetBrowser.setupCreateNewAsset(\"ShapeAsset\", AssetBrowser.selectedModule, \"makeSelectedAMesh\");"; + %popup.item[ 5 ] = "-"; + %popup.item[ 6 ] = "Make selected a Sub-Level" TAB "" TAB "MakeSelectionASublevel();"; } else { @@ -2206,6 +2209,29 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %popup.item[ 13 ] = "Convert to SubScene" TAB "" TAB "EWorldEditor.createSelectedAsSubScene( " @ %popup.object @ " );"; } } + else if(%obj.getClassName() $= "TSStatic") + { + if(AssetDatabase.isDeclaredAsset(%obj.shapeAsset)) + { + %assetDef = AssetDatabase.acquireAsset(%obj.shapeAsset); + + %assetFileName = %assetDef.getFilename(); + %assetFileBase = strreplace(fileBase(%assetFileName), ".asset", ""); + %assetFileBase = strreplace(%assetFileBase, ".taml", ""); + + %prefabFile = filePath(%assetFileName) @ "/" @ %assetFileBase @ ".prefab"; + if(isFile(%prefabFile)) + { + %popup.item[ 8 ] = "-"; + %popup.item[ 9 ] = "Restore to Prefab" TAB "" TAB "EWorldEditor.restoreSelectedToPrefab( " @ %popup.object @ " );"; + %popup.item[ 10 ] = "Rebake Mesh" TAB "" TAB "EWorldEditor.rebakeSelectedMesh( " @ %popup.object @ " );"; + } + } + } + else if( %obj.isMemberOfClass( "Prefab" ) ) + { + %popup.item[ 8 ] = "Explode Prefab" TAB "" TAB "EWorldEditor.explodeSelectedPrefab();"; + } } } diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript index 6f57ffd0f..81c0a2c7f 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.tscript @@ -135,7 +135,7 @@ function ObjectCreator::createObject( %this, %cmd ) if(startsWith(%cmd, "return ")) %objId = eval(%cmd); else - %objId = eval("return " @ %cmd); + %objId = eval("return " @ %cmd); popInstantGroup(); if( isObject( %objId ) ) @@ -246,7 +246,7 @@ function ObjectCreator::addMissionObjectIcon( %this, %class, %name, %buildfunc ) %cmd = "ObjectBuilderGui." @ %method @ "();"; %ctrl.altCommand = "ObjectBuilderGui.newObjectCallback = \"ObjectCreator.onFinishCreateObject\"; ObjectCreator.createObject( \"" @ %cmd @ "\" );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.iconBitmapFile = EditorIconRegistry::findIconByClassName( %class ); %ctrl.text = %name; %ctrl.class = "CreatorMissionObjectIconBtn"; %ctrl.tooltip = %class; @@ -270,7 +270,7 @@ function ObjectCreator::addShapeIcon( %this, %datablock ) %createCmd = "ObjectCreator.createObject( \\\"" @ %cmd @ "\\\" );"; %ctrl.altCommand = "showImportDialog( \"" @ %shapePath @ "\", \"" @ %createCmd @ "\" );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( %class ); + %ctrl.iconBitmapFile = EditorIconRegistry::findIconByClassName( %class ); %ctrl.text = %name; %ctrl.class = "CreatorShapeIconBtn"; %ctrl.tooltip = %name; @@ -296,7 +296,7 @@ function ObjectCreator::addStaticIcon( %this, %fullPath ) %createCmd = "ObjectCreator.createStatic( \\\"" @ %fullPath @ "\\\" );"; %ctrl.altCommand = "showImportDialog( \"" @ %fullPath @ "\", \"" @ %createCmd @ "\" );"; - %ctrl.iconBitmap = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); + %ctrl.iconBitmapFile = ( ( %ext $= ".dts" ) ? EditorIconRegistry::findIconByClassName( "TSStatic" ) : "tools/gui/images/iconCollada" ); %ctrl.text = %file; %ctrl.class = "CreatorStaticIconBtn"; %ctrl.tooltip = %tip; @@ -320,7 +320,7 @@ function ObjectCreator::addPrefabIcon( %this, %fullPath ) "Last Modified: " @ fileModifiedTime( %fullPath ); %ctrl.altCommand = "ObjectCreator.createPrefab( \"" @ %fullPath @ "\" );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); + %ctrl.iconBitmapFile = EditorIconRegistry::findIconByClassName( "Prefab" ); %ctrl.text = %file; %ctrl.class = "CreatorPrefabIconBtn"; %ctrl.tooltip = %tip; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.tscript index 389d83839..c2e2fd591 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/worldEditor.ed.tscript @@ -516,6 +516,15 @@ function Inspector::inspect( %this, %obj ) %name = %obj.getName(); else FieldInfoControl.setText( "" ); + + %category = getCategoryOfClass(%obj.getClassName()); + if(getFieldCount(%category > 1) && trim(getField(%category, 1)) $= "Controllable") + { + %genGroup = %this.findExistentGroup("General"); + + if(isObject(%genGroup)) + %genGroup.addField("ToggleControlBtn", "ToggleControlButton", "Takes control of the selected controllable object"); + } //InspectorNameEdit.setValue( %name ); Parent::inspect( %this, %obj ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript index 531862641..8b0dddd22 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menuHandlers.ed.tscript @@ -455,7 +455,7 @@ function EditorAutoSaveMission() AssetBackupListArray.empty(); - %scenePath = makeFullPath(getRootScene().getFileName()); + %scenePath = getRootScene().getFileName(); if(startsWith(%scenePath, "tools/levels/")) return false; @@ -793,7 +793,7 @@ function EditorExplodePrefab() EditorTree.buildVisibleTree( true ); } -function makeSelectedAMesh(%assetId) +function makeSelectedAMesh(%assetId, %createPrefab, %spawnNewStatic) { %selectedCount = EWorldEditor.getSelectionSize(); @@ -803,6 +803,12 @@ function makeSelectedAMesh(%assetId) return; } + if(%createPrefab $= "") + %createPrefab = true; + + if(%spawnNewStatic $= "") + %spawnNewStatic = true; + %assetDef = AssetDatabase.acquireAsset(%assetId); %assetPath = AssetDatabase.getAssetPath(%assetId); @@ -836,31 +842,48 @@ function makeSelectedAMesh(%assetId) } } - %prefabPath = %assetPath @ "/" @ %assetDef.AssetName @ ".prefab"; - EWorldEditor.makeSelectionPrefab(%prefabPath, false); - %selectionPos = EWorldEditor.getSelectedObject(0).getPosition(); - //Next, nuke 'em - EditorMenuEditDelete(); - - //now make a new static - %newStatic = new TSStatic() + if(%createPrefab) { - shapeAsset = %assetId; - position = %selectionPos; - }; - - if(%sameParent) - %firstParent.add(%newStatic); - else - getRootScene().add(%newStatic); + %prefabPath = %assetPath @ "/" @ %assetDef.AssetName @ ".prefab"; + EWorldEditor.makeSelectionPrefab(%prefabPath, false); + } + + if(%spawnNewStatic) + { + %selectionPos = EWorldEditor.getSelectedObject(0).getPosition(); - EWorldEditor.clearSelection(); - EWorldEditor.selectObject(%newStatic); + //Next, nuke 'em + EditorMenuEditDelete(); + + //now make a new static + %newStatic = new TSStatic() + { + shapeAsset = %assetId; + position = %selectionPos; + }; + + if(%sameParent) + %firstParent.add(%newStatic); + else + getRootScene().add(%newStatic); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newStatic); + } } EditorTree.buildVisibleTree( true ); } +function EditorToggleControlOfEntity() +{ + %object = EWorldEditor.getSelectedObject(0); + if(%object == localClientConnection.getControlObject()) + EditorReleaseControlOfEntity(); + else + EditorTakeControlOfEntity(); +} + function EditorTakeControlOfEntity() { %object = EWorldEditor.getSelectedObject(0); @@ -868,8 +891,9 @@ function EditorTakeControlOfEntity() { $Editor::previousControlObject = localClientConnection.getControlObject(); localClientConnection.setControlObject(%object); - } + + Inspector.refresh(); } function EditorReleaseControlOfEntity() @@ -878,6 +902,8 @@ function EditorReleaseControlOfEntity() { localClientConnection.setControlObject($Editor::previousControlObject); } + + Inspector.refresh(); } function EditorMount() From 098a5ac36d60a991f11ccb3b359ef19c40c4c876 Mon Sep 17 00:00:00 2001 From: JeffR Date: Mon, 25 Aug 2025 23:42:58 -0500 Subject: [PATCH 2/2] - Fixed issue of TypeCommand field type not applying change when text was edited in the textpad - Fixed it to check both 0 and -1 values when exiting out of shapeEditor since both can be returns --- Templates/BaseGame/game/tools/shapeEditor/main.tscript | 2 +- .../BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Templates/BaseGame/game/tools/shapeEditor/main.tscript b/Templates/BaseGame/game/tools/shapeEditor/main.tscript index 21516fb48..8877863e0 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/main.tscript +++ b/Templates/BaseGame/game/tools/shapeEditor/main.tscript @@ -323,7 +323,7 @@ function ShapeEditorPlugin::onExitMission( %this ) { // unselect the current shape ShapeEdShapeView.setModel( "" ); - if (ShapeEditor.shape != 0) + if (ShapeEditor.shape != 0 && ShapeEditor.shape != -1) ShapeEditor.shape.delete(); ShapeEditor.shape = 0; ShapeEdUndoManager.clearAll(); diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui index 1af096387..5058099fb 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -893,7 +893,7 @@ function ObjectBuilderGui::createCommandType(%this, %index) text = %this.field[%index, value]; position = %this.curXPos + %this.columnOffset @ " " @ %this.curYPos; modal = "1"; - command = "TextPad($ThisControl.text, \"$ThisControl.apply\", $ThisControl.getRoot());"; + command = "TextPad($ThisControl.text, $ThisControl@\".apply\", $ThisControl.getRoot());"; }; %this.numControls++;