11/* -----------------------------------------------------------------------------------------------------------------------------------------------------
22 * Changelog:
33 * ---------
4+ * 2.2: (24.10.2021) (A1m`)
5+ * 1. Fixed: in some cases we received the coordinates of the infected 0.0.0, now the plugin always gets the correct coordinates.
6+ *
47 * 2.0: (14.08.2021) (A1m`)
58 * 1. Completely rewrite the method of identifying uncommon infected.
69 * 2. Added some uncommon infected (fallen survivor and Jimmy Gibbs).
710 * 3. Optimization and code improvement.
811 * 4. Plugin tested for all uncommon infected.
912 * 5. A bug is noticed in the plugin, sometimes we get zero coordinates on the SDKHook_SpawnPost, what should we do about it?
10- *
13+ *
1114 * 0.1d: (06.07.2021) (A1m`)
1215 * 1. fixes description of cvar 'sm_uncinfblock_enabled' after 12+- years of using the plugin :D.
13- *
16+ *
1417 * 0.1c: (23.06.2021) (A1m`)
1518 * 1. new syntax, little fixes.
16- *
19+ *
1720 * 0.1b:
1821 * 1. spawns infected after killing uncommon entity.
19- *
22+ *
2023 * 0.1a
2124 * 1. first version (not really optimized).
22- *
25+ *
2326 * -----------------------------------------------------------------------------------------------------------------------------------------------------
2427 * Plugin test results (these are all uncommon infected):
25- *
28+ *
2629 * L4D2Gender_Ceda = 11
2730 * Plugin flag: (11 - 11 = 0) (1 << 0) = 1
2831 * Uncommon infected spawned! Model: models/infected/common_male_ceda_l4d1.mdl, gender: 11, plugin flag: 1.
2932 * Uncommon infected spawned! Model: models/infected/common_male_ceda.mdl, gender: 11, plugin flag: 1.
30- *
33+ *
3134 * L4D2Gender_Crawler = 12
3235 * Plugin flag: (12 - 11 = 1) (1 << 1) = 2
3336 * Uncommon infected spawned! Model: models/infected/common_male_mud_L4D1.mdl, gender: 12, plugin flag: 2.
3437 * Uncommon infected spawned! Model: models/infected/common_male_mud.mdl, gender: 12, plugin flag: 2.
35- *
38+ *
3639 * L4D2Gender_Undistractable = 13
3740 * Plugin flag: (13 - 11 = 2) (1 << 2) = 4
3841 * Uncommon infected spawned! Model: models/infected/common_male_roadcrew_l4d1.mdl, gender: 13, plugin flag: 4.
3942 * Uncommon infected spawned! Model: models/infected/common_male_roadcrew.mdl, gender: 13, plugin flag: 4.
4043 * Uncommon infected spawned! Model: models/infected/common_male_baggagehandler_02.mdl, gender: 13, plugin flag: 4.
4144 * Note: common_male_roadcrew_rain.mdl is this model used in the game?
42- *
45+ *
4346 * L4D2Gender_Fallen = 14
4447 * Plugin flag: (14 - 11 = 3) (1 << 3) = 8
4548 * Uncommon infected spawned! Model: models/infected/common_male_fallen_survivor_l4d1.mdl, gender: 14, plugin flag: 8.
6265*/
6366
6467#pragma semicolon 1
65- #pragma newdecls required ;
68+ #pragma newdecls required
6669
6770#include <sourcemod>
6871#include <sdktools>
6972#include <sdkhooks>
70- #define L4D2UTIL_STOCKS_ONLY
73+ #define L4D2UTIL_STOCKS_ONLY 1
7174#include <l4d2util>
7275
7376#define DEBUG 0
7477#define UNCOMMON_INFECTED_AMOUNT 7
7578
76- static const char sUncommon [][] =
79+ public const char sUncommon [][] =
7780{
7881 " ceda" ,
7982 " crawler" ,
@@ -84,12 +87,6 @@ static const char sUncommon[][] =
8487 " jimmy"
8588};
8689
87- int
88- g_iBlockUncInfFlags = 0 ;
89-
90- bool
91- g_bIsPluginEnable = false ;
92-
9390ConVar
9491 g_hPluginEnabled = null ,
9592 g_hBlockUncInfFlags = null ;
@@ -111,7 +108,7 @@ public void OnPluginStart()
111108 " Enable uncommon blocker plugin?" , \
112109 _ , true , 0.0 , true , 1.0 \
113110 );
114-
111+
115112 // 1 + 2 + 4 + 8 + 16 + 32 + 64 = 127 - Block all
116113 // 55 - All except fallen survivor and Jimmy Gibbs
117114 g_hBlockUncInfFlags = CreateConVar ( \
@@ -120,12 +117,7 @@ public void OnPluginStart()
120117 " Which uncommon infected to block (1:ceda, 2:crawler(mudmen), 4:undistractable(roadcrew), 8:fallen, 16:riotcop, 32:clown, 64:jimmy). 127 - All." , \
121118 _ , true , 1.0 , true , 127.0 \
122119 );
123-
124- CvarsToType ();
125-
126- g_hPluginEnabled .AddChangeHook (Cvars_Changed );
127- g_hBlockUncInfFlags .AddChangeHook (Cvars_Changed );
128-
120+
129121 RegAdminCmd (" sm_uncinfblock_check" , Cmd_UncInfBlock_Check , ADMFLAG_GENERIC );
130122}
131123
@@ -134,50 +126,44 @@ public Action Cmd_UncInfBlock_Check(int iClient, int iArgs)
134126 for (int i = 0 ; i < UNCOMMON_INFECTED_AMOUNT ; i ++ ) {
135127 ReplyToCommand (iClient , " Uncommon class '%s ' %s . Uncommon infected Flag: %d ." , sUncommon [i ], (IsUncommonInfectedBlocked (i )) ? " blocked" : " unblocked" , (1 << i ));
136128 }
137-
138- return Plugin_Handled ;
139- }
140-
141- public void Cvars_Changed (ConVar hConVar , const char [] sOldValue , const char [] sNewValue )
142- {
143- CvarsToType ();
144- }
145129
146- void CvarsToType ()
147- {
148- g_bIsPluginEnable = g_hPluginEnabled .BoolValue ;
149- g_iBlockUncInfFlags = g_hBlockUncInfFlags .IntValue ;
130+ return Plugin_Handled ;
150131}
151132
152133public void OnEntityCreated (int iEntity , const char [] sClassName )
153134{
154- if (sClassName [0 ] != ' i' || ! g_bIsPluginEnable ) {
135+ if (sClassName [0 ] != ' i' || ! g_hPluginEnabled . BoolValue ) {
155136 return ;
156137 }
157-
138+
158139 if (strncmp (sClassName , " infected" , 8 , false ) == 0 ) {
159140 SDKHook (iEntity , SDKHook_SpawnPost , Hook_OnEntitySpawned );
160141 }
161142}
162143
163144public void Hook_OnEntitySpawned (int iEntity )
164145{
165- if (iEntity < MaxClients || ! IsValidEntity (iEntity )) {
146+ RequestFrame (OnNextFrame , EntIndexToEntRef (iEntity ));
147+ }
148+
149+ public void OnNextFrame (int iEntity )
150+ {
151+ if (EntRefToEntIndex (iEntity ) == INVALID_ENT_REFERENCE || ! IsValidEdict (iEntity )) {
166152 return ;
167153 }
168-
154+
169155 int iUncommonInfected = view_as <int >(GetGender (iEntity ) - L4D2Gender_Ceda );
170156 bool bIsUncommonInfected = (iUncommonInfected >= 0 && iUncommonInfected < UNCOMMON_INFECTED_AMOUNT );
171-
157+
172158 if (! bIsUncommonInfected ) {
173159 return ;
174160 }
175-
161+
176162#if DEBUG
177163 char sModel [PLATFORM_MAX_PATH ];
178164 GetEntPropString (iEntity , Prop_Data , " m_ModelName" , sModel , sizeof (sModel ));
179165 PrintToChatAll (" Uncommon infected spawned! Entity: %d , model: %s , gender: %d , plugin flag: %d , blocked: %s ." , \
180- iEntity , sModel , GetGender (iEntity ), (1 << iUncommonInfected ), (IsUncommonInfectedBlocked (iUncommonInfected )) ? " true" : " false" );
166+ EntRefToEntIndex ( iEntity ) , sModel , GetGender (iEntity ), (1 << iUncommonInfected ), (IsUncommonInfectedBlocked (iUncommonInfected )) ? " true" : " false" );
181167#endif
182168
183169 if (! IsUncommonInfectedBlocked (iUncommonInfected )) {
@@ -186,18 +172,18 @@ public void Hook_OnEntitySpawned(int iEntity)
186172
187173 float fLocation [3 ];
188174 GetEntPropVector (iEntity , Prop_Send , " m_vecOrigin" , fLocation ); // get location
189-
175+
190176#if DEBUG
191- PrintToChatAll (" 2 Blocked uncommon infected! Entity: %d , location: %.0f %.0f %.0f ." , iEntity , fLocation [0 ], fLocation [1 ], fLocation [2 ]);
177+ PrintToChatAll (" 2 Blocked uncommon infected! Entity: %d , location: %.0f %.0f %.0f ." , EntRefToEntIndex (iEntity ), fLocation [0 ], fLocation [1 ], fLocation [2 ]);
178+ #endif
179+
180+ // kill the uncommon infected
181+ #if SOURCEMOD_V_MINOR > 8
182+ RemoveEntity (iEntity );
183+ #else
184+ AcceptEntityInput (iEntity , " Kill" );
192185#endif
193186
194- KillEntity (iEntity ); // kill the uncommon infected
195-
196- // some zombies have zero coordinates, temporary fix :D
197- if (fLocation [0 ] == 0.0 && fLocation [1 ] == 0.0 && fLocation [2 ] == 0.0 ) {
198- return ;
199- }
200-
201187 SpawnNewInfected (fLocation ); // spawn infected in location instead
202188}
203189
@@ -211,16 +197,15 @@ void SpawnNewInfected(const float fLocation[3])
211197 /*
212198 * Original game code:
213199 * #define TICK_INTERVAL (gpGlobals->interval_per_tick)
214- * #define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) )
200+ * #define TIME_TO_TICKS( dt ) ( (int)( 0.5f + (float)(dt) / TICK_INTERVAL ) )
215201 * SetNextThink( TIME_TO_TICKS(gpGlobals->curtime ) );
216- * Right?
217202 */
218203 int iTickTime = RoundToNearest (GetGameTime () / GetTickInterval ()) + 5 ; // copied from uncommon spawner plugin, prolly helps avoid the zombie get 'stuck' ?
219-
204+
220205 SetEntProp (iInfected , Prop_Data , " m_nNextThinkTick" , iTickTime );
221206 DispatchSpawn (iInfected );
222207 ActivateEntity (iInfected );
223-
208+
224209 TeleportEntity (iInfected , fLocation , NULL_VECTOR , NULL_VECTOR );
225210
226211#if DEBUG
@@ -230,14 +215,5 @@ void SpawnNewInfected(const float fLocation[3])
230215
231216bool IsUncommonInfectedBlocked (const int iUncommonInfected )
232217{
233- return (((1 << iUncommonInfected ) & g_iBlockUncInfFlags ) != 0 );
234- }
235-
236- void KillEntity (int iEntity )
237- {
238- #if SOURCEMOD_V_MINOR > 8
239- RemoveEntity (iEntity );
240- #else
241- AcceptEntityInput (iEntity , " Kill" );
242- #endif
218+ return (((1 << iUncommonInfected ) & g_hBlockUncInfFlags .IntValue ) != 0 );
243219}
0 commit comments