HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > Общие вопросы программирования
   
 
 
Опции темы Поиск в этой теме Опции просмотра

  #2  
Старый 06.04.2016, 03:37
Wolfer
Участник форума
Регистрация: 05.04.2016
Сообщений: 222
С нами: 5318817

Репутация: 0
По умолчанию

PlayableAI.java

Цитата:
Сообщение от Спойлер  


PHP:


Код:
package l2p.gameserver.ai;

import l2p.commons.threading.RunnableImpl;
import l2p.gameserver.ThreadPoolManager;
import l2p.gameserver.geodata.GeoEngine;
import l2p.gameserver.model.Creature;
import l2p.gameserver.model.GameObject;
import l2p.gameserver.model.Playable;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.Skill;
import l2p.gameserver.model.Skill.NextAction;
import l2p.gameserver.model.Skill.SkillType;
import l2p.gameserver.model.Summon;
import l2p.gameserver.serverpackets.MyTargetSelected;
import l2p.gameserver.serverpackets.components.SystemMsg;
import l2p.gameserver.utils.Location;

import java.util.concurrent.ScheduledFuture;

import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_INTERACT;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;

public class PlayableAI extends CharacterAI
{
    private volatile int thinking = 0; // to prevent recursive thinking

    protected Object _intention_arg0 = null, _intention_arg1 = null;
    protected Skill _skill;

    private nextAction _nextAction;
    private Object _nextAction_arg0;
    private Object _nextAction_arg1;
    private boolean _nextAction_arg2;
    private boolean _nextAction_arg3;

    protected boolean _forceUse;
    private boolean _dontMove;

    private ScheduledFuture
 _followTask;

    public PlayableAI(Playable actor)
    {
        super(actor);
    }

    public enum nextAction
    {
        ATTACK,
        CAST,
        MOVE,
        REST,
        PICKUP,
        INTERACT
    }

    @Override
    public void changeIntention(CtrlIntention intention, Object arg0, Object arg1)
    {
        super.changeIntention(intention, arg0, arg1);
        _intention_arg0 = arg0;
        _intention_arg1 = arg1;
    }

    @Override
    public void setIntention(CtrlIntention intention, Object arg0, Object arg1)
    {
        _intention_arg0 = null;
        _intention_arg1 = null;
        super.setIntention(intention, arg0, arg1);
    }

    @Override
    protected void onIntentionCast(Skill skill, Creature target)
    {
        _skill = skill;
        super.onIntentionCast(skill, target);
    }

    @Override
    public void setNextAction(nextAction action, Object arg0, Object arg1, boolean arg2, boolean arg3)
    {
        _nextAction = action;
        _nextAction_arg0 = arg0;
        _nextAction_arg1 = arg1;
        _nextAction_arg2 = arg2;
        _nextAction_arg3 = arg3;
    }

    public boolean setNextIntention()
    {
        nextAction nextAction = _nextAction;
        Object nextAction_arg0 = _nextAction_arg0;
        Object nextAction_arg1 = _nextAction_arg1;
        boolean nextAction_arg2 = _nextAction_arg2;
        boolean nextAction_arg3 = _nextAction_arg3;

        Playable actor = getActor();
        if(nextAction == null || actor.isActionsDisabled())
            return false;

        Skill skill;
        Creature target;
        GameObject object;

        switch(nextAction)
        {
            case ATTACK:
                if(nextAction_arg0 == null)
                    return false;
                target = (Creature) nextAction_arg0;
                _forceUse = nextAction_arg2;
                _dontMove = nextAction_arg3;
                clearNextAction();
                setIntention(AI_INTENTION_ATTACK, target);
                break;
            case CAST:
                if(nextAction_arg0 == null || nextAction_arg1 == null)
                    return false;
                skill = (Skill) nextAction_arg0;
                target = (Creature) nextAction_arg1;
                _forceUse = nextAction_arg2;
                _dontMove = nextAction_arg3;
                clearNextAction();
                if(!skill.checkCondition(actor, target, _forceUse, _dontMove, true))
                {
                    if(skill.getNextAction() == NextAction.ATTACK && !actor.equals(target))
                    {
                        setNextAction(PlayableAI.nextAction.ATTACK, target, null, _forceUse, false);
                        return setNextIntention();
                    }
                    return false;
                }
                setIntention(AI_INTENTION_CAST, skill, target);
                break;
            case MOVE:
                if(nextAction_arg0 == null || nextAction_arg1 == null)
                    return false;
                Location loc = (Location) nextAction_arg0;
                Integer offset = (Integer) nextAction_arg1;
                clearNextAction();
                actor.moveToLocation(loc, offset, nextAction_arg2);
                break;
            case REST:
                actor.sitDown(null);
                break;
            case INTERACT:
                if(nextAction_arg0 == null)
                    return false;
                object = (GameObject) nextAction_arg0;
                clearNextAction();
                onIntentionInteract(object);
                break;
            case PICKUP:
                if(nextAction_arg0 == null)
                    return false;
                object = (GameObject) nextAction_arg0;
                clearNextAction();
                onIntentionPickUp(object);
                break;
            default:
                return false;
        }
        return true;
    }

