/** * 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>Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop * (broadcast) * <li>Cancel action client side by sending Server->Client packet ActionFailed to the L2Player * actor * <li>Set the AI skill used by INTENTION_CAST * <li>Set the Intention of this AI to AI_INTENTION_CAST * <li>Launch the Think Event <br> * <br> */ @Override protected void onIntentionCast(SkillUsageRequest request) { final L2Skill skill = request.getSkill(); if (getIntention() == AI_INTENTION_REST && skill.isMagic()) { clientActionFailed(); return; } // 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 L2Player // actor // no need for second ActionFailed packet, abortAttack() already sent it // clientActionFailed(); } final L2Object target = request.getSkill().getFirstOfTargetList(_actor); // Change the Intention of this AbstractAI to AI_INTENTION_CAST changeIntention(AI_INTENTION_CAST, request, target); final Point3D p = request.getSkillWorldPosition(); if (p != null) { // normally magicskilluse packet turns char client side but for these skills, it doesn't (even // with correct target) _actor.setHeading( Util.calculateHeadingFrom(_actor.getX(), _actor.getY(), p.getX(), p.getY())); _actor.broadcastPacket(new ValidateLocation(_actor)); } // Launch the Think Event notifyEvent(CtrlEvent.EVT_THINK, null); }
/** * 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>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>If the distance <= offset+20, Stop the actor movement server side AND client side by * sending Server->Client packet StopMove/StopRotation (broadcast)<br> * <br> * <B><U> Example of use </U> :</B><br> * <br> * <li>L2PLayerAI, L2SummonAI<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) { final int originalOffset = offset; // Get the distance between the current position of the L2Character and the target (x,y) if (target == null) { _log.warn("maybeMoveToPawn: target == NULL!"); return false; } if (offset < 0) return false; // skill radius -1 offset += _actor.getTemplate().getCollisionRadius(); if (target instanceof L2Character) offset += ((L2Character) target).getTemplate().getCollisionRadius(); final double distance = Util.calculateDistance(_actor, target, false); if (distance > offset) { // Caller should be L2Playable and thinkAttack/thinkCast/thinkInteract/thinkPickUp if (getFollowTarget() != null) { if (!isInsideActingRadius(target, distance, offset)) return true; stopFollow(); return false; } if (_actor.isMovementDisabled()) return true; // while flying there is no move to cast if (getIntention() == CtrlIntention.AI_INTENTION_CAST && _actor instanceof L2Player && ((L2Player) _actor).getPlayerTransformation().isTransformed()) { if (!((L2Player) _actor) .getPlayerTransformation() .getTransformation() .canStartFollowToCast()) { _actor.sendPacket(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED); _actor.sendPacket(ActionFailed.STATIC_PACKET); return true; } } if (getIntention() == CtrlIntention.AI_INTENTION_CAST) { if (getCurrentSkill().isShiftPressed()) { _actor.sendPacket(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED); _actor.sendPacket(ActionFailed.STATIC_PACKET); return true; } } // If not running, set the L2Character movement type to run and send Server->Client packet // ChangeMoveType to all others L2Player if (!_actor.isRunning() && !(this instanceof L2PlayerAI) && !(this instanceof L2SummonAI)) _actor.setRunning(); stopFollow(); if ((target instanceof L2Character) && !(target instanceof L2DoorInstance)) { startFollow((L2Character) target, originalOffset); } 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; }