Procházet zdrojové kódy

BETA: Improving Improved baby pet AI.
* Fixing [6257], preventing heal skills to be set, leaving all skills as buffs.
* Fixed continuous casting for heals (HP and MP).
* Reported by: laxsur
* Improved casting logic, preventing buff casting when a buff with equal or higher abnormal level and same abnormal type is present.
* Continuing with [6249].
* Reported by: Cresceus

Zoey76 před 11 roky
rodič
revize
ca2febe873

+ 1 - 5
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Summon.java

@@ -587,11 +587,7 @@ public abstract class L2Summon extends L2Playable
 	@Override
 	public boolean isInParty()
 	{
-		if (_owner == null)
-		{
-			return false;
-		}
-		return _owner.getParty() != null;
+		return (_owner != null) && _owner.isInParty();
 	}
 	
 	/**

+ 113 - 128
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2BabyPetInstance.java

@@ -18,12 +18,10 @@
  */
 package com.l2jserver.gameserver.model.actor.instance;
 
+import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Future;
 
-import javolution.util.FastList;
-
 import com.l2jserver.gameserver.ThreadPoolManager;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.datatables.PetDataTable;
@@ -37,7 +35,6 @@ import com.l2jserver.gameserver.model.holders.SkillHolder;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 import com.l2jserver.gameserver.model.skills.BuffInfo;
 import com.l2jserver.gameserver.model.skills.L2Skill;
-import com.l2jserver.gameserver.model.skills.L2SkillType;
 import com.l2jserver.gameserver.network.SystemMessageId;
 import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
 import com.l2jserver.util.Rnd;
@@ -73,7 +70,6 @@ public final class L2BabyPetInstance extends L2PetInstance
 	{
 		super.onSpawn();
 		
-		L2Skill skill;
 		double healPower = 0;
 		for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getId()).getAvailableSkills())
 		{
@@ -83,51 +79,55 @@ public final class L2BabyPetInstance extends L2PetInstance
 			{
 				continue;
 			}
-			skill = SkillTable.getInstance().getInfo(id, lvl);
-			if (skill != null)
+			
+			final L2Skill skill = SkillTable.getInstance().getInfo(id, lvl);
+			if (skill == null)
 			{
-				if ((skill.getId() == BUFF_CONTROL) || (skill.getId() == AWAKENING))
-				{
-					continue;
-				}
-				
-				if (skill.isContinuous() && !skill.isDebuff())
+				continue;
+			}
+			
+			if ((skill.getId() == BUFF_CONTROL) || (skill.getId() == AWAKENING))
+			{
+				continue;
+			}
+			
+			if (skill.hasEffectType(L2EffectType.MANAHEAL_BY_LEVEL))
+			{
+				_recharge = new SkillHolder(skill);
+				continue;
+			}
+			
+			if (skill.hasEffectType(L2EffectType.HEAL))
+			{
+				if (healPower == 0)
 				{
-					if (_buffs == null)
-					{
-						_buffs = new FastList<>();
-					}
-					_buffs.add(new SkillHolder(skill));
+					// set both heal types to the same skill
+					_majorHeal = new SkillHolder(skill);
+					_minorHeal = _majorHeal;
+					healPower = skill.getPower();
 				}
-				else if (skill.getSkillType() == L2SkillType.DUMMY)
+				else
 				{
-					if (skill.hasEffectType(L2EffectType.MANAHEAL_BY_LEVEL))
+					// another heal skill found - search for most powerful
+					if (skill.getPower() > healPower)
 					{
-						_recharge = new SkillHolder(skill);
+						_majorHeal = new SkillHolder(skill);
 					}
-					else if (skill.hasEffectType(L2EffectType.HEAL))
+					else
 					{
-						if (healPower == 0)
-						{
-							// set both heal types to the same skill
-							_majorHeal = new SkillHolder(skill);
-							_minorHeal = _majorHeal;
-							healPower = skill.getPower();
-						}
-						else
-						{
-							// another heal skill found - search for most powerful
-							if (skill.getPower() > healPower)
-							{
-								_majorHeal = new SkillHolder(skill);
-							}
-							else
-							{
-								_minorHeal = new SkillHolder(skill);
-							}
-						}
+						_minorHeal = new SkillHolder(skill);
 					}
 				}
+				continue;
+			}
+			
+			if (skill.isContinuous() && !skill.isDebuff())
+			{
+				if (_buffs == null)
+				{
+					_buffs = new ArrayList<>();
+				}
+				_buffs.add(new SkillHolder(skill));
 			}
 		}
 		startCastTask();