    @Override
    public void clearNextAction()
    {
        _nextAction = null;
        _nextAction_arg0 = null;
        _nextAction_arg1 = null;
        _nextAction_arg2 = false;
        _nextAction_arg3 = false;
    }

    @Override
    protected void onEvtFinishCasting()
    {
        if(!setNextIntention())
            setIntention(AI_INTENTION_ACTIVE);
    }

    @Override
    protected void onEvtReadyToAct()
    {
        if(!setNextIntention())
            onEvtThink();
    }

    @Override
    protected void onEvtArrived()
    {
        if(!setNextIntention())
            if(getIntention() == AI_INTENTION_INTERACT || getIntention() == AI_INTENTION_PICK_UP)
                onEvtThink();
            else
                changeIntention(AI_INTENTION_ACTIVE, null, null);
    }

    @Override
    protected void onEvtArrivedTarget()
    {
        switch(getIntention())
        {
            case AI_INTENTION_ATTACK:
                thinkAttack(false);
                break;
            case AI_INTENTION_CAST:
                thinkCast(false);
                break;
            case AI_INTENTION_FOLLOW:
                thinkFollow();
                break;
            default:
                onEvtThink();
                break;
        }
    }

    @Override
    protected final void onEvtThink()
    {
        Playable actor = getActor();
        if(actor.isActionsDisabled())
            return;

        try
        {
            if(thinking++ > 1)
                return;

            switch(getIntention())
            {
                case AI_INTENTION_ACTIVE:
                    thinkActive();
                    break;
                case AI_INTENTION_ATTACK:
                    thinkAttack(true);
                    break;
                case AI_INTENTION_CAST:
                    thinkCast(true);
                    break;
                case AI_INTENTION_PICK_UP:
                    thinkPickUp();
                    break;
                case AI_INTENTION_INTERACT:
                    thinkInteract();
                    break;
                case AI_INTENTION_FOLLOW:
                    thinkFollow();
                    break;
            }
        }
        catch(Exception e)
        {
            _log.error("Unexpected error in PlayableAI.onEvtThink()", e);
        }
        finally
        {
            thinking--;
        }
    }

    protected void thinkActive()
    {

    }

    protected void thinkFollow()
    {
        Playable actor = getActor();

        Creature target = (Creature) _intention_arg0;
        Integer offset = (Integer) _intention_arg1;

        //Находимся слишком далеко цели, либо цель не пригодна для следования
        if(target == null || target.isAlikeDead() || actor.getDistance(target) > 4000 || offset == null)
        {
            clientActionFailed();
            return;
        }

        //Уже следуем за этой целью
        if(actor.isFollow && actor.getFollowTarget() == target)
        {
            clientActionFailed();
            return;
        }

        //Находимся достаточно близко или не можем двигаться - побежим потом ?
        if(actor.isInRange(target, offset + 20) || actor.isMovementDisabled())
            clientActionFailed();

        if(_followTask != null)
        {
            _followTask.cancel(false);
            _followTask = null;
        }

        _followTask = ThreadPoolManager.getInstance().schedule(new ThinkFollow(), 250L);
    }

    protected class ThinkFollow extends RunnableImpl
    {
        @Override
        public void runImpl() throws Exception
        {
            Playable actor = getActor();

            if(getIntention() != AI_INTENTION_FOLLOW)
            {
                // Если пет прекратил преследование, меняем статус, чтобы не пришлось щелкать на кнопку следования 2 раза.
                if((actor.isPet() || actor.isSummon()) && getIntention() == AI_INTENTION_ACTIVE)
                    ((Summon) actor).setFollowMode(false);
                return;
            }

            Creature target = (Creature) _intention_arg0;
            int offset = _intention_arg1 instanceof Integer ? (Integer) _intention_arg1 : 0;

            if(target == null || !target.isVisible() || target.isAlikeDead() || actor.getDistance(target) > 4000)
            {
                setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
                return;
            }

            Player player = actor.getPlayer();
            if(player == null || player.isLogoutStarted() || (actor.isPet() || actor.isSummon()) && player.getPet() != actor)
            {
                setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
                return;
            }

            if(!actor.isInRange(target, offset + 20) && (!actor.isFollow || actor.getFollowTarget() != target))
                actor.followToCharacter(target, offset, false);
            _followTask = ThreadPoolManager.getInstance().schedule(this, 250L);
        }
    }

    protected class ExecuteFollow extends RunnableImpl
    {
        private Creature _target;
        private int _range;

        public ExecuteFollow(Creature target, int range)
        {
            _target = target;
            _range = range;
        }

        @Override
        public void runImpl()
        {
            if(_target.isDoor())
                _actor.moveToLocation(_target.getLoc(), 40, true);
            else
                _actor.followToCharacter(_target, _range, true);
        }
    }

    @Override
    protected void onIntentionInteract(GameObject object)
    {
        Playable actor = getActor();

        if(actor.isActionsDisabled())
        {
            setNextAction(nextAction.INTERACT, object, null, false, false);
            clientActionFailed();
            return;
        }

        clearNextAction();
        changeIntention(AI_INTENTION_INTERACT, object, null);
        onEvtThink();
    }

