[FilterScript] Server Sided Vehicle Damage
#1

Server Sided Vehicle Damage

Notes:
IsValidVehicle() is a real function but not defined in the SAMP includes you will need to add it or uncomment it from the FS.

Lets you shoot cars with no players in them, I accidentally found a way this would work when trying to do something else. It basically checks to see if your shot will intersect a sphere around a vehicle so the detection isn't perfect but actually works reasonably well I plan on releasing some more updates cheers.

There is only one callback to hook so this could very easily be implemented into a gamemode.

pawn Код:
// Creates server sided vehicle damage detection version 1.0
// By [uL]Pottus
//
// This uses a method of checking when a player shoots if a line representing an origin and destination intersects a sphere
// an intersection will result in the vehicle being damaged.
//
// Just compile and load

#include <a_samp>

// native IsValidVehicle(vehicleid);

forward OnPlayerShoot(playerid,weaponid,ammo);

new OldAmmo[MAX_PLAYERS], OldWeap[MAX_PLAYERS];
new CurrAmmo[MAX_PLAYERS], CurrWeap[MAX_PLAYERS];

//------------------------------------------------------------------------------

// Update the players weapon and possibly call OnPlayerShoot()
public 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])
    {
        OnPlayerShoot(playerid, CurrWeap[playerid], CurrAmmo[playerid]);
    }
    OldWeap[playerid] = CurrWeap[playerid];
    OldAmmo[playerid] = CurrAmmo[playerid];
    return 1;
}

// Check if a vehicle is occupied
stock IsVehicleOccupied(vehicleid)
{
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
        if(!IsPlayerConnected(i)) continue;

        if(IsPlayerInAnyVehicle(i))
        {
            if(GetPlayerVehicleID(i)==vehicleid)
            {
                return 1;
            }
        }
    }
    return 0;
}

public OnPlayerShoot(playerid, weaponid, ammo)
{
    for(new i = 0; i < MAX_VEHICLES; i++)
    {
        if(IsValidVehicle(i))
        {
            if(IsVehicleStreamedIn(i, playerid) && !IsVehicleOccupied(i))
            {
                new Float:vx, Float:vy, Float:vz, Float:radius, Float:dist, Float:amount;
                GetVehiclePos(i, vx, vy, vz);

                // This offsets the sphere (Add vehicle models later for better detection)
                vz -= 1.0;
                radius = 2.0;


                // Select damage amount and collision radius
                switch(weaponid)
                {
                    case 22: // 9MM
                    {
                        amount = 40.0;
                        dist = 30.0;
                    }
                    case 23: // Silencer
                    {
                        amount = 40.0;
                        dist = 50.0;
                    }
                    case 24: // Deagle
                    {
                        amount = 140.0;
                        dist = 50.0;
                    }
                    case 25: // Shotgun
                    {
                        amount = 80.0;
                        dist = 50.0;
                    }
                    case 26: // Sawn
                    {
                        amount = 80.0;
                        dist = 50.0;
                    }
                    case 27: // Combat
                    {
                        amount = 80.0;
                        dist = 50.0;
                    }
                    case 28: // Uzi
                    {
                        amount = 25.0;
                        dist = 20.0;
                    }
                    case 29: // MP5
                    {
                        amount = 25.0;
                        dist = 50.0;
                    }
                    case 30: // AK
                    {
                        amount = 30.0;
                        dist = 150.0;
                    }
                    case 31: // m4
                    {
                        amount = 30.0;
                        dist = 150.0;
                    }
                    case 32: // Tec
                    {
                        amount = 25.0;
                        dist = 30.0;
                    }
                    case 33: // Rifle
                    {
                        amount = 75.0;
                        dist = 200.0;
                    }
                    case 34: // Sniper
                    {
                        amount = 125.0;
                        dist = 300.0;
                    }
                    case 35: // RPG
                    {
                        amount = 751.0;
                        dist = 100.0;
                    }
                    case 36: // HEatseek
                    {
                        amount = 751.0;
                        dist = 100.0;
                    }
                    case 38: // Mini
                    {
                        amount = 50.0;
                        dist = 100.0;
                    }
                }

                if(BulletCollision(playerid, weaponid, vx, vy, vz, dist, radius))
                {
                    new Float:vhp;
                    GetVehicleHealth(i, vhp);
                    if(vhp >= 250.0)
                    {
                        vhp -= amount;
                        if(vhp < 250.0) SetTimerEx("ResetVehicle", 15000, false, "i", i);
                        SetVehicleHealth(i, vhp);
                    }
                    // SendClientMessage(playerid, -1, "Collision");
                }
                // else SendClientMessage(playerid, -1, "No Collision");
            }
        }
    }
    return 1;
}
// Respawn vehicle (They bug if you don't do this)
forward ResetVehicle(vid);
public ResetVehicle(vid)
{
    SetVehicleToRespawn(vid);
    return 1;
}

// Checks if a players bullet intersects a sphere
stock BulletCollision(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;
}
Reply
#2

I tried compiling it, but this happened:
Код:
E:\Rockstar Games\Server\samp03x_svr_win32\filterscripts\vehicledamage.pwn(57) : error 017: undefined symbol "IsValidVehicle"
Pawn compiler 3.2.3664	 	 	Copyright © 1997-2006, ITB CompuPhase


1 Error.
Interesting concept though.
Reply
#3

Sorry I forgot to mention something, thanks for pointing that out.

https://sampwiki.blast.hk/wiki/IsValidVehicle
Reply
#4

Nice! I suppose you could use this to improve the precision.
Reply
#5

Quote:
Originally Posted by Slice
Посмотреть сообщение
Nice! I suppose you could use this to improve the precision.
Next update I was planning on doing that actually, first thing is i'd like to try and figure out how to calculate for GTA's aim offset right now it uses the camera which works great for sniper but there is a bit of loss of precision because the way I'm doing it right now is more of a bandaid solution.
Reply
#6

Nice
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)