Chain skill rework.

This commit is contained in:
MobiusDevelopment
2020-03-29 08:27:18 +00:00
parent d8021624a1
commit 9cb1ed319e
39 changed files with 1241 additions and 1221 deletions

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.enums.CategoryType; import org.l2jmobius.gameserver.enums.CategoryType;
@@ -28,7 +30,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
@@ -38,44 +39,44 @@ import org.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} }
public AirBind(StatSet params) public AirBind(StatSet params)
@@ -88,24 +89,22 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) if (!ACTIVE_AIRBINDS.contains(effected))
{ {
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // ACTIVE_AIRBINDS.add(effected);
&& nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{ {
final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
}
} }
} }
} }
@@ -114,6 +113,8 @@ public class AirBind extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_AIRBINDS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);

View File

@@ -18,6 +18,8 @@ package handlers.effecthandlers;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
@@ -31,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.base.ClassId; import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -54,44 +55,44 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
// skill data private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainKnockSkills = new EnumMap<>(ClassId.class); private static final Map<ClassId, Integer> KNOCKBACK_SKILLS = new EnumMap<>(ClassId.class);
static static
{ {
_chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit
_chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit KNOCKBACK_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit
} }
public KnockBack(StatSet params) public KnockBack(StatSet params)
@@ -116,12 +117,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -143,6 +138,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -151,40 +148,41 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
}
// Prevent knocking back raids and town NPCs.
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected)); if (effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if (nearbyPlayer.getRace() == Race.ERTHEIA)
{ {
continue; return;
} }
if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{ {
final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); effected.setHeading(Util.calculateHeadingFrom(effected, effector));
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) }
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
{
if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
{ {
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); final int chainSkill = KNOCKBACK_SKILLS.get(nearbyPlayer.getClassId());
if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
{
nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3));
}
} }
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,

View File

@@ -16,14 +16,13 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.HashMap; import java.util.Set;
import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.base.ClassId;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
@@ -32,45 +31,45 @@ import org.l2jmobius.gameserver.model.skills.Skill;
*/ */
public class AirBind extends AbstractEffect public class AirBind extends AbstractEffect
{ {
// skill data private static final Set<Creature> ACTIVE_AIRBINDS = ConcurrentHashMap.newKeySet();
private static final Map<ClassId, Integer> _chainedAirSkills = new HashMap<>(36); // private static final Map<ClassId, Integer> AIRBIND_SKILLS = new EnumMap<>(ClassId.class);
static // static
{ // {
_chainedAirSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.SIGEL_HELL_KNIGHT, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.SIGEL_EVA_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10249); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_DUELIST, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_DREADNOUGHT, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_TITAN, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_GRAND_KHAVATARI, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_MAESTRO, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.TYRR_DOOMBRINGER, 10499); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.OTHELL_ADVENTURER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.OTHELL_WIND_RIDER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.OTHELL_GHOST_HUNTER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.OTHELL_FORTUNE_SEEKER, 10749); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.YUL_SAGITTARIUS, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.YUL_MOONLIGHT_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.YUL_GHOST_SENTINEL, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.YUL_TRICKSTER, 10999); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.FEOH_ARCHMAGE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.FEOH_SOULTAKER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.FEOH_MYSTIC_MUSE, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.FEOH_STORM_SCREAMER, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.FEOH_SOUL_HOUND, 11249); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.ISS_HIEROPHANT, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.ISS_SWORD_MUSE, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.ISS_SPECTRAL_DANCER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.ISS_DOMINATOR, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.ISS_DOOMCRYER, 11749); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.WYNN_ARCANA_LORD, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.WYNN_ELEMENTAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.WYNN_SPECTRAL_MASTER, 11499); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.AEORE_CARDINAL, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.AEORE_EVA_SAINT, 11999); // Heavy Hit
_chainedAirSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit // AIRBIND_SKILLS.put(ClassId.AEORE_SHILLIEN_SAINT, 11999); // Heavy Hit
} // }
public AirBind(StatSet params) public AirBind(StatSet params)
{ {
@@ -82,26 +81,35 @@ public class AirBind extends AbstractEffect
return false; return false;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void continuousInstant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
/* if (!ACTIVE_AIRBINDS.contains(effected))
* for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200)) { if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) // && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && {
* !nearbyPlayer.isAlterSkillActive()) { final int chainSkill = _chainedAirSkills.get(nearbyPlayer.getClassId()); if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1) { nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5)); } } } ACTIVE_AIRBINDS.add(effected);
*/
// for (PlayerInstance nearbyPlayer : World.getInstance().getVisibleObjectsInRange(effected, PlayerInstance.class, 1200))
// {
// if ((nearbyPlayer.getRace() != Race.ERTHEIA) && (nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.SIXTH_CLASS_GROUP) && !nearbyPlayer.isAlterSkillActive())
// {
// final int chainSkill = AIRBIND_SKILLS.get(nearbyPlayer.getClassId());
// if (nearbyPlayer.getSkillRemainingReuseTime(chainSkill) == -1)
// {
// nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 5));
// }
// }
// }
}
} }
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
/* ACTIVE_AIRBINDS.remove(effected);
* if (!effected.isPlayer()) { effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); }
*/ if (!effected.isPlayer())
{
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
}
} }
} }

