|
@@ -18,12 +18,10 @@
|
|
*/
|
|
*/
|
|
package com.l2jserver.gameserver.model.actor.instance;
|
|
package com.l2jserver.gameserver.model.actor.instance;
|
|
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
-import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
import java.util.concurrent.Future;
|
|
import java.util.concurrent.Future;
|
|
|
|
|
|
-import javolution.util.FastList;
|
|
|
|
-
|
|
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.ThreadPoolManager;
|
|
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
import com.l2jserver.gameserver.ai.CtrlIntention;
|
|
import com.l2jserver.gameserver.datatables.PetDataTable;
|
|
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.items.instance.L2ItemInstance;
|
|
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
|
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
|
import com.l2jserver.gameserver.model.skills.L2Skill;
|
|
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.SystemMessageId;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
|
import com.l2jserver.util.Rnd;
|
|
import com.l2jserver.util.Rnd;
|
|
@@ -73,7 +70,6 @@ public final class L2BabyPetInstance extends L2PetInstance
|
|
{
|
|
{
|
|
super.onSpawn();
|
|
super.onSpawn();
|
|
|
|
|
|
- L2Skill skill;
|
|
|
|
double healPower = 0;
|
|
double healPower = 0;
|
|
for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getId()).getAvailableSkills())
|
|
for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getId()).getAvailableSkills())
|
|
{
|
|
{
|
|
@@ -83,51 +79,55 @@ public final class L2BabyPetInstance extends L2PetInstance
|
|
{
|
|
{
|
|
continue;
|
|
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();
|
|
startCastTask();
|
|
@@ -173,9 +173,9 @@ public final class L2BabyPetInstance extends L2PetInstance
|
|
|
|
|
|
private final void startCastTask()
|
|
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
|
|
* @return {@code true} if this baby pet is in support mode, {@code false} otherwise
|
|
*/
|
|
*/
|
|
public boolean isInSupportMode()
|
|
public boolean isInSupportMode()
|
|
@@ -238,7 +239,7 @@ public final class L2BabyPetInstance extends L2PetInstance
|
|
private class CastTask implements Runnable
|
|
private class CastTask implements Runnable
|
|
{
|
|
{
|
|
private final L2BabyPetInstance _baby;
|
|
private final L2BabyPetInstance _baby;
|
|
- private final List<L2Skill> _currentBuffs = new CopyOnWriteArrayList<>();
|
|
|
|
|
|
+ private final List<L2Skill> _currentBuffs = new ArrayList<>();
|
|
|
|
|
|
public CastTask(L2BabyPetInstance baby)
|
|
public CastTask(L2BabyPetInstance baby)
|
|
{
|
|
{
|
|
@@ -248,114 +249,98 @@ public final class L2BabyPetInstance extends L2PetInstance
|
|
@Override
|
|
@Override
|
|
public void run()
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|