Немного критики, если позволите.
VIP_OnVIPLoaded() вызывается только один раз при старте ядра. При подгрузке модулей, он не вызывается, что вызывает некоторые возможные проблемы в работе модулей. Потому имеет смысл добавить
OnPluginStart(), и ещё. При старте плагина, стоит так же хукнуть всех игроков, которые находятся на сервере. И необходимо делать анхук при выходе.
public void OnPluginStart() {
if (VIP_IsVIPLoaded())
VIP_OnVIPLoaded();
for (int iClient = 1; iClient <= MaxClients; iClient++) {
if (IsClientInGame(iClient))
OnClientPutInServer(iClient);
}
}
public void OnClientDisconnect(int iClient) {
SDKUnhook(iClient, SDKHook_OnTakeDamage, OnTakeDamage);
}
Далее...
public void OnPluginEnd()
{
VIP_UnregisterFeature(g_sFeature);
}
-->
public void OnPluginEnd() {
if ((CanTestFeatures() && GetFeatureStatus(FeatureType_Native, "VIP_UnregisterFeature") == FeatureStatus_Available) || LibraryExists("vip_core"))
VIP_UnregisterFeature(g_sFeature);
}
public Action OnTakeDamage(int iVictim, int &iAttacker, int &inflictor, float &damage, int &damagetype)
{
if((IsValidPlayer(iVictim) && IsValidPlayer(iAttacker)) && (iVictim != iAttacker) && (GetClientTeam(iVictim) == GetClientTeam(iAttacker)))
{
if(VIP_IsClientVIP(iAttacker) && VIP_IsClientFeatureUse(iAttacker, g_sFeature))
{
int HP = GetClientHealth(iVictim);
<...>
А не проще эти два условия объединить? По сути, выйдет то же самое.
Потому что если хотя бы одно выражение в условии не прошло валидность, то все дальнейшие сверки и вызовы функций в нём не выполняются.
public Action OnTakeDamage(int iVictim, int &iAttacker, int &inflictor, float &damage, int &damagetype)
{
if((IsValidPlayer(iVictim) && IsValidPlayer(iAttacker)) && (iVictim != iAttacker) && (GetClientTeam(iVictim) == GetClientTeam(iAttacker)) && VIP_IsClientVIP(iAttacker) && VIP_IsClientFeatureUse(iAttacker, g_sFeature))
{
int HP = GetClientHealth(iVictim);
<...>
Следующий кусок вызывает немного негодования.
KeyValues cfg;
int cfg_iHPH, cfg_iMH;
<...>
KFG_Load()
{
if(cfg) delete cfg;
cfg = new KeyValues("settings");
if(!cfg.ImportFromFile("addons/sourcemod/data/vip/modules/teammates_heal.ini")) SetFailState("[VIP][Teammates Heal] - Файл конфигураций не найден");
else
{
cfg.Rewind();
cfg_iHPH = cfg.GetNum("hp_per_hit", 1);
cfg_iMH = cfg.GetNum("max_hp", 100);
}
}
1). Не совсем ясно, зачем хранить глобально KeyValues конфига, если с ним операции происходит один раз за всю карту? Лишняя трата памяти.
2). У некоторых SourceMod может стоять не в
/addons/sourcemod/, а, скажем, в
/addons/sourcemod_2/. Но путь к конфигу захардкожен. Будет ошибка.
int cfg_iHPH, cfg_iMH;
<...>
KFG_Load() {
char szPath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, szPath, sizeof(szPath), "data/vip/modules/teammates_heal.ini");
KeyValues cfg = new KeyValues("settings");
if (!cfg.ImportFromFile(szPath)) SetFailState("[VIP][Teammates Heal] - Файл конфигураций не найден");
// пора бы запомнить, что SetFailState() так же блокирует выполнение всего дальнейшего кода. Он даже блокирует любое дальнейшее выполнение кода плагина. Потому смысл от else теряется.
cfg.Rewind();
cfg_iHPH = cfg.GetNum("hp_per_hit", 1);
cfg_iMH = cfg.GetNum("max_hp", 100);
delete cfg;
}