@@ -173,9 +173,9 @@ public final class L2BabyPetInstance extends L2PetInstance
 	
 	private final void startCastTask()
 	{
-		if (((_majorHeal != null) || (_buffs != null) || (_recharge != null)) && (_castTask == null) && !isDead())
+		if ((_majorHeal != null) || (_buffs != null) || ((_recharge != null) && (_castTask == null) && !isDead()))
 		{
-			_castTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CastTask(this), 3000, 1000);
+			_castTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CastTask(this), 3000, 2000);
 		}
 	}
 	
@@ -186,6 +186,7 @@ public final class L2BabyPetInstance extends L2PetInstance
 	}
 	
 	/**
+	 * Verify if this pet is in support mode.
 	 * @return {@code true} if this baby pet is in support mode, {@code false} otherwise
 	 */
 	public boolean isInSupportMode()
@@ -238,7 +239,7 @@ public final class L2BabyPetInstance extends L2PetInstance
 	private class CastTask implements Runnable
 	{
 		private final L2BabyPetInstance _baby;
-		private final List<L2Skill> _currentBuffs = new CopyOnWriteArrayList<>();
+		private final List<L2Skill> _currentBuffs = new ArrayList<>();
 		
 		public CastTask(L2BabyPetInstance baby)
 		{
@@ -248,114 +249,98 @@ public final class L2BabyPetInstance extends L2PetInstance
 		@Override
 		public void run()
 		{
-			L2PcInstance owner = _baby.getOwner();
+			final L2PcInstance owner = _baby.getOwner();
+			// If the owner doesn't meet the conditions avoid casting.
+			if ((owner == null) || owner.isDead() || owner.isInvul())
+			{
+				return;
+			}
+			// If the pet doesn't meet the conditions avoid casting.
+			if (_baby.isCastingNow() || _baby.isBetrayed() || _baby.isMuted() || _baby.isOutOfControl() || !_bufferMode || (_baby.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST))
+			{
+				return;
+			}
 			
-			// if the owner is dead, merely wait for the owner to be resurrected
-			// if the pet is still casting from the previous iteration, allow the cast to complete...
-			if ((owner != null) && !owner.isDead() && !owner.isInvul() && !_baby.isCastingNow() && !_baby.isBetrayed() && !_baby.isMuted() && !_baby.isOutOfControl() && _bufferMode && (_baby.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
+			L2Skill skill = null;
+			if (_majorHeal != null)
 			{
-				L2Skill skill = null;
-				
-				if (_majorHeal != null)
+				// If the owner's HP is more than 80% for Baby Pets and 70% for Improved Baby pets, do nothing.
+				// If the owner's HP is very low, under 15% for Baby pets and under 30% for Improved Baby Pets, have 75% chances of using a strong heal.
+				// Otherwise, have 25% chances for weak heal.
+				final double hpPercent = owner.getCurrentHp() / owner.getMaxHp();
+				final boolean isImprovedBaby = PetDataTable.isUpgradeBabyPetGroup(getId());
+				if ((isImprovedBaby && (hpPercent < 0.3)) || (!isImprovedBaby && (hpPercent < 0.15)))
 				{
-					/**
-					 * If the owner's HP is more than 80% for Baby Pets and 70% for Improved Baby pets, do nothing. If the owner's HP is very low, under 15% for Baby pets and under 30% for Improved Baby Pets, have 75% chances of using a strong heal. Otherwise, have 25% chances for weak heal.
-					 */
-					final double hpPercent = owner.getCurrentHp() / owner.getMaxHp();
-					final boolean isImprovedBaby = PetDataTable.isUpgradeBabyPetGroup(getId());
-					if ((isImprovedBaby && (hpPercent < 0.3)) || (!isImprovedBaby && (hpPercent < 0.15)))
+					skill = _majorHeal.getSkill();
+					if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 75))
 					{
-						skill = _majorHeal.getSkill();
-						if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 75))
+						if (_baby.getCurrentMp() >= skill.getMpConsume())
 						{
-							if (_baby.getCurrentMp() >= skill.getMpConsume())
-							{
-								castSkill(skill);
-								return;
-							}
+							castSkill(skill);
+							return;
 						}
 					}
-					else if ((_majorHeal.getSkill() != _minorHeal.getSkill()) && ((isImprovedBaby && (hpPercent < 0.7)) || (!isImprovedBaby && (hpPercent < 0.8))))
+				}
+				else if ((_majorHeal.getSkill() != _minorHeal.getSkill()) && ((isImprovedBaby && (hpPercent < 0.7)) || (!isImprovedBaby && (hpPercent < 0.8))))
+				{
+					// Cast _minorHeal only if it's different than _majorHeal, then pet has two heals available.
+					skill = _minorHeal.getSkill();
+					if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 25))
 					{
-						// Cast _minorHeal only if it's different than _majorHeal, then pet has two heals available.
-						skill = _minorHeal.getSkill();
-						if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 25))
+						if (_baby.getCurrentMp() >= skill.getMpConsume())
 						{
-							if (_baby.getCurrentMp() >= skill.getMpConsume())
-							{
-								castSkill(skill);
-								return;
-							}
+							castSkill(skill);
+							return;
 						}
 					}
 				}
