TriggerSkillByDamageReceived

Psycho

I salute the valkyries calling me home!
Легенда
Орден Золотого Заката
Сообщения
5 278
Розыгрыши
1
Решения
6
Репутация
4 533
Реакции
3 798
Баллы
2 648
Хроники
  1. Salvation
Исходники
Присутствуют
Сборка
мобиус
Не могу понять что не так. Почему-то не срабатывает.
Проверяю на шилке 788, 5564.
Полностью исправно работает, если перса будет бить другой перс, но не работает, если тебя бьет пачка мобов, не важно какого лвла.
Шанс выкручен в сотку для дебага.

Код:
[27/09 10:07:30] 🎯 TRIGGER SKILL BY DAMAGE RECEIVED - EVENT CAUGHT
[27/09 10:07:30] 🎯 Effect Skill ID: 5564
[27/09 10:07:30] 🎯 MinDamage: 1, Chance: 100
[27/09 10:07:30] 🎯 AttackerType: Creature
[27/09 10:07:30] 🎯 Actual Damage: 8.0
[27/09 10:07:30] ✅ ALL CHECKS PASSED for skill 5564
[27/09 10:07:30] ✅ Target acquired: Player:ШК[268492931]
[27/09 10:07:30] ✅ BuffInfo for skill 5564: null
[27/09 10:07:30] ✅ Using base skill level: 1


XML:
    <skill id="788" toLevel="1" name="Pain of Shilen">
        <icon>icon.skill0788</icon>
        <operateType>A2</operateType>
        <targetType>SELF</targetType>
        <abnormalLevel>1</abnormalLevel>
        <abnormalTime>60</abnormalTime>
        <abnormalType>SEED_OF_KNIGHT</abnormalType>
        <affectScope>SINGLE</affectScope>
        <basicProperty>NONE</basicProperty>
        <effectPoint>138</effectPoint>
        <hitTime>2500</hitTime>
        <isMagic>1</isMagic> <!-- Magic Skill -->
        <magicCriticalRate>5</magicCriticalRate>
        <magicLevel>83</magicLevel>
        <mpConsume>29</mpConsume>
        <mpInitialConsume>8</mpInitialConsume>
        <reuseDelay>15000</reuseDelay>
        <effects>
            <effect name="TriggerSkillByDamageReceived">
                <!-- Pain of Shillien -->
                <attackerType>Creature</attackerType>
                <chance>100</chance>
                <targetType>SELF</targetType>
                <minDamage>1</minDamage>
                <skillId>5564</skillId> <!-- Pain of Shilen -->
                <skillLevel>1</skillLevel>
            </effect>
            <effect name="CriticalDamage">
                <amount>10</amount>
                <mode>PER</mode>
            </effect>
        </effects>
    </skill>

    <skill id="5564" toLevel="3" name="Pain of Shilen">
        <icon>
            <value level="1">icon.skill0788</value>
            <value level="2">icon.skill0788_2</value>
            <value level="3">icon.skill0788_3</value>
        </icon>
        <operateType>A2</operateType>
        <targetType>TARGET</targetType>
        <abnormalLevel>
            <value level="1">2</value>
            <value level="2">3</value>
            <value level="3">4</value>
        </abnormalLevel>
        <abnormalTime>20</abnormalTime>
        <abnormalType>SEED_OF_KNIGHT</abnormalType>
        <affectScope>SINGLE</affectScope>
        <basicProperty>NONE</basicProperty>
        <castRange>400</castRange>
        <effectRange>900</effectRange>
        <isMagic>4</isMagic> <!-- Item Skill -->
        <isTriggeredSkill>true</isTriggeredSkill>
        <magicCriticalRate>-5</magicCriticalRate>
        <magicLevel>81</magicLevel>
        <effects>
            <effect name="TriggerSkillByDamageReceived">
                <!-- Pain of Shillien -->
                <attackerType>Creature</attackerType>
                <chance>
                    <value level="1">10</value>
                    <value level="2">10</value>
                    <value level="3">0</value>
                </chance>
                <targetType>SELF</targetType>
                <minDamage>1</minDamage>
                <skillId>5564</skillId> <!-- Pain of Shilen -->
                <skillLevel>
                    <value level="1">2</value>
                    <value level="2">3</value>
                    <value level="3">0</value>
                </skillLevel>
            </effect>
            <effect name="VampiricAttack" fromLevel="3" toLevel="3">
                <amount>8</amount>
                <chance>30</chance>
            </effect>
            <effect name="CriticalDamage">
                <amount>20</amount>
                <mode>PER</mode>
            </effect>
            <effect name="AttackAttribute">
                <amount>
                    <value level="1">0</value>
                    <value level="2">20</value>
                    <value level="3">20</value>
                </amount>
                <attribute>WIND</attribute>
            </effect>
        </effects>
    </skill>

