Cubics rework.

Contributed by Liamxroy.
This commit is contained in:
MobiusDev
2017-09-30 23:41:08 +00:00
parent 9d7a14bdae
commit 36b9f58139
44 changed files with 732 additions and 644 deletions

View File

@@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect
@Override @Override
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
{ {
// TODO: Unhardcode Cubic Skill to avoid double damage if (effector.isAlikeDead())
if (effector.isAlikeDead() || (skill.getId() == 4049))
{ {
return; return;
} }

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder
} }
@Override @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)); return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target));
} }

View File

@@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.stream.Stream;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate;
@@ -52,7 +54,7 @@ public class CubicInstance
private void activate() 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); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000);
} }
@@ -74,23 +76,120 @@ public class CubicInstance
_owner.broadcastCharInfo(); _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; final double random = Rnd.nextDouble() * 100;
double commulativeChance = 0; double commulativeChance = 0;
for (CubicSkill cubicSkill : _template.getSkills()) for (CubicSkill cubicSkill : _template.getSkills())
{ {
commulativeChance += cubicSkill.getTriggerRate(); if ((commulativeChance += cubicSkill.getTriggerRate()) > random)
if (commulativeChance > 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(); final Skill skill = cubicSkill.getSkill();
if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate()))
{ {
final L2Character target = findTarget(cubicSkill); final L2Party party = _owner.getParty();
Stream<L2Character> 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) if (target != null)
{ {
_owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); activateCubicSkill(skill, target);
skill.activateSkill(_owner, target);
break; 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;
{
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;
} }
case TARGET:
if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target))
{ {
switch (cubicSkill.getTargetType()) if (Rnd.get(100) < cubicSkill.getSuccessRate())
{ {
case HEAL: activateCubicSkill(skill, target);
{
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;
}
} }
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());
}
} }
/** /**

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; 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 _triggerRate;
private final int _successRate; private final int _successRate;
private final boolean _canUseOnStaticObjects; private final boolean _canUseOnStaticObjects;
private final CubicSkillTargetType _targetType; private final CubicTargetType _targetType;
private final List<ICubicCondition> _conditions = new ArrayList<>(); private final List<ICubicCondition> _conditions = new ArrayList<>();
private final boolean _targetDebuff; private final boolean _targetDebuff;
@@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
_triggerRate = set.getInt("triggerRate", 100); _triggerRate = set.getInt("triggerRate", 100);
_successRate = set.getInt("successRate", 100); _successRate = set.getInt("successRate", 100);
_canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); _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); _targetDebuff = set.getBoolean("targetDebuff", false);
} }
@@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
return _canUseOnStaticObjects; return _canUseOnStaticObjects;
} }
public CubicSkillTargetType getTargetType() public CubicTargetType getTargetType()
{ {
return _targetType; return _targetType;
} }
@@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
} }
@Override @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 @Override

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.cubic;
/**
* @author UnAfraid
*/
public enum CubicSkillTargetType
{
HEAL,
MASTER,
TARGET
}

View File

@@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic;
*/ */
public enum CubicTargetType public enum CubicTargetType
{ {
BY_SKILL,
TARGET, TARGET,
HEAL; BY_SKILL,
HEAL,
MASTER;
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic; package com.l2jmobius.gameserver.model.cubic;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
@@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
*/ */
public interface ICubicConditionHolder public interface ICubicConditionHolder
{ {
boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target);
void addCondition(ICubicCondition condition); void addCondition(ICubicCondition condition);
} }

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
return (hpPer > _min) && (hpPer < _max); {
final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
return (hpPer > _min) && (hpPer < _max);
}
return false;
} }
@Override @Override

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
switch (_type)
{ {
case GREATER: final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
switch (_type)
{ {
return hpPer > _hpPer; case GREATER:
} {
case LESSER: return hpPer > _hpPer;
{ }
return hpPer < _hpPer; case LESSER:
{
return hpPer < _hpPer;
}
} }
} }
return true; return false;
} }
@Override @Override

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance;
*/ */
public interface ICubicCondition public interface ICubicCondition
{ {
boolean test(CubicInstance cubic, L2Character owner, L2Character target); boolean test(CubicInstance cubic, L2Character owner, L2Object target);
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition
} }
@Override @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;
} }
} }

View File

@@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect
@Override @Override
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
{ {
// TODO: Unhardcode Cubic Skill to avoid double damage if (effector.isAlikeDead())
if (effector.isAlikeDead() || (skill.getId() == 4049))
{ {
return; return;
} }

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder
} }
@Override @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)); return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target));
} }

View File

@@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.stream.Stream;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate;
@@ -52,7 +54,7 @@ public class CubicInstance
private void activate() 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); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000);
} }
@@ -74,23 +76,120 @@ public class CubicInstance
_owner.broadcastCharInfo(); _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; final double random = Rnd.nextDouble() * 100;
double commulativeChance = 0; double commulativeChance = 0;
for (CubicSkill cubicSkill : _template.getSkills()) for (CubicSkill cubicSkill : _template.getSkills())
{ {
commulativeChance += cubicSkill.getTriggerRate(); if ((commulativeChance += cubicSkill.getTriggerRate()) > random)
if (commulativeChance > 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(); final Skill skill = cubicSkill.getSkill();
if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate()))
{ {
final L2Character target = findTarget(cubicSkill); final L2Party party = _owner.getParty();
Stream<L2Character> 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) if (target != null)
{ {
_owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); activateCubicSkill(skill, target);
skill.activateSkill(_owner, target);
break; 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;
{
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;
} }
case TARGET:
if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target))
{ {
switch (cubicSkill.getTargetType()) if (Rnd.get(100) < cubicSkill.getSuccessRate())
{ {
case HEAL: activateCubicSkill(skill, target);
{
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;
}
} }
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());
}
} }
/** /**

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; 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 _triggerRate;
private final int _successRate; private final int _successRate;
private final boolean _canUseOnStaticObjects; private final boolean _canUseOnStaticObjects;
private final CubicSkillTargetType _targetType; private final CubicTargetType _targetType;
private final List<ICubicCondition> _conditions = new ArrayList<>(); private final List<ICubicCondition> _conditions = new ArrayList<>();
private final boolean _targetDebuff; private final boolean _targetDebuff;
@@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
_triggerRate = set.getInt("triggerRate", 100); _triggerRate = set.getInt("triggerRate", 100);
_successRate = set.getInt("successRate", 100); _successRate = set.getInt("successRate", 100);
_canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); _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); _targetDebuff = set.getBoolean("targetDebuff", false);
} }
@@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
return _canUseOnStaticObjects; return _canUseOnStaticObjects;
} }
public CubicSkillTargetType getTargetType() public CubicTargetType getTargetType()
{ {
return _targetType; return _targetType;
} }
@@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
} }
@Override @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 @Override

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.cubic;
/**
* @author UnAfraid
*/
public enum CubicSkillTargetType
{
HEAL,
MASTER,
TARGET
}

View File

@@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic;
*/ */
public enum CubicTargetType public enum CubicTargetType
{ {
BY_SKILL,
TARGET, TARGET,
HEAL; BY_SKILL,
HEAL,
MASTER;
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic; package com.l2jmobius.gameserver.model.cubic;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
@@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
*/ */
public interface ICubicConditionHolder public interface ICubicConditionHolder
{ {
boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target);
void addCondition(ICubicCondition condition); void addCondition(ICubicCondition condition);
} }

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
return (hpPer > _min) && (hpPer < _max); {
final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
return (hpPer > _min) && (hpPer < _max);
}
return false;
} }
@Override @Override

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
switch (_type)
{ {
case GREATER: final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
switch (_type)
{ {
return hpPer > _hpPer; case GREATER:
} {
case LESSER: return hpPer > _hpPer;
{ }
return hpPer < _hpPer; case LESSER:
{
return hpPer < _hpPer;
}
} }
} }
return true; return false;
} }
@Override @Override

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance;
*/ */
public interface ICubicCondition public interface ICubicCondition
{ {
boolean test(CubicInstance cubic, L2Character owner, L2Character target); boolean test(CubicInstance cubic, L2Character owner, L2Object target);
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition
} }
@Override @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;
} }
} }

View File

@@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect
@Override @Override
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
{ {
// TODO: Unhardcode Cubic Skill to avoid double damage if (effector.isAlikeDead())
if (effector.isAlikeDead() || (skill.getId() == 4049))
{ {
return; return;
} }

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder
} }
@Override @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)); return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target));
} }

View File

@@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.stream.Stream;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate;
@@ -52,7 +54,7 @@ public class CubicInstance
private void activate() 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); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000);
} }
@@ -74,23 +76,120 @@ public class CubicInstance
_owner.broadcastCharInfo(); _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; final double random = Rnd.nextDouble() * 100;
double commulativeChance = 0; double commulativeChance = 0;
for (CubicSkill cubicSkill : _template.getSkills()) for (CubicSkill cubicSkill : _template.getSkills())
{ {
commulativeChance += cubicSkill.getTriggerRate(); if ((commulativeChance += cubicSkill.getTriggerRate()) > random)
if (commulativeChance > 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(); final Skill skill = cubicSkill.getSkill();
if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate()))
{ {
final L2Character target = findTarget(cubicSkill); final L2Party party = _owner.getParty();
Stream<L2Character> 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) if (target != null)
{ {
_owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); activateCubicSkill(skill, target);
skill.activateSkill(_owner, target);
break; 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;
{
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;
} }
case TARGET:
if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target))
{ {
switch (cubicSkill.getTargetType()) if (Rnd.get(100) < cubicSkill.getSuccessRate())
{ {
case HEAL: activateCubicSkill(skill, target);
{
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;
}
} }
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());
}
} }
/** /**

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; 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 _triggerRate;
private final int _successRate; private final int _successRate;
private final boolean _canUseOnStaticObjects; private final boolean _canUseOnStaticObjects;
private final CubicSkillTargetType _targetType; private final CubicTargetType _targetType;
private final List<ICubicCondition> _conditions = new ArrayList<>(); private final List<ICubicCondition> _conditions = new ArrayList<>();
private final boolean _targetDebuff; private final boolean _targetDebuff;
@@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
_triggerRate = set.getInt("triggerRate", 100); _triggerRate = set.getInt("triggerRate", 100);
_successRate = set.getInt("successRate", 100); _successRate = set.getInt("successRate", 100);
_canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); _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); _targetDebuff = set.getBoolean("targetDebuff", false);
} }
@@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
return _canUseOnStaticObjects; return _canUseOnStaticObjects;
} }
public CubicSkillTargetType getTargetType() public CubicTargetType getTargetType()
{ {
return _targetType; return _targetType;
} }
@@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
} }
@Override @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 @Override

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.cubic;
/**
* @author UnAfraid
*/
public enum CubicSkillTargetType
{
HEAL,
MASTER,
TARGET
}

View File

@@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic;
*/ */
public enum CubicTargetType public enum CubicTargetType
{ {
BY_SKILL,
TARGET, TARGET,
HEAL; BY_SKILL,
HEAL,
MASTER;
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic; package com.l2jmobius.gameserver.model.cubic;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
@@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
*/ */
public interface ICubicConditionHolder public interface ICubicConditionHolder
{ {
boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target);
void addCondition(ICubicCondition condition); void addCondition(ICubicCondition condition);
} }

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
return (hpPer > _min) && (hpPer < _max); {
final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
return (hpPer > _min) && (hpPer < _max);
}
return false;
} }
@Override @Override

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
switch (_type)
{ {
case GREATER: final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
switch (_type)
{ {
return hpPer > _hpPer; case GREATER:
} {
case LESSER: return hpPer > _hpPer;
{ }
return hpPer < _hpPer; case LESSER:
{
return hpPer < _hpPer;
}
} }
} }
return true; return false;
} }
@Override @Override

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance;
*/ */
public interface ICubicCondition public interface ICubicCondition
{ {
boolean test(CubicInstance cubic, L2Character owner, L2Character target); boolean test(CubicInstance cubic, L2Character owner, L2Object target);
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition
} }
@Override @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;
} }
} }

View File

@@ -60,8 +60,7 @@ public final class MagicalAttack extends AbstractEffect
@Override @Override
public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item) public void instant(L2Character effector, L2Character effected, Skill skill, L2ItemInstance item)
{ {
// TODO: Unhardcode Cubic Skill to avoid double damage if (effector.isAlikeDead())
if (effector.isAlikeDead() || (skill.getId() == 4049))
{ {
return; return;
} }

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -109,7 +110,7 @@ public class L2CubicTemplate implements ICubicConditionHolder
} }
@Override @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)); return _conditions.isEmpty() || _conditions.stream().allMatch(condition -> condition.test(cubic, owner, target));
} }

View File

@@ -18,12 +18,14 @@ package com.l2jmobius.gameserver.model.cubic;
import java.util.Comparator; import java.util.Comparator;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.stream.Stream;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd; import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.ThreadPoolManager; import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.L2Object; import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate; import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate;
@@ -52,7 +54,7 @@ public class CubicInstance
private void activate() 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); _expireTask = ThreadPoolManager.schedule(this::deactivate, _template.getDuration() * 1000);
} }
@@ -74,23 +76,120 @@ public class CubicInstance
_owner.broadcastCharInfo(); _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; final double random = Rnd.nextDouble() * 100;
double commulativeChance = 0; double commulativeChance = 0;
for (CubicSkill cubicSkill : _template.getSkills()) for (CubicSkill cubicSkill : _template.getSkills())
{ {
commulativeChance += cubicSkill.getTriggerRate(); if ((commulativeChance += cubicSkill.getTriggerRate()) > random)
if (commulativeChance > 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(); final Skill skill = cubicSkill.getSkill();
if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate())) if ((skill != null) && (Rnd.get(100) < cubicSkill.getSuccessRate()))
{ {
final L2Character target = findTarget(cubicSkill); final L2Party party = _owner.getParty();
Stream<L2Character> 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) if (target != null)
{ {
_owner.broadcastPacket(new MagicSkillUse(_owner, target, skill.getDisplayId(), skill.getDisplayLevel(), skill.getHitTime(), skill.getReuseDelay())); activateCubicSkill(skill, target);
skill.activateSkill(_owner, target);
break; 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;
{
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;
} }
case TARGET:
if (_template.validateConditions(this, _owner, target) && cubicSkill.validateConditions(this, _owner, target))
{ {
switch (cubicSkill.getTargetType()) if (Rnd.get(100) < cubicSkill.getSuccessRate())
{ {
case HEAL: activateCubicSkill(skill, target);
{
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;
}
} }
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());
}
} }
/** /**

View File

@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.l2jmobius.Config; import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; 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 _triggerRate;
private final int _successRate; private final int _successRate;
private final boolean _canUseOnStaticObjects; private final boolean _canUseOnStaticObjects;
private final CubicSkillTargetType _targetType; private final CubicTargetType _targetType;
private final List<ICubicCondition> _conditions = new ArrayList<>(); private final List<ICubicCondition> _conditions = new ArrayList<>();
private final boolean _targetDebuff; private final boolean _targetDebuff;
@@ -43,7 +44,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
_triggerRate = set.getInt("triggerRate", 100); _triggerRate = set.getInt("triggerRate", 100);
_successRate = set.getInt("successRate", 100); _successRate = set.getInt("successRate", 100);
_canUseOnStaticObjects = set.getBoolean("canUseOnStaticObjects", false); _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); _targetDebuff = set.getBoolean("targetDebuff", false);
} }
@@ -62,7 +63,7 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
return _canUseOnStaticObjects; return _canUseOnStaticObjects;
} }
public CubicSkillTargetType getTargetType() public CubicTargetType getTargetType()
{ {
return _targetType; return _targetType;
} }
@@ -73,9 +74,9 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
} }
@Override @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 @Override

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.cubic;
/**
* @author UnAfraid
*/
public enum CubicSkillTargetType
{
HEAL,
MASTER,
TARGET
}

View File

@@ -21,7 +21,8 @@ package com.l2jmobius.gameserver.model.cubic;
*/ */
public enum CubicTargetType public enum CubicTargetType
{ {
BY_SKILL,
TARGET, TARGET,
HEAL; BY_SKILL,
HEAL,
MASTER;
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic; package com.l2jmobius.gameserver.model.cubic;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.actor.L2Character; import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition; import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
@@ -24,7 +25,7 @@ import com.l2jmobius.gameserver.model.cubic.conditions.ICubicCondition;
*/ */
public interface ICubicConditionHolder public interface ICubicConditionHolder
{ {
boolean validateConditions(CubicInstance cubic, L2Character owner, L2Character target); boolean validateConditions(CubicInstance cubic, L2Character owner, L2Object target);
void addCondition(ICubicCondition condition); void addCondition(ICubicCondition condition);
} }

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,10 +36,14 @@ public class HealthCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
return (hpPer > _min) && (hpPer < _max); {
final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
return (hpPer > _min) && (hpPer < _max);
}
return false;
} }
@Override @Override

View File

@@ -16,7 +16,9 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/** /**
@@ -34,21 +36,24 @@ public class HpCondition implements ICubicCondition
} }
@Override @Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target) public boolean test(CubicInstance cubic, L2Character owner, L2Object target)
{ {
final double hpPer = target.getCurrentHpPercent(); if (target.isCharacter() || target.isDoor())
switch (_type)
{ {
case GREATER: final double hpPer = (target.isDoor() ? (L2DoorInstance) target : (L2Character) target).getCurrentHpPercent();
switch (_type)
{ {
return hpPer > _hpPer; case GREATER:
} {
case LESSER: return hpPer > _hpPer;
{ }
return hpPer < _hpPer; case LESSER:
{
return hpPer < _hpPer;
}
} }
} }
return true; return false;
} }
@Override @Override

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -24,5 +25,5 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance;
*/ */
public interface ICubicCondition public interface ICubicCondition
{ {
boolean test(CubicInstance cubic, L2Character owner, L2Character target); boolean test(CubicInstance cubic, L2Character owner, L2Object target);
} }

View File

@@ -16,6 +16,7 @@
*/ */
package com.l2jmobius.gameserver.model.cubic.conditions; 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.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance; import com.l2jmobius.gameserver.model.cubic.CubicInstance;
@@ -32,8 +33,8 @@ public class RangeCondition implements ICubicCondition
} }
@Override @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;
} }
} }