Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2014
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.22 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2004-2013 L2J Server
  3.  *
  4.  * This file is part of L2J Server.
  5.  *
  6.  * L2J Server is free software: you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation, either version 3 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * L2J Server is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18.  */
  19. package com.l2jserver.gameserver.model.actor.instance;
  20.  
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.concurrent.Future;
  24.  
  25. import javolution.util.FastList;
  26.  
  27. import com.l2jserver.gameserver.ThreadPoolManager;
  28. import com.l2jserver.gameserver.ai.CtrlIntention;
  29. import com.l2jserver.gameserver.datatables.PetDataTable;
  30. import com.l2jserver.gameserver.datatables.SkillTable;
  31. import com.l2jserver.gameserver.model.L2PetData.L2PetSkillLearn;
  32. import com.l2jserver.gameserver.model.actor.L2Character;
  33. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  34. import com.l2jserver.gameserver.model.effects.L2Effect;
  35. import com.l2jserver.gameserver.model.effects.L2EffectType;
  36. import com.l2jserver.gameserver.model.holders.SkillHolder;
  37. import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
  38. import com.l2jserver.gameserver.model.skills.L2Skill;
  39. import com.l2jserver.gameserver.network.SystemMessageId;
  40. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  41. import com.l2jserver.util.Rnd;
  42.  
  43. public final class L2BabyPetInstance extends L2PetInstance
  44. {
  45.     private static final int BUFF_CONTROL = 5771;
  46.     private static final int AWAKENING = 5753;
  47.    
  48.     protected List<SkillHolder> _buffs = null;
  49.     protected SkillHolder _majorHeal = null;
  50.     protected SkillHolder _minorHeal = null;
  51.     protected SkillHolder _recharge = null;
  52.    
  53.     private Future<?> _castTask;
  54.    
  55.     protected boolean _bufferMode = true;
  56.    
  57.     public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control)
  58.     {
  59.         super(objectId, template, owner, control);
  60.         setInstanceType(InstanceType.L2BabyPetInstance);
  61.     }
  62.    
  63.     public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control, byte level)
  64.     {
  65.         super(objectId, template, owner, control, level);
  66.         setInstanceType(InstanceType.L2BabyPetInstance);
  67.     }
  68.    
  69.     @Override
  70.     public void onSpawn()
  71.     {
  72.         super.onSpawn();
  73.        
  74.         L2Skill skill;
  75.         double healPower = 0;
  76.         for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getNpcId()).getAvailableSkills())
  77.         {
  78.             int id = psl.getSkillId();
  79.             int lvl = PetDataTable.getInstance().getPetData(getNpcId()).getAvailableLevel(id, getLevel());
  80.             if (lvl == 0)
  81.             {
  82.                 continue;
  83.             }
  84.             skill = SkillTable.getInstance().getInfo(id, lvl);
  85.             if (skill != null)
  86.             {
  87.                 if ((skill.getId() == BUFF_CONTROL) || (skill.getId() == AWAKENING))
  88.                 {
  89.                     continue;
  90.                 }
  91.                
  92.                 switch (skill.getSkillType())
  93.                 {
  94.                     case BUFF:
  95.                         if (_buffs == null)
  96.                         {
  97.                             _buffs = new FastList<>();
  98.                         }
  99.                         _buffs.add(new SkillHolder(skill));
  100.                         break;
  101.                     case DUMMY:
  102.                         if (skill.hasEffectType(L2EffectType.MANAHEAL_BY_LEVEL))
  103.                         {
  104.                             _recharge = new SkillHolder(skill);
  105.                         }
  106.                         else if (skill.hasEffectType(L2EffectType.HEAL))
  107.                         {
  108.                             if (healPower == 0)
  109.                             {
  110.                                 // set both heal types to the same skill
  111.                                 _majorHeal = new SkillHolder(skill);
  112.                                 _minorHeal = _majorHeal;
  113.                                 healPower = skill.getPower();
  114.                             }
  115.                             else
  116.                             {
  117.                                 // another heal skill found - search for most powerful
  118.                                 if (skill.getPower() > healPower)
  119.                                 {
  120.                                     _majorHeal = new SkillHolder(skill);
  121.                                 }
  122.                                 else
  123.                                 {
  124.                                     _minorHeal = new SkillHolder(skill);
  125.                                 }
  126.                             }
  127.                         }
  128.                         break;
  129.                 }
  130.             }
  131.         }
  132.         startCastTask();
  133.     }
  134.    
  135.     @Override
  136.     public boolean doDie(L2Character killer)
  137.     {
  138.         if (!super.doDie(killer))
  139.         {
  140.             return false;
  141.         }
  142.         stopCastTask();
  143.         abortCast();
  144.         return true;
  145.     }
  146.    
  147.     @Override
  148.     public synchronized void unSummon(L2PcInstance owner)
  149.     {
  150.         stopCastTask();
  151.         abortCast();
  152.         super.unSummon(owner);
  153.     }
  154.    
  155.     @Override
  156.     public void doRevive()
  157.     {
  158.         super.doRevive();
  159.         startCastTask();
  160.     }
  161.    
  162.     @Override
  163.     public void onDecay()
  164.     {
  165.         super.onDecay();
  166.        
  167.         if (_buffs != null)
  168.         {
  169.             _buffs.clear();
  170.         }
  171.     }
  172.    
  173.     private final void startCastTask()
  174.     {
  175.         if (((_majorHeal != null) || (_buffs != null) || (_recharge != null)) && (_castTask == null) && !isDead())
  176.         {
  177.             _castTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CastTask(this), 3000, 1000);
  178.         }
  179.     }
  180.    
  181.     @Override
  182.     public void switchMode()
  183.     {
  184.         _bufferMode = !_bufferMode;
  185.     }
  186.    
  187.     /**
  188.      * @return {@code true} if this baby pet is in support mode, {@code false} otherwise
  189.      */
  190.     public boolean isInSupportMode()
  191.     {
  192.         return _bufferMode;
  193.     }
  194.    
  195.     private final void stopCastTask()
  196.     {
  197.         if (_castTask != null)
  198.         {
  199.             _castTask.cancel(false);
  200.             _castTask = null;
  201.         }
  202.     }
  203.    
  204.     protected void castSkill(L2Skill skill)
  205.     {
  206.         // casting automatically stops any other action (such as autofollow or a move-to).
  207.         // We need to gather the necessary info to restore the previous state.
  208.         final boolean previousFollowStatus = getFollowStatus();
  209.        
  210.         // pet not following and owner outside cast range
  211.         if (!previousFollowStatus && !isInsideRadius(getOwner(), skill.getCastRange(), true, true))
  212.         {
  213.             return;
  214.         }
  215.        
  216.         setTarget(getOwner());
  217.         useMagic(skill, false, false);
  218.        
  219.         SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.PET_USES_S1);
  220.         msg.addSkillName(skill);
  221.         sendPacket(msg);
  222.        
  223.         // calling useMagic changes the follow status, if the babypet actually casts
  224.         // (as opposed to failing due some factors, such as too low MP, etc).
  225.         // if the status has actually been changed, revert it. Else, allow the pet to
  226.         // continue whatever it was trying to do.
  227.         // NOTE: This is important since the pet may have been told to attack a target.
  228.         // reverting the follow status will abort this attack! While aborting the attack
  229.         // in order to heal is natural, it is not acceptable to abort the attack on its own,
  230.         // merely because the timer stroke and without taking any other action...
  231.         if (previousFollowStatus != getFollowStatus())
  232.         {
  233.             setFollowStatus(previousFollowStatus);
  234.         }
  235.     }
  236.    
  237.     private class CastTask implements Runnable
  238.     {
  239.         private final L2BabyPetInstance _baby;
  240.         private final List<L2Skill> _currentBuffs = new FastList<>();
  241.        
  242.         public CastTask(L2BabyPetInstance baby)
  243.         {
  244.             _baby = baby;
  245.         }
  246.        
  247.         @Override
  248.         public void run()
  249.         {
  250.             L2PcInstance owner = _baby.getOwner();
  251.            
  252.             // if the owner is dead, merely wait for the owner to be resurrected
  253.             // if the pet is still casting from the previous iteration, allow the cast to complete...
  254.             if ((owner != null) && !owner.isDead() && !owner.isInvul() && !_baby.isCastingNow() && !_baby.isBetrayed() && !_baby.isMuted() && !_baby.isOutOfControl() && _bufferMode && (_baby.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
  255.             {
  256.                 L2Skill skill = null;
  257.                
  258.                 if (_majorHeal != null)
  259.                 {
  260.                     /**
  261.                      * 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.
  262.                      */
  263.                     final double hpPercent = owner.getCurrentHp() / owner.getMaxHp();
  264.                     final boolean isImprovedBaby = PetDataTable.isUpgradeBabyPetGroup(getNpcId());
  265.                     if ((isImprovedBaby && (hpPercent < 0.3)) || (!isImprovedBaby && (hpPercent < 0.15)))
  266.                     {
  267.                         skill = _majorHeal.getSkill();
  268.                         if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 75))
  269.                         {
  270.                             if (_baby.getCurrentMp() >= skill.getMpConsume())
  271.                             {
  272.                                 castSkill(skill);
  273.                                 return;
  274.                             }
  275.                         }
  276.                     }
  277.                     else if ((_majorHeal.getSkill() != _minorHeal.getSkill()) && ((isImprovedBaby && (hpPercent < 0.7)) || (!isImprovedBaby && (hpPercent < 0.8))))
  278.                     {
  279.                         // Cast _minorHeal only if it's different than _majorHeal, then pet has two heals available.
  280.                         skill = _minorHeal.getSkill();
  281.                         if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 25))
  282.                         {
  283.                             if (_baby.getCurrentMp() >= skill.getMpConsume())
  284.                             {
  285.                                 castSkill(skill);
  286.                                 return;
  287.                             }
  288.                         }
  289.                     }
  290.                 }
  291.                
  292.                 if (_baby.getFirstEffect(BUFF_CONTROL) == null) // Buff Control is not active
  293.                 {
  294.                     // searching for usable buffs
  295.                     if ((_buffs != null) && !_buffs.isEmpty())
  296.                     {
  297.                         for (SkillHolder i : _buffs)
  298.                         {
  299.                             skill = i.getSkill();
  300.                             if (_baby.isSkillDisabled(skill))
  301.                             {
  302.                                 continue;
  303.                             }
  304.                             if (_baby.getCurrentMp() >= skill.getMpConsume())
  305.                             {
  306.                                 _currentBuffs.add(skill);
  307.                             }
  308.                         }
  309.                     }
  310.                    
  311.                     // buffs found, checking owner buffs
  312.                     if (!_currentBuffs.isEmpty())
  313.                     {
  314.                         L2Effect[] effects = owner.getAllEffects();
  315.                         Iterator<L2Skill> iter;
  316.                         L2Skill currentSkill;
  317.                         for (L2Effect e : effects)
  318.                         {
  319.                             if (e == null)
  320.                             {
  321.                                 continue;
  322.                             }
  323.                            
  324.                             currentSkill = e.getSkill();
  325.                             // skipping debuffs, passives, toggles
  326.                             if (currentSkill.isDebuff() || currentSkill.isPassive() || currentSkill.isToggle())
  327.                             {
  328.                                 continue;
  329.                             }
  330.                            
  331.                             // if buff does not need to be casted - remove it from list
  332.                             iter = _currentBuffs.iterator();
  333.                             while (iter.hasNext())
  334.                             {
  335.                                 skill = iter.next();
  336.                                 if ((currentSkill.getId() == skill.getId()) && (currentSkill.getLevel() >= skill.getLevel()))
  337.                                 {
  338.                                     iter.remove();
  339.                                 }
  340.                                 else
  341.                                 {
  342.                                     // effect with same stacktype and greater or equal stackorder
  343.                                     if (skill.hasEffects() && !"none".equals(skill.getEffectTemplates()[0].abnormalType) && e.getAbnormalType().equals(skill.getEffectTemplates()[0].abnormalType) && (e.getAbnormalLvl() >= skill.getEffectTemplates()[0].abnormalLvl))
  344.                                     {
  345.                                         iter.remove();
  346.                                     }
  347.                                 }
  348.                             }
  349.                             // no more buffs in list
  350.                             if (_currentBuffs.isEmpty())
  351.                             {
  352.                                 break;
  353.                             }
  354.                         }
  355.                         // buffs list ready, casting random
  356.                         if (!_currentBuffs.isEmpty())
  357.                         {
  358.                             castSkill(_currentBuffs.get(Rnd.get(_currentBuffs.size())));
  359.                             _currentBuffs.clear();
  360.                             return;
  361.                         }
  362.                     }
  363.                 }
  364.                
  365.                 // buffs/heal not casted, trying recharge, if exist
  366.                 if ((_recharge != null) && owner.isInCombat() // recharge casted only if owner in combat stance
  367.                     && ((owner.getCurrentMp() / owner.getMaxMp()) < 0.6) && (Rnd.get(100) <= 60))
  368.                 {
  369.                     skill = _recharge.getSkill();
  370.                     if (!_baby.isSkillDisabled(skill) && (_baby.getCurrentMp() >= skill.getMpConsume()))
  371.                     {
  372.                         castSkill(skill);
  373.                         return;
  374.                     }
  375.                 }
  376.             }
  377.         }
  378.     }
  379. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement