Adds utility function and method to be able to enact a load of subscenes at a specific world position

Adds loadIf conditional logic to evaluate if a subscene is 'allowed' to load when tested
Adds isAlwaysActive to GameMode to be able to flag a gamemode as being defaulted to on and used automatically
Updated GetGameModesList function to return an arrayObject of the gamemodes found
Overhauled CallGameModeFunction to utilize the gamemodes list with active/alwaysActive modes being called against, rather than level-scanning
Updated ChooseLevelMenu to be able to toggle on/off multiple gamemodes with an image indicator if it's active or not
This commit is contained in:
JeffR 2024-10-04 00:10:26 -05:00
parent 20a01d9f02
commit e4d07c7e8d
14 changed files with 259 additions and 198 deletions

View file

@ -391,6 +391,21 @@ Vector<SceneObject*> Scene::getObjectsByClass(String className)
return Vector<SceneObject*>();
}
void Scene::loadAtPosition(const Point3F& position)
{
for (U32 i = 0; i < mSubScenes.size(); i++)
{
Box3F testBox = Box3F(0.5);
testBox.setCenter(position);
if (mSubScenes[i]->testBox(testBox))
{
mSubScenes[i]->setUnloadTimeMS(-1);
mSubScenes[i]->load();
}
}
}
DefineEngineFunction(getScene, Scene*, (U32 sceneId), (0),
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
@ -489,3 +504,9 @@ DefineEngineMethod(Scene, save, bool, (const char* fileName), (""),
{
return object->saveScene(StringTable->insert(fileName));
}
DefineEngineMethod(Scene, loadAtPosition, void, (Point3F position), (Point3F::Zero),
"Loads any subscenes at a given point by force.\n")
{
object->loadAtPosition(position);
}

View file

@ -93,6 +93,8 @@ public:
template <class T>
Vector<T*> getObjectsByClass();
void loadAtPosition(const Point3F& position);
static Scene *getRootScene()
{
if (Scene::smSceneList.empty())

View file

@ -49,6 +49,7 @@ void SubScene::initPersistFields()
addGroup("SubScene");
addField("isGlobalLayer", TypeBool, Offset(mGlobalLayer, SubScene), "");
INITPERSISTFIELD_LEVELASSET(Level, SubScene, "The level asset to load.");
addField("loadIf", TypeCommand, Offset(mLoadIf, SubScene), "evaluation condition (true/false)");
addField("gameModes", TypeGameModeList, Offset(mGameModesNames, SubScene), "The game modes that this subscene is associated with.");
endGroup("SubScene");
@ -143,9 +144,18 @@ bool SubScene::testBox(const Box3F& testBox)
if (mGlobalLayer)
return true;
bool isOverlapped = getWorldBox().isOverlapped(testBox);
return getWorldBox().isOverlapped(testBox);
bool passes = getWorldBox().isOverlapped(testBox);
if (passes && !mLoadIf.isEmpty())
{
//test the mapper plugged in condition line
String resVar = getIdString() + String(".result");
Con::setBoolVariable(resVar.c_str(), false);
String command = resVar + "=" + mLoadIf + ";";
Con::evaluatef(command.c_str());
passes = Con::getBoolVariable(resVar.c_str());
}
return passes;
}
void SubScene::write(Stream& stream, U32 tabStop, U32 flags)

View file

@ -38,6 +38,7 @@ private:
S32 mStartUnloadTimerMS;
bool mLoaded;
String mLoadIf;
bool mGlobalLayer;
public:

View file

@ -4,6 +4,8 @@
#include "gui/containers/guiDynamicCtrlArrayCtrl.h"
#endif
#include "console/arrayObject.h"
IMPLEMENT_CONOBJECT(GameMode);
IMPLEMENT_CALLBACK(GameMode, onActivated, void, (), (),
@ -47,7 +49,9 @@ ConsoleSetType(TypeGameModeList)
GameMode::GameMode() :
mGameModeName(StringTable->EmptyString()),
mGameModeDesc(StringTable->EmptyString())
mGameModeDesc(StringTable->EmptyString()),
mIsActive(false),
mIsAlwaysActive(false)
{
INIT_ASSET(PreviewImage);
}
@ -62,6 +66,7 @@ void GameMode::initPersistFields()
INITPERSISTFIELD_IMAGEASSET(PreviewImage, GameMode, "Preview Image");
addField("active", TypeBool, Offset(mIsActive, GameMode), "Is the gamemode active");
addField("alwaysActive", TypeBool, Offset(mIsAlwaysActive, GameMode), "Is the gamemode always active");
}
bool GameMode::onAdd()
@ -110,6 +115,11 @@ void GameMode::setActive(const bool& active)
onDeactivated_callback();
}
void GameMode::setAlwaysActive(const bool& alwaysActive)
{
mIsAlwaysActive = alwaysActive;
}
DefineEngineMethod(GameMode, isActive, bool, (), ,
"Returns if the GameMode is currently active.\n"
"@return The active status of the GameMode")
@ -124,24 +134,38 @@ DefineEngineMethod(GameMode, setActive, void, (bool active), (true),
object->setActive(active);
}
DefineEngineFunction(getGameModesList, const char*, (), , "")
DefineEngineMethod(GameMode, isALwaysActive, bool, (), ,
"Returns if the GameMode is currently active.\n"
"@return The active status of the GameMode")
{
char* returnBuffer = Con::getReturnBuffer(1024);
return object->isActive();
}
String formattedList;
DefineEngineMethod(GameMode, setAlwaysActive, void, (bool alwaysActive), (true),
"Sets the active state of the GameMode.\n"
"@param active A bool of the state the GameMode should be set to")
{
object->setAlwaysActive(alwaysActive);
}
DefineEngineFunction(getGameModesList, ArrayObject*, (), , "")
{
ArrayObject* dictionary = new ArrayObject();
dictionary->registerObject();
char activeValBuffer[16];
for (SimGroup::iterator itr = Sim::getRootGroup()->begin(); itr != Sim::getRootGroup()->end(); itr++)
{
GameMode* gm = dynamic_cast<GameMode*>(*itr);
if (gm)
{
formattedList += String(gm->getName()) + ";";
dSprintf(activeValBuffer, 16, "%d", (gm->mIsActive || gm->mIsAlwaysActive));
dictionary->push_back(gm->getName(), activeValBuffer);
}
}
dSprintf(returnBuffer, 1024, "%s", formattedList.c_str());
return returnBuffer;
return dictionary;
}
//-----------------------------------------------------------------------------

View file

@ -22,6 +22,7 @@ private:
DECLARE_ASSET_SETGET(GameMode, PreviewImage);
bool mIsActive;
bool mIsAlwaysActive;
public:
@ -34,6 +35,9 @@ public:
bool isActive() { return mIsActive; }
void setActive(const bool& active);
bool isAlwaysActive() { return mIsAlwaysActive; }
void setAlwaysActive(const bool& alwaysActive);
DECLARE_CONOBJECT(GameMode);
static void findGameModes(const char* gameModeList, Vector<GameMode*>* outGameModes);