SkillEffectHandler - skill effect handler system

Lets you write skill logic in scripts without touching core. All custom logic goes into separate classes in scripts/handler/skills/


Where to put handlers:
scripts/handler/skills/MyHandler.java

Three effect types:
i_call_handler - onStart only. One-shot effects.
p_call_handler - onStart + onExit. Buffs with cleanup logic.
t_call_handler - onStart + onExit + onActionTime. Periodic effects.


Connecting in skill XML

One-shot effect:
Code:
<effect name="i_call_handler" time="0" val="0">
    <def name="handler" val="MyHandler"/>
</effect>

Persistent buff:
Code:
<effect name="p_call_handler" time="60" val="0">
    <def name="handler" val="MyHandler"/>
</effect>

Periodic tick every 3 seconds, 10 times:
Code:
<effect name="t_call_handler" time="3" count="10" val="0">
    <def name="handler" val="MyHandler"/>
</effect>

The value of def name="handler" must match the handler class name exactly.


Basic handler template:
Code:
public class MyHandler extends AbstractSkillEffect
{
    @Override
    public void onStart(Effect effect)
    {
        Creature effected = effect.getEffected();
        Creature effector = effect.getEffector();

        // your logic
    }
}

Override only the methods you need. All methods have no-op defaults.

Example 1 - one-shot effect

XML:
Code:
<effect name="i_call_handler" time="0" val="0">
    <def name="handler" val="SummonCubic"/>
</effect>

Handler:
Code:
public class SummonCubic extends AbstractSkillEffect
{
    @Override
    public void onStart(Effect effect)
    {
        Creature effected = effect.getEffected();

        if (effected == null || effected.isDead())
            return;

        // logic
    }
}


Example 2 - persistent buff

XML:
Code:
<effect name="p_call_handler" time="60" val="0">
    <def name="handler" val="MyBuff"/>
</effect>

Handler:
Code:
public class MyBuff extends AbstractSkillEffect
{
    @Override
    public void onStart(Effect effect)
    {
        if (!effect.getEffected().isPlayer())
            return;

        // logic on application
    }

    @Override
    public void onExit(Effect effect)
    {
        if (!effect.getEffected().isPlayer())
            return;

        // cleanup on removal
    }
}


Example 3 - periodic tick

XML:
Code:
<effect name="t_call_handler" time="3" count="10" val="0">
    <def name="handler" val="MyDoT"/>
</effect>

Handler:
Code:
public class MyDoT extends AbstractSkillEffect
{
    @Override
    public boolean onActionTime(Effect effect)
    {
        if (effect.getEffected().isDead())
            return false; // false = cancel early

        // periodic logic

        return true; // true = keep ticking
    }

    @Override
    public void onExit(Effect effect)
    {
        // called once on removal
    }
}


Example 4 - blocking application

Code:
@Override
public boolean checkCondition(Effect effect)
{
    if (!effect.getEffected().isPlayer())
        return false;

    if (effect.getEffected().isDead())
        return false;

    return true;
}

What is available inside a handler:
effect.getEffected() - effect target (Creature)
effect.getEffector() - caster (Creature)
effect.getSkill() - skill object
effect.getSkill().getId() - skill ID
effect.getSkill().getLevel() - skill level
effect.calc() - the val value from the effect XML
effect.getTimeLeft() - remaining duration in seconds
 
Back
Top