diff --git a/AmmoManager/configs/AmmoManager.cfg b/AmmoManager/configs/AmmoManager.cfg new file mode 100644 index 0000000..101993d --- /dev/null +++ b/AmmoManager/configs/AmmoManager.cfg @@ -0,0 +1,173 @@ +"weapons" +{ + "weapon_ak47" + { + "primary clip" "30" + "primary reserve" "90" + } + "weapon_aug" + { + "primary clip" "30" + "primary reserve" "90" + } + "weapon_awp" + { + "primary clip" "10" + "primary reserve" "30" + } + "weapon_bizon" + { + "primary clip" "64" + "primary reserve" "120" + } + "weapon_cz75a" + { + "primary clip" "12" + "primary reserve" "12" + } + "weapon_deagle" + { + "primary clip" "7" + "primary reserve" "35" + } + "weapon_elite" + { + "primary clip" "30" + "primary reserve" "120" + } + "weapon_famas" + { + "primary clip" "25" + "primary reserve" "90" + } + "weapon_fiveseven" + { + "primary clip" "20" + "primary reserve" "100" + } + "weapon_g3sg1" + { + "primary clip" "20" + "primary reserve" "90" + } + "weapon_galilar" + { + "primary clip" "35" + "primary reserve" "90" + } + "weapon_glock" + { + "primary clip" "20" + "primary reserve" "120" + } + "weapon_hkp2000" + { + "primary clip" "13" + "primary reserve" "52" + } + "weapon_m249" + { + "primary clip" "100" + "primary reserve" "200" + } + "weapon_m4a1" + { + "primary clip" "30" + "primary reserve" "90" + } + "weapon_m4a1_silencer" + { + "primary clip" "20" + "primary reserve" "60" + } + "weapon_mac10" + { + "primary clip" "30" + "primary reserve" "100" + } + "weapon_mag7" + { + "primary clip" "5" + "primary reserve" "32" + } + "weapon_mp7" + { + "primary clip" "30" + "primary reserve" "120" + } + "weapon_mp9" + { + "primary clip" "30" + "primary reserve" "120" + } + "weapon_negev" + { + "primary clip" "150" + "primary reserve" "300" + } + "weapon_nova" + { + "primary clip" "8" + "primary reserve" "32" + } + "weapon_p250" + { + "primary clip" "13" + "primary reserve" "26" + } + "weapon_p90" + { + "primary clip" "50" + "primary reserve" "100" + } + "weapon_sawedoff" + { + "primary clip" "7" + "primary reserve" "32" + } + "weapon_scar20" + { + "primary clip" "20" + "primary reserve" "90" + } + "weapon_sg556" + { + "primary clip" "30" + "primary reserve" "90" + } + "weapon_ssg08" + { + "primary clip" "10" + "primary reserve" "90" + } + "weapon_taser" + { + "primary clip" "1" + "primary reserve" "0" + } + "weapon_tec9" + { + "primary clip" "18" + "primary reserve" "90" + } + "weapon_ump45" + { + "primary clip" "25" + "primary reserve" "100" + } + "weapon_usp_silencer" + { + "primary clip" "12" + "primary reserve" "24" + } + "weapon_xm1014" + { + "primary clip" "7" + "primary reserve" "32" + } + "weapon_revolver" + { + "primary clip" "8" + "primary reserve" "8" + } +} \ No newline at end of file diff --git a/AmmoManager/gamedata/AmmoManager.games.txt b/AmmoManager/gamedata/AmmoManager.games.txt new file mode 100644 index 0000000..40fe54f --- /dev/null +++ b/AmmoManager/gamedata/AmmoManager.games.txt @@ -0,0 +1,30 @@ +"Games" +{ + "csgo" + { + "Offsets" + { + "GetMaxClip" + { + "windows" "347" + "linux" "353" + } + "GetMaxReserve" + { + "windows" "351" + "linux" "357" + } + } + } + "cstrike" + { + "Offsets" + { + "GetMaxClip" + { + "windows" "311" + "linux" "312" + } + } + } +} \ No newline at end of file diff --git a/AmmoManager/scripting/AmmoManager.sp b/AmmoManager/scripting/AmmoManager.sp new file mode 100644 index 0000000..343d934 --- /dev/null +++ b/AmmoManager/scripting/AmmoManager.sp @@ -0,0 +1,168 @@ +#pragma newdecls required + +#include +#include +#include + +Handle g_hGetMaxClip; +Handle g_hGetMaxReserve; + +KeyValues g_aKeyValues; + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public Plugin myinfo = +{ + name = "AmmoManager", + author = "zaCade", + description = "", + version = "1.0.0" +}; + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnPluginStart() +{ + Handle hGameConf; + if ((hGameConf = LoadGameConfigFile("AmmoManager.games")) == INVALID_HANDLE) + { + SetFailState("Couldn't load \"AmmoManager.games\" game config!"); + return; + } + + // + int iMaxClipOffset; + if ((iMaxClipOffset = GameConfGetOffset(hGameConf, "GetMaxClip")) == -1) + { + CloseHandle(hGameConf); + SetFailState("GameConfGetOffset(hGameConf, \"GetMaxClip\") failed!"); + return; + } + + if ((g_hGetMaxClip = DHookCreate(iMaxClipOffset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnGetMaxClip)) == INVALID_HANDLE) + { + CloseHandle(hGameConf); + SetFailState("DHookCreate(iMaxClipOffset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnGetMaxClip) failed!"); + return; + } + + // + if (GetEngineVersion() == Engine_CSGO) + { + int iMaxReserveOffset; + if ((iMaxReserveOffset = GameConfGetOffset(hGameConf, "GetMaxReserve")) == -1) + { + CloseHandle(hGameConf); + SetFailState("GameConfGetOffset(hGameConf, \"GetMaxReserve\") failed!"); + return; + } + + if ((g_hGetMaxReserve = DHookCreate(iMaxReserveOffset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnGetMaxReserve)) == INVALID_HANDLE) + { + CloseHandle(hGameConf); + SetFailState("DHookCreate(iMaxReserveOffset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnGetMaxReserve) failed!"); + return; + } + } + + // Late load. + int entity = INVALID_ENT_REFERENCE; + while ((entity = FindEntityByClassname(entity, "weapon_*")) != INVALID_ENT_REFERENCE) + { + OnEntityCreated(entity, "weapon_*"); + } + + CloseHandle(hGameConf); +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnMapStart() +{ + char sFilePath[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, sFilePath, sizeof(sFilePath), "configs/AmmoManager.cfg"); + + if (!FileExists(sFilePath)) + { + LogMessage("Config file doesn't exist: \"%s\"!", sFilePath); + return; + } + + g_aKeyValues = new KeyValues("weapons"); + + if (!g_aKeyValues.ImportFromFile(sFilePath)) + { + LogMessage("Couldn't load config file: \"%s\"!", sFilePath); + delete g_aKeyValues; + return; + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public void OnEntityCreated(int entity, const char[] classname) +{ + if (strncmp(classname, "weapon_", 7, false) == 0) + { + DHookEntity(g_hGetMaxClip, true, entity); + DHookEntity(g_hGetMaxReserve, true, entity); + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public MRESReturn OnGetMaxClip(int entity, Handle hReturn) +{ + if (!IsValidEntity(entity)) + return MRES_Ignored; + + bool bChanged; + char sClassname[128]; + GetEntityClassname(entity, sClassname, sizeof(sClassname)) + + if (g_aKeyValues && g_aKeyValues.JumpToKey(sClassname, false)) + { + int iClip; + if ((iClip = g_aKeyValues.GetNum("primary clip", -1)) != -1) + { + DHookSetReturn(hReturn, iClip); + bChanged = true; + } + + g_aKeyValues.Rewind(); + } + + return (bChanged) ? MRES_Supercede : MRES_Ignored; +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: +//---------------------------------------------------------------------------------------------------- +public MRESReturn OnGetMaxReserve(int entity, Handle hReturn) +{ + if (!IsValidEntity(entity)) + return MRES_Ignored; + + bool bChanged; + char sClassname[128]; + GetEntityClassname(entity, sClassname, sizeof(sClassname)) + + if (g_aKeyValues && g_aKeyValues.JumpToKey(sClassname, false)) + { + int iReserve; + if ((iReserve = g_aKeyValues.GetNum("primary reserve", -1)) != -1) + { + DHookSetReturn(hReturn, iReserve); + bChanged = true; + } + + g_aKeyValues.Rewind(); + } + + return (bChanged) ? MRES_Supercede : MRES_Ignored; +} \ No newline at end of file