Форум администраторов игровых серверов

Форум администраторов игровых серверов (https://forum.zone-game.info/TT.php)
-   Работа со скриптами (https://forum.zone-game.info/forumdisplay.php?f=37)
-   -   Не могу подцепить AI гварду (https://forum.zone-game.info/showthread.php?t=29689)

energy 23.06.2013 23:09

Не могу подцепить AI гварду
 
Создал гварда по аналогии с L2GuardInstance. Имеется три класа (GuardLevelInstance, GuardLevelKnownlist, GuardLevelAI) - все сделано как в классах L2GuardInstance, GuardKnownList, L2AttackableAI - соответственно, за исключением удаления/редактирования некоторых полей и изменения подключаеммых пакетов. Также создал в базе тип "Type" "GuardLevel".
Когда включаю гварда без GuardLevelAI сервер грузится, гвард переходит из режима IDLE в ACTIVE, тип гварда определяется как GuardLevel. Но стоит только подключить AI в GuardLevelInstance
Код:

       
@Override
        public L2CharacterAI getAI() {
                L2CharacterAI ai = _ai; // copy handle
                if (ai == null) {
                        synchronized (this) {
                                if (_ai == null)
                                        _ai = new GuardLevelAI(new AIAccessor());
                                return _ai;
                        }
                }
                return ai;
        }

как появляется такая ошибка
[SPOILER]:
Свернуть ↑Развернуть ↓


Подскажите в чем может быть проблемма? Где этот Spawn прописать?

L2Jserver CT2.3

Mifesto 23.06.2013 23:35

Re: Не могу подцепить AI гварду
 
у вас в ошибке пишется что не может преобразовать в L2AttackableAI, у вас самого АИ родитель не тот, нужно унаследовать от L2AttackableAI.

energy 23.06.2013 23:49

Re: Не могу подцепить AI гварду
 
Цитата:

Сообщение от Mifesto (Сообщение 307286)
у вас в ошибке пишется что не может преобразовать в L2AttackableAI, у вас самого АИ родитель не тот, нужно унаследовать от L2AttackableAI.

Хорошо, спасибо, ппопробую, но почему же обычные гварды нормально работают. У них этот же суперкласс.

Добавлено через 1 час 2 минуты
Если не сложно, то посмотрите эти коды. Я пробовал изменять родительский клас, но результат тот же.

GuardLevelInstance

Код:

/*
 * 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 net.sf.l2j.gameserver.model.actor.instance;

import java.util.logging.Logger;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ThreadPoolManager;
import net.sf.l2j.gameserver.ai.CtrlIntention;
import net.sf.l2j.gameserver.ai.GuardLevelAI;
import net.sf.l2j.gameserver.model.L2CharPosition;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.L2WorldRegion;
import net.sf.l2j.gameserver.model.actor.L2Attackable;
import net.sf.l2j.gameserver.model.actor.L2Character;
import net.sf.l2j.gameserver.model.actor.L2Summon;
import net.sf.l2j.gameserver.model.actor.knownlist.GuardLevelKnownList;
import net.sf.l2j.gameserver.model.quest.Quest;
import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
import net.sf.l2j.gameserver.network.serverpackets.MyTargetSelected;
import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
import net.sf.l2j.gameserver.network.serverpackets.ValidateLocation;
import net.sf.l2j.gameserver.templates.chars.L2NpcTemplate;
import net.sf.l2j.util.Rnd;

/**
 * This class manages all Guards in the world. It inherits all methods from
 * L2Attackable and adds some more such as tracking PK and aggressive
 * L2MonsterInstance.<BR>
 * <BR>
 *
 * @version $Revision: 1.11.2.1.2.7 $ $Date: 2005/04/06 16:13:40 $
 */
public final class GuardLevelInstance extends L2Attackable {
        private static Logger _log = Logger.getLogger(GuardLevelInstance.class
                        .getName());

        private static final int RETURN_INTERVAL = 60000;

        public class ReturnTask implements Runnable {
                public void run() {
                        if (getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
                                returnHome();
                }
        }

        /**
        * Constructor of GuardLevelInstance (use L2Character and L2NpcInstance
        * constructor).<BR>
        * <BR>
        *
        * <B><U> Actions</U> :</B><BR>
        * <BR>
        * <li>Call the L2Character constructor to set the _template of the
        * GuardLevelInstance (copy skills from template to object and link
        * _calculators to NPC_STD_CALCULATOR)</li> <li>Set the name of the
        * GuardLevelInstance</li> <li>Create a RandomAnimation Task that will be
        * launched after the calculated delay if the server allow it</li><BR>
        * <BR>
        *
        * @param objectId
        *            Identifier of the object to initialized
        * @param L2NpcTemplate
        *            Template to apply to the NPC
        */
        public GuardLevelInstance(int objectId, L2NpcTemplate template) {
                super(objectId, template);

                ThreadPoolManager.getInstance().scheduleAiAtFixedRate(new ReturnTask(),
                                RETURN_INTERVAL, RETURN_INTERVAL + Rnd.nextInt(60000));
        }

        @Override
        public final GuardLevelKnownList getKnownList() {
                return (GuardLevelKnownList) super.getKnownList();
        }

        @Override
        public void initKnownList() {
                setKnownList(new GuardLevelKnownList(this));
        }

        /**
        * Return True if hte attacker is a L2MonsterInstance.<BR>
        * <BR>
        */
        @Override
        public boolean isAutoAttackable(L2Character attacker)
        {
                if (((L2PcInstance) attacker).getLevel()>40)
                        return true;
                if (attacker instanceof L2Summon
                                && ((L2Summon) attacker).getOwner().getLevel()>40)
                        return true;

                else
                        return attacker instanceof L2MonsterInstance;
        }

        /**
        * Notify the GuardLevelInstance to return to its home location
        * (AI_INTENTION_MOVE_TO) and clear its _aggroList.<BR>
        * <BR>
        */
        public void returnHome() {
                if (!isInsideRadius(getSpawn().getLocx(), getSpawn().getLocy(), 150,
                                false)) {
                        clearAggroList();

                        getAI().setIntention(
                                        CtrlIntention.AI_INTENTION_MOVE_TO,
                                        new L2CharPosition(getSpawn().getLocx(), getSpawn()
                                                        .getLocy(), getSpawn().getLocz(), 0));
                }
        }

        /**
        * Set the home location of its GuardLevelInstance.<BR>
        * <BR>
        */
        @Override
        public void onSpawn() {
                setIsNoRndWalk(true);
                super.onSpawn();

                // check the region where this mob is, do not activate the AI if region
                // is inactive.
                L2WorldRegion region = L2World.getInstance().getRegion(getX(), getY());
                if ((region != null) && (!region.isActive()))
                        ((GuardLevelAI) getAI()).stopAITask();
        }

        /**
        * Return the pathfile of the selected HTML file in function of the
        * GuardLevelInstance Identifier and of the page number.<BR>
        * <BR>
        *
        * <B><U> Format of the pathfile </U> :</B><BR>
        * <BR>
        * <li>if page number = 0 : <B>data/html/guard/12006.htm</B> (npcId-page
        * number)</li> <li>if page number > 0 : <B>data/html/guard/12006-1.htm</B>
        * (npcId-page number)</li><BR>
        * <BR>
        *
        * @param npcId
        *            The Identifier of the L2NpcInstance whose text must be display
        * @param val
        *            The number of the page to display
        *
        */
        @Override
        public String getHtmlPath(int npcId, int val) {
                String pom = "";
                if (val == 0) {
                        pom = "" + npcId;
                } else {
                        pom = npcId + "-" + val;
                }
                return "data/html/guard/" + pom + ".htm";
        }

        /**
        * Manage actions when a player click on the GuardLevelInstance.<BR>
        * <BR>
        *
        * <B><U> Actions on first click on the GuardLevelInstance (Select it)</U>
        * :</B><BR>
        * <BR>
        * <li>Set the GuardLevelInstance as target of the L2PcInstance player (if
        * necessary)</li> <li>Send a Server->Client packet MyTargetSelected to the
        * L2PcInstance player (display the select window)</li> <li>Set the
        * L2PcInstance Intention to AI_INTENTION_IDLE</li> <li>Send a
        * Server->Client packet ValidateLocation to correct the GuardLevelInstance
        * position and heading on the client</li><BR>
        * <BR>
        *
        * <B><U> Actions on second click on the GuardLevelInstance (Attack it/Interact
        * with it)</U> :</B><BR>
        * <BR>
        * <li>If L2PcInstance is in the _aggroList of the GuardLevelInstance, set the
        * L2PcInstance Intention to AI_INTENTION_ATTACK</li> <li>If L2PcInstance is
        * NOT in the _aggroList of the GuardLevelInstance, set the L2PcInstance
        * Intention to AI_INTENTION_INTERACT (after a distance verification) and
        * show message</li><BR>
        * <BR>
        *
        * <B><U> Example of use </U> :</B><BR>
        * <BR>
        * <li>Client packet : Action, AttackRequest</li><BR>
        * <BR>
        *
        * @param player
        *            The L2PcInstance that start an action on the GuardLevelInstance
        *
        */
        @Override
        public void onAction(L2PcInstance player) {
                if (!canTarget(player))
                        return;

                // Check if the L2PcInstance already target the GuardLevelInstance
                if (getObjectId() != player.getTargetId()) {
                        if (Config.DEBUG)
                                _log.fine(player.getObjectId() + ": Targetted guard "
                                                + getObjectId());

                        // Set the target of the L2PcInstance player
                        player.setTarget(this);

                        // Send a Server->Client packet MyTargetSelected to the L2PcInstance
                        // player
                        // The color to display in the select window is White
                        MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
                        player.sendPacket(my);

                        // Send a Server->Client packet ValidateLocation to correct the
                        // L2NpcInstance position and heading on the client
                        player.sendPacket(new ValidateLocation(this));
                } else {
                        // Check if the L2PcInstance is in the _aggroList of the
                        // GuardLevelInstance
                        if (containsTarget(player)) {
                                if (Config.DEBUG)
                                        _log.fine(player.getObjectId() + ": Attacked guard "
                                                        + getObjectId());

                                // Set the L2PcInstance Intention to AI_INTENTION_ATTACK
                                player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK,
                                                this);
                        } else {
                                // Calculate the distance between the L2PcInstance and the
                                // L2NpcInstance
                                if (!canInteract(player)) {
                                        // Set the L2PcInstance Intention to AI_INTENTION_INTERACT
                                        player.getAI().setIntention(
                                                        CtrlIntention.AI_INTENTION_INTERACT, this);
                                } else {
                                        // Send a Server->Client packet SocialAction to the all
                                        // L2PcInstance on the _knownPlayer of the L2NpcInstance
                                        // to display a social action of the GuardLevelInstance on
                                        // their client
                                        SocialAction sa = new SocialAction(getObjectId(),
                                                        Rnd.nextInt(8));
                                        broadcastPacket(sa);

                                        // Open a chat window on client with the text of the
                                        // GuardLevelInstance
                                        Quest[] qlsa = getTemplate().getEventQuests(
                                                        Quest.QuestEventType.QUEST_START);
                                        if ((qlsa != null) && qlsa.length > 0)
                                                player.setLastQuestNpcObject(getObjectId());
                                        Quest[] qlst = getTemplate().getEventQuests(
                                                        Quest.QuestEventType.ON_FIRST_TALK);
                                        if ((qlst != null) && qlst.length == 1)
                                                qlst[0].notifyFirstTalk(this, player);
                                        else
                                                showChatWindow(player, 0);
                                }
                        }
                }
                // Send a Server->Client ActionFailed to the L2PcInstance in order to
                // avoid that the client wait another packet
                player.sendPacket(ActionFailed.STATIC_PACKET);
        }
}

GuardLevelKnownList
Код:

/*
 * 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 net.sf.l2j.gameserver.model.actor.knownlist;

import java.util.logging.Logger;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ai.CtrlIntention;
import net.sf.l2j.gameserver.ai.L2CharacterAI;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.actor.instance.GuardLevelInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;


public class GuardLevelKnownList extends AttackableKnownList
{
        private static Logger _log = Logger.getLogger(GuardLevelKnownList.class
                        .getName());

        // =========================================================
        // Data Field

        // =========================================================
        // Constructor
        public GuardLevelKnownList(GuardLevelInstance activeChar) {
                super(activeChar);
        }

        // =========================================================
        // Method - Public
        @Override
        public boolean addKnownObject(L2Object object) {
                if (!super.addKnownObject(object))
                        return false;

                if (object instanceof L2PcInstance) {
                        // Check if the object added is a L2PcInstance that owns Karma
                        L2PcInstance player = (L2PcInstance) object;

                        if ((player.getLevel()>40))
                        {
                                if (Config.DEBUG)
                                        _log.fine(getActiveChar().getObjectId() + ": Enemy "
                                                        + player.getObjectId() + " entered scan range");

                                // Set the GuardLevelInstance Intention to AI_INTENTION_ACTIVE
                                if (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
                                        getActiveChar().getAI().setIntention(
                                                        CtrlIntention.AI_INTENTION_ACTIVE, null);
                        }
                } else if ((Config.GUARD_ATTACK_AGGRO_MOB && getActiveChar()
                                .isInActiveRegion()) && object instanceof L2MonsterInstance) {
                        // Check if the object added is an aggressive L2MonsterInstance
                        L2MonsterInstance mob = (L2MonsterInstance) object;

                        if (mob.isAggressive()) {
                                if (Config.DEBUG)
                                        _log.fine(getActiveChar().getObjectId()
                                                        + ": Aggressive mob " + mob.getObjectId()
                                                        + " entered scan range");

                                // Set the GuardLevelInstance Intention to AI_INTENTION_ACTIVE
                                if (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
                                        getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
                        }
                }

                return true;
        }

        @Override
        public boolean removeKnownObject(L2Object object) {
                if (!super.removeKnownObject(object))
                        return false;

                // Check if the _aggroList of the GuardLevelInstance is Empty
                if (getActiveChar().noTarget()) {
                        // removeAllKnownObjects();

                        // Set the GuardLevelInstance to AI_INTENTION_IDLE
                        L2CharacterAI ai = getActiveChar().getAI();
                        if (ai != null)
                                ai.setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
                }

                return true;
        }

        // =========================================================
        // Method - Private

        // =========================================================
        // Property - Public
        @Override
        public final GuardLevelInstance getActiveChar() {
                return (GuardLevelInstance) super.getActiveChar();
        }
}

GuardLevelAI
Код:

/*
 * 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 net.sf.l2j.gameserver.ai;

import static net.sf.l2j.gameserver.ai.CtrlIntention.*;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.Future;

import javolution.util.FastList;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.GameTimeController;
import net.sf.l2j.gameserver.GeoData;
import net.sf.l2j.gameserver.Territory;
import net.sf.l2j.gameserver.ThreadPoolManager;
import net.sf.l2j.gameserver.model.L2CharPosition;
import net.sf.l2j.gameserver.model.L2Object;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.actor.L2Attackable;
import net.sf.l2j.gameserver.model.actor.L2Character;
import net.sf.l2j.gameserver.model.actor.L2Npc;
import net.sf.l2j.gameserver.model.actor.L2Playable;
import net.sf.l2j.gameserver.model.actor.L2Summon;
import net.sf.l2j.gameserver.model.actor.instance.L2DoorInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2FestivalMonsterInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2FriendlyMobInstance;
import net.sf.l2j.gameserver.model.actor.instance.GuardLevelInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2MinionInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2MonsterInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.util.Util;
import net.sf.l2j.util.Rnd;

/**
 * This class manages AI of L2Attackable.<BR>
 * <BR>
 *
 */
public class GuardLevelAI extends L2CharacterAI implements Runnable
{

        // protected static final Logger _log =
        // Logger.getLogger(L2AttackableAI.class.getName());

        private static final int RANDOM_WALK_RATE = 30; // confirmed
        // private static final int MAX_DRIFT_RANGE = 300;
        private static final int MAX_ATTACK_TIMEOUT = 300; // int ticks, i.e. 30
                                                                                                                // seconds

        /** The L2Attackable AI task executed every 1s (call onEvtThink method) */
        private Future<?> _aiTask;

        /** The delay after which the attacked is stopped */
        private int _attackTimeout;

        /** The L2Attackable aggro counter */
        private int _globalAggro;

        /** The flag used to indicate that a thinking action is in progress */
        private boolean _thinking; // to prevent recursive thinking

        /** For attack AI, analysis of mob and its targets */
        private SelfAnalysis _selfAnalysis = new SelfAnalysis();
        private TargetAnalysis _mostHatedAnalysis = new TargetAnalysis();
        private TargetAnalysis _secondMostHatedAnalysis = new TargetAnalysis();

        /**
        * Constructor of L2AttackableAI.<BR>
        * <BR>
        *
        * @param accessor
        *            The AI accessor of the L2Character
        *
        */
        public GuardLevelAI(L2Character.AIAccessor accessor) {
                super(accessor);
                _selfAnalysis.init();
                _attackTimeout = Integer.MAX_VALUE;
                _globalAggro = -10; // 10 seconds timeout of ATTACK after respawn
        }

        public void run() {
                // Launch actions corresponding to the Event Think
                onEvtThink();

        }

        /**
        * Return True if the target is autoattackable (depends on the actor type).<BR>
        * <BR>
        *
        * <B><U> Actor is a GuardLevelInstance</U> :</B><BR>
        * <BR>
        * <li>The target isn't a Folk or a Door</li> <li>The target isn't dead,
        * isn't invulnerable, isn't in silent moving mode AND too far (>100)</li>
        * <li>The target is in the actor Aggro range and is at the same height</li>
        * <li>The L2PcInstance target has karma (=PK)</li> <li>The
        * L2MonsterInstance target is aggressive</li><BR>
        * <BR>
        *
        * <B><U> Actor is a L2SiegeGuardInstance</U> :</B><BR>
        * <BR>
        * <li>The target isn't a Folk or a Door</li> <li>The target isn't dead,
        * isn't invulnerable, isn't in silent moving mode AND too far (>100)</li>
        * <li>The target is in the actor Aggro range and is at the same height</li>
        * <li>A siege is in progress</li> <li>The L2PcInstance target isn't a
        * Defender</li><BR>
        * <BR>
        *
        * <B><U> Actor is a L2FriendlyMobInstance</U> :</B><BR>
        * <BR>
        * <li>The target isn't a Folk, a Door or another L2NpcInstance</li> <li>The
        * target isn't dead, isn't invulnerable, isn't in silent moving mode AND
        * too far (>100)</li> <li>The target is in the actor Aggro range and is at
        * the same height</li> <li>The L2PcInstance target has karma (=PK)</li><BR>
        * <BR>
        *
        * <B><U> Actor is a L2MonsterInstance</U> :</B><BR>
        * <BR>
        * <li>The target isn't a Folk, a Door or another L2NpcInstance</li> <li>The
        * target isn't dead, isn't invulnerable, isn't in silent moving mode AND
        * too far (>100)</li> <li>The target is in the actor Aggro range and is at
        * the same height</li> <li>The actor is Aggressive</li><BR>
        * <BR>
        *
        * @param target
        *            The targeted L2Object
        *
        */
        private boolean autoAttackCondition(L2Character target) {
                if (target == null || !(_actor instanceof L2Attackable))
                        return false;
                L2Attackable me = (L2Attackable) _actor;

                // Check if the target isn't invulnerable
                if (target.isInvul()) {
                        // However EffectInvincible requires to check GMs specially
                        if (target instanceof L2PcInstance
                                        && ((L2PcInstance) target).isGM())
                                return false;
                        if (target instanceof L2Summon
                                        && ((L2Summon) target).getOwner().isGM())
                                return false;
                }

                // Check if the target isn't a Folk or a Door
                if (target instanceof L2NpcInstance || target instanceof L2DoorInstance)
                        return false;

                // Check if the target isn't dead, is in the Aggro range and is at the
                // same height
                if (target.isAlikeDead()
                                || !me.isInsideRadius(target, me.getAggroRange(), false, false)
                                || Math.abs(_actor.getZ() - target.getZ()) > 300)
                        return false;

                if (_selfAnalysis.cannotMoveOnLand
                                && !target.isInsideZone(L2Character.ZONE_WATER))
                        return false;

                // Check if the target is a L2PlayableInstance
                if (target instanceof L2Playable) {
                        // Check if the AI isn't a Raid Boss and the target isn't in silent
                        // move mode
                        if (!(me.isRaid()) && ((L2Playable) target).isSilentMoving())
                                return false;
                }

                // Check if the target is a L2PcInstance
                if (target instanceof L2PcInstance) {
                        // Don't take the aggro if the GM has the access level below or
                        // equal to GM_DONT_TAKE_AGGRO
                        if (((L2PcInstance) target).isGM()
                                        && !((L2PcInstance) target).getAccessLevel().canTakeAggro())
                                return false;

                        // TODO: Ideally, autoattack condition should be called from the AI
                        // script. In that case,
                        // it should only implement the basic behaviors while the script
                        // will add more specific
                        // behaviors (like varka/ketra alliance, etc). Once implemented,
                        // remove specialized stuff
                        // from this location. (Fulminus)


                        // check if the target is within the grace period for JUST getting
                        // up from fake death
                        if (((L2PcInstance) target).isRecentFakeDeath())
                                return false;


                }
                // Check if the target is a L2Summon
                if (target instanceof L2Summon)
                {
                        L2PcInstance owner = ((L2Summon) target).getOwner();
                        if (owner != null)
                        {
                                // Don't take the aggro if the GM has the access level below or
                                // equal to GM_DONT_TAKE_AGGRO
                                if (owner.isGM()
                                                && (owner.isInvul() || !owner.getAccessLevel()
                                                                .canTakeAggro()))
                                        return false;

                        }
                }
                // Check if the actor is a GuardLevelInstance
                if (_actor instanceof GuardLevelInstance) {

                        // Check if the L2PcInstance target has karma (=PK)
                        if (target instanceof L2PcInstance
                                        && ((L2PcInstance) target).getLevel()>40)
                                // Los Check
                                return GeoData.getInstance().canSeeTarget(me, target);

                        // if (target instanceof L2Summon)
                        // return ((L2Summon)target).getKarma() > 0;

                        // Check if the L2MonsterInstance target is aggressive
                        if (target instanceof L2MonsterInstance)
                                return (((L2MonsterInstance) target).isAggressive() && GeoData
                                                .getInstance().canSeeTarget(me, target));

                        return false;
                } else if (_actor instanceof L2FriendlyMobInstance) { // the actor is a
                                                                                                                                // L2FriendlyMobInstance

                        // Check if the target isn't another L2NpcInstance
                        if (target instanceof L2Npc)
                                return false;

                        // Check if the L2PcInstance target has karma (=PK)
                        if (target instanceof L2PcInstance
                                        && ((L2PcInstance) target).getLevel()>40)
                                // Los Check
                                return GeoData.getInstance().canSeeTarget(me, target);
                        else
                                return false;
                }
                else
                { // The actor is a L2MonsterInstance

                        // Check if the target isn't another L2NpcInstance
                        if (target instanceof L2Npc)
                                return false;



                        // Check if the actor is Aggressive
                        return (me.isAggressive() && GeoData.getInstance().canSeeTarget(me,
                                        target));
                }
        }

        public void startAITask() {
                // If not idle - create an AI task (schedule onEvtThink repeatedly)
                if (_aiTask == null) {
                        _aiTask = ThreadPoolManager.getInstance().scheduleAiAtFixedRate(
                                        this, 1000, 1000);
                }
        }

        public void stopAITask() {
                if (_aiTask != null) {
                        _aiTask.cancel(false);
                        _aiTask = null;
                }
        }

        @Override
        protected void onEvtDead() {
                stopAITask();
                super.onEvtDead();
        }

        /**
        * Set the Intention of this L2CharacterAI and create an AI Task executed
        * every 1s (call onEvtThink method) for this L2Attackable.<BR>
        * <BR>
        *
        * <FONT COLOR=#FF0000><B> <U>Caution</U> : If actor _knowPlayer isn't
        * EMPTY, AI_INTENTION_IDLE will be change in AI_INTENTION_ACTIVE</B></FONT><BR>
        * <BR>
        *
        * @param intention
        *            The new Intention to set to the AI
        * @param arg0
        *            The first parameter of the Intention
        * @param arg1
        *            The second parameter of the Intention
        *
        */
        @Override
        synchronized void changeIntention(CtrlIntention intention, Object arg0,
                        Object arg1) {
                if (intention == AI_INTENTION_IDLE || intention == AI_INTENTION_ACTIVE) {
                        // Check if actor is not dead
                        if (!_actor.isAlikeDead()) {
                                L2Attackable npc = (L2Attackable) _actor;

                                // If its _knownPlayer isn't empty set the Intention to
                                // AI_INTENTION_ACTIVE
                                if (!npc.getKnownList().getKnownPlayers().isEmpty())
                                        intention = AI_INTENTION_ACTIVE;
                                else {
                                        if (npc.getSpawn() != null) {
                                                final int range = Config.MAX_DRIFT_RANGE;
                                                if (!npc.isInsideRadius(npc.getSpawn().getLocx(), npc
                                                                .getSpawn().getLocy(),
                                                                npc.getSpawn().getLocz(), range + range, true,
                                                                false))
                                                        intention = AI_INTENTION_ACTIVE;
                                        }
                                }
                        }

                        if (intention == AI_INTENTION_IDLE) {
                                // Set the Intention of this L2AttackableAI to AI_INTENTION_IDLE
                                super.changeIntention(AI_INTENTION_IDLE, null, null);

                                // Stop AI task and detach AI from NPC
                                if (_aiTask != null) {
                                        _aiTask.cancel(true);
                                        _aiTask = null;
                                }

                                // Cancel the AI
                                _accessor.detachAI();

                                return;
                        }
                }

                // Set the Intention of this L2AttackableAI to intention
                super.changeIntention(intention, arg0, arg1);

                // If not idle - create an AI task (schedule onEvtThink repeatedly)
                startAITask();
        }

        /**
        * Manage the Attack Intention : Stop current Attack (if necessary),
        * Calculate attack timeout, Start a new Attack and Launch Think Event.<BR>
        * <BR>
        *
        * @param target
        *            The L2Character to attack
        *
        */
        @Override
        protected void onIntentionAttack(L2Character target) {
                // Calculate the attack timeout
                _attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks();

                // self and buffs
                if (_selfAnalysis.lastBuffTick + 100 < GameTimeController
                                .getGameTicks()) {
                        for (L2Skill sk : _selfAnalysis.buffSkills) {
                                if (_actor.getFirstEffect(sk.getId()) == null) {
                                        if (_actor.getCurrentMp() < sk.getMpConsume())
                                                continue;
                                        if (_actor.isSkillDisabled(sk.getId()))
                                                continue;
                                        // no clan buffs here?
                                        if (sk.getTargetType() == L2Skill.SkillTargetType.TARGET_CLAN)
                                                continue;
                                        L2Object OldTarget = _actor.getTarget();
                                        _actor.setTarget(_actor);
                                        clientStopMoving(null);
                                        _accessor.doCast(sk);
                                        // forcing long reuse delay so if cast get interrupted or
                                        // there would be several buffs, doesn't cast again
                                        _selfAnalysis.lastBuffTick = GameTimeController
                                                        .getGameTicks();
                                        _actor.setTarget(OldTarget);
                                }
                        }
                }
                // Manage the Attack Intention : Stop current Attack (if necessary),
                // Start a new Attack and Launch Think Event
                super.onIntentionAttack(target);
        }

        /**
        * Manage AI standard thinks of a L2Attackable (called by onEvtThink).<BR>
        * <BR>
        *
        * <B><U> Actions</U> :</B><BR>
        * <BR>
        * <li>Update every 1s the _globalAggro counter to come close to 0</li> <li>
        * If the actor is Aggressive and can attack, add all autoAttackable
        * L2Character in its Aggro Range to its _aggroList, chose a target and
        * order to attack it</li> <li>If the actor is a GuardLevelInstance that can't
        * attack, order to it to return to its home location</li> <li>If the actor
        * is a L2MonsterInstance that can't attack, order to it to random walk
        * (1/100)</li><BR>
        * <BR>
        *
        */
        private void thinkActive() {
                L2Attackable npc = (L2Attackable) _actor;

                // Update every 1s the _globalAggro counter to come close to 0
                if (_globalAggro != 0) {
                        if (_globalAggro < 0)
                                _globalAggro++;
                        else
                                _globalAggro--;
                }

                // Add all autoAttackable L2Character in L2Attackable Aggro Range to its
                // _aggroList with 0 damage and 1 hate
                // A L2Attackable isn't aggressive during 10s after its spawn because
                // _globalAggro is set to -10
                if (_globalAggro >= 0) {
                        // Get all visible objects inside its Aggro Range
                        // L2Object[] objects =
                        // L2World.getInstance().getVisibleObjects(_actor,
                        // ((L2NpcInstance)_actor).getAggroRange());
                        // Go through visible objects
                        Collection<L2Object> objs = npc.getKnownList().getKnownObjects()
                                        .values();
                        // synchronized (npc.getKnownList().getKnownObjects())
                        {
                                for (L2Object obj : objs) {
                                        if (!(obj instanceof L2Character))
                                                continue;
                                        L2Character target = (L2Character) obj;



                                        /*
                                        * Temporarily adding this commented code as a concept to be
                                        * used eventually. However, the way it is written below
                                        * will NOT work correctly. The NPC should only notify Aggro
                                        * Range Enter when someone enters the range from outside.
                                        * Instead, the below code will keep notifying even while
                                        * someone remains within the range. Perhaps we need a short
                                        * knownlist of range = aggroRange for just people who are
                                        * actively within the npc's aggro range?...(Fulminus) //
                                        * notify AI that a playable instance came within aggro
                                        * range if ((obj instanceof L2PcInstance) || (obj
                                        * instanceof L2Summon)) { if (
                                        * !((L2Character)obj).isAlikeDead() &&
                                        * !npc.isInsideRadius(obj, npc.getAggroRange(), true,
                                        * false) ) { L2PcInstance targetPlayer = (obj instanceof
                                        * L2PcInstance)? (L2PcInstance) obj: ((L2Summon)
                                        * obj).getOwner(); if
                                        * (npc.getTemplate().getEventQuests(Quest
                                        * .QuestEventType.ON_AGGRO_RANGE_ENTER) !=null) for (Quest
                                        * quest:
                                        * npc.getTemplate().getEventQuests(Quest.QuestEventType
                                        * .ON_AGGRO_RANGE_ENTER)) quest.notifyAggroRangeEnter(npc,
                                        * targetPlayer, (obj instanceof L2Summon)); } }
                                        */
                                        // TODO: The AI Script ought to handle aggro behaviors in
                                        // onSee. Once implemented, aggro behaviors ought
                                        // to be removed from here. (Fulminus)
                                        // For each L2Character check if the target is
                                        // autoattackable
                                        if (autoAttackCondition(target)) // check aggression
                                        {
                                                // Get the hate level of the L2Attackable against this
                                                // L2Character target contained in _aggroList
                                                int hating = npc.getHating(target);

                                                // Add the attacker to the L2Attackable _aggroList with
                                                // 0 damage and 1 hate
                                                if (hating == 0)
                                                        npc.addDamageHate(target, 0, 0);
                                        }
                                }
                        }

                        // Chose a target from its aggroList
                        L2Character hated;
                        if (_actor.isConfused())
                                hated = getAttackTarget(); // effect handles selection
                        else
                                hated = npc.getMostHated();

                        // Order to the L2Attackable to attack the target
                        if (hated != null) {
                                // Get the hate level of the L2Attackable against this
                                // L2Character target contained in _aggroList
                                int aggro = npc.getHating(hated);

                                if (aggro + _globalAggro > 0) {
                                        // Set the L2Character movement type to run and send
                                        // Server->Client packet ChangeMoveType to all others
                                        // L2PcInstance
                                        if (!_actor.isRunning())
                                                _actor.setRunning();

                                        // Set the AI Intention to AI_INTENTION_ATTACK
                                        setIntention(CtrlIntention.AI_INTENTION_ATTACK, hated);
                                }

                                return;
                        }

                }

                // Check if the actor is a GuardLevelInstance
                if (_actor instanceof GuardLevelInstance) {
                        // Order to the GuardLevelInstance to return to its home location
                        // because there's no target to attack
                        ((GuardLevelInstance) _actor).returnHome();
                }

                // If this is a festival monster, then it remains in the same location.
                if (_actor instanceof L2FestivalMonsterInstance)
                        return;

                // Check if the mob should not return to spawn point
                if (!npc.canReturnToSpawnPoint())
                        return;

                // Minions following leader
                if (_actor instanceof L2MinionInstance
                                && ((L2MinionInstance) _actor).getLeader() != null) {
                        int offset;

                        if (_actor.isRaidMinion())
                                offset = 500; // for Raids - need correction
                        else
                                offset = 200; // for normal minions - need correction :)

                        if (((L2MinionInstance) _actor).getLeader().isRunning())
                                _actor.setRunning();
                        else
                                _actor.setWalking();

                        if (_actor.getPlanDistanceSq(((L2MinionInstance) _actor)
                                        .getLeader()) > offset * offset) {
                                int x1, y1, z1;
                                x1 = ((L2MinionInstance) _actor).getLeader().getX()
                                                + Rnd.nextInt((offset - 30) * 2) - (offset - 30);
                                y1 = ((L2MinionInstance) _actor).getLeader().getY()
                                                + Rnd.nextInt((offset - 30) * 2) - (offset - 30);
                                z1 = ((L2MinionInstance) _actor).getLeader().getZ();
                                // Move the actor to Location (x,y,z) server side AND client
                                // side by sending Server->Client packet CharMoveToLocation
                                // (broadcast)
                                moveTo(x1, y1, z1);
                                return;
                        } else if (Rnd.nextInt(RANDOM_WALK_RATE) == 0) {
                                // self and clan buffs
                                for (L2Skill sk : _selfAnalysis.buffSkills) {
                                        if (_actor.getFirstEffect(sk.getId()) == null) {
                                                // if clan buffs, don't buff every time
                                                if (sk.getTargetType() != L2Skill.SkillTargetType.TARGET_SELF
                                                                && Rnd.nextInt(2) != 0)
                                                        continue;
                                                if (_actor.getCurrentMp() < sk.getMpConsume())
                                                        continue;
                                                if (_actor.isSkillDisabled(sk.getId()))
                                                        continue;
                                                L2Object OldTarget = _actor.getTarget();
                                                _actor.setTarget(_actor);
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _actor.setTarget(OldTarget);
                                                return;
                                        }
                                }
                        }
                }
                // Order to the L2MonsterInstance to random walk (1/100)
                else if (npc.getSpawn() != null && Rnd.nextInt(RANDOM_WALK_RATE) == 0
                                && !_actor.isNoRndWalk()) {
                        int x1, y1, z1;
                        final int range = Config.MAX_DRIFT_RANGE;

                        // self and clan buffs
                        for (L2Skill sk : _selfAnalysis.buffSkills) {
                                if (_actor.getFirstEffect(sk.getId()) == null) {
                                        // if clan buffs, don't buff every time
                                        if (sk.getTargetType() != L2Skill.SkillTargetType.TARGET_SELF
                                                        && Rnd.nextInt(2) != 0)
                                                continue;
                                        if (_actor.getCurrentMp() < sk.getMpConsume())
                                                continue;
                                        if (_actor.isSkillDisabled(sk.getId()))
                                                continue;
                                        L2Object OldTarget = _actor.getTarget();
                                        _actor.setTarget(_actor);
                                        clientStopMoving(null);
                                        _accessor.doCast(sk);
                                        _actor.setTarget(OldTarget);
                                        return;
                                }
                        }

                        // If NPC with random coord in territory
                        if (npc.getSpawn().getLocx() == 0 && npc.getSpawn().getLocy() == 0) {
                                // Calculate a destination point in the spawn area
                                int p[] = Territory.getInstance().getRandomPoint(
                                                npc.getSpawn().getLocation());
                                x1 = p[0];
                                y1 = p[1];
                                z1 = p[2];

                                // Calculate the distance between the current position of the
                                // L2Character and the target (x,y)
                                double distance2 = _actor.getPlanDistanceSq(x1, y1);

                                if (distance2 > (range + range) * (range + range)) {
                                        npc.setisReturningToSpawnPoint(true);
                                        float delay = (float) Math.sqrt(distance2) / range;
                                        x1 = _actor.getX() + (int) ((x1 - _actor.getX()) / delay);
                                        y1 = _actor.getY() + (int) ((y1 - _actor.getY()) / delay);
                                }

                                // If NPC with random fixed coord, don't move (unless needs to
                                // return to spawnpoint)
                                if (Territory.getInstance().getProcMax(
                                                npc.getSpawn().getLocation()) > 0
                                                && !npc.isReturningToSpawnPoint())
                                        return;
                        } else {
                                // If NPC with fixed coord
                                x1 = npc.getSpawn().getLocx();
                                y1 = npc.getSpawn().getLocy();
                                z1 = npc.getSpawn().getLocz();

                                if (!_actor.isInsideRadius(x1, y1, z1, range + range, true,
                                                false))
                                        npc.setisReturningToSpawnPoint(true);
                                else {
                                        x1 += Rnd.nextInt(range * 2) - range;
                                        y1 += Rnd.nextInt(range * 2) - range;
                                        z1 = npc.getZ();
                                }
                        }

                        // _log.config("Curent pos ("+getX()+", "+getY()+"), moving to ("+x1+", "+y1+").");
                        // Move the actor to Location (x,y,z) server side AND client side by
                        // sending Server->Client packet CharMoveToLocation (broadcast)
                        moveTo(x1, y1, z1);
                }
        }

        /**
        * Manage AI attack thinks of a L2Attackable (called by onEvtThink).<BR>
        * <BR>
        *
        * <B><U> Actions</U> :</B><BR>
        * <BR>
        * <li>Update the attack timeout if actor is running</li> <li>If target is
        * dead or timeout is expired, stop this attack and set the Intention to
        * AI_INTENTION_ACTIVE</li> <li>Call all L2Object of its Faction inside the
        * Faction Range</li> <li>Chose a target and order to attack it with magic
        * skill or physical attack</li><BR>
        * <BR>
        *
        * TODO: Manage casting rules to healer mobs (like Ant Nurses)
        *
        */
        private void thinkAttack() {
                if (_attackTimeout < GameTimeController.getGameTicks()) {
                        // Check if the actor is running
                        if (_actor.isRunning()) {
                                // Set the actor movement type to walk and send Server->Client
                                // packet ChangeMoveType to all others L2PcInstance
                                _actor.setWalking();

                                // Calculate a new attack timeout
                                _attackTimeout = MAX_ATTACK_TIMEOUT
                                                + GameTimeController.getGameTicks();
                        }
                }

                L2Character originalAttackTarget = getAttackTarget();
                // Check if target is dead or if timeout is expired to stop this attack
                if (originalAttackTarget == null || originalAttackTarget.isAlikeDead()
                                || _attackTimeout < GameTimeController.getGameTicks()) {
                        // Stop hating this target after the attack timeout or if target is
                        // dead
                        if (originalAttackTarget != null)
                                ((L2Attackable) _actor).stopHating(originalAttackTarget);

                        // Set the AI Intention to AI_INTENTION_ACTIVE
                        setIntention(AI_INTENTION_ACTIVE);

                        _actor.setWalking();
                        return;
                }



                if (_actor.isAttackingDisabled())
                        return;

                // Get 2 most hated chars
                List<L2Character> hated = ((L2Attackable) _actor).get2MostHated();
                if (_actor.isConfused()) {
                        if (hated != null)
                                hated.set(0, originalAttackTarget); // effect handles selection
                        else {
                                hated = new FastList<L2Character>();
                                hated.add(originalAttackTarget);
                                hated.add(null);
                        }
                }

                if (hated == null || hated.get(0) == null) {
                        setIntention(AI_INTENTION_ACTIVE);
                        return;
                }
                if (hated.get(0) != originalAttackTarget) {
                        setAttackTarget(hated.get(0));
                }
                _mostHatedAnalysis.update(hated.get(0));
                _secondMostHatedAnalysis.update(hated.get(1));

                // Get all information needed to choose between physical or magical
                // attack
                _actor.setTarget(_mostHatedAnalysis.character);
                double dist2 = _actor.getPlanDistanceSq(
                                _mostHatedAnalysis.character.getX(),
                                _mostHatedAnalysis.character.getY());
                int combinedCollision = _actor.getTemplate().collisionRadius
                                + _mostHatedAnalysis.character.getTemplate().collisionRadius;
                int range = _actor.getPhysicalAttackRange() + combinedCollision;

                // Reconsider target next round if _actor hasn't got hits in for last 14
                // seconds
                if (!_actor.isMuted()
                                && _attackTimeout - 160 < GameTimeController.getGameTicks()
                                && _secondMostHatedAnalysis.character != null) {
                        if (Util.checkIfInRange(900, _actor, hated.get(1), true)) {
                                // take off 2* the amount the aggro is larger than second most
                                ((L2Attackable) _actor)
                                                .reduceHate(hated.get(0),
                                                                2 * (((L2Attackable) _actor).getHating(hated
                                                                                .get(0)) - ((L2Attackable) _actor)
                                                                                .getHating(hated.get(1))));
                                // Calculate a new attack timeout
                                _attackTimeout = MAX_ATTACK_TIMEOUT
                                                + GameTimeController.getGameTicks();
                        }
                }
                // Reconsider target during next round if actor is rooted and cannot
                // reach mostHated but can
                // reach secondMostHated
                if (_actor.isRooted() && _secondMostHatedAnalysis.character != null) {
                        if (_selfAnalysis.isMage
                                        && dist2 > _selfAnalysis.maxCastRange
                                                        * _selfAnalysis.maxCastRange
                                        && _actor.getPlanDistanceSq(
                                                        _secondMostHatedAnalysis.character.getX(),
                                                        _secondMostHatedAnalysis.character.getY()) < _selfAnalysis.maxCastRange
                                                        * _selfAnalysis.maxCastRange) {
                                ((L2Attackable) _actor)
                                                .reduceHate(hated.get(0),
                                                                1 + (((L2Attackable) _actor).getHating(hated
                                                                                .get(0)) - ((L2Attackable) _actor)
                                                                                .getHating(hated.get(1))));
                        } else if (dist2 > range * range
                                        && _actor.getPlanDistanceSq(
                                                        _secondMostHatedAnalysis.character.getX(),
                                                        _secondMostHatedAnalysis.character.getY()) < range
                                                        * range) {
                                ((L2Attackable) _actor)
                                                .reduceHate(hated.get(0),
                                                                1 + (((L2Attackable) _actor).getHating(hated
                                                                                .get(0)) - ((L2Attackable) _actor)
                                                                                .getHating(hated.get(1))));
                        }
                }

                // Considering, if bigger range will be attempted
                if ((dist2 < 10000 + combinedCollision * combinedCollision)
                                && !_selfAnalysis.isFighter
                                && !_selfAnalysis.isBalanced
                                && (_selfAnalysis.hasLongRangeSkills || _selfAnalysis.isArcher || _selfAnalysis.isHealer)
                                && (_mostHatedAnalysis.isBalanced || _mostHatedAnalysis.isFighter)
                                && (_mostHatedAnalysis.character.isRooted() || _mostHatedAnalysis.isSlower)
                                && (Config.GEODATA == 2 ? 20 : 12) >= Rnd.get(100) // chance
                ) {
                        int posX = _actor.getX();
                        int posY = _actor.getY();
                        int posZ = _actor.getZ();
                        double distance = Math.sqrt(dist2); // This way, we only do the sqrt
                                                                                                // if we need it

                        int signx = -1;
                        int signy = -1;
                        if (_actor.getX() > _mostHatedAnalysis.character.getX())
                                signx = 1;
                        if (_actor.getY() > _mostHatedAnalysis.character.getY())
                                signy = 1;
                        posX += Math
                                        .round((float) ((signx * ((range / 2) + (Rnd.get(range)))) - distance));
                        posY += Math
                                        .round((float) ((signy * ((range / 2) + (Rnd.get(range)))) - distance));
                        setIntention(CtrlIntention.AI_INTENTION_MOVE_TO,
                                        new L2CharPosition(posX, posY, posZ, 0));
                        return;
                }

                // Cannot see target, needs to go closer, currently just goes to range
                // 300 if mage
                if ((dist2 > 310 * 310 + combinedCollision * combinedCollision)
                                && this._selfAnalysis.hasLongRangeSkills
                                && !GeoData.getInstance().canSeeTarget(_actor,
                                                _mostHatedAnalysis.character)) {
                        if (!(_selfAnalysis.isMage && _actor.isMuted())) {
                                moveToPawn(_mostHatedAnalysis.character, 300);
                                return;
                        }
                }

                if (_mostHatedAnalysis.character.isMoving())
                        range += 50;
                // Check if the actor is far from target
                if (dist2 > range * range) {
                        if (!_actor.isMuted()
                                        && (_selfAnalysis.hasLongRangeSkills || !_selfAnalysis.healSkills
                                                        .isEmpty())) {
                                // check for long ranged skills and heal/buff skills
                                if (!_mostHatedAnalysis.isCanceled) {
                                        for (L2Skill sk : _selfAnalysis.cancelSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= 8) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _mostHatedAnalysis.isCanceled = true;
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (this._selfAnalysis.lastDebuffTick + 60 < GameTimeController
                                                .getGameTicks()) {
                                        for (L2Skill sk : _selfAnalysis.debuffSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                int chance = 8;
                                                if (_selfAnalysis.isFighter
                                                                && _mostHatedAnalysis.isMage)
                                                        chance = 3;
                                                if (_selfAnalysis.isFighter
                                                                && _mostHatedAnalysis.isArcher)
                                                        chance = 12;
                                                if (_selfAnalysis.isMage && !_mostHatedAnalysis.isMage)
                                                        chance = 10;
                                                if (_selfAnalysis.isHealer)
                                                        chance = 12;
                                                if (_mostHatedAnalysis.isMagicResistant)
                                                        chance /= 2;

                                                if (Rnd.nextInt(100) <= chance) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _selfAnalysis.lastDebuffTick = GameTimeController
                                                                        .getGameTicks();
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (!_mostHatedAnalysis.character.isMuted()) {
                                        int chance = 8;
                                        if (!(_mostHatedAnalysis.isMage || _mostHatedAnalysis.isBalanced))
                                                chance = 3;
                                        for (L2Skill sk : _selfAnalysis.muteSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= chance) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (_secondMostHatedAnalysis.character != null
                                                && !_secondMostHatedAnalysis.character.isMuted()
                                                && (_secondMostHatedAnalysis.isMage || _secondMostHatedAnalysis.isBalanced)) {
                                        double secondHatedDist2 = _actor.getPlanDistanceSq(
                                                        _secondMostHatedAnalysis.character.getX(),
                                                        _secondMostHatedAnalysis.character.getY());
                                        for (L2Skill sk : _selfAnalysis.muteSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (secondHatedDist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= 2) {
                                                        _actor.setTarget(_secondMostHatedAnalysis.character);
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _actor.setTarget(_mostHatedAnalysis.character);
                                                        return;
                                                }
                                        }
                                }
                                if (!_mostHatedAnalysis.character.isSleeping()) {
                                        for (L2Skill sk : _selfAnalysis.sleepSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= (_selfAnalysis.isHealer ? 10
                                                                : 1)) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (_secondMostHatedAnalysis.character != null
                                                && !_secondMostHatedAnalysis.character.isSleeping()) {
                                        double secondHatedDist2 = _actor.getPlanDistanceSq(
                                                        _secondMostHatedAnalysis.character.getX(),
                                                        _secondMostHatedAnalysis.character.getY());
                                        for (L2Skill sk : _selfAnalysis.sleepSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (secondHatedDist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= (_selfAnalysis.isHealer ? 10
                                                                : 3)) {
                                                        _actor.setTarget(_secondMostHatedAnalysis.character);
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _actor.setTarget(_mostHatedAnalysis.character);
                                                        return;
                                                }
                                        }
                                }
                                if (!_mostHatedAnalysis.character.isRooted()) {
                                        for (L2Skill sk : _selfAnalysis.rootSkills) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= (_mostHatedAnalysis.isSlower ? 3
                                                                : 8)) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (!_mostHatedAnalysis.character.isAttackingDisabled()) {
                                        for (L2Skill sk : _selfAnalysis.generalDisablers) {
                                                int castRange = sk.getCastRange() + combinedCollision;
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk)
                                                                || (dist2 > castRange * castRange))
                                                        continue;
                                                if (Rnd.nextInt(100) <= ((_selfAnalysis.isFighter && _actor
                                                                .isRooted()) ? 15 : 7)) {
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                        + GameTimeController.getGameTicks();
                                                        return;
                                                }
                                        }
                                }
                                if (_actor.getCurrentHp() < _actor.getMaxHp() * 0.4) {
                                        for (L2Skill sk : _selfAnalysis.healSkills) {
                                                if (_actor.isSkillDisabled(sk.getId())
                                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                                .getMpConsume(sk))
                                                        continue;
                                                int chance = 7;
                                                if (_mostHatedAnalysis.character.isAttackingDisabled())
                                                        chance += 10;
                                                if (_secondMostHatedAnalysis.character == null
                                                                || _secondMostHatedAnalysis.character
                                                                                .isAttackingDisabled())
                                                        chance += 10;
                                                if (Rnd.nextInt(100) <= chance) {
                                                        _actor.setTarget(_actor);
                                                        clientStopMoving(null);
                                                        _accessor.doCast(sk);
                                                        _actor.setTarget(_mostHatedAnalysis.character);
                                                        return;
                                                }
                                        }
                                }

                                // chance decision for launching long range skills
                                int castingChance = 5;
                                if (_selfAnalysis.isMage || _selfAnalysis.isHealer)
                                        castingChance = 50; // mages
                                if (_selfAnalysis.isBalanced) {
                                        if (!_mostHatedAnalysis.isFighter) // advance to mages
                                                castingChance = 15;
                                        else
                                                castingChance = 25; // stay away from fighters
                                }
                                if (_selfAnalysis.isFighter) {
                                        if (_mostHatedAnalysis.isMage)
                                                castingChance = 3;
                                        else
                                                castingChance = 7;
                                        if (_actor.isRooted())
                                                castingChance = 20; // doesn't matter if no success
                                                                                        // first round
                                }
                                for (L2Skill sk : _selfAnalysis.generalSkills) {

                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;

                                        if (Rnd.nextInt(100) <= castingChance) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                + GameTimeController.getGameTicks();
                                                return;
                                        }
                                }
                        }

                        // Move the actor to Pawn server side AND client side by sending
                        // Server->Client packet MoveToPawn (broadcast)
                        if (_selfAnalysis.isMage && !_actor.isMuted()) {
                                // mages stay a bit further away if not muted or low mana
                                if ((_actor.getMaxMp() / 3) < _actor.getCurrentMp()) {
                                        range = _selfAnalysis.maxCastRange;
                                        if (dist2 < range * range) // don't move backwards here
                                                return;
                                }
                        }
                        // healers do not even follow
                        if (_selfAnalysis.isHealer)
                                return;

                        if (_mostHatedAnalysis.character.isMoving())
                                range -= 100;
                        if (range < 5)
                                range = 5;
                        moveToPawn(_mostHatedAnalysis.character, range);
                        return;
                }
                // **************************************************
                // Else, if this is close enough for physical attacks
                else {
                        // In case many mobs are trying to hit from same place, move a bit,
                        // circling around the target
                        if (Rnd.nextInt(100) <= 33) // check it once per 3 seconds
                        {
                                for (L2Object nearby : _actor.getKnownList()
                                                .getKnownCharactersInRadius(10)) {
                                        if (nearby instanceof L2Attackable
                                                        && nearby != _mostHatedAnalysis.character) {
                                                int diffx = Rnd.get(combinedCollision,
                                                                combinedCollision + 40);
                                                if (Rnd.get(10) < 5)
                                                        diffx = -diffx;
                                                int diffy = Rnd.get(combinedCollision,
                                                                combinedCollision + 40);
                                                if (Rnd.get(10) < 5)
                                                        diffy = -diffy;
                                                moveTo(_mostHatedAnalysis.character.getX() + diffx,
                                                                _mostHatedAnalysis.character.getY() + diffy,
                                                                _mostHatedAnalysis.character.getZ());
                                                return;
                                        }
                                }
                        }

                        // Calculate a new attack timeout.
                        _attackTimeout = MAX_ATTACK_TIMEOUT
                                        + GameTimeController.getGameTicks();

                        // check for close combat skills && heal/buff skills

                        if (!_mostHatedAnalysis.isCanceled) {
                                for (L2Skill sk : _selfAnalysis.cancelSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= 8) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _mostHatedAnalysis.isCanceled = true;
                                                return;
                                        }
                                }
                        }
                        if (this._selfAnalysis.lastDebuffTick + 60 < GameTimeController
                                        .getGameTicks()) {
                                for (L2Skill sk : _selfAnalysis.debuffSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        int chance = 5;
                                        if (_selfAnalysis.isFighter && _mostHatedAnalysis.isMage)
                                                chance = 3;
                                        if (_selfAnalysis.isFighter && _mostHatedAnalysis.isArcher)
                                                chance = 3;
                                        if (_selfAnalysis.isMage && !_mostHatedAnalysis.isMage)
                                                chance = 4;
                                        if (_selfAnalysis.isHealer)
                                                chance = 12;
                                        if (_mostHatedAnalysis.isMagicResistant)
                                                chance /= 2;
                                        if (sk.getCastRange() < 200)
                                                chance += 3;
                                        if (Rnd.nextInt(100) <= chance) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _selfAnalysis.lastDebuffTick = GameTimeController
                                                                .getGameTicks();
                                                return;
                                        }
                                }
                        }
                        if (!_mostHatedAnalysis.character.isMuted()
                                        && (_mostHatedAnalysis.isMage || _mostHatedAnalysis.isBalanced)) {
                                for (L2Skill sk : _selfAnalysis.muteSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= 7) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                return;
                                        }
                                }
                        }
                        if (_secondMostHatedAnalysis.character != null
                                        && !_secondMostHatedAnalysis.character.isMuted()
                                        && (_secondMostHatedAnalysis.isMage || _secondMostHatedAnalysis.isBalanced)) {
                                double secondHatedDist2 = _actor.getPlanDistanceSq(
                                                _secondMostHatedAnalysis.character.getX(),
                                                _secondMostHatedAnalysis.character.getY());
                                for (L2Skill sk : _selfAnalysis.muteSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (secondHatedDist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= 3) {
                                                _actor.setTarget(_secondMostHatedAnalysis.character);
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _actor.setTarget(_mostHatedAnalysis.character);
                                                return;
                                        }
                                }
                        }
                        if (!_mostHatedAnalysis.character.isSleeping()
                                        && _selfAnalysis.isHealer) {
                                for (L2Skill sk : _selfAnalysis.sleepSkills) {
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= 10) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _attackTimeout = MAX_ATTACK_TIMEOUT
                                                                + GameTimeController.getGameTicks();
                                                return;
                                        }
                                }
                        }
                        if (_secondMostHatedAnalysis.character != null
                                        && !_secondMostHatedAnalysis.character.isSleeping()) {
                                double secondHatedDist2 = _actor.getPlanDistanceSq(
                                                _secondMostHatedAnalysis.character.getX(),
                                                _secondMostHatedAnalysis.character.getY());
                                for (L2Skill sk : _selfAnalysis.sleepSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (secondHatedDist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= (_selfAnalysis.isHealer ? 10 : 4)) {
                                                _actor.setTarget(_secondMostHatedAnalysis.character);
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _actor.setTarget(_mostHatedAnalysis.character);
                                                return;
                                        }
                                }
                        }
                        if (!_mostHatedAnalysis.character.isRooted()
                                        && _mostHatedAnalysis.isFighter && !_selfAnalysis.isFighter) {
                                for (L2Skill sk : _selfAnalysis.rootSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= (_selfAnalysis.isHealer ? 10 : 4)) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                return;
                                        }
                                }
                        }
                        if (!_mostHatedAnalysis.character.isAttackingDisabled()) {
                                for (L2Skill sk : _selfAnalysis.generalDisablers) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        int castRange = sk.getCastRange() + combinedCollision;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk)
                                                        || (dist2 > castRange * castRange))
                                                continue;
                                        if (Rnd.nextInt(100) <= ((sk.getCastRange() < 200) ? 10 : 7)) {
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                return;
                                        }
                                }
                        }
                        if (_actor.getCurrentHp() < _actor.getMaxHp()
                                        * (_selfAnalysis.isHealer ? 0.7 : 0.4)) {
                                for (L2Skill sk : _selfAnalysis.healSkills) {
                                        if ((_actor.isMuted() && sk.isMagic())
                                                        || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                                continue;
                                        if (_actor.isSkillDisabled(sk.getId())
                                                        || _actor.getCurrentMp() < _actor.getStat()
                                                                        .getMpConsume(sk))
                                                continue;
                                        int chance = (_selfAnalysis.isHealer ? 15 : 7);
                                        if (_mostHatedAnalysis.character.isAttackingDisabled())
                                                chance += 10;
                                        if (_secondMostHatedAnalysis.character == null
                                                        || _secondMostHatedAnalysis.character
                                                                        .isAttackingDisabled())
                                                chance += 10;
                                        if (Rnd.nextInt(100) <= chance) {
                                                _actor.setTarget(_actor);
                                                clientStopMoving(null);
                                                _accessor.doCast(sk);
                                                _actor.setTarget(_mostHatedAnalysis.character);
                                                return;
                                        }
                                }
                        }
                        for (L2Skill sk : _selfAnalysis.generalSkills) {
                                if ((_actor.isMuted() && sk.isMagic())
                                                || (_actor.isPhysicalMuted() && !sk.isMagic()))
                                        continue;
                                int castRange = sk.getCastRange() + combinedCollision;
                                if (_actor.isSkillDisabled(sk.getId())
                                                || _actor.getCurrentMp() < _actor.getStat()
                                                                .getMpConsume(sk)
                                                || (dist2 > castRange * castRange))
                                        continue;

                                // chance decision for launching general skills in melee fight
                                // close range skills should be higher, long range lower
                                int castingChance = 5;
                                if (_selfAnalysis.isMage || _selfAnalysis.isHealer) {
                                        if (sk.getCastRange() < 200)
                                                castingChance = 35;
                                        else
                                                castingChance = 25; // mages
                                }
                                if (_selfAnalysis.isBalanced) {
                                        if (sk.getCastRange() < 200)
                                                castingChance = 12;
                                        else {
                                                if (_mostHatedAnalysis.isMage) // hit mages
                                                        castingChance = 2;
                                                else
                                                        castingChance = 5;
                                        }

                                }
                                if (_selfAnalysis.isFighter) {
                                        if (sk.getCastRange() < 200)
                                                castingChance = 12;
                                        else {
                                                if (_mostHatedAnalysis.isMage)
                                                        castingChance = 1;
                                                else
                                                        castingChance = 3;
                                        }
                                }
                                if (Rnd.nextInt(100) <= castingChance) {
                                        clientStopMoving(null);
                                        _accessor.doCast(sk);
                                        return;
                                }
                        }

                        // Finally, physical attacks
                        if (!_selfAnalysis.isHealer) {
                                clientStopMoving(null);
                                _accessor.doAttack(_mostHatedAnalysis.character);
                        }
                }
        }

        /**
        * Manage AI thinking actions of a L2Attackable.<BR>
        * <BR>
        */
        @Override
        protected void onEvtThink() {
                // Check if the thinking action is already in progress
                if (_thinking || _actor.isCastingNow() || _actor.isAllSkillsDisabled())
                        return;

                // Start thinking action
                _thinking = true;

                try {
                        // Manage AI thinks of a L2Attackable
                        if (getIntention() == AI_INTENTION_ACTIVE)
                                thinkActive();
                        else if (getIntention() == AI_INTENTION_ATTACK)
                                thinkAttack();
                } finally {
                        // Stop thinking action
                        _thinking = false;
                }
        }

        /**
        * Launch actions corresponding to the Event Attacked.<BR>
        * <BR>
        *
        * <B><U> Actions</U> :</B><BR>
        * <BR>
        * <li>Init the attack : Calculate the attack timeout, Set the _globalAggro
        * to 0, Add the attacker to the actor _aggroList</li> <li>Set the
        * L2Character movement type to run and send Server->Client packet
        * ChangeMoveType to all others L2PcInstance</li> <li>Set the Intention to
        * AI_INTENTION_ATTACK</li><BR>
        * <BR>
        *
        * @param attacker
        *            The L2Character that attacks the actor
        *
        */
        @Override
        protected void onEvtAttacked(L2Character attacker) {
                // if (_actor instanceof L2ChestInstance &&
                // !((L2ChestInstance)_actor).isInteracted())
                // {
                // ((L2ChestInstance)_actor).deleteMe();
                // ((L2ChestInstance)_actor).getSpawn().startRespawn();
                // return;
                // }

                // Calculate the attack timeout
                _attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks();

                // Set the _globalAggro to 0 to permit attack even just after spawn
                if (_globalAggro < 0)
                        _globalAggro = 0;

                // Add the attacker to the _aggroList of the actor
                if (!((L2Attackable) _actor).isCoreAIDisabled())
                        ((L2Attackable) _actor).addDamageHate(attacker, 0, 1);

                // Set the L2Character movement type to run and send Server->Client
                // packet ChangeMoveType to all others L2PcInstance
                if (!_actor.isRunning())
                        _actor.setRunning();

                // Set the Intention to AI_INTENTION_ATTACK
                if (getIntention() != AI_INTENTION_ATTACK
                                && !((L2Attackable) _actor).isCoreAIDisabled()) {
                        setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
                } else if (((L2Attackable) _actor).getMostHated() != getAttackTarget()
                                && !((L2Attackable) _actor).isCoreAIDisabled()) {
                        setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
                } else if (getIntention() != AI_INTENTION_INTERACT
                                && ((L2Attackable) _actor).isCoreAIDisabled())
                        setIntention(CtrlIntention.AI_INTENTION_INTERACT, attacker);

                super.onEvtAttacked(attacker);
        }

        /**
        * Launch actions corresponding to the Event Aggression.<BR>
        * <BR>
        *
        * <B><U> Actions</U> :</B><BR>
        * <BR>
        * <li>Add the target to the actor _aggroList or update hate if already
        * present</li> <li>Set the actor Intention to AI_INTENTION_ATTACK (if actor
        * is GuardLevelInstance check if it isn't too far from its home location)</li><BR>
        * <BR>
        *
        * @param attacker
        *            The L2Character that attacks
        * @param aggro
        *            The value of hate to add to the actor against the target
        *
        */
        @Override
        protected void onEvtAggression(L2Character target, int aggro) {
                L2Attackable me = (L2Attackable) _actor;

                if (target != null) {
                        // Add the target to the actor _aggroList or update hate if already
                        // present
                        me.addDamageHate(target, 0, aggro);

                        // Set the actor AI Intention to AI_INTENTION_ATTACK
                        if (getIntention() != CtrlIntention.AI_INTENTION_ATTACK) {
                                // Set the L2Character movement type to run and send
                                // Server->Client packet ChangeMoveType to all others
                                // L2PcInstance
                                if (!_actor.isRunning())
                                        _actor.setRunning();

                                setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
                        }
                }
        }

        @Override
        protected void onIntentionActive() {
                // Cancel attack timeout
                _attackTimeout = Integer.MAX_VALUE;
                super.onIntentionActive();
        }

        public void setGlobalAggro(int value) {
                _globalAggro = value;
        }

}

Добавлено через 1 час 3 минуты
Я отредактировал все что нужно. Надо, просто, создать классы.

Mifesto 24.06.2013 01:21

Re: Не могу подцепить AI гварду
 
а тут?
public class GuardLevelAI extends L2CharacterAI implements Runnable

замените на L2AttackableAI

energy 24.06.2013 02:13

Re: Не могу подцепить AI гварду
 
Цитата:

Сообщение от Mifesto (Сообщение 307296)
а тут?
public class GuardLevelAI extends L2CharacterAI implements Runnable

замените на L2AttackableAI

Менял. Такое вот выскакивает.
[SPOILER]:
Свернуть ↑Развернуть ↓


Добавлено через 9 минут
Я не знаю где этот onSpawn(GuardLevelInstance.java:142) который он не может найти( и я в том числе).

SkyWard 24.06.2013 09:10

Re: Не могу подцепить AI гварду
 
Цитата:

Сообщение от energy (Сообщение 307299)
Я не знаю где этот onSpawn(GuardLevelInstance.java:142) который он не может найти( и я в том числе).

public void onSpawn() {
setIsNoRndWalk(true);
super.onSpawn();

energy 24.06.2013 14:50

Re: Не могу подцепить AI гварду
 
Цитата:

Сообщение от KapkapoB (Сообщение 307304)
public void onSpawn() {
setIsNoRndWalk(true);
super.onSpawn();

Я имел ввиду почему оно не хочет принимать координаты спавна. Нада ли где-нибудь прописать еще эти координаты, кроме спавнлиста?


Текущее время: 10:07. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot