Player position check
#1

I have code, that checks player position. If player after 30 sec in the same position, the text is appears. How to do, that if player after 30 sec. went away for 1-2 meters also got that text? I tried to use IsPlayerInRangeOfPoint, but thet after every 30 sec. I got that text.

Код:
new Float:AFK_X[MAX_PLAYERS], Float:AFK_Y[MAX_PLAYERS], Float:AFK_Z[MAX_PLAYERS];  

forward UpdatePlayer(playerid);
public UpdatePlayer(playerid)
{
           new Float:x[MAX_PLAYERS], Float:y[MAX_PLAYERS], Float:z[MAX_PLAYERS];
           GetPlayerPos(playerid, x[playerid], y[playerid], z[playerid]);
           if(x[playerid] == AFK_X[playerid] || y[playerid] == AFK_Y[playerid] || z[playerid] == AFK_Z[playerid])
           {
        SetPVarInt(playerid, "AFK", GetPVarInt(playerid, "AFK")+1);
        if(GetPVarInt(playerid, "AFK") > 30)
        {
             new stroka[20];
             format(stroka, 20, "AFK: %d sec", GetPVarInt(playerid, "AFK"));
            SetPlayerChatBubble(playerid, stroka, -1, 20.0, 1100);
        }
            }
            if(x[playerid] != AFK_X[playerid] || y[playerid] != AFK_Y[playerid] || z[playerid] != AFK_Z[playerid])
            {
                 if(GetPVarInt(playerid, "AFK") > 0) return SetPVarInt(playerid, "AFK", 0);
                 GetPlayerPos(playerid, AFK_X[playerid], AFK_Y[playerid], AFK_Z[playerid]);
            }
     return 1;
}
Reply
#2

Your code is... terribly formatted and it hurts my eyes to read it... you should consider taking more use of macro definitions, enumerators and generally naming your variables to a position where it's understandable to say

"oh, I wonder what this variable holds for data... 'playerIdlePositions' - oh! it must be holding the positions of the players positions where they've been marked to be idling!"


