SA-MP Forums Archive
[FilterScript] Distance bug fix - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Filterscripts (https://sampforum.blast.hk/forumdisplay.php?fid=17)
+--- Thread: [FilterScript] Distance bug fix (/showthread.php?tid=451380)



Distance bug fix - Slice - 16.07.2013

Most of you are probably not aware of this bug. When you exit a vehicle that isn't a bike, all weapons will have a virtually infinite range when you're being shot at.

This filterscript takes care of that problem.

How does it work?
The filterscript waits for everyone to leave the vehicle, then for the vehicle to stop moving (if it's rolling or something).

Beware: Credits
F0rce helped develop this (sssssssss).

The code:

pawn Код:
#include <a_samp>

#if !defined IsValidVehicle
    native IsValidVehicle(vehicleid);
#endif

enum E_VEHICLE_DATA {
          Monitor,
          Timer,
          RePosition,
          SetZAngle,
    Float:Health,
    Float:ZAngle,
    Float:X,
    Float:Y,
    Float:Z,
          DamagePanels,
          DamageDoors,
          DamageLights,
          DamageTires
}

new
    g_VehicleData[MAX_VEHICLES][E_VEHICLE_DATA],
    g_EnteringVehicle[MAX_PLAYERS] = {INVALID_VEHICLE_ID, ...},
    g_EnteringTimer[MAX_PLAYERS] = {-1, ...},
    g_LastVehicleId[MAX_PLAYERS] = {INVALID_VEHICLE_ID, ...}
;

stock IsVehicleBeingEntered(vehicleid) {
    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (g_EnteringVehicle[i] == vehicleid) {
            return true;
        }
    }
   
    return false;
}

stock GetPlayerInVehicle(vehicleid, seat = 0) {
    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (!IsPlayerConnected(i)) {
            continue;
        }
         
        if (GetPlayerVehicleID(i) == vehicleid &&
            GetPlayerVehicleSeat(i) == seat) {
            return i;
        }
    }

    return INVALID_PLAYER_ID;
}

stock IsVehicleEmpty(vehicleid, except = INVALID_PLAYER_ID) {
    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (!IsPlayerConnected(i) || i == except) {
            continue;
        }
       
        if (GetPlayerVehicleID(i) == vehicleid) {
            return false;
        }
    }

    return true;
}

stock EnteringStopped(playerid) {
    new vehicleid = g_EnteringVehicle[playerid];
   
    if (vehicleid == INVALID_VEHICLE_ID) {
        return;
    }
   
    g_EnteringVehicle[playerid] = INVALID_VEHICLE_ID;
    g_EnteringTimer[playerid] = -1;
   
    if (g_EnteringTimer[playerid] != -1) {
        KillTimer(g_EnteringTimer[playerid]);
    }
}

public OnFilterScriptInit() {
    for (new i = 0; i < MAX_VEHICLES; i++) {
        g_VehicleData[i][Timer] = -1;
    }
   
    for (new i = 0; i < MAX_PLAYERS; i++) {
        new vehicleid = GetPlayerVehicleID(i);
       
        if (vehicleid != 0) {
            g_LastVehicleId[i] = vehicleid;
        }
    }
}

public OnPlayerConnect(playerid) {
    g_LastVehicleId[playerid] = INVALID_VEHICLE_ID;
   
    return 1;
}

public OnPlayerDisconnect(playerid, reason) {
    EnteringStopped(playerid);
   
    return 1;
}

public OnPlayerDeath(playerid, killerid, reason) {
    EnteringStopped(playerid);
   
    return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate) {
    EnteringStopped(playerid);
   
    if (oldstate == PLAYER_STATE_DRIVER || oldstate == PLAYER_STATE_PASSENGER) {
        new vehicleid = g_LastVehicleId[playerid];
       
        if (IsVehicleEmpty(vehicleid, playerid)) {
            UpdateMonitoring(vehicleid);
        }
    }
   
    if (newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER) {
        g_LastVehicleId[playerid] = GetPlayerVehicleID(playerid);
       
        StopMonitoring(GetPlayerVehicleID(playerid));
    }
   
    return 1;
}

public OnVehicleDeath(vehicleid, killerid) {
    StopMonitoring(vehicleid);
   
    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (g_EnteringVehicle[i] == vehicleid) {
            EnteringStopped(i);
        }
    }
   
    return 1;
}

