@@ -71,7 +71,7 @@ void MovableObject::Clear()
71
71
m_ToSettle = false ;
72
72
m_ToDelete = false ;
73
73
m_HUDVisible = true ;
74
- m_ScriptPath .clear ();
74
+ m_LoadedScripts .clear ();
75
75
m_ScriptPresetName.clear ();
76
76
m_ScriptObjectName.clear ();
77
77
m_ScreenEffectFile.Reset ();
@@ -205,10 +205,10 @@ int MovableObject::Create(const MovableObject &reference)
205
205
m_MissionCritical = reference.m_MissionCritical ;
206
206
m_CanBeSquished = reference.m_CanBeSquished ;
207
207
m_HUDVisible = reference.m_HUDVisible ;
208
- m_ScriptPath = reference.m_ScriptPath ;
208
+ for (std::pair<std::string, bool > scriptEntry : reference.m_LoadedScripts ) {
209
+ m_LoadedScripts.push_back ({scriptEntry.first , scriptEntry.second });
210
+ }
209
211
m_ScriptPresetName = reference.m_ScriptPresetName ;
210
- // Should be unique to the object, will be created lazily upon first UpdateScript
211
- // m_ScriptObjectName
212
212
if (reference.m_pScreenEffect )
213
213
{
214
214
m_ScreenEffectFile = reference.m_ScreenEffectFile ;
@@ -449,108 +449,113 @@ int MovableObject::Save(Writer &writer) const
449
449
return 0 ;
450
450
}
451
451
452
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
452
453
453
- // ////////////////////////////////////////////////////////////////////////////////////////
454
- // Method: Destroy
455
- // ////////////////////////////////////////////////////////////////////////////////////////
456
- // Description: Destroys and resets (through Clear()) the MovableObject object.
457
-
458
- void MovableObject::Destroy (bool notInherited)
459
- {
460
- // Clean up the existence of this in the script state
461
- if (!m_ScriptObjectName.empty ())
462
- {
463
- // Call the scripted destruction function, but only after first checking if it and this instance's Lua representation really exists
464
- g_LuaMan.RunScriptString (" if " + m_ScriptPresetName + " and " + m_ScriptPresetName + " .Destroy and " + m_ScriptObjectName + " then " + m_ScriptPresetName + " .Destroy(" + m_ScriptObjectName + " ); end" );
465
- // Assign nil to the variable that held this' representation in Lua
466
- g_LuaMan.RunScriptString (" if " + m_ScriptObjectName + " then " + m_ScriptObjectName + " = nil; end" );
454
+ void MovableObject::Destroy (bool notInherited) {
455
+ if (!m_ScriptObjectName.empty ()) {
456
+ for (std::pair<std::string, bool > scriptEntry: m_LoadedScripts) {
457
+ if (scriptEntry.second == true ) {
458
+ g_LuaMan.RunFunctionInPresetScript (" Destroy" , scriptEntry.first , m_ScriptPresetName, m_ScriptObjectName);
459
+ }
460
+ }
461
+ g_LuaMan.RunScriptString (m_ScriptObjectName + " = nil;" );
467
462
}
468
463
469
- if (!notInherited)
470
- SceneObject::Destroy ();
464
+ if (!notInherited) { SceneObject::Destroy (); }
471
465
Clear ();
472
466
473
467
g_MovableMan.UnregisterObject (this );
474
468
}
475
469
470
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
476
471
477
- // ////////////////////////////////////////////////////////////////////////////////////////
478
- // Virtual method: LoadScripts
479
- // ////////////////////////////////////////////////////////////////////////////////////////
480
- // Description: Loads the preset scripts of this object, from a specified path.
481
-
482
- int MovableObject::LoadScripts (string scriptPath)
483
- {
484
- if (scriptPath.empty ())
472
+ int MovableObject::LoadScript (std::string const &scriptPath, bool loadAsEnabledScript) {
473
+ // Return an error if the script path is empty or already there
474
+ if (scriptPath.empty ()) {
485
475
return -1 ;
486
-
487
- // Read in the Lua script function definitions for this preset
488
- int error = 0 ;
489
-
490
- // Save the script path
491
- m_ScriptPath = scriptPath;
476
+ } else if (HasScript (scriptPath)) {
477
+ return -2 ;
478
+ }
479
+ m_LoadedScripts.push_back ({scriptPath, loadAsEnabledScript});
492
480
493
481
// Clear the temporary variable names that will hold the functions read in from the file
494
- if ((error = g_LuaMan.RunScriptString (" Create = nil; Destroy = nil; Update = nil;" )) < 0 )
495
- return error;
496
-
497
- // Run the file that specifies the Lua functions for this' operating logic
498
- if ((error = g_LuaMan.RunScriptFile (m_ScriptPath)) < 0 )
499
- return error;
500
-
482
+ for (std::string functionName : GetSupportedScriptFunctionNames ()) {
483
+ if (g_LuaMan.RunScriptString (functionName + " = nil;" ) < 0 ) {
484
+ return -3 ;
485
+ }
486
+ }
501
487
// Create a new table for all presets and object instances of this class, to organize things a bit
502
- if ((error = g_LuaMan.RunScriptString (" if not " + GetClassName () + " s then " + GetClassName () + " s = {}; end" )) < 0 )
503
- return error;
504
- // TODO WAIT A MINUTE.. is this an original preset????!! .. does it matter? A: not really
505
- // Get a new ID for this original preset so we can assign the read-in function definitions to it
506
- m_ScriptPresetName = GetClassName () + " s." + g_LuaMan.GetNewPresetID ();
488
+ if (g_LuaMan.RunScriptString (GetClassName () + " s = " + GetClassName () + " s or {};" ) < 0 ) {
489
+ return -3 ;
490
+ }
507
491
508
- // Clear out the instance object name so it gets created in the state upon first UpdateScript
509
- m_ScriptObjectName.clear ();
492
+ // Run the specified lua file to load everything in it into the global namespace for assignment
493
+ if (g_LuaMan.RunScriptFile (scriptPath) < 0 ) {
494
+ return -4 ;
495
+ }
510
496
511
- // Under the class' table, create a new table for all functions of this specific preset and its unique ID
512
- if ((error = g_LuaMan.RunScriptString (m_ScriptPresetName + " = {};" )) < 0 )
513
- return error;
497
+ // If there's no ScriptPresetName this is the first script being loaded for this preset, or scripts have been reloaded.
498
+ // Generate a ScriptPresetName, setup a table for the preset's functions, and clear the instance object name so it gets created in the first run of UpdateScripts
499
+ if (m_ScriptPresetName.empty ()) {
500
+ // TODO WAIT A MINUTE.. is this an original preset????!! .. does it matter? A: not really
501
+ m_ScriptPresetName = GetClassName () + " s." + g_LuaMan.GetNewPresetID ();
514
502
515
- // Now assign the different functions read in from the script file to the permanent locations of this original preset's table
516
- if ((error = g_LuaMan.RunScriptString (" if Create then " + m_ScriptPresetName + " .Create = Create; end;" )) < 0 )
517
- return error;
518
- if ((error = g_LuaMan.RunScriptString (" if Destroy then " + m_ScriptPresetName + " .Destroy = Destroy; end;" )) < 0 )
519
- return error;
520
- if ((error = g_LuaMan.RunScriptString (" if Update then " + m_ScriptPresetName + " .Update = Update; end;" )) < 0 )
521
- return error;
522
- if ((error = g_LuaMan.RunScriptString (" if OnPieMenu then " + m_ScriptPresetName + " .OnPieMenu = OnPieMenu; end;" )) < 0 )
523
- return error;
503
+ if (g_LuaMan.RunScriptString (m_ScriptPresetName + " = {};" ) < 0 ) {
504
+ return -3 ;
505
+ }
524
506
525
- return error ;
526
- }
507
+ m_ScriptObjectName. clear () ;
508
+ }
527
509
510
+ // Assign the different functions read in from the script to their permanent locations in the preset's table
511
+ for (std::string functionName : GetSupportedScriptFunctionNames ()) {
512
+ if (g_LuaMan.GlobalIsDefined (functionName)) {
513
+ int error = g_LuaMan.RunScriptString (
514
+ m_ScriptPresetName + " ." + functionName + " = " + m_ScriptPresetName + " ." + functionName + " or {}; " +
515
+ m_ScriptPresetName + " ." + functionName + " [\" " + scriptPath + " \" ] = " + functionName + " ;"
516
+ );
517
+
518
+ if (error < 0 ) {
519
+ return -3 ;
520
+ }
521
+ }
522
+ }
523
+ return 0 ;
524
+ }
528
525
529
- // ////////////////////////////////////////////////////////////////////////////////////////
530
- // Virtual method: ReloadScripts
531
- // ////////////////////////////////////////////////////////////////////////////////////////
532
- // Description: Reloads the preset scripts of this object, from the same script file
533
- // path as was originally defined. This will also update the original
534
- // preset in the PresetMan with the updated scripts so future objects
535
- // spawned will use the new scripts.
526
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
536
527
537
- int MovableObject::ReloadScripts ()
538
- {
539
- int error = 0 ;
528
+ int MovableObject::ReloadScripts () {
529
+ if (m_LoadedScripts.empty ()) {
530
+ return 0 ;
531
+ }
540
532
541
- // Read in the Lua script function definitions for this preset
542
- if (!m_ScriptPath.empty ())
543
- {
544
- // Reload the preset funcitons of this instance
545
- if ((error = LoadScripts (m_ScriptPath)) < 0 )
546
- return error;
547
- // Now also reload the ones of the original preset of this so all future objects will use the new scripts
548
- MovableObject *pPreset = const_cast <MovableObject *>(dynamic_cast <const MovableObject *>(g_PresetMan.GetEntityPreset (GetClassName (), GetPresetName (), GetModuleID ())));
549
- if (pPreset && pPreset != this )
550
- {
551
- if ((error = pPreset->LoadScripts (m_ScriptPath)) < 0 )
552
- return error;
533
+ auto clearScriptConfigurationAndLoadPreexistingScripts = [](MovableObject *object) {
534
+ std::vector<std::pair<std::string, bool >> loadedScriptsCopy = object->m_LoadedScripts ;
535
+ object->m_LoadedScripts .clear ();
536
+ object->m_ScriptPresetName .clear ();
537
+
538
+ int status = 0 ;
539
+ for (std::pair<std::string, bool > scriptEntry : loadedScriptsCopy) {
540
+ status = object->LoadScript (scriptEntry.first , scriptEntry.second );
541
+ if (status < 0 ) {
542
+ return status;
543
+ }
553
544
}
545
+ return status;
546
+ };
547
+
548
+ int status = clearScriptConfigurationAndLoadPreexistingScripts (this );
549
+ if (status >= 0 ) {
550
+ return status;
551
+ }
552
+ MovableObject *pPreset = const_cast <MovableObject *>(dynamic_cast <const MovableObject *>(g_PresetMan.GetEntityPreset (GetClassName (), GetPresetName (), GetModuleID ())));
553
+ if (pPreset && pPreset != this ) {
554
+ status = clearScriptConfigurationAndLoadPreexistingScripts (pPreset);
555
+ }
556
+
557
+ return status;
558
+ }
554
559
}
555
560
556
561
return error;
@@ -811,75 +816,60 @@ void MovableObject::Update()
811
816
}
812
817
*/
813
818
814
- // ////////////////////////////////////////////////////////////////////////////////////////
815
- // Virtual method: UpdateScript
816
- // ////////////////////////////////////////////////////////////////////////////////////////
817
- // Description: Updates this MovableObject's Lua script. Supposed to be done every
818
- // frame after the rest of the hardcoded C++ update is done.
819
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
819
820
820
- int MovableObject::UpdateScript ()
821
- {
822
- // This preset doesn't seem to have any script file defined, so then just return
823
- if (m_ScriptPath.empty () || m_ScriptPresetName.empty ())
821
+ int MovableObject::UpdateScripts () {
822
+ if (m_LoadedScripts.empty () || m_ScriptPresetName.empty ()) {
824
823
return -1 ;
825
-
826
- int error = 0 ;
824
+ }
827
825
828
826
// Check to make sure the preset of this is still defined in the Lua state. If not, re-create it and recover gracefully
829
- if (!g_LuaMan.ExpressionIsTrue (m_ScriptPresetName, false ))
830
- ReloadScripts ();
827
+ if (!g_LuaMan.ExpressionIsTrue (m_ScriptPresetName, false )) { ReloadScripts (); }
831
828
832
- // First see if we even have a representation stored in the Lua state, and if not, create one
833
- if (m_ScriptObjectName.empty ())
834
- {
835
- // Get the unique object identifier for this object and construct the object isntance name in Lua that points to this object so we can pass it into the preset functions
829
+ // If we don't have a Lua representation for this object instance, create one and call the Lua Create function on it
830
+ if (m_ScriptObjectName.empty ()) {
836
831
m_ScriptObjectName = GetClassName () + " s." + g_LuaMan.GetNewObjectID ();
837
832
838
- // Give access to this in the Lua state
833
+ // Give Lua access to this object, then use that access to set up the object's Lua representation
839
834
g_MovableMan.SetScriptedEntity (this );
840
- // Create the Lua variable which will hold the object instance of this instance for as long as it exists
841
- if ((error = g_LuaMan. RunScriptString (m_ScriptObjectName + " = To " + GetClassName () + " (MovableMan.ScriptedEntity); " )) < 0 )
842
- return error;
835
+ if (g_LuaMan. RunScriptString (m_ScriptObjectName + " = To " + GetClassName () + " (MovableMan.ScriptedEntity); " ) < 0 ) {
836
+ return - 2 ;
837
+ }
843
838
844
- // Call the scripted creation function, but only after first checking if it and this instance's Lua representation really exists
845
- if ((error = g_LuaMan.RunScriptString (" if " + m_ScriptPresetName + " .Create and " + m_ScriptObjectName + " then " + m_ScriptPresetName + " .Create(" + m_ScriptObjectName + " ); end" )) < 0 )
846
- return error;
839
+ for (std::pair<std::string, bool > scriptEntry : m_LoadedScripts) {
840
+ if (g_LuaMan.RunFunctionInPresetScript (" Create" , scriptEntry.first , m_ScriptPresetName, m_ScriptObjectName) < 0 ) {
841
+ return -3 ;
842
+ }
843
+ }
847
844
}
848
845
849
- // Call the defined function, but only after first checking if it and this instance's Lua representation exists
850
- if ((error = g_LuaMan.RunScriptString (" if " + m_ScriptPresetName + " .Update and " + m_ScriptObjectName + " then " + m_ScriptPresetName + " .Update(" + m_ScriptObjectName + " ); end" )) < 0 )
851
- return error;
846
+ for (std::pair<std::string, bool > scriptEntry : m_LoadedScripts) {
847
+ if (scriptEntry.second == true && g_LuaMan.RunFunctionInPresetScript (" Update" , scriptEntry.first , m_ScriptPresetName, m_ScriptObjectName) < 0 ) {
848
+ return -3 ;
849
+ }
850
+ }
852
851
853
- return error ;
852
+ return 0 ;
854
853
}
855
854
856
- // ////////////////////////////////////////////////////////////////////////////////////////
857
- // Virtual method: OnPieMenu
858
- // ////////////////////////////////////////////////////////////////////////////////////////
859
- // Description: Executes the Lua-defined OnPieMenu event handler.
860
-
861
- int MovableObject::OnPieMenu (Actor * pActor)
862
- {
863
- if (!pActor)
864
- return -1 ;
865
-
866
- // This preset doesn't seem to have any script file defined, so then just return
867
- if (m_ScriptPath.empty () || m_ScriptPresetName.empty ())
868
- return -1 ;
869
-
870
- if (m_ScriptObjectName.empty ())
871
- return -1 ;
855
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
872
856
857
+ int MovableObject::OnPieMenu (Actor * pActor) {
858
+ if (!pActor || m_LoadedScripts.empty () || m_ScriptPresetName.empty () || m_ScriptObjectName.empty ()) {
859
+ return -1 ;
860
+ }
873
861
m_pPieMenuActor = pActor;
874
862
875
- int error = 0 ;
876
-
877
- if ((error = g_LuaMan. RunScriptString ( " if " + m_ScriptPresetName + " .OnPieMenu and " + m_ScriptObjectName + " then " + m_ScriptPresetName + " .OnPieMenu( " + m_ScriptObjectName + " ); end " )) < 0 )
878
- return error;
879
-
880
- return error ;
863
+ int status = 0 ;
864
+ for (std::pair<std::string, bool > scriptEntry : m_LoadedScripts) {
865
+ status = scriptEntry. second == true ? g_LuaMan. RunFunctionInPresetScript ( " OnPieMenu " , scriptEntry. first , m_ScriptPresetName, m_ScriptObjectName) : status;
866
+ if (status < 0 ) { break ; }
867
+ }
868
+ return status ;
881
869
}
882
870
871
+ // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
872
+
883
873
void MovableObject::Update ()
884
874
{
885
875
if (m_RandomizeEffectRotAngleEveryFrame)
0 commit comments