    protected void thinkInteract()
    {
        Playable actor = getActor();

        GameObject target = (GameObject) _intention_arg0;

        if(target == null)
        {
            setIntention(AI_INTENTION_ACTIVE);
            return;
        }

        int range = (int) (Math.max(30, actor.getMinDistance(target)) + 20);

        if(actor.isInRangeZ(target, range))
        {
            if(actor.isPlayer())
                ((Player) actor).doInteract(target);
            setIntention(AI_INTENTION_ACTIVE);
        }
        else
        {
            actor.moveToLocation(target.getLoc(), 40, true);
            setNextAction(nextAction.INTERACT, target, null, false, false);
        }
    }

    @Override
    protected void onIntentionPickUp(GameObject object)
    {
        Playable actor = getActor();

        if(actor.isActionsDisabled())
        {
            setNextAction(nextAction.PICKUP, object, null, false, false);
            clientActionFailed();
            return;
        }

        clearNextAction();
        changeIntention(AI_INTENTION_PICK_UP, object, null);
        onEvtThink();
    }

    protected void thinkPickUp()
    {
        final Playable actor = getActor();

        final GameObject target = (GameObject) _intention_arg0;

        if(target == null)
        {
            setIntention(AI_INTENTION_ACTIVE);
            return;
        }

        if(actor.isInRange(target, 30) && Math.abs(actor.getZ() - target.getZ())  200 || Math.abs(actor.getZ() - attack_target.getZ()) > 200))
        {
            actor.sendPacket(SystemMsg.CANNOT_SEE_TARGET);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        range += actor.getMinDistance(attack_target);

        if(actor.isFakeDeath())
            actor.breakFakeDeath();

        if(actor.isInRangeZ(attack_target, range))
        {
            if(!canSee)
            {
                actor.sendPacket(SystemMsg.CANNOT_SEE_TARGET);
                setIntention(AI_INTENTION_ACTIVE);
                actor.sendActionFailed();
                return;
            }

            clientStopMoving(false);
            actor.doAttack(attack_target);
        }
        else if(!_dontMove)
            ThreadPoolManager.getInstance().execute(new ExecuteFollow(attack_target, range - 20));
        else
            actor.sendActionFailed();
    }

    protected void thinkCast(boolean checkRange)
    {
        Playable actor = getActor();

        Creature target = getAttackTarget();

        if(_skill.getSkillType() == SkillType.CRAFT || _skill.isToggle())
        {
            if(_skill.checkCondition(actor, target, _forceUse, _dontMove, true))
                actor.doCast(_skill, target, _forceUse);
            return;
        }

        if(target == null || target.isDead() != _skill.getCorpse() && !_skill.isNotTargetAoE())
        {
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        if(!checkRange)
        {
            // Если скилл имеет следующее действие, назначим это действие после окончания действия скилла
            if(_skill.getNextAction() == NextAction.ATTACK && !actor.equals(target))
                setNextAction(nextAction.ATTACK, target, null, _forceUse, false);
            else
                clearNextAction();

            clientStopMoving();

            if(_skill.checkCondition(actor, target, _forceUse, _dontMove, true))
                actor.doCast(_skill, target, _forceUse);
            else
            {
                setNextIntention();
                if(getIntention() == CtrlIntention.AI_INTENTION_ATTACK)
                    thinkAttack(true);
            }

            return;
        }

        int range = actor.getMagicalAttackRange(_skill);
        if(range  200 || Math.abs(actor.getZ() - target.getZ()) > 200))
        {
            actor.sendPacket(SystemMsg.CANNOT_SEE_TARGET);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        range += actor.getMinDistance(target);

        if(actor.isFakeDeath())
            actor.breakFakeDeath();

        if(actor.isInRangeZ(target, range) || noRangeSkill)
        {
            if(!noRangeSkill && !canSee)
            {
                actor.sendPacket(SystemMsg.CANNOT_SEE_TARGET);
                setIntention(AI_INTENTION_ACTIVE);
                actor.sendActionFailed();
                return;
            }

            // Если скилл имеет следующее действие, назначим это действие после окончания действия скилла
            if(_skill.getNextAction() == NextAction.ATTACK && !actor.equals(target) && !_forceUse)
            {
                //clearNextAction();
                setNextAction(nextAction.ATTACK, target, null, _forceUse, false);
            }
            else
                clearNextAction();

            if(_skill.checkCondition(actor, target, _forceUse, _dontMove, true))
            {
                clientStopMoving(false);
                actor.doCast(_skill, target, _forceUse);
            }
            else
            {
                setNextIntention();
                if(getIntention() == CtrlIntention.AI_INTENTION_ATTACK)
                    thinkAttack(true);
            }
        }
        else if(!_dontMove)
            ThreadPoolManager.getInstance().execute(new ExecuteFollow(target, range - 20));
        else
        {
            actor.sendPacket(SystemMsg.YOUR_TARGET_IS_OUT_OF_RANGE);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
        }
    }

    @Override
    protected void onEvtDead(Creature killer)
    {
        clearNextAction();
        super.onEvtDead(killer);
    }

    @Override
    protected void onEvtFakeDeath()
    {
        clearNextAction();
        super.onEvtFakeDeath();
    }

    public void lockTarget(Creature target)
    {
        Playable actor = getActor();

        if(target == null || target.isDead())
            actor.setAggressionTarget(null);
        else if(actor.getAggressionTarget() == null)
        {
            GameObject actorStoredTarget = actor.getTarget();
            actor.setAggressionTarget(target);
            actor.setTarget(target);

            clearNextAction();
            // DS: агрессия только перекидывает видимую цель, но не обрывает текущую атаку/каст
            /*if (getIntention() == CtrlIntention.AI_INTENTION_ATTACK)
                setAttackTarget(target);
            switch(getIntention())
            {
                case AI_INTENTION_ATTACK:
                    setAttackTarget(target);
                    break;
                case AI_INTENTION_CAST:
                    L2Skill skill = actor.getCastingSkill();
                    if(skill == null)
                        skill = _skill;
                    if(skill != null && !skill.isUsingWhileCasting())
                        switch(skill.getTargetType())
                        {
                            case TARGET_ONE:
                            case TARGET_AREA:
                            case TARGET_MULTIFACE:
                            case TARGET_TUNNEL:
                                setAttackTarget(target);
                                actor.setCastingTarget(target);
                                break;
                        }
                    break;
            }*/

            if(actorStoredTarget != target)
                actor.sendPacket(new MyTargetSelected(target.getObjectId(), 0));
        }
    }

    @Override
    public void Attack(GameObject target, boolean forceUse, boolean dontMove)
    {
        Playable actor = getActor();

        if(target.isCreature() && (actor.isActionsDisabled() || actor.isAttackingDisabled()))
        {
            // Если не можем атаковать, то атаковать позже
            setNextAction(nextAction.ATTACK, target, null, forceUse, false);
            actor.sendActionFailed();
            return;
        }

        _dontMove = dontMove;
        _forceUse = forceUse;
        clearNextAction();
        setIntention(AI_INTENTION_ATTACK, target);
    }

    @Override
    public void Cast(Skill skill, Creature target, boolean forceUse, boolean dontMove)
    {
        Playable actor = getActor();

        // Если скилл альтернативного типа (например, бутылка на хп),
        // то он может использоваться во время каста других скиллов, или во время атаки, или на бегу.
        // Поэтому пропускаем дополнительные проверки.
        if(skill.altUse() || skill.isToggle())
        {
            if((skill.isToggle() || skill.isHandler()) && (actor.isOutOfControl() || actor.isStunned() || actor.isSleeping() || actor.isParalyzed() || actor.isAlikeDead()))
                clientActionFailed();
            else
                actor.altUseSkill(skill, target);
            return;
        }

        // Если не можем кастовать, то использовать скилл позже
        if(actor.isActionsDisabled())
        {
            //if(!actor.isSkillDisabled(skill.getId()))
            setNextAction(nextAction.CAST, skill, target, forceUse, dontMove);
            clientActionFailed();
            return;
        }

        //_actor.stopMove(null);
        _forceUse = forceUse;
        _dontMove = dontMove;
        clearNextAction();
        setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
    }

    @Override
    public Playable getActor()
    {
        return (Playable) super.getActor();
    }
}
Цитата:
Сообщение от Спойлер  


PHP:


Код:
package l2p.gameserver.ai;

import static java.lang.Math.abs;
import static java.lang.Math.max;
import java.util.concurrent.ScheduledFuture;
import l2p.commons.threading.RunnableImpl;
import static l2p.gameserver.ThreadPoolManager.getInstance;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_INTERACT;
import static l2p.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;
import static l2p.gameserver.ai.PlayableAI.nextAction.ATTACK;
import static l2p.gameserver.ai.PlayableAI.nextAction.CAST;
import static l2p.gameserver.ai.PlayableAI.nextAction.INTERACT;
import static l2p.gameserver.ai.PlayableAI.nextAction.PICKUP;
import static l2p.gameserver.geodata.GeoEngine.canSeeTarget;
import l2p.gameserver.model.Creature;
import l2p.gameserver.model.GameObject;
import l2p.gameserver.model.Playable;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.Skill;
import static l2p.gameserver.model.Skill.SkillType.CRAFT;
import static l2p.gameserver.model.Skill.SkillType.TAKECASTLE;
import static l2p.gameserver.model.Skill.SkillType.TAKEFORTRESS;
import l2p.gameserver.model.Summon;
import l2p.gameserver.serverpackets.MyTargetSelected;
import static l2p.gameserver.serverpackets.components.SystemMsg.CANNOT_SEE_TARGET;
import static l2p.gameserver.serverpackets.components.SystemMsg.YOUR_TARGET_IS_OUT_OF_RANGE;
import l2p.gameserver.utils.Location;

public class PlayableAI extends CharacterAI
{
    private volatile int thinking = 0; // to prevent recursive thinking
    private Object _intention_arg0 = null;
    private Object _intention_arg1 = null;
    private Skill _skill;

    private nextAction _nextAction;
    private Object _nextAction_arg0;
    private Object _nextAction_arg1;
    private boolean _nextAction_arg2;
    private boolean _nextAction_arg3;

    private boolean _forceUse;
    private boolean _dontMove;

