[share] Skill Handlers - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Пользователи Календарь Все разделы прочитаны
Вернуться   Форум администраторов игровых серверов > MMO > Lineage II

Lineage II
Дискуссии на тему создания, настройки и обслуживания серверов Lineage 2. При поддержке: Премиум услуги по рекламе

Описание темы:предновогодняя шара ^_^

Ответ
Опции темы
Непрочитано 22.12.2011, 21:28   #1
Аватар для Gaikotsu
Герой

Автор темы (Топик Стартер) [share] Skill Handlers

Маленькая шара от меня, так сказать подарочек на Новый Год

Многие наверное видели в сервере от l2jserver так называемые SkillHandlers, позволяющие без особого труда объявлять в датапаке новые обработчики скиллов и вызывать их когда зарегистрированный в них скилл использован.

Вобщем я реализовал нечто подобное и для серверов на базе феникса, но с небольшими отличиями: у l2jserver обрабатывается только useSkill и ничего более, у меня же дополнительно можно проверять условия для применения самого скилла, для старта эффекта в нем, делать какие-нибудь действия при старте и окончании эффекта, а так же действия с заданным периодом пока эффект работает.

Куда это все применить я пока даже хз - делал реализацию этого всего чисто ради интересу и руководствуясь принципом "потом может пригодится для чего нибудь"

Ладно, перейдем к делу, а конкретно к содержимому необходимых классов для ядра.

ISkillHandler.java:
PHP код:
package l2p.gameserver.handler;

import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Effect;
import l2p.gameserver.model.L2Skill;
import l2p.util.GArray;

/**
 * Класс для обработки хэндлеров, прикрепляемых к скиллам и их эффектам.
 * <br><br>
 * Для того, чтобы вызывались методы checkCondition(L2Skill skill, ...), isUseAdditionalCheck(), isOffensive() и useSkill(L2Skill skill, ...), 
 * необходимо чтобы умение, к которому прикреплен хэндлер, имело тип HANDLER. 
 * <br><br>
 * Для того, чтобы вызывались методы checkCondition(L2Effect effect, ...), onStart(L2Effect effect, ...), onExit(L2Effect effect, ...) и
 * onActionTime(L2Effect effect, ...), необходимо чтобы в умении, к которому прикреплен хэндлер, имелся эффект с именем Handler.
 * 
 * @author Gaikotsu
 */
public interface ISkillHandler
{
    
/**
     * Проверка возможности использовать умение на заданную цель. 
     * 
     * @param skill        - умение
     * @param caster    - персонаж, кастующий умение
     * @param target    - цель, на которую используется умение
     * @param forceUse    - форсированое использование умения (через Ctrl) или обычное
     * 
     * @return        - true - умение можно использовать, false - нельзя
     * <br><br>
     * Если метод isUseAdditionalCheck() хэндлера возвращает true, то после проверок в этом методе, дополнительно будет 
     * вызван одноименный метод и родительского класса (метод из L2Skill), который проведет дополнительно стандартные проверки на
     * возможность использования умения на эту цель.
     */
    
public boolean checkCondition(L2Skill skillL2Character casterL2Character targetboolean forceUse);

    
/**
     * Возвращает признак того, надо ли делать дополнительные проверки возможности использовать умение на заданную цель.
     * 
     * @return    - true - проверки проводить надо, false - дополнительные проверки не требуются
     */
    
public boolean isUseAdditionalCheck();

    
/**
     * Возвращает признак того, является ли умение "плохим" (вызывающим PvP-флаг).
     * 
     * @return        - true - умение "плохое", false - умение "хорошее"
     */
    
public boolean isOffensive();

    
/**
     * Использование умения на список целей.
     * 
     * @param skill        - умение
     * @param caster    - персонаж, кастующий умение
     * @param targets    - список целей, на которые используется умение
     */
    
public void useSkill(L2Skill skillL2Character casterGArray<L2Charactertargets);
    
    
/**
     * Проверка возможности использовать эффект на заданную цель.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, накладывающий эффект
     * @param target    - цель, на которую накладывается эффект
     * 
     * @return        - true - эффект можно использовать, false - нельзя
     */
    
public boolean checkCondition(L2Effect effectL2Character casterL2Character target);

    
/**
     * Вызывается при начале работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     */
    
public void onStart(L2Effect effectL2Character casterL2Character target);
    
    
/**
     * Вызывается при окончании работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     */
    
public void onExit(L2Effect effectL2Character casterL2Character target);
    
    
/**
     * Вызывается периодически во время действия эффекта.<br>
     * Количество и частота вызовов задается в самом описании эффекта в умении (параметры count и time).<br>
     * Возвращает возможность дальнейшей работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     * 
     * @return        - true - эффект может работать дальше, false - работу эффекта необходимо прервать незамедлительно
     */
    
public boolean onActionTime(L2Effect effectL2Character casterL2Character target);
    
    
/**
     * Возвращает список умений, на которые зарегистрирован хэндлер.
     * 
     * @return        - список умений в виде их идентификаторов
     */
    
public int[] getSkillIds();

SkillHandler.java:
PHP код:
package l2p.gameserver.handler;

import java.util.Map;
import java.util.TreeMap;

public class 
SkillHandler
{
    private static 
SkillHandler _instance;

    private 
Map<IntegerISkillHandler_datatable;

    public static 
SkillHandler getInstance()
    {
        if (
_instance == null)
            
_instance = new SkillHandler();
        return 
_instance;
    }

    public 
int size()
    {
        return 
_datatable.size();
    }

    private 
SkillHandler()
    {
        
_datatable = new TreeMap<IntegerISkillHandler>();
    }

    public 
void registerSkillHandler(ISkillHandler handler)
    {
        
int[] ids handler.getSkillIds();
        for (
int element ids)
            
_datatable.put(elementhandler);
    }

    public 
ISkillHandler getSkillHandler(int skillId)
    {
        return 
_datatable.get(skillId);
    }

    public 
void clear()
    {
        
_datatable.clear();
    }

Handler.java:
PHP код:
package l2p.gameserver.skills.skillclasses;

import l2p.gameserver.handler.ISkillHandler;
import l2p.gameserver.handler.SkillHandler;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Skill;
import l2p.gameserver.templates.StatsSet;
import l2p.util.GArray;

public class 
Handler extends L2Skill
{
    private 
ISkillHandler handler null;

    public 
Handler(StatsSet set)
    {
        
super(set);
    }

    private 
ISkillHandler getHandler(int skillId)
    {
        if (
handler == null)
            
handler SkillHandler.getInstance().getSkillHandler(this.getId());
        
        if (
handler == null)
            
_log.warning("Warning: Not found skill handler for skill " this.getId() + ", class");

        return 
handler;
    }
    
    @
Override
    
public boolean checkCondition(L2Character activeCharL2Character targetboolean forceUseboolean dontMoveboolean first)
    {
        if (
getHandler(this.getId()) != null && handler.checkCondition(thisactiveChartargetforceUse))
        {
            if (
handler.isUseAdditionalCheck())
                return 
super.checkCondition(activeChartargetforceUsedontMovefirst);
            else
                return 
true;
        }
        else
            return 
false;
    }

    @
Override
    
public void useSkill(L2Character activeCharGArray<L2Charactertargets)
    {
        if (
getHandler(this.getId()) != null)
            
handler.useSkill(thisactiveChartargets);
    }
    
    @
Override
    
public boolean isOffensive()
    {
        if (
getHandler(this.getId()) != null)
            return 
handler.isOffensive();
        else
            return 
super.isOffensive();
    }

EffectHandler.java:
PHP код:
package l2p.gameserver.skills.effects;

import l2p.gameserver.handler.ISkillHandler;
import l2p.gameserver.handler.SkillHandler;
import l2p.gameserver.model.L2Effect;
import l2p.gameserver.skills.Env;

public final class 
EffectHandler extends L2Effect
{
    private 
ISkillHandler handler null;

    public 
EffectHandler(Env envEffectTemplate template)
    {
        
super(envtemplate);
        
handler SkillHandler.getInstance().getSkillHandler(this.getSkill().getId());
        
        if (
handler == null)
            
_log.warning("Warning: Not found skill handler for skill " this.getSkill().getId() + ", effect");
    }

    @
Override
    
public boolean checkCondition()
    {
        if (
handler != null && handler.checkCondition(this_effector_effected))        
            return 
super.checkCondition();
        else
            return 
false;
    }

    @
Override
    
public void onStart()
    {
        
super.onStart();

        if (
handler != null)
            
handler.onStart(this_effector_effected);
    }

    @
Override
    
public void onExit()
    {
        
super.onExit();

        if (
handler != null)
            
handler.onExit(this_effector_effected);
    }

    @
Override
    
public boolean onActionTime()
    {
        if (
handler != null)        
            return 
handler.onActionTime(this_effector_effected);
        else
            return 
false;
    }


Как зарегистрировать новые класс (HANDLER) и эффект (Handler) скилла в ядре - объяснять уж не буду - это делается легко и просто.

Ну и пример того, как это все работает:

Объявление самого скилла:
PHP код:
    <skill id="7068" levels="1" name="Test Skill">
        <
set name="target" val="TARGET_ONE" />
        <
set name="skillType" val="HANDLER" />
        <
set name="operateType" val="OP_ACTIVE" />
        <for>
            <
effect count="5" name="Handler" time="3" val="0" />
        </for>
    </
skill
Обработчик методов для этого скилла:
PHP код:
package handlers.skills;

import l2p.extensions.scripts.ScriptFile;
import l2p.gameserver.handler.ISkillHandler;
import l2p.gameserver.handler.SkillHandler;
import l2p.gameserver.model.L2Character;
import l2p.gameserver.model.L2Effect;
import l2p.gameserver.model.L2Skill;
import l2p.util.GArray;

/**
 * Пример работы хэндлера, прицепленного к умению.<br>
 * Ничего не делает кроме вывода разных сообщений о том, какой из методов хэндлера сработал при работе умения.
 * <br><br>
 * Для того, чтобы вызывались методы checkCondition(L2Skill skill, ...), isUseAdditionalCheck(), isOffensive() и useSkill(L2Skill skill, ...), 
 * необходимо чтобы умение, к которому прикреплен хэндлер, имело тип HANDLER. 
 * <br><br>
 * Для того, чтобы вызывались методы checkCondition(L2Effect effect, ...), onStart(L2Effect effect, ...), onExit(L2Effect effect, ...) и
 * onActionTime(L2Effect effect, ...), необходимо чтобы в умении, к которому прикреплен хэндлер, имелся эффект с именем Handler.
 * 
 * @author Gaikotsu
 */
public class Sample implements ISkillHandlerScriptFile
{
    private static final 
int[] _skillIds = { 7068 };

    
/**
     * Проверка возможности использовать умение на заданную цель. 
     * 
     * @param skill        - умение
     * @param caster    - персонаж, кастующий умение
     * @param target    - цель, на которую используется умение
     * @param forceUse    - форсированое использование умения (через Ctrl) или обычное
     * 
     * @return        - true - умение можно использовать, false - нельзя
     * <br><br>
     * Если метод isUseAdditionalCheck() хэндлера возвращает true, то после проверок в этом методе, дополнительно будет 
     * вызван одноименный метод и родительского класса (метод из L2Skill), который проведет дополнительно стандартные проверки на
     * возможность использования умения на эту цель.
     */
    
@Override
    
public boolean checkCondition(L2Skill skillL2Character casterL2Character targetboolean forceUse)
    {
        if (
caster != null && caster.isPlayer())
            
caster.getPlayer().sendMessage("skill class: method - checkCondition, caster - " caster.getName() + ", target - " target.getName());
        
        return 
true;
    }

    
/**
     * Возвращает признак того, надо ли делать дополнительные проверки возможности использовать умение на заданную цель.
     * 
     * @return    - true - проверки проводить надо, false - дополнительные проверки не требуются
     */
    
@Override
    
public boolean isUseAdditionalCheck()
    {
        return 
true;
    }

    
/**
     * Возвращает признак того, является ли умение "плохим" (вызывающим PvP-флаг).
     * 
     * @return        - true - умение "плохое", false - умение "хорошее"
     */
    
@Override
    
public boolean isOffensive()
    {
        return 
false;
    }

    
/**
     * Использование умения на список целей.
     * 
     * @param skill        - умение
     * @param caster    - персонаж, кастующий умение
     * @param targets    - список целей, на которые используется умение
     */
    
@Override
    
public void useSkill(L2Skill skillL2Character casterGArray<L2Charactertargets)
    {
        if (
caster != null && caster.isPlayer())
        {
            
String _targets "";
            
            for (
L2Character target targets)
                
_targets _targets target.getName() + " ";
            
            
caster.getPlayer().sendMessage("skill class: method - useSkill, caster - " caster.getName() + ", target(s) - " _targets);
                
            for (
L2Character target targets)
                
skill.getEffects(castertargetfalsefalse);
        }
    }

    
/**
     * Проверка возможности использовать эффект на заданную цель.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, накладывающий эффект
     * @param target    - цель, на которую накладывается эффект
     * 
     * @return        - true - эффект можно использовать, false - нельзя
     */
    
@Override
    
public boolean checkCondition(L2Effect effectL2Character casterL2Character target)
    {
        if (
caster != null && caster.isPlayer())
            
caster.getPlayer().sendMessage("skill effect: method - checkCondition, caster - " caster.getName() + ", target - " target.getName());
        
        return 
true;
    }

    
/**
     * Вызывается при начале работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     */
    
@Override
    
public void onStart(L2Effect effectL2Character casterL2Character target)
    {
        if (
caster != null && caster.isPlayer())
            
caster.getPlayer().sendMessage("skill effect: method - onStart, caster - " caster.getName() + ", target - " target.getName());
    }

    
/**
     * Вызывается при окончании работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     */
    
@Override
    
public void onExit(L2Effect effectL2Character casterL2Character target)
    {
        if (
caster != null && caster.isPlayer())
            
caster.getPlayer().sendMessage("skill effect: method - onExit, caster - " caster.getName() + ", target - " target.getName());
    }

    
/**
     * Вызывается периодически во время действия эффекта.<br>
     * Количество и частота вызовов задается в самом описании эффекта в умении (параметры count и time).<br>
     * Возвращает возможность дальнейшей работы эффекта.
     * 
     * @param effect    - эффект
     * @param caster    - персонаж, наложивший эффект
     * @param target    - цель, на которую действует эффект
     * 
     * @return        - true - эффект может работать дальше, false - работу эффекта необходимо прервать незамедлительно
     */
    
@Override
    
public boolean onActionTime(L2Effect effectL2Character casterL2Character target)
    {
        if (
caster != null && caster.isPlayer())
            
caster.getPlayer().sendMessage("skill effect: method - onActionTime, caster - " caster.getName() + ", target - " target.getName());
        
        return 
true;
    }

    
/**
     * Возвращает список умений, на которые зарегистрирован хэндлер.
     * 
     * @return        - список умений в виде их идентификаторов
     */
    
@Override
    
public int[] getSkillIds()
    {
        return 
_skillIds;
    }

    @
Override
    
public void onLoad()
    {
        
SkillHandler.getInstance().registerSkillHandler(this);
    }

    @
Override
    
public void onReload()
    {}

    @
Override
    
public void onShutdown()
    {}


P.S. С наступающим всех.
Gaikotsu вне форума Ответить с цитированием
Непрочитано 22.12.2011, 22:30   #2
Забанен за кидаловo/обман/развод

По умолчанию Re: [share] Skill Handlers

Экстрасенс? ЧИТАЕШЬ МЫСЛИ?!!! ))))) Была идея, не-добрался пока...
От души!!!
KilRoy вне форума Отправить сообщение для KilRoy с помощью ICQ Отправить сообщение для KilRoy с помощью Skype™ Ответить с цитированием
Непрочитано 06.04.2012, 23:54   #3
Аватар для ruslanback
Пользователь

По умолчанию Re: [share] Skill Handlers

Кто может под Ил это?Спасибо.
ruslanback вне форума Отправить сообщение для ruslanback с помощью ICQ Ответить с цитированием
Непрочитано 07.04.2012, 00:11   #4
Забанен за кидаловo/обман/развод

По умолчанию Re: [share] Skill Handlers

Цитата:
Сообщение от ruslanback Посмотреть сообщение
Кто может под Ил это?Спасибо.
СФ может Не за что.
KilRoy вне форума Отправить сообщение для KilRoy с помощью ICQ Отправить сообщение для KilRoy с помощью Skype™ Ответить с цитированием
Непрочитано 10.04.2012, 09:07   #5
Аватар для rage
Герой

По умолчанию Re: [share] Skill Handlers

Идея со скиллтайпом и хендлерами к ним в корне не верная, так что в корзину.
rage вне форума Ответить с цитированием
Непрочитано 10.04.2012, 09:37   #6
Аватар для bloodshed
Герой

По умолчанию Re: [share] Skill Handlers

Цитата:
Сообщение от rage Посмотреть сообщение
Идея со скиллтайпом и хендлерами к ним в корне не верная, так что в корзину.
Аргументируйте свою точку зрения.
__________________
bloodshed вне форума Отправить сообщение для bloodshed с помощью ICQ Отправить сообщение для bloodshed с помощью Skype™ Ответить с цитированием
Непрочитано 10.04.2012, 11:05   #7
Аватар для rage
Герой

По умолчанию Re: [share] Skill Handlers

Посмотрите офф скиллдату, там нет "типов скилов". Типы скилов придумали в л2ж и пытаются с помощью "типа и таргета" описать то, на что в офф скиллдате 4 параметра.
От сюда и тянется кривая работа почти всех скиллов, тонны говнокогда, багов и ужасной НЕ гибкости в описании скиллов.
rage вне форума Ответить с цитированием
Сказали спасибо:
Ответ

Метки
handler, phoenix, skill, геодата бункера


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Skill mastery HastemaNS Lineage II 0 15.02.2011 10:47
Skill tree ProX Сервер 3 13.10.2010 20:53
Как зделать skill [Red Dragon] Курилка / Yak floor 5 10.08.2010 00:32
skill's 81+ Rakitmiha Lineage II 6 31.10.2009 22:51
Skill not implemented. Skill id: **** NOTDONE Raincast Lineage II 3 16.03.2009 20:22


© 2007–2020 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 13:41. Часовой пояс GMT +3.

Вверх