-				
-				if (!_baby.isAffectedBySkill(BUFF_CONTROL)) // Buff Control is not active
+			}
+			
+			// Buff Control is not active
+			if (!_baby.isAffectedBySkill(BUFF_CONTROL))
+			{
+				// searching for usable buffs
+				if ((_buffs != null) && !_buffs.isEmpty())
 				{
-					// searching for usable buffs
-					if ((_buffs != null) && !_buffs.isEmpty())
+					for (SkillHolder buff : _buffs)
 					{
-						for (SkillHolder i : _buffs)
+						skill = buff.getSkill();
+						if (_baby.isSkillDisabled(skill))
 						{
-							skill = i.getSkill();
-							if (_baby.isSkillDisabled(skill))
-							{
-								continue;
-							}
-							if (_baby.getCurrentMp() >= skill.getMpConsume())
-							{
-								_currentBuffs.add(skill);
-							}
+							continue;
 						}
-					}
-					
-					// buffs found, checking owner buffs
-					if (!_currentBuffs.isEmpty())
-					{
-						for (BuffInfo info : owner.getEffectList().getBuffs().values())
+						
+						if (_baby.getCurrentMp() < skill.getMpConsume())
 						{
-							final L2Skill currentSkill = info.getSkill();
-							// if buff does not need to be casted - remove it from list
-							for (L2Skill buff : _currentBuffs)
-							{
-								if ((currentSkill.getId() == buff.getId()) && (currentSkill.getLevel() >= buff.getLevel()))
-								{
-									_currentBuffs.remove(buff);
-								}
-								else
-								{
-									if (!buff.getAbnormalType().isNone() && (currentSkill.getAbnormalType() == buff.getAbnormalType()) && (currentSkill.getAbnormalLvl() >= buff.getAbnormalLvl()))
-									{
-										_currentBuffs.remove(buff);
-									}
-								}
-							}
-							// no more buffs in list
-							if (_currentBuffs.isEmpty())
-							{
-								break;
-							}
+							continue;
 						}
-						// buffs list ready, casting random
-						if (!_currentBuffs.isEmpty())
+						
+						final BuffInfo buffInfo = owner.getEffectList().getBuffInfoByAbnormalType(skill.getAbnormalType());
+						if ((buffInfo != null) && (skill.getAbnormalLvl() <= buffInfo.getSkill().getAbnormalLvl()))
 						{
-							castSkill(_currentBuffs.get(Rnd.get(_currentBuffs.size())));
-							_currentBuffs.clear();
-							return;
+							continue;
 						}
+						
+						_currentBuffs.add(skill);
 					}
 				}
 				
-				// buffs/heal not casted, trying recharge, if exist
-				if ((_recharge != null) && owner.isInCombat() // recharge casted only if owner in combat stance
-					&& ((owner.getCurrentMp() / owner.getMaxMp()) < 0.6) && (Rnd.get(100) <= 60))
+				if (!_currentBuffs.isEmpty())
 				{
-					skill = _recharge.getSkill();
-					if (!_baby.isSkillDisabled(skill) && (_baby.getCurrentMp() >= skill.getMpConsume()))
-					{
-						castSkill(skill);
-						return;
-					}
+					skill = _currentBuffs.get(Rnd.get(_currentBuffs.size()));
+					castSkill(skill);
+					_currentBuffs.clear();
+					return;
+				}
+			}
+			
+			// buffs/heal not casted, trying recharge, if exist recharge casted only if owner in combat stance.
+			if ((_recharge != null) && owner.isInCombat() && ((owner.getCurrentMp() / owner.getMaxMp()) < 0.6) && (Rnd.get(100) <= 60))
+			{
+				skill = _recharge.getSkill();
+				if (!_baby.isSkillDisabled(skill) && (_baby.getCurrentMp() >= skill.getMpConsume()))
+				{
+					castSkill(skill);
 				}
 			}
 		}