PHP код:
#define PLAYER_IDLE_MOVE_RANGE    (3.0)
#define PLAYER_IDLE_LABEL_RANGE   (20.0)
#define MAX_PLAYER_IDLE           (30)
enum COORDINATION {
  
Float:BREADTH,
  
Float:HEIGHT,
  
Float:DEPTH
}
new 
playerIdlePositions[MAX_PLAYERS+1][COORDINATION];
forward public OnPlayerIdleCheck(playerid);
public 
OnPlayerIdleCheck(playerid) {
  new 
pedPosition[COORDINATION];
  
  
GetPlayerPos(playeridpedPosition[BREADTH], pedPosition[HEIGHT], pedPosition[DEPTH]);
  if(
IsPlayerInRangeOfPoint(playeridPLAYER_IDLE_MOVE_RANGEplayerIdlePositions[playerid][BREADTH], playerIdlePositions[playerid][HEIGHT], playerIdlePositions[playerid][DEPTH])) {
    new 
idleTime GetPVarInt(playerid"AFK")+1;
    
SetPVarInt(playerid"AFK"idleTime);
    
    if(
idleTime MAX_PLAYER_IDLE) {
      new 
stroka[9+11+1]; // 9 = AFK:  sec, 11 = integer, 1 = \0
      
format(stroka20"AFK: %d sec"idleTime);
      
SetPlayerChatBubble(playeridstroka, -1PLAYER_IDLE_LABEL_RANGE1100);
    }
  }
  else {
    if(
GetPVarInt(playerid"AFK") > 0)
      return 
SetPVarInt(playerid"AFK"0);
    
    
GetPlayerPos(playeridplayerIdlePositions[playerid][BREADTH], playerIdlePositions[playerid][HEIGHT], playerIdlePositions[playerid][DEPTH]);
  }
  return 
1;

To add on to this 'feature' overall: I wouldn't be too safe to use this kind of method to detect if a player is idling for thirty seconds. When I'm playing on for say a role play server, I usually don't move around for up to 15 minutes because I might just like to spectate scenarios and so on. I'm not sure what kind of game mode you're running, but it's just a friendly tip! Good luck.
Reply
#3

Код:
new Float:AfkPos[MAX_PLAYERS][3];
new Float:GPos[3];

SetTimer("CheckAFK",5000,true);

function CheckAFK()
{
	GetPlayerPos(i, GPos[0],GPos[1],GPos[2]);
	if(AfkPos[i][0] == GPos[0] && AfkPos[i][1] == GPos[1] && AfkPos[i][2] == GPos[2]) AFKTime[i] += 5;
	else
	{
		if(AFKTime[i] == 30) //Player is not moving for 30 seconds.. also don't forget to add 'return 1;' in the end
   		GetPlayerPos(i, AfkPos[i][0], AfkPos[i][1], AfkPos[i][2]);
	}
	return 1;
}
Also there is a way to detect if a player pressed ESC or minimized his game
Reply
#4

Quote:
Originally Posted by NeXTGoD
Посмотреть сообщение
Код:
new Float:AfkPos[MAX_PLAYERS][3];
new Float:GPos[4];

SetTimer("CheckAFK",5000,true);

function CheckAFK()
{
	GetPlayerPos(i, GPos[0],GPos[1],GPos[2]);
	if(AfkPos[i][0] == GPos[0] && AfkPos[i][1] == GPos[1] && AfkPos[i][2] == GPos[2]) AFKTime[i] += 5;
	else
	{
		if(AFKTime[i] == 30) //Player is not moving for 30 seconds.. also don't forget to add 'return 1;' in the end
   		GetPlayerPos(i, AfkPos[i][0], AfkPos[i][1], AfkPos[i][2]);
	}
	return 1;
}
Also there is a way to detect if a player pressed ESC or minimized his game
Do not use this code. Not only will this not work since this is a clear copy and paste, but also, this is very unoptimized and... just terrible in general.


Quote:

Also there is a way to detect if a player pressed ESC or minimized his game

There is not. There is however a possibility to detect when the server has stopped receiving packets from the client, but the client is still connected, might be what you refer to.
Reply
#5

Quote:
Originally Posted by DBZdabIt3Bro7
Посмотреть сообщение
Do not use this code. Not only will this not work since this is a clear copy and paste, but also, this is very unoptimized and... just terrible in general.



There is not. There is however a possibility to detect when the server has stopped receiving packets from the client, but the client is still connected, might be what you refer to.
Well this code untested but there is a way and by using OnPlayerUpdate ( :
Reply
#6

Quote:
Originally Posted by NeXTGoD
Посмотреть сообщение
Well this code untested but there is a way and by using OnPlayerUpdate ( :
I'm gonna repeat myself, check your facts.
Reply
#7

Quote:
Originally Posted by DBZdabIt3Bro7
Посмотреть сообщение
I'm gonna repeat myself, check your facts.
I'm currently using this and no bugs at all, maybe when a player reaches over 300 ping it may detect him as 'pauser' so you can increase the time check for avoiding that
Reply
#8

Hey man, it works great, but I have one question.

Код:
new playerIdlePositions[MAX_PLAYERS+1][COORDINATION];
Why here MAX_PLAYERS+1? What means that +1?
Reply
#9

Quote:
Originally Posted by ,TomY'
Посмотреть сообщение
Hey man, it works great, but I have one question.

Код:
new playerIdlePositions[MAX_PLAYERS+1][COORDINATION];
Why here MAX_PLAYERS+1? What means that +1?
I prefer to add an empty index to be able to reset the values when a player for i.e. connects.

PHP код:
public OnPlayerConnect(playerid) {
    
playerIdlePositions[playerid] = playerIdlePositions[MAX_PLAYERS];
    
// also valid:
    
playerIdlePositions[playerid] = EOS;
    return 
1;

Reply
#10

After OnPlayerConnet I should write this code to reset values?

Код:
playerIdlePositions[playerid] = playerIdlePositions[MAX_PLAYERS];
How about this line, because after OnPlayerConnet you writed 2 lines.

Код:
playerIdlePositions[playerid] = EOS;
Or this line the same like first? I need to add 2 times, or just one?

Also, if I need this. As I see, this code nothing checks.

Код:
new pedPosition[COORDINATION]; 
   
  GetPlayerPos(playerid, pedPosition[BREADTH], pedPosition[HEIGHT], pedPosition[DEPTH]);
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)