Java:
package handlers.effecthandlers;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;

import l2j.commons.util.Rnd;
import l2j.gameserver.data.xml.SkillData;
import l2j.gameserver.handler.TargetHandler;
import l2j.gameserver.model.StatSet;
import l2j.gameserver.model.WorldObject;
import l2j.gameserver.model.actor.Creature;
import l2j.gameserver.model.actor.enums.creature.InstanceType;
import l2j.gameserver.model.effects.AbstractEffect;
import l2j.gameserver.model.events.EventType;
import l2j.gameserver.model.events.holders.actor.creature.OnCreatureDamageReceived;
import l2j.gameserver.model.events.listeners.ConsumerEventListener;
import l2j.gameserver.model.item.instance.Item;
import l2j.gameserver.model.skill.BuffInfo;
import l2j.gameserver.model.skill.Skill;
import l2j.gameserver.model.skill.SkillCaster;
import l2j.gameserver.model.skill.enums.SkillFinishType;
import l2j.gameserver.model.skill.holders.SkillHolder;
import l2j.gameserver.model.skill.targets.TargetType;

/**
 * Trigger skill by damage received effect implementation.
 * @author UnAfraid
 */
public class TriggerSkillByDamageReceived extends AbstractEffect
{
    private final int _minAttackerLevel;
    private final int _maxAttackerLevel;
    private final int _minDamage;
    private final int _chance;
    private final int _hpPercent;
    private final SkillHolder _skill;
    private final TargetType _targetType;
    private final InstanceType _attackerType;
    private final int _skillLevelScaleTo;
    private final List<SkillHolder> _triggerSkills;
   
    public TriggerSkillByDamageReceived(StatSet params)
    {
        _minAttackerLevel = params.getInt("minAttackerLevel", 1);
        _maxAttackerLevel = params.getInt("maxAttackerLevel", Integer.MAX_VALUE);
        _minDamage = params.getInt("minDamage", 1);
        _chance = params.getInt("chance", 100);
        _hpPercent = params.getInt("hpPercent", 100);
        _skill = new SkillHolder(params.getInt("skillId", 0), params.getInt("skillLevel", 1));
        _targetType = params.getEnum("targetType", TargetType.class, TargetType.SELF);
        _attackerType = params.getEnum("attackerType", InstanceType.class, InstanceType.Creature);
        _skillLevelScaleTo = params.getInt("skillLevelScaleTo", 0);
       
        // Specific skills by level.
        final String triggerSkills = params.getString("triggerSkills", "");
        if (triggerSkills.isEmpty())
        {
            _triggerSkills = null;
        }
        else
        {
            final String[] split = triggerSkills.split(";");
            _triggerSkills = new ArrayList<>(split.length);
            for (String skill : split)
            {
                final String[] splitSkill = skill.split(",");
                _triggerSkills.add(new SkillHolder(Integer.parseInt(splitSkill[0]), Integer.parseInt(splitSkill[1])));
            }
        }
    }
   
