• Новые темы в этом разделе публикуются автоматически при добавлении файла в менеджер ресурсов.
    Ручное создание новых тем невозможно.

Мануал Добавляем снятие бафов через Alt+click(double click)

interlude
  • VAAADIM

    Заблокирован
    Заблокирован
    Сообщения
    37
    Розыгрыши
    0
    Репутация
    42
    Реакции
    15
    Баллы
    188
    Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
    Нам понадобится
    • исходники сервера
    • исходники interface.u с компилятором

    Все, что вам нужно, находится в свободном доступе.
    Cерверная часть

    Сервер в нашем случае ACIS 36x, но подойдет любой (возможно PTS). Все, что требуется, это добавить команду, которая снимет указанный бафф. Чтобы не усложнять пример, давайте обойдемся обходом .

    Чтобы снять бафф, более современные клиенты отправляют пакет RequestDispel , поэтому мы будем использовать термин dispel

    Сначала добавим метод dispel в L2Character. Как и в более поздних версиях игры, не удаляются эффекты, которые должны остаться после смерти (например, штрафы), дебаффы, танцы и песни:
    Java:
    // L2Character.java
     
    public  final  void dispelSkillEffect ( int skillId, int skillLevel )  {
        // Найти скилл с подходящим ID и уровнем
        final L2Skill skill = SkillTable. getInstance ( ) . getInfo ( skillId, skillLevel ) ;
        // Skill не найден и не может быть отменён
        if  ( skill ==  null )
        {
            return ;
        }
        // Пенальти и дебафы не могут быть отменены
        if  ( skill.isStayAfterDeath ( )  || skill. isDebuff ( ) )
        {
            return ;
        }
       
        // Сбрасывать с персонажа эфект скила с ид
        _effects. stopSkillEffects ( skill
    Теперь добавим обработку в to the runImpl RequestBypassToServer network пакета RequestBypassToServer, который приходит от клиента. Так как метод dispelSkillEffect требует ID навыка и уровень навыка в качестве аргументов, клиент должен передать их в качестве параметров команде dispel :
    Java:
    // RequestBypassToServer.java
     
    // Usage: _dispel:<int:skill_id>,<int:skill_level>
    // Example: _dispel:313,8
    else  if  ( _command. startsWith ( "_dispel" ) )
    {
       
        String params = _command. substring ( _command. indexOf ( ":" )  +  1 ) ;
        // Split params into tokens
        StringTokenizer st =  new  StringTokenizer ( params, "," ) ;
        // Get skill ID from first token
        intid =  Integer . parseInt ( st.nextToken ( ) ) ;
        activeChar. dispelSkillEffect ( id, level ) ; }
    Пример вызова: _dispel:313,8 I

    рекомендую сделать команду с аналогичными параметрами вместо обхода. Кроме того, тогда игроки смогут писать макросы для снятия баффа.

    Сторона клиента

    К сожалению, простого способа отслеживания Alt+Click в клиенте Interlude нет, поэтому используем обычный двойной клик левой кнопки мыши для снятия баффа . Событие будет обрабатываться окном AbnormalStatusWnd , в котором отображаются иконки бафов и дебаффов

    Алгоритм:

    1. Слушаем в окне AbnormalStatusWnd событие двойного клика (OnLButtonDblClick)
    2. Определить бафф, на который нажали (через StatusIcon.GetItem)
    3. Определите идентификатор и уровень навыка этого баффа (через GetSkillInfo)
    4. Отправляем запрос на сервер (через RequestBypassToServer или ExecuteCommand)
    5. Вызываем dispelSkillEffect на сервере с полученным ID и уровнем навыка

    Событие двойного щелчка левой кнопки мыши OnLButtonDblClick получает в качестве аргументов только координаты щелчка. В то же время StatusIcon.GetItem требует указания строки и столбца ячейки. Соответственно надо определить в какой строке и в какой колонке наших бафов игрок нажал

    Поскольку мы знаем, что размер ячейки баффа равен 24 пикселям, а размер ручки, за которую перетаскивается окно, равен 12 пикселям, то вычислить строку и ячейку несложно: достаточно определить координаты окна с бафами вычесть все значения и разделить остаток на размер ячейки. Значения будут правильно округлены при приведении к типу int Во-первых, давайте добавим NSTATUSICON_SIZE

    константа, которая описывает размер ячейки баффа, в начало скрипта. Остальные константы разработчика уже описаны:
    Java:
    // AbnormalStatusWnd.uc
     
    class AbnormalStatusWnd extends UIScript ;
     
    const NSTATUSICON_FRAMESIZE =  12 ;
    const NSTATUSICON_MAXCOL =  12 ;
    const NSTATUSICON_SIZE =  24 ;
     
    // ...
    Теперь в любом месте (например, сразу после функции OnEvent) добавьте обработку события двойного клика:
    Java:
    // AbnormalStatusWnd.uc
     
    function OnLButtonDblClick ( int X ,  int Y )  {
        local Rect windowBounds ;
        local int targetRow ;
        local int targetCol ;
     
        local StatusIconInfo info ;
        local SkillInfo skillInfo ;
     
        // Find window position
        windowBounds = Me. GetRect ( ) ;
     
        // Process clicks outside of window frame only
        if  ( X >  ( windowBounds. nX +  NSTATUSICON_FRAMESIZE ) ) { 
            targetRow =  ( Y - windowBounds. nY )  / NSTATUSICON_SIZE ;
            targetCol =  ( X - windowBounds. nX  - NSTATUSICON_FRAMESIZE )  / NSTATUSICON_SIZE ;
     
          
            StatusIcon. GetItem ( targetRow , targetCol , info ) ;
     
          
            if  ( GetSkillInfo ( info. ClassID , info. Level , skillInfo ) )  {
                // Request server to stop skill effect
                // Usage: _dispel:<int:skill_id>,<int :skill_level>
                // Example: _dispel:313,8
                RequestBypassToServer ( "_dispel:" $ string ( skillInfo. SkillID ) $ "," $ string ( skillInfo. SkillLevel ) ) ) ;
            }
        }
    }
    Скомпилировать interface.u, скопировать в клиент, запустить игру

    Готово!
     

    Назад
    Сверху Снизу