//==================================================================================================== // // Name: [entWatch] Core // Author: zaCade & Prometheum // Description: Handle the core functions of [entWatch] // //==================================================================================================== #include #pragma newdecls required #include #include #include #include /* BOOLS */ bool g_bLate; /* ARRAYS */ ArrayList g_hArray_Items; ArrayList g_hArray_Config; /* FORWARDS */ Handle g_hFwd_OnClientItemDrop; Handle g_hFwd_OnClientItemDeath; Handle g_hFwd_OnClientItemPickup; Handle g_hFwd_OnClientItemActivate; Handle g_hFwd_OnClientItemDisconnect; /* HOOKS */ Handle g_hFwd_OnClientItemCanPickup; Handle g_hFwd_OnClientItemCanActivate; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "[entWatch] Core", author = "zaCade & Prometheum", description = "Handle the core functions of [entWatch]", version = "4.0.0" }; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int errorSize) { g_bLate = bLate; CreateNative("EW_GetItemCount", Native_GetItemCount); CreateNative("EW_GetItemArray", Native_GetItemArray); CreateNative("EW_SetItemArray", Native_SetItemArray); RegPluginLibrary("entWatch-core"); return APLRes_Success; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { g_hFwd_OnClientItemDrop = CreateGlobalForward("EW_OnClientItemDrop", ET_Ignore, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemDeath = CreateGlobalForward("EW_OnClientItemDeath", ET_Ignore, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemPickup = CreateGlobalForward("EW_OnClientItemPickup", ET_Ignore, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemActivate = CreateGlobalForward("EW_OnClientItemActivate", ET_Ignore, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemDisconnect = CreateGlobalForward("EW_OnClientItemDisconnect", ET_Ignore, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemCanPickup = CreateGlobalForward("EW_OnClientItemCanPickup", ET_Hook, Param_Array, Param_Cell, Param_Cell); g_hFwd_OnClientItemCanActivate = CreateGlobalForward("EW_OnClientItemCanActivate", ET_Hook, Param_Array, Param_Cell, Param_Cell); g_hArray_Items = new ArrayList(512); g_hArray_Config = new ArrayList(512); HookEvent("player_death", OnClientDeath); HookEvent("round_start", OnRoundStart); if (g_bLate) { for (int client = 1; client <= MaxClients; client++) { if (!IsClientInGame(client) || IsFakeClient(client)) continue; SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponPickup); SDKHook(client, SDKHook_WeaponDropPost, OnWeaponDrop); SDKHook(client, SDKHook_WeaponCanUse, OnWeaponTouch); } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnMapStart() { g_hArray_Items.Clear(); g_hArray_Config.Clear(); char sCurrentMap[128]; GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); String_ToLower(sCurrentMap, sCurrentMap, sizeof(sCurrentMap)); char sFilePathDefault[PLATFORM_MAX_PATH]; char sFilePathOverride[PLATFORM_MAX_PATH]; BuildPath(Path_SM, sFilePathDefault, sizeof(sFilePathDefault), "configs/entwatch/%s.cfg", sCurrentMap); BuildPath(Path_SM, sFilePathOverride, sizeof(sFilePathOverride), "configs/entwatch/%s.override.cfg", sCurrentMap); KeyValues hConfig = new KeyValues("items"); if (FileExists(sFilePathOverride)) { if (!hConfig.ImportFromFile(sFilePathOverride)) { LogMessage("Unable to load config \"%s\"!", sFilePathOverride); delete hConfig; return; } else LogMessage("Loaded config \"%s\"", sFilePathOverride); } else { if (!hConfig.ImportFromFile(sFilePathDefault)) { LogMessage("Unable to load config \"%s\"!", sFilePathDefault); delete hConfig; return; } else LogMessage("Loaded config \"%s\"", sFilePathDefault); } if (hConfig.GotoFirstSubKey()) { do { any itemArray[items]; hConfig.GetString("name", itemArray[item_name], sizeof(itemArray[item_name])); hConfig.GetString("short", itemArray[item_short], sizeof(itemArray[item_short])); hConfig.GetString("color", itemArray[item_color], sizeof(itemArray[item_color])); hConfig.GetString("filter", itemArray[item_filter], sizeof(itemArray[item_filter])); itemArray[item_weaponid] = hConfig.GetNum("weaponid"); itemArray[item_buttonid] = hConfig.GetNum("buttonid"); itemArray[item_triggerid] = hConfig.GetNum("triggerid"); itemArray[item_display] = hConfig.GetNum("display"); itemArray[item_mode] = hConfig.GetNum("mode"); itemArray[item_maxuses] = hConfig.GetNum("maxuses"); itemArray[item_cooldown] = hConfig.GetNum("cooldown"); g_hArray_Config.PushArray(itemArray, sizeof(itemArray)); } while (hConfig.GotoNextKey()); } delete hConfig; return; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast) { if (g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_owned] && itemArray[item_owner] >= 0) g_hArray_Items.Erase(index); } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnEntityCreated(int entity, const char[] sClassname) { if (Entity_IsValid(entity)) { SDKHook(entity, SDKHook_SpawnPost, OnEntitySpawned); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnEntitySpawned(int entity) { if (Entity_IsValid(entity) && g_hArray_Config.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (RegisterItem(itemArray, entity)) { g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return; } } for (int index; index < g_hArray_Config.Length; index++) { any itemArray[items]; g_hArray_Config.GetArray(index, itemArray, sizeof(itemArray)); if (RegisterItem(itemArray, entity)) { g_hArray_Items.PushArray(itemArray, sizeof(itemArray)); return; } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock bool RegisterItem(any[] itemArray, int entity) { if (Entity_IsValid(entity)) { if (itemArray[item_weaponid] && itemArray[item_weaponid] == Entity_GetHammerId(entity)) { if (!itemArray[item_weapon] && (Entity_GetOwner(entity) == INVALID_ENT_REFERENCE)) { itemArray[item_weapon] = entity; return true; } } else if (itemArray[item_buttonid] && itemArray[item_buttonid] == Entity_GetHammerId(entity)) { if (!itemArray[item_button] && (Entity_GetParent(entity) == INVALID_ENT_REFERENCE || (itemArray[item_weapon] && Entity_GetParent(entity) == itemArray[item_weapon]))) { SDKHook(entity, SDKHook_Use, OnButtonPress); itemArray[item_button] = entity; return true; } } else if (itemArray[item_triggerid] && itemArray[item_triggerid] == Entity_GetHammerId(entity)) { if (!itemArray[item_trigger] && (Entity_GetParent(entity) == INVALID_ENT_REFERENCE || (itemArray[item_weapon] && Entity_GetParent(entity) == itemArray[item_weapon]))) { SDKHook(entity, SDKHook_StartTouch, OnTriggerTouch); SDKHook(entity, SDKHook_EndTouch, OnTriggerTouch); SDKHook(entity, SDKHook_Touch, OnTriggerTouch); itemArray[item_trigger] = entity; return true; } } } return false; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnEntityDestroyed(int entity) { if (Entity_IsValid(entity) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_weapon] && itemArray[item_weapon] == entity) { g_hArray_Items.Erase(index); return; } if (itemArray[item_button] && itemArray[item_button] == entity) { itemArray[item_button] = INVALID_ENT_REFERENCE; g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return; } if (itemArray[item_trigger] && itemArray[item_trigger] == entity) { itemArray[item_trigger] = INVALID_ENT_REFERENCE; g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return; } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { if (!IsFakeClient(client)) { SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponPickup); SDKHook(client, SDKHook_WeaponDropPost, OnWeaponDrop); SDKHook(client, SDKHook_WeaponCanUse, OnWeaponTouch); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientDisconnect(int client) { if (!IsFakeClient(client) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_owned] && itemArray[item_owner] == client) { itemArray[item_owner] = INVALID_ENT_REFERENCE; itemArray[item_owned] = false; Call_StartForward(g_hFwd_OnClientItemDisconnect); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast) { int client = GetClientOfUserId(hEvent.GetInt("userid")); if (Client_IsValid(client) && !IsFakeClient(client) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_owned] && itemArray[item_owner] == client) { itemArray[item_owner] = INVALID_ENT_REFERENCE; itemArray[item_owned] = false; Call_StartForward(g_hFwd_OnClientItemDeath); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnWeaponPickup(int client, int weapon) { if (Client_IsValid(client) && Entity_IsValid(weapon) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_weapon] && itemArray[item_weapon] == weapon) { itemArray[item_owner] = client; itemArray[item_owned] = true; Call_StartForward(g_hFwd_OnClientItemPickup); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return; } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnWeaponDrop(int client, int weapon) { if (Client_IsValid(client) && Entity_IsValid(weapon) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_weapon] && itemArray[item_weapon] == weapon) { itemArray[item_owner] = INVALID_ENT_REFERENCE; itemArray[item_owned] = false; Call_StartForward(g_hFwd_OnClientItemDrop); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return; } } } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnButtonPress(int button, int client) { if (Client_IsValid(client) && Entity_IsValid(button) && g_hArray_Items.Length) { if (HasEntProp(button, Prop_Data, "m_bLocked") && GetEntProp(button, Prop_Data, "m_bLocked")) return Plugin_Handled; for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_button] && itemArray[item_button] == button) { if (itemArray[item_owned] && itemArray[item_owner] == client) { Action aResult; Call_StartForward(g_hFwd_OnClientItemCanActivate); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(aResult); if ((aResult == Plugin_Continue) || (aResult == Plugin_Changed)) { switch(itemArray[item_mode]) { case(1): { if (itemArray[item_nextuse] < RoundToCeil(GetEngineTime())) { itemArray[item_nextuse] = RoundToCeil(GetEngineTime()) + itemArray[item_cooldown]; } else return Plugin_Handled; } case(2): { if (itemArray[item_uses] < itemArray[item_maxuses]) { itemArray[item_uses]++; } else return Plugin_Handled; } case(3): { if (itemArray[item_nextuse] < RoundToCeil(GetEngineTime()) && itemArray[item_uses] < itemArray[item_maxuses]) { itemArray[item_nextuse] = RoundToCeil(GetEngineTime()) + itemArray[item_cooldown]; itemArray[item_uses]++; } else return Plugin_Handled; } case(4): { if (itemArray[item_nextuse] < RoundToCeil(GetEngineTime())) { itemArray[item_uses]++; if (itemArray[item_uses] >= itemArray[item_maxuses]) { itemArray[item_nextuse] = RoundToCeil(GetEngineTime()) + itemArray[item_cooldown]; itemArray[item_uses] = 0; } } else return Plugin_Handled; } } if (itemArray[item_filter][0]) Entity_SetName(client, itemArray[item_filter]); Call_StartForward(g_hFwd_OnClientItemActivate); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(); } g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return aResult; } } } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnTriggerTouch(int trigger, int client) { if (Client_IsValid(client) && Entity_IsValid(trigger) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_trigger] && itemArray[item_trigger] == trigger) { Action aResult; Call_StartForward(g_hFwd_OnClientItemCanPickup); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(aResult); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return aResult; } } } return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnWeaponTouch(int client, int weapon) { if (Client_IsValid(client) && Entity_IsValid(weapon) && g_hArray_Items.Length) { for (int index; index < g_hArray_Items.Length; index++) { any itemArray[items]; g_hArray_Items.GetArray(index, itemArray, sizeof(itemArray)); if (itemArray[item_weapon] && itemArray[item_weapon] == weapon) { Action aResult; Call_StartForward(g_hFwd_OnClientItemCanPickup); Call_PushArray(itemArray, sizeof(itemArray)); Call_PushCell(client); Call_PushCell(index); Call_Finish(aResult); g_hArray_Items.SetArray(index, itemArray, sizeof(itemArray)); return aResult; } } } return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_GetItemCount(Handle hPlugin, int numParams) { return g_hArray_Items.Length; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_GetItemArray(Handle hPlugin, int numParams) { any itemArray[items]; int index = GetNativeCell(1); int size = GetNativeCell(3); g_hArray_Items.GetArray(index, itemArray, size); SetNativeArray(2, itemArray, size); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_SetItemArray(Handle hPlugin, int numParams) { any itemArray[items]; int index = GetNativeCell(1); int size = GetNativeCell(3); GetNativeArray(2, itemArray, size); g_hArray_Items.SetArray(index, itemArray, size); }