Обратите внимание, что данный пользователь заблокирован! Не совершайте с ним никаких сделок! Перейдите в его профиль, чтобы узнать причину блокировки.
	
Нам понадобится
Все, что вам нужно, находится в свободном доступе.
Cерверная часть
 
Сервер в нашем случае ACIS 36x, но подойдет любой (возможно PTS). Все, что требуется, это добавить команду, которая снимет указанный бафф. Чтобы не усложнять пример, давайте обойдемся обходом .
Чтобы снять бафф, более современные клиенты отправляют пакет RequestDispel , поэтому мы будем использовать термин dispel
Сначала добавим метод dispel в L2Character. Как и в более поздних версиях игры, не удаляются эффекты, которые должны остаться после смерти (например, штрафы), дебаффы, танцы и песни:
	
	
	
		
Теперь добавим обработку в to the runImpl  RequestBypassToServer network пакета RequestBypassToServer, который приходит от клиента. Так как  метод dispelSkillEffect  требует ID навыка и уровень навыка в качестве аргументов, клиент должен передать их в качестве параметров команде  dispel  :
	
	
	
		
Пример вызова:  _dispel:313,8 I
 
рекомендую сделать команду с аналогичными параметрами вместо обхода. Кроме того, тогда игроки смогут писать макросы для снятия баффа.
Сторона клиента
К сожалению, простого способа отслеживания Alt+Click в клиенте Interlude нет, поэтому используем обычный двойной клик левой кнопки мыши для снятия баффа . Событие будет обрабатываться окном AbnormalStatusWnd , в котором отображаются иконки бафов и дебаффов
 
Алгоритм:
 
Событие двойного щелчка левой кнопки мыши OnLButtonDblClick получает в качестве аргументов только координаты щелчка. В то же время StatusIcon.GetItem требует указания строки и столбца ячейки. Соответственно надо определить в какой строке и в какой колонке наших бафов игрок нажал
 
Поскольку мы знаем, что размер ячейки баффа равен 24 пикселям, а размер ручки, за которую перетаскивается окно, равен 12 пикселям, то вычислить строку и ячейку несложно: достаточно определить координаты окна с бафами вычесть все значения и разделить остаток на размер ячейки. Значения будут правильно округлены при приведении к типу int Во-первых, давайте добавим NSTATUSICON_SIZE
 
константа, которая описывает размер ячейки баффа, в начало скрипта. Остальные константы разработчика уже описаны:
	
	
	
		
Теперь в любом месте (например, сразу после функции OnEvent) добавьте обработку события двойного клика:
	
	
	
		
Скомпилировать interface.u, скопировать в клиент, запустить игру
Готово!
				
			- исходники сервера
 - исходники 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
	
		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 ) ; }
	рекомендую сделать команду с аналогичными параметрами вместо обхода. Кроме того, тогда игроки смогут писать макросы для снятия баффа.
Сторона клиента
К сожалению, простого способа отслеживания Alt+Click в клиенте Interlude нет, поэтому используем обычный двойной клик левой кнопки мыши для снятия баффа . Событие будет обрабатываться окном AbnormalStatusWnd , в котором отображаются иконки бафов и дебаффов
Алгоритм:
- Слушаем в окне AbnormalStatusWnd событие двойного клика (OnLButtonDblClick)
 - Определить бафф, на который нажали (через StatusIcon.GetItem)
 - Определите идентификатор и уровень навыка этого баффа (через GetSkillInfo)
 - Отправляем запрос на сервер (через RequestBypassToServer или ExecuteCommand)
 - Вызываем 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 ;
 
// ...
	
		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 ) ) ) ;
        }
    }
}
	Готово!
	















