From 01b10cfb8904492d4641064a962fd45514b27817 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Thu, 19 Feb 2026 14:46:19 -0600 Subject: [PATCH 1/7] make reflectors optional don't waste memory per object-instance on non reflective objects --- Engine/source/T3D/shapeBase.cpp | 39 +++++++++++++++++++++++---------- Engine/source/T3D/shapeBase.h | 2 +- Engine/source/T3D/tsStatic.cpp | 36 +++++++++++++++++++++--------- Engine/source/T3D/tsStatic.h | 2 +- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 729271fae..96fadaf6e 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -975,6 +975,7 @@ ShapeBase::ShapeBase() mMoveMotion( false ), mShapeBaseMount( NULL ), mShapeInstance( NULL ), + mCubeReflector(NULL), mConvexList( new Convex ), mEnergy( 0.0f ), mRechargeRate( 0.0f ), @@ -1053,6 +1054,12 @@ ShapeBase::~ShapeBase() mShapeInstance = NULL; } + if (mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } + CollisionTimeout* ptr = mTimeoutList; while (ptr) { CollisionTimeout* cur = ptr; @@ -1173,7 +1180,11 @@ void ShapeBase::onRemove() if ( isClientObject() ) { - mCubeReflector.unregisterReflector(); + if (mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } } } @@ -1349,11 +1360,17 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) mLightPlugin->reset(); if ( isClientObject() ) - { - mCubeReflector.unregisterReflector(); - - if ( mDataBlock->reflectorDesc ) - mCubeReflector.registerReflector( this, mDataBlock->reflectorDesc ); + { + if (mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } + if (mDataBlock->reflectorDesc) + { + mCubeReflector = new CubeReflector(); + mCubeReflector->registerReflector(this, mDataBlock->reflectorDesc); + } } return true; @@ -2681,7 +2698,7 @@ void ShapeBase::_prepRenderImage( SceneRenderState *state, // If we're currently rendering our own reflection we // don't want to render ourselves into it. - if ( mCubeReflector.isRendering() ) + if (mCubeReflector && mCubeReflector->isRendering()) return; // We force all the shapes to use the highest detail @@ -2785,8 +2802,8 @@ void ShapeBase::prepBatchRender(SceneRenderState* state, S32 mountedImageIndex ) // Set up our TS render state. TSRenderState rdata; rdata.setSceneState( state ); - if ( mCubeReflector.isEnabled() ) - rdata.setCubemap( mCubeReflector.getCubemap() ); + if (mCubeReflector && mCubeReflector->isEnabled()) + rdata.setCubemap( mCubeReflector->getCubemap() ); rdata.setFadeOverride( (1.0f - mCloakLevel) * mFadeVal ); // We might have some forward lit materials @@ -2810,14 +2827,14 @@ void ShapeBase::prepBatchRender(SceneRenderState* state, S32 mountedImageIndex ) mat.scale( mObjScale ); GFX->setWorldMatrix( mat ); - if ( state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery() ) + if ( state->isDiffusePass() && mCubeReflector && mCubeReflector->isEnabled() && mCubeReflector->getOcclusionQuery() ) { RenderPassManager *pass = state->getRenderPass(); OccluderRenderInst *ri = pass->allocInst(); ri->type = RenderPassManager::RIT_Occluder; - ri->query = mCubeReflector.getOcclusionQuery(); + ri->query = mCubeReflector->getOcclusionQuery(); mObjToWorld.mulP( mObjBox.getCenter(), &ri->position ); ri->scale.set( mObjBox.getExtents() ); ri->orientation = pass->allocUniqueXform( mObjToWorld ); diff --git a/Engine/source/T3D/shapeBase.h b/Engine/source/T3D/shapeBase.h index a8807a026..71967bbe1 100644 --- a/Engine/source/T3D/shapeBase.h +++ b/Engine/source/T3D/shapeBase.h @@ -1207,7 +1207,7 @@ public: static F32 sFullCorrectionDistance; static F32 sCloakSpeed; // Time to cloak, in seconds - CubeReflector mCubeReflector; + CubeReflector* mCubeReflector; /// @name Initialization /// @{ diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 329485b4f..c244d25c3 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -109,7 +109,8 @@ F32 TSStatic::smStaticObjectUnfadeableSize = 75; TSStatic::TSStatic() : cubeDescId(0), - reflectorDesc(NULL) + reflectorDesc(NULL), + mCubeReflector(NULL) { mNetFlags.set(Ghostable | ScopeAlways); @@ -159,6 +160,11 @@ TSStatic::~TSStatic() delete mConvexList; mConvexList = NULL; mShapeAsset.unregisterRefreshNotify(); + if (mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } } ImplementEnumType(TSMeshType, @@ -361,10 +367,17 @@ bool TSStatic::onAdd() if (isClientObject()) { - mCubeReflector.unregisterReflector(); + if (mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } if (reflectorDesc) - mCubeReflector.registerReflector(this, reflectorDesc); + { + mCubeReflector = new CubeReflector(); + mCubeReflector->registerReflector(this, reflectorDesc); + } } _updateShouldTick(); @@ -594,8 +607,11 @@ void TSStatic::onRemove() mShapeInstance = NULL; mAmbientThread = NULL; - if (isClientObject()) - mCubeReflector.unregisterReflector(); + if (isClientObject() && mCubeReflector) + { + mCubeReflector->unregisterReflector(); + SAFE_DELETE(mCubeReflector); + } Parent::onRemove(); } @@ -780,7 +796,7 @@ void TSStatic::prepRenderImage(SceneRenderState* state) // If we're currently rendering our own reflection we // don't want to render ourselves into it. - if (mCubeReflector.isRendering()) + if (mCubeReflector && mCubeReflector->isRendering()) return; @@ -800,8 +816,8 @@ void TSStatic::prepRenderImage(SceneRenderState* state) rdata.setFadeOverride(1.0f); rdata.setOriginSort(mUseOriginSort); - if (mCubeReflector.isEnabled()) - rdata.setCubemap(mCubeReflector.getCubemap()); + if (mCubeReflector && mCubeReflector->isEnabled()) + rdata.setCubemap(mCubeReflector->getCubemap()); // Acculumation rdata.setAccuTex(mAccuTex); @@ -830,13 +846,13 @@ void TSStatic::prepRenderImage(SceneRenderState* state) mat.scale(mObjScale); GFX->setWorldMatrix(mat); - if (state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery()) + if (state->isDiffusePass() && mCubeReflector && mCubeReflector->isEnabled() && mCubeReflector->getOcclusionQuery()) { RenderPassManager* pass = state->getRenderPass(); OccluderRenderInst* ri = pass->allocInst(); ri->type = RenderPassManager::RIT_Occluder; - ri->query = mCubeReflector.getOcclusionQuery(); + ri->query = mCubeReflector->getOcclusionQuery(); mObjToWorld.mulP(mObjBox.getCenter(), &ri->position); ri->scale.set(mObjBox.getExtents()); ri->orientation = pass->allocUniqueXform(mObjToWorld); diff --git a/Engine/source/T3D/tsStatic.h b/Engine/source/T3D/tsStatic.h index 150aa59cf..7ab21ba0a 100644 --- a/Engine/source/T3D/tsStatic.h +++ b/Engine/source/T3D/tsStatic.h @@ -184,7 +184,7 @@ protected: String cubeDescName; U32 cubeDescId; ReflectorDesc* reflectorDesc; - CubeReflector mCubeReflector; + CubeReflector* mCubeReflector; void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override { From 57890a432764fe8df457c66c1d49054c48450559 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 21 Feb 2026 09:29:33 -0600 Subject: [PATCH 2/7] don't spool up new helper proxies if the goals are unchanged --- Engine/source/T3D/AI/AIAimTarget.cpp | 4 ++- Engine/source/T3D/AI/AIController.cpp | 47 ++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/Engine/source/T3D/AI/AIAimTarget.cpp b/Engine/source/T3D/AI/AIAimTarget.cpp index 35c7d927e..86ea7145b 100644 --- a/Engine/source/T3D/AI/AIAimTarget.cpp +++ b/Engine/source/T3D/AI/AIAimTarget.cpp @@ -194,7 +194,9 @@ DefineEngineMethod(AIController, getAimObject, S32, (), , "@see setAimObject()\n") { - SceneObject* obj = dynamic_cast(object->getAim()->mObj.getPointer()); + SceneObject* obj = NULL; + if (object->getAim()) + obj = dynamic_cast(object->getAim()->mObj.getPointer()); return obj ? obj->getId() : -1; } diff --git a/Engine/source/T3D/AI/AIController.cpp b/Engine/source/T3D/AI/AIController.cpp index 8ace880f1..d38eb4bfd 100644 --- a/Engine/source/T3D/AI/AIController.cpp +++ b/Engine/source/T3D/AI/AIController.cpp @@ -70,7 +70,12 @@ bool AIController::setControllerDataProperty(void* obj, const char* index, const void AIController::setGoal(AIInfo* targ) { - if (mGoal) { delete(mGoal); mGoal = NULL; } + if (mGoal) + { + if (mGoal->mObj.isValid() && targ->mObj.isValid() && mGoal->mObj == targ->mObj) + return; + delete(mGoal); mGoal = NULL; + } if (targ->mObj.isValid()) { @@ -86,26 +91,58 @@ void AIController::setGoal(AIInfo* targ) void AIController::setGoal(Point3F loc, F32 rad) { - if (mGoal) delete(mGoal); + if (mGoal) + { + if (mGoal->mPosSet && mGoal->getPosition() == loc) + { + mGoal->mRadius = rad; + return; + } + delete(mGoal); + } mGoal = new AIGoal(this, loc, rad); } void AIController::setGoal(SimObjectPtr objIn, F32 rad) { - if (mGoal) delete(mGoal); + if (mGoal) + { + if (mGoal->mObj.isValid() && objIn.isValid() && mGoal->mObj == objIn) + { + mGoal->mRadius = rad; + return; + } + delete(mGoal); + } mGoal = new AIGoal(this, objIn, rad); } void AIController::setAim(Point3F loc, F32 rad, Point3F offset) { - if (mAimTarget) delete(mAimTarget); + if (mAimTarget) + { + if (mAimTarget->mPosSet && mAimTarget->getPosition() == loc) + { + mAimTarget->mAimOffset = offset; + return; + } + delete(mAimTarget); + } mAimTarget = new AIAimTarget(this, loc, rad); mAimTarget->mAimOffset = offset; } void AIController::setAim(SimObjectPtr objIn, F32 rad, Point3F offset) { - if (mAimTarget) delete(mAimTarget); + if (mAimTarget) + { + if (mAimTarget->mObj.isValid() && objIn.isValid() && mAimTarget->mObj == objIn) + { + mAimTarget->mAimOffset = offset; + return; + } + delete(mAimTarget); + } mAimTarget = new AIAimTarget(this, objIn, rad); mAimTarget->mAimOffset = offset; } From 8e7af0bf55c7604943e39f216b402eeccb451508 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 21 Feb 2026 09:59:15 -0600 Subject: [PATCH 3/7] don't spool up new cover proxies if those are unchanged either --- Engine/source/T3D/AI/AIController.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Engine/source/T3D/AI/AIController.h b/Engine/source/T3D/AI/AIController.h index dcc46f661..361e4f518 100644 --- a/Engine/source/T3D/AI/AIController.h +++ b/Engine/source/T3D/AI/AIController.h @@ -70,8 +70,24 @@ public: private: AICover* mCover; public: - void setCover(Point3F loc, F32 rad = 0.0f) { delete(mCover); mCover = new AICover(this, loc, rad); } - void setCover(SimObjectPtr objIn, F32 rad = 0.0f) { delete(mCover); mCover = new AICover(this, objIn, rad); } + void setCover(Point3F loc, F32 rad = 0.0f) + { + if (mCover && mCover->mPosSet && mCover->getPosition() == loc) + { + mCover->mRadius == rad; + return; + } + delete(mCover); mCover = new AICover(this, loc, rad); + } + void setCover(SimObjectPtr objIn, F32 rad = 0.0f) + { + if (mCover && mCover->mObj == objIn) + { + mCover->mRadius == rad; + return; + } + delete(mCover); mCover = new AICover(this, objIn, rad); + } AICover* getCover() { return mCover; } bool findCover(const Point3F& from, F32 radius); void clearCover(); From 171211c4e2c8db036d5d33cf8d8f190a1748debd Mon Sep 17 00:00:00 2001 From: JeffR Date: Sat, 21 Feb 2026 11:03:07 -0600 Subject: [PATCH 4/7] Caches the processed line in CodeBlock for better assert reporting Adds additional context on eval and evaluate calls to better isolate script executions that are throwing errors, such as via command fields or eval() calls. --- Engine/source/T3D/trigger.cpp | 16 +++++++++++++--- Engine/source/console/consoleFunctions.cpp | 3 +-- Engine/source/console/torquescript/astNodes.cpp | 3 ++- Engine/source/console/torquescript/codeBlock.cpp | 2 ++ Engine/source/console/torquescript/codeBlock.h | 1 + Engine/source/console/torquescript/compiler.cpp | 9 ++++++--- .../source/gui/controls/guiGameListMenuCtrl.cpp | 4 +++- .../source/gui/controls/guiGameSettingsCtrl.cpp | 4 +++- Engine/source/gui/controls/guiListBoxCtrl.cpp | 4 +++- Engine/source/gui/controls/guiMLTextEditCtrl.cpp | 4 +++- Engine/source/gui/core/guiControl.cpp | 4 +++- Engine/source/sim/actionMap.cpp | 8 ++++++-- 12 files changed, 46 insertions(+), 16 deletions(-) diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index 9df293ba5..5df83f681 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/Engine/source/T3D/trigger.cpp @@ -742,7 +742,10 @@ void Trigger::potentialEnterObject(GameBase* enter) { String command = String("%obj = ") + enter->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mEnterCommand; - Con::evaluate(command.c_str()); + + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); + String context = String::ToString("%s, %s", getGroup(), objectName); + Con::evaluate(command.c_str(), false, context); } if( mDataBlock && testTrippable() && testCondition()) @@ -791,7 +794,10 @@ void Trigger::processTick(const Move* move) { String command = String("%obj = ") + remove->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mLeaveCommand; - Con::evaluate(command.c_str()); + + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); + String context = String::ToString("%s, %s", getGroup(), objectName); + Con::evaluate(command.c_str(), false, context); } if (testTrippable() && testCondition()) mDataBlock->onLeaveTrigger_callback( this, remove ); @@ -800,7 +806,11 @@ void Trigger::processTick(const Move* move) } if (evalCmD(&mTickCommand)) - Con::evaluate(mTickCommand.c_str()); + { + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); + String context = String::ToString("%s, %s", getGroup(), objectName); + Con::evaluate(mTickCommand.c_str(), false, context); + } if (mObjects.size() != 0 && testTrippable() && testCondition()) mDataBlock->onTickTrigger_callback( this ); diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index 77f1e78c2..5da712e5d 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -2367,8 +2367,7 @@ DefineEngineFunction( exec, bool, ( const char* fileName, bool noCalls, bool jou DefineEngineFunction( eval, const char*, ( const char* consoleString, bool echo ), (false), "eval(consoleString)") { - Con::EvalResult returnValue = Con::evaluate(consoleString, echo, NULL); - + Con::EvalResult returnValue = Con::evaluate(consoleString, echo, Platform::makeRelativePathName(Con::getCurrentScriptModulePath(), NULL)); return Con::getReturnBuffer(returnValue.value.getString()); } diff --git a/Engine/source/console/torquescript/astNodes.cpp b/Engine/source/console/torquescript/astNodes.cpp index 6fd28bc58..e1f3f6224 100644 --- a/Engine/source/console/torquescript/astNodes.cpp +++ b/Engine/source/console/torquescript/astNodes.cpp @@ -59,7 +59,8 @@ inline FuncVars* getFuncVars(S32 lineNumber) { if (gFuncVars == &gGlobalScopeFuncVars) { - const char* str = avar("Attemping to use local variable in global scope. File: %s Line: %d", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); + const char* lineTxt = CodeBlock::smCurrentLineText; + const char* str = avar("Attemping to use local variable in global scope. File: %s Line Num: %d \nLine: %s", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); scriptErrorHandler(str); } return gFuncVars; diff --git a/Engine/source/console/torquescript/codeBlock.cpp b/Engine/source/console/torquescript/codeBlock.cpp index 5a4bdb30a..cd324767d 100644 --- a/Engine/source/console/torquescript/codeBlock.cpp +++ b/Engine/source/console/torquescript/codeBlock.cpp @@ -35,6 +35,7 @@ using namespace Compiler; bool CodeBlock::smInFunction = false; CodeBlock * CodeBlock::smCodeBlockList = NULL; +StringTableEntry CodeBlock::smCurrentLineText = StringTable->EmptyString(); TorqueScriptParser *CodeBlock::smCurrentParser = NULL; extern FuncVars gEvalFuncVars; @@ -578,6 +579,7 @@ Con::EvalResult CodeBlock::compileExec(StringTableEntry fileName, const char *in consoleAllocReset(); name = fileName; + smCurrentLineText = inString; if (fileName) { diff --git a/Engine/source/console/torquescript/codeBlock.h b/Engine/source/console/torquescript/codeBlock.h index b9d7dd207..cef6d2683 100644 --- a/Engine/source/console/torquescript/codeBlock.h +++ b/Engine/source/console/torquescript/codeBlock.h @@ -61,6 +61,7 @@ private: public: static bool smInFunction; static TorqueScriptParser * smCurrentParser; + static StringTableEntry smCurrentLineText; static CodeBlock *getCodeBlockList() { diff --git a/Engine/source/console/torquescript/compiler.cpp b/Engine/source/console/torquescript/compiler.cpp index 51bf7c0c5..24e9135cc 100644 --- a/Engine/source/console/torquescript/compiler.cpp +++ b/Engine/source/console/torquescript/compiler.cpp @@ -160,7 +160,8 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber, if (found->second.isConstant) { - const char* str = avar("Script Warning: Reassigning variable %s when it is a constant. File: %s Line : %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); + const char* lineTxt = CodeBlock::smCurrentLineText; + const char* str = avar("Script Warning: Reassigning variable %s when it is a constant. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); scriptErrorHandler(str); } return found->second.reg; @@ -179,7 +180,8 @@ S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber) if (found == vars.end()) { - const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); + const char* lineTxt = CodeBlock::smCurrentLineText; + const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); scriptErrorHandler(str); return assign(var, TypeReqString, lineNumber, false); @@ -194,7 +196,8 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber) if (found == vars.end()) { - const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber); + const char* lineText = CodeBlock::smCurrentLineText; + const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineText); scriptErrorHandler(str); assign(var, TypeReqString, lineNumber, false); diff --git a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp index fb69fbc71..a81551d0e 100644 --- a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp +++ b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp @@ -974,7 +974,9 @@ void GuiGameListMenuCtrl::doScriptCommand(StringTableEntry command) if (command && command[0]) { setThisControl(); - Con::evaluate(command, false, __FILE__); + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + Con::evaluate(command, false, context); } } diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp index 0b1e7ebea..ea3fd2ece 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -494,7 +494,9 @@ void GuiGameSettingsCtrl::doScriptCommand(StringTableEntry command) if (command && command[0]) { setThisControl(); - Con::evaluate(command, false, __FILE__); + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + Con::evaluate(command, false, context); } } diff --git a/Engine/source/gui/controls/guiListBoxCtrl.cpp b/Engine/source/gui/controls/guiListBoxCtrl.cpp index 66328b2b3..5a5a81e6a 100644 --- a/Engine/source/gui/controls/guiListBoxCtrl.cpp +++ b/Engine/source/gui/controls/guiListBoxCtrl.cpp @@ -1539,7 +1539,9 @@ StringTableEntry GuiListBoxCtrl::_makeMirrorItemName( SimObject *inObj ) Con::setIntVariable( "$ThisControl", getId() ); Con::setIntVariable( "$ThisObject", inObj->getId() ); - outName = StringTable->insert( Con::evaluate( mMakeNameCallback ).value, true ); + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + outName = StringTable->insert( Con::evaluate( mMakeNameCallback, false, context).value, true ); } else if ( inObj->getName() ) outName = StringTable->insert( inObj->getName() ); diff --git a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp index 75cebfd41..d22300f37 100644 --- a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp @@ -211,7 +211,9 @@ bool GuiMLTextEditCtrl::onKeyDown(const GuiEvent& event) case KEY_ESCAPE: if ( mEscapeCommand[0] ) { - Con::evaluate( mEscapeCommand ); + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + Con::evaluate( mEscapeCommand, false, context ); return( true ); } return( Parent::onKeyDown( event ) ); diff --git a/Engine/source/gui/core/guiControl.cpp b/Engine/source/gui/core/guiControl.cpp index bc175e9fb..406a803d4 100644 --- a/Engine/source/gui/core/guiControl.cpp +++ b/Engine/source/gui/core/guiControl.cpp @@ -2495,7 +2495,9 @@ void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent const char* GuiControl::evaluate( const char* str ) { smThisControl = this; - const char* result = Con::evaluate(str, false).value; + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + const char* result = Con::evaluate(str, false, context).value; smThisControl = NULL; return result; diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index 2e9c3b0e7..d392ab3d2 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -1482,8 +1482,12 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) if(pNode->flags & Node::BindCmd) { // it's a bind command - if(pNode->makeConsoleCommand) - Con::evaluate(pNode->makeConsoleCommand); + if (pNode->makeConsoleCommand) + { + StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); + String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + Con::evaluate(pNode->makeConsoleCommand, false, context); + } } else if (pNode->flags & Node::Held) { From 9084e81bc1fd80a55c6a3483037f52dfb5612b5a Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 22 Feb 2026 18:18:42 -0600 Subject: [PATCH 5/7] Shifted CodeBlock::smCurrentLineText to be a const char* so it's use is clearer Ensured CodeBlock::smCurrentLineText is cleared at the end of execution Tweaked and cleaned up the context lines passed along for further debugging data in the event of a script assert --- Engine/source/T3D/SubScene.cpp | 11 ++++- Engine/source/T3D/missionMarker.cpp | 12 ++++- Engine/source/T3D/trigger.cpp | 45 ++++++++++++++++--- .../source/console/torquescript/astNodes.cpp | 2 +- .../source/console/torquescript/codeBlock.cpp | 8 +++- .../source/console/torquescript/codeBlock.h | 2 +- .../source/console/torquescript/compiler.cpp | 34 +++++++++++--- .../gui/controls/guiGameListMenuCtrl.cpp | 2 +- .../gui/controls/guiGameSettingsCtrl.cpp | 2 +- Engine/source/gui/core/guiControl.cpp | 10 ++++- Engine/source/sim/actionMap.cpp | 2 +- 11 files changed, 107 insertions(+), 23 deletions(-) diff --git a/Engine/source/T3D/SubScene.cpp b/Engine/source/T3D/SubScene.cpp index effda500f..4dca81595 100644 --- a/Engine/source/T3D/SubScene.cpp +++ b/Engine/source/T3D/SubScene.cpp @@ -225,7 +225,16 @@ bool SubScene::evaluateCondition() Con::setBoolVariable(resVar.c_str(), false); String command = resVar + "=" + mLoadIf + ";"; - Con::evaluatef(command.c_str()); + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); + Con::evaluate(command.c_str(), false, context); return Con::getBoolVariable(resVar.c_str()); } return true; diff --git a/Engine/source/T3D/missionMarker.cpp b/Engine/source/T3D/missionMarker.cpp index 69ae9ab81..9acf4c61c 100644 --- a/Engine/source/T3D/missionMarker.cpp +++ b/Engine/source/T3D/missionMarker.cpp @@ -367,7 +367,17 @@ bool SpawnSphere::testCondition() String resVar = getIdString() + String(".result"); Con::setBoolVariable(resVar.c_str(), false); String command = resVar + "=" + mSpawnIf + ";"; - Con::evaluatef(command.c_str()); + + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); + Con::evaluate(command.c_str(), false, context); if (Con::getBoolVariable(resVar.c_str()) == 1) { return true; diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index 5df83f681..95a331851 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/Engine/source/T3D/trigger.cpp @@ -704,7 +704,17 @@ bool Trigger::testCondition() String resVar = getIdString() + String(".result"); Con::setBoolVariable(resVar.c_str(), false); String command = resVar + "=" + mTripIf + ";"; - Con::evaluatef(command.c_str()); + + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); + Con::evaluate(command.c_str(), false, context); if (Con::getBoolVariable(resVar.c_str()) == 1) { return true; @@ -743,8 +753,15 @@ void Trigger::potentialEnterObject(GameBase* enter) String command = String("%obj = ") + enter->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mEnterCommand; - StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); - String context = String::ToString("%s, %s", getGroup(), objectName); + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); Con::evaluate(command.c_str(), false, context); } @@ -795,8 +812,15 @@ void Trigger::processTick(const Move* move) String command = String("%obj = ") + remove->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mLeaveCommand; - StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); - String context = String::ToString("%s, %s", getGroup(), objectName); + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); Con::evaluate(command.c_str(), false, context); } if (testTrippable() && testCondition()) @@ -807,8 +831,15 @@ void Trigger::processTick(const Move* move) if (evalCmD(&mTickCommand)) { - StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getIdString(); - String context = String::ToString("%s, %s", getGroup(), objectName); + StringTableEntry objectName = getName(); + if (objectName != NULL) + objectName = getIdString(); + + StringTableEntry groupName = getGroup()->getName(); + if (groupName != NULL) + groupName = getGroup()->getIdString(); + + String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); Con::evaluate(mTickCommand.c_str(), false, context); } diff --git a/Engine/source/console/torquescript/astNodes.cpp b/Engine/source/console/torquescript/astNodes.cpp index e1f3f6224..c20a0b975 100644 --- a/Engine/source/console/torquescript/astNodes.cpp +++ b/Engine/source/console/torquescript/astNodes.cpp @@ -60,7 +60,7 @@ inline FuncVars* getFuncVars(S32 lineNumber) if (gFuncVars == &gGlobalScopeFuncVars) { const char* lineTxt = CodeBlock::smCurrentLineText; - const char* str = avar("Attemping to use local variable in global scope. File: %s Line Num: %d \nLine: %s", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); + const char* str = avar("Attemping to use local variable in global scope. File: %s\nLine Num: %d\nLine: \"%s\"", CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); scriptErrorHandler(str); } return gFuncVars; diff --git a/Engine/source/console/torquescript/codeBlock.cpp b/Engine/source/console/torquescript/codeBlock.cpp index cd324767d..d3bf6b3f5 100644 --- a/Engine/source/console/torquescript/codeBlock.cpp +++ b/Engine/source/console/torquescript/codeBlock.cpp @@ -35,7 +35,7 @@ using namespace Compiler; bool CodeBlock::smInFunction = false; CodeBlock * CodeBlock::smCodeBlockList = NULL; -StringTableEntry CodeBlock::smCurrentLineText = StringTable->EmptyString(); +const char* CodeBlock::smCurrentLineText = "\0"; TorqueScriptParser *CodeBlock::smCurrentParser = NULL; extern FuncVars gEvalFuncVars; @@ -625,6 +625,7 @@ Con::EvalResult CodeBlock::compileExec(StringTableEntry fileName, const char *in if (!Script::gStatementList) { + smCurrentLineText = "\0"; delete this; return Con::EvalResult(Con::getVariable("$ScriptError")); } @@ -670,7 +671,10 @@ Con::EvalResult CodeBlock::compileExec(StringTableEntry fileName, const char *in Con::warnf(ConsoleLogEntry::General, "precompile size mismatch, precompile: %d compile: %d", codeSize, lastIp); // repurpose argc as local register counter for global state - return (exec(0, fileName, NULL, localRegisterCount, 0, noCalls, NULL, setFrame)); + Con::EvalResult execResult = (exec(0, fileName, NULL, localRegisterCount, 0, noCalls, NULL, setFrame)); + + smCurrentLineText = "\0"; + return execResult; } //------------------------------------------------------------------------- diff --git a/Engine/source/console/torquescript/codeBlock.h b/Engine/source/console/torquescript/codeBlock.h index cef6d2683..33404d9a6 100644 --- a/Engine/source/console/torquescript/codeBlock.h +++ b/Engine/source/console/torquescript/codeBlock.h @@ -61,7 +61,7 @@ private: public: static bool smInFunction; static TorqueScriptParser * smCurrentParser; - static StringTableEntry smCurrentLineText; + static const char* smCurrentLineText; static CodeBlock *getCodeBlockList() { diff --git a/Engine/source/console/torquescript/compiler.cpp b/Engine/source/console/torquescript/compiler.cpp index 24e9135cc..206f7d679 100644 --- a/Engine/source/console/torquescript/compiler.cpp +++ b/Engine/source/console/torquescript/compiler.cpp @@ -160,8 +160,16 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber, if (found->second.isConstant) { - const char* lineTxt = CodeBlock::smCurrentLineText; - const char* str = avar("Script Warning: Reassigning variable %s when it is a constant. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); + const char* lineText = CodeBlock::smCurrentLineText; + + String codeString = CodeBlock::smCurrentLineText; + Vector splitLines; + codeString.split("\n", splitLines); + + if (lineNumber > 0 && splitLines.size() > lineNumber) + lineText = splitLines[lineNumber - 1].c_str(); + + const char* str = avar("Script Warning: Reassigning variable %s when it is a constant. File: %s\nLine Num: %d\nLine: \"%s\"", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineText); scriptErrorHandler(str); } return found->second.reg; @@ -180,8 +188,16 @@ S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber) if (found == vars.end()) { - const char* lineTxt = CodeBlock::smCurrentLineText; - const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineTxt); + const char* lineText = CodeBlock::smCurrentLineText; + + String codeString = CodeBlock::smCurrentLineText; + Vector splitLines; + codeString.split("\n", splitLines); + + if (lineNumber > 0 && splitLines.size() > lineNumber) + lineText = splitLines[lineNumber - 1].c_str(); + + const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s\nLine Num: %d\nLine: \"%s\"", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineText); scriptErrorHandler(str); return assign(var, TypeReqString, lineNumber, false); @@ -197,7 +213,15 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber) if (found == vars.end()) { const char* lineText = CodeBlock::smCurrentLineText; - const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line Num: %d \nLine: %s", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineText); + + String codeString = CodeBlock::smCurrentLineText; + Vector splitLines; + codeString.split("\n", splitLines); + + if (lineNumber > 0 && splitLines.size() > lineNumber) + lineText = splitLines[lineNumber-1].c_str(); + + const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s\nLine Num: %d\nLine: \"%s\"", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber, lineText); scriptErrorHandler(str); assign(var, TypeReqString, lineNumber, false); diff --git a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp index a81551d0e..2509c8cbd 100644 --- a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp +++ b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp @@ -975,7 +975,7 @@ void GuiGameListMenuCtrl::doScriptCommand(StringTableEntry command) { setThisControl(); StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); - String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + String context = String::ToString("%s\nObject: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); Con::evaluate(command, false, context); } } diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp index ea3fd2ece..778c3c7b7 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -495,7 +495,7 @@ void GuiGameSettingsCtrl::doScriptCommand(StringTableEntry command) { setThisControl(); StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); - String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + String context = String::ToString("%s\nObject: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); Con::evaluate(command, false, context); } } diff --git a/Engine/source/gui/core/guiControl.cpp b/Engine/source/gui/core/guiControl.cpp index 406a803d4..b7b272612 100644 --- a/Engine/source/gui/core/guiControl.cpp +++ b/Engine/source/gui/core/guiControl.cpp @@ -2495,8 +2495,14 @@ void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent const char* GuiControl::evaluate( const char* str ) { smThisControl = this; - StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); - String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + StringTableEntry objectName = getName(); + if (getName() == NULL) + objectName = getInternalName(); + StringTableEntry fileName = getFilename(); + if (fileName != NULL) + fileName = Platform::makeRelativePathName(fileName, NULL); + + String context = String::ToString("%s\nObject: %s", fileName, objectName); const char* result = Con::evaluate(str, false, context).value; smThisControl = NULL; diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index d392ab3d2..e492752f5 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -1485,7 +1485,7 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) if (pNode->makeConsoleCommand) { StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); - String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); + String context = String::ToString("%s\nObject: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); Con::evaluate(pNode->makeConsoleCommand, false, context); } } From 627b9bc076304ee447afff382ce65ac6dd3796b4 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 24 Feb 2026 15:04:38 -0600 Subject: [PATCH 6/7] minor cleanups for https://github.com/TorqueGameEngines/Torque3D/pull/1672 for context Strings, use c_str(), for triggers, use Con::getCurrentScriptModulePath() as otherwise, the "%this =" and "%obj=" injections will be treated as within the global scope. which is not allowed. --- Engine/source/T3D/trigger.cpp | 34 +++++-------------- .../gui/controls/guiGameSettingsCtrl.cpp | 2 +- .../source/gui/controls/guiMLTextEditCtrl.cpp | 2 +- Engine/source/sim/actionMap.cpp | 2 +- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/Engine/source/T3D/trigger.cpp b/Engine/source/T3D/trigger.cpp index 95a331851..33075e70d 100644 --- a/Engine/source/T3D/trigger.cpp +++ b/Engine/source/T3D/trigger.cpp @@ -28,6 +28,7 @@ #include "console/engineAPI.h" #include "collision/boxConvex.h" #include "console/script.h" +#include "console/consoleInternal.h" #include "core/stream/bitStream.h" #include "math/mathIO.h" @@ -172,8 +173,9 @@ Trigger::Trigger() mPhysicsRep = NULL; mTripOnce = false; + mTripped = false; mTrippedBy = 0xFFFFFFFF; - mTripIf = ""; + mTripIf.clear(); //Default up a basic square Point3F vecs[3] = { Point3F(1.0, 0.0, 0.0), @@ -748,21 +750,11 @@ void Trigger::potentialEnterObject(GameBase* enter) mObjects.push_back(enter); deleteNotify(enter); - if(evalCmD(&mEnterCommand)) + if(isServerObject() && evalCmD(&mEnterCommand)) { String command = String("%obj = ") + enter->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mEnterCommand; - - StringTableEntry objectName = getName(); - if (objectName != NULL) - objectName = getIdString(); - - StringTableEntry groupName = getGroup()->getName(); - if (groupName != NULL) - groupName = getGroup()->getIdString(); - - String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); - Con::evaluate(command.c_str(), false, context); + Con::evaluate(command.c_str(), false, Con::getCurrentScriptModulePath()); } if( mDataBlock && testTrippable() && testCondition()) @@ -807,21 +799,11 @@ void Trigger::processTick(const Move* move) mObjects.erase(i); clearNotify(remove); - if (evalCmD(&mLeaveCommand)) + if (isServerObject() && evalCmD(&mLeaveCommand)) { String command = String("%obj = ") + remove->getIdString() + ";"; command = command + String("%this = ") + getIdString() + ";" + mLeaveCommand; - - StringTableEntry objectName = getName(); - if (objectName != NULL) - objectName = getIdString(); - - StringTableEntry groupName = getGroup()->getName(); - if (groupName != NULL) - groupName = getGroup()->getIdString(); - - String context = String::ToString("%s\nGroup: %s, Object: %s", getFilename(), groupName, objectName); - Con::evaluate(command.c_str(), false, context); + Con::evaluate(command.c_str(), false, Con::getCurrentScriptModulePath()); } if (testTrippable() && testCondition()) mDataBlock->onLeaveTrigger_callback( this, remove ); @@ -829,7 +811,7 @@ void Trigger::processTick(const Move* move) } } - if (evalCmD(&mTickCommand)) + if (isServerObject() && evalCmD(&mTickCommand)) { StringTableEntry objectName = getName(); if (objectName != NULL) diff --git a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp index 778c3c7b7..a562782a3 100644 --- a/Engine/source/gui/controls/guiGameSettingsCtrl.cpp +++ b/Engine/source/gui/controls/guiGameSettingsCtrl.cpp @@ -496,7 +496,7 @@ void GuiGameSettingsCtrl::doScriptCommand(StringTableEntry command) setThisControl(); StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); String context = String::ToString("%s\nObject: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); - Con::evaluate(command, false, context); + Con::evaluate(command, false, context.c_str()); } } diff --git a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp index d22300f37..04a176f9e 100644 --- a/Engine/source/gui/controls/guiMLTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiMLTextEditCtrl.cpp @@ -213,7 +213,7 @@ bool GuiMLTextEditCtrl::onKeyDown(const GuiEvent& event) { StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); String context = String::ToString("%s, Object: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); - Con::evaluate( mEscapeCommand, false, context ); + Con::evaluate( mEscapeCommand, false, context.c_str()); return( true ); } return( Parent::onKeyDown( event ) ); diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index e492752f5..16d107eb3 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -1486,7 +1486,7 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) { StringTableEntry objectName = getName() != StringTable->EmptyString() ? getName() : getInternalName(); String context = String::ToString("%s\nObject: %s", Platform::makeRelativePathName(getFilename(), NULL), objectName); - Con::evaluate(pNode->makeConsoleCommand, false, context); + Con::evaluate(pNode->makeConsoleCommand, false, context.c_str()); } } else if (pNode->flags & Node::Held) From 2b6b56d0d98296991f1d072fbcb122ffd862c0a0 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Tue, 24 Feb 2026 17:03:12 -0600 Subject: [PATCH 7/7] don't flip invertroughness on by default --- Engine/source/T3D/assets/assetImporter.cpp | 2 +- Engine/source/ts/assimp/assimpAppMaterial.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index a807bbc0f..ec0fd1f89 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -3003,7 +3003,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) if (hasRoughness) { - newMat->mInvertRoughness[0] = true; + newMat->mInvertRoughness[0] = false; } newAsset->addObject(newMat); diff --git a/Engine/source/ts/assimp/assimpAppMaterial.cpp b/Engine/source/ts/assimp/assimpAppMaterial.cpp index fce979dfc..1d560da30 100644 --- a/Engine/source/ts/assimp/assimpAppMaterial.cpp +++ b/Engine/source/ts/assimp/assimpAppMaterial.cpp @@ -206,15 +206,15 @@ void AssimpAppMaterial::initMaterial(const Torque::Path& path, Material* mat) co if (rmName.isNotEmpty()) { mat->_setRoughMap(cleanTextureName(rmName, cleanFile, path, false), 0); // Roughness - mat->mRoughnessChan[0] = 1.0f; - mat->mInvertRoughness[0] = (floatVal == 1.0f); + mat->mRoughnessChan[0] = 1; + mat->mInvertRoughness[0] = false; mat->_setMetalMap(cleanTextureName(rmName, cleanFile, path, false), 0); // Metallic - mat->mMetalChan[0] = 2.0f; + mat->mMetalChan[0] = 2; } if (aoName.isNotEmpty()) { mat->_setAOMap(cleanTextureName(aoName, cleanFile, path, false), 0); // occlusion - mat->mAOChan[0] = 0.0f; + mat->mAOChan[0] = 0; } else {