Move global effects from ::Game to ::ScriptEngine

This even enables some simplification in the CompileFuncs, since the global
effects were already put in the same section as the other ScriptEngine
parts. The callback for updates due to relinks also fits nicely.

The reset in C4Game::Default was redundant with C4Game::Clear already.
liquid_container
Günther Brammer 2015-12-19 19:53:08 +01:00
parent e2c6c2a841
commit e8811a7b21
8 changed files with 61 additions and 59 deletions

View File

@ -574,7 +574,6 @@ void C4Game::Clear()
::Definitions.Clear();
Landscape.Clear();
PXS.Clear();
if (pGlobalEffects) { delete pGlobalEffects; pGlobalEffects=NULL; }
ScriptGuiRoot.reset();
Particles.Clear();
::MaterialMap.Clear();
@ -721,7 +720,7 @@ bool C4Game::Execute() // Returns true if the game is over
// Game
EXEC_S( ExecObjects(); , ExecObjectsStat )
EXEC_S_DR( C4Effect::Execute(NULL, &Game.pGlobalEffects);
EXEC_S_DR( C4Effect::Execute(NULL, &ScriptEngine.pGlobalEffects);
, GEStats , "GEEx\0");
EXEC_S_DR( PXS.Execute(); , PXSStat , "PXSEx")
EXEC_S_DR( MassMover.Execute(); , MassMoverStat , "MMvEx")
@ -909,8 +908,8 @@ void C4Game::ClearPointers(C4Object * pObj)
::MouseControl.ClearPointers(pObj);
ScriptGuiRoot->ClearPointers(pObj);
TransferZones.ClearPointers(pObj);
if (pGlobalEffects)
pGlobalEffects->ClearPointers(pObj);
if (::ScriptEngine.pGlobalEffects)
::ScriptEngine.pGlobalEffects->ClearPointers(pObj);
if (::Landscape.pFoW) ::Landscape.pFoW->Remove(pObj);
}
@ -1464,7 +1463,6 @@ void C4Game::Default()
pParentGroup=NULL;
pScenarioSections=pCurrentScenarioSection=NULL;
*CurrentScenarioSection=0;
pGlobalEffects=NULL;
fResortAnyObject=false;
pNetworkStatistics.reset();
::Application.MusicSystem.ClearGame();
@ -1724,40 +1722,7 @@ void C4Game::CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumber
pComp->Value(mkParAdapt(Objects, !comp.fExact, numbers));
pComp->Name("Script");
if (!comp.fScenarioSection)
{
pComp->Value(mkParAdapt(ScriptEngine, numbers));
}
if (comp.fScenarioSection && pComp->isCompiler())
{
// loading scenario section: Merge effects
// Must keep old effects here even if they're dead, because the LoadScenarioSection call typically came from execution of a global effect
// and otherwise dead pointers would remain on the stack
C4Effect *pOldGlobalEffects, *pNextOldGlobalEffects=pGlobalEffects;
pGlobalEffects = NULL;
try
{
pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers));
}
catch (...)
{
delete pNextOldGlobalEffects;
throw;
}
while ((pOldGlobalEffects=pNextOldGlobalEffects))
{
pNextOldGlobalEffects = pOldGlobalEffects->pNext;
pOldGlobalEffects->Register(&pGlobalEffects, Abs(pOldGlobalEffects->iPriority));
}
}
else
{
// Otherwise, just compile effects
pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers));
}
pComp->Value(mkNamingAdapt(*numbers, "Values"));
pComp->NameEnd();
pComp->Value(mkNamingAdapt(mkParAdapt(ScriptEngine, comp.fScenarioSection, numbers), "Script"));
}
bool C4Game::CompileRuntimeData(C4Group &hGroup, bool fLoadSection, bool exact, bool sync, C4ValueNumbers * numbers)
@ -2278,7 +2243,6 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value
// Denumerate game data pointers
if (!fLoadSection) ScriptEngine.Denumerate(numbers);
if (!fLoadSection && pGlobalEffects) pGlobalEffects->Denumerate(numbers);
if (!fLoadSection) GlobalSoundModifier.Denumerate(numbers);
numbers->Denumerate();
if (!fLoadSection) ScriptGuiRoot->Denumerate(numbers);
@ -3513,12 +3477,12 @@ bool C4Game::LoadScenarioSection(const char *szSection, DWORD dwFlags)
}
DeleteObjects(false);
// remove global effects
if (pGlobalEffects) if (!(dwFlags & C4S_KEEP_EFFECTS))
{
pGlobalEffects->ClearAll(NULL, C4FxCall_RemoveClear);
// scenario section call might have been done from a global effect
// rely on dead effect removal for actually removing the effects; do not clear the array here!
}
if (::ScriptEngine.pGlobalEffects && !(dwFlags & C4S_KEEP_EFFECTS))
{
::ScriptEngine.pGlobalEffects->ClearAll(NULL, C4FxCall_RemoveClear);
// scenario section call might have been done from a global effect
// rely on dead effect removal for actually removing the effects; do not clear the array here!
}
// del particles as well
Particles.ClearAllParticles();
// clear transfer zones

View File

@ -83,7 +83,6 @@ public:
C4Extra Extra;
class C4ScenarioObjectsScriptHost *pScenarioObjectsScript;
C4ScenarioSection *pScenarioSections, *pCurrentScenarioSection;
C4Effect *pGlobalEffects;
C4PlayerControlDefs PlayerControlDefs;
C4PlayerControlAssignmentSets PlayerControlUserAssignmentSets, PlayerControlDefaultAssignmentSets;
C4Scoreboard Scoreboard;

View File

