Заказать игровой сервер Контакты (заказать плагин/исправить ошибки/другое) Пожертвовать Поиск

[ вход ]
[ последние сообщения ]

  • Страница 1 из 1
  • 1
Найти игроков на нужной дистанции
polo79655 Дата: Пятница, 01.05.2020, 11:26:57 | Сообщение # 1
Сообщений: 99
Репутация: -1 [ +/- ]
Всем привет. Мне нужна функция, чтобы найти игроков на определенном расстоянии. Но так, чтобы она не игнорировала стены и пропы, то есть если между игроками есть что-то, то тогда нужно исключить данного игрока из поиска.

Я использовал эту функцию из плагина для турели, которая находит ближайшего игрока:
Код
stock FindFirstTargetInRange(client, Float:vAngle[3], Float:vEntPosition[3], Float:entHeight = 60.0)
{
    new Float:vClientPosition[3];
    
    GetEntPropVector(client, Prop_Send, "m_vecOrigin", vEntPosition);
    vEntPosition[2] += entHeight;
    
    new Float:fDistance[MAXPLAYERS + 1];
    new iTager[MAXPLAYERS + 1];
    new numb = 0;
    for (new i = 1; i <= MaxClients; i++)
    {
  if (IsClientConnected(i) && IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(client) != GetClientTeam(i))
  {
   GetClientEyePosition(i, vClientPosition);
   fDistance[numb] = GetVectorDistance(vClientPosition, vEntPosition, false);
   if(fDistance[numb] <= 9000000 && fDistance[numb] > 50)
   {
    iTager[numb] = i;
    numb++;    
   }
  }
    }
    
    new zombie = GetZombieMinDistance(iTager, fDistance, numb+1);
    if(zombie < 1 || !IsClientInGame(zombie) || !IsPlayerAlive(zombie))
    {
  return (-1);
    }
    
    GetClientEyePosition(zombie, vClientPosition);
    vClientPosition[2] -= 10.0;
    MakeVectorFromPoints(vEntPosition, vClientPosition, vAngle);
    vClientPosition[2] += 10.0;
    //NormalizeVector(vAngle, vAngle);
    GetVectorAngles(vAngle, vAngle);
    
    new Handle:trace = TR_TraceRayFilterEx(vEntPosition, vClientPosition, MASK_SHOT, RayType_EndPoint, TraceASDF, client);
    if(!TR_DidHit(trace))
    {
  CloseHandle(trace);
  return (zombie);
    }
    CloseHandle(trace);
    return (-1);
}

GetZombieMinDistance(clients[], Float:distance[], max_clients)
{
    if(max_clients < 1)
    {
  return -1;
    }
    new Float:min_distance = 999999999.0;
    new zombie = -1;
    for(new i = 0; i < max_clients; i++)
    {
  // 999999999   >  10000000
  if(min_distance > distance[i])
  {
   if(distance[i] <= 9000000009 && distance[i] > 50)
   {
    min_distance = distance[i];
    zombie = clients[i];    
   }
  }
    }
    return zombie;
}

public bool:TraceASDF(entity, mask, any:data)
{
    return (data != entity);
}


Но она очень плохо работает, зачастую не видит игрока в упор, даже если между ними ничего нет. Не подскажите, как можно сделать нормальную функцию? Заранее спаибо prikol
 
Sedge Дата: Понедельник, 04.05.2020, 08:09:37 | Сообщение # 2
Сообщений: 16
Репутация: 9 [ +/- ]
Просто используй на свою энти SDKHook(ent, SDKHook_SetTransmit, Hook_Ragdoll); и в нем уже делай определения радиуса что-то вроде этого:

Код
public Action:Hook_Ragdoll(entity, client)
{
  if (entcontrol[entity] > 0)
  {
    new Float:pos1[3];
    new Float:pos2[3];
    GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos1);
    GetEntPropVector(client, Prop_Send, "m_vecOrigin", pos2);
    if ((GetVectorDistance(pos1, pos2) < g_spwn[entcontrol[entity]]))
    {
       SetEntityMoveType(entity, MOVETYPE_FLY);
    }
  }
}

 
polo79655 Дата: Вторник, 12.05.2020, 10:40:59 | Сообщение # 3
Сообщений: 99
Репутация: -1 [ +/- ]
Цитата Sedge ()
Просто используй на свою энти SDKHook(ent, SDKHook_SetTransmit, Hook_Ragdoll); и в нем уже делай определения радиуса что-то вроде этого:

Код
public Action:Hook_Ragdoll(entity, client)
{
  if (entcontrol[entity] > 0)
  {
    new Float:pos1[3];
    new Float:pos2[3];
    GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos1);
    GetEntPropVector(client, Prop_Send, "m_vecOrigin", pos2);
    if ((GetVectorDistance(pos1, pos2) < g_spwn[entcontrol[entity]]))
    {
       SetEntityMoveType(entity, MOVETYPE_FLY);
    }
  }
}


