sharivan

zmbr_fixes.sp

Sep 12th, 2014
644
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. *
  3. * Attention:
  4. *
  5. * This code is not the actual version of plugin zmbr_fixes. The actual version (at this date, June 18th, 2017) is 1.14, while the version of this code is 1.3 and was uploaded here at Sep 12th, 2014, almost 3 years ago.
  6. * Instead of this public version counting with only 533 lines, the actual version of zmbr_fixes have 4032 lines in whole its extension (counting only my own sources, excluding sourcemod libraries and 3rd party libraries), besides using an extension created by myself and alot of gamedata files.
  7. * The actual version of zmbr_fixes apply many fixes and modifications in the game server, including the correct uncache of particle system stringtables at end of each map.
  8. * Who is interested to acquire the actual version of this plugin please contact me by my email misterioso_matematico@hotmail.com.
  9. *
  10. * Atenção:
  11. *
  12. * Este código não é a versão atual de meu plugin zmbr_fixes. A versão atual (nesta data, 18/06/2017) é 1.14, enquanto a versão deste código é a 1.3 e seu upload foi feito em 14/09/2014, à quase 3 anos atrás.
  13. * Ao contrário desta versão pública que conta com somente 533 linhas, a versão atual de meu zmbr_fixes possui 4032 linhas em toda a sua extensão (contando somente com meus códigos fontes, excluindo as bibliotecas do sourcemod e outras bibliotecas de terceiros), além de usar uma extensão criada por mim mesmo e vários arquivos de gamedata.
  14. * A atual version do zmbr_fixes realiza várias correções e modificações no lado do servidor do jogo, incluindo a correção do problema das partículas onde o uncache de suas stringtables não é realizada no final de cada mapa.
  15. * Quem estiver interessado em adquirir a versão atual deste plugin por favor entre em contato comigo pelo meu e-mail misterioso_matematico@hotmail.com.
  16. *
  17. */
  18.  
  19. #include <sourcemod>
  20. #include <sdktools>
  21. #include <sdkhooks>
  22. #include <smlib>
  23. #include <zombiereloaded>
  24.  
  25. #pragma semicolon 1
  26.  
  27. #define VERSION "1.3"
  28.  
  29. #define MATERIAL_BEAM               "materials/sprites/laserbeam.vmt"
  30. #define MATERIAL_HALO               "materials/sprites/halo01.vmt"
  31. #define BEAM_COLOR                  {255, 0, 0, 255}
  32. #define BEAM_COLOR_SELECTED         {0, 0, 255, 255}
  33. #define BEAM_TIME                   0.3
  34.  
  35. #define USE_OFF 0
  36. #define USE_ON 1
  37.  
  38. #define MAX_PCFS 256
  39.  
  40. new String:g_sOriginName[MAX_NAME_LENGTH];
  41. new origin;
  42. new Handle:g_hParentedTriggers;
  43. new Handle:g_hParents;
  44. new Handle:g_hLaserMaterial;
  45. new Handle:g_hHaloMaterial;
  46. new bool:g_bMapRunning;
  47.  
  48. public Plugin:myinfo = {
  49.     name = "ZMBR Fixes",
  50.     author = "SHARIVAN from ΖмBя.™ Clan",
  51.     description = "Aplica algumas correções e modificações",
  52.     version = VERSION,
  53.     url = "http://www.zmbrasil.com.br/"
  54. };
  55.  
  56. public OnPluginStart() {
  57.     CreateConVar("zmbr_fixes_version", VERSION, "Versão", FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
  58.  
  59.     HookEvent("round_prestart", OnRoundPreStart, EventHookMode_Pre);
  60.     HookEvent("round_end", OnRoundEnd);
  61.     HookEvent("player_spawn", OnPlayerSpawn);
  62.     HookEvent("player_death", OnPlayerDeath, EventHookMode_Pre);
  63.    
  64.     g_hParentedTriggers = CreateTrie();
  65.     g_hParents = CreateTrie();
  66.    
  67.     g_bMapRunning = false;
  68. }
  69.  
  70. public OnPluginEnd() {
  71.     UnhookEvent("round_prestart", OnRoundPreStart, EventHookMode_Pre);
  72.     UnhookEvent("round_end", OnRoundEnd);
  73.     UnhookEvent("player_spawn", OnPlayerSpawn);
  74.     UnhookEvent("player_death", OnPlayerDeath, EventHookMode_Pre);
  75.    
  76.     ClearTrie(g_hParentedTriggers);
  77.     ClearTrie(g_hParents);
  78.    
  79.     CloseHandle(g_hParentedTriggers);
  80.     CloseHandle(g_hParents);
  81. }
  82.  
  83. public OnMapStart() {
  84.     g_bMapRunning = true;
  85.    
  86.     g_hLaserMaterial = PrecacheModel(MATERIAL_BEAM);
  87.     g_hHaloMaterial = PrecacheModel(MATERIAL_HALO);
  88.    
  89.     LoadPerMapParticleManifest();
  90.    
  91.     origin = INVALID_ENT_REFERENCE;
  92. }
  93.  
  94. public OnMapEnd() {
  95.     g_bMapRunning = false;
  96.    
  97.     ClearTrie(g_hParentedTriggers);
  98.     ClearTrie(g_hParents);
  99. }
  100.  
  101. public OnEntityCreated(entity, const String:classname[]) {
  102.     if (g_bMapRunning && StrContains(classname, "trigger_") == 0)
  103.         SDKHook(entity, SDKHook_Spawn, OnEntitySpawned);
  104. }
  105.  
  106. public Action:TimerBeam(Handle:timer, any:trigger) {
  107.     if (!IsValidEntRef(trigger))
  108.         return Plugin_Stop;
  109.    
  110.     decl Float:vMaxs[3], Float:vMins[3], Float:vPos[3];
  111.     Entity_GetAbsOrigin(trigger, vPos);
  112.     Entity_GetMaxSize(trigger, vMaxs);
  113.     Entity_GetMinSize(trigger, vMins);
  114.     AddVectors(vPos, vMaxs, vMaxs);
  115.     AddVectors(vPos, vMins, vMins);
  116.     TE_SendBox(false, vMins, vMaxs);
  117.  
  118.     return Plugin_Continue;
  119. }
  120.  
  121. TE_SendBox(bool:bSelected, Float:vMins[3], Float:vMaxs[3]) {
  122.     decl Float:maxs[3], Float:vPos1[3], Float:vPos2[3], Float:vPos3[3], Float:vPos4[3], Float:vPos5[3], Float:vPos6[3];
  123.    
  124.     maxs[0] = vMaxs[0] - 1.0;
  125.     maxs[1] = vMaxs[1] - 1.0;
  126.     maxs[2] = vMaxs[2] - 1.0;
  127.    
  128.     vPos1 = maxs;
  129.     vPos1[0] = vMins[0];
  130.     vPos2 = maxs;
  131.     vPos2[1] = vMins[1];
  132.     vPos3 = maxs;
  133.     vPos3[2] = vMins[2];
  134.     vPos4 = vMins;
  135.     vPos4[0] = maxs[0];
  136.     vPos5 = vMins;
  137.     vPos5[1] = maxs[1];
  138.     vPos6 = vMins;
  139.     vPos6[2] = maxs[2];
  140.    
  141.     TE_SendBeam(bSelected, maxs, vPos1);
  142.     TE_SendBeam(bSelected, maxs, vPos2);
  143.     TE_SendBeam(bSelected, maxs, vPos3);
  144.     TE_SendBeam(bSelected, vPos4, vMins);
  145.     TE_SendBeam(bSelected, vPos4, vPos3);
  146.     TE_SendBeam(bSelected, vPos4, vPos2);
  147.     TE_SendBeam(bSelected, vPos5, vMins);
  148.     TE_SendBeam(bSelected, vPos5, vPos1);
  149.     TE_SendBeam(bSelected, vPos5, vPos3);
  150.     TE_SendBeam(bSelected, vPos6, vPos1);
  151.     TE_SendBeam(bSelected, vPos6, vPos2);
  152.     TE_SendBeam(bSelected, vPos6, vMins);
  153. }
  154.  
  155. TE_SendBeam(bool:bSelected, Float:vMins[3], Float:vMaxs[3]) {
  156.     if (bSelected)
  157.         TE_SetupBeamPoints(vMins, vMaxs, g_hLaserMaterial, g_hHaloMaterial, 0, 0, BEAM_TIME + 0.1, 1.0, 1.0, 1, 0.0, BEAM_COLOR_SELECTED, 0);
  158.     else
  159.         TE_SetupBeamPoints(vMins, vMaxs, g_hLaserMaterial, g_hHaloMaterial, 0, 0, BEAM_TIME + 0.1, 1.0, 1.0, 1, 0.0, BEAM_COLOR, 0);
  160.     TE_SendToAll();
  161. }
  162.  
  163. FindEntityByName(startEnt, const String:sName[]) {
  164.     new realMaxEntities = GetMaxEntities() * 2;
  165.     if (startEnt == INVALID_ENT_REFERENCE)
  166.         startEnt = 0;
  167.     else
  168.         startEnt++;
  169.     for (new entity = startEnt; entity < realMaxEntities; entity++) {
  170.         if (!IsValidEntity(entity))
  171.             continue;
  172.        
  173.         if (Entity_NameMatches(entity, sName))
  174.             return entity;
  175.     }
  176.    
  177.     return INVALID_ENT_REFERENCE;
  178. }
  179.  
  180. bool:IsAFreeName(const String:sName[]) {
  181.     new entity = FindEntityByName(INVALID_ENT_REFERENCE, sName);
  182.     if (entity == INVALID_ENT_REFERENCE)
  183.         return true;
  184.        
  185.     return false;
  186. }
  187.  
  188. bool:IsNameUsedOnlyByOne(const String:sName[]) {
  189.     new entity = FindEntityByName(INVALID_ENT_REFERENCE, sName);
  190.     if (entity == INVALID_ENT_REFERENCE)
  191.         return false;
  192.        
  193.     entity = FindEntityByName(entity, sName);
  194.     if (entity == INVALID_ENT_REFERENCE)
  195.         return true;
  196.        
  197.     return false;
  198. }
  199.  
  200. GiveAUniqueName(entity, const String:sPrefix[], String:sName[], nameSize) {
  201.     new counter = 0;
  202.     decl entity1;
  203.     do {
  204.         if (counter == 0)
  205.             Format(sName, nameSize, "%s", sPrefix);
  206.         else
  207.             Format(sName, nameSize, "%s%d", sPrefix, counter);
  208.         counter++;
  209.         entity1 = FindEntityByName(INVALID_ENT_REFERENCE, sName);
  210.     } while (entity1 != INVALID_ENT_REFERENCE);
  211.    
  212.     Entity_SetName(entity, sName);
  213. }
  214.  
  215. public OnEntitySpawned(entity) {
  216.     SDKUnhook(entity, SDKHook_Spawn, OnEntitySpawned);
  217.    
  218.     if (!IsValidEntity(entity))
  219.         return;
  220.    
  221.     //new String:parentname[128];
  222.     //Entity_GetParentName(entity, parentname, sizeof(parentname));
  223.     //if (StrEqual(parentname, ""))
  224.     //  return;
  225.    
  226.     new parent = Entity_GetParent(entity);
  227.     if (!IsValidEntity(parent))
  228.         return;
  229.        
  230.     new String:sName[128];
  231.     Entity_GetName(entity, sName, sizeof(sName));
  232.     new String:sClassName[MAX_NAME_LENGTH];
  233.     Entity_GetClassName(entity, sClassName, sizeof(sClassName));
  234.    
  235.     LogMessage("*****Fixing trigger %s [%d] of class %s*****", sName, entity, sClassName);
  236.    
  237.     if (StrEqual(sName, ""))
  238.         GiveAUniqueName(entity, sClassName, sName, sizeof(sName));
  239.     else if (!IsNameUsedOnlyByOne(sName)) {
  240.         LogMessage("The trigger %s of class %s could not be fixed because their name is not unique.", sName, sClassName);
  241.        
  242.         return;
  243.     }
  244.        
  245.     Entity_RemoveParent(entity);
  246.    
  247.     if (origin == INVALID_ENT_REFERENCE) {
  248.         origin = CreateEntityByName("info_teleport_destination");
  249.         GiveAUniqueName(origin, "origin", g_sOriginName, sizeof(g_sOriginName));
  250.         DispatchSpawn(origin);
  251.         TeleportEntity(origin, {1.0, 1.0, 1.0}, NULL_VECTOR, NULL_VECTOR);
  252.     }
  253.    
  254.     new Float:vEntityOrigin[3];
  255.     Entity_GetAbsOrigin(entity, vEntityOrigin);
  256.    
  257.     new itd = CreateEntityByName("info_teleport_destination");
  258.     new String:sOriginPrefix[128];
  259.     new String:sOriginName[128];
  260.     Format(sOriginPrefix, sizeof(sOriginPrefix), "%s_origin", sName);
  261.     GiveAUniqueName(itd, sOriginPrefix, sOriginName, sizeof(sOriginName));
  262.     LogMessage("Creating the origin %s", sOriginName);
  263.     DispatchSpawn(itd);
  264.     TeleportEntity(itd, vEntityOrigin, NULL_VECTOR, NULL_VECTOR);
  265.     Entity_SetParent(itd, parent);
  266.    
  267.     new String:key[MAX_NAME_LENGTH];
  268.     IntToString(parent, key, sizeof(key));
  269.     SetTrieValue(g_hParents, key, entity);
  270.    
  271.     LogMessage("Creating the measure movement for the trigger %s", sName);
  272.     new measure = CreateEntityByName("logic_measure_movement");
  273.     IntToString(entity, key, sizeof(key));
  274.     SetTrieValue(g_hParentedTriggers, key, measure);
  275.     DispatchKeyValue(measure, "MeasureTarget", sOriginName);
  276.     DispatchKeyValue(measure, "MeasureReference", g_sOriginName);
  277.     DispatchKeyValue(measure, "Target", sName);
  278.     DispatchKeyValue(measure, "TargetReference", g_sOriginName);
  279.     DispatchKeyValue(measure, "MeasureType", "0");
  280.     DispatchKeyValue(measure, "TargetScale", "1");
  281.     DispatchSpawn(measure);
  282.     ActivateEntity(measure);
  283. }
  284.  
  285. public OnEntityDestroyed(entity) {
  286.     if (entity == origin) {
  287.         origin = INVALID_ENT_REFERENCE;
  288.        
  289.         return;
  290.     }
  291.    
  292.     new String:key[MAX_NAME_LENGTH];
  293.     IntToString(entity, key, sizeof(key));
  294.    
  295.     new measure;
  296.     if (GetTrieValue(g_hParentedTriggers, key, measure)) {
  297.         if (IsValidEntity(measure))
  298.             AcceptEntityInput(measure, "Kill");
  299.         RemoveFromTrie(g_hParentedTriggers, key);
  300.        
  301.         return;
  302.     }
  303.    
  304.     new child;
  305.     if (GetTrieValue(g_hParents, key, child)) {
  306.         if (IsValidEntity(child))
  307.             AcceptEntityInput(child, "Kill");
  308.         RemoveFromTrie(g_hParents, key);
  309.        
  310.         return;
  311.     }
  312. }
  313.  
  314. Handle:CreateManifestKv(String:sPath[]) {
  315.     new Handle:hFile = CreateKeyValues("particles_manifest");
  316.    
  317.     KvSetEscapeSequences(hFile, true);
  318.     if (FileToKeyValues(hFile, sPath)) {
  319.    
  320.         return hFile;
  321.     }
  322.    
  323.     return INVALID_HANDLE;
  324. }
  325.  
  326. Handle:GetParticleManifestKv(String:sMapName[]) {
  327.     decl String:sFileName[PLATFORM_MAX_PATH];
  328.    
  329.     Format(sFileName, sizeof(sFileName), "particles/%s_manifest_override.txt", sMapName);
  330.     LogMessage("Checking for particles/%s_manifest_override.txt", sMapName);
  331.     if (FileExists(sFileName, true)) {
  332.         if (FileExists(sFileName, false))
  333.             AddFileToDownloadsTable(sFileName);
  334.        
  335.         return CreateManifestKv(sFileName);
  336.     }
  337.    
  338.     LogMessage("Checking for maps/%s_particles_override.txt", sMapName);
  339.     Format(sFileName, sizeof(sFileName), "maps/%s_particles_override.txt", sMapName);
  340.     if (FileExists(sFileName, true)) {
  341.         if (FileExists(sFileName, false))
  342.             AddFileToDownloadsTable(sFileName);
  343.        
  344.         return CreateManifestKv(sFileName);
  345.     }
  346.    
  347.     Format(sFileName, sizeof(sFileName), "particles/%s_manifest.txt", sMapName);
  348.     LogMessage("Checking for particles/%s_manifest.txt", sMapName);
  349.     if (FileExists(sFileName, true)) {
  350.         if (FileExists(sFileName, false))
  351.             AddFileToDownloadsTable(sFileName);
  352.        
  353.         return CreateManifestKv(sFileName);
  354.     }
  355.    
  356.     LogMessage("Checking for maps/%s_particles.txt", sMapName);
  357.     Format(sFileName, sizeof(sFileName), "maps/%s_particles.txt", sMapName);
  358.     if (FileExists(sFileName, true)) {
  359.         if (FileExists(sFileName, false))
  360.             AddFileToDownloadsTable(sFileName);
  361.        
  362.         return CreateManifestKv(sFileName);
  363.     }
  364.        
  365.     LogMessage("No per-map particle manifest file found for the map %s", sMapName);
  366.    
  367.     return INVALID_HANDLE;
  368. }
  369.  
  370. LoadPerMapParticleManifest() {
  371.     decl String:sMapName[MAX_NAME_LENGTH];
  372.     GetCurrentMap(sMapName, sizeof(sMapName));
  373.  
  374.     new Handle:hFile = GetParticleManifestKv(sMapName);
  375.     if (hFile == INVALID_HANDLE)
  376.         return;
  377.        
  378.     LogMessage("Parsing the particle manifest for the map %s", sMapName);
  379.  
  380.     decl String:sPCF[MAX_NAME_LENGTH];
  381.     if (KvGotoFirstSubKey(hFile, false))
  382.         do {
  383.             KvGetString(hFile, NULL_STRING, sPCF, sizeof(sPCF));
  384.             if (strlen(sPCF) == 0)
  385.                 continue;
  386.             if (FindCharInString(sPCF, '!') == 0)
  387.                 strcopy(sPCF, sizeof(sPCF), sPCF[1]);
  388.             if (FileExists(sPCF, true)) {
  389.                 if (FileExists(sPCF, false))
  390.                     AddFileToDownloadsTable(sPCF);
  391.                 PrecachePCF(sPCF);
  392.             } else
  393.                 LogMessage("PCF file %s not found", sPCF);
  394.         } while (KvGotoNextKey(hFile, false));
  395.        
  396.     LogMessage("Particle manifest for the map %s was parsed successfully", sMapName);
  397.  
  398.     CloseHandle(hFile);
  399. }
  400.  
  401. PrecachePCF(String:name[]) {
  402.     LogMessage("Precaching PCF file %s", name);
  403.     //if (IsGenericPrecached(name))
  404.     //  LogMessage("Particle PCF file %s is already precached", name);
  405.     //else
  406.     if (PrecacheGeneric(name, true))
  407.         LogMessage("Particle PCF file %s precached successfully", name);
  408.     else
  409.         LogMessage("Particle PCF file %s not precached", name);
  410. }
  411.  
  412. ClientToString(client, String:result[], size) {
  413.     if (Client_IsIngame(client)) {
  414.         Format(result, size, "%N (%d)", client, client);
  415.         return 1;
  416.     }
  417.  
  418.     Format(result, size, "INVALID_CLIENT (%d)", client);
  419.     return 2;
  420. }
  421.  
  422. EdictToString(edict, String:result[], size) {
  423.     if (edict == 0) {
  424.         strcopy(result, size, "WORLD");
  425.         return 0;
  426.     }
  427.     if (edict <= MaxClients)
  428.         return ClientToString(edict, result, size);
  429.     if (IsValidEntity(edict) && IsValidEdict(edict)) {
  430.         decl String:classname[MAX_NAME_LENGTH];
  431.         Entity_GetClassName(edict, classname, sizeof(classname));
  432.        
  433.         decl String:name[MAX_NAME_LENGTH];
  434.         Entity_GetName(edict, name, sizeof(name));
  435.        
  436.         new owner = Entity_GetOwner(edict);
  437.         decl String:owner_name[MAX_NAME_LENGTH];
  438.         //new r = EdictToString(owner, owner_name, sizeof(owner_name));
  439.        
  440.         //if (r != 2 && r != 3)
  441.         //  Format(result, size, "%s:%s[%s] (%d)", name, classname, owner_name, edict);
  442.         //else
  443.             Format(result, size, "%s:%s (%d)", name, classname, edict);
  444.  
  445.         return 3;
  446.     }
  447.  
  448.     Format(result, size, "INVALID_EDICT (%d)", edict);
  449.     return 4;
  450. }
  451.  
  452. UnparentAllPlayers() {
  453.     for (new client = 1; client <= MAXPLAYERS; client++)
  454.         if (Client_IsIngame(client))
  455.             Entity_RemoveParent(client);
  456. }
  457.  
  458. DisableAllPointViewControls() {
  459.     new ent = -1;
  460.     while ((ent = FindEntityByClassname(ent, "point_viewcontrol")) != -1) {
  461.         new m_state = GetEntProp(ent, Prop_Data, "m_state");
  462.         if (m_state != USE_ON)
  463.             continue;
  464.  
  465.         AcceptEntityInput(ent, "Disable");
  466.     }
  467. }
  468.  
  469. DisablePointViewControlOfClient(client) {
  470.     new ent = -1;
  471.     while ((ent = FindEntityByClassname(ent, "point_viewcontrol")) != -1) {
  472.         new m_state = GetEntProp(ent, Prop_Data, "m_state");
  473.         if (m_state != USE_ON)
  474.             continue;
  475.  
  476.         new m_hPlayer = GetEntPropEnt(ent, Prop_Data, "m_hPlayer");
  477.         //PrintToChatAll(" \x04[ZMBR FIXES] Trying to disable point_viewcontrol attached to player %d (client=%d)", player, client);
  478.         if (m_hPlayer == client) {
  479.             //PrintToChatAll(" \x04[ZMBR FIXES] Disabling point_viewcontrol attached to player %d", player);
  480.             AcceptEntityInput(ent, "Disable");
  481.  
  482.             return;
  483.         }
  484.     }
  485. }
  486.  
  487. DeactivateAllGameUI() {
  488.     new ent = -1;
  489.     while ((ent = FindEntityByClassname(ent, "game_ui")) != -1) {
  490.         new player = GetEntPropEnt(ent, Prop_Data, "m_player");
  491.         if (player == client)
  492.             AcceptEntityInput(ent, "Deactivate");
  493.     }
  494. }
  495.  
  496. DeactivateGameUIOfClient(client) {
  497.     new ent = -1;
  498.     while ((ent = FindEntityByClassname(ent, "game_ui")) != -1) {
  499.         new player = GetEntPropEnt(ent, Prop_Data, "m_player");
  500.         //PrintToChatAll(" \x04[ZMBR FIXES] Trying to deactivate game_ui attached to player %d (client=%d)", player, client);
  501.         if (player == client) {
  502.             //PrintToChatAll(" \x04[ZMBR FIXES] Deactivating game_ui attached to player %d", player);
  503.             AcceptEntityInput(ent, "Deactivate");
  504.         }
  505.     }
  506. }
  507.  
  508. public Action:OnRoundPreStart(Handle:event, const String:name[], bool:dontBroadcast) {
  509.     UnparentAllPlayers();
  510.     DisableAllPointViewControls();
  511.    
  512.     return Plugin_Continue;
  513. }
  514.  
  515. public Action:OnRoundEnd(Handle:event, const String:name[], bool:dontBroadcast) {
  516.     for (new client = 1; client <= MAXPLAYERS; client++)
  517.         if (Client_IsIngame(client))
  518.             SetEntProp(client, Prop_Data, "m_takedamage", 0, 1);
  519.    
  520.     return Plugin_Continue;
  521. }
  522.  
  523. public Action:OnPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast) {
  524.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  525.    
  526.     DisablePointViewControlOfClient(client);
  527.     DeactivateGameUIOfClient(client);
  528.    
  529.     return Plugin_Continue;
  530. }
  531.  
  532. public Action:OnPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) {
  533.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  534.    
  535.     DisablePointViewControlOfClient(client);
  536.     DeactivateGameUIOfClient(client);
  537.  
  538.     return Plugin_Continue;
  539. }
  540.  
  541. public ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOverride, bool:respawn) {
  542.     new health = Entity_GetHealth(client);
  543.     Entity_SetMaxHealth(client, health);
  544. }
  545.  
  546. bool:IsValidEntRef(entity) {
  547.     if (entity && EntRefToEntIndex(entity) != INVALID_ENT_REFERENCE)
  548.         return true;
  549.  
  550.     return false;
  551. }
RAW Paste Data