Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 1st, 2012  |  syntax: PAWN  |  size: 5.13 KB  |  hits: 26  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <sourcemod>
  2. #include <sdkhooks>
  3. #include <sdktools>
  4. #include <weapons.inc>
  5.  
  6. #define SURVIVOR_TEAM 2
  7. #define INFECTED_TEAM 3
  8. #define ENT_CHECK_INTERVAL 1.0
  9. #define TRACE_TOLERANCE 75.0
  10.  
  11. public Plugin:myinfo =
  12. {
  13.         name = "Blind Infected",
  14.         author = "CanadaRox, ProdigySim",
  15.         description = "Hides specified weapons from the infected team until they are (possibly) visible to one of the survivors to prevent SI scouting the map",
  16.         version = "1.0",
  17.         url = "https://github.com/CanadaRox/sourcemod-plugins/tree/master/blind_infected_l4d2"
  18. };
  19.  
  20. enum EntInfo
  21. {
  22.         iEntRef,
  23.         bool:hasBeenSeen
  24. }
  25.  
  26. new const WeaponId:iIdsToBlock[] =
  27. {
  28.         WEPID_PISTOL,
  29.         WEPID_SMG,
  30.         WEPID_PUMPSHOTGUN,
  31.         WEPID_AUTOSHOTGUN,
  32.         WEPID_RIFLE,
  33.         WEPID_HUNTING_RIFLE,
  34.         WEPID_SMG_SILENCED,
  35.         WEPID_SHOTGUN_CHROME,
  36.         WEPID_RIFLE_DESERT,
  37.         WEPID_SNIPER_MILITARY,
  38.         WEPID_SHOTGUN_SPAS,
  39.         WEPID_FIRST_AID_KIT,
  40.         WEPID_MOLOTOV,
  41.         WEPID_PIPE_BOMB,
  42.         WEPID_PAIN_PILLS,
  43.         WEPID_MELEE,
  44.         WEPID_CHAINSAW,
  45.         WEPID_GRENADE_LAUNCHER,
  46.         WEPID_AMMO_PACK,
  47.         WEPID_ADRENALINE,
  48.         WEPID_DEFIBRILLATOR,
  49.         WEPID_VOMITJAR,
  50.         WEPID_RIFLE_AK47,
  51.         WEPID_INCENDIARY_AMMO,
  52.         WEPID_FRAG_AMMO,
  53.         WEPID_PISTOL_MAGNUM,
  54.         WEPID_SMG_MP5,
  55.         WEPID_RIFLE_SG552,
  56.         WEPID_SNIPER_SCOUT,
  57.         WEPID_SNIPER_AWP
  58. };
  59.  
  60. new Handle:hBlockedEntities;
  61.  
  62. public OnPluginStart()
  63. {
  64.         L4D2Weapons_Init();
  65.  
  66.         HookEvent("round_start", RoundStart_Event, EventHookMode_PostNoCopy);
  67.  
  68.         hBlockedEntities = CreateArray(_:EntInfo);
  69.  
  70.         CreateTimer(ENT_CHECK_INTERVAL, EntCheck_Timer, _, TIMER_REPEAT);
  71. }
  72.  
  73. public Action:EntCheck_Timer(Handle:timer)
  74. {
  75.         new size = GetArraySize(hBlockedEntities);
  76.         decl currentEnt[EntInfo];
  77.  
  78.         for (new i; i < size; i++)
  79.         {
  80.                 GetArrayArray(hBlockedEntities, i, currentEnt[0]);
  81.                 new ent = EntRefToEntIndex(currentEnt[iEntRef]);
  82.                 if (ent != INVALID_ENT_REFERENCE && !currentEnt[hasBeenSeen] && IsVisibleToSurvivors(ent))
  83.                 {
  84.                         decl String:tmp[128];
  85.                         GetEntPropString(ent, Prop_Data, "m_ModelName", tmp, sizeof(tmp));
  86.                         currentEnt[hasBeenSeen] = true;
  87.                         SetArrayArray(hBlockedEntities, i, currentEnt[0]);
  88.                 }
  89.         }
  90. }
  91.  
  92. public RoundStart_Event(Handle:event, const String:name[], bool:dontBroadcast)
  93. {
  94.         ClearArray(hBlockedEntities);
  95.         CreateTimer(1.2, RoundStartDelay_Timer);
  96. }
  97.  
  98. public Action:RoundStartDelay_Timer(Handle:timer)
  99. {
  100.         decl bhTemp[EntInfo];
  101.         decl WeaponId:weapon;
  102.         new psychonic = GetEntityCount();
  103.  
  104.         for (new i = MaxClients; i < psychonic; i++)
  105.         {
  106.                 weapon = IdentifyWeapon(i);
  107.                 if (weapon)
  108.                 {
  109.                         for (new j; j < sizeof(iIdsToBlock); j++)
  110.                         {
  111.                                 if (weapon == iIdsToBlock[j])
  112.                                 {
  113.                                         SDKHook(i, SDKHook_SetTransmit, OnTransmit);
  114.                                         bhTemp[iEntRef] = EntIndexToEntRef(i);
  115.                                         bhTemp[hasBeenSeen] = false;
  116.                                         PushArrayArray(hBlockedEntities, bhTemp[0]);
  117.                                         break;
  118.                                 }
  119.                         }
  120.                 }
  121.         }
  122. }
  123.  
  124. public Action:OnTransmit(entity, client)
  125. {
  126.         if (GetClientTeam(client) != INFECTED_TEAM) return Plugin_Continue;
  127.  
  128.         new size = GetArraySize(hBlockedEntities);
  129.         decl currentEnt[EntInfo];
  130.  
  131.         for (new i; i < size; i++)
  132.         {
  133.                 GetArrayArray(hBlockedEntities, i, currentEnt[0]);
  134.                 if (entity == EntRefToEntIndex(currentEnt[iEntRef]))
  135.                 {
  136.                         if (currentEnt[hasBeenSeen]) return Plugin_Continue;
  137.                         else return Plugin_Handled;
  138.                 }
  139.         }
  140.        
  141.         return Plugin_Continue;
  142. }
  143.  
  144. // from http://code.google.com/p/srsmod/source/browse/src/scripting/srs.despawninfected.sp
  145. stock bool:IsVisibleToSurvivors(entity)
  146. {
  147.         new iSurv;
  148.  
  149.         for (new i = 1; i < MaxClients && iSurv < 4; i++)
  150.         {
  151.                 if (IsClientInGame(i) && GetClientTeam(i) == SURVIVOR_TEAM)
  152.                 {
  153.                         iSurv++
  154.                         if (IsPlayerAlive(i) && IsVisibleTo(i, entity))
  155.                         {
  156.                                 return true;
  157.                         }
  158.                 }
  159.         }
  160.  
  161.         return false;
  162. }
  163.  
  164. stock bool:IsVisibleTo(client, entity) // check an entity for being visible to a client
  165. {
  166.         decl Float:vAngles[3], Float:vOrigin[3], Float:vEnt[3], Float:vLookAt[3];
  167.        
  168.         GetClientEyePosition(client,vOrigin); // get both player and zombie position
  169.        
  170.         GetEntPropVector(entity, Prop_Send, "m_vecOrigin", vEnt);
  171.        
  172.         MakeVectorFromPoints(vOrigin, vEnt, vLookAt); // compute vector from player to zombie
  173.        
  174.         GetVectorAngles(vLookAt, vAngles); // get angles from vector for trace
  175.        
  176.         // execute Trace
  177.         new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_Infinite, TraceFilter);
  178.        
  179.         new bool:isVisible = false;
  180.         if (TR_DidHit(trace))
  181.         {
  182.                 decl Float:vStart[3];
  183.                 TR_GetEndPosition(vStart, trace); // retrieve our trace endpoint
  184.                
  185.                 if ((GetVectorDistance(vOrigin, vStart, false) + TRACE_TOLERANCE) >= GetVectorDistance(vOrigin, vEnt))
  186.                 {
  187.                         isVisible = true; // if trace ray lenght plus tolerance equal or bigger absolute distance, you hit the targeted zombie
  188.                 }
  189.         }
  190.         else
  191.         {
  192.                 //Debug_Print("Zombie Despawner Bug: Player-Zombie Trace did not hit anything, WTF");
  193.                 isVisible = true;
  194.         }
  195.         CloseHandle(trace);
  196.         return isVisible;
  197. }
  198.  
  199. public bool:TraceFilter(entity, contentsMask)
  200. {
  201.         if (entity <= MaxClients || !IsValidEntity(entity)) // dont let WORLD, players, or invalid entities be hit
  202.         {
  203.                 return false;
  204.         }
  205.        
  206.         decl String:class[128];
  207.         GetEdictClassname(entity, class, sizeof(class)); // Ignore prop_physics since some can be seen through
  208.        
  209.         return !StrEqual(class, "prop_physics", false);
  210. }