Package lineage2.gameserver.model

Source Code of lineage2.gameserver.model.EffectList

/*
* 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 lineage2.gameserver.model;

import gnu.trove.list.array.TIntArrayList;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.set.hash.TIntHashSet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import lineage2.gameserver.skills.EffectType;
import lineage2.gameserver.skills.effects.EffectTemplate;
import lineage2.gameserver.skills.skillclasses.Transformation;
import lineage2.gameserver.stats.Stats;
import lineage2.gameserver.stats.funcs.FuncTemplate;

import org.apache.commons.lang3.ArrayUtils;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public class EffectList
{
  /**
   * Field NONE_SLOT_TYPE. (value is -1)
   */
  public static final int NONE_SLOT_TYPE = -1;
  /**
   * Field BUFF_SLOT_TYPE. (value is 0)
   */
  public static final int BUFF_SLOT_TYPE = 0;
  /**
   * Field MUSIC_SLOT_TYPE. (value is 1)
   */
  public static final int MUSIC_SLOT_TYPE = 1;
  /**
   * Field TRIGGER_SLOT_TYPE. (value is 2)
   */
  public static final int TRIGGER_SLOT_TYPE = 2;
  /**
   * Field DEBUFF_SLOT_TYPE. (value is 3)
   */
  public static final int DEBUFF_SLOT_TYPE = 3;
  /**
   * Field DEBUFF_LIMIT. (value is 8)
   */
  public static final int DEBUFF_LIMIT = 8;
  /**
   * Field MUSIC_LIMIT. (value is 12)
   */
  public static final int MUSIC_LIMIT = 12;
  /**
   * Field TRIGGER_LIMIT. (value is 12)
   */
  public static final int TRIGGER_LIMIT = 12;
  /**
   * Field _actor.
   */
  private final Creature _actor;
  /**
   * Field _effects.
   */
  private List<Effect> _effects;
  /**
   * Field lock.
   */
  private final Lock lock = new ReentrantLock();
 
  /**
   * Constructor for EffectList.
   * @param owner Creature
   */
  public EffectList(Creature owner)
  {
    _actor = owner;
  }
 
  /**
   * Method getEffectsCountForSkill.
   * @param skill_id int
   * @return int
   */
  public int getEffectsCountForSkill(int skill_id)
  {
    if (isEmpty())
    {
      return 0;
    }
    int count = 0;
    for (Effect e : _effects)
    {
      if (e.getSkill().getId() == skill_id)
      {
        count++;
      }
    }
    return count;
  }
 
  /**
   * Method getEffectByType.
   * @param et EffectType
   * @return Effect
   */
  public Effect getEffectByType(EffectType et)
  {
    if (isEmpty())
    {
      return null;
    }
    for (Effect e : _effects)
    {
      if (e.getEffectType() == et)
      {
        return e;
      }
    }
    return null;
  }
 
  /**
   * Method getEffectsBySkill.
   * @param skill Skill
   * @return List<Effect>
   */
  public List<Effect> getEffectsBySkill(Skill skill)
  {
    if (skill == null)
    {
      return null;
    }
    return getEffectsBySkillId(skill.getId());
  }
 
  /**
   * Method getEffectsBySkillId.
   * @param skillId int
   * @return List<Effect>
   */
  public List<Effect> getEffectsBySkillId(int skillId)
  {
    if (isEmpty())
    {
      return null;
    }
    List<Effect> list = new ArrayList<>(2);
    for (Effect e : _effects)
    {
      if (e.getSkill().getId() == skillId)
      {
        list.add(e);
      }
    }
    return list.isEmpty() ? null : list;
  }
 
  /**
   * Method getEffectByIndexAndType.
   * @param skillId int
   * @param type EffectType
   * @return Effect
   */
  public Effect getEffectByIndexAndType(int skillId, EffectType type)
  {
    if (isEmpty())
    {
      return null;
    }
    for (Effect e : _effects)
    {
      if ((e.getSkill().getId() == skillId) && (e.getEffectType() == type))
      {
        return e;
      }
    }
    return null;
  }
 
  /**
   * Method getEffectByStackType.
   * @param type String
   * @return Effect
   */
  public Effect getEffectByStackType(String type)
  {
    if (isEmpty())
    {
      return null;
    }
    for (Effect e : _effects)
    {
      if (e.getStackType().contains(type))
      {
        return e;
      }
    }
    return null;
  }
 
  /**
   * Method containEffectFromSkills.
   * @param skillIds int[]
   * @return boolean
   */
  public boolean containEffectFromSkills(int[] skillIds)
  {
    if (isEmpty())
    {
      return false;
    }
    int skillId;
    for (Effect e : _effects)
    {
      skillId = e.getSkill().getId();
      if (ArrayUtils.contains(skillIds, skillId))
      {
        return true;
      }
    }
    return false;
  }

  /**
   * Method containEffectFromSkill.
   * @param skillId integer
   * @param removeEffects boolean
   * @return boolean
   */
  public boolean containEffectFromSkillId(int skillId, boolean removeEffects)
  {
    boolean contain = false;
    if (isEmpty())
    {
      return contain;
    }
    for (Effect e : _effects)
    {
      if (skillId == e.getSkill().getId())
      {
        contain = true;
        e.exit();
      }
    }
    return contain;
  }

  /**
   * Method getAllEffects.
   * @return List<Effect>
   */
  public List<Effect> getAllEffects()
  {
    if (isEmpty())
    {
      return Collections.emptyList();
    }
    return new ArrayList<>(_effects);
  }
 
  /**
   * Method isEmpty.
   * @return boolean
   */
  public boolean isEmpty()
  {
    return (_effects == null) || _effects.isEmpty();
  }
 
  /**
   * Method getAllFirstEffects.
   * @return Effect[]
   */
  public Effect[] getAllFirstEffects()
  {
    if (isEmpty())
    {
      return Effect.EMPTY_L2EFFECT_ARRAY;
    }
    TIntObjectHashMap<Effect> map = new TIntObjectHashMap<>();
    for (Effect e : _effects)
    {
      map.put(e.getSkill().getId(), e);
    }
    return map.values(new Effect[map.size()]);
  }
 
  /**
   * Method checkSlotLimit.
   * @param newEffect Effect
   */
  private void checkSlotLimit(Effect newEffect)
  {
    if (_effects == null)
    {
      return;
    }
    int slotType = getSlotType(newEffect);
    if (slotType == NONE_SLOT_TYPE)
    {
      return;
    }
    int size = 0;
    TIntArrayList skillIds = new TIntArrayList();
    for (Effect e : _effects)
    {
      if (e.isInUse())
      {
        if (e.getSkill().equals(newEffect.getSkill()))
        {
          return;
        }
        if (!skillIds.contains(e.getSkill().getId()))
        {
          int subType = getSlotType(e);
          if (subType == slotType)
          {
            size++;
            skillIds.add(e.getSkill().getId());
          }
        }
      }
    }
    int limit = 0;
    switch (slotType)
    {
      case BUFF_SLOT_TYPE:
        limit = _actor.getBuffLimit();
        break;
      case MUSIC_SLOT_TYPE:
        limit = MUSIC_LIMIT;
        break;
      case DEBUFF_SLOT_TYPE:
        limit = DEBUFF_LIMIT;
        break;
      case TRIGGER_SLOT_TYPE:
        limit = TRIGGER_LIMIT;
        break;
    }
    if (size < limit)
    {
      return;
    }
    int skillId = 0;
    for (Effect e : _effects)
    {
      if (e.isInUse())
      {
        if (getSlotType(e) == slotType)
        {
          skillId = e.getSkill().getId();
          break;
        }
      }
    }
    if (skillId != 0)
    {
      stopEffect(skillId);
    }
  }
 
  /**
   * Method getSlotType.
   * @param e Effect
   * @return int
   */
  public static int getSlotType(Effect e)
  {
    if (e.getSkill().isPassive() || e.getSkill().isToggle() || (e.getSkill() instanceof Transformation) || e.getStackType().contains(EffectTemplate.HP_RECOVER_CAST) || (e.getEffectType() == EffectType.Cubic))
    {
      return NONE_SLOT_TYPE;
    }
    else if (e.getSkill().isOffensive())
    {
      return DEBUFF_SLOT_TYPE;
    }
    else if (e.getSkill().isMusic())
    {
      return MUSIC_SLOT_TYPE;
    }
    else if (e.getSkill().isTrigger())
    {
      return TRIGGER_SLOT_TYPE;
    }
    else
    {
      return BUFF_SLOT_TYPE;
    }
  }
 
  /**
   * Method checkStackType.
   * @param ef1 EffectTemplate
   * @param ef2 EffectTemplate
   * @return boolean
   */
  public static boolean checkStackType(EffectTemplate ef1, EffectTemplate ef2)
  {
    if (!ef1._stackTypes.contains(EffectTemplate.NO_STACK))
    {
      for (String arg : ef2._stackTypes)
      {
        if (ef1._stackTypes.contains(arg))
        {
          return true;
        }
      }
    }
    return false;
  }
 
  /**
   * Method addEffect.
   * @param effect Effect
   */
  public void addEffect(Effect effect)
  {
    double hp = _actor.getCurrentHp();
    double mp = _actor.getCurrentMp();
    double cp = _actor.getCurrentCp();
    boolean add = false;
    lock.lock();
    try
    {
      if (_effects == null)
      {
        _effects = new CopyOnWriteArrayList<>();
      }
      if (effect.getStackType().contains(EffectTemplate.NO_STACK))
      {
        for (Effect e : _effects)
        {
          if (!e.isInUse())
          {
            continue;
          }
          if (e.getStackType().contains(EffectTemplate.NO_STACK) && (e.getSkill().getId() == effect.getSkill().getId()) && (e.getEffectType() == effect.getEffectType()))
          {
            if (effect.getTimeLeft() > e.getTimeLeft())
            {
              e.exit();
            }
            else
            {
              return;
            }
          }
        }
      }
      else
      {
        for (Effect e : _effects)
        {
          if (!e.isInUse())
          {
            continue;
          }
          if (!checkStackType(e.getTemplate(), effect.getTemplate()))
          {
            continue;
          }
          if ((e.getSkill().getId() == effect.getSkill().getId()) && (e.getEffectType() != effect.getEffectType()))
          {
            break;
          }
          if (e.getStackOrder() == -1)
          {
            return;
          }
          if (!e.maybeScheduleNext(effect))
          {
            return;
          }
        }
      }
      checkSlotLimit(effect);
      add = _effects.add(effect);
      if (add)
      {
        effect.setInUse(true);
      }
    }
    finally
    {
      lock.unlock();
    }
    if (!add)
    {
      return;
    }
    effect.start();
    for (FuncTemplate ft : effect.getTemplate().getAttachedFuncs())
    {
      if (ft._stat == Stats.MAX_HP)
      {
        _actor.setCurrentHp(hp, false);
      }
      else if (ft._stat == Stats.MAX_MP)
      {
        _actor.setCurrentMp(mp);
      }
      else if (ft._stat == Stats.MAX_CP)
      {
        _actor.setCurrentCp(cp);
      }
    }
    _actor.updateStats();
    _actor.updateEffectIcons();
  }
 
  /**
   * Method removeEffect.
   * @param effect Effect
   */
  public void removeEffect(Effect effect)
  {
    if (effect == null)
    {
      return;
    }
    boolean remove = false;
    lock.lock();
    try
    {
      if (_effects == null)
      {
        return;
      }
      if (!((remove = _effects.remove(effect))))
      {
        return;
      }
    }
    finally
    {
      lock.unlock();
    }
    if (!remove)
    {
      return;
    }
    _actor.updateStats();
    _actor.updateEffectIcons();
  }
 
  /**
   * Method removeEffect.
   * @param skillId int
   */
  public void removeEffect(int skillId)
  {
    if (isEmpty())
    {
      return;
    }
    for (Effect e : _effects)
    {
      if (e.getSkill().getId() == skillId)
      {
        boolean remove = false;
        lock.lock();
        try
        {
          if (_effects == null)
          {
            return;
          }
          if (!((remove = _effects.remove(e))))
          {
            return;
          }
        }
        finally
        {
          lock.unlock();
        }
        if (!remove)
        {
          return;
        }
        _actor.updateStats();
        _actor.updateEffectIcons();
      }
    }
  }
 
  /**
   * Method stopAllEffects.
   */
  public void stopAllEffects()
  {
    if (isEmpty())
    {
      return;
    }
    lock.lock();
    try
    {
      for (Effect e : _effects)
      {
        e.exit();
      }
    }
    finally
    {
      lock.unlock();
    }
    _actor.updateStats();
    _actor.updateEffectIcons();
  }
 
  /**
   * Method stopEffect.
   * @param skillId int
   */
  public void stopEffect(int skillId)
  {
    if (isEmpty())
    {
      return;
    }
    for (Effect e : _effects)
    {
      if (e.getSkill().getId() == skillId)
      {
        e.exit();
      }
    }
  }
 
  /**
   * Method stopEffect.
   * @param skill Skill
   */
  public void stopEffect(Skill skill)
  {
    if (skill != null)
    {
      stopEffect(skill.getId());
    }
  }
 
  /**
   * Method stopEffectByDisplayId.
   * @param skillId int
   */
  public void stopEffectByDisplayId(int skillId)
  {
    if (isEmpty())
    {
      return;
    }
    for (Effect e : _effects)
    {
      if (e.getSkill().getDisplayId() == skillId)
      {
        e.exit();
      }
    }
  }
 
  /**
   * Method stopEffects.
   * @param type EffectType
   */
  public void stopEffects(EffectType type)
  {
    if (isEmpty())
    {
      return;
    }
    for (Effect e : _effects)
    {
      if (e.getEffectType() == type)
      {
        e.exit();
      }
    }
  }
 
  /**
   * Method stopAllSkillEffects.
   * @param type EffectType
   */
  public void stopAllSkillEffects(EffectType type)
  {
    if (isEmpty())
    {
      return;
    }
    TIntHashSet skillIds = new TIntHashSet();
    for (Effect e : _effects)
    {
      if (e.getEffectType() == type)
      {
        skillIds.add(e.getSkill().getId());
      }
    }
    for (int skillId : skillIds.toArray())
    {
      stopEffect(skillId);
    }
  }
}
TOP

Related Classes of lineage2.gameserver.model.EffectList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.