diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/MasterHandler.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/MasterHandler.java
index cf3e6615cd..f9a9d3921c 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/MasterHandler.java
@@ -181,6 +181,7 @@ import handlers.communityboard.RegionBoard;
import handlers.itemhandlers.Appearance;
import handlers.itemhandlers.BeastSoulShot;
import handlers.itemhandlers.BeastSpiritShot;
+import handlers.itemhandlers.BlessedSoulShots;
import handlers.itemhandlers.BlessedSpiritShot;
import handlers.itemhandlers.Book;
import handlers.itemhandlers.Bypass;
@@ -497,6 +498,7 @@ public class MasterHandler
Appearance.class,
BeastSoulShot.class,
BeastSpiritShot.class,
+ BlessedSoulShots.class,
BlessedSpiritShot.class,
Book.class,
Bypass.class,
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/Backstab.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
index c9a6db7ddf..0a9760db2b 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
@@ -78,7 +78,7 @@ public final class Backstab extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, true, _power, shld, ss);
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
index ab74235f45..6086cd5051 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
@@ -139,7 +139,18 @@ public final class EnergyAttack extends AbstractEffect
// Skill specific mods.
final double energyChargesBoost = 1 + (charge * 0.1); // 10% bonus damage for each charge used.
final double critMod = critical ? Formulas.calcCritDamage(attacker, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && attacker.isChargedShot(ShotType.SOULSHOTS)) ? (2 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (attacker.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * attacker.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (attacker.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * attacker.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................________Initial Damage_________...__Charges Additional Damage__...____________________________________
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
index 560373de58..3991d26090 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
@@ -108,7 +108,7 @@ public final class FatalBlow extends AbstractEffect
power += _abnormalPower;
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, power, shld, ss);
final boolean crit = Formulas.calcCrit(_criticalChance, effector, effected, skill);
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
index 3e3f266a98..959f47aac4 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
@@ -151,7 +151,18 @@ public final class PhysicalAttack extends AbstractEffect
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double abnormalMod = _abnormals.stream().anyMatch(effected::hasAbnormalType) ? _abnormalPowerMod : 1;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
index 3572414842..71410e4865 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
@@ -113,7 +113,18 @@ public final class PhysicalAttackHpLink extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
index b9d7172f2d..e03f74aa73 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
@@ -123,7 +123,18 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
index 58720b8cc4..774c4cee99 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
@@ -144,7 +144,18 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
final double weaponBonus = _weaponBonus.getOrDefault(effector.getAttackType(), 1.0);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
index db8d2dcb0f..402b0ea3fd 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
@@ -137,7 +137,18 @@ public final class PhysicalSoulAttack extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? (2 * effector.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
final double soulsMod = 1 + (souls * 0.04); // Souls Formula (each soul increase +4%)
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
index 999daafeb0..02f6612439 100644
--- a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
@@ -82,7 +82,7 @@ public final class SoulBlow extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, _power, shld, ss);
if ((skill.getMaxSoulConsumeCount() > 0) && effector.isPlayer())
diff --git a/L2J_Mobius_Classic/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
new file mode 100644
index 0000000000..b8a223f1d4
--- /dev/null
+++ b/L2J_Mobius_Classic/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package handlers.itemhandlers;
+
+import java.util.List;
+
+import com.l2jmobius.commons.util.Rnd;
+import com.l2jmobius.gameserver.enums.ItemSkillType;
+import com.l2jmobius.gameserver.enums.ShotType;
+import com.l2jmobius.gameserver.handler.IItemHandler;
+import com.l2jmobius.gameserver.model.actor.L2Playable;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
+import com.l2jmobius.gameserver.model.items.L2Weapon;
+import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jmobius.gameserver.model.items.type.ActionType;
+import com.l2jmobius.gameserver.network.SystemMessageId;
+import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jmobius.gameserver.util.Broadcast;
+
+/**
+ * @author Mobius
+ */
+public class BlessedSoulShots implements IItemHandler
+{
+ @Override
+ public boolean useItem(L2Playable playable, L2ItemInstance item, boolean forceUse)
+ {
+ if (!playable.isPlayer())
+ {
+ playable.sendPacket(SystemMessageId.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
+ return false;
+ }
+
+ final L2PcInstance activeChar = playable.getActingPlayer();
+ final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
+ final L2Weapon weaponItem = activeChar.getActiveWeaponItem();
+ final List skills = item.getItem().getSkills(ItemSkillType.NORMAL);
+ if (skills == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": is missing skills!");
+ return false;
+ }
+
+ final int itemId = item.getId();
+
+ // Check if Soul shot can be used
+ if ((weaponInst == null) || (weaponItem.getSoulShotCount() == 0))
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_SOULSHOTS);
+ }
+ return false;
+ }
+
+ final boolean gradeCheck = item.isEtcItem() && (item.getEtcItem().getDefaultAction() == ActionType.SOULSHOT) && (weaponInst.getItem().getCrystalTypePlus() == item.getItem().getCrystalTypePlus());
+
+ if (!gradeCheck)
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.THE_SOULSHOT_YOU_ARE_ATTEMPTING_TO_USE_DOES_NOT_MATCH_THE_GRADE_OF_YOUR_EQUIPPED_WEAPON);
+ }
+ return false;
+ }
+
+ activeChar.soulShotLock.lock();
+ try
+ {
+ // Check if Soul shot is already active
+ if (activeChar.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ return false;
+ }
+
+ // Consume Soul shots if player has enough of them
+ int SSCount = weaponItem.getSoulShotCount();
+ if ((weaponItem.getReducedSoulShot() > 0) && (Rnd.get(100) < weaponItem.getReducedSoulShotChance()))
+ {
+ SSCount = weaponItem.getReducedSoulShot();
+ }
+
+ if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), SSCount, null, false))
+ {
+ if (!activeChar.disableAutoShot(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SOULSHOTS_FOR_THAT);
+ }
+ return false;
+ }
+ // Charge soul shot
+ weaponInst.setChargedShot(ShotType.BLESSED_SOULSHOTS, true);
+ }
+ finally
+ {
+ activeChar.soulShotLock.unlock();
+ }
+
+ // Send message to client
+ if (!activeChar.getAutoSoulShot().contains(item.getId()))
+ {
+ activeChar.sendPacket(SystemMessageId.YOUR_SOULSHOTS_ARE_ENABLED);
+ }
+
+ // Visual effect change if player has equipped Ruby lvl 3 or higher
+ if (activeChar.getActiveRubyJewel() != null)
+ {
+ Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, activeChar.getActiveRubyJewel().getEffectId(), 1, 0, 0), 600);
+ }
+ else
+ {
+ skills.forEach(holder -> Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, holder.getSkillId(), holder.getSkillLevel(), 0, 0), 600));
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/enums/ShotType.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/enums/ShotType.java
index 56a2ec6691..2e98cb6d93 100644
--- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/enums/ShotType.java
+++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/enums/ShotType.java
@@ -23,6 +23,7 @@ public enum ShotType
{
SOULSHOTS,
SPIRITSHOTS,
+ BLESSED_SOULSHOTS,
BLESSED_SPIRITSHOTS,
FISH_SOULSHOTS;
diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java
index 6fa47963d7..795bf13a3e 100644
--- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java
+++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/actor/L2Character.java
@@ -1134,7 +1134,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
setCurrentCp(getCurrentCp() - 10);
}
- final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS); // Verify if soulshots are charged.
+ final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS) || isChargedShot(ShotType.BLESSED_SOULSHOTS); // Verify if soulshots are charged.
final int timeAtk = Formulas.calculateTimeBetweenAttacks(this, weaponType); // Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
final int timeToHit = timeAtk / 2; // the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case
final int ssGrade = (weaponItem != null) ? weaponItem.getItemGrade().ordinal() : 0;
@@ -4013,7 +4013,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
else
{
// If we didn't miss the hit, discharge the shoulshots, if any
- setChargedShot(ShotType.SOULSHOTS, false);
+ setChargedShot(isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Check Raidboss attack
diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/Skill.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/Skill.java
index 4db95c40b5..2b568af5e3 100644
--- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/Skill.java
+++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/Skill.java
@@ -1467,7 +1467,7 @@ public final class Skill implements IIdentifiable
}
else if (useSoulShot())
{
- caster.setChargedShot(ShotType.SOULSHOTS, false);
+ caster.setChargedShot(caster.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
}
diff --git a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
index a2b9564f4f..47cf19adfa 100644
--- a/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
+++ b/L2J_Mobius_Classic/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
@@ -221,7 +221,7 @@ public class SkillChannelizer implements Runnable
}
else
{
- _channelizer.setChargedShot(ShotType.SOULSHOTS, false);
+ _channelizer.setChargedShot(_channelizer.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Shots are re-charged every cast.
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/MasterHandler.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/MasterHandler.java
index b069ae1dab..067310d847 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/MasterHandler.java
@@ -179,6 +179,7 @@ import handlers.communityboard.RegionBoard;
import handlers.itemhandlers.Appearance;
import handlers.itemhandlers.BeastSoulShot;
import handlers.itemhandlers.BeastSpiritShot;
+import handlers.itemhandlers.BlessedSoulShots;
import handlers.itemhandlers.BlessedSpiritShot;
import handlers.itemhandlers.Book;
import handlers.itemhandlers.Bypass;
@@ -493,6 +494,7 @@ public class MasterHandler
Appearance.class,
BeastSoulShot.class,
BeastSpiritShot.class,
+ BlessedSoulShots.class,
BlessedSpiritShot.class,
Book.class,
Bypass.class,
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/Backstab.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
index c9a6db7ddf..0a9760db2b 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
@@ -78,7 +78,7 @@ public final class Backstab extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, true, _power, shld, ss);
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
index ab74235f45..6086cd5051 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
@@ -139,7 +139,18 @@ public final class EnergyAttack extends AbstractEffect
// Skill specific mods.
final double energyChargesBoost = 1 + (charge * 0.1); // 10% bonus damage for each charge used.
final double critMod = critical ? Formulas.calcCritDamage(attacker, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && attacker.isChargedShot(ShotType.SOULSHOTS)) ? (2 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (attacker.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * attacker.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (attacker.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * attacker.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................________Initial Damage_________...__Charges Additional Damage__...____________________________________
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
index 560373de58..3991d26090 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
@@ -108,7 +108,7 @@ public final class FatalBlow extends AbstractEffect
power += _abnormalPower;
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, power, shld, ss);
final boolean crit = Formulas.calcCrit(_criticalChance, effector, effected, skill);
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
index 3e3f266a98..959f47aac4 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
@@ -151,7 +151,18 @@ public final class PhysicalAttack extends AbstractEffect
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double abnormalMod = _abnormals.stream().anyMatch(effected::hasAbnormalType) ? _abnormalPowerMod : 1;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
index 3572414842..71410e4865 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
@@ -113,7 +113,18 @@ public final class PhysicalAttackHpLink extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
index b9d7172f2d..e03f74aa73 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
@@ -123,7 +123,18 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
index 58720b8cc4..774c4cee99 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
@@ -144,7 +144,18 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
final double weaponBonus = _weaponBonus.getOrDefault(effector.getAttackType(), 1.0);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
index db8d2dcb0f..402b0ea3fd 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
@@ -137,7 +137,18 @@ public final class PhysicalSoulAttack extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? (2 * effector.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
final double soulsMod = 1 + (souls * 0.04); // Souls Formula (each soul increase +4%)
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
index 999daafeb0..02f6612439 100644
--- a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
@@ -82,7 +82,7 @@ public final class SoulBlow extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, _power, shld, ss);
if ((skill.getMaxSoulConsumeCount() > 0) && effector.isPlayer())
diff --git a/L2J_Mobius_Helios/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
new file mode 100644
index 0000000000..b8a223f1d4
--- /dev/null
+++ b/L2J_Mobius_Helios/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package handlers.itemhandlers;
+
+import java.util.List;
+
+import com.l2jmobius.commons.util.Rnd;
+import com.l2jmobius.gameserver.enums.ItemSkillType;
+import com.l2jmobius.gameserver.enums.ShotType;
+import com.l2jmobius.gameserver.handler.IItemHandler;
+import com.l2jmobius.gameserver.model.actor.L2Playable;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
+import com.l2jmobius.gameserver.model.items.L2Weapon;
+import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jmobius.gameserver.model.items.type.ActionType;
+import com.l2jmobius.gameserver.network.SystemMessageId;
+import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jmobius.gameserver.util.Broadcast;
+
+/**
+ * @author Mobius
+ */
+public class BlessedSoulShots implements IItemHandler
+{
+ @Override
+ public boolean useItem(L2Playable playable, L2ItemInstance item, boolean forceUse)
+ {
+ if (!playable.isPlayer())
+ {
+ playable.sendPacket(SystemMessageId.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
+ return false;
+ }
+
+ final L2PcInstance activeChar = playable.getActingPlayer();
+ final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
+ final L2Weapon weaponItem = activeChar.getActiveWeaponItem();
+ final List skills = item.getItem().getSkills(ItemSkillType.NORMAL);
+ if (skills == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": is missing skills!");
+ return false;
+ }
+
+ final int itemId = item.getId();
+
+ // Check if Soul shot can be used
+ if ((weaponInst == null) || (weaponItem.getSoulShotCount() == 0))
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_SOULSHOTS);
+ }
+ return false;
+ }
+
+ final boolean gradeCheck = item.isEtcItem() && (item.getEtcItem().getDefaultAction() == ActionType.SOULSHOT) && (weaponInst.getItem().getCrystalTypePlus() == item.getItem().getCrystalTypePlus());
+
+ if (!gradeCheck)
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.THE_SOULSHOT_YOU_ARE_ATTEMPTING_TO_USE_DOES_NOT_MATCH_THE_GRADE_OF_YOUR_EQUIPPED_WEAPON);
+ }
+ return false;
+ }
+
+ activeChar.soulShotLock.lock();
+ try
+ {
+ // Check if Soul shot is already active
+ if (activeChar.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ return false;
+ }
+
+ // Consume Soul shots if player has enough of them
+ int SSCount = weaponItem.getSoulShotCount();
+ if ((weaponItem.getReducedSoulShot() > 0) && (Rnd.get(100) < weaponItem.getReducedSoulShotChance()))
+ {
+ SSCount = weaponItem.getReducedSoulShot();
+ }
+
+ if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), SSCount, null, false))
+ {
+ if (!activeChar.disableAutoShot(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SOULSHOTS_FOR_THAT);
+ }
+ return false;
+ }
+ // Charge soul shot
+ weaponInst.setChargedShot(ShotType.BLESSED_SOULSHOTS, true);
+ }
+ finally
+ {
+ activeChar.soulShotLock.unlock();
+ }
+
+ // Send message to client
+ if (!activeChar.getAutoSoulShot().contains(item.getId()))
+ {
+ activeChar.sendPacket(SystemMessageId.YOUR_SOULSHOTS_ARE_ENABLED);
+ }
+
+ // Visual effect change if player has equipped Ruby lvl 3 or higher
+ if (activeChar.getActiveRubyJewel() != null)
+ {
+ Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, activeChar.getActiveRubyJewel().getEffectId(), 1, 0, 0), 600);
+ }
+ else
+ {
+ skills.forEach(holder -> Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, holder.getSkillId(), holder.getSkillLevel(), 0, 0), 600));
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/enums/ShotType.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/enums/ShotType.java
index 56a2ec6691..2e98cb6d93 100644
--- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/enums/ShotType.java
+++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/enums/ShotType.java
@@ -23,6 +23,7 @@ public enum ShotType
{
SOULSHOTS,
SPIRITSHOTS,
+ BLESSED_SOULSHOTS,
BLESSED_SPIRITSHOTS,
FISH_SOULSHOTS;
diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java
index 6fa47963d7..795bf13a3e 100644
--- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java
+++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java
@@ -1134,7 +1134,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
setCurrentCp(getCurrentCp() - 10);
}
- final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS); // Verify if soulshots are charged.
+ final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS) || isChargedShot(ShotType.BLESSED_SOULSHOTS); // Verify if soulshots are charged.
final int timeAtk = Formulas.calculateTimeBetweenAttacks(this, weaponType); // Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
final int timeToHit = timeAtk / 2; // the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case
final int ssGrade = (weaponItem != null) ? weaponItem.getItemGrade().ordinal() : 0;
@@ -4013,7 +4013,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
else
{
// If we didn't miss the hit, discharge the shoulshots, if any
- setChargedShot(ShotType.SOULSHOTS, false);
+ setChargedShot(isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Check Raidboss attack
diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/Skill.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/Skill.java
index 4db95c40b5..2b568af5e3 100644
--- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/Skill.java
+++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/Skill.java
@@ -1467,7 +1467,7 @@ public final class Skill implements IIdentifiable
}
else if (useSoulShot())
{
- caster.setChargedShot(ShotType.SOULSHOTS, false);
+ caster.setChargedShot(caster.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
}
diff --git a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
index a2b9564f4f..47cf19adfa 100644
--- a/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
+++ b/L2J_Mobius_Helios/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
@@ -221,7 +221,7 @@ public class SkillChannelizer implements Runnable
}
else
{
- _channelizer.setChargedShot(ShotType.SOULSHOTS, false);
+ _channelizer.setChargedShot(_channelizer.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Shots are re-charged every cast.
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/MasterHandler.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/MasterHandler.java
index b069ae1dab..067310d847 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/MasterHandler.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/MasterHandler.java
@@ -179,6 +179,7 @@ import handlers.communityboard.RegionBoard;
import handlers.itemhandlers.Appearance;
import handlers.itemhandlers.BeastSoulShot;
import handlers.itemhandlers.BeastSpiritShot;
+import handlers.itemhandlers.BlessedSoulShots;
import handlers.itemhandlers.BlessedSpiritShot;
import handlers.itemhandlers.Book;
import handlers.itemhandlers.Bypass;
@@ -493,6 +494,7 @@ public class MasterHandler
Appearance.class,
BeastSoulShot.class,
BeastSpiritShot.class,
+ BlessedSoulShots.class,
BlessedSpiritShot.class,
Book.class,
Bypass.class,
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/Backstab.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
index c9a6db7ddf..0a9760db2b 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/Backstab.java
@@ -78,7 +78,7 @@ public final class Backstab extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, true, _power, shld, ss);
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
index ab74235f45..6086cd5051 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/EnergyAttack.java
@@ -139,7 +139,18 @@ public final class EnergyAttack extends AbstractEffect
// Skill specific mods.
final double energyChargesBoost = 1 + (charge * 0.1); // 10% bonus damage for each charge used.
final double critMod = critical ? Formulas.calcCritDamage(attacker, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && attacker.isChargedShot(ShotType.SOULSHOTS)) ? (2 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (attacker.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * attacker.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (attacker.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * attacker.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................________Initial Damage_________...__Charges Additional Damage__...____________________________________
// ATTACK CALCULATION ((77 * ((pAtk * lvlMod) + power) * (1 + (0.1 * chargesConsumed)) / pdef) * skillPower) + skillPowerAdd
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
index 560373de58..3991d26090 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/FatalBlow.java
@@ -108,7 +108,7 @@ public final class FatalBlow extends AbstractEffect
power += _abnormalPower;
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, power, shld, ss);
final boolean crit = Formulas.calcCrit(_criticalChance, effector, effected, skill);
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
index 3e3f266a98..959f47aac4 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttack.java
@@ -151,7 +151,18 @@ public final class PhysicalAttack extends AbstractEffect
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double abnormalMod = _abnormals.stream().anyMatch(effected::hasAbnormalType) ? _abnormalPowerMod : 1;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
index 3572414842..71410e4865 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackHpLink.java
@@ -113,7 +113,18 @@ public final class PhysicalAttackHpLink extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
index b9d7172f2d..e03f74aa73 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackSaveHp.java
@@ -123,7 +123,18 @@ public final class PhysicalAttackSaveHp extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
index 58720b8cc4..774c4cee99 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalAttackWeaponBonus.java
@@ -144,7 +144,18 @@ public final class PhysicalAttackWeaponBonus extends AbstractEffect
final double weaponBonus = _weaponBonus.getOrDefault(effector.getAttackType(), 1.0);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? effector.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
// ATTACK CALCULATION 77 * ((pAtk * lvlMod) + power) / pdef RANGED ATTACK CALCULATION 70 * ((pAtk * lvlMod) + power + patk + power) / pdef
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
index db8d2dcb0f..402b0ea3fd 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/PhysicalSoulAttack.java
@@ -137,7 +137,18 @@ public final class PhysicalSoulAttack extends AbstractEffect
final double wpnMod = effector.getAttackType().isRanged() ? 70 : (70 * 1.10113);
final double rangedBonus = effector.getAttackType().isRanged() ? (attack + _power) : 0;
final double critMod = critical ? Formulas.calcCritDamage(effector, effected, skill) : 1;
- final double ssmod = (skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS)) ? (2 * effector.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
+ double ssmod = 1;
+ if (skill.useSoulShot())
+ {
+ if (effector.isChargedShot(ShotType.SOULSHOTS))
+ {
+ ssmod = 2 * effector.getStat().getValue(Stats.SHOTS_BONUS); // 2.04 for dual weapon?
+ }
+ else if (effector.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ ssmod = 4 * effector.getStat().getValue(Stats.SHOTS_BONUS);
+ }
+ }
final double soulsMod = 1 + (souls * 0.04); // Souls Formula (each soul increase +4%)
// ...................____________Melee Damage_____________......................................___________________Ranged Damage____________________
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
index 999daafeb0..02f6612439 100644
--- a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/effecthandlers/SoulBlow.java
@@ -82,7 +82,7 @@ public final class SoulBlow extends AbstractEffect
((L2Attackable) effected).overhitEnabled(true);
}
- final boolean ss = skill.useSoulShot() && effector.isChargedShot(ShotType.SOULSHOTS);
+ final boolean ss = skill.useSoulShot() && (effector.isChargedShot(ShotType.SOULSHOTS) || effector.isChargedShot(ShotType.BLESSED_SOULSHOTS));
final byte shld = Formulas.calcShldUse(effector, effected);
double damage = Formulas.calcBlowDamage(effector, effected, skill, false, _power, shld, ss);
if ((skill.getMaxSoulConsumeCount() > 0) && effector.isPlayer())
diff --git a/L2J_Mobius_Underground/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
new file mode 100644
index 0000000000..b8a223f1d4
--- /dev/null
+++ b/L2J_Mobius_Underground/dist/game/data/scripts/handlers/itemhandlers/BlessedSoulShots.java
@@ -0,0 +1,131 @@
+/*
+ * This file is part of the L2J Mobius project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package handlers.itemhandlers;
+
+import java.util.List;
+
+import com.l2jmobius.commons.util.Rnd;
+import com.l2jmobius.gameserver.enums.ItemSkillType;
+import com.l2jmobius.gameserver.enums.ShotType;
+import com.l2jmobius.gameserver.handler.IItemHandler;
+import com.l2jmobius.gameserver.model.actor.L2Playable;
+import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
+import com.l2jmobius.gameserver.model.items.L2Weapon;
+import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
+import com.l2jmobius.gameserver.model.items.type.ActionType;
+import com.l2jmobius.gameserver.network.SystemMessageId;
+import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
+import com.l2jmobius.gameserver.util.Broadcast;
+
+/**
+ * @author Mobius
+ */
+public class BlessedSoulShots implements IItemHandler
+{
+ @Override
+ public boolean useItem(L2Playable playable, L2ItemInstance item, boolean forceUse)
+ {
+ if (!playable.isPlayer())
+ {
+ playable.sendPacket(SystemMessageId.YOUR_PET_CANNOT_CARRY_THIS_ITEM);
+ return false;
+ }
+
+ final L2PcInstance activeChar = playable.getActingPlayer();
+ final L2ItemInstance weaponInst = activeChar.getActiveWeaponInstance();
+ final L2Weapon weaponItem = activeChar.getActiveWeaponItem();
+ final List skills = item.getItem().getSkills(ItemSkillType.NORMAL);
+ if (skills == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": is missing skills!");
+ return false;
+ }
+
+ final int itemId = item.getId();
+
+ // Check if Soul shot can be used
+ if ((weaponInst == null) || (weaponItem.getSoulShotCount() == 0))
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.CANNOT_USE_SOULSHOTS);
+ }
+ return false;
+ }
+
+ final boolean gradeCheck = item.isEtcItem() && (item.getEtcItem().getDefaultAction() == ActionType.SOULSHOT) && (weaponInst.getItem().getCrystalTypePlus() == item.getItem().getCrystalTypePlus());
+
+ if (!gradeCheck)
+ {
+ if (!activeChar.getAutoSoulShot().contains(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.THE_SOULSHOT_YOU_ARE_ATTEMPTING_TO_USE_DOES_NOT_MATCH_THE_GRADE_OF_YOUR_EQUIPPED_WEAPON);
+ }
+ return false;
+ }
+
+ activeChar.soulShotLock.lock();
+ try
+ {
+ // Check if Soul shot is already active
+ if (activeChar.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ return false;
+ }
+
+ // Consume Soul shots if player has enough of them
+ int SSCount = weaponItem.getSoulShotCount();
+ if ((weaponItem.getReducedSoulShot() > 0) && (Rnd.get(100) < weaponItem.getReducedSoulShotChance()))
+ {
+ SSCount = weaponItem.getReducedSoulShot();
+ }
+
+ if (!activeChar.destroyItemWithoutTrace("Consume", item.getObjectId(), SSCount, null, false))
+ {
+ if (!activeChar.disableAutoShot(itemId))
+ {
+ activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SOULSHOTS_FOR_THAT);
+ }
+ return false;
+ }
+ // Charge soul shot
+ weaponInst.setChargedShot(ShotType.BLESSED_SOULSHOTS, true);
+ }
+ finally
+ {
+ activeChar.soulShotLock.unlock();
+ }
+
+ // Send message to client
+ if (!activeChar.getAutoSoulShot().contains(item.getId()))
+ {
+ activeChar.sendPacket(SystemMessageId.YOUR_SOULSHOTS_ARE_ENABLED);
+ }
+
+ // Visual effect change if player has equipped Ruby lvl 3 or higher
+ if (activeChar.getActiveRubyJewel() != null)
+ {
+ Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, activeChar.getActiveRubyJewel().getEffectId(), 1, 0, 0), 600);
+ }
+ else
+ {
+ skills.forEach(holder -> Broadcast.toSelfAndKnownPlayersInRadius(activeChar, new MagicSkillUse(activeChar, activeChar, holder.getSkillId(), holder.getSkillLevel(), 0, 0), 600));
+ }
+ return true;
+ }
+}
diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/enums/ShotType.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/enums/ShotType.java
index 56a2ec6691..2e98cb6d93 100644
--- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/enums/ShotType.java
+++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/enums/ShotType.java
@@ -23,6 +23,7 @@ public enum ShotType
{
SOULSHOTS,
SPIRITSHOTS,
+ BLESSED_SOULSHOTS,
BLESSED_SPIRITSHOTS,
FISH_SOULSHOTS;
diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java
index 6fa47963d7..795bf13a3e 100644
--- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java
+++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java
@@ -1134,7 +1134,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
setCurrentCp(getCurrentCp() - 10);
}
- final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS); // Verify if soulshots are charged.
+ final boolean wasSSCharged = isChargedShot(ShotType.SOULSHOTS) || isChargedShot(ShotType.BLESSED_SOULSHOTS); // Verify if soulshots are charged.
final int timeAtk = Formulas.calculateTimeBetweenAttacks(this, weaponType); // Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
final int timeToHit = timeAtk / 2; // the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case
final int ssGrade = (weaponItem != null) ? weaponItem.getItemGrade().ordinal() : 0;
@@ -4013,7 +4013,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
else
{
// If we didn't miss the hit, discharge the shoulshots, if any
- setChargedShot(ShotType.SOULSHOTS, false);
+ setChargedShot(isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Check Raidboss attack
diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/Skill.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/Skill.java
index 4db95c40b5..2b568af5e3 100644
--- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/Skill.java
+++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/Skill.java
@@ -1467,7 +1467,7 @@ public final class Skill implements IIdentifiable
}
else if (useSoulShot())
{
- caster.setChargedShot(ShotType.SOULSHOTS, false);
+ caster.setChargedShot(caster.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
}
diff --git a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
index a2b9564f4f..47cf19adfa 100644
--- a/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
+++ b/L2J_Mobius_Underground/java/com/l2jmobius/gameserver/model/skills/SkillChannelizer.java
@@ -221,7 +221,7 @@ public class SkillChannelizer implements Runnable
}
else
{
- _channelizer.setChargedShot(ShotType.SOULSHOTS, false);
+ _channelizer.setChargedShot(_channelizer.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS, false);
}
// Shots are re-charged every cast.