    private void onDamageReceivedEvent(OnCreatureDamageReceived event)
    {
        LOGGER.info("🎯 TRIGGER SKILL BY DAMAGE RECEIVED - EVENT CAUGHT");
        LOGGER.info("🎯 Effect Skill ID: " + _skill.getSkillId());
        LOGGER.info("🎯 MinDamage: " + _minDamage + ", Chance: " + _chance);
        LOGGER.info("🎯 AttackerType: " + _attackerType);
        LOGGER.info("🎯 Actual Damage: " + event.getDamage());

        if (event.isDamageOverTime() || (_chance == 0) || ((_triggerSkills == null) && ((_skill.getSkillId() == 0) || (_skill.getSkillLevel() == 0))))
        {
            LOGGER.info("❌ FAIL: DOT or invalid chance/skill");
            return;
        }

        if (event.getAttacker() == event.getTarget())
        {
            LOGGER.info("❌ FAIL: self damage");
            return;
        }

        if ((event.getAttacker().getLevel() < _minAttackerLevel) || (event.getAttacker().getLevel() > _maxAttackerLevel))
        {
            LOGGER.info("❌ FAIL: attacker level mismatch");
            return;
        }

        if (_minDamage > 0 && event.getDamage() < _minDamage)
        {
            LOGGER.info("❌ FAIL: Damage too low - " + event.getDamage() + " < " + _minDamage);
            return;
        }
       
        if ((_chance < 100) && (Rnd.get(100) > _chance))
        {
            return;
        }
       
        if ((_hpPercent < 100) && (event.getTarget().getCurrentHpPercent() > _hpPercent))
        {
            return;
        }
       
        if (!event.getAttacker().getInstanceType().isType(_attackerType))
        {
            return;
        }
        LOGGER.info("✅ ALL CHECKS PASSED for skill " + _skill.getSkillId());
        WorldObject target = null;
        try
        {
            target = TargetHandler.getInstance().getHandler(_targetType).getTarget(event.getTarget(), event.getAttacker(), _triggerSkills == null ? _skill.getSkill() : _triggerSkills.get(0).getSkill(), false, false, false);
        }
        catch (Exception e)
        {
            LOGGER.log(Level.WARNING, "Exception in ITargetTypeHandler.getTarget(): " + e.getMessage(), e);
        }
       
        if ((target == null) || !target.isCreature())
        {
            LOGGER.info("❌ FAIL: target is null or not creature");
            return;
        }
       
        Skill triggerSkill = null;
        if (_triggerSkills == null)
        {
            final BuffInfo buffInfo = target.asCreature().getEffectList().getBuffInfoBySkillId(_skill.getSkillId());
            if ((_skillLevelScaleTo <= 0) || (buffInfo == null))
            {
                triggerSkill = _skill.getSkill();
            }
            else
            {
                triggerSkill = SkillData.getInstance().getSkill(_skill.getSkillId(), Math.min(_skillLevelScaleTo, buffInfo.getSkill().getLevel() + 1));
            }
           
            if ((buffInfo == null) || (buffInfo.getSkill().getLevel() < triggerSkill.getLevel()))
            {
                SkillCaster.triggerCast(event.getAttacker(), target.asCreature(), triggerSkill);
            }
        }
        else // Multiple trigger skills.
        {
            final Iterator<SkillHolder> iterator = _triggerSkills.iterator();
            while (iterator.hasNext())
            {
                final Skill nextSkill = iterator.next().getSkill();
                if (target.asCreature().isAffectedBySkill(nextSkill.getId()))
                {
                    if (iterator.hasNext())
                    {
                        target.asCreature().stopSkillEffects(SkillFinishType.SILENT, nextSkill.getId());
                        triggerSkill = iterator.next().getSkill();
                        break;
                    }
                   
                    // Already at last skill.
                    return;
                }
            }
           
            if (triggerSkill == null)
            {
                triggerSkill = _triggerSkills.get(0).getSkill();
            }
           
            SkillCaster.triggerCast(event.getAttacker(), target.asCreature(), triggerSkill);
        }
    }
   
    @Override
    public void onExit(Creature effector, Creature effected, Skill skill)
    {
        effected.removeListenerIf(EventType.ON_CREATURE_DAMAGE_RECEIVED, listener -> listener.getOwner() == this);
    }
   
    @Override
    public void onStart(Creature effector, Creature effected, Skill skill, Item item)
    {
        effected.addListener(new ConsumerEventListener(effected, EventType.ON_CREATURE_DAMAGE_RECEIVED, (OnCreatureDamageReceived event) -> onDamageReceivedEvent(event), this));
    }
}
 
Оверпостинг
Hidden text for users: Psycho


Предыдущий ответ - актуален, но я решил перепроверить в ПТС, и в целом, оба варианта "твой/мой" - мусор полный, там нету оч много условий/логики дополнительной.
А как мнимум то что я написал - это "в данный" момент основной косяк проблемы.
 
  • Люблю это
Реакции: Psycho

    Psycho

    Баллов: 50
    за помощь
*** Скрытый текст не может быть процитирован. ***

Предыдущий ответ - актуален, но я решил перепроверить в ПТС, и в целом, оба варианта "твой/мой" - мусор полный, там нету оч много условий/логики дополнительной.
А как мнимум то что я написал - это "в данный" момент основной косяк проблемы.
Hidden text for users: Bankir

То-есть этот полудурок сломал логику работы, и сделал так, чтобы к примеру 5564 применялся от имени моба? 🤦‍♂️
 
Последнее редактирование:
*** Скрытый текст не может быть процитирован. ***
То-есть этот полудурок сломал логику работы, и сделал так, чтобы к примеру 5564 применялся от имени моба? 🤦‍♂️
Я уже несколько раз писал на форуме, что таргеты и определение цели (от кого, кто, кому) - все это сломано, но у меня зафиксили.
Да много жопочасов и не понимания/дебага было впорото.
Если в глобальном проанализировать таргеты - вы в целом просто оху*** от реализации и того что они делают (там ограничений почти нет - грубо и не понятно описал, после анализа кода - станет и вам понятнее).
Но догма такова - все возможно пофиксить, годом ранее, позже :ROFLMAO: :ROFLMAO::ROFLMAO::ROFLMAO::ROFLMAO::ROFLMAO::ROFLMAO:

Hidden text for users: Psycho
 
Назад
Сверху