16.07.2013, 22:29
(
Последний раз редактировалось Slice; 18.07.2013 в 00:17.
)
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:
F0rce helped develop this (sssssssss).
The code:
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:
- You must set the vehicle's color again in OnVehicleSpawn.
- You must add vehicle components again in OnVehicleSpawn.
- Vehicles that end up in the water will not be respawned (due to OnVehicleDeath being called). You could respawn or destroy it in OnVehicleDeath.
- The fix will not be applied until all players leave the vehicle.
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;
}