Спасибо. Я не проверял ещё, потому что смог сделать другую функцию, которая более менее работает. Сразу говорю, это говно код, но как умею)))
Код
FindAllTargets(client, players[])
{
    new Float:vAngle[3],Float:vClientPosition[3],Float:vEntPositionIgroks[3];
    for (new i = 1; i <= MaxClients; i++)
    {
  players[i] = -1;
    }
    new Handle:trace;
    for (new igroks = 1; igroks <= MaxClients; igroks++)
    {
  if (!IsClientConnected(igroks) || !IsClientInGame(igroks) || !IsPlayerAlive(igroks) || players[igroks] == 1)
  {
   continue;
  }
  for (new j = 0; j<=9; j++)
  {
   if (players[igroks] == 1)
   {
    break;
   }
   GetClientEyePosition(igroks, vEntPositionIgroks);
   if (j == 0)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
   }
   else if (j == 1)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 30;
   }
   else if (j == 2)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 45;
    vEntPositionIgroks[1] -= 30;
    vEntPositionIgroks[0] += 30;
   }
   else if (j == 3)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 45;
    vEntPositionIgroks[1] += 30;
    vEntPositionIgroks[0] -= 30;
   }
   else if (j == 4)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 45;
    vEntPositionIgroks[1] += 30;
    vEntPositionIgroks[0] += 30;
   }
   else if (j == 5)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 45;
    vEntPositionIgroks[1] -= 30;
    vEntPositionIgroks[0] += 30;
   }
   else if (j == 6)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 25;
    vEntPositionIgroks[1] -= 30;
    vEntPositionIgroks[0] -= 30;
   }
   else if (j == 7)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 25;
    vEntPositionIgroks[1] += 30;
    vEntPositionIgroks[0] -= 30;
   }
   else if (j == 8)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 25;
    vEntPositionIgroks[1] += 30;
    vEntPositionIgroks[0] += 30;
   }
   else if (j == 9)
   {
    GetClientEyePosition(igroks, vEntPositionIgroks);
    vEntPositionIgroks[2] -= 25;
    vEntPositionIgroks[1] -= 30;
    vEntPositionIgroks[0] += 30;
   }
   for (new i = 0; i <= 9; i++)
   {
    if (i == 0)
    {
     GetClientEyePosition(client, vClientPosition);
    }
    else if (i == 1)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 30;
    }
    else if (i == 2)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 45;
     vClientPosition[1] -= 30;
     vClientPosition[0] += 30;
    }
    else if (i == 3)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 45;
     vClientPosition[1] += 30;
     vClientPosition[0] -= 30;
    }
    else if (i == 4)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 45;
     vClientPosition[1] += 30;
     vClientPosition[0] += 30;
    }
    else if (i == 5)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 45;
     vClientPosition[1] -= 30;
     vClientPosition[0] += 30;
    }
    else if (i == 6)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 25;
     vClientPosition[1] -= 30;
     vClientPosition[0] -= 30;
    }
    else if (i == 7)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 25;
     vClientPosition[1] += 30;
     vClientPosition[0] -= 30;
    }
    else if (i == 8)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 25;
     vClientPosition[1] += 30;
     vClientPosition[0] += 30;
    }
    else if (i == 9)
    {
     GetClientEyePosition(client, vClientPosition);
     vClientPosition[2] -= 25;
     vClientPosition[1] -= 30;
     vClientPosition[0] += 30;
    }
    vClientPosition[2] -= 10.0;
    MakeVectorFromPoints(vEntPositionIgroks, vClientPosition, vAngle);
    vClientPosition[2] += 10.0;
    NormalizeVector(vAngle, vAngle);
    GetVectorAngles(vAngle, vAngle);
    trace = TR_TraceRayFilterEx(vEntPositionIgroks, vClientPosition, MASK_SHOT, RayType_EndPoint, TraceASDF, client);
    if(!TR_DidHit(trace))
    {
     players[igroks] = 1;
     CloseHandle(trace);
     break;
    }
    CloseHandle(trace);
   }
  }
    }
}
 
tonline_kms65 Дата: Вторник, 09.06.2020, 03:45:09 | Сообщение # 4
Сообщений: 215
Репутация: 3 [ +/- ]
Ничего бредовее ещё не встречал. Что у тебя с мыслями? Как, будучи в здравом уме, такое придумать возможно?
Или что нужно употребить, что бы такое изобрести, а главное зачем?
==============================================
Как-то грубовато получилось. Исправляюсь.

Объясню на словах(код давать не буду) как это делается:

-для начала получим мах. размеры коробки(карты), это делать, естественно, один раз на всю карту.
-циклом ищем всех игроков которые в игре и живые(отсеивать можно по командам или по дистанции)
-самый интересный момент - нужно сравнить дистанцию от игрока до максимального размера карты(коробки), у какого игрока дистанция меньше тот и есть искомый-ближайший, это будет дистанция на которой есть ближайший игрок(пока без учета препятствий). Эту дистанцию, обязательно!, делаем след. дистанцией заместо размеров коробки(карты), так сказать, каждый тик уменьшаем радиус поиска игроков.
-делаем трассировку к ближайшему игроку, что бы определить за препятствием игрок или нет, если за препятствием - цикл дальше, если игрок в зоне видимости - это цель. Нужно сделать еще возможность радиуса обзора, иначе беда(на затылке глаз не бывает) но это уже отдельная и достаточно сложная тема, знания математики приветствуются.

Безупречная работа кода обеспечена.


Сообщение отредактировал tonline_kms65 - Суббота, 18.09.2021, 08:51:24
 
  • Страница 1 из 1
  • 1
Поиск: