IsPlayerInRangePoint Help.... +Rep -
kesarthakur - 12.04.2015
Hey guys
i made a command which creates object at playerspos when he use a specific command
and i want to make that if any player approaches near the object it should send them a clientmessage for that i think i should use IsPlayerInRangePoint under OnPlayerUpdate but how to make this for all the objects that are created in the server
Please Help me
Thanks in Advance
Edit: After showing client message and exploding the object will be destroyed so the pos should be removed from the loop
is it possible??
Re: IsPlayerInRangePoint Help.... +Rep -
Gammix - 12.04.2015
1) Use arrays for storing object position. For example:
pawn Код:
enum objectsenum
{
Float:ox,
Float:oy,
Float:oz
}
new Objects[MAX_OBJECTS][objectsenum];
MAX_OBJECTS can be your own value too.
Now when you create a object, just save the coords of position of object while creating. For example:
pawn Код:
CreateObject(model, X, Y, Z, rX, rY, r)
Objects[i][ox] = X, Objects[i][oy] = Y, Objects[i][oz] = Z;
You can also hook CeateObject.
Now onplayerupdate, i don't recommend onplayerupdate though.
pawn Код:
public OnPlayerUpdate(playerid)
{
for(new i; i < MAX_OBJECTS; i++)
{
if(IsValidObject(i))
{
if(IsPlayerInRangeOfPoint(playerid, 5.0, Objects[i][ox], Objects[i][oy], Objects[i][oz]))
{
SendClientMessage(playerid, -1, "your msg");
}
}
}
return 1;
}
Re: IsPlayerInRangePoint Help.... +Rep -
kesarthakur - 12.04.2015
Quote:
Originally Posted by Gammix
1) Use arrays for storing object position. For example:
pawn Код:
enum objectsenum { Float:ox, Float:oy, Float:oz } new Objects[MAX_OBJECTS][objectsenum];
MAX_OBJECTS can be your own value too.
Now when you create a object, just save the coords of position of object while creating. For example:
pawn Код:
CreateObject(model, X, Y, Z, rX, rY, r) Objects[i][ox] = X, Objects[i][oy] = Y, Objects[i][oz] = Z;
You can also hook CeateObject.
Now onplayerupdate, i don't recommend onplayerupdate though.
pawn Код:
public OnPlayerUpdate(playerid) { for(new i; i < MAX_OBJECTS; i++) { if(IsValidObject(i)) { if(IsPlayerInRangeOfPoint(playerid, 5.0, Objects[i][ox], Objects[i][oy], Objects[i][oz])) { SendClientMessage(playerid, -1, "your msg"); } } } return 1; }
|
I think this will work only for one object
i want it to work for all the created objects
and what you recommend otherthan onplayerupdate?
Re: IsPlayerInRangePoint Help.... +Rep -
Crayder - 12.04.2015
I think you should just attach labels to each object. This is way more efficient and they are streamed (which is what you want your message to do).
EDIT: No his version will not just be for one object, that's what the loop (which is very un-efficient but is the only way to stream the messages) is for.
Re: IsPlayerInRangePoint Help.... +Rep -
kesarthakur - 12.04.2015
Quote:
Originally Posted by Crayder
I think you should just attach labels to each object. This is way more efficient and they are streamed (which is what you want your message to do).
|
They not only sendclientmessage but also explodes thats the reason i want it
Edit: After showing client message and exploding the object will be destroyed so the pos should be reomved from the loop
is it possible??
Re: IsPlayerInRangePoint Help.... +Rep -
Crayder - 12.04.2015
Quote:
Originally Posted by kesarthakur
They not only sendclientmessage but also explodes thats the reason i want it
Edit: After showing client message and exploding the object will be destroyed so the pos should be reomved from the loop
is it possible??
|
1. You should use y_iterate at the least (add only objects you want to explode).
2. You have to destroy the object yourself, an explosion won't do so for you.
3. An object will no longer be in the loop if it is destroyed so the position will not need to be removed.
Re: IsPlayerInRangePoint Help.... +Rep -
Gammix - 12.04.2015
My method will work for all objects you created and having position stored in the array. I missed a check just add this:
pawn Код:
public OnPlayerUpdate(playerid)
{
for(new i; i < MAX_OBJECTS; i++)
{
if(IsValidObject(i) && Objects[i][ox] != 0.0 && Objects[i][oy] != 0.0 && Objects[i][oz] != 0.0)
{
if(IsPlayerInRangeOfPoint(playerid, 5.0, Objects[i][ox], Objects[i][oy], Objects[i][oz]))
{
SendClientMessage(playerid, -1, "your msg");
}
}
}
return 1;
}
Rather than OnPlayerUpdate, use a timer or make use of a custom callback based on player position updating(best way).
Re: IsPlayerInRangePoint Help.... +Rep -
Crayder - 12.04.2015
Again, it is still way more efficient to use y_iterate. I'll give an example (some snips of my old proximity mine script) in a sec (done).
Код:
#include <a_samp>
#include <sscanf>
#include <YSI\y_commands> // Or ZCMD. This system is compatible with both (as is all other scripts using ZCMD).
#include <YSI\y_iterate>
#define MAX_PROX 5 //Change to your liking.
new Iterator:Proximeter[MAX_PLAYERS]<MAX_OBJECTS>, bool:Active[MAX_OBJECTS];
CMD:prox(playerid, params[])
{
if(Iter_Count(Proximeter[playerid]) == MAX_PROX)
return SendClientMessage(playerid, -1, "You can't have more than 5 Proximity Mines planted.");
new time;
if(sscanf(params, "i", time))
return SendClientMessage(playerid, COLOR_ERROR, "[Command] Error: /Prox <time before activation>");
else if(5 > time > 30)
return SendClientMessage(playerid, COLOR_ERROR, "[Command] Error: The timer can only be set between 5 and 30 seconds.");
else
{
GetPlayerPos(playerid, nx, ny, z);
new id = CreateObject(19602, nx, ny, nz, rx, ry, rz);
Iter_Add(Proximeter[playerid], id);
Active[id] = false;
SetTimerEx("AddProx", time*1000, false, "i", id);
return SendClientMessage(playerid, -1, sprintf("You now have %i Proximity Mine(s) planted.", Iter_Count(Proximeter[playerid])));
}
}
forward AddProx(proxid); public AddProx(proxid)
{
SetObjectMaterial(proxid, 0, -1, "none", "none", 0xFFFF0000); //Turns it red when active, nice touch!
Active[proxid] = true; //Activates the proximeter.
return 1;
}
public OnGameModeInit()
{
Iter_Init(Proximeter);
return 1;
}
public OnPlayerUpdate(playerid)
{
foreach(new p : Player) //if(GetPlayerTeam(p) != GetPlayerTeam(playerid))// Remove this comment if you want to check the teams.
foreach(new m : Proximeter[p]) if(Active[m])
{
new Float:P[3];
GetObjectPos(m, P[0], P[1], P[2]);
if(IsPlayerInRangeOfPoint(playerid, 10.0, P[0], P[1], P[2]))
{
Iter_Remove(Proximeter[p], m);
DestroyObject(m);
CreateExplosion(P[0], P[1], P[2], 6, 10.0);
}
}
return 1;
}
Features:
- Sly use of y_iterate for object handling.
- Efficient foreach (aka y_iterate) loops, the loop will not even go on if the mines do not exist.
- Command with time to run away, used to activate the mines.
- Mines are green when inactive, but turn red when they are active.
- Explosions (because you said you like explosions ofc).
@Gammix, I'm not against your method at all, just pointing out the better efficiency of this method.
Re: IsPlayerInRangePoint Help.... +Rep -
kesarthakur - 12.04.2015
Thank you both
+repped