diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java index e96bad403a..553009ab81 100644 --- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java +++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java @@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - // TODO: Unhardcode Cubic Skill to avoid double damage - if (effector.isAlikeDead() || (skill.getId() == 4049)) + if (effector.isAlikeDead()) { return; } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java index 2e8e8f6631..ded399b50f 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target)); } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java index c92709158b..33473d382d 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java @@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic; import java.util.Comparator; import java.util.concurrent.ScheduledFuture; +import java.util.stream.Stream; import com.l2jmobius.Config; import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; @@ -52,7 +54,7 @@ public class CubicInstance private void activate() { - _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::tryToUseSkill, 0, _template.getDelay() * 1000); + _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::readyToUseSkill, 0, _template.getDelay() * 1000); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000); } @@ -74,23 +76,120 @@ public class CubicInstance _owner.broadcastCharInfo(); } - private void tryToUseSkill() + private void readyToUseSkill() + { + switch (_template.getTargetType()) + { + case TARGET: + { + actionToCurrentTarget(); + break; + } + case BY_SKILL: + { + actionToTargetBySkill(); + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + actionToMaster(); + break; + } + } + } + + private CubicSkill chooseSkill() { final double random = Rnd.nextDouble() * 100; double commulativeChance = 0; for (CubicSkill cubicSkill : _template.getSkills()) { - commulativeChance += cubicSkill.getTriggerRate(); - if (commulativeChance > random) + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) + { + return cubicSkill; + } + } + + return null; + } + + private void actionToCurrentTarget() + { + final CubicSkill skill = chooseSkill(); + final L2Object target = _owner.getTarget(); + if ((skill != null) && (target != null)) + { + tryToUseSkill(target, skill); + } + } + + private void actionToTargetBySkill() + { + final CubicSkill skill = chooseSkill(); + if (skill != null) + { + switch (skill.getTargetType()) + { + case TARGET: + { + final L2Object target = _owner.getTarget(); + if (target != null) + { + tryToUseSkill(target, skill); + } + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + tryToUseSkill(_owner, skill); + break; + } + } + } + } + + private void actionHeal() + { + final double random = Rnd.nextDouble() * 100; + double commulativeChance = 0; + for (CubicSkill cubicSkill : _template.getSkills()) + { + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) { final Skill skill = cubicSkill.getSkill(); if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) { - final L2Character target = findTarget(cubicSkill); + final L2Party party = _owner.getParty(); + Stream stream; + if (party != null) + { + stream = L2World.getInstance().getVisibleObjects(_owner, L2Character.class, Config.ALT_PARTY_RANGE, c -> (c.getParty() == party) && _template.validateConditions(this, _owner, c) && cubicSkill.validateConditions(this, _owner, c)).stream(); + } + else + { + stream = _owner.getServitorsAndPets().stream().filter(summon -> _template.validateConditions(this, _owner, summon) && cubicSkill.validateConditions(this, _owner, summon)).map(L2Character.class::cast); + + } + + if (_template.validateConditions(this, _owner, _owner) && cubicSkill.validateConditions(this, _owner, _owner)) + { + stream = Stream.concat(stream, Stream.of(_owner)); + } + + final L2Character target = stream.sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent)).findFirst().orElse(null); if (target != null) { - _owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); - skill.activateSkill(_owner, target); + activateCubicSkill(skill, target); break; } } @@ -98,115 +197,49 @@ public class CubicInstance } } - private L2Character findTarget(CubicSkill cubicSkill) + private void actionToMaster() { - switch (_template.getTargetType()) + final CubicSkill skill = chooseSkill(); + if (skill != null) { - case BY_SKILL: + tryToUseSkill(_owner, skill); + } + } + + private void tryToUseSkill(L2Object target, CubicSkill cubicSkill) + { + final Skill skill = cubicSkill.getSkill(); + if ((_template.getTargetType() != CubicTargetType.MASTER) && !((_template.getTargetType() == CubicTargetType.BY_SKILL) && (cubicSkill.getTargetType() == CubicTargetType.MASTER))) + { + target = skill.getTarget(_owner, target, false, false, false); + } + + if (target != null) + { + if (target.isDoor() && !cubicSkill.canUseOnStaticObjects()) { - if (!_template.validateConditions(this, _owner, _owner)) - { - return null; - } - - final Skill skill = cubicSkill.getSkill(); - if (skill != null) - { - switch (cubicSkill.getTargetType()) - { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object possibleTarget = skill.getTarget(_owner, false, false, false); - if ((possibleTarget != null) && possibleTarget.isCharacter()) - { - if (cubicSkill.validateConditions(this, _owner, (L2Character) possibleTarget)) - { - return (L2Character) possibleTarget; - } - } - break; - } - } - } - break; + return; } - case TARGET: + + if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target)) { - switch (cubicSkill.getTargetType()) + if (Rnd.get(100) < cubicSkill.getSuccessRate()) { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object targetObject = _owner.getTarget(); - if ((targetObject != null) && targetObject.isCharacter()) - { - final L2Character target = (L2Character) targetObject; - if (cubicSkill.validateConditions(this, _owner, target)) - { - return target; - } - } - break; - } + activateCubicSkill(skill, target); } - break; - } - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; } } - return null; + } + + private void activateCubicSkill(Skill skill, L2Object target) + { + if (!_owner.hasSkillReuse(skill.getReuseHashCode())) + { + _caster.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); + skill.activateSkill(this, target); + + _owner.addTimeStamp(skill, skill.getReuseDelay()); + } } /** diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java index c6d16e20ab..2e1595822b 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -33,7 +34,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder private final int _triggerRate; private final int _successRate; private final boolean _canUseOnStaticObjects; - private final CubicSkillTargetType _targetType; + private final CubicTargetType _targetType; private final List _conditions = new ArrayList<>(); private final boolean _targetDebuff; @@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder _triggerRate = set.getInt("triggerRate", 100); _successRate = set.getInt("successRate", 100); _canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); - _targetType = set.getEnum("target", CubicSkillTargetType.class, CubicSkillTargetType.TARGET); + _targetType = set.getEnum("target", CubicTargetType.class, CubicTargetType.TARGET); _targetDebuff = set.getBoolean("targetDebuff", false); } @@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder return _canUseOnStaticObjects; } - public CubicSkillTargetType getTargetType() + public CubicTargetType getTargetType() { return _targetType; } @@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { - return (!_targetDebuff || (_targetDebuff && (target.getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); + return (!_targetDebuff || (_targetDebuff && target.isCharacter() && (((L2Character) target).getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); } @Override diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java deleted file mode 100644 index e49fbd92d0..0000000000 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 com.l2jmobius.gameserver.model.cubic; - -/** - * @author UnAfraid - */ -public enum CubicSkillTargetType -{ - HEAL, - MASTER, - TARGET -} diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java index a5a287bbab..b3565fa0f7 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java @@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic; */ public enum CubicTargetType { - BY_SKILL, TARGET, - HEAL; + BY_SKILL, + HEAL, + MASTER; } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java index 7f1ca986c1..7fff07e017 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; */ public interface ICubicConditionHolder { - boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); + boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target); void addCondition(ICubicCondition condition); } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java index 5bc0317993..134926eb7b 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - return (hpPer > _min) && (hpPer < _max); + if (target.isCharacter() || target.isDoor()) + { + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + return (hpPer > _min) && (hpPer < _max); + } + return false; } @Override diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java index 73916319c3..eb2388a69b 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - switch (_type) + if (target.isCharacter() || target.isDoor()) { - case GREATER: + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + switch (_type) { - return hpPer > _hpPer; - } - case LESSER: - { - return hpPer < _hpPer; + case GREATER: + { + return hpPer > _hpPer; + } + case LESSER: + { + return hpPer < _hpPer; + } } } - return true; + return false; } @Override diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java index 4bd8567f1d..f936f41355 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance; */ public interface ICubicCondition { - boolean test(CubicInstance cubic, L2Character owner, L2Character target); + boolean test(CubicInstance cubic, L2Character owner, L2Object target); } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java index e92f8fbacf..c5d04fc123 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - return owner.distFromMe(target) <= _range; + return owner.calculateDistance(target, false, false) <= _range; } } diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java index e96bad403a..553009ab81 100644 --- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java +++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java @@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - // TODO: Unhardcode Cubic Skill to avoid double damage - if (effector.isAlikeDead() || (skill.getId() == 4049)) + if (effector.isAlikeDead()) { return; } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java index 2e8e8f6631..ded399b50f 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target)); } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java index c92709158b..33473d382d 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java @@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic; import java.util.Comparator; import java.util.concurrent.ScheduledFuture; +import java.util.stream.Stream; import com.l2jmobius.Config; import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; @@ -52,7 +54,7 @@ public class CubicInstance private void activate() { - _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::tryToUseSkill, 0, _template.getDelay() * 1000); + _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::readyToUseSkill, 0, _template.getDelay() * 1000); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000); } @@ -74,23 +76,120 @@ public class CubicInstance _owner.broadcastCharInfo(); } - private void tryToUseSkill() + private void readyToUseSkill() + { + switch (_template.getTargetType()) + { + case TARGET: + { + actionToCurrentTarget(); + break; + } + case BY_SKILL: + { + actionToTargetBySkill(); + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + actionToMaster(); + break; + } + } + } + + private CubicSkill chooseSkill() { final double random = Rnd.nextDouble() * 100; double commulativeChance = 0; for (CubicSkill cubicSkill : _template.getSkills()) { - commulativeChance += cubicSkill.getTriggerRate(); - if (commulativeChance > random) + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) + { + return cubicSkill; + } + } + + return null; + } + + private void actionToCurrentTarget() + { + final CubicSkill skill = chooseSkill(); + final L2Object target = _owner.getTarget(); + if ((skill != null) && (target != null)) + { + tryToUseSkill(target, skill); + } + } + + private void actionToTargetBySkill() + { + final CubicSkill skill = chooseSkill(); + if (skill != null) + { + switch (skill.getTargetType()) + { + case TARGET: + { + final L2Object target = _owner.getTarget(); + if (target != null) + { + tryToUseSkill(target, skill); + } + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + tryToUseSkill(_owner, skill); + break; + } + } + } + } + + private void actionHeal() + { + final double random = Rnd.nextDouble() * 100; + double commulativeChance = 0; + for (CubicSkill cubicSkill : _template.getSkills()) + { + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) { final Skill skill = cubicSkill.getSkill(); if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) { - final L2Character target = findTarget(cubicSkill); + final L2Party party = _owner.getParty(); + Stream stream; + if (party != null) + { + stream = L2World.getInstance().getVisibleObjects(_owner, L2Character.class, Config.ALT_PARTY_RANGE, c -> (c.getParty() == party) && _template.validateConditions(this, _owner, c) && cubicSkill.validateConditions(this, _owner, c)).stream(); + } + else + { + stream = _owner.getServitorsAndPets().stream().filter(summon -> _template.validateConditions(this, _owner, summon) && cubicSkill.validateConditions(this, _owner, summon)).map(L2Character.class::cast); + + } + + if (_template.validateConditions(this, _owner, _owner) && cubicSkill.validateConditions(this, _owner, _owner)) + { + stream = Stream.concat(stream, Stream.of(_owner)); + } + + final L2Character target = stream.sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent)).findFirst().orElse(null); if (target != null) { - _owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); - skill.activateSkill(_owner, target); + activateCubicSkill(skill, target); break; } } @@ -98,115 +197,49 @@ public class CubicInstance } } - private L2Character findTarget(CubicSkill cubicSkill) + private void actionToMaster() { - switch (_template.getTargetType()) + final CubicSkill skill = chooseSkill(); + if (skill != null) { - case BY_SKILL: + tryToUseSkill(_owner, skill); + } + } + + private void tryToUseSkill(L2Object target, CubicSkill cubicSkill) + { + final Skill skill = cubicSkill.getSkill(); + if ((_template.getTargetType() != CubicTargetType.MASTER) && !((_template.getTargetType() == CubicTargetType.BY_SKILL) && (cubicSkill.getTargetType() == CubicTargetType.MASTER))) + { + target = skill.getTarget(_owner, target, false, false, false); + } + + if (target != null) + { + if (target.isDoor() && !cubicSkill.canUseOnStaticObjects()) { - if (!_template.validateConditions(this, _owner, _owner)) - { - return null; - } - - final Skill skill = cubicSkill.getSkill(); - if (skill != null) - { - switch (cubicSkill.getTargetType()) - { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object possibleTarget = skill.getTarget(_owner, false, false, false); - if ((possibleTarget != null) && possibleTarget.isCharacter()) - { - if (cubicSkill.validateConditions(this, _owner, (L2Character) possibleTarget)) - { - return (L2Character) possibleTarget; - } - } - break; - } - } - } - break; + return; } - case TARGET: + + if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target)) { - switch (cubicSkill.getTargetType()) + if (Rnd.get(100) < cubicSkill.getSuccessRate()) { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object targetObject = _owner.getTarget(); - if ((targetObject != null) && targetObject.isCharacter()) - { - final L2Character target = (L2Character) targetObject; - if (cubicSkill.validateConditions(this, _owner, target)) - { - return target; - } - } - break; - } + activateCubicSkill(skill, target); } - break; - } - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; } } - return null; + } + + private void activateCubicSkill(Skill skill, L2Object target) + { + if (!_owner.hasSkillReuse(skill.getReuseHashCode())) + { + _caster.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); + skill.activateSkill(this, target); + + _owner.addTimeStamp(skill, skill.getReuseDelay()); + } } /** diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java index c6d16e20ab..2e1595822b 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -33,7 +34,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder private final int _triggerRate; private final int _successRate; private final boolean _canUseOnStaticObjects; - private final CubicSkillTargetType _targetType; + private final CubicTargetType _targetType; private final List _conditions = new ArrayList<>(); private final boolean _targetDebuff; @@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder _triggerRate = set.getInt("triggerRate", 100); _successRate = set.getInt("successRate", 100); _canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); - _targetType = set.getEnum("target", CubicSkillTargetType.class, CubicSkillTargetType.TARGET); + _targetType = set.getEnum("target", CubicTargetType.class, CubicTargetType.TARGET); _targetDebuff = set.getBoolean("targetDebuff", false); } @@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder return _canUseOnStaticObjects; } - public CubicSkillTargetType getTargetType() + public CubicTargetType getTargetType() { return _targetType; } @@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { - return (!_targetDebuff || (_targetDebuff && (target.getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); + return (!_targetDebuff || (_targetDebuff && target.isCharacter() && (((L2Character) target).getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); } @Override diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java deleted file mode 100644 index e49fbd92d0..0000000000 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 com.l2jmobius.gameserver.model.cubic; - -/** - * @author UnAfraid - */ -public enum CubicSkillTargetType -{ - HEAL, - MASTER, - TARGET -} diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java index a5a287bbab..b3565fa0f7 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java @@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic; */ public enum CubicTargetType { - BY_SKILL, TARGET, - HEAL; + BY_SKILL, + HEAL, + MASTER; } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java index 7f1ca986c1..7fff07e017 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; */ public interface ICubicConditionHolder { - boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); + boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target); void addCondition(ICubicCondition condition); } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java index 5bc0317993..134926eb7b 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - return (hpPer > _min) && (hpPer < _max); + if (target.isCharacter() || target.isDoor()) + { + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + return (hpPer > _min) && (hpPer < _max); + } + return false; } @Override diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java index 73916319c3..eb2388a69b 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - switch (_type) + if (target.isCharacter() || target.isDoor()) { - case GREATER: + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + switch (_type) { - return hpPer > _hpPer; - } - case LESSER: - { - return hpPer < _hpPer; + case GREATER: + { + return hpPer > _hpPer; + } + case LESSER: + { + return hpPer < _hpPer; + } } } - return true; + return false; } @Override diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java index 4bd8567f1d..f936f41355 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance; */ public interface ICubicCondition { - boolean test(CubicInstance cubic, L2Character owner, L2Character target); + boolean test(CubicInstance cubic, L2Character owner, L2Object target); } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java index e92f8fbacf..c5d04fc123 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - return owner.distFromMe(target) <= _range; + return owner.calculateDistance(target, false, false) <= _range; } } diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java index e96bad403a..553009ab81 100644 --- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java +++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java @@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - // TODO: Unhardcode Cubic Skill to avoid double damage - if (effector.isAlikeDead() || (skill.getId() == 4049)) + if (effector.isAlikeDead()) { return; } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java index 2e8e8f6631..ded399b50f 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target)); } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java index c92709158b..33473d382d 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java @@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic; import java.util.Comparator; import java.util.concurrent.ScheduledFuture; +import java.util.stream.Stream; import com.l2jmobius.Config; import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; @@ -52,7 +54,7 @@ public class CubicInstance private void activate() { - _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::tryToUseSkill, 0, _template.getDelay() * 1000); + _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::readyToUseSkill, 0, _template.getDelay() * 1000); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000); } @@ -74,23 +76,120 @@ public class CubicInstance _owner.broadcastCharInfo(); } - private void tryToUseSkill() + private void readyToUseSkill() + { + switch (_template.getTargetType()) + { + case TARGET: + { + actionToCurrentTarget(); + break; + } + case BY_SKILL: + { + actionToTargetBySkill(); + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + actionToMaster(); + break; + } + } + } + + private CubicSkill chooseSkill() { final double random = Rnd.nextDouble() * 100; double commulativeChance = 0; for (CubicSkill cubicSkill : _template.getSkills()) { - commulativeChance += cubicSkill.getTriggerRate(); - if (commulativeChance > random) + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) + { + return cubicSkill; + } + } + + return null; + } + + private void actionToCurrentTarget() + { + final CubicSkill skill = chooseSkill(); + final L2Object target = _owner.getTarget(); + if ((skill != null) && (target != null)) + { + tryToUseSkill(target, skill); + } + } + + private void actionToTargetBySkill() + { + final CubicSkill skill = chooseSkill(); + if (skill != null) + { + switch (skill.getTargetType()) + { + case TARGET: + { + final L2Object target = _owner.getTarget(); + if (target != null) + { + tryToUseSkill(target, skill); + } + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + tryToUseSkill(_owner, skill); + break; + } + } + } + } + + private void actionHeal() + { + final double random = Rnd.nextDouble() * 100; + double commulativeChance = 0; + for (CubicSkill cubicSkill : _template.getSkills()) + { + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) { final Skill skill = cubicSkill.getSkill(); if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) { - final L2Character target = findTarget(cubicSkill); + final L2Party party = _owner.getParty(); + Stream stream; + if (party != null) + { + stream = L2World.getInstance().getVisibleObjects(_owner, L2Character.class, Config.ALT_PARTY_RANGE, c -> (c.getParty() == party) && _template.validateConditions(this, _owner, c) && cubicSkill.validateConditions(this, _owner, c)).stream(); + } + else + { + stream = _owner.getServitorsAndPets().stream().filter(summon -> _template.validateConditions(this, _owner, summon) && cubicSkill.validateConditions(this, _owner, summon)).map(L2Character.class::cast); + + } + + if (_template.validateConditions(this, _owner, _owner) && cubicSkill.validateConditions(this, _owner, _owner)) + { + stream = Stream.concat(stream, Stream.of(_owner)); + } + + final L2Character target = stream.sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent)).findFirst().orElse(null); if (target != null) { - _owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); - skill.activateSkill(_owner, target); + activateCubicSkill(skill, target); break; } } @@ -98,115 +197,49 @@ public class CubicInstance } } - private L2Character findTarget(CubicSkill cubicSkill) + private void actionToMaster() { - switch (_template.getTargetType()) + final CubicSkill skill = chooseSkill(); + if (skill != null) { - case BY_SKILL: + tryToUseSkill(_owner, skill); + } + } + + private void tryToUseSkill(L2Object target, CubicSkill cubicSkill) + { + final Skill skill = cubicSkill.getSkill(); + if ((_template.getTargetType() != CubicTargetType.MASTER) && !((_template.getTargetType() == CubicTargetType.BY_SKILL) && (cubicSkill.getTargetType() == CubicTargetType.MASTER))) + { + target = skill.getTarget(_owner, target, false, false, false); + } + + if (target != null) + { + if (target.isDoor() && !cubicSkill.canUseOnStaticObjects()) { - if (!_template.validateConditions(this, _owner, _owner)) - { - return null; - } - - final Skill skill = cubicSkill.getSkill(); - if (skill != null) - { - switch (cubicSkill.getTargetType()) - { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object possibleTarget = skill.getTarget(_owner, false, false, false); - if ((possibleTarget != null) && possibleTarget.isCharacter()) - { - if (cubicSkill.validateConditions(this, _owner, (L2Character) possibleTarget)) - { - return (L2Character) possibleTarget; - } - } - break; - } - } - } - break; + return; } - case TARGET: + + if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target)) { - switch (cubicSkill.getTargetType()) + if (Rnd.get(100) < cubicSkill.getSuccessRate()) { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object targetObject = _owner.getTarget(); - if ((targetObject != null) && targetObject.isCharacter()) - { - final L2Character target = (L2Character) targetObject; - if (cubicSkill.validateConditions(this, _owner, target)) - { - return target; - } - } - break; - } + activateCubicSkill(skill, target); } - break; - } - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; } } - return null; + } + + private void activateCubicSkill(Skill skill, L2Object target) + { + if (!_owner.hasSkillReuse(skill.getReuseHashCode())) + { + _caster.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); + skill.activateSkill(this, target); + + _owner.addTimeStamp(skill, skill.getReuseDelay()); + } } /** diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java index c6d16e20ab..2e1595822b 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -33,7 +34,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder private final int _triggerRate; private final int _successRate; private final boolean _canUseOnStaticObjects; - private final CubicSkillTargetType _targetType; + private final CubicTargetType _targetType; private final List _conditions = new ArrayList<>(); private final boolean _targetDebuff; @@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder _triggerRate = set.getInt("triggerRate", 100); _successRate = set.getInt("successRate", 100); _canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); - _targetType = set.getEnum("target", CubicSkillTargetType.class, CubicSkillTargetType.TARGET); + _targetType = set.getEnum("target", CubicTargetType.class, CubicTargetType.TARGET); _targetDebuff = set.getBoolean("targetDebuff", false); } @@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder return _canUseOnStaticObjects; } - public CubicSkillTargetType getTargetType() + public CubicTargetType getTargetType() { return _targetType; } @@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { - return (!_targetDebuff || (_targetDebuff && (target.getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); + return (!_targetDebuff || (_targetDebuff && target.isCharacter() && (((L2Character) target).getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); } @Override diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java deleted file mode 100644 index e49fbd92d0..0000000000 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 com.l2jmobius.gameserver.model.cubic; - -/** - * @author UnAfraid - */ -public enum CubicSkillTargetType -{ - HEAL, - MASTER, - TARGET -} diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java index a5a287bbab..b3565fa0f7 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java @@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic; */ public enum CubicTargetType { - BY_SKILL, TARGET, - HEAL; + BY_SKILL, + HEAL, + MASTER; } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java index 7f1ca986c1..7fff07e017 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; */ public interface ICubicConditionHolder { - boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); + boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target); void addCondition(ICubicCondition condition); } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java index 5bc0317993..134926eb7b 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - return (hpPer > _min) && (hpPer < _max); + if (target.isCharacter() || target.isDoor()) + { + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + return (hpPer > _min) && (hpPer < _max); + } + return false; } @Override diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java index 73916319c3..eb2388a69b 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - switch (_type) + if (target.isCharacter() || target.isDoor()) { - case GREATER: + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + switch (_type) { - return hpPer > _hpPer; - } - case LESSER: - { - return hpPer < _hpPer; + case GREATER: + { + return hpPer > _hpPer; + } + case LESSER: + { + return hpPer < _hpPer; + } } } - return true; + return false; } @Override diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java index 4bd8567f1d..f936f41355 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance; */ public interface ICubicCondition { - boolean test(CubicInstance cubic, L2Character owner, L2Character target); + boolean test(CubicInstance cubic, L2Character owner, L2Object target); } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java index e92f8fbacf..c5d04fc123 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - return owner.distFromMe(target) <= _range; + return owner.calculateDistance(target, false, false) <= _range; } } diff --git a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java index e96bad403a..553009ab81 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java +++ b/L2J_Mobius_Classic_2.0_Saviors/dist/game/data/scripts/handlers/effecthandlers/MagicalAttack.java @@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect @Override public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) { - // TODO: Unhardcode Cubic Skill to avoid double damage - if (effector.isAlikeDead() || (skill.getId() == 4049)) + if (effector.isAlikeDead()) { return; } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java index 2e8e8f6631..ded399b50f 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/templates/L2CubicTemplate.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target)); } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java index c92709158b..33473d382d 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicInstance.java @@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic; import java.util.Comparator; import java.util.concurrent.ScheduledFuture; +import java.util.stream.Stream; import com.l2jmobius.Config; import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Party; +import com.l2jmobius.gameserver.model.L2World; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; @@ -52,7 +54,7 @@ public class CubicInstance private void activate() { - _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::tryToUseSkill, 0, _template.getDelay() * 1000); + _skillUseTask = ThreadPoolManager.scheduleAtFixedRate(this::readyToUseSkill, 0, _template.getDelay() * 1000); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000); } @@ -74,23 +76,120 @@ public class CubicInstance _owner.broadcastCharInfo(); } - private void tryToUseSkill() + private void readyToUseSkill() + { + switch (_template.getTargetType()) + { + case TARGET: + { + actionToCurrentTarget(); + break; + } + case BY_SKILL: + { + actionToTargetBySkill(); + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + actionToMaster(); + break; + } + } + } + + private CubicSkill chooseSkill() { final double random = Rnd.nextDouble() * 100; double commulativeChance = 0; for (CubicSkill cubicSkill : _template.getSkills()) { - commulativeChance += cubicSkill.getTriggerRate(); - if (commulativeChance > random) + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) + { + return cubicSkill; + } + } + + return null; + } + + private void actionToCurrentTarget() + { + final CubicSkill skill = chooseSkill(); + final L2Object target = _owner.getTarget(); + if ((skill != null) && (target != null)) + { + tryToUseSkill(target, skill); + } + } + + private void actionToTargetBySkill() + { + final CubicSkill skill = chooseSkill(); + if (skill != null) + { + switch (skill.getTargetType()) + { + case TARGET: + { + final L2Object target = _owner.getTarget(); + if (target != null) + { + tryToUseSkill(target, skill); + } + break; + } + case HEAL: + { + actionHeal(); + break; + } + case MASTER: + { + tryToUseSkill(_owner, skill); + break; + } + } + } + } + + private void actionHeal() + { + final double random = Rnd.nextDouble() * 100; + double commulativeChance = 0; + for (CubicSkill cubicSkill : _template.getSkills()) + { + if ((commulativeChance += cubicSkill.getTriggerRate()) > random) { final Skill skill = cubicSkill.getSkill(); if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) { - final L2Character target = findTarget(cubicSkill); + final L2Party party = _owner.getParty(); + Stream stream; + if (party != null) + { + stream = L2World.getInstance().getVisibleObjects(_owner, L2Character.class, Config.ALT_PARTY_RANGE, c -> (c.getParty() == party) && _template.validateConditions(this, _owner, c) && cubicSkill.validateConditions(this, _owner, c)).stream(); + } + else + { + stream = _owner.getServitorsAndPets().stream().filter(summon -> _template.validateConditions(this, _owner, summon) && cubicSkill.validateConditions(this, _owner, summon)).map(L2Character.class::cast); + + } + + if (_template.validateConditions(this, _owner, _owner) && cubicSkill.validateConditions(this, _owner, _owner)) + { + stream = Stream.concat(stream, Stream.of(_owner)); + } + + final L2Character target = stream.sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent)).findFirst().orElse(null); if (target != null) { - _owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); - skill.activateSkill(_owner, target); + activateCubicSkill(skill, target); break; } } @@ -98,115 +197,49 @@ public class CubicInstance } } - private L2Character findTarget(CubicSkill cubicSkill) + private void actionToMaster() { - switch (_template.getTargetType()) + final CubicSkill skill = chooseSkill(); + if (skill != null) { - case BY_SKILL: + tryToUseSkill(_owner, skill); + } + } + + private void tryToUseSkill(L2Object target, CubicSkill cubicSkill) + { + final Skill skill = cubicSkill.getSkill(); + if ((_template.getTargetType() != CubicTargetType.MASTER) && !((_template.getTargetType() == CubicTargetType.BY_SKILL) && (cubicSkill.getTargetType() == CubicTargetType.MASTER))) + { + target = skill.getTarget(_owner, target, false, false, false); + } + + if (target != null) + { + if (target.isDoor() && !cubicSkill.canUseOnStaticObjects()) { - if (!_template.validateConditions(this, _owner, _owner)) - { - return null; - } - - final Skill skill = cubicSkill.getSkill(); - if (skill != null) - { - switch (cubicSkill.getTargetType()) - { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object possibleTarget = skill.getTarget(_owner, false, false, false); - if ((possibleTarget != null) && possibleTarget.isCharacter()) - { - if (cubicSkill.validateConditions(this, _owner, (L2Character) possibleTarget)) - { - return (L2Character) possibleTarget; - } - } - break; - } - } - } - break; + return; } - case TARGET: + + if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target)) { - switch (cubicSkill.getTargetType()) + if (Rnd.get(100) < cubicSkill.getSuccessRate()) { - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> cubicSkill.validateConditions(this, _owner, member) && member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case MASTER: - { - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; - } - case TARGET: - { - final L2Object targetObject = _owner.getTarget(); - if ((targetObject != null) && targetObject.isCharacter()) - { - final L2Character target = (L2Character) targetObject; - if (cubicSkill.validateConditions(this, _owner, target)) - { - return target; - } - } - break; - } + activateCubicSkill(skill, target); } - break; - } - case HEAL: - { - final L2Party party = _owner.getParty(); - if (party != null) - { - return party.getMembers().stream().filter(member -> member.isInsideRadius(_owner, Config.ALT_PARTY_RANGE, true, true)).sorted(Comparator.comparingInt(L2Character::getCurrentHpPercent).reversed()).findFirst().orElse(null); - } - if (cubicSkill.validateConditions(this, _owner, _owner)) - { - return _owner; - } - break; } } - return null; + } + + private void activateCubicSkill(Skill skill, L2Object target) + { + if (!_owner.hasSkillReuse(skill.getReuseHashCode())) + { + _caster.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); + skill.activateSkill(this, target); + + _owner.addTimeStamp(skill, skill.getReuseDelay()); + } } /** diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java index c6d16e20ab..2e1595822b 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkill.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import com.l2jmobius.Config; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -33,7 +34,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder private final int _triggerRate; private final int _successRate; private final boolean _canUseOnStaticObjects; - private final CubicSkillTargetType _targetType; + private final CubicTargetType _targetType; private final List _conditions = new ArrayList<>(); private final boolean _targetDebuff; @@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder _triggerRate = set.getInt("triggerRate", 100); _successRate = set.getInt("successRate", 100); _canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); - _targetType = set.getEnum("target", CubicSkillTargetType.class, CubicSkillTargetType.TARGET); + _targetType = set.getEnum("target", CubicTargetType.class, CubicTargetType.TARGET); _targetDebuff = set.getBoolean("targetDebuff", false); } @@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder return _canUseOnStaticObjects; } - public CubicSkillTargetType getTargetType() + public CubicTargetType getTargetType() { return _targetType; } @@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder } @Override - public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target) + public boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target) { - return (!_targetDebuff || (_targetDebuff && (target.getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); + return (!_targetDebuff || (_targetDebuff && target.isCharacter() && (((L2Character) target).getEffectList().getDebuffCount() > 0))) && (_conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target))); } @Override diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java deleted file mode 100644 index e49fbd92d0..0000000000 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicSkillTargetType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 com.l2jmobius.gameserver.model.cubic; - -/** - * @author UnAfraid - */ -public enum CubicSkillTargetType -{ - HEAL, - MASTER, - TARGET -} diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java index a5a287bbab..b3565fa0f7 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/CubicTargetType.java @@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic; */ public enum CubicTargetType { - BY_SKILL, TARGET, - HEAL; + BY_SKILL, + HEAL, + MASTER; } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java index 7f1ca986c1..7fff07e017 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/ICubicConditionHolder.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; @@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; */ public interface ICubicConditionHolder { - boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); + boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target); void addCondition(ICubicCondition condition); } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java index 5bc0317993..134926eb7b 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HealthCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - return (hpPer > _min) && (hpPer < _max); + if (target.isCharacter() || target.isDoor()) + { + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + return (hpPer > _min) && (hpPer < _max); + } + return false; } @Override diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java index 73916319c3..eb2388a69b 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/HpCondition.java @@ -16,7 +16,9 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; +import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance; /** @@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - final double hpPer = target.getCurrentHpPercent(); - switch (_type) + if (target.isCharacter() || target.isDoor()) { - case GREATER: + final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent(); + switch (_type) { - return hpPer > _hpPer; - } - case LESSER: - { - return hpPer < _hpPer; + case GREATER: + { + return hpPer > _hpPer; + } + case LESSER: + { + return hpPer < _hpPer; + } } } - return true; + return false; } @Override diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java index 4bd8567f1d..f936f41355 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/ICubicCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance; */ public interface ICubicCondition { - boolean test(CubicInstance cubic, L2Character owner, L2Character target); + boolean test(CubicInstance cubic, L2Character owner, L2Object target); } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java index e92f8fbacf..c5d04fc123 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/cubic/conditions/RangeCondition.java @@ -16,6 +16,7 @@ */ package com.l2jmobius.gameserver.model.cubic.conditions; +import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.cubic.CubicInstance; @@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition } @Override - public boolean test(CubicInstance cubic, L2Character owner, L2Character target) + public boolean test(CubicInstance cubic, L2Character owner, L2Object target) { - return owner.distFromMe(target) <= _range; + return owner.calculateDistance(target, false, false) <= _range; } }