|
Работа со скриптами Помощь в редактировании и написании квестов к Java серверам, а так же эвентов.
Описание темы:Помогите пожалуйсто |
Ссылки сообщества |
Изображения и альбомы |
Пользователи |
К странице... |
Опции темы |
12.02.2013, 23:15 | #11 |
Пользователь
Регистрация: 18.10.2010
Адрес: Харьков
Возраст: 30
Сообщений: 527
Отблагодарили 98 раз(а)
Рейтинг мнений:
77
|
Re: Guard
Добавлено через 6 минут
вот например у гвадра с исходников overworld: GuardInstance Код:
@Override public boolean isAutoAttackable(Creature attacker) { return attacker.isMonster() && ((MonsterInstance)attacker).isAggressive() || attacker.isPlayable() && attacker.getKarma() > 0; } Код:
@Override public boolean isAutoAttackable(Creature attacker) { return attacker.isPlayer() && attacker.getRace() != getRace(); } Вот АИ гварда: Код:
public boolean canAttackCharacter(Creature target) { NpcInstance actor = getActor(); if(getIntention() == CtrlIntention.AI_INTENTION_ATTACK) { AggroInfo ai = actor.getAggroList().get(target); return ai != null && ai.hate > 0; } return target.isMonster() || target.isPlayable(); } public boolean checkAggression(Creature target) { NpcInstance actor = getActor(); if(getIntention() != CtrlIntention.AI_INTENTION_ACTIVE || !isGlobalAggro()) return false; if(target.isPlayable()) { if(target.getKarma() == 0 || (actor.getParameter("evilGuard", false) && target.getPvpFlag() > 0)) return false; } if(target.isMonster()) { if(!((MonsterInstance)target).isAggressive()) return false; } return super.checkAggression(target); } Код:
public boolean canAttackCharacter(Creature target) { NpcInstance actor = getActor(); if(getIntention() == CtrlIntention.AI_INTENTION_ATTACK) { AggroInfo ai = actor.getAggroList().get(target); return ai != null && ai.hate > 0; } return target.isPlayer(); } public boolean checkAggression(Creature target) { NpcInstance actor = getActor(); if(getIntention() != CtrlIntention.AI_INTENTION_ACTIVE || !isGlobalAggro()) return false; if(target.isPlayer() && actor().getRace() == target.isRace()) return false; return super.checkAggression(target); } Последний раз редактировалось Mifesto; 12.02.2013 в 23:34. Причина: Добавлено сообщение |
12.02.2013, 23:22 | #12 |
Пользователь
|
Re: Guard
я кинул Гвардов Фортов! Если я не ошибаюсь гвардов фортов легче запилить под рассы...
L2FortSiegeGuardAI:Свернуть ↑
/*
Свернуть ↑Развернуть ↓
* 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 com.l2jfrozen.gameserver.ai; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_ACTIVE; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_ATTACK; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_IDLE; import java.util.List; import java.util.concurrent.Future; import java.util.logging.Logger; import javolution.util.FastList; import com.l2jfrozen.Config; import com.l2jfrozen.gameserver.controllers.GameTimeContr oller; import com.l2jfrozen.gameserver.geo.GeoData; import com.l2jfrozen.gameserver.model.L2Attackable; import com.l2jfrozen.gameserver.model.L2Character; import com.l2jfrozen.gameserver.model.L2Effect; import com.l2jfrozen.gameserver.model.L2Object; import com.l2jfrozen.gameserver.model.L2Skill; import com.l2jfrozen.gameserver.model.L2Skill.SkillType; import com.l2jfrozen.gameserver.model.L2Summon; import com.l2jfrozen.gameserver.model.actor.instance.L2Co mmanderInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Do orInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Fo lkInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Fo rtSiegeGuardInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Np cInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Pc Instance; import com.l2jfrozen.gameserver.model.actor.instance.L2Pl ayableInstance; import com.l2jfrozen.gameserver.thread.ThreadPoolManager; import com.l2jfrozen.gameserver.util.Util; import com.l2jfrozen.util.random.Rnd; /** * This class manages AI of L2Attackable.<BR> * <BR> */ public class L2FortSiegeGuardAI extends L2CharacterAI implements Runnable { protected static final Logger _log1 = Logger.getLogger(L2FortSiegeGuardAI.class.getName( )); //SelfAnalisis )) public List<L2Skill> pdamSkills = new FastList<L2Skill>(); public List<L2Skill> mdamSkills = new FastList<L2Skill>(); public List<L2Skill> healSkills = new FastList<L2Skill>(); public List<L2Skill> rootSkills = new FastList<L2Skill>(); public boolean hasPDam = false; public boolean hasMDam = false; public boolean hasHeal = false; public boolean hasRoot = false; 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; /** For attack AI, analysis of mob and its targets */ //private SelfAnalysis _selfAnalysis = new SelfAnalysis(); /** 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 private int _attackRange; /** * Constructor of L2AttackableAI.<BR> * <BR> * * @param accessor The AI accessor of the L2Character */ public L2FortSiegeGuardAI(L2Character.AIAccessor accessor) { super(accessor); //_selfAnalysis.init(); _attackTimeout = Integer.MAX_VALUE; _globalAggro = -10; // 10 seconds timeout of ATTACK after respawn _attackRange = ((L2Attackable) _actor).getPhysicalAttackRange(); } @Override 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 L2GuardInstance</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 * @return */ private boolean autoAttackCondition(L2Character target) { // Check if the target isn't another guard, folk or a door if(target == null || target instanceof L2FortSiegeGuardInstance || target instanceof L2FolkInstance || target instanceof L2DoorInstance || target.isAlikeDead() || target instanceof L2CommanderInstance || target instanceof L2PlayableInstance) { L2PcInstance player = null; if(target instanceof L2PcInstance) { player = (L2PcInstance) target; } else if(target instanceof L2Summon) { player = ((L2Summon) target).getOwner(); } if((player == null) || (player.getClan() != null) && player.getClan().getHasFort() == ((L2NpcInstance) _actor).getFort().getFortId()) return false; } // 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; } // Get the owner if the target is a summon if(target instanceof L2Summon) { L2PcInstance owner = ((L2Summon) target).getOwner(); if(_actor.isInsideRadius(owner, 1000, true, false)) { target = owner; } } // Check if the target is a L2PcInstance if(target instanceof L2PcInstance) { // Check if the target isn't in silent move mode AND too far (>100) if(((L2PcInstance) target).isSilentMoving() && !_actor.isInsideRadius(target, 250, false, false)) return false; } // Los Check Here return _actor.isAutoAttackable(target) && GeoData.getInstance().canSeeTarget(_actor, target); } /** * 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 public synchronized void changeIntention(CtrlIntention intention, Object arg0, Object arg1) { if(Config.DEBUG) { _log1.info("L2SiegeAI.changeIntention(" + intention + ", " + arg0 + ", " + arg1 + ")"); } if(intention == AI_INTENTION_IDLE /*|| intention == AI_INTENTION_ACTIVE*/) // active becomes idle if only a summon is present { // 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().size() > 0) { intention = AI_INTENTION_ACTIVE; } else { intention = AI_INTENTION_IDLE; } } 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) if(_aiTask == null) { _aiTask = ThreadPoolManager.getInstance().scheduleAiAtFixedR ate(this, 1000, 1000); } } /** * 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(); // Manage the Attack Intention : Stop current Attack (if necessary), Start a new Attack and Launch Think Event //if (_actor.getTarget() != null) 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 can't attack, order to it to return to its home location</li> */ 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) { for(L2Character target : npc.getKnownList().getKnownCharactersInRadius(_att ackRange)) { if(target == null) { continue; } 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, 1); } } } // Chose a target from its aggroList L2Character hated; if(_actor.isConfused()) { hated = getAttackTarget(); // Force mobs to attack anybody if confused } else { hated = npc.getMostHated(); //_mostHatedAnalysis.Update(hated); } // 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, null); } return; } } // Order to the L2SiegeGuardInstance to return to its home location because there's no target to attack if(_actor.getWalkSpeed() >= 0) { if(_actor instanceof L2FortSiegeGuardInstance) { ((L2FortSiegeGuardInstance) _actor).returnHome(); } else { ((L2CommanderInstance) _actor).returnHome(); } } return; } /** * 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(Config.DEBUG) { _log1.info("L2FortSiegeGuardAI.thinkAttack(); timeout=" + (_attackTimeout - GameTimeController.getGameTicks())); } 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 attackTarget = getAttackTarget(); // Check if target is dead or if timeout is expired to stop this attack if(attackTarget == null || attackTarget.isAlikeDead() || _attackTimeout < GameTimeController.getGameTicks()) { // Stop hating this target after the attack timeout or if target is dead if(attackTarget != null) { L2Attackable npc = (L2Attackable) _actor; npc.stopHating(attackTarget); } // Cancel target and timeout _attackTimeout = Integer.MAX_VALUE; setAttackTarget(null); // Set the AI Intention to AI_INTENTION_ACTIVE setIntention(AI_INTENTION_ACTIVE, null, null); _actor.setWalking(); return; } factionNotifyAndSupport(); attackPrepare(); } private final void factionNotifyAndSupport() { L2Character target = getAttackTarget(); // Call all L2Object of its Faction inside the Faction Range if(((L2NpcInstance) _actor).getFactionId() == null || target == null) return; if(target.isInvul()) return; // speeding it up for siege guards if(Rnd.get(10) > 4) return; // test for reducing CPU load String faction_id = ((L2NpcInstance) _actor).getFactionId(); // SalfAnalisis )) for(L2Skill sk : _actor.getAllSkills()) { if(sk.isPassive()) { continue; } switch(sk.getSkillType()) { case PDAM: rootSkills.add(sk); hasPDam = true; break; case MDAM: rootSkills.add(sk); hasMDam = true; break; case HEAL: healSkills.add(sk); hasHeal = true; break; case ROOT: rootSkills.add(sk); hasRoot = true; break; default: //Haven`t anything useful for us. break; } } // Go through all L2Character that belong to its faction //for (L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(( (L2NpcInstance) _actor).getFactionRange()+_actor.getTemplate().col lisionRadius)) for(L2Character cha : _actor.getKnownList().getKnownCharactersInRadius(1 000)) { if(cha == null) { continue; } if(!(cha instanceof L2NpcInstance)) { if(/*_selfAnalysis.hasHealOrResurrect &&*/cha instanceof L2PcInstance && ((L2NpcInstance) _actor).getFort().getSiege().checkIsDefender(((L2P cInstance) cha).getClan())) { // heal friends if(!_actor.isAttackingDisabled() && cha.getCurrentHp() < cha.getMaxHp() * 0.6 && _actor.getCurrentHp() > _actor.getMaxHp() / 2 && _actor.getCurrentMp() > _actor.getMaxMp() / 2 && cha.isInCombat()) { for(L2Skill sk : /*_selfAnalysis.healSkills*/healSkills) { if(_actor.getCurrentMp() < sk.getMpConsume()) { continue; } if(_actor.isSkillDisabled(sk.getId())) { continue; } if(!Util.checkIfInRange(sk.getCastRange(), _actor, cha, true)) { continue; } int chance = 5; if(chance >= Rnd.get(100)) { continue; } if(!GeoData.getInstance().canSeeTarget(_actor, cha)) { break; } L2Object OldTarget = _actor.getTarget(); _actor.setTarget(cha); clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); return; } } } continue; } L2NpcInstance npc = (L2NpcInstance) cha; if(!faction_id.equalsIgnoreCase(npc.getFactionId() )) { continue; } if(npc.getAI() != null) // TODO: possibly check not needed { if(!npc.isDead() && Math.abs(target.getZ() - npc.getZ()) < 600 //&& _actor.getAttackByList().contains(getAttackTarget( )) && (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE || npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE) //limiting aggro for siege guards && target.isInsideRadius(npc, 1500, true, false) && GeoData.getInstance().canSeeTarget(npc, target)) { // Notify the L2Object AI with EVT_AGGRESSION L2CharacterAI ai = npc.getAI(); if(ai!=null) ai.notifyEvent(CtrlEvent.EVT_AGGRESSION, getAttackTarget(), 1); } // heal friends if(/*_selfAnalysis.hasHealOrResurrect && */!_actor.isAttackingDisabled() && npc.getCurrentHp() < npc.getMaxHp() * 0.6 && _actor.getCurrentHp() > _actor.getMaxHp() / 2 && _actor.getCurrentMp() > _actor.getMaxMp() / 2 && npc.isInCombat()) { for(L2Skill sk : /* _selfAnalysis.healSkills*/healSkills) { if(_actor.getCurrentMp() < sk.getMpConsume()) { continue; } if(_actor.isSkillDisabled(sk.getId())) { continue; } if(!Util.checkIfInRange(sk.getCastRange(), _actor, npc, true)) { continue; } int chance = 4; if(chance >= Rnd.get(100)) { continue; } if(!GeoData.getInstance().canSeeTarget(_actor, npc)) { break; } L2Object OldTarget = _actor.getTarget(); _actor.setTarget(npc); clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); return; } } } } } private void attackPrepare() { // Get all information needed to choose between physical or magical attack L2Skill[] skills = null; double dist_2 = 0; int range = 0; L2FortSiegeGuardInstance sGuard; sGuard = (L2FortSiegeGuardInstance) _actor; L2Character attackTarget = getAttackTarget(); try { _actor.setTarget(attackTarget); skills = _actor.getAllSkills(); dist_2 = _actor.getPlanDistanceSq(attackTarget.getX(), attackTarget.getY()); range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + attackTarget.getTemplate().collisionRadius; if(attackTarget.isMoving()) { range += 50; } } catch(NullPointerException e) { if(Config.ENABLE_ALL_EXCEPTIONS) e.printStackTrace(); //_log.warning("AttackableAI: Attack target is NULL."); _actor.setTarget(null); setIntention(AI_INTENTION_IDLE, null, null); return; } // never attack defenders if(attackTarget instanceof L2PcInstance && sGuard.getFort().getSiege().checkIsDefender(((L2Pc Instance) attackTarget).getClan())) { // Cancel the target sGuard.stopHating(attackTarget); _actor.setTarget(null); setIntention(AI_INTENTION_IDLE, null, null); return; } if(!GeoData.getInstance().canSeeTarget(_actor, attackTarget)) { // Siege guards differ from normal mobs currently: // If target cannot seen, don't attack any more sGuard.stopHating(attackTarget); _actor.setTarget(null); setIntention(AI_INTENTION_IDLE, null, null); return; } // Check if the actor isn't muted and if it is far from target if(!_actor.isMuted() && dist_2 > range * range) { // check for long ranged skills and heal/buff skills for(L2Skill sk : skills) { int castRange = sk.getCastRange(); if(dist_2 <= castRange * castRange && castRange > 70 && !_actor.isSkillDisabled(sk.getId()) && _actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk) && !sk.isPassive()) { L2Object OldTarget = _actor.getTarget(); if(sk.getSkillType() == SkillType.BUFF || sk.getSkillType() == SkillType.HEAL) { boolean useSkillSelf = true; if(sk.getSkillType() == SkillType.HEAL && _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)) { useSkillSelf = false; break; } if(sk.getSkillType() == SkillType.BUFF) { L2Effect[] effects = _actor.getAllEffects(); for(int i = 0; effects != null && i < effects.length; i++) { L2Effect effect = effects[i]; if(effect.getSkill() == sk) { useSkillSelf = false; break; } } } if(useSkillSelf) { _actor.setTarget(_actor); } } clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); return; } } // Check if the L2SiegeGuardInstance is attacking, knows the target and can't run if(!_actor.isAttackingNow() && _actor.getRunSpeed() == 0 && _actor.getKnownList().knowsObject(attackTarget)) { // Cancel the target _actor.getKnownList().removeKnownObject(attackTarg et); _actor.setTarget(null); setIntention(AI_INTENTION_IDLE, null, null); } else { double dx = _actor.getX() - attackTarget.getX(); double dy = _actor.getY() - attackTarget.getY(); double dz = _actor.getZ() - attackTarget.getZ(); double homeX = attackTarget.getX() - sGuard.getSpawn().getLocx(); double homeY = attackTarget.getY() - sGuard.getSpawn().getLocy(); // Check if the L2SiegeGuardInstance isn't too far from it's home location if(dx * dx + dy * dy > 10000 && homeX * homeX + homeY * homeY > 3240000 && _actor.getKnownList().knowsObject(attackTarget)) { // Cancel the target _actor.getKnownList().removeKnownObject(attackTarg et); _actor.setTarget(null); setIntention(AI_INTENTION_IDLE, null, null); } else // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast) { // Temporary hack for preventing guards jumping off towers, // before replacing this with effective GeoClient checks and AI modification if(dz * dz < 170 * 170) // normally 130 if guard z coordinates correct { //if (_selfAnalysis.isMage) // range = _selfAnalysis.maxCastRange - 50; if(_actor.getWalkSpeed() <= 0) return; if(attackTarget.isMoving()) { moveToPawn(attackTarget, range - 70); } else { moveToPawn(attackTarget, range); } } } } return; } // Else, if the actor is muted and far from target, just "move to pawn" else if(_actor.isMuted() && dist_2 > range * range) { // Temporary hack for preventing guards jumping off towers, // before replacing this with effective GeoClient checks and AI modification double dz = _actor.getZ() - attackTarget.getZ(); if(dz * dz < 170 * 170) // normally 130 if guard z coordinates correct { //if (_selfAnalysis.isMage) // range = _selfAnalysis.maxCastRange - 50; if(_actor.getWalkSpeed() <= 0) return; if(attackTarget.isMoving()) { moveToPawn(attackTarget, range - 70); } else { moveToPawn(attackTarget, range); } } return; } // Else, if this is close enough to attack else if(dist_2 <= range * range) { // Force mobs to attack anybody if confused L2Character hated = null; if(_actor.isConfused()) { hated = attackTarget; } else { hated = ((L2Attackable) _actor).getMostHated(); } if(hated == null) { setIntention(AI_INTENTION_ACTIVE, null, null); return; } if(hated != attackTarget) { attackTarget = hated; } _attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks(); // check for close combat skills && heal/buff skills if(!_actor.isMuted() && Rnd.nextInt(100) <= 5) { for(L2Skill sk : skills) { int castRange = sk.getCastRange(); if(castRange * castRange >= dist_2 && !sk.isPassive() && _actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk) && !_actor.isSkillDisabled(sk.getId())) { L2Object OldTarget = _actor.getTarget(); if(sk.getSkillType() == SkillType.BUFF || sk.getSkillType() == SkillType.HEAL) { boolean useSkillSelf = true; if(sk.getSkillType() == SkillType.HEAL && _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)) { useSkillSelf = false; break; } if(sk.getSkillType() == SkillType.BUFF) { L2Effect[] effects = _actor.getAllEffects(); for(int i = 0; effects != null && i < effects.length; i++) { L2Effect effect = effects[i]; if(effect.getSkill() == sk) { useSkillSelf = false; break; } } } if(useSkillSelf) { _actor.setTarget(_actor); } } clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); return; } } } // Finally, do the physical attack itself _accessor.doAttack(attackTarget); } } /** * Manage AI thinking actions of a L2Attackable.<BR> * <BR> */ @Override protected void onEvtThink() { // if(getIntention() != AI_INTENTION_IDLE && (!_actor.isVisible() || !_actor.hasAI() || !_actor.isKnownPlayers())) // setIntention(AI_INTENTION_IDLE); // Check if the actor can't use skills and if a thinking action isn't 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) { // 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 ((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) { setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker, null); } 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 L2GuardInstance check if it isn't too far from its home location)</li><BR> * <BR> * * @param target 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) { if(_actor == null) return; 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); // Get the hate of the actor against the target aggro = me.getHating(target); if(aggro <= 0) { if(me.getMostHated() == null) { _globalAggro = -25; me.clearAggroList(); setIntention(AI_INTENTION_IDLE, null, null); } return; } // 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(); } L2FortSiegeGuardInstance sGuard; sGuard = (L2FortSiegeGuardInstance) _actor; double homeX = target.getX() - sGuard.getSpawn().getLocx(); double homeY = target.getY() - sGuard.getSpawn().getLocy(); // Check if the L2SiegeGuardInstance is not too far from its home location if(homeX * homeX + homeY * homeY < 3240000) { setIntention(CtrlIntention.AI_INTENTION_ATTACK, target, null); } } } else { // currently only for setting lower general aggro if(aggro >= 0) return; L2Character mostHated = me.getMostHated(); if(mostHated == null) { _globalAggro = -25; return; } for(L2Character aggroed : me.getAggroListRP().keySet()) { me.addDamageHate(aggroed, 0, aggro); } aggro = me.getHating(mostHated); if(aggro <= 0) { _globalAggro = -25; me.clearAggroList(); setIntention(AI_INTENTION_IDLE, null, null); } } } @Override protected void onEvtDead() { stopAITask(); super.onEvtDead(); } public void stopAITask() { if(_aiTask != null) { _aiTask.cancel(false); _aiTask = null; } _accessor.detachAI(); } } |
12.02.2013, 23:29 | #14 |
Пользователь
|
Re: Guard
та да Извини туплю!!! спасибо большое за помощь щя буду пробовать (отпишусь)
Добавлено через 14 минут блин я в етих фрозентах е****х не могу найти нифига жееесть!!! Последний раз редактировалось smy55; 12.02.2013 в 23:43. Причина: Добавлено сообщение |
12.02.2013, 23:58 | #16 |
Пользователь
|
Re: Guard
я так понял в моем случии ето?
L2GuardInstance:Свернуть ↑
/*
Свернуть ↑Развернуть ↓
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * http://www.gnu.org/copyleft/gpl.html */ package com.l2jfrozen.gameserver.model.actor.instance; import java.util.logging.Logger; import com.l2jfrozen.Config; import com.l2jfrozen.gameserver.ai.CtrlIntention; import com.l2jfrozen.gameserver.ai.L2AttackableAI; import com.l2jfrozen.gameserver.model.L2Attackable; import com.l2jfrozen.gameserver.model.L2Character; import com.l2jfrozen.gameserver.model.L2World; import com.l2jfrozen.gameserver.model.L2WorldRegion; import com.l2jfrozen.gameserver.model.actor.knownlist.Gua rdKnownList; import com.l2jfrozen.gameserver.model.actor.position.L2Ch arPosition; import com.l2jfrozen.gameserver.network.serverpackets.Act ionFailed; import com.l2jfrozen.gameserver.network.serverpackets.MyT argetSelected; import com.l2jfrozen.gameserver.network.serverpackets.Soc ialAction; import com.l2jfrozen.gameserver.network.serverpackets.Val idateLocation; import com.l2jfrozen.gameserver.templates.L2NpcTemplate; import com.l2jfrozen.gameserver.thread.ThreadPoolManager; import com.l2jfrozen.util.random.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 L2GuardInstance extends L2Attackable { private static Logger _log = Logger.getLogger(L2GuardInstance.class.getName()); private int _homeX; private int _homeY; private int _homeZ; private static final int RETURN_INTERVAL = 60000; public class ReturnTask implements Runnable { @Override public void run() { if(getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE) { returnHome(); } } } /** * Constructor of L2GuardInstance (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 L2GuardInstance (copy skills from template to * object and link _calculators to NPC_STD_CALCULATOR)</li> <li>Set the name of the L2GuardInstance</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 L2GuardInstance(int objectId, L2NpcTemplate template) { super(objectId, template); getKnownList(); // init knownlist ThreadPoolManager.getInstance().scheduleAiAtFixedR ate(new ReturnTask(), RETURN_INTERVAL, RETURN_INTERVAL + Rnd.nextInt(60000)); } @Override public final GuardKnownList getKnownList() { if(super.getKnownList() == null || !(super.getKnownList() instanceof GuardKnownList)) { setKnownList(new GuardKnownList(this)); } return (GuardKnownList) super.getKnownList(); } /** * Return True if the attacker is a L2PlayableInstance.<BR> * <BR> */ @Override public boolean isAutoAttackable(L2Character attacker) { return attacker instanceof L2PlayableInstance; } /** * Set home location of the L2GuardInstance.<BR> * <BR> * <B><U> Concept</U> :</B><BR> * <BR> * Guard will always try to return to this location after it has killed all PK's in range <BR> * <BR> */ public void getHomeLocation() { _homeX = getX(); _homeY = getY(); _homeZ = getZ(); if(Config.DEBUG) { _log.finer(getObjectId() + ": Home location set to" + " X:" + _homeX + " Y:" + _homeY + " Z:" + _homeZ); } } public int getHomeX() { return _homeX; } /** * Notify the L2GuardInstance to return to its home location (AI_INTENTION_MOVE_TO) and clear its _aggroList.<BR> * <BR> */ public void returnHome() { if(!isInsideRadius(_homeX, _homeY, 150, false)) { if(Config.DEBUG) { _log.fine(getObjectId() + ": moving hometo" + " X:" + _homeX + " Y:" + _homeY + " Z:" + _homeZ); } clearAggroList(); getAI().setIntention(CtrlIntention.AI_INTENTION_MO VE_TO, new L2CharPosition(_homeX, _homeY, _homeZ, 0)); } } /** * Set the home location of its L2GuardInstance.<BR> * <BR> */ @Override public void onSpawn() { super.onSpawn(); _homeX = getX(); _homeY = getY(); _homeZ = getZ(); if(Config.DEBUG) { _log.finer(getObjectId() + ": Home location set to" + " X:" + _homeX + " Y:" + _homeY + " Z:" + _homeZ); } // 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()) { ((L2AttackableAI) getAI()).stopAITask(); } region = null; } /** * Return the pathfile of the selected HTML file in function of the L2GuardInstance 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 L2GuardInstance.<BR> * <BR> * <B><U> Actions on first click on the L2GuardInstance (Select it)</U> :</B><BR> * <BR> * <li>Set the L2GuardInstance 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 * L2GuardInstance position and heading on the client</li><BR> * <BR> * <B><U> Actions on second click on the L2GuardInstance (Attack it/Interact with it)</U> :</B><BR> * <BR> * <li>If L2PcInstance is in the _aggroList of the L2GuardInstance, set the L2PcInstance Intention to * AI_INTENTION_ATTACK</li> <li>If L2PcInstance is NOT in the _aggroList of the L2GuardInstance, 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 L2GuardInstance */ @Override public void onAction(L2PcInstance player) { if(!canTarget(player)) return; // Check if the L2PcInstance already target the L2GuardInstance 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); my = null; // 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 L2GuardInstance 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_INTEN TION_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_INTEN TION_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 L2GuardInstance on their client SocialAction sa = new SocialAction(getObjectId(), Rnd.nextInt(8)); broadcastPacket(sa); sa = null; // Open a chat window on client with the text of the L2GuardInstance 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); } } Добавлено через 1 минуту АИ:Свернуть ↑
и ето:
Свернуть ↑Развернуть ↓
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * http://www.gnu.org/copyleft/gpl.html */ package com.l2jfrozen.gameserver.ai; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_ACTIVE; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_ATTACK; import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTEN TION_IDLE; import java.util.concurrent.Future; import com.l2jfrozen.Config; import com.l2jfrozen.gameserver.controllers.GameTimeContr oller; import com.l2jfrozen.gameserver.datatables.sql.TerritoryT able; import com.l2jfrozen.gameserver.geo.GeoData; import com.l2jfrozen.gameserver.managers.DimensionalRiftM anager; import com.l2jfrozen.gameserver.model.L2Attackable; import com.l2jfrozen.gameserver.model.L2Character; import com.l2jfrozen.gameserver.model.L2Effect; import com.l2jfrozen.gameserver.model.L2Object; import com.l2jfrozen.gameserver.model.L2Skill; import com.l2jfrozen.gameserver.model.L2Summon; import com.l2jfrozen.gameserver.model.actor.instance.L2Ch estInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Do orInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Fe stivalMonsterInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Fo lkInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Fr iendlyMobInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Gu ardInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Mi nionInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Mo nsterInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Np cInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Pc Instance; import com.l2jfrozen.gameserver.model.actor.instance.L2Pe naltyMonsterInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Ra idBossInstance; import com.l2jfrozen.gameserver.model.actor.instance.L2Ri ftInvaderInstance; import com.l2jfrozen.gameserver.model.actor.position.L2Ch arPosition; import com.l2jfrozen.gameserver.model.quest.Quest; import com.l2jfrozen.gameserver.templates.L2Weapon; import com.l2jfrozen.gameserver.templates.L2WeaponType; import com.l2jfrozen.gameserver.thread.ThreadPoolManager; import com.l2jfrozen.util.random.Rnd; /** * This class manages AI of L2Attackable.<BR> * <BR> */ public class L2AttackableAI 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 wich 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 /** * Constructor of L2AttackableAI.<BR> * <BR> * * @param accessor The AI accessor of the L2Character */ public L2AttackableAI(L2Character.AIAccessor accessor) { super(accessor); _attackTimeout = Integer.MAX_VALUE; _globalAggro = -10; // 10 seconds timeout of ATTACK after respawn } @Override 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 L2GuardInstance</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 * @return */ 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 L2FolkInstance || 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; // 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; // Check if the AI isn't a Raid Boss and the target isn't in silent move mode if(!(me instanceof L2RaidBossInstance) && ((L2PcInstance) target).isSilentMoving()) return false; //if in offline mode if(((L2PcInstance) target).isOffline()) return false; // Check if player is an ally //TODO! [Nemesiss] it should be rather boolean or smth like that // Comparing String isnt good idea! if(me.getFactionId() == "varka" && ((L2PcInstance) target).isAlliedWithVarka()) return false; if(me.getFactionId() == "ketra" && ((L2PcInstance) target).isAlliedWithKetra()) return false; // check if the target is within the grace period for JUST getting up from fake death if(((L2PcInstance) target).isRecentFakeDeath()) return false; // check player is in away mod if(((L2PcInstance) target).isAway() && !Config.AWAY_PLAYER_TAKE_AGGRO) return false; if(target.isInParty() && target.getParty().isInDimensionalRift()) { byte riftType = target.getParty().getDimensionalRift().getType(); byte riftRoom = target.getParty().getDimensionalRift().getCurrentR oom(); if(me instanceof L2RiftInvaderInstance && !DimensionalRiftManager.getInstance().getRoom(rift Type, riftRoom).checkIfInZone(me.getX(), me.getY(), me.getZ())) return false; } } // Check if the actor is a L2GuardInstance if(_actor instanceof L2GuardInstance) { // Check if the L2PcInstance target has karma (=PK) if(target instanceof L2PcInstance && ((L2PcInstance) target).getKarma() > 0) // 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 L2NpcInstance) return false; // Check if the L2PcInstance target has karma (=PK) if(target instanceof L2PcInstance && ((L2PcInstance) target).getKarma() > 0) // Los Check return GeoData.getInstance().canSeeTarget(me, target); return false; } else { //The actor is a L2MonsterInstance // Check if the target isn't another L2NpcInstance if(target instanceof L2NpcInstance) return false; // depending on config, do not allow mobs to attack _new_ players in peacezones, // unless they are already following those players from outside the peacezone. if(!Config.ALT_MOB_AGRO_IN_PEACEZONE && target.isInsideZone(L2Character.ZONE_PEACE)) return false; // Check if the actor is Aggressive return me.isAggressive() && GeoData.getInstance().canSeeTarget(me, target); } } public synchronized void startAITask() { // If not idle - create an AI task (schedule onEvtThink repeatedly) if(_aiTask == null) { _aiTask = ThreadPoolManager.getInstance().scheduleAiAtFixedR ate(this, 1000, 1000); } } public synchronized 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 public 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().size() > 0) { intention = AI_INTENTION_ACTIVE; } npc = null; } 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 stopAITask(); // 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(); // 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 L2GuardInstance 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 for(L2Object obj : npc.getKnownList().getKnownObjects().values()) { if(obj == null || !(obj instanceof L2Character)) { continue; } L2Character target = (L2Character) obj; /* * Check to see if this is a festival mob spawn. * If it is, then check to see if the aggro trigger * is a festival participant...if so, move to attack it. */ if(_actor instanceof L2FestivalMonsterInstance && obj instanceof L2PcInstance) { L2PcInstance targetPlayer = (L2PcInstance) obj; if(!targetPlayer.isFestivalParticipant()) { continue; } targetPlayer = null; } 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.QuestEve ntType.ON_AGGRO_RANGE_ENTER) != null) { for(Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventT ype.ON_AGGRO_RANGE_ENTER)) { quest.notifyAggroRangeEnter(npc, targetPlayer, obj instanceof L2Summon); } } } } // 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, 1); } } target = null; } // Chose a target from its aggroList L2Character hated; // Force mobs to attak anybody if confused if(_actor.isConfused()) { hated = getAttackTarget(); } 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 L2GuardInstance if(_actor instanceof L2GuardInstance) { // Order to the L2GuardInstance to return to its home location because there's no target to attack ((L2GuardInstance) _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; // for Raids - need correction if(_actor.isRaid()) { offset = 500; } else { // for normal minions - need correction offset = 200; } 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; } } // Order to the L2MonsterInstance to random walk (1/100) else if(!(npc instanceof L2ChestInstance) && npc.getSpawn() != null && Rnd.nextInt(RANDOM_WALK_RATE) == 0) { int x1, y1, z1; // If NPC with random coord in territory if(npc.getSpawn().getLocx() == 0 && npc.getSpawn().getLocy() == 0) { // If NPC with random fixed coord, don't move if(TerritoryTable.getInstance().getProcMax(npc.get Spawn().getLocation()) > 0) return; // Calculate a destination point in the spawn area int p[] = TerritoryTable.getInstance().getRandomPoint(npc.ge tSpawn().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 > Config.MAX_DRIFT_RANGE * Config.MAX_DRIFT_RANGE) { npc.setisReturningToSpawnPoint(true); float delay = (float) Math.sqrt(distance2) / Config.MAX_DRIFT_RANGE; x1 = _actor.getX() + (int) ((x1 - _actor.getX()) / delay); y1 = _actor.getY() + (int) ((y1 - _actor.getY()) / delay); } else { npc.setisReturningToSpawnPoint(false); } } else { if(Config.MONSTER_RETURN_DELAY > 0 && npc instanceof L2MonsterInstance && !npc.isAlikeDead() && !npc.isDead() && npc.getSpawn() != null && !npc.isInsideRadius(npc.getSpawn().getLocx(), npc.getSpawn().getLocy(), Config.MAX_DRIFT_RANGE, false)) { ((L2MonsterInstance) _actor).returnHome(); } // If NPC with fixed coord x1 = npc.getSpawn().getLocx() + Rnd.nextInt(Config.MAX_DRIFT_RANGE * 2) - Config.MAX_DRIFT_RANGE; y1 = npc.getSpawn().getLocy() + Rnd.nextInt(Config.MAX_DRIFT_RANGE * 2) - Config.MAX_DRIFT_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); } npc = null; return; } /** * 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 (_actor.isCastingNow()) return; 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(); } } final L2Character originalAttackTarget = getAttackTarget(); // Check if target is dead or if timeout is expired to stop this attack if (originalAttackTarget == null || originalAttackTarget.isAlikeDead() || (originalAttackTarget instanceof L2PcInstance && (((L2PcInstance)originalAttackTarget).isOffline() || ((L2PcInstance)originalAttackTarget).isOnline()==0 )) || _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; } /* // Handle all L2Object of its Faction inside the Faction Range if (_actor instanceof L2NpcInstance && ((L2NpcInstance) _actor).getFactionId() != null) { String faction_id = ((L2NpcInstance) _actor).getFactionId(); // Go through all L2Object that belong to its faction Collection<L2Object> objs = _actor.getKnownList().getKnownObjects().values(); //synchronized (_actor.getKnownList().getKnownObjects()) try { for (L2Object obj : objs) { if (obj instanceof L2NpcInstance) { L2NpcInstance npc = (L2NpcInstance) obj; //Handle SevenSigns mob Factions String npcfaction = npc.getFactionId(); boolean sevenSignFaction = false; // TODO: Unhardcode this by AI scripts (DrHouse) //Catacomb mobs should assist lilim and nephilim other than dungeon if ("c_dungeon_clan".equals(faction_id) && ("c_dungeon_lilim".equals(npcfaction) || "c_dungeon_nephi".equals(npcfaction))) sevenSignFaction = true; //Lilim mobs should assist other Lilim and catacomb mobs else if ("c_dungeon_lilim".equals(faction_id) && "c_dungeon_clan".equals(npcfaction)) sevenSignFaction = true; //Nephilim mobs should assist other Nephilim and catacomb mobs else if ("c_dungeon_nephi".equals(faction_id) && "c_dungeon_clan".equals(npcfaction)) sevenSignFaction = true; if (!faction_id.equals(npc.getFactionId()) && !sevenSignFaction) continue; // Check if the L2Object is inside the Faction Range of // the actor if (_actor.isInsideRadius(npc, npc.getFactionRange() + npc.getTemplate().collisionRadius, true, false) && npc.getAI() != null) { if (Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600 && _actor.getAttackByList().contains(originalAttackTa rget) && (npc.getAI()._intention == CtrlIntention.AI_INTENTION_IDLE || npc.getAI()._intention == CtrlIntention.AI_INTENTION_ACTIVE) && GeoData.getInstance().canSeeTarget(_actor, npc)) { if ((originalAttackTarget instanceof L2PcInstance) || (originalAttackTarget instanceof L2Summon)) { if (npc.getTemplate().getEventQuests(Quest.QuestEvent Type.ON_FACTION_CALL) != null) { L2PcInstance player = (originalAttackTarget instanceof L2PcInstance) ? (L2PcInstance) originalAttackTarget : ((L2Summon) originalAttackTarget).getOwner(); for (Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventT ype.ON_FACTION_CALL)) quest.notifyFactionCall(npc, (L2NpcInstance) _actor, player, (originalAttackTarget instanceof L2Summon)); } } else if (npc instanceof L2Attackable && getAttackTarget() != null && npc.getAI()._intention != CtrlIntention.AI_INTENTION_ATTACK) { ((L2Attackable) npc).addDamageHate(getAttackTarget(), 0, ((L2Attackable) _actor).getHating(getAttackTarget())); npc.getAI().setIntention(CtrlIntention.AI_INTENTIO N_ATTACK, getAttackTarget()); } } } } } } catch (NullPointerException e) { _log.log(Level.WARNING, "L2AttackableAI: thinkAttack() faction call failed: " + e.getMessage(), e); } } */ // Call all L2Object of its Faction inside the Faction Range if(((L2NpcInstance) _actor).getFactionId() != null) { // Go through all L2Object that belong to its faction for(L2Object obj : _actor.getKnownList().getKnownObjects().values()) { if(obj instanceof L2NpcInstance) { L2NpcInstance npc = (L2NpcInstance) obj; String faction_id = ((L2NpcInstance) _actor).getFactionId(); if(!faction_id.equalsIgnoreCase(npc.getFactionId() ) || npc.getFactionRange() == 0) { faction_id = null; continue; } // Check if the L2Object is inside the Faction Range of the actor if(_actor != null && _actor.getAttackByList()!=null && _actor.isInsideRadius(npc, npc.getFactionRange(), true, false) && npc.getAI() != null && _actor.getAttackByList().contains(originalAttackTa rget)) { if(npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE || npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE){ if(GeoData.getInstance().canSeeTarget(_actor, npc) && Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 600){ if(originalAttackTarget instanceof L2PcInstance && originalAttackTarget.isInParty() && originalAttackTarget.getParty().isInDimensionalRif t()) { byte riftType = originalAttackTarget.getParty().getDimensionalRift ().getType(); byte riftRoom = originalAttackTarget.getParty().getDimensionalRift ().getCurrentRoom(); if(_actor instanceof L2RiftInvaderInstance && !DimensionalRiftManager.getInstance().getRoom(rift Type, riftRoom).checkIfInZone(npc.getX(), npc.getY(), npc.getZ())) { continue; } } // Notify the L2Object AI with EVT_AGGRESSION npc.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, originalAttackTarget, 1); } } if(GeoData.getInstance().canSeeTarget(_actor, npc) && Math.abs(originalAttackTarget.getZ() - npc.getZ()) < 500){ if(originalAttackTarget instanceof L2PcInstance || originalAttackTarget instanceof L2Summon) { if(npc.getTemplate().getEventQuests(Quest.QuestEve ntType.ON_FACTION_CALL) != null) { L2PcInstance player = originalAttackTarget instanceof L2PcInstance ? (L2PcInstance) originalAttackTarget : ((L2Summon) originalAttackTarget).getOwner(); for(Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventT ype.ON_FACTION_CALL)) { quest.notifyFactionCall(npc, (L2NpcInstance) _actor, player, (originalAttackTarget instanceof L2Summon)); } } } } } npc = null; } } } if(_actor.isAttackingDisabled()) return; // Get all information needed to chose between physical or magical attack L2Skill[] skills = null; double dist2 = 0; int range = 0; try { _actor.setTarget(originalAttackTarget); skills = _actor.getAllSkills(); dist2 = _actor.getPlanDistanceSq(originalAttackTarget.getX (), originalAttackTarget.getY()); range = _actor.getPhysicalAttackRange() + _actor.getTemplate().collisionRadius + originalAttackTarget.getTemplate().collisionRadius ; } catch(NullPointerException e) { //_log.warning("AttackableAI: Attack target is NULL."); if(Config.ENABLE_ALL_EXCEPTIONS) e.printStackTrace(); setIntention(AI_INTENTION_ACTIVE); return; } L2Weapon weapon = _actor.getActiveWeaponItem(); final int collision = _actor.getTemplate().collisionRadius; final int combinedCollision = collision + originalAttackTarget.getTemplate().collisionRadius ; //------------------------------------------------------ // In case many mobs are trying to hit from same place, move a bit, // circling around the target // Note from Gnacik: // On l2js because of that sometimes mobs don't attack player only running // around player without any sense, so decrease chance for now if (!_actor.isMovementDisabled() && Rnd.nextInt(100) <= 3) { for (L2Object nearby : _actor.getKnownList().getKnownObjects().values()) { if (nearby instanceof L2Attackable && _actor.isInsideRadius(nearby, collision, false, false) && nearby != originalAttackTarget) { int newX = combinedCollision + Rnd.get(40); if (Rnd.nextBoolean()) newX = originalAttackTarget.getX() + newX; else newX = originalAttackTarget.getX() - newX; int newY = combinedCollision + Rnd.get(40); if (Rnd.nextBoolean()) newY = originalAttackTarget.getY() + newY; else newY = originalAttackTarget.getY() - newY; if (!_actor.isInsideRadius(newX, newY, collision, false)) { int newZ = _actor.getZ() + 30; if (Config.GEODATA == 0 || GeoData.getInstance().canMoveFromToTarget(_actor.g etX(), _actor.getY(), _actor.getZ(), newX, newY, newZ)) moveTo(newX, newY, newZ); } return; } } } if(weapon != null && weapon.getItemType() == L2WeaponType.BOW) { // Micht: kepping this one otherwise we should do 2 sqrt double distance2 = _actor.getPlanDistanceSq(originalAttackTarget.getX (), originalAttackTarget.getY()); if (Math.sqrt(distance2) <= 60 + combinedCollision) { //double distance2 = _actor.getPlanDistanceSq(originalAttackTarget.getX (), originalAttackTarget.getY()); //if(distance2 <= 10000) //{ int chance = 5; if(chance >= Rnd.get(100)) { int posX = _actor.getX(); int posY = _actor.getY(); int posZ = _actor.getZ(); double distance = Math.sqrt(distance2); // This way, we only do the sqrt if we need it int signx = -1; int signy = -1; if(_actor.getX() > originalAttackTarget.getX()) { signx = 1; } if(_actor.getY() > originalAttackTarget.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; } } } weapon = null; // Force mobs to attack anybody if confused L2Character hated; if(_actor.isConfused()) { hated = originalAttackTarget; } else { hated = ((L2Attackable) _actor).getMostHated(); } if(hated == null) { setIntention(AI_INTENTION_ACTIVE); return; } if(hated != originalAttackTarget) { setAttackTarget(hated); } // We should calculate new distance cuz mob can have changed the target dist2 = _actor.getPlanDistanceSq(hated.getX(), hated.getY()); if(hated.isMoving()) { range += 50; } // Check if the actor isn't far from target if(dist2 > range * range) { // check for long ranged skills and heal/buff skills if(!_actor.isMuted() && (!Config.ALT_GAME_MOB_ATTACK_AI || _actor instanceof L2MonsterInstance && Rnd.nextInt(100) <= 5)) { for(L2Skill sk : skills) { int castRange = sk.getCastRange(); boolean _inRange = false; if(dist2 >= castRange * castRange / 9.0 && dist2 <= castRange * castRange && castRange > 70){ _inRange = true; } if((sk.getSkillType() == L2Skill.SkillType.BUFF || sk.getSkillType() == L2Skill.SkillType.HEAL || _inRange) && !_actor.isSkillDisabled(sk.getId()) && _actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk) && !sk.isPassive() && Rnd.nextInt(100) <= 5) { if(sk.getSkillType() == L2Skill.SkillType.BUFF || sk.getSkillType() == L2Skill.SkillType.HEAL) { boolean useSkillSelf = true; if(sk.getSkillType() == L2Skill.SkillType.HEAL && _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)) { useSkillSelf = false; break; } if(sk.getSkillType() == L2Skill.SkillType.BUFF) { L2Effect[] effects = _actor.getAllEffects(); for(int i = 0; effects != null && i < effects.length; i++) { L2Effect effect = effects[i]; if(effect.getSkill() == sk) { useSkillSelf = false; break; } } effects = null; } if(useSkillSelf) { _actor.setTarget(_actor); } } L2Object OldTarget = _actor.getTarget(); clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); OldTarget = null; return; } } } // Move the actor to Pawn server side AND client side by sending Server->Client packet MoveToPawn (broadcast) if(hated.isMoving()) { range -= 100; } if(range < 5) { range = 5; } moveToPawn(originalAttackTarget, range); return; } // Else, if this is close enough to attack _attackTimeout = MAX_ATTACK_TIMEOUT + GameTimeController.getGameTicks(); // check for close combat skills && heal/buff skills if(!_actor.isMuted() /*&& _rnd.nextInt(100) <= 5*/) { boolean useSkillSelf = true; for(L2Skill sk : skills) { if(/*sk.getCastRange() >= dist && sk.getCastRange() <= 70 && */!sk.isPassive() && _actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk) && !_actor.isSkillDisabled(sk.getId()) && (Rnd.nextInt(100) <= 8 || _actor instanceof L2PenaltyMonsterInstance && Rnd.nextInt(100) <= 20)) { if(sk.getSkillType() == L2Skill.SkillType.BUFF || sk.getSkillType() == L2Skill.SkillType.HEAL) { useSkillSelf = true; if(sk.getSkillType() == L2Skill.SkillType.HEAL && _actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)) { useSkillSelf = false; break; } if(sk.getSkillType() == L2Skill.SkillType.BUFF) { L2Effect[] effects = _actor.getAllEffects(); for(int i = 0; effects != null && i < effects.length; i++) { L2Effect effect = effects[i]; if(effect.getSkill() == sk) { useSkillSelf = false; break; } } effects = null; } if(useSkillSelf) { _actor.setTarget(_actor); } } // GeoData Los Check here if(!useSkillSelf && !GeoData.getInstance().canSeeTarget(_actor, _actor.getTarget())) return; L2Object OldTarget = _actor.getTarget(); clientStopMoving(null); _accessor.doCast(sk); _actor.setTarget(OldTarget); OldTarget = null; return; } } } // Finally, physical attacks clientStopMoving(null); _accessor.doAttack(hated); skills = null; hated = null; } /** * Manage AI thinking actions of a L2Attackable.<BR> * <BR> */ @Override protected void onEvtThink() { // Check if the actor can't use skills and if a thinking action isn't already in progress if(_thinking || _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) { // 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 ((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) { setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker); } else if(((L2Attackable) _actor).getMostHated() != getAttackTarget()) { setIntention(CtrlIntention.AI_INTENTION_ATTACK, 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 L2GuardInstance check if it isn't too far from its home location)</li><BR> * <BR> * * @param target 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); } } me = null; } @Override protected void onIntentionActive() { // Cancel attack timeout _attackTimeout = Integer.MAX_VALUE; super.onIntentionActive(); } public void setGlobalAggro(int value) { _globalAggro = value; } } Добавлено через 23 минуты не получается... в фрозенах всьо по другому....(((((((((((( ппц по другому public boolean isAutoAttackable(L2Character attacker) { return attacker instanceof L2PlayableInstance; } Последний раз редактировалось smy55; 13.02.2013 в 00:25. Причина: Добавлено сообщение |
13.02.2013, 00:28 | #17 |
Пользователь
Регистрация: 18.10.2010
Адрес: Харьков
Возраст: 30
Сообщений: 527
Отблагодарили 98 раз(а)
Рейтинг мнений:
77
|
Re: Guard
вот оно в АИ:
Код:
if(_actor instanceof L2GuardInstance) { // Check if the L2PcInstance target has karma (=PK) if(target instanceof L2PcInstance && ((L2PcInstance) target).getKarma() > 0) // 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; } Код:
if(_actor instanceof L2GuardInstance) { // Check if the L2PcInstance target has karma (=PK) if(target instanceof L2PcInstance && _actor.getRace() != target.getRace()) // 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; } |
13.02.2013, 01:08 | #18 |
Пользователь
|
Re: Guard
не работает но спасибо!!! надо норм исходники искать!!!
|
14.02.2013, 19:30 | #19 |
Олдфаг
Регистрация: 03.05.2010
Адрес: lsp:25
Возраст: 38
Сообщений: 2,443
Отблагодарили 548 раз(а)
Рейтинг мнений:
215
|
Re: Guard
СЕО Оптимизация сайтов |
gorodetskiy |
Посмотреть профиль |
Найти ещё сообщения от gorodetskiy |
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Вопросы косающие SQL запросов | Amaterasu | Lineage II | 67 | 09.08.2015 12:18 |
[Продам] Gracia Part 2 L2Dream | PaInKiLlEr | Рынок / Marketplace | 10 | 04.06.2010 00:18 |
Адаптируем SQL | BimBom | Работа со скриптами | 9 | 14.10.2009 15:14 |
Id Мобов Для Rf Online | Redon | Документация | 1 | 04.07.2009 11:30 |