This site is a testing version, but all data is shared with the live forum.


Raised This Month: $ Target: $400
 0% 

Tutorial: Catching Weapons Fire in mod inspecific fashion


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
Urahara
Member
Join Date: Apr 2006
Old 05-07-2006 , 20:38   Tutorial: Catching Weapons Fire in mod inspecific fashion
Reply With Quote #1

This tutorial brought to you by: Urahara
More tutorials, as well as additional assistance, can be found at:
http://urahara.amxmodx.org/forums/


This doesn't seem like such a hard thing to figure out; after all, mods do it all the time. However, it becomes rather tricky once you realize four things:

1. Mods don't all follow the same standards.
2. Mini-mods can fuck with buttons.
3. Melee and explosive devices don't use trace line
4. There are tons of trace lines sent out each second


However, by briefly looking in the HLSDK, we can see that these three Trace_*'s are used:

trace_line - guns
trace_hull - melee
trace_sphere - explosives


However, all three types of weapons use trace_line. So, we will start with trace_line.

Hooking trace_line with FM is a simple task; unfortunately, trace_line doesn't say what entity fired the trace_line, for speed.

To get a place to start, we'll consider this:

1. The starting point for firing a weapon is the player who fired.
2. The end point for firing a weapon is where it hits.


So, in theory, if we loop through the clients, comparing their origins and points of convergence for sight to the trace_line, we should come up with who fired!

Lets make some code!
Code:
public check_trace( Float:start[3], Float:end[3], monsters, skip_ent, TraceResult:ptr)
{
	new Players[32]
	new playerCount, i, player
	get_players(Players, playerCount, "a")

	new Float:origin[3];
	for (i=0; i<playerCount; i++)
	{
		player = Players[i];
		entity_get_vector(player,EV_VEC_origin,origin)

		if(is_my_traceline(start,origin) == 1) server_print("%i fired a shot!",player)
	}
		
}
As you can see, I edited out the end point origin, both for speed and for transparency.

Unfortunately, we hit a problem: The z origin is always different. Why? Because the gun is the one shooting, not the player. In order to keep with mod independence, we simply ignore the z origin. In addition, we need this:

Code:
#define XS_FLEQ_TOLERANCE 5.0
#define XS_FLEQ(%1,%2) (((%1) <= ((%2) + XS_FLEQ_TOLERANCE)) && ((%1) >= ((%2) - XS_FLEQ_TOLERANCE)))


public is_my_traceline(Float:one[3],Float:two[3])
{
	if( XS_FLEQ(one[0],two[0]) && XS_FLEQ(one[1],two[1]) /*&& (one[2] == two[2])*/ ) return 1;

	return 0;
}
Why is the tolerance so high? Lag and client prediction. The client could move a bit before we get his shot. In reality, no one can come close enough to a client under normal circumstances to interfer with this, so its fine.

As you might see, this is a little ineffecient. We could be losing a lot of speed, but at least it works, and always works. However, we can make it better.

The gun must not shoot the player aiming it. That would be bad; you'd kill yourself. So, lets assume that skip_ent will be the id of the shooter:

Code:
public check_trace( Float:start[3], Float:end[3], monsters, skip_ent, TraceResult:ptr)
{
	if(skip_ent > 0 && skip_ent <= get_maxplayers() ) server_print("%i fired a shot!",skip_ent)
}
Much more effecient, eh? Unfortunately, its also unreliable; some mods use trace_lines for other things, notably TS, which uses it for stunts. So, we can get false positives.

Since sending out a forward to other plugins is MUCH more expensive, speed wise, then doing a few math checks, we cna increase the speed of this function by adding back in some origin checking:

Code:
public check_trace( Float:start[3], Float:end[3], monsters, skip_ent, TraceResult:ptr)
{
	if(skip_ent > 0 && skip_ent <= get_maxplayers() )
	{
		new Float:origin[3]
		entity_get_vector(skip_ent,EV_VEC_origin,origin)

		if(is_my_traceline(start,origin) == 1) server_print("%i fired a shot!",skip_ent)
	}
}
In effect, we now have three versions of the same functions: One that has no false positives or negatives, but is computational expensive, one that has false positives, but is very cheap, and now one that is cheap and has no false positives or negatives.

Putting in the appropriate formatting, and add a few more bells and whistles, we have our plugin, which is uploaded below.

Feel free to use this as much as you like.
Attached Files
File Type: sma Get Plugin or Get Source (fire_hook.sma - 1484 views - 1.7 KB)
__________________

Urahara's Shop is open! For all your needs:
http://urahara.amxmodx.org/forums/
Projects:
Ururu AntiCheat
MetaScript Library
Jinta Hax
Urahara is offline
 



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 03:11.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode