From acb163259c23ecd9f3de7c320bf653d477099a3e Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Tue, 7 Nov 2017 15:43:21 +0000 Subject: [PATCH] Support for knockback chain skills. --- .../dist/game/config/Character.ini | 3 + .../handlers/effecthandlers/KnockBack.java | 63 ++++++++++++++++++- .../java/com/l2jmobius/Config.java | 2 + .../model/actor/instance/L2PcInstance.java | 19 ++++++ .../serverpackets/ExAlterSkillRequest.java | 25 +++++++- .../dist/game/config/Character.ini | 3 + .../handlers/effecthandlers/KnockBack.java | 63 ++++++++++++++++++- .../java/com/l2jmobius/Config.java | 2 + .../model/actor/instance/L2PcInstance.java | 19 ++++++ .../serverpackets/ExAlterSkillRequest.java | 25 +++++++- .../dist/game/config/Character.ini | 3 + .../handlers/effecthandlers/KnockBack.java | 63 ++++++++++++++++++- .../java/com/l2jmobius/Config.java | 2 + .../model/actor/instance/L2PcInstance.java | 19 ++++++ .../serverpackets/ExAlterSkillRequest.java | 25 +++++++- 15 files changed, 327 insertions(+), 9 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/config/Character.ini b/L2J_Mobius_1.0_Ertheia/dist/game/config/Character.ini index dc52986fec..1124e06eda 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/config/Character.ini +++ b/L2J_Mobius_1.0_Ertheia/dist/game/config/Character.ini @@ -140,6 +140,9 @@ SubclassStoreSkillCooltime = False # Default: 666 EffectTickRatio = 666 +# This option will enable alter skills (chain skills) +EnableAlterSkills = True + # --------------------------------------------------------------------------- # Class, Sub-class and skill learning options diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java index e2ddb48286..c7be363c4e 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java @@ -16,18 +16,27 @@ */ package handlers.effecthandlers; +import java.util.HashMap; +import java.util.Map; + import com.l2jmobius.gameserver.ai.CtrlEvent; import com.l2jmobius.gameserver.ai.CtrlIntention; +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.Race; import com.l2jmobius.gameserver.geoengine.GeoEngine; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.base.ClassId; import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.effects.L2EffectType; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.skills.BuffInfo; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.model.stats.Formulas; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType; import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation; @@ -35,7 +44,7 @@ import com.l2jmobius.gameserver.util.Util; /** * Check if this effect is not counted as being stunned. - * @author UnAfraid + * @author UnAfraid, Mobius */ public final class KnockBack extends AbstractEffect { @@ -46,6 +55,45 @@ public final class KnockBack extends AbstractEffect private final boolean _knockDown; private final FlyType _type; + // skill data + private static final Map _chainKnockSkills = new HashMap<>(36); + { + _chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit + } + public KnockBack(StatsSet params) { _distance = params.getInt("distance", 50); @@ -118,5 +166,18 @@ public final class KnockBack extends AbstractEffect effected.setXYZ(loc); effected.broadcastPacket(new ValidateLocation(effected)); effected.revalidateZone(true); + + for (L2PcInstance nearbyPlayer : L2World.getInstance().getVisibleObjects(effected, L2PcInstance.class, 1200)) + { + if (nearbyPlayer.getRace() == Race.ERTHEIA) + { + continue; + } + if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.AWAKEN_GROUP) && !nearbyPlayer.isAlterSkillActive()) + { + final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); + nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); + } + } } } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/Config.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/Config.java index dcbe8fe7c5..076ee7776e 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/Config.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/Config.java @@ -168,6 +168,7 @@ public final class Config public static boolean SUBCLASS_STORE_SKILL_COOLTIME; public static boolean SUMMON_STORE_SKILL_COOLTIME; public static long EFFECT_TICK_RATIO; + public static boolean ENABLE_ALTER_SKILLS; public static boolean LIFE_CRYSTAL_NEEDED; public static boolean ES_SP_BOOK_NEEDED; public static boolean DIVINE_SP_BOOK_NEEDED; @@ -1459,6 +1460,7 @@ public final class Config SUBCLASS_STORE_SKILL_COOLTIME = Character.getBoolean("SubclassStoreSkillCooltime", false); SUMMON_STORE_SKILL_COOLTIME = Character.getBoolean("SummonStoreSkillCooltime", true); EFFECT_TICK_RATIO = Character.getLong("EffectTickRatio", 666); + ENABLE_ALTER_SKILLS = Character.getBoolean("EnableAlterSkills", true); LIFE_CRYSTAL_NEEDED = Character.getBoolean("LifeCrystalNeeded", true); ES_SP_BOOK_NEEDED = Character.getBoolean("EnchantSkillSpBookNeeded", true); DIVINE_SP_BOOK_NEEDED = Character.getBoolean("DivineInspirationSpBookNeeded", true); diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index fb50687c3d..37f5893390 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -270,6 +270,7 @@ import com.l2jmobius.gameserver.network.serverpackets.ConfirmDlg; import com.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import com.l2jmobius.gameserver.network.serverpackets.ExAbnormalStatusUpdateFromTarget; import com.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import com.l2jmobius.gameserver.network.serverpackets.ExDuelUpdateUserInfo; import com.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; @@ -752,6 +753,7 @@ public final class L2PcInstance extends L2Playable /** Skills queued because a skill is already in progress */ private SkillUseHolder _queuedSkill; + private boolean _alterSkillActive = false; private int _cursedWeaponEquippedId = 0; private boolean _combatFlagEquippedId = false; @@ -8304,6 +8306,13 @@ public final class L2PcInstance extends L2Playable skill = attachedSkill; } + // Alter skills + if (_alterSkillActive) + { + sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _alterSkillActive = false; + } + // ************************************* Check Player State ******************************************* // Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic() @@ -11242,6 +11251,16 @@ public final class L2PcInstance extends L2Playable _queuedSkill = new SkillUseHolder(queuedSkill, item, ctrlPressed, shiftPressed); } + public boolean isAlterSkillActive() + { + return _alterSkillActive; + } + + public void setAlterSkillActive(boolean alterSkillActive) + { + _alterSkillActive = alterSkillActive; + } + /** * @return {@code true} if player is jailed, {@code false} otherwise. */ diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java index e973bd9962..4fe79bf68d 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java @@ -16,20 +16,25 @@ */ package com.l2jmobius.gameserver.network.serverpackets; +import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.ThreadPoolManager; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; /** - * @author UnAfraid + * @author UnAfraid, Mobius */ public class ExAlterSkillRequest implements IClientOutgoingPacket { private final int _currentSkillId; private final int _nextSkillId; private final int _alterTime; + private final L2PcInstance _player; - public ExAlterSkillRequest(int currentSkill, int nextSkill, int alterTime) + public ExAlterSkillRequest(L2PcInstance player, int currentSkill, int nextSkill, int alterTime) { + _player = player; _currentSkillId = currentSkill; _nextSkillId = nextSkill; _alterTime = alterTime; @@ -38,10 +43,26 @@ public class ExAlterSkillRequest implements IClientOutgoingPacket @Override public boolean write(PacketWriter packet) { + if (!Config.ENABLE_ALTER_SKILLS) + { + return true; + } + OutgoingPackets.EX_ALTER_SKILL_REQUEST.writeId(packet); packet.writeD(_nextSkillId); packet.writeD(_currentSkillId); packet.writeD(_alterTime); + + if (_alterTime > 0) + { + _player.setAlterSkillActive(true); + ThreadPoolManager.schedule(() -> + { + _player.sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _player.setAlterSkillActive(false); + }, _alterTime * 1000); + } + return true; } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/config/Character.ini b/L2J_Mobius_2.5_Underground/dist/game/config/Character.ini index ddaa169ab3..3cb4b0882b 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/config/Character.ini +++ b/L2J_Mobius_2.5_Underground/dist/game/config/Character.ini @@ -140,6 +140,9 @@ SubclassStoreSkillCooltime = False # Default: 666 EffectTickRatio = 666 +# This option will enable alter skills (chain skills) +EnableAlterSkills = True + # --------------------------------------------------------------------------- # Class, Sub-class and skill learning options diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java index e2ddb48286..c7be363c4e 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java @@ -16,18 +16,27 @@ */ package handlers.effecthandlers; +import java.util.HashMap; +import java.util.Map; + import com.l2jmobius.gameserver.ai.CtrlEvent; import com.l2jmobius.gameserver.ai.CtrlIntention; +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.Race; import com.l2jmobius.gameserver.geoengine.GeoEngine; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.base.ClassId; import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.effects.L2EffectType; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.skills.BuffInfo; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.model.stats.Formulas; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType; import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation; @@ -35,7 +44,7 @@ import com.l2jmobius.gameserver.util.Util; /** * Check if this effect is not counted as being stunned. - * @author UnAfraid + * @author UnAfraid, Mobius */ public final class KnockBack extends AbstractEffect { @@ -46,6 +55,45 @@ public final class KnockBack extends AbstractEffect private final boolean _knockDown; private final FlyType _type; + // skill data + private static final Map _chainKnockSkills = new HashMap<>(36); + { + _chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit + } + public KnockBack(StatsSet params) { _distance = params.getInt("distance", 50); @@ -118,5 +166,18 @@ public final class KnockBack extends AbstractEffect effected.setXYZ(loc); effected.broadcastPacket(new ValidateLocation(effected)); effected.revalidateZone(true); + + for (L2PcInstance nearbyPlayer : L2World.getInstance().getVisibleObjects(effected, L2PcInstance.class, 1200)) + { + if (nearbyPlayer.getRace() == Race.ERTHEIA) + { + continue; + } + if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.AWAKEN_GROUP) && !nearbyPlayer.isAlterSkillActive()) + { + final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); + nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); + } + } } } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/Config.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/Config.java index 8c5d68cf9f..2745eff147 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/Config.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/Config.java @@ -168,6 +168,7 @@ public final class Config public static boolean SUBCLASS_STORE_SKILL_COOLTIME; public static boolean SUMMON_STORE_SKILL_COOLTIME; public static long EFFECT_TICK_RATIO; + public static boolean ENABLE_ALTER_SKILLS; public static boolean LIFE_CRYSTAL_NEEDED; public static boolean ES_SP_BOOK_NEEDED; public static boolean DIVINE_SP_BOOK_NEEDED; @@ -1460,6 +1461,7 @@ public final class Config SUBCLASS_STORE_SKILL_COOLTIME = Character.getBoolean("SubclassStoreSkillCooltime", false); SUMMON_STORE_SKILL_COOLTIME = Character.getBoolean("SummonStoreSkillCooltime", true); EFFECT_TICK_RATIO = Character.getLong("EffectTickRatio", 666); + ENABLE_ALTER_SKILLS = Character.getBoolean("EnableAlterSkills", true); LIFE_CRYSTAL_NEEDED = Character.getBoolean("LifeCrystalNeeded", true); ES_SP_BOOK_NEEDED = Character.getBoolean("EnchantSkillSpBookNeeded", true); DIVINE_SP_BOOK_NEEDED = Character.getBoolean("DivineInspirationSpBookNeeded", true); diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 23c1c9865f..48f116f5cb 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -269,6 +269,7 @@ import com.l2jmobius.gameserver.network.serverpackets.ConfirmDlg; import com.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import com.l2jmobius.gameserver.network.serverpackets.ExAbnormalStatusUpdateFromTarget; import com.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import com.l2jmobius.gameserver.network.serverpackets.ExDuelUpdateUserInfo; import com.l2jmobius.gameserver.network.serverpackets.ExGetBookMarkInfoPacket; @@ -751,6 +752,7 @@ public final class L2PcInstance extends L2Playable /** Skills queued because a skill is already in progress */ private SkillUseHolder _queuedSkill; + private boolean _alterSkillActive = false; private int _cursedWeaponEquippedId = 0; private boolean _combatFlagEquippedId = false; @@ -8304,6 +8306,13 @@ public final class L2PcInstance extends L2Playable skill = attachedSkill; } + // Alter skills + if (_alterSkillActive) + { + sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _alterSkillActive = false; + } + // ************************************* Check Player State ******************************************* // Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic() @@ -11243,6 +11252,16 @@ public final class L2PcInstance extends L2Playable _queuedSkill = new SkillUseHolder(queuedSkill, item, ctrlPressed, shiftPressed); } + public boolean isAlterSkillActive() + { + return _alterSkillActive; + } + + public void setAlterSkillActive(boolean alterSkillActive) + { + _alterSkillActive = alterSkillActive; + } + /** * @return {@code true} if player is jailed, {@code false} otherwise. */ diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java index e973bd9962..4fe79bf68d 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java @@ -16,20 +16,25 @@ */ package com.l2jmobius.gameserver.network.serverpackets; +import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.ThreadPoolManager; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; /** - * @author UnAfraid + * @author UnAfraid, Mobius */ public class ExAlterSkillRequest implements IClientOutgoingPacket { private final int _currentSkillId; private final int _nextSkillId; private final int _alterTime; + private final L2PcInstance _player; - public ExAlterSkillRequest(int currentSkill, int nextSkill, int alterTime) + public ExAlterSkillRequest(L2PcInstance player, int currentSkill, int nextSkill, int alterTime) { + _player = player; _currentSkillId = currentSkill; _nextSkillId = nextSkill; _alterTime = alterTime; @@ -38,10 +43,26 @@ public class ExAlterSkillRequest implements IClientOutgoingPacket @Override public boolean write(PacketWriter packet) { + if (!Config.ENABLE_ALTER_SKILLS) + { + return true; + } + OutgoingPackets.EX_ALTER_SKILL_REQUEST.writeId(packet); packet.writeD(_nextSkillId); packet.writeD(_currentSkillId); packet.writeD(_alterTime); + + if (_alterTime > 0) + { + _player.setAlterSkillActive(true); + ThreadPoolManager.schedule(() -> + { + _player.sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _player.setAlterSkillActive(false); + }, _alterTime * 1000); + } + return true; } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/config/Character.ini b/L2J_Mobius_3.0_Helios/dist/game/config/Character.ini index ddaa169ab3..3cb4b0882b 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/config/Character.ini +++ b/L2J_Mobius_3.0_Helios/dist/game/config/Character.ini @@ -140,6 +140,9 @@ SubclassStoreSkillCooltime = False # Default: 666 EffectTickRatio = 666 +# This option will enable alter skills (chain skills) +EnableAlterSkills = True + # --------------------------------------------------------------------------- # Class, Sub-class and skill learning options diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java index e2ddb48286..c7be363c4e 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/KnockBack.java @@ -16,18 +16,27 @@ */ package handlers.effecthandlers; +import java.util.HashMap; +import java.util.Map; + import com.l2jmobius.gameserver.ai.CtrlEvent; import com.l2jmobius.gameserver.ai.CtrlIntention; +import com.l2jmobius.gameserver.enums.CategoryType; +import com.l2jmobius.gameserver.enums.Race; import com.l2jmobius.gameserver.geoengine.GeoEngine; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.Location; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; +import com.l2jmobius.gameserver.model.base.ClassId; import com.l2jmobius.gameserver.model.effects.AbstractEffect; import com.l2jmobius.gameserver.model.effects.L2EffectType; import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance; import com.l2jmobius.gameserver.model.skills.BuffInfo; import com.l2jmobius.gameserver.model.skills.Skill; import com.l2jmobius.gameserver.model.stats.Formulas; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation; import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType; import com.l2jmobius.gameserver.network.serverpackets.ValidateLocation; @@ -35,7 +44,7 @@ import com.l2jmobius.gameserver.util.Util; /** * Check if this effect is not counted as being stunned. - * @author UnAfraid + * @author UnAfraid, Mobius */ public final class KnockBack extends AbstractEffect { @@ -46,6 +55,45 @@ public final class KnockBack extends AbstractEffect private final boolean _knockDown; private final FlyType _type; + // skill data + private static final Map _chainKnockSkills = new HashMap<>(36); + { + _chainKnockSkills.put(ClassId.SIGEL_PHOENIX_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_HELL_KNIGHT, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_EVA_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.SIGEL_SHILLIEN_TEMPLAR, 10250); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DUELIST, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DREADNOUGHT, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_TITAN, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_GRAND_KHAVATARI, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_MAESTRO, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.TYRR_DOOMBRINGER, 10500); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_ADVENTURER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_WIND_RIDER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_GHOST_HUNTER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.OTHELL_FORTUNE_SEEKER, 10750); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_SAGITTARIUS, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_MOONLIGHT_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_GHOST_SENTINEL, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.YUL_TRICKSTER, 11000); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_ARCHMAGE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOULTAKER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_MYSTIC_MUSE, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_STORM_SCREAMER, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.FEOH_SOUL_HOUND, 11250); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_HIEROPHANT, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SWORD_MUSE, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_SPECTRAL_DANCER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOMINATOR, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.ISS_DOOMCRYER, 11750); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ARCANA_LORD, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_ELEMENTAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.WYNN_SPECTRAL_MASTER, 11500); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_CARDINAL, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_EVA_SAINT, 12000); // Heavy Hit + _chainKnockSkills.put(ClassId.AEORE_SHILLIEN_SAINT, 12000); // Heavy Hit + } + public KnockBack(StatsSet params) { _distance = params.getInt("distance", 50); @@ -118,5 +166,18 @@ public final class KnockBack extends AbstractEffect effected.setXYZ(loc); effected.broadcastPacket(new ValidateLocation(effected)); effected.revalidateZone(true); + + for (L2PcInstance nearbyPlayer : L2World.getInstance().getVisibleObjects(effected, L2PcInstance.class, 1200)) + { + if (nearbyPlayer.getRace() == Race.ERTHEIA) + { + continue; + } + if ((nearbyPlayer.getTarget() == effected) && nearbyPlayer.isInCategory(CategoryType.AWAKEN_GROUP) && !nearbyPlayer.isAlterSkillActive()) + { + final int chainSkill = _chainKnockSkills.get(nearbyPlayer.getClassId()); + nearbyPlayer.sendPacket(new ExAlterSkillRequest(nearbyPlayer, chainSkill, chainSkill, 3)); + } + } } } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/Config.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/Config.java index 85cb12d0f6..e822225315 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/Config.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/Config.java @@ -168,6 +168,7 @@ public final class Config public static boolean SUBCLASS_STORE_SKILL_COOLTIME; public static boolean SUMMON_STORE_SKILL_COOLTIME; public static long EFFECT_TICK_RATIO; + public static boolean ENABLE_ALTER_SKILLS; public static boolean LIFE_CRYSTAL_NEEDED; public static boolean ES_SP_BOOK_NEEDED; public static boolean DIVINE_SP_BOOK_NEEDED; @@ -1468,6 +1469,7 @@ public final class Config SUBCLASS_STORE_SKILL_COOLTIME = Character.getBoolean("SubclassStoreSkillCooltime", false); SUMMON_STORE_SKILL_COOLTIME = Character.getBoolean("SummonStoreSkillCooltime", true); EFFECT_TICK_RATIO = Character.getLong("EffectTickRatio", 666); + ENABLE_ALTER_SKILLS = Character.getBoolean("EnableAlterSkills", true); LIFE_CRYSTAL_NEEDED = Character.getBoolean("LifeCrystalNeeded", true); ES_SP_BOOK_NEEDED = Character.getBoolean("EnchantSkillSpBookNeeded", true); DIVINE_SP_BOOK_NEEDED = Character.getBoolean("DivineInspirationSpBookNeeded", true); diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 60ee7f3fcd..1493ce0153 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -270,6 +270,7 @@ import com.l2jmobius.gameserver.network.serverpackets.ConfirmDlg; import com.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate; import com.l2jmobius.gameserver.network.serverpackets.ExAbnormalStatusUpdateFromTarget; import com.l2jmobius.gameserver.network.serverpackets.ExAdenaInvenCount; +import com.l2jmobius.gameserver.network.serverpackets.ExAlterSkillRequest; import com.l2jmobius.gameserver.network.serverpackets.ExAutoSoulShot; import com.l2jmobius.gameserver.network.serverpackets.ExBrPremiumState; import com.l2jmobius.gameserver.network.serverpackets.ExDuelUpdateUserInfo; @@ -753,6 +754,7 @@ public final class L2PcInstance extends L2Playable /** Skills queued because a skill is already in progress */ private SkillUseHolder _queuedSkill; + private boolean _alterSkillActive = false; private int _cursedWeaponEquippedId = 0; private boolean _combatFlagEquippedId = false; @@ -8306,6 +8308,13 @@ public final class L2PcInstance extends L2Playable skill = attachedSkill; } + // Alter skills + if (_alterSkillActive) + { + sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _alterSkillActive = false; + } + // ************************************* Check Player State ******************************************* // Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic() @@ -11253,6 +11262,16 @@ public final class L2PcInstance extends L2Playable _queuedSkill = new SkillUseHolder(queuedSkill, item, ctrlPressed, shiftPressed); } + public boolean isAlterSkillActive() + { + return _alterSkillActive; + } + + public void setAlterSkillActive(boolean alterSkillActive) + { + _alterSkillActive = alterSkillActive; + } + /** * @return {@code true} if player is jailed, {@code false} otherwise. */ diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java index e973bd9962..4fe79bf68d 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/serverpackets/ExAlterSkillRequest.java @@ -16,20 +16,25 @@ */ package com.l2jmobius.gameserver.network.serverpackets; +import com.l2jmobius.Config; import com.l2jmobius.commons.network.PacketWriter; +import com.l2jmobius.gameserver.ThreadPoolManager; +import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.network.OutgoingPackets; /** - * @author UnAfraid + * @author UnAfraid, Mobius */ public class ExAlterSkillRequest implements IClientOutgoingPacket { private final int _currentSkillId; private final int _nextSkillId; private final int _alterTime; + private final L2PcInstance _player; - public ExAlterSkillRequest(int currentSkill, int nextSkill, int alterTime) + public ExAlterSkillRequest(L2PcInstance player, int currentSkill, int nextSkill, int alterTime) { + _player = player; _currentSkillId = currentSkill; _nextSkillId = nextSkill; _alterTime = alterTime; @@ -38,10 +43,26 @@ public class ExAlterSkillRequest implements IClientOutgoingPacket @Override public boolean write(PacketWriter packet) { + if (!Config.ENABLE_ALTER_SKILLS) + { + return true; + } + OutgoingPackets.EX_ALTER_SKILL_REQUEST.writeId(packet); packet.writeD(_nextSkillId); packet.writeD(_currentSkillId); packet.writeD(_alterTime); + + if (_alterTime > 0) + { + _player.setAlterSkillActive(true); + ThreadPoolManager.schedule(() -> + { + _player.sendPacket(new ExAlterSkillRequest(null, -1, -1, -1)); + _player.setAlterSkillActive(false); + }, _alterTime * 1000); + } + return true; } }