Package com.l2jfrozen.gameserver.ai

Source Code of com.l2jfrozen.gameserver.ai.L2CharacterAI

/*
* 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 2, 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jfrozen.gameserver.ai;

import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_CAST;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_INTERACT;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_REST;

import com.l2jfrozen.gameserver.ai.L2PlayerAI.IntentionCommand;
import com.l2jfrozen.gameserver.model.Inventory;
import com.l2jfrozen.gameserver.model.L2Attackable;
import com.l2jfrozen.gameserver.model.L2Character;
import com.l2jfrozen.gameserver.model.L2Object;
import com.l2jfrozen.gameserver.model.L2Skill;
import com.l2jfrozen.gameserver.model.actor.instance.L2BoatInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2ItemInstance.ItemLocation;
import com.l2jfrozen.gameserver.model.actor.instance.L2NpcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance;
import com.l2jfrozen.gameserver.model.actor.position.L2CharPosition;
import com.l2jfrozen.gameserver.network.serverpackets.AutoAttackStop;
import com.l2jfrozen.gameserver.taskmanager.AttackStanceTaskManager;
import com.l2jfrozen.gameserver.templates.L2WeaponType;
/**
* This class manages AI of L2Character.<BR>
* <BR>
* L2CharacterAI :<BR>
* <BR>
* <li>L2AttackableAI</li> <li>L2DoorAI</li> <li>L2PlayerAI</li> <li>L2SummonAI</li><BR>
* <BR>
*/
public class L2CharacterAI extends AbstractAI
{
  private static final int ZONE_PVP = 1;

  /** The skill we are curently casting by INTENTION_CAST */
  private L2Skill _skill;

  @Override
  protected void onEvtAttacked(L2Character attacker)
  {
    clientStartAutoAttack();
  }

  /**
   * Constructor of L2CharacterAI.<BR>
   * <BR>
   *
   * @param accessor The AI accessor of the L2Character
   */
  public L2CharacterAI(L2Character.AIAccessor accessor)
  {
    super(accessor);
  }

  /**
   * Manage the Idle Intention : Stop Attack, Movement and Stand Up the actor.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Set the AI Intention to AI_INTENTION_IDLE</li> <li>Init cast and attack target</li> <li>Stop the actor
   * auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor
   * movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>
   * Stand up the actor server side AND client side by sending Server->Client packet ChangeWaitType (broadcast)</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionIdle()
  {
    // Set the AI Intention to AI_INTENTION_IDLE
    changeIntention(AI_INTENTION_IDLE, null, null);

    // Init cast and attack target
    setCastTarget(null);
    setAttackTarget(null);

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);

    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();
  }

  /**
   * Manage the Active Intention : Stop Attack, Movement and Launch Think Event.<BR>
   * <BR>
   * <B><U> Actions</U> : <I>if the Intention is not already Active</I></B><BR>
   * <BR>
   * <li>Set the AI Intention to AI_INTENTION_ACTIVE</li> <li>Init cast and attack target</li> <li>Stop the actor
   * auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Stop the actor
   * movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li> <li>
   * Launch the Think Event</li><BR>
   * <BR>
   * @param target
   */
  protected void onIntentionActive(L2Character target)
  {
    if(target instanceof L2PcInstance && _actor instanceof L2PcInstance)
    {
      if(((L2PcInstance) _actor).getKarma() > 0 && _actor.getLevel() - target.getLevel() >= 10 && ((L2PlayableInstance) target).getProtectionBlessing() && !target.isInsideZone(ZONE_PVP))
      {
        //If attacker have karma and have level >= 10 than his target and target have Newbie Protection Buff,
        clientActionFailed();
        return;
      }
    }

    // Check if the Intention is not already Active
    if(getIntention() != AI_INTENTION_ACTIVE)
    {
      // Set the AI Intention to AI_INTENTION_ACTIVE
      changeIntention(AI_INTENTION_ACTIVE, null, null);

      // Init cast and attack target
      setCastTarget(null);
      setAttackTarget(null);

      // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
      clientStopMoving(null);

      // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
      clientStopAutoAttack();

      // Also enable random animations for this L2Character if allowed
      // This is only for mobs - town npcs are handled in their constructor
      if(_actor instanceof L2Attackable)
      {
        ((L2NpcInstance) _actor).startRandomAnimationTimer();
      }

      // Launch the Think Event
      onEvtThink();
    }
  }

