Looping through victims for zombie
#1

Well, I've this function to get the player within the range of zombie. Today I was with my friend and all the zombies were after him and ignored me, so I thought that the loop is taking the player which comes in it on first that means if there are more than 1 player near the zombies, it won't get the other players. So I'm thinking something like to get the ids of the players near the zombies and return a random id from those player ids for the zombie. But I got no idea how would I make that.

PHP Code:
for(new playerid 0playerid MAX_PLAYERSplayerid++)
    {
        if(!
IsPlayerNPC(playerid) && IsPlayerConnected(playerid))
        {
            new 
Float:xFloat:yFloat:z;
            
FCNPC_GetPosition(npcidxyz);
            if(
IsPlayerInRangeOfPoint(playeridGetVictimDetectRange[playerid], xyz) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && GetPlayerInterior(playerid) == && GetPlayerVirtualWorld(playerid) == 0)
            {
                return 
playerid;
            }
        }
    } 
EDIT: At the moment, I made this, if I look it at it, the code looks pretty bad and unoptimized, so I gotta find a better way, help me.
PHP Code:
new ids[MAX_PLAYERS],i=0;
    for(new 
playerid 0playerid MAX_PLAYERSplayerid++)
    {
        if(!
IsPlayerNPC(playerid) && IsPlayerConnected(playerid))
        {
            new 
Float:xFloat:yFloat:z;
            
FCNPC_GetPosition(npcidxyz);
            if(
IsPlayerInRangeOfPoint(playeridGetVictimDetectRange[playerid], xyz) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && GetPlayerInterior(playerid) == && GetPlayerVirtualWorld(playerid) == 0)
            {
                
ids[i] = playerid;
                
i++;
            }
        }
    }
    if(
!= 0)
    {
        return 
ids[random(i)];
    }
    return 
INVALID_PLAYER_ID
Reply
#2

Modified version of this: http://forum.sa-mp.com/showpost.php?...50&postcount=2

pawn Code:
new Float:x, Float:y, Float:z;
FCNPC_GetPosition(npcid, x, y, z);    

new Float:minDist = 9999.9; // I guess you don't have FLOAT_INFINITY
new id = INVALID_PLAYER_ID;

for(new playerid = 0; playerid < MAX_PLAYERS; playerid++)
{
    if(!IsPlayerNPC(playerid) && IsPlayerConnected(playerid) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && GetPlayerInterior(playerid) == 0 && GetPlayerVirtualWorld(playerid) == 0)
    {
        new Float:dist = GetPlayerDistanceFromPoint(playerid, x, y, z);

        if(dist < minDist && dist < GetVictimDetectRange[playerid])
        {
            minDist = dist;
            id = playerid;
        }
    }
}

if (id != INVALID_PLAYER_ID) {
    // Here's your closest player id, otherwise none found in range
}
Edit: oh, you want random not closest, your attempt is good, will check in a sec
Reply
#3

Quote:
Originally Posted by Misiur
View Post
Modified version of this: http://forum.sa-mp.com/showpost.php?...50&postcount=2

pawn Code:
new Float:x, Float:y, Float:z;
FCNPC_GetPosition(npcid, x, y, z);    

new Float:minDist = 9999.9; // I guess you don't have FLOAT_INFINITY
new id = INVALID_PLAYER_ID;

for(new playerid = 0; playerid < MAX_PLAYERS; playerid++)
{
    if(!IsPlayerNPC(playerid) && IsPlayerConnected(playerid) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && GetPlayerInterior(playerid) == 0 && GetPlayerVirtualWorld(playerid) == 0)
    {
        new Float:dist = GetPlayerDistanceFromPoint(playerid, x, y, z);

        if(dist < minDist && dist < GetVictimDetectRange[playerid])
        {
            minDist = dist;
            id = playerid;
        }
    }
}

if (id != INVALID_PLAYER_ID) {
    // Here's your closest player id, otherwise none found in range
}
Edit: oh, you want random not closest, your attempt is good, will check in a sec
I'm working to make it like this. For example: Suppose there are 5 players near zombies all are near to them at equal distance, so the function will make a random of those 5 player's playerid for zombie as a victim and if there is only one player then thats simple just return his id.
Reply
#4

Your code is good. All I would improve, would be getting the NPC/Zombie position once, not on every iteration.
pawn Code:
new ids[MAX_PLAYERS], count = 0;
new Float:x, Float:y, Float:z;
FCNPC_GetPosition(npcid, x, y, z);

for(new playerid = 0; playerid < MAX_PLAYERS; playerid++)
{
    if(!IsPlayerNPC(playerid) && IsPlayerConnected(playerid))
    {
        if(IsPlayerInRangeOfPoint(playerid, GetVictimDetectRange[playerid], x, y, z) && GetPlayerState(playerid) == PLAYER_STATE_ONFOOT && GetPlayerInterior(playerid) == 0 && GetPlayerVirtualWorld(playerid) == 0)
        {
            ids[count] = playerid;
            count++;
        }
    }
}
if(count != 0)
{
    return ids[random(count)];
}

return INVALID_PLAYER_ID;
Other problem you might run into is how often you run this, it might make the zombie twitch between each player
Reply
#5

Thanks for helping out.
Reply
#6

Well, it's taking around 3-4 seconds for the zombies to identify the player id near them and that's a too much delay
Reply
#7

Hm, can you dump a bunch of prints here and there and posting the results?
Reply
#8

Quote:
Originally Posted by Misiur
View Post
Hm, can you dump a bunch of prints here and there and posting the results?
Well I debugged the loop, the time taken in the starting and ending of it is same but I check for collisions and water detection before moving the zombie maybe that's causing the delay?
Reply
#9

I think so, only way to be sure is to time it as well.
Reply
#10

Simple random player in range and if npc see player.
PHP Code:
stock GetTarget(npcid){
    new 
Float:xFloat:yFloat:zFloat:anglepstate,
        
pool_players[MAX_PLAYERS], pool_upp = -1;
    
    
FCNPC_GetPosition(npcid,x,y,z);
    
angle FCNPC_GetAngle(npcid);
    
Tryg3D::Foreach(i){
        
pstate GetPlayerState(i);
        if(
GetElementsDistance(i,item_player,npcid,item_fcnpc) <= 300.0 && GetPlayerInterior(i) == && GetPlayerVirtualWorld(i) == 0){
            if(
pstate != PLAYER_STATE_SPECTATING && pstate != PLAYER_STATE_WASTED){
                if(
IsElementOnFakeScreen(x,y,z,i,item_player,0.0,angle)){ //for vehicle collision: .veh_col=true
                    
pool_upp++;
                    
pool_players[pool_upp] = i;
                }
            }
        }
    }
    
    if(
pool_upp == -1) return INVALID_PLAYER_ID;
    return 
pool_players[random(pool_upp+1)];

Libs:
3DTryg
Reply


Forum Jump:


Users browsing this thread: 4 Guest(s)