    private ScheduledFuture
 _followTask;

    public PlayableAI(Playable actor)
    {
        super(actor);
    }

    /**
     * @return the thinking
     */
    public int getThinking() {
        return thinking;
    }

    /**
     * @param thinking the thinking to set
     */
    public void setThinking(int thinking) {
        this.thinking = thinking;
    }

    /**
     * @return the _intention_arg0
     */
    public Object getIntention_arg0() {
        return _intention_arg0;
    }

    /**
     * @param _intention_arg0 the _intention_arg0 to set
     */
    public void setIntention_arg0(Object _intention_arg0) {
        this._intention_arg0 = _intention_arg0;
    }

    /**
     * @return the _intention_arg1
     */
    public Object getIntention_arg1() {
        return _intention_arg1;
    }

    /**
     * @param _intention_arg1 the _intention_arg1 to set
     */
    public void setIntention_arg1(Object _intention_arg1) {
        this._intention_arg1 = _intention_arg1;
    }

    /**
     * @return the _skill
     */
    public Skill getSkill() {
        return _skill;
    }

    /**
     * @param _skill the _skill to set
     */
    public void setSkill(Skill _skill) {
        this._skill = _skill;
    }

    /**
     * @return the _nextAction
     */
    public nextAction getNextAction() {
        return _nextAction;
    }

    /**
     * @param _nextAction the _nextAction to set
     */
    public void setNextAction(nextAction _nextAction) {
        this._nextAction = _nextAction;
    }

    /**
     * @return the _nextAction_arg0
     */
    public Object getNextAction_arg0() {
        return _nextAction_arg0;
    }

    /**
     * @param _nextAction_arg0 the _nextAction_arg0 to set
     */
    public void setNextAction_arg0(Object _nextAction_arg0) {
        this._nextAction_arg0 = _nextAction_arg0;
    }

    /**
     * @return the _nextAction_arg1
     */
    public Object getNextAction_arg1() {
        return _nextAction_arg1;
    }

    /**
     * @param _nextAction_arg1 the _nextAction_arg1 to set
     */
    public void setNextAction_arg1(Object _nextAction_arg1) {
        this._nextAction_arg1 = _nextAction_arg1;
    }

    /**
     * @return the _nextAction_arg2
     */
    public boolean isNextAction_arg2() {
        return _nextAction_arg2;
    }

    /**
     * @param _nextAction_arg2 the _nextAction_arg2 to set
     */
    public void setNextAction_arg2(boolean _nextAction_arg2) {
        this._nextAction_arg2 = _nextAction_arg2;
    }

    /**
     * @return the _nextAction_arg3
     */
    public boolean isNextAction_arg3() {
        return _nextAction_arg3;
    }

    /**
     * @param _nextAction_arg3 the _nextAction_arg3 to set
     */
    public void setNextAction_arg3(boolean _nextAction_arg3) {
        this._nextAction_arg3 = _nextAction_arg3;
    }

    /**
     * @return the _forceUse
     */
    public boolean isForceUse() {
        return _forceUse;
    }

    /**
     * @param _forceUse the _forceUse to set
     */
    public void setForceUse(boolean _forceUse) {
        this._forceUse = _forceUse;
    }

    /**
     * @return the _dontMove
     */
    public boolean isDontMove() {
        return _dontMove;
    }

    /**
     * @param _dontMove the _dontMove to set
     */
    public void setDontMove(boolean _dontMove) {
        this._dontMove = _dontMove;
    }

    /**
     * @return the _followTask
     */
    public ScheduledFuture
getFollowTask() {
        return _followTask;
    }

    /**
     * @param _followTask the _followTask to set
     */
    public void setFollowTask(ScheduledFuture
 _followTask) {
        this._followTask = _followTask;
    }

    public enum nextAction
    {
        ATTACK,
        CAST,
        MOVE,
        REST,
        PICKUP,
        INTERACT
    }

    @Override
    public void changeIntention(CtrlIntention intention, Object arg0, Object arg1)
    {
        super.changeIntention(intention, arg0, arg1);
        setIntention_arg0(arg0);
        setIntention_arg1(arg1);
    }

    @Override
    public void setIntention(CtrlIntention intention, Object arg0, Object arg1)
    {
        setIntention_arg0(null);
        setIntention_arg1(null);
        super.setIntention(intention, arg0, arg1);
    }

    @Override
    protected void onIntentionCast(Skill skill, Creature target)
    {
        setSkill(skill);
        super.onIntentionCast(skill, target);
    }

    @Override
    public void setNextAction(nextAction action, Object arg0, Object arg1, boolean arg2, boolean arg3)
    {
        setNextAction(action);
        setNextAction_arg0(arg0);
        setNextAction_arg1(arg1);
        setNextAction_arg2(arg2);
        setNextAction_arg3(arg3);
    }

    public boolean setNextIntention()
    {
        nextAction nextAction = getNextAction();
        Object nextAction_arg0 = getNextAction_arg0();
        Object nextAction_arg1 = getNextAction_arg1();
        boolean nextAction_arg2 = isNextAction_arg2();
        boolean nextAction_arg3 = isNextAction_arg3();

        Playable actor = getActor();
        if(nextAction == null || actor.isActionsDisabled())
            return false;

        Skill skill;
        Creature target;
        GameObject object;

        switch(nextAction)
        {
            case ATTACK:
                if(nextAction_arg0 == null)
                    return false;
                target = (Creature) nextAction_arg0;
                setForceUse(nextAction_arg2);
                setDontMove(nextAction_arg3);
                clearNextAction();
                setIntention(AI_INTENTION_ATTACK, target);
                break;
            case CAST:
                if(nextAction_arg0 == null || nextAction_arg1 == null)
                    return false;
                skill = (Skill) nextAction_arg0;
                target = (Creature) nextAction_arg1;
                setForceUse(nextAction_arg2);
                setDontMove(nextAction_arg3);
                clearNextAction();
                if(!skill.checkCondition(actor, target, _forceUse, _dontMove, true))
                {
                    if(skill.getNextAction() == ATTACK && !actor.equals(target))
                    {
                        setNextAction(ATTACK, target, null, isForceUse(), false);
                        return setNextIntention();
                    }
                    return false;
                }
                setIntention(AI_INTENTION_CAST, skill, target);
                break;
            case MOVE:
                if(nextAction_arg0 == null || nextAction_arg1 == null)
                    return false;
                Location loc = (Location) nextAction_arg0;
                Integer offset = (Integer) nextAction_arg1;
                clearNextAction();
                actor.moveToLocation(loc, offset, nextAction_arg2);
                break;
            case REST:
                actor.sitDown(null);
                break;
            case INTERACT:
                if(nextAction_arg0 == null)
                    return false;
                object = (GameObject) nextAction_arg0;
                clearNextAction();
                onIntentionInteract(object);
                break;
            case PICKUP:
                if(nextAction_arg0 == null)
                    return false;
                object = (GameObject) nextAction_arg0;
                clearNextAction();
                onIntentionPickUp(object);
                break;
            default:
                return false;
        }
        return true;
    }

    @Override
    public void clearNextAction()
    {
        setNextAction(null);
        setNextAction_arg0(null);
        setNextAction_arg1(null);
        setNextAction_arg2(false);
        setNextAction_arg3(false);
    }

    @Override
    protected void onEvtFinishCasting()
    {
        if(!setNextIntention())
            setIntention(AI_INTENTION_ACTIVE);
    }

    @Override
    protected void onEvtReadyToAct()
    {
        if(!setNextIntention())
            onEvtThink();
    }

    @Override
    protected void onEvtArrived()
    {
        if(!setNextIntention())
            if(getIntention() == AI_INTENTION_INTERACT || getIntention() == AI_INTENTION_PICK_UP)
                onEvtThink();
            else
                changeIntention(AI_INTENTION_ACTIVE, null, null);
    }

    @Override
    protected void onEvtArrivedTarget()
    {
        switch(getIntention())
        {
            case AI_INTENTION_ATTACK:
                thinkAttack(false);
                break;
            case AI_INTENTION_CAST:
                thinkCast(false);
                break;
            case AI_INTENTION_FOLLOW:
                thinkFollow();
                break;
            default:
                onEvtThink();
                break;
        }
    }

    @Override
    protected final void onEvtThink()
    {
        Playable actor = getActor();
        if(actor.isActionsDisabled())
            return;

        try
        {
            if(thinking++ > 1)
                return;

            switch(getIntention())
            {
                case AI_INTENTION_ACTIVE:
                    thinkActive();
                    break;
                case AI_INTENTION_ATTACK:
                    thinkAttack(true);
                    break;
                case AI_INTENTION_CAST:
                    thinkCast(true);
                    break;
                case AI_INTENTION_PICK_UP:
                    thinkPickUp();
                    break;
                case AI_INTENTION_INTERACT:
                    thinkInteract();
                    break;
                case AI_INTENTION_FOLLOW:
                    thinkFollow();
                    break;
            }
        }
        catch(Exception e)
        {
            _log.error("Unexpected error in PlayableAI.onEvtThink()", e);
        }
        finally
        {
            setThinking(getThinking() - 1);
        }
    }

    protected void thinkActive()
    {

    }

    protected void thinkFollow()
    {
        Playable actor = getActor();

        Creature target = (Creature) getIntention_arg0();
        Integer offset = (Integer) getIntention_arg1();

        //Находимся слишком далеко цели, либо цель не пригодна для следования
        if(target == null || target.isAlikeDead() || actor.getDistance(target) > 4000 || offset == null)
        {
            clientActionFailed();
            return;
        }

        //Уже следуем за этой целью
        if(actor.isFollow && actor.getFollowTarget() == target)
        {
            clientActionFailed();
            return;
        }

        //Находимся достаточно близко или не можем двигаться - побежим потом ?
        if(actor.isInRange(target, offset + 20) || actor.isMovementDisabled())
            clientActionFailed();

        if(getFollowTask() != null)
        {
            getFollowTask().cancel(false);
            setFollowTask(null);
        }

        setFollowTask(getInstance().schedule(new ThinkFollow(), 250L));
    }

    protected class ThinkFollow extends RunnableImpl
    {
        @Override
        public void runImpl() throws Exception
        {
            Playable actor = getActor();

            if(getIntention() != AI_INTENTION_FOLLOW)
            {
                // Если пет прекратил преследование, меняем статус, чтобы не пришлось щелкать на кнопку следования 2 раза.
                if((actor.isPet() || actor.isSummon()) && getIntention() == AI_INTENTION_ACTIVE)
                    ((Summon) actor).setFollowMode(false);
                return;
            }

            Creature target = (Creature) getIntention_arg0();
            int offset = getIntention_arg1() instanceof Integer ? (Integer) getIntention_arg1() : 0;

            if(target == null || !target.isVisible() || target.isAlikeDead() || actor.getDistance(target) > 4000)
            {
                setIntention(AI_INTENTION_ACTIVE);
                return;
            }

            Player player = actor.getPlayer();
            if(player == null || player.isLogoutStarted() || (actor.isPet() || actor.isSummon()) && player.getPet() != actor)
            {
                setIntention(AI_INTENTION_ACTIVE);
                return;
            }

            if(!actor.isInRange(target, offset + 20) && (!actor.isFollow || actor.getFollowTarget() != target))
                actor.followToCharacter(target, offset, false);
            setFollowTask(getInstance().schedule(this, 250L));
        }
    }

    protected class ExecuteFollow extends RunnableImpl
    {
        private final Creature _target;
        private final int _range;

        public ExecuteFollow(Creature target, int range)
        {
            _target = target;
            _range = range;
        }

        @Override
        public void runImpl()
        {
            if(_target.isDoor())
                _actor.moveToLocation(_target.getLoc(), 40, true);
            else
                _actor.followToCharacter(_target, _range, true);
        }
    }

    @Override
    protected void onIntentionInteract(GameObject object)
    {
        Playable actor = getActor();

        if(actor.isActionsDisabled())
        {
            setNextAction(INTERACT, object, null, false, false);
            clientActionFailed();
            return;
        }

        clearNextAction();
        changeIntention(AI_INTENTION_INTERACT, object, null);
        onEvtThink();
    }

    protected void thinkInteract()
    {
        Playable actor = getActor();

        GameObject target = (GameObject) getIntention_arg0();

        if(target == null)
        {
            setIntention(AI_INTENTION_ACTIVE);
            return;
        }

        int range = (int) (max(30, actor.getMinDistance(target)) + 20);

        if(actor.isInRangeZ(target, range))
        {
            if(actor.isPlayer())
                ((Player) actor).doInteract(target);
            setIntention(AI_INTENTION_ACTIVE);
        }
        else
        {
            actor.moveToLocation(target.getLoc(), 40, true);
            setNextAction(INTERACT, target, null, false, false);
        }
    }

    @Override
    protected void onIntentionPickUp(GameObject object)
    {
        Playable actor = getActor();

        if(actor.isActionsDisabled())
        {
            setNextAction(PICKUP, object, null, false, false);
            clientActionFailed();
            return;
        }

        clearNextAction();
        changeIntention(AI_INTENTION_PICK_UP, object, null);
        onEvtThink();
    }

    protected void thinkPickUp()
    {
        final Playable actor = getActor();

        final GameObject target = (GameObject) getIntention_arg0();

        if(target == null)
        {
            setIntention(AI_INTENTION_ACTIVE);
            return;
        }

        if(actor.isInRange(target, 30) && abs(actor.getZ() - target.getZ())  200 || abs(actor.getZ() - attack_target.getZ()) > 200))
        {
            actor.sendPacket(CANNOT_SEE_TARGET);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        range += actor.getMinDistance(attack_target);

        if(actor.isFakeDeath())
            actor.breakFakeDeath();

        if(actor.isInRangeZ(attack_target, range))
        {
            if(!canSee)
            {
                actor.sendPacket(CANNOT_SEE_TARGET);
                setIntention(AI_INTENTION_ACTIVE);
                actor.sendActionFailed();
                return;
            }

            clientStopMoving(false);
            actor.doAttack(attack_target);
        }
        else if(!isDontMove())
            getInstance().execute(new ExecuteFollow(attack_target, range - 20));
        else
            actor.sendActionFailed();
    }

