Добавляем в Interlude снятие баффов по клику
Я пытался разместить это в обучающие статьи, но застрял на модерации, поэтому разместил сюда, поправив пару опечаток
https://s8.hostingkartinok.com/uploa...887b7aa915.gif Возможность снять UD, Snipe, Stealth или CoV — отличная штука, особенно в Interlude, где эти умения не имеют заточки на штраф. Многие уже привыкли отменять Chant of Revenge перед нажатием Mirage или хилиться, снимая Celestial Shield Нам понадобятся
Серверная часть https://s8.hostingkartinok.com/uploa...b58fdb8b78.png Сервер в нашем случае — ACIS 36x, но подойдет любой (возможно и PTS). Всё, что потребуется — добавить команду, которая будет снимать указанный бафф. Для простоты примера обойдемся байпасом Для снятия баффа более современные клиенты отправляют пакет RequestDispel, поэтому будем использовать термин dispel Сперва в L2Character добавим метод диспела. По аналогии с более свежими версиями игры он не будет снимать эффекты, которые должны оставаться после смерти (напр., пенальти), дебаффы, денсы и сонги: // L2Character.java public final void dispelSkillEffect(int skillId, int skillLevel) { // Find skill with matching ID and level final L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLevel); // Skill wasn't found and can't be dispelled if (skill == null) { return; } // Penalty-like or debuff skill effect can't be dispelled if (skill.isStayAfterDeath() || skill.isDebuff()) { return; } // Dance-like skill effect can't be dispelled if (skill.isDance()) { return; } // Stop skill effect by ID _effects.stopSkillEffects(skill.getId()); } Теперь добавим обработку байпаса в runImpl сетевого пакета RequestBypassToServer, который приходит от клиента. Поскольку метод dispelSkillEffect в качестве аргументов требует ID и уровень скилла, клиент должен передать их в качестве параметров к команде dispel: // RequestBypassToServer.java // Usage: _dispel:<int:skill_id>,<int:skill_level> // Example: _dispel:313,8 else if (_command.startsWith("_dispel")) { // Cut out command params String params = _command.substring(_command.indexOf(":") + 1); // Split params into tokens StringTokenizer st = new StringTokenizer(params, ","); // Get skill ID from first token int id = Integer.parseInt(st.nextToken()); // Get skill level from second token int level = Integer.parseInt(st.nextToken()); // Dispel skill effect on current character activeChar.dispelSkillEffect(id, level); } Пример вызова: _dispel:313,8 Рекомендую вместо байпаса сделать команду с аналогичными параметрами. Кроме того, тогда игроки смогут писать макросы на снятие баффа Клиентская часть https://s8.hostingkartinok.com/uploa...5f686a37ad.png К сожалению, в клиенте Interlude нет простого способа отследить нажатие Alt+Click, поэтому используем для снятия баффа обычный двойной клик левой кнопки мыши. Обрабатывать событие будет окно AbnormalStatusWnd, которое отображает иконки баффов и дебаффов Алгоритм:
Поскольку мы знаем, что размер ячейки баффа 24 пикселя, а размер ручки, за которое перетаскивается окно — 12 пикселей, то вычислить ряд и ячейку легко: достаточно определить координаты окна с баффами, вычесть все значения и поделить остаток на размер ячейки. При приведении к int значения будут правильно округлены Сперва добавим константу NSTATUSICON_SIZE, описывающую размер ячейки баффа в начало скрипта. Остальные константы разработчки уже описали: // AbnormalStatusWnd.uc class AbnormalStatusWnd extends UIScript; const NSTATUSICON_FRAMESIZE = 12; const NSTATUSICON_MAXCOL = 12; const NSTATUSICON_SIZE = 24; // ... Теперь в любое место (например, сразу после функции OnEvent), добавим обработку события двойного клика: // 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)) { // Calc row and col of targeted icon targetRow = (Y - windowBounds.nY) / NSTATUSICON_SIZE; targetCol = (X - windowBounds.nX - NSTATUSICON_FRAMESIZE) / NSTATUSICON_SIZE; // Store status info of targeted icon StatusIcon.GetItem(targetRow, targetCol, info); // Store actual skill info and make sure it is exists 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, копируем в клиент, запускаем игру Готово! |
Текущее время: 09:51. Часовой пояс GMT +3. |
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot