[CS:GO - CSS ] Дистанция между игроками

Max Rhine

Участник
Сообщения
176
Реакции
30
Всем доброго времени суток. Кратко обо мне :Оффтоп

Теперь к делу - на днях, нужно было сделать проверку дистанции между игроками. Нашёл 2 примера, переписал под свои нужды. В итоге - плагин скомпилировался без ошибок, а условие работало не корректно.

Первый пример, я взял с античита Little Anti-Cheat.
Быдлокод первой версии:
public Action timer_check_aimlock(Handle timer)
{
    float pos[3], pos2[3];

    for (int i = 1; i <= MaxClients; i++)
    {
        if (!is_player_valid(i) || IsFakeClient(i))
        {
            continue;
        }
        if (!IsPlayerAlive(i) || GetClientTeam(i) < 2)
        {
            continue;
        }   

        GetClientEyePosition(i, pos);

        for (int k = 1; k <= MaxClients; k++)
        {
            if (!is_player_valid(k) || k == i)
            {
                continue;
            }
            
            if (GetClientTeam(k) == GetClientTeam(i))
            {
                continue;
            }

            if (!IsPlayerAlive(k) || GetClientTeam(k) < 2)
            {
                continue;
            }

            GetClientEyePosition(k, pos2);
            if (GetVectorDistance(pos, pos2) < 300.0)
            {
                continue;
            }
        }
    }
}

bool is_player_valid(int client)
{
    return (client >= 1 && client <= MaxClients
        && IsClientConnected(client) && IsClientInGame(client));
}
И
Быдлокод второй версии:
public Action timer_check_aimlock(Handle timer)
{
    float pos[3], pos2[3];

    for (int i = 1; i <= MaxClients; i++)
    {
        if (!is_player_valid(i) || IsFakeClient(i))
        {
            GetClientEyePosition(i, pos);
        }

        for (int k = 1; k <= MaxClients; k++) 
        {
            if (!is_player_valid(k) || k == i)
            {
                GetClientEyePosition(k, pos2);
            }

            if (GetVectorDistance(pos, pos2) < 5.0)
            {
                PrintToChatAll("Близко, условие не работает", client); // тест
            }
            else
            {
                PrintToChatAll("Далеко, условие работает", client);    // тест
            }
        }
    }
}

bool is_player_valid(int client)
{
    return (client >= 1 && client <= MaxClients
        && IsClientConnected(client) && IsClientInGame(client));
}
Отдельно тестировал aimlock в Little Anti-Cheat, проверка дистанции отказывалась работать

Второй пример нашёл на форуме, к сожалению, он отказался работать корректно.
Оригинальный вид:
static const float HULL_SIZES[][]    = {{-2.0, -2.0, -2.0}, {2.0, 2.0, 2.0}}; // 4x4x4

stock int GetAvailableTargets(int client, int targets[], int maxsize)
{
    int i, t, num;
    static float pos[3], eye[3];
    GetClientEyePosition(client, eye);
    for(i = 1, t = GetClientTeam(client); i <= MaxClients && num < maxsize; ++i)
        if(i != client && IsClientInGame(i) && IsPlayerAlive(i) && t != GetClientTeam(i))
        {
            GetClientEyePosition(i, pos);
            // проверяем есть ли препятствия м/у глазами игроков
            TR_TraceHullFilter(eye, pos, HULL_SIZES[0], HULL_SIZES[1], CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_DEBRIS|CONTENTS_HITBOX, DontHitOwnerOrNade, client);
            // если препятствий нет, то заносим в массив
            if(TR_GetEntityIndex() == i) targets[num++] = i;
        }
    return num;
}

Переделка:
    int i, t, num;
    static float pos[3], eye[3];
    GetClientEyePosition(client, eye);
    for(i = 1, t = GetClientTeam(client); i <= MaxClients && num < maxsize; ++i)
        if(i != client && IsClientInGame(i) && IsPlayerAlive(i) && t != GetClientTeam(i))
        {
            GetClientEyePosition(i, pos);
            if (GetVectorDistance(eye, pos) < 5.0)
            {
                PrintToChatAll("Близко, условие не работает", client); // тест
            }
            else
            {
                PrintToChatAll("Далеко, условие работает", client);    // тест
            }
        }
    return num;
В переделке 100% есть ошибки, т.к. сделал на коленке для примера

Вся проблема в том, чтобы сделать рабочую проверку дистанции двух игроков через GetVectorDistance() <= 0.0. Игра : сss v34
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
не может расстояние быть меньше 0
Сообщения автоматически склеены:

высота модельки игрока 60 - 70 юнитов
ширина/глубина - 30 - 35 юнитов
 

Max Rhine

Участник
Сообщения
176
Реакции
30
не может расстояние быть меньше 0
0 написал для примера. А так, нужна проверка дистанции. Если есть лучше идеи, чем GetVectorDistance - где найти этот код?
Prop_Send "m_vecOrigin" не совсем подходит, но если он будет лучше, можно примеры??
Буду очень благодарен.
@Danyas предложил код, а как правильно его реализовать, я не смог...
C-подобный:
GetClientEyePosition(client1, pos1)
GetClientEyePosition(client2, pos2)
Сообщения автоматически склеены:

Для себя нашёл вариант ± подходящий вариант от смака 0.8.6.0, только нужно без event и с GetClientEyePosition двух клиентов

C-подобный:
#define AIM_MIN_DISTANCE    450.0    // Minimum distance acceptable for a detection.

public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    decl String:sWeapon[32], dummy;
    GetEventString(event, "weapon", sWeapon, sizeof(sWeapon));
    
    if (GetTrieValue(g_IgnoreWeapons, sWeapon, dummy))
        return;
        
    new victim = GetClientOfUserId(GetEventInt(event, "userid"));
    new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
    
    if (IS_CLIENT(victim) && IS_CLIENT(attacker) && victim != attacker && IsClientInGame(victim) && IsClientInGame(attacker))
    {
        decl Float:vVictim[3], Float:vAttacker[3];
        GetClientAbsOrigin(victim, vVictim);
        GetClientAbsOrigin(attacker, vAttacker);
        
        if (GetVectorDistance(vVictim, vAttacker) >= AIM_MIN_DISTANCE)
        {
        }
    }
}
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
я не понимаю что ты хочешь получить в результате

если просто расстояние м/у игроками, то можно брать как положение глаз (GetClientEyePosition), так и точку под ногами (GetClientAbsOrigin)
Отличие только в том (если один игрок станет на другого), что в первом случае измеряемое расстояние между игроками будет уменьшаться, когда верхний игрок присядет, а во втором - когда присядет нижний.

Вот так можно вывести в чат расстояние м/у всеми живыми игроками:
C-подобный:
stock void SomeFunction()
{
    for(int i = 1, j; i <= MaxClients; i++) if(IsClientValid(i))
        for(j = i+1; j <= MaxClients; j++) if(IsClientValid(j))
            PrintToChatAll("Distance between %N and %N: %.1f", i, j, GetDistance(i, j, false);    // тут можно выбрать между какими точками измерять расстояние
}

stock float GetDistance(int client, int target, bool eye)
{
    static int pos1[3], pos2[3];
    if(eye)
    {
        GetClientEyePosition(client, pos1);
        GetClientEyePosition(target, pos2);
    }
    else
    {
        GetClientAbsOrigin(client, pos1);
        GetClientAbsOrigin(target, pos2);
    }
    return GetVectorDistance(pos1, pos2);
}

stock bool IsClientValid(int client)
{
    return IsClientInGame(client) && GetClientTeam(client) > 1 && IsPlayerAlive(client);
}
 
Последнее редактирование:

Max Rhine

Участник
Сообщения
176
Реакции
30
я не понимаю что ты хочешь получить в результате
Если дистанция между игроками больше указанного значения, выполняется какой-то код. Если же меньше, то просто игнорируется.
C-подобный:
            if (GetVectorDistance(pos, pos2) <= DISTANCE)
            {
                PrintToChatAll("Близко - плохо", client); // тест
            }
            else
            {
                PrintToChatAll("Далеко - хорошо", client);    // тест
            }
Сообщения автоматически склеены:

Вот так можно вывести в чат расстояние м/у всеми живыми игроками:
Посмотрю, может это то, что мне нужно. Спасибо за помощь🙂
Сообщения автоматически склеены:

я не понимаю что ты хочешь получить в результате
Не получилось реализовать задуманное ( если дистанция <= то данный код не работает ). Когда делал у себя, писало ошибки на локальный target. Может что и не правильно делаю, но с костылями на первое время - самое то. Со временем, начну химичить что-то получше, чем мой код на данной стадии.
C-подобный:
Handle trace = TR_TraceRayFilterEx(vOrigin, AnglesVec, MASK_SHOT, RayType_Infinite, TraceRayDontHitSelf, client);
    
    if (TR_DidHit(trace))
    {
        int target = TR_GetEntityIndex(trace);
        if ((target > 0) && (target <= MaxClients) && GetClientTeam(target) != GetClientTeam(client) && IsPlayerAlive(target) && IsPlayerAlive(client))
        {
        }
    }
 
Последнее редактирование:

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
нужно было сделать проверку дистанции между игроками. Нашёл 2 примера, переписал под свои нужды. В итоге - плагин скомпилировался без ошибок, а условие работало не корректно.

Некорректность в чем заключается? И как ты эту некорректность определил? На глаз что ли.
Тебе Grey83 дал код, как по мне - это самый реально работающий код, сам принцип.
Единственно, мне так кажется, цикл в цикле ни к чему. Находишь всех игроков(живых) в твоём радиусе, определяешь кто из них в поле зрения, из них выбираешь ближайшего, и до него уже делаешь определение дистанции. Определяешь размеры игрока и эти размеры передаешь в трассировку, трассировку делаешь до "коллайдера" игрока а не конкретной точки(я понимаю так, что тебе не до точки расстояние нужно, а просто до игрока).
 

Max Rhine

Участник
Сообщения
176
Реакции
30
Некорректность в чем заключается? И как ты эту некорректность определил? На глаз что ли.
Определил на глаз компилятора. Да, я совершил ошибку в коде (есть такая фраза - ошибайтесь, учитесь и побеждайте). Взял часть кода который дал @Grey83, немного подумал и всё скомпилировалось, заработало. Тема на данный момент не актуальна. Спасибо за советы)
 

alexmy

Участник
Сообщения
284
Реакции
13
Всем привет. Как можно реализовать, дистанцию всех игроков к одному, к меньшему к большему.
Например игрок
1 - 100.0
2.- 150.0
ну и ид. У меня получается через цикл, используя GetVectorDistance считает самих игроков а не их дистанцию по порядку.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
@alexmy, в смысле сделать сортировку массива расстояний от игроков до определённой точки?
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,569
Реакции
5,071
@alexmy, сначала делаешь массив, который заполняешь расстояниями, а потом делаешь сортировку как вот тут (правда у меня там сортировка 2 параметра учитывает, так что нуно будет чуть упростить код ^_^):
 
Сверху Снизу