16.10.2013, 03:35
You can't do NPC damage detection like that in fact no NPC to date that I know of can directly triggle OnPlayerTakeDamage() FCNPC will trigger OnPlayerGiveDamage() however. Anyways to do hit detection you need to get a little more creative fortunately for you I've written a few functions to take care of this problem.
This detects when a player shoots a weapon (Doesn't work for melee weapons)
Now we need some functions to detect when a player shoots a NPC, basically what you do is loop through all your NPCs every time a player shoots and if one is streamed in you check if there was a bullet collision. All you really need to know here is sx, sy, sz is your NPC position which is where the collision check sphere will be created fScale will scale your shooting vector the higher the value the further the collision detection will check and radius is your sphere size 1.0 is pretty good for NPCs.
This detects when a player shoots a weapon (Doesn't work for melee weapons)
pawn Code:
#include <YSI\y_hooks>
forward OnPlayerShoot(playerid,weaponid,ammo);
new OldAmmo[MAX_PLAYERS], OldWeap[MAX_PLAYERS];
new CurrAmmo[MAX_PLAYERS], CurrWeap[MAX_PLAYERS];
hook OnPlayerUpdate(playerid)
{
// Get the current weapon and ammo
CurrWeap[playerid] = GetPlayerWeapon(playerid);
CurrAmmo[playerid] = GetPlayerAmmo(playerid);
// Player still has old weapon does this weapon now have less ammo?
if(CurrWeap[playerid] == OldWeap[playerid] && CurrAmmo[playerid] < OldAmmo[playerid])
{
CallLocalFunction( "OnPlayerShoot", "iii", playerid, CurrWeap[playerid], CurrAmmo[playerid]);
}
OldWeap[playerid] = CurrWeap[playerid];
OldAmmo[playerid] = CurrAmmo[playerid];
return 1;
}
pawn Code:
// Checks if a players bullet intersects a sphere
stock BulletCollisionSphere(playerid, weapon, Float:sx, Float:sy, Float:sz, Float:fScale = 30.0, Float:radius = 1.0)
{
new
Float:fP[3],
Float:fV[3],
Float:object[3],
Float:sphere[3];
sphere[0] = sx, sphere[1] = sy, sphere[2] = sz;
GetPlayerCameraPos(playerid, fP[0], fP[1], fP[2]);
GetPlayerCameraFrontVector(playerid, fV[0], fV[1], fV[2]);
// Compensate (This is not perfect yet any ideas anyone?)
if(weapon != 34 && weapon != 35 && weapon != 36)
{
new Float:FacingA;
GetPlayerFacingAngle(playerid, FacingA);
FacingA -= 90.0;
if(FacingA < 0.0) FacingA += 360.0;
else if(FacingA > 360.0) FacingA -= 360.0;
fP[0] = (fP[0] + 0.6 * floatsin(-FacingA,degrees));
fP[2] += 1.2;
}
object[0] = fP[0] + floatmul(fV[0], fScale);
object[1] = fP[1] + floatmul(fV[1], fScale);
object[2] = fP[2] + floatmul(fV[2], fScale);
// Check if line intersects sphere
if(RaySphere(fP, object, sphere, radius)) return 1;
return 0;
}
// This checks to see if a line intersects a sphere
stock RaySphere(Float:p1[3],Float:p2[3],Float:sc[3],Float:r)
{
new Float:a, Float:b, Float:c;
new Float:bb4ac;
new Float:dp[3];
dp[0] = p2[0] - p1[0];
dp[1] = p2[1] - p1[1];
dp[2] = p2[2] - p1[2];
a = dp[0] * dp[0] + dp[1] * dp[1] + dp[2] * dp[2];
b = 2 * (dp[0] * (p1[0] - sc[0]) + dp[1] * (p1[1] - sc[1]) + dp[2] * (p1[2] - sc[2]));
c = sc[0] * sc[0] + sc[1] * sc[1] + sc[2] * sc[2];
c += p1[0] * p1[0] + p1[1] * p1[1] + p1[2] * p1[2];
c -= 2 * (sc[0] * p1[0] + sc[1] * p1[1] + sc[2] * p1[2]);
c -= r * r;
bb4ac = b * b - 4 * a * c;
if(bb4ac < 0) return 0;
return 1;
}