Advertisement
GOODPower

Untitled

May 28th, 2014
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.79 KB | None | 0 0
  1. package l2p.gameserver.model;
  2.  
  3. import gnu.trove.list.array.TIntArrayList;
  4. import gnu.trove.map.hash.TIntObjectHashMap;
  5. import gnu.trove.set.hash.TIntHashSet;
  6. import l2p.gameserver.skills.EffectType;
  7. import l2p.gameserver.skills.effects.EffectTemplate;
  8. import l2p.gameserver.skills.skillclasses.Transformation;
  9. import l2p.gameserver.stats.Stats;
  10. import l2p.gameserver.stats.funcs.FuncTemplate;
  11. import l2p.gameserver.Config;
  12. import org.apache.commons.lang3.ArrayUtils;
  13.  
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.List;
  17. import java.util.concurrent.CopyOnWriteArrayList;
  18. import java.util.concurrent.locks.Lock;
  19. import java.util.concurrent.locks.ReentrantLock;
  20.  
  21. public class EffectList
  22. {
  23.     public static final int NONE_SLOT_TYPE      =   -1;
  24.     public static final int BUFF_SLOT_TYPE      =   0;
  25.     public static final int MUSIC_SLOT_TYPE     =   1;
  26.     public static final int TRIGGER_SLOT_TYPE   =   2;
  27.     public static final int DEBUFF_SLOT_TYPE    =   3;
  28.     public static final int SELF_SLOT_TYPE      =   4;
  29.  
  30.     public static final int DEBUFF_LIMIT    =   8;
  31.     public static final int MUSIC_LIMIT     =   Config.DANCEANDSONGELIMIT;
  32.     public static final int TRIGGER_LIMIT   =   Config.TRIGGERELIMIT;
  33.     public static final int SELF_LIMIT  =   Config.SELFLIMIT;
  34.  
  35.     private Creature _actor;
  36.     private List<Effect> _effects;
  37.     private Lock lock = new ReentrantLock();
  38.  
  39.     public EffectList(Creature owner)
  40.     {
  41.         _actor = owner;
  42.     }
  43.  
  44.     /**
  45.      * Возвращает число эффектов соответствующее данному скиллу
  46.      */
  47.     public int getEffectsCountForSkill(int skill_id)
  48.     {
  49.         if(isEmpty())
  50.             return 0;
  51.  
  52.         int count = 0;
  53.  
  54.         for(Effect e : _effects)
  55.             if(e.getSkill().getId() == skill_id)
  56.                 count++;
  57.  
  58.         return count;
  59.     }
  60.  
  61.     public Effect getEffectByType(EffectType et)
  62.     {
  63.         if(isEmpty())
  64.             return null;
  65.  
  66.         for(Effect e : _effects)
  67.             if(e.getEffectType() == et)
  68.                 return e;
  69.  
  70.         return null;
  71.     }
  72.  
  73.     public List<Effect> getEffectsBySkill(Skill skill)
  74.     {
  75.         if(skill == null)
  76.             return null;
  77.         return getEffectsBySkillId(skill.getId());
  78.     }
  79.  
  80.     public List<Effect> getEffectsBySkillId(int skillId)
  81.     {
  82.         if(isEmpty())
  83.             return null;
  84.  
  85.         List<Effect> list = new ArrayList<Effect>(2);
  86.         for(Effect e : _effects)
  87.             if(e.getSkill().getId() == skillId)
  88.                 list.add(e);
  89.  
  90.         return list.isEmpty() ? null : list;
  91.     }
  92.  
  93.     public Effect getEffectByIndexAndType(int skillId, EffectType type)
  94.     {
  95.         if(isEmpty())
  96.             return null;
  97.         for(Effect e : _effects)
  98.             if(e.getSkill().getId() == skillId && e.getEffectType() == type)
  99.                 return e;
  100.  
  101.         return null;
  102.     }
  103.  
  104.     public Effect getEffectByStackType(String type)
  105.     {
  106.         if(isEmpty())
  107.             return null;
  108.         for(Effect e : _effects)
  109.             if(e.getStackType().equals(type))
  110.                 return e;
  111.  
  112.         return null;
  113.     }
  114.  
  115.     public boolean containEffectFromSkills(int[] skillIds)
  116.     {
  117.         if(isEmpty())
  118.             return false;
  119.  
  120.         int skillId;
  121.         for(Effect e : _effects)
  122.         {
  123.             skillId = e.getSkill().getId();
  124.             if(ArrayUtils.contains(skillIds, skillId))
  125.                 return true;
  126.         }
  127.  
  128.         return false;
  129.     }
  130.  
  131.     public List<Effect> getAllEffects()
  132.     {
  133.         if(isEmpty())
  134.             return Collections.emptyList();
  135.         return new ArrayList<Effect>(_effects);
  136.     }
  137.  
  138.     public boolean isEmpty()
  139.     {
  140.         return _effects == null || _effects.isEmpty();
  141.     }
  142.  
  143.     /**
  144.      * Возвращает первые эффекты для всех скиллов. Нужно для отображения не
  145.      * более чем 1 иконки для каждого скилла.
  146.      */
  147.     public Effect[] getAllFirstEffects()
  148.     {
  149.         if(isEmpty())
  150.             return Effect.EMPTY_L2EFFECT_ARRAY;
  151.  
  152.         TIntObjectHashMap<Effect> map = new TIntObjectHashMap<Effect>();
  153.  
  154.         for(Effect e : _effects)
  155.             map.put(e.getSkill().getId(), e);
  156.  
  157.         return map.values(new Effect[map.size()]);
  158.     }
  159.  
  160.     private void checkSlotLimit(Effect newEffect)
  161.     {
  162.         if(_effects == null)
  163.             return;
  164.  
  165.         int slotType = getSlotType(newEffect);
  166.         if(slotType == NONE_SLOT_TYPE)
  167.             return;
  168.  
  169.         int size = 0;
  170.         TIntArrayList skillIds = new TIntArrayList();
  171.         for(Effect e : _effects)
  172.             if(e.isInUse())
  173.             {
  174.                 if(e.getSkill().equals(newEffect.getSkill())) // мы уже имеем эффект от этого скилла
  175.                     return;
  176.  
  177.                 if(!skillIds.contains(e.getSkill().getId()))
  178.                 {
  179.                     int subType = getSlotType(e);
  180.                     if(subType == slotType)
  181.                     {
  182.                         size ++;
  183.                         skillIds.add(e.getSkill().getId());
  184.                     }
  185.                 }
  186.             }
  187.  
  188.         int limit = 0;
  189.         switch(slotType)
  190.         {
  191.             case BUFF_SLOT_TYPE:
  192.                 limit = _actor.getBuffLimit();
  193.                 break;
  194.             case MUSIC_SLOT_TYPE:
  195.                 limit = MUSIC_LIMIT;
  196.                 break;
  197.             case DEBUFF_SLOT_TYPE:
  198.                 limit = DEBUFF_LIMIT;
  199.                 break;
  200.             case TRIGGER_SLOT_TYPE:
  201.                 limit = TRIGGER_LIMIT;
  202.                 break;
  203.             case SELF_SLOT_TYPE:
  204.                 limit = SELF_LIMIT;
  205.                 break;
  206.         }
  207.  
  208.         if(size < limit)
  209.             return;
  210.  
  211.         int skillId = 0;
  212.         for(Effect e : _effects)
  213.             if(e.isInUse())
  214.             {
  215.                 if(getSlotType(e) == slotType)
  216.                 {
  217.                     skillId = e.getSkill().getId();
  218.                     break;
  219.                 }
  220.             }
  221.  
  222.         if(skillId != 0)
  223.             stopEffect(skillId);
  224.     }
  225.  
  226.     public static int getSlotType(Effect e)
  227.     {
  228.         if(e.getSkill().isPassive() || e.getSkill().isToggle() || e.getSkill() instanceof Transformation || e.getStackType().equals(EffectTemplate.HP_RECOVER_CAST) || e.getEffectType() == EffectType.Cubic)
  229.             return NONE_SLOT_TYPE;
  230.         else if(e.getSkill().isOffensive())
  231.             return DEBUFF_SLOT_TYPE;
  232.         else if(e.getSkill().isMusic())
  233.             return MUSIC_SLOT_TYPE;
  234.         else if(e.getSkill().isTrigger())
  235.             return TRIGGER_SLOT_TYPE;
  236.         else if (e.getSkill().getTargetType() == Skill.SkillTargetType.TARGET_SELF) {
  237.             return SELF_SLOT_TYPE;
  238.         }
  239.         else
  240.             return BUFF_SLOT_TYPE;
  241.     }
  242.  
  243.     public static boolean checkStackType(EffectTemplate ef1, EffectTemplate ef2)
  244.     {
  245.         if(!ef1._stackType.equals(EffectTemplate.NO_STACK) && ef1._stackType.equalsIgnoreCase(ef2._stackType))
  246.             return true;
  247.         if(!ef1._stackType.equals(EffectTemplate.NO_STACK) && ef1._stackType.equalsIgnoreCase(ef2._stackType2))
  248.             return true;
  249.         if(!ef1._stackType2.equals(EffectTemplate.NO_STACK) && ef1._stackType2.equalsIgnoreCase(ef2._stackType))
  250.             return true;
  251.         if(!ef1._stackType2.equals(EffectTemplate.NO_STACK) && ef1._stackType2.equalsIgnoreCase(ef2._stackType2))
  252.             return true;
  253.         return false;
  254.     }
  255.  
  256.     public void addEffect(Effect effect)
  257.     {
  258.         //TODO [G1ta0] затычка на статы повышающие HP/MP/CP
  259.         double hp = _actor.getCurrentHp();
  260.         double mp = _actor.getCurrentMp();
  261.         double cp = _actor.getCurrentCp();
  262.  
  263.         String stackType = effect.getStackType();
  264.         boolean add = false;
  265.  
  266.         lock.lock();
  267.         try
  268.         {
  269.             if(_effects == null)
  270.                 _effects = new CopyOnWriteArrayList<Effect>();
  271.  
  272.             if(stackType.equals(EffectTemplate.NO_STACK))
  273.                 // Удаляем такие же эффекты
  274.                 for(Effect e : _effects)
  275.                 {
  276.                     if(!e.isInUse())
  277.                         continue;
  278.  
  279.                     if(e.getStackType().equals(EffectTemplate.NO_STACK) && e.getSkill().getId() == effect.getSkill().getId() && e.getEffectType() == effect.getEffectType())
  280.                         // Если оставшаяся длительность старого эффекта больше чем длительность нового, то оставляем старый.
  281.                         if(effect.getTimeLeft() > e.getTimeLeft())
  282.                             e.exit();
  283.                         else
  284.                             return;
  285.                 }
  286.             else
  287.                 // Проверяем, нужно ли накладывать эффект, при совпадении StackType.
  288.                 // Новый эффект накладывается только в том случае, если у него больше StackOrder и больше длительность.
  289.                 // Если условия подходят - удаляем старый.
  290.                 for(Effect e : _effects)
  291.                 {
  292.                     if(!e.isInUse())
  293.                         continue;
  294.  
  295.                     if(!checkStackType(e.getTemplate(), effect.getTemplate()))
  296.                         continue;
  297.  
  298.                     if(e.getSkill().getId() == effect.getSkill().getId() && e.getEffectType() != effect.getEffectType())
  299.                         break;
  300.  
  301.                     // Эффекты со StackOrder == -1 заменить нельзя (например, Root).
  302.                     if(e.getStackOrder() == -1)
  303.                         return;
  304.  
  305.                     if(!e.maybeScheduleNext(effect))
  306.                         return;
  307.                 }
  308.  
  309.             // Проверяем на лимиты бафов/дебафов
  310.             checkSlotLimit(effect);
  311.  
  312.             // Добавляем новый эффект
  313.             if(add = _effects.add(effect))
  314.                 effect.setInUse(true);
  315.         }
  316.         finally
  317.         {
  318.             lock.unlock();
  319.         }
  320.  
  321.         if(!add)
  322.             return;
  323.  
  324.         // Запускаем эффект
  325.         effect.start();
  326.  
  327.         //TODO [G1ta0] затычка на статы повышающие HP/MP/CP
  328.         for(FuncTemplate ft : effect.getTemplate().getAttachedFuncs())
  329.             if(ft._stat == Stats.MAX_HP)
  330.                 _actor.setCurrentHp(hp, false);
  331.             else if(ft._stat == Stats.MAX_MP)
  332.                 _actor.setCurrentMp(mp);
  333.             else if(ft._stat == Stats.MAX_CP)
  334.                 _actor.setCurrentCp(cp);
  335.  
  336.         // Обновляем иконки
  337.         _actor.updateStats();
  338.         _actor.updateEffectIcons();
  339.     }
  340.  
  341.     /**
  342.      * Удаление эффекта из списка
  343.      *
  344.      * @param effect эффект для удаления
  345.      */
  346.     public void removeEffect(Effect effect)
  347.     {
  348.         if(effect == null)
  349.             return;
  350.  
  351.         boolean remove = false;
  352.  
  353.         lock.lock();
  354.         try
  355.         {
  356.             if(_effects == null)
  357.                 return;
  358.  
  359.             if(!(remove = _effects.remove(effect)))
  360.                 return;
  361.         }
  362.         finally
  363.         {
  364.             lock.unlock();
  365.         }
  366.  
  367.         if(!remove)
  368.             return;
  369.  
  370.         _actor.updateStats();
  371.         _actor.updateEffectIcons();
  372.     }
  373.  
  374.     public void stopAllEffects()
  375.     {
  376.         if(isEmpty())
  377.             return;
  378.  
  379.         lock.lock();
  380.         try
  381.         {
  382.             for(Effect e : _effects)
  383.                 e.exit();
  384.         }
  385.         finally
  386.         {
  387.             lock.unlock();
  388.         }
  389.  
  390.         _actor.updateStats();
  391.         _actor.updateEffectIcons();
  392.     }
  393.  
  394.     public void stopEffect(int skillId)
  395.     {
  396.         if(isEmpty())
  397.             return;
  398.  
  399.         for(Effect e : _effects)
  400.             if(e.getSkill().getId() == skillId)
  401.                 e.exit();
  402.     }
  403.  
  404.     public void stopEffect(Skill skill)
  405.     {
  406.         if(skill != null)
  407.             stopEffect(skill.getId());
  408.     }
  409.  
  410.     public void stopEffectByDisplayId(int skillId)
  411.     {
  412.         if(isEmpty())
  413.             return;
  414.  
  415.         for(Effect e : _effects)
  416.             if(e.getSkill().getDisplayId() == skillId)
  417.                 e.exit();
  418.     }
  419.  
  420.     public void stopEffects(EffectType type)
  421.     {
  422.         if(isEmpty())
  423.             return;
  424.  
  425.         for(Effect e : _effects)
  426.             if(e.getEffectType() == type)
  427.                 e.exit();
  428.     }
  429.  
  430.     /**
  431.      * Находит скиллы с указанным эффектом, и останавливает у этих скиллов все эффекты (не только указанный).
  432.      */
  433.     public void stopAllSkillEffects(EffectType type)
  434.     {
  435.         if(isEmpty())
  436.             return;
  437.  
  438.         TIntHashSet skillIds = new TIntHashSet();
  439.  
  440.         for(Effect e : _effects)
  441.             if(e.getEffectType() == type)
  442.                 skillIds.add(e.getSkill().getId());
  443.  
  444.         for(int skillId : skillIds.toArray())
  445.             stopEffect(skillId);
  446.     }
  447. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement