Объект находящийся на прицеле. Способ который работает.

Сообщения
1,117
Реакции
349
Есть объект небольшая моделька с установленными mins maxs 15х15.
Задача следующая, через эту модель игрок должен проходить, а при попадании на прицел, должно высвечиваться описание предмета.

И так что я испробовал и какие проблемы это преподнесло.

1. find_ent_in_sphere в точке куда целится игрок
Не подходит совсем. Так как игрок не целится никогда в землю. А для этого способа игрок должен прицелится не в сущность, а в землю рядом с ней.

2. find_ent_in_sphere от игрока и до точки куда игрок целится.
Использовал в старой версии RUNEMOD. Не подходит. Так как потребуется огромное количество ресурсов и циклов что бы это сработало. Например если искать entity в сфере размером 30, то нужно в цикле добавлять +15 к дистанции, до конечной точки. Допустим игрок целится в даль на 2000 юнитов, Потребуется около 150 попыток поиска entity, и это только за 1 раз. Представим на секунду что это делают 32 игрока и например раз 10 в секунду. Расточительство :) К тому же это сбивает с толку когда игрок стоит рядом с другой сущностью но не целится в нее, т.к сфера срабатывает и на нее в первую очередь. А уменьшение размера сферы увеличивает количество циклов.

3. хук TraceLine и установка SOLID_TRIGGER когда игрок рядом
Использую сейчас в RUNEMOD но тоже не подходит. Дело в том что TraceLine срабатывает лишь 1 раз, и не ясно смотрит ли игрок на эту сущность. К тому же entity не проходимая при использовании SOLID SLIDEBOX/BBOX и приходится костылявить заставляя ее быть проходимой когда любой игрок находится рядом.

Вопрос в том как это сделать с меньшим количеством затрат, сейчас я использую 3 способ это работает и более ли менее мало ресурсов использует. Но костыль с переключением SOLID_BBOX->SOLID_TRIGGER и обратно слишком костыльный :)
 
Сообщения
341
Реакции
178
Помог
11 раз(а)
karaulov, для такой задачи подойдёт get_user_aiming. Установите объекту к примеру:

Код:
set_entvar(iEnt,var_impulse,13);

//Проверяем на что смотрит игрок:

    new pAiming;
    get_user_aiming(id,pAiming);
    if(!is_user_connected(pAiming) && get_entvar(pAiming,var_impulse) == 13) {
        //code
    }
Но для того, чтобы отловить смотрит ли игрок на, что-то объект должен быть плотным SOLID_BBOX
 
Сообщения
1,117
Реакции
349
b0t., ну так прочитать мое сообщение не судьба?:( Я же об этом уже написал в пункте 1.
25 Апр 2022
А нет, не писал. ) Но да это то же самое что пункт 3 только по таймеру надо проверять. Но все равно от костыля с переключением BBOX/TRIGGER никуда не избавиться с этим вариантом)
25 Апр 2022
BalbuR, действительно не знал об этой функции, спс попробую!
 
Сообщения
711
Реакции
476
Помог
10 раз(а)
1. создаешь дин. массив, пишешь туда айди своих объектов
2. когда требуется - крутишь цикл по этим объектам и проверяешь что это именно твой объект

Пункт 1 нужен чтобы не крутить цикл по всем объектам на карте
25 Апр 2022
ошибся, текст выше нужен для чекбокса (в ресемклипе подсмотреть можно)
тут достаточно просто по endpos чекать
 
Сообщения
341
Реакции
178
Помог
11 раз(а)
karaulov, найти объекты в радиусе конечной точки взгляда игрока.
Ставим объекту *_classname. Находим конечную точку взгляда:

Код:
    new get_user_origin(id,Origin,Origin_AimEndClient);
    new iEnt;
    while((iEnt = rg_find_ent_by_class(iEnt,"ent_classname"))) {
        client_print(id,print_chat,"Смотрим рядом с объектом");
        break;
    }
Не подойдёт... Извиняюсь, дичь пишу с просонья
 
Сообщения
658
Реакции
230
Помог
11 раз(а)
Чекай алгоритм SentryBuild
register_forward(FM_TraceLine, "forward_traceline_post", 1)
 

Вложения

Сообщения
1,117
Реакции
349
b0t., пункт первый я уже писал что игроку надо будет целится в землю
 
Сообщения
341
Реакции
178
Помог
11 раз(а)
karaulov, да-да. Я отписал под своим комментарием, что дичь пишу с просонья.
Извиняюсь
 
Сообщения
1,117
Реакции
349
Limbooc, уже было в пункте 3, у меня сейчас это и используется но проблема в том что срабатывает лишь 1 раз.

То есть я навожу на руну, срабатывает. Но потом надо как-то понимать что руна все еще находится на прицеле и надо обновлять описание.

Попробую с EngFunc_TraceModel звучит многообещающе
 
Сообщения
711
Реакции
476
Помог
10 раз(а)
Limbooc, у него объект неосязаемый, его трейслайн не пробьет
+нерациональное использование имхо. Какой-либо таск в 0.2 - 0.5 будет лучше
 
Сообщения
1,117
Реакции
349
BalbuR, спасибо способ с EngFunc_TraceModel в таске работает просто идеально!
Выкинул большой кусок кода с костылями благодаря этому :)



Код:
new Float:fOrigin[3];
new iOriginEnd[3];
get_entvar(id,var_origin, fOrigin );
get_user_origin( id, iOriginEnd, Origin_AimEndEyes );
new Float:fOriginEnd[ 3 ];
IVecFVec( iOriginEnd, fOriginEnd );


for(new i = 0; i < filled_spawns;i++)
{
    new iEnt = spawn_filled[i];
    if (iEnt > 0 && !is_nullent(iEnt))
    {
        engfunc(EngFunc_TraceModel,fOrigin,fOriginEnd,HULL_POINT,iEnt,g_pCommonTr);
        if (get_tr2(g_pCommonTr, TR_pHit) == iEnt)
        {
            RM_UPDATE_HUD_RUNE(id,iEnt);
            break;
        }
    }
}
 
Последнее редактирование:
Сообщения
711
Реакции
476
Помог
10 раз(а)
karaulov,
цикл тебе по сути не нужен
достаточно проверить на то, что это именно твой объект, записать заранее в него индекс из твоего массива и получать далее данные по нему
Код:
get_tr2(g_pCommonTr, TR_pHit)
 
Сообщения
1,117
Реакции
349
karaulov,
цикл тебе по сути не нужен
достаточно проверить на то, что это именно твой объект, записать заранее в него индекс из твоего массива и получать далее данные по нему
Код:
get_tr2(g_pCommonTr, TR_pHit)
Наверное так не получится? В EngFunc_TraceModel ведь надо указать сущность которую я хочу проверить
 
Сообщения
711
Реакции
476
Помог
10 раз(а)
karaulov, там указывается сущность для игнорирования в трейслайне, грубо говоря айди игрока
 
Сообщения
1,117
Реакции
349
странно а чего у меня не работало когда я игрока вставлял может наоборот цель?
 
Сообщения
1,117
Реакции
349
В голову дурная идея пришла, а не будет ли быстрее без TraceModel ?

То есть то же в цикле, расстояние между глазами игрока и сущностью, взять направление взгляда , добавить расстояние, и проверить расстояние между получившимися точками, если меньше чем указанный радиус, то выдавать true
26 Апр 2022
Получилось, если кому пригодится вот как было и как стало:

БЫЛО
C++:
public user_think(id)
public user_think(id)
{
    if (is_user_alive(id))
    {
        if (runemod_active)
        {
            new iOriginStart[3];
            new iOriginEnd[3];
            get_user_origin( id, iOriginStart, Origin_Eyes );
            get_user_origin( id, iOriginEnd, Origin_AimEndEyes );
            new Float:fOriginStart[ 3 ];
            IVecFVec( iOriginStart, fOriginStart );
            new Float:fOriginEnd[ 3 ];
            IVecFVec( iOriginEnd, fOriginEnd );
    
            
            for(new i = 0; i < filled_spawns;i++)
            {
                new iEnt = spawn_filled[i];
                if (iEnt > 0 && !is_nullent(iEnt))
                {
                    engfunc(EngFunc_TraceModel,fOriginStart,fOriginEnd,HULL_POINT,iEnt,g_pCommonTr);
                    if (get_tr2(g_pCommonTr, TR_pHit) == iEnt)
                    {
                        RM_UPDATE_HUD_RUNE(id,iEnt);
                        break;
                    }
                }
            }
        }
    }
}
СТАЛО
C++:
public user_think(id)
{
    if (is_user_alive(id))
    {
        if (runemod_active)
        {
            new iOriginStart[3];
            get_user_origin( id, iOriginStart, Origin_Eyes );
            
            new Float:fOriginStart[ 3 ];
            IVecFVec( iOriginStart, fOriginStart );
        
            new iOriginEnd[3];
            get_user_origin( id, iOriginEnd, Origin_AimEndEyes );
            
            new Float:fOriginEnd[ 3 ];
            IVecFVec( iOriginEnd, fOriginEnd );
            
            new fMaxDistance = floatround(get_distance_f(fOriginStart,fOriginEnd));
            
            
            for(new i = 0; i < filled_spawns;i++)
            {
                new iEnt = spawn_filled[i];
                if (iEnt > 0 && !is_nullent(iEnt))
                {
                    new Float:fOriginEnt[3];
                    get_entvar(iEnt,var_origin,fOriginEnt);
                    
                    new fCurDistance = floatround(get_distance_f(fOriginStart,fOriginEnt));
                    if (fCurDistance < fMaxDistance)
                    {
                        new Float:fVelocityValue[ 3 ];
                        velocity_by_aim( id, fCurDistance, fVelocityValue );
                        
                        new Float:fTargetEyesOrigin[ 3 ];
                        xs_vec_add( fOriginStart, fVelocityValue, fTargetEyesOrigin );
                        
                        if (get_distance_f(fTargetEyesOrigin,fOriginEnt) < 30.0)
                        {
                            RM_UPDATE_HUD_RUNE(id,iEnt);
                            break;
                        }
                    }
                }
            }
        }
    }
}
 
Сообщения
1,117
Реакции
349
Перенес это в стоки https://dev-cs.ru/threads/222/post-124958, думаю кому-нибудь пригодится.

Работает в 2 раза быстрее чем TraceModel, но тоже как костыль, лучше бы в TraceLine добавили флаг для трассировки SOLID_TRIGGER, было бы явно быстрее )
 
Последнее редактирование:

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу