Обработка каста l2jmobius

Reboot

Знаменитый
Пользователь
Сообщения
51
Розыгрыши
0
Репутация
1
Реакции
1
Баллы
1 250
Хроники
  1. Salvation
Исходники
Присутствуют
Сборка
L2jmobius
Всём привет. Подскажите пожалуйста, где храниться обработка каста игрока, к примеру если скилл имеет тип Single, в хандлерах нет никаких условий, а хотелось бы добавить к примеру без контрол, если персонаж флагнут, то его нельзя хилить
 
Reboot, походу все хардкор проверки (и не только) при юзе/касте умения находятся тут:



 

    Reboot

    Баллов: 10
    Спасибо, но не совсем то
Странно, ни там, ни там, ни в ДП скриптах не нашел то, что нужно.
К примеру, мы имеем скилл:
Код:
<skill id="11755" toLevel="13" name="Radiant Heal">
        <!-- Recovers target's HP with $s1 power. If HP is full, recovers CP. <The character is targeted automatically> -->
        <icon>icon.skill11755</icon>
        <operateType>A1</operateType>
        <magicLevel>
            <value level="1">85</value>
            <value level="2">86</value>
            <value level="3">88</value>
            <value level="4">90</value>
            <value level="5">92</value>
            <value level="6">94</value>
            <value level="7">96</value>
            <value level="8">98</value>
            <value level="9">101</value>
            <value level="10">103</value>
            <value level="11">105</value>
            <value level="12">107</value>
            <value level="13">109</value>
        </magicLevel>
        <mpConsume>
            <value level="1">110</value>
            <value level="2">110</value>
            <value level="3">113</value>
            <value level="4">114</value>
            <value level="5">117</value>
            <value level="6">118</value>
            <value level="7">121</value>
            <value level="8">122</value>
            <value level="9">123</value>
            <value level="10">124</value>
            <value level="11">126</value>
            <value level="12">128</value>
            <value level="13">130</value>
        </mpConsume>
        <castRange>600</castRange>
        <effectPoint>
            <value level="1">867</value>
            <value level="2">874</value>
            <value level="3">886</value>
            <value level="4">895</value>
            <value level="5">902</value>
            <value level="6">909</value>
            <value level="7">918</value>
            <value level="8">927</value>
            <value level="9">935</value>
            <value level="10">944</value>
            <value level="11">952</value>
            <value level="12">960</value>
            <value level="13">969</value>
        </effectPoint>
        <effectRange>1100</effectRange>
        <hitTime>4500</hitTime>
        <coolTime>500</coolTime>
        <reuseDelay>3000</reuseDelay>
        <isMagic>1</isMagic>
        <magicCriticalRate>
            <value fromLevel="1" toLevel="13">5</value>
            <value fromLevel="7" toLevel="13" fromSubLevel="2001" toSubLevel="2020">{base + (base / 100 * subIndex)}</value>
        </magicCriticalRate>
        <hitCancelTime>1</hitCancelTime>
        <mpInitialConsume>
            <value level="1">28</value>
            <value level="2">28</value>
            <value level="3">28</value>
            <value level="4">29</value>
            <value level="5">29</value>
            <value level="6">30</value>
            <value level="7">30</value>
            <value level="8">31</value>
            <value level="9">32</value>
            <value level="10">33</value>
            <value level="11">34</value>
            <value level="12">35</value>
            <value level="13">36</value>
        </mpInitialConsume>
        <targetType>TARGET</targetType>
        <affectScope>SINGLE</affectScope>
        <effects>
            <effect name="HpCpHeal">
                <power>
                    <value level="1">1488</value>
                    <value level="2">1495</value>
                    <value level="3">1507</value>
                    <value level="4">1519</value>
                    <value level="5">1532</value>
                    <value level="6">1544</value>
                    <value level="7">1557</value>
                    <value level="8">1570</value>
                    <value level="9">1749</value>
                    <value level="10">1763</value>
                    <value level="11">1777</value>
                    <value level="12">1793</value>
                    <value level="13">1809</value>
                    <value fromLevel="7" toLevel="13" fromSubLevel="1001" toSubLevel="1020">{base + (base / 100 * subIndex)}</value>
                </power>
            </effect>
        </effects>
    </skill>
Который имеет такие параметры:

Код:
        <targetType>TARGET</targetType>
        <affectScope>SINGLE</affectScope>

Соответственно идем в хандлер сингл:
Код:
/*
 * This file is part of the L2J Mobius project.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package handlers.targethandlers.affectscope;

import java.util.function.Consumer;

import org.l2jmobius.gameserver.handler.AffectObjectHandler;
import org.l2jmobius.gameserver.handler.IAffectObjectHandler;
import org.l2jmobius.gameserver.handler.IAffectScopeHandler;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.skill.Skill;
import org.l2jmobius.gameserver.model.skill.targets.AffectScope;
import org.l2jmobius.gameserver.model.skill.targets.TargetType;

/**
 * Single target affect scope implementation.
 * @author Nik
 */
public class Single implements IAffectScopeHandler
{
    @Override
    public void forEachAffected(Creature creature, WorldObject target, Skill skill, Consumer<? super WorldObject> action)
    {
        final IAffectObjectHandler affectObject = AffectObjectHandler.getInstance().getHandler(skill.getAffectObject());
        
        if (target.isCreature())
        {
            if (skill.getTargetType() == TargetType.GROUND)
            {
                action.accept(creature); // Return yourself to mark that effects can use your current skill's world position.
            }
            if (((affectObject == null) || affectObject.checkAffectedObject(creature, (Creature) target)))
            {
                action.accept(target); // Return yourself to mark that effects can use your current skill's world position.
            }
        }
        else if (target.isItem())
        {
            action.accept(target); // Return yourself to mark that effects can use your current skill's world position.
        }
    }
    
    @Override
    public Enum<AffectScope> getAffectScopeType()
    {
        return AffectScope.SINGLE;
    }
}

Ни одной проверки, ни на ПК, ни на флаг, дальше идем в хандлер TARGET:

Код:
/*
 * This file is part of the L2J Mobius project.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package handlers.targethandlers;

import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.handler.ITargetTypeHandler;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.skill.Skill;
import org.l2jmobius.gameserver.model.skill.targets.TargetType;
import org.l2jmobius.gameserver.network.SystemMessageId;

/**
 * Any friendly selected target or enemy if force use. Works on dead targets or doors as well.
 * @author Nik
 */
public class Target implements ITargetTypeHandler
{
    @Override
    public Enum<TargetType> getTargetType()
    {
        return TargetType.TARGET;
    }
    
    @Override
    public WorldObject getTarget(Creature creature, WorldObject selectedTarget, Skill skill, boolean forceUse, boolean dontMove, boolean sendMessage)
    {
        if (selectedTarget == null)
        {
            return null;
        }
        
        if (!selectedTarget.isCreature())
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.INVALID_TARGET);
            }
            return null;
        }
        
        final Creature target = (Creature) selectedTarget;
        
        // You can always target yourself.
        if (creature == target)
        {
            return target;
        }
        
        // Check for cast range if character cannot move. TODO: char will start follow until within castrange, but if his moving is blocked by geodata, this msg will be sent.
        if (dontMove && (creature.calculateDistance2D(target) > skill.getCastRange()))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.THE_DISTANCE_IS_TOO_FAR_AND_SO_THE_CASTING_HAS_BEEN_CANCELLED);
            }
            
            return null;
        }
        
        if (skill.isFlyType() && !GeoEngine.getInstance().canMoveToTarget(creature.getX(), creature.getY(), creature.getZ(), target.getX(), target.getY(), target.getZ(), creature.getInstanceWorld()))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.YOU_CANNOT_ATTACK_THE_TARGET);
            }
            return null;
        }
        
        // Geodata check when character is within range.
        if (!GeoEngine.getInstance().canSeeTarget(creature, target))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.CANNOT_SEE_TARGET);
            }
            
            return null;
        }
        return target;
    }
}
И тут ни одной проверки, а по идее то, ни флагнутого, ни ПК, нельзя хилить без КТРЛ? Где это обрабатывается?
 
Странно, ни там, ни там, ни в ДП скриптах не нашел то, что нужно.
К примеру, мы имеем скилл:
Код:
<skill id="11755" toLevel="13" name="Radiant Heal">
        <!-- Recovers target's HP with $s1 power. If HP is full, recovers CP. <The character is targeted automatically> -->
        <icon>icon.skill11755</icon>
        <operateType>A1</operateType>
        <magicLevel>
            <value level="1">85</value>
            <value level="2">86</value>
            <value level="3">88</value>
            <value level="4">90</value>
            <value level="5">92</value>
            <value level="6">94</value>
            <value level="7">96</value>
            <value level="8">98</value>
            <value level="9">101</value>
            <value level="10">103</value>
            <value level="11">105</value>
            <value level="12">107</value>
            <value level="13">109</value>
        </magicLevel>
        <mpConsume>
            <value level="1">110</value>
            <value level="2">110</value>
            <value level="3">113</value>
            <value level="4">114</value>
            <value level="5">117</value>
            <value level="6">118</value>
            <value level="7">121</value>
            <value level="8">122</value>
            <value level="9">123</value>
            <value level="10">124</value>
            <value level="11">126</value>
            <value level="12">128</value>
            <value level="13">130</value>
        </mpConsume>
        <castRange>600</castRange>
        <effectPoint>
            <value level="1">867</value>
            <value level="2">874</value>
            <value level="3">886</value>
            <value level="4">895</value>
            <value level="5">902</value>
            <value level="6">909</value>
            <value level="7">918</value>
            <value level="8">927</value>
            <value level="9">935</value>
            <value level="10">944</value>
            <value level="11">952</value>
            <value level="12">960</value>
            <value level="13">969</value>
        </effectPoint>
        <effectRange>1100</effectRange>
        <hitTime>4500</hitTime>
        <coolTime>500</coolTime>
        <reuseDelay>3000</reuseDelay>
        <isMagic>1</isMagic>
        <magicCriticalRate>
            <value fromLevel="1" toLevel="13">5</value>
            <value fromLevel="7" toLevel="13" fromSubLevel="2001" toSubLevel="2020">{base + (base / 100 * subIndex)}</value>
        </magicCriticalRate>
        <hitCancelTime>1</hitCancelTime>
        <mpInitialConsume>
            <value level="1">28</value>
            <value level="2">28</value>
            <value level="3">28</value>
            <value level="4">29</value>
            <value level="5">29</value>
            <value level="6">30</value>
            <value level="7">30</value>
            <value level="8">31</value>
            <value level="9">32</value>
            <value level="10">33</value>
            <value level="11">34</value>
            <value level="12">35</value>
            <value level="13">36</value>
        </mpInitialConsume>
        <targetType>TARGET</targetType>
        <affectScope>SINGLE</affectScope>
        <effects>
            <effect name="HpCpHeal">
                <power>
                    <value level="1">1488</value>
                    <value level="2">1495</value>
                    <value level="3">1507</value>
                    <value level="4">1519</value>
                    <value level="5">1532</value>
                    <value level="6">1544</value>
                    <value level="7">1557</value>
                    <value level="8">1570</value>
                    <value level="9">1749</value>
                    <value level="10">1763</value>
                    <value level="11">1777</value>
                    <value level="12">1793</value>
                    <value level="13">1809</value>
                    <value fromLevel="7" toLevel="13" fromSubLevel="1001" toSubLevel="1020">{base + (base / 100 * subIndex)}</value>
                </power>
            </effect>
        </effects>
    </skill>
Который имеет такие параметры:

Код:
        <targetType>TARGET</targetType>
        <affectScope>SINGLE</affectScope>

Соответственно идем в хандлер сингл:
Код:
/*
 * This file is part of the L2J Mobius project.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package handlers.targethandlers.affectscope;

import java.util.function.Consumer;

import org.l2jmobius.gameserver.handler.AffectObjectHandler;
import org.l2jmobius.gameserver.handler.IAffectObjectHandler;
import org.l2jmobius.gameserver.handler.IAffectScopeHandler;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.skill.Skill;
import org.l2jmobius.gameserver.model.skill.targets.AffectScope;
import org.l2jmobius.gameserver.model.skill.targets.TargetType;

/**
 * Single target affect scope implementation.
 * @author Nik
 */
public class Single implements IAffectScopeHandler
{
    @Override
    public void forEachAffected(Creature creature, WorldObject target, Skill skill, Consumer<? super WorldObject> action)
    {
        final IAffectObjectHandler affectObject = AffectObjectHandler.getInstance().getHandler(skill.getAffectObject());
       
        if (target.isCreature())
        {
            if (skill.getTargetType() == TargetType.GROUND)
            {
                action.accept(creature); // Return yourself to mark that effects can use your current skill's world position.
            }
            if (((affectObject == null) || affectObject.checkAffectedObject(creature, (Creature) target)))
            {
                action.accept(target); // Return yourself to mark that effects can use your current skill's world position.
            }
        }
        else if (target.isItem())
        {
            action.accept(target); // Return yourself to mark that effects can use your current skill's world position.
        }
    }
   
    @Override
    public Enum<AffectScope> getAffectScopeType()
    {
        return AffectScope.SINGLE;
    }
}

Ни одной проверки, ни на ПК, ни на флаг, дальше идем в хандлер TARGET:

Код:
/*
 * This file is part of the L2J Mobius project.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package handlers.targethandlers;

import org.l2jmobius.gameserver.geoengine.GeoEngine;
import org.l2jmobius.gameserver.handler.ITargetTypeHandler;
import org.l2jmobius.gameserver.model.WorldObject;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.skill.Skill;
import org.l2jmobius.gameserver.model.skill.targets.TargetType;
import org.l2jmobius.gameserver.network.SystemMessageId;

/**
 * Any friendly selected target or enemy if force use. Works on dead targets or doors as well.
 * @author Nik
 */
public class Target implements ITargetTypeHandler
{
    @Override
    public Enum<TargetType> getTargetType()
    {
        return TargetType.TARGET;
    }
   
    @Override
    public WorldObject getTarget(Creature creature, WorldObject selectedTarget, Skill skill, boolean forceUse, boolean dontMove, boolean sendMessage)
    {
        if (selectedTarget == null)
        {
            return null;
        }
       
        if (!selectedTarget.isCreature())
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.INVALID_TARGET);
            }
            return null;
        }
       
        final Creature target = (Creature) selectedTarget;
       
        // You can always target yourself.
        if (creature == target)
        {
            return target;
        }
       
        // Check for cast range if character cannot move. TODO: char will start follow until within castrange, but if his moving is blocked by geodata, this msg will be sent.
        if (dontMove && (creature.calculateDistance2D(target) > skill.getCastRange()))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.THE_DISTANCE_IS_TOO_FAR_AND_SO_THE_CASTING_HAS_BEEN_CANCELLED);
            }
           
            return null;
        }
       
        if (skill.isFlyType() && !GeoEngine.getInstance().canMoveToTarget(creature.getX(), creature.getY(), creature.getZ(), target.getX(), target.getY(), target.getZ(), creature.getInstanceWorld()))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.YOU_CANNOT_ATTACK_THE_TARGET);
            }
            return null;
        }
       
        // Geodata check when character is within range.
        if (!GeoEngine.getInstance().canSeeTarget(creature, target))
        {
            if (sendMessage)
            {
                creature.sendPacket(SystemMessageId.CANNOT_SEE_TARGET);
            }
           
            return null;
        }
        return target;
    }
}
И тут ни одной проверки, а по идее то, ни флагнутого, ни ПК, нельзя хилить без КТРЛ? Где это обрабатывается?
У мобиуса нет реализации того, что ты хочешь
 
Ясно, тогда может подскажите, где и каким образом это реализовать?
Что именно необходимо реализовать? Что бы энеми можно было хилить без зажатого ктрл или что бы при выделенном таргете персонаж продолжал хилить себя?
 

    Reboot

    Баллов: 10
    спасибо
Что именно необходимо реализовать? Что бы энеми можно было хилить без зажатого ктрл или что бы при выделенном таргете персонаж продолжал хилить себя?
Наоборот, чтобы ПК и флагнутых игроков нельзя было хилить никак, ни с КТРЛ, ни без него

Наверное проще всем хил скилам переделать таргет скила и вписать туда Friend?
 
Наоборот, чтобы ПК и флагнутых игроков нельзя было хилить никак, ни с КТРЛ, ни без него
не лучше тогда тут поставить проверку на флаг/пк?


или соседний класс HealPercent там же

как я понял, в методе instant аргументы effector - кто хилит, effected - кого хилят
 
Последнее редактирование:
Наоборот, чтобы ПК и флагнутых игроков нельзя было хилить никак, ни с КТРЛ, ни без него

Наверное проще всем хил скилам переделать таргет скила и вписать туда Friend?
1. Самый простой способ. В общую проверку юза умений в раздел умений на таргет создать условие, что есть определенный список умений который нельзя юзать на флаг > 0.
Выносишь этот список под конфиг. Ну и наполняешь его нужными умениями и будет пофигу что это за скилл хилл не хилл главное все id выписать.

2. Способ уже интереснее. Во все классы хиллов пропихать проверку под конфиг на флаг > 0. (Как предложил Оби.)

3. Этот способ немного посложнее.
Создать отдельное условие true/false и вынести в наполнение xml. Прописываем необходимые условия и выносим в xml нужную строчку. Будет что-то вроде: <set name="UseSkillTargetPvpFlag" val="True"/>

Ну и еще можно пяток вариантов реализовать, но дальше уже сам додумывай :)

Самое правильное по моему мнению реализовать по 3 варианту, так как это будет подниматься с загрузкой сборки и больше не парить никаким образом код.
 

    Reboot

    Баллов: 10
    спасибо
Проверки должны быть в AffectObject в функции checkAffectedObject
 
может просто в хандлерах хеала добавить костыль для проверки и покончить с этим?

на пример: Heal.java
воткнуть это, где проверка

JavaScript:
public void instant(Creature effector, Creature effected, Skill skill, Item item)
{
    if (effector.isPlayer() && ((effected.getPvpFlag() > 0) || (effected.getReputation() < 0)))
    {
         return;
    }
    бла, бла, бла, .....
}
не круто но своё дела сделает, банки шманки будут хилить но игрок не сможет

А вообще вопрос, почему нельзя хилить флагнутого игрока если он на пример ПвП зоне или во время клан-вара?
 
Последнее редактирование:
Назад
Сверху Снизу