31.12.2012, 12:33
(
Последний раз редактировалось Dinnozor; 06.01.2013 в 15:12.
Причина: v2.0 update
)
How it works
Using GetPlayerCameraFrontVector, GetPlayerCameraPos, but not any loops, this simple function detects where the shooter is aiming, and it returns a value according to where the shooter is aiming.
Works for every weapon : you can use this with guns, but also with close range weapons - see the video with the katana for example. It even detect the headshots when the target is in a vehicle, and headshots/armshots for crouched players !
Ideal for DM and zombie servers of course, but also nice for RP servers to get more realistic shootings !
Function
Callbacks
Put them wherever you want in your script.
In Game function
I made this function so the player manages manually the Widescreen ON/OFF mode. Indeed, as I try to explain below, although in the 1.0 and 1.01 versions being in Widescreen ON mode made it really easier to make headshots, this is not anymore a problem since 2.0, so the script doesn't have to check itself if the player uses Widescreen or not. It is now the player's problem since it doesn't give him advantages to use it or not. Don't hesitate to ask questions about this
v2.0 update (06/01/2013)
Here is how I used the callbacks in the video (see code below) :
Video
Installation
Just put this on top of your script :
Then, just put the callbacks seen above wherever you want in your script.
Q & A
Don't hesitate to ask questions or suggest improvements. Feel free to share/use/modify but please don't remove credits if you share it.
Using GetPlayerCameraFrontVector, GetPlayerCameraPos, but not any loops, this simple function detects where the shooter is aiming, and it returns a value according to where the shooter is aiming.
Works for every weapon : you can use this with guns, but also with close range weapons - see the video with the katana for example. It even detect the headshots when the target is in a vehicle, and headshots/armshots for crouched players !
Ideal for DM and zombie servers of course, but also nice for RP servers to get more realistic shootings !
Function
pawn Код:
stock GetPlayerAimedBodyPart(playerid, targetid, Float:range,weapon); //Returns the bodypart of targetid which playerid is aiming. Use it with OnPlayerTakeDamage ; I only tested it with it.
pawn Код:
public OnPlayerHeadshot(playerid,targetid,weaponid);//Do whatever you want when a player is hit in the head, the arm, the leg...
public OnPlayerLegshot(playerid,targetid,weaponid);
public OnPlayerArmshot(playerid,targetid,weaponid);
In Game function
Код:
/widescreen - since 2.0, activates or deactivates the Widescreen mode for the player.
v2.0 update (06/01/2013)
- finally got this working as a real include
- greatly improved the accuracy thanks to Nero_3D GetPlayerCameraWeaponVector include that let me take the correct offset with Widescreen ON
- /widescreen command to let the player take the Widescreen ON/OFF mode. Being in Widescreen ON mode is no longer a problem since it doesn't make it easier to do headshots. Indeed, the script now checks if the player aims a point, no more just the coord on Z axis. Please note it is still working better with Widescreen OFF mode.
Pastebin (v2.0)
v1.01 update (03/01/2013) - made it easier to shoot the arm, which was almost impossible in the 1.0
- kind of found a solution about the widescreen on/off problem (thanks to Nanory on Samp Forums for reporting) : the script checks if the player has an "overcorrection" with the GetPlayerCameraFrontVector Z-coord (which was the case when the player used Widescreen). If so, it will put the player in a "Widescreen" mode.
Also (since all the values were got experimentally), it will make the inverse check with angle correction (still about the GetPlayerCameraFrontVector inaccuracy with other weapons than sniper rifle) to check if the player lacks of correction. So basically, if the player is not in Widescreen but the script detected so (because of any bug or a wrong calculation), the script will automatically put the player back in non-Widescreen mode.
Added some calculation to do that, and a PVar "Widescreen". - Also took TheArcher's (thanks by the way) piece of advice about the callbacks.
Here is how I used the callbacks in the video (see code below) :
- If hit in the head, if the player doesn't have a helmet the player dies or loses a lot of health according to the shooter weapon.
- If hit in the leg, player will randomly fall or not.
- If hit in the arm, the player might lose his weapon.
pawn Код:
public OnPlayerHeadshot(playerid,targetid,weaponid)
{
new Float:Arm,Float:heal;
GetPlayerArmour(targetid,Arm);
GetPlayerHealth(targetid,heal);
switch(weaponid){
case 33,34,30,31,25..27,24:{
if(Casque[playerid]>1&&Arm>0){
Casque[playerid]--;
SetPlayerArmour(targetid,Arm-25);
}
else SetPlayerHealth(targetid,0);
}
case 22,23,28,29,32:{
if((Arm>0&&Casque[targetid]>0)||GetPlayerSkin(targetid)==285){
Casque[targetid]--;
SetPlayerArmour(targetid,Arm-15);
}
else SetPlayerHealth(targetid,floatround(heal-30,floatround_round));
}
case 8:SetPlayerHealth(targetid,0);
case 4..6,1:SetPlayerHealth(targetid,floatround(heal-30,floatround_round));
default:SetPlayerHealth(targetid,floatround(heal-5,floatround_round));
}
GameTextForPlayer(playerid,"HEADSHOT !",1000,6);
GameTextForPlayer(targetid,"OUCH ! HEADSHOT !",1000,6);
return 1;
}
public OnPlayerLegshot(playerid,targetid,weaponid)
{
switch(weaponid){
case 33,34,30,31,25..27,24:{
if(random(3)==1) OnePlayAnim(targetid,"ped","FLOOR_hit",4,0,1,1,0,0);
}
case 22,23,28,29,32:{
if(random(5)==1) OnePlayAnim(targetid,"ped","FLOOR_hit",4,0,1,1,0,0);
}
case 8:{
if(random(2)==1) OnePlayAnim(targetid,"ped","FLOOR_hit",4,0,1,1,0,0);
}
case 4..6,1:
{
if(random(3)==1) OnePlayAnim(targetid,"ped","FLOOR_hit",4,0,1,1,0,0);
}
default:{
if(random(3)==1) OnePlayAnim(targetid,"ped","FLOOR_hit",4,0,1,1,0,0);
}
}
GameTextForPlayer(playerid,"LEGSHOT !",1000,6);
GameTextForPlayer(targetid,"OUCH ! LEGSHOT !",1000,6);
return 1;
}
public OnPlayerArmshot(playerid,targetid,weaponid)
{
new wep=GetPlayerWeapon(targetid);
if(wep!=0){
switch(weaponid){
case 33,34,30,31,25..27,24:{
if(random(2)==1) DropWep(targetid,wep);
}
case 22,23,28,29,32:{
if(random(3)==1) DropWep(targetid,wep);
}
case 8:{
if(random(2)==1) DropWep(targetid,wep);
}
case 4..6,1:
{
if(random(2)==1) DropWep(targetid,wep);
}
default:{
if(random(2)==1) DropWep(targetid,wep);
}
}
GameTextForPlayer(playerid,"ARMSHOT !",1000,6);
GameTextForPlayer(targetid,"OUCH ! ARMSHOT !",1000,6);
}
return 1;
}
[ame="http://www.youtube.com/watch?v=2Y4ngd_wpzY"]Video[/ame]
Notice it works pretty well (this video was made with 1.0 version)Installation
Just put this on top of your script :
pawn Код:
#include <GPABP>
Q & A
- What if the target is in movement? (His arms would swing and his legs would move)
What if the target is falling/jumping?
Does it detect those things?
Basically the script calculates where the player is aiming and, if the target (whose Pos is X Y Z for example) is hit and if the shooter aims below Z-0.3, the player is aiming the legs. Then if the target moves, the script doesn't care if the legs move, it just determines if the player is aiming below Z-0.3.
It is almost the same with the arms, except it depends on the X and Y coordinates (and the facing angle then) - that actually makes the armshot the toughest to detect.
About the falling/jumping stuff, it should work just as fine as any other movement (player running...). - What happens when the victim is lying on the floor? for example, if he has just got out of a moving vehicle, you know that he rolls on the floor a bit, then he lies for a moment and finally gets up. Same when the victim has just been hit by a vehicle.
If the player is lying on the floor you would have to aim down, so I guess the script would detect a legshot. However this is not so frequent, so it wouldn't be really bothering.
- wups for GetDistanceFromPointToLine
- Double-O-Seven for CrossProduct system
- Nero3D for GetPlayerCameraWeaponVector
Don't hesitate to ask questions or suggest improvements. Feel free to share/use/modify but please don't remove credits if you share it.