@ -65,6 +65,72 @@ inline void CheckIncompatibleMods()
CheckEnderalStatics ( ) ;
}
inline bool PapyrusGlobalFunctionExists ( const char * scriptName , const char * funcName )
{
logger : : info ( " Real - GetGlobalFunctionNames of {} " , scriptName ) ;
std : : vector < std : : string > functionNames ;
RE : : BSTSmartPointer < RE : : BSScript : : ObjectTypeInfo > typeInfoPtr ;
RE : : BSScript : : Internal : : VirtualMachine : : GetSingleton ( ) - > GetScriptObjectType ( RE : : BSFixedString ( scriptName ) , typeInfoPtr ) ;
auto functionCount = typeInfoPtr - > GetNumGlobalFuncs ( ) ;
auto functions = typeInfoPtr - > GetGlobalFuncIter ( ) ;
for ( uint32_t i = 0 ; i < functionCount ; i + + ) {
if ( functions [ i ] . func - > GetName ( ) . c_str ( ) = = funcName ) {
return true ;
}
}
return false ;
}
inline void CheckScriptVersions ( )
{
class ScriptVersionCallback : public RE : : BSScript : : IStackCallbackFunctor
{
private :
std : : uint32_t expectedVersion ;
const RE : : BSFixedString scriptName ;
const RE : : BSFixedString funcName = " _GetScriptVersion " ;
public :
ScriptVersionCallback ( const RE : : BSFixedString a_scriptName , int a_version ) :
scriptName ( a_scriptName ) ,
expectedVersion ( a_version )
{
if ( PapyrusGlobalFunctionExists ( scriptName . c_str ( ) , funcName . c_str ( ) ) ) {
const auto vm = RE : : BSScript : : Internal : : VirtualMachine : : GetSingleton ( ) ;
auto callbackPtr = RE : : BSTSmartPointer < RE : : BSScript : : IStackCallbackFunctor > ( this ) ;
vm - > DispatchStaticCall ( scriptName , funcName , RE : : MakeFunctionArguments ( ) , callbackPtr ) ;
} else {
auto a_script = scriptName ;
auto a_version = expectedVersion ;
SKSE : : GetTaskInterface ( ) - > AddTask ( [ a_script , a_version ] ( ) {
RE : : DebugMessageBox ( std : : format ( " Script {} is overwritten by a mod, incompatible with current version of Enderal. Expected version: {}, installed version: N/A. " , a_script . c_str ( ) , a_version ) . c_str ( ) ) ;
} ) ;
}
}
void operator ( ) ( RE : : BSScript : : Variable a_result )
{
if ( a_result . GetUInt ( ) ! = expectedVersion ) {
RE : : DebugMessageBox ( std : : format ( " Script {} is overwritten by a mod, incompatible with current version of Enderal. Expected version: {}, installed version: {}. " , scriptName . c_str ( ) , expectedVersion , a_result . GetUInt ( ) ) . c_str ( ) ) ;
}
}
bool CanSave ( ) { return false ; }
void SetObject ( const RE : : BSTSmartPointer < RE : : BSScript : : Object > & ) { }
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_PlayerSetUpScript " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_QuestFunctions " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_Game_SkillmenuSC " , 1 )
} ;
RE : : BSTSmartPointer < ScriptVersionCallback > {
new ScriptVersionCallback ( " _00E_Theriantrophist_AlchemyControl " , 1 )
} ;
}
inline void LoadINI ( std : : map < std : : string , bool > * settings , const char * iniPath )
{
for ( auto it = settings - > begin ( ) ; it ! = settings - > end ( ) ; it + + ) {