/*
* 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;
}
}