@ -45,7 +45,7 @@
C4Effect ** FnGetEffectsFor(C4Object * pTarget)
{
return pTarget ? &pTarget->pEffects : &Game.pGlobalEffects;
return pTarget ? &pTarget->pEffects : &ScriptEngine.pGlobalEffects;
}
// undocumented!

View File

@ -346,8 +346,6 @@ void C4GameObjects::UpdateScriptPointers()
// call in sublists
C4ObjectList::UpdateScriptPointers();
InactiveObjects.UpdateScriptPointers();
// adjust global effects
if (Game.pGlobalEffects) Game.pGlobalEffects->ReAssignAllCallbackFunctions();
}
C4Value C4GameObjects::GRBroadcast(const char *szFunction, C4AulParSet *pPars, bool fPassError, bool fRejectTest)

View File

@ -1195,7 +1195,8 @@ bool C4Object::ChangeDef(C4ID idNew)
SetOCF();
// Any effect callbacks to this object might need to reinitialize their target functions
// This is ugly, because every effect there is must be updated...
if (Game.pGlobalEffects) Game.pGlobalEffects->OnObjectChangedDef(this);
if (::ScriptEngine.pGlobalEffects)
::ScriptEngine.pGlobalEffects->OnObjectChangedDef(this);
for (C4Object *obj : Objects)
if (obj->pEffects) obj->pEffects->OnObjectChangedDef(this);
// Containment (no Entrance)

View File

@ -17,11 +17,12 @@
#include <C4Include.h>
#include <C4Aul.h>
#include <C4AulExec.h>
#include <C4AulDebug.h>
#include <C4Config.h>
#include <C4Def.h>
#include <C4Effect.h>
#include <C4Log.h>
#include <C4Components.h>
#include <C4LangStringTable.h>
@ -84,6 +85,7 @@ void C4AulScriptEngine::Clear()
RegisterGlobalConstant("Global", C4VPropList(this));
GlobalNamed.Reset();
GlobalNamed.SetNameList(&GlobalNamedNames);
delete pGlobalEffects; pGlobalEffects=NULL;
UserFiles.clear();
}
@ -115,15 +117,47 @@ void C4AulScriptEngine::Denumerate(C4ValueNumbers * numbers)
// runtime data only: don't denumerate consts
GameScript.ScenPropList.Denumerate(numbers);
C4PropListStaticMember::Denumerate(numbers);
if (pGlobalEffects) pGlobalEffects->Denumerate(numbers);
}
void C4AulScriptEngine::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
void C4AulScriptEngine::CompileFunc(StdCompiler *pComp, bool fScenarioSection, C4ValueNumbers * numbers)
{
assert(UserFiles.empty()); // user files must not be kept open
C4ValueMapData GlobalNamedDefault;
GlobalNamedDefault.SetNameList(&GlobalNamedNames);
pComp->Value(mkNamingAdapt(mkParAdapt(GlobalNamed, numbers), "StaticVariables", GlobalNamedDefault));
pComp->Value(mkNamingAdapt(mkParAdapt(*GameScript.ScenPropList._getPropList(), numbers), "Scenario"));
if (!fScenarioSection)
{
assert(UserFiles.empty()); // user files must not be kept open
C4ValueMapData GlobalNamedDefault;
GlobalNamedDefault.SetNameList(&GlobalNamedNames);
pComp->Value(mkNamingAdapt(mkParAdapt(GlobalNamed, numbers), "StaticVariables", GlobalNamedDefault));
pComp->Value(mkNamingAdapt(mkParAdapt(*GameScript.ScenPropList._getPropList(), numbers), "Scenario"));
}
if (fScenarioSection && pComp->isCompiler())
{
// loading scenario section: Merge effects
// Must keep old effects here even if they're dead, because the LoadScenarioSection call typically came from execution of a global effect
// and otherwise dead pointers would remain on the stack
C4Effect *pOldGlobalEffects, *pNextOldGlobalEffects=pGlobalEffects;
pGlobalEffects = NULL;
try
{
pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers));
}
catch (...)
{
delete pNextOldGlobalEffects;
throw;
}
while ((pOldGlobalEffects=pNextOldGlobalEffects))
{
pNextOldGlobalEffects = pOldGlobalEffects->pNext;
pOldGlobalEffects->Register(&pGlobalEffects, Abs(pOldGlobalEffects->iPriority));
}
}
else
{
// Otherwise, just compile effects
pComp->Value(mkParAdapt(mkNamingPtrAdapt(pGlobalEffects, "Effects"), numbers));
}
pComp->Value(mkNamingAdapt(*numbers, "Values"));
}
std::list<const char*> C4AulScriptEngine::GetFunctionNames(C4PropList * p)

View File

@ -121,6 +121,8 @@ public:
C4ValueMapNames GlobalConstNames;
C4ValueMapData GlobalConsts;
C4Effect * pGlobalEffects = NULL;
C4AulScriptEngine(); // constructor
~C4AulScriptEngine(); // destructor
void Clear(); // clear data
@ -139,7 +141,7 @@ public:
void UnLink(); // called when a script is being reloaded (clears string table)
// Compile scenario script data (without strings and constants)
void CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers);
void CompileFunc(StdCompiler *pComp, bool fScenarioSection, C4ValueNumbers * numbers);
// Handle user files
int32_t CreateUserFile(); // create new file and return handle

View File

@ -20,6 +20,7 @@
#include <C4Def.h>
#include <C4DefList.h>
#include <C4Effect.h>
#include <C4Material.h>
#include <C4Game.h>
#include <C4GameObjects.h>
@ -189,6 +190,9 @@ void C4AulScriptEngine::ReLink(C4DefList *rDefs)
// display state
LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));
// adjust global effects
if (pGlobalEffects) pGlobalEffects->ReAssignAllCallbackFunctions();
}
bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)