Package lineage2.gameserver.ai

Source Code of lineage2.gameserver.ai.PlayableAI$ExecuteFollow

/*
* 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 lineage2.gameserver.ai;

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

import java.util.concurrent.ScheduledFuture;

import lineage2.commons.threading.RunnableImpl;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.cache.Msg;
import lineage2.gameserver.geodata.GeoEngine;
import lineage2.gameserver.model.Creature;
import lineage2.gameserver.model.GameObject;
import lineage2.gameserver.model.Playable;
import lineage2.gameserver.model.Player;
import lineage2.gameserver.model.Skill;
import lineage2.gameserver.model.Skill.NextAction;
import lineage2.gameserver.model.Skill.SkillType;
import lineage2.gameserver.model.Summon;
import lineage2.gameserver.model.ClonePlayer;
import lineage2.gameserver.network.serverpackets.components.SystemMsg;
import lineage2.gameserver.utils.Location;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public class PlayableAI extends CharacterAI
{
  /**
   * Field thinking.
   */
  private volatile int thinking = 0;
  /**
   * Field _intention_arg1. Field _intention_arg0.
   */
  protected Object _intention_arg0 = null, _intention_arg1 = null;
  /**
   * Field _skill.
   */
  protected Skill _skill;
  /**
   * Field _nextAction.
   */
  private nextAction _nextAction;
  /**
   * Field _nextAction_arg0.
   */
  private Object _nextAction_arg0;
  /**
   * Field _nextAction_arg1.
   */
  private Object _nextAction_arg1;
  /**
   * Field _nextAction_arg2.
   */
  private boolean _nextAction_arg2;
  /**
   * Field _nextAction_arg3.
   */
  private boolean _nextAction_arg3;
  /**
   * Field _forceUse.
   */
  protected boolean _forceUse;
  /**
   * Field _dontMove.
   */
  private boolean _dontMove;
  /**
   * Field _followTask.
   */
  ScheduledFuture<?> _followTask;
 
  /**
   * Constructor for PlayableAI.
   * @param actor Playable
   */
  public PlayableAI(Playable actor)
  {
    super(actor);
  }
 
  /**
   * @author Mobius
   */
  public enum nextAction
  {
    /**
     * Field ATTACK.
     */
    ATTACK,
    /**
     * Field CAST.
     */
    CAST,
    /**
     * Field MOVE.
     */
    MOVE,
    /**
     * Field REST.
     */
    REST,
    /**
     * Field PICKUP.
     */
    PICKUP,
    /**
     * Field INTERACT.
     */
    INTERACT,
    /**
     * Field COUPLE_ACTION.
     */
    COUPLE_ACTION
  }
 
  /**
   * Method changeIntention.
   * @param intention CtrlIntention
   * @param arg0 Object
   * @param arg1 Object
   */
  @Override
  public void changeIntention(CtrlIntention intention, Object arg0, Object arg1)
  {
    super.changeIntention(intention, arg0, arg1);
    _intention_arg0 = arg0;
    _intention_arg1 = arg1;
  }
 
  /**
   * Method setIntention.
   * @param intention CtrlIntention
   * @param arg0 Object
   * @param arg1 Object
   */
  @Override
  public void setIntention(CtrlIntention intention, Object arg0, Object arg1)
  {
    _intention_arg0 = null;
    _intention_arg1 = null;
    super.setIntention(intention, arg0, arg1);
  }
 
  /**
   * Method onIntentionCast.
   * @param skill Skill
   * @param target Creature
   */
  @Override
  protected void onIntentionCast(Skill skill, Creature target)
  {
    _skill = skill;
    super.onIntentionCast(skill, target);
  }
 
  /**
   * Method setNextAction.
   * @param action nextAction
   * @param arg0 Object
   * @param arg1 Object
   * @param arg2 boolean
   * @param arg3 boolean
   */
  @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;
  }
 
  /**
   * Method setNextIntention.
   * @return boolean
   */
  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;
      case COUPLE_ACTION:
        if ((nextAction_arg0 == null) || (nextAction_arg1 == null))
        {
          return false;
        }
        target = (Creature) nextAction_arg0;
        Integer socialId = (Integer) nextAction_arg1;
        _forceUse = nextAction_arg2;
        _nextAction = null;
        clearNextAction();
        onIntentionCoupleAction((Player) target, socialId);
        break;
      default:
        return false;
    }
    return true;
  }
 
  /**
   * Method clearNextAction.
   */
  @Override
  public void clearNextAction()
  {
    _nextAction = null;
    _nextAction_arg0 = null;
    _nextAction_arg1 = null;
    _nextAction_arg2 = false;
    _nextAction_arg3 = false;
  }
 
  /**
   * Method onEvtFinishCasting.
   * @param skill_id int
   * @param success boolean
   */
  @Override
  protected void onEvtFinishCasting(int skill_id, boolean success)
  {
    if (!setNextIntention())
    {
      setIntention(AI_INTENTION_ACTIVE);
    }
  }
 
  /**
   * Method onEvtReadyToAct.
   */
  @Override
  protected void onEvtReadyToAct()
  {
    if (!setNextIntention())
    {
      onEvtThink();
    }
  }
 
  /**
   * Method onEvtArrived.
   */
  @Override
  protected void onEvtArrived()
  {
    if (!setNextIntention())
    {
      if ((getIntention() == AI_INTENTION_INTERACT) || (getIntention() == AI_INTENTION_PICK_UP))
      {
        onEvtThink();
      }
      else
      {
        changeIntention(AI_INTENTION_ACTIVE, null, null);
      }
    }
  }
 
  /**
   * Method onEvtArrivedTarget.
   */
  @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;
    }
  }
 
  /**
   * Method onEvtThink.
   */
  @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;
        case AI_INTENTION_COUPLE_ACTION:
          thinkCoupleAction((Player) _intention_arg0, (Integer) _intention_arg1, false);
          break;
        case AI_INTENTION_IDLE:
          thinkIdle();
          break;
        case AI_INTENTION_REST:
          thinkRest();
          break;
      }
    }
    catch (Exception e)
    {
      _log.error("", e);
    }
    finally
    {
      thinking--;
    }
  }
 
  /**
   * Method thinkActive.
   */
  protected void thinkActive()
  {
  }
 
  /**
   * Method thinkFollow.
   */
  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);
  }
 
  /**
   * @author Mobius
   */
  protected class ThinkFollow extends RunnableImpl
  {
    /**
     * Method runImpl.
     */
    @Override
    public void runImpl()
    {
      Playable actor = getActor();
      if (getIntention() != AI_INTENTION_FOLLOW)
      {
        if (actor.isClone() && getIntention() == AI_INTENTION_ACTIVE)
        {
          ((ClonePlayer) actor).setFollowMode(false);
        }
        else if ((actor.isPet() || actor.isServitor()) && (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.isAlikeDead() || (actor.getDistance(target) > 4000))
      {
        setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
        return;
      }
      Player player = actor.getPlayer();
      if ((player == null) || player.isLogoutStarted() || ((actor.isPet() || actor.isServitor()) && !player.getSummonList().contains(actor) && !actor.isClone()))
      {
        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);
    }
  }
 
  /**
   * @author Mobius
   */
  protected class ExecuteFollow extends RunnableImpl
  {
    /**
     * Field _target.
     */
    private final Creature _target;
    /**
     * Field _range.
     */
    private final int _range;
   
    /**
     * Constructor for ExecuteFollow.
     * @param target Creature
     * @param range int
     */
    public ExecuteFollow(Creature target, int range)
    {
      _target = target;
      _range = range;
    }
   
    /**
     * Method runImpl.
     */
    @Override
    public void runImpl()
    {
      if (_target.isDoor())
      {
        _actor.moveToLocation(_target.getLoc(), 40, true);
      }
      else
      {
        _actor.followToCharacter(_target, _range, true);
      }
    }
  }
 
  /**
   * Method onIntentionInteract.
   * @param object GameObject
   */
  @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();
  }
 
  /**
   * Method onIntentionCoupleAction.
   * @param player Player
   * @param socialId Integer
   */
  @Override
  protected void onIntentionCoupleAction(Player player, Integer socialId)
  {
    clearNextAction();
    changeIntention(CtrlIntention.AI_INTENTION_COUPLE_ACTION, player, socialId);
    onEvtThink();
  }
 
  /**
   * Method thinkInteract.
   */
  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);
        target.onActionSelect((Player) actor, false);
      }
      setIntention(AI_INTENTION_ACTIVE);
    }
    else
    {
      actor.moveToLocation(target.getLoc(), 40, true);
      setNextAction(nextAction.INTERACT, target, null, false, false);
    }
  }
 
  /**
   * Method onIntentionPickUp.
   * @param object GameObject
   */
  @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();
  }
 
  /**
   * Method thinkPickUp.
   */
  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()) < 50))
    {
      if (actor.isPlayer() || actor.isPet())
      {
        actor.doPickupItem(target);
      }
      setIntention(AI_INTENTION_ACTIVE);
    }
    else
    {
      ThreadPoolManager.getInstance().execute(new RunnableImpl()
      {
        @Override
        public void runImpl()
        {
          actor.moveToLocation(target.getLoc(), 10, true);
          setNextAction(nextAction.PICKUP, target, null, false, false);
        }
      });
    }
  }
 
  /**
   * Method thinkAttack.
   * @param checkRange boolean
   */
  protected void thinkAttack(boolean checkRange)
  {
    Playable actor = getActor();
    Player player = actor.getPlayer();
    if (player == null)
    {
      setIntention(AI_INTENTION_ACTIVE);
      return;
    }
    if (actor.isActionsDisabled() || actor.isAttackingDisabled())
    {
      actor.sendActionFailed();
      return;
    }
    boolean isPosessed = (actor instanceof Summon) && ((Summon) actor).isDepressed();
    Creature attack_target = getAttackTarget();
    if ((attack_target == null) || attack_target.isDead() || (!isPosessed && !(_forceUse ? attack_target.isAttackable(actor) : attack_target.isAutoAttackable(actor))))
    {
      setIntention(AI_INTENTION_ACTIVE);
      actor.sendActionFailed();
      return;
    }
    if (!checkRange)
    {
      clientStopMoving();
      actor.doAttack(attack_target);
      return;
    }
    int range = actor.getPhysicalAttackRange();
    if (range < 10)
    {
      range = 10;
    }
    boolean canSee = GeoEngine.canSeeTarget(actor, attack_target, false);
    if (!canSee && ((range > 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();
    }
  }
 
  /**
   * Method thinkCast.
   * @param checkRange boolean
   */
  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 < 10)
    {
      range = 10;
    }
    boolean canSee = (_skill.getSkillType() == SkillType.TAKECASTLE) || (_skill.getSkillType() == SkillType.TAKEFORTRESS) || GeoEngine.canSeeTarget(actor, target, actor.isFlying());
    boolean noRangeSkill = _skill.getCastRange() == 32767;
    if (!noRangeSkill && !canSee && ((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))
      {
        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(Msg.YOUR_TARGET_IS_OUT_OF_RANGE);
      setIntention(AI_INTENTION_ACTIVE);
      actor.sendActionFailed();
    }
  }
 
  /**
   * Method thinkCoupleAction.
   * @param target Player
   * @param socialId Integer
   * @param cancel boolean
   */
  protected void thinkCoupleAction(Player target, Integer socialId, boolean cancel)
  {
  }
 
  /**
   * Method thinkIdle.
   */
  protected void thinkIdle()
  {
  }
 
  /**
   * Method thinkRest.
   */
  protected void thinkRest()
  {
  }
 
  /**
   * Method onEvtDead.
   * @param killer Creature
   */
  @Override
  protected void onEvtDead(Creature killer)
  {
    clearNextAction();
    super.onEvtDead(killer);
  }
 
  /**
   * Method onEvtFakeDeath.
   */
  @Override
  protected void onEvtFakeDeath()
  {
    clearNextAction();
    super.onEvtFakeDeath();
  }
 
  /**
   * Method lockTarget.
   * @param target Creature
   */
  public void lockTarget(Creature target)
  {
    Playable actor = getActor();
    if ((target == null) || target.isDead())
    {
      actor.setAggressionTarget(null);
    }
    else if (actor.getAggressionTarget() == null)
    {
      actor.getTarget();
      actor.setAggressionTarget(target);
      actor.setTarget(target);
      clearNextAction();
    }
  }
 
  /**
   * Method Attack.
   * @param target GameObject
   * @param forceUse boolean
   * @param dontMove boolean
   */
  @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);
  }
 
  /**
   * Method Cast.
   * @param skill Skill
   * @param target Creature
   * @param forceUse boolean
   * @param dontMove boolean
   */
  @Override
  public void Cast(Skill skill, Creature target, boolean forceUse, boolean dontMove)
  {
    Playable actor = getActor();
    if (skill.altUse() || skill.isToggle())
    {
      if (((skill.isToggle() && !skill.isAwakeningToggle())|| skill.isHandler()) && (actor.isOutOfControl() || actor.isStunned() || actor.isSleeping() || actor.isParalyzed() || actor.isAlikeDead() || actor.isAirBinded() || actor.isKnockedBack() || actor.isKnockedDown() || actor.isPulledNow()))
      {
        clientActionFailed();
      }
      else
      {
        actor.altUseSkill(skill, target);
      }
      return;
    }
    if (actor.isActionsDisabled())
    {
      setNextAction(nextAction.CAST, skill, target, forceUse, dontMove);
      clientActionFailed();
      return;
    }
    _forceUse = forceUse;
    _dontMove = dontMove;
    clearNextAction();
    setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
  }
 
  /**
   * Method getActor.
   * @return Playable
   */
  @Override
  public Playable getActor()
  {
    return (Playable) super.getActor();
  }
}
TOP

Related Classes of lineage2.gameserver.ai.PlayableAI$ExecuteFollow

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.