Health Arm Box

Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
C++:
void HealthArmBox(IActor*Player, IEntity* pEnt, float HP, float Ar)
{
    DWORD color=GREEN;
    Vec3 ScreenPos1, ScreenPos2;

    //Выходим на класс костей
    ICharacterInstance* GetCharacter = pEnt->GetCharacter(0);
    if (!GetCharacter)return;

    ISkeletonPose* m_pSkeleton = GetCharacter->GetISkeletonPose();
    if (!m_pSkeleton)return;

    //Получаем матрицу кости, головы
    Matrix34 Head = pEnt->GetProjectedWorldBBox()*Matrix34(m_pSkeleton->GetAbsJointByID(m_pSkeleton->GetJointIDByName("Bip01 Head")));
  
    //Получаем позицию игрока
    Vec3 Ground = позиция игрока

    //Проверяем на валидность позиции
    if (Head.GetTranslation() == Vec3{ZERO}) return;
    if (Ground == Vec3{ ZERO }) return;

    //Определяем цвет согласно значению жизней
    if (HP < 60)color = YELLOW(150);
    if (HP < 30) color = RED(150);
  
    //Переводим 3Д координаты головы в 2Д координаты
    if (WorldToScreen(Head.GetTranslation(), ScreenPos2))
    {
        //Переводим 3Д координаты позиции в 2Д координаты
        WorldToScreen(Ground, ScreenPos1);//ноги
      
        //Вычесляем расстояние между 2Д координатами
        float w = (ScreenPos1.y - ScreenPos2.y) / 4;
      
        //Вычесляем расстояние между 2Д координатами в соответствии жизней
        int hw = (int)(((ScreenPos1.y - ScreenPos2.y)*(HP)) / -100);

        //Вычесляем расстояние между 2Д координатами в соответствии брони
        int arrmory = (int)(((ScreenPos1.y - ScreenPos2.y)*(Ar)) / -100);
      
        //рисуем жизни
        pRender->GradientBox(ScreenPos1.x + w, ScreenPos1.y, 4, hw, RED, color, vertical);//градиент жизней
        pRender->Border(Vec2(ScreenPos1.x + w, ScreenPos1.y), 4, hw, 1, BLACK);//рамка градиента
      
        //рисуем броню
        pRender->GradientBox(ScreenPos1.x + w + 5, ScreenPos1.y, 4, arrmory, ORANGE, ORANGE, vertical);//градиент брони
        pRender->Border(Vec2(ScreenPos1.x + w + 5, ScreenPos1.y), 4, arrmory, 1, BLACK);//градиент рамки
      
    }
}
GradientBox думаю есть у каждого.
vertical - говорит о том, что он вертикальный.

Вот что имеем: хп.jpg

Взято из основ одного хорошего человека.
 
Последнее редактирование:
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Забаненный
Статус
Оффлайн
Регистрация
2 Ноя 2018
Сообщения
18
Реакции[?]
1
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Эксперт
Статус
Оффлайн
Регистрация
12 Июн 2014
Сообщения
991
Реакции[?]
1,209
Поинты[?]
3K
не совсем рационально сделано. ISkeletonPose и матрица WorldTM имеют один указатель на протяжении всей жизни Entity. а у условием, что эти данные ты еще используешь и в скелетах, то целесообразней вынести их за пределы множественных итераций:


Код:
for (; IActor* pActor = pIActorIterator->Next();)
                    {
                        if (!pActor)
                            continue;
                        if (pActor->IsDead())
                            continue;
 
                            if (!pActor->m_pEntity()->GetCharacter(0))
                                continue;
                            ISkeletonPose* m_pSkeleton = pActor->m_pEntity()->GetCharacter(0)->GetISkeletonPose();
                            Matrix34       m_pWorld = pActor->m_pEntity()->GetWorldTM();

                            Vec3  v2dVector = { ZERO };
                            Vec3  vWorld = vGetBone(m_pWorld, m_pSkeleton, "Bip01 R Clavicle");


                            if (!IRender::Singleton()->WorldToScreen(vWorld, v2dVector))
                                continue;
                                
                                //рисуем используя данные выше (скелеты, боксы..... + используем данные для аима и других расчетов)
таким образом мы получаем эти данные один раз за итерацию, а не обращаемся для каждый раз для получения

Код:
Vec3    vGetBone(Matrix34 m_pWorld, ISkeletonPose* m_pSkeleton, const char* szJointName)
{
    if (!m_pSkeleton)
        return Vec3{ ZERO };
    __int16 BoneId = m_pSkeleton->GetJointIDByName(szJointName);
    Matrix34 mOut = m_pWorld * Matrix34(m_pSkeleton->GetAbsJointByID(BoneId));
    return mOut.GetTranslation();
}
 
сдерживаю выходящее наружу зло
Пользователь
Статус
Оффлайн
Регистрация
25 Ноя 2018
Сообщения
503
Реакции[?]
104
Поинты[?]
1K
Energy Reload
Забаненный
Статус
Оффлайн
Регистрация
20 Авг 2017
Сообщения
1,206
Реакции[?]
330
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сверху Снизу