Implementation of Subscenes, SceneGroups and Gamemodes

Standardizes Gamemodes to be an actual class with data and utility functions that can be parsed
Adds inspector field handling for selecting gamemodes
Updated Scene class to work with Gamemodes for the gamemode field
Updates editor suite elements to be able to create SubScenes, SceneGroups and Gamemodes
Adds ability to convert SimGroup to SubScene
Updates BaseUI's chooselevel menu to have gamemode selection and filters shown levels based on selected gamemode
This commit is contained in:
Areloch 2024-09-01 16:39:00 -05:00
parent 0d07823ecd
commit ae8eca48e1
36 changed files with 2963 additions and 173 deletions

View file

@ -104,7 +104,7 @@ ConsoleSetType(TypeImageAssetId)
}
// Warn.
Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
Con::warnf("(TypeImageAssetId) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
@ -748,7 +748,7 @@ void GuiInspectorTypeImageAssetPtr::setPreviewImage(StringTableEntry assetId)
IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetId);
ConsoleDocClass(GuiInspectorTypeImageAssetId,
"@brief Inspector field type for Shapes\n\n"
"@brief Inspector field type for Images\n\n"
"Editor use only.\n\n"
"@internal"
);

View file

@ -42,12 +42,14 @@
// Debug Profiling.
#include "platform/profiler.h"
#include "gfx/gfxDrawUtil.h"
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(LevelAsset);
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, const char*, "")
//-----------------------------------------------------------------------------
@ -74,6 +76,28 @@ ConsoleSetType(TypeLevelAssetPtr)
Con::warnf("(TypeLevelAssetPtr) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
ConsoleType(assetIdString, TypeLevelAssetId, const char*, "")
ConsoleGetType(TypeLevelAssetId)
{
// Fetch asset Id.
return *((const char**)(dptr));
}
ConsoleSetType(TypeLevelAssetId)
{
// Was a single argument specified?
if (argc == 1)
{
*((const char**)dptr) = StringTable->insert(argv[0]);
return;
}
// Warn.
Con::warnf("(TypeLevelAssetId) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
@ -91,7 +115,7 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
mForestPath = StringTable->EmptyString();
mNavmeshPath = StringTable->EmptyString();
mGamemodeName = StringTable->EmptyString();
mGameModesNames = StringTable->EmptyString();
mMainLevelAsset = StringTable->EmptyString();
mEditorFile = StringTable->EmptyString();
@ -134,7 +158,7 @@ void LevelAsset::initPersistFields()
&setBakedSceneFile, &getBakedSceneFile, "Path to the level file with the objects generated as part of the baking process");
addField("isSubScene", TypeBool, Offset(mIsSubLevel, LevelAsset), "Is this a sublevel to another Scene");
addField("gameModeName", TypeString, Offset(mGamemodeName, LevelAsset), "Name of the Game Mode to be used with this level");
addField("gameModesNames", TypeString, Offset(mGameModesNames, LevelAsset), "Name of the Game Mode to be used with this level");
}
//------------------------------------------------------------------------------
@ -357,7 +381,7 @@ void LevelAsset::unloadDependencies()
}
}
DefineEngineMethod(LevelAsset, getLevelPath, const char*, (),,
DefineEngineMethod(LevelAsset, getLevelPath, const char*, (), ,
"Gets the full path of the asset's defined level file.\n"
"@return The string result of the level path")
{
@ -417,3 +441,99 @@ DefineEngineMethod(LevelAsset, unloadDependencies, void, (), ,
{
return object->unloadDependencies();
}
//-----------------------------------------------------------------------------
// GuiInspectorTypeAssetId
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(GuiInspectorTypeLevelAssetPtr);
ConsoleDocClass(GuiInspectorTypeLevelAssetPtr,
"@brief Inspector field type for Shapes\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeLevelAssetPtr::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType(TypeLevelAssetPtr)->setInspectorFieldType("GuiInspectorTypeLevelAssetPtr");
}
GuiControl* GuiInspectorTypeLevelAssetPtr::constructEditControl()
{
// Create base filename edit controls
GuiControl* retCtrl = Parent::constructEditControl();
if (retCtrl == NULL)
return retCtrl;
// Change filespec
char szBuffer[512];
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"LevelAsset\", \"AssetBrowser.changeAsset\", %s, \"\");",
getIdString());
mBrowseButton->setField("Command", szBuffer);
setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
// Create "Open in Editor" button
mEditButton = new GuiBitmapButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");",
getIdString());
mEditButton->setField("Command", szBuffer);
char bitmapName[512] = "ToolsModule:iconAdd_image";
mEditButton->setBitmap(StringTable->insert(bitmapName));
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Test play this sound");
mEditButton->registerObject();
addObject(mEditButton);
return retCtrl;
}
bool GuiInspectorTypeLevelAssetPtr::updateRects()
{
S32 dividerPos, dividerMargin;
mInspector->getDivider(dividerPos, dividerMargin);
Point2I fieldExtent = getExtent();
Point2I fieldPos = getPosition();
mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mBrowseButton != NULL)
{
mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
}
if (mEditButton != NULL)
{
RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent);
}
return resized;
}
IMPLEMENT_CONOBJECT(GuiInspectorTypeLevelAssetId);
ConsoleDocClass(GuiInspectorTypeLevelAssetId,
"@brief Inspector field type for Levels\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeLevelAssetId::consoleInit()
{
Parent::consoleInit();
ConsoleBaseType::getType(TypeLevelAssetId)->setInspectorFieldType("GuiInspectorTypeLevelAssetId");
}

View file

@ -40,6 +40,11 @@
#endif
#include "T3D/assets/ImageAsset.h"
#ifndef _GUI_INSPECTOR_TYPES_H_
#include "gui/editor/guiInspectorTypes.h"
#endif
#include <gui/controls/guiBitmapCtrl.h>
//-----------------------------------------------------------------------------
class LevelAsset : public AssetBase
{
@ -64,7 +69,7 @@ class LevelAsset : public AssetBase
bool mIsSubLevel;
StringTableEntry mMainLevelAsset;
StringTableEntry mGamemodeName;
StringTableEntry mGameModesNames;
Vector<AssetBase*> mAssetDependencies;
@ -114,7 +119,7 @@ public:
U32 load() override { return Ok; };
protected:
static bool setLevelFile(void *obj, const char *index, const char *data) { static_cast<LevelAsset*>(obj)->setLevelFile(data); return false; }
static bool setLevelFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setLevelFile(data); return false; }
static const char* getLevelFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getLevelFile(); }
static bool setEditorFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setEditorFile(data); return false; }
@ -135,10 +140,96 @@ protected:
void initializeAsset(void) override;
void onAssetRefresh(void) override;
void loadAsset();
void loadAsset();
typedef Signal<void()> LevelAssetChanged;
LevelAssetChanged mChangeSignal;
public:
LevelAssetChanged& getChangedSignal() { return mChangeSignal; }
};
#ifdef TORQUE_TOOLS
class GuiInspectorTypeLevelAssetPtr : public GuiInspectorTypeFileName
{
typedef GuiInspectorTypeFileName Parent;
public:
GuiBitmapButtonCtrl* mEditButton;
DECLARE_CONOBJECT(GuiInspectorTypeLevelAssetPtr);
static void consoleInit();
GuiControl* constructEditControl() override;
bool updateRects() override;
};
class GuiInspectorTypeLevelAssetId : public GuiInspectorTypeLevelAssetPtr
{
typedef GuiInspectorTypeLevelAssetPtr Parent;
public:
DECLARE_CONOBJECT(GuiInspectorTypeLevelAssetId);
static void consoleInit();
};
#endif
DefineConsoleType(TypeLevelAssetPtr, LevelAsset)
DefineConsoleType(TypeLevelAssetId, String)
#pragma region Singular Asset Macros
//Singular assets
/// <Summary>
/// Declares an level asset
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
/// </Summary>
#define DECLARE_LEVELASSET(className, name, changeFunc) public: \
StringTableEntry m##name##AssetId;\
AssetPtr<LevelAsset> m##name##Asset;\
public: \
const AssetPtr<LevelAsset> & get##name##Asset() const { return m##name##Asset; }\
void set##name##Asset(const AssetPtr<LevelAsset> &_in) { m##name##Asset = _in;}\
\
bool _set##name(StringTableEntry _in)\
{\
if(m##name##AssetId != _in)\
{\
if (m##name##Asset.notNull())\
{\
m##name##Asset->getChangedSignal().remove(this, &className::changeFunc);\
}\
if (_in == NULL || _in == StringTable->EmptyString())\
{\
m##name##AssetId = StringTable->EmptyString();\
m##name##Asset = NULL;\
return true;\
}\
if (AssetDatabase.isDeclaredAsset(_in))\
{\
m##name##AssetId = _in;\
m##name##Asset = _in;\
return true;\
}\
}\
\
if(get##name() == StringTable->EmptyString())\
return true;\
\
return false;\
}\
\
const StringTableEntry get##name() const\
{\
return m##name##AssetId;\
}\
bool name##Valid() {return (get##name() != StringTable->EmptyString() && m##name##Asset->getStatus() == AssetBase::Ok); }
#define INITPERSISTFIELD_LEVELASSET(name, consoleClass, docs) \
addProtectedField(assetText(name, Asset), TypeLevelAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
#pragma endregion
#endif // _ASSET_BASE_H_