View difference between Paste ID: NNsdDzVf and DAkKDiWp
SHOW: | | - or go back to the newest paste.
1
#pragma semicolon 1
2
#pragma newdecls required
3
4
#include <sourcemod>
5
#include <sdktools>
6
#include <sdkhooks>
7
8
#define Sound "weapons/fx/rics/ric1.wav"
9
10
#define Tracer "weapon_tracers_incendiary"
11
#define Tracer1 "weapon_tracers_explosive"
12
#define Tracer2 "weapon_tracers"
13
14
static const char g_szNames[][] =
15
{
16
    "weapon_autoshotgun",
17
    "weapon_hunting_rifle",
18
    "weapon_pistol",
19
    "weapon_pistol_magnum",
20
    "weapon_pumpshotgun",
21
    "weapon_rifle",
22
    "weapon_rifle_ak47",
23
    "weapon_rifle_desert",
24
    "weapon_rifle_m60",
25
    "weapon_rifle_sg552",
26
    "weapon_shotgun_chrome",
27
    "weapon_shotgun_spas",
28
    "weapon_smg",
29
    "weapon_smg_mp5",
30
    "weapon_smg_silenced",
31
    "weapon_sniper_awp",
32
    "weapon_sniper_military",
33
    "weapon_sniper_scout"
34
};
35
 
36
static const float g_flMaxDistance[] =
37
{
38
    3116.0,
39
    3046.0,
40
    2860.0,
41
    3146.0,
42
    3116.0,
43
    3046.0,
44
    3046.0,
45
    3046.0,
46
    3046.0,
47
    3046.0,
48
    3096.0,
49
    3096.0,
50
    2860.0,
51
    2860.0,
52
    1001.0,
53
    3046.0,
54
    3046.0,
55
    3046.0
56
};
57
58
static const float g_flAngle[] =
59
{
60
    135.0,
61
    135.0,
62
    135.0,
63
    135.0,
64
    135.0,
65
    135.0,
66
    135.0,
67
    135.0,
68
    135.0,
69
    135.0,
70
    135.0,
71
    135.0,
72
    135.0,
73
    135.0,
74
    135.0,
75
    135.0,
76
    135.0,
77
    135.0
78
};
79
80
static const int g_iChance[] =
81
{
82
    100,
83
    100,
84
    100,
85
    100,
86
    100,
87
    100,
88
    100,
89
    100,
90
    100,
91
    100,
92
    100,
93
    100,
94
    100,
95
    100,
96
    100,
97
    100,
98
    100,
99
    100
100
};
101
102
103
int g_iTracerType, g_iDamage, g_iDamageType;
104
ConVar g_hTracerType, g_hDamage, g_hDamageType;
105
106
public void OnPluginStart()
107
{
108
	g_hTracerType = CreateConVar("sm_ricochet_tracer_type", "0", "What type of tracers shuld we use?\n 0 - incendiary\n 1 - explosive\n 2 - Original weapon tracers", FCVAR_NONE, true, 0.0, true, 2.0);
109
	g_hDamage = CreateConVar("sm_ricochet_damage", "5", "Damage of ricochet", FCVAR_NONE);
110
	g_hDamageType = CreateConVar("sm_ricochet_damage_type", "8", "Damage type of ricochet", FCVAR_NONE);
111
	
112
	AutoExecConfig(true, "l4d2_ricohet");
113
	
114
	g_iTracerType = g_hTracerType.IntValue;
115
	g_iDamage = g_hDamage.IntValue;
116
	g_iDamageType = g_hDamageType.IntValue;
117
	
118
	g_hTracerType.AddChangeHook(OnConVarChanged);
119
	g_hDamage.AddChangeHook(OnConVarChanged);
120
	g_hDamageType.AddChangeHook(OnConVarChanged);
121
	
122
	HookEvent("bullet_impact", eEvent);
123
}
124
125
public void OnMapStart()
126
{
127
	PrecacheSound(Sound);
128
	
129
	PrecacheParticle(Tracer);
130
	PrecacheParticle(Tracer1);
131
	PrecacheParticle(Tracer2);
132
}
133
134
public void OnConVarChanged(Handle convar, const char[] oldValue, const char[] newValue)
135
{
136
	g_iTracerType = g_hTracerType.IntValue;
137
	g_iDamage = g_hDamage.IntValue;
138
	g_iDamageType = g_hDamageType.IntValue;
139
}
140
141
public void eEvent (Event event, const char[] name, bool dontbroadcast)
142
{
143
	int client = GetClientOfUserId(event.GetInt("userid"));
144
	
145
	if (!client || GetClientTeam(client) != 2)
146
		return;
147
		
148
	int iCurrentWeapon = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon");
149
	
150
	if (iCurrentWeapon <= MaxClients)
151
		return;
152
	
153
	int index = -1;
154
	
155
	char szName[36];
156
	GetEntityClassname(iCurrentWeapon, szName, sizeof szName);
157
	
158
	for (int i; i < sizeof g_szNames; i++)
159
	{
160
		if (strcmp(g_szNames[i], szName) == 0)
161
		{
162
			index = i;
163
			break;
164
		}
165
	}
166
	
167
	if (index == -1)
168
		return;
169
	
170
	float vAngles[3], vOrigin[3], vEnd[3], vDir[3], vResult[3], vPlane[3];
171
	
172
	vEnd[0] = event.GetFloat("x");
173
	vEnd[1] = event.GetFloat("y");
174
	vEnd[2] = event.GetFloat("z");
175
	
176
	GetClientEyeAngles(client, vAngles);
177
	GetClientEyePosition(client, vOrigin);
178
	
179
	if (!IsVisibleTo(client, vEnd, vOrigin))
180
		return;
181
	
182
	GetAngleVectors(vAngles, vDir, NULL_VECTOR, NULL_VECTOR);
183
	
184-
	Handle TraceRay = TR_TraceRayFilterEx(vEnd, vAngles, MASK_SOLID, RayType_Infinite, TraceFilter, -1);
184+
	Handle TraceRay = TR_TraceRayFilterEx(vEnd, vAngles, MASK_SOLID, RayType_Infinite, TraceFilter);
185
	
186
	if (!TR_DidHit(TraceRay))
187
	{
188
		delete TraceRay;
189
		return;
190
	}
191
192
	TR_GetPlaneNormal(TraceRay, vPlane);
193
	delete TraceRay;
194
	
195
	if (RadToDeg(ArcCosine(GetVectorDotProduct(vDir, vPlane))) > g_flAngle[index] || GetRandomInt(1, 100) > g_iChance[index])
196
		return;
197
	
198
	TE_SetupSparks(vEnd, vDir, GetRandomInt(1, 2), GetRandomInt(1, 2));
199
	TE_SendToAll();
200
	
201
	NormalizeVector(vDir, vDir);
202
	
203
	ScaleVector(vPlane, 2.0);
204
	ScaleVector(vPlane, GetVectorDotProduct(vDir, vPlane));
205
	ScaleVector(vPlane, GetVectorLength(vDir));
206
	
207
	SubtractVectors(vDir, vPlane, vResult);
208
	
209
	GetVectorAngles(vResult, vAngles);
210
	
211
	vAngles[0] += GetRandomFloat(-5.0, 5.0);
212
	vAngles[1] += GetRandomFloat(-5.0, 5.0);
213
	
214-
	TraceRay = TR_TraceRayFilterEx(vEnd, vAngles, MASK_SOLID, RayType_Infinite, TraceFilter);
214+
	TraceRay = TR_TraceRayFilterEx(vEnd, vAngles, MASK_SOLID, RayType_Infinite, TraceFilter, -2);
215
	
216
	if (!TR_DidHit(TraceRay))
217
	{
218
		delete TraceRay;
219
		return;
220
	}
221
	
222
	TR_GetEndPosition(vResult, TraceRay);
223
	
224
	if (GetVectorDistance(vResult, vEnd) > g_flMaxDistance[index])
225
	{
226
		delete TraceRay;
227
		return;
228
	}
229
	
230
	int iTarget = TR_GetEntityIndex(TraceRay);
231
	
232
	delete TraceRay;
233
	
234
	DisplayRicochet(vEnd, vResult);
235
	EmitSoundToAll(Sound, SOUND_FROM_WORLD, SNDCHAN_AUTO, SNDLEVEL_NORMAL, SND_NOFLAGS, SNDVOL_NORMAL, SNDPITCH_NORMAL, _, vEnd);
236
	
237
	if (iTarget <= 0 || g_iDamage == 0)
238
		return;
239
	
240
	SDKHooks_TakeDamage(iTarget, client, client, float(g_iDamage), g_iDamageType);
241
}
242
243
void DisplayRicochet(float vStart[3], float vEnd[3])
244
{  
245
 	char szName[16];
246
	int iEntity = CreateEntityByName("info_particle_target");
247
	
248
	if (iEntity == -1)
249
		return;
250
	
251
	Format(szName, sizeof szName, "IInfo%d", iEntity);
252
	DispatchKeyValue(iEntity, "targetname", szName);	
253
	
254
	TeleportEntity(iEntity, vEnd, NULL_VECTOR, NULL_VECTOR); 
255
	ActivateEntity(iEntity); 
256
	
257
	SetVariantString("OnUser4 !self:Kill::1.1:-1");
258
	AcceptEntityInput(iEntity, "AddOutput");
259
	AcceptEntityInput(iEntity, "FireUser4");
260
	
261
	iEntity = CreateEntityByName("info_particle_system");
262
	
263
	if (iEntity == -1)
264
		return;
265
	
266
	switch (g_iTracerType)
267
	{
268
		case 0: DispatchKeyValue(iEntity, "effect_name", Tracer);
269
		case 1: DispatchKeyValue(iEntity, "effect_name", Tracer1);
270
		case 2: DispatchKeyValue(iEntity, "effect_name", Tracer2);
271
	}
272
	
273
	DispatchKeyValue(iEntity, "cpoint1", szName);
274
	
275
	TeleportEntity(iEntity, vStart, NULL_VECTOR, NULL_VECTOR);
276
	DispatchSpawn(iEntity);
277
	ActivateEntity(iEntity); 
278
	
279
	AcceptEntityInput(iEntity, "Start");
280
	
281
	SetVariantString("OnUser4 !self:Kill::1.1:-1");
282
	AcceptEntityInput(iEntity, "AddOutput");
283
	AcceptEntityInput(iEntity, "FireUser4");
284
}
285
286
void PrecacheParticle(const char[] sEffectName)
287
{
288
	static int table = INVALID_STRING_TABLE;
289
290
	if( table == INVALID_STRING_TABLE )
291
	{
292
		table = FindStringTable("ParticleEffectNames");
293
	}
294
295
	if( FindStringIndex(table, sEffectName) == INVALID_STRING_INDEX )
296
	{
297
		bool save = LockStringTables(false);
298
		AddToStringTable(table, sEffectName);
299
		LockStringTables(save);
300
	}
301
}
302
303
bool IsVisibleTo(int client, float vOrigin[3], float vPos[3])
304
{
305
	bool bResult;
306
	Handle TraceRay = TR_TraceRayFilterEx(vOrigin, vPos, MASK_SHOT, RayType_EndPoint, TraceFilterVisible, client);
307
308
	if (!TR_DidHit(TraceRay))
309
		bResult = true;
310
	delete TraceRay;
311
	
312
	return bResult;
313
}
314
315
public bool TraceFilterVisible(int entity, int mask, int client)
316
{
317
	if (entity != 0)
318
		return true;
319
	return false;
320
}
321
322
public bool TraceFilter(int entity, int mask, int client)
323
{
324-
	if (client == -1 && entity > 0 && entity <= MaxClients)
324+
	if (client == -2 && entity > 0 && entity <= MaxClients)
325-
		return false;
325+
326-
	return true;
326+
	else if (entity == 0 || entity > MaxClients)
327
		return true;
328
	return false;
329
}