Channeling skills rework.

Adapted from: L2jUnity free files.
This commit is contained in:
MobiusDev
2018-09-05 16:01:11 +00:00
parent b4be2cc560
commit 735d2f6384
182 changed files with 1705 additions and 1559 deletions

View File

@ -126,7 +126,7 @@ public final class Skill implements IIdentifiable
private final int _refId;
// all times in milliseconds
private final int _hitTime;
// private final int _skillInterruptTime;
private final double _hitCancelTime;
private final int _coolTime;
private final long _reuseHashCode;
private final int _reuseDelay;
@ -185,8 +185,8 @@ public final class Skill implements IIdentifiable
// Channeling data
private final int _channelingSkillId;
private final int _channelingTickInitialDelay;
private final int _channelingTickInterval;
private final long _channelingStart;
private final long _channelingTickInterval;
// Mentoring
private final boolean _isMentoring;
@ -259,6 +259,7 @@ public final class Skill implements IIdentifiable
_stayAfterDeath = set.getBoolean("stayAfterDeath", false);
_hitTime = set.getInt("hitTime", 0);
_hitCancelTime = set.getDouble("hitCancelTime", 0);
_coolTime = set.getInt("coolTime", 0);
_isDebuff = set.getBoolean("isDebuff", false);
_isRecoveryHerb = set.getBoolean("isRecoveryHerb", false);
@ -391,8 +392,8 @@ public final class Skill implements IIdentifiable
_icon = set.getString("icon", "icon.skill0000");
_channelingSkillId = set.getInt("channelingSkillId", 0);
_channelingTickInterval = set.getInt("channelingTickInterval", 2000);
_channelingTickInitialDelay = set.getInt("channelingTickInitialDelay", _channelingTickInterval);
_channelingTickInterval = (long) set.getFloat("channelingTickInterval", 2000f) * 1000;
_channelingStart = (long) (set.getFloat("channelingStart", 0f) * 1000);
_isMentoring = set.getBoolean("isMentoring", false);
@ -478,11 +479,6 @@ public final class Skill implements IIdentifiable
return false;
}
public boolean isDamage()
{
return hasEffectType(L2EffectType.MAGICAL_ATTACK, L2EffectType.HP_DRAIN, L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK);
}
public boolean isSuicideAttack()
{
return _isSuicideAttack;
@ -863,6 +859,11 @@ public final class Skill implements IIdentifiable
return _hitTime;
}
public double getHitCancelTime()
{
return _hitCancelTime;
}
/**
* @return the cool time
*/
@ -1355,8 +1356,6 @@ public final class Skill implements IIdentifiable
final EffectScope pvpOrPveEffectScope = effector.isPlayable() && effected.isAttackable() ? EffectScope.PVE : effector.isPlayable() && effected.isPlayable() ? EffectScope.PVP : null;
applyEffectScope(pvpOrPveEffectScope, info, instant, addContinuousEffects);
applyEffectScope(EffectScope.CHANNELING, info, instant, addContinuousEffects);
if (addContinuousEffects)
{
// Aura skills reset the abnormal time.
@ -1430,6 +1429,23 @@ public final class Skill implements IIdentifiable
}
}
/**
* Applies the channeling effects from this skill to the target.
* @param effector the caster of the skill
* @param effected the target of the effect
*/
public void applyChannelingEffects(L2Character effector, L2Character effected)
{
// null targets cannot receive any effects.
if (effected == null)
{
return;
}
final BuffInfo info = new BuffInfo(effector, effected, this, false, null, null);
applyEffectScope(EffectScope.CHANNELING, info, true, true);
}
/**
* Activates a skill for the given creature and targets.
* @param caster the caster
@ -1489,8 +1505,6 @@ public final class Skill implements IIdentifiable
final EffectScope pvpOrPveEffectScope = caster.isPlayable() && target.isAttackable() ? EffectScope.PVE : caster.isPlayable() && target.isPlayable() ? EffectScope.PVP : null;
applyEffectScope(pvpOrPveEffectScope, info, true, false);
applyEffectScope(EffectScope.CHANNELING, info, true, false);
}
else
{
@ -1709,14 +1723,14 @@ public final class Skill implements IIdentifiable
return _icon;
}
public int getChannelingTickInterval()
public long getChannelingTickInterval()
{
return _channelingTickInterval;
}
public int getChannelingTickInitialDelay()
public long getChannelingTickInitialDelay()
{
return _channelingTickInitialDelay;
return _channelingStart;
}
public Set<MountType> getRideState()

View File

@ -389,7 +389,7 @@ public class SkillCaster implements Runnable
}
// Start channeling if skill is channeling.
if (_skill.isChanneling() && (_skill.getChannelingSkillId() > 0))
if (_skill.isChanneling())
{
caster.getSkillChannelizer().startChanneling(_skill);
}

View File

@ -149,82 +149,84 @@ public class SkillChannelizer implements Runnable
}
// Apply channeling skills on the targets.
if (skill.getChannelingSkillId() > 0)
final List<L2Character> targetList = new ArrayList<>();
final L2Object target = skill.getTarget(_channelizer, false, false, false);
if (target != null)
{
final List<L2Character> targetList = new ArrayList<>();
final L2Object target = skill.getTarget(_channelizer, false, false, false);
if (target != null)
skill.forEachTargetAffected(_channelizer, target, o ->
{
skill.forEachTargetAffected(_channelizer, target, o ->
if (o.isCharacter())
{
if (o.isCharacter())
targetList.add((L2Character) o);
((L2Character) o).getSkillChannelized().addChannelizer(skill.getChannelingSkillId(), _channelizer);
}
});
}
if (targetList.isEmpty())
{
return;
}
channelized = targetList;
for (L2Character character : channelized)
{
if (!Util.checkIfInRange(skill.getEffectRange(), _channelizer, character, true))
{
continue;
}
else if (!GeoEngine.getInstance().canSeeTarget(_channelizer, character))
{
continue;
}
if (skill.getChannelingSkillId() > 0)
{
final int maxSkillLevel = SkillData.getInstance().getMaxLevel(skill.getChannelingSkillId());
final int skillLevel = Math.min(character.getSkillChannelized().getChannerlizersSize(skill.getChannelingSkillId()), maxSkillLevel);
final BuffInfo info = character.getEffectList().getBuffInfoBySkillId(skill.getChannelingSkillId());
if ((info == null) || (info.getSkill().getLevel() < skillLevel))
{
final Skill channeledSkill = SkillData.getInstance().getSkill(skill.getChannelingSkillId(), skillLevel);
if (channeledSkill == null)
{
targetList.add((L2Character) o);
((L2Character) o).getSkillChannelized().addChannelizer(skill.getChannelingSkillId(), _channelizer);
LOGGER.warning(getClass().getSimpleName() + ": Non existent channeling skill requested: " + skill);
_channelizer.abortCast();
return;
}
});
}
if (targetList.isEmpty())
{
return;
}
channelized = targetList;
for (L2Character character : channelized)
{
if (!Util.checkIfInRange(skill.getEffectRange(), _channelizer, character, true))
{
continue;
}
else if (!GeoEngine.getInstance().canSeeTarget(_channelizer, character))
{
continue;
}
else
{
final int maxSkillLevel = SkillData.getInstance().getMaxLevel(skill.getChannelingSkillId());
final int skillLevel = Math.min(character.getSkillChannelized().getChannerlizersSize(skill.getChannelingSkillId()), maxSkillLevel);
final BuffInfo info = character.getEffectList().getBuffInfoBySkillId(skill.getChannelingSkillId());
if ((info == null) || (info.getSkill().getLevel() < skillLevel))
// Update PvP status
if (character.isPlayable() && _channelizer.isPlayer())
{
final Skill channeledSkill = SkillData.getInstance().getSkill(skill.getChannelingSkillId(), skillLevel);
if (channeledSkill == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Non existent channeling skill requested: " + skill);
_channelizer.abortCast();
return;
}
// Update PvP status
if (character.isPlayable() && _channelizer.isPlayer())
{
((L2PcInstance) _channelizer).updatePvPStatus(character);
}
// Be warned, this method has the possibility to call doDie->abortCast->stopChanneling method. Variable cache above try"+ +" is used in this case to avoid NPEs.
channeledSkill.applyEffects(_channelizer, character);
// Reduce shots.
if (skill.useSpiritShot())
{
_channelizer.unchargeShot(_channelizer.isChargedShot(ShotType.BLESSED_SPIRITSHOTS) ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS);
}
else
{
_channelizer.unchargeShot(_channelizer.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS);
}
// Shots are re-charged every cast.
_channelizer.rechargeShots(skill.useSoulShot(), skill.useSpiritShot(), false);
}
if (!skill.isToggle())
{
_channelizer.broadcastPacket(new MagicSkillLaunched(_channelizer, skill.getId(), skill.getLevel(), SkillCastingType.NORMAL, character));
((L2PcInstance) _channelizer).updatePvPStatus(character);
}
// Be warned, this method has the possibility to call doDie->abortCast->stopChanneling method. Variable cache above try{} is used in this case to avoid NPEs.
channeledSkill.applyEffects(_channelizer, character);
}
if (!skill.isToggle())
{
_channelizer.broadcastPacket(new MagicSkillLaunched(_channelizer, skill.getId(), skill.getLevel(), SkillCastingType.NORMAL, character));
}
}
else
{
skill.applyChannelingEffects(_channelizer, character);
}
// Reduce shots.
if (skill.useSpiritShot())
{
_channelizer.unchargeShot(_channelizer.isChargedShot(ShotType.BLESSED_SPIRITSHOTS) ? ShotType.BLESSED_SPIRITSHOTS : ShotType.SPIRITSHOTS);
}
else
{
_channelizer.unchargeShot(_channelizer.isChargedShot(ShotType.BLESSED_SOULSHOTS) ? ShotType.BLESSED_SOULSHOTS : ShotType.SOULSHOTS);
}
// Shots are re-charged every cast.
_channelizer.rechargeShots(skill.useSoulShot(), skill.useSpiritShot(), false);
}
}
catch (Exception e)

View File

@ -484,13 +484,7 @@ public final class Formulas
public static double calcSkillCancelTime(L2Character creature, Skill skill)
{
// Fishing skills.
if ((skill.getId() == 1312) || (skill.getId() == 1314) || (skill.getId() == 1315))
{
return 0;
}
// return (int) Math.max(skill.getCancelTime() / calcSkillTimeFactor(attacker, skill), 500);
return Math.max(skill.getHitTime() / calcSkillTimeFactor(creature, skill), SKILL_LAUNCH_TIME);
return Math.max((skill.getHitCancelTime() * 1000) / calcSkillTimeFactor(creature, skill), SKILL_LAUNCH_TIME);
}
/**