Use new RandomAnimationTask.
This commit is contained in:
		@@ -151,7 +151,7 @@ public class L2CharacterAI extends AbstractAI
 | 
			
		||||
			// This is only for mobs - town npcs are handled in their constructor
 | 
			
		||||
			if (_actor instanceof L2Attackable)
 | 
			
		||||
			{
 | 
			
		||||
				((L2NpcInstance) _actor).startRandomAnimationTimer();
 | 
			
		||||
				((L2NpcInstance) _actor).startRandomAnimationTask();
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Launch the Think Event
 | 
			
		||||
@@ -1219,7 +1219,7 @@ public class L2CharacterAI extends AbstractAI
 | 
			
		||||
			// This is only for mobs - town npcs are handled in their constructor
 | 
			
		||||
			if (_actor instanceof L2Attackable)
 | 
			
		||||
			{
 | 
			
		||||
				((L2NpcInstance) _actor).startRandomAnimationTimer();
 | 
			
		||||
				((L2NpcInstance) _actor).startRandomAnimationTask();
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Launch the Think Event
 | 
			
		||||
 
 | 
			
		||||
@@ -265,7 +265,7 @@ public final class L2WorldRegion
 | 
			
		||||
				{
 | 
			
		||||
					// Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it
 | 
			
		||||
					// L2Monsterinstance/L2Attackable socials are handled by AI (TODO: check the instances)
 | 
			
		||||
					((L2NpcInstance) o).startRandomAnimationTimer();
 | 
			
		||||
					((L2NpcInstance) o).startRandomAnimationTask();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (Config.DEBUG)
 | 
			
		||||
 
 | 
			
		||||
@@ -485,8 +485,8 @@ public class L2Attackable extends L2NpcInstance
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		 * // CommandChannel if(_commandChannelTimer == null && isRaid() && attacker != null) { if(attacker.isInParty() && attacker.getParty().isInCommandChannel() && attacker.getParty().getCommandChannel().meetRaidWarCondition(this)) { _firstCommandChannelAttacked =
 | 
			
		||||
		 * attacker.getParty().getCommandChannel(); _commandChannelTimer = new CommandChannelTimer(this, attacker.getParty().getCommandChannel()); ThreadPoolManager.scheduleGeneral(_commandChannelTimer, 300000); // 5 min _firstCommandChannelAttacked.broadcastToChannelMembers(new
 | 
			
		||||
		 * CreatureSay(0, Say2.PARTYROOM_ALL, "", "You have looting rights!")); } }
 | 
			
		||||
		 * attacker.getParty().getCommandChannel(); _commandChannelTimer = new CommandChannelTimer(this, attacker.getParty().getCommandChannel()); ThreadPoolManager.scheduleGeneral(_commandChannelTimer, 300000); // 5 min _firstCommandChannelAttacked.broadcastToChannelMembers(new CreatureSay(0,
 | 
			
		||||
		 * Say2.PARTYROOM_ALL, "", "You have looting rights!")); } }
 | 
			
		||||
		 */
 | 
			
		||||
		if (isEventMob)
 | 
			
		||||
		{
 | 
			
		||||
@@ -3342,12 +3342,6 @@ public class L2Attackable extends L2NpcInstance
 | 
			
		||||
		return (Config.MAX_MONSTER_ANIMATION > 0) && !(this instanceof L2GrandBossInstance);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isMob()
 | 
			
		||||
	{
 | 
			
		||||
		return true; // This means we use MAX_MONSTER_ANIMATION instead of MAX_NPC_ANIMATION
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected void setCommandChannelTimer(CommandChannelTimer commandChannelTimer)
 | 
			
		||||
	{
 | 
			
		||||
		_commandChannelTimer = commandChannelTimer;
 | 
			
		||||
 
 | 
			
		||||
@@ -150,8 +150,12 @@ public class L2NpcInstance extends L2Character
 | 
			
		||||
	/** The _is spoiled by. */
 | 
			
		||||
	private int _isSpoiledBy = 0;
 | 
			
		||||
	
 | 
			
		||||
	/** Time of last social packet broadcast */
 | 
			
		||||
	private long _lastSocialBroadcast = 0;
 | 
			
		||||
	/** Minimum interval between social packets */
 | 
			
		||||
	private static final int MINIMUM_SOCIAL_INTERVAL = 6000;
 | 
			
		||||
	/** The _r ani task. */
 | 
			
		||||
	protected RandomAnimationTask _rAniTask = null;
 | 
			
		||||
	protected RandomAnimationTask _rAniTask;
 | 
			
		||||
	
 | 
			
		||||
	/** The _current l hand id. */
 | 
			
		||||
	private int _currentLHandId; // normally this shouldn't change from the template, but there exist exceptions
 | 
			
		||||
@@ -167,89 +171,122 @@ public class L2NpcInstance extends L2Character
 | 
			
		||||
	
 | 
			
		||||
	private int _scriptValue = 0;
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Task launching the function onRandomAnimation().
 | 
			
		||||
	 */
 | 
			
		||||
	protected class RandomAnimationTask implements Runnable
 | 
			
		||||
	public class RandomAnimationTask implements Runnable
 | 
			
		||||
	{
 | 
			
		||||
		/*
 | 
			
		||||
		 * (non-Javadoc)
 | 
			
		||||
		 * @see java.lang.Runnable#run()
 | 
			
		||||
		 */
 | 
			
		||||
		private final L2NpcInstance _npc;
 | 
			
		||||
		private boolean _stopTask;
 | 
			
		||||
		
 | 
			
		||||
		public RandomAnimationTask(L2NpcInstance npc)
 | 
			
		||||
		{
 | 
			
		||||
			_npc = npc;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		@Override
 | 
			
		||||
		public void run()
 | 
			
		||||
		{
 | 
			
		||||
			if (_stopTask)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if (this != _rAniTask)
 | 
			
		||||
				if (!_npc.isInActiveRegion())
 | 
			
		||||
				{
 | 
			
		||||
					return; // Shouldn't happen, but who knows... just to make sure every active npc has only one timer.
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				if (isMob())
 | 
			
		||||
				// Cancel further animation timers until intention is changed to ACTIVE again.
 | 
			
		||||
				if (_npc.isAttackable() && (_npc.getAI().getIntention() != AI_INTENTION_ACTIVE))
 | 
			
		||||
				{
 | 
			
		||||
					// Cancel further animation timers until intention is changed to ACTIVE again.
 | 
			
		||||
					if (getAI().getIntention() != AI_INTENTION_ACTIVE)
 | 
			
		||||
					{
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					if (!isInActiveRegion())
 | 
			
		||||
					{
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					// update knownlist to remove playable which aren't in range any more
 | 
			
		||||
					getKnownList().updateKnownObjects();
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				if ((!isDead() && !isStunned() && !isSleeping() && !isParalyzed()))
 | 
			
		||||
				if (!(_npc.isDead() || _npc.isStunned() || _npc.isSleeping() || _npc.isParalyzed()))
 | 
			
		||||
				{
 | 
			
		||||
					onRandomAnimation();
 | 
			
		||||
					_npc.onRandomAnimation(Rnd.get(2, 3));
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				startRandomAnimationTimer();
 | 
			
		||||
			}
 | 
			
		||||
			catch (Throwable t)
 | 
			
		||||
			catch (Exception e)
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/**
 | 
			
		||||
		 * Create a RandomAnimation Task that will be launched after the calculated delay.
 | 
			
		||||
		 */
 | 
			
		||||
		public void startRandomAnimationTimer()
 | 
			
		||||
		{
 | 
			
		||||
			if (!_npc.hasRandomAnimation() || _stopTask)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			final int minWait = _npc.isAttackable() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION;
 | 
			
		||||
			final int maxWait = _npc.isAttackable() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION;
 | 
			
		||||
			
 | 
			
		||||
			// Calculate the delay before the next animation
 | 
			
		||||
			final int interval = Rnd.get(minWait, maxWait) * 1000;
 | 
			
		||||
			
 | 
			
		||||
			// Create a RandomAnimation Task that will be launched after the calculated delay
 | 
			
		||||
			ThreadPool.schedule(this, interval);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/**
 | 
			
		||||
		 * Stops the task from continuing and blocks it from continuing ever again. You need to create new task if you want to start it again.
 | 
			
		||||
		 */
 | 
			
		||||
		public void stopRandomAnimationTimer()
 | 
			
		||||
		{
 | 
			
		||||
			_stopTask = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance and create a new RandomAnimation Task.<BR>
 | 
			
		||||
	 * <BR>
 | 
			
		||||
	 */
 | 
			
		||||
	public void onRandomAnimation()
 | 
			
		||||
	{
 | 
			
		||||
		final int min = _customNpcInstance != null ? 1 : 2;
 | 
			
		||||
		final int max = _customNpcInstance != null ? 13 : 3;
 | 
			
		||||
		// Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance
 | 
			
		||||
		SocialAction sa = new SocialAction(getObjectId(), Rnd.get(min, max));
 | 
			
		||||
		broadcastPacket(sa);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a RandomAnimation Task that will be launched after the calculated delay.<BR>
 | 
			
		||||
	 * <BR>
 | 
			
		||||
	 */
 | 
			
		||||
	public void startRandomAnimationTimer()
 | 
			
		||||
	public void startRandomAnimationTask()
 | 
			
		||||
	{
 | 
			
		||||
		if (!hasRandomAnimation())
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		final int minWait = isMob() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION;
 | 
			
		||||
		final int maxWait = isMob() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION;
 | 
			
		||||
		if (_rAniTask == null)
 | 
			
		||||
		{
 | 
			
		||||
			synchronized (this)
 | 
			
		||||
			{
 | 
			
		||||
				if (_rAniTask == null)
 | 
			
		||||
				{
 | 
			
		||||
					_rAniTask = new RandomAnimationTask(this);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Calculate the delay before the next animation
 | 
			
		||||
		final int interval = Rnd.get(minWait, maxWait) * 1000;
 | 
			
		||||
		
 | 
			
		||||
		// Create a RandomAnimation Task that will be launched after the calculated delay
 | 
			
		||||
		_rAniTask = new RandomAnimationTask();
 | 
			
		||||
		ThreadPool.schedule(_rAniTask, interval);
 | 
			
		||||
		_rAniTask.startRandomAnimationTimer();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void stopRandomAnimationTask()
 | 
			
		||||
	{
 | 
			
		||||
		final RandomAnimationTask rAniTask = _rAniTask;
 | 
			
		||||
		if (rAniTask != null)
 | 
			
		||||
		{
 | 
			
		||||
			rAniTask.stopRandomAnimationTimer();
 | 
			
		||||
			_rAniTask = null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance and create a new RandomAnimation Task.
 | 
			
		||||
	 * @param animationId
 | 
			
		||||
	 */
 | 
			
		||||
	public void onRandomAnimation(int animationId)
 | 
			
		||||
	{
 | 
			
		||||
		// Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance
 | 
			
		||||
		final long now = System.currentTimeMillis();
 | 
			
		||||
		if ((now - _lastSocialBroadcast) > MINIMUM_SOCIAL_INTERVAL)
 | 
			
		||||
		{
 | 
			
		||||
			_lastSocialBroadcast = now;
 | 
			
		||||
			broadcastPacket(new SocialAction(getObjectId(), animationId));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
@@ -3355,15 +3392,6 @@ public class L2NpcInstance extends L2Character
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Checks if is mob.
 | 
			
		||||
	 * @return true, if is mob
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isMob() // rather delete this check
 | 
			
		||||
	{
 | 
			
		||||
		return false; // This means we use MAX_NPC_ANIMATION instead of MAX_MONSTER_ANIMATION
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Two functions to change the appearance of the equipped weapons on the NPC
 | 
			
		||||
	// This is only useful for a few NPCs and is most likely going to be called from AI
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
@@ -1620,13 +1620,7 @@ public class L2Attackable extends L2Npc
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean hasRandomAnimation()
 | 
			
		||||
	{
 | 
			
		||||
		return (Config.MAX_MONSTER_ANIMATION > 0) && isRandomAnimationEnabled() && !(this instanceof L2GrandBossInstance);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean isMob()
 | 
			
		||||
	{
 | 
			
		||||
		return true; // This means we use MAX_MONSTER_ANIMATION instead of MAX_NPC_ANIMATION
 | 
			
		||||
		return ((Config.MAX_MONSTER_ANIMATION > 0) && isRandomAnimationEnabled() && !(this instanceof L2GrandBossInstance));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void setCommandChannelTimer(CommandChannelTimer commandChannelTimer)
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,6 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.l2jmobius.gameserver.model.actor;
 | 
			
		||||
 | 
			
		||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
@@ -65,6 +63,7 @@ import com.l2jmobius.gameserver.model.actor.instance.L2TrainerInstance;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.instance.L2WarehouseInstance;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.stat.NpcStat;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.status.NpcStatus;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.tasks.npc.RandomAnimationTask;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
 | 
			
		||||
import com.l2jmobius.gameserver.model.entity.Castle;
 | 
			
		||||
import com.l2jmobius.gameserver.model.entity.Fort;
 | 
			
		||||
@@ -138,7 +137,7 @@ public class L2Npc extends L2Character
 | 
			
		||||
	private boolean _isTalkable = getTemplate().isTalkable();
 | 
			
		||||
	private final boolean _isFakePlayer = getTemplate().isFakePlayer();
 | 
			
		||||
	
 | 
			
		||||
	protected RandomAnimationTask _rAniTask = null;
 | 
			
		||||
	protected RandomAnimationTask _rAniTask;
 | 
			
		||||
	private int _currentLHandId; // normally this shouldn't change from the template, but there exist exceptions
 | 
			
		||||
	private int _currentRHandId; // normally this shouldn't change from the template, but there exist exceptions
 | 
			
		||||
	private int _currentEnchant; // normally this shouldn't change from the template, but there exist exceptions
 | 
			
		||||
@@ -241,48 +240,35 @@ public class L2Npc extends L2Character
 | 
			
		||||
		return getTemplate().getAISkills(AISkillScope.SHORT_RANGE);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Task launching the function onRandomAnimation() */
 | 
			
		||||
	protected static class RandomAnimationTask implements Runnable
 | 
			
		||||
	public void startRandomAnimationTask()
 | 
			
		||||
	{
 | 
			
		||||
		private final L2Npc _npc;
 | 
			
		||||
		
 | 
			
		||||
		protected RandomAnimationTask(L2Npc npc)
 | 
			
		||||
		if (!hasRandomAnimation())
 | 
			
		||||
		{
 | 
			
		||||
			_npc = npc;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		@Override
 | 
			
		||||
		public void run()
 | 
			
		||||
		if (_rAniTask == null)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			synchronized (this)
 | 
			
		||||
			{
 | 
			
		||||
				if (_npc.isMob())
 | 
			
		||||
				if (_rAniTask == null)
 | 
			
		||||
				{
 | 
			
		||||
					// Cancel further animation timers until intention is changed to ACTIVE again.
 | 
			
		||||
					if (_npc.getAI().getIntention() != AI_INTENTION_ACTIVE)
 | 
			
		||||
					{
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
					_rAniTask = new RandomAnimationTask(this);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					if (!_npc.isInActiveRegion())
 | 
			
		||||
					{
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				if (!(_npc.isDead() || _npc.isStunned() || _npc.isSleeping() || _npc.isParalyzed()))
 | 
			
		||||
				{
 | 
			
		||||
					_npc.onRandomAnimation(Rnd.get(2, 3));
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				_npc.startRandomAnimationTask();
 | 
			
		||||
			}
 | 
			
		||||
			catch (Exception e)
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		_rAniTask.startRandomAnimationTimer();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void stopRandomAnimationTask()
 | 
			
		||||
	{
 | 
			
		||||
		final RandomAnimationTask rAniTask = _rAniTask;
 | 
			
		||||
		if (rAniTask != null)
 | 
			
		||||
		{
 | 
			
		||||
			rAniTask.stopRandomAnimationTimer();
 | 
			
		||||
			_rAniTask = null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
@@ -300,27 +286,6 @@ public class L2Npc extends L2Character
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a RandomAnimation Task that will be launched after the calculated delay.
 | 
			
		||||
	 */
 | 
			
		||||
	public void startRandomAnimationTask()
 | 
			
		||||
	{
 | 
			
		||||
		if (!hasRandomAnimation())
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		final int minWait = isMob() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION;
 | 
			
		||||
		final int maxWait = isMob() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION;
 | 
			
		||||
		
 | 
			
		||||
		// Calculate the delay before the next animation
 | 
			
		||||
		final int interval = Rnd.get(minWait, maxWait) * 1000;
 | 
			
		||||
		
 | 
			
		||||
		// Create a RandomAnimation Task that will be launched after the calculated delay
 | 
			
		||||
		_rAniTask = new RandomAnimationTask(this);
 | 
			
		||||
		ThreadPool.schedule(_rAniTask, interval);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return true if the server allows Random Animation.
 | 
			
		||||
	 */
 | 
			
		||||
@@ -1460,11 +1425,6 @@ public class L2Npc extends L2Character
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean isMob() // rather delete this check
 | 
			
		||||
	{
 | 
			
		||||
		return false; // This means we use MAX_NPC_ANIMATION instead of MAX_MONSTER_ANIMATION
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Two functions to change the appearance of the equipped weapons on the NPC
 | 
			
		||||
	// This is only useful for a few NPCs and is most likely going to be called from AI
 | 
			
		||||
	public void setLHandId(int newWeaponId)
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,104 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of the L2J Mobius project.
 | 
			
		||||
 * 
 | 
			
		||||
 * 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.l2jmobius.gameserver.model.actor.tasks.npc;
 | 
			
		||||
 | 
			
		||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
 | 
			
		||||
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import com.l2jmobius.Config;
 | 
			
		||||
import com.l2jmobius.commons.concurrent.ThreadPool;
 | 
			
		||||
import com.l2jmobius.commons.util.Rnd;
 | 
			
		||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Nik
 | 
			
		||||
 */
 | 
			
		||||
public class RandomAnimationTask implements Runnable
 | 
			
		||||
{
 | 
			
		||||
	private static final Logger LOGGER = Logger.getLogger(RandomAnimationTask.class.getName());
 | 
			
		||||
	private final L2Npc _npc;
 | 
			
		||||
	private boolean _stopTask;
 | 
			
		||||
	
 | 
			
		||||
	public RandomAnimationTask(L2Npc npc)
 | 
			
		||||
	{
 | 
			
		||||
		_npc = npc;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void run()
 | 
			
		||||
	{
 | 
			
		||||
		if (_stopTask)
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			if (!_npc.isInActiveRegion())
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Cancel further animation timers until intention is changed to ACTIVE again.
 | 
			
		||||
			if (_npc.isAttackable() && (_npc.getAI().getIntention() != AI_INTENTION_ACTIVE))
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (!(_npc.isDead() || _npc.isStunned() || _npc.isSleeping() || _npc.isParalyzed()))
 | 
			
		||||
			{
 | 
			
		||||
				_npc.onRandomAnimation(Rnd.get(2, 3));
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			startRandomAnimationTimer();
 | 
			
		||||
		}
 | 
			
		||||
		catch (Exception e)
 | 
			
		||||
		{
 | 
			
		||||
			LOGGER.log(Level.SEVERE, "Execution of RandomAnimationTask has failed.", e);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a RandomAnimation Task that will be launched after the calculated delay.
 | 
			
		||||
	 */
 | 
			
		||||
	public void startRandomAnimationTimer()
 | 
			
		||||
	{
 | 
			
		||||
		if (!_npc.hasRandomAnimation() || _stopTask)
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		final int minWait = _npc.isAttackable() ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION;
 | 
			
		||||
		final int maxWait = _npc.isAttackable() ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION;
 | 
			
		||||
		
 | 
			
		||||
		// Calculate the delay before the next animation
 | 
			
		||||
		final int interval = Rnd.get(minWait, maxWait) * 1000;
 | 
			
		||||
		
 | 
			
		||||
		// Create a RandomAnimation Task that will be launched after the calculated delay
 | 
			
		||||
		ThreadPool.schedule(this, interval);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Stops the task from continuing and blocks it from continuing ever again. You need to create new task if you want to start it again.
 | 
			
		||||
	 */
 | 
			
		||||
	public void stopRandomAnimationTimer()
 | 
			
		||||
	{
 | 
			
		||||
		_stopTask = true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user