PDA

View Full Version : Detect Vehicle HP


arjanforgames
21/07/2013, 07:31 PM
I have:

public OnPlayerUpdate(playerid)
{
if(IsPlayerInAnyVehicle(playerid))
{
new Float:health;
new vehid = GetPlayerVehicleID(playerid);
GetVehicleHealth(vehid, health);
if(health <= 500)
{
SendClientMessage(playerid, -1, "BROKEN");
}
}
return 1;
}

I think it's under the wrong callback put the point is it keeps spamming "BROKEN". I understand why I does spamm but I don't know where I need to put it so its working fine.
It should say "BROKEN" when the vehicle health is 500 or lower.

Boolean
21/07/2013, 07:39 PM
It keeps sending the message because the health stays below 500. If you want it to send one message you'll have to use another variable. For example:

public OnPlayerUpdate(playerid)
{
if(IsPlayerInAnyVehicle(playerid))
{
new Float:health;
new vehid = GetPlayerVehicleID(playerid);
new message = GetPVarInt(playerid, "Message");
GetVehicleHealth(vehid, health);
if(health <= 500 && message == 0) // Checks if we didn't receive a message yet
{
SendClientMessage(playerid, -1, "BROKEN");
SetPVarInt(playerid, "Message", 1); // Message sent
}
}
return 1;
}

Pottus
21/07/2013, 07:59 PM
It keeps sending the message because the health stays below 500. If you want it to send one message you'll have to use another variable. For example:

public OnPlayerUpdate(playerid)
{
if(IsPlayerInAnyVehicle(playerid))
{
new Float:health;
new vehid = GetPlayerVehicleID(playerid);
new message = GetPVarInt(playerid, "Message");
GetVehicleHealth(vehid, health);
if(health <= 500 && message == 0) // Checks if we didn't receive a message yet
{
SendClientMessage(playerid, -1, "BROKEN");
SetPVarInt(playerid, "Message", 1); // Message sent
}
}
return 1;
}

That is not really a good way to do it, you should make a vehicle enum and variable to keep track of a vehicles status (If you have more than one associated variable of course).

Do this.

Note: vModel has no purpose except to demonstrate enum usage.

// Timer interval for vehicle update
#define VEHICLE_UPDATE_TIME 1000

// Amount before car is broken
#define VEHICLE_BROKEN_DAMAGE 500

// Current car status
#define STATUS_WORKING 0
#define STATUS_BROKEN 1

// Vehicle enum data
enum VINFO
{
vModel,
vStatus,
}

// Vehicle data
new gVehicleData[MAX_VEHICHLES][VINFO];

// Start the update timer
public OnGameModeInit()
{
SetTimer("VUpdate", VEHICLE_UPDATE_TIME, true);
return 1;
}

// update vehicles
forward VUpdate();
public VUpdate()
{
// We only need to check if players online are the driver (requires foreach() include otherwise use a MAX_PLAYER loop / IsPlayerConnected();
foreach(new i : Player)
{
// Player is was not the driver skip iteration
if(GetPlayerVehicleSeat(i) != 0) continue;

// Get the vehicleid of the car
new vid = GetPlayerVehicleID(i);

// Is it broken? skip iteration
if(gVehicleData[vid][vStatus] == STATUS_BROKEN) continue;

// Lets check the health now
new Float:hp;
GetVehicleHealth(vid , hp);

// Health too low? set to broken status message player
if(hp <= VEHICLE_BROKEN_DAMAGE)
{
gVehicleData[vid][vStatus] = STATUS_BROKEN;
SendClientMessage(playerid, -1, "BROKEN");
}
}
}

// When a vehicle respawns set the status to working
public OnVehicleSpawn(vehicleid)
{
gVehicleData[vid][vStatus] = STATUS_WORKING;
return 1;
}

That is probably the best way to do it maybe not the fastest OnPlayerStateChange() http://wiki.sa-mp.com/wiki/OnPlayerStateChange could be used with a custom iterator but it just seems you'd probably have a higher potential for something to go wrong during a packet loss event.