View File

@@ -16,6 +16,9 @@
*/ */
package handlers.effecthandlers; package handlers.effecthandlers;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.l2jmobius.gameserver.ai.CtrlEvent; import org.l2jmobius.gameserver.ai.CtrlEvent;
import org.l2jmobius.gameserver.ai.CtrlIntention; import org.l2jmobius.gameserver.ai.CtrlIntention;
import org.l2jmobius.gameserver.geoengine.GeoEngine; import org.l2jmobius.gameserver.geoengine.GeoEngine;
@@ -23,7 +26,6 @@ import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatSet; import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature; import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.effects.AbstractEffect; import org.l2jmobius.gameserver.model.effects.AbstractEffect;
import org.l2jmobius.gameserver.model.effects.EffectType;
import org.l2jmobius.gameserver.model.items.instance.ItemInstance; import org.l2jmobius.gameserver.model.items.instance.ItemInstance;
import org.l2jmobius.gameserver.model.skills.Skill; import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.stats.Formulas; import org.l2jmobius.gameserver.model.stats.Formulas;
@@ -45,6 +47,8 @@ public class KnockBack extends AbstractEffect
private final boolean _knockDown; private final boolean _knockDown;
private final FlyType _type; private final FlyType _type;
private static final Set<Creature> ACTIVE_KNOCKBACKS = ConcurrentHashMap.newKeySet();
public KnockBack(StatSet params) public KnockBack(StatSet params)
{ {
_distance = params.getInt("distance", 50); _distance = params.getInt("distance", 50);
@@ -67,12 +71,6 @@ public class KnockBack extends AbstractEffect
return !_knockDown; return !_knockDown;
} }
@Override
public EffectType getEffectType()
{
return EffectType.KNOCK;
}
@Override @Override
public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item) public void instant(Creature effector, Creature effected, Skill skill, ItemInstance item)
{ {
@@ -94,6 +92,8 @@ public class KnockBack extends AbstractEffect
@Override @Override
public void onExit(Creature effector, Creature effected, Skill skill) public void onExit(Creature effector, Creature effected, Skill skill)
{ {
ACTIVE_KNOCKBACKS.remove(effected);
if (!effected.isPlayer()) if (!effected.isPlayer())
{ {
effected.getAI().notifyEvent(CtrlEvent.EVT_THINK); effected.getAI().notifyEvent(CtrlEvent.EVT_THINK);
@@ -102,26 +102,31 @@ public class KnockBack extends AbstractEffect
private void knockBack(Creature effector, Creature effected) private void knockBack(Creature effector, Creature effected)
{ {
// Prevent knocking back raids and town NPCs. if (!ACTIVE_KNOCKBACKS.contains(effected))
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{ {
return; ACTIVE_KNOCKBACKS.add(effected);
// Prevent knocking back raids and town NPCs.
if ((effected == null) || effected.isRaid() || (effected.isNpc() && !effected.isAttackable()))
{
return;
}
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
final double radians = Math.toRadians(Util.calculateAngleFrom(effector, effected));
final int x = (int) (effected.getX() + (_distance * Math.cos(radians)));
final int y = (int) (effected.getY() + (_distance * Math.sin(radians)));
final int z = effected.getZ();
final Location loc = GeoEngine.getInstance().canMoveToTargetLoc(effected.getX(), effected.getY(), effected.getZ(), x, y, z, effected.getInstanceWorld());
effected.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
effected.broadcastPacket(new FlyToLocation(effected, loc, _type, _speed, _delay, _animationSpeed));
if (_knockDown)
{
effected.setHeading(Util.calculateHeadingFrom(effected, effector));
}
effected.setXYZ(loc);
effected.broadcastPacket(new ValidateLocation(effected));
effected.revalidateZone(true);
} }
} }

View File

@@ -57,7 +57,6 @@ public enum EffectType
SLEEP, SLEEP,
STEAL_ABNORMAL, STEAL_ABNORMAL,
BLOCK_ACTIONS, BLOCK_ACTIONS,
KNOCK,
SUMMON, SUMMON,
SUMMON_PET, SUMMON_PET,
SUMMON_NPC, SUMMON_NPC,