1. Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, сыграть в увлекательные ФРПГ, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
    Скрыть объявление
  2. Форум аддона "Возвращение" 2.0:
    — Обсудить игру, почитать о прохождениях и/или разрешить свои вопросы по игре вы можете в одной из тем одноименного форума. Посетить...
    — Прочитать историю изменения и/или скачать последнюю версию аддона "Возвращение", вы можете на страницах наших ресурсов. Скачать...
    Скрыть объявление

Туториал: Управление цветом фокусной надписи.

Тема в разделе "Уpоки AST", создана пользователем Jr13San, 13 янв 2018 в 18:17.

  1. Jr13San

    Jr13San Участник форума

    Регистрация:
    1 апр 2010
    Сообщения:
    453
    Благодарности:
    130
    Баллы:
    210
    Пол:
    Мужской
    1) Для начала определимся с тех. заданием. В качестве примера напишем обработчики для следующих объектов:
    • НПС
    - Если он входит в состав группы игрока, то подкрашиваем его имя зелёным цветом.
    - Если он находится в состоянии атаки на игрока, то окрашиваем его имя в красный цвет.
    - Если он мёртв и у него нечего взять, то делаем надпись полупрозрачной (чтобы не привлекал внимание).
    - В остальных случаях цвет фокусной надписи не меняется.​
    • Предмет
    - Если предмет является игровой валютой, то подкрашиваем надпись в жёлтый цвет.
    - В остальных случаях - используется цвет по умолчанию.​
    • Сундук
    - Если сундук пустой, то его название становится полупрозрачным (чтобы не привлекал внимание).
    - В остальных случаях цвет фокусной надписи не меняется.
    2) Открываем рабочий проект плагина для версии "003" в Visual Studio, и добавляем в раздел “Plugin main” новый файл, под названием “UpdateFocusColor.cpp”, как показано на рисунках:

    1.jpg 2.jpg

    3) Добавляем в файл следующий код:
    PHP:
    #include "AST.h"

    // Функция обработки цвета текста фокусной надписи
    // (изменяет цвет текста вьюпорта перед печатью, или не изменяет)
    void UpdateFocusColor()
    {
        
    //*****
        // НПС
        //*****

        // Пытаемся преобразовать указатель на объект в указатель на НПС
        
    oCNpcpNpc dynamic_cast<oCNpc*>(player->focus_vob);

        
    // Если преобразование в НПС прошло успешно
        
    if (pNpc)
        {
            
    // Если НПС входит в состав группы игрока
            
    if (pNpc->m_nAivar[15])
                
    // Устанавливаем зелёный цвет фокусной надписи
                
    screen->SetFontColor(zCOLOR(100,255,100));
          
            
    // Если ГГ является врагом НПС
            
    if (pNpc->enemy == player)
            {
                
    // Получаем название состояния в котором находится НПС
                
    zSTRING stateName pNpc->state.curState.name;

                
    // Если это название состояния атаки для людей или животных
                
    if (!stateName.Compare("ZS_ATTACK") || !stateName.Compare("ZS_MM_ATTACK"))
                    
    // Устанавливаем красный цвет фокусной надписи
                    
    screen->SetFontColor(zCOLOR(255,60,60));
            }

            
    // Получаем указатель на инвентарь НПС
            
    oCNpcInventorypInv pNpc->GetInventory();

            
    // Если НПС мёртв и у него нечего взять
            
    if (pNpc->IsDead() && pInv && pInv->IsEmpty() && pInv->packString.IsEmpty())
                
    // Делаем цвет текста полупрозрачным
                
    screen->SetFontColor(zCOLOR(255,255,255,128));

            
    // Выходим из функции
            
    return;
        }

        
    //*********
        // ПРЕДМЕТ
        //*********

        // Пытаемся преобразовать указатель на объект в указатель на предмет
        
    oCItempItem dynamic_cast<oCItem*>(player->focus_vob);
      
        
    // Если преобразование прошло успешно
        
    if (pItem)
        {
            
    // Выполняем поиск игровой валюты:
            // Ищем текстовую переменную в скриптах с названием "TRADE_CURRENCY_INSTANCE"
            
    zCPar_Symbolps parser->GetSymbol("TRADE_CURRENCY_INSTANCE");

            
    // Если нашли
            
    if (ps)
            {
                
    // Объявляем переменную для хранения названия
                
    zSTRING gold_inst;

                
    // Получаем название инстанции и записываем его в переменную
                
    ps->GetValue(gold_inst0);

                
    // Если название инстанции предмета в фокусе совпадает с названием игровой валюты
                
    if (!pItem->GetInstanceName().Compare(gold_inst))
                    
    // Подкрашиваем текст в жёлтый цвет
                    
    screen->SetFontColor(zCOLOR(255,255,0));
            }

            
    // Выходим из функции
            
    return;
        }

        
    //********
        // СУНДУК
        //********

        // Пытаемся преобразовать указатель на объект в указатель на сундук
        
    oCMobContainerpMobCont dynamic_cast<oCMobContainer*>(player->focus_vob);

        
    // Если преобразование в сундук прошло успешно
        
    if (pMobCont)
        {
            
    // Если сундук пустой
            
    if (!pMobCont->containList.GetNumInList())
                
    // Делаем цвет текста полупрозрачным
                
    screen->SetFontColor(zCOLOR(255,255,255,128));

            
    // Выходим из функции
            
    return;
        }
    }


    //****************************************************************
    // Перехват функции, в которой вызывается печать фокусной надписи
    //****************************************************************
    //0x006C3140 public: void __thiscall oCGame::UpdatePlayerStatus()
    void __fastcall UpdatePlayerStatus(int _this);
    CInvoke <void(__thiscall*) (int)> pUpdatePlayerStatus(0x006C3140UpdatePlayerStatusIVK_AUTO);
    void __fastcall UpdatePlayerStatus(int _this)
    {
        
    // Запоминаем цвет текста вьюпорта
        
    zCOLOR color screen->fontColor;

        
    // Если указатель на игрока, а также на его фокусный объект существует, то
        
    if (player && player->focus_vob)
            
    // Вызываем наш обработчик цвета
            
    UpdateFocusColor();

        
    // Вызываем оригинальную функцию,
        // в которой происходит печать текста
        
    pUpdatePlayerStatus(_this);

        
    // Если цвет текста вьюпорта был изменён
        
    if (screen->fontColor != color)
            
    // Восстанавливаем ему ранее сохранённый цвет
            
    screen->SetFontColor(color);
    }
    4) В коде, в разделе обработчика сундука, находим класс "oCMobContainer", нажимаем на него правой кнопкой мыши и выбираем пункт меню: "Перейти к определению", как показано на рисунке:

    3.jpg
    Мы быстро перешли к заголовку "ocmob.h". Класс контейнера нас не интересует. Листаем вверх до класса oCMobInter или через поиск(Ctrl+F) и обязательно исправляем недочёт, добавив в класс недостающие поля, как показано на рисунке:

    4.jpg

    Недостающие поля класса (открыть)
    Код:
    zVEC3               startPos;
    zREAL               aniCombHeight;
    zCVob*              inUseVob;
    zREAL               timerEnd;


    5) Компилируем проект, смотрим результат.
    Тестовые скриншоты (открыть)

    ASTSTART_9.jpg ASTSTART_10.jpg ASTSTART_11.jpg
    ASTSTART_12.jpg ASTSTART_13.jpg ASTSTART_14.jpg ASTSTART_16.jpg ASTSTART_17.jpg
    ASTSTART_23.jpg ASTSTART_24.jpg
    ASTSTART_18.jpg ASTSTART_20.jpg ASTSTART_21.jpg
    ASTSTART_6.jpg ASTSTART_7.jpg


    Скачать готовый плагин: "UpdateFocusColor.rar"
     

    Вложения:

    Последнее редактирование: 14 янв 2018 в 08:44
    Ur-tRall, Beowulf, hell9999 и ещё 1 пользователь поблагодарили.

Поделиться этой страницей