public OnVehicleSpawn(vehicleid) {
    if (g_VehicleData[vehicleid][RePosition]) {
        SetVehicleHealth(vehicleid, g_VehicleData[vehicleid][Health]);
        SetVehiclePos(
            vehicleid,
            g_VehicleData[vehicleid][X],
            g_VehicleData[vehicleid][Y],
            g_VehicleData[vehicleid][Z] + 0.3
        );
       
        UpdateVehicleDamageStatus(
            vehicleid,
            g_VehicleData[vehicleid][DamagePanels],
            g_VehicleData[vehicleid][DamageDoors],
            g_VehicleData[vehicleid][DamageLights],
            g_VehicleData[vehicleid][DamageTires]
        );
       
        StopMonitoring(vehicleid);
       
        g_VehicleData[vehicleid][SetZAngle] = 30;
       
        SetTimerEx("UpdateZAngle", 50, false, "i", vehicleid);
    } else {
        StopMonitoring(vehicleid);
    }
   
    return 1;
}

forward UpdateZAngle(vehicleid);
public UpdateZAngle(vehicleid) {
    if (g_VehicleData[vehicleid][SetZAngle]) {
        SetVehicleZAngle(vehicleid, g_VehicleData[vehicleid][ZAngle]);
       
        g_VehicleData[vehicleid][SetZAngle]--;
       
        SetTimerEx("UpdateZAngle", 50, false, "i", vehicleid);
    }
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) {
    EnteringStopped(playerid);
   
    g_EnteringVehicle[playerid] = vehicleid;
    g_EnteringTimer[playerid] = SetTimerEx("OnEnteringAborted", 7000, false, "i", playerid);
   
    return 1;
}

forward OnEnteringAborted(playerid);
public OnEnteringAborted(playerid) {
    EnteringStopped(playerid);
}

stock StopMonitoring(vehicleid) {
    g_VehicleData[vehicleid][Monitor] = false;
    g_VehicleData[vehicleid][RePosition] = false;

    if (g_VehicleData[vehicleid][Timer] != -1) {
        KillTimer(g_VehicleData[vehicleid][Timer]);

        g_VehicleData[vehicleid][Timer] = -1;
    }
}

stock UpdateMonitoring(vehicleid, finish_delay = 2000) {
    StopMonitoring(vehicleid);
   
    if (!IsValidVehicle(vehicleid)) {
        return;
    }
   
    g_VehicleData[vehicleid][Monitor] = true;
    g_VehicleData[vehicleid][Timer] = SetTimerEx("OnMonitoringFinish", finish_delay, false, "i", vehicleid);
}

forward OnMonitoringFinish(vehicleid);
public OnMonitoringFinish(vehicleid) {
    if (!IsValidVehicle(vehicleid)) {
        return;
    }
   
    if (IsVehicleBeingEntered(vehicleid)) {
        UpdateMonitoring(vehicleid, 150);
       
        return;
    }
   
    StopMonitoring(vehicleid);
   
    CallRemoteFunction("OnVehicleStoppedMoving", "i", vehicleid);
   
    GetVehicleHealth(vehicleid, g_VehicleData[vehicleid][Health]);
    GetVehicleZAngle(vehicleid, g_VehicleData[vehicleid][ZAngle]);
    GetVehiclePos(
        vehicleid,
        g_VehicleData[vehicleid][X],
        g_VehicleData[vehicleid][Y],
        g_VehicleData[vehicleid][Z]
    );
   
    GetVehicleDamageStatus(
        vehicleid,
        g_VehicleData[vehicleid][DamagePanels],
        g_VehicleData[vehicleid][DamageDoors],
        g_VehicleData[vehicleid][DamageLights],
        g_VehicleData[vehicleid][DamageTires]
    );
   
    g_VehicleData[vehicleid][RePosition] = true;
   
    SetVehicleToRespawn(vehicleid);
}

public OnUnoccupiedVehicleUpdate(vehicleid, playerid, passenger_seat) {
    if (g_VehicleData[vehicleid][Monitor]) {
        UpdateMonitoring(vehicleid);
    }
   
    return 1;
}



Re: Distance bug fix - Darius - 18.07.2013

Thanks alot Slice, this has been a real pain in the neck for us DMers having to deal with this all the time, not being able to use normal vehicles due to some bizarre bug.


Re: Distance bug fix - WhaTJr - 18.07.2013

nice1 senior muy bueno


Re: Distance bug fix - Whitetiger - 18.07.2013

can't this just be fixed (I think - just a theory) wiith just a few SetPlayerPos's when exiting the vehicle? why respawn the vehicle? put player in a bike after exiting car, etc.. can't it be fixed without destroying the vehicle?


Re: Distance bug fix - Slice - 18.07.2013

The vehicle has to be destroyed in the client (streamed out, deleted, respawned). Quickly putting the player in a bike would fix it, but that would be annoying if you're jumping out and running away for example.

One other possible solution would be changing the vehicle's virtual world, waiting for it to stream out, then changing it back. Now that I think of it that would be a better solution. It would require a low streaming rate, however.