diff --git a/modules/ns/amxxapi.cpp b/modules/ns/amxxapi.cpp index c562d56f..b19e24bc 100644 --- a/modules/ns/amxxapi.cpp +++ b/modules/ns/amxxapi.cpp @@ -30,7 +30,8 @@ extern BOOL iscombat; TitleManager TitleMan; ParticleManager ParticleMan; -void MFuncs_Initialize(void); +void MFuncs_Initialize(char *base); +void MPlayerFuncs_Initialize(char *base); // Native register calls here void AddNatives_MemberFunc(); @@ -86,6 +87,20 @@ void OnAmxxAttach() AddNatives_Structure(); AddNatives_General(); - MFuncs_Initialize(); + char *FuncBase; + char FileName[256]; + DLHANDLE DLLBase; +#ifdef __linux__ + UTIL_Format(FileName, sizeof(FileName), "%s/dlls/ns_i386.so", MF_GetModname()); +#else + UTIL_Format(FileName, sizeof(FileName), "%s\\dlls\\ns.dll", MF_GetModname()); +#endif + + DLLBase = DLOPEN(FileName); + FuncBase = (char *)DLSYM(DLLBase, MAKE_OFFSET(BASE)); + DLCLOSE(DLLBase); + + MFuncs_Initialize(FuncBase); + MPlayerFuncs_Initialize(FuncBase); } diff --git a/modules/ns/natives/memberfuncs.cpp b/modules/ns/natives/memberfuncs.cpp index 127b623d..4af84b22 100644 --- a/modules/ns/natives/memberfuncs.cpp +++ b/modules/ns/natives/memberfuncs.cpp @@ -42,63 +42,10 @@ static void (GenericClass::*MFP_WeldFinished)(float); // AvHGameRules *GetGameRules(void) static void *(*FP_GetGameRules)(); - -char *FuncBase; - -/** - * sizeof(void (detail::GenericClass::*fptr)()) - * is 8 in GCC. Add an empty void * pointer at - * the end to compensate. - * Layout in GCC: - * union { - * void *address; // When this is an address it will always be positive - * int vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1 - * }; - * int delta; - * - - * Delta is the adjustment to the this pointer - * For my implementations I will only need it to 0 - */ -#ifdef __GNUC__ -template -inline void set_mfp(OutType &out, void *in) +void MFuncs_Initialize(char *base) { - union - { - void *in[2]; - OutType out; - } mfpu; - - mfpu.in[0]=in; - mfpu.in[1]=NULL; - out=mfpu.out; -}; -#else -template -inline void set_mfp(OutType &out, void *in) -{ - out=horrible_cast(in); -}; -#endif - -void MFuncs_Initialize(void) -{ - char FileName[256]; - DLHANDLE DLLBase; -#ifdef __linux__ - UTIL_Format(FileName,sizeof(FileName)-1,"%s/dlls/ns_i386.so",MF_GetModname()); -#else - UTIL_Format(FileName, sizeof(FileName)-1, "%s\\dlls\\ns.dll", MF_GetModname()); -#endif - - DLLBase=DLOPEN(FileName); - FuncBase=(char *)DLSYM(DLLBase, MAKE_OFFSET(BASE)); - DLCLOSE(DLLBase); - -#define MFP(Offs) (((void *)(((char *)FuncBase)+MAKE_OFFSET(Offs)))) - set_mfp(MFP_Recycle,MFP(MEMBER_RECYCLE)); - + set_mfp(MFP_WeldFinished,MFP(MEMBER_TRIGGER_WELDABLE)); // This is not a member function pointer, but use MFP since it diff --git a/modules/ns/natives/player_memory.cpp b/modules/ns/natives/player_memory.cpp index 538ce63b..f6fe5ace 100644 --- a/modules/ns/natives/player_memory.cpp +++ b/modules/ns/natives/player_memory.cpp @@ -20,6 +20,16 @@ #include "GameManager.h" #include "CPlayer.h" +#include "FastDelegate.h" + +using namespace fastdelegate::detail; + +static bool (GenericClass::*MFP_SetResearchDone)(int inMessageID, bool inState); + +void MPlayerFuncs_Initialize(char *base) +{ + set_mfp(MFP_SetResearchDone, MFP(MEMBER_SET_RESEARCH_DONE)); +}; // Float:ns_get_res(Player) static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params) @@ -378,6 +388,9 @@ static cell AMX_NATIVE_CALL ns_remove_upgrade(AMX *amx, cell *params) if (bfound) { + void *pTechTree = reinterpret_cast(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(COMBAT_TECHTREE); + (reinterpret_cast(pTechTree)->*(MFP_SetResearchDone))(params[2], false); + if (afound) { return 2; diff --git a/modules/ns/ns_const.h b/modules/ns/ns_const.h index 30d5deac..daea20b3 100644 --- a/modules/ns/ns_const.h +++ b/modules/ns/ns_const.h @@ -122,6 +122,10 @@ #define OFFSET_WIN_UPGRADES_ACTIVE 0x198C #define OFFSET_LIN_UPGRADES_ACTIVE 0x19A0 +#define OFFSET_WIN_COMBAT_TECHTREE 0x1998 +#define OFFSET_LIN_COMBAT_TECHTREE 0x19AC + + // TODO: Symbols / signatures instead // Not actually offsets, but easier to use MAKE_OFFSET stuff for this :o @@ -147,7 +151,9 @@ #define OFFSET_WIN_MEMBER_TRIGGER_WELDABLE MAKE_MEMBER_OFFSET(0x000A0E20) #define OFFSET_LIN_MEMBER_TRIGGER_WELDABLE MAKE_MEMBER_OFFSET(0x00232840) - +// Research: bool AvHTechTree::SetResearchDone(AvHMessageID inMessageID, bool inState) +#define OFFSET_WIN_MEMBER_SET_RESEARCH_DONE MAKE_MEMBER_OFFSET(0x0009EC40) +#define OFFSET_LIN_MEMBER_SET_RESEARCH_DONE MAKE_MEMBER_OFFSET(0x0022E740) // Game Rules: AvHGameRules *GetGameRules(void) #define OFFSET_WIN_GETGAMERULES MAKE_MEMBER_OFFSET(0x00068000) diff --git a/modules/ns/utilfunctions.h b/modules/ns/utilfunctions.h index 5984a487..0b84e7c7 100644 --- a/modules/ns/utilfunctions.h +++ b/modules/ns/utilfunctions.h @@ -233,6 +233,43 @@ inline unsigned char set_private_b(edict_t *pEntity, int offset, unsigned char v }; +/** +* sizeof(void (detail::GenericClass::*fptr)()) +* is 8 in GCC. Add an empty void * pointer at +* the end to compensate. +* Layout in GCC: +* union { +* void *address; // When this is an address it will always be positive +* int vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1 +* }; +* int delta; +* - +* Delta is the adjustment to the this pointer +* For my implementations I will only need it to 0 +*/ +#ifdef __GNUC__ +template +inline void set_mfp(OutType &out, void *in) +{ + union + { + void *in[2]; + OutType out; + } mfpu; + + mfpu.in[0] = in; + mfpu.in[1] = NULL; + out = mfpu.out; +}; +#else +template +inline void set_mfp(OutType &out, void *in) +{ + out = horrible_cast(in); +}; +#endif + +#define MFP(Offs) (((void *)(((char *)base)+MAKE_OFFSET(Offs)))) #endif // UTILFUNCTIONS_H