Package lineage2.gameserver.model

Source Code of lineage2.gameserver.model.Skill$AddedSkill

/*
* 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 java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import lineage2.commons.collections.LazyArrayList;
import lineage2.commons.geometry.Polygon;
import lineage2.commons.lang.ArrayUtils;
import lineage2.commons.threading.RunnableImpl;
import lineage2.commons.util.Rnd;
import lineage2.gameserver.Config;
import lineage2.gameserver.ThreadPoolManager;
import lineage2.gameserver.cache.Msg;
import lineage2.gameserver.geodata.GeoEngine;
import lineage2.gameserver.instancemanager.games.HandysBlockCheckerManager;
import lineage2.gameserver.instancemanager.games.HandysBlockCheckerManager.ArenaParticipantsHolder;
import lineage2.gameserver.model.Zone.ZoneType;
import lineage2.gameserver.model.base.BaseStats;
import lineage2.gameserver.model.base.ClassId;
import lineage2.gameserver.model.base.Element;
import lineage2.gameserver.model.base.SkillTrait;
import lineage2.gameserver.model.entity.events.GlobalEvent;
import lineage2.gameserver.model.instances.ChestInstance;
import lineage2.gameserver.model.instances.DecoyInstance;
import lineage2.gameserver.model.instances.FeedableBeastInstance;
import lineage2.gameserver.model.items.Inventory;
import lineage2.gameserver.model.items.ItemInstance;
import lineage2.gameserver.network.serverpackets.FlyToLocation.FlyType;
import lineage2.gameserver.network.serverpackets.SystemMessage;
import lineage2.gameserver.network.serverpackets.SystemMessage2;
import lineage2.gameserver.network.serverpackets.components.SystemMsg;
import lineage2.gameserver.skills.effects.EffectTemplate;
import lineage2.gameserver.skills.skillclasses.AIeffects;
import lineage2.gameserver.skills.skillclasses.Aggression;
import lineage2.gameserver.skills.skillclasses.Balance;
import lineage2.gameserver.skills.skillclasses.BeastFeed;
import lineage2.gameserver.skills.skillclasses.BuffCharger;
import lineage2.gameserver.skills.skillclasses.CPDam;
import lineage2.gameserver.skills.skillclasses.Call;
import lineage2.gameserver.skills.skillclasses.ChainHeal;
import lineage2.gameserver.skills.skillclasses.Charge;
import lineage2.gameserver.skills.skillclasses.ChargeSoul;
import lineage2.gameserver.skills.skillclasses.ClanGate;
import lineage2.gameserver.skills.skillclasses.CombatPointHeal;
import lineage2.gameserver.skills.skillclasses.Continuous;
import lineage2.gameserver.skills.skillclasses.Craft;
import lineage2.gameserver.skills.skillclasses.DeathPenalty;
import lineage2.gameserver.skills.skillclasses.Decoy;
import lineage2.gameserver.skills.skillclasses.Default;
import lineage2.gameserver.skills.skillclasses.DefuseTrap;
import lineage2.gameserver.skills.skillclasses.DeleteHate;
import lineage2.gameserver.skills.skillclasses.DeleteHateOfMe;
import lineage2.gameserver.skills.skillclasses.DestroySummon;
import lineage2.gameserver.skills.skillclasses.DetectTrap;
import lineage2.gameserver.skills.skillclasses.Disablers;
import lineage2.gameserver.skills.skillclasses.Drain;
import lineage2.gameserver.skills.skillclasses.DrainSoul;
import lineage2.gameserver.skills.skillclasses.EMDam;
import lineage2.gameserver.skills.skillclasses.EffectsFromSkills;
import lineage2.gameserver.skills.skillclasses.EnergyReplenish;
import lineage2.gameserver.skills.skillclasses.ExtractStone;
import lineage2.gameserver.skills.skillclasses.FishingSkill;
import lineage2.gameserver.skills.skillclasses.Harvesting;
import lineage2.gameserver.skills.skillclasses.Heal;
import lineage2.gameserver.skills.skillclasses.HealHpCp;
import lineage2.gameserver.skills.skillclasses.HealPercent;
import lineage2.gameserver.skills.skillclasses.HealWithCp;
import lineage2.gameserver.skills.skillclasses.ItemR;
import lineage2.gameserver.skills.skillclasses.KamaelWeaponExchange;
import lineage2.gameserver.skills.skillclasses.LethalShot;
import lineage2.gameserver.skills.skillclasses.MDam;
import lineage2.gameserver.skills.skillclasses.ManaDam;
import lineage2.gameserver.skills.skillclasses.ManaHeal;
import lineage2.gameserver.skills.skillclasses.ManaHealPercent;
import lineage2.gameserver.skills.skillclasses.NegateEffects;
import lineage2.gameserver.skills.skillclasses.NegateStats;
import lineage2.gameserver.skills.skillclasses.PDam;
import lineage2.gameserver.skills.skillclasses.PcBangPointsAdd;
import lineage2.gameserver.skills.skillclasses.PetSummon;
import lineage2.gameserver.skills.skillclasses.Plunder;
import lineage2.gameserver.skills.skillclasses.Recall;
import lineage2.gameserver.skills.skillclasses.ReelingPumping;
import lineage2.gameserver.skills.skillclasses.Refill;
import lineage2.gameserver.skills.skillclasses.Replace;
import lineage2.gameserver.skills.skillclasses.Restoration;
import lineage2.gameserver.skills.skillclasses.Resurrect;
import lineage2.gameserver.skills.skillclasses.Ride;
import lineage2.gameserver.skills.skillclasses.SPHeal;
import lineage2.gameserver.skills.skillclasses.ShiftAggression;
import lineage2.gameserver.skills.skillclasses.Sowing;
import lineage2.gameserver.skills.skillclasses.Spoil;
import lineage2.gameserver.skills.skillclasses.StealBuff;
import lineage2.gameserver.skills.skillclasses.Subjob;
import lineage2.gameserver.skills.skillclasses.SummonItem;
import lineage2.gameserver.skills.skillclasses.SummonMentor;
import lineage2.gameserver.skills.skillclasses.SummonServitor;
import lineage2.gameserver.skills.skillclasses.SummonSiegeFlag;
import lineage2.gameserver.skills.skillclasses.Sweep;
import lineage2.gameserver.skills.skillclasses.TakeCastle;
import lineage2.gameserver.skills.skillclasses.TakeFortress;
import lineage2.gameserver.skills.skillclasses.TameControl;
import lineage2.gameserver.skills.skillclasses.TeleportNpc;
import lineage2.gameserver.skills.skillclasses.Toggle;
import lineage2.gameserver.skills.skillclasses.Transformation;
import lineage2.gameserver.skills.skillclasses.Unlock;
import lineage2.gameserver.skills.skillclasses.VitalityHeal;
import lineage2.gameserver.stats.Env;
import lineage2.gameserver.stats.Formulas;
import lineage2.gameserver.stats.StatTemplate;
import lineage2.gameserver.stats.Stats;
import lineage2.gameserver.stats.conditions.Condition;
import lineage2.gameserver.stats.funcs.Func;
import lineage2.gameserver.stats.funcs.FuncTemplate;
import lineage2.gameserver.tables.SkillTable;
import lineage2.gameserver.templates.StatsSet;
import lineage2.gameserver.utils.Location;
import lineage2.gameserver.utils.PositionUtils;

import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public abstract class Skill extends StatTemplate implements Cloneable
{
  /**
   * @author Mobius
   */
  public static class AddedSkill
  {
    /**
     * Field EMPTY_ARRAY.
     */
    public static final AddedSkill[] EMPTY_ARRAY = new AddedSkill[0];
    /**
     * Field id.
     */
    public int id;
    /**
     * Field level.
     */
    public int level;
    /**
     * Field _skill.
     */
    private Skill _skill;
   
    /**
     * Constructor for AddedSkill.
     * @param id int
     * @param level int
     */
    public AddedSkill(int id, int level)
    {
      this.id = id;
      this.level = level;
    }
   
    /**
     * Method getSkill.
     * @return Skill
     */
    public Skill getSkill()
    {
      if (_skill == null)
      {
        _skill = SkillTable.getInstance().getInfo(id, level);
      }
      return _skill;
    }
  }
 
  /**
   * @author Mobius
   */
  public static enum NextAction
  {
    /**
     * Field ATTACK.
     */
    ATTACK,
    /**
     * Field CAST.
     */
    CAST,
    /**
     * Field DEFAULT.
     */
    DEFAULT,
    /**
     * Field MOVE.
     */
    MOVE,
    /**
     * Field NONE.
     */
    NONE
  }
 
  /**
   * @author Mobius
   */
  public static enum SkillOpType
  {
    /**
     * Field OP_ACTIVE.
     */
    OP_ACTIVE,
    /**
     * Field OP_PASSIVE.
     */
    OP_PASSIVE,
    /**
     * Field OP_TOGGLE.
     */
    OP_TOGGLE,
    /**
     * Field OP_ACTIVE_TOGGLE.
     */
    OP_ACTIVE_TOGGLE
  }
 
  /**
   * @author Mobius
   */
  public static enum Ternary
  {
    /**
     * Field TRUE.
     */
    TRUE,
    /**
     * Field FALSE.
     */
    FALSE,
    /**
     * Field DEFAULT.
     */
    DEFAULT
  }
 
  /**
   * @author Mobius
   */
  public static enum SkillMagicType
  {
    /**
     * Field PHYSIC.
     */
    PHYSIC,
    /**
     * Field MAGIC.
     */
    MAGIC,
    /**
     * Field SPECIAL.
     */
    SPECIAL,
    /**
     * Field MUSIC.
     */
    MUSIC
  }
 
  /**
   * @author Mobius
   */
  public static enum SkillTargetType
  {
    /**
     * Field TARGET_ALLY.
     */
    TARGET_ALLY,
    /**
     * Field TARGET_AREA.
     */
    TARGET_AREA,
    /**
     * Field TARGET_AREA_AIM_CORPSE.
     */
    TARGET_AREA_AIM_CORPSE,
    /**
     * Field TARGET_AURA.
     */
    TARGET_AURA,
    /**
     * Field TARGET_PET_AURA.
     */
    TARGET_PET_AURA,
    /**
     * Field TARGET_CHEST.
     */
    TARGET_CHEST,
    /**
     * Field TARGET_FEEDABLE_BEAST.
     */
    TARGET_FEEDABLE_BEAST,
    /**
     * Field TARGET_CLAN.
     */
    TARGET_CLAN,
    /**
     * Field TARGET_CLAN_ONLY.
     */
    TARGET_CLAN_ONLY,
    /**
     * Field TARGET_CORPSE.
     */
    TARGET_CORPSE,
    /**
     * Field TARGET_CORPSE_PLAYER.
     */
    TARGET_CORPSE_PLAYER,
    /**
     * Field TARGET_ENEMY_PET.
     */
    TARGET_ENEMY_PET,
    /**
     * Field TARGET_ENEMY_SUMMON.
     */
    TARGET_ENEMY_SUMMON,
    /**
     * Field TARGET_ENEMY_SERVITOR.
     */
    TARGET_ENEMY_SERVITOR,
    /**
     * Field TARGET_EVENT.
     */
    TARGET_EVENT,
    /**
     * Field TARGET_FLAGPOLE.
     */
    TARGET_FLAGPOLE,
    /**
     * Field TARGET_COMMCHANNEL.
     */
    TARGET_COMMCHANNEL,
    /**
     * Field TARGET_HOLY.
     */
    TARGET_HOLY,
    /**
     * Field TARGET_ITEM.
     */
    TARGET_ITEM,
    /**
     * Field TARGET_MENTEE.
     */
    TARGET_MENTEE,
    /**
     * Field TARGET_MULTIFACE.
     */
    TARGET_MULTIFACE,
    /**
     * Field TARGET_MULTIFACE_AURA.
     */
    TARGET_MULTIFACE_AURA,
    /**
     * Field TARGET_TUNNEL.
     */
    TARGET_TUNNEL,
    /**
     * Field TARGET_NONE.
     */
    TARGET_NONE,
    /**
     * Field TARGET_ONE.
     */
    TARGET_ONE,
    /**
     * Field TARGET_ONE_PLAYER.
     */
    TARGET_ONE_PLAYER,
    /**
     * Field TARGET_OWNER.
     */
    TARGET_OWNER,
    /**
     * Field TARGET_PARTY.
     */
    TARGET_PARTY,
    /**
     * Field TARGET_PARTY_ONE.
     */
    TARGET_PARTY_ONE,
    /**
     * Field TARGET_PARTY_WITHOUT_ME.
     */
    TARGET_PARTY_WITHOUT_ME,
    /**
     * Field TARGET_PET.
     */
    TARGET_PET,
    /**
     * Field TARGET_SUMMON.
     */
    TARGET_SUMMON,
    /**
     * Field TARGET_SELF.
     */
    TARGET_SELF,
    /**
     * Field TARGET_SIEGE.
     */
    TARGET_SIEGE,
    /**
     * Field TARGET_UNLOCKABLE.
     */
    TARGET_UNLOCKABLE,
    /**
     * Field TARGET_SUMMON_AURA.
     */
    TARGET_SUMMON_AURA,
    /**
     * Field TARGET_SUMMON_AURA_AND_ME.
     */
    TARGET_SUMMON_AURA_AND_ME,
    /**
     * Field TARGET_GROUND.
     */
    TARGET_GROUND
  }
 
  /**
   * @author Mobius
   */
  public static enum SkillType
  {
    /**
     * Field AGGRESSION.
     */
    AGGRESSION(Aggression.class),
    /**
     * Field AIEFFECTS.
     */
    AIEFFECTS(AIeffects.class),
    /**
     * Field BALANCE.
     */
    BALANCE(Balance.class),
    /**
     * Field BEAST_FEED.
     */
    BEAST_FEED(BeastFeed.class),
    /**
     * Field BLEED.
     */
    BLEED(Continuous.class),
    /**
     * Field BUFF.
     */
    BUFF(Continuous.class),
    /**
     * Field BUFF_CHARGER.
     */
    BUFF_CHARGER(BuffCharger.class),
    /**
     * Field CALL.
     */
    CALL(Call.class),
    /**
     * Field CHAIN_HEAL.
     */
    CHAIN_HEAL(ChainHeal.class),
    /**
     * Field CHARGE.
     */
    CHARGE(Charge.class),
    /**
     * Field CHARGE_SOUL.
     */
    CHARGE_SOUL(ChargeSoul.class),
    /**
     * Field CLAN_GATE.
     */
    CLAN_GATE(ClanGate.class),
    /**
     * Field COMBATPOINTHEAL.
     */
    COMBATPOINTHEAL(CombatPointHeal.class),
    /**
     * Field CONT.
     */
    CONT(Toggle.class),
    /**
     * Field CPDAM.
     */
    CPDAM(CPDam.class),
    /**
     * Field CPHOT.
     */
    CPHOT(Continuous.class),
    /**
     * Field CRAFT.
     */
    CRAFT(Craft.class),
    /**
     * Field DEATH_PENALTY.
     */
    DEATH_PENALTY(DeathPenalty.class),
    /**
     * Field DECOY.
     */
    DECOY(Decoy.class),
    /**
     * Field DEBUFF.
     */
    DEBUFF(Continuous.class),
    /**
     * Field DELETE_HATE.
     */
    DELETE_HATE(DeleteHate.class),
    /**
     * Field DELETE_HATE_OF_ME.
     */
    DELETE_HATE_OF_ME(DeleteHateOfMe.class),
    /**
     * Field DESTROY_SUMMON.
     */
    DESTROY_SUMMON(DestroySummon.class),
    /**
     * Field DEFUSE_TRAP.
     */
    DEFUSE_TRAP(DefuseTrap.class),
    /**
     * Field DETECT_TRAP.
     */
    DETECT_TRAP(DetectTrap.class),
    /**
     * Field DISCORD.
     */
    DISCORD(Continuous.class),
    /**
     * Field DOT.
     */
    DOT(Continuous.class),
    /**
     * Field DRAIN.
     */
    DRAIN(Drain.class),
    /**
     * Field DRAIN_SOUL.
     */
    DRAIN_SOUL(DrainSoul.class),
    /**
     * Field EFFECT.
     */
    EFFECT(lineage2.gameserver.skills.skillclasses.Effect.class),
    /**
     * Field EFFECTS_FROM_SKILLS.
     */
    EFFECTS_FROM_SKILLS(EffectsFromSkills.class),
    /**
     * Field ENERGY_REPLENISH.
     */
    ENERGY_REPLENISH(EnergyReplenish.class),
    /**
     * Field ENCHANT_ARMOR.
     */
    ENCHANT_ARMOR,
    /**
     * Field ENCHANT_WEAPON.
     */
    ENCHANT_WEAPON,
    /**
     * Field EXTRACT_STONE.
     */
    EXTRACT_STONE(ExtractStone.class),
    /**
     * Field FEED_PET.
     */
    FEED_PET,
    /**
     * Field FISHING.
     */
    FISHING(FishingSkill.class),
    /**
     * Field HARDCODED.
     */
    HARDCODED(lineage2.gameserver.skills.skillclasses.Effect.class),
    /**
     * Field HARVESTING.
     */
    HARVESTING(Harvesting.class),
    /**
     * Field HEAL.
     */
    HEAL(Heal.class),
    /**
     * Field HEAL_WITH_CP.
     */
    HEAL_WITH_CP(HealWithCp.class),
    /**
     * Field HEAL_HP_CP.
     */
    HEAL_HP_CP(HealHpCp.class),
    /**
     * Field HEAL_PERCENT.
     */
    HEAL_PERCENT(HealPercent.class),
    /**
     * Field HOT.
     */
    HOT(Continuous.class),
    /**
     * Field KAMAEL_WEAPON_EXCHANGE.
     */
    KAMAEL_WEAPON_EXCHANGE(KamaelWeaponExchange.class),
    /**
     * Field ITEM_R.
     */
    ITEM_R(ItemR.class),
    /**
     * Field LETHAL_SHOT.
     */
    LETHAL_SHOT(LethalShot.class),
    /**
     * Field LUCK.
     */
    LUCK,
    /**
     * Field MANADAM.
     */
    MANADAM(ManaDam.class),
    /**
     * Field MANAHEAL.
     */
    MANAHEAL(ManaHeal.class),
    /**
     * Field MANAHEAL_PERCENT.
     */
    MANAHEAL_PERCENT(ManaHealPercent.class),
    /**
     * Field MDAM.
     */
    MDAM(MDam.class),
    /**
     * Field EMDAM.
     */
    EMDAM(EMDam.class),
    /**
     * Field MDOT.
     */
    MDOT(Continuous.class),
    /**
     * Field MPHOT.
     */
    MPHOT(Continuous.class),
    /**
     * Field MUTE.
     */
    MUTE(Disablers.class),
    /**
     * Field NEGATE_EFFECTS.
     */
    NEGATE_EFFECTS(NegateEffects.class),
    /**
     * Field NEGATE_STATS.
     */
    NEGATE_STATS(NegateStats.class),
    /**
     * Field ADD_PC_BANG.
     */
    ADD_PC_BANG(PcBangPointsAdd.class),
    /**
     * Field NOTDONE.
     */
    NOTDONE,
    /**
     * Field NOTUSED.
     */
    NOTUSED,
    /**
     * Field PARALYZE.
     */
    PARALYZE(Disablers.class),
    /**
     * Field PASSIVE.
     */
    PASSIVE,
    /**
     * Field PDAM.
     */
    PDAM(PDam.class),
    /**
     * Field PET_SUMMON.
     */
    PET_SUMMON(PetSummon.class),
    /**
     * Field POISON.
     */
    POISON(Continuous.class),
    /**
     * Field PUMPING.
     */
    PUMPING(ReelingPumping.class),
    /**
     * Field RECALL.
     */
    RECALL(Recall.class),
    /**
     * Field REELING.
     */
    REELING(ReelingPumping.class),
    /**
     * Field REFILL.
     */
    REFILL(Refill.class),
    /**
     * Field RESURRECT.
     */
    RESURRECT(Resurrect.class),
    /**
     * Field RESTORE_ITEM.
     */
    RESTORE_ITEM(lineage2.gameserver.skills.skillclasses.Effect.class),
    /**
     * Field REPLACE.
     */
    REPLACE(Replace.class),
    /**
     * Field RIDE.
     */
    RIDE(Ride.class),
    /**
     * Field ROOT.
     */
    ROOT(Disablers.class),
    /**
     * Field SHIFT_AGGRESSION.
     */
    SHIFT_AGGRESSION(ShiftAggression.class),
    /**
     * Field SLEEP.
     */
    SLEEP(Disablers.class),
    /**
     * Field SOULSHOT.
     */
    SOULSHOT,
    /**
     * Field SOWING.
     */
    SOWING(Sowing.class),
    /**
     * Field SPHEAL.
     */
    SPHEAL(SPHeal.class),
    /**
     * Field SPIRITSHOT.
     */
    SPIRITSHOT,
    /**
     * Field SPOIL.
     */
    SPOIL(Spoil.class),
    /**
     * Field STEAL_BUFF.
     */
    STEAL_BUFF(StealBuff.class),
    /**
     * Field STUN.
     */
    STUN(Disablers.class),
    /**
     * Field SUB_JOB.
     */
    SUB_JOB(Subjob.class),
    /**
     * Field SUMMON.
     */
    SUMMON(SummonServitor.class),
    /**
     * Field SUMMON_FLAG.
     */
    SUMMON_FLAG(SummonSiegeFlag.class),
    /**
     * Field SUMMON_ITEM.
     */
    SUMMON_ITEM(SummonItem.class),
    RESTORATION(Restoration.class),
    /**
     * Field SUMMON_MENTOR.
     */
    SUMMON_MENTOR(SummonMentor.class),
    /**
     * Field SWEEP.
     */
    SWEEP(Sweep.class),
    /**
     * Field TAKECASTLE.
     */
    TAKECASTLE(TakeCastle.class),
    /**
     * Field TAKEFORTRESS.
     */
    TAKEFORTRESS(TakeFortress.class),
    /**
     * Field TAMECONTROL.
     */
    TAMECONTROL(TameControl.class),
    /**
     * Field TELEPORT_NPC.
     */
    TELEPORT_NPC(TeleportNpc.class),
    /**
     * Field TRANSFORMATION.
     */
    TRANSFORMATION(Transformation.class),
    /**
     * Field UNLOCK.
     */
    UNLOCK(Unlock.class),
    /**
     * Field WATCHER_GAZE.
     */
    WATCHER_GAZE(Continuous.class),
    /**
     * Field VITALITY_HEAL.
     */
    VITALITY_HEAL(VitalityHeal.class),
    /**
     * Field SWEEP.
     */
    PLUNDER(Plunder.class);
    /**
     * Field clazz.
     */
    private final Class<? extends Skill> clazz;
   
    /**
     * Constructor for SkillType.
     */
    private SkillType()
    {
      clazz = Default.class;
    }
   
    /**
     * Constructor for SkillType.
     * @param clazz Class<? extends Skill>
     */
    private SkillType(Class<? extends Skill> clazz)
    {
      this.clazz = clazz;
    }
   
    /**
     * Method makeSkill.
     * @param set StatsSet
     * @return Skill
     */
    public Skill makeSkill(StatsSet set)
    {
      try
      {
        Constructor<? extends Skill> c = clazz.getConstructor(StatsSet.class);
        return c.newInstance(set);
      }
      catch (Exception e)
      {
        _log.error("", e);
        throw new RuntimeException(e);
      }
    }
   
    /**
     * Method isPvM.
     * @return boolean
     */
    public final boolean isPvM()
    {
      switch (this)
      {
        case DISCORD:
          return true;
        default:
          return false;
      }
    }
   
    /**
     * Method isAI.
     * @return boolean
     */
    public boolean isAI()
    {
      switch (this)
      {
        case AGGRESSION:
        case AIEFFECTS:
        case SOWING:
        case DELETE_HATE:
        case DELETE_HATE_OF_ME:
          return true;
        default:
          return false;
      }
    }
   
    /**
     * Method isPvpSkill.
     * @return boolean
     */
    public final boolean isPvpSkill()
    {
      switch (this)
      {
        case BLEED:
        case AGGRESSION:
        case DEBUFF:
        case DOT:
        case MDOT:
        case MUTE:
        case PARALYZE:
        case POISON:
        case ROOT:
        case SLEEP:
        case MANADAM:
        case DESTROY_SUMMON:
        case NEGATE_STATS:
        case NEGATE_EFFECTS:
        case STEAL_BUFF:
        case DELETE_HATE:
        case DELETE_HATE_OF_ME:
          return true;
        default:
          return false;
      }
    }
   
    /**
     * Method isOffensive.
     * @return boolean
     */
    public boolean isOffensive()
    {
      switch (this)
      {
        case AGGRESSION:
        case AIEFFECTS:
        case BLEED:
        case DEBUFF:
        case DOT:
        case DRAIN:
        case DRAIN_SOUL:
        case LETHAL_SHOT:
        case MANADAM:
        case MDAM:
        case MDOT:
        case MUTE:
        case PARALYZE:
        case PDAM:
        case CPDAM:
        case POISON:
        case ROOT:
        case SLEEP:
        case SOULSHOT:
        case SPIRITSHOT:
        case SPOIL:
        case STUN:
        case SWEEP:
        case HARVESTING:
        case TELEPORT_NPC:
        case SOWING:
        case DELETE_HATE:
        case DELETE_HATE_OF_ME:
        case DESTROY_SUMMON:
        case STEAL_BUFF:
        case DISCORD:
        case PLUNDER:
          return true;
        default:
          return false;
      }
    }
  }
 
  /**
   * Field _log.
   */
  static final Logger _log = LoggerFactory.getLogger(Skill.class);
  /**
   * Field EMPTY_ARRAY.
   */
  public static final Skill[] EMPTY_ARRAY = new Skill[0];
  /**
   * Field _effectTemplates.
   */
  protected EffectTemplate[] _effectTemplates = EffectTemplate.EMPTY_ARRAY;
  /**
   * Field _teachers.
   */
  protected List<Integer> _teachers;
  /**
   * Field _canLearn.
   */
  protected List<ClassId> _canLearn;
  /**
   * Field _addedSkills.
   */
  protected AddedSkill[] _addedSkills = AddedSkill.EMPTY_ARRAY;
  /**
   * Field _itemConsume.
   */
  protected final int[] _itemConsume;
  /**
   * Field _itemConsumeId.
   */
  protected final int[] _itemConsumeId;
  /**
   * Field _relationSkillsId.
   */
  protected final int[] _relationSkillsId;
  /**
   * Field _referenceItemId.
   */
  protected final int _referenceItemId;
  /**
   * Field _referenceItemMpConsume.
   */
  protected final int _referenceItemMpConsume;
  /**
   * Field SKILL_CRAFTING. (value is 172)
   */
  public static final int SKILL_CRAFTING = 172;
  /**
   * Field SKILL_POLEARM_MASTERY. (value is 216)
   */
  public static final int SKILL_POLEARM_MASTERY = 216;
  /**
   * Field SKILL_CRYSTALLIZE. (value is 248)
   */
  public static final int SKILL_CRYSTALLIZE = 248;
  /**
   * Field SKILL_WEAPON_MAGIC_MASTERY1. (value is 249)
   */
  public static final int SKILL_WEAPON_MAGIC_MASTERY1 = 249;
  /**
   * Field SKILL_WEAPON_MAGIC_MASTERY2. (value is 250)
   */
  public static final int SKILL_WEAPON_MAGIC_MASTERY2 = 250;
  /**
   * Field SKILL_BLINDING_BLOW. (value is 321)
   */
  public static final int SKILL_BLINDING_BLOW = 321;
  /**
   * Field SKILL_STRIDER_ASSAULT. (value is 325)
   */
  public static final int SKILL_STRIDER_ASSAULT = 325;
  /**
   * Field SKILL_WYVERN_AEGIS. (value is 327)
   */
  public static final int SKILL_WYVERN_AEGIS = 327;
  /**
   * Field SKILL_BLUFF. (value is 358)
   */
  public static final int SKILL_BLUFF = 358;
  /**
   * Field SKILL_HEROIC_MIRACLE. (value is 395)
   */
  public static final int SKILL_HEROIC_MIRACLE = 395;
  /**
   * Field SKILL_HEROIC_BERSERKER. (value is 396)
   */
  public static final int SKILL_HEROIC_BERSERKER = 396;
  /**
   * Field SKILL_SOUL_MASTERY. (value is 467)
   */
  public static final int SKILL_SOUL_MASTERY = 467;
  /**
   * Field SKILL_TRANSFORM_DISPEL. (value is 619)
   */
  public static final int SKILL_TRANSFORM_DISPEL = 619;
  /**
   * Field SKILL_FINAL_FLYING_FORM. (value is 840)
   */
  public static final int SKILL_FINAL_FLYING_FORM = 840;
  /**
   * Field SKILL_AURA_BIRD_FALCON. (value is 841)
   */
  public static final int SKILL_AURA_BIRD_FALCON = 841;
  /**
   * Field SKILL_AURA_BIRD_OWL. (value is 842)
   */
  public static final int SKILL_AURA_BIRD_OWL = 842;
  /**
   * Field SKILL_DETECTION. (value is 933)
   */
  public static final int SKILL_DETECTION = 933;
  /**
   * Field SKILL_RECHARGE. (value is 1013)
   */
  public static final int SKILL_RECHARGE = 1013;
  /**
   * Field SKILL_TRANSFER_PAIN. (value is 1262)
   */
  public static final int SKILL_TRANSFER_PAIN = 1262;
  /**
   * Field SKILL_FISHING_MASTERY. (value is 1315)
   */
  public static final int SKILL_FISHING_MASTERY = 1315;
  /**
   * Field SKILL_NOBLESSE_BLESSING. (value is 1323)
   */
  public static final int SKILL_NOBLESSE_BLESSING = 1323;
  /**
   * Field SKILL_SUMMON_CP_POTION. (value is 1324)
   */
  public static final int SKILL_SUMMON_CP_POTION = 1324;
  /**
   * Field SKILL_FORTUNE_OF_NOBLESSE. (value is 1325)
   */
  public static final int SKILL_FORTUNE_OF_NOBLESSE = 1325;
  /**
   * Field SKILL_HARMONY_OF_NOBLESSE. (value is 1326)
   */
  public static final int SKILL_HARMONY_OF_NOBLESSE = 1326;
  /**
   * Field SKILL_SYMPHONY_OF_NOBLESSE. (value is 1327)
   */
  public static final int SKILL_SYMPHONY_OF_NOBLESSE = 1327;
  /**
   * Field SKILL_HEROIC_VALOR. (value is 1374)
   */
  public static final int SKILL_HEROIC_VALOR = 1374;
  /**
   * Field SKILL_HEROIC_GRANDEUR. (value is 1375)
   */
  public static final int SKILL_HEROIC_GRANDEUR = 1375;
  /**
   * Field SKILL_HEROIC_DREAD. (value is 1376)
   */
  public static final int SKILL_HEROIC_DREAD = 1376;
  /**
   * Field SKILL_MYSTIC_IMMUNITY. (value is 1411)
   */
  public static final int SKILL_MYSTIC_IMMUNITY = 1411;
  /**
   * Field SKILL_RAID_BLESSING. (value is 2168)
   */
  public static final int SKILL_RAID_BLESSING = 2168;
  /**
   * Field SKILL_HINDER_STRIDER. (value is 4258)
   */
  public static final int SKILL_HINDER_STRIDER = 4258;
  /**
   * Field SKILL_WYVERN_BREATH. (value is 4289)
   */
  public static final int SKILL_WYVERN_BREATH = 4289;
  /**
   * Field SKILL_RAID_CURSE. (value is 4515)
   */
  public static final int SKILL_RAID_CURSE = 4515;
  /**
   * Field SKILL_CHARM_OF_COURAGE. (value is 5041)
   */
  public static final int SKILL_CHARM_OF_COURAGE = 5041;
  /**
   * Field SKILL_EVENT_TIMER. (value is 5239)
   */
  public static final int SKILL_EVENT_TIMER = 5239;
  /**
   * Field SKILL_BATTLEFIELD_DEATH_SYNDROME. (value is 5660)
   */
  public static final int SKILL_BATTLEFIELD_DEATH_SYNDROME = 5660;
  /**
   * Field SKILL_SERVITOR_SHARE. (value is 1557)
   */
  public static final int SKILL_SERVITOR_SHARE = 1557;
  /**
   * Field SKILL_TRUE_FIRE. (value is 11007)
   */
  public static final int SKILL_TRUE_FIRE = 11007;
  /**
   * Field SKILL_TRUE_WATER. (value is 11008)
   */
  public static final int SKILL_TRUE_WATER = 11008;
  /**
   * Field SKILL_TRUE_WIND. (value is 11009)
   */
  public static final int SKILL_TRUE_WIND = 11009;
  /**
   * Field SKILL_TRUE_EARTH. (value is 11010)
   */
  public static final int SKILL_TRUE_EARTH = 11010;
  /**
   * Field SKILL_DUAL_CAST. (value is 11068)
   */
  public static final int SKILL_DUAL_CAST = 11068;
  /**
   * Field _isAuraSkill.
   */
  protected boolean _isAuraSkill;
  /**
   * Field _isAlterSkill.
   */
  protected boolean _isAlterSkill;
  /**
   * Field _isAltUse.
   */
  protected boolean _isAltUse;
  /**
   * Field _isBehind.
   */
  protected boolean _isBehind;
  /**
   * Field _scopeAngle.
   */
  protected int _scopeAngle;
  /**
   * Field _maxHitCancelCount.
   */
  protected int _maxHitCancelCount;
  /**
   * Field _isCancelable.
   */
  protected boolean _isCancelable;
  /**
   * Field _isCorpse.
   */
  protected boolean _isCorpse;
  /**
   * Field _isCommon.
   */
  protected boolean _isCommon;
  /**
   * Field _castOverStun.
   */
  protected boolean _castOverStun;
  /**
   * Field _isItemHandler.
   */
  protected boolean _isItemHandler;
  /**
   * Field _isOffensive.
   */
  protected boolean _isOffensive;
  /**
   * Field _isPvpSkill.
   */
  protected boolean _isPvpSkill;
  /**
   * Field _isNotUsedByAI.
   */
  protected boolean _isNotUsedByAI;
  /**
   * Field _isFishingSkill.
   */
  protected boolean _isFishingSkill;
  /**
   * Field _isPvm.
   */
  protected boolean _isPvm;
  /**
   * Field _isForceUse.
   */
  protected boolean _isForceUse;
  /**
   * Field _isNewbie.
   */
  protected boolean _isNewbie;
  /**
   * Field _isPreservedOnDeath.
   */
  protected boolean _isPreservedOnDeath;
  /**
   * Field _isHeroic.
   */
  protected boolean _isHeroic;
  /**
   * Field _isSaveable.
   */
  protected boolean _isSaveable;
  /**
   * Field _isSkillTimePermanent.
   */
  protected boolean _isSkillTimePermanent;
  /**
   * Field _isReuseDelayPermanent.
   */
  protected boolean _isReuseDelayPermanent;
  /**
   * Field _isHealDamageSkill.
   */
  protected boolean _isHealDamageSkill = false;
  /**
   * Field _lakcisHealStance.
   */
  protected boolean _skillHealStance = false;
  /**
   * Field _isReflectable.
   */
  protected boolean _isReflectable;
  /**
   * Field _isSuicideAttack.
   */
  protected boolean _isSuicideAttack;
  /**
   * Field _isShieldignore.
   */
  protected boolean _isShieldignore;
  /**
   * Field _isUndeadOnly.
   */
  protected boolean _isUndeadOnly;
  /**
   * Field _isUseSS.
   */
  protected Ternary _isUseSS;
  /**
   * Field _isOverhit.
   */
  protected boolean _isOverhit;
  /**
   * Field _isSoulBoost.
   */
  protected boolean _isSoulBoost;
  /**
   * Field _isChargeBoost.
   */
  protected boolean _isChargeBoost;
  /**
   * Field _isUsingWhileCasting.
   */
  protected boolean _isUsingWhileCasting;
  /**
   * Field _isIgnoreResists.
   */
  protected boolean _isIgnoreResists;
  /**
   * Field _isIgnoreInvul.
   */
  protected boolean _isIgnoreInvul;
  /**
   * Field _isTrigger.
   */
  protected boolean _isTrigger;
  /**
   * Field _isNotAffectedByMute.
   */
  protected boolean _isNotAffectedByMute;
  /**
   * Field _basedOnTargetDebuff.
   */
  protected boolean _basedOnTargetDebuff;
  /**
   * Field _deathlink.
   */
  protected boolean _deathlink;
  /**
   * Field _hideStartMessage.
   */
  protected boolean _hideStartMessage;
  /**
   * Field _hideUseMessage.
   */
  protected boolean _hideUseMessage;
  /**
   * Field _skillInterrupt.
   */
  protected boolean _skillInterrupt;
  /**
   * Field _flyingTransformUsage.
   */
  protected boolean _flyingTransformUsage;
  /**
   * Field _flySpeed.
   */
  protected int _flySpeed;
  /**
   * Field _canUseTeleport.
   */
  protected boolean _canUseTeleport;
  /**
   * Field _isProvoke.
   */
  protected boolean _isProvoke;
  /**
   * Field _isCubicSkill.
   */
  protected boolean _isCubicSkill = false;
  /**
   * Field _isAwakeningToggle.
   */
  protected boolean _isAwakeningToggle = false;
  /**
   * Field _isSelfDispellable.
   */
  protected boolean _isSelfDispellable;
  /**
   * Field _isRelation.
   */
  protected boolean _isRelation = false;
  /**
   * Field _skillType.
   */
  protected SkillType _skillType;
  /**
   * Field _operateType.
   */
  protected SkillOpType _operateType;
  /**
   * Field _targetType.
   */
  protected SkillTargetType _targetType;
  /**
   * Field _magicType.
   */
  protected SkillMagicType _magicType;
  /**
   * Field _traitType.
   */
  protected SkillTrait _traitType;
  /**
   * Field _saveVs.
   */
  protected BaseStats _saveVs;
  /**
   * Field _dispelOnDamage;
   */
  protected boolean _dispelOnDamage;
  /**
   * Field _nextAction.
   */
  protected NextAction _nextAction;
  /**
   * Field _element.
   */
  protected Element _element;
  /**
   * Field _flyType.
   */
  protected FlyType _flyType;
  /**
   * Field _flyToBack.
   */
  protected boolean _flyToBack;
  /**
   * Field _preCondition.
   */
  protected Condition[] _preCondition = Condition.EMPTY_ARRAY;
  /**
   * Field _id.
   */
  public int _id;
  /**
   * Field _level.
   */
  protected int _level;
  /**
   * Field _baseLevel.
   */
  protected int _baseLevel;
  /**
   * Field _displayId.
   */
  protected int _displayId;
  /**
   * Field _displayLevel.
   */
  protected int _displayLevel;
  /**
   * Field _activateRate.
   */
  protected int _activateRate;
  /**
   * Field _castRange.
   */
  protected int _castRange;
  /**
   * Field _cancelTarget.
   */
  protected int _cancelTarget;
  /**
   * Field _condCharges.
   */
  protected int _condCharges;
  /**
   * Field _coolTime.
   */
  protected int _coolTime;
  /**
   * Field _delayedEffect.
   */
  protected int _delayedEffect;
  /**
   * Field _effectPoint.
   */
  protected int _effectPoint;
  /**
   * Field _energyConsume.
   */
  protected int _energyConsume;
  /**
   * Field _elementPower.
   */
  protected int _elementPower;
  /**
   * Field _flyRadius.
   */
  protected int _flyRadius;
  /**
   * Field _hitTime.
   */
  protected int _hitTime;
  /**
   * Field _hpConsume.
   */
  protected int _hpConsume;
  /**
   * Field _levelModifier.
   */
  protected int _levelModifier;
  /**
   * Field _magicLevel.
   */
  protected int _magicLevel;
  /**
   * Field _matak.
   */
  protected int _matak;
  /**
   * Field _minPledgeClass.
   */
  protected int _minPledgeClass;
  /**
   * Field _minRank.
   */
  protected int _minRank;
  /**
   * Field _negatePower.
   */
  protected int _negatePower;
  /**
   * Field _negateSkill.
   */
  protected int _negateSkill;
  /**
   * Field _npcId.
   */
  protected int _npcId;
  /**
   * Field _numCharges.
   */
  protected int _numCharges;
  /**
   * Field _maxCharges.
   */
  protected int _maxCharges;
  /**
   * Field _skillInterruptTime.
   */
  protected int _skillInterruptTime;
  /**
   * Field _skillRadius.
   */
  protected int _skillRadius;
  /**
   * Field _soulsConsume.
   */
  protected int _soulsConsume;
  /**
   * Field _symbolId.
   */
  protected int _symbolId;
  /**
   * Field _weaponsAllowed.
   */
  protected int _weaponsAllowed;
  /**
   * Field _castCount.
   */
  protected int _castCount;
  /**
   * Field _enchantLevelCount.
   */
  protected int _enchantLevelCount;
  /**
   * Field _criticalRate.
   */
  protected int _criticalRate;
  /**
   * Field _reuseDelay.
   */
  protected long _reuseDelay;
  /**
   * Field _power.
   */
  protected double _power;
  /**
   * Field _powerPvP.
   */
  protected double _powerPvP;
  /**
   * Field _powerPvE.
   */
  protected double _powerPvE;
  /**
   * Field _mpConsume1.
   */
  protected double _mpConsume1;
  /**
   * Field _mpConsume2.
   */
  protected double _mpConsume2;
  /**
   * Field _lethal1.
   */
  protected double _lethal1;
  /**
   * Field _lethal2.
   */
  protected double _lethal2;
  /**
   * Field _absorbPart.
   */
  protected double _absorbPart;
  /**
   * Field _name.
   */
  protected String _name;
  /**
   * Field _baseValues.
   */
  protected String _baseValues;
  /**
   * Field _icon.
   */
  protected String _icon;

  protected boolean _isMarkDamage;
  /**
   * Field _skillToCast.
   */
  protected int _skillToCast;
  /**
   * Field _skillToCastLevel.
   */
  protected int _skillToCastLevel;
  /**
   * Field hashCode.
   */
  private final int hashCode;
  /**
   * Field reuseGroupId.
   */
  private final int reuseGroupId = -1;
  protected boolean _isPowerModified = false;
  private int _powerModCount;
  private HashMap <List<String>, Double> _powerModifiers = new HashMap<List<String>, Double>();
  private double _power2;
 
  /**
   * Constructor for Skill.
   * @param set StatsSet
   */
  protected Skill(StatsSet set)
  {
    _id = set.getInteger("skill_id");
    _level = set.getInteger("level");
    _displayId = set.getInteger("displayId", _id);
    _displayLevel = set.getInteger("displayLevel", _level);
    _baseLevel = set.getInteger("base_level");
    _name = set.getString("name");
    _operateType = set.getEnum("operateType", SkillOpType.class);
    _isNewbie = set.getBool("isNewbie", false);
    _isSelfDispellable = set.getBool("isSelfDispellable", true);
    _isPreservedOnDeath = set.getBool("isPreservedOnDeath", false);
    _isAwakeningToggle = set.getBool("isAwakeningToggle", false);
    _isHeroic = set.getBool("isHeroic", false);
    _isAltUse = set.getBool("altUse", false);
    _mpConsume1 = set.getInteger("mpConsume1", 0);
    _mpConsume2 = set.getInteger("mpConsume2", 0);
    _maxHitCancelCount = set.getInteger("maxHitCancelCount", 0);
    _energyConsume = set.getInteger("energyConsume", 0);
    _hpConsume = set.getInteger("hpConsume", 0);
    _soulsConsume = set.getInteger("soulsConsume", 0);
    _isSoulBoost = set.getBool("soulBoost", false);
    _isChargeBoost = set.getBool("chargeBoost", false);
    _isProvoke = set.getBool("provoke", false);
    _isUsingWhileCasting = set.getBool("isUsingWhileCasting", false);
    _matak = set.getInteger("mAtk", 0);
    _isUseSS = Ternary.valueOf(set.getString("useSS", Ternary.DEFAULT.toString()).toUpperCase());
    _magicLevel = set.getInteger("magicLevel", 0);
    _castCount = set.getInteger("castCount", 0);
    _castRange = set.getInteger("castRange", 40);
    _baseValues = set.getString("baseValues", null);
    _skillToCast = set.getInteger("skillToCast", 0);
    _skillToCastLevel = set.getInteger("skillToCastLevel", 0);
    String s1 = set.getString("itemConsumeCount", "");
    String s2 = set.getString("itemConsumeId", "");
    String s3 = set.getString("relationSkillsId", "");
    _powerModCount = set.getInteger("powerModCount",0);
    if(!(_powerModCount == 0))
    {
      _isPowerModified = true;
      for(int i = 0; i < _powerModCount; i++)
      {
        List <String> weaponsMod = new ArrayList<String>();
        String sPowerMod = set.getString("powerModByWeapon"+String.valueOf(i+1),"");
        double dPowerMod = set.getDouble("powerModPercent"+String.valueOf(i+1),1.);
        if(sPowerMod.length() == 0)
        {
          weaponsMod.add("None");
        }
        else
        {
          String[] s = sPowerMod.split(";");
          for(int j = 0; j < s.length; j++)
          {
            weaponsMod.add(s[j]);
          }
        }
        _powerModifiers.put(weaponsMod,dPowerMod);
      }
    }
    if (s1.length() == 0)
    {
      _itemConsume = new int[]
      {
        0
      };
    }
    else
    {
      String[] s = s1.split(" ");
      _itemConsume = new int[s.length];
      for (int i = 0; i < s.length; i++)
      {
        _itemConsume[i] = Integer.parseInt(s[i]);
      }
    }
    if (s2.length() == 0)
    {
      _itemConsumeId = new int[]
      {
        0
      };
    }
    else
    {
      String[] s = s2.split(" ");
      _itemConsumeId = new int[s.length];
      for (int i = 0; i < s.length; i++)
      {
        _itemConsumeId[i] = Integer.parseInt(s[i]);
      }
    }
    if (s3.length() == 0)
    {
      _relationSkillsId = new int[]
      {
        0
      };
    }
    else
    {
      _isRelation = true;
      String[] s = s3.split(";");
      _relationSkillsId = new int[s.length];
      for (int i = 0; i < s.length; i++)
      {
        _relationSkillsId[i] = Integer.parseInt(s[i]);
      }
    }
    _referenceItemId = set.getInteger("referenceItemId", 0);
    _referenceItemMpConsume = set.getInteger("referenceItemMpConsume", 0);
    _castOverStun = set.getBool("castOverStun", false);
    _isItemHandler = set.getBool("isHandler", false);
    _isCommon = set.getBool("isCommon", false);
    _isAuraSkill= set.getBool("isAuraSkill", false);
    _isAlterSkill= set.getBool("isAlterSkill", false);
    _isSaveable = set.getBool("isSaveable", true);
    _coolTime = set.getInteger("coolTime", 0);
    _skillInterruptTime = set.getInteger("hitCancelTime", 0);
    _reuseDelay = set.getLong("reuseDelay", 0);
    _hitTime = set.getInteger("hitTime", 0);
    _skillRadius = set.getInteger("skillRadius", 80);
    _targetType = set.getEnum("target", SkillTargetType.class);
    _magicType = set.getEnum("magicType", SkillMagicType.class, SkillMagicType.PHYSIC);
    _traitType = set.getEnum("trait", SkillTrait.class, null);
    _saveVs = set.getEnum("saveVs", BaseStats.class, null);
    _dispelOnDamage = set.getBool("dispelOnDamage", false);
    _hideStartMessage = set.getBool("isHideStartMessage", false);
    _hideUseMessage = set.getBool("isHideUseMessage", false);
    _isUndeadOnly = set.getBool("undeadOnly", false);
    _isCorpse = set.getBool("corpse", false);
    _power = set.getDouble("power", 0.);
    _power2 = set.getDouble("power2", 0.);
    _powerPvP = set.getDouble("powerPvP", 0.);
    _powerPvE = set.getDouble("powerPvE", 0.);
    _effectPoint = set.getInteger("effectPoint", 0);
    _nextAction = NextAction.valueOf(set.getString("nextAction", "DEFAULT").toUpperCase());
    _skillType = set.getEnum("skillType", SkillType.class);
    _isSuicideAttack = set.getBool("isSuicideAttack", false);
    _isSkillTimePermanent = set.getBool("isSkillTimePermanent", false);
    _isReuseDelayPermanent = set.getBool("isReuseDelayPermanent", false);
    _deathlink = set.getBool("deathlink", false);
    _basedOnTargetDebuff = set.getBool("basedOnTargetDebuff", false);
    _isNotUsedByAI = set.getBool("isNotUsedByAI", false);
    _isIgnoreResists = set.getBool("isIgnoreResists", false);
    _isIgnoreInvul = set.getBool("isIgnoreInvul", false);
    _isTrigger = set.getBool("isTrigger", false);
    _isNotAffectedByMute = set.getBool("isNotAffectedByMute", false);
    _flyingTransformUsage = set.getBool("flyingTransformUsage", false);
    _flySpeed = set.getInteger("flySpeed", 0);
    _canUseTeleport = set.getBool("canUseTeleport", true);
    if (NumberUtils.isNumber(set.getString("element", "NONE")))
    {
      _element = Element.getElementById(set.getInteger("element", -1));
    }
    else
    {
      _element = Element.getElementByName(set.getString("element", "none").toUpperCase());
    }
    _elementPower = set.getInteger("elementPower", 0);
    _activateRate = set.getInteger("activateRate", -1);
    _levelModifier = set.getInteger("levelModifier", 1);
    _isCancelable = set.getBool("cancelable", true);
    _isReflectable = set.getBool("reflectable", true);
    _isHealDamageSkill = set.getBool("isHealDamageSkill", false);
    _isShieldignore = set.getBool("shieldignore", false);
    _criticalRate = set.getInteger("criticalRate", 0);
    _isOverhit = set.getBool("overHit", false);
    _weaponsAllowed = set.getInteger("weaponsAllowed", 0);
    _minPledgeClass = set.getInteger("minPledgeClass", 0);
    _minRank = set.getInteger("minRank", 0);
    _isOffensive = set.getBool("isOffensive", _skillType.isOffensive());
    _isPvpSkill = set.getBool("isPvpSkill", _skillType.isPvpSkill());
    _isFishingSkill = set.getBool("isFishingSkill", false);
    _isPvm = set.getBool("isPvm", _skillType.isPvM());
    _isForceUse = set.getBool("isForceUse", false);
    _isBehind = set.getBool("behind", false);
    _scopeAngle = set.getInteger("scopeAngle", 120);
    _symbolId = set.getInteger("symbolId", 0);
    _npcId = set.getInteger("npcId", 0);
    _flyType = FlyType.valueOf(set.getString("flyType", "NONE").toUpperCase());
    _flyToBack = set.getBool("flyToBack", false);
    _flyRadius = set.getInteger("flyRadius", 200);
    _negateSkill = set.getInteger("negateSkill", 0);
    _negatePower = set.getInteger("negatePower", Integer.MAX_VALUE);
    _numCharges = set.getInteger("num_charges", 0);
    _maxCharges = set.getInteger("max_charges", 0);
    _condCharges = set.getInteger("cond_charges", 0);
    _delayedEffect = set.getInteger("delayedEffect", 0);
    _cancelTarget = set.getInteger("cancelTarget", 0);
    _skillInterrupt = set.getBool("skillInterrupt", false);
    _lethal1 = set.getDouble("lethal1", 0.);
    _lethal2 = set.getDouble("lethal2", 0.);
    _absorbPart = set.getDouble("absorbPart", 0.);
    _icon = set.getString("icon", "");
    _isMarkDamage = set.getBool("isMarkDamage", false);

    StringTokenizer st = new StringTokenizer(set.getString("addSkills", ""), ";");
    while (st.hasMoreTokens())
    {
      int id = Integer.parseInt(st.nextToken());
      int level = Integer.parseInt(st.nextToken());
      if (level == -1)
      {
        level = _level;
      }
      _addedSkills = ArrayUtils.add(_addedSkills, new AddedSkill(id, level));
    }
    if (_nextAction == NextAction.DEFAULT)
    {
      switch (_skillType)
      {
        case PDAM:
        case CPDAM:
        case LETHAL_SHOT:
        case SPOIL:
        case SOWING:
        case STUN:
        case DRAIN_SOUL:
          _nextAction = NextAction.ATTACK;
          break;
        default:
          _nextAction = NextAction.NONE;
      }
    }
    String canLearn = set.getString("canLearn", null);
    if (canLearn == null)
    {
      _canLearn = null;
    }
    else
    {
      _canLearn = new ArrayList<ClassId>();
      st = new StringTokenizer(canLearn, " \r\n\t,;");
      while (st.hasMoreTokens())
      {
        String cls = st.nextToken();
        _canLearn.add(ClassId.valueOf(cls));
      }
    }
    String teachers = set.getString("teachers", null);
    if (teachers == null)
    {
      _teachers = null;
    }
    else
    {
      _teachers = new ArrayList<Integer>();
      st = new StringTokenizer(teachers, " \r\n\t,;");
      while (st.hasMoreTokens())
      {
        String npcid = st.nextToken();
        _teachers.add(Integer.parseInt(npcid));
      }
    }
    hashCode = (_id * 1023) + _level;
  }
 
  /**
   * Method getWeaponDependancy.
   * @param activeChar Creature
   * @return boolean
   */
  public final boolean getWeaponDependancy(Creature activeChar)
  {
    if (_weaponsAllowed == 0)
    {
      return true;
    }
    if ((activeChar.getActiveWeaponInstance() != null) && (activeChar.getActiveWeaponItem() != null))
    {
      if ((activeChar.getActiveWeaponItem().getItemType().mask() & _weaponsAllowed) != 0)
      {
        return true;
      }
    }
    if ((activeChar.getSecondaryWeaponInstance() != null) && (activeChar.getSecondaryWeaponItem() != null))
    {
      if ((activeChar.getSecondaryWeaponItem().getItemType().mask() & _weaponsAllowed) != 0)
      {
        return true;
      }
    }
    activeChar.sendPacket(new SystemMessage(SystemMessage.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS).addSkillName(_displayId, _displayLevel));
    return false;
  }
 

  /**
   * Method getWeaponModifiedPower.
   * @param activeChar Creature
   * @return boolean
   */
  public double getWeaponModifiedPower(Creature activeChar)
  {
    if ((activeChar.getActiveWeaponInstance() != null) && (activeChar.getActiveWeaponItem() != null))
    {   
     
      for(Iterator <Entry<List<String>,Double>> i = _powerModifiers.entrySet().iterator(); i.hasNext();)
      {
        Map.Entry<List<String>,Double> e = i.next();
        for(String weaponName : e.getKey())
        {
          if(activeChar.getActiveWeaponItem().getItemType().toString().equals(weaponName))
          {
            return e.getValue();
          }
        }
      }
    }
    if ((activeChar.getSecondaryWeaponInstance() != null) && (activeChar.getSecondaryWeaponItem() != null))
    {     
      for(Iterator <Entry<List<String>,Double>> i = _powerModifiers.entrySet().iterator(); i.hasNext();)
      {
        Map.Entry<List<String>,Double> e = i.next();
        for(String weaponName : e.getKey())
        {
          if(activeChar.getActiveWeaponItem().getItemType().toString().equals(weaponName))
          {
            return e.getValue();
          }
        }
      }     
    }
    return 1.;   
  }


 
  /**
   * Method checkCondition.
   * @param activeChar Creature
   * @param target Creature
   * @param forceUse boolean
   * @param dontMove boolean
   * @param first boolean
   * @return boolean
   */
  public boolean checkCondition(Creature activeChar, Creature target, boolean forceUse, boolean dontMove, boolean first)
  {
    Player player = activeChar.getPlayer();
    if (activeChar.isDead())
    {
      return false;
    }
    if ((target != null) && (activeChar.getReflection() != target.getReflection()))
    {
      activeChar.sendPacket(SystemMsg.CANNOT_SEE_TARGET);
      return false;
    }
    if (!getWeaponDependancy(activeChar))
    {
      return false;
    }
    if (activeChar.isUnActiveSkill(_id))
    {
      return false;
    }
    if (first && activeChar.isSkillDisabled(this))
    {
      activeChar.sendReuseMessage(this);
      return false;
    }
    if (first && (activeChar.getCurrentMp() < (isMagic() ? _mpConsume1 + activeChar.calcStat(Stats.MP_MAGIC_SKILL_CONSUME, _mpConsume2, target, this) : _mpConsume1 + activeChar.calcStat(Stats.MP_PHYSICAL_SKILL_CONSUME, _mpConsume2, target, this))))
    {
      activeChar.sendPacket(Msg.NOT_ENOUGH_MP);
      return false;
    }
    if (activeChar.getCurrentHp() < (_hpConsume + 1))
    {
      activeChar.sendPacket(Msg.NOT_ENOUGH_HP);
      return false;
    }
    if (!(_isItemHandler || _isAltUse) && activeChar.isMuted(this))
    {
      return false;
    }
    if (_soulsConsume > activeChar.getConsumedSouls())
    {
      activeChar.sendPacket(Msg.THERE_IS_NOT_ENOUGHT_SOUL);
      return false;
    }
    if ((activeChar.getIncreasedForce() < _condCharges) || (activeChar.getIncreasedForce() < _numCharges))
    {
      activeChar.sendPacket(Msg.YOUR_FORCE_HAS_REACHED_MAXIMUM_CAPACITY_);
      return false;
    }
    if (player != null)
    {
      if (player.isInFlyingTransform() && _isItemHandler && !flyingTransformUsage())
      {
        player.sendPacket(new SystemMessage(SystemMessage.S1_CANNOT_BE_USED_DUE_TO_UNSUITABLE_TERMS).addItemName(getItemConsumeId()[0]));
        return false;
      }
      if (player.isInBoat())
      {
        if (player.getBoat().isAirShip() && !_isItemHandler)
        {
          return false;
        }
        if (player.getBoat().isVehicle() && !((this instanceof FishingSkill) || (this instanceof ReelingPumping)))
        {
          return false;
        }
      }
      if (player.isInObserverMode())
      {
        activeChar.sendPacket(Msg.OBSERVERS_CANNOT_PARTICIPATE);
        return false;
      }
      if (first && (_itemConsume[0] > 0))
      {
        for (int i = 0; i < _itemConsume.length; i++)
        {
          Inventory inv = ((Playable) activeChar).getInventory();
          if (inv == null)
          {
            inv = player.getInventory();
          }
          ItemInstance requiredItems = inv.getItemByItemId(_itemConsumeId[i]);
          if ((requiredItems == null) || (requiredItems.getCount() < _itemConsume[i]))
          {
            if (activeChar == player)
            {
              player.sendPacket(isHandler() ? SystemMsg.INCORRECT_ITEM_COUNT : SystemMsg.THERE_ARE_NOT_ENOUGH_NECESSARY_ITEMS_TO_USE_THE_SKILL);
            }
            return false;
          }
        }
      }
      if (player.isFishing() && !isFishingSkill() && !altUse() && !(activeChar.isServitor() || activeChar.isPet()))
      {
        if (activeChar == player)
        {
          player.sendPacket(Msg.ONLY_FISHING_SKILLS_ARE_AVAILABLE);
        }
        return false;
      }
    }
    if ((getFlyType() != FlyType.NONE) && (getId() != 628) && (getId() != 821) && (activeChar.isImmobilized() || activeChar.isRooted()))
    {
      activeChar.getPlayer().sendPacket(Msg.YOUR_TARGET_IS_OUT_OF_RANGE);
      return false;
    }
    if (first && (target != null) && (getFlyType() == FlyType.CHARGE) && activeChar.isInRange(target.getLoc(), Math.min(150, getFlyRadius())))
    {
      activeChar.getPlayer().sendPacket(Msg.THERE_IS_NOT_ENOUGH_SPACE_TO_MOVE_THE_SKILL_CANNOT_BE_USED);
      return false;
    }
    SystemMsg msg = checkTarget(activeChar, target, target, forceUse, first);
    if ((msg != null) && (activeChar.getPlayer() != null))
    {
      activeChar.getPlayer().sendPacket(msg);
      return false;
    }
    if (_preCondition.length == 0)
    {
      return true;
    }
    Env env = new Env();
    env.character = activeChar;
    env.skill = this;
    env.target = target;
    if (first)
    {
      for (Condition p : _preCondition)
      {
        if (!p.test(env))
        {
          SystemMsg cond_msg = p.getSystemMsg();
          if (cond_msg != null)
          {
            if (cond_msg.size() > 0)
            {
              activeChar.sendPacket(new SystemMessage2(cond_msg).addSkillName(this));
            }
            else
            {
              activeChar.sendPacket(cond_msg);
            }
          }
          return false;
        }
      }
    }
    return true;
  }
 
  /**
   * Method checkTarget.
   * @param activeChar Creature
   * @param target Creature
   * @param aimingTarget Creature
   * @param forceUse boolean
   * @param first boolean
   * @return SystemMsg
   */
  public SystemMsg checkTarget(Creature activeChar, Creature target, Creature aimingTarget, boolean forceUse, boolean first)
  {
    if (((target == activeChar) && isNotTargetAoE()) || (activeChar.isPlayer() && (target == activeChar.getPlayer().getSummonList().getFirstServitor()) && (_targetType == SkillTargetType.TARGET_PET_AURA)))
    {
      return null;
    }
    if ((target == null) || (isOffensive() && (target == activeChar)))
    {
      return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
    }
    if (activeChar.getReflection() != target.getReflection())
    {
      return SystemMsg.CANNOT_SEE_TARGET;
    }
    if (!first && (target != activeChar) && (target == aimingTarget) && (getCastRange() > 0) && (getCastRange() != 32767) && !activeChar.isInRange(target.getLoc(), getCastRange() + (getCastRange() < 200 ? 400 : 500)))
    {
      return SystemMsg.YOUR_TARGET_IS_OUT_OF_RANGE;
    }
    if ((_skillType == SkillType.TAKECASTLE) || (_skillType == SkillType.TAKEFORTRESS))
    {
      return null;
    }
    if (!first && (target != activeChar) && ((_targetType == SkillTargetType.TARGET_MULTIFACE) || (_targetType == SkillTargetType.TARGET_MULTIFACE_AURA) || (_targetType == SkillTargetType.TARGET_TUNNEL)) && (_isBehind ? PositionUtils.isFacing(activeChar, target, (360 - _scopeAngle)) : !PositionUtils.isFacing(activeChar, target, _scopeAngle)))
    {
      return SystemMsg.YOUR_TARGET_IS_OUT_OF_RANGE;
    }
    if (((target.isDead() != _isCorpse) && (_targetType != SkillTargetType.TARGET_AREA_AIM_CORPSE)) || (_isUndeadOnly && !target.isUndead()))
    {
      return SystemMsg.INVALID_TARGET;
    }
    if(target.isNpc() && (!_skillHealStance && _isHealDamageSkill))
    {
      return null;
    }
    if(!target.isPlayer() && (_skillHealStance && _isHealDamageSkill))
    {
      return SystemMsg.INVALID_TARGET;
    }
    if (_isAltUse || (_targetType == SkillTargetType.TARGET_FEEDABLE_BEAST) || (_targetType == SkillTargetType.TARGET_UNLOCKABLE) || (_targetType == SkillTargetType.TARGET_CHEST))
    {
      return null;
    }
    Player player = activeChar.getPlayer();
    if (player != null)
    {
      Player pcTarget = target.getPlayer();
      if (pcTarget != null)
      {
        if (isPvM())
        {
          return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
        }
        if (player.isInZone(ZoneType.epic) != pcTarget.isInZone(ZoneType.epic))
        {
          return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
        }
        if (pcTarget.isInOlympiadMode() && (!player.isInOlympiadMode() || (player.getOlympiadGame() != pcTarget.getOlympiadGame())))
        {
          return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
        }
        if ((player.getBlockCheckerArena() > -1) && (pcTarget.getBlockCheckerArena() > -1) && (_targetType == SkillTargetType.TARGET_EVENT))
        {
          return null;
        }
        if (isOffensive() ||(!_skillHealStance && _isHealDamageSkill))
        {
          if (player.isInOlympiadMode() && !player.isOlympiadCompStart())
          {
            return SystemMsg.INVALID_TARGET;
          }
          if (player.isInOlympiadMode() && player.isOlympiadCompStart() && (player.getOlympiadSide() == pcTarget.getOlympiadSide()) && !forceUse)
          {
            return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
          }
          if (isAoE() && (getCastRange() < Integer.MAX_VALUE) && !GeoEngine.canSeeTarget(activeChar, target, activeChar.isFlying()))
          {
            return SystemMsg.CANNOT_SEE_TARGET;
          }
          if ((activeChar.isInZoneBattle() != target.isInZoneBattle()) && !player.getPlayerAccess().PeaceAttack)
          {
            return SystemMsg.YOU_MAY_NOT_ATTACK_THIS_TARGET_IN_A_PEACEFUL_ZONE;
          }
          if ((activeChar.isInZonePeace() || target.isInZonePeace()) && !player.getPlayerAccess().PeaceAttack)
          {
            return SystemMsg.YOU_MAY_NOT_ATTACK_THIS_TARGET_IN_A_PEACEFUL_ZONE;
          }
          if (activeChar.isInZoneBattle())
          {
            if (!forceUse && !isForceUse() && (player.getParty() != null) && (player.getParty() == pcTarget.getParty()))
            {
              return SystemMsg.INVALID_TARGET;
            }
            return null;
          }
          SystemMsg msg = null;
          for (GlobalEvent e : player.getEvents())
          {
            if ((msg = e.checkForAttack(target, activeChar, this, forceUse)) != null)
            {
              return msg;
            }
          }
          for (GlobalEvent e : player.getEvents())
          {
            if (e.canAttack(target, activeChar, this, forceUse))
            {
              return null;
            }
          }
          if (isProvoke())
          {
            if (!forceUse && (player.getParty() != null) && (player.getParty() == pcTarget.getParty()))
            {
              return SystemMsg.INVALID_TARGET;
            }
            return null;
          }
          if (isPvpSkill() || !forceUse || isAoE())
          {
            if (player == pcTarget)
            {
              return SystemMsg.INVALID_TARGET;
            }
            if ((player.getParty() != null) && (player.getParty() == pcTarget.getParty()))
            {
              return SystemMsg.INVALID_TARGET;
            }
            if ((player.getClanId() != 0) && (player.getClanId() == pcTarget.getClanId()))
            {
              return SystemMsg.INVALID_TARGET;
            }
          }
          if (activeChar.isInZone(ZoneType.SIEGE) && target.isInZone(ZoneType.SIEGE))
          {
            return null;
          }
          if (player.atMutualWarWith(pcTarget))
          {
            return null;
          }
          if (isForceUse())
          {
            return null;
          }
          if (pcTarget.getPvpFlag() != 0)
          {
            return null;
          }
          if (pcTarget.isChaotic())
          {
            return null;
          }
          if (forceUse && !isPvpSkill() && (!isAoE() || (aimingTarget == target)))
          {
            return null;
          }
          return SystemMsg.INVALID_TARGET;
        }
        if ((_targetType == SkillTargetType.TARGET_MENTEE) && (pcTarget.getMenteeMentorList().getMentor() != player.getObjectId()))
        {
          return SystemMsg.INVALID_TARGET;
        }
        if ((player.getParty() == null) && (_skillHealStance && _isHealDamageSkill))
        {
          return SystemMsg.INVALID_TARGET;
        }
        if ((pcTarget == player) && (_skillHealStance && _isHealDamageSkill) && ((player.getParty() != null) && (player.getParty() != pcTarget.getParty())))
        {
          return SystemMsg.INVALID_TARGET;
        }
        if ((pcTarget == player) && (_skillHealStance && _isHealDamageSkill) && ((player.getParty() != null) && (player.getParty() == pcTarget.getParty())))
        {
          return null;
        }
        if (pcTarget == player)
        {
          return null;
        }
        if (player.isInOlympiadMode() && !forceUse && (player.getOlympiadSide() != pcTarget.getOlympiadSide()))
        {
          return SystemMsg.THAT_IS_AN_INCORRECT_TARGET;
        }
        if (!activeChar.isInZoneBattle() && target.isInZoneBattle())
        {
          return SystemMsg.INVALID_TARGET;
        }
        if (forceUse || isForceUse())
        {
          return null;
        }
        if ((player.getParty() != null) && (player.getParty() == pcTarget.getParty()))
        {
          return null;
        }
        if ((player.getClanId() != 0) && (player.getClanId() == pcTarget.getClanId()))
        {
          return null;
        }
        if (player.atMutualWarWith(pcTarget))
        {
          return SystemMsg.INVALID_TARGET;
        }
        if (pcTarget.getPvpFlag() != 0)
        {
          return SystemMsg.INVALID_TARGET;
        }
        if (pcTarget.isChaotic())
        {
          return SystemMsg.INVALID_TARGET;
        }
        return null;
      }
    }
    if (isAoE() && isOffensive() && (!_skillHealStance && _isHealDamageSkill) && (getCastRange() < Integer.MAX_VALUE) && !GeoEngine.canSeeTarget(activeChar, target, activeChar.isFlying()))
    {
      return SystemMsg.CANNOT_SEE_TARGET;
    }
    if (!forceUse && !isForceUse() && !isOffensive() && target.isAutoAttackable(activeChar))
    {
      return SystemMsg.INVALID_TARGET;
    }
    if (!forceUse && !isForceUse() && isOffensive() && !target.isAutoAttackable(activeChar))
    {
      return SystemMsg.INVALID_TARGET;
    }
    if (!target.isAttackable(activeChar))
    {
      return SystemMsg.INVALID_TARGET;
    }
    return null;
  }
 
  /**
   * Method getAimingTarget.
   * @param activeChar Creature
   * @param obj GameObject
   * @return Creature
   */
  public final Creature getAimingTarget(Creature activeChar, GameObject obj)
  {
    Creature target = (obj == null) || !obj.isCreature() ? null : (Creature) obj;
    switch (_targetType)
    {
      case TARGET_SUMMON_AURA:
      case TARGET_SUMMON_AURA_AND_ME:
      case TARGET_ALLY:
      case TARGET_CLAN:
      case TARGET_PARTY:
      case TARGET_PARTY_WITHOUT_ME:
      case TARGET_CLAN_ONLY:
      case TARGET_SELF:
        return activeChar;
      case TARGET_AURA:
      case TARGET_GROUND:
      case TARGET_COMMCHANNEL:
      case TARGET_MULTIFACE_AURA:
        return activeChar;
      case TARGET_HOLY:
        return (target != null) && activeChar.isPlayer() && target.isArtefact() ? target : null;
      case TARGET_FLAGPOLE:
        return activeChar;
      case TARGET_UNLOCKABLE:
        return ((target != null) && target.isDoor()) || (target instanceof ChestInstance) ? target : null;
      case TARGET_CHEST:
        return target instanceof ChestInstance ? target : null;
      case TARGET_FEEDABLE_BEAST:
        return target instanceof FeedableBeastInstance ? target : null;
      case TARGET_PET:
        return (target != null) && (target.isPet()) && (target.isDead() == _isCorpse) ? target : null;
      case TARGET_PET_AURA:
        target = activeChar.getPlayer().getSummonList().getFirstServitor();
        return (target != null) && (target.isDead() == _isCorpse) ? target : null;
      case TARGET_SUMMON:
        return (target != null) && (target.isServitor()) && (target.isDead() == _isCorpse) ? target : null;
      case TARGET_OWNER:
        if (activeChar.isServitor() || activeChar.isPet())
        {
          target = activeChar.getPlayer();
        }
        else
        {
          return null;
        }
        return (target != null) && (target.isDead() == _isCorpse) ? target : null;
      case TARGET_ENEMY_PET:
        if ((target == null) || (target == activeChar.getPlayer().getSummonList().getPet()) || !target.isPet())
        {
          return null;
        }
        return target;
      case TARGET_ENEMY_SUMMON:
        if ((target == null) || (target == activeChar.getPlayer().getSummonList().getPet()) || !target.isServitor())
        {
          return null;
        }
        return target;
      case TARGET_ENEMY_SERVITOR:
        if ((target == null) || (target == activeChar.getPlayer().getSummonList().getPet()) || !(target instanceof Summon))
        {
          return null;
        }
        return target;
      case TARGET_EVENT:
        return (target != null) && !target.isDead() && (target.getPlayer().getBlockCheckerArena() > -1) ? target : null;
      case TARGET_MENTEE:
      case TARGET_ONE:
        return (target != null) && (target.isDead() == _isCorpse) && !((target == activeChar) && isOffensive()) && (!_isUndeadOnly || target.isUndead()) ? target : null;
      case TARGET_ONE_PLAYER:
        return (target != null) && target.isPlayer() && (target.isDead() == _isCorpse) && !((target == activeChar) && isOffensive()) && (!_isUndeadOnly || target.isUndead()) ? target : null;
      case TARGET_PARTY_ONE:
        if (target == null)
        {
          return null;
        }
        Player player = activeChar.getPlayer();
        Player ptarget = target.getPlayer();
        if ((ptarget != null) && (ptarget == activeChar))
        {
          return target;
        }
        if ((player != null) && player.isInOlympiadMode() && (ptarget != null) && (player.getOlympiadSide() == ptarget.getOlympiadSide()) && (player.getOlympiadGame() == ptarget.getOlympiadGame()) && (target.isDead() == _isCorpse) && !((target == activeChar) && isOffensive()) && (!_isUndeadOnly || target.isUndead()))
        {
          return target;
        }
        if ((ptarget != null) && (player != null) && (player.getParty() != null) && player.getParty().containsMember(ptarget) && (target.isDead() == _isCorpse) && !((target == activeChar) && isOffensive()) && (!_isUndeadOnly || target.isUndead()))
        {
          return target;
        }
        return null;
      case TARGET_AREA:
      case TARGET_MULTIFACE:
      case TARGET_TUNNEL:
        return (target != null) && (target.isDead() == _isCorpse) && !((target == activeChar) && isOffensive()) && (!_isUndeadOnly || target.isUndead()) ? target : null;
      case TARGET_AREA_AIM_CORPSE:
        return (target != null) && target.isDead() ? target : null;
      case TARGET_CORPSE:
        if ((target == null) || !target.isDead())
        {
          return null;
        }
        if (target.isServitor() && (target != activeChar.getPlayer().getSummonList().getPet()))
        {
          return target;
        }
        return target.isNpc() ? target : null;
      case TARGET_CORPSE_PLAYER:
        return (target != null) && target.isPlayable() && target.isDead() ? target : null;
      case TARGET_SIEGE:
        return (target != null) && !target.isDead() && target.isDoor() ? target : null;
      default:
        activeChar.sendMessage("Target type of skill is not currently handled");
        return null;
    }
  }
 
  /**
   * Method getTargets.
   * @param activeChar Creature
   * @param aimingTarget Creature
   * @param forceUse boolean
   * @return List<Creature>
   */
  public List<Creature> getTargets(Creature activeChar, Creature aimingTarget, boolean forceUse)
  {
    List<Creature> targets;
    if (oneTarget())
    {
      targets = new LazyArrayList<Creature>(1);
      targets.add(aimingTarget);
      return targets;
    }
    targets = new LazyArrayList<Creature>();
    switch (_targetType)
    {
      case TARGET_EVENT:
      {
        if (activeChar.isPlayer())
        {
          Player player = activeChar.getPlayer();
          int playerArena = player.getBlockCheckerArena();
          if (playerArena != -1)
          {
            ArenaParticipantsHolder holder = HandysBlockCheckerManager.getInstance().getHolder(playerArena);
            int team = holder.getPlayerTeam(player);
            for (Player actor : World.getAroundPlayers(activeChar, 250, 100))
            {
              if (holder.getAllPlayers().contains(actor) && (holder.getPlayerTeam(actor) != team))
              {
                targets.add(actor);
              }
            }
          }
        }
        break;
      }
      case TARGET_AREA_AIM_CORPSE:
      case TARGET_AREA:
      case TARGET_MULTIFACE:
      case TARGET_TUNNEL:
      {
        if ((aimingTarget.isDead() == _isCorpse) && (!_isUndeadOnly || aimingTarget.isUndead()))
        {
          targets.add(aimingTarget);
        }
        if (_targetType == SkillTargetType.TARGET_MULTIFACE)
        {
          addTargetsToList(targets, activeChar, activeChar, forceUse);
        }
        else
        {
          addTargetsToList(targets, aimingTarget, activeChar, forceUse);
        }
        break;
      }
      case TARGET_AURA:
      case TARGET_MULTIFACE_AURA:
      {
        addTargetsToList(targets, activeChar, activeChar, forceUse);
        break;
      }
      case TARGET_COMMCHANNEL:
      {
        if (activeChar.getPlayer() != null)
        {
          if (activeChar.getPlayer().isInParty())
          {
            if (activeChar.getPlayer().getParty().isInCommandChannel())
            {
              for (Player p : activeChar.getPlayer().getParty().getCommandChannel())
              {
                if (!p.isDead() && p.isInRange(activeChar, _skillRadius == 0 ? 600 : _skillRadius))
                {
                  targets.add(p);
                }
              }
              addTargetAndPetToList(targets, activeChar.getPlayer(), activeChar.getPlayer());
              break;
            }
            for (Player p : activeChar.getPlayer().getParty().getPartyMembers())
            {
              if (!p.isDead() && p.isInRange(activeChar, _skillRadius == 0 ? 600 : _skillRadius))
              {
                targets.add(p);
              }
            }
            addTargetAndPetToList(targets, activeChar.getPlayer(), activeChar.getPlayer());
            break;
          }
          targets.add(activeChar);
          addTargetAndPetToList(targets, activeChar.getPlayer(), activeChar.getPlayer());
        }
        break;
      }
      case TARGET_PET_AURA:
        if (activeChar.getPlayer().getSummonList().getFirstServitor() == null)
        {
          break;
        }
        addTargetsToList(targets, activeChar.getPlayer().getSummonList().getFirstServitor(), activeChar, forceUse);
        break;
      case TARGET_SUMMON_AURA:
      case TARGET_SUMMON_AURA_AND_ME:
        List<Summon> servitors = activeChar.getPlayer().getSummonList().getServitors();
        for (Summon summon : servitors)
        {
          targets.add(summon);
        }
        switch (_targetType)
        {
          case TARGET_SUMMON_AURA_AND_ME:
            targets.add(activeChar);
            break;
          default:
            break;
        }
        break;
      case TARGET_PARTY:
      case TARGET_PARTY_WITHOUT_ME:
      case TARGET_CLAN:
      case TARGET_CLAN_ONLY:
      case TARGET_ALLY:
      {
        if (activeChar.isMonster() || activeChar.isSiegeGuard())
        {
          targets.add(activeChar);
          for (Creature c : World.getAroundCharacters(activeChar, _skillRadius, 600))
          {
            if (!c.isDead() && (c.isMonster() || c.isSiegeGuard()))
            {
              targets.add(c);
            }
          }
          break;
        }
        Player player = activeChar.getPlayer();
        if (player == null)
        {
          break;
        }
        for (Player target : World.getAroundPlayers(player, _skillRadius, 600))
        {
          boolean check = false;
          switch (_targetType)
          {
            case TARGET_PARTY:
              check = (player.getParty() != null) && (player.getParty() == target.getParty());
              break;
            case TARGET_PARTY_WITHOUT_ME:
              check = (player.getParty() != null) && (player.getParty() == target.getParty()) && (player != target);
              break;
            case TARGET_CLAN:
              check = ((player.getClanId() != 0) && (target.getClanId() == player.getClanId())) || ((player.getParty() != null) && (target.getParty() == player.getParty()));
              break;
            case TARGET_CLAN_ONLY:
              check = (player.getClanId() != 0) && (target.getClanId() == player.getClanId());
              break;
            case TARGET_ALLY:
              check = ((player.getClanId() != 0) && (target.getClanId() == player.getClanId())) || ((player.getAllyId() != 0) && (target.getAllyId() == player.getAllyId()));
              break;
            default:
              break;
          }
          if (!check)
          {
            continue;
          }
          if (player.isInOlympiadMode() && target.isInOlympiadMode() && (player.getOlympiadSide() != target.getOlympiadSide()))
          {
            continue;
          }
          if (checkTarget(player, target, aimingTarget, forceUse, false) != null)
          {
            continue;
          }
          addTargetAndPetToList(targets, player, target);
        }
        if (_targetType != SkillTargetType.TARGET_PARTY_WITHOUT_ME)
        {
          addTargetAndPetToList(targets, player, player);
        }
        break;
      }
      case TARGET_GROUND:
      {
        Player player = activeChar.getPlayer();
        if (player == null)
        {
          break;
        }
        Location loc = player.getGroundSkillLoc();
        addTargetsToList(targets, loc, activeChar, forceUse);
        break;
      }
      default:
        break;
    }
    return targets;
  }
 
  /**
   * Method addTargetAndPetToList.
   * @param targets List<Creature>
   * @param actor Player
   * @param target Player
   */
  private void addTargetAndPetToList(List<Creature> targets, Player actor, Player target)
  {
    if (((actor == target) || actor.isInRange(target, _skillRadius)) && (target.isDead() == _isCorpse))
    {
      targets.add(target);
    }
    for (Summon pet : target.getSummonList())
    {
      if ((pet != null) && actor.isInRange(pet, _skillRadius) && (pet.isDead() == _isCorpse))
      {
        targets.add(pet);
      }
    }
  }
 
  /**
   * Method addTargetsToList.
   * @param targets List<Creature>
   * @param aimingTarget Creature
   * @param activeChar Creature
   * @param forceUse boolean
   */
  private void addTargetsToList(List<Creature> targets, Creature aimingTarget, Creature activeChar, boolean forceUse)
  {
    int count = 0;
    Polygon terr = null;
    if (_targetType == SkillTargetType.TARGET_TUNNEL)
    {
      int radius = 100;
      int zmin1 = activeChar.getZ() - 200;
      int zmax1 = activeChar.getZ() + 200;
      int zmin2 = aimingTarget.getZ() - 200;
      int zmax2 = aimingTarget.getZ() + 200;
      double angle = PositionUtils.convertHeadingToDegree(activeChar.getHeading());
      double radian1 = Math.toRadians(angle - 90);
      double radian2 = Math.toRadians(angle + 90);
      terr = new Polygon().add(activeChar.getX() + (int) (Math.cos(radian1) * radius), activeChar.getY() + (int) (Math.sin(radian1) * radius)).add(activeChar.getX() + (int) (Math.cos(radian2) * radius), activeChar.getY() + (int) (Math.sin(radian2) * radius)).add(aimingTarget.getX() + (int) (Math.cos(radian2) * radius), aimingTarget.getY() + (int) (Math.sin(radian2) * radius)).add(aimingTarget.getX() + (int) (Math.cos(radian1) * radius), aimingTarget.getY() + (int) (Math.sin(radian1) * radius)).setZmin(Math.min(zmin1, zmin2)).setZmax(Math.max(zmax1, zmax2));
    }
    for (Creature target : aimingTarget.getAroundCharacters(_skillRadius, 300))
    {
      if ((terr != null) && !terr.isInside(target.getX(), target.getY(), target.getZ()))
      {
        continue;
      }
      if ((target == null) || (activeChar == target) || ((activeChar.getPlayer() != null) && (activeChar.getPlayer() == target.getPlayer())))
      {
        continue;
      }
      if (getId() == SKILL_DETECTION)
      {
        target.checkAndRemoveInvisible();
      }
      if (checkTarget(activeChar, target, aimingTarget, forceUse, false) != null)
      {
        continue;
      }
      if (!(activeChar instanceof DecoyInstance) && activeChar.isNpc() && target.isNpc())
      {
        continue;
      }
      targets.add(target);
      count++;
      if (isOffensive() && (count >= 20) && !activeChar.isRaid())
      {
        break;
      }
    }
  }
 
  /**
   * Method addTargetsToLakcisDamage.
   * @param targets List<Creature>
   * @param aimingTarget Creature
   * @param activeChar Creature
   * @param forceUse boolean
   */
  public void addTargetsToLakcis(List<Creature> targets, Creature activeChar, boolean isHealTask)
  {   
    _skillHealStance = isHealTask;
    int count = 0;
    Polygon terr = null;
    for (Creature target : activeChar.getAroundCharacters(_skillRadius, 300))
    {
      if ((terr != null) && !terr.isInside(target.getX(), target.getY(), target.getZ()))
      {
        continue;
      }
      if ((target == null) || (activeChar == target) || ((activeChar.getPlayer() != null) && (activeChar.getPlayer() == target.getPlayer())))
      {
        continue;
      }
      if (checkTarget(activeChar, target, activeChar, false, false) != null)
      {
        continue;
      }
      if (!(activeChar instanceof DecoyInstance) && activeChar.isNpc() && target.isNpc())
      {
        continue;
      }
      targets.add(target);
      count++;
      if (isOffensive() && (count >= 20) && !activeChar.isRaid())
      {
        break;
      }
    }
  }
  /**
   * Method addTargetsToList.
   * @param targets List<Creature>
   * @param loc Location
   * @param activeChar Creature
   * @param forceUse boolean
   */
  private void addTargetsToList(List<Creature> targets, Location loc, Creature activeChar, boolean forceUse)
  {
    int count = 0;
    for (Creature target : activeChar.getAroundCharacters(1600, 300))
    {
      if ((target == null) || (activeChar == target) || ((activeChar.getPlayer() != null) && (activeChar.getPlayer() == target.getPlayer())))
      {
        continue;
      }
      if (target.getDistance(loc) < getSkillRadius())
      {
        if (checkTarget(activeChar, target, target, forceUse, false) != null)
        {
          continue;
        }
        if (!(activeChar instanceof DecoyInstance) && activeChar.isNpc() && target.isNpc())
        {
          continue;
        }
        targets.add(target);
      }
      count++;
      if (isOffensive() && (count >= 20) && !activeChar.isRaid())
      {
        break;
      }
    }
  }

  /**
   * Method getEffects.
   * @param effector Creature
   * @param effected Creature
   * @param calcChance boolean
   * @param applyOnCaster boolean
   */
  public final void getEffects(Creature effector, Creature effected, boolean calcChance, boolean applyOnCaster)
  {
    getEffects(effector, effected, calcChance, applyOnCaster, false);
  }
 
  /**
   * Method getEffects.
   * @param effector Creature
   * @param effected Creature
   * @param calcChance boolean
   * @param applyOnCaster boolean
   * @param skillReflected boolean
   */
  public final void getEffects(Creature effector, Creature effected, boolean calcChance, boolean applyOnCaster, boolean skillReflected)
  {
    double timeMult = 1.0;
    if (isMusic())
    {
      timeMult = Config.SONGDANCETIME_MODIFIER;
    }
    else if ((getId() >= 4342) && (getId() <= 4360))
    {
      timeMult = Config.CLANHALL_BUFFTIME_MODIFIER;
    }
    getEffects(effector, effected, calcChance, applyOnCaster, 0, timeMult, skillReflected);
  }
 
  /**
   * Method getEffects.
   * @param effector Creature
   * @param effected Creature
   * @param calcChance boolean
   * @param applyOnCaster boolean
   * @param timeConst long
   * @param timeMult double
   * @param skillReflected boolean
   */
  public final void getEffects(final Creature effector, final Creature effected, final boolean calcChance, final boolean applyOnCaster, final long timeConst, final double timeMult, final boolean skillReflected)
  {
    if (isPassive() || !hasEffects() || (effector == null) || (effected == null))
    {
      return;
    }
    if ((effected.isEffectImmune() || (effected.isInvul() && isOffensive())) && (effector != effected))
    {
      if (effector.isPlayer())
      {
        effector.sendPacket(new SystemMessage(SystemMessage.C1_HAS_RESISTED_YOUR_S2).addName(effected).addSkillName(_displayId, _displayLevel));
      }
      return;
    }
    if (effected.isDoor() || (effected.isAlikeDead() && !isPreservedOnDeath()))
    {
      return;
    }
    ThreadPoolManager.getInstance().execute(new RunnableImpl()
    {
      @Override
      public void runImpl()
      {
        boolean success = false;
        boolean skillMastery = false;
        int sps = effector.getChargedSpiritShot();
        if (effector.getSkillMastery(getId()) == 2)
        {
          skillMastery = true;
          effector.removeSkillMastery(getId());
        }
        for (EffectTemplate et : getEffectTemplates())
        {
          if ((applyOnCaster != et._applyOnCaster) || (et._count == 0))
          {
            continue;
          }
          Creature character = et._applyOnCaster || (et._isReflectable && skillReflected) ? effector : effected;
          List<Creature> targets = new LazyArrayList<Creature>(1);
          targets.add(character);
          if (et._applyOnSummon && character.isPlayer())
          {
            for (Summon summon : character.getPlayer().getSummonList())
            {
              if ((summon != null) && summon.isServitor() && !isOffensive() && !isToggle() && !isCubicSkill())
              {
                targets.add(summon);
              }
            }
          }
          loop:
          for (Creature target : targets)
          {
            if (target.isAlikeDead() && !isPreservedOnDeath())
            {
              continue;
            }
            if (target.isRaid() && et.getEffectType().isRaidImmune())
            {
              continue;
            }
            if (((effected.isBuffImmune() && !isOffensive()) || (effected.isDebuffImmune() && isOffensive())) && (et.getPeriod() > 0) && (effector != effected))
            {
              continue;
            }
            if (isBlockedByChar(target, et))
            {
              continue;
            }
            if (et._stackOrder == -1)
            {
              if (!et._stackTypes.contains(EffectTemplate.NO_STACK))
              {
                for (Effect e : target.getEffectList().getAllEffects())
                {
                  for (String arg : et._stackTypes)
                  {
                    if (e.getStackType().contains(arg))
                    {
                      continue loop;
                    }
                  }
                }
              }
              else if (target.getEffectList().getEffectsBySkillId(getId()) != null)
              {
                continue;
              }
            }
            Env env = new Env(effector, target, Skill.this);
            int chance = et.chance(getActivateRate());
            if ((calcChance || (chance >= 0)) && !et._applyOnCaster)
            {
              env.value = chance;
              if (!Formulas.calcSkillSuccess(env, et, sps))
              {
                continue;
              }
            }
            if (_isReflectable && et._isReflectable && isOffensive() && (target != effector) && !effector.isTrap())
            {
              if (Rnd.chance(target.calcStat(isMagic() ? Stats.REFLECT_MAGIC_DEBUFF : Stats.REFLECT_PHYSIC_DEBUFF, 0, effector, Skill.this)))
              {
                target.sendPacket(new SystemMessage(SystemMessage.YOU_COUNTERED_C1S_ATTACK).addName(effector));
                effector.sendPacket(new SystemMessage(SystemMessage.C1_DODGES_THE_ATTACK).addName(target));
                target = effector;
                env.target = target;
              }
            }
            if (success)
            {
              env.value = Integer.MAX_VALUE;
            }
            final Effect e = et.getEffect(env);
            if (e != null)
            {
              if (chance > 0)
              {
                success = true;
              }
              if (e.isOneTime())
              {
                if (e.checkCondition())
                {
                  e.onStart();
                  e.onActionTime();
                  e.onExit();
                }
              }
              else
              {
                int count = et.getCount();
                long period = et.getPeriod();
                if (skillMastery)
                {
                  if (count > 1)
                  {
                    count *= 2;
                  }
                  else
                  {
                    period *= 2;
                  }
                }
                if (!et._applyOnCaster && isOffensive() && !isIgnoreResists() && !effector.isRaid())
                {
                  double res = 0;
                  if (et.getEffectType().getResistType() != null)
                  {
                    res += effected.calcStat(et.getEffectType().getResistType(), effector, Skill.this);
                  }
                  if (et.getEffectType().getAttributeType() != null)
                  {
                    res -= effector.calcStat(et.getEffectType().getAttributeType(), effected, Skill.this);
                  }
                  res += effected.calcStat(Stats.DEBUFF_RESIST, effector, Skill.this);
                  if (res != 0)
                  {
                    double mod = 1 + Math.abs(0.01 * res);
                    if (res > 0)
                    {
                      mod = 1. / mod;
                    }
                    if (count > 1)
                    {
                      count = (int) Math.floor(Math.max(count * mod, 1));
                    }
                    else
                    {
                      period = (long) Math.floor(Math.max(period * mod, 1));
                    }
                  }
                }
                if (timeConst > 0L)
                {
                  if (count > 1)
                  {
                    period = timeConst / count;
                  }
                  else
                  {
                    period = timeConst;
                  }
                }
                else if (timeMult > 1.0)
                {
                  if (count > 1)
                  {
                    count *= timeMult;
                  }
                  else
                  {
                    period *= timeMult;
                  }
                }
                e.setCount(count);
                e.setPeriod(period);
                e.schedule();
              }
            }
          }
        }
        if (calcChance)
        {
          if (success)
          {
            effector.sendPacket(new SystemMessage(SystemMessage.S1_HAS_SUCCEEDED).addSkillName(_displayId, _displayLevel));
          }
          else
          {
            effector.sendPacket(new SystemMessage(SystemMessage.S1_HAS_FAILED).addSkillName(_displayId, _displayLevel));
          }
        }
      }
    });
  }
 
  /**
   * Method attach.
   * @param effect EffectTemplate
   */
  public final void attach(EffectTemplate effect)
  {
    _effectTemplates = ArrayUtils.add(_effectTemplates, effect);
  }
 
  /**
   * Method getEffectTemplates.
   * @return EffectTemplate[]
   */
  public EffectTemplate[] getEffectTemplates()
  {
    return _effectTemplates;
  }
 
  /**
   * Method hasEffects.
   * @return boolean
   */
  public boolean hasEffects()
  {
    return _effectTemplates.length > 0;
  }
 
  /**
   * Method getStatFuncs.
   * @return Func[]
   */
  public final Func[] getStatFuncs()
  {
    return getStatFuncs(this);
  }
 
  /**
   * Method equals.
   * @param obj Object
   * @return boolean
   */
  @Override
  public boolean equals(Object obj)
  {
    if (this == obj)
    {
      return true;
    }
    if (obj == null)
    {
      return false;
    }
    if (getClass() != obj.getClass())
    {
      return false;
    }
    return hashCode() == ((Skill) obj).hashCode();
  }
 
  /**
   * Method hashCode.
   * @return int
   */
  @Override
  public int hashCode()
  {
    return hashCode;
  }
 
  /**
   * Method attach.
   * @param c Condition
   */
  public final void attach(Condition c)
  {
    _preCondition = ArrayUtils.add(_preCondition, c);
  }
 
  /**
   * Method altUse.
   * @return boolean
   */
  public final boolean altUse()
  {
    return _isAltUse;
  }
 
  /**
   * Method canTeachBy.
   * @param npcId int
   * @return boolean
   */
  public final boolean canTeachBy(int npcId)
  {
    return (_teachers == null) || _teachers.contains(npcId);
  }
 
  /**
   * Method getActivateRate.
   * @return int
   */
  public final int getActivateRate()
  {
    return _activateRate;
  }
 
  /**
   * Method getAddedSkills.
   * @return AddedSkill[]
   */
  public AddedSkill[] getAddedSkills()
  {
    return _addedSkills;
  }
 
  /**
   * Method getCanLearn.
   * @param cls ClassId
   * @return boolean
   */
  public final boolean getCanLearn(ClassId cls)
  {
    return (_canLearn == null) || _canLearn.contains(cls);
  }
 
  /**
   * Method getCastRange.
   * @return int
   */
  public final int getCastRange()
  {
    return _castRange;
  }
 
  /**
   * Method getAOECastRange.
   * @return int
   */
  public final int getAOECastRange()
  {
    return Math.max(_castRange, _skillRadius);
  }
 
  /**
   * Method getCondCharges.
   * @return int
   */
  public int getCondCharges()
  {
    return _condCharges;
  }
 
  /**
   * Method getCoolTime.
   * @return int
   */
  public final int getCoolTime()
  {
    return _coolTime;
  }
 
  /**
   * Method setCoolTime.
   * @param _time int
   */
  public final void setCoolTime(int _time)
  {
    _coolTime = _time;
  }
 
  /**
   * Method getCorpse.
   * @return boolean
   */
  public boolean getCorpse()
  {
    return _isCorpse;
  }
 
  /**
   * Method getDelayedEffect.
   * @return int
   */
  public int getDelayedEffect()
  {
    return _delayedEffect;
  }
 
  /**
   * Method getSkillToCast.
   * @return int
   */
  public final int getSkillToCast()
  {
    return _skillToCast;
  }
 
  /**
   * Method getSkillToCastLevel.
   * @return int
   */
  public final int getSkillToCastLevel()
  {
    return _skillToCastLevel;
  }
 
  /**
   * Method getDisplayId.
   * @return int
   */
  public final int getDisplayId()
  {
    return _displayId;
  }
 
  /**
   * Method getDisplayLevel.
   * @return int
   */
  public int getDisplayLevel()
  {
    return _displayLevel;
  }
 
  /**
   * Method getEffectPoint.
   * @return int
   */
  public int getEffectPoint()
  {
    return _effectPoint;
  }
 
  /**
   * Method getSameByStackType.
   * @param list List<Effect>
   * @return Effect
   */
  public Effect getSameByStackType(List<Effect> list)
  {
    Effect ret;
    for (EffectTemplate et : getEffectTemplates())
    {
      if ((et != null) && ((ret = et.getSameByStackType(list)) != null))
      {
        return ret;
      }
    }
    return null;
  }
 
  /**
   * Method getSameByStackType.
   * @param list EffectList
   * @return Effect
   */
  public Effect getSameByStackType(EffectList list)
  {
    return getSameByStackType(list.getAllEffects());
  }
 
  /**
   * Method getSameByStackType.
   * @param actor Creature
   * @return Effect
   */
  public Effect getSameByStackType(Creature actor)
  {
    return getSameByStackType(actor.getEffectList().getAllEffects());
  }
 
  /**
   * Method getElement.
   * @return Element
   */
  public final Element getElement()
  {
    return _element;
  }
 
  /**
   * Method getElementPower.
   * @return int
   */
  public final int getElementPower()
  {
    return _elementPower;
  }
 
  /**
   * Method getFirstAddedSkill.
   * @return Skill
   */
  public Skill getFirstAddedSkill()
  {
    if (_addedSkills.length == 0)
    {
      return null;
    }
    return _addedSkills[0].getSkill();
  }
 
  /**
   * Method getFlyRadius.
   * @return int
   */
  public int getFlyRadius()
  {
    return _flyRadius;
  }
 
  /**
   * Method getFlyType.
   * @return FlyType
   */
  public FlyType getFlyType()
  {
    return _flyType;
  }
 
  /**
   * Method isFlyToBack.
   * @return boolean
   */
  public boolean isFlyToBack()
  {
    return _flyToBack;
  }
 
  /**
   * Method getHitTime.
   * @return int
   */
  public final int getHitTime()
  {
    return _hitTime;
  }
 
  /**
   * Method getHpConsume.
   * @return int
   */
  public final int getHpConsume()
  {
    return _hpConsume;
  }
 
  /**
   * Method getId.
   * @return int
   */
  public int getId()
  {
    return _id;
  }
 
  /**
   * Method setId.
   * @param id int
   */
  public void setId(int id)
  {
    _id = id;
  }
 
  /**
   * Method getItemConsume.
   * @return int[]
   */
  public final int[] getItemConsume()
  {
    return _itemConsume;
  }
 
  /**
   * Method getItemConsumeId.
   * @return int[]
   */
  public final int[] getItemConsumeId()
  {
    return _itemConsumeId;
  }
 
  /**
   * Method getReferenceItemId.
   * @return int
   */
  public final int getReferenceItemId()
  {
    return _referenceItemId;
  }
 
  /**
   * Method getReferenceItemMpConsume.
   * @return int
   */
  public final int getReferenceItemMpConsume()
  {
    return _referenceItemMpConsume;
  }
 
  /**
   * Method getLevel.
   * @return int
   */
  public final int getLevel()
  {
    return _level;
  }
 
  /**
   * Method getBaseLevel.
   * @return int
   */
  public final int getBaseLevel()
  {
    return _baseLevel;
  }
 
  /**
   * Method setBaseLevel.
   * @param baseLevel int
   */
  public final void setBaseLevel(int baseLevel)
  {
    _baseLevel = baseLevel;
  }
 
  /**
   * Method getLevelModifier.
   * @return int
   */
  public final int getLevelModifier()
  {
    return _levelModifier;
  }
 
  /**
   * Method getMagicLevel.
   * @return int
   */
  public final int getMagicLevel()
  {
    return _magicLevel;
  }
 
  /**
   * Method getMatak.
   * @return int
   */
  public int getMatak()
  {
    return _matak;
  }
 
  /**
   * Method getMinPledgeClass.
   * @return int
   */
  public int getMinPledgeClass()
  {
    return _minPledgeClass;
  }
 
  /**
   * Method getMinRank.
   * @return int
   */
  public int getMinRank()
  {
    return _minRank;
  }
 
  /**
   * Method getMpConsume.
   * @return double
   */
  public final double getMpConsume()
  {
    return _mpConsume1 + _mpConsume2;
  }
 
  /**
   * Method getMpConsume1.
   * @return double
   */
  public final double getMpConsume1()
  {
    return _mpConsume1;
  }
 
  /**
   * Method getMpConsume2.
   * @return double
   */
  public final double getMpConsume2()
  {
    return _mpConsume2;
  }
 
  /**
   * Method getName.
   * @return String
   */
  public final String getName()
  {
    return _name;
  }
 
  /**
   * Method getNegatePower.
   * @return int
   */
  public int getNegatePower()
  {
    return _negatePower;
  }
 
  /**
   * Method getNegateSkill.
   * @return int
   */
  public int getNegateSkill()
  {
    return _negateSkill;
  }
 
  /**
   * Method getNextAction.
   * @return NextAction
   */
  public NextAction getNextAction()
  {
    return _nextAction;
  }
 
  /**
   * Method getNpcId.
   * @return int
   */
  public int getNpcId()
  {
    return _npcId;
  }
 
  /**
   * Method getNumCharges.
   * @return int
   */
  public int getNumCharges()
  {
    return _numCharges;
  }
 
  /**
   * Method getMaxCharges.
   * @return int
   */
  public int getMaxCharges()
  {
    return _maxCharges;
  }
 
  /**
   * Method getPower.
   * @param target Creature
   * @return double
   */
  public final double getPower(Creature target)
  {
    if (target != null)
    {
      if (target.isPlayable())
      {
        return getPowerPvP();
      }
      if (target.isMonster())
      {
        return getPowerPvE();
      }
    }
    return getPower();
  }
 
  /**
   * Method getPower.
   * @return double
   */
  public final double getPower()
  {
    return _power;
  }
 
  /**
   * Method getPower2.
   * @return double
   */
  public final double getPower2()
  {
    return _power2;
  }
 
  /**
   * Method getPowerPvP.
   * @return double
   */
  public final double getPowerPvP()
  {
    return _powerPvP != 0 ? _powerPvP : _power;
  }
 
  /**
   * Method getPowerPvE.
   * @return double
   */
  public final double getPowerPvE()
  {
    return _powerPvE != 0 ? _powerPvE : _power;
  }
 
  /**
   * Method getReuseDelay.
   * @return long
   */
  public final long getReuseDelay()
  {
    return _reuseDelay;
  }
 
  /**
   * Method setReuseDelay.
   * @param newReuseDelay long
   */
  public final void setReuseDelay(long newReuseDelay)
  {
    _reuseDelay = newReuseDelay;
  }

  /**
   * Method getMaxHitCancelCount.
   * @return double
   */
  public final int getMaxHitCancelCount()
  {
    return _maxHitCancelCount;
  }
  /**
   * Method getShieldIgnore.
   * @return boolean
   */
  public final boolean getShieldIgnore()
  {
    return _isShieldignore;
  }
 
  /**
   * Method isReflectable.
   * @return boolean
   */
  public final boolean isReflectable()
  {
    return _isReflectable;
  }
 
  /**
   * Method getSkillInterruptTime.
   * @return int
   */
  public final int getSkillInterruptTime()
  {
    return _skillInterruptTime;
  }
 
  /**
   * Method getSkillRadius.
   * @return int
   */
  public final int getSkillRadius()
  {
    return _skillRadius;
  }
 
  /**
   * Method getSkillType.
   * @return SkillType
   */
  public final SkillType getSkillType()
  {
    return _skillType;
  }
 
  /**
   * Method getSoulsConsume.
   * @return int
   */
  public int getSoulsConsume()
  {
    return _soulsConsume;
  }
 
  /**
   * Method getSymbolId.
   * @return int
   */
  public int getSymbolId()
  {
    return _symbolId;
  }
 
  /**
   * Method getTargetType.
   * @return SkillTargetType
   */
  public final SkillTargetType getTargetType()
  {
    return _targetType;
  }
 
  /**
   * Method getTraitType.
   * @return SkillTrait
   */
  public final SkillTrait getTraitType()
  {
    return _traitType;
  }
 
  /**
   * Method getSaveVs.
   * @return BaseStats
   */
  public final BaseStats getSaveVs()
  {
    return _saveVs;
  }
 
  public final boolean isDispelOnDamage()
  {
    return _dispelOnDamage;
  }
 
  /**
   * Method getWeaponsAllowed.
   * @return int
   */
  public final int getWeaponsAllowed()
  {
    return _weaponsAllowed;
  }
 
  /**
   * Method getLethal1.
   * @return double
   */
  public double getLethal1()
  {
    return _lethal1;
  }
 
  /**
   * Method getLethal2.
   * @return double
   */
  public double getLethal2()
  {
    return _lethal2;
  }
 
  /**
   * Method getBaseValues.
   * @return String
   */
  public String getBaseValues()
  {
    return _baseValues;
  }
 
  /**
   * Method isBlockedByChar.
   * @param effected Creature
   * @param et EffectTemplate
   * @return boolean
   */
  public boolean isBlockedByChar(Creature effected, EffectTemplate et)
  {
    if (et.getAttachedFuncs() == null)
    {
      return false;
    }
    for (FuncTemplate func : et.getAttachedFuncs())
    {
      if ((func != null) && effected.checkBlockedStat(func._stat))
      {
        return true;
      }
    }
    return false;
  }
 
  /**
   * Method isCancelable.
   * @return boolean
   */
  public final boolean isCancelable()
  {
    return _isCancelable && (getSkillType() != SkillType.TRANSFORMATION) && !isToggle();
  }
 
  /**
   * Method isCommon.
   * @return boolean
   */
  public final boolean isCommon()
  {
    return _isCommon;
  }
 
  /**
   * Method getCriticalRate.
   * @return int
   */
  public final int getCriticalRate()
  {
    return _criticalRate;
  }
 
  /**
   * Method isHandler.
   * @return boolean
   */
  public final boolean isHandler()
  {
    return _isItemHandler;
  }

  /**
   * Method castOverStun.
   * @return boolean
   */
  public final boolean isCastOverStun()
  {
    return _castOverStun;
  }
  /**
   * Method isMagic.
   * @return boolean
   */
  public final boolean isMagic()
  {
    return _magicType == SkillMagicType.MAGIC;
  }
 
  /**
   * Method getMagicType.
   * @return SkillMagicType
   */
  public final SkillMagicType getMagicType()
  {
    return _magicType;
  }
 
  /**
   * Method isNewbie.
   * @return boolean
   */
  public final boolean isNewbie()
  {
    return _isNewbie;
  }
 
  /**
   * Method isPreservedOnDeath.
   * @return boolean
   */
  public final boolean isPreservedOnDeath()
  {
    return _isPreservedOnDeath;
  }
 
  /**
   * Method isHeroic.
   * @return boolean
   */
  public final boolean isHeroic()
  {
    return _isHeroic;
  }
 
  /**
   * Method isAwakeningToggle.
   * @return boolean
   */
  public final boolean isAwakeningToggle()
  {
    return _isAwakeningToggle;
  }
 
  /**
   * Method isSelfDispellable.
   * @return boolean
   */
  public final boolean isSelfDispellable()
  {
    return _isSelfDispellable;
  }
 
  /**
   * Method setOperateType.
   * @param type SkillOpType
   */
  public void setOperateType(SkillOpType type)
  {
    _operateType = type;
  }
 
  /**
   * Method isOverhit.
   * @return boolean
   */
  public final boolean isOverhit()
  {
    return _isOverhit;
  }
 
  /**
   * Method isActive.
   * @return boolean
   */
  public final boolean isActive()
  {
    return (_operateType == SkillOpType.OP_ACTIVE) || (_operateType == SkillOpType.OP_ACTIVE_TOGGLE);
  }
 
  /**
   * Method isPassive.
   * @return boolean
   */
  public final boolean isPassive()
  {
    return _operateType == SkillOpType.OP_PASSIVE;
  }
 
  /**
   * Method isSaveable.
   * @return boolean
   */
  public boolean isSaveable()
  {
    if (!Config.ALT_SAVE_UNSAVEABLE && (isMusic() || _name.startsWith("Herb of")))
    {
      return false;
    }
    return _isSaveable;
  }
 
  /**
   * Method isSkillTimePermanent.
   * @return boolean
   */
  public final boolean isSkillTimePermanent()
  {
    return _isSkillTimePermanent || _isItemHandler || _name.contains("Talisman");
  }
 
  /**
   * Method isReuseDelayPermanent.
   * @return boolean
   */
  public final boolean isReuseDelayPermanent()
  {
    return _isReuseDelayPermanent || _isItemHandler;
  }
 
  /**
   * Method isDeathlink.
   * @return boolean
   */
  public boolean isDeathlink()
  {
    return _deathlink;
  }
 
  /**
   * Method isBasedOnTargetDebuff.
   * @return boolean
   */
  public boolean isBasedOnTargetDebuff()
  {
    return _basedOnTargetDebuff;
  }
 
  /**
   * Method isSoulBoost.
   * @return boolean
   */
  public boolean isSoulBoost()
  {
    return _isSoulBoost;
  }
 
  /**
   * Method isChargeBoost.
   * @return boolean
   */
  public boolean isChargeBoost()
  {
    return _isChargeBoost;
  }
 
  /**
   * Method isUsingWhileCasting.
   * @return boolean
   */
  public boolean isUsingWhileCasting()
  {
    return _isUsingWhileCasting;
  }
 
  /**
   * Method isBehind.
   * @return boolean
   */
  public boolean isBehind()
  {
    return _isBehind;
  }
 
  /**
   * Method isHideStartMessage.
   * @return boolean
   */
  public boolean isHideStartMessage()
  {
    return _hideStartMessage;
  }
 
  /**
   * Method isHideUseMessage.
   * @return boolean
   */
  public boolean isHideUseMessage()
  {
    return _hideUseMessage;
  }
 
  /**
   * Method isSSPossible.
   * @return boolean
   */
  public boolean isSSPossible()
  {
    return (_isUseSS == Ternary.TRUE) || ((_isUseSS == Ternary.DEFAULT) && !_isItemHandler && !isMusic() && isActive() && !((getTargetType() == SkillTargetType.TARGET_SELF) && !isMagic()));
  }
 
  /**
   * Method isSuicideAttack.
   * @return boolean
   */
  public final boolean isSuicideAttack()
  {
    return _isSuicideAttack;
  }
 
  /**
   * Method isToggle.
   * @return boolean
   */
  public final boolean isToggle()
  {
    return (_operateType == SkillOpType.OP_TOGGLE) || (_operateType == SkillOpType.OP_ACTIVE_TOGGLE);
  }
 
  /**
   * Method isActiveToggle.
   * @return boolean
   */
  public final boolean isActiveToggle()
  {
    return _operateType == SkillOpType.OP_ACTIVE_TOGGLE;
  }
 
  /**
   * Method setCastRange.
   * @param castRange int
   */
  public void setCastRange(int castRange)
  {
    _castRange = castRange;
  }
 
  /**
   * Method setDisplayLevel.
   * @param lvl int
   */
  public void setDisplayLevel(int lvl)
  {
    _displayLevel = lvl;
  }
 
  /**
   * Method setHitTime.
   * @param hitTime int
   */
  public void setHitTime(int hitTime)
  {
    _hitTime = hitTime;
  }
 
  /**
   * Method setHpConsume.
   * @param hpConsume int
   */
  public void setHpConsume(int hpConsume)
  {
    _hpConsume = hpConsume;
  }
 
  /**
   * Method setMagicType.
   * @param type SkillMagicType
   */
  public void setMagicType(SkillMagicType type)
  {
    _magicType = type;
  }
 
  /**
   * Method setMagicLevel.
   * @param newlevel int
   */
  public final void setMagicLevel(int newlevel)
  {
    _magicLevel = newlevel;
  }
 
  /**
   * Method setMpConsume1.
   * @param mpConsume1 double
   */
  public void setMpConsume1(double mpConsume1)
  {
    _mpConsume1 = mpConsume1;
  }
 
  /**
   * Method setMpConsume2.
   * @param mpConsume2 double
   */
  public void setMpConsume2(double mpConsume2)
  {
    _mpConsume2 = mpConsume2;
  }
 
  /**
   * Method setName.
   * @param name String
   */
  public void setName(String name)
  {
    _name = name;
  }
 
  /**
   * Method setOverhit.
   * @param isOverhit boolean
   */
  public void setOverhit(final boolean isOverhit)
  {
    _isOverhit = isOverhit;
  }
 
  /**
   * Method setPower.
   * @param power double
   */
  public final void setPower(double power)
  {
    _power = power;
  }
 
  /**
   * Method setSkillInterruptTime.
   * @param skillInterruptTime int
   */
  public void setSkillInterruptTime(int skillInterruptTime)
  {
    _skillInterruptTime = skillInterruptTime;
  }
 
  /**
   * Method isItemSkill.
   * @return boolean
   */
  public boolean isItemSkill()
  {
    return _name.contains("Item Skill") || _name.contains("Talisman");
  }

   
  /**
   * Method toString.
   * @return String
   */
  @Override
  public String toString()
  {
    return _name + "[id=" + _id + ",lvl=" + _level + "]";
  }
 
  /**
   * Method useSkill.
   * @param activeChar Creature
   * @param targets List<Creature>
   */
  public abstract void useSkill(Creature activeChar, List<Creature> targets);
 
  /**
   * Method isAoE.
   * @return boolean
   */
  public boolean isAoE()
  {
    switch (_targetType)
    {
      case TARGET_AREA:
      case TARGET_AREA_AIM_CORPSE:
      case TARGET_AURA:
      case TARGET_GROUND:
      case TARGET_PET_AURA:
      case TARGET_MULTIFACE:
      case TARGET_MULTIFACE_AURA:
      case TARGET_TUNNEL:
        return true;
      default:
        return false;
    }
  }
 
  /**
   * Method isNotTargetAoE.
   * @return boolean
   */
  public boolean isNotTargetAoE()
  {
    switch (_targetType)
    {
      case TARGET_AURA:
      case TARGET_GROUND:
      case TARGET_MULTIFACE_AURA:
      case TARGET_ALLY:
      case TARGET_CLAN:
      case TARGET_CLAN_ONLY:
      case TARGET_PARTY:
      case TARGET_PARTY_WITHOUT_ME:
      case TARGET_SUMMON_AURA:
      case TARGET_SUMMON_AURA_AND_ME:
        return true;
      default:
        return false;
    }
  }
  /**
   * Method isAlterSkill.
   * @return boolean
   */
  public boolean isAlterSkill()
  {
    return _isAlterSkill;
  }

  /**
   * Method isAuraSkill.
   * @return boolean
   */
  public boolean isAuraSkill()
  {
    return _isAuraSkill;
  }
 
  /**
   * Method isOffensive.
   * @return boolean
   */
  public boolean isOffensive()
  {
    return _isOffensive;
  }
 
  /**
   * Method isForceUse.
   * @return boolean
   */
  public final boolean isForceUse()
  {
    return _isForceUse;
  }
 
  /**
   * Method isAI.
   * @return boolean
   */
  public boolean isAI()
  {
    return _skillType.isAI();
  }
 
  /**
   * Method isPvM.
   * @return boolean
   */
  public boolean isPvM()
  {
    return _isPvm;
  }
 
  /**
   * Method isPvpSkill.
   * @return boolean
   */
  public final boolean isPvpSkill()
  {
    return _isPvpSkill;
  }
 
  /**
   * Method isFishingSkill.
   * @return boolean
   */
  public final boolean isFishingSkill()
  {
    return _isFishingSkill;
  }
 
  /**
   * Method isMusic.
   * @return boolean
   */
  public boolean isMusic()
  {
    return _magicType == SkillMagicType.MUSIC;
  }
 
  /**
   * Method isTrigger.
   * @return boolean
   */
  public boolean isTrigger()
  {
    return _isTrigger;
  }
 
  /**
   * Method oneTarget.
   * @return boolean
   */
  public boolean oneTarget()
  {
    switch (_targetType)
    {
      case TARGET_CORPSE:
      case TARGET_CORPSE_PLAYER:
      case TARGET_HOLY:
      case TARGET_FLAGPOLE:
      case TARGET_ITEM:
      case TARGET_NONE:
      case TARGET_MENTEE:
      case TARGET_ONE:
      case TARGET_ONE_PLAYER:
      case TARGET_PARTY_ONE:
      case TARGET_PET:
      case TARGET_SUMMON:
      case TARGET_OWNER:
      case TARGET_ENEMY_PET:
      case TARGET_ENEMY_SUMMON:
      case TARGET_ENEMY_SERVITOR:
      case TARGET_SELF:
      case TARGET_UNLOCKABLE:
      case TARGET_CHEST:
      case TARGET_FEEDABLE_BEAST:
      case TARGET_SIEGE:
        return true;
      default:
        return false;
    }
  }
 
  /**
   * Method getCancelTarget.
   * @return int
   */
  public int getCancelTarget()
  {
    return _cancelTarget;
  }
 
  /**
   * Method isSkillInterrupt.
   * @return boolean
   */
  public boolean isSkillInterrupt()
  {
    return _skillInterrupt;
  }
 
  /**
   * Method isNotUsedByAI.
   * @return boolean
   */
  public boolean isNotUsedByAI()
  {
    return _isNotUsedByAI;
  }
 
  /**
   * Method isIgnoreResists.
   * @return boolean
   */
  public boolean isIgnoreResists()
  {
    return _isIgnoreResists;
  }
 
  /**
   * Method isIgnoreInvul.
   * @return boolean
   */
  public boolean isIgnoreInvul()
  {
    return _isIgnoreInvul;
  }
 
  /**
   * Method isNotAffectedByMute.
   * @return boolean
   */
  public boolean isNotAffectedByMute()
  {
    return _isNotAffectedByMute;
  }
 
  /**
   * Method flyingTransformUsage.
   * @return boolean
   */
  public boolean flyingTransformUsage()
  {
    return _flyingTransformUsage;
  }
 
  /**
   * Method canUseTeleport.
   * @return boolean
   */
  public boolean canUseTeleport()
  {
    return _canUseTeleport;
  }
 
  /**
   * Method getCastCount.
   * @return int
   */
  public int getCastCount()
  {
    return _castCount;
  }
 
  /**
   * Method getEnchantLevelCount.
   * @return int
   */
  public int getEnchantLevelCount()
  {
    return _enchantLevelCount;
  }
 
  /**
   * Method setEnchantLevelCount.
   * @param count int
   */
  public void setEnchantLevelCount(int count)
  {
    _enchantLevelCount = count;
  }
 
  /**
   * Method isClanSkill.
   * @return boolean
   */
  public boolean isClanSkill()
  {
    return ((_id >= 370) && (_id <= 391)) || ((_id >= 611) && (_id <= 616)) || ((_id >= 19003) && (_id <= 19076));
  }
 
  /**
   * Method isBaseTransformation.
   * @return boolean
   */
  public boolean isBaseTransformation()
  {
    return ((_id >= 810) && (_id <= 813)) || ((_id >= 1520) && (_id <= 1522)) || (_id == 538);
  }
 
  /**
   * Method isSummonerTransformation.
   * @return boolean
   */
  public boolean isSummonerTransformation()
  {
    return (_id >= 929) && (_id <= 931);
  }
 
  /**
   * Method getSimpleDamage.
   * @param attacker Creature
   * @param target Creature
   * @return double
   */
  public double getSimpleDamage(Creature attacker, Creature target)
  {
    if (isMagic())
    {
      double mAtk = attacker.getMAtk(target, this);
      double mdef = target.getMDef(null, this);
      double power = getPower();
      int sps = (attacker.getChargedSpiritShot() > 0) && isSSPossible() ? attacker.getChargedSpiritShot() * 2 : 1;
      return (91 * power * Math.sqrt(sps * mAtk)) / mdef;
    }
    double pAtk = attacker.getPAtk(target);
    double pdef = target.getPDef(attacker);
    double power = getPower();
    int ss = attacker.getChargedSoulShot() && isSSPossible() ? 2 : 1;
    return (ss * (pAtk + power) * 70.) / pdef;
  }
 
  /**
   * Method getReuseForMonsters.
   * @return long
   */
  public long getReuseForMonsters()
  {
    long min = 1000;
    switch (_skillType)
    {
      case PARALYZE:
      case DEBUFF:
      case NEGATE_EFFECTS:
      case NEGATE_STATS:
      case STEAL_BUFF:
        min = 10000;
        break;
      case MUTE:
      case ROOT:
      case SLEEP:
      case STUN:
        min = 5000;
        break;
      default:
        break;
    }
    return Math.max(Math.max(_hitTime + _coolTime, _reuseDelay), min);
  }
 
  /**
   * Method getAbsorbPart.
   * @return double
   */
  public double getAbsorbPart()
  {
    return _absorbPart;
  }
 
  /**
   * Method isProvoke.
   * @return boolean
   */
  public boolean isProvoke()
  {
    return _isProvoke;
  }
 
  /**
   * Method getIcon.
   * @return String
   */
  public String getIcon()
  {
    return _icon;
  }
 
  public Boolean isMarkDamage()
  {
    return _isMarkDamage;
  }
 
  /**
   * Method getEnergyConsume.
   * @return int
   */
  public int getEnergyConsume()
  {
    return _energyConsume;
  }
 
  /**
   * Method setCubicSkill.
   * @param value boolean
   */
  public void setCubicSkill(boolean value)
  {
    _isCubicSkill = value;
  }
 
  /**
   * Method isCubicSkill.
   * @return boolean
   */
  public boolean isCubicSkill()
  {
    return _isCubicSkill;
  }
 
  /**
   * Method getReuseGroupId.
   * @return int
   */
  public int getReuseGroupId()
  {
    return reuseGroupId;
  }
 
  /**
   * Method getRelationSkills.
   * @return int[]
   */
  public int[] getRelationSkills()
  {
    return _relationSkillsId;
  }
 
  /**
   * Method isRelationSkill.
   * @return boolean
   */
  public boolean isRelationSkill()
  {
    return _isRelation;
  }
 
  /**
   * Method getFlySpeed.
   * @return int
   */
  public int getFlySpeed()
  {
    return _flySpeed;
  }

  public boolean isPowerModified()
  {   
    return _isPowerModified;
  }
}
TOP

Related Classes of lineage2.gameserver.model.Skill$AddedSkill

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.