    protected void thinkCast(boolean checkRange)
    {
        Playable actor = getActor();

        Creature target = getAttackTarget();

        if(getSkill().getSkillType() == CRAFT || getSkill().isToggle())
        {
            if(getSkill().checkCondition(actor, target, isForceUse(), isDontMove(), true))
                actor.doCast(getSkill(), target, isForceUse());
            return;
        }

        if(target == null || target.isDead() != getSkill().getCorpse() && !_skill.isNotTargetAoE())
        {
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        if(!checkRange)
        {
            // Если скилл имеет следующее действие, назначим это действие после окончания действия скилла
            if(getSkill().getNextAction() == ATTACK && !actor.equals(target))
                setNextAction(ATTACK, target, null, isForceUse(), false);
            else
                clearNextAction();

            clientStopMoving();

            if(getSkill().checkCondition(actor, target, isForceUse(), isDontMove(), true))
                actor.doCast(getSkill(), target, isForceUse());
            else
            {
                setNextIntention();
                if(getIntention() == AI_INTENTION_ATTACK)
                    thinkAttack(true);
            }

            return;
        }

        int range = actor.getMagicalAttackRange(getSkill());
        if(range  200 || abs(actor.getZ() - target.getZ()) > 200))
        {
            actor.sendPacket(CANNOT_SEE_TARGET);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
            return;
        }

        range += actor.getMinDistance(target);

        if(actor.isFakeDeath())
            actor.breakFakeDeath();

        if(actor.isInRangeZ(target, range) || noRangeSkill)
        {
            if(!noRangeSkill && !canSee)
            {
                actor.sendPacket(CANNOT_SEE_TARGET);
                setIntention(AI_INTENTION_ACTIVE);
                actor.sendActionFailed();
                return;
            }

            // Если скилл имеет следующее действие, назначим это действие после окончания действия скилла
            if(getSkill().getNextAction() == ATTACK && !actor.equals(target) && !isForceUse())
            {
                //clearNextAction();
                setNextAction(ATTACK, target, null, isForceUse(), false);
            }
            else
                clearNextAction();

            if(getSkill().checkCondition(actor, target, isForceUse(), isDontMove(), true))
            {
                clientStopMoving(false);
                actor.doCast(getSkill(), target, isForceUse());
            }
            else
            {
                setNextIntention();
                if(getIntention() == AI_INTENTION_ATTACK)
                    thinkAttack(true);
            }
        }
        else if(!isDontMove())
            getInstance().execute(new ExecuteFollow(target, range - 20));
        else
        {
            actor.sendPacket(YOUR_TARGET_IS_OUT_OF_RANGE);
            setIntention(AI_INTENTION_ACTIVE);
            actor.sendActionFailed();
        }
    }

    @Override
    protected void onEvtDead(Creature killer)
    {
        clearNextAction();
        super.onEvtDead(killer);
    }

    @Override
    protected void onEvtFakeDeath()
    {
        clearNextAction();
        super.onEvtFakeDeath();
    }

    public void lockTarget(Creature target)
    {
        Playable actor = getActor();

        if(target == null || target.isDead())
            actor.setAggressionTarget(null);
        else if(actor.getAggressionTarget() == null)
        {
            GameObject actorStoredTarget = actor.getTarget();
            actor.setAggressionTarget(target);
            actor.setTarget(target);

            clearNextAction();
            // DS: агрессия только перекидывает видимую цель, но не обрывает текущую атаку/каст
            /*if (getIntention() == CtrlIntention.AI_INTENTION_ATTACK)
                setAttackTarget(target);
            switch(getIntention())
            {
                case AI_INTENTION_ATTACK:
                    setAttackTarget(target);
                    break;
                case AI_INTENTION_CAST:
                    L2Skill skill = actor.getCastingSkill();
                    if(skill == null)
                        skill = _skill;
                    if(skill != null && !skill.isUsingWhileCasting())
                        switch(skill.getTargetType())
                        {
                            case TARGET_ONE:
                            case TARGET_AREA:
                            case TARGET_MULTIFACE:
                            case TARGET_TUNNEL:
                                setAttackTarget(target);
                                actor.setCastingTarget(target);
                                break;
                        }
                    break;
            }*/

            if(actorStoredTarget != target)
                actor.sendPacket(new MyTargetSelected(target.getObjectId(), 0));
        }
    }

    @Override
    public void Attack(GameObject target, boolean forceUse, boolean dontMove)
    {
        Playable actor = getActor();

        if(target.isCreature() && (actor.isActionsDisabled() || actor.isAttackingDisabled()))
        {
            // Если не можем атаковать, то атаковать позже
            setNextAction(ATTACK, target, null, forceUse, false);
            actor.sendActionFailed();
            return;
        }

        setDontMove(dontMove);
        setForceUse(forceUse);
        clearNextAction();
        setIntention(AI_INTENTION_ATTACK, target);
    }

    @Override
    public void Cast(Skill skill, Creature target, boolean forceUse, boolean dontMove)
    {
        Playable actor = getActor();

        // Если скилл альтернативного типа (например, бутылка на хп),
        // то он может использоваться во время каста других скиллов, или во время атаки, или на бегу.
        // Поэтому пропускаем дополнительные проверки.
        if(skill.altUse() || skill.isToggle())
        {
            if((skill.isToggle() || skill.isHandler()) && (actor.isOutOfControl() || actor.isStunned() || actor.isSleeping() || actor.isParalyzed() || actor.isAlikeDead()))
                clientActionFailed();
            else
                actor.altUseSkill(skill, target);
            return;
        }

        // Если не можем кастовать, то использовать скилл позже
        if(actor.isActionsDisabled())
        {
            //if(!actor.isSkillDisabled(skill.getId()))
            setNextAction(CAST, skill, target, forceUse, dontMove);
            clientActionFailed();
            return;
        }

        //_actor.stopMove(null);
        setForceUse(forceUse);
        setDontMove(dontMove);
        clearNextAction();
        setIntention(AI_INTENTION_CAST, skill, target);
    }

    @Override
    public Playable getActor()
    {
        return (Playable) super.getActor();
    }
}
 
Ответить с цитированием
 





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


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




ANTICHAT ™ © 2001- Antichat Kft.