  /**
   * Manage the Rest Intention.<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Set the AI Intention to AI_INTENTION_IDLE</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionRest()
  {
    // Set the AI Intention to AI_INTENTION_IDLE
    setIntention(AI_INTENTION_IDLE);
  }

  /**
   * Manage the Attack Intention : Stop current Attack (if necessary), Start a new Attack and Launch Think Event.<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_ATTACK</li> <li>Set or change the AI attack target</li> <li>Start the actor Auto Attack client side by sending Server->Client packet
   * AutoAttackStart (broadcast)</li> <li>Launch the Think Event</li><BR>
   * <BR>
   * <B><U> Overridden in</U> :</B><BR>
   * <BR>
   * <li>L2AttackableAI : Calculate attack timeout</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionAttack(L2Character target)
  {
    if (target == null)
    {
      clientActionFailed();
      return;
    }
   
    if (getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }
   
    if (_actor.isAllSkillsDisabled() || _actor.isAfraid())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }
   
    // Check if the Intention is already AI_INTENTION_ATTACK
    if (getIntention() == AI_INTENTION_ATTACK)
    {
      // Check if the AI already targets the L2Character
      if (getAttackTarget() != target)
      {
        // Set the AI attack target (change target)
        setAttackTarget(target);
       
        stopFollow();
       
        // Launch the Think Event
        notifyEvent(CtrlEvent.EVT_THINK, null);
      }
      else
      {
        clientActionFailed(); // else client freezes until cancel target
      }
    }
    else
    {
      // Set the Intention of this AbstractAI to AI_INTENTION_ATTACK
      changeIntention(AI_INTENTION_ATTACK, target, null);
     
      // Set the AI attack target
      setAttackTarget(target);
     
      stopFollow();
     
      // Launch the Think Event
      notifyEvent(CtrlEvent.EVT_THINK, null);
    }
  }

  /**
   * Manage the Cast Intention : Stop current Attack, Init the AI in order to cast and Launch Think Event.<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Set the AI cast target</li> <li>Stop the actor auto-attack client side by sending Server->Client packet
   * AutoAttackStop (broadcast)</li> <li>Cancel action client side by sending Server->Client packet ActionFailed to
   * the L2PcInstance actor</li> <li>Set the AI skill used by INTENTION_CAST</li> <li>Set the Intention of this AI to
   * AI_INTENTION_CAST</li> <li>Launch the Think Event</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionCast(L2Skill skill, L2Object target)
  {
    if(getIntention() == AI_INTENTION_REST && skill.isMagic())
    {
      clientActionFailed();
      return;
    }

    if(_actor.isAllSkillsDisabled() && !skill.isPotion())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    // can't cast if muted
    if(_actor.isMuted() && skill.isMagic())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }
    if(target instanceof L2PcInstance && _actor instanceof L2PcInstance)
    {
      if(((L2PcInstance) _actor).getKarma() > 0 && _actor.getLevel() - ((L2PcInstance) target).getLevel() >= 10 && ((L2PlayableInstance) target).getProtectionBlessing() && !((L2Character) target).isInsideZone(ZONE_PVP))
      {
        //If attacker have karma and have level >= 10 than his target and target have Newbie Protection Buff,
        clientActionFailed();
        return;
      }
    }

    // Set the AI cast target
    setCastTarget((L2Character) target);

    // Stop actions client-side to cast the skill
    if(skill.getHitTime() > 50)
    {
      // Abort the attack of the L2Character and send Server->Client ActionFailed packet
      _actor.abortAttack();

      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      // no need for second ActionFailed packet, abortAttack() already sent it
      //clientActionFailed();
    }

    // Set the AI skill used by INTENTION_CAST
    set_skill(skill);

    // Change the Intention of this AbstractAI to AI_INTENTION_CAST
    changeIntention(AI_INTENTION_CAST, skill, target);

    // Launch the Think Event
    notifyEvent(CtrlEvent.EVT_THINK, null);
  }

  /**
   * Manage the Move To Intention : Stop current Attack and Launch a Move to Location Task.<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_MOVE_TO</li> <li>Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet
   * CharMoveToLocation (broadcast)</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionMoveTo(L2CharPosition pos)
  {
    if (getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }
   
    // Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
    changeIntention(AI_INTENTION_MOVE_TO, pos, null);
   
    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();
   
    // Abort the attack of the L2Character and send Server->Client ActionFailed packet
    if (_actor instanceof L2PcInstance)
    {
      L2ItemInstance rhand = ((L2PcInstance) _actor).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
      if ((rhand != null && rhand.getItemType() == L2WeaponType.BOW))
      {
        if (!_actor.isAttackingNow())
          _actor.abortAttack();
      }
      else
      {
        _actor.abortAttack();
      }
    }
    else
    // case Npc
    {
      _actor.abortAttack();
    }
   
    // Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
    moveTo(pos.x, pos.y, pos.z);
  }
 
 
  /* (non-Javadoc)
   * @see com.l2jfrozen.gameserver.ai.AbstractAI#onIntentionMoveToInABoat(com.l2jfrozen.gameserver.model.L2CharPosition, com.l2jfrozen.gameserver.model.L2CharPosition)
   */
  @Override
  protected void onIntentionMoveToInABoat(L2CharPosition destination, L2CharPosition origin)
  {
    if(getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    if(_actor.isAllSkillsDisabled())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    // Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
    //
    //changeIntention(AI_INTENTION_MOVE_TO, new L2CharPosition(((L2PcInstance)_actor).getBoat().getX() - destination.x, ((L2PcInstance)_actor).getBoat().getY() - destination.y, ((L2PcInstance)_actor).getBoat().getZ() - destination.z, 0)  , null);

    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();

    // Abort the attack of the L2Character and send Server->Client ActionFailed packet
    _actor.abortAttack();

    // Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
    moveToInABoat(destination, origin);
  }

  /**
   * Manage the Follow Intention : Stop current Attack and Launch a Follow Task.<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Stop the actor auto-attack server side AND client side by sending Server->Client packet AutoAttackStop
   * (broadcast)</li> <li>Set the Intention of this AI to AI_INTENTION_FOLLOW</li> <li>Create and Launch an AI Follow
   * Task to execute every 1s</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionFollow(L2Character target)
  {
    if(getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    if(_actor.isAllSkillsDisabled())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    if(_actor.isImobilised() || _actor.isRooted())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    // Dead actors can`t follow
    if(_actor.isDead())
    {
      clientActionFailed();
      return;
    }

    // do not follow yourself
    if(_actor == target)
    {
      clientActionFailed();
      return;
    }

    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();

    // Set the Intention of this AbstractAI to AI_INTENTION_FOLLOW
    changeIntention(AI_INTENTION_FOLLOW, target, null);

    // Create and Launch an AI Follow Task to execute every 1s
    startFollow(target);
  }

  /**
   * Manage the PickUp Intention : Set the pick up target and Launch a Move To Pawn Task (offset=20).<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Set the AI pick up target</li> <li>Set the Intention of this AI to AI_INTENTION_PICK_UP</li> <li>Move the
   * actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionPickUp(L2Object object)
  {
    if(getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    if(_actor.isAllSkillsDisabled() || _actor.isCastingNow())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();

    if (object instanceof L2ItemInstance && ((L2ItemInstance)object).getLocation() != ItemLocation.VOID)
      return;
   
    // Set the Intention of this AbstractAI to AI_INTENTION_PICK_UP
    changeIntention(AI_INTENTION_PICK_UP, object, null);

    // Set the AI pick up target
    setTarget(object);
   
    if(object.getX() == 0 && object.getY() == 0) // TODO: Find the drop&spawn bug
    {
      L2Character player_char = getActor();     
      if(player_char instanceof L2PcInstance)
      {   
        clientActionFailed();
        return;
      }     
      object.setXYZ(getActor().getX(), getActor().getY(), getActor().getZ() + 5);
    }

    // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
    moveToPawn(object, 20);
  }

  /**
   * Manage the Interact Intention : Set the interact target and Launch a Move To Pawn Task (offset=60).<BR>
   * <BR>
   * <B><U> Actions</U> : </B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>
   * Set the AI interact target</li> <li>Set the Intention of this AI to AI_INTENTION_INTERACT</li> <li>Move the actor
   * to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)</li><BR>
   * <BR>
   */
  @Override
  protected void onIntentionInteract(L2Object object)
  {
    if(getIntention() == AI_INTENTION_REST)
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    if(_actor.isAllSkillsDisabled())
    {
      // Cancel action client side by sending Server->Client packet ActionFailed to the L2PcInstance actor
      clientActionFailed();
      return;
    }

    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    clientStopAutoAttack();

    if(getIntention() != AI_INTENTION_INTERACT)
    {
      // Set the Intention of this AbstractAI to AI_INTENTION_INTERACT
      changeIntention(AI_INTENTION_INTERACT, object, null);

      // Set the AI interact target
      setTarget(object);

      // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
      moveToPawn(object, 60);
    }
  }

  /**
   * Do nothing.<BR>
   * <BR>
   */
  @Override
  protected void onEvtThink()
  {
  // do nothing
  }

  /**
   * Do nothing.<BR>
   * <BR>
   */
  @Override
  protected void onEvtAggression(L2Character target, int aggro)
  {
  // do nothing
  }

  /**
   * Launch actions corresponding to the Event Stunned then onAttacked Event.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>
   * Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the
   * L2Character</li> <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the
   * L2Character</li> <li>Launch actions corresponding to the Event onAttacked (only for L2AttackableAI after the
   * stunning periode)</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtStunned(L2Character attacker)
  {
    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));

    if(AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
    {
      AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);
    }

    // Stop Server AutoAttack also
    setAutoAttacking(false);

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);

    // Launch actions corresponding to the Event onAttacked (only for L2AttackableAI after the stunning periode)
    onEvtAttacked(attacker);
  }

  /**
   * Launch actions corresponding to the Event Sleeping.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>
   * Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>Break an attack and send Server->Client ActionFailed packet and a System Message to the
   * L2Character</li> <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the
   * L2Character</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtSleeping(L2Character attacker)
  {
    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));

    if(AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
    {
      AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);
    }

    // stop Server AutoAttack also
    setAutoAttacking(false);

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);
  }

  /**
   * Launch actions corresponding to the Event Rooted.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>Launch actions corresponding to the Event onAttacked</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtRooted(L2Character attacker)
  {
    // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
    //_actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
    //if (AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
    //    AttackStanceTaskManager.getInstance().removeAttackStanceTask(_actor);

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);

    // Launch actions corresponding to the Event onAttacked
    onEvtAttacked(attacker);

  }

  /**
   * Launch actions corresponding to the Event Confused.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>Launch actions corresponding to the Event onAttacked</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtConfused(L2Character attacker)
  {
    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);

    // Launch actions corresponding to the Event onAttacked
    onEvtAttacked(attacker);
  }

  /**
   * Launch actions corresponding to the Event Muted.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtMuted(L2Character attacker)
  {
    // Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character
    onEvtAttacked(attacker);
  }

  /**
   * Launch actions corresponding to the Event ReadyToAct.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Launch actions corresponding to the Event Think</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtReadyToAct()
  {
    // Launch actions corresponding to the Event Think
    onEvtThink();
  }

  /**
   * Do nothing.<BR>
   * <BR>
   */
  @Override
  protected void onEvtUserCmd(Object arg0, Object arg1)
  {
  // do nothing
  }

  /**
   * Launch actions corresponding to the Event Arrived.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE</li> <li>Launch actions
   * corresponding to the Event Think</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtArrived()
  {
    // Launch an explore task if necessary
    if(_accessor.getActor() instanceof L2PcInstance)
      ((L2PcInstance) _accessor.getActor()).revalidateZone(true);
    else
      _accessor.getActor().revalidateZone();

    if(_accessor.getActor().moveToNextRoutePoint())
      return;

    clientStoppedMoving();

    // If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE
    if(getIntention() == AI_INTENTION_MOVE_TO)
    {
      setIntention(AI_INTENTION_ACTIVE);
    }

    // Launch actions corresponding to the Event Think
    onEvtThink();

    if(_actor instanceof L2BoatInstance)
    {
      ((L2BoatInstance) _actor).evtArrived();
    }
  }

  /**
   * Launch actions corresponding to the Event ArrivedRevalidate.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Launch actions corresponding to the Event Think</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtArrivedRevalidate()
  {
    // Launch actions corresponding to the Event Think
    onEvtThink();
  }

  /**
   * Launch actions corresponding to the Event ArrivedBlocked.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE</li> <li>
   * Launch actions corresponding to the Event Think</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtArrivedBlocked(L2CharPosition blocked_at_pos)
  {
    // If the Intention was AI_INTENTION_MOVE_TO, set the Intention to AI_INTENTION_ACTIVE
    if ((getIntention() == AI_INTENTION_MOVE_TO) || (getIntention() == AI_INTENTION_CAST))
      setIntention(AI_INTENTION_ACTIVE);

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(blocked_at_pos);

    // Launch actions corresponding to the Event Think
    onEvtThink();
  }

  /**
   * Launch actions corresponding to the Event ForgetObject.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>If the object was targeted and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the
   * Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to attack, stop the auto-attack, cancel
   * target and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to cast, cancel target
   * and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the object was targeted to follow, stop the movement,
   * cancel AI Follow Task and set the Intention to AI_INTENTION_ACTIVE</li> <li>If the targeted object was the actor
   * , cancel AI target, stop AI Follow Task, stop the movement and set the Intention to AI_INTENTION_IDLE</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtForgetObject(L2Object object)
  {
    // If the object was targeted  and the Intention was AI_INTENTION_INTERACT or AI_INTENTION_PICK_UP, set the Intention to AI_INTENTION_ACTIVE
    if(getTarget() == object)
    {
      setTarget(null);

      if(getIntention() == AI_INTENTION_INTERACT)
      {
        setIntention(AI_INTENTION_ACTIVE);
      }
      else if(getIntention() == AI_INTENTION_PICK_UP)
      {
        setIntention(AI_INTENTION_ACTIVE);
      }
    }

    // Check if the object was targeted to attack
    if(getAttackTarget() == object)
    {
      // Cancel attack target
      setAttackTarget(null);

      // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
      setIntention(AI_INTENTION_ACTIVE);
    }

    // Check if the object was targeted to cast
    if(getCastTarget() == object)
    {
      // Cancel cast target
      setCastTarget(null);

      // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
      setIntention(AI_INTENTION_ACTIVE);
    }

    // Check if the object was targeted to follow
    if(getFollowTarget() == object)
    {
      // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
      clientStopMoving(null);

      // Stop an AI Follow Task
      stopFollow();

      // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
      setIntention(AI_INTENTION_ACTIVE);
    }

    // Check if the targeted object was the actor
    if(_actor == object)
    {
      // Cancel AI target
      setTarget(null);
      setAttackTarget(null);
      setCastTarget(null);

      // Stop an AI Follow Task
      stopFollow();

      // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
      clientStopMoving(null);

      // Set the Intention of this AbstractAI to AI_INTENTION_IDLE
      changeIntention(AI_INTENTION_IDLE, null, null);
    }
  }

  /**
   * Launch actions corresponding to the Event Cancel.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop an AI Follow Task</li> <li>Launch actions corresponding to the Event Think</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtCancel()
  {
    // Stop an AI Follow Task
    stopFollow();

    if(!AttackStanceTaskManager.getInstance().getAttackStanceTask(_actor))
    {
      _actor.broadcastPacket(new AutoAttackStop(_actor.getObjectId()));
    }

    // Launch actions corresponding to the Event Think
    onEvtThink();
  }

  /**
   * Launch actions corresponding to the Event Dead.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop an AI Follow Task</li> <li>Kill the actor client side by sending Server->Client packet AutoAttackStop,
   * StopMove/StopRotation, Die (broadcast)</li><BR>
   * <BR>
   */
  @Override
  protected void onEvtDead()
  {
    // Stop an AI Follow Task
    stopFollow();

    // Kill the actor client side by sending Server->Client packet AutoAttackStop, StopMove/StopRotation, Die (broadcast)
    clientNotifyDead();

    if(!(_actor instanceof L2PcInstance))
    {
      _actor.setWalking();
    }
  }

  /**
   * Launch actions corresponding to the Event Fake Death.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Stop an AI Follow Task</li>
   */
  @Override
  protected void onEvtFakeDeath()
  {
    // Stop an AI Follow Task
    stopFollow();

    // Stop the actor movement and send Server->Client packet StopMove/StopRotation (broadcast)
    clientStopMoving(null);

    // Init AI
    setIntention(AI_INTENTION_IDLE);
    setTarget(null);
    setCastTarget(null);
    setAttackTarget(null);
  }

  /**
   * Do nothing.<BR>
   * <BR>
   */
  @Override
  protected void onEvtFinishCasting()
  {
  // do nothing
  }

  /**
   * Manage the Move to Pawn action in function of the distance and of the Interact area.<BR>
   * <BR>
   * <B><U> Actions</U> :</B><BR>
   * <BR>
   * <li>Get the distance between the current position of the L2Character and the target (x,y)</li> <li>If the
   * distance > offset+20, move the actor (by running) to Pawn server side AND client side by sending Server->Client
   * packet MoveToPawn (broadcast)</li> <li>If the distance <= offset+20, Stop the actor movement server side AND
   * client side by sending Server->Client packet StopMove/StopRotation (broadcast)</li><BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>L2PLayerAI, L2SummonAI</li><BR>
   * <BR>
   *
   * @param target The targeted L2Object
   * @param offset The Interact area radius
   * @return True if a movement must be done
   */
  protected boolean maybeMoveToPawn(L2Object target, int offset)
  {
    // Get the distance between the current position of the L2Character and the target (x,y)
    if(target == null)
    {
      _log.warning("maybeMoveToPawn: target == NULL!");
      return false;
    }

    // skill radius -1
    if(offset < 0)
      return false;

    offset += _actor.getTemplate().collisionRadius;

    if(target instanceof L2Character)
    {
      offset += ((L2Character) target).getTemplate().collisionRadius;
    }

    if(!_actor.isInsideRadius(target, offset, false, false))
    {
      final L2Character follow = getFollowTarget();

      // Caller should be L2Playable and thinkAttack/thinkCast/thinkInteract/thinkPickUp
      if(follow != null)
      {
        // prevent attack-follow into peace zones
        if(getAttackTarget() != null && _actor instanceof L2PlayableInstance && target instanceof L2PlayableInstance)
        {
          if(getAttackTarget() == follow)
          {
            // allow GMs to keep following
            boolean isGM = _actor instanceof L2PcInstance ? ((L2PcInstance) _actor).isGM() : false;
            if(L2Character.isInsidePeaceZone(_actor, target) && !isGM)
            {
              stopFollow();
              setIntention(AI_INTENTION_IDLE);
              return true;
            }
          }
        }
        // if the target is too far (maybe also teleported)
        if(!_actor.isInsideRadius(target, 2000, false, false))
        {
          stopFollow();
          setIntention(AI_INTENTION_IDLE);
          return true;
        }
        // allow larger hit range when the target is moving (check is run only once per second)
        if(!_actor.isInsideRadius(target, offset + 100, false, false))
          return true;

        stopFollow();
        return false;
      }

      if(_actor.isMovementDisabled())
        return true;

      // If not running, set the L2Character movement type to run and send Server->Client packet ChangeMoveType to all others L2PcInstance
      if(!_actor.isRunning() && !(this instanceof L2PlayerAI))
      {
        _actor.setRunning();
      }

      stopFollow();

      if(target instanceof L2Character && !(target instanceof L2DoorInstance))
      {
        if(((L2Character) target).isMoving())
        {
          offset -= 100;
        }
        if(offset < 5)
        {
          offset = 5;
        }

        startFollow((L2Character) target, offset);
      }
      else
      {
        // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast)
        moveToPawn(target, offset);
      }
      return true;
    }

    if(getFollowTarget() != null)
    {
      stopFollow();
    }

    // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
    // clientStopMoving(null);
    return false;
  }

  /**
   * Modify current Intention and actions if the target is lost or dead.<BR>
   * <BR>
   * <B><U> Actions</U> : <I>If the target is lost or dead</I></B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li><BR>
   * Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation<BR>
   * (broadcast)</li> <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>L2PLayerAI, L2SummonAI</li><BR>
   * <BR>
   * @param target The targeted L2Object
   * @return True if the target is lost or dead (false if fakedeath)
   */
  protected boolean checkTargetLostOrDead(L2Character target)
  {
    if (target == null || target.isAlikeDead())
    {
      // check if player is fakedeath
      if (target != null && target.isFakeDeath())
      {
        // target.stopFakeDeath(null);
        return false;
      }
     
      // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
      setIntention(AI_INTENTION_ACTIVE);
     
      return true;
    }
    return false;
  }

  /**
   * Modify current Intention and actions if the target is lost.<BR>
   * <BR>
   * <B><U> Actions</U> : <I>If the target is lost</I></B><BR>
   * <BR>
   * <li>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)</li> <li>
   * Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation
   * (broadcast)</li> <li>Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE</li><BR>
   * <BR>
   * <B><U> Example of use </U> :</B><BR>
   * <BR>
   * <li>L2PLayerAI, L2SummonAI</li><BR>
   * <BR>
   *
   * @param target The targeted L2Object
   * @return True if the target is lost
   */
  protected boolean checkTargetLost(L2Object target)
  {
    // check if player is fakedeath
    if(target instanceof L2PcInstance)
    {
      L2PcInstance target2 = (L2PcInstance) target; //convert object to chara

      if(target2.isFakeDeath())
      {
        target2.stopFakeDeath(null);
        return false;
      }
      target2 = null;
    }
    if(target == null)
    {
      // Set the Intention of this AbstractAI to AI_INTENTION_ACTIVE
      setIntention(AI_INTENTION_ACTIVE);

      return true;
    }
    return false;
  }

  /**
   * @see com.l2jfrozen.gameserver.ai.AbstractAI#onIntentionActive()
   */
  @Override
  protected void onIntentionActive()
  {
    // Check if the Intention is not already Active
    if(getIntention() != AI_INTENTION_ACTIVE)
    {
      // Set the AI Intention to AI_INTENTION_ACTIVE
      changeIntention(AI_INTENTION_ACTIVE, null, null);

      // Init cast and attack target
      setCastTarget(null);
      setAttackTarget(null);

      // Stop the actor movement server side AND client side by sending Server->Client packet StopMove/StopRotation (broadcast)
      clientStopMoving(null);

      // Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
      clientStopAutoAttack();

      // Also enable random animations for this L2Character if allowed
      // This is only for mobs - town npcs are handled in their constructor
      if(_actor instanceof L2Attackable)
      {
        ((L2NpcInstance) _actor).startRandomAnimationTimer();
      }

      // Launch the Think Event
      onEvtThink();
    }
  }

  /**
   * @return the _skill
   */
  public synchronized L2Skill get_skill()
  {
    return _skill;
  }

  /**
   * @param _skill the _skill to set
   */
  public synchronized void set_skill(L2Skill _skill)
  {
    this._skill = _skill;
  }
 
    public IntentionCommand getNextIntention()
    {
      return null;
    }

}
TOP

Related Classes of com.l2jfrozen.gameserver.ai.L2CharacterAI

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.